void cliFunc_kbdProtocol( char* args ) { print( NL ); // Parse number from argument // NOTE: Only first argument is used char* arg1Ptr; char* arg2Ptr; CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); if ( arg1Ptr[0] != '\0' ) { uint8_t mode = (uint8_t)numToInt( arg1Ptr ); // Do nothing if the argument was wrong if ( mode == 0 || mode == 1 ) { USBKeys_Protocol = mode; info_msg("Setting Keyboard Protocol to: "); printInt8( USBKeys_Protocol ); } } else { info_msg("Keyboard Protocol: "); printInt8( USBKeys_Protocol ); } }
void LED_printConfig() { print(" \033[35mBrightness\033[0m "); printInt8(settings.brightness); print( NL ); print(" \033[35mFramerate (ms/f)\033[0m "); printInt8(settings.framerate); print( NL ); }
int main() { char buf[CHUNK]; char* bootloaderSecondStageName = "BOOT2.SYS;1"; readSector(buf, 0x10); //0x10 sector Primary Volume Descriptor, 0x11 Boot Record #if IS_DEBUG == 1 printInt8((char*)buf); printString(((char*)buf) + 1, 5); #endif int rootDirExtendLBA = *((int32_t*)(buf + 156 + 2)); int rootDirExtendSize = *((int32_t*)(buf + 156 + 10)); PRINTF("rootDirExtendLBA=%d rootDirExtendSize=%d\n", rootDirExtendLBA, rootDirExtendSize); //-------------- EXTEND of ROOT dir ---------------------------- readSector(buf, rootDirExtendLBA); #if IS_DEBUG == 1 printInt8(buf); #endif int i = 0; int locationOfExtendLBA; int sizeOfExtendLBA; while (i < rootDirExtendSize) { int dirRecordLength = buf[i]; if (dirRecordLength ==0 ) break; PRINTF("-------------------------------------------------------------------------------\n"); PRINTF("dirRecordLength=%d\n", dirRecordLength); int fileNameLength = buf[i + 32]; #if IS_DEBUG == 1 printString(buf + i + 33, fileNameLength); #endif locationOfExtendLBA = *((int32_t*)(buf + i + 2)); sizeOfExtendLBA = *((int32_t*)(buf + i + 10)); PRINTF("locationOfExtendLBA=%d sizeOfExtendLBA=%d\n", locationOfExtendLBA, sizeOfExtendLBA); if (strcmp(bootloaderSecondStageName, buf + i + 33)) { break; } i += dirRecordLength; } FILE *f = fopen("BOOT2.SYS", "wb"); if (f == NULL) { PRINTF("Error opening file!\n"); exit(1); } i = 0; while (i < sizeOfExtendLBA) { readSector(buf, i); if (sizeOfExtendLBA - i < CHUNK) { fwrite (buf , sizeof(char), sizeOfExtendLBA - i, f); } else { fwrite (buf , sizeof(char), sizeof(buf), f); } i += CHUNK; } fclose(f); }
// Shows a TriggerEvent void Macro_showTriggerEvent( TriggerEvent *event ) { // Decode type Macro_showTriggerType( event->type ); print(" "); // Show state Macro_showScheduleType( event->state ); print(" "); // Show index number printInt8( event->type ); print(":"); printInt8( event->index ); }
void cliFunc_voteDebug( char* args ) { // Parse number from argument // NOTE: Only first argument is used char* arg1Ptr; char* arg2Ptr; CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); // Set the vote debug flag depending on the argument switch ( arg1Ptr[0] ) { // No argument case 1: case '\0': voteDebugMode = voteDebugMode != 1 ? 1 : 0; break; // Invalid argument default: return; } print( NL ); info_msg("Vote Debug Mode: "); printInt8( voteDebugMode ); }
void cliFunc_connectLst( char* args ) { const char *Command_strs[] = { "CableCheck", "IdRequest", "IdEnumeration", "IdReport", "ScanCode", "Animation", "RemoteCapability", "RemoteOutput", "RemoteInput", "CurrentEvent", }; print( NL ); info_msg("List of UARTConnect commands"); for ( uint8_t cmd = 0; cmd < Command_TOP; cmd++ ) { print( NL ); printInt8( cmd ); print(" - "); dPrint( (char*)Command_strs[ cmd ] ); } }
void cliFunc_storage( char* args ) { print( NL ); print("Page: "); printHex( storage_page_position() ); print(", Block: "); printHex( storage_block_position() ); print( NL ); print("Address: "); printHex32((STORAGE_FLASH_START + storage_page_position() * STORAGE_FLASH_PAGE_SIZE) + (storage_block_position() * (STORAGE_SIZE + 1)) ); print( NL ); print("Cleared?: "); printInt8( storage_is_storage_cleared() ); print( NL ); for (uint8_t i=0; i<module_count; i++) { print( NL "\033[1;32m" ); print(storage_modules[i]->name); print(" Storage\033[0m" NL ); storage_modules[i]->display(); } }
void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart ) { // Too big to fit into buffer if ( count > UART_Buffer_Size ) { erro_msg("Too big of a command to fit into the buffer..."); return; } // Invalid UART if ( uart >= UART_Num_Interfaces ) { erro_print("Invalid UART to send from..."); return; } // Delay UART copy until there's some space left while ( uart_tx_buf[ uart ].items + count > UART_Buffer_Size ) { warn_msg("Too much data to send on UART"); printInt8( uart ); print( ", waiting..." NL ); delay_ms( 1 ); // FIXME Buffer will not drain here.... } // Append data to ring buffer for ( uint8_t c = 0; c < count; c++ ) { if ( Connect_debug ) { printHex( buffer[ c ] ); print(" +"); printInt8( uart ); print( NL ); } uart_tx_buf[ uart ].buffer[ uart_tx_buf[ uart ].tail++ ] = buffer[ c ]; uart_tx_buf[ uart ].items++; if ( uart_tx_buf[ uart ].tail >= UART_Buffer_Size ) uart_tx_buf[ uart ].tail = 0; if ( uart_tx_buf[ uart ].head == uart_tx_buf[ uart ].tail ) uart_tx_buf[ uart ].head++; if ( uart_tx_buf[ uart ].head >= UART_Buffer_Size ) uart_tx_buf[ uart ].head = 0; } }
void cliFunc_capDebug( char* args ) { // Toggle layer debug mode capDebugMode = capDebugMode ? 0 : 1; print( NL ); info_msg("Capability Debug Mode: "); printInt8( capDebugMode ); }
void cliFunc_layerDebug( char *args ) { // Toggle layer debug mode layerDebugMode = layerDebugMode ? 0 : 1; print( NL ); info_msg("Layer Debug Mode: "); printInt8( layerDebugMode ); }
void cliFunc_macroProc( char* args ) { // Toggle macro pause mode macroPauseMode = macroPauseMode ? 0 : 1; print( NL ); info_msg("Macro Processing Mode: "); printInt8( macroPauseMode ); }
void cliFunc_layerState( char* args ) { // Parse codes from arguments char* curArgs; char* arg1Ptr; char* arg2Ptr = args; uint8_t arg1 = 0; uint8_t arg2 = 0; // Process first two args for ( uint8_t c = 0; c < 2; c++ ) { curArgs = arg2Ptr; CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); // Stop processing args if no more are found if ( *arg1Ptr == '\0' ) break; switch ( c ) { // First argument (e.g. L1) case 0: if ( arg1Ptr[0] != 'L' ) return; arg1 = (uint8_t)numToInt( &arg1Ptr[1] ); break; // Second argument (e.g. 4) case 1: arg2 = (uint8_t)numToInt( arg1Ptr ); // Display operation (to indicate that it worked) print( NL ); info_msg("Setting Layer L"); printInt8( arg1 ); print(" to - "); printHex( arg2 ); // Set the layer state LayerState[ arg1 ] = arg2; break; } } }
// Shows a ScheduleParam void Macro_showScheduleParam( ScheduleParam *param, uint8_t analog ) { // Analog if ( analog ) { printInt8( param->analog ); } // Everything else else { Macro_showScheduleType( param->state ); } // Time print(":"); printInt32( param->time.ms ); print("."); printInt32( param->time.ticks ); }
void cliFunc_idle( char* args ) { print( NL ); // Parse number from argument // NOTE: Only first argument is used char* arg1Ptr; char* arg2Ptr; CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); // Set Idle count if ( arg1Ptr[0] != '\0' ) { uint8_t idle = (uint8_t)numToInt( arg1Ptr ); USBKeys_Idle_Config = idle; } // Show Idle count info_msg("USB Idle Config: "); printInt16( 4 * USBKeys_Idle_Config ); print(" ms - "); printInt8( USBKeys_Idle_Config ); }
void cliFunc_macroDebug( char* args ) { // Parse number from argument // NOTE: Only first argument is used char* arg1Ptr; char* arg2Ptr; CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); // Set the macro debug flag depending on the argument switch ( arg1Ptr[0] ) { // 3 as argument case '3': macroDebugMode = macroDebugMode != 3 ? 3 : 0; break; // 2 as argument case '2': macroDebugMode = macroDebugMode != 2 ? 2 : 0; break; // No argument case '1': case '\0': macroDebugMode = macroDebugMode != 1 ? 1 : 0; break; // Invalid argument default: return; } print( NL ); info_msg("Macro Debug Mode: "); printInt8( macroDebugMode ); }
void LED_printConfig() { print(" \033[35mBrightness\033[0m "); printInt8(settings.brightness); print( NL ); }
// Macro Processing Loop, called from the periodic execution thread // Called once per USB buffer send void Macro_periodic() { // Latency measurement Latency_start_time( macroLatencyResource ); #if defined(ConnectEnabled_define) // Only compile in if a Connect node module is available // If this is a interconnect slave node, send all scancodes to master node if ( !Connect_master ) { if ( macroTriggerEventBufferSize > 0 ) { Connect_send_ScanCode( Connect_id, macroTriggerEventBuffer, macroTriggerEventBufferSize ); macroTriggerEventBufferSize = 0; } return; } #endif #if defined(ConnectEnabled_define) || defined(PressReleaseCache_define) #if defined(ConnectEnabled_define) // Check if there are any ScanCodes in the interconnect cache to process if ( Connect_master && macroInterconnectCacheSize > 0 ) #endif { // 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 macroTriggerEventBuffer[ macroTriggerEventBufferSize++ ] = macroInterconnectCache[ c ]; // TODO Handle other TriggerGuide types (e.g. analog) switch ( macroInterconnectCache[ c ].type ) { // Normal (Press/Hold/Release) case TriggerType_Switch1: case TriggerType_Switch2: case TriggerType_Switch3: case TriggerType_Switch4: case TriggerType_LED1: // Decide what to do based on the current state switch ( macroInterconnectCache[ c ].state ) { // Re-add to interconnect cache in hold state case ScheduleType_P: // Press //case ScheduleType_H: // Hold // XXX Why does this not work? -HaaTa macroInterconnectCache[ c ].state = ScheduleType_H; macroInterconnectCache[ macroInterconnectCacheSize++ ] = macroInterconnectCache[ c ]; break; case ScheduleType_R: // Release break; // Otherwise, do not re-add default: break; } break; // Not implemented default: erro_msg("Interconnect Trigger Event Type - Not Implemented "); printInt8( macroInterconnectCache[ c ].type ); print( NL ); break; } } } #endif // Macro incoming state debug switch ( macroDebugMode ) { case 1: case 2: // Iterate over incoming triggers for ( uint16_t trigger = 0; trigger < macroTriggerEventBufferSize; trigger++ ) { // Show debug info about incoming trigger Macro_showTriggerEvent( ¯oTriggerEventBuffer[trigger] ); print( NL ); } case 3: default: break; } // Check macroTriggerEventBufferSize to make sure no overflow if ( macroTriggerEventBufferSize >= MaxScanCode_KLL ) { // No scancodes defined if ( MaxScanCode_KLL == 0 ) { warn_print("No scancodes defined! Check your BaseMap!"); } // Bug! else { erro_msg("Macro Trigger Event Overflow! Serious Bug! "); printInt16( macroTriggerEventBufferSize ); print( NL ); macroTriggerEventBufferSize = 0; } } // If the pause flag is set, only process if the step counter is non-zero if ( macroPauseMode ) { if ( macroStepCounter == 0 ) return; // Proceed, decrementing the step counter macroStepCounter--; dbug_print("Macro Step"); } // Process Trigger Macros Trigger_process(); // Store events processed var_uint_t macroTriggerEventBufferSize_processed = macroTriggerEventBufferSize; // Reset TriggerList buffer macroTriggerEventBufferSize = 0; // Process result macros Result_process(); // Signal buffer that we've used it Scan_finishedWithMacro( macroTriggerEventBufferSize_processed ); #if defined(_host_) // Signal host to read layer state Output_callback( "layerState", "" ); #endif // Latency measurement Latency_end_time( macroLatencyResource ); // If Macro debug mode is set, clear the USB Buffer #if defined(Output_USBEnabled_define) if ( macroDebugMode == 1 || macroDebugMode == 3 ) { USBKeys_primary.changed = 0; } #endif }
void Trigger_process() { // Update pending trigger list, before processing TriggerMacros Trigger_updateTriggerMacroPendingList(); // Tail pointer for macroTriggerMacroPendingList // Macros must be explicitly re-added var_uint_t macroTriggerMacroPendingListTail = 0; // Display trigger information before processing if ( triggerPendingDebugMode ) { print("\033[1;30mTPe\033[0m"); for ( var_uint_t macro = 0; macro < macroTriggerMacroPendingListSize; macro++ ) { print(" "); printInt8( macroTriggerMacroPendingList[ macro ] ); } print(NL); } // Iterate through the pending TriggerMacros, processing each of them for ( var_uint_t macro = 0; macro < macroTriggerMacroPendingListSize; macro++ ) { index_uint_t cur_macro = macroTriggerMacroPendingList[ macro ]; switch ( Trigger_evalTriggerMacro( cur_macro ) ) { // Trigger Result Macro (purposely falling through) case TriggerMacroEval_DoResult: if ( voteDebugMode ) { print(" DR"); } // Append ResultMacro to PendingList Result_appendResultMacroToPendingList( &TriggerMacroList[ cur_macro ] ); default: if ( voteDebugMode ) { print(" _" NL); } macroTriggerMacroPendingList[ macroTriggerMacroPendingListTail++ ] = cur_macro; break; // Trigger Result Macro and Remove (purposely falling through) case TriggerMacroEval_DoResultAndRemove: if ( voteDebugMode ) { print(" DRaR"); } // Append ResultMacro to PendingList Result_appendResultMacroToPendingList( &TriggerMacroList[ cur_macro ] ); // Remove Macro from Pending List, nothing to do, removing by default case TriggerMacroEval_Remove: if ( voteDebugMode ) { print(" R" NL); } break; } } // Update the macroTriggerMacroPendingListSize with the tail pointer macroTriggerMacroPendingListSize = macroTriggerMacroPendingListTail; }
int32_t i2c_send_sequence( uint8_t ch, uint16_t *sequence, uint32_t sequence_length, uint8_t *received_data, void ( *callback_fn )( void* ), void *user_data ) { int32_t result = 0; volatile I2C_Channel *channel = &( i2c_channels[ch - ISSI_I2C_FirstBus_define] ); uint8_t address; #if defined(_kinetis_) uint8_t status; volatile uint8_t *I2C_C1 = (uint8_t*)(&I2C0_C1) + i2c_offset[ch]; volatile uint8_t *I2C_S = (uint8_t*)(&I2C0_S) + i2c_offset[ch]; volatile uint8_t *I2C_D = (uint8_t*)(&I2C0_D) + i2c_offset[ch]; #elif defined(_sam_) Twi *twi_dev = twi_devs[ch]; #endif if ( channel->status == I2C_BUSY ) { return -1; } // Check if there are back-to-back errors // in succession if ( channel->last_error > 5 ) { warn_msg("I2C Bus Error: "); printInt8( ch ); print(" errors: "); printInt32( channel->error_count ); print( NL ); } // 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 #if defined(_kinetis_) // Acknowledge the interrupt request, just in case *I2C_S |= I2C_S_IICIF; *I2C_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE ); // Generate a start condition and prepare for transmitting. *I2C_C1 |= ( I2C_C1_MST | I2C_C1_TX ); status = *I2C_S; if ( status & I2C_S_ARBL ) { warn_print("Arbitration lost"); result = -1; goto i2c_send_sequence_cleanup; } // Write the first (address) byte. address = *channel->sequence++; *I2C_D = address; // Everything is OK. return result; i2c_send_sequence_cleanup: // Record error, and reset last error counter channel->error_count++; channel->last_error++; // Generate STOP and disable further interrupts. *I2C_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX ); channel->status = I2C_ERROR; #elif defined(_sam_) // Convert 8 bit address to 7bit + RW address = *channel->sequence++; //print("Address: "); //printHex( address ); //print( NL ); uint8_t mread = address & 1; address >>= 1; // Set slave address twi_dev->TWI_MMR = TWI_MMR_DADR(address) | (mread ? TWI_MMR_MREAD : 0); // Enable interrupts twi_dev->TWI_IER = TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_ARBLST; //twi_dev->TWI_IDR = 0xFFFFFFFF; // Generate a start condition twi_dev->TWI_CR |= TWI_CR_START; // Fire off the first read or write. // The first (address) byte is automatically trasmitted before any data // Arbitration errors will be handled in the isr i2c_isr(ch); // Everything is OK. return result; #endif return result; }
void cliFunc_capSelect( char* args ) { // Parse code from argument char* curArgs; char* arg1Ptr; char* arg2Ptr = args; // Total number of args to scan (must do a lookup if a keyboard capability is selected) var_uint_t totalArgs = 2; // Always at least two args var_uint_t cap = 0; // Arguments used for keyboard capability function var_uint_t argSetCount = 0; uint8_t *argSet = (uint8_t*)args; // Process all args for ( var_uint_t c = 0; argSetCount < totalArgs; c++ ) { curArgs = arg2Ptr; CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); // Stop processing args if no more are found // Extra arguments are ignored if ( *arg1Ptr == '\0' ) break; // For the first argument, choose the capability if ( c == 0 ) switch ( arg1Ptr[0] ) { // Keyboard Capability case 'K': // Determine capability index cap = numToInt( &arg1Ptr[1] ); // Lookup the number of args totalArgs += CapabilitiesList[ cap ].argCount; continue; } // Because allocating memory isn't doable, and the argument count is arbitrary // The argument pointer is repurposed as the argument list (much smaller anyways) argSet[ argSetCount++ ] = (uint8_t)numToInt( arg1Ptr ); // Once all the arguments are prepared, call the keyboard capability function if ( argSetCount == totalArgs ) { // Indicate that the capability was called print( NL ); info_msg("K"); printInt8( cap ); print(" - "); printHex( argSet[0] ); print(" - "); printHex( argSet[1] ); print(" - "); printHex( argSet[2] ); print( "..." NL ); // Make sure this isn't the reload capability // If it is, and the remote reflash define is not set, ignore if ( flashModeEnabled_define == 0 ) for ( uint32_t cap = 0; cap < CapabilitiesNum; cap++ ) { if ( CapabilitiesList[ cap ].func == (const void*)Output_flashMode_capability ) { print( NL ); warn_print("flashModeEnabled not set, cancelling firmware reload..."); info_msg("Set flashModeEnabled to 1 in your kll configuration."); return; } } void (*capability)(TriggerMacro*, uint8_t, uint8_t, uint8_t*) = \ (void(*)(TriggerMacro*, uint8_t, uint8_t, uint8_t*))(CapabilitiesList[ cap ].func); capability( 0, argSet[0], argSet[1], &argSet[2] ); } } }
void cliFunc_readLEDs( char* args ) { print( NL ); info_msg("LED State: "); printInt8( USBKeys_LEDs ); }
// Shows a ScheduleType void Macro_showScheduleType( ScheduleState state ) { // State types switch ( state & 0x0F ) { case ScheduleType_P: //case ScheduleType_A: print("\033[1;33mP\033[0m"); break; case ScheduleType_H: //case ScheduleType_On: print("\033[1;32mH\033[0m"); break; case ScheduleType_R: //case ScheduleType_D: print("\033[1;35mR\033[0m"); break; case ScheduleType_O: //case ScheduleType_Off: print("\033[1mO\033[0m"); break; case ScheduleType_UP: print("UP"); break; case ScheduleType_UR: print("UR"); break; case ScheduleType_Done: print("Done"); break; case ScheduleType_Repeat: print("Repeat"); break; case ScheduleType_Debug: print("Debug"); break; default: print("\033[1;31mINVALID\033[0m"); printInt8( state & 0x0F ); break; } // Check for Shift/Latch/Lock type switch ( state & 0xF0 ) { case ScheduleType_Shift: print("Sh"); break; case ScheduleType_Latch: print("La"); break; case ScheduleType_Lock: print("Lo"); break; default: break; } }
void cliFunc_kbdProtocol( char* args ) { print( NL ); info_msg("Keyboard Protocol: "); printInt8( USBKeys_Protocol ); }