]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Working support for Interconnect
authorJacob Alexander <haata@kiibohd.com>
Sun, 16 Aug 2015 04:53:59 +0000 (21:53 -0700)
committerJacob Alexander <haata@kiibohd.com>
Sun, 16 Aug 2015 04:53:59 +0000 (21:53 -0700)
- Supports up to 255 slave nodes (you'll run into ScanCode limitations before then)
- Requires most recent kll compiler update
- Additional debugging output and stats counters
- Noise and parity checking
- Fixed TxFIFO issue when sending buffers larger than the FIFO
- Cleaned up defaultMap.kll
- Added ScanCode caching (reduces interconnect traffic significantly)
- Interconnect module code is conditionally compiled into PartialMap module if required

Lib/CMake/kll.cmake
Macro/PartialMap/macro.c
Macro/PartialMap/macro.h
Scan/MDErgo1/defaultMap.kll
Scan/UARTConnect/connect_scan.c
Scan/UARTConnect/connect_scan.h

index f41b92a1b93550fa3e50bba0ae47736507f04d24..36802e40a9a9dce21a35e3239748d456dd4cacca 100644 (file)
@@ -58,7 +58,6 @@ set ( pathname "${PROJECT_SOURCE_DIR}/${ScanModulePath}" )
 string ( REPLACE " " ";" MAP_LIST ${BaseMap} ) # Change spaces to semicolons
 foreach ( MAP ${MAP_LIST} )
        # Only check the Scan Module for BaseMap .kll files, default to defaultMap.kll
-       message("THIS -> ${pathname} ${MAP}")
        if ( NOT EXISTS ${pathname}/${MAP}.kll )
                set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll )
                set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll )
index 3122519f9b4252aabfd947bd51545366f98a9918..89444dcfc1e390f0f3ec0753853ba7658cf0a545 100644 (file)
@@ -156,6 +156,13 @@ uint16_t macroLayerIndexStackSize = 0;
 uint16_t macroResultMacroPendingList[ ResultMacroNum ] = { 0 };
 uint16_t macroResultMacroPendingListSize = 0;
 
+// Interconnect ScanCode Cache
+#if defined(ConnectEnabled_define)
+// TODO This can be shrunk by the size of the max node 0 ScanCode
+TriggerGuide macroInterconnectCache[ MaxScanCode ];
+uint8_t macroInterconnectCacheSize = 0;
+#endif
+
 
 
 // ----- Capabilities -----
@@ -424,18 +431,73 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire )
        // Otherwise no defined Trigger Macro
        erro_msg("Scan Code has no defined Trigger Macro: ");
        printHex( scanCode );
+       print( NL );
        return 0;
 }
 
 
-// Update the scancode using a list of TriggerGuides
-// TODO Handle led state and analog
-inline void Macro_triggerState( void *triggers, uint8_t num )
+// Add an interconnect ScanCode
+// These are handled differently (less information is sent, hold/off states must be assumed)
+#if defined(ConnectEnabled_define)
+inline void Macro_interconnectAdd( void *trigger_ptr )
 {
-       // Copy each of the TriggerGuides to the TriggerListBuffer
-       for ( uint8_t c = 0; c < num; c++ )
-               macroTriggerListBuffer[ macroTriggerListBufferSize++ ] = ((TriggerGuide*)triggers)[ c ];
+       TriggerGuide *trigger = (TriggerGuide*)trigger_ptr;
+
+       // Error checking
+       uint8_t error = 0;
+       switch ( trigger->type )
+       {
+       case 0x00: // Normal key
+               switch ( trigger->state )
+               {
+               case 0x00:
+               case 0x01:
+               case 0x02:
+               case 0x03:
+                       break;
+               default:
+                       erro_print("Invalid key state");
+                       error = 1;
+                       break;
+               }
+               break;
+
+       // Invalid TriggerGuide type
+       default:
+               erro_print("Invalid type");
+               error = 1;
+               break;
+       }
+
+       // Display TriggerGuide
+       if ( error )
+       {
+               printHex( trigger->type );
+               print(" ");
+               printHex( trigger->state );
+               print(" ");
+               printHex( trigger->scanCode );
+               print( NL );
+               return;
+       }
+
+       // Add trigger to the Interconnect Cache
+       // During each processing loop, a scancode may be re-added depending on it's state
+       for ( uint8_t c = 0; c < macroInterconnectCacheSize; c++ )
+       {
+               // Check if the same ScanCode
+               if ( macroInterconnectCache[ c ].scanCode == trigger->scanCode )
+               {
+                       // Update the state
+                       macroInterconnectCache[ c ].state = trigger->state;
+                       return;
+               }
+       }
+
+       // If not in the list, add it
+       macroInterconnectCache[ macroInterconnectCacheSize++ ] = *trigger;
 }
