comparison Scan/UARTConnect/connect_scan.c @ 361:7c6ac7b88cda

Working support for Interconnect - 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
author Jacob Alexander <haata@kiibohd.com>
date Sat, 15 Aug 2015 21:53:59 -0700
parents dbefb68411e1
children fc2c2a1e9615
comparison
equal deleted inserted replaced
360:dbefb68411e1 361:7c6ac7b88cda
31 31
32 32
33 33
34 // ----- Macros ----- 34 // ----- Macros -----
35 35
36 #define UART_Master 1
37 #define UART_Slave 0
38 #define uart_lock_m( uartNum ) uart##uartNum##_lock
39 #define uart_buffer_items_m( uartNum ) uart##uartNum##_buffer_items
40 #define uart_buffer_m( uartNum ) uart##uartNum##_buffer
41 #define uart_buffer_head_m( uartNum ) uart##uartNum##_buffer_head
42 #define uart_buffer_tail_m( uartNum ) uart##uartNum##_buffer_tail
43 #define uart_tx_status_m( uartNum ) uart##uartNum##_tx_status
44
36 // Macro for adding to each uart Tx ring buffer 45 // Macro for adding to each uart Tx ring buffer
37 #define uart_addTxBuffer( uartNum ) \ 46 #define uart_addTxBuffer( uartNum ) \
38 case uartNum: \ 47 case uartNum: \
39 /* Delay UART copy until there's some space left */ \ 48 /* Delay UART copy until there's some space left */ \
40 while ( uart##uartNum##_buffer_items + count > uart_buffer_size ) \ 49 while ( uart_buffer_items_m( uartNum ) + count > uart_buffer_size ) \
41 { \ 50 { \
42 warn_msg("Too much data to send on UART0, waiting..."); \ 51 warn_msg("Too much data to send on UART0, waiting..."); \
43 delay( 1 ); \ 52 delay( 1 ); \
44 } \ 53 } \
45 /* Append data to ring buffer */ \ 54 /* Append data to ring buffer */ \
48 if ( Connect_debug ) \ 57 if ( Connect_debug ) \
49 { \ 58 { \
50 printHex( buffer[ c ] ); \ 59 printHex( buffer[ c ] ); \
51 print( " +" #uartNum NL ); \ 60 print( " +" #uartNum NL ); \
52 } \ 61 } \
53 uart##uartNum##_buffer[ uart##uartNum##_buffer_tail++ ] = buffer[ c ]; \ 62 uart_buffer_m( uartNum )[ uart_buffer_tail_m( uartNum )++ ] = buffer[ c ]; \
54 uart##uartNum##_buffer_items++; \ 63 uart_buffer_items_m( uartNum )++; \
55 if ( uart##uartNum##_buffer_tail >= uart_buffer_size ) \ 64 if ( uart_buffer_tail_m( uartNum ) >= uart_buffer_size ) \
56 uart##uartNum##_buffer_tail = 0; \ 65 uart_buffer_tail_m( uartNum ) = 0; \
57 if ( uart##uartNum##_buffer_head == uart##uartNum##_buffer_tail ) \ 66 if ( uart_buffer_head_m( uartNum ) == uart_buffer_tail_m( uartNum ) ) \
58 uart##uartNum##_buffer_head++; \ 67 uart_buffer_head_m( uartNum )++; \
59 if ( uart##uartNum##_buffer_head >= uart_buffer_size ) \ 68 if ( uart_buffer_head_m( uartNum ) >= uart_buffer_size ) \
60 uart##uartNum##_buffer_head = 0; \ 69 uart_buffer_head_m( uartNum ) = 0; \
61 } \ 70 } \
62 break 71 break
63 72
64 // Macro for popping from Tx ring buffer 73 // Macro for popping from Tx ring buffer
65 #define uart_fillTxFifo( uartNum ) \ 74 #define uart_fillTxFifo( uartNum ) \
66 { \ 75 { \
67 uint8_t fifoSize = ( ( UART##uartNum##_PFIFO & UART_PFIFO_TXFIFOSIZE ) >> 2 ); \ 76 uint8_t fifoSize = ( ( UART##uartNum##_PFIFO & UART_PFIFO_TXFIFOSIZE ) >> 2 ); \
68 if ( fifoSize == 0 ) \ 77 if ( fifoSize == 0 ) \
69 fifoSize = 1; \ 78 fifoSize = 1; \
70 while ( UART##uartNum##_TCFIFO < fifoSize ) \ 79 if ( Connect_debug ) \
80 { \
81 print( "TxFIFO " #uartNum " - " ); \
82 printHex( fifoSize ); \
83 print("/"); \
84 printHex( UART##uartNum##_TCFIFO ); \
85 print("/"); \
86 printHex( uart##uartNum##_buffer_items ); \
87 print( NL ); \
88 } \
89 /* XXX Doesn't work well */ \
90 /* while ( UART##uartNum##_TCFIFO < fifoSize ) */ \
91 /* More reliable, albeit slower */ \
92 fifoSize -= UART##uartNum##_TCFIFO; \
93 while ( fifoSize-- != 0 ) \
71 { \ 94 { \
72 if ( uart##uartNum##_buffer_items == 0 ) \ 95 if ( uart##uartNum##_buffer_items == 0 ) \
73 break; \ 96 break; \
74 UART##uartNum##_D = uart##uartNum##_buffer[ uart##uartNum##_buffer_head++ ]; \ 97 UART##uartNum##_D = uart##uartNum##_buffer[ uart##uartNum##_buffer_head++ ]; \
75 uart##uartNum##_buffer_items--; \ 98 uart##uartNum##_buffer_items--; \
91 return; \ 114 return; \
92 } \ 115 } \
93 /* Process each byte in the UART buffer */ \ 116 /* Process each byte in the UART buffer */ \
94 while ( available-- > 0 ) \ 117 while ( available-- > 0 ) \
95 { \ 118 { \
119 /* First check if there was noise or Parity issues with current byte */ \
120 uint8_t err_status = UART##uartNum##_ED; \
121 /* Read byte from Rx FIFO */ \
96 uint8_t byteRead = UART##uartNum##_D; \ 122 uint8_t byteRead = UART##uartNum##_D; \
97 if ( Connect_debug ) \ 123 if ( Connect_debug ) \
98 { \ 124 { \
99 printHex( byteRead ); \ 125 printHex( byteRead ); \
100 print( "(" ); \ 126 print("("); \
101 printInt8( available ); \ 127 printInt8( available ); \
102 print( ") <-" ); \ 128 print(") <-"); \
129 } \
130 /* Check error status */ \
131 if ( err_status & 0x80 ) \
132 { \
133 print(" NOISY "); \
134 } \
135 if ( err_status & 0x40 ) \
136 { \
137 print(" PARITY ERR "); \
138 } \
139 /* Ignore current byte if there was an error */ \
140 if ( err_status ) \
141 { \
142 uart##uartNum##_rx_status = UARTStatus_Wait; \
143 if ( Connect_debug ) \
144 { \
145 print( NL ); \
146 } \
147 continue; \
103 } \ 148 } \
104 switch ( uart##uartNum##_rx_status ) \ 149 switch ( uart##uartNum##_rx_status ) \
105 { \ 150 { \
106 case UARTStatus_Wait: \ 151 case UARTStatus_Wait: \
107 if ( Connect_debug ) \ 152 if ( Connect_debug ) \
108 { \ 153 { \
109 print(" SYN "); \ 154 print(" Wait "); \
110 } \ 155 } \
111 uart##uartNum##_rx_status = byteRead == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; \ 156 uart##uartNum##_rx_status = byteRead == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; \
112 break; \ 157 break; \
113 case UARTStatus_SYN: \ 158 case UARTStatus_SYN: \
114 if ( Connect_debug ) \ 159 if ( Connect_debug ) \
115 { \ 160 { \
116 print(" SOH "); \ 161 print(" SYN "); \
117 } \ 162 } \
118 uart##uartNum##_rx_status = byteRead == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; \ 163 uart##uartNum##_rx_status = byteRead == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; \
119 break; \ 164 break; \
120 case UARTStatus_SOH: \ 165 case UARTStatus_SOH: \
121 { \ 166 { \
122 if ( Connect_debug ) \ 167 if ( Connect_debug ) \
123 { \ 168 { \
124 print(" CMD "); \ 169 print(" SOH "); \
125 } \ 170 } \
171 /* Check if this is actually a reserved CMD 0x16 */ \
172 if ( byteRead == Command_SYN ) \
173 { \
174 uart##uartNum##_rx_status = UARTStatus_SYN; \
175 break; \
176 } \
177 /* Otherwise process the command */ \
126 uint8_t byte = byteRead; \ 178 uint8_t byte = byteRead; \
127 if ( byte <= Animation ) \ 179 if ( byte < Command_TOP ) \
128 { \ 180 { \
129 uart##uartNum##_rx_status = UARTStatus_Command; \ 181 uart##uartNum##_rx_status = UARTStatus_Command; \
130 uart##uartNum##_rx_command = byte; \ 182 uart##uartNum##_rx_command = byte; \
131 uart##uartNum##_rx_bytes_waiting = 0xFFFF; \ 183 uart##uartNum##_rx_bytes_waiting = 0xFFFF; \
132 } \ 184 } \
141 uart##uartNum##_rx_status = UARTStatus_Wait; \ 193 uart##uartNum##_rx_status = UARTStatus_Wait; \
142 break; \ 194 break; \
143 default: \ 195 default: \
144 if ( Connect_debug ) \ 196 if ( Connect_debug ) \
145 { \ 197 { \
146 print("###"); \ 198 print(" ### "); \
199 printHex( uart##uartNum##_rx_command ); \
147 } \ 200 } \
148 break; \ 201 break; \
149 } \ 202 } \
150 break; \ 203 break; \
151 } \ 204 } \
175 } 228 }
176 229
177 // Macros for locking/unlock Tx buffers 230 // Macros for locking/unlock Tx buffers
178 #define uart_lockTx( uartNum ) \ 231 #define uart_lockTx( uartNum ) \
179 { \ 232 { \
180 while ( uart##uartNum##_tx_status == UARTStatus_Wait ); \ 233 /* First, secure place in line for the resource */ \
181 uart##uartNum##_tx_status = UARTStatus_Wait; \ 234 while ( uart_lock_m( uartNum ) ); \
235 uart_lock_m( uartNum ) = 1; \
236 /* Next, wait unit the UART is ready */ \
237 while ( uart_tx_status_m( uartNum ) != UARTStatus_Ready ); \
238 uart_tx_status_m( uartNum ) = UARTStatus_Wait; \
239 }
240
241 #define uart_lockBothTx( uartNum1, uartNum2 ) \
242 { \
243 /* First, secure place in line for the resource */ \
244 while ( uart_lock_m( uartNum1 ) || uart_lock_m( uartNum2 ) ); \
245 uart_lock_m( uartNum1 ) = 1; \
246 uart_lock_m( uartNum2 ) = 1; \
247 /* Next, wait unit the UARTs are ready */ \
248 while ( uart_tx_status_m( uartNum1 ) != UARTStatus_Ready || uart_tx_status_m( uartNum2 ) != UARTStatus_Ready ); \
249 uart_tx_status_m( uartNum1 ) = UARTStatus_Wait; \
250 uart_tx_status_m( uartNum2 ) = UARTStatus_Wait; \
182 } 251 }
183 252
184 #define uart_unlockTx( uartNum ) \ 253 #define uart_unlockTx( uartNum ) \
185 { \ 254 { \
186 uart##uartNum##_tx_status = UARTStatus_Ready; \ 255 /* Ready the UART */ \
256 uart_tx_status_m( uartNum ) = UARTStatus_Ready; \
257 /* Unlock the resource */ \
258 uart_lock_m( uartNum ) = 0; \
187 } 259 }
188 260
189 261
190 262
191 // ----- Function Declarations ----- 263 // ----- Function Declarations -----
192 264
193 // CLI Functions 265 // CLI Functions
194 void cliFunc_connectCmd ( char *args ); 266 void cliFunc_connectCmd ( char *args );
267 void cliFunc_connectDbg ( char *args );
195 void cliFunc_connectIdl ( char *args ); 268 void cliFunc_connectIdl ( char *args );
196 void cliFunc_connectLst ( char *args ); 269 void cliFunc_connectLst ( char *args );
197 void cliFunc_connectMst ( char *args ); 270 void cliFunc_connectMst ( char *args );
198 void cliFunc_connectRst ( char *args ); 271 void cliFunc_connectRst ( char *args );
199 void cliFunc_connectSts ( char *args ); 272 void cliFunc_connectSts ( char *args );
202 275
203 // ----- Variables ----- 276 // ----- Variables -----
204 277
205 // Connect Module command dictionary 278 // Connect Module command dictionary
206 CLIDict_Entry( connectCmd, "Sends a command via UART Connect, first arg is which uart, next arg is the command, rest are the arguments." ); 279 CLIDict_Entry( connectCmd, "Sends a command via UART Connect, first arg is which uart, next arg is the command, rest are the arguments." );
280 CLIDict_Entry( connectDbg, "Toggle UARTConnect debug mode." );
207 CLIDict_Entry( connectIdl, "Sends N number of Idle commands, 2 is the default value, and should be sufficient in most cases." ); 281 CLIDict_Entry( connectIdl, "Sends N number of Idle commands, 2 is the default value, and should be sufficient in most cases." );
208 CLIDict_Entry( connectLst, "Lists available UARTConnect commands and index id" ); 282 CLIDict_Entry( connectLst, "Lists available UARTConnect commands and index id" );
209 CLIDict_Entry( connectMst, "Sets the device as master. Use argument of s to set as slave." ); 283 CLIDict_Entry( connectMst, "Sets the device as master. Use argument of s to set as slave." );
210 CLIDict_Entry( connectRst, "Resets both Rx and Tx connect buffers and state variables." ); 284 CLIDict_Entry( connectRst, "Resets both Rx and Tx connect buffers and state variables." );
211 CLIDict_Entry( connectSts, "UARTConnect status." ); 285 CLIDict_Entry( connectSts, "UARTConnect status." );
212 CLIDict_Def( uartConnectCLIDict, "UARTConnect Module Commands" ) = { 286 CLIDict_Def( uartConnectCLIDict, "UARTConnect Module Commands" ) = {
213 CLIDict_Item( connectCmd ), 287 CLIDict_Item( connectCmd ),
288 CLIDict_Item( connectDbg ),
214 CLIDict_Item( connectIdl ), 289 CLIDict_Item( connectIdl ),
215 CLIDict_Item( connectLst ), 290 CLIDict_Item( connectLst ),
216 CLIDict_Item( connectMst ), 291 CLIDict_Item( connectMst ),
217 CLIDict_Item( connectRst ), 292 CLIDict_Item( connectRst ),
218 CLIDict_Item( connectSts ), 293 CLIDict_Item( connectSts ),
221 296
222 297
223 // -- Connect Device Id Variables -- 298 // -- Connect Device Id Variables --
224 uint8_t Connect_id = 255; // Invalid, unset 299 uint8_t Connect_id = 255; // Invalid, unset
225 uint8_t Connect_master = 0; 300 uint8_t Connect_master = 0;
301 uint8_t Connect_maxId = 0;
226 302
227 303
228 // -- Control Variables -- 304 // -- Control Variables --
229 uint32_t Connect_lastCheck = 0; // Cable Check scheduler 305 uint32_t Connect_lastCheck = 0; // Cable Check scheduler
230 uint8_t Connect_debug = 0; // Set 1 for debug 306 uint8_t Connect_debug = 0; // Set 1 for debug
307 uint8_t Connect_override = 0; // Prevents master from automatically being set
231 308
232 309
233 // -- Rx Status Variables -- 310 // -- Rx Status Variables --
234 311
235 volatile UARTStatus uart0_rx_status; 312 volatile UARTStatus uart0_rx_status;
236 volatile UARTStatus uart1_rx_status; 313 volatile UARTStatus uart1_rx_status;
237 volatile uint16_t uart0_rx_bytes_waiting; 314 volatile uint16_t uart0_rx_bytes_waiting;
238 volatile uint16_t uart1_rx_bytes_waiting; 315 volatile uint16_t uart1_rx_bytes_waiting;
239 volatile Command uart0_rx_command; 316 volatile Command uart0_rx_command;
240 volatile Command uart1_rx_command; 317 volatile Command uart1_rx_command;
318 volatile uint8_t uart0_lock;
319 volatile uint8_t uart1_lock;
241 320
242 321
243 // -- Tx Status Variables -- 322 // -- Tx Status Variables --
244 323
245 volatile UARTStatus uart0_tx_status; 324 volatile UARTStatus uart0_tx_status;
273 } 352 }
274 353
275 // Choose the uart 354 // Choose the uart
276 switch ( uart ) 355 switch ( uart )
277 { 356 {
278 uart_addTxBuffer( 0 ); 357 uart_addTxBuffer( UART_Master );
279 uart_addTxBuffer( 1 ); 358 uart_addTxBuffer( UART_Slave );
280 default: 359 default:
281 erro_msg("Invalid UART to send from..."); 360 erro_msg("Invalid UART to send from...");
282 break; 361 break;
283 } 362 }
284 } 363 }
288 367
289 // patternLen defines how many bytes should the incrementing pattern have 368 // patternLen defines how many bytes should the incrementing pattern have
290 void Connect_send_CableCheck( uint8_t patternLen ) 369 void Connect_send_CableCheck( uint8_t patternLen )
291 { 370 {
292 // Wait until the Tx buffers are ready, then lock them 371 // Wait until the Tx buffers are ready, then lock them
293 uart_lockTx( 0 ); 372 uart_lockBothTx( UART_Master, UART_Slave );
294 uart_lockTx( 1 );
295 373
296 // Prepare header 374 // Prepare header
297 uint8_t header[] = { 0x16, 0x01, CableCheck, patternLen }; 375 uint8_t header[] = { 0x16, 0x01, CableCheck, patternLen };
298 376
299 // Send header 377 // Send header
300 Connect_addBytes( header, sizeof( header ), 1 ); // Master 378 Connect_addBytes( header, sizeof( header ), UART_Master );
301 Connect_addBytes( header, sizeof( header ), 0 ); // Slave 379 Connect_addBytes( header, sizeof( header ), UART_Slave );
302 380
303 // Send 0xD2 (11010010) for each argument 381 // Send 0xD2 (11010010) for each argument
304 uint8_t value = 0xD2; 382 uint8_t value = 0xD2;
305 for ( uint8_t c = 0; c < patternLen; c++ ) 383 for ( uint8_t c = 0; c < patternLen; c++ )
306 { 384 {
307 Connect_addBytes( &value, 1, 1 ); // Master 385 Connect_addBytes( &value, 1, UART_Master );
308 Connect_addBytes( &value, 1, 0 ); // Slave 386 Connect_addBytes( &value, 1, UART_Slave );
309 } 387 }
310 388
311 // Release Tx buffers 389 // Release Tx buffers
312 uart_unlockTx( 0 ); 390 uart_unlockTx( UART_Master );
313 uart_unlockTx( 1 ); 391 uart_unlockTx( UART_Slave );
314 } 392 }
315 393
316 void Connect_send_IdRequest() 394 void Connect_send_IdRequest()
317 { 395 {
318 // Lock master bound Tx 396 // Lock master bound Tx
319 uart_lockTx( 1 ); 397 uart_lockTx( UART_Master );
320 398
321 // Prepare header 399 // Prepare header
322 uint8_t header[] = { 0x16, 0x01, IdRequest }; 400 uint8_t header[] = { 0x16, 0x01, IdRequest };
323 401
324 // Send header 402 // Send header
325 Connect_addBytes( header, sizeof( header ), 1 ); // Master 403 Connect_addBytes( header, sizeof( header ), UART_Master );
326 404
327 // Unlock Tx 405 // Unlock Tx
328 uart_unlockTx( 1 ); 406 uart_unlockTx( UART_Master );
329 } 407 }
330 408
331 // id is the value the next slave should enumerate as 409 // id is the value the next slave should enumerate as
332 void Connect_send_IdEnumeration( uint8_t id ) 410 void Connect_send_IdEnumeration( uint8_t id )
333 { 411 {
334 // Lock slave bound Tx 412 // Lock slave bound Tx
335 uart_lockTx( 0 ); 413 uart_lockTx( UART_Slave );
336 414
337 // Prepare header 415 // Prepare header
338 uint8_t header[] = { 0x16, 0x01, IdEnumeration, id }; 416 uint8_t header[] = { 0x16, 0x01, IdEnumeration, id };
339 417
340 // Send header 418 // Send header
341 Connect_addBytes( header, sizeof( header ), 0 ); // Slave 419 Connect_addBytes( header, sizeof( header ), UART_Slave );
342 420
343 // Unlock Tx 421 // Unlock Tx
344 uart_unlockTx( 0 ); 422 uart_unlockTx( UART_Slave );
345 } 423 }
346 424
347 // id is the currently assigned id to the slave 425 // id is the currently assigned id to the slave
348 void Connect_send_IdReport( uint8_t id ) 426 void Connect_send_IdReport( uint8_t id )
349 { 427 {
350 // Lock master bound Tx 428 // Lock master bound Tx
351 uart_lockTx( 1 ); 429 uart_lockTx( UART_Master );
352 430
353 // Prepare header 431 // Prepare header
354 uint8_t header[] = { 0x16, 0x01, IdReport, id }; 432 uint8_t header[] = { 0x16, 0x01, IdReport, id };
355 433
356 // Send header 434 // Send header
357 Connect_addBytes( header, sizeof( header ), 1 ); // Master 435 Connect_addBytes( header, sizeof( header ), UART_Master );
358 436
359 // Unlock Tx 437 // Unlock Tx
360 uart_unlockTx( 1 ); 438 uart_unlockTx( UART_Master );
361 } 439 }
362 440
363 // id is the currently assigned id to the slave 441 // id is the currently assigned id to the slave
364 // scanCodeStateList is an array of [scancode, state]'s (8 bit values) 442 // scanCodeStateList is an array of [scancode, state]'s (8 bit values)
365 // numScanCodes is the number of scan codes to parse from array 443 // numScanCodes is the number of scan codes to parse from array
366 void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ) 444 void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes )
367 { 445 {
368 // Lock master bound Tx 446 // Lock master bound Tx
369 uart_lockTx( 1 ); 447 uart_lockTx( UART_Master );
370 448
371 // Prepare header 449 // Prepare header
372 uint8_t header[] = { 0x16, 0x01, ScanCode, id, numScanCodes }; 450 uint8_t header[] = { 0x16, 0x01, ScanCode, id, numScanCodes };
373 451
374 // Send header 452 // Send header
375 Connect_addBytes( header, sizeof( header ), 1 ); // Master 453 Connect_addBytes( header, sizeof( header ), UART_Master );
376 454
377 // Send each of the scan codes 455 // Send each of the scan codes
378 Connect_addBytes( (uint8_t*)scanCodeStateList, numScanCodes * TriggerGuideSize, 1 ); // Master 456 Connect_addBytes( (uint8_t*)scanCodeStateList, numScanCodes * TriggerGuideSize, UART_Master );
379 457
380 // Unlock Tx 458 // Unlock Tx
381 uart_unlockTx( 1 ); 459 uart_unlockTx( UART_Master );
382 } 460 }
383 461
384 // id is the currently assigned id to the slave 462 // id is the currently assigned id to the slave
385 // paramList is an array of [param, value]'s (8 bit values) 463 // paramList is an array of [param, value]'s (8 bit values)
386 // numParams is the number of params to parse from the array 464 // numParams is the number of params to parse from the array
387 void Connect_send_Animation( uint8_t id, uint8_t *paramList, uint8_t numParams ) 465 void Connect_send_Animation( uint8_t id, uint8_t *paramList, uint8_t numParams )
388 { 466 {
389 // Lock slave bound Tx 467 // Lock slave bound Tx
390 uart_lockTx( 0 ); 468 uart_lockTx( UART_Slave );
391 469
392 // Prepare header 470 // Prepare header
393 uint8_t header[] = { 0x16, 0x01, Animation, id, numParams }; 471 uint8_t header[] = { 0x16, 0x01, Animation, id, numParams };
394 472
395 // Send header 473 // Send header
396 Connect_addBytes( header, sizeof( header ), 0 ); // Slave 474 Connect_addBytes( header, sizeof( header ), UART_Slave );
397 475
398 // Send each of the scan codes 476 // Send each of the scan codes
399 Connect_addBytes( paramList, numParams, 0 ); // Slave 477 Connect_addBytes( paramList, numParams, UART_Slave );
400 478
401 // Unlock Tx 479 // Unlock Tx
402 uart_unlockTx( 0 ); 480 uart_unlockTx( UART_Slave );
403 } 481 }
404 482
405 void Connect_send_Idle( uint8_t num ) 483 void Connect_send_Idle( uint8_t num )
406 { 484 {
407 // Wait until the Tx buffers are ready, then lock them 485 // Wait until the Tx buffers are ready, then lock them
408 uart_lockTx( 0 ); 486 uart_lockBothTx( UART_Slave, UART_Master );
409 uart_lockTx( 1 );
410 487
411 // Send n number of idles to reset link status (if in a bad state) 488 // Send n number of idles to reset link status (if in a bad state)
412 uint8_t value = 0x16; 489 uint8_t value = 0x16;
413 for ( uint8_t c = 0; c < num; c++ ) 490 for ( uint8_t c = 0; c < num; c++ )
414 { 491 {
415 Connect_addBytes( &value, 1, 1 ); // Master 492 Connect_addBytes( &value, 1, UART_Master );
416 Connect_addBytes( &value, 1, 0 ); // Slave 493 Connect_addBytes( &value, 1, UART_Slave );
417 } 494 }
418 495
419 // Release Tx buffers 496 // Release Tx buffers
420 uart_unlockTx( 0 ); 497 uart_unlockTx( UART_Master );
421 uart_unlockTx( 1 ); 498 uart_unlockTx( UART_Slave );
422 } 499 }
423 500
424 501
425 // -- Connect receive functions -- 502 // -- Connect receive functions --
426 503
427 // - Cable Check variables - 504 // - Cable Check variables -
428 uint32_t Connect_cableFaultsMaster = 0; 505 uint32_t Connect_cableFaultsMaster = 0;
429 uint32_t Connect_cableFaultsSlave = 0; 506 uint32_t Connect_cableFaultsSlave = 0;
507 uint32_t Connect_cableChecksMaster = 0;
508 uint32_t Connect_cableChecksSlave = 0;
430 uint8_t Connect_cableOkMaster = 0; 509 uint8_t Connect_cableOkMaster = 0;
431 uint8_t Connect_cableOkSlave = 0; 510 uint8_t Connect_cableOkSlave = 0;
432 511
433 uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) 512 uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
434 { 513 {
435 // Check if this is the first byte 514 // Check if this is the first byte
436 if ( *pending_bytes == 0xFFFF ) 515 if ( *pending_bytes == 0xFFFF )
437 { 516 {
438 *pending_bytes = byte; 517 *pending_bytes = byte;
455 if ( byte != 0xD2 ) 534 if ( byte != 0xD2 )
456 { 535 {
457 warn_print("Cable Fault!"); 536 warn_print("Cable Fault!");
458 537
459 // Check which side of the chain 538 // Check which side of the chain
460 if ( to_slave ) 539 if ( uart_num == UART_Slave )
540 {
541 Connect_cableFaultsSlave++;
542 Connect_cableOkSlave = 0;
543 print(" Slave ");
544 }
545 else
461 { 546 {
462 Connect_cableFaultsMaster++; 547 Connect_cableFaultsMaster++;
463 Connect_cableOkMaster = 0; 548 Connect_cableOkMaster = 0;
464 print(" Master "); 549 print(" Master ");
465 } 550 }
466 else
467 {
468 Connect_cableFaultsSlave++;
469 Connect_cableOkSlave = 0;
470 print(" Slave ");
471 }
472 printHex( byte ); 551 printHex( byte );
473 print( NL ); 552 print( NL );
474 553
475 // Signal that the command should wait for a SYN again 554 // Signal that the command should wait for a SYN again
476 return 1; 555 return 1;
477 } 556 }
557 else
558 {
559 // Check which side of the chain
560 if ( uart_num == UART_Slave )
561 {
562 Connect_cableChecksSlave++;
563 }
564 else
565 {
566 Connect_cableChecksMaster++;
567 }
568 }
478 } 569 }
479 570
480 // If cable check was successful, set cable ok 571 // If cable check was successful, set cable ok
481 if ( *pending_bytes == 0 ) 572 if ( *pending_bytes == 0 )
482 { 573 {
483 if ( to_slave ) 574 if ( uart_num == UART_Slave )
484 { 575 {
485 Connect_cableOkMaster = 1; 576 Connect_cableOkSlave = 1;
486 } 577 }
487 else 578 else
488 { 579 {
489 Connect_cableOkSlave = 1; 580 Connect_cableOkMaster = 1;
490 } 581 }
491 } 582 }
492 583
493 if ( Connect_debug ) 584 if ( Connect_debug )
494 { 585 {
501 592
502 // Check whether the cable check has finished 593 // Check whether the cable check has finished
503 return *pending_bytes == 0 ? 1 : 0; 594 return *pending_bytes == 0 ? 1 : 0;
504 } 595 }
505 596
506 uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) 597 uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
507 { 598 {
508 dbug_print("IdRequest"); 599 dbug_print("IdRequest");
509 // Check the directionality 600 // Check the directionality
510 if ( to_slave ) 601 if ( uart_num == UART_Master )
511 { 602 {
512 erro_print("Invalid IdRequest direction..."); 603 erro_print("Invalid IdRequest direction...");
513 } 604 }
514 605
515 // Check if master, begin IdEnumeration 606 // Check if master, begin IdEnumeration
526 } 617 }
527 618
528 return 1; 619 return 1;
529 } 620 }
530 621
531 uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave ) 622 uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint8_t uart_num )
532 { 623 {
533 dbug_print("IdEnumeration"); 624 dbug_print("IdEnumeration");
534 // Check the directionality 625 // Check the directionality
535 if ( !to_slave ) 626 if ( uart_num == UART_Slave )
536 { 627 {
537 erro_print("Invalid IdEnumeration direction..."); 628 erro_print("Invalid IdEnumeration direction...");
538 } 629 }
539 630
540 // Set the device id 631 // Set the device id
550 } 641 }
551 642
552 return 1; 643 return 1;
553 } 644 }
554 645
555 uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave ) 646 uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t uart_num )
556 { 647 {
557 dbug_print("IdReport"); 648 dbug_print("IdReport");
558 // Check the directionality 649 // Check the directionality
559 if ( to_slave ) 650 if ( uart_num == UART_Master )
560 { 651 {
561 erro_print("Invalid IdRequest direction..."); 652 erro_print("Invalid IdRequest direction...");
562 } 653 }
563 654
564 // Track Id response if master 655 // Track Id response if master
565 if ( Connect_master ) 656 if ( Connect_master )
566 { 657 {
567 // TODO, setup id's
568 info_msg("Id Reported: "); 658 info_msg("Id Reported: ");
569 printHex( id ); 659 printHex( id );
570 print( NL ); 660 print( NL );
661
662 // Check if this is the highest ID
663 if ( id > Connect_maxId )
664 Connect_maxId = id;
571 return 1; 665 return 1;
572 } 666 }
573 // Propagate id if yet another slave 667 // Propagate id if yet another slave
574 else 668 else
575 { 669 {
582 // - Scan Code Variables - 676 // - Scan Code Variables -
583 TriggerGuide Connect_receive_ScanCodeBuffer; 677 TriggerGuide Connect_receive_ScanCodeBuffer;
584 uint8_t Connect_receive_ScanCodeBufferPos; 678 uint8_t Connect_receive_ScanCodeBufferPos;
585 uint8_t Connect_receive_ScanCodeDeviceId; 679 uint8_t Connect_receive_ScanCodeDeviceId;
586 680
587 uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) 681 uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
588 { 682 {
589 dbug_print("ScanCode");
590 // Check the directionality 683 // Check the directionality
591 if ( to_slave ) 684 if ( uart_num == UART_Master )
592 { 685 {
593 erro_print("Invalid ScanCode direction..."); 686 erro_print("Invalid ScanCode direction...");
594 } 687 }
595 688
596 // Master node, trigger scan codes 689 // Master node, trigger scan codes
610 // Set the specific TriggerGuide entry 703 // Set the specific TriggerGuide entry
611 ((uint8_t*)&Connect_receive_ScanCodeBuffer)[ Connect_receive_ScanCodeBufferPos++ ] = byte; 704 ((uint8_t*)&Connect_receive_ScanCodeBuffer)[ Connect_receive_ScanCodeBufferPos++ ] = byte;
612 705
613 // Reset the BufferPos if higher than sizeof TriggerGuide 706 // Reset the BufferPos if higher than sizeof TriggerGuide
614 // And send the TriggerGuide to the Macro Module 707 // And send the TriggerGuide to the Macro Module
615 if ( Connect_receive_ScanCodeBufferPos > sizeof( TriggerGuide ) ) 708 if ( Connect_receive_ScanCodeBufferPos >= sizeof( TriggerGuide ) )
616 { 709 {
617 Connect_receive_ScanCodeBufferPos = 0; 710 Connect_receive_ScanCodeBufferPos = 0;
618 711
619 // Adjust ScanCode offset 712 // Adjust ScanCode offset
620 if ( Connect_receive_ScanCodeDeviceId > 0 ) 713 if ( Connect_receive_ScanCodeDeviceId > 0 )
621 { 714 {
715 // Check if this node is too large
716 if ( Connect_receive_ScanCodeDeviceId >= InterconnectNodeMax )
717 {
718 warn_msg("Not enough interconnect layout nodes configured: ");
719 printHex( Connect_receive_ScanCodeDeviceId );
720 print( NL );
721 break;
722 }
723
622 // This variable is in generatedKeymaps.h 724 // This variable is in generatedKeymaps.h
623 extern uint8_t InterconnectOffsetList[]; 725 extern uint8_t InterconnectOffsetList[];
624 Connect_receive_ScanCodeBuffer.scanCode = Connect_receive_ScanCodeBuffer.scanCode + InterconnectOffsetList[ Connect_receive_ScanCodeDeviceId - 1 ]; 726 Connect_receive_ScanCodeBuffer.scanCode = Connect_receive_ScanCodeBuffer.scanCode + InterconnectOffsetList[ Connect_receive_ScanCodeDeviceId - 1 ];
625 } 727 }
626 728
627 // ScanCode receive debug 729 // ScanCode receive debug
628 dbug_print(""); 730 if ( Connect_debug )
629 printHex( Connect_receive_ScanCodeBuffer.type ); 731 {
630 print(" "); 732 dbug_msg("");
631 printHex( Connect_receive_ScanCodeBuffer.state ); 733 printHex( Connect_receive_ScanCodeBuffer.type );
632 print(" "); 734 print(" ");
633 printHex( Connect_receive_ScanCodeBuffer.scanCode ); 735 printHex( Connect_receive_ScanCodeBuffer.state );
634 print( NL ); 736 print(" ");
737 printHex( Connect_receive_ScanCodeBuffer.scanCode );
738 print( NL );
739 }
635 740
636 // Send ScanCode to macro module 741 // Send ScanCode to macro module
637 // TODO 742 Macro_interconnectAdd( &Connect_receive_ScanCodeBuffer );
638 //Macro_triggerState( &Connect_receive_ScanCodeBuffer, 1 );
639 } 743 }
640 744
641 break; 745 break;
642 } 746 }
643 // Propagate ScanCode packet 747 // Propagate ScanCode packet
647 case 0xFFFF: // Device Id 751 case 0xFFFF: // Device Id
648 { 752 {
649 Connect_receive_ScanCodeDeviceId = byte; 753 Connect_receive_ScanCodeDeviceId = byte;
650 754
651 // Lock the master Tx buffer 755 // Lock the master Tx buffer
652 uart_lockTx( 1 ); 756 uart_lockTx( UART_Master );
653 757
654 // Send header + Id byte 758 // Send header + Id byte
655 uint8_t header[] = { 0x16, 0x01, ScanCode, byte }; 759 uint8_t header[] = { 0x16, 0x01, ScanCode, byte };
656 Connect_addBytes( header, sizeof( header ), 1 ); // Master 760 Connect_addBytes( header, sizeof( header ), UART_Master );
657 break; 761 break;
658 } 762 }
659 case 0xFFFE: // Number of TriggerGuides in bytes 763 case 0xFFFE: // Number of TriggerGuides in bytes
660 *pending_bytes = byte * sizeof( TriggerGuide ); 764 *pending_bytes = byte * sizeof( TriggerGuide );
661 Connect_receive_ScanCodeBufferPos = 0; 765 Connect_receive_ScanCodeBufferPos = 0;
662 766
663 // Pass through byte 767 // Pass through byte
664 Connect_addBytes( &byte, 1, 1 ); // Master 768 Connect_addBytes( &byte, 1, UART_Master );
665 break; 769 break;
666 770
667 default: 771 default:
668 // Pass through byte 772 // Pass through byte
669 Connect_addBytes( &byte, 1, 1 ); // Master 773 Connect_addBytes( &byte, 1, UART_Master );
670 774
671 // Unlock Tx Buffer after sending last byte 775 // Unlock Tx Buffer after sending last byte
672 if ( *pending_bytes == 0 ) 776 if ( *pending_bytes == 0 )
673 uart_unlockTx( 1 ); 777 uart_unlockTx( UART_Master );
674 break; 778 break;
675 } 779 }
676 780
677 // Check whether the scan codes have finished sending 781 // Check whether the scan codes have finished sending
678 return *pending_bytes == 0 ? 1 : 0; 782 return *pending_bytes == 0 ? 1 : 0;
679 } 783 }
680 784
681 uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) 785 uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
682 { 786 {
683 dbug_print("Animation"); 787 dbug_print("Animation");
684 return 1; 788 return 1;
685 } 789 }
686 790
728 // Rx Status Variables 832 // Rx Status Variables
729 uart0_rx_status = UARTStatus_Wait; 833 uart0_rx_status = UARTStatus_Wait;
730 uart1_rx_status = UARTStatus_Wait; 834 uart1_rx_status = UARTStatus_Wait;
731 uart0_rx_bytes_waiting = 0; 835 uart0_rx_bytes_waiting = 0;
732 uart1_rx_bytes_waiting = 0; 836 uart1_rx_bytes_waiting = 0;
837 uart0_lock = 0;
838 uart1_lock = 0;
733 839
734 // Tx Status Variables 840 // Tx Status Variables
735 uart0_tx_status = UARTStatus_Ready; 841 uart0_tx_status = UARTStatus_Ready;
736 uart1_tx_status = UARTStatus_Ready; 842 uart1_tx_status = UARTStatus_Ready;
737 843
788 // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT 894 // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT
789 UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; 895 UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
790 UART1_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; 896 UART1_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
791 897
792 // Number of bytes in FIFO before TX Interrupt 898 // Number of bytes in FIFO before TX Interrupt
793 // TODO Set 0
794 UART0_TWFIFO = 1; 899 UART0_TWFIFO = 1;
795 UART1_TWFIFO = 1; 900 UART1_TWFIFO = 1;
796 901
797 // Number of bytes in FIFO before RX Interrupt 902 // Number of bytes in FIFO before RX Interrupt
798 UART0_RWFIFO = 1; 903 UART0_RWFIFO = 1;
836 // - SyncEvent is also blocking until sent 941 // - SyncEvent is also blocking until sent
837 void Connect_scan() 942 void Connect_scan()
838 { 943 {
839 // Check if initially configured as a slave and usb comes up 944 // Check if initially configured as a slave and usb comes up
840 // Then reconfigure as a master 945 // Then reconfigure as a master
841 if ( !Connect_master && Output_Available ) 946 if ( !Connect_master && Output_Available && !Connect_override )
842 { 947 {
843 Connect_setup( Output_Available ); 948 Connect_setup( Output_Available );
844 } 949 }
845 950
846 // Limit how often we do cable checks 951 // Limit how often we do cable checks
930 break; 1035 break;
931 1036
932 default: 1037 default:
933 break; 1038 break;
934 } 1039 }
1040 }
1041
1042 void cliFunc_connectDbg( char* args )
1043 {
1044 print( NL );
1045 info_msg("Connect Debug Mode Toggle");
1046 Connect_debug = !Connect_debug;
935 } 1047 }
936 1048
937 void cliFunc_connectIdl( char* args ) 1049 void cliFunc_connectIdl( char* args )
938 { 1050 {
939 // Parse number from argument 1051 // Parse number from argument
986 char* arg2Ptr; 1098 char* arg2Ptr;
987 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); 1099 CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
988 1100
989 print( NL ); 1101 print( NL );
990 1102
1103 // Set override
1104 Connect_override = 1;
1105
991 switch ( arg1Ptr[0] ) 1106 switch ( arg1Ptr[0] )
992 { 1107 {
1108 // Disable override
1109 case 'd':
1110 case 'D':
1111 Connect_override = 0;
993 case 's': 1112 case 's':
994 case 'S': 1113 case 'S':
995 info_msg("Setting device as slave."); 1114 info_msg("Setting device as slave.");
996 Connect_master = 0; 1115 Connect_master = 0;
997 Connect_id = 0xFF; 1116 Connect_id = 0xFF;
1023 info_msg("UARTConnect Status"); 1142 info_msg("UARTConnect Status");
1024 print( NL "Device Type:\t" ); 1143 print( NL "Device Type:\t" );
1025 print( Connect_master ? "Master" : "Slave" ); 1144 print( Connect_master ? "Master" : "Slave" );
1026 print( NL "Device Id:\t" ); 1145 print( NL "Device Id:\t" );
1027 printHex( Connect_id ); 1146 printHex( Connect_id );
1147 print( NL "Max Id:\t" );
1148 printHex( Connect_maxId );
1028 print( NL "Master <=" NL "\tStatus:\t"); 1149 print( NL "Master <=" NL "\tStatus:\t");
1029 printHex( Connect_cableOkMaster ); 1150 printHex( Connect_cableOkMaster );
1030 print( NL "\tFaults:\t"); 1151 print( NL "\tFaults:\t");
1031 printHex( Connect_cableFaultsMaster ); 1152 printHex32( Connect_cableFaultsMaster );
1153 print("/");
1154 printHex32( Connect_cableChecksMaster );
1032 print( NL "\tRx:\t"); 1155 print( NL "\tRx:\t");
1033 printHex( uart1_rx_status ); 1156 printHex( uart1_rx_status );
1034 print( NL "\tTx:\t"); 1157 print( NL "\tTx:\t");
1035 printHex( uart1_tx_status ); 1158 printHex( uart1_tx_status );
1036 print( NL "Slave <=" NL "\tStatus:\t"); 1159 print( NL "Slave <=" NL "\tStatus:\t");
1037 printHex( Connect_cableOkSlave ); 1160 printHex( Connect_cableOkSlave );
1038 print( NL "\tFaults:\t"); 1161 print( NL "\tFaults:\t");
1039 printHex( Connect_cableFaultsSlave ); 1162 printHex32( Connect_cableFaultsSlave );
1163 print("/");
1164 printHex32( Connect_cableChecksSlave );
1040 print( NL "\tRx:\t"); 1165 print( NL "\tRx:\t");
1041 printHex( uart0_rx_status ); 1166 printHex( uart0_rx_status );
1042 print( NL "\tTx:\t"); 1167 print( NL "\tTx:\t");
1043 printHex( uart0_tx_status ); 1168 printHex( uart0_tx_status );
1044 } 1169 }