diff --git a/Keyboards/icpad.bash b/Keyboards/icpad.bash index de299fd..ea3d414 100755 --- a/Keyboards/icpad.bash +++ b/Keyboards/icpad.bash @@ -43,7 +43,7 @@ PartialMaps[1]="" # Keyboard Module Configuration ScanModule="ICPad" -MacroModule="PartialMap" +MacroModule="PixelMap" OutputModule="pjrcUSB" DebugModule="full" diff --git a/Keyboards/ktype.bash b/Keyboards/ktype.bash new file mode 100755 index 0000000..500a037 --- /dev/null +++ b/Keyboards/ktype.bash @@ -0,0 +1,72 @@ +#!/bin/bash +# This is a build script template +# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) +# Jacob Alexander 2015 + + + +################# +# Configuration # +################# + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="KType" + +## KLL Configuration ## + +# Generally shouldn't be changed, this will affect every layer +BaseMap="defaultMap" + +# This is the default layer of the keyboard +# NOTE: To combine kll files into a single layout, separate them by spaces +# e.g. DefaultMap="mylayout mylayoutmod" +DefaultMap="stdFuncMap" + +# This is where you set the additional layers +# NOTE: Indexing starts at 1 +# NOTE: Each new layer is another array entry +# e.g. PartialMaps[1]="layer1 layer1mod" +# PartialMaps[2]="layer2" +# PartialMaps[3]="layer3" +PartialMaps[1]="" + + + +########################## +# Advanced Configuration # +########################## + +# Don't change the variables in this section unless you know what you're doing +# These are useful for completely custom keyboards +# NOTE: Changing any of these variables will require a force build to compile correctly + +# Keyboard Module Configuration +ScanModule="KType" +MacroModule="PixelMap" +OutputModule="pjrcUSB" +DebugModule="full" + +# Microcontroller +Chip="mk20dx256vlh7" + +# Compiler Selection +Compiler="gcc" + + + +######################## +# Bash Library Include # +######################## + +# Shouldn't need to touch this section + +# Check if the library can be found +if [ ! -f cmake.bash ]; then + echo "ERROR: Cannot find 'cmake.bash'" + exit 1 +fi + +# Load the library +source cmake.bash + diff --git a/Lib/CMake/build.cmake b/Lib/CMake/build.cmake index b3209bf..4cdf8b8 100644 --- a/Lib/CMake/build.cmake +++ b/Lib/CMake/build.cmake @@ -24,7 +24,7 @@ endif () #| Create the .ELF file set( TARGET_ELF ${TARGET}.elf ) -add_executable( ${TARGET_ELF} ${SRCS} generatedKeymap.h ) +add_executable( ${TARGET_ELF} ${SRCS} generatedKeymap.h kll_defs.h ) #| .ELF Properties diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 36802e4..0f5b580 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -11,7 +11,7 @@ # Check if KLL compiler is needed # -if ( "${MacroModule}" STREQUAL "PartialMap" ) +if ( "${MacroModule}" STREQUAL "PartialMap" OR "${MacroModule}" STREQUAL "PixelMap" ) @@ -148,6 +148,7 @@ add_custom_target ( kll_regen set ( SRCS ${SRCS} ${kll_outputname} ) - +else () +message ( AUTHOR_WARNING "Unknown Macro module, ignoring kll generation" ) endif () # PartialMap diff --git a/Scan/ICPad/defaultMap.kll b/Scan/ICPad/defaultMap.kll index c558967..fdf7b6d 100644 --- a/Scan/ICPad/defaultMap.kll +++ b/Scan/ICPad/defaultMap.kll @@ -143,27 +143,27 @@ ISSILedBrightness2 = " "; # Misc -ISSILedBrightness1 = " -0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, /* C1-1 -> C1-16 */ -0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* C2-1 -> C2-16 */ -0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, /* C3-1 -> C3-16 */ -0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, /* C6-1 -> C6-16 */ -0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, /* C7-1 -> C7-16 */ -0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, /* C8-1 -> C8-16 */ -0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* C9-1 -> C9-16 */ -"; +#ISSILedBrightness1 = " +#0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, /* C1-1 -> C1-16 */ +#0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* C2-1 -> C2-16 */ +#0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, /* C3-1 -> C3-16 */ +#0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, /* C6-1 -> C6-16 */ +#0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, /* C7-1 -> C7-16 */ +#0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, /* C8-1 -> C8-16 */ +#0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* C9-1 -> C9-16 */ +#"; -ISSILedBrightness2 = " -0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ -0x00, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ -0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ -0x00, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ -0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ -0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ -"; +#ISSILedBrightness2 = " +#0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +#0x00, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +#0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +#0x00, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +#0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +#0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +#0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +#"; diff --git a/Scan/ICPad/scan_loop.c b/Scan/ICPad/scan_loop.c index c1db646..3f20cd9 100644 --- a/Scan/ICPad/scan_loop.c +++ b/Scan/ICPad/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,7 @@ #include #include #include +#include // Local Includes #include "scan_loop.h" @@ -66,6 +67,9 @@ inline void Scan_setup() // Setup ISSI chip to control the leds LED_setup(); + // Setup Pixel Map + Pixel_setup(); + // Reset scan count Scan_scanCount = 0; } @@ -83,6 +87,9 @@ inline uint8_t Scan_loop() // Process any interconnect commands Connect_scan(); + // Prepare any LED events + Pixel_process(); + // Process any LED events LED_scan(); diff --git a/Scan/ISSILed/capabilities.kll b/Scan/ISSILed/capabilities.kll index 6aaad88..fa39dec 100644 --- a/Scan/ISSILed/capabilities.kll +++ b/Scan/ISSILed/capabilities.kll @@ -28,6 +28,22 @@ ledControl => LED_control_capability( mode : 1, amount : 1, index : 2 ); ISSI_Chips => ISSI_Chips_define; ISSI_Chips = 1; # 1 by default +# Default animation speed +# Can be set from 0 to 63 (A) +# Formula is TxA (T is approx 11ms) +# 0 - 1.4 fps (represents 64) +# 1 - 90 fps +# 2 - 45 fps +# 3 - 30 fps +# 4 - 22 fps +# etc. +# For a 400 kHz I2C, with a single chip, updating all 144 channels, generally 30 fps is the max for continuous animations +# Each additional chip consumes more bandwidth +# 20 - 4.5 fps - Slow, but should always work without glitches +# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details +ISSI_AnimationSpeed => ISSI_AnimationSpeed_define; +ISSI_AnimationSpeed = 20; # 20 by default + # LED Default Enable Mask # # By default, all LEDs are enabled diff --git a/Scan/ISSILed/i2c.c b/Scan/ISSILed/i2c.c new file mode 100644 index 0000000..f690e61 --- /dev/null +++ b/Scan/ISSILed/i2c.c @@ -0,0 +1,313 @@ +/* + * Copyright ( C ) 2014 Jan Rychter + * Modifications ( C ) 2015 Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files ( the "Software" ), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// ----- Includes ---- + +// Compiler Includes +#include + +// Project Includes +#include + +// Local Includes +#include "i2c.h" + + + +// ----- Variables ----- + +volatile I2C_Channel i2c_channels[1]; + + + +// ----- Functions ----- + +inline void i2c_setup( ) +{ + // Enable I2C internal clock + SIM_SCGC4 |= SIM_SCGC4_I2C0; // Bus 0 + + // External pull-up resistor + PORTB_PCR0 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); + PORTB_PCR1 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); + + // SCL Frequency Divider + // 1.8 MBaud ( likely higher than spec ) + // 0x82 -> 36 MHz / (4 * 3) = 2.25 MBaud + // 0x80 => mul(4) + // 0x05 => ICL(5) + I2C0_F = 0x84; + I2C0_FLT = 4; + I2C0_C1 = I2C_C1_IICEN; + I2C0_C2 = I2C_C2_HDRS; // High drive select + + // Enable I2C Interrupt + NVIC_ENABLE_IRQ( IRQ_I2C0 ); +} + +uint8_t i2c_busy() +{ + volatile I2C_Channel *channel = &( i2c_channels[0] ); + if ( channel->status == I2C_BUSY ) + { + return 1; + } + + return 0; +} + + +// These are here for readability and correspond to bit 0 of the address byte. +#define I2C_WRITING 0 +#define I2C_READING 1 + +int32_t i2c_send_sequence( + uint16_t *sequence, + uint32_t sequence_length, + uint8_t *received_data, + void ( *callback_fn )( void* ), + void *user_data +) { + volatile I2C_Channel *channel = &( i2c_channels[0] ); + int32_t result = 0; + uint8_t status; + + if ( channel->status == I2C_BUSY ) + { + return -1; + } + + // Debug + /* + for ( uint8_t c = 0; c < sequence_length; c++ ) + { + printHex( sequence[c] ); + print(" "); + } + print(NL); + */ + + channel->sequence = sequence; + channel->sequence_end = sequence + sequence_length; + channel->received_data = received_data; + channel->status = I2C_BUSY; + channel->txrx = I2C_WRITING; + channel->callback_fn = callback_fn; + channel->user_data = user_data; + + // reads_ahead does not need to be initialized + + // Acknowledge the interrupt request, just in case + I2C0_S |= I2C_S_IICIF; + I2C0_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE ); + + // Generate a start condition and prepare for transmitting. + I2C0_C1 |= ( I2C_C1_MST | I2C_C1_TX ); + + status = I2C0_S; + if ( status & I2C_S_ARBL ) + { + warn_print("Arbitration lost"); + result = -1; + goto i2c_send_sequence_cleanup; + } + + // Write the first (address) byte. + I2C0_D = *channel->sequence++; + + // Everything is OK. + return result; + +i2c_send_sequence_cleanup: + I2C0_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX ); + channel->status = I2C_ERROR; + return result; +} + + +void i2c0_isr() +{ + volatile I2C_Channel* channel = &i2c_channels[0]; + uint8_t element; + uint8_t status; + + status = I2C0_S; + + // Acknowledge the interrupt request + I2C0_S |= I2C_S_IICIF; + + // Arbitration problem + if ( status & I2C_S_ARBL ) + { + warn_print("Arbitration error"); + I2C0_S |= I2C_S_ARBL; + goto i2c_isr_error; + } + + if ( channel->txrx == I2C_READING ) + { + + switch( channel->reads_ahead ) + { + // All the reads in the sequence have been processed ( but note that the final data register read still needs to + // be done below! Now, the next thing is either a restart or the end of a sequence. In any case, we need to + // switch to TX mode, either to generate a repeated start condition, or to avoid triggering another I2C read + // when reading the contents of the data register. + case 0: + I2C0_C1 |= I2C_C1_TX; + + // Perform the final data register read now that it's safe to do so. + *channel->received_data++ = I2C0_D; + + // Do we have a repeated start? + if ( ( channel->sequence < channel->sequence_end ) && ( *channel->sequence == I2C_RESTART ) ) + { + + // Generate a repeated start condition. + I2C0_C1 |= I2C_C1_RSTA; + + // A restart is processed immediately, so we need to get a new element from our sequence. This is safe, because + // a sequence cannot end with a RESTART: there has to be something after it. Note that the only thing that can + // come after a restart is an address write. + channel->txrx = I2C_WRITING; + channel->sequence++; + element = *channel->sequence; + I2C0_D = element; + } + else + { + goto i2c_isr_stop; + } + break; + + case 1: + // do not ACK the final read + I2C0_C1 |= I2C_C1_TXAK; + *channel->received_data++ = I2C0_D; + break; + + default: + *channel->received_data++ = I2C0_D; + break; + } + + channel->reads_ahead--; + + } + // channel->txrx == I2C_WRITING + else + { + // First, check if we are at the end of a sequence. + if ( channel->sequence == channel->sequence_end ) + goto i2c_isr_stop; + + // We received a NACK. Generate a STOP condition and abort. + if ( status & I2C_S_RXAK ) + { + warn_print("NACK Received"); + goto i2c_isr_error; + } + + // check next thing in our sequence + element = *channel->sequence; + + // Do we have a restart? If so, generate repeated start and make sure TX is on. + if ( element == I2C_RESTART ) + { + I2C0_C1 |= I2C_C1_RSTA | I2C_C1_TX; + + // A restart is processed immediately, so we need to get a new element from our sequence. + // This is safe, because a sequence cannot end with a RESTART: there has to be something after it. + channel->sequence++; + element = *channel->sequence; + + // Note that the only thing that can come after a restart is a write. + I2C0_D = element; + } + else + { + if ( element == I2C_READ ) { + channel->txrx = I2C_READING; + // How many reads do we have ahead of us ( not including this one )? + // For reads we need to know the segment length to correctly plan NACK transmissions. + // We already know about one read + channel->reads_ahead = 1; + while ( + ( ( channel->sequence + channel->reads_ahead ) < channel->sequence_end ) && + ( *( channel->sequence + channel->reads_ahead ) == I2C_READ ) + ) { + channel->reads_ahead++; + } + + // Switch to RX mode. + I2C0_C1 &= ~I2C_C1_TX; + + // do not ACK the final read + if ( channel->reads_ahead == 1 ) + { + I2C0_C1 |= I2C_C1_TXAK; + } + // ACK all but the final read + else + { + I2C0_C1 &= ~( I2C_C1_TXAK ); + } + + // Dummy read comes first, note that this is not valid data! + // This only triggers a read, actual data will come in the next interrupt call and overwrite this. + // This is why we do not increment the received_data pointer. + *channel->received_data = I2C0_D; + channel->reads_ahead--; + } + // Not a restart, not a read, must be a write. + else + { + I2C0_D = element; + } + } + } + + channel->sequence++; + return; + +i2c_isr_stop: + // Generate STOP ( set MST=0 ), switch to RX mode, and disable further interrupts. + I2C0_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE | I2C_C1_TXAK ); + channel->status = I2C_AVAILABLE; + + // Call the user-supplied callback function upon successful completion (if it exists). + if ( channel->callback_fn ) + { + // Delay 10 microseconds before starting linked function + delayMicroseconds(10); + ( *channel->callback_fn )( channel->user_data ); + } + return; + +i2c_isr_error: + // Generate STOP and disable further interrupts. + I2C0_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE ); + channel->status = I2C_ERROR; + return; +} + diff --git a/Scan/ISSILed/i2c.h b/Scan/ISSILed/i2c.h new file mode 100644 index 0000000..1a0ff07 --- /dev/null +++ b/Scan/ISSILed/i2c.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 Jan Rychter + * Modifications (C) 2015 Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#pragma once + +// ----- Includes ---- + +// Compiler Includes +#include + + + +// ----- Defines ----- + +// Channel status definitions. These are not enumerated, as I want them to be uint8_t. +#define I2C_AVAILABLE 0 +#define I2C_BUSY 1 +#define I2C_ERROR 2 + + +#define I2C_RESTART 1<<8 +#define I2C_READ 2<<8 + + + +// ----- Structs ----- + +typedef struct { + uint16_t *sequence; + uint16_t *sequence_end; + uint8_t *received_data; + void (*callback_fn)(void*); + void *user_data; + uint8_t reads_ahead; + uint8_t status; + uint8_t txrx; +} I2C_Channel; + + + +// ----- Variables ----- + +extern volatile I2C_Channel i2c_channels[1]; + + + +// ----- Functions ----- + +/* + * I2C Module Setup - Channel 0 only + */ + +void i2c_setup(); + + +/* + * Sends a command/data sequence that can include restarts, writes and reads. Every transmission begins with a START, + * and ends with a STOP so you do not have to specify that. + * + * sequence is the I2C operation sequence that should be performed. It can include any number of writes, restarts and + * reads. Note that the sequence is composed of uint16_t, not uint8_t. This is because we have to support out-of-band + * signalling of I2C_RESTART and I2C_READ operations, while still passing through 8-bit data. + * + * sequence_length is the number of sequence elements (not bytes). Sequences of arbitrary length are supported. The + * minimum sequence length is (rather obviously) 2. + * + * received_data should point to a buffer that can hold as many bytes as there are I2C_READ operations in the + * sequence. If there are no reads, 0 can be passed, as this parameter will not be used. + * + * callback_fn is a pointer to a function that will get called upon successful completion of the entire sequence. If 0 is + * supplied, no function will be called. Note that the function will be called fron an interrupt handler, so it should do + * the absolute minimum possible (such as enqueue an event to be processed later, set a flag, exit sleep mode, etc.) + * + * user_data is a pointer that will be passed to the callback_fn. + */ + +int32_t i2c_send_sequence( + uint16_t *sequence, + uint32_t sequence_length, + uint8_t *received_data, + void (*callback_fn)(void*), + void *user_data +); + +/* + * Convenience macros + */ +#define i2c_send(seq, seq_len) i2c_send_sequence( seq, seq_len, 0, 0, 0 ) +#define i2c_read(seq, seq_len, rec) i2c_send_sequence( seq, seq_len, rec, 0, 0 ) + +/* + * Check if busy + */ +uint8_t i2c_busy(); + diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index 6a639a1..e04067a 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -24,6 +24,7 @@ #include #include #include +#include // Interconnect module if compiled in #if defined(ConnectEnabled_define) @@ -31,25 +32,23 @@ #endif // Local Includes +#include "i2c.h" #include "led_scan.h" // ----- Defines ----- -// Increase buffer sizes for RGB -#ifdef ISSI_RGB_define -#define I2C_TxBufferLength 600 -#define I2C_RxBufferLength 16 -#else -#define I2C_TxBufferLength 300 -#define I2C_RxBufferLength 8 -#endif - +// TODO Make this a kll define +// I2C transfers are more efficient if all 144 don't have to be updated +// (and most implementations don't use all the channels) +// Ergodox tested @ 83fps /w 38 +// Whitefox tested @ 45fps /w 71 #define LED_BufferLength 144 -#define LED_EnableBufferLength 18 -#define LED_TotalChannels (144 * ISSI_Chips_define) +#define LED_EnableBufferLength 18 +#define LED_FrameBuffersMax 4 +#define LED_TotalChannels (LED_BufferLength * ISSI_Chips_define) // ISSI Addresses // IS31FL3731 (max 4 channels per bus) @@ -89,24 +88,16 @@ // ----- Structs ----- -typedef struct I2C_Buffer { - uint16_t head; - uint16_t tail; - uint8_t sequencePos; - uint16_t size; - uint8_t *buffer; -} I2C_Buffer; - typedef struct LED_Buffer { - uint8_t i2c_addr; - uint8_t reg_addr; - uint8_t buffer[LED_BufferLength]; + uint16_t i2c_addr; + uint16_t reg_addr; + uint16_t buffer[LED_BufferLength]; } LED_Buffer; typedef struct LED_EnableBuffer { - uint8_t i2c_addr; - uint8_t reg_addr; - uint8_t buffer[LED_EnableBufferLength]; + uint16_t i2c_addr; + uint16_t reg_addr; + uint16_t buffer[LED_EnableBufferLength]; } LED_EnableBuffer; @@ -114,39 +105,31 @@ typedef struct LED_EnableBuffer { // ----- Function Declarations ----- // CLI Functions -void cliFunc_i2cRecv ( char* args ); -void cliFunc_i2cSend ( char* args ); -void cliFunc_ledCtrl ( char* args ); -void cliFunc_ledRPage( char* args ); -void cliFunc_ledStart( char* args ); -void cliFunc_ledTest ( char* args ); -void cliFunc_ledWPage( char* args ); -void cliFunc_ledZero ( char* args ); - -uint8_t I2C_TxBufferPop(); -void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer ); -uint16_t I2C_BufferLen( I2C_Buffer *buffer ); -uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ); +void cliFunc_i2cSend ( char* args ); +void cliFunc_ledCtrl ( char* args ); +void cliFunc_ledNFrame( char* args ); +void cliFunc_ledStart ( char* args ); +void cliFunc_ledTest ( char* args ); +void cliFunc_ledWPage ( char* args ); +void cliFunc_ledZero ( char* args ); // ----- Variables ----- // Scan Module command dictionary -CLIDict_Entry( i2cRecv, "Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence." NL "\t\tUse |'s to split sequences with a stop." ); CLIDict_Entry( i2cSend, "Send I2C sequence of bytes. Use |'s to split sequences with a stop." ); CLIDict_Entry( ledCtrl, "Basic LED control. Args: []" ); -CLIDict_Entry( ledRPage, "Read the given register page." ); +CLIDict_Entry( ledNFrame, "Increment led frame." ); CLIDict_Entry( ledStart, "Disable software shutdown." ); CLIDict_Entry( ledTest, "Test out the led pages." ); CLIDict_Entry( ledWPage, "Write to given register page starting at address. i.e. 0xE8 0x2 0x24 0xF0 0x12" ); CLIDict_Entry( ledZero, "Zero out LED register pages (non-configuration)." ); CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { - CLIDict_Item( i2cRecv ), CLIDict_Item( i2cSend ), CLIDict_Item( ledCtrl ), - CLIDict_Item( ledRPage ), + CLIDict_Item( ledNFrame ), CLIDict_Item( ledStart ), CLIDict_Item( ledTest ), CLIDict_Item( ledWPage ), @@ -155,17 +138,13 @@ CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { }; - -// Before sending the sequence, I2C_TxBuffer_CurLen is assigned and as each byte is sent, it is decremented -// Once I2C_TxBuffer_CurLen reaches zero, a STOP on the I2C bus is sent -volatile uint8_t I2C_TxBufferPtr[ I2C_TxBufferLength ]; -volatile uint8_t I2C_RxBufferPtr[ I2C_TxBufferLength ]; - -volatile I2C_Buffer I2C_TxBuffer = { 0, 0, 0, I2C_TxBufferLength, (uint8_t*)I2C_TxBufferPtr }; -volatile I2C_Buffer I2C_RxBuffer = { 0, 0, 0, I2C_RxBufferLength, (uint8_t*)I2C_RxBufferPtr }; - LED_Buffer LED_pageBuffer[ ISSI_Chips_define ]; + uint8_t LED_FrameBuffersReady; // Starts at maximum, reset on interrupt from ISSI +volatile uint8_t LED_FrameBufferReset; // INTB interrupt received, reset available buffer count when ready + uint8_t LED_FrameBufferPage; // Current page of the buffer + uint8_t LED_FrameBufferStart; // Whether or not a start signal can be sent + // Enable mask and default brightness for ISSI chip channel const LED_EnableBuffer LED_ledEnableMask[ISSI_Chips_define] = { LED_MaskDefine( 1 ), @@ -203,245 +182,130 @@ const LED_Buffer LED_defaultBrightness[ISSI_Chips_define] = { // ----- Interrupt Functions ----- -void i2c0_isr() +void portb_isr() { - cli(); // Disable Interrupts - - uint8_t status = I2C0_S; // Read I2C Bus status - - // Master Mode Transmit - if ( I2C0_C1 & I2C_C1_TX ) + // Check for ISSI INTB IRQ + if ( PORTB_ISFR & (1 << 17) ) { - // Check current use of the I2C bus - // Currently sending data - if ( I2C_TxBuffer.sequencePos > 0 ) - { - // Make sure slave sent an ACK - if ( status & I2C_S_RXAK ) - { - // NACK Detected, disable interrupt - erro_print("I2C NAK detected..."); - I2C0_C1 = I2C_C1_IICEN; + // Set frame buffer replenish condition + LED_FrameBufferReset = 1; - // Abort Tx Buffer - I2C_TxBuffer.head = 0; - I2C_TxBuffer.tail = 0; - I2C_TxBuffer.sequencePos = 0; - } - else - { - // Transmit byte - I2C0_D = I2C_TxBufferPop(); - } - } - // Receiving data - else if ( I2C_RxBuffer.sequencePos > 0 ) - { - // Master Receive, addr sent - if ( status & I2C_S_ARBL ) - { - // Arbitration Lost - erro_print("Arbitration lost..."); - // TODO Abort Rx - - I2C0_C1 = I2C_C1_IICEN; - I2C0_S = I2C_S_ARBL | I2C_S_IICIF; // Clear ARBL flag and interrupt - } - if ( status & I2C_S_RXAK ) - { - // Slave Address NACK Detected, disable interrupt - erro_print("Slave Address I2C NAK detected..."); - // TODO Abort Rx - - I2C0_C1 = I2C_C1_IICEN; - } - else - { - dbug_msg("Attempting to read byte - "); - printHex( I2C_RxBuffer.sequencePos ); - print( NL ); - I2C0_C1 = I2C_RxBuffer.sequencePos == 1 - ? I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TXAK // Single byte read - : I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST; // Multi-byte read - } - } - else - { - /* - dbug_msg("STOP - "); - printHex( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) ); - print(NL); - */ - - // Delay around STOP to make sure it actually happens... - delayMicroseconds( 1 ); - I2C0_C1 = I2C_C1_IICEN; // Send STOP - delayMicroseconds( 7 ); - - // If there is another sequence, start sending - if ( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) < I2C_TxBuffer.size ) - { - // Clear status flags - I2C0_S = I2C_S_IICIF | I2C_S_ARBL; - - // Wait...till the master dies - while ( I2C0_S & I2C_S_BUSY ); - - // Enable I2C interrupt - I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX; - - // Transmit byte - I2C0_D = I2C_TxBufferPop(); - } - } + // Clear IRQ + PORTB_ISFR |= (1 << 17); } - // Master Mode Receive - else - { - // XXX Do we need to handle 2nd last byte? - //I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TXAK; // No STOP, Rx, NAK on recv - - // Last byte - if ( I2C_TxBuffer.sequencePos <= 1 ) - { - // Change to Tx mode - I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; - - // Grab last byte - I2C_BufferPush( I2C0_D, (I2C_Buffer*)&I2C_RxBuffer ); - - delayMicroseconds( 1 ); // Should be enough time before issuing the stop - I2C0_C1 = I2C_C1_IICEN; // Send STOP - } - else - { - // Retrieve data - I2C_BufferPush( I2C0_D, (I2C_Buffer*)&I2C_RxBuffer ); - } - } - - I2C0_S = I2C_S_IICIF; // Clear interrupt - - sei(); // Re-enable Interrupts } // ----- Functions ----- -inline void I2C_setup() -{ - // Enable I2C internal clock - SIM_SCGC4 |= SIM_SCGC4_I2C0; // Bus 0 - - // External pull-up resistor - PORTB_PCR0 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); - PORTB_PCR1 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); - - // SCL Frequency Divider - // 1.8 MBaud (likely higher than spec) - // 0x85 -> 36 MHz / (4 * 5) = 1.8 MBaud - // 0x80 => mul(4) - // 0x05 => ICL(5) - I2C0_F = 0x85; - I2C0_FLT = 4; - I2C0_C1 = I2C_C1_IICEN; - I2C0_C2 = I2C_C2_HDRS; // High drive select - - // Enable I2C Interrupt - NVIC_ENABLE_IRQ( IRQ_I2C0 ); -} - void LED_zeroPages( uint8_t addr, uint8_t startPage, uint8_t numPages, uint8_t startReg, uint8_t endReg ) { - // Page Setup - uint8_t pageSetup[] = { addr, 0xFD, 0x00 }; - + // Clear Page // Max length of a page + chip id + reg start - uint8_t fullPage[ 0xB4 + 2 ] = { 0 }; // Max size of page - fullPage[0] = addr; // Set chip id - fullPage[1] = startReg; // Set start reg + uint16_t clearPage[2 + 0xB4] = { 0 }; + clearPage[0] = addr; + clearPage[1] = startReg; // Iterate through given pages, zero'ing out the given register regions for ( uint8_t page = startPage; page < startPage + numPages; page++ ) { - // Set page - pageSetup[2] = page; + // Page Setup + uint16_t pageSetup[] = { addr, 0xFD, page }; // Setup page - while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) delay(1); // Zero out page - while ( I2C_Send( fullPage, endReg - startReg + 2, 0 ) == 0 ) + while ( i2c_send( clearPage, 2 + endReg - startReg ) == -1 ) delay(1); } + + // Wait until finished zero'ing + while ( i2c_busy() ) + delay(1); } -void LED_sendPage( uint8_t addr, uint8_t *buffer, uint8_t len, uint8_t page ) +void LED_sendPage( uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page ) { + /* + info_msg("I2C Send Page Addr: "); + printHex( addr ); + print(" Len: "); + printHex( len ); + print(" Page: "); + printHex( page ); + print( NL ); + */ + // Page Setup - uint8_t pageSetup[] = { addr, 0xFD, page }; + uint16_t pageSetup[] = { addr, 0xFD, page }; // Setup page - while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) delay(1); // Write page to I2C Tx Buffer - while ( I2C_Send( buffer, len, 0 ) == 0 ) + while ( i2c_send( buffer, len ) == -1 ) delay(1); - } // Write address void LED_writeReg( uint8_t addr, uint8_t reg, uint8_t val, uint8_t page ) { // Page Setup - uint8_t pageSetup[] = { addr, 0xFD, page }; + uint16_t pageSetup[] = { addr, 0xFD, page }; // Reg Write Setup - uint8_t writeData[] = { addr, reg, val }; + uint16_t writeData[] = { addr, reg, val }; // Setup page - while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) delay(1); // Write register - while ( I2C_Send( writeData, sizeof( writeData ), 0 ) == 0 ) + while ( i2c_send( writeData, sizeof( writeData ) / 2 ) == -1 ) + delay(1); + + // Delay until written + while ( i2c_busy() ) delay(1); } // Read address -void LED_readReg( uint8_t addr, uint8_t reg, uint8_t page ) +// TODO Not working? +uint8_t LED_readReg( uint8_t addr, uint8_t reg, uint8_t page ) { // Software shutdown must be enabled to read registers LED_writeReg( addr, 0x0A, 0x00, 0x0B ); // Page Setup - uint8_t pageSetup[] = { addr, 0xFD, page }; + uint16_t pageSetup[] = { addr, 0xFD, page }; // Setup page - while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) delay(1); // Register Setup - uint8_t regSetup[] = { addr, reg }; + uint16_t regSetup[] = { addr, reg }; // Configure register - while ( I2C_Send( regSetup, sizeof( regSetup ), 0 ) == 0 ) + while ( i2c_send( regSetup, sizeof( regSetup ) / 2 ) == -1 ) delay(1); // Register Read Command - uint8_t regReadCmd[] = { addr | 0x1 }; + uint16_t regReadCmd[] = { addr | 0x1, I2C_READ }; + uint8_t recv_data; // Request single register byte - while ( I2C_Send( regReadCmd, sizeof( regReadCmd ), 1 ) == 0 ) + while ( i2c_read( regReadCmd, sizeof( regReadCmd ) / 2, &recv_data ) == -1 ) delay(1); - // TODO get byte from buffer - // Disable software shutdown LED_writeReg( addr, 0x0A, 0x01, 0x0B ); + + return recv_data; } // Setup @@ -451,7 +315,7 @@ inline void LED_setup() CLI_registerDictionary( ledCLIDict, ledCLIDictName ); // Initialize I2C - I2C_setup(); + i2c_setup(); // Setup LED_pageBuffer addresses and brightness section LED_pageBuffer[0].i2c_addr = ISSI_Ch1; @@ -469,6 +333,11 @@ inline void LED_setup() LED_pageBuffer[3].reg_addr = 0x24; #endif + // Enable Hardware shutdown (pull low) + GPIOB_PDDR |= (1<<16); + PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOB_PCOR |= (1<<16); + // Zero out Frame Registers // This needs to be done before disabling the hardware shutdown (or the leds will do undefined things) for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) @@ -478,19 +347,60 @@ inline void LED_setup() } // Disable Hardware shutdown of ISSI chip (pull high) - GPIOB_PDDR |= (1<<16); - PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); GPIOB_PSOR |= (1<<16); + // Prepare pin to read INTB interrupt of ISSI chip (Active Low) + // Enable interrupt to detect falling edge + // Uses external pullup resistor + GPIOB_PDDR |= ~(1<<17); + PORTB_PCR17 = PORT_PCR_IRQC(0xA) | PORT_PCR_PFE | PORT_PCR_MUX(1); + LED_FrameBufferReset = 0; // Clear frame buffer reset condition for ISSI + + // Enable PORTB interrupt + NVIC_ENABLE_IRQ( IRQ_PORTB ); + + // Reset frame buffer used count + LED_FrameBuffersReady = LED_FrameBuffersMax; + + // Starting page for the buffers + LED_FrameBufferPage = 4; + + // Initially do not allow autoplay to restart + LED_FrameBufferStart = 0; + // Clear LED Pages // Enable LEDs based upon mask - // Set default brightness for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers - LED_sendPage( addr, (uint8_t*)&LED_ledEnableMask[ ch ], sizeof( LED_EnableBuffer ), 0 ); - LED_sendPage( addr, (uint8_t*)&LED_defaultBrightness[ ch ], sizeof( LED_Buffer ), 0 ); + + // For each page + for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ ) + { + LED_sendPage( + addr, + (uint16_t*)&LED_ledEnableMask[ ch ], + sizeof( LED_EnableBuffer ) / 2, + pg + ); + } + } + + // Setup ISSI auto frame play, but do not start yet + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + // CNS 1 loop, FNS 4 frames - 0x14 + LED_writeReg( addr, 0x02, 0x14, 0x0B ); + + // Default refresh speed - TxA + // T is typically 11ms + // A is 1 to 64 (where 0 is 64) + LED_writeReg( addr, 0x03, ISSI_AnimationSpeed_define, 0x0B ); + + // Set MODE to Auto Frame Play + LED_writeReg( addr, 0x00, 0x08, 0x0B ); } // Disable Software shutdown of ISSI chip @@ -502,231 +412,143 @@ inline void LED_setup() } -inline uint8_t I2C_BufferCopy( uint8_t *data, uint8_t sendLen, uint8_t recvLen, I2C_Buffer *buffer ) +// LED Linked Send +// Call-back for i2c write when updating led display +uint8_t LED_chipSend; +void LED_linkedSend() { - uint8_t reTurn = 0; - - // If sendLen is greater than buffer fail right away - if ( sendLen > buffer->size ) - return 0; - - // Calculate new tail to determine if buffer has enough space - // The first element specifies the expected number of bytes from the slave (+1) - // The second element in the new buffer is the length of the buffer sequence (+1) - uint16_t newTail = buffer->tail + sendLen + 2; - if ( newTail >= buffer->size ) - newTail -= buffer->size; - - if ( I2C_BufferLen( buffer ) < sendLen + 2 ) - return 0; - -/* - print("|"); - printHex( sendLen + 2 ); - print("|"); - printHex( *tail ); - print("@"); - printHex( newTail ); - print("@"); -*/ - - // If buffer is clean, return 1, otherwise 2 - reTurn = buffer->head == buffer->tail ? 1 : 2; - - // Add to buffer, already know there is enough room (simplifies adding logic) - uint8_t bufferHeaderPos = 0; - for ( uint16_t c = 0; c < sendLen; c++ ) + // Check if we've updated all the ISSI chips for this frame + if ( LED_chipSend >= ISSI_Chips_define ) { - // Add data to buffer - switch ( bufferHeaderPos ) + // Increment the buffer page + // And reset if necessary + if ( ++LED_FrameBufferPage >= LED_FrameBuffersMax * 2 ) { - case 0: - buffer->buffer[ buffer->tail ] = recvLen; - bufferHeaderPos++; - c--; - break; - - case 1: - buffer->buffer[ buffer->tail ] = sendLen; - bufferHeaderPos++; - c--; - break; - - default: - buffer->buffer[ buffer->tail ] = data[ c ]; - break; + LED_FrameBufferPage = 0; } - // Check for wrap-around case - if ( buffer->tail + 1 >= buffer->size ) - { - buffer->tail = 0; - } - // Normal case - else - { - buffer->tail++; - } - } - - return reTurn; -} - - -inline uint16_t I2C_BufferLen( I2C_Buffer *buffer ) -{ - // Tail >= Head - if ( buffer->tail >= buffer->head ) - return buffer->head + buffer->size - buffer->tail; - - // Head > Tail - return buffer->head - buffer->tail; -} - - -void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer ) -{ - dbug_msg("DATA: "); - printHex( byte ); - - // Make sure buffer isn't full - if ( buffer->tail + 1 == buffer->head || ( buffer->head > buffer->tail && buffer->tail + 1 - buffer->size == buffer->head ) ) - { - warn_msg("I2C_BufferPush failed, buffer full: "); - printHex( byte ); - print( NL ); + // Now ready to update the frame buffer + Pixel_FrameState = FrameState_Update; return; } - // Check for wrap-around case - if ( buffer->tail + 1 >= buffer->size ) - { - buffer->tail = 0; - } - // Normal case - else - { - buffer->tail++; - } - - // Add byte to buffer - buffer->buffer[ buffer->tail ] = byte; -} - - -uint8_t I2C_TxBufferPop() -{ - // Return 0xFF if no buffer left (do not rely on this) - if ( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) >= I2C_TxBuffer.size ) - { - erro_msg("No buffer to pop an entry from... "); - printHex( I2C_TxBuffer.head ); - print(" "); - printHex( I2C_TxBuffer.tail ); - print(" "); - printHex( I2C_TxBuffer.sequencePos ); - print(NL); - return 0xFF; - } - - // If there is currently no sequence being sent, the first entry in the RingBuffer is the length - if ( I2C_TxBuffer.sequencePos == 0 ) - { - I2C_TxBuffer.sequencePos = 0xFF; // So this doesn't become an infinite loop - I2C_RxBuffer.sequencePos = I2C_TxBufferPop(); - I2C_TxBuffer.sequencePos = I2C_TxBufferPop(); - } - - uint8_t data = I2C_TxBuffer.buffer[ I2C_TxBuffer.head ]; - - // Prune head - I2C_TxBuffer.head++; - - // Wrap-around case - if ( I2C_TxBuffer.head >= I2C_TxBuffer.size ) - I2C_TxBuffer.head = 0; - - // Decrement buffer sequence (until next stop will be sent) - I2C_TxBuffer.sequencePos--; + // Update ISSI Frame State + Pixel_FrameState = FrameState_Sending; + // Debug /* - dbug_msg("Popping: "); - printHex( data ); - print(" "); - printHex( I2C_TxBuffer.head ); - print(" "); - printHex( I2C_TxBuffer.tail ); - print(" "); - printHex( I2C_TxBuffer.sequencePos ); - print(NL); - */ - return data; -} - - -uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ) -{ - // Check head and tail pointers - // If full, return 0 - // If empty, start up I2C Master Tx - // If buffer is non-empty and non-full, just append to the buffer - switch ( I2C_BufferCopy( data, sendLen, recvLen, (I2C_Buffer*)&I2C_TxBuffer ) ) + dbug_msg("Linked Send: chip("); + printHex( LED_chipSend ); + print(") frame("); + printHex( LED_FrameBufferPage ); + print(") addr("); + printHex( LED_pageBuffer[0].i2c_addr ); + print(") reg("); + printHex( LED_pageBuffer[0].reg_addr ); + print(") len("); + printHex( sizeof( LED_Buffer ) / 2 ); + print(") data[]" NL "("); + for ( uint8_t c = 0; c < 9; c++ ) + //for ( uint8_t c = 0; c < sizeof( LED_Buffer ) / 2 - 2; c++ ) { - // Not enough buffer space... - case 0: - /* - erro_msg("Not enough Tx buffer space... "); - printHex( I2C_TxBuffer.head ); - print(":"); - printHex( I2C_TxBuffer.tail ); - print("+"); - printHex( sendLen ); - print("|"); - printHex( I2C_TxBuffer.size ); - print( NL ); - */ - return 0; - - // Empty buffer, initialize I2C - case 1: - // Clear status flags - I2C0_S = I2C_S_IICIF | I2C_S_ARBL; - - // Check to see if we already have control of the bus - if ( I2C0_C1 & I2C_C1_MST ) - { - // Already the master (ah yeah), send a repeated start - I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX; - } - // Otherwise, seize control - else - { - // Wait...till the master dies - while ( I2C0_S & I2C_S_BUSY ); - - // Now we're the master (ah yisss), get ready to send stuffs - I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; - } - - // Enable I2C interrupt - I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX; - - // Depending on what type of transfer, the first byte is configured for R or W - I2C0_D = I2C_TxBufferPop(); - - return 1; + printHex( LED_pageBuffer[0].buffer[c] ); + print(" "); } + print(")" NL); + */ - // Dirty buffer, I2C already initialized - return 2; + // Send, and recursively call this function when finished + while ( i2c_send_sequence( + (uint16_t*)&LED_pageBuffer[ LED_chipSend ], + sizeof( LED_Buffer ) / 2, + 0, + LED_linkedSend, + 0 + ) == -1 ) + delay(1); + + // Increment chip position + LED_chipSend++; } - // LED State processing loop -inline uint8_t LED_scan() +uint32_t LED_timePrev = 0; +inline void LED_scan() { - return 0; + // Check to see if frame buffers are ready to replenish + if ( LED_FrameBufferReset ) + { + LED_FrameBufferReset = 0; + LED_FrameBufferStart = 1; + + // Debug Status + dbug_msg("4frames/"); + printInt32( systick_millis_count - LED_timePrev ); + LED_timePrev = systick_millis_count; + print("ms" NL); + } + + // Make sure there are buffers available + if ( LED_FrameBuffersReady == 0 ) + { + // Only start if we haven't already + // And if we've finished updating the buffers + if ( !LED_FrameBufferStart || Pixel_FrameState == FrameState_Sending ) + return; + + // Buffers are now full, start signal can be sent + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + + // Start Auto Frame Play on either frame 1 or 5 + uint8_t frame = LED_FrameBufferPage == 0 ? 4 : 0; + LED_writeReg( addr, 0x00, 0x08 | frame, 0x0B ); + } + + LED_FrameBufferStart = 0; + LED_FrameBuffersReady = LED_FrameBuffersMax; + + return; + } + /* + else + { + dbug_msg(":/ - Start("); + printHex( LED_FrameBufferStart ); + print(") BuffersReady("); + printHex( LED_FrameBuffersReady ); + print(") State("); + printHex( Pixel_FrameState ); + print(")"NL); + } + */ + + // Only send frame to ISSI chip if buffers are ready + if ( Pixel_FrameState != FrameState_Ready ) + return; + + LED_FrameBuffersReady--; + + // Set the page of all the ISSI chips + // This way we can easily link the buffers to send the brightnesses in the background + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + // Page Setup + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + uint16_t pageSetup[] = { addr, 0xFD, LED_FrameBufferPage }; + + // Send each update + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) + delay(1); + } + + // Send current set of buffers + // Uses interrupts to send to all the ISSI chips + // Pixel_FrameState will be updated when complete + LED_chipSend = 0; // Start with chip 0 + LED_linkedSend(); } @@ -802,7 +624,7 @@ void LED_control( LedControl *control ) // TODO Support multiple frames for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { - LED_sendPage( LED_pageBuffer[ ch ].i2c_addr, (uint8_t*)&LED_pageBuffer[ ch ], sizeof( LED_Buffer ), 0 ); + LED_sendPage( LED_pageBuffer[ ch ].i2c_addr, (uint16_t*)&LED_pageBuffer[ ch ], sizeof( LED_Buffer ) / 2, 0 ); } } @@ -916,8 +738,8 @@ void cliFunc_i2cSend( char* args ) // Buffer used after interpretting the args, will be sent to I2C functions // NOTE: Limited to 8 bytes currently (can be increased if necessary #define i2cSend_BuffLenMax 8 - uint8_t buffer[ i2cSend_BuffLenMax ]; - uint8_t bufferLen = 0; + uint16_t buffer[ i2cSend_BuffLenMax ]; + uint8_t bufferLen = 0; // No \r\n by default after the command is entered print( NL ); @@ -937,7 +759,7 @@ void cliFunc_i2cSend( char* args ) if ( *arg1Ptr == '|' ) { print("| "); - I2C_Send( buffer, bufferLen, 0 ); + i2c_send( buffer, bufferLen ); bufferLen = 0; continue; } @@ -952,85 +774,12 @@ void cliFunc_i2cSend( char* args ) print( NL ); - I2C_Send( buffer, bufferLen, 0 ); -} - -void cliFunc_i2cRecv( char* args ) -{ - char* curArgs; - char* arg1Ptr; - char* arg2Ptr = args; - - // Buffer used after interpretting the args, will be sent to I2C functions - // NOTE: Limited to 8 bytes currently (can be increased if necessary - #define i2cSend_BuffLenMax 8 - uint8_t buffer[ i2cSend_BuffLenMax ]; - uint8_t bufferLen = 0; - - // No \r\n by default after the command is entered - print( NL ); - info_msg("Sending: "); - - // Parse args until a \0 is found - while ( bufferLen < i2cSend_BuffLenMax ) - { - curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list - CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); - - // Stop processing args if no more are found - if ( *arg1Ptr == '\0' ) - break; - - // If | is found, end sequence and start new one - if ( *arg1Ptr == '|' ) - { - print("| "); - I2C_Send( buffer, bufferLen, 0 ); - bufferLen = 0; - continue; - } - - // Interpret the argument - buffer[ bufferLen++ ] = (uint8_t)numToInt( arg1Ptr ); - - // Print out the arg - dPrint( arg1Ptr ); - print(" "); - } - - print( NL ); - - I2C_Send( buffer, bufferLen, 1 ); // Only 1 byte is ever read at a time with the ISSI chip -} - -// TODO Currently not working correctly -void cliFunc_ledRPage( char* args ) -{ - /* TODO Use readReg command instead - // Parse number from argument - // NOTE: Only first argument is used - char* arg1Ptr; - char* arg2Ptr; - CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); - - // Default to 0 if no argument is given - uint8_t page = 0; - - if ( arg1Ptr[0] != '\0' ) - { - page = (uint8_t)numToInt( arg1Ptr ); - } - - // No \r\n by default after the command is entered - print( NL ); - - // TODO, multi-channel - LED_readPage( ISSI_Ch1, 0xB4, page ); - */ + i2c_send( buffer, bufferLen ); } void cliFunc_ledWPage( char* args ) { + /* char* curArgs; char* arg1Ptr; char* arg2Ptr = args; @@ -1084,6 +833,7 @@ void cliFunc_ledWPage( char* args ) // Increment address data[1]++; } + */ } void cliFunc_ledStart( char* args ) @@ -1095,7 +845,7 @@ void cliFunc_ledStart( char* args ) LED_zeroPages( LED_ledEnableMask[ ch ].i2c_addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers //LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers LED_writeReg( LED_ledEnableMask[ ch ].i2c_addr, 0x0A, 0x01, 0x0B ); - LED_sendPage( LED_ledEnableMask[ ch ].i2c_addr, (uint8_t*)&LED_ledEnableMask[ ch ], sizeof( LED_EnableBuffer ), 0 ); + LED_sendPage( LED_ledEnableMask[ ch ].i2c_addr, (uint16_t*)&LED_ledEnableMask[ ch ], sizeof( LED_EnableBuffer ) / 2, 0 ); } } @@ -1103,10 +853,120 @@ void cliFunc_ledTest( char* args ) { print( NL ); // No \r\n by default after the command is entered + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + uint8_t speed = ISSI_AnimationSpeed_define; + + // Process speed argument if given + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr != '\0' ) + speed = numToInt( arg1Ptr ); + + + // TODO REMOVEME for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { - LED_sendPage( LED_defaultBrightness[ ch ].i2c_addr, (uint8_t*)&LED_defaultBrightness[ ch ], sizeof( LED_Buffer ), 0 ); + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + // CNS 1 loop, FNS 4 frames - 0x14 + //LED_writeReg( addr, 0x02, 0x14, 0x0B ); + + // Default refresh speed - TxA + // T is typically 11ms + // A is 1 to 64 (where 0 is 64) + LED_writeReg( addr, 0x03, speed, 0x0B ); + + // Set MODE to Auto Frame Play + // Set FS to 5, this is to train the IRQ on the ISSI for the processing loop + // The first 4 frames are blank, we fill the last 4 + // Clear the interrupt, and the movie display starts at frame 5 + //LED_writeReg( addr, 0x00, 0x0C, 0x0B ); } + return; + + // Zero out Frame Registers + // This needs to be done before disabling the hardware shutdown (or the leds will do undefined things) + info_print("LED - Zeroing out all pages"); + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + LED_zeroPages( addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers + LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers + } + + // Clear LED Pages + // Enable LEDs based upon mask + info_print("LED - Setting LED enable mask"); + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + //for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + + // For each page + for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ ) + { + LED_sendPage( + addr, + (uint16_t*)&LED_ledEnableMask[ ch ], + sizeof( LED_EnableBuffer ) / 2, + pg + ); + } + } + + // Setup ISSI auto frame play, but do not start yet + /* + info_print("LED - Enabling 8 frame 3 loop auto play"); + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + // CNS 3 loops, FNS all frames - 0x30 + LED_writeReg( addr, 0x02, 0x30, 0x0B ); + + // Default refresh speed - TxA + // T is typically 11ms + // A is 1 to 64 (where 0 is 64) + LED_writeReg( addr, 0x03, speed, 0x0B ); + + // Set MODE to Auto Frame Play + // Set FS to frame 1 + //LED_writeReg( addr, 0x00, 0x08, 0x0B ); + } + */ + + // Load frame data + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + + // Load each page with a different led enabled + uint16_t data[] = { + addr, 0xFD, 0x00, + }; + while( i2c_send( data, sizeof( data ) / 2 ) == -1 ) + delay( 1 ); + data[1] = 0x24; + data[2] = 0xFF; + while( i2c_send( data, sizeof( data ) / 2 ) == -1 ) + delay( 1 ); + } + + // Disable Software shutdown of ISSI chip + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + LED_writeReg( addr, 0x0A, 0x01, 0x0B ); + } + +/* + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + LED_sendPage( LED_defaultBrightness[ ch ].i2c_addr, (uint16_t*)&LED_defaultBrightness[ ch ], sizeof( LED_Buffer ), 0 ); + } +*/ } void cliFunc_ledZero( char* args ) @@ -1115,6 +975,7 @@ void cliFunc_ledZero( char* args ) for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { + LED_zeroPages( LED_defaultBrightness[ ch ].i2c_addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers LED_zeroPages( LED_defaultBrightness[ ch ].i2c_addr, 0x00, 8, 0x24, 0xB4 ); // Only PWMs } } @@ -1156,3 +1017,44 @@ void cliFunc_ledCtrl( char* args ) LED_control( &control ); } +void cliFunc_ledNFrame( char* args ) +{ + // TODO REMOVEME + LED_FrameBufferStart = 1; + return; + /* + LED_FrameBufferReset = 0; + LED_FrameBuffersReady = LED_FrameBuffersMax; + LED_FrameBufferStart = 1; + */ + //LED_FrameBuffersReady++; + //LED_FrameBufferStart = 1; + //uint8_t addr = LED_pageBuffer[ 0 ].i2c_addr; + //LED_writeReg( addr, 0x00, 0x08, 0x0B ); + + //LED_FrameBuffersReady--; + + // Iterate over available buffers + // Each pass can only send one buffer (per chip) + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + // XXX It is more efficient to only send positions that are used + // However, this may actually have more addressing overhead + // For simplicity, just sending the full 144 positions per ISSI chip + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + LED_sendPage( + addr, + (uint16_t*)&LED_pageBuffer[ ch ], + sizeof( LED_Buffer ) / 2, + LED_FrameBufferPage + ); + } + + // Increment the buffer page + // And reset if necessary + if ( ++LED_FrameBufferPage >= LED_FrameBuffersMax * 2 ) + { + LED_FrameBufferPage = 0; + } +} + diff --git a/Scan/ISSILed/led_scan.h b/Scan/ISSILed/led_scan.h index 71d8e80..b89531e 100644 --- a/Scan/ISSILed/led_scan.h +++ b/Scan/ISSILed/led_scan.h @@ -23,8 +23,14 @@ +// ----- Variables ----- + +extern uint8_t LED_FrameBuffersReady; + + + // ----- Functions ----- void LED_setup(); -uint8_t LED_scan(); +void LED_scan(); diff --git a/Scan/ISSILed/setup.cmake b/Scan/ISSILed/setup.cmake index c2cef01..ecd88d9 100644 --- a/Scan/ISSILed/setup.cmake +++ b/Scan/ISSILed/setup.cmake @@ -17,6 +17,7 @@ set ( SubModule 1 ) # Module C files # set ( Module_SRCS + i2c.c led_scan.c ) diff --git a/Scan/KType/defaultMap.kll b/Scan/KType/defaultMap.kll index ea4e3c9..8917a50 100644 --- a/Scan/KType/defaultMap.kll +++ b/Scan/KType/defaultMap.kll @@ -4,9 +4,10 @@ Author = "HaaTa (Jacob Alexander) 2015"; KLL = 0.3c; # Modified Date -Date = 2015-09-29; +Date = 2016-01-03; +# Function Row S0x00 : U"Esc"; S0x01 : U"F1"; S0x02 : U"F2"; @@ -23,6 +24,8 @@ S0x0C : U"F12"; S0x0D : U"PrintScreen"; S0x0E : U"ScrollLock"; S0x0F : U"Pause"; + +# Number Row S0x10 : U"Backtick"; S0x11 : U"1"; S0x12 : U"2"; @@ -36,67 +39,87 @@ S0x19 : U"9"; S0x1A : U"0"; S0x1B : U"Minus"; S0x1C : U"Equals"; -S0x1D : U"Backspace"; -S0x1E : U"Insert"; -S0x1F : U"Home"; -S0x20 : U"PageUp"; -S0x21 : U"Tab"; -S0x22 : U"Q"; -S0x23 : U"W"; -S0x24 : U"E"; -S0x25 : U"R"; -S0x26 : U"T"; -S0x27 : U"Y"; -S0x28 : U"U"; -S0x29 : U"I"; -S0x2A : U"O"; -S0x2B : U"P"; -S0x2C : U"LBrace"; -S0x2D : U"RBrace"; -S0x2E : U"Backslash"; -S0x2F : U"Delete"; -S0x30 : U"End"; -S0x31 : U"PageDown"; -S0x32 : U"CapsLock"; -S0x33 : U"A"; -S0x34 : U"S"; -S0x35 : U"D"; -S0x36 : U"F"; -S0x37 : U"G"; -S0x38 : U"H"; -S0x39 : U"J"; -S0x3A : U"K"; -S0x3B : U"L"; -S0x3C : U"Semicolon"; -S0x3D : U"Quote"; -S0x3E : U"Enter"; -S0x3F : U"LShift"; -S0x40 : U"Z"; -S0x41 : U"X"; -S0x42 : U"C"; -S0x43 : U"V"; -S0x44 : U"B"; -S0x45 : U"N"; -S0x46 : U"M"; -S0x47 : U"Comma"; -S0x48 : U"Period"; -S0x49 : U"Slash"; -S0x4A : U"RShift"; -S0x4B : U"Up"; -S0x4C : U"LCtrl"; -S0x4D : U"LGui"; -S0x4E : U"LAlt"; -S0x4F : U"Space"; -S0x50 : U"RAlt"; -S0x51 : U"RGui"; -S0x52 : U"Menu"; -S0x53 : U"RCtrl"; -S0x54 : U"Left"; -S0x55 : U"Down"; -S0x56 : U"Right"; +S0x1D : U"Hash"; +S0x1E : U"Backspace"; +S0x1F : U"Backspace"; # ISO Backspace +S0x20 : U"Insert"; +S0x21 : U"Home"; +S0x22 : U"PageUp"; + +# Top Alphabet Row +S0x23 : U"Tab"; +S0x24 : U"Q"; +S0x25 : U"W"; +S0x26 : U"E"; +S0x27 : U"R"; +S0x28 : U"T"; +S0x29 : U"Y"; +S0x2A : U"U"; +S0x2B : U"I"; +S0x2C : U"O"; +S0x2D : U"P"; +S0x2E : U"LBrace"; +S0x2F : U"RBrace"; +S0x30 : U"Backslash"; +S0x31 : U"Enter"; # ISO Enter +S0x32 : U"Delete"; +S0x33 : U"End"; +S0x34 : U"End"; + +# Middle Alphabet Row +S0x35 : U"CapsLock"; +S0x36 : U"A"; +S0x37 : U"S"; +S0x38 : U"D"; +S0x39 : U"F"; +S0x3A : U"G"; +S0x3B : U"H"; +S0x3C : U"J"; +S0x3D : U"K"; +S0x3E : U"L"; +S0x3F : U"Semicolon"; +S0x40 : U"Quote"; +S0x41 : U"Backslash"; # ISO Backslash +S0x42 : U"Enter"; + +# Bottom Alphabet Row +S0x43 : U"LShift"; +S0x44 : U"LShift"; +S0x45 : U"ISO/"; +S0x46 : U"Z"; +S0x47 : U"X"; +S0x48 : U"C"; +S0x49 : U"V"; +S0x4A : U"B"; +S0x4B : U"N"; +S0x4C : U"M"; +S0x4D : U"Comma"; +S0x4E : U"Period"; +S0x4F : U"Slash"; +S0x50 : U"RShift"; # HHKB RShift +S0x51 : U"RShift"; +S0x52 : U"Function1"; +S0x53 : U"Up"; + +# Modifier Row +S0x54 : U"LCtrl"; +S0x55 : U"LGui"; +S0x56 : U"LAlt"; +S0x57 : U"Space"; +S0x58 : U"RAlt"; +S0x59 : U"RGui"; +S0x5A : U"Menu"; +S0x5B : U"RCtrl"; +S0x5C : U"Left"; +S0x5D : U"Down"; +S0x5E : U"Right"; + # Available ISSI Chips -ISSI_Chips = 4; # 1 by default +ISSI_Chips = 3; # 1 by default + +# Default animation speed +ISSI_AnimationSpeed = 14; # 20 by default # LED Default Enable Mask # @@ -152,17 +175,18 @@ ISSILedMask4 = " 0xFF, 0xFF, /* C9-1 -> C9-16 */ "; -#ISSILedMask4 = " -# 0x00, 0x00, /* C1-1 -> C1-16 */ -# 0x00, 0x00, /* C2-1 -> C2-16 */ -# 0x00, 0x00, /* C3-1 -> C3-16 */ -# 0x00, 0x00, /* C4-1 -> C4-16 */ -# 0x00, 0x00, /* C5-1 -> C5-16 */ -# 0x00, 0x00, /* C6-1 -> C6-16 */ -# 0x00, 0x00, /* C7-1 -> C7-16 */ -# 0x00, 0x00, /* C8-1 -> C8-16 */ -# 0x00, 0x00, /* C9-1 -> C9-16 */ -#"; +# Disabled for now +ISSILedMask4 = " + 0x00, 0x00, /* C1-1 -> C1-16 */ + 0x00, 0x00, /* C2-1 -> C2-16 */ + 0x00, 0x00, /* C3-1 -> C3-16 */ + 0x00, 0x00, /* C4-1 -> C4-16 */ + 0x00, 0x00, /* C5-1 -> C5-16 */ + 0x00, 0x00, /* C6-1 -> C6-16 */ + 0x00, 0x00, /* C7-1 -> C7-16 */ + 0x00, 0x00, /* C8-1 -> C8-16 */ + 0x00, 0x00, /* C9-1 -> C9-16 */ +"; ISSILedBrightness1 = " 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* C1-1 -> C1-16 */ @@ -213,50 +237,50 @@ ISSILedBrightness4 = " "; ISSILedBrightness1 = " -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C1-1 -> C1-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C2-1 -> C2-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C3-1 -> C3-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C4-1 -> C4-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C5-1 -> C5-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C6-1 -> C6-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C7-1 -> C7-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C8-1 -> C8-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */ "; ISSILedBrightness2 = " -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C1-1 -> C1-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C2-1 -> C2-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C3-1 -> C3-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C4-1 -> C4-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C5-1 -> C5-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C6-1 -> C6-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C7-1 -> C7-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C8-1 -> C8-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */ "; ISSILedBrightness3 = " -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C1-1 -> C1-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C2-1 -> C2-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C3-1 -> C3-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C4-1 -> C4-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C5-1 -> C5-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C6-1 -> C6-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C7-1 -> C7-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C8-1 -> C8-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */ "; ISSILedBrightness4 = " -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C1-1 -> C1-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C2-1 -> C2-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C3-1 -> C3-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C4-1 -> C4-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C5-1 -> C5-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C6-1 -> C6-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C7-1 -> C7-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C8-1 -> C8-16 */ -0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */ "; diff --git a/Scan/KType/matrix.h b/Scan/KType/matrix.h index 912a700..8835d5e 100644 --- a/Scan/KType/matrix.h +++ b/Scan/KType/matrix.h @@ -37,20 +37,20 @@ // Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down // Checking this is completely on the ownness of the user -// MDErgo1 +// KType // -// Column (Strobe) - 9 Total +// Column (Strobe) - 10 Total // PTB2,3,18,19 -// PTC0,9..11 +// PTC0,8..11 // PTD0 // -// Rows (Sense) - 5 Total +// Rows (Sense) - 10 Total // PTD1,4..7 +// PTC1..5 // Define Rows (Sense) and Columns (Strobes) -// TODO -GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11) }; -GPIO_Pin Matrix_rows[] = { gpio(D,0), gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2) }; +GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11), gpio(D,0) }; +GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2), gpio(C,3), gpio(C,4), gpio(C,5) }; // Define type of scan matrix Config Matrix_type = Config_Pulldown; diff --git a/Scan/KType/scan_loop.c b/Scan/KType/scan_loop.c index 7999853..3f20cd9 100644 --- a/Scan/KType/scan_loop.c +++ b/Scan/KType/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,6 +33,8 @@ #include #include #include +#include +#include // Local Includes #include "scan_loop.h" @@ -53,6 +55,9 @@ uint16_t Scan_scanCount = 0; // Setup inline void Scan_setup() { + // Setup Port Swap module + Port_setup(); + // Setup UART Connect, if Output_Available, this is the master node Connect_setup( Output_Available ); @@ -62,6 +67,9 @@ inline void Scan_setup() // Setup ISSI chip to control the leds LED_setup(); + // Setup Pixel Map + Pixel_setup(); + // Reset scan count Scan_scanCount = 0; } @@ -70,12 +78,18 @@ inline void Scan_setup() // Main Detection Loop inline uint8_t Scan_loop() { + // Port Swap detection + Port_scan(); + // Scan Matrix Matrix_scan( Scan_scanCount++ ); // Process any interconnect commands Connect_scan(); + // Prepare any LED events + Pixel_process(); + // Process any LED events LED_scan(); diff --git a/Scan/KType/setup.cmake b/Scan/KType/setup.cmake index 50aef79..5696ccd 100644 --- a/Scan/KType/setup.cmake +++ b/Scan/KType/setup.cmake @@ -12,6 +12,7 @@ # AddModule ( Scan ISSILed ) AddModule ( Scan MatrixARM ) +AddModule ( Scan PortSwap ) AddModule ( Scan UARTConnect ) diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index a9018df..8463b26 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -196,7 +196,6 @@ void Matrix_setup() print( NL ); info_msg("Max Keys: "); printHex( Matrix_maxKeys ); - print( NL ); // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll index 798a0c7..e692d7b 100644 --- a/Scan/WhiteFox/defaultMap.kll +++ b/Scan/WhiteFox/defaultMap.kll @@ -82,6 +82,9 @@ S0x46 : U"Right"; # Defines available to the WhiteFox Scan Module +# Default animation speed +ISSI_AnimationSpeed = 3; # 20 by default + # LED Default Enable Mask Override # # Each LED is represented by a single bit @@ -115,15 +118,15 @@ ISSILedBrightness1 = " "; # Full brightness example -#ISSILedBrightness1 = " -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ -#"; +ISSILedBrightness1 = " +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +"; diff --git a/Scan/WhiteFox/scan_loop.c b/Scan/WhiteFox/scan_loop.c index 16cefa2..cac143b 100644 --- a/Scan/WhiteFox/scan_loop.c +++ b/Scan/WhiteFox/scan_loop.c @@ -32,6 +32,7 @@ #include #include #include +#include // Local Includes #include "scan_loop.h" @@ -58,6 +59,9 @@ inline void Scan_setup() // Setup ISSI chip to control the leds LED_setup(); + // Setup Pixel Map + Pixel_setup(); + // Reset scan count Scan_scanCount = 0; } @@ -69,6 +73,9 @@ inline uint8_t Scan_loop() // Scan Matrix Matrix_scan( Scan_scanCount++ ); + // Prepare any LED events + Pixel_process(); + // Process any LED events LED_scan();