+#endif
 
 
 // Update the scancode key state
@@ -447,6 +509,20 @@ inline void Macro_triggerState( void *triggers, uint8_t num )
 //   * 0x04 - Unpressed (this is currently ignored)
 inline void Macro_keyState( uint8_t scanCode, uint8_t state )
 {
+#if defined(ConnectEnabled_define)
+       // Only compile in if a Connect node module is available
+       if ( !Connect_master )
+       {
+               // ScanCodes are only added if there was a state change (on/off)
+               switch ( state )
+               {
+               case 0x00: // Off
+               case 0x02: // Held
+                       return;
+               }
+       }
+#endif
+
        // Only add to macro trigger list if one of three states
        switch ( state )
        {
@@ -470,6 +546,7 @@ inline void Macro_keyState( uint8_t scanCode, uint8_t state )
 inline void Macro_analogState( uint8_t scanCode, uint8_t state )
 {
        // Only add to macro trigger list if non-off
+       // TODO Handle change for interconnect
        if ( state != 0x00 )
        {
                macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode;
@@ -487,6 +564,7 @@ inline void Macro_analogState( uint8_t scanCode, uint8_t state )
 inline void Macro_ledState( uint8_t ledCode, uint8_t state )
 {
        // Only add to macro trigger list if non-off
+       // TODO Handle change for interconnect
        if ( state != 0x00 )
        {
                macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = ledCode;
@@ -907,6 +985,10 @@ inline void Macro_updateTriggerMacroPendingList()
                // Lookup Trigger List
                nat_ptr_t *triggerList = Macro_layerLookup( &macroTriggerListBuffer[ key ], latch_expire );
 
+               // If there was an error during lookup, skip
+               if ( triggerList == 0 )
+                       continue;
+
                // Number of Triggers in list
                nat_ptr_t triggerListSize = triggerList[0];
 
@@ -953,10 +1035,7 @@ inline void Macro_process()
        {
                if ( macroTriggerListBufferSize > 0 )
                {
-                       dbug_msg("Yuh");
-                       printHex( macroTriggerListBufferSize );
-                       print( NL );
-                       //Connect_send_ScanCode( Connect_id, macroTriggerListBuffer, macroTriggerListBufferSize );
+                       Connect_send_ScanCode( Connect_id, macroTriggerListBuffer, macroTriggerListBufferSize );
                        macroTriggerListBufferSize = 0;
                }
                return;
@@ -967,6 +1046,41 @@ inline void Macro_process()
        if ( USBKeys_Sent != 0 )
                return;
 
+#if defined(ConnectEnabled_define)
+       // Check if there are any ScanCodes in the interconnect cache to process
+       if ( Connect_master && macroInterconnectCacheSize > 0 )
+       {
+               // Iterate over all the cache ScanCodes
+               uint8_t currentInterconnectCacheSize = macroInterconnectCacheSize;
+               macroInterconnectCacheSize = 0;
+               for ( uint8_t c = 0; c < currentInterconnectCacheSize; c++ )
+               {
+                       // Add to the trigger list
+                       macroTriggerListBuffer[ macroTriggerListBufferSize++ ] = macroInterconnectCache[ c ];
+
+                       // TODO Handle other TriggerGuide types (e.g. analog)
+                       switch ( macroInterconnectCache[ c ].type )
+                       {
+                       // Normal (Press/Hold/Release)
+                       case 0x00:
+                               // Decide what to do based on the current state
+                               switch ( macroInterconnectCache[ c ].state )
+                               {
+                               // Re-add to interconnect cache in hold state
+                               case 0x01: // Press
+                               //case 0x02: // Hold // XXX Why does this not work? -HaaTa
+                                       macroInterconnectCache[ c ].state = 0x02;
+                                       macroInterconnectCache[ macroInterconnectCacheSize++ ] = macroInterconnectCache[ c ];
+                                       break;
+                               case 0x03: // Remove
+                                       break;
+                               // Otherwise, do not re-add
+                               }
+                       }
+               }
+       }
+#endif
+
        // If the pause flag is set, only process if the step counter is non-zero
        if ( macroPauseMode )
        {
index a165a458d503897c5b76ce17de9ff39713be5635..eae77dd3009c7b7cae09e5f2c81141a61a690558 100644 (file)
@@ -37,7 +37,7 @@ void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *arg
 void Macro_analogState( uint8_t scanCode, uint8_t state );
 void Macro_keyState( uint8_t scanCode, uint8_t state );
 void Macro_ledState( uint8_t ledCode, uint8_t state );
-void Macro_triggerState( void *triggers, uint8_t num ); // triggers is of type TriggerGuide, void* for circular dependencies
+void Macro_interconnectAdd( void *trigger ); // triggers is of type TriggerGuide, void* for circular dependencies
 void Macro_process();
 void Macro_setup();
 
index 94038e8220970a815ee9a0ded98600448eb68d64..1f96cb510f8f68fb002c54aa0820030d2bffb454 100644 (file)
@@ -4,7 +4,7 @@ Author = "HaaTa (Jacob Alexander) 2014-2015";
 KLL = 0.3c;
 
 # Modified Date
-Date = 2015-08-05;
+Date = 2015-08-15;
 
 ########
 # NOTE #
@@ -30,7 +30,6 @@ Date = 2015-08-05;
 #
 # Each LED is represented by a single bit
 # See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details
-ISSILedMask1 => ISSILedMask1_define;
 ISSILedMask1 = "
        0xFF, 0x00, /* C1-1 -> C1-16 */
        0xFF, 0x00, /* C2-1 -> C2-16 */
@@ -46,7 +45,6 @@ ISSILedMask1 = "
 # LED Brightness Override
 #
 # Each LED channel supports 256 levels (8-bit control)
-ISSILedBrightness1 => ISSILedBrightness1_define;
 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 */
index 89bb7729a670bee1ee83d832ba5e5dd3e4bf31f6..8b647accbcdb513a0a3068be3f03804c0170d138 100644 (file)
 
 // ----- Macros -----
 
+#define UART_Master 1
+#define UART_Slave  0
+#define uart_lock_m( uartNum )         uart##uartNum##_lock
+#define uart_buffer_items_m( uartNum ) uart##uartNum##_buffer_items
+#define uart_buffer_m( uartNum )       uart##uartNum##_buffer
+#define uart_buffer_head_m( uartNum )  uart##uartNum##_buffer_head
+#define uart_buffer_tail_m( uartNum )  uart##uartNum##_buffer_tail
+#define uart_tx_status_m( uartNum )    uart##uartNum##_tx_status
+
 // Macro for adding to each uart Tx ring buffer
 #define uart_addTxBuffer( uartNum ) \
 case uartNum: \
        /* Delay UART copy until there's some space left */ \
-       while ( uart##uartNum##_buffer_items + count > uart_buffer_size ) \
+       while ( uart_buffer_items_m( uartNum ) + count > uart_buffer_size ) \
        { \
                warn_msg("Too much data to send on UART0, waiting..."); \
                delay( 1 ); \
@@ -50,14 +59,14 @@ case uartNum: \
                        printHex( buffer[ c ] ); \
                        print( " +" #uartNum NL ); \
                } \
-               uart##uartNum##_buffer[ uart##uartNum##_buffer_tail++ ] = buffer[ c ]; \
-               uart##uartNum##_buffer_items++; \
-               if ( uart##uartNum##_buffer_tail >= uart_buffer_size ) \
-                       uart##uartNum##_buffer_tail = 0; \
-               if ( uart##uartNum##_buffer_head == uart##uartNum##_buffer_tail ) \
-                       uart##uartNum##_buffer_head++; \
-               if ( uart##uartNum##_buffer_head >= uart_buffer_size ) \
-                       uart##uartNum##_buffer_head = 0; \
+               uart_buffer_m( uartNum )[ uart_buffer_tail_m( uartNum )++ ] = buffer[ c ]; \
+               uart_buffer_items_m( uartNum )++; \
+               if ( uart_buffer_tail_m( uartNum ) >= uart_buffer_size ) \
+                       uart_buffer_tail_m( uartNum ) = 0; \
+               if ( uart_buffer_head_m( uartNum ) == uart_buffer_tail_m( uartNum ) ) \
+                       uart_buffer_head_m( uartNum )++; \
+               if ( uart_buffer_head_m( uartNum ) >= uart_buffer_size ) \
+                       uart_buffer_head_m( uartNum ) = 0; \
        } \
        break
 
@@ -67,7 +76,21 @@ case uartNum: \
        uint8_t fifoSize = ( ( UART##uartNum##_PFIFO & UART_PFIFO_TXFIFOSIZE ) >> 2 ); \
        if ( fifoSize == 0 ) \
                fifoSize = 1; \
-       while ( UART##uartNum##_TCFIFO < fifoSize ) \
+       if ( Connect_debug ) \
+       { \
+               print( "TxFIFO " #uartNum " - " ); \
+               printHex( fifoSize ); \
+               print("/"); \
+               printHex( UART##uartNum##_TCFIFO ); \
+               print("/"); \
+               printHex( uart##uartNum##_buffer_items ); \
+               print( NL ); \
+       } \
+       /* XXX Doesn't work well */ \
+       /* while ( UART##uartNum##_TCFIFO < fifoSize ) */ \
+       /* More reliable, albeit slower */ \
+       fifoSize -= UART##uartNum##_TCFIFO; \
+       while ( fifoSize-- != 0 ) \
        { \
                if ( uart##uartNum##_buffer_items == 0 ) \
                        break; \
@@ -93,27 +116,49 @@ case uartNum: \
        /* Process each byte in the UART buffer */ \
        while ( available-- > 0 ) \
        { \
+               /* First check if there was noise or Parity issues with current byte */ \
+               uint8_t err_status = UART##uartNum##_ED; \
+               /* Read byte from Rx FIFO */ \
                uint8_t byteRead = UART##uartNum##_D; \
                if ( Connect_debug ) \
                { \
                        printHex( byteRead ); \
-                       print( "(" ); \
+                       print("("); \
                        printInt8( available ); \
-                       print( ") <-" ); \
+                       print(") <-"); \
+               } \
+               /* Check error status */ \
+               if ( err_status & 0x80 ) \
+               { \
+                       print(" NOISY "); \
+               } \
+               if ( err_status & 0x40 ) \
+               { \
+                       print(" PARITY ERR "); \
+               } \
+               /* Ignore current byte if there was an error */ \
+               if ( err_status ) \
+               { \
+                       uart##uartNum##_rx_status = UARTStatus_Wait; \
+                       if ( Connect_debug ) \
+                       { \
+                               print( NL ); \
+                       } \
+                       continue; \
                } \
                switch ( uart##uartNum##_rx_status ) \
                { \
                case UARTStatus_Wait: \
                        if ( Connect_debug ) \
                        { \
-                               print(" SYN "); \
+                               print(" Wait "); \
                        } \
                        uart##uartNum##_rx_status = byteRead == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; \
                        break; \
                case UARTStatus_SYN: \
                        if ( Connect_debug ) \
                        { \
-                               print(" SOH "); \
+                               print(" SYN "); \
                        } \
                        uart##uartNum##_rx_status = byteRead == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; \
                        break; \
@@ -121,10 +166,17 @@ case uartNum: \
                { \
                        if ( Connect_debug ) \
                        { \
-                               print(" CMD "); \
+                               print(" SOH "); \
+                       } \
+                       /* Check if this is actually a reserved CMD 0x16 */ \
+                       if ( byteRead == Command_SYN ) \
+                       { \
+                               uart##uartNum##_rx_status = UARTStatus_SYN; \
+                               break; \
                        } \
+                       /* Otherwise process the command */ \
                        uint8_t byte = byteRead; \
-                       if ( byte <= Animation ) \
+                       if ( byte < Command_TOP ) \
                        { \
                                uart##uartNum##_rx_status = UARTStatus_Command; \
                                uart##uartNum##_rx_command = byte; \
@@ -143,7 +195,8 @@ case uartNum: \
                        default: \
                                if ( Connect_debug ) \
                                { \
-                                       print("###"); \
+                                       print(" ### "); \
+                                       printHex( uart##uartNum##_rx_command ); \
                                } \
                                break; \
                        } \
@@ -177,13 +230,32 @@ case uartNum: \
 // Macros for locking/unlock Tx buffers
 #define uart_lockTx( uartNum ) \
 { \
-       while ( uart##uartNum##_tx_status == UARTStatus_Wait ); \
-       uart##uartNum##_tx_status = UARTStatus_Wait; \
+       /* First, secure place in line for the resource */ \
+       while ( uart_lock_m( uartNum ) ); \
+       uart_lock_m( uartNum ) = 1; \
+       /* Next, wait unit the UART is ready */ \
+       while ( uart_tx_status_m( uartNum ) != UARTStatus_Ready ); \
+       uart_tx_status_m( uartNum ) = UARTStatus_Wait; \
+}
+
+#define uart_lockBothTx( uartNum1, uartNum2 ) \
+{ \
+       /* First, secure place in line for the resource */ \
+       while ( uart_lock_m( uartNum1 ) || uart_lock_m( uartNum2 ) ); \
+       uart_lock_m( uartNum1 ) = 1; \
+       uart_lock_m( uartNum2 ) = 1; \
+       /* Next, wait unit the UARTs are ready */ \
+       while ( uart_tx_status_m( uartNum1 ) != UARTStatus_Ready || uart_tx_status_m( uartNum2 ) != UARTStatus_Ready ); \
+       uart_tx_status_m( uartNum1 ) = UARTStatus_Wait; \
+       uart_tx_status_m( uartNum2 ) = UARTStatus_Wait; \
 }
 
 #define uart_unlockTx( uartNum ) \
 { \
-       uart##uartNum##_tx_status = UARTStatus_Ready; \
+       /* Ready the UART */ \
+       uart_tx_status_m( uartNum ) = UARTStatus_Ready; \
+       /* Unlock the resource */ \
+       uart_lock_m( uartNum ) = 0; \
 }
 
 
@@ -192,6 +264,7 @@ case uartNum: \
 
 // CLI Functions
 void cliFunc_connectCmd ( char *args );
+void cliFunc_connectDbg ( char *args );
 void cliFunc_connectIdl ( char *args );
 void cliFunc_connectLst ( char *args );
 void cliFunc_connectMst ( char *args );
@@ -204,6 +277,7 @@ void cliFunc_connectSts ( char *args );
 
 // Connect Module command dictionary
 CLIDict_Entry( connectCmd,  "Sends a command via UART Connect, first arg is which uart, next arg is the command, rest are the arguments." );
+CLIDict_Entry( connectDbg,  "Toggle UARTConnect debug mode." );
 CLIDict_Entry( connectIdl,  "Sends N number of Idle commands, 2 is the default value, and should be sufficient in most cases." );
 CLIDict_Entry( connectLst,  "Lists available UARTConnect commands and index id" );
 CLIDict_Entry( connectMst,  "Sets the device as master. Use argument of s to set as slave." );
@@ -211,6 +285,7 @@ CLIDict_Entry( connectRst,  "Resets both Rx and Tx connect buffers and state var
 CLIDict_Entry( connectSts,  "UARTConnect status." );
 CLIDict_Def( uartConnectCLIDict, "UARTConnect Module Commands" ) = {
        CLIDict_Item( connectCmd ),
+       CLIDict_Item( connectDbg ),
        CLIDict_Item( connectIdl ),
        CLIDict_Item( connectLst ),
        CLIDict_Item( connectMst ),
@@ -223,11 +298,13 @@ CLIDict_Def( uartConnectCLIDict, "UARTConnect Module Commands" ) = {
 // -- Connect Device Id Variables --
 uint8_t Connect_id = 255; // Invalid, unset
 uint8_t Connect_master = 0;
+uint8_t Connect_maxId = 0;
 
 
 // -- Control Variables --
 uint32_t Connect_lastCheck = 0; // Cable Check scheduler
-uint8_t Connect_debug = 0; // Set 1 for debug
+uint8_t Connect_debug = 0;      // Set 1 for debug
+uint8_t Connect_override = 0;   // Prevents master from automatically being set
 
 
 // -- Rx Status Variables --
@@ -238,6 +315,8 @@ volatile uint16_t uart0_rx_bytes_waiting;
 volatile uint16_t uart1_rx_bytes_waiting;
 volatile Command uart0_rx_command;
 volatile Command uart1_rx_command;
+volatile uint8_t uart0_lock;
+volatile uint8_t uart1_lock;
 
 
 // -- Tx Status Variables --
@@ -275,8 +354,8 @@ void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart )
        // Choose the uart
        switch ( uart )
        {
-       uart_addTxBuffer( 0 );
-       uart_addTxBuffer( 1 );
+       uart_addTxBuffer( UART_Master );
+       uart_addTxBuffer( UART_Slave );
        default:
                erro_msg("Invalid UART to send from...");
                break;
@@ -290,74 +369,73 @@ void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart )
 void Connect_send_CableCheck( uint8_t patternLen )
 {
        // Wait until the Tx buffers are ready, then lock them
-       uart_lockTx( 0 );
-       uart_lockTx( 1 );
+       uart_lockBothTx( UART_Master, UART_Slave );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, CableCheck, patternLen };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 1 ); // Master
-       Connect_addBytes( header, sizeof( header ), 0 ); // Slave
+       Connect_addBytes( header, sizeof( header ), UART_Master );
+       Connect_addBytes( header, sizeof( header ), UART_Slave );
 
        // Send 0xD2 (11010010) for each argument
        uint8_t value = 0xD2;
        for ( uint8_t c = 0; c < patternLen; c++ )
        {
-               Connect_addBytes( &value, 1, 1 ); // Master
-               Connect_addBytes( &value, 1, 0 ); // Slave
+               Connect_addBytes( &value, 1, UART_Master );
+               Connect_addBytes( &value, 1, UART_Slave );
        }
 
        // Release Tx buffers
-       uart_unlockTx( 0 );
-       uart_unlockTx( 1 );
+       uart_unlockTx( UART_Master );
+       uart_unlockTx( UART_Slave );
 }
 
 void Connect_send_IdRequest()
 {
        // Lock master bound Tx
-       uart_lockTx( 1 );
+       uart_lockTx( UART_Master );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, IdRequest };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 1 ); // Master
+       Connect_addBytes( header, sizeof( header ), UART_Master );
 
        // Unlock Tx
-       uart_unlockTx( 1 );
+       uart_unlockTx( UART_Master );
 }
 
 // id is the value the next slave should enumerate as
 void Connect_send_IdEnumeration( uint8_t id )
 {
        // Lock slave bound Tx
-       uart_lockTx( 0 );
+       uart_lockTx( UART_Slave );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, IdEnumeration, id };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 0 ); // Slave
+       Connect_addBytes( header, sizeof( header ), UART_Slave );
 
        // Unlock Tx
-       uart_unlockTx( 0 );
+       uart_unlockTx( UART_Slave );
 }
 
 // id is the currently assigned id to the slave
 void Connect_send_IdReport( uint8_t id )
 {
        // Lock master bound Tx
-       uart_lockTx( 1 );
+       uart_lockTx( UART_Master );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, IdReport, id };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 1 ); // Master
+       Connect_addBytes( header, sizeof( header ), UART_Master );
 
        // Unlock Tx
-       uart_unlockTx( 1 );
+       uart_unlockTx( UART_Master );
 }
 
 // id is the currently assigned id to the slave
@@ -366,19 +444,19 @@ void Connect_send_IdReport( uint8_t id )
 void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes )
 {
        // Lock master bound Tx
-       uart_lockTx( 1 );
+       uart_lockTx( UART_Master );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, ScanCode, id, numScanCodes };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 1 ); // Master
+       Connect_addBytes( header, sizeof( header ), UART_Master );
 
        // Send each of the scan codes
-       Connect_addBytes( (uint8_t*)scanCodeStateList, numScanCodes * TriggerGuideSize, 1 ); // Master
+       Connect_addBytes( (uint8_t*)scanCodeStateList, numScanCodes * TriggerGuideSize, UART_Master );
 
        // Unlock Tx
-       uart_unlockTx( 1 );
+       uart_unlockTx( UART_Master );
 }
 
 // id is the currently assigned id to the slave
@@ -387,38 +465,37 @@ void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t
 void Connect_send_Animation( uint8_t id, uint8_t *paramList, uint8_t numParams )
 {
        // Lock slave bound Tx
-       uart_lockTx( 0 );
+       uart_lockTx( UART_Slave );
 
        // Prepare header
        uint8_t header[] = { 0x16, 0x01, Animation, id, numParams };
 
        // Send header
-       Connect_addBytes( header, sizeof( header ), 0 ); // Slave
+       Connect_addBytes( header, sizeof( header ), UART_Slave );
 
        // Send each of the scan codes
-       Connect_addBytes( paramList, numParams, 0 ); // Slave
+       Connect_addBytes( paramList, numParams, UART_Slave );
 
        // Unlock Tx
-       uart_unlockTx( 0 );
+       uart_unlockTx( UART_Slave );
 }
 
 void Connect_send_Idle( uint8_t num )
 {
        // Wait until the Tx buffers are ready, then lock them
-       uart_lockTx( 0 );
-       uart_lockTx( 1 );
+       uart_lockBothTx( UART_Slave, UART_Master );
 
        // Send n number of idles to reset link status (if in a bad state)
        uint8_t value = 0x16;
        for ( uint8_t c = 0; c < num; c++ )
        {
-               Connect_addBytes( &value, 1, 1 ); // Master
-               Connect_addBytes( &value, 1, 0 ); // Slave
+               Connect_addBytes( &value, 1, UART_Master );
+               Connect_addBytes( &value, 1, UART_Slave );
        }
 
        // Release Tx buffers
-       uart_unlockTx( 0 );
-       uart_unlockTx( 1 );
+       uart_unlockTx( UART_Master );
+       uart_unlockTx( UART_Slave );
 }
 
 
@@ -426,11 +503,13 @@ void Connect_send_Idle( uint8_t num )
 
 // - Cable Check variables -
 uint32_t Connect_cableFaultsMaster = 0;
-uint32_t Connect_cableFaultsSlave = 0;
+uint32_t Connect_cableFaultsSlave  = 0;
+uint32_t Connect_cableChecksMaster = 0;
+uint32_t Connect_cableChecksSlave  = 0;
 uint8_t  Connect_cableOkMaster = 0;
-uint8_t  Connect_cableOkSlave = 0;
+uint8_t  Connect_cableOkSlave  = 0;
 
-uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
 {
        // Check if this is the first byte
        if ( *pending_bytes == 0xFFFF )
@@ -457,36 +536,48 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8
                        warn_print("Cable Fault!");
 
                        // Check which side of the chain
-                       if ( to_slave )
-                       {
-                               Connect_cableFaultsMaster++;
-                               Connect_cableOkMaster = 0;
-                               print(" Master ");
-                       }
-                       else
+                       if ( uart_num == UART_Slave )
                        {
                                Connect_cableFaultsSlave++;
                                Connect_cableOkSlave = 0;
                                print(" Slave ");
                        }
+                       else
+                       {
+                               Connect_cableFaultsMaster++;
+                               Connect_cableOkMaster = 0;
+                               print(" Master ");
+                       }
                        printHex( byte );
                        print( NL );
 
                        // Signal that the command should wait for a SYN again
                        return 1;
                }
+               else
+               {
+                       // Check which side of the chain
+                       if ( uart_num == UART_Slave )
+                       {
+                               Connect_cableChecksSlave++;
+                       }
+                       else
+                       {
+                               Connect_cableChecksMaster++;
+                       }
+               }
        }
 
        // If cable check was successful, set cable ok
        if ( *pending_bytes == 0 )
        {
-               if ( to_slave )
+               if ( uart_num == UART_Slave )
                {
-                       Connect_cableOkMaster = 1;
+                       Connect_cableOkSlave = 1;
                }
                else
                {
-                       Connect_cableOkSlave = 1;
+                       Connect_cableOkMaster = 1;
                }
        }
 
@@ -503,11 +594,11 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8
        return *pending_bytes == 0 ? 1 : 0;
 }
 
-uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
 {
        dbug_print("IdRequest");
        // Check the directionality
-       if ( to_slave )
+       if ( uart_num == UART_Master )
        {
                erro_print("Invalid IdRequest direction...");
        }
@@ -528,11 +619,11 @@ uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_
        return 1;
 }
 
-uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint8_t uart_num )
 {
        dbug_print("IdEnumeration");
        // Check the directionality
-       if ( !to_slave )
+       if ( uart_num == UART_Slave )
        {
                erro_print("Invalid IdEnumeration direction...");
        }
@@ -552,11 +643,11 @@ uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint
        return 1;
 }
 
-uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t uart_num )
 {
        dbug_print("IdReport");
        // Check the directionality
-       if ( to_slave )
+       if ( uart_num == UART_Master )
        {
                erro_print("Invalid IdRequest direction...");
        }
@@ -564,10 +655,13 @@ uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t t
        // Track Id response if master
        if ( Connect_master )
        {
-               // TODO, setup id's
                info_msg("Id Reported: ");
                printHex( id );
                print( NL );
+
+               // Check if this is the highest ID
+               if ( id > Connect_maxId )
+                       Connect_maxId = id;
                return 1;
        }
        // Propagate id if yet another slave
@@ -584,11 +678,10 @@ TriggerGuide Connect_receive_ScanCodeBuffer;
 uint8_t Connect_receive_ScanCodeBufferPos;
 uint8_t Connect_receive_ScanCodeDeviceId;
 
-uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
 {
-       dbug_print("ScanCode");
        // Check the directionality
-       if ( to_slave )
+       if ( uart_num == UART_Master )
        {
                erro_print("Invalid ScanCode direction...");
        }
@@ -612,30 +705,41 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t
 
                // Reset the BufferPos if higher than sizeof TriggerGuide
                // And send the TriggerGuide to the Macro Module
-               if ( Connect_receive_ScanCodeBufferPos > sizeof( TriggerGuide ) )
+               if ( Connect_receive_ScanCodeBufferPos >= sizeof( TriggerGuide ) )
                {
                        Connect_receive_ScanCodeBufferPos = 0;
 
                        // Adjust ScanCode offset
                        if ( Connect_receive_ScanCodeDeviceId > 0 )
                        {
+                               // Check if this node is too large
+                               if ( Connect_receive_ScanCodeDeviceId >= InterconnectNodeMax )
+                               {
+                                       warn_msg("Not enough interconnect layout nodes configured: ");
+                                       printHex( Connect_receive_ScanCodeDeviceId );
+                                       print( NL );
+                                       break;
+                               }
+
                                // This variable is in generatedKeymaps.h
                                extern uint8_t InterconnectOffsetList[];
                                Connect_receive_ScanCodeBuffer.scanCode = Connect_receive_ScanCodeBuffer.scanCode + InterconnectOffsetList[ Connect_receive_ScanCodeDeviceId - 1 ];
                        }
 
                        // ScanCode receive debug
-                       dbug_print("");
-                       printHex( Connect_receive_ScanCodeBuffer.type );
-                       print(" ");
-                       printHex( Connect_receive_ScanCodeBuffer.state );
-                       print(" ");
-                       printHex( Connect_receive_ScanCodeBuffer.scanCode );
-                       print( NL );
+                       if ( Connect_debug )
+                       {
+                               dbug_msg("");
+                               printHex( Connect_receive_ScanCodeBuffer.type );
+                               print(" ");
+                               printHex( Connect_receive_ScanCodeBuffer.state );
+                               print(" ");
+                               printHex( Connect_receive_ScanCodeBuffer.scanCode );
+                               print( NL );
+                       }
 
                        // Send ScanCode to macro module
-                       // TODO
-                       //Macro_triggerState( &Connect_receive_ScanCodeBuffer, 1 );
+                       Macro_interconnectAdd( &Connect_receive_ScanCodeBuffer );
                }
 
                break;
@@ -649,11 +753,11 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t
                Connect_receive_ScanCodeDeviceId = byte;
 
                // Lock the master Tx buffer
-               uart_lockTx( 1 );
+               uart_lockTx( UART_Master );
 
                // Send header + Id byte
                uint8_t header[] = { 0x16, 0x01, ScanCode, byte };
-               Connect_addBytes( header, sizeof( header ), 1 ); // Master
+               Connect_addBytes( header, sizeof( header ), UART_Master );
                break;
        }
        case 0xFFFE: // Number of TriggerGuides in bytes
@@ -661,16 +765,16 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t
                Connect_receive_ScanCodeBufferPos = 0;
 
                // Pass through byte
-               Connect_addBytes( &byte, 1, 1 ); // Master
+               Connect_addBytes( &byte, 1, UART_Master );
                break;
 
        default:
                // Pass through byte
-               Connect_addBytes( &byte, 1, 1 ); // Master
+               Connect_addBytes( &byte, 1, UART_Master );
 
                // Unlock Tx Buffer after sending last byte
                if ( *pending_bytes == 0 )
-                       uart_unlockTx( 1 );
+                       uart_unlockTx( UART_Master );
                break;
        }
 
@@ -678,7 +782,7 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t
        return *pending_bytes == 0 ? 1 : 0;
 }
 
-uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave )
+uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
 {
        dbug_print("Animation");
        return 1;
@@ -730,6 +834,8 @@ void Connect_reset()
        uart1_rx_status = UARTStatus_Wait;
        uart0_rx_bytes_waiting = 0;
        uart1_rx_bytes_waiting = 0;
+       uart0_lock = 0;
+       uart1_lock = 0;
 
        // Tx Status Variables
        uart0_tx_status = UARTStatus_Ready;
@@ -790,7 +896,6 @@ void Connect_setup( uint8_t master )
        UART1_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
 
        // Number of bytes in FIFO before TX Interrupt
-       // TODO Set 0
        UART0_TWFIFO = 1;
        UART1_TWFIFO = 1;
 
@@ -838,7 +943,7 @@ void Connect_scan()
 {
        // Check if initially configured as a slave and usb comes up
        // Then reconfigure as a master
-       if ( !Connect_master && Output_Available )
+       if ( !Connect_master && Output_Available && !Connect_override )
        {
                Connect_setup( Output_Available );
        }
@@ -934,6 +1039,13 @@ void cliFunc_connectCmd( char* args )
        }
 }
 
+void cliFunc_connectDbg( char* args )
+{
+       print( NL );
+       info_msg("Connect Debug Mode Toggle");
+       Connect_debug = !Connect_debug;
+}
+
 void cliFunc_connectIdl( char* args )
 {
        // Parse number from argument
@@ -988,8 +1100,15 @@ void cliFunc_connectMst( char* args )
 
        print( NL );
 
+       // Set override
+       Connect_override = 1;
+
        switch ( arg1Ptr[0] )
        {
+       // Disable override
+       case 'd':
+       case 'D':
+               Connect_override = 0;
        case 's':
        case 'S':
                info_msg("Setting device as slave.");
@@ -1025,10 +1144,14 @@ void cliFunc_connectSts( char* args )
        print( Connect_master ? "Master" : "Slave" );
        print( NL "Device Id:\t" );
        printHex( Connect_id );
+       print( NL "Max Id:\t" );
+       printHex( Connect_maxId );
        print( NL "Master <=" NL "\tStatus:\t");
        printHex( Connect_cableOkMaster );
        print( NL "\tFaults:\t");
-       printHex( Connect_cableFaultsMaster );
+       printHex32( Connect_cableFaultsMaster );
+       print("/");
+       printHex32( Connect_cableChecksMaster );
        print( NL "\tRx:\t");
        printHex( uart1_rx_status );
        print( NL "\tTx:\t");
@@ -1036,7 +1159,9 @@ void cliFunc_connectSts( char* args )
        print( NL "Slave <=" NL "\tStatus:\t");
        printHex( Connect_cableOkSlave );
        print( NL "\tFaults:\t");
-       printHex( Connect_cableFaultsSlave );
+       printHex32( Connect_cableFaultsSlave );
+       print("/");
+       printHex32( Connect_cableChecksSlave );
        print( NL "\tRx:\t");
        printHex( uart0_rx_status );
        print( NL "\tTx:\t");
index 1b752e6b4006a0850ee2e06f31b90118e65fb853..bb50610dfdb2b79ca753907502e78a171c136366 100644 (file)
@@ -41,6 +41,7 @@ typedef enum Command {
        RemoteInput,      // Remote command to send to a given node's debug cli
 
        Command_TOP,      // Enum bounds
+       Command_SYN = 0x16, // Reserved for error handling
 } Command;
 
 // UART Rx/Tx Status