From 98f796d4df16c5aa14d0d07a5250c589dfb5f13a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 19 Jun 2015 01:50:56 -0700 Subject: [PATCH 01/79] Adding timing based debounce code - Uses expiry timer to decide on when to allow a state change - Initial state transitions are unaffected - Use MinDebounceTime define in kll to configure - ms granularity --- Scan/MatrixARM/capabilities.kll | 7 ++++++ Scan/MatrixARM/matrix_scan.c | 41 +++++++++++++++++++++++++++++---- Scan/MatrixARM/matrix_scan.h | 13 ++++++++--- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Scan/MatrixARM/capabilities.kll b/Scan/MatrixARM/capabilities.kll index 8221ec8..fe0192d 100644 --- a/Scan/MatrixARM/capabilities.kll +++ b/Scan/MatrixARM/capabilities.kll @@ -32,3 +32,10 @@ DebounceThrottleDiv => DebounceThrottleDiv_define; DebounceThrottleDiv = 0; # Default #DebounceThrottleDiv = 2; # /4 divider +# This defines the minimum amount of time after a transition until allowing another transition +# Generally switches require a minimum 5 ms debounce period +# Since a decision can usually be made quite quickly, there is little latency on each press +# However, this defines the latency at which the switch state can change +MinDebounceTime => MinDebounceTime_define; +MinDebounceTime = 5; # 5 ms + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 85f8205..a48e287 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -82,6 +82,9 @@ uint16_t matrixMaxScans = 0; uint16_t matrixCurScans = 0; uint16_t matrixPrevScans = 0; +// System Timer used for delaying debounce decisions +extern volatile uint32_t systick_millis_count; + // ----- Functions ----- @@ -197,10 +200,11 @@ void Matrix_setup() // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) { - Matrix_scanArray[ item ].prevState = KeyState_Off; - Matrix_scanArray[ item ].curState = KeyState_Off; - Matrix_scanArray[ item ].activeCount = 0; - Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state + Matrix_scanArray[ item ].prevState = KeyState_Off; + Matrix_scanArray[ item ].curState = KeyState_Off; + Matrix_scanArray[ item ].activeCount = 0; + Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state + Matrix_scanArray[ item ].prevDecisionTime = 0; } // Clear scan stats counters @@ -262,6 +266,9 @@ void Matrix_scan( uint16_t scanNum ) matrixCurScans++; } + // Read systick for event scheduling + uint8_t currentTime = (uint8_t)systick_millis_count; + // For each strobe, scan each of the sense pins for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ ) { @@ -305,11 +312,16 @@ void Matrix_scan( uint16_t scanNum ) } // Check for state change if it hasn't been set + // But only if enough time has passed since last state change // Only check if the minimum number of scans has been met // the current state is invalid // and either active or inactive count is over the debounce threshold if ( state->curState == KeyState_Invalid ) { + // Determine time since last decision + uint8_t lastTransition = currentTime - state->prevDecisionTime; + + // Attempt state transition switch ( state->prevState ) { case KeyState_Press: @@ -320,6 +332,15 @@ void Matrix_scan( uint16_t scanNum ) } else { + // If not enough time has passed since Hold + // Keep previous state + if ( lastTransition < MinDebounceTime_define ) + { + //warn_print("FAST Release stopped"); + state->curState = state->prevState; + continue; + } + state->curState = KeyState_Release; } break; @@ -328,6 +349,15 @@ void Matrix_scan( uint16_t scanNum ) case KeyState_Off: if ( state->activeCount > state->inactiveCount ) { + // If not enough time has passed since Hold + // Keep previous state + if ( lastTransition < MinDebounceTime_define ) + { + //warn_print("FAST Press stopped"); + state->curState = state->prevState; + continue; + } + state->curState = KeyState_Press; } else @@ -342,6 +372,9 @@ void Matrix_scan( uint16_t scanNum ) break; } + // Update decision time + state->prevDecisionTime = currentTime; + // Send keystate to macro module Macro_keyState( key, state->curState ); diff --git a/Scan/MatrixARM/matrix_scan.h b/Scan/MatrixARM/matrix_scan.h index 06ae75f..810e6d9 100644 --- a/Scan/MatrixARM/matrix_scan.h +++ b/Scan/MatrixARM/matrix_scan.h @@ -40,6 +40,12 @@ #error "Debounce threshold is too high... 32 bit max. Check .kll defines." #endif +#if ( MinDebounceTime_define > 0xFF ) +#error "MinDebounceTime is a maximum of 255 ms" +#elif ( MinDebounceTime_define < 0x00 ) +#error "MinDebounceTime is a minimum 0 ms" +#endif + // ----- Enums ----- @@ -126,11 +132,12 @@ typedef struct GPIO_Pin { // Debounce Element typedef struct KeyState { - KeyPosition prevState; - KeyPosition curState; DebounceCounter activeCount; DebounceCounter inactiveCount; -} KeyState; + KeyPosition prevState; + KeyPosition curState; + uint8_t prevDecisionTime; +} __attribute__((packed)) KeyState; From 99098fb2d6614f0c3538f67d61ff13251a04c741 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 19 Jun 2015 20:14:37 -0700 Subject: [PATCH 02/79] Adding layerDebug cli command - Useful when trying to report layer stacking bugs - Or at least getting unconfused about what's happening with the layers --- Macro/PartialMap/macro.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 1bb68ac..76d830e 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -41,6 +41,7 @@ void cliFunc_capSelect ( char* args ); void cliFunc_keyHold ( char* args ); void cliFunc_keyPress ( char* args ); void cliFunc_keyRelease( char* args ); +void cliFunc_layerDebug( char* args ); void cliFunc_layerList ( char* args ); void cliFunc_layerState( char* args ); void cliFunc_macroDebug( char* args ); @@ -86,6 +87,7 @@ CLIDict_Entry( capSelect, "Triggers the specified capabilities. First two args CLIDict_Entry( keyHold, "Send key-hold events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); CLIDict_Entry( keyPress, "Send key-press events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); CLIDict_Entry( keyRelease, "Send key-release event to macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); +CLIDict_Entry( layerDebug, "Layer debug mode. Shows layer stack and any changes." ); CLIDict_Entry( layerList, "List available layers." ); CLIDict_Entry( layerState, "Modify specified indexed layer state ." NL "\t\t\033[35mL2\033[0m Indexed Layer 0x02" NL "\t\t0 Off, 1 Shift, 2 Latch, 4 Lock States" ); CLIDict_Entry( macroDebug, "Disables/Enables sending USB keycodes to the Output Module and prints U/K codes." ); @@ -100,6 +102,7 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = { CLIDict_Item( keyHold ), CLIDict_Item( keyPress ), CLIDict_Item( keyRelease ), + CLIDict_Item( layerDebug ), CLIDict_Item( layerList ), CLIDict_Item( layerState ), CLIDict_Item( macroDebug ), @@ -111,6 +114,9 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = { }; +// Layer debug flag - If set, displays any changes to layers and the full layer stack on change +uint8_t layerDebugMode = 0; + // Macro debug flag - If set, clears the USB Buffers after signalling processing completion uint8_t macroDebugMode = 0; @@ -204,6 +210,30 @@ void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t // Reduce LayerIndexStack size macroLayerIndexStackSize--; } + + // Layer Debug Mode + if ( layerDebugMode ) + { + dbug_msg("Layer "); + + // Iterate over each of the layers displaying the state as a hex value + for ( uint16_t index = 0; index < LayerNum; index++ ) + { + printHex_op( LayerState[ index ], 0 ); + } + + // Always show the default layer (it's always 0) + print(" 0"); + + // Iterate over the layer stack starting from the bottom of the stack + for ( uint16_t index = 0; index < macroLayerIndexStackSize; index++ ) + { + print(":"); + printHex_op( macroLayerIndexStack[ index ], 0 ); + } + + print( NL ); + } } // Modifies the specified Layer control byte @@ -1204,6 +1234,16 @@ void cliFunc_keyRelease( char* args ) } } +void cliFunc_layerDebug( char *args ) +{ + // Toggle layer debug mode + layerDebugMode = layerDebugMode ? 0 : 1; + + print( NL ); + info_msg("Layer Debug Mode: "); + printInt8( layerDebugMode ); +} + void cliFunc_layerList( char* args ) { print( NL ); From 216b1513026e45e44794f15cfa4d02ff1c9d49f4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 23 Jun 2015 07:58:31 -0700 Subject: [PATCH 03/79] Fixing order of layer debug stack display - Adding NL's for fault messages --- Lib/mk20dx.c | 12 ++++++------ Macro/PartialMap/macro.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Lib/mk20dx.c b/Lib/mk20dx.c index 2b11943..47759a4 100644 --- a/Lib/mk20dx.c +++ b/Lib/mk20dx.c @@ -70,7 +70,7 @@ void ResetHandler(); // NVIC - Default ISR void fault_isr() { - print("Fault!"); + print("Fault!" NL ); while ( 1 ) { // keep polling some communication while in fault @@ -99,35 +99,35 @@ void systick_default_isr() // NVIC - Non-Maskable Interrupt ISR void nmi_default_isr() { - print("NMI!"); + print("NMI!" NL ); } // NVIC - Hard Fault ISR void hard_fault_default_isr() { - print("Hard Fault!"); + print("Hard Fault!" NL ); } // NVIC - Memory Manager Fault ISR void memmanage_fault_default_isr() { - print("Memory Manager Fault!"); + print("Memory Manager Fault!" NL ); } // NVIC - Bus Fault ISR void bus_fault_default_isr() { - print("Bus Fault!"); + print("Bus Fault!" NL ); } // NVIC - Usage Fault ISR void usage_fault_default_isr() { - print("Usage Fault!"); + print("Usage Fault!" NL ); } diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 76d830e..bc2d7d6 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -226,10 +226,10 @@ void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t print(" 0"); // Iterate over the layer stack starting from the bottom of the stack - for ( uint16_t index = 0; index < macroLayerIndexStackSize; index++ ) + for ( uint16_t index = macroLayerIndexStackSize; index > 0; index-- ) { print(":"); - printHex_op( macroLayerIndexStack[ index ], 0 ); + printHex_op( macroLayerIndexStack[ index - 1 ], 0 ); } print( NL ); From 6c67bc77bc0c42ae8a67d6bbe6abce8de235de56 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 23 Jun 2015 08:00:16 -0700 Subject: [PATCH 04/79] Revert "Merge pull request #27 from smasher816/wakeup-devel" This reverts commit 622ea5d85f94be4b1694fdf08e30fa76eeb18fe4, reversing changes made to c21439cb48daec7514da4250c41962205fa96624. --- Output/pjrcUSB/arm/usb_dev.c | 19 +------------------ Output/pjrcUSB/arm/usb_dev.h | 2 -- Output/pjrcUSB/arm/usb_keyboard.c | 7 ------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 5c12a41..f09540c 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -167,7 +167,6 @@ volatile uint8_t usb_reboot_timer = 0; static uint8_t reply_buffer[8]; -volatile uint8_t remote_wakeup_enabled = 0; // ----- Functions ----- @@ -295,8 +294,7 @@ static void usb_setup() data = reply_buffer; break; case 0x0080: // GET_STATUS (device) - //I think this is the corrent endianess - reply_buffer[0] = (remote_wakeup_enabled)<<1; + reply_buffer[0] = 0; reply_buffer[1] = 0; datalen = 2; data = reply_buffer; @@ -316,11 +314,6 @@ static void usb_setup() datalen = 2; break; case 0x0100: // CLEAR_FEATURE (device) - //Disable DEVICE_REMOTE_WAKEUP feature - if (setup.wValue == 0x01) { - remote_wakeup_enabled = 0; - } - break; case 0x0101: // CLEAR_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa endpoint0_stall(); @@ -341,11 +334,6 @@ static void usb_setup() endpoint0_stall(); return; case 0x0300: // SET_FEATURE (device) - //Enable DEVICE_REMOTE_WAKEUP feature - if (setup.wValue == 0x01) { - remote_wakeup_enabled = 1; - } - break; case 0x0301: // SET_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa endpoint0_stall(); @@ -1120,11 +1108,6 @@ restart: //serial_print("sleep\n"); USB0_ISTAT = USB_ISTAT_SLEEP; } - - if ( (status & USB_ISTAT_RESUME /* 20 */ ) ) { - //serial_print("resume\n"); - USB0_ISTAT = USB_ISTAT_RESUME; - } } diff --git a/Output/pjrcUSB/arm/usb_dev.h b/Output/pjrcUSB/arm/usb_dev.h index e4f8add..0f445de 100644 --- a/Output/pjrcUSB/arm/usb_dev.h +++ b/Output/pjrcUSB/arm/usb_dev.h @@ -55,8 +55,6 @@ extern volatile uint8_t usb_cdc_line_coding[7]; extern volatile uint8_t usb_cdc_line_rtsdtr; extern volatile uint8_t usb_cdc_transmit_flush_timer; -extern volatile uint8_t remote_wakeup_enabled; - // ----- Functions ----- diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index 8453534..d3c9632 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -78,13 +78,6 @@ void usb_keyboard_send() uint32_t wait_count = 0; usb_packet_t *tx_packet; - if (remote_wakeup_enabled) { - USB0_CTL |= USB_CTL_RESUME; - _delay_ms(5); //wait 1 to 15ms - USB0_CTL &= ~USB_CTL_RESUME; - _delay_ms(5); - } - // Wait till ready while ( 1 ) { From 55d03f448e42ea581810bef3d55eb9c017572665 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 18 Jul 2015 18:53:21 -0700 Subject: [PATCH 05/79] UARTConnect enumeration working! - Fixed cli reflash mode set - Cleaned up debugging code - 4 500 000 baud seems to be reliable - Fixed master selection (assumes slave node unless USB enumerates) --- Bootloader/main.c | 29 ------ Output/pjrcUSB/arm/usb_dev.c | 15 +-- Output/pjrcUSB/output_com.c | 36 ++++---- Output/pjrcUSB/output_com.h | 2 +- Output/usbMuxUart/output_com.c | 137 +++++++++++++++++++-------- Scan/STLcd/lcd_scan.c | 14 ++- Scan/UARTConnect/capabilities.kll | 14 ++- Scan/UARTConnect/connect_scan.c | 149 ++++++++++++++++++++++-------- Scan/UARTConnect/connect_scan.h | 2 +- 9 files changed, 261 insertions(+), 137 deletions(-) diff --git a/Bootloader/main.c b/Bootloader/main.c index 9a830dc..bca3fdf 100644 --- a/Bootloader/main.c +++ b/Bootloader/main.c @@ -210,35 +210,6 @@ void main() printHex( memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ); print( NL ); - // XXX REMOVEME - /* - GPIOB_PDDR |= (1<<16); - PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOB_PSOR |= (1<<16); - - // RST - GPIOC_PDDR |= (1<<8); - PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PSOR |= (1<<8); - - // CS1B - GPIOC_PDDR |= (1<<4); - PORTC_PCR4 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<4); - */ - // Backlight - /* - GPIOC_PDDR |= (1<<1); - PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<1); - GPIOC_PDDR |= (1<<2); - PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<2); - GPIOC_PDDR |= (1<<3); - PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<3); - */ - #ifdef FLASH_DEBUG for ( uint8_t sector = 0; sector < 3; sector++ ) sector_print( &_app_rom, sector, 16 ); diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index f09540c..1f2e725 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modifications by Jacob Alexander (2013-2014) + * Modifications by Jacob Alexander (2013-2015) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -204,6 +204,7 @@ static void usb_setup() print("CONFIGURE - "); #endif usb_configuration = setup.wValue; + Output_Available = usb_configuration; reg = &USB0_ENDPT1; cfg = usb_endpoint_config_table; // clear all BDT entries, free any allocated memory... @@ -861,6 +862,13 @@ void usb_device_reload() SOFTWARE_RESET(); } +// Kiibohd mk20dx256vlh7 +#elif defined(_mk20dx256vlh7_) + // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode + for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ ) + (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ]; + SOFTWARE_RESET(); + // Teensy 3.0 and 3.1 #else asm volatile("bkpt"); @@ -1118,11 +1126,6 @@ uint8_t usb_init() print("USB INIT"NL); #endif - // If no USB cable is attached, do not initialize usb - // XXX Test -HaaTa - //if ( USB0_OTGISTAT & USB_OTGSTAT_ID ) - // return 0; - // Clear out endpoints table for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ ) { diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 7a9b84b..dc6bfcd 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -93,20 +93,20 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { // Which modifier keys are currently pressed // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui - uint8_t USBKeys_Modifiers = 0; - uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer +uint8_t USBKeys_Modifiers = 0; +uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer // Currently pressed keys, max is defined by USB_MAX_KEY_SEND - uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS]; - uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer +uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS]; +uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer // System Control and Consumer Control 1KRO containers - uint8_t USBKeys_SysCtrl; - uint16_t USBKeys_ConsCtrl; +uint8_t USBKeys_SysCtrl; +uint16_t USBKeys_ConsCtrl; // The number of keys sent to the usb in the array - uint8_t USBKeys_Sent = 0; - uint8_t USBKeys_SentCLI = 0; +uint8_t USBKeys_Sent = 0; +uint8_t USBKeys_SentCLI = 0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t USBKeys_LEDs = 0; @@ -122,20 +122,20 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed - uint8_t USBKeys_Idle_Config = 125; +uint8_t USBKeys_Idle_Config = 125; // count until idle timeout - uint8_t USBKeys_Idle_Count = 0; +uint8_t USBKeys_Idle_Count = 0; // Indicates whether the Output module is fully functional // 0 - Not fully functional, 1 - Fully functional // 0 is often used to show that a USB cable is not plugged in (but has power) - uint8_t Output_Available = 0; +volatile uint8_t Output_Available = 0; // Debug control variable for Output modules // 0 - Debug disabled (default) // 1 - Debug enabled - uint8_t Output_DebugMode = 0; +uint8_t Output_DebugMode = 0; @@ -505,13 +505,11 @@ void Output_flushBuffers() // USB Module Setup inline void Output_setup() { - // Initialize the USB, and then wait for the host to set configuration. - // This will hang forever if USB does not initialize - // If no USB cable is attached, does not try and initialize USB - if ( usb_init() ) - { - while ( !usb_configured() ); - } + // Initialize the USB + // If a USB connection does not exist, just ignore it + // All usb related functions will non-fatally fail if called + // If the USB initialization is delayed, then functionality will just be delayed + usb_init(); // Register USB Output CLI dictionary CLI_registerDictionary( outputCLIDict, outputCLIDictName ); diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index f2f2f58..0462c20 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -78,7 +78,7 @@ extern uint8_t USBKeys_Idle_Count; extern USBKeyChangeState USBKeys_Changed; -extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working +extern volatile uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index a9859b4..3fa26c9 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -61,6 +61,7 @@ // ----- Function Declarations ----- void cliFunc_kbdProtocol( char* args ); +void cliFunc_outputDebug( char* args ); void cliFunc_readLEDs ( char* args ); void cliFunc_readUART ( char* args ); void cliFunc_sendKeys ( char* args ); @@ -74,6 +75,7 @@ void cliFunc_setMod ( char* args ); // Output Module command dictionary CLIDict_Entry( kbdProtocol, "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode" ); +CLIDict_Entry( outputDebug, "Toggle Output Debug mode." ); CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." ); CLIDict_Entry( readUART, "Read UART buffer until empty." ); CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." ); @@ -83,6 +85,7 @@ CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { CLIDict_Item( kbdProtocol ), + CLIDict_Item( outputDebug ), CLIDict_Item( readLEDs ), CLIDict_Item( readUART ), CLIDict_Item( sendKeys ), @@ -96,20 +99,20 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { // Which modifier keys are currently pressed // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui - uint8_t USBKeys_Modifiers = 0; - uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer +uint8_t USBKeys_Modifiers = 0; +uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer // Currently pressed keys, max is defined by USB_MAX_KEY_SEND - uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS]; - uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer +uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS]; +uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer // System Control and Consumer Control 1KRO containers - uint8_t USBKeys_SysCtrl; - uint16_t USBKeys_ConsCtrl; +uint8_t USBKeys_SysCtrl; +uint16_t USBKeys_ConsCtrl; // The number of keys sent to the usb in the array - uint8_t USBKeys_Sent = 0; - uint8_t USBKeys_SentCLI = 0; +uint8_t USBKeys_Sent = 0; +uint8_t USBKeys_SentCLI = 0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t USBKeys_LEDs = 0; @@ -117,7 +120,7 @@ volatile uint8_t USBKeys_LEDs = 0; // Protocol setting from the host. // 0 - Boot Mode // 1 - NKRO Mode (Default, unless set by a BIOS or boot interface) -volatile uint8_t USBKeys_Protocol = 0; +volatile uint8_t USBKeys_Protocol = 1; // Indicate if USB should send update // OS only needs update if there has been a change in state @@ -125,20 +128,20 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed - uint8_t USBKeys_Idle_Config = 125; +uint8_t USBKeys_Idle_Config = 125; // count until idle timeout - uint8_t USBKeys_Idle_Count = 0; +uint8_t USBKeys_Idle_Count = 0; // Indicates whether the Output module is fully functional // 0 - Not fully functional, 1 - Fully functional // 0 is often used to show that a USB cable is not plugged in (but has power) - uint8_t Output_Available = 0; +volatile uint8_t Output_Available = 0; // Debug control variable for Output modules // 0 - Debug disabled (default) // 1 - Debug enabled - uint8_t Output_DebugMode = 0; +uint8_t Output_DebugMode = 0; @@ -222,7 +225,10 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t * // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_ConsCtrl = 0; return; + } // Set consumer control code USBKeys_ConsCtrl = *(uint16_t*)(&args[0]); @@ -268,7 +274,10 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_SysCtrl = 0; return; + } // Set system control code USBKeys_SysCtrl = args[0]; @@ -317,9 +326,10 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a // Depending on which mode the keyboard is in, USBKeys_Keys array is used differently // Boot mode - Maximum of 6 byte codes // NKRO mode - Each bit of the 26 byte corresponds to a key - // Bits 0 - 160 (first 20 bytes) correspond to USB Codes 4 - 164 - // Bits 161 - 205 (last 6 bytes) correspond to USB Codes 176 - 221 - // Bits 206 - 208 (last byte) correspond to the 3 padded bits in USB (unused) + // Bits 0 - 45 (bytes 0 - 5) correspond to USB Codes 4 - 49 (Main) + // Bits 48 - 161 (bytes 6 - 20) correspond to USB Codes 51 - 164 (Secondary) + // Bits 168 - 213 (bytes 21 - 26) correspond to USB Codes 176 - 221 (Tertiary) + // Bits 214 - 216 unused uint8_t bytePosition = 0; uint8_t byteShift = 0; switch ( USBKeys_Protocol ) @@ -371,11 +381,12 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a USBKeys_Changed |= USBKeyChangeState_Modifiers; break; } - // First 20 bytes - else if ( key >= 4 && key <= 164 ) + // First 6 bytes + else if ( key >= 4 && key <= 49 ) { // Lookup (otherwise division or multiple checks are needed to do alignment) - uint8_t keyPos = key - 4; // Starting position in array + // Starting at 0th position, each byte has 8 bits, starting at 4th bit + uint8_t keyPos = key + (0 * 8 - 4); // Starting position in array, Ignoring 4 keys switch ( keyPos ) { byteLookup( 0 ); @@ -384,6 +395,18 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a byteLookup( 3 ); byteLookup( 4 ); byteLookup( 5 ); + } + + USBKeys_Changed |= USBKeyChangeState_MainKeys; + } + // Next 14 bytes + else if ( key >= 51 && key <= 155 ) + { + // Lookup (otherwise division or multiple checks are needed to do alignment) + // Starting at 6th byte position, each byte has 8 bits, starting at 51st bit + uint8_t keyPos = key + (6 * 8 - 51); // Starting position in array + switch ( keyPos ) + { byteLookup( 6 ); byteLookup( 7 ); byteLookup( 8 ); @@ -400,29 +423,52 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a byteLookup( 19 ); } - USBKeys_Changed |= USBKeyChangeState_MainKeys; + USBKeys_Changed |= USBKeyChangeState_SecondaryKeys; + } + // Next byte + else if ( key >= 157 && key <= 164 ) + { + // Lookup (otherwise division or multiple checks are needed to do alignment) + uint8_t keyPos = key + (20 * 8 - 157); // Starting position in array, Ignoring 6 keys + switch ( keyPos ) + { + byteLookup( 20 ); + } + + USBKeys_Changed |= USBKeyChangeState_TertiaryKeys; } // Last 6 bytes else if ( key >= 176 && key <= 221 ) { // Lookup (otherwise division or multiple checks are needed to do alignment) - uint8_t keyPos = key - 176; // Starting position in array + uint8_t keyPos = key + (21 * 8 - 176); // Starting position in array switch ( keyPos ) { - byteLookup( 20 ); byteLookup( 21 ); byteLookup( 22 ); byteLookup( 23 ); byteLookup( 24 ); byteLookup( 25 ); + byteLookup( 26 ); } - USBKeys_Changed |= USBKeyChangeState_SecondaryKeys; + USBKeys_Changed |= USBKeyChangeState_QuartiaryKeys; + } + // Received 0x00 + // This is a special USB Code that internally indicates a "break" + // It is used to send "nothing" in order to break up sequences of USB Codes + else if ( key == 0x00 ) + { + USBKeys_Changed |= USBKeyChangeState_MainKeys; + + // Also flush out buffers just in case + Output_flushBuffers(); + break; } // Invalid key else { - warn_msg("USB Code not within 4-164 (0x4-0xA4) or 176-221 (0xB0-0xDD) NKRO Mode: "); + warn_msg("USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: "); printHex( key ); print( NL ); break; @@ -467,20 +513,18 @@ inline void Output_setup() { // Setup UART uart_serial_setup(); - print("\033[2J"); // Clear screen - // Initialize the USB, and then wait for the host to set configuration. - // This will hang forever if USB does not initialize + // Initialize the USB + // If a USB connection does not exist, just ignore it + // All usb related functions will non-fatally fail if called + // If the USB initialization is delayed, then functionality will just be delayed usb_init(); - while ( !usb_configured() ); - // Register USB Output CLI dictionary CLI_registerDictionary( outputCLIDict, outputCLIDictName ); - // Zero out USBKeys_Keys array - for ( uint8_t c = 0; c < USB_NKRO_BITFIELD_SIZE_KEYS; c++ ) - USBKeys_Keys[ c ] = 0; + // Flush key buffers + Output_flushBuffers(); } @@ -496,14 +540,15 @@ inline void Output_send() while ( USBKeys_Changed ) usb_keyboard_send(); - // Clear modifiers and keys - USBKeys_Modifiers = 0; - USBKeys_Sent = 0; + // Clear keys sent + USBKeys_Sent = 0; // Signal Scan Module we are finished switch ( USBKeys_Protocol ) { case 0: // Boot Mode + // Clear modifiers only in boot mode + USBKeys_Modifiers = 0; Scan_finishedWithOutput( USBKeys_Sent <= USB_BOOT_MAX_KEYS ? USBKeys_Sent : USB_BOOT_MAX_KEYS ); break; case 1: // NKRO Mode @@ -514,9 +559,9 @@ inline void Output_send() // Sets the device into firmware reload mode -inline void Output_firmwareReload() +void Output_firmwareReload() { - uart_device_reload(); + usb_device_reload(); } @@ -593,6 +638,24 @@ void cliFunc_kbdProtocol( char* args ) } +void cliFunc_outputDebug( char* args ) +{ + // Parse number from argument + // NOTE: Only first argument is used + char* arg1Ptr; + char* arg2Ptr; + CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); + + // Default to 1 if no argument is given + Output_DebugMode = 1; + + if ( arg1Ptr[0] != '\0' ) + { + Output_DebugMode = (uint16_t)numToInt( arg1Ptr ); + } +} + + void cliFunc_readLEDs( char* args ) { print( NL ); diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index b5123c9..df07b5a 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -258,7 +258,6 @@ inline void LCD_setup() // Initialize SPI SPI_setup(); - // Setup Register Control Signal (A0) // Start in display register mode (1) GPIOC_PDDR |= (1<<7); @@ -274,6 +273,19 @@ inline void LCD_setup() // Run LCD intialization sequence LCD_initialize(); + + // Setup Backlight + // TODO Expose default settings + // TODO Setup PWM + GPIOC_PDDR |= (1<<1); + PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOC_PCOR |= (1<<1); + GPIOC_PDDR |= (1<<2); + PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOC_PCOR |= (1<<2); + GPIOC_PDDR |= (1<<3); + PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOC_PCOR |= (1<<3); } diff --git a/Scan/UARTConnect/capabilities.kll b/Scan/UARTConnect/capabilities.kll index a651dc2..f02c111 100644 --- a/Scan/UARTConnect/capabilities.kll +++ b/Scan/UARTConnect/capabilities.kll @@ -26,6 +26,16 @@ UARTConnectBaudFine => UARTConnectBaudFine_define; # Thus baud setting = 26 # NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet # Baud fine setting = 0x02 -UARTConnectBaud = 26; -UARTConnectBaudFine = 0x02; +UARTConnectBaud = 1; # 4.5 Mbps @ 72 MHz +UARTConnectBaudFine = 0x0; + +# Cable Check Command Length +# This defines the length of the cable command +# 0xD2 11010010 is used for each check byte +# +# For example: +# Length: 4 +# Args: 0xD2 0xD2 0xD2 0xD2 +UARTConnectCableCheckLength => UARTConnectCableCheckLength_define; +UARTConnectCableCheckLength = 2; diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 03691a3..fea798a 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -42,8 +42,11 @@ case uartNum: \ } \ for ( uint8_t c = 0; c < count; c++ ) \ { \ - printHex( buffer[ c ] ); \ - print( " +" #uartNum NL ); \ + if ( Connect_debug ) \ + { \ + 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 ) \ @@ -87,23 +90,35 @@ case uartNum: \ while ( available-- > 0 ) \ { \ uint8_t byteRead = UART##uartNum##_D; \ - printHex( byteRead ); \ - print( "(" ); \ - printInt8( available ); \ - print( ") <-" ); \ + if ( Connect_debug ) \ + { \ + printHex( byteRead ); \ + print( "(" ); \ + printInt8( available ); \ + print( ") <-" ); \ + } \ switch ( uart##uartNum##_rx_status ) \ { \ case UARTStatus_Wait: \ - print(" SYN "); \ + if ( Connect_debug ) \ + { \ + print(" SYN "); \ + } \ uart##uartNum##_rx_status = byteRead == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; \ break; \ case UARTStatus_SYN: \ - print(" SOH "); \ + if ( Connect_debug ) \ + { \ + print(" SOH "); \ + } \ uart##uartNum##_rx_status = byteRead == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; \ break; \ case UARTStatus_SOH: \ { \ - print(" CMD "); \ + if ( Connect_debug ) \ + { \ + print(" CMD "); \ + } \ uint8_t byte = byteRead; \ if ( byte <= Animation ) \ { \ @@ -122,14 +137,20 @@ case uartNum: \ uart##uartNum##_rx_status = UARTStatus_Wait; \ break; \ default: \ - print("###"); \ + if ( Connect_debug ) \ + { \ + print("###"); \ + } \ break; \ } \ break; \ } \ case UARTStatus_Command: \ { \ - print(" CMD "); \ + if ( Connect_debug ) \ + { \ + print(" CMD "); \ + } \ uint8_t (*rcvFunc)(uint8_t, uint16_t(*), uint8_t) = (uint8_t(*)(uint8_t, uint16_t(*), uint8_t))(Connect_receiveFunctions[ uart##uartNum##_rx_command ]); \ if ( rcvFunc( byteRead, (uint16_t*)&uart##uartNum##_rx_bytes_waiting, uartNum ) ) \ uart##uartNum##_rx_status = UARTStatus_Wait; \ @@ -141,7 +162,10 @@ case uartNum: \ available++; \ continue; \ } \ - print( NL ); \ + if ( Connect_debug ) \ + { \ + print( NL ); \ + } \ } \ } @@ -193,6 +217,11 @@ uint8_t Connect_id = 255; // Invalid, unset uint8_t Connect_master = 0; +// -- Control Variables -- +uint32_t Connect_lastCheck = 0; // Cable Check scheduler +uint8_t Connect_debug = 0; // Set 1 for debug + + // -- Rx Status Variables -- volatile UARTStatus uart0_rx_status; @@ -398,12 +427,16 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8 // Check if this is the first byte if ( *pending_bytes == 0xFFFF ) { - dbug_msg("PENDING SET -> "); - printHex( byte ); - print(" "); *pending_bytes = byte; - printHex( *pending_bytes ); - print( NL ); + + if ( Connect_debug ) + { + dbug_msg("PENDING SET -> "); + printHex( byte ); + print(" "); + printHex( *pending_bytes ); + print( NL ); + } } // Verify byte else @@ -448,11 +481,15 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8 Connect_cableOkSlave = 1; } } - dbug_msg("CABLECHECK RECEIVE - "); - printHex( byte ); - print(" "); - printHex( *pending_bytes ); - print(NL); + + if ( Connect_debug ) + { + dbug_msg("CABLECHECK RECEIVE - "); + printHex( byte ); + print(" "); + printHex( *pending_bytes ); + print( NL ); + } // Check whether the cable check has finished return *pending_bytes == 0 ? 1 : 0; @@ -462,7 +499,7 @@ uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_ { dbug_print("IdRequest"); // Check the directionality - if ( !to_master ) + if ( to_master ) { erro_print("Invalid IdRequest direction..."); } @@ -487,7 +524,7 @@ uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint { dbug_print("IdEnumeration"); // Check the directionality - if ( to_master ) + if ( !to_master ) { erro_print("Invalid IdEnumeration direction..."); } @@ -511,7 +548,7 @@ uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t t { dbug_print("IdReport"); // Check the directionality - if ( !to_master ) + if ( to_master ) { erro_print("Invalid IdRequest direction..."); } @@ -690,7 +727,10 @@ void Connect_setup( uint8_t master ) // Register Connect CLI dictionary CLI_registerDictionary( uartConnectCLIDict, uartConnectCLIDictName ); + // Check if master Connect_master = master; + if ( Connect_master ) + Connect_id = 0; // 0x00 is always the master Id // Master / UART0 setup // Slave / UART1 setup @@ -699,15 +739,10 @@ void Connect_setup( uint8_t master ) SIM_SCGC4 |= SIM_SCGC4_UART1; // Disable clock gating // Pin Setup for UART0 / UART1 - // XXX TODO Set to actual (Teensy 3.1s don't have the correct pins available) - PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin - PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin - PORTC_PCR3 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin - PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin - //PORTA_PCR1 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(2); // RX Pin - //PORTA_PCR2 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(2); // TX Pin - //PORTE_PCR0 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin - //PORTE_PCR1 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin + PORTA_PCR1 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(2); // RX Pin + PORTA_PCR2 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(2); // TX Pin + PORTE_PCR0 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin + PORTE_PCR1 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin // Baud Rate setting UART0_BDH = (uint8_t)(Connect_baud >> 8); @@ -771,12 +806,44 @@ void Connect_setup( uint8_t master ) // - SyncEvent is also blocking until sent void Connect_scan() { - // Check if Tx Buffers are empty and the Tx Ring buffers have data to send - // This happens if there was previously nothing to send - if ( uart0_buffer_items > 0 && UART0_TCFIFO == 0 ) - uart_fillTxFifo( 0 ); - if ( uart1_buffer_items > 0 && UART1_TCFIFO == 0 ) - uart_fillTxFifo( 1 ); + // Check if initially configured as a slave and usb comes up + // Then reconfigure as a master + if ( !Connect_master && Output_Available ) + { + Connect_setup( Output_Available ); + } + + // Limit how often we do cable checks + uint32_t time_compare = 0x7FF; // Must be all 1's, 0x3FF is valid, 0x4FF is not + uint32_t current_time = systick_millis_count; + if ( Connect_lastCheck != current_time + && ( current_time & time_compare ) == time_compare + ) + { + // Make sure we don't double check if the clock speed is too high + Connect_lastCheck = current_time; + + // Send a cable check command of 2 bytes + Connect_send_CableCheck( UARTConnectCableCheckLength_define ); + + // If this is a slave, and we don't have an id yeth + // Don't bother sending if there are cable issues + if ( !Connect_master && Connect_id == 0xFF && Connect_cableOkMaster ) + { + Connect_send_IdRequest(); + } + } + + // Only process commands if uarts have been configured + if ( uarts_configured ) + { + // Check if Tx Buffers are empty and the Tx Ring buffers have data to send + // This happens if there was previously nothing to send + if ( uart0_buffer_items > 0 && UART0_TCFIFO == 0 ) + uart_fillTxFifo( 0 ); + if ( uart1_buffer_items > 0 && UART1_TCFIFO == 0 ) + uart_fillTxFifo( 1 ); + } } @@ -796,7 +863,7 @@ void cliFunc_connectCmd( char* args ) switch ( numToInt( &arg1Ptr[0] ) ) { case CableCheck: - Connect_send_CableCheck( 2 ); + Connect_send_CableCheck( UARTConnectCableCheckLength_define ); break; case IdRequest: diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index 9ba6da1..492f4b1 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -41,7 +41,7 @@ typedef enum UARTStatus { UARTStatus_SYN = 1, // Rx: SYN Received, waiting for SOH UARTStatus_SOH = 2, // Rx: SOH Received, waiting for Command UARTStatus_Command = 3, // Rx: Command Received, waiting for data - UARTStatus_Ready = 4, // Tx: Ready to receive commands + UARTStatus_Ready = 4, // Tx: Ready to send commands } UARTStatus; From b6e2f0ebf00570e1fcae308d05763bd6f897fb92 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 25 Jul 2015 14:54:36 -0700 Subject: [PATCH 06/79] Adding connection type list --- Scan/UARTConnect/connect_scan.c | 45 +++++++++++++++++++++++++++- Scan/UARTConnect/connect_scan.h | 53 ++++++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index fea798a..dd6980e 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -188,6 +188,7 @@ case uartNum: \ // CLI Functions void cliFunc_connectCmd ( char *args ); void cliFunc_connectIdl ( char *args ); +void cliFunc_connectLst ( char *args ); void cliFunc_connectMst ( char *args ); void cliFunc_connectRst ( char *args ); void cliFunc_connectSts ( char *args ); @@ -199,12 +200,14 @@ 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( 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." ); CLIDict_Entry( connectRst, "Resets both Rx and Tx connect buffers and state variables." ); CLIDict_Entry( connectSts, "UARTConnect status." ); CLIDict_Def( uartConnectCLIDict, "UARTConnect Module Commands" ) = { CLIDict_Item( connectCmd ), CLIDict_Item( connectIdl ), + CLIDict_Item( connectLst ), CLIDict_Item( connectMst ), CLIDict_Item( connectRst ), CLIDict_Item( connectSts ), @@ -885,6 +888,20 @@ void cliFunc_connectCmd( char* args ) break; } case Animation: + break; + + case RemoteCapability: + // TODO + break; + + case RemoteOutput: + // TODO + break; + + case RemoteInput: + // TODO + break; + default: break; } @@ -909,6 +926,31 @@ void cliFunc_connectIdl( char* args ) Connect_send_Idle( count ); } +void cliFunc_connectLst( char* args ) +{ + const char *Command_strs[] = { + "CableCheck", + "IdRequest", + "IdEnumeration", + "IdReport", + "ScanCode", + "Animation", + "RemoteCapability", + "RemoteOutput", + "RemoteInput", + }; + + 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_connectMst( char* args ) { // Parse number from argument @@ -944,7 +986,8 @@ void cliFunc_connectRst( char* args ) info_msg("Resetting UARTConnect state..."); Connect_reset(); - // TODO - Argument for re-sync + // Reset node id + Connect_id = 0xFF; } void cliFunc_connectSts( char* args ) diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index 492f4b1..c2daca5 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -27,12 +27,20 @@ // Functions typedef enum Command { - CableCheck = 0, // Comm check - IdRequest = 1, // Slave initialization (request id from master) - IdEnumeration = 2, // Slave initialization (begin enumeration from master) - IdReport = 3, // Slave initialization complete, report id to master - ScanCode = 4, // ScanCode event status change - Animation = 5, // Master trigger animation event (same command is sent back to master when ready) + CableCheck, // Comm check + + IdRequest, // Slave initialization (request id from master) + IdEnumeration, // Slave initialization (begin enumeration from master) + IdReport, // Slave initialization complete, report id to master + + ScanCode, // ScanCode event status change + Animation, // Master trigger animation event (same command is sent back to master when ready) + + RemoteCapability, // Activate a capability on the given node + RemoteOutput, // Remote debug output from a given node + RemoteInput, // Remote command to send to a given node's debug cli + + Command_TOP, // Enum bounds } Command; // UART Rx/Tx Status @@ -71,7 +79,6 @@ typedef struct IdRequestCommand { // Id Enumeration Command // Issued by the master whenever an Id Request is received -// XXX Future work may include an "external capabilities" list in this command typedef struct IdEnumerationCommand { Command command; uint8_t id; @@ -79,7 +86,6 @@ typedef struct IdEnumerationCommand { // Id Report Command // Issued by each slave to the master when assigned an Id -// XXX Future work will include an "external capabilities" list in this command typedef struct IdReportCommand { Command command; uint8_t id; @@ -109,6 +115,37 @@ typedef struct AnimationCommand { uint8_t firstParam[0]; } AnimationCommand; +// Remote Capability Command +// Initiated by the master to trigger a capability on a given node +// RemoteOutput is enabled while capability is activated +typedef struct RemoteCapabilityCommand { + Command command; + uint8_t id; + Capability capability; + uint8_t numArgs; + uint8_t firstArg[0]; +} RemoteCapabilityCommand; + +// Remote Output Command +// Sends debug output to the master node +// Uses print command redirection to generate each command message +typedef struct RemoteOutputCommand { + Command command; + uint8_t id; + uint8_t length; + uint8_t firstChar[0]; +} RemoteOutputCommand; + +// Remote Input Command +// Sends debug input to given node (usually from master) +// Uses debug cli to execute command and sends all output using Remote Output Command +typedef struct RemoteInputCommand { + Command command; + uint8_t id; + uint8_t length; + uint8_t firstChar[0]; +} RemoteInputCommand; + // ----- Functions ----- From 865be6145fc111ceba1fc2103ec09147dab95c83 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 25 Jul 2015 15:06:19 -0700 Subject: [PATCH 07/79] Initial commit of MDErgo1 --- Scan/MDErgo1/defaultMap.kll | 73 ++++++++++++++++++ Scan/MDErgo1/led_conf.h | 74 ++++++++++++++++++ Scan/MDErgo1/matrix.h | 56 ++++++++++++++ Scan/MDErgo1/pinout | 144 ++++++++++++++++++++++++++++++++++++ Scan/MDErgo1/scan_loop.c | 104 ++++++++++++++++++++++++++ Scan/MDErgo1/scan_loop.h | 40 ++++++++++ Scan/MDErgo1/setup.cmake | 33 +++++++++ 7 files changed, 524 insertions(+) create mode 100644 Scan/MDErgo1/defaultMap.kll create mode 100644 Scan/MDErgo1/led_conf.h create mode 100644 Scan/MDErgo1/matrix.h create mode 100644 Scan/MDErgo1/pinout create mode 100644 Scan/MDErgo1/scan_loop.c create mode 100644 Scan/MDErgo1/scan_loop.h create mode 100644 Scan/MDErgo1/setup.cmake diff --git a/Scan/MDErgo1/defaultMap.kll b/Scan/MDErgo1/defaultMap.kll new file mode 100644 index 0000000..7ed3492 --- /dev/null +++ b/Scan/MDErgo1/defaultMap.kll @@ -0,0 +1,73 @@ +Name = MDErgo1; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2014"; +KLL = 0.3a; + +# Modified Date +Date = 2015-03-10; + + +S0x00 : U"Esc"; +S0x01 : U"1"; +S0x02 : U"2"; +S0x03 : U"3"; +S0x04 : U"4"; +S0x05 : U"5"; +S0x06 : U"6"; +S0x07 : U"7"; +S0x08 : U"8"; +S0x09 : U"9"; +S0x0A : U"0"; +S0x0B : U"Minus"; +S0x0C : U"Equal"; +S0x0D : U"Backslash"; +S0x0E : U"Tab"; +S0x0F : U"Q"; +S0x10 : U"W"; +S0x11 : U"E"; +S0x12 : U"R"; +S0x13 : U"T"; +S0x14 : U"Y"; +S0x15 : U"U"; +S0x16 : U"I"; +S0x17 : U"O"; +S0x18 : U"P"; +S0x19 : U"LBrace"; +S0x1A : U"RBrace"; +S0x1B : U"Backspace"; +S0x1C : U"Ctrl"; +S0x1D : U"A"; +S0x1E : U"S"; +S0x1F : U"D"; +S0x20 : U"F"; +S0x21 : U"G"; +S0x22 : U"H"; +S0x23 : U"J"; +S0x24 : U"K"; +S0x25 : U"L"; +S0x26 : U"Semicolon"; +S0x27 : U"Quote"; +S0x28 : U"Enter"; +S0x29 : U"LShift"; +S0x2A : U"Z"; +S0x2B : U"X"; +S0x2C : U"C"; +S0x2D : U"V"; +S0x2E : U"B"; +S0x2F : U"N"; +S0x30 : U"M"; +S0x31 : U"Comma"; +S0x32 : U"Period"; +S0x33 : U"Slash"; +S0x34 : U"RShift"; +S0x35 : U"F1"; # Fun key +S0x36 : U"F2"; # Left Blank Key +S0x37 : U"LAlt"; +S0x38 : U"LGui"; +S0x39 : U"Space"; +S0x3A : U"RGui"; +S0x3B : U"RAlt"; +S0x3C : U"F3"; # Right Blank Key 1 +S0x3D : U"F4"; # Right Blank Key 2 +S0x3E : U"BackTick"; + diff --git a/Scan/MDErgo1/led_conf.h b/Scan/MDErgo1/led_conf.h new file mode 100644 index 0000000..8483753 --- /dev/null +++ b/Scan/MDErgo1/led_conf.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + + +// ----- Variables ----- + +// A bit mask determining which LEDs are enabled in the ISSI chip +// Infinity ErgoDox full mask +// 0x00 -> 0x11 +/* +const uint8_t LED_ledEnableMask[] = { +0xE8, // I2C address +0x00, // Starting register address +0x37, 0x37, // C1-1 -> C1-16 +0xBF, 0xBF, // C2-1 -> C2-16 +0xFF, 0xFF, // C3-1 -> C3-16 +0xEF, 0xEF, // C4-1 -> C4-16 +0xF7, 0xF7, // C5-1 -> C5-16 +0xFF, 0xFF, // C6-1 -> C6-16 +0xF3, 0xF3, // C7-1 -> C7-16 +0x6C, 0x6C, // C8-1 -> C8-16 +0x24, 0x24, // C9-1 -> C9-16 +}; +*/ +/* +const uint8_t LED_ledEnableMask[] = { +0xE8, // I2C address +0x00, // Starting register address +0x00, 0x00, // C1-1 -> C1-16 +//0xEC, 0xEC, // C1-1 -> C1-16 +//0xFD, 0xFD, // C2-1 -> C2-16 +0x00, 0x00, // C3-1 -> C3-16 +0x00, 0x00, // C4-1 -> C4-16 +0x00, 0x00, // C5-1 -> C5-16 +0x00, 0x00, // C6-1 -> C6-16 +0x00, 0x00, // C7-1 -> C7-16 +0x00, 0x00, // C8-1 -> C8-16 +0x00, 0x00, // C9-1 -> C9-16 +}; +*/ +const uint8_t LED_ledEnableMask[] = { +0xE8, // I2C address +0x00, // Starting register address +0xFF, 0xFF, // C1-1 -> C1-16 +0xFF, 0xFF, // C2-1 -> C2-16 +0xFF, 0xFF, // C3-1 -> C3-16 +0xFF, 0xFF, // C4-1 -> C4-16 +0xFF, 0xFF, // C5-1 -> C5-16 +0xFF, 0xFF, // C6-1 -> C6-16 +0xFF, 0xFF, // C7-1 -> C7-16 +0xFF, 0xFF, // C8-1 -> C8-16 +0xFF, 0xFF, // C9-1 -> C9-16 +}; + diff --git a/Scan/MDErgo1/matrix.h b/Scan/MDErgo1/matrix.h new file mode 100644 index 0000000..687ca65 --- /dev/null +++ b/Scan/MDErgo1/matrix.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Project Includes +#include + + + +// ----- Matrix Definition ----- + +// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 +// Not all chips have access to all of these pins (most don't have 160 pins :P) +// +// NOTE: +// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down +// Checking this is completely on the ownness of the user + +// MDErgo1 +// +// Column (Strobe) - 9 Total +// PTB2,3,18,19 +// PTC0,9..11 +// PTD0 +// +// Rows (Sense) - 5 Total +// PTD1,4..7 + +// Define Rows (Sense) and Columns (Strobes) +GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,9), gpio(C,10), gpio(C,11), gpio(D,0) }; +GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; + +// Define type of scan matrix +Config Matrix_type = Config_Pulldown; + diff --git a/Scan/MDErgo1/pinout b/Scan/MDErgo1/pinout new file mode 100644 index 0000000..d814f79 --- /dev/null +++ b/Scan/MDErgo1/pinout @@ -0,0 +1,144 @@ +Pin Usage +========= + +mk20dx256vlh7 + + ---- +|Keys| + ---- + +* Strobe (Columns) + +TODO + +* Sense (Rows) + +TODO + + + ----- +|Clock| + ----- + +PTA18 <-> PTA19 + + + --- +|I2C| + --- + +* Main - Connect to all ISSI Chips - Also break out header for debugging + +PTB0 - SCL0 (add header pin, label as SCL0) +PTB1 - SDA0 (add header pin, label as SDA0) + +* Reserved for I2C usage + +PTC10 - SCL1 (Reserved, can use as GPIO) +PTC11 - SDA1 (Reserved, can use as GPIO) + +* ISSI Control (enough pins for 3 chips reserved) + +PTB17 - INTB Chip 1 +PTB18 - INTB Chip 2 (Reserved, can use as GPIO) +PTB19 - INTB Chip 3 (Reserved, can use as GPIO) + +PTB16 - SDB (tied to all Chips, hardware shutdown) + + + --- +|PWM| + --- + +NHD-C12832A1Z-FS(RGB)-FBW-3V + +PTC1 - K(R) +PTC2 - K(G) +PTC3 - K(B) + + + --- +|SPI| + --- + +NHD-C12832A1Z-FS(RGB)-FBW-3V + +PTC4 - CS1B - SS1 +PTC5 - SCL - SCLK +PTC6 - SDA(SI) - MOSI +PTC7 - A0 (Not SPI, used for display) +PTC8 - RST (Not SPI, used for display) + + + --- +|DAC| + --- + +DAC0 (N/C) + + + ---- +|UART| + ---- + +* Comm - For bi-directional communication between halves + +PTA1 - RX0 (Master Side) +PTA2 - TX0 (Master Side) + +PTE0 - TX1 (Slave Side) +PTE1 - RX1 (Slave Side) + +PTD2 - RX2 (UART Debug Header) +PTD3 - TX2 (UART Debug Header) + + + ----- +|Debug| + ----- + +* SWD - (Main reflash header) + +PTA0 (Pull-down) +PTA3 (Pull-up) + +* LEDs + +PTA5 (LED only for PCB, not Teensy) + +* UARTs + +PTD2 - RX2 (UART Debug Header, label as RX2) +PTD3 - TX2 (UART Debug Header, label as TX2) + + + ------ +|Unused| + ------ + +* GPIO + +PTA4 +PTA12 +PTA13 +PTB2 +PTB3 +PTB16 +PTB17 +PTB18 +PTB19 +PTC0 +PTC9 +PTC10 +PTC11 +PTD0 +PTD1 +PTD4 +PTD5 +PTD6 +PTD7 + +* Analog + +TODO + diff --git a/Scan/MDErgo1/scan_loop.c b/Scan/MDErgo1/scan_loop.c new file mode 100644 index 0000000..8e824c3 --- /dev/null +++ b/Scan/MDErgo1/scan_loop.c @@ -0,0 +1,104 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Variables ----- + +// Number of scans since the last USB send +uint16_t Scan_scanCount = 0; + + + +// ----- Functions ----- + +// Setup +inline void Scan_setup() +{ + // Setup UART Connect, if Output_Available, this is the master node + Connect_setup( Output_Available ); + + // Setup GPIO pins for matrix scanning + //Matrix_setup(); + + // Setup ISSI chip to control the leds + LED_setup(); + + // Setup the ST/NHD lcd display + LCD_setup(); + + // Reset scan count + Scan_scanCount = 0; +} + + +// Main Detection Loop +inline uint8_t Scan_loop() +{ + // Scan Matrix + //Matrix_scan( Scan_scanCount++ ); + + // Process any interconnect commands + Connect_scan(); + + // Process any LED events + LED_scan(); + + // Process any LCD events + LCD_scan(); + + return 0; +} + + +// Signal from Macro Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithMacro( uint8_t sentKeys ) +{ +} + + +// Signal from Output Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithOutput( uint8_t sentKeys ) +{ + // Reset scan loop indicator (resets each key debounce state) + // TODO should this occur after USB send or Macro processing? + Scan_scanCount = 0; +} + diff --git a/Scan/MDErgo1/scan_loop.h b/Scan/MDErgo1/scan_loop.h new file mode 100644 index 0000000..17a06fc --- /dev/null +++ b/Scan/MDErgo1/scan_loop.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Functions ----- + +// Functions to be called by main.c +void Scan_setup( void ); +uint8_t Scan_loop( void ); + +// Call-backs +void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module +void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + diff --git a/Scan/MDErgo1/setup.cmake b/Scan/MDErgo1/setup.cmake new file mode 100644 index 0000000..2e5f89f --- /dev/null +++ b/Scan/MDErgo1/setup.cmake @@ -0,0 +1,33 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Sub-modules +# +AddModule ( Scan ISSILed ) +AddModule ( Scan MatrixARM ) +AddModule ( Scan STLcd ) +AddModule ( Scan UARTConnect ) + + +### +# Module C files +# +set ( Module_SRCS + scan_loop.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + From 581b464a13969e0a7f195879513adece5eea2b53 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 1 Aug 2015 18:26:04 -0700 Subject: [PATCH 08/79] Setting ICED bootloader to turn LCD backlight red --- Bootloader/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Bootloader/main.c b/Bootloader/main.c index bca3fdf..aabaeeb 100644 --- a/Bootloader/main.c +++ b/Bootloader/main.c @@ -192,6 +192,12 @@ void main() // Setup pin - A5 - See Lib/pin_map.mchck for more details on pins PORTA_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); GPIOA_PSOR |= (1<<5); + + // TODO Add CMake configuration for disabling + // Set LCD backlight on ICED to Red + GPIOC_PDDR |= (1<<1); + PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + GPIOC_PCOR |= (1<<1); #else #error "Incompatible chip for bootloader" #endif From 64b232c87808fd2016831604f42cee9d30e10d8b Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 1 Aug 2015 21:59:43 -0700 Subject: [PATCH 09/79] Adding 16-bit brightness control to LCD backlight --- Scan/STLcd/capabilities.kll | 44 ++++++++++++++++++++++++++++++ Scan/STLcd/lcd_scan.c | 54 ++++++++++++++++++++++++++++++------- 2 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 Scan/STLcd/capabilities.kll diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll new file mode 100644 index 0000000..a327bc2 --- /dev/null +++ b/Scan/STLcd/capabilities.kll @@ -0,0 +1,44 @@ +Name = STLcdCapabilities; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-01; + +# Defines available to the STLcd sub-module + +# PWM Prescalar +# In general this can be left alone +# A higher prescalar should be lower power usage (less switching) +# However, flickering may be noticeable. +# +# Here's a calculation table valid at a 72 MHz system clock +# Prescalars range from 0 to 7 (1 to 128) +# 0 - 72 MHz - Highest power usage/best result +# 1 - 36 MHz +# 2 - 18 MHz +# 3 - 9 MHz - Slightly visible flicker (peripheral vision) +# 4 - 4 500 kHz - Visible flickering +# 5 - 2 250 kHz +# 6 - 1 125 kHz +# 7 - 562 500 Hz +# Defaulting to no prescalar, looks the best +STLcdBacklightPrescalar => STLcdBacklightPrescalar_define; +STLcdBacklightPrescalar = 0; + +# Default Backlight Channel Brightness +# There are 3 channels, RGB +# In order to get other colors you must mix the 3 colors +# Each channel is a 16-bit register (65536 levels) +# Technically, this means, the backlight is a 48-bit RGB pixel +# In practice, it may be difficult to get color consistency at times if too bright or too dim +STLcdBacklightRed => STLcdBacklightRed_define; +STLcdBacklightGreen => STLcdBacklightGreen_define; +STLcdBacklightBlue => STLcdBacklightBlue_define; + +# Defaults to 6% brightness, white +STLcdBacklightRed = 0xFFF; +STLcdBacklightGreen = 0xFFF; +STLcdBacklightBlue = 0xFFF; + diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index df07b5a..49a1b82 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -21,6 +21,7 @@ // Project Includes #include +#include #include #include @@ -276,16 +277,49 @@ inline void LCD_setup() // Setup Backlight // TODO Expose default settings - // TODO Setup PWM - GPIOC_PDDR |= (1<<1); - PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<1); - GPIOC_PDDR |= (1<<2); - PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<2); - GPIOC_PDDR |= (1<<3); - PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - GPIOC_PCOR |= (1<<3); + SIM_SCGC6 |= SIM_SCGC6_FTM0; + FTM0_CNT = 0; // Reset counter + + // PWM Period + // 16-bit maximum + FTM0_MOD = 0xFFFF; + + // Set FTM to PWM output - Edge Aligned, Low-true pulses + FTM0_C0SC = 0x24; // MSnB:MSnA = 10, ELSnB:ELSnA = 01 + FTM0_C1SC = 0x24; + FTM0_C2SC = 0x24; + + // Base FTM clock selection (72 MHz system clock) + // Pre-scalar calculations + // 0 - 72 MHz - Highest power usage/best result + // 1 - 36 MHz + // 2 - 18 MHz + // 3 - 9 MHz - Slightly visible flicker (peripheral vision) + // 4 - 4 500 kHz - Visible flickering + // 5 - 2 250 kHz + // 6 - 1 125 kHz + // 7 - 562 500 Hz + // System clock, /w prescalar setting + FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS( STLcdBacklightPrescalar_define ); + + /* Write frequency TODO API + FTM0_SC = 0; + FTM0_CNT = 0; + FTM0_MOD = mod; + FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale); + */ + + // Red + FTM0_C0V = STLcdBacklightRed_define; + PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4); + + // Green + FTM0_C1V = STLcdBacklightGreen_define; + PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4); + + // Blue + FTM0_C2V = STLcdBacklightBlue_define; + PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4); } From 5ca169abd7775c88a219425002329e644759bea9 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 1 Aug 2015 22:47:34 -0700 Subject: [PATCH 10/79] Adding cli API call to set LCD backlight brightness (16 bit per channel) --- Scan/STLcd/capabilities.kll | 28 ++++++++------- Scan/STLcd/lcd_scan.c | 68 +++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index a327bc2..73a97e1 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -15,15 +15,19 @@ Date = 2015-08-01; # # Here's a calculation table valid at a 72 MHz system clock # Prescalars range from 0 to 7 (1 to 128) -# 0 - 72 MHz - Highest power usage/best result -# 1 - 36 MHz -# 2 - 18 MHz -# 3 - 9 MHz - Slightly visible flicker (peripheral vision) -# 4 - 4 500 kHz - Visible flickering -# 5 - 2 250 kHz -# 6 - 1 125 kHz -# 7 - 562 500 Hz -# Defaulting to no prescalar, looks the best + +# Base FTM clock selection (72 MHz system clock) +# @ 0xFFFF period, 72 MHz / 0xFFFF * 2 = Actual period +# Higher pre-scalar will use the most power (also look the best) +# Pre-scalar calculations +# 0 - 72 MHz -> 549 Hz +# 1 - 36 MHz -> 275 Hz +# 2 - 18 MHz -> 137 Hz +# 3 - 9 MHz -> 69 Hz (Slightly visible flicker) +# 4 - 4 500 kHz -> 34 Hz (Visible flickering) +# 5 - 2 250 kHz -> 17 Hz +# 6 - 1 125 kHz -> 9 Hz +# 7 - 562 500 Hz -> 4 Hz STLcdBacklightPrescalar => STLcdBacklightPrescalar_define; STLcdBacklightPrescalar = 0; @@ -38,7 +42,7 @@ STLcdBacklightGreen => STLcdBacklightGreen_define; STLcdBacklightBlue => STLcdBacklightBlue_define; # Defaults to 6% brightness, white -STLcdBacklightRed = 0xFFF; -STLcdBacklightGreen = 0xFFF; -STLcdBacklightBlue = 0xFFF; +STLcdBacklightRed = 0x0FFF; +STLcdBacklightGreen = 0x0FFF; +STLcdBacklightBlue = 0x0FFF; diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index 49a1b82..b4933cb 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -49,9 +49,10 @@ // ----- Function Declarations ----- // CLI Functions -void cliFunc_lcdCmd( char* args ); -void cliFunc_lcdInit( char* args ); -void cliFunc_lcdTest( char* args ); +void cliFunc_lcdCmd ( char* args ); +void cliFunc_lcdColor( char* args ); +void cliFunc_lcdInit ( char* args ); +void cliFunc_lcdTest ( char* args ); @@ -65,11 +66,13 @@ uint8_t cliNormalReverseToggleState = 0; // Scan Module command dictionary CLIDict_Entry( lcdCmd, "Send byte via SPI, second argument enables a0. Defaults to control." ); +CLIDict_Entry( lcdColor, "Set backlight color. 3 16-bit numbers: R G B. i.e. 0xFFF 0x1444 0x32" ); CLIDict_Entry( lcdInit, "Re-initialize the LCD display." ); CLIDict_Entry( lcdTest, "Test out the LCD display." ); CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = { CLIDict_Item( lcdCmd ), + CLIDict_Item( lcdColor ), CLIDict_Item( lcdInit ), CLIDict_Item( lcdTest ), { 0, 0, 0 } // Null entry for dictionary end @@ -290,25 +293,23 @@ inline void LCD_setup() FTM0_C2SC = 0x24; // Base FTM clock selection (72 MHz system clock) + // @ 0xFFFF period, 72 MHz / 0xFFFF * 2 = Actual period + // Higher pre-scalar will use the most power (also look the best) // Pre-scalar calculations - // 0 - 72 MHz - Highest power usage/best result - // 1 - 36 MHz - // 2 - 18 MHz - // 3 - 9 MHz - Slightly visible flicker (peripheral vision) - // 4 - 4 500 kHz - Visible flickering - // 5 - 2 250 kHz - // 6 - 1 125 kHz - // 7 - 562 500 Hz + // 0 - 72 MHz -> 549 Hz + // 1 - 36 MHz -> 275 Hz + // 2 - 18 MHz -> 137 Hz + // 3 - 9 MHz -> 69 Hz (Slightly visible flicker) + // 4 - 4 500 kHz -> 34 Hz (Visible flickering) + // 5 - 2 250 kHz -> 17 Hz + // 6 - 1 125 kHz -> 9 Hz + // 7 - 562 500 Hz -> 4 Hz + // Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced + // Which will reduce the brightness range + // System clock, /w prescalar setting FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS( STLcdBacklightPrescalar_define ); - /* Write frequency TODO API - FTM0_SC = 0; - FTM0_CNT = 0; - FTM0_MOD = mod; - FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale); - */ - // Red FTM0_C0V = STLcdBacklightRed_define; PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4); @@ -400,3 +401,34 @@ cmd: LCD_writeControlReg( cmd ); } +void cliFunc_lcdColor( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // Colors + uint16_t rgb[3]; // Red, Green, Blue + + // Parse integers from 3 arguments + for ( uint8_t color = 0; color < 3; color++ ) + { + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Give up if not enough args given + if ( *arg1Ptr == '\0' ) + return; + + // Convert argument to integer + rgb[ color ] = numToInt( arg1Ptr ); + } + + // Set PWM channels + FTM0_C0V = rgb[0]; + FTM0_C1V = rgb[1]; + FTM0_C2V = rgb[2]; + + print( NL ); // No \r\n by default after the command is entered +} + From 9a96c4635d9b4102f832056a3d5e38045dc19082 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 1 Aug 2015 23:13:19 -0700 Subject: [PATCH 11/79] Adding capability to set default image on LCD --- Scan/STLcd/capabilities.kll | 12 ++++++++++++ Scan/STLcd/lcd_scan.c | 33 +++++++++------------------------ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index 73a97e1..114e1f2 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -46,3 +46,15 @@ STLcdBacklightRed = 0x0FFF; STLcdBacklightGreen = 0x0FFF; STLcdBacklightBlue = 0x0FFF; + +# Default LCD Image +# +# The easiest way to generate this data is using the bitmap2Struct.py script in this folder +# It will output the necessary uint8_t array to set here +# +STLcdDefaultImage => STLcdDefaultImage_define; + +# Only the data portion is required +# Must be on a single line +STLcdDefaultImage = "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"; + diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index b4933cb..b8211f8 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -58,6 +58,9 @@ void cliFunc_lcdTest ( char* args ); // ----- Variables ----- +// Default Image - Displays on startup +const uint8_t STLcdDefaultImage[] = { STLcdDefaultImage_define }; + // Full Toggle State uint8_t cliFullToggleState = 0; @@ -278,6 +281,10 @@ inline void LCD_setup() // Run LCD intialization sequence LCD_initialize(); + // Write default image to LCD + for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) + LCD_writeDisplayReg( page, (uint8_t*)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); + // Setup Backlight // TODO Expose default settings SIM_SCGC6 |= SIM_SCGC6_FTM0; @@ -338,34 +345,14 @@ inline uint8_t LCD_scan() void cliFunc_lcdInit( char* args ) { - print( NL ); // No \r\n by default after the command is entered LCD_initialize(); } void cliFunc_lcdTest( char* args ) { - print( NL ); // No \r\n by default after the command is entered - - //LCD_initialize(); - // Test pattern - uint8_t pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - -uint8_t logo[] = { -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - //uint8_t pattern[] = { 0xFF, 0x00, 0x96, 0xFF, 0x00, 0xFF, 0x00 }; - - // Write to page D0 - //LCD_writeDisplayReg( 0, pattern, sizeof( pattern ) ); - + // Write default image for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) - { - LCD_writeDisplayReg( page, &logo[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); - } + LCD_writeDisplayReg( page, (uint8_t *)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); } void cliFunc_lcdCmd( char* args ) @@ -428,7 +415,5 @@ void cliFunc_lcdColor( char* args ) FTM0_C0V = rgb[0]; FTM0_C1V = rgb[1]; FTM0_C2V = rgb[2]; - - print( NL ); // No \r\n by default after the command is entered } From d7b7d31cc2a62c7a82a524301cd1f03e9d2024e3 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 2 Aug 2015 00:00:11 -0700 Subject: [PATCH 12/79] Adding API to set pixels on LCD screen --- Scan/STLcd/capabilities.kll | 2 +- Scan/STLcd/lcd_scan.c | 58 +++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index 114e1f2..efc84aa 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -17,7 +17,7 @@ Date = 2015-08-01; # Prescalars range from 0 to 7 (1 to 128) # Base FTM clock selection (72 MHz system clock) -# @ 0xFFFF period, 72 MHz / 0xFFFF * 2 = Actual period +# @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period # Higher pre-scalar will use the most power (also look the best) # Pre-scalar calculations # 0 - 72 MHz -> 549 Hz diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index b8211f8..0c2c8b7 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -33,6 +33,7 @@ // ----- Defines ----- #define LCD_TOTAL_VISIBLE_PAGES 4 +#define LCD_TOTAL_PAGES 9 #define LCD_PAGE_LEN 128 @@ -51,6 +52,7 @@ // CLI Functions void cliFunc_lcdCmd ( char* args ); void cliFunc_lcdColor( char* args ); +void cliFunc_lcdDisp ( char* args ); void cliFunc_lcdInit ( char* args ); void cliFunc_lcdTest ( char* args ); @@ -70,12 +72,14 @@ uint8_t cliNormalReverseToggleState = 0; // Scan Module command dictionary CLIDict_Entry( lcdCmd, "Send byte via SPI, second argument enables a0. Defaults to control." ); CLIDict_Entry( lcdColor, "Set backlight color. 3 16-bit numbers: R G B. i.e. 0xFFF 0x1444 0x32" ); +CLIDict_Entry( lcdDisp, "Write byte(s) to given page starting at given address. i.e. 0x1 0x5 0xFF 0x00" ); CLIDict_Entry( lcdInit, "Re-initialize the LCD display." ); CLIDict_Entry( lcdTest, "Test out the LCD display." ); CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = { CLIDict_Item( lcdCmd ), CLIDict_Item( lcdColor ), + CLIDict_Item( lcdDisp ), CLIDict_Item( lcdInit ), CLIDict_Item( lcdTest ), { 0, 0, 0 } // Null entry for dictionary end @@ -204,7 +208,7 @@ inline void LCD_clearPage( uint8_t page ) void LCD_clear() { // Setup each page - for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) + for ( uint8_t page = 0; page < LCD_TOTAL_PAGES; page++ ) { LCD_clearPage( page ); } @@ -286,7 +290,6 @@ inline void LCD_setup() LCD_writeDisplayReg( page, (uint8_t*)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); // Setup Backlight - // TODO Expose default settings SIM_SCGC6 |= SIM_SCGC6_FTM0; FTM0_CNT = 0; // Reset counter @@ -300,7 +303,7 @@ inline void LCD_setup() FTM0_C2SC = 0x24; // Base FTM clock selection (72 MHz system clock) - // @ 0xFFFF period, 72 MHz / 0xFFFF * 2 = Actual period + // @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period // Higher pre-scalar will use the most power (also look the best) // Pre-scalar calculations // 0 - 72 MHz -> 549 Hz @@ -334,8 +337,6 @@ inline void LCD_setup() // LCD State processing loop inline uint8_t LCD_scan() { - // NOP - Screen Refresh - //LCD_writeControlReg( 0xE3 ); return 0; } @@ -417,3 +418,50 @@ void cliFunc_lcdColor( char* args ) FTM0_C2V = rgb[2]; } +void cliFunc_lcdDisp( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // First process page and starting address + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + uint8_t page = numToInt( arg1Ptr ); + + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + uint8_t address = numToInt( arg1Ptr ); + + // Set the register page + LCD_writeControlReg( 0xB0 | ( 0x0F & page ) ); + + // Set starting address + LCD_writeControlReg( 0x10 | ( ( 0xF0 & address ) >> 4 ) ); + LCD_writeControlReg( 0x00 | ( 0x0F & address )); + + // Process all args + for ( ;; ) + { + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + break; + + uint8_t value = numToInt( arg1Ptr ); + + // Write buffer to SPI + SPI_write( &value, 1 ); + } +} + From 61cb9138331930d04a0439978ddf7b891808653a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 2 Aug 2015 13:43:28 -0700 Subject: [PATCH 13/79] Using multi-line define support (requires latest kll compiler) --- Scan/STLcd/capabilities.kll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index efc84aa..49319d2 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -56,5 +56,10 @@ STLcdDefaultImage => STLcdDefaultImage_define; # Only the data portion is required # Must be on a single line -STLcdDefaultImage = "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,"; +STLcdDefaultImage = " +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +"; From d3eaa7a798c2ca7aa06480eea3bdebd69161672f Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 2 Aug 2015 16:28:21 -0700 Subject: [PATCH 14/79] Adding ISSILed API calls and default brightness - Adds override functionality in main module --- Scan/ISSILed/capabilities.kll | 59 ++++++++++++ Scan/ISSILed/led_scan.c | 170 +++++++++++++++------------------- Scan/MDErgo1/defaultMap.kll | 43 ++++++++- 3 files changed, 174 insertions(+), 98 deletions(-) create mode 100644 Scan/ISSILed/capabilities.kll diff --git a/Scan/ISSILed/capabilities.kll b/Scan/ISSILed/capabilities.kll new file mode 100644 index 0000000..2c0a32c --- /dev/null +++ b/Scan/ISSILed/capabilities.kll @@ -0,0 +1,59 @@ +Name = ISSILedCapabilities; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-02; + +# Defines available to the ISSILed sub-module + +# LED Default Enable Mask +# +# By default, all LEDs are enabled +# However, this may cause issuse with some led matrices, so it is recommended to disable unused positions +# Each LED is represented by a single bit +# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details +ISSILedMask1 => ISSILedMask1_define; +ISSILedMask1 = " + 0xFF, 0xFF, /* C1-1 -> C1-16 */ + 0xFF, 0xFF, /* C2-1 -> C2-16 */ + 0xFF, 0xFF, /* C3-1 -> C3-16 */ + 0xFF, 0xFF, /* C4-1 -> C4-16 */ + 0xFF, 0xFF, /* C5-1 -> C5-16 */ + 0xFF, 0xFF, /* C6-1 -> C6-16 */ + 0xFF, 0xFF, /* C7-1 -> C7-16 */ + 0xFF, 0xFF, /* C8-1 -> C8-16 */ + 0xFF, 0xFF, /* C9-1 -> C9-16 */ +"; + +# LED Default Brightness +# +# By default, all LEDs are set to max brightness +# Each LED channel supports 256 levels (8-bit control) +ISSILedBrightness1 => ISSILedBrightness1_define; +ISSILedBrightness1 = " +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */ +"; + +# Example starting from 0 brightness to 0x8F +ISSILedBrightness_example = " +0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* C1-1 -> C1-16 */ +0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* C2-1 -> C2-16 */ +0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* C3-1 -> C3-16 */ +0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, /* C4-1 -> C4-16 */ +0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* C5-1 -> C5-16 */ +0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, /* C6-1 -> C6-16 */ +0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, /* C7-1 -> C7-16 */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, /* C8-1 -> C8-16 */ +0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, /* C9-1 -> C9-16 */ +"; + diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index dfa54d7..ef3032f 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -21,9 +21,9 @@ // Project Includes #include +#include #include #include -#include // Located with scan_loop.c // Local Includes #include "led_scan.h" @@ -57,12 +57,13 @@ typedef struct LED_Buffer { // ----- Function Declarations ----- // CLI Functions -void cliFunc_i2cRecv( char* args ); -void cliFunc_i2cSend( char* args ); -void cliFunc_ledPage( char* args ); +void cliFunc_i2cRecv ( char* args ); +void cliFunc_i2cSend ( char* args ); +void cliFunc_ledRPage( char* args ); void cliFunc_ledStart( char* args ); -void cliFunc_ledTest( char* args ); -void cliFunc_ledZero( char* args ); +void cliFunc_ledTest ( char* args ); +void cliFunc_ledWPage( char* args ); +void cliFunc_ledZero ( char* args ); uint8_t I2C_TxBufferPop(); void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer ); @@ -76,17 +77,19 @@ uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ); // Scan Module command dictionary CLIDict_Entry( i2cRecv, "Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence." NL "\t\tUse |'s to split sequences with a stop." ); CLIDict_Entry( i2cSend, "Send I2C sequence of bytes. Use |'s to split sequences with a stop." ); -CLIDict_Entry( ledPage, "Read the given register page." ); +CLIDict_Entry( ledRPage, "Read the given register page." ); CLIDict_Entry( ledStart, "Disable software shutdown." ); CLIDict_Entry( ledTest, "Test out the led pages." ); +CLIDict_Entry( ledWPage, "Write to given register page starting at address. i.e. 0x2 0x24 0xF0 0x12" ); CLIDict_Entry( ledZero, "Zero out LED register pages (non-configuration)." ); CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { CLIDict_Item( i2cRecv ), CLIDict_Item( i2cSend ), - CLIDict_Item( ledPage ), + CLIDict_Item( ledRPage ), CLIDict_Item( ledStart ), CLIDict_Item( ledTest ), + CLIDict_Item( ledWPage ), CLIDict_Item( ledZero ), { 0, 0, 0 } // Null entry for dictionary end }; @@ -103,92 +106,18 @@ volatile I2C_Buffer I2C_RxBuffer = { 0, 0, 0, I2C_RxBufferLength, (uint8_t*)I2C_ LED_Buffer LED_pageBuffer; -/* // A bit mask determining which LEDs are enabled in the ISSI chip -// All channel mask example -// 0x00 -> 0x11 -const uint8_t LED_ledEnableMask[] = { -0xE8, // I2C address -0x00, // Starting register address -0xFF, 0xFF, // C1-1 -> C1-16 -0xFF, 0xFF, // C2-1 -> C2-16 -0xFF, 0xFF, // C3-1 -> C3-16 -0xFF, 0xFF, // C4-1 -> C4-16 -0xFF, 0xFF, // C5-1 -> C5-16 -0xFF, 0xFF, // C6-1 -> C6-16 -0xFF, 0xFF, // C7-1 -> C7-16 -0xFF, 0xFF, // C8-1 -> C8-16 -0xFF, 0xFF, // C9-1 -> C9-16 +const uint8_t LED_ledEnableMask1[] = { + 0xE8, // I2C address + 0x00, // Starting register address + ISSILedMask1_define }; -*/ -/* -// A bit mask determining which LEDs are enabled in the ISSI chip -// Infinity ErgoDox full mask -// 0x00 -> 0x11 -const uint8_t LED_ledEnableMask[] = { -0xE8, // I2C address -0x00, // Starting register address -0xFC, 0xFC, // C1-1 -> C1-16 -0xFB, 0xFB, // C2-1 -> C2-16 -0xFF, 0xFF, // C3-1 -> C3-16 -0xFE, 0xFE, // C4-1 -> C4-16 -0x7F, 0x7F, // C5-1 -> C5-16 -0xFF, 0xFF, // C6-1 -> C6-16 -0xCF, 0xCF, // C7-1 -> C7-16 -0xC7, 0xC7, // C8-1 -> C8-16 -0x43, 0x43, // C9-1 -> C9-16 -}; -*/ - -/* -const uint8_t LED_ledEnableMask[] = { -0xE8, // I2C address -0x00, // Starting register address -0x00, 0x00, // C1-1 -> C1-16 -//0xEC, 0xEC, // C1-1 -> C1-16 -0x00, 0x00, // C2-1 -> C2-16 -0x00, 0x00, // C3-1 -> C3-16 -0x00, 0x00, // C4-1 -> C4-16 -0x00, 0x00, // C5-1 -> C5-16 -0x00, 0x00, // C6-1 -> C6-16 -0x08, 0x08, // C7-1 -> C7-16 -0x00, 0x00, // C8-1 -> C8-16 -0x00, 0x00, // C9-1 -> C9-16 -}; -*/ - - -/* -// XXX Pre-fill example of buffers -const uint8_t examplePage[] = { -0xE8, // I2C address -0x24, // Starting register address -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C1-1 -> C1-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C2-1 -> C2-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C3-1 -> C3-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C4-1 -> C4-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C5-1 -> C5-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C6-1 -> C6-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C7-1 -> C7-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C8-1 -> C8-16 -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C9-1 -> C9-16 -}; -*/ - -// XXX Pre-fill example of buffers -const uint8_t examplePage[] = { -0xE8, // I2C address -0x24, // Starting register address -0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // C1-1 -> C1-16 -0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // C2-1 -> C2-16 -0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // C3-1 -> C3-16 -0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // C4-1 -> C4-16 -0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // C5-1 -> C5-16 -0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // C6-1 -> C6-16 -0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // C7-1 -> C7-16 -0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, // C8-1 -> C8-16 -0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // C9-1 -> C9-16 +// Default LED brightness +const uint8_t LED_defaultBrightness1[] = { + 0xE8, // I2C address + 0x24, // Starting register address + ISSILedBrightness1_define }; @@ -446,7 +375,10 @@ inline void LED_setup() LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers // Enable LEDs based upon mask - LED_sendPage( (uint8_t*)LED_ledEnableMask, sizeof( LED_ledEnableMask ), 0 ); + LED_sendPage( (uint8_t*)LED_ledEnableMask1, sizeof( LED_ledEnableMask1 ), 0 ); + + // Set default brightness + LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 ); // Disable Software shutdown of ISSI chip LED_writeReg( 0x0A, 0x01, 0x0B ); @@ -785,7 +717,7 @@ void cliFunc_i2cRecv( char* args ) I2C_Send( buffer, bufferLen, 1 ); // Only 1 byte is ever read at a time with the ISSI chip } -void cliFunc_ledPage( char* args ) +void cliFunc_ledRPage( char* args ) { // Parse number from argument // NOTE: Only first argument is used @@ -807,20 +739,68 @@ void cliFunc_ledPage( char* args ) LED_readPage( 0xB4, page ); } +void cliFunc_ledWPage( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // First process page and starting address + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + uint8_t page[] = { 0xE8, 0xFD, numToInt( arg1Ptr ) }; + + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + uint8_t data[] = { 0xE8, numToInt( arg1Ptr ), 0 }; + + // Set the register page + while ( I2C_Send( page, sizeof( page ), 0 ) == 0 ) + delay(1); + + // Process all args + for ( ;; ) + { + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + break; + + data[2] = numToInt( arg1Ptr ); + + // Write register location and data to I2C + while ( I2C_Send( data, sizeof( data ), 0 ) == 0 ) + delay(1); + + // Increment address + data[1]++; + } +} + void cliFunc_ledStart( char* args ) { print( NL ); // No \r\n by default after the command is entered LED_zeroPages( 0x0B, 1, 0x00, 0x0C ); // Control Registers //LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers LED_writeReg( 0x0A, 0x01, 0x0B ); - LED_sendPage( (uint8_t*)LED_ledEnableMask, sizeof( LED_ledEnableMask ), 0 ); + LED_sendPage( (uint8_t*)LED_ledEnableMask1, sizeof( LED_ledEnableMask1 ), 0 ); } void cliFunc_ledTest( char* args ) { print( NL ); // No \r\n by default after the command is entered - LED_sendPage( (uint8_t*)examplePage, sizeof( examplePage ), 0 ); + LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 ); } void cliFunc_ledZero( char* args ) diff --git a/Scan/MDErgo1/defaultMap.kll b/Scan/MDErgo1/defaultMap.kll index 7ed3492..cb2aebc 100644 --- a/Scan/MDErgo1/defaultMap.kll +++ b/Scan/MDErgo1/defaultMap.kll @@ -1,10 +1,10 @@ Name = MDErgo1; -Version = 0.1; +Version = 0.2; Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3a; +KLL = 0.3c; # Modified Date -Date = 2015-03-10; +Date = 2015-08-02; S0x00 : U"Esc"; @@ -71,3 +71,40 @@ S0x3C : U"F3"; # Right Blank Key 1 S0x3D : U"F4"; # Right Blank Key 2 S0x3E : U"BackTick"; + +# Defines available to the MDErgo1 Scan Module + +# LED Default Enable Mask Override +# +# 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 */ + 0xFF, 0x00, /* C3-1 -> C3-16 */ + 0xFF, 0x00, /* C4-1 -> C4-16 */ + 0xFC, 0x00, /* C5-1 -> C5-16 */ + 0x00, 0x00, /* C6-1 -> C6-16 */ + 0x00, 0x00, /* C7-1 -> C7-16 */ + 0x00, 0x00, /* C8-1 -> C8-16 */ + 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + +# 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 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + + From 0013d7a4f31d35ad054369037e20b683085c6116 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 3 Aug 2015 21:42:01 -0700 Subject: [PATCH 15/79] Fixing CMake dependency checking for kll_defs.h --- Scan/ISSILed/led_scan.c | 2 +- Scan/MatrixARM/matrix_scan.c | 2 +- Scan/STLcd/lcd_scan.c | 2 +- Scan/UARTConnect/connect_scan.c | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index ef3032f..33073ab 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -21,7 +21,7 @@ // Project Includes #include -#include +#include #include #include diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index a48e287..8463b26 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -26,7 +26,7 @@ // Project Includes #include -#include +#include #include #include #include diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index 0c2c8b7..a7d7d44 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -21,7 +21,7 @@ // Project Includes #include -#include +#include #include #include diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index dd6980e..587a5e7 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -21,6 +21,7 @@ // Project Includes #include +#include #include #include #include From a824a0fe52b1c2c3a88b3590d0513f63a334333a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 5 Aug 2015 10:18:35 -0700 Subject: [PATCH 16/79] Add Unique Id to version information --- Debug/cli/cli.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Debug/cli/cli.c b/Debug/cli/cli.c index a5aa94c..03fb3ca 100644 --- a/Debug/cli/cli.c +++ b/Debug/cli/cli.c @@ -548,5 +548,15 @@ void cliFunc_version( char* args ) print( " \033[1mCPU:\033[0m " CLI_CPU NL ); print( " \033[1mDevice:\033[0m " CLI_Device NL ); print( " \033[1mModules:\033[0m " CLI_Modules NL ); +#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) + print( " \033[1mUnique Id:\033[0m " ); + printHex32_op( SIM_UIDH, 4 ); + printHex32_op( SIM_UIDMH, 4 ); + printHex32_op( SIM_UIDML, 4 ); + printHex32_op( SIM_UIDL, 4 ); +#elif defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) +#else +#error "No unique id defined." +#endif } From 1c0f94c4ea300a4380d6559318292452d67f941b Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 6 Aug 2015 00:36:37 -0700 Subject: [PATCH 17/79] Adding preliminary MDErgo keymap - Required updates to CMake in order to handle the multi-layer BaseMaps --- CMakeLists.txt | 1 - Lib/CMake/kll.cmake | 28 +++++---- Scan/MDErgo1/defaultMap.kll | 109 ++++++++++++++---------------------- Scan/MDErgo1/leftHand.kll | 61 ++++++++++++++++++++ Scan/MDErgo1/rightHand.kll | 62 ++++++++++++++++++++ Scan/MDErgo1/scan_loop.c | 4 +- Scan/MDErgo1/slave1.kll | 11 ++++ 7 files changed, 195 insertions(+), 81 deletions(-) create mode 100644 Scan/MDErgo1/leftHand.kll create mode 100644 Scan/MDErgo1/rightHand.kll create mode 100644 Scan/MDErgo1/slave1.kll diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b88e93..1f14bbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,7 +106,6 @@ set( DebugModule "full" ##| Set the base keyboard .kll map, defaults to "defaultMap" if not found ##| Looks in Scan/ for the available BaseMaps -##| TODO Support layering in basemap set( BaseMap "defaultMap" CACHE STRING "KLL BaseMap/Scancode Keymapping" ) diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 80d44c1..f41b92a 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -54,15 +54,21 @@ endforeach () #| If set BaseMap cannot be found, use default map set ( pathname "${PROJECT_SOURCE_DIR}/${ScanModulePath}" ) -if ( NOT EXISTS ${pathname}/${BaseMap}.kll ) - set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll ) -elseif ( EXISTS "${pathname}/${BaseMap}.kll" ) - set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${BaseMap}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${BaseMap}.kll ) -else () - message ( FATAL "Could not find '${BaseMap}.kll'" ) -endif () + +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 ) + elseif ( EXISTS "${pathname}/${MAP}.kll" ) + set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${MAP}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${MAP}.kll ) + else () + message ( FATAL " Could not find '${MAP}.kll' BaseMap in Scan module directory" ) + endif () +endforeach () #| Configure DefaultMap if specified if ( NOT "${DefaultMap}" STREQUAL "" ) @@ -78,7 +84,7 @@ if ( NOT "${DefaultMap}" STREQUAL "" ) set ( DefaultMap_Args ${DefaultMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) else () - message ( FATAL "Could not find '${MAP}.kll'" ) + message ( FATAL " Could not find '${MAP}.kll' DefaultMap" ) endif () endforeach () endif () @@ -100,7 +106,7 @@ if ( NOT "${PartialMaps}" STREQUAL "" ) set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) else () - message ( FATAL "Could not find '${MAP_PART}.kll'" ) + message ( FATAL " Could not find '${MAP_PART}.kll' PartialMap" ) endif () endforeach () endforeach () diff --git a/Scan/MDErgo1/defaultMap.kll b/Scan/MDErgo1/defaultMap.kll index cb2aebc..ac6158c 100644 --- a/Scan/MDErgo1/defaultMap.kll +++ b/Scan/MDErgo1/defaultMap.kll @@ -1,78 +1,30 @@ Name = MDErgo1; Version = 0.2; -Author = "HaaTa (Jacob Alexander) 2014"; +Author = "HaaTa (Jacob Alexander) 2014-2015"; KLL = 0.3c; # Modified Date -Date = 2015-08-02; - - -S0x00 : U"Esc"; -S0x01 : U"1"; -S0x02 : U"2"; -S0x03 : U"3"; -S0x04 : U"4"; -S0x05 : U"5"; -S0x06 : U"6"; -S0x07 : U"7"; -S0x08 : U"8"; -S0x09 : U"9"; -S0x0A : U"0"; -S0x0B : U"Minus"; -S0x0C : U"Equal"; -S0x0D : U"Backslash"; -S0x0E : U"Tab"; -S0x0F : U"Q"; -S0x10 : U"W"; -S0x11 : U"E"; -S0x12 : U"R"; -S0x13 : U"T"; -S0x14 : U"Y"; -S0x15 : U"U"; -S0x16 : U"I"; -S0x17 : U"O"; -S0x18 : U"P"; -S0x19 : U"LBrace"; -S0x1A : U"RBrace"; -S0x1B : U"Backspace"; -S0x1C : U"Ctrl"; -S0x1D : U"A"; -S0x1E : U"S"; -S0x1F : U"D"; -S0x20 : U"F"; -S0x21 : U"G"; -S0x22 : U"H"; -S0x23 : U"J"; -S0x24 : U"K"; -S0x25 : U"L"; -S0x26 : U"Semicolon"; -S0x27 : U"Quote"; -S0x28 : U"Enter"; -S0x29 : U"LShift"; -S0x2A : U"Z"; -S0x2B : U"X"; -S0x2C : U"C"; -S0x2D : U"V"; -S0x2E : U"B"; -S0x2F : U"N"; -S0x30 : U"M"; -S0x31 : U"Comma"; -S0x32 : U"Period"; -S0x33 : U"Slash"; -S0x34 : U"RShift"; -S0x35 : U"F1"; # Fun key -S0x36 : U"F2"; # Left Blank Key -S0x37 : U"LAlt"; -S0x38 : U"LGui"; -S0x39 : U"Space"; -S0x3A : U"RGui"; -S0x3B : U"RAlt"; -S0x3C : U"F3"; # Right Blank Key 1 -S0x3D : U"F4"; # Right Blank Key 2 -S0x3E : U"BackTick"; +Date = 2015-08-05; + +######## +# NOTE # +######## + +# Default ScanCode mappings are in rightHand.kll and leftHand.kll +# To change which node you are refering to, set the ConnectId variable +# i.e. +# ConnectId = 0; +# S0x02 : U"A"; # Sets scan code 0x02 on keyboard connected to USB +# ConnectId = 1; +# S0x02 : U"B"; # Sets scan code 0x02 on the first slave node +# +# ConnectId may be set in the previously parsed kll file +# In general you shouldn't have to worry about setting ConnectId unless you want a single configuration file +# # Defines available to the MDErgo1 Scan Module +# # LED Default Enable Mask Override # @@ -107,4 +59,27 @@ ISSILedBrightness1 = " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ "; +# LCD Backlight Channel Brightness Override +# There are 3 channels, RGB +# In order to get other colors you must mix the 3 colors +# Each channel is a 16-bit register (65536 levels) +# Technically, this means, the backlight is a 48-bit RGB pixel +# In practice, it may be difficult to get color consistency at times if too bright or too dim +# +# Defaults to 6% brightness, white +STLcdBacklightRed = 0x0FFF; +STLcdBacklightGreen = 0x0FFF; +STLcdBacklightBlue = 0x0FFF; + +# LCD Image Override +# +# The easiest way to generate this data is using the bitmap2Struct.py script in the STLcd folder +# It will output the necessary uint8_t array to set here +# +STLcdDefaultImage = " +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +"; diff --git a/Scan/MDErgo1/leftHand.kll b/Scan/MDErgo1/leftHand.kll new file mode 100644 index 0000000..c814c55 --- /dev/null +++ b/Scan/MDErgo1/leftHand.kll @@ -0,0 +1,61 @@ +Name = MDErgo1 Right Hand; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-06; + + +# Top Row +S0x02 : U"6"; +S0x03 : U"5"; +S0x04 : U"4"; +S0x05 : U"3"; +S0x06 : U"2"; +S0x07 : U"1"; +S0x08 : U"Esc"; + +# Top-Middle Row +S0x0B : U"F4"; +S0x0C : U"T"; +S0x0D : U"R"; +S0x0E : U"E"; +S0x0F : U"W"; +S0x10 : U"Q"; +S0x11 : U"Tab"; + +# Middle Row +S0x15 : U"G"; +S0x16 : U"F"; +S0x17 : U"D"; +S0x18 : U"S"; +S0x19 : U"A"; +S0x1A : U"Function1"; + +# Top Thumb Cluster +S0x1B : U"Home"; +S0x1C : U"End"; + +# Bottom-Middle Row +S0x1D : U"F5"; +S0x1E : U"B"; +S0x1F : U"V"; +S0x20 : U"C"; +S0x21 : U"X"; +S0x22 : U"Z"; +S0x23 : U"Left Shift"; + +# Bottom Thumb Cluster +S0x24 : U"Left Alt"; +S0x25 : U"Left Ctrl"; +S0x26 : U"Delete"; +S0x27 : U"Space"; + +# Bottom Row +S0x28 : U"Function5"; +S0x29 : U"Backtick"; +S0x2A : U"Right Brace"; +S0x2B : U"Left Brace"; +S0x2C : U"Function3"; + diff --git a/Scan/MDErgo1/rightHand.kll b/Scan/MDErgo1/rightHand.kll new file mode 100644 index 0000000..840b696 --- /dev/null +++ b/Scan/MDErgo1/rightHand.kll @@ -0,0 +1,62 @@ +Name = MDErgo1 Right Hand; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-06; + + +# Top Row +S0x02 : U"7"; +S0x03 : U"8"; +S0x04 : U"9"; +S0x05 : U"0"; +S0x06 : U"Minus"; +S0x07 : U"Equal"; +S0x08 : U"Backspace"; + +# Top-Middle Row +S0x0B : U"PageUp"; +S0x0C : U"Y"; +S0x0D : U"U"; +S0x0E : U"I"; +S0x0F : U"O"; +S0x10 : U"P"; +S0x11 : U"BackSlash"; + +# Middle Row +S0x15 : U"H"; +S0x16 : U"J"; +S0x17 : U"K"; +S0x18 : U"L"; +S0x19 : U"Semicolon"; +S0x1A : U"Quote"; + +# Top Thumb Cluster +S0x1B : U"PrintScreen"; +S0x1C : U"Insert"; + +# Bottom-Middle Row +S0x1D : U"PageDown"; +S0x1E : U"N"; +S0x1F : U"M"; +S0x20 : U"Comma"; +S0x21 : U"Period"; +S0x22 : U"Slash"; +S0x23 : U"Right Shift"; + +# Bottom Thumb Cluster +S0x24 : U"Right Alt"; +S0x25 : U"Right Ctrl"; +S0x26 : U"Enter"; +S0x27 : U"Function2"; + +# Bottom Row +S0x28 : U"Left"; +S0x29 : U"Down"; +S0x2A : U"Up"; +S0x2B : U"Right"; +S0x2C : U"Function4"; + + diff --git a/Scan/MDErgo1/scan_loop.c b/Scan/MDErgo1/scan_loop.c index 8e824c3..d5e97e5 100644 --- a/Scan/MDErgo1/scan_loop.c +++ b/Scan/MDErgo1/scan_loop.c @@ -56,7 +56,7 @@ inline void Scan_setup() Connect_setup( Output_Available ); // Setup GPIO pins for matrix scanning - //Matrix_setup(); + Matrix_setup(); // Setup ISSI chip to control the leds LED_setup(); @@ -73,7 +73,7 @@ inline void Scan_setup() inline uint8_t Scan_loop() { // Scan Matrix - //Matrix_scan( Scan_scanCount++ ); + Matrix_scan( Scan_scanCount++ ); // Process any interconnect commands Connect_scan(); diff --git a/Scan/MDErgo1/slave1.kll b/Scan/MDErgo1/slave1.kll new file mode 100644 index 0000000..792ba48 --- /dev/null +++ b/Scan/MDErgo1/slave1.kll @@ -0,0 +1,11 @@ +Name = MDErgo1 Slave1; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-06; + +# Sets all future Scan Code definitions to be applied to the first slave node +ConnectId = 1; + From ecd9923926af0f500e8f65e665687b7d99219118 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 9 Aug 2015 00:20:41 -0700 Subject: [PATCH 18/79] Initial UARTConnect scancode support - Still some issues - Will require some changes to MatrixARM and PartialMap * Currently state information is passed around too frequently * Needs to be reduced to state changes only --- Macro/PartialMap/macro.c | 22 +++++++++++ Scan/MDErgo1/defaultMap.kll | 2 +- Scan/UARTConnect/capabilities.kll | 5 +++ Scan/UARTConnect/connect_scan.c | 62 ++++++++++++++++++++++--------- Scan/UARTConnect/connect_scan.h | 9 +++++ 5 files changed, 81 insertions(+), 19 deletions(-) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index bc2d7d6..3122519 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -29,6 +29,11 @@ #include "usb_hid.h" #include // Generated using kll at compile time, in build directory +// Connect Includes +#if defined(ConnectEnabled_define) +#include +#endif + // Local Includes #include "macro.h" @@ -941,6 +946,23 @@ inline void Macro_updateTriggerMacroPendingList() // Called once per USB buffer send inline void Macro_process() { +#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 ( macroTriggerListBufferSize > 0 ) + { + dbug_msg("Yuh"); + printHex( macroTriggerListBufferSize ); + print( NL ); + //Connect_send_ScanCode( Connect_id, macroTriggerListBuffer, macroTriggerListBufferSize ); + macroTriggerListBufferSize = 0; + } + return; + } +#endif + // Only do one round of macro processing between Output Module timer sends if ( USBKeys_Sent != 0 ) return; diff --git a/Scan/MDErgo1/defaultMap.kll b/Scan/MDErgo1/defaultMap.kll index ac6158c..94038e8 100644 --- a/Scan/MDErgo1/defaultMap.kll +++ b/Scan/MDErgo1/defaultMap.kll @@ -36,7 +36,7 @@ ISSILedMask1 = " 0xFF, 0x00, /* C2-1 -> C2-16 */ 0xFF, 0x00, /* C3-1 -> C3-16 */ 0xFF, 0x00, /* C4-1 -> C4-16 */ - 0xFC, 0x00, /* C5-1 -> C5-16 */ + 0x3F, 0x00, /* C5-1 -> C5-16 */ 0x00, 0x00, /* C6-1 -> C6-16 */ 0x00, 0x00, /* C7-1 -> C7-16 */ 0x00, 0x00, /* C8-1 -> C8-16 */ diff --git a/Scan/UARTConnect/capabilities.kll b/Scan/UARTConnect/capabilities.kll index f02c111..b907221 100644 --- a/Scan/UARTConnect/capabilities.kll +++ b/Scan/UARTConnect/capabilities.kll @@ -39,3 +39,8 @@ UARTConnectBaudFine = 0x0; UARTConnectCableCheckLength => UARTConnectCableCheckLength_define; UARTConnectCableCheckLength = 2; +# Connect Enable +# Define used to indicate to non-connect modules that support should be compiled in +ConnectEnabled => ConnectEnabled_define; +ConnectEnabled = 1; + diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 587a5e7..89bb772 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -36,11 +36,13 @@ // 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 ) \ { \ warn_msg("Too much data to send on UART0, waiting..."); \ delay( 1 ); \ } \ + /* Append data to ring buffer */ \ for ( uint8_t c = 0; c < count; c++ ) \ { \ if ( Connect_debug ) \ @@ -88,6 +90,7 @@ case uartNum: \ UART##uartNum##_CFIFO = UART_CFIFO_RXFLUSH; \ return; \ } \ + /* Process each byte in the UART buffer */ \ while ( available-- > 0 ) \ { \ uint8_t byteRead = UART##uartNum##_D; \ @@ -152,6 +155,7 @@ case uartNum: \ { \ print(" CMD "); \ } \ + /* Call specific UARTConnect command receive function */ \ uint8_t (*rcvFunc)(uint8_t, uint16_t(*), uint8_t) = (uint8_t(*)(uint8_t, uint16_t(*), uint8_t))(Connect_receiveFunctions[ uart##uartNum##_rx_command ]); \ if ( rcvFunc( byteRead, (uint16_t*)&uart##uartNum##_rx_bytes_waiting, uartNum ) ) \ uart##uartNum##_rx_status = UARTStatus_Wait; \ @@ -426,7 +430,7 @@ uint32_t Connect_cableFaultsSlave = 0; uint8_t Connect_cableOkMaster = 0; uint8_t Connect_cableOkSlave = 0; -uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t to_master ) +uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) { // Check if this is the first byte if ( *pending_bytes == 0xFFFF ) @@ -453,7 +457,7 @@ 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_master ) + if ( to_slave ) { Connect_cableFaultsMaster++; Connect_cableOkMaster = 0; @@ -476,7 +480,7 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8 // If cable check was successful, set cable ok if ( *pending_bytes == 0 ) { - if ( to_master ) + if ( to_slave ) { Connect_cableOkMaster = 1; } @@ -499,11 +503,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_master ) +uint8_t Connect_receive_IdRequest( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) { dbug_print("IdRequest"); // Check the directionality - if ( to_master ) + if ( to_slave ) { erro_print("Invalid IdRequest direction..."); } @@ -524,11 +528,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_master ) +uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave ) { dbug_print("IdEnumeration"); // Check the directionality - if ( !to_master ) + if ( !to_slave ) { erro_print("Invalid IdEnumeration direction..."); } @@ -548,11 +552,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_master ) +uint8_t Connect_receive_IdReport( uint8_t id, uint16_t *pending_bytes, uint8_t to_slave ) { dbug_print("IdReport"); // Check the directionality - if ( to_master ) + if ( to_slave ) { erro_print("Invalid IdRequest direction..."); } @@ -580,11 +584,11 @@ 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_master ) +uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) { dbug_print("ScanCode"); // Check the directionality - if ( !to_master ) + if ( to_slave ) { erro_print("Invalid ScanCode direction..."); } @@ -592,12 +596,13 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t // Master node, trigger scan codes if ( Connect_master ) switch ( (*pending_bytes)-- ) { + // Byte count always starts at 0xFFFF case 0xFFFF: // Device Id Connect_receive_ScanCodeDeviceId = byte; break; case 0xFFFE: // Number of TriggerGuides in bytes (byte * 3) - *pending_bytes = byte * 3; + *pending_bytes = byte * sizeof( TriggerGuide ); Connect_receive_ScanCodeBufferPos = 0; break; @@ -605,12 +610,32 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t // Set the specific TriggerGuide entry ((uint8_t*)&Connect_receive_ScanCodeBuffer)[ Connect_receive_ScanCodeBufferPos++ ] = byte; - // Reset the BufferPos if higher than 3 + // Reset the BufferPos if higher than sizeof TriggerGuide // And send the TriggerGuide to the Macro Module - if ( Connect_receive_ScanCodeBufferPos > 3 ) + if ( Connect_receive_ScanCodeBufferPos > sizeof( TriggerGuide ) ) { Connect_receive_ScanCodeBufferPos = 0; - Macro_triggerState( &Connect_receive_ScanCodeBuffer, 1 ); + + // Adjust ScanCode offset + if ( Connect_receive_ScanCodeDeviceId > 0 ) + { + // 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 ); + + // Send ScanCode to macro module + // TODO + //Macro_triggerState( &Connect_receive_ScanCodeBuffer, 1 ); } break; @@ -618,6 +643,7 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t // Propagate ScanCode packet else switch ( (*pending_bytes)-- ) { + // Byte count always starts at 0xFFFF case 0xFFFF: // Device Id { Connect_receive_ScanCodeDeviceId = byte; @@ -630,8 +656,8 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t Connect_addBytes( header, sizeof( header ), 1 ); // Master break; } - case 0xFFFE: // Number of TriggerGuides in bytes (byte * 3) - *pending_bytes = byte * 3; + case 0xFFFE: // Number of TriggerGuides in bytes + *pending_bytes = byte * sizeof( TriggerGuide ); Connect_receive_ScanCodeBufferPos = 0; // Pass through byte @@ -652,7 +678,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_master ) +uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_t to_slave ) { dbug_print("Animation"); return 1; diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index c2daca5..1b752e6 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -148,8 +148,17 @@ typedef struct RemoteInputCommand { +// ----- Variables ----- + +extern uint8_t Connect_id; +extern uint8_t Connect_master; // Set if master + + + // ----- Functions ----- void Connect_setup( uint8_t master ); void Connect_scan(); +void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ); + From a8caf6e51537e09478a93339e73292913a05e0a8 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 15 Aug 2015 21:53:59 -0700 Subject: [PATCH 19/79] 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 --- Lib/CMake/kll.cmake | 1 - Macro/PartialMap/macro.c | 134 +++++++++++++- Macro/PartialMap/macro.h | 2 +- Scan/MDErgo1/defaultMap.kll | 4 +- Scan/UARTConnect/connect_scan.c | 319 ++++++++++++++++++++++---------- Scan/UARTConnect/connect_scan.h | 1 + 6 files changed, 349 insertions(+), 112 deletions(-) diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index f41b92a..36802e4 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -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 ) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 3122519..89444dc 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -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( ¯oTriggerListBuffer[ 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 ) { diff --git a/Macro/PartialMap/macro.h b/Macro/PartialMap/macro.h index a165a45..eae77dd 100644 --- a/Macro/PartialMap/macro.h +++ b/Macro/PartialMap/macro.h @@ -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(); diff --git a/Scan/MDErgo1/defaultMap.kll b/Scan/MDErgo1/defaultMap.kll index 94038e8..1f96cb5 100644 --- a/Scan/MDErgo1/defaultMap.kll +++ b/Scan/MDErgo1/defaultMap.kll @@ -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 */ diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 89bb772..8b647ac 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -33,11 +33,20 @@ // ----- 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"); diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index 1b752e6..bb50610 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -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 From 59c14fcdea7403288dab85b64b66c6daaa8404fc Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 16 Aug 2015 12:27:12 -0700 Subject: [PATCH 20/79] Adding initial WhiteFox support. - Includes fix for over-range ScanCodes (would cause hard faults) - Updated some documentation - Requires recent kll compiler for the layout --- Keyboards/README.markdown | 1 + Keyboards/whitefox.bash | 72 +++++++++++++++++++ Macro/PartialMap/macro.c | 32 ++++++++- README.markdown | 4 +- Scan/WhiteFox/defaultMap.kll | 129 +++++++++++++++++++++++++++++++++++ Scan/WhiteFox/matrix.h | 56 +++++++++++++++ Scan/WhiteFox/pinout | 112 ++++++++++++++++++++++++++++++ Scan/WhiteFox/scan_loop.c | 92 +++++++++++++++++++++++++ Scan/WhiteFox/scan_loop.h | 40 +++++++++++ Scan/WhiteFox/setup.cmake | 31 +++++++++ 10 files changed, 566 insertions(+), 3 deletions(-) create mode 100755 Keyboards/whitefox.bash create mode 100644 Scan/WhiteFox/defaultMap.kll create mode 100644 Scan/WhiteFox/matrix.h create mode 100644 Scan/WhiteFox/pinout create mode 100644 Scan/WhiteFox/scan_loop.c create mode 100644 Scan/WhiteFox/scan_loop.h create mode 100644 Scan/WhiteFox/setup.cmake diff --git a/Keyboards/README.markdown b/Keyboards/README.markdown index c9c93fa..ff8e60c 100644 --- a/Keyboards/README.markdown +++ b/Keyboards/README.markdown @@ -29,6 +29,7 @@ Projects * infinity.bash (Infinity Keyboard 2014/10/15) * template.bash (Example template for new keyboards) +* whitefox.bash (Soon?) **Extra files** diff --git a/Keyboards/whitefox.bash b/Keyboards/whitefox.bash new file mode 100755 index 0000000..c5ff835 --- /dev/null +++ b/Keyboards/whitefox.bash @@ -0,0 +1,72 @@ +#!/bin/bash +# This is a build script template +# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) +# Jacob Alexander 2015 + + + +################# +# Configuration # +################# + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="WhiteFox" + +## KLL Configuration ## + +# Generally shouldn't be changed, this will affect every layer +BaseMap="defaultMap" + +# This is the default layer of the keyboard +# NOTE: To combine kll files into a single layout, separate them by spaces +# e.g. DefaultMap="mylayout mylayoutmod" +DefaultMap="stdFuncMap" + +# This is where you set the additional layers +# NOTE: Indexing starts at 1 +# NOTE: Each new layer is another array entry +# e.g. PartialMaps[1]="layer1 layer1mod" +# PartialMaps[2]="layer2" +# PartialMaps[3]="layer3" +PartialMaps[1]="whitefox" + + + +########################## +# Advanced Configuration # +########################## + +# Don't change the variables in this section unless you know what you're doing +# These are useful for completely custom keyboards +# NOTE: Changing any of these variables will require a force build to compile correctly + +# Keyboard Module Configuration +ScanModule="WhiteFox" +MacroModule="PartialMap" +OutputModule="pjrcUSB" +DebugModule="full" + +# Microcontroller +Chip="mk20dx256vlh7" + +# Compiler Selection +Compiler="gcc" + + + +######################## +# Bash Library Include # +######################## + +# Shouldn't need to touch this section + +# Check if the library can be found +if [ ! -f cmake.bash ]; then + echo "ERROR: Cannot find 'cmake.bash'" + exit 1 +fi + +# Load the library +source cmake.bash + diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 89444dc..8cebce4 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -456,7 +456,7 @@ inline void Macro_interconnectAdd( void *trigger_ptr ) case 0x03: break; default: - erro_print("Invalid key state"); + erro_msg("Invalid key state - "); error = 1; break; } @@ -464,11 +464,18 @@ inline void Macro_interconnectAdd( void *trigger_ptr ) // Invalid TriggerGuide type default: - erro_print("Invalid type"); + erro_msg("Invalid type - "); error = 1; break; } + // Check if ScanCode is out of range + if ( scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined - "); + error = 1; + } + // Display TriggerGuide if ( error ) { @@ -529,6 +536,15 @@ inline void Macro_keyState( uint8_t scanCode, uint8_t state ) case 0x01: // Pressed case 0x02: // Held case 0x03: // Released + // Check if ScanCode is out of range + if ( scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined: "); + printHex( scanCode ); + print( NL ); + return; + } + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x00; // Normal key @@ -549,6 +565,15 @@ inline void Macro_analogState( uint8_t scanCode, uint8_t state ) // TODO Handle change for interconnect if ( state != 0x00 ) { + // Check if ScanCode is out of range + if ( scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined: "); + printHex( scanCode ); + print( NL ); + return; + } + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x02; // Analog key @@ -567,6 +592,9 @@ inline void Macro_ledState( uint8_t ledCode, uint8_t state ) // TODO Handle change for interconnect if ( state != 0x00 ) { + // Check if LedCode is out of range + // TODO + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = ledCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x01; // LED key diff --git a/README.markdown b/README.markdown index 90e44aa..f020072 100644 --- a/README.markdown +++ b/README.markdown @@ -12,7 +12,9 @@ Please refer to the [KLL](https://github.com/kiibohd/kll) repo or [kiibohd.com]( Official Keyboards ------------------ -* MD1 (Infinity Keyboard 2014/10/15) +* MD1 (Infinity Keyboard/IC60 2014/10/15) +* MDErgo1 (Infinity Ergodox /ICED 2015/03/31) +* WhiteFox (Soon to be released?) The Kiibohd firmware supports a lot of other keyboards, but these are more obscure/custom/lesser known. diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll new file mode 100644 index 0000000..474d8ba --- /dev/null +++ b/Scan/WhiteFox/defaultMap.kll @@ -0,0 +1,129 @@ +Name = WhiteFox; +Version = 0.2; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-08-16; + + +S0x00 : U"Esc"; +S0x01 : U"1"; +S0x02 : U"2"; +S0x03 : U"3"; +S0x04 : U"4"; +S0x05 : U"5"; +S0x06 : U"6"; +S0x07 : U"7"; +S0x08 : U"8"; +S0x09 : U"9"; +S0x0A : U"0"; +S0x0B : U"Minus"; +S0x0C : U"Equal"; +S0x0D : U"Hash"; +S0x0E : U"Backspace"; +S0x0F : U"BackTick"; +S0x10 : U"Tab"; +S0x11 : U"Q"; +S0x12 : U"W"; +S0x13 : U"E"; +S0x14 : U"R"; +S0x15 : U"T"; +S0x16 : U"Y"; +S0x17 : U"U"; +S0x18 : U"I"; +S0x19 : U"O"; +S0x1A : U"P"; +S0x1B : U"LBrace"; +S0x1C : U"RBrace"; +S0x1D : U"Backslash"; +S0x1E : U"Delete"; +S0x1F : U"CapsLock"; +S0x20 : U"A"; +S0x21 : U"S"; +S0x22 : U"D"; +S0x23 : U"F"; +S0x24 : U"G"; +S0x25 : U"H"; +S0x26 : U"J"; +S0x27 : U"K"; +S0x28 : U"L"; +S0x29 : U"Semicolon"; +S0x2A : U"Quote"; +S0x2B : U"App"; +S0x2C : U"Enter"; +S0x2D : U"PageUp"; +S0x2E : U"LShift"; +S0x2F : U"ISO Slash"; +S0x30 : U"Z"; +S0x31 : U"X"; +S0x32 : U"C"; +S0x33 : U"V"; +S0x34 : U"B"; +S0x35 : U"N"; +S0x36 : U"M"; +S0x37 : U"Comma"; +S0x38 : U"Period"; +S0x39 : U"Slash"; +S0x3A : U"RShift"; +S0x3B : U"Up"; +S0x3C : U"PageDown"; +S0x3D : U"Ctrl"; +S0x3E : U"Function1"; +S0x3F : U"LAlt"; +S0x40 : U"Space"; +S0x41 : U"RAlt"; +S0x42 : U"Gui"; +S0x43 : U"Menu"; +S0x44 : U"Left"; +S0x45 : U"Down"; +S0x46 : U"Right"; + + +# Defines available to the WhiteFox Scan Module + +# LED Default Enable Mask Override +# +# Each LED is represented by a single bit +# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details +ISSILedMask1 = " + 0xFF, 0x00, /* C1-1 -> C1-16 */ + 0xFF, 0x00, /* C2-1 -> C2-16 */ + 0xFF, 0x00, /* C3-1 -> C3-16 */ + 0xFF, 0x00, /* C4-1 -> C4-16 */ + 0xFF, 0x00, /* C5-1 -> C5-16 */ + 0xFF, 0x00, /* C6-1 -> C6-16 */ + 0xFF, 0x00, /* C7-1 -> C7-16 */ + 0xFF, 0x00, /* C8-1 -> C8-16 */ + 0xFE, 0x00, /* C9-1 -> C9-16 */ +"; + +# LED Brightness Override +# +# Each LED channel supports 256 levels (8-bit control) +# By default, LEDs are set to 0 brightness +ISSILedBrightness1 = " +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + +# Full brightness example +#ISSILedBrightness1 = " +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +#"; + diff --git a/Scan/WhiteFox/matrix.h b/Scan/WhiteFox/matrix.h new file mode 100644 index 0000000..f2037e0 --- /dev/null +++ b/Scan/WhiteFox/matrix.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Project Includes +#include + + + +// ----- Matrix Definition ----- + +// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 +// Not all chips have access to all of these pins (most don't have 160 pins :P) +// +// NOTE: +// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down +// Checking this is completely on the ownness of the user + +// MDErgo1 +// +// Column (Strobe) - 9 Total +// PTB2,3,18,19 +// PTC0,9..11 +// PTD0 +// +// Rows (Sense) - 5 Total +// PTD1,4..7 + +// Define Rows (Sense) and Columns (Strobes) +GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11) }; +GPIO_Pin Matrix_rows[] = { gpio(D,0), gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2) }; + +// Define type of scan matrix +Config Matrix_type = Config_Pulldown; + diff --git a/Scan/WhiteFox/pinout b/Scan/WhiteFox/pinout new file mode 100644 index 0000000..cb2f687 --- /dev/null +++ b/Scan/WhiteFox/pinout @@ -0,0 +1,112 @@ +Pin Usage +========= + +mk20dx256vlh7 + + ---- +|Keys| + ---- + +* Strobe (Columns) + +PTB2 +PTB3 +PTB18 +PTB19 +PTC0 +PTC9 +PTC10 +PTC11 +PTD0 + +* Sense (Rows) + +PTD1 +PTD4 +PTD5 +PTD6 +PTD7 +PTC1 +PTC2 +PTC3 + + + ----- +|Clock| + ----- + +PTA18 <-> PTA19 + + + --- +|I2C| + --- + +* IS31FL3731C + +PTB0 - SCL0 (add header pin, label as SCL0) +PTB1 - SDA0 (add header pin, label as SDA0) +PTB17 - INTB Chip 1 +PTB16 - SDB (tied to all Chips, hardware shutdown) + + + + --- +|DAC| + --- + +DAC0 (N/C) + + + ---- +|UART| + ---- + +* Comm - For bi-directional communication between halves + +PTA1 - RX0 (Master Side) +PTA2 - TX0 (Master Side) + +PTD2 - RX2 (UART Debug Header) +PTD3 - TX2 (UART Debug Header) + + + ----- +|Debug| + ----- + +* SWD - (Main reflash header) + +PTA0 (Pull-down) +PTA3 (Pull-up) + +* LEDs + +PTA5 (LED only for PCB, not Teensy) + +* UARTs + +PTD2 - RX2 (UART Debug Header, label as RX2) +PTD3 - TX2 (UART Debug Header, label as TX2) + + + ------ +|Unused| + ------ + +* GPIO + +PTA4 +PTA12 +PTA13 +PTC4 +PTC5 +PTC6 +PTC7 +PTE0 +PTE1 + +* Analog + +TODO + diff --git a/Scan/WhiteFox/scan_loop.c b/Scan/WhiteFox/scan_loop.c new file mode 100644 index 0000000..16cefa2 --- /dev/null +++ b/Scan/WhiteFox/scan_loop.c @@ -0,0 +1,92 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include +#include +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Function Declarations ----- + +// ----- Variables ----- + +// Number of scans since the last USB send +uint16_t Scan_scanCount = 0; + + + +// ----- Functions ----- + +// Setup +inline void Scan_setup() +{ + // Setup GPIO pins for matrix scanning + Matrix_setup(); + + // Setup ISSI chip to control the leds + LED_setup(); + + // Reset scan count + Scan_scanCount = 0; +} + + +// Main Detection Loop +inline uint8_t Scan_loop() +{ + // Scan Matrix + Matrix_scan( Scan_scanCount++ ); + + // Process any LED events + LED_scan(); + + return 0; +} + + +// Signal from Macro Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithMacro( uint8_t sentKeys ) +{ +} + + +// Signal from Output Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithOutput( uint8_t sentKeys ) +{ + // Reset scan loop indicator (resets each key debounce state) + // TODO should this occur after USB send or Macro processing? + Scan_scanCount = 0; +} + diff --git a/Scan/WhiteFox/scan_loop.h b/Scan/WhiteFox/scan_loop.h new file mode 100644 index 0000000..17a06fc --- /dev/null +++ b/Scan/WhiteFox/scan_loop.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Functions ----- + +// Functions to be called by main.c +void Scan_setup( void ); +uint8_t Scan_loop( void ); + +// Call-backs +void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module +void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + diff --git a/Scan/WhiteFox/setup.cmake b/Scan/WhiteFox/setup.cmake new file mode 100644 index 0000000..9860b1a --- /dev/null +++ b/Scan/WhiteFox/setup.cmake @@ -0,0 +1,31 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Sub-modules +# +AddModule ( Scan ISSILed ) +AddModule ( Scan MatrixARM ) + + +### +# Module C files +# +set ( Module_SRCS + scan_loop.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + From 398018ecf86bac3174d40b8cfb7d7321130759db Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 16 Aug 2015 14:46:26 -0700 Subject: [PATCH 21/79] Adding examples of custom action/capabilties - See md1Action.kll for usage - Includes Block/Unblock --- Scan/MD1/defaultMap.kll | 20 ++++++++--- Scan/MD1/scan_loop.c | 77 +++++++++++++++++++++++++++++++++++++++++ Scan/MD1/scan_loop.h | 8 +++++ 3 files changed, 101 insertions(+), 4 deletions(-) diff --git a/Scan/MD1/defaultMap.kll b/Scan/MD1/defaultMap.kll index c53aeac..b2eb8e5 100644 --- a/Scan/MD1/defaultMap.kll +++ b/Scan/MD1/defaultMap.kll @@ -1,10 +1,10 @@ Name = MD1; -Version = 0.2; -Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3; +Version = 0.3; +Author = "HaaTa (Jacob Alexander) 2014-2015"; +KLL = 0.3c; # Modified Date -Date = 2014-09-14; +Date = 2015-08-16; S0x00 : U"Esc"; @@ -71,3 +71,15 @@ S0x3C : U"RAlt"; S0x3D : U"Function3"; # Right Blank Key 1 S0x3E : U"Function4"; # Right Blank Key 2 + +# Custom Action Examples + +# Example capability, prints to cli +action1 => CustomAction_action1_capability(); # No arguments + +# Blocks given USB Code, must be used with blockLink +# Simple example, supports only blocking a single key at a time +# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h +blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument +blockKey => CustomAction_blockKey_capability( usbCode : 1 ); + diff --git a/Scan/MD1/scan_loop.c b/Scan/MD1/scan_loop.c index f908f39..02d6326 100644 --- a/Scan/MD1/scan_loop.c +++ b/Scan/MD1/scan_loop.c @@ -98,6 +98,83 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys ) } + +// ----- Capabilities ----- + +// Custom capability examples +// Refer to kll.h in Macros/PartialMap for state and stateType information +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + // XXX This is required for debug cli to give you a list of capabilities + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_action1_capability()"); + return; + } + + // Prints Action1 info message to the debug cli + info_print("Action1"); +} + +uint8_t CustomAction_blockHold_storage = 0; +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockHold_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // We only care about normal keys + if ( stateType == 0x00 ) + { + // Block given key if we're in the "Press" or "Hold" state + if ( ( state == 0x01 || state == 0x02 ) + && CustomAction_blockHold_storage == 0 ) + { + CustomAction_blockHold_storage = key; + info_msg("Blocking Key: "); + printHex( key ); + print( NL ); + } + // Release if in the "Off" or "Release" state and we're blocking + else if ( ( state == 0x00 || state == 0x03 ) + && key == CustomAction_blockHold_storage ) + { + info_msg("Unblocking Key: "); + printHex( CustomAction_blockHold_storage ); + print( NL ); + CustomAction_blockHold_storage = 0; + } + } +} + +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockKey_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // If key is not blocked, process + if ( key != CustomAction_blockHold_storage ) + { + Output_usbCodeSend_capability( state, stateType, &key ); + } +} + + + // ----- CLI Command Functions ----- // XXX Just an example command showing how to parse arguments (more complex than generally needed) diff --git a/Scan/MD1/scan_loop.h b/Scan/MD1/scan_loop.h index 17a06fc..0c89838 100644 --- a/Scan/MD1/scan_loop.h +++ b/Scan/MD1/scan_loop.h @@ -38,3 +38,11 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + +// ----- Capabilities ----- + +// Example capabilities +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + From 79ee501e03a6ea1ee84f33c23a45b8fdc3873f43 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 16 Aug 2015 15:53:07 -0700 Subject: [PATCH 22/79] Fixing typo on range check for MDErgo1 --- Macro/PartialMap/macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 8cebce4..f6c70ed 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -470,7 +470,7 @@ inline void Macro_interconnectAdd( void *trigger_ptr ) } // Check if ScanCode is out of range - if ( scanCode > MaxScanCode ) + if ( trigger->scanCode > MaxScanCode ) { warn_msg("ScanCode is out of range/not defined - "); error = 1; From 35185928938b33d67a0c80f051cd7dbf96b63150 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 15 Aug 2015 23:45:23 -0700 Subject: [PATCH 23/79] Updating convenience scripts --- Keyboards/README.markdown | 1 + Keyboards/ergodox.bash | 72 +++++++++++++++++++++++++++++++++++++++ Keyboards/infinity.bash | 2 +- 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100755 Keyboards/ergodox.bash diff --git a/Keyboards/README.markdown b/Keyboards/README.markdown index ff8e60c..9240c18 100644 --- a/Keyboards/README.markdown +++ b/Keyboards/README.markdown @@ -28,6 +28,7 @@ Projects -------- * infinity.bash (Infinity Keyboard 2014/10/15) +* ergodox.bash (Infinity Ergodox 2015/08/15) * template.bash (Example template for new keyboards) * whitefox.bash (Soon?) diff --git a/Keyboards/ergodox.bash b/Keyboards/ergodox.bash new file mode 100755 index 0000000..0fe0f29 --- /dev/null +++ b/Keyboards/ergodox.bash @@ -0,0 +1,72 @@ +#!/bin/bash +# This is a build script template +# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) +# Jacob Alexander 2015 + + + +################# +# Configuration # +################# + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="ICED" + +## KLL Configuration ## + +# Generally shouldn't be changed, this will affect every layer +BaseMap="defaultMap leftHand slave1 rightHand" + +# This is the default layer of the keyboard +# NOTE: To combine kll files into a single layout, separate them by spaces +# e.g. DefaultMap="mylayout mylayoutmod" +DefaultMap="stdFuncMap" + +# This is where you set the additional layers +# NOTE: Indexing starts at 1 +# NOTE: Each new layer is another array entry +# e.g. PartialMaps[1]="layer1 layer1mod" +# PartialMaps[2]="layer2" +# PartialMaps[3]="layer3" +PartialMaps[1]="hhkbpro2" + + + +########################## +# Advanced Configuration # +########################## + +# Don't change the variables in this section unless you know what you're doing +# These are useful for completely custom keyboards +# NOTE: Changing any of these variables will require a force build to compile correctly + +# Keyboard Module Configuration +ScanModule="MDErgo1" +MacroModule="PartialMap" +OutputModule="pjrcUSB" +DebugModule="full" + +# Microcontroller +Chip="mk20dx256vlh7" + +# Compiler Selection +Compiler="gcc" + + + +######################## +# Bash Library Include # +######################## + +# Shouldn't need to touch this section + +# Check if the library can be found +if [ ! -f cmake.bash ]; then + echo "ERROR: Cannot find 'cmake.bash'" + exit 1 +fi + +# Load the library +source cmake.bash + diff --git a/Keyboards/infinity.bash b/Keyboards/infinity.bash index 259183f..bc3c0ac 100755 --- a/Keyboards/infinity.bash +++ b/Keyboards/infinity.bash @@ -11,7 +11,7 @@ # Feel free to change the variables in this section to configure your keyboard -BuildPath="template" +BuildPath="IC60" ## KLL Configuration ## From c0fb084eb4624b71d5761edd49a0dd987dbaf25f Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 18 Aug 2015 01:10:44 -0700 Subject: [PATCH 24/79] Adding basic support for LCDLayerDisplay using capabilities - Requires lcdFuncMap.kll instead of stdFuncMap.kll --- Scan/STLcd/capabilities.kll | 11 +++++ Scan/STLcd/lcd_scan.c | 89 ++++++++++++++++++++++++++++++++++++ Scan/STLcd/numbers/0.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/1.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/2.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/3.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/4.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/5.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/6.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/7.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/8.bmp | Bin 0 -> 4234 bytes Scan/STLcd/numbers/9.bmp | Bin 0 -> 4234 bytes 12 files changed, 100 insertions(+) create mode 100644 Scan/STLcd/numbers/0.bmp create mode 100644 Scan/STLcd/numbers/1.bmp create mode 100644 Scan/STLcd/numbers/2.bmp create mode 100644 Scan/STLcd/numbers/3.bmp create mode 100644 Scan/STLcd/numbers/4.bmp create mode 100644 Scan/STLcd/numbers/5.bmp create mode 100644 Scan/STLcd/numbers/6.bmp create mode 100644 Scan/STLcd/numbers/7.bmp create mode 100644 Scan/STLcd/numbers/8.bmp create mode 100644 Scan/STLcd/numbers/9.bmp diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index 49319d2..62d52c0 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -63,3 +63,14 @@ STLcdDefaultImage = " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "; + +# Layer Status Display + +LCDLayerDisplay => LCD_layerStack_capability(); + + +# LCD Module Enabled + +LCDEnabled => LCDEnabled_define; +LCDEnabled = 1; + diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index a7d7d44..639920b 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -342,6 +342,95 @@ inline uint8_t LCD_scan() +// ----- Capabilities ----- + +uint16_t LCD_layerStack_prevSize = 0; +void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("LCD_layerStack_capability"); + return; + } + + // Parse the layer stack, top to bottom + extern uint16_t macroLayerIndexStack[]; + extern uint16_t macroLayerIndexStackSize; + + // Only process if the stack size has changed + if ( macroLayerIndexStackSize == LCD_layerStack_prevSize ) + { + return; + } + LCD_layerStack_prevSize = macroLayerIndexStackSize; + + // Number data for LCD + const uint8_t numbers[10][128] = { + { STLcdNumber0_define }, + { STLcdNumber1_define }, + { STLcdNumber2_define }, + { STLcdNumber3_define }, + { STLcdNumber4_define }, + { STLcdNumber5_define }, + { STLcdNumber6_define }, + { STLcdNumber7_define }, + { STLcdNumber8_define }, + { STLcdNumber9_define }, + }; + + // Only display if there are layers active + if ( macroLayerIndexStackSize > 0 ) + { + + // Iterate through each of the pages + // XXX Many of the values here are hard-coded + // Eventually a proper font rendering engine should take care of things like this... -HaaTa + for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) + { + // Set the register page + LCD_writeControlReg( 0xB0 | ( 0x0F & page ) ); + + // Set starting address + LCD_writeControlReg( 0x10 ); + LCD_writeControlReg( 0x00 ); + + // Write data + for ( uint16_t layer = 1; layer <= macroLayerIndexStackSize; layer++ ) + { + uint16_t layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - layer ]; + + // Default to 0, if over 9 + if ( layerIndex > 9 ) + { + layerIndex = 0; + } + + // Write page of number to display + SPI_write( (uint8_t*)&numbers[ layerIndex ][ page * 32 ], 32 ); + } + + // Blank out rest of display + uint8_t data = 0; + for ( uint8_t c = 0; c < 4 - macroLayerIndexStackSize; c++ ) + { + for ( uint8_t byte = 0; byte < 32; byte++ ) + { + SPI_write( &data, 1 ); + } + } + } + } + else + { + // Write default image + for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) + LCD_writeDisplayReg( page, (uint8_t *)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); + } +} + + + // ----- CLI Command Functions ----- void cliFunc_lcdInit( char* args ) diff --git a/Scan/STLcd/numbers/0.bmp b/Scan/STLcd/numbers/0.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9eb7e67e8b25d15fc6a84f026e32052c2e39b16a GIT binary patch literal 4234 zcmeH_p>6^}6h((XNLoeG)NW7&-PIUORYj}O`vbLD3 z35pHVH*c#D-N|7>sJ&c5>9pWMLx{{R2| zCs%~F?miua_8mt#<%5(kFxjtV$OM4tI_v-BWrE~f6S=!@xxmRb`FP+Pm&(a>pOTA|p?vtPZ literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/1.bmp b/Scan/STLcd/numbers/1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c203d1a0f1fb69bf0f1aa2e9dbc055c9a8ec8f66 GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5kO)9p@L>{-BUw2>e%uNH6~YY+VRs literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/2.bmp b/Scan/STLcd/numbers/2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..07b5e85fedf280b6c8550b99f25a876b8a802852 GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z8vfYRKT;6Ul!+_+X=*8w;iLAC#y_?+fRsdN%EV?jEyQqnf);jRGjr5_>>+?HtY{&I z-S+=_+XUPY8^L|In&Wam5$4#c`!RYTJX$yixnHhXAhdqP948+Xtrp F0RR~8lb`?q literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/3.bmp b/Scan/STLcd/numbers/3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7ec47ce678ba6340f992e918f4027eb90ea8b561 GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z(!(DqD5%236`oWvoCrfk?Z;l85fOA$Q8F6-)CqrF;YhAHsgX;rJ-GCZ+D}>t;0i}_ z#YwaMKh@hrq}oredR*Z{u6d;D8?~Q0Yp%RF>@ nVSHTbsVxq(51ppAJ-Ez6w-?68rJma2F#FJHYTJX$JY;(TVg3I! literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/4.bmp b/Scan/STLcd/numbers/4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd3bc5f017dcdd328311bbf3ae3da99ca2dd2a9d GIT binary patch literal 4234 zcmeH{u?_)27=-t7BB7Fq_M(!jU9Him6x8Z_0j*Y}QQw=Wy@ZEQtJy>1pJX;M$!>QW zEB}nS`8dmReHyvDZx!Uf}*GIXz6qDk3&#I~# z*L6MfyWcd;U@^SqfyVN~;Q zF%fE?nkPuG)IK#2Fe21GHBXRWseNi5U__{WYMvm$Qv1|Az=%-$)I33grS_?LfDxhg dsd<6~OYKwh03$-}Q}YA~mfEN00Y=0>eJ_U%ch~>` literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/5.bmp b/Scan/STLcd/numbers/5.bmp new file mode 100644 index 0000000000000000000000000000000000000000..545747fa76867000508a789461fdd7079e2b9b94 GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z(!(DqD5%236`oWvoCrfk?Z;l85fOA$Q8F6-q=i4O@S?UjuE?dfJ-EypwI6#3;0iBl zi(|L_KV8~BAiv-OxcrGrJ+;M0?I*3g8V!HyhQMG=f4JO5t~jnxBiB4q^^Mw(Jp@P% NM{?C;w|!vh9{?Eclb`?q literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/6.bmp b/Scan/STLcd/numbers/6.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5f7a3c1c934531b35cbab905a5cdc4b97c938cd6 GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z8vfYRKT;5p#KaYzxC|jxJuY)#;-s2Ks(P3`xM)(%BUL>vdtu_Fnn$X7m_4{?Qq3b( zJuZ7;;-s2Ks(P3`xM)(%!=;|u;-tEF)PC&cBDvu*8vfWr09SZoS51Ap@&Z`6M5AwX(4lB*usb^x@c79Icq literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/7.bmp b/Scan/STLcd/numbers/7.bmp new file mode 100644 index 0000000000000000000000000000000000000000..24d55972e59d97f0fcb58500af983879a748839d GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5&=7!($A)QWC5qA5?544oN9{)n zfzj|EP5;=^08$d6DHEIBqxqkvMLtS=(j)wF*?~_S#gPhuFJ-EypwI6#3;0iBli(|L_Ki0l7we1F(hYSD31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z8vfYRKT;5p#KaYzxC|jxJuY)#;-s2Ks(P3`xM)(%BUL>vdtu_Fnn$X7m_4{?Qq3b( zJuZ7;;-s2Ks(P3`xM)(%!=;|u;-tEF)PC&cBDvu*8vfWr09SZoS4~)yRP#txPsjzN znn$YoQTy?S0IA_gs(Spk|Hs*vz@=}n+K>+?Fyr?aX-FDph Ig_iaM0Ei@*jQ{`u literal 0 HcmV?d00001 diff --git a/Scan/STLcd/numbers/9.bmp b/Scan/STLcd/numbers/9.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1a0bcdc9917e5ed44312f4e0369ad50e369e6b2f GIT binary patch literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8vc@Pr;{xdK@5J>31lY3Bc|DmrMfji_x^fNH9Aag*5AOR4U9vI0=6ed0FM)UHh{YW7& z(!(DqD5%236`oWvoCrfk?Z;l85fOA$Q8F6-q=i4O@S?UjuE?dfJ-EypwI6#3;0iBl zi(|L_KV8~BAiv-OxcrGrJt1*Y%_CL)sQvgufYk6LRXu*&ai?co`bO=?USHt~7jnf( d4S#a&!KH81e(WKDE4-*Jj@@?L`IVOT0|4w^79Icq literal 0 HcmV?d00001 From ef7da32d123bd389bdb786670540f311272900d4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 18 Aug 2015 10:46:55 -0700 Subject: [PATCH 25/79] Adding color association to layers --- Scan/STLcd/lcd_scan.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index 639920b..fcd487e 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -379,9 +379,28 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args { STLcdNumber9_define }, }; + // Color data for numbers + const uint16_t colors[10][3] = { + { STLcdNumber0Color_define }, + { STLcdNumber1Color_define }, + { STLcdNumber2Color_define }, + { STLcdNumber3Color_define }, + { STLcdNumber4Color_define }, + { STLcdNumber5Color_define }, + { STLcdNumber6Color_define }, + { STLcdNumber7Color_define }, + { STLcdNumber8Color_define }, + { STLcdNumber9Color_define }, + }; + // Only display if there are layers active if ( macroLayerIndexStackSize > 0 ) { + // Set the color according to the "top-of-stack" layer + uint16_t layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - 1 ]; + FTM0_C0V = colors[ layerIndex ][0]; + FTM0_C1V = colors[ layerIndex ][1]; + FTM0_C2V = colors[ layerIndex ][2]; // Iterate through each of the pages // XXX Many of the values here are hard-coded @@ -398,7 +417,7 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args // Write data for ( uint16_t layer = 1; layer <= macroLayerIndexStackSize; layer++ ) { - uint16_t layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - layer ]; + layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - layer ]; // Default to 0, if over 9 if ( layerIndex > 9 ) @@ -423,6 +442,11 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args } else { + // Set default backlight + FTM0_C0V = STLcdBacklightRed_define; + FTM0_C1V = STLcdBacklightGreen_define; + FTM0_C2V = STLcdBacklightBlue_define; + // Write default image for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ ) LCD_writeDisplayReg( page, (uint8_t *)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN ); From 20b62afb9a05a64b1f15c6329866600913775eea Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 19 Aug 2015 00:01:15 -0700 Subject: [PATCH 26/79] FIxing Media Keys and general USB compatibilty - Media keys tested working on Linux/Windows/Mac (use Consumer control) - Fixed enumeration delays - Fixed virtual serial port configuration issues - Fixed GET_REPORT and SET_REPORT - Added intial descriptors and endpoints for Mouse and Joystick devices - Split out the consumer and system control endpoint - Added more fault debugging messages - Added interface names to endpoints (visible in Windows Device Manager) - Added KLL define for keyboard locale --- Lib/mk20dx.c | 21 +++- Lib/mk20dx.h | 4 +- Output/pjrcUSB/arm/usb_desc.c | 201 ++++++++++++++++++++++++------ Output/pjrcUSB/arm/usb_desc.h | 22 +++- Output/pjrcUSB/arm/usb_dev.c | 78 ++++++++---- Output/pjrcUSB/arm/usb_keyboard.c | 105 +++++++++------- Output/pjrcUSB/capabilities.kll | 8 +- Output/pjrcUSB/setup.cmake | 2 + 8 files changed, 328 insertions(+), 113 deletions(-) diff --git a/Lib/mk20dx.c b/Lib/mk20dx.c index 47759a4..ec6908c 100644 --- a/Lib/mk20dx.c +++ b/Lib/mk20dx.c @@ -106,28 +106,41 @@ void nmi_default_isr() // NVIC - Hard Fault ISR void hard_fault_default_isr() { - print("Hard Fault!" NL ); + print("Hard Fault! SCB_HFSR: "); + printHex32( SCB_HFSR ); + print( NL ); + SOFTWARE_RESET(); } // NVIC - Memory Manager Fault ISR void memmanage_fault_default_isr() { - print("Memory Manager Fault!" NL ); + print("Memory Manager Fault! SCB_CFSR: "); + printHex32( SCB_CFSR ); + print(" SCB_MMAR: "); + printHex32( SCB_MMAR ); + print( NL ); } // NVIC - Bus Fault ISR void bus_fault_default_isr() { - print("Bus Fault!" NL ); + print("Bus Fault! SCB_CFSR: "); + printHex32( SCB_CFSR ); + print(" SCB_BFAR: "); + printHex32( SCB_BFAR ); + print( NL ); } // NVIC - Usage Fault ISR void usage_fault_default_isr() { - print("Usage Fault!" NL ); + print("Usage Fault! SCB_CFSR: "); + printHex32( SCB_CFSR ); + print( NL ); } diff --git a/Lib/mk20dx.h b/Lib/mk20dx.h index aff530a..277cfed 100644 --- a/Lib/mk20dx.h +++ b/Lib/mk20dx.h @@ -1951,7 +1951,9 @@ typedef struct { #define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register #define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault Status #define SCB_DFSR *(volatile uint32_t *)0xE000ED30 // Debug Fault Status -#define SCB_MMFAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address +#define SCB_MMAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address +#define SCB_BFAR *(volatile uint32_t *)0xE000ED38 // BusFault Addreses Register +#define SCB_AFSR *(volatile uint32_t *)0xE000ED3C // Auxilary Fault Status Register #define SYST_CSR *(volatile uint32_t *)0xE000E010 // SysTick Control and Status #define SYST_CSR_COUNTFLAG (uint32_t)0x00010000 diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 0a44d5c..9616d45 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2013-2014) + * Modified by Jacob Alexander (2013-2015) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -34,6 +34,9 @@ // Local Includes #include "usb_desc.h" +// Generated Includes +#include + // ----- Macros ----- @@ -260,7 +263,10 @@ static uint8_t nkro_keyboard_report_desc[] = { 0x95, 0x01, // Report Count (1), 0x81, 0x03, // Input (Constant), 0xc0, // End Collection - Keyboard +}; +// System Control and Consumer Control +static uint8_t sys_ctrl_report_desc[] = { // System Control Collection // // NOTES: @@ -290,16 +296,15 @@ static uint8_t nkro_keyboard_report_desc[] = { 0x85, 0x03, // Report ID (3), 0x75, 0x10, // Report Size (16), 0x95, 0x01, // Report Count (1), - 0x16, 0x20, 0x00, // Logical Minimum (32), + 0x16, 0x01, 0x00, // Logical Minimum (1), 0x26, 0x9C, 0x02, // Logical Maximum (668), 0x05, 0x0C, // Usage Page (Consumer), - 0x19, 0x20, // Usage Minimum (32), + 0x19, 0x01, // Usage Minimum (1), 0x2A, 0x9C, 0x02, // Usage Maximum (668), 0x81, 0x00, // Input (Data, Array), 0xc0, // End Collection - Consumer Control }; -/* MOUSE // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension static uint8_t mouse_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) @@ -332,7 +337,52 @@ static uint8_t mouse_report_desc[] = { 0x81, 0x06, // Input (Data, Variable, Relative) 0xC0 // End Collection }; -*/ + +// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65 +static uint8_t joystick_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x04, // Usage (Joystick) + 0xA1, 0x01, // Collection (Application) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x20, // Report Count (32) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button #1) + 0x29, 0x20, // Usage Maximum (Button #32) + 0x81, 0x02, // Input (variable,absolute) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x07, // Logical Maximum (7) + 0x35, 0x00, // Physical Minimum (0) + 0x46, 0x3B, 0x01, // Physical Maximum (315) + 0x75, 0x04, // Report Size (4) + 0x95, 0x01, // Report Count (1) + 0x65, 0x14, // Unit (20) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x39, // Usage (Hat switch) + 0x81, 0x42, // Input (variable,absolute,null_state) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection () + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x04, // Report Count (4) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x09, 0x32, // Usage (Z) + 0x09, 0x35, // Usage (Rz) + 0x81, 0x02, // Input (variable,absolute) + 0xC0, // End Collection + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x02, // Report Count (2) + 0x09, 0x36, // Usage (Slider) + 0x09, 0x36, // Usage (Slider) + 0x81, 0x02, // Input (variable,absolute) + 0xC0 // End Collection +}; @@ -365,13 +415,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x03, // bInterfaceClass (0x03 = HID) 0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) 0x01, // bInterfaceProtocol (0x01 = Keyboard) - 0, // iInterface + KEYBOARD_INTERFACE + 4, // iInterface // - 9 bytes - // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID - 0, // bCountryCode + KeyboardLocale_define, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(keyboard_report_desc)), // wDescriptorLength @@ -396,13 +446,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) 0x01, // bInterfaceProtocol (0x01 = Keyboard) - 0, // iInterface + NKRO_KEYBOARD_INTERFACE + 4, // iInterface // - 9 bytes - // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength 0x21, // bDescriptorType 0x11, 0x01, // bcdHID - 0, // bCountryCode + KeyboardLocale_define, // bCountryCode 1, // bNumDescriptors 0x22, // bDescriptorType LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength @@ -426,7 +476,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x02, // bFunctionClass 0x02, // bFunctionSubClass 0x01, // bFunctionProtocol - 0, // iFunction + CDC_STATUS_INTERFACE + 4, // iFunction // --- Serial CDC --- CDC Data Interface // - 9 bytes - @@ -439,7 +489,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x02, // bInterfaceClass 0x02, // bInterfaceSubClass 0x01, // bInterfaceProtocol - 0, // iInterface + CDC_STATUS_INTERFACE + 4, // iInterface // - 5 bytes - // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 5, // bFunctionLength @@ -484,7 +534,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x0A, // bInterfaceClass 0x00, // bInterfaceSubClass 0x00, // bInterfaceProtocol - 0, // iInterface + CDC_DATA_INTERFACE + 4, // iInterface // - 7 bytes - // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 7, // bLength @@ -502,8 +552,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { CDC_TX_SIZE, 0, // wMaxPacketSize 0, // bInterval -/* -// Mouse Interface +// --- Mouse Interface --- // - 9 bytes - // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength @@ -513,8 +562,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 1, // bNumEndpoints 0x03, // bInterfaceClass (0x03 = HID) 0x00, // bInterfaceSubClass (0x01 = Boot) - 0x00, // bInterfaceProtocol (0x02 = Mouse) - 0, // iInterface + 0x02, // bInterfaceProtocol (0x02 = Mouse) + MOUSE_INTERFACE + 4, // iInterface // - 9 bytes - // HID interface descriptor, HID 1.11 spec, section 6.2.1 9, // bLength @@ -533,8 +582,68 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 0x03, // bmAttributes (0x03=intr) MOUSE_SIZE, 0, // wMaxPacketSize MOUSE_INTERVAL, // bInterval -#endif // MOUSE_INTERFACE -*/ + +// --- Joystick Interface --- +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + JOYSTICK_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + JOYSTICK_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(joystick_report_desc)), // wDescriptorLength + MSB(sizeof(joystick_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + JOYSTICK_SIZE, 0, // wMaxPacketSize + JOYSTICK_INTERVAL, // bInterval + +// --- System/Consumer Control --- +// - 9 bytes - + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + SYS_CTRL_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) + 0x00, // bInterfaceProtocol (0x00 = None) + SYS_CTRL_INTERFACE + 4, // iInterface +// - 9 bytes - + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + KeyboardLocale_define, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(sys_ctrl_report_desc)), // wDescriptorLength + MSB(sizeof(sys_ctrl_report_desc)), +// - 7 bytes - + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + SYS_CTRL_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + SYS_CTRL_SIZE, 0, // wMaxPacketSize + SYS_CTRL_INTERVAL, // bInterval }; @@ -564,21 +673,23 @@ struct usb_string_descriptor_struct string0 = { {0x0409} }; -struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { - sizeof(STR_MANUFACTURER), - 3, - {STR_MANUFACTURER} -}; -struct usb_string_descriptor_struct usb_string_product_name_default = { - sizeof(STR_PRODUCT), - 3, - {STR_PRODUCT} -}; -struct usb_string_descriptor_struct usb_string_serial_number_default = { - sizeof(STR_SERIAL), - 3, - {STR_SERIAL} -}; +#define usb_string_descriptor(name, str) \ + struct usb_string_descriptor_struct name = { \ + sizeof(str), \ + 3, \ + {str} \ + } + +usb_string_descriptor( usb_string_manufacturer_name_default, STR_MANUFACTURER ); +usb_string_descriptor( usb_string_product_name_default, STR_PRODUCT ); +usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL ); +usb_string_descriptor( usb_string_keyboard_name, KEYBOARD_NAME ); +usb_string_descriptor( usb_string_nkro_keyboard_name, NKRO_KEYBOARD_NAME ); +usb_string_descriptor( usb_string_cdc_status_name, CDC_STATUS_NAME ); +usb_string_descriptor( usb_string_cdc_data_name, CDC_DATA_NAME ); +usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME ); +usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME ); +usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME ); @@ -592,18 +703,36 @@ const usb_descriptor_list_t usb_descriptor_list[] = { {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, {0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)}, {0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)}, + {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, {0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9}, + {0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)}, {0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9}, -/* MOUSE + {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, - {0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9}, -*/ + {0x2100, MOUSE_INTERFACE, config_descriptor + MOUSE_DESC_OFFSET, 9}, + + {0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, + {0x2100, JOYSTICK_INTERFACE, config_descriptor + JOYSTICK_DESC_OFFSET, 9}, + + {0x2200, SYS_CTRL_INTERFACE, sys_ctrl_report_desc, sizeof(sys_ctrl_report_desc)}, + {0x2100, SYS_CTRL_INTERFACE, config_descriptor + SYS_CTRL_DESC_OFFSET, 9}, + +#define iInterfaceString(num, var) \ + {0x0300 + 4 + num, 0x409, (const uint8_t *)&var, 0 } + {0x0300, 0x0000, (const uint8_t *)&string0, 0}, {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, + iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ), + iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ), + iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ), + iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ), + iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ), + iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ), + iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ), {0, 0, NULL, 0} }; diff --git a/Output/pjrcUSB/arm/usb_desc.h b/Output/pjrcUSB/arm/usb_desc.h index e3b6fb5..16d37da 100644 --- a/Output/pjrcUSB/arm/usb_desc.h +++ b/Output/pjrcUSB/arm/usb_desc.h @@ -54,19 +54,21 @@ #define DEVICE_SUBCLASS 0x00 #define DEVICE_PROTOCOL 0x00 #define EP0_SIZE 64 -#define NUM_ENDPOINTS 5 +#define NUM_ENDPOINTS 8 #define NUM_USB_BUFFERS 30 -#define NUM_INTERFACE 4 +#define NUM_INTERFACE 7 #define KEYBOARD_INTERFACE 0 // Keyboard #define KEYBOARD_ENDPOINT 1 #define KEYBOARD_SIZE 8 #define KEYBOARD_INTERVAL 1 +#define KEYBOARD_NAME L"Boot Keyboard" #define NKRO_KEYBOARD_INTERFACE 1 // NKRO Keyboard #define NKRO_KEYBOARD_ENDPOINT 2 #define NKRO_KEYBOARD_SIZE 64 #define NKRO_KEYBOARD_INTERVAL 1 +#define NKRO_KEYBOARD_NAME L"NKRO Keyboard" #define CDC_IAD_DESCRIPTOR 1 #define CDC_STATUS_INTERFACE 2 @@ -77,25 +79,34 @@ #define CDC_ACM_SIZE 16 #define CDC_RX_SIZE 64 #define CDC_TX_SIZE 64 +#define CDC_STATUS_NAME L"Virtual Serial Port - Status" +#define CDC_DATA_NAME L"Virtual Serial Port - Data" #define MOUSE_INTERFACE 4 // Mouse #define MOUSE_ENDPOINT 6 #define MOUSE_SIZE 8 #define MOUSE_INTERVAL 2 +#define MOUSE_NAME L"Mouse" #define JOYSTICK_INTERFACE 5 // Joystick #define JOYSTICK_ENDPOINT 7 #define JOYSTICK_SIZE 16 #define JOYSTICK_INTERVAL 1 +#define JOYSTICK_NAME L"Joystick" + +#define SYS_CTRL_INTERFACE 6 // Media Keys +#define SYS_CTRL_ENDPOINT 8 +#define SYS_CTRL_SIZE 8 +#define SYS_CTRL_INTERVAL 1 +#define SYS_CTRL_NAME L"Media Keys" #define KEYBOARD_DESC_OFFSET (9 + 9) #define NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9) #define SERIAL_CDC_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8) -#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7) - -// XXX Unused #define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9) #define JOYSTICK_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9) +#define SYS_CTRL_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9) +#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7) #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY @@ -104,6 +115,7 @@ #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY #define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY +#define ENDPOINT8_CONFIG ENDPOINT_TRANSIMIT_ONLY diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 1f2e725..9af914d 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -173,6 +173,9 @@ static uint8_t reply_buffer[8]; static void endpoint0_stall() { + #ifdef UART_DEBUG_UNKNOWN + print("STALL" NL ); + #endif USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; } @@ -198,7 +201,8 @@ static void usb_setup() switch ( setup.wRequestAndType ) { case 0x0500: // SET_ADDRESS - break; + goto send; + case 0x0900: // SET_CONFIGURATION #ifdef UART_DEBUG print("CONFIGURE - "); @@ -288,18 +292,21 @@ static void usb_setup() table[ index( i, TX, EVEN ) ].desc = 0; table[ index( i, TX, ODD ) ].desc = 0; } - break; + goto send; + case 0x0880: // GET_CONFIGURATION reply_buffer[0] = usb_configuration; datalen = 1; data = reply_buffer; - break; + goto send; + case 0x0080: // GET_STATUS (device) reply_buffer[0] = 0; reply_buffer[1] = 0; datalen = 2; data = reply_buffer; - break; + goto send; + case 0x0082: // GET_STATUS (endpoint) if ( setup.wIndex > NUM_ENDPOINTS ) { @@ -313,12 +320,15 @@ static void usb_setup() reply_buffer[0] = 1; data = reply_buffer; datalen = 2; - break; + goto send; + case 0x0100: // CLEAR_FEATURE (device) case 0x0101: // CLEAR_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa + warn_print("CLEAR_FEATURE - Device/Interface"); endpoint0_stall(); return; + case 0x0102: // CLEAR_FEATURE (interface) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) @@ -326,6 +336,7 @@ static void usb_setup() endpoint0_stall(); return; } + warn_print("CLEAR_FEATURE - Interface"); //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; // TODO: do we need to clear the data toggle here? //break; @@ -334,11 +345,14 @@ static void usb_setup() // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa endpoint0_stall(); return; + case 0x0300: // SET_FEATURE (device) case 0x0301: // SET_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa + warn_print("SET_FEATURE"); endpoint0_stall(); return; + case 0x0302: // SET_FEATURE (endpoint) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) @@ -349,7 +363,8 @@ static void usb_setup() } (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; // TODO: do we need to clear the data toggle here? - break; + goto send; + case 0x0680: // GET_DESCRIPTOR case 0x0681: #ifdef UART_DEBUG @@ -401,8 +416,7 @@ static void usb_setup() case 0x2221: // CDC_SET_CONTROL_LINE_STATE usb_cdc_line_rtsdtr = setup.wValue; //serial_print("set control line state\n"); - endpoint0_stall(); - return; + goto send; case 0x21A1: // CDC_GET_LINE_CODING data = (uint8_t*)usb_cdc_line_coding; @@ -412,30 +426,44 @@ static void usb_setup() case 0x2021: // CDC_SET_LINE_CODING // XXX Needed? //serial_print("set coding, waiting...\n"); - endpoint0_stall(); - return; // Cannot stall here (causes issues) + return; case 0x0921: // HID SET_REPORT #ifdef UART_DEBUG - print("SET_REPORT - "); + warn_msg("SET_REPORT - "); printHex( setup.wValue ); print(" - "); printHex( setup.wValue & 0xFF ); print( NL ); #endif USBKeys_LEDs = setup.wValue & 0xFF; + + // Must be stall for some reason... -HaaTa endpoint0_stall(); return; case 0x01A1: // HID GET_REPORT #ifdef UART_DEBUG print("GET_REPORT - "); - printHex( USBKeys_LEDs ); + printHex( setup.wIndex ); print(NL); #endif - data = (uint8_t*)&USBKeys_LEDs; - datalen = 1; - goto send; + // Search through descriptors returning necessary info + for ( list = usb_descriptor_list; 1; list++ ) + { + if ( list->addr == NULL ) + break; + if ( list->wValue != 0x2200 ) + continue; + if ( setup.wIndex == list->wIndex ) + { + data = list->addr; + datalen = list->length; + goto send; + } + } + endpoint0_stall(); + return; case 0x0A21: // HID SET_IDLE #ifdef UART_DEBUG @@ -445,8 +473,7 @@ static void usb_setup() #endif USBKeys_Idle_Config = (setup.wValue >> 8); USBKeys_Idle_Count = 0; - endpoint0_stall(); - return; + goto send; case 0x0B21: // HID SET_PROTOCOL #ifdef UART_DEBUG @@ -457,8 +484,7 @@ static void usb_setup() print(NL); #endif USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode - endpoint0_stall(); - return; + goto send; // case 0xC940: default: @@ -472,10 +498,16 @@ static void usb_setup() send: #ifdef UART_DEBUG print("setup send "); - printHex32((uint32_t)data); + printHex32( (uint32_t)data ); print(","); - printHex(datalen); - print(NL); + for ( uint8_t c = 0; c < datalen; c++ ) + { + printHex( data[c] ); + print(" "); + } + print(","); + printHex( datalen ); + print( NL ); #endif if ( datalen > setup.wLength ) @@ -592,6 +624,7 @@ static void usb_control( uint32_t stat ) // unfreeze the USB, now that we're ready USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit break; + case 0x01: // OUT transaction received from host case 0x02: #ifdef UART_DEBUG @@ -663,6 +696,7 @@ static void usb_control( uint32_t stat ) } break; + default: #ifdef UART_DEBUG print("PID=unknown:"); diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index d3c9632..d362bb3 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -52,10 +52,16 @@ // When the PC isn't listening, how long do we wait before discarding data? #define TX_TIMEOUT_MSEC 50 -#if F_CPU == 96000000 +#if F_CPU == 168000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100) +#elif F_CPU == 144000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932) +#elif F_CPU == 120000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764) +#elif F_CPU == 96000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) #elif F_CPU == 72000000 - #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) // XXX Correct? + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) #elif F_CPU == 48000000 #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) #elif F_CPU == 24000000 @@ -89,7 +95,7 @@ void usb_keyboard_send() if ( USBKeys_Protocol == 0 ) // Boot Mode { - if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) + if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) { tx_packet = usb_malloc(); if ( tx_packet ) @@ -98,7 +104,18 @@ void usb_keyboard_send() } else if ( USBKeys_Protocol == 1 ) // NKRO Mode { - if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) + if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) + { + tx_packet = usb_malloc(); + if ( tx_packet ) + break; + } + } + else if ( USBKeys_Changed & + ( USBKeyChangeState_System | USBKeyChangeState_Consumer ) + ) + { + if ( usb_tx_packet_count( SYS_CTRL_ENDPOINT ) < TX_PACKET_LIMIT ) { tx_packet = usb_malloc(); if ( tx_packet ) @@ -118,6 +135,47 @@ void usb_keyboard_send() // Pointer to USB tx packet buffer uint8_t *tx_buf = tx_packet->buf; + // Check system control keys + if ( USBKeys_Changed & USBKeyChangeState_System ) + { + if ( Output_DebugMode ) + { + print("SysCtrl["); + printHex_op( USBKeys_SysCtrl, 2 ); + print( "] " NL ); + } + + *tx_buf++ = 0x02; // ID + *tx_buf = USBKeys_SysCtrl; + tx_packet->len = 2; + + // Send USB Packet + usb_tx( SYS_CTRL_ENDPOINT, tx_packet ); + USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent + return; + } + + // Check consumer control keys + if ( USBKeys_Changed & USBKeyChangeState_Consumer ) + { + if ( Output_DebugMode ) + { + print("ConsCtrl["); + printHex_op( USBKeys_ConsCtrl, 2 ); + print( "] " NL ); + } + + *tx_buf++ = 0x03; // ID + *tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); + *tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); + tx_packet->len = 3; + + // Send USB Packet + usb_tx( SYS_CTRL_ENDPOINT, tx_packet ); + USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent + return; + } + switch ( USBKeys_Protocol ) { // Send boot keyboard interrupt packet(s) @@ -157,45 +215,6 @@ void usb_keyboard_send() dbug_msg("NKRO USB: "); } - // Check system control keys - if ( USBKeys_Changed & USBKeyChangeState_System ) - { - if ( Output_DebugMode ) - { - print("SysCtrl["); - printHex_op( USBKeys_SysCtrl, 2 ); - print( "] " NL ); - } - - *tx_buf++ = 0x02; // ID - *tx_buf = USBKeys_SysCtrl; - tx_packet->len = 2; - - // Send USB Packet - usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); - USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent - } - - // Check consumer control keys - if ( USBKeys_Changed & USBKeyChangeState_Consumer ) - { - if ( Output_DebugMode ) - { - print("ConsCtrl["); - printHex_op( USBKeys_ConsCtrl, 2 ); - print( "] " NL ); - } - - *tx_buf++ = 0x03; // ID - *tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); - *tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); - tx_packet->len = 3; - - // Send USB Packet - usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); - USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent - } - // Standard HID Keyboard if ( USBKeys_Changed ) { diff --git a/Output/pjrcUSB/capabilities.kll b/Output/pjrcUSB/capabilities.kll index 04e6d12..a9b1eb4 100644 --- a/Output/pjrcUSB/capabilities.kll +++ b/Output/pjrcUSB/capabilities.kll @@ -1,10 +1,10 @@ Name = pjrcUSBCapabilities; -Version = 0.4; +Version = 0.5; Author = "HaaTa (Jacob Alexander) 2014-2015"; KLL = 0.3b; # Modified Date -Date = 2015-05-02; +Date = 2015-07-12; # Output capabilities @@ -17,3 +17,7 @@ usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); kbdProtocolBoot => Output_kbdProtocolBoot_capability(); kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); +# Locale Settings +keyboardLocale => KeyboardLocale_define; +keyboardLocale = 0; + diff --git a/Output/pjrcUSB/setup.cmake b/Output/pjrcUSB/setup.cmake index 519c4a8..7e7a874 100644 --- a/Output/pjrcUSB/setup.cmake +++ b/Output/pjrcUSB/setup.cmake @@ -26,8 +26,10 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) output_com.c arm/usb_desc.c arm/usb_dev.c + arm/usb_joystick.c arm/usb_keyboard.c arm/usb_mem.c + arm/usb_mouse.c arm/usb_serial.c ) From 1cbc1755514bb2a012c7b045fc29d20dd3563e77 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 21 Aug 2015 18:26:46 -0700 Subject: [PATCH 27/79] Forgot to add these files in an earlier commit --- Output/pjrcUSB/arm/usb_joystick.c | 114 +++++++++++++ Output/pjrcUSB/arm/usb_joystick.h | 48 ++++++ Output/pjrcUSB/arm/usb_mouse.c | 256 ++++++++++++++++++++++++++++++ Output/pjrcUSB/arm/usb_mouse.h | 58 +++++++ 4 files changed, 476 insertions(+) create mode 100644 Output/pjrcUSB/arm/usb_joystick.c create mode 100644 Output/pjrcUSB/arm/usb_joystick.h create mode 100644 Output/pjrcUSB/arm/usb_mouse.c create mode 100644 Output/pjrcUSB/arm/usb_mouse.h diff --git a/Output/pjrcUSB/arm/usb_joystick.c b/Output/pjrcUSB/arm/usb_joystick.c new file mode 100644 index 0000000..2b5ea79 --- /dev/null +++ b/Output/pjrcUSB/arm/usb_joystick.c @@ -0,0 +1,114 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * Modified by Jacob Alexander (2015) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include // for memcpy() + +// Project Includes +#include +#include + +// Local Includes +#include "usb_dev.h" +#include "usb_joystick.h" + + + +// ----- Defines ----- + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 3 + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 30 + +#if F_CPU == 168000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100) +#elif F_CPU == 144000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932) +#elif F_CPU == 120000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764) +#elif F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 72000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + + + +// ----- Variables ----- + +uint32_t usb_joystick_data[3]; + + +static uint8_t transmit_previous_timeout = 0; + + + +// ----- Functions ----- + +int usb_joystick_send() +{ + uint32_t wait_count=0; + usb_packet_t *tx_packet; + + //serial_print("send"); + //serial_print("\n"); + while (1) { + if (!usb_configuration) { + //serial_print("error1\n"); + return -1; + } + if (usb_tx_packet_count(JOYSTICK_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + //serial_print("error2\n"); + return -1; + } + yield(); + } + transmit_previous_timeout = 0; + memcpy(tx_packet->buf, usb_joystick_data, 12); + tx_packet->len = 12; + usb_tx(JOYSTICK_ENDPOINT, tx_packet); + //serial_print("ok\n"); + return 0; +} + diff --git a/Output/pjrcUSB/arm/usb_joystick.h b/Output/pjrcUSB/arm/usb_joystick.h new file mode 100644 index 0000000..a0b5c23 --- /dev/null +++ b/Output/pjrcUSB/arm/usb_joystick.h @@ -0,0 +1,48 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * Modified by Jacob Alexander (2015) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + +// Local Includes +#include + + + +// ----- Functions ----- + +int usb_joystick_send(); +extern uint32_t usb_joystick_data[3]; // TODO - Move, more generic + diff --git a/Output/pjrcUSB/arm/usb_mouse.c b/Output/pjrcUSB/arm/usb_mouse.c new file mode 100644 index 0000000..2b1dc72 --- /dev/null +++ b/Output/pjrcUSB/arm/usb_mouse.c @@ -0,0 +1,256 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * Modified by Jacob Alexander (2015) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include // for memcpy() + +// Project Includes +#include +#include + +// Local Includes +#include "usb_dev.h" +#include "usb_mouse.h" + + + +// ----- Defines ----- + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 3 + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 30 + +#if F_CPU == 168000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100) +#elif F_CPU == 144000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932) +#elif F_CPU == 120000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764) +#elif F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 72000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + +//#define DEFAULT_XRES 640 +//#define DEFAULT_YRES 480 + +//#define DEFAULT_XRES 800 +//#define DEFAULT_YRES 600 + +//#define DEFAULT_XRES 1024 +//#define DEFAULT_YRES 768 + +//#define DEFAULT_XRES 1280 +//#define DEFAULT_YRES 720 + +//#define DEFAULT_XRES 1280 +//#define DEFAULT_YRES 800 + +#define DEFAULT_XRES 1366 +#define DEFAULT_YRES 768 + +//#define DEFAULT_XRES 1440 +//#define DEFAULT_YRES 900 + +//#define DEFAULT_XRES 1920 +//#define DEFAULT_YRES 1080 + +//#define DEFAULT_XRES 2560 +//#define DEFAULT_YRES 1440 + +//#define DEFAULT_XRES 2560 +//#define DEFAULT_YRES 1600 + +//#define DEFAULT_XRES 2880 +//#define DEFAULT_YRES 1800 + +//#define DEFAULT_XRES 3840 +//#define DEFAULT_YRES 2160 + +//#define DEFAULT_XRES 7680 +//#define DEFAULT_YRES 4320 + + +#define DEFAULT_XSCALE ((0x80000000ul+DEFAULT_XRES/2)/DEFAULT_XRES) +#define DEFAULT_YSCALE ((0x80000000ul+DEFAULT_YRES/2)/DEFAULT_YRES) + + + +// ----- Variables ----- + +// which buttons are currently pressed +uint8_t usb_mouse_buttons_state=0; + +static uint16_t usb_mouse_resolution_x=DEFAULT_XRES; +static uint16_t usb_mouse_resolution_y=DEFAULT_YRES; +static uint16_t usb_mouse_position_x=DEFAULT_XRES/2; +static uint16_t usb_mouse_position_y=DEFAULT_YRES/2; +static uint32_t usb_mouse_scale_x=DEFAULT_XSCALE; +static uint32_t usb_mouse_scale_y=DEFAULT_YSCALE; +static uint32_t usb_mouse_offset_x=DEFAULT_XSCALE/2-1; +static uint32_t usb_mouse_offset_y=DEFAULT_YSCALE/2-1; + + + +// ----- Functions ----- + +// Set the mouse buttons. To create a "click", 2 calls are needed, +// one to push the button down and the second to release it +int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) +{ + uint8_t mask=0; + + if (left) mask |= 1; + if (middle) mask |= 4; + if (right) mask |= 2; + usb_mouse_buttons_state = mask; + return usb_mouse_move(0, 0, 0); +} + + +static uint8_t transmit_previous_timeout=0; + +// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. +int usb_mouse_move(int8_t x, int8_t y, int8_t wheel) +{ + uint32_t wait_count=0; + usb_packet_t *tx_packet; + + //serial_print("move"); + //serial_print("\n"); + if (x == -128) x = -127; + if (y == -128) y = -127; + if (wheel == -128) wheel = -127; + + while (1) { + if (!usb_configuration) { + return -1; + } + if (usb_tx_packet_count(MOUSE_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + return -1; + } + yield(); + } + transmit_previous_timeout = 0; + *(tx_packet->buf + 0) = 1; + *(tx_packet->buf + 1) = usb_mouse_buttons_state; + *(tx_packet->buf + 2) = x; + *(tx_packet->buf + 3) = y; + *(tx_packet->buf + 4) = wheel; + tx_packet->len = 5; + usb_tx(MOUSE_ENDPOINT, tx_packet); + return 0; +} + +int usb_mouse_position(uint16_t x, uint16_t y) +{ + uint32_t wait_count=0, val32; + usb_packet_t *tx_packet; + + if (x >= usb_mouse_resolution_x) x = usb_mouse_resolution_x - 1; + usb_mouse_position_x = x; + if (y >= usb_mouse_resolution_y) y = usb_mouse_resolution_y - 1; + usb_mouse_position_y = y; + + while (1) { + if (!usb_configuration) { + return -1; + } + if (usb_tx_packet_count(MOUSE_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + return -1; + } + yield(); + } + transmit_previous_timeout = 0; + *(tx_packet->buf + 0) = 2; + val32 = usb_mouse_position_x * usb_mouse_scale_x + usb_mouse_offset_x; + //serial_print("position:"); + //serial_phex16(usb_mouse_position_x); + //serial_print("->"); + //serial_phex32(val32); + *(tx_packet->buf + 1) = val32 >> 16; + *(tx_packet->buf + 2) = val32 >> 24; + val32 = usb_mouse_position_y * usb_mouse_scale_y + usb_mouse_offset_y; + //serial_print(","); + //serial_phex16(usb_mouse_position_y); + //serial_print("->"); + //serial_phex32(val32); + //serial_print("\n"); + *(tx_packet->buf + 3) = val32 >> 16; + *(tx_packet->buf + 4) = val32 >> 24; + tx_packet->len = 5; + usb_tx(MOUSE_ENDPOINT, tx_packet); + return 0; +} + +void usb_mouse_screen_size(uint16_t width, uint16_t height, uint8_t mac) +{ + if (width < 128) width = 128; + else if (width > 7680) width = 7680; + if (height < 128) height = 128; + else if (height > 7680) height = 7680; + usb_mouse_resolution_x = width; + usb_mouse_resolution_y = height; + usb_mouse_position_x = width / 2; + usb_mouse_position_y = height / 2; + usb_mouse_scale_x = (0x80000000ul + (width >> 1)) / width; + usb_mouse_scale_y = (0x80000000ul + (height >> 1)) / height; + usb_mouse_offset_x = (usb_mouse_scale_x >> 1) - 1; + usb_mouse_offset_y = (usb_mouse_scale_y >> 1) - 1; + if (mac) { + // ugly workaround for Mac's HID coordinate scaling: + // http://lists.apple.com/archives/usb/2011/Jun/msg00032.html + usb_mouse_offset_x += 161061273ul; + usb_mouse_offset_y += 161061273ul; + usb_mouse_scale_x = (1825361101ul + (width >> 1)) / width; + usb_mouse_scale_y = (1825361101ul + (height >> 1)) / height; + } +} + diff --git a/Output/pjrcUSB/arm/usb_mouse.h b/Output/pjrcUSB/arm/usb_mouse.h new file mode 100644 index 0000000..ffa9fe2 --- /dev/null +++ b/Output/pjrcUSB/arm/usb_mouse.h @@ -0,0 +1,58 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * Modified by Jacob Alexander (2015) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + +// Local Includes +#include + + + +// ----- Functions ----- + +// TODO - More generic +int usb_mouse_buttons( uint8_t left, uint8_t middle, uint8_t right ); +int usb_mouse_move( int8_t x, int8_t y, int8_t wheel ); +int usb_mouse_position( uint16_t x, uint16_t y ); +void usb_mouse_screen_size( uint16_t width, uint16_t height, uint8_t mac ); +extern uint8_t usb_mouse_buttons_state; + +// TODO - Move +#define MOUSE_LEFT 1 +#define MOUSE_MIDDLE 4 +#define MOUSE_RIGHT 2 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + From 9c52fb32fa476249c35279ef4fff1be59e3e7eac Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 21 Aug 2015 19:43:45 -0700 Subject: [PATCH 28/79] Fixing default ErgoDox layout and adding FlashMode button - Adds proper flashMode support for all keyboards and microcontrollers (usb and serial) - flashModeEnabled must be set to 1 otherwise it will only show an error * This is on purpose (somewhat dangerous feature as it allows remote flashing) - Capability cleanup --- Macro/PartialMap/macro.h | 9 ------- Output/pjrcUSB/arm/usb_dev.c | 11 +++++++- Output/pjrcUSB/capabilities.kll | 15 ++++++++--- Output/pjrcUSB/output_com.c | 13 ++++++++++ Output/pjrcUSB/output_com.h | 14 ---------- Output/uartOut/arm/uart_serial.c | 44 ++++++++++++++++++++++++++++++++ Output/uartOut/capabilities.kll | 13 ++++++++-- Output/uartOut/output_com.c | 13 ++++++++++ Output/usbMuxUart/output_com.c | 13 ++++++++++ Scan/MDErgo1/leftHand.kll | 32 +++++++++++------------ Scan/MDErgo1/rightHand.kll | 33 ++++++++++++------------ 11 files changed, 148 insertions(+), 62 deletions(-) diff --git a/Macro/PartialMap/macro.h b/Macro/PartialMap/macro.h index eae77dd..2df411e 100644 --- a/Macro/PartialMap/macro.h +++ b/Macro/PartialMap/macro.h @@ -23,15 +23,6 @@ -// ----- Capabilities ----- - -void Macro_layerState_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Macro_layerLatch_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Macro_layerLock_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *args ); - - - // ----- Functions ----- void Macro_analogState( uint8_t scanCode, uint8_t state ); diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 9af914d..37541e4 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -34,6 +34,7 @@ // Project Includes #include #include +#include // Local Includes #include "usb_dev.h" @@ -872,6 +873,14 @@ void usb_tx( uint32_t endpoint, usb_packet_t *packet ) void usb_device_reload() { + if ( flashModeEnabled_define == 0 ) + { + print( NL ); + warn_print("flashModeEnabled not set, cancelling firmware reload..."); + info_msg("Set flashModeEnabled to 1 in your kll configuration."); + return; + } + // MCHCK #if defined(_mk20dx128vlf5_) @@ -882,7 +891,7 @@ void usb_device_reload() PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up // Check for jumper - if ( GPIOA_PDIR & (1<<3) ) + if ( GPIOA_PDIR & (1<<3) && flashModeEnabled_define != 0 ) { print( NL ); warn_print("Security jumper not present, cancelling firmware reload..."); diff --git a/Output/pjrcUSB/capabilities.kll b/Output/pjrcUSB/capabilities.kll index a9b1eb4..7646625 100644 --- a/Output/pjrcUSB/capabilities.kll +++ b/Output/pjrcUSB/capabilities.kll @@ -1,10 +1,10 @@ Name = pjrcUSBCapabilities; -Version = 0.5; +Version = 0.6; Author = "HaaTa (Jacob Alexander) 2014-2015"; -KLL = 0.3b; +KLL = 0.3c; # Modified Date -Date = 2015-07-12; +Date = 2015-08-21; # Output capabilities @@ -21,3 +21,12 @@ kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); keyboardLocale => KeyboardLocale_define; keyboardLocale = 0; +# Bootloader Mode capability +# XXX +# By default this is disabled on purpose +# It is a large security hazard +flashModeEnabled => flashModeEnabled_define; +flashModeEnabled = 0; + +flashMode => Output_flashMode_capability(); + diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index dc6bfcd..d594ac1 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -484,6 +484,19 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a } } +void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_flashMode(usbCode)"); + return; + } + + // Start flash mode + Output_firmwareReload(); +} + // ----- Functions ----- diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index 0462c20..c82ed98 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -84,20 +84,6 @@ extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enab -// ----- Capabilities ----- - -// Output capabilities -void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Output_noneSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); - -// Configuration capabilities -void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ); -void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ); - - - // ----- Functions ----- void Output_setup(); diff --git a/Output/uartOut/arm/uart_serial.c b/Output/uartOut/arm/uart_serial.c index db7a3aa..d06f2f5 100644 --- a/Output/uartOut/arm/uart_serial.c +++ b/Output/uartOut/arm/uart_serial.c @@ -27,6 +27,8 @@ // Project Includes #include #include +#include +#include // Local Includes #include "uart_serial.h" @@ -325,6 +327,48 @@ void uart_serial_flush_output() void uart_device_reload() { + if ( flashModeEnabled_define == 0 ) + { + print( NL ); + warn_print("flashModeEnabled not set, cancelling firmware reload..."); + info_msg("Set flashModeEnabled to 1 in your kll configuration."); + return; + } + +// MCHCK +#if defined(_mk20dx128vlf5_) + + // MCHCK Kiibohd Variant + // Check to see if PTA3 (has a pull-up) is connected to GND (usually via jumper) + // Only allow reload if the jumper is present (security) + GPIOA_PDDR &= ~(1<<3); // Input + PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up + + // Check for jumper + if ( GPIOA_PDIR & (1<<3) && flashModeEnabled_define != 0 ) + { + print( NL ); + warn_print("Security jumper not present, cancelling firmware reload..."); + info_msg("Replace jumper on middle 2 pins, or manually press the firmware reload button."); + } + else + { + // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode + for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ ) + (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ]; + SOFTWARE_RESET(); + } + +// Kiibohd mk20dx256vlh7 +#elif defined(_mk20dx256vlh7_) + // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode + for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ ) + (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ]; + SOFTWARE_RESET(); + +// Teensy 3.0 and 3.1 +#else asm volatile("bkpt"); +#endif } diff --git a/Output/uartOut/capabilities.kll b/Output/uartOut/capabilities.kll index d45e181..663c034 100644 --- a/Output/uartOut/capabilities.kll +++ b/Output/uartOut/capabilities.kll @@ -1,12 +1,21 @@ Name = uartOutCapabilities; -Version = 0.1; +Version = 0.2; Author = "HaaTa (Jacob Alexander) 2014"; KLL = 0.3; # Modified Date -Date = 2014-09-27; +Date = 2014-08-21; # Capabilties available to the uartOut output module usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); +# Bootloader Mode capability +# XXX +# By default this is disabled on purpose +# It is a large security hazard +flashModeEnabled => flashModeEnabled_define; +flashModeEnabled = 0; + +flashMode => Output_flashMode_capability(); + diff --git a/Output/uartOut/output_com.c b/Output/uartOut/output_com.c index 8558fc1..a45193b 100644 --- a/Output/uartOut/output_com.c +++ b/Output/uartOut/output_com.c @@ -129,6 +129,19 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a } } +void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_flashMode(usbCode)"); + return; + } + + // Start flash mode + Output_firmwareReload(); +} + // ----- Functions ----- diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 3fa26c9..928f342 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -490,6 +490,19 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a } } +void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_flashMode(usbCode)"); + return; + } + + // Start flash mode + Output_firmwareReload(); +} + // ----- Functions ----- diff --git a/Scan/MDErgo1/leftHand.kll b/Scan/MDErgo1/leftHand.kll index c814c55..a2b3a36 100644 --- a/Scan/MDErgo1/leftHand.kll +++ b/Scan/MDErgo1/leftHand.kll @@ -1,4 +1,4 @@ -Name = MDErgo1 Right Hand; +Name = MDErgo1 Left Hand; Version = 0.1; Author = "HaaTa (Jacob Alexander) 2015"; KLL = 0.3c; @@ -8,22 +8,22 @@ Date = 2015-08-06; # Top Row -S0x02 : U"6"; +S0x02 : U"Esc"; S0x03 : U"5"; S0x04 : U"4"; S0x05 : U"3"; S0x06 : U"2"; S0x07 : U"1"; -S0x08 : U"Esc"; +S0x08 : U"Equals"; # Top-Middle Row -S0x0B : U"F4"; +S0x0B : U"Function1"; S0x0C : U"T"; S0x0D : U"R"; S0x0E : U"E"; S0x0F : U"W"; S0x10 : U"Q"; -S0x11 : U"Tab"; +S0x11 : U"Backslash"; # Middle Row S0x15 : U"G"; @@ -31,14 +31,14 @@ S0x16 : U"F"; S0x17 : U"D"; S0x18 : U"S"; S0x19 : U"A"; -S0x1A : U"Function1"; +S0x1A : U"Tab"; # Top Thumb Cluster -S0x1B : U"Home"; -S0x1C : U"End"; +S0x1B : U"LAlt"; +S0x1C : U"LCtrl"; # Bottom-Middle Row -S0x1D : U"F5"; +S0x1D : U"Function2"; S0x1E : U"B"; S0x1F : U"V"; S0x20 : U"C"; @@ -47,15 +47,15 @@ S0x22 : U"Z"; S0x23 : U"Left Shift"; # Bottom Thumb Cluster -S0x24 : U"Left Alt"; -S0x25 : U"Left Ctrl"; +S0x24 : U"Home"; +S0x25 : U"End"; S0x26 : U"Delete"; -S0x27 : U"Space"; +S0x27 : U"Backspace"; # Bottom Row S0x28 : U"Function5"; -S0x29 : U"Backtick"; -S0x2A : U"Right Brace"; -S0x2B : U"Left Brace"; -S0x2C : U"Function3"; +S0x29 : U"Function4"; +S0x2A : U"Function3"; +S0x2B : U"Backtick"; +S0x2C : U"LGui"; diff --git a/Scan/MDErgo1/rightHand.kll b/Scan/MDErgo1/rightHand.kll index 840b696..d31000e 100644 --- a/Scan/MDErgo1/rightHand.kll +++ b/Scan/MDErgo1/rightHand.kll @@ -8,22 +8,22 @@ Date = 2015-08-06; # Top Row -S0x02 : U"7"; -S0x03 : U"8"; -S0x04 : U"9"; -S0x05 : U"0"; -S0x06 : U"Minus"; -S0x07 : U"Equal"; -S0x08 : U"Backspace"; +S0x02 : U"Function6"; +S0x03 : U"6"; +S0x04 : U"7"; +S0x05 : U"8"; +S0x06 : U"9"; +S0x07 : U"0"; +S0x08 : U"Minus"; # Top-Middle Row -S0x0B : U"PageUp"; +S0x0B : U"Left Brace"; S0x0C : U"Y"; S0x0D : U"U"; S0x0E : U"I"; S0x0F : U"O"; S0x10 : U"P"; -S0x11 : U"BackSlash"; +S0x11 : U"Right Brace"; # Middle Row S0x15 : U"H"; @@ -34,11 +34,11 @@ S0x19 : U"Semicolon"; S0x1A : U"Quote"; # Top Thumb Cluster -S0x1B : U"PrintScreen"; -S0x1C : U"Insert"; +S0x1B : U"RAlt"; +S0x1C : U"RCtrl"; # Bottom-Middle Row -S0x1D : U"PageDown"; +S0x1D : U"Function7"; S0x1E : U"N"; S0x1F : U"M"; S0x20 : U"Comma"; @@ -47,16 +47,15 @@ S0x22 : U"Slash"; S0x23 : U"Right Shift"; # Bottom Thumb Cluster -S0x24 : U"Right Alt"; -S0x25 : U"Right Ctrl"; +S0x24 : U"PageUp"; +S0x25 : U"PageDown"; S0x26 : U"Enter"; -S0x27 : U"Function2"; +S0x27 : U"Space"; # Bottom Row S0x28 : U"Left"; S0x29 : U"Down"; S0x2A : U"Up"; S0x2B : U"Right"; -S0x2C : U"Function4"; - +S0x2C : U"RGui"; From 51486bc4e16830c16c30f696b3a4f84c93a5baf8 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 21 Aug 2015 20:33:47 -0700 Subject: [PATCH 29/79] Fixing layer stack evaluation - Layers were stacked correctly, but evaluated backwards --- Macro/PartialMap/macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index f6c70ed..7161fbf 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -374,7 +374,7 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) } // If no trigger macro is defined at the given layer, fallthrough to the next layer - for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ ) + for ( uint16_t layerIndex = macroLayerIndexStackSize; layerIndex != 0xFFFF; layerIndex-- ) { // Lookup Layer const Layer *layer = &LayerIndex[ macroLayerIndexStack[ layerIndex ] ]; From 1fe9dd2a5313c8da752c763fd335ac5a2387017b Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 21 Aug 2015 22:59:11 -0700 Subject: [PATCH 30/79] Bootloader fix --- Bootloader/debug.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Bootloader/debug.h b/Bootloader/debug.h index 83e9bac..ceb7d88 100644 --- a/Bootloader/debug.h +++ b/Bootloader/debug.h @@ -53,6 +53,7 @@ void uart_serial_setup(); // Convenience #define printHex(hex) printHex_op(hex, 1) +#define printHex32(hex) printHex_op(hex, 1) void printHex_op( uint32_t in, uint8_t op ); #else @@ -60,6 +61,7 @@ void printHex_op( uint32_t in, uint8_t op ); #define uart_serial_write(buf,size) #define uart_serial_setup() #define printHex(hex) +#define printHex32(hex) #define printHex_op(in,op) #endif From 85586c574ac72a160593e7675aa9029d9b2a6713 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 21 Aug 2015 23:23:52 -0700 Subject: [PATCH 31/79] Updating convenience build scripts to build Left and Right sides - Includes minor fix for MD1 --- Keyboards/cmake.bash | 1 + Keyboards/ergodox.bash | 31 ++++++++++++++++++++++++++++--- Scan/MD1/scan_loop.c | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Keyboards/cmake.bash b/Keyboards/cmake.bash index 61995b0..9142526 100644 --- a/Keyboards/cmake.bash +++ b/Keyboards/cmake.bash @@ -85,4 +85,5 @@ cmake -DCHIP="${Chip}" -DCOMPILER="${Compiler}" -DScanModule="${ScanModule}" -DM make echo "Firmware has been compiled into: '${BuildPath}'" +cd - diff --git a/Keyboards/ergodox.bash b/Keyboards/ergodox.bash index 0fe0f29..b07eb16 100755 --- a/Keyboards/ergodox.bash +++ b/Keyboards/ergodox.bash @@ -9,9 +9,11 @@ # Configuration # ################# +######## Left Side ######## + # Feel free to change the variables in this section to configure your keyboard -BuildPath="ICED" +BuildPath="ICED-L" ## KLL Configuration ## @@ -21,7 +23,7 @@ BaseMap="defaultMap leftHand slave1 rightHand" # This is the default layer of the keyboard # NOTE: To combine kll files into a single layout, separate them by spaces # e.g. DefaultMap="mylayout mylayoutmod" -DefaultMap="stdFuncMap" +DefaultMap="mdergo1Overlay lcdFuncMap" # This is where you set the additional layers # NOTE: Indexing starts at 1 @@ -29,7 +31,8 @@ DefaultMap="stdFuncMap" # e.g. PartialMaps[1]="layer1 layer1mod" # PartialMaps[2]="layer2" # PartialMaps[3]="layer3" -PartialMaps[1]="hhkbpro2" +PartialMaps[1]="iced_func" +PartialMaps[2]="iced_numpad" @@ -70,3 +73,25 @@ fi # Load the library source cmake.bash + + +######################### +# Re-run for right side # +######################### + +######## Right Side ######## + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="ICED-R" + +## KLL Configuration ## + +# Only changing the basemap (everything else is the same) +# Generally shouldn't be changed, this will affect every layer +BaseMap="defaultMap rightHand slave1 leftHand" + +# Load the library (starts the build) +source cmake.bash + + diff --git a/Scan/MD1/scan_loop.c b/Scan/MD1/scan_loop.c index 02d6326..22d43c2 100644 --- a/Scan/MD1/scan_loop.c +++ b/Scan/MD1/scan_loop.c @@ -169,6 +169,7 @@ void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t // If key is not blocked, process if ( key != CustomAction_blockHold_storage ) { + extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); Output_usbCodeSend_capability( state, stateType, &key ); } } From 2c25f085b678f19cc70386d165b6a63e7fba4d78 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 14 Sep 2015 00:48:48 -0700 Subject: [PATCH 32/79] Single MDErgo1 layout used for KiiConf initial layout setup --- Scan/MDErgo1/leftThenRight.kll | 117 +++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Scan/MDErgo1/leftThenRight.kll diff --git a/Scan/MDErgo1/leftThenRight.kll b/Scan/MDErgo1/leftThenRight.kll new file mode 100644 index 0000000..baa3bed --- /dev/null +++ b/Scan/MDErgo1/leftThenRight.kll @@ -0,0 +1,117 @@ +Name = MDErgo1 Left then Right; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-09-12; + + +# Top Row +S0x02 : U"Esc"; +S0x03 : U"5"; +S0x04 : U"4"; +S0x05 : U"3"; +S0x06 : U"2"; +S0x07 : U"1"; +S0x08 : U"Equals"; + +# Top-Middle Row +S0x0B : U"Function1"; +S0x0C : U"T"; +S0x0D : U"R"; +S0x0E : U"E"; +S0x0F : U"W"; +S0x10 : U"Q"; +S0x11 : U"Backslash"; + +# Middle Row +S0x15 : U"G"; +S0x16 : U"F"; +S0x17 : U"D"; +S0x18 : U"S"; +S0x19 : U"A"; +S0x1A : U"Tab"; + +# Top Thumb Cluster +S0x1B : U"LAlt"; +S0x1C : U"LCtrl"; + +# Bottom-Middle Row +S0x1D : U"Function2"; +S0x1E : U"B"; +S0x1F : U"V"; +S0x20 : U"C"; +S0x21 : U"X"; +S0x22 : U"Z"; +S0x23 : U"LShift"; + +# Bottom Thumb Cluster +S0x24 : U"Home"; +S0x25 : U"End"; +S0x26 : U"Delete"; +S0x27 : U"Backspace"; + +# Bottom Row +S0x28 : U"Function5"; +S0x29 : U"Function4"; +S0x2A : U"Function3"; +S0x2B : U"Backtick"; +S0x2C : U"LGui"; + + +# Sets all future Scan Code definitions to be applied to the first slave node +ConnectId = 1; + +# Top Row +S0x02 : U"Function6"; +S0x03 : U"6"; +S0x04 : U"7"; +S0x05 : U"8"; +S0x06 : U"9"; +S0x07 : U"0"; +S0x08 : U"Minus"; + +# Top-Middle Row +S0x0B : U"LBrace"; +S0x0C : U"Y"; +S0x0D : U"U"; +S0x0E : U"I"; +S0x0F : U"O"; +S0x10 : U"P"; +S0x11 : U"RBrace"; + +# Middle Row +S0x15 : U"H"; +S0x16 : U"J"; +S0x17 : U"K"; +S0x18 : U"L"; +S0x19 : U"Semicolon"; +S0x1A : U"Quote"; + +# Top Thumb Cluster +S0x1B : U"RAlt"; +S0x1C : U"RCtrl"; + +# Bottom-Middle Row +S0x1D : U"Function7"; +S0x1E : U"N"; +S0x1F : U"M"; +S0x20 : U"Comma"; +S0x21 : U"Period"; +S0x22 : U"Slash"; +S0x23 : U"RShift"; + +# Bottom Thumb Cluster +S0x24 : U"PageUp"; +S0x25 : U"PageDown"; +S0x26 : U"Enter"; +S0x27 : U"Space"; + +# Bottom Row +S0x28 : U"Left"; +S0x29 : U"Down"; +S0x2A : U"Up"; +S0x2B : U"Right"; +S0x2C : U"RGui"; + From df7d0be00d11dead100a688f37b6465612dd7f0c Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 14 Sep 2015 23:37:32 -0700 Subject: [PATCH 33/79] Adding example API scripts --- Scan/ISSILed/exampleAPI.bash | 31 +++++++++++++++++++++++++ Scan/STLcd/exampleAPI.bash | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100755 Scan/ISSILed/exampleAPI.bash create mode 100755 Scan/STLcd/exampleAPI.bash diff --git a/Scan/ISSILed/exampleAPI.bash b/Scan/ISSILed/exampleAPI.bash new file mode 100755 index 0000000..5d66c37 --- /dev/null +++ b/Scan/ISSILed/exampleAPI.bash @@ -0,0 +1,31 @@ +#!/bin/bash +# ISSILed +# Virtual Serial Port API Example +# Jacob Alexander 2015 + +# XXX Set this to match your virtual serialport +# TODO Show examples for Mac OSX and Cygwin/Windows +SERIALPORT=/dev/ttyACM0 + +# NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer +# Generally this just means commands will get ignored +# I'm using 100 ms sleeps here, but much smaller are probably sufficient + +# Clear out cli buffer +printf "\r" > $SERIALPORT + +# Write to ISSI Page +# Arguments +# - page +# - starting address +# - data (usually brightness) (8 bits) +# +# For brightness control, set the starting address to 0x24 +# By default only page 0x00 is used +# There are 8 pages of memory (these can be cycled through for animiations) +# 144 led channels +# Page 0x0A is used for configuration +# See the datasheet for full details http://www.issi.com/WW/pdf/31FL3731C.pdf +sleep 0.1 +printf "ledWPage 0x00 0x24 0x10 0x20 0x30 0x40 0x50\r" > $SERIALPORT + diff --git a/Scan/STLcd/exampleAPI.bash b/Scan/STLcd/exampleAPI.bash new file mode 100755 index 0000000..8c2dda5 --- /dev/null +++ b/Scan/STLcd/exampleAPI.bash @@ -0,0 +1,44 @@ +#!/bin/bash +# STLcd +# Virtual Serial Port API Example +# Jacob Alexander 2015 + +# XXX Set this to match your virtual serialport +# TODO Show examples for Mac OSX and Cygwin/Windows +SERIALPORT=/dev/ttyACM0 + +# NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer +# Generally this just means commands will get ignored +# I'm using 100 ms sleeps here, but much smaller are probably sufficient + +# Clear out cli buffer +printf "\r" > $SERIALPORT + +# Change backlight color +# 3 16-bit numbers (hex or decimal) Red, Green and Blue +sleep 0.1 +printf "lcdColor 0x100 0x2000 0x4000\r" > $SERIALPORT # Light blue + +# Change the lcd image +# Arguments: +# - page +# - starting address +# - pixels (1 bit per pixel) +# +# There are 9 total pages of display memory, but only 4 are visable at time (it is possible to scroll though) +# Each page is 128 bits wide (16 bytes) +# See the datasheet for full details http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf +sleep 0.1 +printf "lcdDisp 0x0 0x0 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT +sleep 0.1 +printf "lcdDisp 0x1 0x10 0xFF 0x13 0xFF 0x11 0xFF 0x44\r" > $SERIALPORT +sleep 0.1 +printf "lcdDisp 0x2 0x20 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT +sleep 0.1 +printf "lcdDisp 0x3 0x30 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT + +# Send command directly to the lcd +# See the datasheet for full details http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf +sleep 0.1 +printf "lcdCmd 0xA7\r" > $SERIALPORT # Reverse display (0xA6 is Normal) + From 3f83274f864fa19d88b79359d8b2717a18d4c082 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 20 Sep 2015 18:47:10 -0700 Subject: [PATCH 34/79] Prep for mouse support --- Output/pjrcUSB/arm/usb_desc.c | 111 ++++++++++++++++++++++++---------- Output/pjrcUSB/arm/usb_desc.h | 2 +- Output/pjrcUSB/arm/usb_dev.c | 4 +- 3 files changed, 83 insertions(+), 34 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 9616d45..7a8e497 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -267,7 +267,7 @@ static uint8_t nkro_keyboard_report_desc[] = { // System Control and Consumer Control static uint8_t sys_ctrl_report_desc[] = { - // System Control Collection + // System Control Collection (8 bits) // // NOTES: // Not bothering with NKRO for this table. If there's need, I can implement it. -HaaTa @@ -285,7 +285,7 @@ static uint8_t sys_ctrl_report_desc[] = { 0x81, 0x00, // Input (Data, Array), 0xc0, // End Collection - System Control - // Consumer Control Collection - Media Keys + // Consumer Control Collection - Media Keys (16 bits) // // NOTES: // Not bothering with NKRO for this table. If there's a need, I can implement it. -HaaTa @@ -307,35 +307,84 @@ static uint8_t sys_ctrl_report_desc[] = { // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension static uint8_t mouse_report_desc[] = { - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x02, // Usage (Mouse) - 0xA1, 0x01, // Collection (Application) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x01, // Usage Minimum (Button #1) - 0x29, 0x03, // Usage Maximum (Button #3) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x95, 0x03, // Report Count (3) - 0x75, 0x01, // Report Size (1) - 0x81, 0x02, // Input (Data, Variable, Absolute) - 0x95, 0x01, // Report Count (1) - 0x75, 0x05, // Report Size (5) - 0x81, 0x03, // Input (Constant) - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x30, // Usage (X) - 0x09, 0x31, // Usage (Y) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x7F, // Logical Maximum (32767) - 0x75, 0x10, // Report Size (16), - 0x95, 0x02, // Report Count (2), - 0x81, 0x02, // Input (Data, Variable, Absolute) - 0x09, 0x38, // Usage (Wheel) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7F, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8), - 0x95, 0x01, // Report Count (1), - 0x81, 0x06, // Input (Data, Variable, Relative) - 0xC0 // End Collection + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x02, // Usage (Mouse) + 0xa1, 0x01, // Collection (Application) + 0x09, 0x02, // Usage (Mouse) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x01, // Usage (Pointer) + + // Buttons (5 bits) + 0xa1, 0x00, // Collection (Physical) - Buttons + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button 1) + 0x29, 0x05, // Usage Maximum (Button 5) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x05, // Report Count (5) + 0x81, 0x02, // Input (Data,Var,Abs) + + // Padding (3 bits) + 0x75, 0x03, // Report Size (3) + 0x95, 0x01, // Report Count (1) + 0x81, 0x03, // Input (Cnst,Var,Abs) + + // Pointer (16 bits) + 0x05, 0x01, // Usage PAGE (Generic Desktop) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x06, // Input (Data,Var,Rel) + + // Vertical Wheel + // - Multiplier (2 bits) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x48, // Usage (Resolution Multiplier) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x35, 0x01, // Physical Minimum (1) + 0x45, 0x04, // Physical Maximum (4) + 0x75, 0x02, // Report Size (2) + 0x95, 0x01, // Report Count (1) + 0xa4, // Push + 0xb1, 0x02, // Feature (Data,Var,Abs) + // - Device (8 bits) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x35, 0x00, // Physical Minimum (0) - reset physical + 0x45, 0x00, // Physical Maximum (0) + 0x75, 0x08, // Report Size (8) + 0x81, 0x06, // Input (Data,Var,Rel) + 0xc0, // End Collection - Vertical Wheel + + // Horizontal Wheel + // - Multiplier (2 bits) + 0xa1, 0x02, // Collection (Logical) + 0x09, 0x48, // Usage (Resolution Multiplier) + 0xb4, // Pop + 0xb1, 0x02, // Feature (Data,Var,Abs) + // - Padding (4 bits) + 0x35, 0x00, // Physical Minimum (0) - reset physical + 0x45, 0x00, // Physical Maximum (0) + 0x75, 0x04, // Report Size (4) + 0xb1, 0x03, // Feature (Cnst,Var,Abs) + // - Device (8 bits) + 0x05, 0x0c, // Usage Page (Consumer Devices) + 0x0a, 0x38, 0x02, // Usage (AC Pan) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7f, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x81, 0x06, // Input (Data,Var,Rel) + 0xc0, // End Collection - Horizontal Wheel + + 0xc0, // End Collection - Buttons + 0xc0, // End Collection - Mouse Logical + 0xc0 // End Collection - Mouse Application }; // Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65 diff --git a/Output/pjrcUSB/arm/usb_desc.h b/Output/pjrcUSB/arm/usb_desc.h index 16d37da..33c6589 100644 --- a/Output/pjrcUSB/arm/usb_desc.h +++ b/Output/pjrcUSB/arm/usb_desc.h @@ -85,7 +85,7 @@ #define MOUSE_INTERFACE 4 // Mouse #define MOUSE_ENDPOINT 6 #define MOUSE_SIZE 8 -#define MOUSE_INTERVAL 2 +#define MOUSE_INTERVAL 1 #define MOUSE_NAME L"Mouse" #define JOYSTICK_INTERFACE 5 // Joystick diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 37541e4..1cc4f13 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -1031,8 +1031,8 @@ restart: break; default: tx_state[ endpoint ] = ((uint32_t)b & 8) - ? TX_STATE_ODD_FREE - : TX_STATE_EVEN_FREE; + ? TX_STATE_ODD_FREE + : TX_STATE_EVEN_FREE; break; } } From 893231b3559bf9e7c6c8eb8e6da7f02b0d6e70cc Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 28 Sep 2015 19:58:39 -0700 Subject: [PATCH 35/79] Adding layer rotation (next/prev) capability - Requires kll update - Including udev id update --- 98-kiibohd.rules | 1 + Macro/PartialMap/capabilities.kll | 21 +++++---- Macro/PartialMap/macro.c | 73 +++++++++++++++++++++++++++---- Scan/STLcd/lcd_scan.c | 7 ++- 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/98-kiibohd.rules b/98-kiibohd.rules index 5e28301..d00a8b2 100644 --- a/98-kiibohd.rules +++ b/98-kiibohd.rules @@ -5,6 +5,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:= # Kiibohd Serial Interface KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" # Kiibohd Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" # DFU Bootloader (MCHCK) diff --git a/Macro/PartialMap/capabilities.kll b/Macro/PartialMap/capabilities.kll index 4572c05..09ac6a2 100644 --- a/Macro/PartialMap/capabilities.kll +++ b/Macro/PartialMap/capabilities.kll @@ -1,17 +1,22 @@ Name = PartialMapCapabilities; -Version = 0.1; -Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3a; +Version = 0.2; +Author = "HaaTa (Jacob Alexander) 2014-2015"; +KLL = 0.3b; # Modified Date -Date = 2014-11-21; +Date = 2015-09-24; # Capabilties available to the PartialMap module -layerState => Macro_layerState_capability( layer : 2, state : 1 ); -layerLatch => Macro_layerLatch_capability( layer : 2 ); -layerLock => Macro_layerLock_capability( layer : 2 ); -layerShift => Macro_layerShift_capability( layer : 2 ); +layerState => Macro_layerState_capability( layer : 2, state : 1 ); +layerLatch => Macro_layerLatch_capability( layer : 2 ); +layerLock => Macro_layerLock_capability( layer : 2 ); +layerShift => Macro_layerShift_capability( layer : 2 ); +# By default, rotate to the next layer +# The current rotating layer is stored separately to the layer stack +# But still sets the layer stack using the layerLock/unlock mechanism +# Argument 0 -> Next, 1 -> Previous +layerRotate => Macro_layerRotate_capability( previous : 1 ); # Defines available to the PartialMap module stateWordSize => StateWordSize_define; diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 7161fbf..690231c 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -170,8 +170,8 @@ uint8_t macroInterconnectCacheSize = 0; // Sets the given layer with the specified layerState void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t layerState ) { - // Ignore if layer does not exist - if ( layer >= LayerNum ) + // Ignore if layer does not exist or trying to manipulate layer 0/Default layer + if ( layer >= LayerNum || layer == 0 ) return; // Is layer in the LayerIndexStack? @@ -350,6 +350,58 @@ void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *arg } +// Rotate layer to next/previous +// Uses state variable to keep track of the current layer position +// Layers are still evaluated using the layer stack +uint16_t Macro_rotationLayer; +void Macro_layerRotate_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Macro_layerRotate(previous)"); + return; + } + + // Only use capability on press + // TODO Analog + // XXX Could also be on release, but that's sorta dumb -HaaTa + if ( stateType == 0x00 && state != 0x01 ) // All normal key conditions except press + return; + + // Unset previous rotation layer if not 0 + if ( Macro_rotationLayer != 0 ) + { + Macro_layerState( state, stateType, Macro_rotationLayer, 0x04 ); + } + + // Get direction of rotation, 0, next, non-zero previous + uint8_t direction = *args; + + // Next + if ( !direction ) + { + Macro_rotationLayer++; + + // Invalid layer + if ( Macro_rotationLayer >= LayerNum ) + Macro_rotationLayer = 0; + } + // Previous + else + { + Macro_rotationLayer--; + + // Layer wrap + if ( Macro_rotationLayer >= LayerNum ) + Macro_rotationLayer = LayerNum - 1; + } + + // Toggle the computed layer rotation + Macro_layerState( state, stateType, Macro_rotationLayer, 0x04 ); +} + + // ----- Functions ----- @@ -398,9 +450,9 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) // Determine if layer has key defined // Make sure scanCode is between layer first and last scancodes if ( map != 0 - && scanCode <= layer->last - && scanCode >= layer->first - && *map[ scanCode - layer->first ] != 0 ) + && scanCode <= layer->last + && scanCode >= layer->first + && *map[ scanCode - layer->first ] != 0 ) { // Set the layer cache macroTriggerListLayerCache[ scanCode ] = macroLayerIndexStack[ layerIndex ]; @@ -418,9 +470,9 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) // Make sure scanCode is between layer first and last scancodes if ( map != 0 - && scanCode <= layer->last - && scanCode >= layer->first - && *map[ scanCode - layer->first ] != 0 ) + && scanCode <= layer->last + && scanCode >= layer->first + && *map[ scanCode - layer->first ] != 0 ) { // Set the layer cache to default map macroTriggerListLayerCache[ scanCode ] = 0; @@ -892,7 +944,7 @@ TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex ) } // If passing and in Waiting state, set macro state to Press else if ( overallVote & TriggerMacroVote_Pass - && ( record->state == TriggerMacro_Waiting || record->state == TriggerMacro_Press ) ) + && ( record->state == TriggerMacro_Waiting || record->state == TriggerMacro_Press ) ) { record->state = TriggerMacro_Press; @@ -1212,6 +1264,9 @@ inline void Macro_setup() // Make sure macro trigger buffer is empty macroTriggerListBufferSize = 0; + // Set the current rotated layer to 0 + Macro_rotationLayer = 0; + // Initialize TriggerMacro states for ( var_uint_t macro = 0; macro < TriggerMacroNum; macro++ ) { diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index fcd487e..74c6763 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -345,6 +345,7 @@ inline uint8_t LCD_scan() // ----- Capabilities ----- uint16_t LCD_layerStack_prevSize = 0; +uint16_t LCD_layerStack_prevTop = 0; void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { // Display capability name @@ -358,12 +359,14 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args extern uint16_t macroLayerIndexStack[]; extern uint16_t macroLayerIndexStackSize; - // Only process if the stack size has changed - if ( macroLayerIndexStackSize == LCD_layerStack_prevSize ) + // Ignore if the stack size hasn't changed and the top of the stack is the same + if ( macroLayerIndexStackSize == LCD_layerStack_prevSize + && macroLayerIndexStack[macroLayerIndexStackSize - 1] == LCD_layerStack_prevTop ) { return; } LCD_layerStack_prevSize = macroLayerIndexStackSize; + LCD_layerStack_prevTop = macroLayerIndexStack[macroLayerIndexStackSize - 1]; // Number data for LCD const uint8_t numbers[10][128] = { From 0501e1dfd0d72a779a619a621138a3037973692a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 29 Sep 2015 19:29:27 -0700 Subject: [PATCH 36/79] Initial code for KType TKL --- Scan/KType/defaultMap.kll | 97 ++++++++++++++++++++++++++++++++++++++ Scan/KType/matrix.h | 57 ++++++++++++++++++++++ Scan/KType/scan_loop.c | 99 +++++++++++++++++++++++++++++++++++++++ Scan/KType/scan_loop.h | 40 ++++++++++++++++ Scan/KType/setup.cmake | 32 +++++++++++++ 5 files changed, 325 insertions(+) create mode 100644 Scan/KType/defaultMap.kll create mode 100644 Scan/KType/matrix.h create mode 100644 Scan/KType/scan_loop.c create mode 100644 Scan/KType/scan_loop.h create mode 100644 Scan/KType/setup.cmake diff --git a/Scan/KType/defaultMap.kll b/Scan/KType/defaultMap.kll new file mode 100644 index 0000000..5d0ddfd --- /dev/null +++ b/Scan/KType/defaultMap.kll @@ -0,0 +1,97 @@ +Name = KType; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3c; + +# Modified Date +Date = 2015-09-29; + + +S0x00 : U"Esc"; +S0x01 : U"F1"; +S0x02 : U"F2"; +S0x03 : U"F3"; +S0x04 : U"F4"; +S0x05 : U"F5"; +S0x06 : U"F6"; +S0x07 : U"F7"; +S0x08 : U"F8"; +S0x09 : U"F9"; +S0x0A : U"F10"; +S0x0B : U"F11"; +S0x0C : U"F12"; +S0x0D : U"Print Screen"; +S0x0E : U"ScrollLock"; +S0x0F : U"Pause"; +S0x10 : U"Backtick"; +S0x11 : U"1"; +S0x12 : U"2"; +S0x13 : U"3"; +S0x14 : U"4"; +S0x15 : U"5"; +S0x16 : U"6"; +S0x17 : U"7"; +S0x18 : U"8"; +S0x19 : U"9"; +S0x1A : U"0"; +S0x1B : U"Minus"; +S0x1C : U"Equals"; +S0x1D : U"Backspace"; +S0x1E : U"Insert"; +S0x1F : U"Home"; +S0x20 : U"PageUp"; +S0x21 : U"Tab"; +S0x22 : U"Q"; +S0x23 : U"W"; +S0x24 : U"E"; +S0x25 : U"R"; +S0x26 : U"T"; +S0x27 : U"Y"; +S0x28 : U"U"; +S0x29 : U"I"; +S0x2A : U"O"; +S0x2B : U"P"; +S0x2C : U"Left Brace"; +S0x2D : U"Right Brace"; +S0x2E : U"Backslash"; +S0x2F : U"Delete"; +S0x30 : U"End"; +S0x31 : U"PageDown"; +S0x32 : U"CapsLock"; +S0x33 : U"A"; +S0x34 : U"S"; +S0x35 : U"D"; +S0x36 : U"F"; +S0x37 : U"G"; +S0x38 : U"H"; +S0x39 : U"J"; +S0x3A : U"K"; +S0x3B : U"L"; +S0x3C : U"Semicolon"; +S0x3D : U"Quote"; +S0x3E : U"Enter"; +S0x3F : U"LShift"; +S0x40 : U"Z"; +S0x41 : U"X"; +S0x42 : U"C"; +S0x43 : U"V"; +S0x44 : U"B"; +S0x45 : U"N"; +S0x46 : U"M"; +S0x47 : U"Comma"; +S0x48 : U"Period"; +S0x49 : U"Slash"; +S0x4A : U"RShift"; +S0x4B : U"Up"; +S0x4C : U"LCtrl"; +S0x4D : U"LGui"; +S0x4E : U"LAlt"; +S0x4F : U"Space"; +S0x50 : U"RAlt"; +S0x51 : U"RGui"; +S0x52 : U"Menu"; +S0x53 : U"RCtrl"; +S0x54 : U"Left"; +S0x55 : U"Down"; +S0x56 : U"Right"; + diff --git a/Scan/KType/matrix.h b/Scan/KType/matrix.h new file mode 100644 index 0000000..912a700 --- /dev/null +++ b/Scan/KType/matrix.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Project Includes +#include + + + +// ----- Matrix Definition ----- + +// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 +// Not all chips have access to all of these pins (most don't have 160 pins :P) +// +// NOTE: +// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down +// Checking this is completely on the ownness of the user + +// MDErgo1 +// +// Column (Strobe) - 9 Total +// PTB2,3,18,19 +// PTC0,9..11 +// PTD0 +// +// Rows (Sense) - 5 Total +// PTD1,4..7 + +// Define Rows (Sense) and Columns (Strobes) +// TODO +GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11) }; +GPIO_Pin Matrix_rows[] = { gpio(D,0), gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2) }; + +// Define type of scan matrix +Config Matrix_type = Config_Pulldown; + diff --git a/Scan/KType/scan_loop.c b/Scan/KType/scan_loop.c new file mode 100644 index 0000000..7999853 --- /dev/null +++ b/Scan/KType/scan_loop.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include +#include +#include +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Function Declarations ----- + +// ----- Variables ----- + +// Number of scans since the last USB send +uint16_t Scan_scanCount = 0; + + + +// ----- Functions ----- + +// Setup +inline void Scan_setup() +{ + // Setup UART Connect, if Output_Available, this is the master node + Connect_setup( Output_Available ); + + // Setup GPIO pins for matrix scanning + Matrix_setup(); + + // Setup ISSI chip to control the leds + LED_setup(); + + // Reset scan count + Scan_scanCount = 0; +} + + +// Main Detection Loop +inline uint8_t Scan_loop() +{ + // Scan Matrix + Matrix_scan( Scan_scanCount++ ); + + // Process any interconnect commands + Connect_scan(); + + // Process any LED events + LED_scan(); + + return 0; +} + + +// Signal from Macro Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithMacro( uint8_t sentKeys ) +{ +} + + +// Signal from Output Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithOutput( uint8_t sentKeys ) +{ + // Reset scan loop indicator (resets each key debounce state) + // TODO should this occur after USB send or Macro processing? + Scan_scanCount = 0; +} + diff --git a/Scan/KType/scan_loop.h b/Scan/KType/scan_loop.h new file mode 100644 index 0000000..17a06fc --- /dev/null +++ b/Scan/KType/scan_loop.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Functions ----- + +// Functions to be called by main.c +void Scan_setup( void ); +uint8_t Scan_loop( void ); + +// Call-backs +void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module +void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + diff --git a/Scan/KType/setup.cmake b/Scan/KType/setup.cmake new file mode 100644 index 0000000..50aef79 --- /dev/null +++ b/Scan/KType/setup.cmake @@ -0,0 +1,32 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2015 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Sub-modules +# +AddModule ( Scan ISSILed ) +AddModule ( Scan MatrixARM ) +AddModule ( Scan UARTConnect ) + + +### +# Module C files +# +set ( Module_SRCS + scan_loop.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + From 8311f1b083a6e9871526c13690fe6156f9169a4e Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 29 Sep 2015 20:21:29 -0700 Subject: [PATCH 37/79] Updating KType layout to work more nicely with KiiConf --- Scan/KType/defaultMap.kll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scan/KType/defaultMap.kll b/Scan/KType/defaultMap.kll index 5d0ddfd..3f9c632 100644 --- a/Scan/KType/defaultMap.kll +++ b/Scan/KType/defaultMap.kll @@ -20,7 +20,7 @@ S0x09 : U"F9"; S0x0A : U"F10"; S0x0B : U"F11"; S0x0C : U"F12"; -S0x0D : U"Print Screen"; +S0x0D : U"PrintScreen"; S0x0E : U"ScrollLock"; S0x0F : U"Pause"; S0x10 : U"Backtick"; @@ -51,8 +51,8 @@ S0x28 : U"U"; S0x29 : U"I"; S0x2A : U"O"; S0x2B : U"P"; -S0x2C : U"Left Brace"; -S0x2D : U"Right Brace"; +S0x2C : U"LBrace"; +S0x2D : U"RBrace"; S0x2E : U"Backslash"; S0x2F : U"Delete"; S0x30 : U"End"; From 3eece241155841c079b357a880bb332094e09de2 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 4 Oct 2015 16:19:20 -0700 Subject: [PATCH 38/79] Fix Latching bug (introduced when fixing shift and lock recently) - Also conditionally refresh the lcd screen if enabled /w interconnect (Not the ideal way to update, but the only way with the current KLL version) --- .gitignore | 1 + Macro/PartialMap/macro.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e404153..7a86e68 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ .Trashes ehthumbs.db Thumbs.db +*.attr # Editor generated files # ########################## diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 690231c..8f1d1b8 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -422,7 +422,22 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) nat_ptr_t **map = (nat_ptr_t**)LayerIndex[ cachedLayer ].triggerMap; const Layer *layer = &LayerIndex[ cachedLayer ]; - return map[ scanCode - layer->first ]; + // Cache trigger list before attempting to expire latch + nat_ptr_t *trigger_list = map[ scanCode - layer->first ]; + + // Check if latch has been pressed for this layer + uint8_t latch = LayerState[ cachedLayer ] & 0x02; + if ( latch && latch_expire ) + { + Macro_layerState( 0, 0, cachedLayer, 0x02 ); +#if defined(ConnectEnabled_define) && defined(LCDEnabled_define) + // Evaluate the layerStack capability if available (LCD + Interconnect) + extern void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + LCD_layerStack_capability( 0, 0, 0 ); +#endif + } + + return trigger_list; } // If no trigger macro is defined at the given layer, fallthrough to the next layer From c90bafd5c4bf6730cba48569b566e6d3ee79b41b Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 6 Oct 2015 00:24:04 -0700 Subject: [PATCH 39/79] Cleaning up CLEAR_FEATURE (endpoint) - Reverting old fix that no longer seems relevant after numerous recent USB fixes --- Output/pjrcUSB/arm/usb_dev.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 1cc4f13..125500a 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -330,27 +330,21 @@ static void usb_setup() endpoint0_stall(); return; - case 0x0102: // CLEAR_FEATURE (interface) + case 0x0102: // CLEAR_FEATURE (endpoint) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) { endpoint0_stall(); return; } - warn_print("CLEAR_FEATURE - Interface"); - //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; + (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; // TODO: do we need to clear the data toggle here? - //break; - - // FIXME: Clearing causes keyboard to freeze, likely an invalid clear - // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa - endpoint0_stall(); - return; + goto send; case 0x0300: // SET_FEATURE (device) case 0x0301: // SET_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa - warn_print("SET_FEATURE"); + warn_print("SET_FEATURE - Device/Interface"); endpoint0_stall(); return; From d7fabf97e9f3c0768bc52942006a690dc594f730 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 7 Oct 2015 20:06:41 -0700 Subject: [PATCH 40/79] Fixing very old bad naming convention (BRACE to BRACKET) --- Macro/PartialMap/usb_hid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Macro/PartialMap/usb_hid.h b/Macro/PartialMap/usb_hid.h index a7d5581..a9ac568 100644 --- a/Macro/PartialMap/usb_hid.h +++ b/Macro/PartialMap/usb_hid.h @@ -74,8 +74,8 @@ #define KEY_SPACE 0x2C #define KEY_MINUS 0x2D #define KEY_EQUAL 0x2E -#define KEY_LEFT_BRACE 0x2F -#define KEY_RIGHT_BRACE 0x30 +#define KEY_LEFT_BRACKET 0x2F +#define KEY_RIGHT_BRACKET 0x30 #define KEY_BACKSLASH 0x31 #define KEY_NUMBER 0x32 #define KEY_SEMICOLON 0x33 From f4da2560c43f8182aa0fd8270fe175148d084b66 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 9 Oct 2015 18:18:07 -0700 Subject: [PATCH 41/79] Fixing long-standing SET_REPORT bug - Implementation was completely wrong (has never worked properly) - Now working in both NKRO and 6KRO modes - Added more debugging code if things go wrong again --- Output/pjrcUSB/arm/usb_dev.c | 88 +++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 125500a..e913006 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -424,17 +424,23 @@ static void usb_setup() return; case 0x0921: // HID SET_REPORT - #ifdef UART_DEBUG - warn_msg("SET_REPORT - "); - printHex( setup.wValue ); - print(" - "); - printHex( setup.wValue & 0xFF ); - print( NL ); - #endif - USBKeys_LEDs = setup.wValue & 0xFF; + // Interface + switch ( setup.wIndex & 0xFF ) + { + // Keyboard Interface + case KEYBOARD_INTERFACE: + break; + // NKRO Keyboard Interface + case NKRO_KEYBOARD_INTERFACE: + break; + default: + warn_msg("Unknown interface - "); + printHex( setup.wIndex ); + print( NL ); + endpoint0_stall(); + break; + } - // Must be stall for some reason... -HaaTa - endpoint0_stall(); return; case 0x01A1: // HID GET_REPORT @@ -612,6 +618,10 @@ static void usb_control( uint32_t stat ) printHex(setup.wIndex); print(", len:"); printHex(setup.wLength); + print(" -- "); + printHex32(setup.word1); + print(" "); + printHex32(setup.word2); print(NL); #endif // actually "do" the setup request @@ -622,9 +632,22 @@ static void usb_control( uint32_t stat ) case 0x01: // OUT transaction received from host case 0x02: - #ifdef UART_DEBUG - print("PID=OUT"NL); + #ifdef UART_DEBUG_UNKNOWN + print("PID=OUT wRequestAndType:"); + printHex(setup.wRequestAndType); + print(", wValue:"); + printHex(setup.wValue); + print(", wIndex:"); + printHex(setup.wIndex); + print(", len:"); + printHex(setup.wLength); + print(" -- "); + printHex32(setup.word1); + print(" "); + printHex32(setup.word2); + print(NL); #endif + // CDC Interface if ( setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/ ) { @@ -643,17 +666,38 @@ static void usb_control( uint32_t stat ) endpoint0_transmit( NULL, 0 ); } - // Keyboard Interface - if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | KEYBOARD_INTERFACE ) ) + // Keyboard SET_REPORT + if ( setup.wRequestAndType == 0x921 && setup.wValue & 0x200 ) { - USBKeys_LEDs = buf[0]; - endpoint0_transmit( NULL, 0 ); - } - // NKRO Keyboard Interface - if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | NKRO_KEYBOARD_INTERFACE ) ) - { - USBKeys_LEDs = buf[0]; - endpoint0_transmit( NULL, 0 ); + // Interface + switch ( setup.wIndex & 0xFF ) + { + // Keyboard Interface + case KEYBOARD_INTERFACE: + USBKeys_LEDs = buf[0]; + endpoint0_transmit( NULL, 0 ); + break; + // NKRO Keyboard Interface + case NKRO_KEYBOARD_INTERFACE: + // Only use 2nd byte, first byte is the report id + USBKeys_LEDs = buf[1]; + endpoint0_transmit( NULL, 0 ); + break; + default: + warn_msg("Unknown interface - "); + printHex( setup.wIndex ); + print( NL ); + break; + } + + #ifdef UART_DEBUG + for ( size_t len = 0; len < setup.wLength; len++ ) + { + printHex( buf[ len ] ); + print(" "); + } + print( NL ); + #endif } // give the buffer back From d9ba60b34ee80e073ef708a7e9e58d8b8529a0e2 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 9 Oct 2015 22:28:31 -0700 Subject: [PATCH 42/79] Adding basic ISSI led brightness control capabilities - 6 modes * Single led: decrease, increase, set * All leds: decrease, increase, set - Currently update speed limited to once every 30 ms * Likely an I2C driver or ISSI limitation preventing even faster updates --- Scan/ISSILed/capabilities.kll | 20 ++- Scan/ISSILed/led_scan.c | 232 +++++++++++++++++++++++++++++----- 2 files changed, 219 insertions(+), 33 deletions(-) diff --git a/Scan/ISSILed/capabilities.kll b/Scan/ISSILed/capabilities.kll index 2c0a32c..6ecd4f6 100644 --- a/Scan/ISSILed/capabilities.kll +++ b/Scan/ISSILed/capabilities.kll @@ -1,10 +1,26 @@ Name = ISSILedCapabilities; -Version = 0.1; +Version = 0.2; Author = "HaaTa (Jacob Alexander) 2015"; KLL = 0.3c; # Modified Date -Date = 2015-08-02; +Date = 2015-10-09; + +# Basic ISSI Capabilities +# Modes +# 0: Decrease single led brightness +# 1: Increase single led brightness +# 2: Set single led brightness +# 3: Decrease brightness of all leds +# 4: Increase brightness of all leds +# 5: Set brightness of all leds +# Amount -> 0 -> 255 +# Index: +# Depends on keyboard. At least from from 0 -> 143 (single chip). +# Remember, it may be possible that all leds on a single chip are connected. +# So it may be possible that you may have index gaps. +# i.e. 23 then 144 +ledControl => LED_control_capability( mode : 1, amount : 1, index : 2 ); # Defines available to the ISSILed sub-module diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index 33073ab..549fc0d 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -49,6 +49,8 @@ typedef struct I2C_Buffer { } I2C_Buffer; typedef struct LED_Buffer { + uint8_t i2c_addr; + uint8_t reg_addr; uint8_t buffer[LED_BufferLength]; } LED_Buffer; @@ -59,6 +61,7 @@ typedef struct LED_Buffer { // CLI Functions void cliFunc_i2cRecv ( char* args ); void cliFunc_i2cSend ( char* args ); +void cliFunc_ledCtrl ( char* args ); void cliFunc_ledRPage( char* args ); void cliFunc_ledStart( char* args ); void cliFunc_ledTest ( char* args ); @@ -77,6 +80,7 @@ uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ); // Scan Module command dictionary CLIDict_Entry( i2cRecv, "Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence." NL "\t\tUse |'s to split sequences with a stop." ); CLIDict_Entry( i2cSend, "Send I2C sequence of bytes. Use |'s to split sequences with a stop." ); +CLIDict_Entry( ledCtrl, "Basic LED control. Args: []" ); CLIDict_Entry( ledRPage, "Read the given register page." ); CLIDict_Entry( ledStart, "Disable software shutdown." ); CLIDict_Entry( ledTest, "Test out the led pages." ); @@ -86,6 +90,7 @@ CLIDict_Entry( ledZero, "Zero out LED register pages (non-configuration)." ) CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { CLIDict_Item( i2cRecv ), CLIDict_Item( i2cSend ), + CLIDict_Item( ledCtrl ), CLIDict_Item( ledRPage ), CLIDict_Item( ledStart ), CLIDict_Item( ledTest ), @@ -178,7 +183,9 @@ void i2c0_isr() } else { - dbug_print("Attempting to read byte"); + dbug_msg("Attempting to read byte - "); + printHex( I2C_RxBuffer.sequencePos ); + print( NL ); I2C0_C1 = I2C_RxBuffer.sequencePos == 1 ? I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TXAK // Single byte read : I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST; // Multi-byte read @@ -309,34 +316,6 @@ void LED_sendPage( uint8_t *buffer, uint8_t len, uint8_t page ) } -void LED_readPage( uint8_t len, uint8_t page ) -{ - // Page Setup - uint8_t pageSetup[] = { 0xE8, 0xFD, page }; - - // Setup page - while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) - delay(1); - - // Register Setup - uint8_t regSetup[] = { 0xE8, 0x00 }; - - // Setup starting register - while ( I2C_Send( regSetup, sizeof( regSetup ), 0 ) == 0 ) - delay(1); - - // Register Read Command - uint8_t regReadCmd[] = { 0xE9 }; - - // Read each register in the page - for ( uint8_t reg = 0; reg < len; reg++ ) - { - // Request register data - while ( I2C_Send( regReadCmd, sizeof( regReadCmd ), 0 ) == 0 ) - delay(1); - } -} - void LED_writeReg( uint8_t reg, uint8_t val, uint8_t page ) { // Page Setup @@ -353,6 +332,44 @@ void LED_writeReg( uint8_t reg, uint8_t val, uint8_t page ) delay(1); } +void LED_readPage( uint8_t len, uint8_t page ) +{ + // Software shutdown must be enabled to read registers + LED_writeReg( 0x0A, 0x00, 0x0B ); + + // Page Setup + uint8_t pageSetup[] = { 0xE8, 0xFD, page }; + + // Setup page + while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) + delay(1); + + // Register Setup + uint8_t regSetup[] = { 0xE8, 0x00 }; + + // Read each register in the page + for ( uint8_t reg = 0; reg < len; reg++ ) + { + // Update register to read + regSetup[1] = reg; + + // Configure register + while ( I2C_Send( regSetup, sizeof( regSetup ), 0 ) == 0 ) + delay(1); + + // Register Read Command + uint8_t regReadCmd[] = { 0xE9 }; + + // Request single register byte + while ( I2C_Send( regReadCmd, sizeof( regReadCmd ), 1 ) == 0 ) + delay(1); + dbug_print("NEXT"); + } + + // Disable software shutdown + LED_writeReg( 0x0A, 0x01, 0x0B ); +} + // Setup inline void LED_setup() { @@ -619,8 +636,122 @@ inline uint8_t LED_scan() +// ----- Capabilities ----- + +// Basic LED Control Capability +typedef enum LedControlMode { + // Single LED Modes + LedControlMode_brightness_decrease, + LedControlMode_brightness_increase, + LedControlMode_brightness_set, + // Set all LEDs (index argument not required) + LedControlMode_brightness_decrease_all, + LedControlMode_brightness_increase_all, + LedControlMode_brightness_set_all, +} LedControlMode; + +typedef struct LedControl { + LedControlMode mode; // XXX Make sure to adjust the .kll capability if this variable is larger than 8 bits + uint8_t amount; + uint16_t index; +} LedControl; + +uint8_t LED_control_timer = 0; +void LED_control( LedControl *control ) +{ + // Only send if we've completed all other transactions + if ( I2C_TxBuffer.sequencePos > 0 ) + return; + + // XXX + // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa) + // Make sure we only send an update every 30 milliseconds at most + // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer + + uint8_t currentTime = (uint8_t)systick_millis_count; + int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F; + if ( compare < 30 ) + { + return; + } + LED_control_timer = currentTime; + + // Configure based upon the given mode + // TODO Handle multiple issi chips per node + // TODO Perhaps do gamma adjustment? + switch ( control->mode ) + { + case LedControlMode_brightness_decrease: + // Don't worry about rolling over, the cycle is quick + LED_pageBuffer.buffer[ control->index ] -= control->amount; + break; + + case LedControlMode_brightness_increase: + // Don't worry about rolling over, the cycle is quick + LED_pageBuffer.buffer[ control->index ] += control->amount; + break; + + case LedControlMode_brightness_set: + LED_pageBuffer.buffer[ control->index ] = control->amount; + break; + + case LedControlMode_brightness_decrease_all: + for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + { + // Don't worry about rolling over, the cycle is quick + LED_pageBuffer.buffer[ channel ] -= control->amount; + } + break; + + case LedControlMode_brightness_increase_all: + for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + { + // Don't worry about rolling over, the cycle is quick + LED_pageBuffer.buffer[ channel ] += control->amount; + } + break; + + case LedControlMode_brightness_set_all: + for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + { + LED_pageBuffer.buffer[ channel ] = control->amount; + } + break; + } + + // Sync LED buffer with ISSI chip buffer + // TODO Support multiple frames + LED_pageBuffer.i2c_addr = 0xE8; // Chip 1 + LED_pageBuffer.reg_addr = 0x24; // Brightness section + LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 ); +} + +void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("LED_control_capability(mode,amount,index)"); + return; + } + + // Only use capability on press + // TODO Analog + if ( stateType == 0x00 && state == 0x03 ) // Not on release + return; + + // Set the input structure + LedControl *control = (LedControl*)args; + + // TODO broadcast to rest of interconnect nodes if necessary + LED_control( control ); +} + + + // ----- CLI Command Functions ----- +// TODO Currently not working correctly void cliFunc_i2cSend( char* args ) { char* curArgs; @@ -717,6 +848,7 @@ void cliFunc_i2cRecv( char* args ) I2C_Send( buffer, bufferLen, 1 ); // Only 1 byte is ever read at a time with the ISSI chip } +// TODO Currently not working correctly void cliFunc_ledRPage( char* args ) { // Parse number from argument @@ -730,13 +862,14 @@ void cliFunc_ledRPage( char* args ) if ( arg1Ptr[0] != '\0' ) { - page = (uint8_t)numToInt( arg1Ptr ); + page = (uint8_t)numToInt( arg1Ptr ); } // No \r\n by default after the command is entered print( NL ); - LED_readPage( 0xB4, page ); + LED_readPage( 0x1, page ); + //LED_readPage( 0xB4, page ); } void cliFunc_ledWPage( char* args ) @@ -809,3 +942,40 @@ void cliFunc_ledZero( char* args ) LED_zeroPages( 0x00, 8, 0x24, 0xB4 ); // Only PWMs } +void cliFunc_ledCtrl( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + LedControl control; + + // First process mode + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + control.mode = numToInt( arg1Ptr ); + + + // Next process amount + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + control.amount = numToInt( arg1Ptr ); + + + // Finally process led index, if it exists + // Default to 0 + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + control.index = *arg1Ptr == '\0' ? 0 : numToInt( arg1Ptr ); + + // Process request + LED_control( &control ); +} + From 59d425ccfe1ca3019ba80ad6dd4a228b7c7cbe33 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 11 Oct 2015 22:07:11 -0700 Subject: [PATCH 43/79] Adding jump to bootloader key - Now enabled by default - Added protection around remote jumps --- Debug/cli/cli.c | 12 +++++++++--- Macro/PartialMap/macro.c | 13 +++++++++++++ Output/pjrcUSB/arm/usb_dev.c | 33 +-------------------------------- Output/pjrcUSB/output_com.c | 2 +- Output/usbMuxUart/output_com.c | 2 +- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/Debug/cli/cli.c b/Debug/cli/cli.c index 03fb3ca..149d12d 100644 --- a/Debug/cli/cli.c +++ b/Debug/cli/cli.c @@ -21,14 +21,12 @@ // ----- Includes ----- -// Compiler Includes -//#include - // Project Includes #include #include "cli.h" #include #include +#include @@ -517,6 +515,14 @@ void cliFunc_led( char* args ) void cliFunc_reload( char* args ) { + if ( flashModeEnabled_define == 0 ) + { + print( NL ); + warn_print("flashModeEnabled not set, cancelling firmware reload..."); + info_msg("Set flashModeEnabled to 1 in your kll configuration."); + return; + } + // Request to output module to be set into firmware reload mode Output_firmwareReload(); } diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 8f1d1b8..e861f0e 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -1378,6 +1378,19 @@ void cliFunc_capSelect( char* args ) 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)(uint8_t, uint8_t, uint8_t*) = (void(*)(uint8_t, uint8_t, uint8_t*))(CapabilitiesList[ cap ].func); capability( argSet[0], argSet[1], &argSet[2] ); } diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index e913006..782f3ac 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -911,40 +911,9 @@ void usb_tx( uint32_t endpoint, usb_packet_t *packet ) void usb_device_reload() { - if ( flashModeEnabled_define == 0 ) - { - print( NL ); - warn_print("flashModeEnabled not set, cancelling firmware reload..."); - info_msg("Set flashModeEnabled to 1 in your kll configuration."); - return; - } - // MCHCK -#if defined(_mk20dx128vlf5_) - - // MCHCK Kiibohd Variant - // Check to see if PTA3 (has a pull-up) is connected to GND (usually via jumper) - // Only allow reload if the jumper is present (security) - GPIOA_PDDR &= ~(1<<3); // Input - PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up - - // Check for jumper - if ( GPIOA_PDIR & (1<<3) && flashModeEnabled_define != 0 ) - { - print( NL ); - warn_print("Security jumper not present, cancelling firmware reload..."); - info_msg("Replace jumper on middle 2 pins, or manually press the firmware reload button."); - } - else - { - // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode - for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ ) - (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ]; - SOFTWARE_RESET(); - } - // Kiibohd mk20dx256vlh7 -#elif defined(_mk20dx256vlh7_) +#if defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) // Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ ) (&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ]; diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index d594ac1..2e97e42 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -489,7 +489,7 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg // Display capability name if ( stateType == 0xFF && state == 0xFF ) { - print("Output_flashMode(usbCode)"); + print("Output_flashMode()"); return; } diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 928f342..44c5b49 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -495,7 +495,7 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg // Display capability name if ( stateType == 0xFF && state == 0xFF ) { - print("Output_flashMode(usbCode)"); + print("Output_flashMode()"); return; } From 425ee673310b32ba581b4c574df12c9791e02fc7 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 11 Oct 2015 23:23:20 -0700 Subject: [PATCH 44/79] More compatible name --- Scan/WhiteFox/defaultMap.kll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll index 474d8ba..798a0c7 100644 --- a/Scan/WhiteFox/defaultMap.kll +++ b/Scan/WhiteFox/defaultMap.kll @@ -54,7 +54,7 @@ S0x2B : U"App"; S0x2C : U"Enter"; S0x2D : U"PageUp"; S0x2E : U"LShift"; -S0x2F : U"ISO Slash"; +S0x2F : U"ISO/"; S0x30 : U"Z"; S0x31 : U"X"; S0x32 : U"C"; From be2a6b35e72eb93a54e5983bf5fad7f30ae98504 Mon Sep 17 00:00:00 2001 From: Jan van Haarst Date: Mon, 12 Oct 2015 22:11:21 +0200 Subject: [PATCH 45/79] Fixed typo --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f020072..7039d59 100644 --- a/README.markdown +++ b/README.markdown @@ -38,7 +38,7 @@ Supported Microcontrollers * Teensy 2.0 (Partial) * Teensy 2.0++ -* Teesny 3.0 +* Teensy 3.0 * Teensy 3.1 * mk20dx128vlf5 * mk20dx256vlh7 From 7e68e81f4757ffff2261ab4a887d4114318aa5b6 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 15 Oct 2015 00:16:36 -0700 Subject: [PATCH 46/79] Adding basic remote capabilities + UART Rx DMA buffers - Rx buffers weren't fast enough, had to use DMA :D - Basic LCD remote capabilities are working, single node - Multi-node broadcast seems to have a bug still - DMA ring buffer allowed for significant processing simplification * There is an overrun risk, but the buffer is large and generally there isn't too much data being sent (just very quickly) - Split out LCD layer stack capability into itself and an "exact" version used for updating remote nodes --- Lib/CMake/modules.cmake | 2 +- Lib/mk20dx.h | 28 ++ Output/pjrcUSB/arm/usb_desc.c | 2 +- Scan/MatrixARM/matrix_scan.c | 1 + Scan/STLcd/capabilities.kll | 3 +- Scan/STLcd/lcd_scan.c | 103 ++++- Scan/UARTConnect/capabilities.kll | 4 +- Scan/UARTConnect/connect_scan.c | 701 +++++++++++++++++++----------- Scan/UARTConnect/connect_scan.h | 8 +- 9 files changed, 572 insertions(+), 280 deletions(-) diff --git a/Lib/CMake/modules.cmake b/Lib/CMake/modules.cmake index 0951d4d..d13b868 100644 --- a/Lib/CMake/modules.cmake +++ b/Lib/CMake/modules.cmake @@ -277,7 +277,7 @@ if ( CTAGS_EXECUTABLE ) endforeach () # Generate the ctags - execute_process ( COMMAND ctags ${CTAG_PATHS} + execute_process ( COMMAND ctags --fields=+l ${CTAG_PATHS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) endif () diff --git a/Lib/mk20dx.h b/Lib/mk20dx.h index 277cfed..ae69dd4 100644 --- a/Lib/mk20dx.h +++ b/Lib/mk20dx.h @@ -511,11 +511,37 @@ #define DMA_ERQ_ERQ1 ((uint32_t)1<<1) // Enable DMA Request 1 #define DMA_ERQ_ERQ2 ((uint32_t)1<<2) // Enable DMA Request 2 #define DMA_ERQ_ERQ3 ((uint32_t)1<<3) // Enable DMA Request 3 +#define DMA_ERQ_ERQ4 ((uint32_t)1<<4) // Enable DMA Request 4 +#define DMA_ERQ_ERQ5 ((uint32_t)1<<5) // Enable DMA Request 5 +#define DMA_ERQ_ERQ6 ((uint32_t)1<<6) // Enable DMA Request 6 +#define DMA_ERQ_ERQ7 ((uint32_t)1<<7) // Enable DMA Request 7 +#define DMA_ERQ_ERQ8 ((uint32_t)1<<8) // Enable DMA Request 8 +#define DMA_ERQ_ERQ9 ((uint32_t)1<<9) // Enable DMA Request 9 +#define DMA_ERQ_ERQ10 ((uint32_t)1<<10) // Enable DMA Request 10 +#define DMA_ERQ_ERQ11 ((uint32_t)1<<11) // Enable DMA Request 11 +#define DMA_ERQ_ERQ12 ((uint32_t)1<<12) // Enable DMA Request 12 +#define DMA_ERQ_ERQ13 ((uint32_t)1<<13) // Enable DMA Request 13 +#define DMA_ERQ_ERQ14 ((uint32_t)1<<14) // Enable DMA Request 14 +#define DMA_ERQ_ERQ15 ((uint32_t)1<<15) // Enable DMA Request 15 +#define DMA_ERQ_ERQ16 ((uint32_t)1<<16) // Enable DMA Request 16 #define DMA_EEI *(volatile uint32_t *)0x40008014 // Enable Error Interrupt Register #define DMA_EEI_EEI0 ((uint32_t)1<<0) // Enable Error Interrupt 0 #define DMA_EEI_EEI1 ((uint32_t)1<<1) // Enable Error Interrupt 1 #define DMA_EEI_EEI2 ((uint32_t)1<<2) // Enable Error Interrupt 2 #define DMA_EEI_EEI3 ((uint32_t)1<<3) // Enable Error Interrupt 3 +#define DMA_EEI_EEI4 ((uint32_t)1<<4) // Enable Error Interrupt 4 +#define DMA_EEI_EEI5 ((uint32_t)1<<5) // Enable Error Interrupt 5 +#define DMA_EEI_EEI6 ((uint32_t)1<<6) // Enable Error Interrupt 6 +#define DMA_EEI_EEI7 ((uint32_t)1<<7) // Enable Error Interrupt 7 +#define DMA_EEI_EEI8 ((uint32_t)1<<8) // Enable Error Interrupt 8 +#define DMA_EEI_EEI9 ((uint32_t)1<<9) // Enable Error Interrupt 9 +#define DMA_EEI_EEI10 ((uint32_t)1<<10) // Enable Error Interrupt 10 +#define DMA_EEI_EEI11 ((uint32_t)1<<11) // Enable Error Interrupt 11 +#define DMA_EEI_EEI12 ((uint32_t)1<<12) // Enable Error Interrupt 12 +#define DMA_EEI_EEI13 ((uint32_t)1<<13) // Enable Error Interrupt 13 +#define DMA_EEI_EEI14 ((uint32_t)1<<14) // Enable Error Interrupt 14 +#define DMA_EEI_EEI15 ((uint32_t)1<<15) // Enable Error Interrupt 15 +#define DMA_EEI_EEI16 ((uint32_t)1<<16) // Enable Error Interrupt 16 #define DMA_CEEI *(volatile uint8_t *)0x40008018 // Clear Enable Error Interrupt Register #define DMA_CEEI_CEEI(n) ((uint8_t)(n & 3)<<0) // Clear Enable Error Interrupt #define DMA_CEEI_CAEE ((uint8_t)1<<6) // Clear All Enable Error Interrupts @@ -1468,6 +1494,8 @@ typedef struct { #define UART0_MA2 *(volatile uint8_t *)0x4006A009 // UART Match Address Registers 2 #define UART0_C4 *(volatile uint8_t *)0x4006A00A // UART Control Register 4 #define UART0_C5 *(volatile uint8_t *)0x4006A00B // UART Control Register 5 +#define UART_C5_TDMAS 0x80 +#define UART_C5_RDMAS 0x20 #define UART0_ED *(volatile uint8_t *)0x4006A00C // UART Extended Data Register #define UART0_MODEM *(volatile uint8_t *)0x4006A00D // UART Modem Register #define UART0_IR *(volatile uint8_t *)0x4006A00E // UART Infrared Register diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 7a8e497..70ece51 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -97,7 +97,7 @@ static uint8_t usb_debug_descriptor[] = { -// ----- USB HID Report Descriptsors ----- +// ----- USB HID Report Descriptors ----- // Each HID interface needs a special report descriptor that tells // the meaning and format of the data. diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 8463b26..a9018df 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -196,6 +196,7 @@ void Matrix_setup() print( NL ); info_msg("Max Keys: "); printHex( Matrix_maxKeys ); + print( NL ); // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) diff --git a/Scan/STLcd/capabilities.kll b/Scan/STLcd/capabilities.kll index 62d52c0..d5daaea 100644 --- a/Scan/STLcd/capabilities.kll +++ b/Scan/STLcd/capabilities.kll @@ -66,7 +66,8 @@ STLcdDefaultImage = " # Layer Status Display -LCDLayerDisplay => LCD_layerStack_capability(); +LCDLayerDisplay => LCD_layerStack_capability(); +LCDLayerDisplayExact => LCD_layerStackExact_capability( display : 1, stack1 : 2, stack2 : 2, stack3 : 2, stack4 : 2 ); # LCD Module Enabled diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index 74c6763..c4bf080 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -25,6 +25,11 @@ #include #include +// Interconnect module if compiled in +#if defined(ConnectEnabled_define) +#include +#endif + // Local Includes #include "lcd_scan.h" @@ -344,29 +349,26 @@ inline uint8_t LCD_scan() // ----- Capabilities ----- -uint16_t LCD_layerStack_prevSize = 0; -uint16_t LCD_layerStack_prevTop = 0; -void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +// Takes 1 8 bit length and 4 16 bit arguments, each corresponding to a layer index +// Ordered from top to bottom +// The first argument indicates how many numbers to display (max 4), set to 0 to load default image +uint16_t LCD_layerStackExact[4]; +uint8_t LCD_layerStackExact_size = 0; +typedef struct LCD_layerStackExact_args { + uint8_t numArgs; + uint16_t layers[4]; +} LCD_layerStackExact_args; +void LCD_layerStackExact_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { // Display capability name if ( stateType == 0xFF && state == 0xFF ) { - print("LCD_layerStack_capability"); + print("LCD_layerStackExact_capability(num,layer1,layer2,layer3,layer4)"); return; } - // Parse the layer stack, top to bottom - extern uint16_t macroLayerIndexStack[]; - extern uint16_t macroLayerIndexStackSize; - - // Ignore if the stack size hasn't changed and the top of the stack is the same - if ( macroLayerIndexStackSize == LCD_layerStack_prevSize - && macroLayerIndexStack[macroLayerIndexStackSize - 1] == LCD_layerStack_prevTop ) - { - return; - } - LCD_layerStack_prevSize = macroLayerIndexStackSize; - LCD_layerStack_prevTop = macroLayerIndexStack[macroLayerIndexStackSize - 1]; + // Read arguments + LCD_layerStackExact_args *stack_args = (LCD_layerStackExact_args*)args; // Number data for LCD const uint8_t numbers[10][128] = { @@ -397,10 +399,10 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args }; // Only display if there are layers active - if ( macroLayerIndexStackSize > 0 ) + if ( stack_args->numArgs > 0 ) { // Set the color according to the "top-of-stack" layer - uint16_t layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - 1 ]; + uint16_t layerIndex = stack_args->layers[0]; FTM0_C0V = colors[ layerIndex ][0]; FTM0_C1V = colors[ layerIndex ][1]; FTM0_C2V = colors[ layerIndex ][2]; @@ -418,9 +420,9 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args LCD_writeControlReg( 0x00 ); // Write data - for ( uint16_t layer = 1; layer <= macroLayerIndexStackSize; layer++ ) + for ( uint16_t layer = 0; layer < stack_args->numArgs; layer++ ) { - layerIndex = macroLayerIndexStack[ macroLayerIndexStackSize - layer ]; + layerIndex = stack_args->layers[ layer ]; // Default to 0, if over 9 if ( layerIndex > 9 ) @@ -434,7 +436,7 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args // Blank out rest of display uint8_t data = 0; - for ( uint8_t c = 0; c < 4 - macroLayerIndexStackSize; c++ ) + for ( uint8_t c = 0; c < 4 - stack_args->numArgs; c++ ) { for ( uint8_t byte = 0; byte < 32; byte++ ) { @@ -456,6 +458,65 @@ void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args } } +// Determines the current layer stack, and sets the LCD output accordingly +// Will only work on a master node when using the interconnect (use LCD_layerStackExact_capability instead) +uint16_t LCD_layerStack_prevSize = 0; +uint16_t LCD_layerStack_prevTop = 0; +void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("LCD_layerStack_capability()"); + return; + } + + // Parse the layer stack, top to bottom + extern uint16_t macroLayerIndexStack[]; + extern uint16_t macroLayerIndexStackSize; + + // Ignore if the stack size hasn't changed and the top of the stack is the same + if ( macroLayerIndexStackSize == LCD_layerStack_prevSize + && macroLayerIndexStack[macroLayerIndexStackSize - 1] == LCD_layerStack_prevTop ) + { + return; + } + LCD_layerStack_prevSize = macroLayerIndexStackSize; + LCD_layerStack_prevTop = macroLayerIndexStack[macroLayerIndexStackSize - 1]; + + LCD_layerStackExact_args stack_args; + memset( stack_args.layers, 0, sizeof( stack_args.layers ) ); + + // Use the LCD_layerStackExact_capability to set the LCD using the determined stack + // Construct argument set for capability + stack_args.numArgs = macroLayerIndexStackSize; + for ( uint16_t layer = 1; layer <= macroLayerIndexStackSize; layer++ ) + { + stack_args.layers[ layer - 1 ] = macroLayerIndexStack[ macroLayerIndexStackSize - layer ]; + } + + // Only deal with the interconnect if it has been compiled in +#if defined(ConnectEnabled_define) + if ( Connect_master ) + { + // generatedKeymap.h + extern const Capability CapabilitiesList[]; + + // Broadcast layerStackExact remote capability (0xFF is the broadcast id) + Connect_send_RemoteCapability( + 0xFF, + LCD_layerStackExact_capability_index, + state, + stateType, + CapabilitiesList[ LCD_layerStackExact_capability_index ].argCount, + (uint8_t*)&stack_args + ); + } +#endif + // Call LCD_layerStackExact directly + LCD_layerStackExact_capability( state, stateType, (uint8_t*)&stack_args ); +} + // ----- CLI Command Functions ----- diff --git a/Scan/UARTConnect/capabilities.kll b/Scan/UARTConnect/capabilities.kll index b907221..bab1b61 100644 --- a/Scan/UARTConnect/capabilities.kll +++ b/Scan/UARTConnect/capabilities.kll @@ -26,9 +26,11 @@ UARTConnectBaudFine => UARTConnectBaudFine_define; # Thus baud setting = 26 # NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet # Baud fine setting = 0x02 -UARTConnectBaud = 1; # 4.5 Mbps @ 72 MHz +UARTConnectBaud = 1; # 4.5 Mbpsa @ 72 MHz UARTConnectBaudFine = 0x0; +#UARTConnectBaud = 39; # 115385 bps @ 72 MHz (close to 115200) + # Cable Check Command Length # This defines the length of the cable command # 0xD2 11010010 is used for each check byte diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 8b647ac..2b223e1 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -31,22 +31,22 @@ -// ----- Macros ----- +// ----- Defines ----- +#define UART_Num_Interfaces 2 #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 +#define UART_Buffer_Size UARTConnectBufSize_define + + + +// ----- Macros ----- // 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_buffer_items_m( uartNum ) + count > uart_buffer_size ) \ + while ( uart_tx_buf[ uartNum ].items + count > UART_Buffer_Size ) \ { \ warn_msg("Too much data to send on UART0, waiting..."); \ delay( 1 ); \ @@ -59,14 +59,14 @@ case uartNum: \ printHex( buffer[ c ] ); \ print( " +" #uartNum NL ); \ } \ - 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; \ + uart_tx_buf[ uartNum ].buffer[ uart_tx_buf[ uartNum ].tail++ ] = buffer[ c ]; \ + uart_tx_buf[ uartNum ].items++; \ + if ( uart_tx_buf[ uartNum ].tail >= UART_Buffer_Size ) \ + uart_tx_buf[ uartNum ].tail = 0; \ + if ( uart_tx_buf[ uartNum ].head == uart_tx_buf[ uartNum ].tail ) \ + uart_tx_buf[ uartNum ].head++; \ + if ( uart_tx_buf[ uartNum ].head >= UART_Buffer_Size ) \ + uart_tx_buf[ uartNum ].head = 0; \ } \ break @@ -83,7 +83,7 @@ case uartNum: \ print("/"); \ printHex( UART##uartNum##_TCFIFO ); \ print("/"); \ - printHex( uart##uartNum##_buffer_items ); \ + printHex( uart_tx_buf[ uartNum ].items ); \ print( NL ); \ } \ /* XXX Doesn't work well */ \ @@ -92,138 +92,12 @@ case uartNum: \ fifoSize -= UART##uartNum##_TCFIFO; \ while ( fifoSize-- != 0 ) \ { \ - if ( uart##uartNum##_buffer_items == 0 ) \ + if ( uart_tx_buf[ uartNum ].items == 0 ) \ break; \ - UART##uartNum##_D = uart##uartNum##_buffer[ uart##uartNum##_buffer_head++ ]; \ - uart##uartNum##_buffer_items--; \ - if ( uart##uartNum##_buffer_head >= uart_buffer_size ) \ - uart##uartNum##_buffer_head = 0; \ - } \ -} - -// Macro for processing UART Rx -#define uart_processRx( uartNum ) \ -{ \ - if ( !( UART##uartNum##_S1 & UART_S1_RDRF ) ) \ - return; \ - uint8_t available = UART##uartNum##_RCFIFO; \ - if ( available == 0 ) \ - { \ - available = UART##uartNum##_D; \ - UART##uartNum##_CFIFO = UART_CFIFO_RXFLUSH; \ - return; \ - } \ - /* 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("("); \ - printInt8( available ); \ - 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(" Wait "); \ - } \ - uart##uartNum##_rx_status = byteRead == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; \ - break; \ - case UARTStatus_SYN: \ - if ( Connect_debug ) \ - { \ - print(" SYN "); \ - } \ - uart##uartNum##_rx_status = byteRead == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; \ - break; \ - case UARTStatus_SOH: \ - { \ - if ( Connect_debug ) \ - { \ - 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 < Command_TOP ) \ - { \ - uart##uartNum##_rx_status = UARTStatus_Command; \ - uart##uartNum##_rx_command = byte; \ - uart##uartNum##_rx_bytes_waiting = 0xFFFF; \ - } \ - else \ - { \ - uart##uartNum##_rx_status = UARTStatus_Wait; \ - } \ - switch ( uart##uartNum##_rx_command ) \ - { \ - case IdRequest: \ - Connect_receive_IdRequest( 0, (uint16_t*)&uart##uartNum##_rx_bytes_waiting, uartNum ); \ - uart##uartNum##_rx_status = UARTStatus_Wait; \ - break; \ - default: \ - if ( Connect_debug ) \ - { \ - print(" ### "); \ - printHex( uart##uartNum##_rx_command ); \ - } \ - break; \ - } \ - break; \ - } \ - case UARTStatus_Command: \ - { \ - if ( Connect_debug ) \ - { \ - print(" CMD "); \ - } \ - /* Call specific UARTConnect command receive function */ \ - uint8_t (*rcvFunc)(uint8_t, uint16_t(*), uint8_t) = (uint8_t(*)(uint8_t, uint16_t(*), uint8_t))(Connect_receiveFunctions[ uart##uartNum##_rx_command ]); \ - if ( rcvFunc( byteRead, (uint16_t*)&uart##uartNum##_rx_bytes_waiting, uartNum ) ) \ - uart##uartNum##_rx_status = UARTStatus_Wait; \ - break; \ - } \ - default: \ - erro_msg("Invalid UARTStatus..."); \ - uart##uartNum##_rx_status = UARTStatus_Wait; \ - available++; \ - continue; \ - } \ - if ( Connect_debug ) \ - { \ - print( NL ); \ - } \ + UART##uartNum##_D = uart_tx_buf[ uartNum ].buffer[ uart_tx_buf[ uartNum ].head++ ]; \ + uart_tx_buf[ uartNum ].items--; \ + if ( uart_tx_buf[ uartNum ].head >= UART_Buffer_Size ) \ + uart_tx_buf[ uartNum ].head = 0; \ } \ } @@ -231,31 +105,31 @@ case uartNum: \ #define uart_lockTx( uartNum ) \ { \ /* First, secure place in line for the resource */ \ - while ( uart_lock_m( uartNum ) ); \ - uart_lock_m( uartNum ) = 1; \ + while ( uart_tx_status[ uartNum ].lock ); \ + uart_tx_status[ uartNum ].lock = 1; \ /* Next, wait unit the UART is ready */ \ - while ( uart_tx_status_m( uartNum ) != UARTStatus_Ready ); \ - uart_tx_status_m( uartNum ) = UARTStatus_Wait; \ + while ( uart_tx_status[ uartNum ].status != UARTStatus_Ready ); \ + uart_tx_status[ uartNum ].status = 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; \ + while ( uart_tx_status[ uartNum1 ].lock || uart_tx_status[ uartNum2 ].lock ); \ + uart_tx_status[ uartNum1 ].lock = 1; \ + uart_tx_status[ uartNum2 ].lock = 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; \ + while ( uart_tx_status[ uartNum1 ].status != UARTStatus_Ready || uart_tx_status[ uartNum2 ].status != UARTStatus_Ready ); \ + uart_tx_status[ uartNum1 ].status = UARTStatus_Wait; \ + uart_tx_status[ uartNum2 ].status = UARTStatus_Wait; \ } #define uart_unlockTx( uartNum ) \ { \ /* Ready the UART */ \ - uart_tx_status_m( uartNum ) = UARTStatus_Ready; \ + uart_tx_status[ uartNum ].status = UARTStatus_Ready; \ /* Unlock the resource */ \ - uart_lock_m( uartNum ) = 0; \ + uart_tx_status[ uartNum ].lock = 0; \ } @@ -273,6 +147,33 @@ void cliFunc_connectSts ( char *args ); +// ----- Structs ----- + +typedef struct UARTRingBuf { + uint8_t head; + uint8_t tail; + uint8_t items; + uint8_t buffer[UART_Buffer_Size]; +} UARTRingBuf; + +typedef struct UARTDMABuf { + uint8_t buffer[UART_Buffer_Size]; + uint16_t last_read; +} UARTDMABuf; + +typedef struct UARTStatusRx { + UARTStatus status; + Command command; + uint16_t bytes_waiting; +} UARTStatusRx; + +typedef struct UARTStatusTx { + UARTStatus status; + uint8_t lock; +} UARTStatusTx; + + + // ----- Variables ----- // Connect Module command dictionary @@ -306,46 +207,27 @@ uint32_t Connect_lastCheck = 0; // Cable Check scheduler uint8_t Connect_debug = 0; // Set 1 for debug uint8_t Connect_override = 0; // Prevents master from automatically being set - -// -- Rx Status Variables -- - -volatile UARTStatus uart0_rx_status; -volatile UARTStatus uart1_rx_status; -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 -- - -volatile UARTStatus uart0_tx_status; -volatile UARTStatus uart1_tx_status; - - -// -- Ring Buffer Variables -- - -#define uart_buffer_size UARTConnectBufSize_define -volatile uint8_t uart0_buffer_head; -volatile uint8_t uart0_buffer_tail; -volatile uint8_t uart0_buffer_items; -volatile uint8_t uart0_buffer[uart_buffer_size]; -volatile uint8_t uart1_buffer_head; -volatile uint8_t uart1_buffer_tail; -volatile uint8_t uart1_buffer_items; -volatile uint8_t uart1_buffer[uart_buffer_size]; - volatile uint8_t uarts_configured = 0; +// -- Rx Variables -- + +volatile UARTDMABuf uart_rx_buf[UART_Num_Interfaces]; +volatile UARTStatusRx uart_rx_status[UART_Num_Interfaces]; + + +// -- Tx Variables -- + +UARTRingBuf uart_tx_buf [UART_Num_Interfaces]; +UARTStatusTx uart_tx_status[UART_Num_Interfaces]; + + // -- Ring Buffer Convenience Functions -- void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart ) { // Too big to fit into buffer - if ( count > uart_buffer_size ) + if ( count > UART_Buffer_Size ) { erro_msg("Too big of a command to fit into the buffer..."); return; @@ -480,6 +362,51 @@ void Connect_send_Animation( uint8_t id, uint8_t *paramList, uint8_t numParams ) uart_unlockTx( UART_Slave ); } +// Send a remote capability command using capability index +// This may not be what's expected (especially if the firmware is not the same on each node) +// To broadcast to all slave nodes, set id to 255 instead of a specific id +void Connect_send_RemoteCapability( uint8_t id, uint8_t capabilityIndex, uint8_t state, uint8_t stateType, uint8_t numArgs, uint8_t *args ) +{ + // Prepare header + uint8_t header[] = { 0x16, 0x01, RemoteCapability, id, capabilityIndex, state, stateType, numArgs }; + + // Ignore current id + if ( id == Connect_id ) + return; + + // Send towards slave node + if ( id > Connect_id ) + { + // Lock slave bound Tx + uart_lockTx( UART_Slave ); + + // Send header + Connect_addBytes( header, sizeof( header ), UART_Slave ); + + // Send arguments + Connect_addBytes( args, numArgs, UART_Slave ); + + // Unlock Tx + uart_unlockTx( UART_Slave ); + } + + // Send towards master node + if ( id < Connect_id || id == 255 ) + { + // Lock slave bound Tx + uart_lockTx( UART_Master ); + + // Send header + Connect_addBytes( header, sizeof( header ), UART_Master ); + + // Send arguments + Connect_addBytes( args, numArgs, UART_Master ); + + // Unlock Tx + uart_unlockTx( UART_Master ); + } +} + void Connect_send_Idle( uint8_t num ) { // Wait until the Tx buffers are ready, then lock them @@ -745,6 +672,8 @@ uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t break; } // Propagate ScanCode packet + // XXX It would be safer to buffer the scancodes first, before transmitting the packet -Jacob + // The current method is the more efficient/aggressive, but could cause issues if there were errors during transmission else switch ( (*pending_bytes)-- ) { // Byte count always starts at 0xFFFF @@ -788,6 +717,103 @@ uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_ return 1; } +// - Remote Capability Variables - +#define Connect_receive_RemoteCapabilityMaxArgs 5 // XXX Calculate the max using kll +RemoteCapabilityCommand Connect_receive_RemoteCapabilityBuffer; +uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs]; + +uint8_t Connect_receive_RemoteCapability( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num ) +{ + // Check which byte in the packet we are at + switch ( (*pending_bytes)-- ) + { + // Byte count always starts at 0xFFFF + case 0xFFFF: // Device Id + Connect_receive_RemoteCapabilityBuffer.id = byte; + break; + + case 0xFFFE: // Capability Index + Connect_receive_RemoteCapabilityBuffer.capabilityIndex = byte; + break; + + case 0xFFFD: // State + Connect_receive_RemoteCapabilityBuffer.state = byte; + break; + + case 0xFFFC: // StateType + Connect_receive_RemoteCapabilityBuffer.stateType = byte; + break; + + case 0xFFFB: // Number of args + Connect_receive_RemoteCapabilityBuffer.numArgs = byte; + *pending_bytes = byte; + break; + + default: // Args (# defined by previous byte) + Connect_receive_RemoteCapabilityArgs[ + Connect_receive_RemoteCapabilityBuffer.numArgs - *pending_bytes + 1 + ] = byte; + + // If entire packet has been fully received + if ( *pending_bytes == 0 ) + { + // Determine if this is the node to run the capability on + // Conditions: Matches or broadcast (0xFF) + if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF + || Connect_receive_RemoteCapabilityBuffer.id == Connect_id ) + { + extern const Capability CapabilitiesList[]; // See generatedKeymap.h + void (*capability)(uint8_t, uint8_t, uint8_t*) = (void(*)(uint8_t, uint8_t, uint8_t*))( + CapabilitiesList[ Connect_receive_RemoteCapabilityBuffer.capabilityIndex ].func + ); + capability( + Connect_receive_RemoteCapabilityBuffer.state, + Connect_receive_RemoteCapabilityBuffer.stateType, + &Connect_receive_RemoteCapabilityArgs[2] + ); + } + + // If this is not the correct node, keep sending it in the same direction (doesn't matter if more nodes exist) + // or if this is a broadcast + if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF + || Connect_receive_RemoteCapabilityBuffer.id != Connect_id ) + { + // Prepare outgoing packet + Connect_receive_RemoteCapabilityBuffer.command = RemoteCapability; + + // Send to the other UART (not the one receiving the packet from + uint8_t uart_direction = uart_num == UART_Master ? UART_Slave : UART_Master; + + // Lock Tx UART + switch ( uart_direction ) + { + case UART_Master: uart_lockTx( UART_Master ); break; + case UART_Slave: uart_lockTx( UART_Slave ); break; + } + + // Send header + uint8_t header[] = { 0x16, 0x01 }; + Connect_addBytes( header, sizeof( header ), uart_direction ); + + // Send Remote Capability and arguments + Connect_addBytes( (uint8_t*)&Connect_receive_RemoteCapabilityBuffer, sizeof( RemoteCapabilityCommand ), uart_direction ); + Connect_addBytes( Connect_receive_RemoteCapabilityArgs, Connect_receive_RemoteCapabilityBuffer.numArgs, uart_direction ); + + // Unlock Tx UART + switch ( uart_direction ) + { + case UART_Master: uart_unlockTx( UART_Master ); break; + case UART_Slave: uart_unlockTx( UART_Slave ); break; + } + } + } + break; + } + + // Check whether the scan codes have finished sending + return *pending_bytes == 0 ? 1 : 0; +} + // Baud Rate // NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet @@ -802,52 +828,29 @@ void *Connect_receiveFunctions[] = { Connect_receive_IdReport, Connect_receive_ScanCode, Connect_receive_Animation, + Connect_receive_RemoteCapability, }; -// ----- Interrupt Functions ----- - -// Master / UART0 ISR -void uart0_status_isr() -{ - // Process Rx buffer - uart_processRx( 0 ); -} - -// Slave / UART1 ISR -void uart1_status_isr() -{ - // Process Rx buffer - uart_processRx( 1 ); -} - - - // ----- Functions ----- // Resets the state of the UART buffers and state variables void Connect_reset() { - // Rx Status Variables - uart0_rx_status = UARTStatus_Wait; - uart1_rx_status = UARTStatus_Wait; - uart0_rx_bytes_waiting = 0; - uart1_rx_bytes_waiting = 0; - uart0_lock = 0; - uart1_lock = 0; + // Reset Rx + memset( (void*)uart_rx_status, 0, sizeof( UARTStatusRx ) * UART_Num_Interfaces ); - // Tx Status Variables - uart0_tx_status = UARTStatus_Ready; - uart1_tx_status = UARTStatus_Ready; + // Reset Tx + memset( (void*)uart_tx_buf, 0, sizeof( UARTRingBuf ) * UART_Num_Interfaces ); + memset( (void*)uart_tx_status, 0, sizeof( UARTStatusTx ) * UART_Num_Interfaces ); - // Ring Buffer Variables - uart0_buffer_head = 0; - uart0_buffer_tail = 0; - uart0_buffer_items = 0; - uart1_buffer_head = 0; - uart1_buffer_tail = 0; - uart1_buffer_items = 0; + // Set Rx/Tx buffers as ready + for ( uint8_t inter = 0; inter < UART_Num_Interfaces; inter++ ) + { + uart_tx_status[ inter ].status = UARTStatus_Ready; + uart_rx_buf[ inter ].last_read = UART_Buffer_Size; + } } @@ -868,8 +871,8 @@ void Connect_setup( uint8_t master ) if ( Connect_master ) Connect_id = 0; // 0x00 is always the master Id - // Master / UART0 setup - // Slave / UART1 setup + // UART0 setup + // UART1 setup // Setup the the UART interface for keyboard data input SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating SIM_SCGC4 |= SIM_SCGC4_UART1; // Disable clock gating @@ -895,30 +898,81 @@ void Connect_setup( uint8_t master ) UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; UART1_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; - // Number of bytes in FIFO before TX Interrupt - UART0_TWFIFO = 1; - UART1_TWFIFO = 1; + // Only using Tx Fifos + UART0_PFIFO = UART_PFIFO_TXFE; + UART1_PFIFO = UART_PFIFO_TXFE; - // Number of bytes in FIFO before RX Interrupt - UART0_RWFIFO = 1; - UART1_RWFIFO = 1; + // Setup DMA clocks + SIM_SCGC6 |= SIM_SCGC6_DMAMUX; + SIM_SCGC7 |= SIM_SCGC7_DMA; - // Enable TX and RX FIFOs - UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; - UART1_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; + // Start with channels disabled first + DMAMUX0_CHCFG0 = 0; + DMAMUX0_CHCFG1 = 0; - // Reciever Inversion Disabled, LSBF - // UART_S2_RXINV UART_S2_MSBF - UART0_S2 |= 0x00; - UART1_S2 |= 0x00; + // Configure DMA channels + //DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK; // TODO What's this? + DMA_TCD0_CSR = 0; + DMA_TCD1_CSR = 0; - // Transmit Inversion Disabled - // UART_C3_TXINV - UART0_C3 |= 0x00; - UART1_C3 |= 0x00; + // Default control register + DMA_CR = 0; + + // DMA Priority + DMA_DCHPRI0 = 0; // Ch 0, priority 0 + DMA_DCHPRI1 = 1; // ch 1, priority 1 + + // Clear error interrupts + DMA_EEI = 0; + + // Setup TCD + DMA_TCD0_SADDR = (uint32_t*)&UART0_D; + DMA_TCD1_SADDR = (uint32_t*)&UART1_D; + DMA_TCD0_SOFF = 0; + DMA_TCD1_SOFF = 0; + + // No modulo, 8-bit transfer size + DMA_TCD0_ATTR = DMA_TCD_ATTR_SMOD(0) | DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DMOD(0) | DMA_TCD_ATTR_DSIZE(0); + DMA_TCD1_ATTR = DMA_TCD_ATTR_SMOD(0) | DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DMOD(0) | DMA_TCD_ATTR_DSIZE(0); + + // One byte transferred at a time + DMA_TCD0_NBYTES_MLNO = 1; + DMA_TCD1_NBYTES_MLNO = 1; + + // Source address does not change + DMA_TCD0_SLAST = 0; + DMA_TCD1_SLAST = 0; + + // Destination buffer + DMA_TCD0_DADDR = (uint32_t*)uart_rx_buf[0].buffer; + DMA_TCD1_DADDR = (uint32_t*)uart_rx_buf[1].buffer; + + // Incoming byte, increment by 1 in the rx buffer + DMA_TCD0_DOFF = 1; + DMA_TCD1_DOFF = 1; + + // Single major loop, must be the same value + DMA_TCD0_CITER_ELINKNO = UART_Buffer_Size; + DMA_TCD1_CITER_ELINKNO = UART_Buffer_Size; + DMA_TCD0_BITER_ELINKNO = UART_Buffer_Size; + DMA_TCD1_BITER_ELINKNO = UART_Buffer_Size; + + // Reset buffer when full + DMA_TCD0_DLASTSGA = -( UART_Buffer_Size ); + DMA_TCD1_DLASTSGA = -( UART_Buffer_Size ); + + // Enable DMA channels + DMA_ERQ |= DMA_ERQ_ERQ0 | DMA_ERQ_ERQ1; + + // Setup DMA channel routing + DMAMUX0_CHCFG0 = DMAMUX_ENABLE | DMAMUX_SOURCE_UART0_RX; + DMAMUX0_CHCFG1 = DMAMUX_ENABLE | DMAMUX_SOURCE_UART1_RX; + + // Enable DMA requests (requires Rx interrupts) + UART0_C5 = UART_C5_RDMAS; + UART1_C5 = UART_C5_RDMAS; // TX Enabled, RX Enabled, RX Interrupt Enabled - // UART_C2_TE UART_C2_RE UART_C2_RIE UART0_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE; UART1_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE; @@ -934,6 +988,143 @@ void Connect_setup( uint8_t master ) } +#define DMA_BUF_POS( x, pos ) \ + case x: \ + pos = DMA_TCD##x##_CITER_ELINKNO; \ + break +void Connect_rx_process( uint8_t uartNum ) +{ + // Determine current position to read until + uint16_t bufpos = 0; + switch ( uartNum ) + { + DMA_BUF_POS( 0, bufpos ); + DMA_BUF_POS( 1, bufpos ); + } + + // Process each of the new bytes + // Even if we receive more bytes during processing, wait until the next check so we don't starve other tasks + while ( bufpos != uart_rx_buf[ uartNum ].last_read ) + { + // If the last_read byte is at the buffer edge, roll back to beginning + if ( uart_rx_buf[ uartNum ].last_read == 0 ) + { + uart_rx_buf[ uartNum ].last_read = UART_Buffer_Size; + + // Check to see if we're at the boundary + if ( bufpos == UART_Buffer_Size ) + break; + } + + // Read the byte out of Rx DMA buffer + uint8_t byte = uart_rx_buf[ uartNum ].buffer[ UART_Buffer_Size - uart_rx_buf[ uartNum ].last_read-- ]; + + if ( Connect_debug ) + { + printHex( byte ); + print(" "); + } + + // Process UART byte + switch ( uart_rx_status[ uartNum ].status ) + { + // Every packet must start with a SYN / 0x16 + case UARTStatus_Wait: + if ( Connect_debug ) + { + print(" Wait "); + } + uart_rx_status[ uartNum ].status = byte == 0x16 ? UARTStatus_SYN : UARTStatus_Wait; + break; + + // After a SYN, there must be a SOH / 0x01 + case UARTStatus_SYN: + if ( Connect_debug ) + { + print(" SYN "); + } + uart_rx_status[ uartNum ].status = byte == 0x01 ? UARTStatus_SOH : UARTStatus_Wait; + break; + + // After a SOH the packet structure may diverge a bit + // This is the packet type field (refer to the Command enum) + // For very small packets (e.g. IdRequest) this is all that's required to take action + case UARTStatus_SOH: + { + if ( Connect_debug ) + { + print(" SOH "); + } + + // Check if this is actually a reserved CMD 0x16 (Error condition) + if ( byte == Command_SYN ) + { + uart_rx_status[ uartNum ].status = UARTStatus_SYN; + break; + } + + // Otherwise process the command + if ( byte < Command_TOP ) + { + uart_rx_status[ uartNum ].status = UARTStatus_Command; + uart_rx_status[ uartNum ].command = byte; + uart_rx_status[ uartNum ].bytes_waiting = 0xFFFF; + } + // Invalid packet type, ignore + else + { + uart_rx_status[ uartNum ].status = UARTStatus_Wait; + } + + // Check if this is a very short packet + switch ( uart_rx_status[ uartNum ].command ) + { + case IdRequest: + Connect_receive_IdRequest( 0, (uint16_t*)&uart_rx_status[ uartNum ].bytes_waiting, uartNum ); + uart_rx_status[ uartNum ].status = UARTStatus_Wait; + break; + + default: + if ( Connect_debug ) + { + print(" ### "); + printHex( uart_rx_status[ uartNum ].command ); + } + break; + } + break; + } + + // After the packet type has been deciphered do Command specific processing + // Until the Command has received all the bytes it requires the UART buffer stays in this state + case UARTStatus_Command: + { + if ( Connect_debug ) + { + print(" CMD "); + } + /* Call specific UARTConnect command receive function */ + uint8_t (*rcvFunc)(uint8_t, uint16_t(*), uint8_t) = (uint8_t(*)(uint8_t, uint16_t(*), uint8_t))(Connect_receiveFunctions[ uart_rx_status[ uartNum ].command ]); + if ( rcvFunc( byte, (uint16_t*)&uart_rx_status[ uartNum ].bytes_waiting, uartNum ) ) + uart_rx_status[ uartNum ].status = UARTStatus_Wait; + break; + } + + // Unknown status, should never get here + default: + erro_msg("Invalid UARTStatus..."); + uart_rx_status[ uartNum ].status = UARTStatus_Wait; + continue; + } + + if ( Connect_debug ) + { + print( NL ); + } + } +} + + // Scan for updates in the master/slave // - Interrupts will deal with most input functions // - Used to send queries @@ -974,10 +1165,14 @@ void Connect_scan() { // Check if Tx Buffers are empty and the Tx Ring buffers have data to send // This happens if there was previously nothing to send - if ( uart0_buffer_items > 0 && UART0_TCFIFO == 0 ) + if ( uart_tx_buf[ 0 ].items > 0 && UART0_TCFIFO == 0 ) uart_fillTxFifo( 0 ); - if ( uart1_buffer_items > 0 && UART1_TCFIFO == 0 ) + if ( uart_tx_buf[ 1 ].items > 0 && UART1_TCFIFO == 0 ) uart_fillTxFifo( 1 ); + + // Process Rx Buffers + Connect_rx_process( 0 ); + Connect_rx_process( 1 ); } } @@ -1153,9 +1348,9 @@ void cliFunc_connectSts( char* args ) print("/"); printHex32( Connect_cableChecksMaster ); print( NL "\tRx:\t"); - printHex( uart1_rx_status ); + printHex( uart_rx_status[UART_Master].status ); print( NL "\tTx:\t"); - printHex( uart1_tx_status ); + printHex( uart_tx_status[UART_Master].status ); print( NL "Slave <=" NL "\tStatus:\t"); printHex( Connect_cableOkSlave ); print( NL "\tFaults:\t"); @@ -1163,8 +1358,8 @@ void cliFunc_connectSts( char* args ) print("/"); printHex32( Connect_cableChecksSlave ); print( NL "\tRx:\t"); - printHex( uart0_rx_status ); + printHex( uart_rx_status[UART_Slave].status ); print( NL "\tTx:\t"); - printHex( uart0_tx_status ); + printHex( uart_tx_status[UART_Slave].status ); } diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index bb50610..cdd7ed0 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -119,11 +119,14 @@ typedef struct AnimationCommand { // Remote Capability Command // Initiated by the master to trigger a capability on a given node // RemoteOutput is enabled while capability is activated +// Set id to 255 if command should be sent in all directions typedef struct RemoteCapabilityCommand { Command command; uint8_t id; - Capability capability; - uint8_t numArgs; + uint8_t capabilityIndex; + uint8_t state; + uint8_t stateType; + uint8_t numArgs; // # of bytes, args may be larger than 1 byte uint8_t firstArg[0]; } RemoteCapabilityCommand; @@ -162,4 +165,5 @@ void Connect_setup( uint8_t master ); void Connect_scan(); void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ); +void Connect_send_RemoteCapability( uint8_t id, uint8_t capabilityIndex, uint8_t state, uint8_t stateType, uint8_t numArgs, uint8_t *args ); From a10afbcc6aa52ef7ec0150802126a2efa053e7a8 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 16 Oct 2015 10:02:01 -0700 Subject: [PATCH 47/79] Adding remote capability LED control - Works for all nodes in chain - Synchronized to 30 ms update rate (required for ISSI chip) * Interconnect cannot handle full update speed from Scan module * Though it should be able to handle quite a bit more than 30 ms updates --- Scan/ISSILed/led_scan.c | 109 ++++++++++++++++++++++++++------ Scan/UARTConnect/connect_scan.c | 71 ++++++++++----------- 2 files changed, 125 insertions(+), 55 deletions(-) diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index 549fc0d..8a92b76 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -25,6 +25,11 @@ #include #include +// Interconnect module if compiled in +#if defined(ConnectEnabled_define) +#include +#endif + // Local Includes #include "led_scan.h" @@ -37,6 +42,10 @@ #define LED_BufferLength 144 +// TODO Needs to be defined per keyboard +#define LED_TotalChannels 144 + + // ----- Structs ----- @@ -656,28 +665,15 @@ typedef struct LedControl { uint16_t index; } LedControl; -uint8_t LED_control_timer = 0; void LED_control( LedControl *control ) { // Only send if we've completed all other transactions + /* if ( I2C_TxBuffer.sequencePos > 0 ) return; - - // XXX - // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa) - // Make sure we only send an update every 30 milliseconds at most - // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer - - uint8_t currentTime = (uint8_t)systick_millis_count; - int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F; - if ( compare < 30 ) - { - return; - } - LED_control_timer = currentTime; + */ // Configure based upon the given mode - // TODO Handle multiple issi chips per node // TODO Perhaps do gamma adjustment? switch ( control->mode ) { @@ -696,7 +692,7 @@ void LED_control( LedControl *control ) break; case LedControlMode_brightness_decrease_all: - for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ ) { // Don't worry about rolling over, the cycle is quick LED_pageBuffer.buffer[ channel ] -= control->amount; @@ -704,7 +700,7 @@ void LED_control( LedControl *control ) break; case LedControlMode_brightness_increase_all: - for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ ) { // Don't worry about rolling over, the cycle is quick LED_pageBuffer.buffer[ channel ] += control->amount; @@ -712,7 +708,7 @@ void LED_control( LedControl *control ) break; case LedControlMode_brightness_set_all: - for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) + for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ ) { LED_pageBuffer.buffer[ channel ] = control->amount; } @@ -726,6 +722,7 @@ void LED_control( LedControl *control ) LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 ); } +uint8_t LED_control_timer = 0; void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { // Display capability name @@ -740,10 +737,84 @@ void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args ) if ( stateType == 0x00 && state == 0x03 ) // Not on release return; + // XXX + // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa) + // Make sure we only send an update every 30 milliseconds at most + // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer + + uint8_t currentTime = (uint8_t)systick_millis_count; + int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F; + if ( compare < 30 ) + { + return; + } + LED_control_timer = currentTime; + // Set the input structure LedControl *control = (LedControl*)args; - // TODO broadcast to rest of interconnect nodes if necessary + // Interconnect broadcasting +#if defined(ConnectEnabled_define) + uint8_t send_packet = 0; + uint8_t ignore_node = 0; + + // By default send to the *next* node, which will determine where to go next + extern uint8_t Connect_id; // connect_scan.c + uint8_t addr = Connect_id + 1; + + switch ( control->mode ) + { + // Calculate the led address to send + // If greater than the Total hannels + // Set address - Total channels + // Otherwise, ignore + case LedControlMode_brightness_decrease: + case LedControlMode_brightness_increase: + case LedControlMode_brightness_set: + // Ignore if led is on this node + if ( control->index < LED_TotalChannels ) + break; + + // Calculate new led index + control->index -= LED_TotalChannels; + + ignore_node = 1; + send_packet = 1; + break; + + // Broadcast to all nodes + // XXX Do not set broadcasting address + // Will send command twice + case LedControlMode_brightness_decrease_all: + case LedControlMode_brightness_increase_all: + case LedControlMode_brightness_set_all: + send_packet = 1; + break; + } + + // Only send interconnect remote capability packet if necessary + if ( send_packet ) + { + // generatedKeymap.h + extern const Capability CapabilitiesList[]; + + // Broadcast layerStackExact remote capability (0xFF is the broadcast id) + Connect_send_RemoteCapability( + addr, + LED_control_capability_index, + state, + stateType, + CapabilitiesList[ LED_control_capability_index ].argCount, + args + ); + } + + // If there is nothing to do on this node, ignore + if ( ignore_node ) + return; +#endif + + // Modify led state of this node LED_control( control ); } diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 2b223e1..1d08777 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -42,34 +42,6 @@ // ----- Macros ----- -// 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_tx_buf[ uartNum ].items + count > UART_Buffer_Size ) \ - { \ - warn_msg("Too much data to send on UART0, waiting..."); \ - delay( 1 ); \ - } \ - /* Append data to ring buffer */ \ - for ( uint8_t c = 0; c < count; c++ ) \ - { \ - if ( Connect_debug ) \ - { \ - printHex( buffer[ c ] ); \ - print( " +" #uartNum NL ); \ - } \ - uart_tx_buf[ uartNum ].buffer[ uart_tx_buf[ uartNum ].tail++ ] = buffer[ c ]; \ - uart_tx_buf[ uartNum ].items++; \ - if ( uart_tx_buf[ uartNum ].tail >= UART_Buffer_Size ) \ - uart_tx_buf[ uartNum ].tail = 0; \ - if ( uart_tx_buf[ uartNum ].head == uart_tx_buf[ uartNum ].tail ) \ - uart_tx_buf[ uartNum ].head++; \ - if ( uart_tx_buf[ uartNum ].head >= UART_Buffer_Size ) \ - uart_tx_buf[ uartNum ].head = 0; \ - } \ - break - // Macro for popping from Tx ring buffer #define uart_fillTxFifo( uartNum ) \ { \ @@ -233,14 +205,41 @@ void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart ) return; } - // Choose the uart - switch ( uart ) + // Invalid UART + if ( uart >= UART_Num_Interfaces ) { - uart_addTxBuffer( UART_Master ); - uart_addTxBuffer( UART_Slave ); - default: - erro_msg("Invalid UART to send from..."); - break; + 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( 1 ); + } + + // 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; } } @@ -718,7 +717,7 @@ uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_ } // - Remote Capability Variables - -#define Connect_receive_RemoteCapabilityMaxArgs 5 // XXX Calculate the max using kll +#define Connect_receive_RemoteCapabilityMaxArgs 25 // XXX Calculate the max using kll RemoteCapabilityCommand Connect_receive_RemoteCapabilityBuffer; uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs]; From 343104297d46b375185fa63f8a821ccf0eeb4724 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 17 Oct 2015 15:03:21 -0700 Subject: [PATCH 48/79] Adding support for kll 0.3d - Requires kll compiler update - Includes descriptor update to handle new consumer control codes --- Macro/PartialMap/usb_hid.h | 13 +++++++++++-- Output/pjrcUSB/arm/usb_desc.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Macro/PartialMap/usb_hid.h b/Macro/PartialMap/usb_hid.h index a9ac568..4f5cd7a 100644 --- a/Macro/PartialMap/usb_hid.h +++ b/Macro/PartialMap/usb_hid.h @@ -438,7 +438,15 @@ #define CONSUMER_BROADCAST_MODE 0x064 #define CONSUMER_SNAPSHOT 0x065 #define CONSUMER_STILL 0x066 -// 0x067 - 0x07F Reserved +// 0x067 - 0x06E Reserved? +#define CONSUMER_BRIGHTNESS_INCREMENT 0x06F +#define CONSUMER_BRIGHTNESS_DECREMENT 0x070 + +#define CONSUMER_BACKLIGHT_TOGGLE 0x072 +#define CONSUMER_BRIGHTNESS_MIN 0x073 +#define CONSUMER_BRIGHTNESS_MAX 0x074 +#define CONSUMER_BRIGHTNESS_AUTO 0x075 +// 0x076 - 0x07F Reserved #define CONSUMER_ASSIGN_SELECTION 0x081 #define CONSUMER_MODE_STEP 0x082 @@ -770,5 +778,6 @@ #define AC_SPLIT 0x29A #define AC_DISTRIBUTE_HORIZONTALLY 0x29B #define AC_DISTRIBUTE_VERTICALLY 0x29C -// 0x29D-0xFFFF Reserved +#define AC_NEXT_KEYBOARD_LAYOUT_SEL 0x29D +// 0x29E-0xFFFF Reserved diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 70ece51..ee278e8 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -300,7 +300,7 @@ static uint8_t sys_ctrl_report_desc[] = { 0x26, 0x9C, 0x02, // Logical Maximum (668), 0x05, 0x0C, // Usage Page (Consumer), 0x19, 0x01, // Usage Minimum (1), - 0x2A, 0x9C, 0x02, // Usage Maximum (668), + 0x2A, 0x9D, 0x02, // Usage Maximum (669), 0x81, 0x00, // Input (Data, Array), 0xc0, // End Collection - Consumer Control }; From ea82a2762be253f502bc95376791a6aaa87f4aed Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 17 Oct 2015 21:03:07 -0700 Subject: [PATCH 49/79] Typo from the last commit. --- Output/pjrcUSB/arm/usb_desc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index ee278e8..b7cb735 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -297,7 +297,7 @@ static uint8_t sys_ctrl_report_desc[] = { 0x75, 0x10, // Report Size (16), 0x95, 0x01, // Report Count (1), 0x16, 0x01, 0x00, // Logical Minimum (1), - 0x26, 0x9C, 0x02, // Logical Maximum (668), + 0x26, 0x9D, 0x02, // Logical Maximum (669), 0x05, 0x0C, // Usage Page (Consumer), 0x19, 0x01, // Usage Minimum (1), 0x2A, 0x9D, 0x02, // Usage Maximum (669), From c48eece590d392e3f822af316c89557f54bb8415 Mon Sep 17 00:00:00 2001 From: Mason Donahue Date: Sun, 18 Oct 2015 14:40:18 -0500 Subject: [PATCH 50/79] Exit quickly when cmake or make fail The compilation process itself doesn't take very long, but it's weird to let it continue trying to build when we've encountered an error worthy of changing cmake/make's return codes. This gives clear indication of a failed build as the last line of the script's output. --- Keyboards/cmake.bash | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Keyboards/cmake.bash b/Keyboards/cmake.bash index 9142526..3a1b6e4 100644 --- a/Keyboards/cmake.bash +++ b/Keyboards/cmake.bash @@ -82,7 +82,18 @@ done mkdir -p "${BuildPath}" cd "${BuildPath}" cmake -DCHIP="${Chip}" -DCOMPILER="${Compiler}" -DScanModule="${ScanModule}" -DMacroModule="${MacroModule}" -DOutputModule="${OutputModule}" -DDebugModule="${DebugModule}" -DBaseMap="${BaseMap}" -DDefaultMap="${DefaultMap}" -DPartialMaps="${PartialMapsExpanded}" "${CMakeListsPath}" +return_code=$? +if [ $return_code != 0 ] ; then + echo "Error in cmake. Exiting..." + exit $return_code +fi + make +return_code=$? +if [ $return_code != 0 ] ; then + echo "Error in make. Exiting..." + exit $return_code +fi echo "Firmware has been compiled into: '${BuildPath}'" cd - From 0e6f107ea108bea0b179bcc2a2ac17d3ba49e1a7 Mon Sep 17 00:00:00 2001 From: Dan McGregor Date: Mon, 10 Aug 2015 14:49:46 -0600 Subject: [PATCH 51/79] Start removing select Linux-isms bash might not be in /bin. Don't expect it there. --- Bootloader/Scripts/easyMode.bash | 2 +- Bootloader/Scripts/generateManufacturingImage.bash | 2 +- Bootloader/Scripts/ledTest.bash | 2 +- Bootloader/Scripts/swdLoad.bash | 2 +- Keyboards/cmake.bash | 2 +- Keyboards/ergodox.bash | 2 +- Keyboards/infinity.bash | 2 +- Keyboards/template.bash | 2 +- Keyboards/whitefox.bash | 2 +- Lib/CMake/sizeCalculator | 2 +- Lib/CMake/writer | 2 +- LoadFile/load.dfu | 2 +- LoadFile/load.teensy | 2 +- LoadFile/winload.teensy | 2 +- Scan/ISSILed/exampleAPI.bash | 2 +- Scan/STLcd/exampleAPI.bash | 2 +- buildall.bash | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Bootloader/Scripts/easyMode.bash b/Bootloader/Scripts/easyMode.bash index 65b4848..ece0b53 100644 --- a/Bootloader/Scripts/easyMode.bash +++ b/Bootloader/Scripts/easyMode.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Just in case there was an extra ledTest.bash (don't care if error) rm /dev/ttyACM0 diff --git a/Bootloader/Scripts/generateManufacturingImage.bash b/Bootloader/Scripts/generateManufacturingImage.bash index ef46e2d..455e570 100755 --- a/Bootloader/Scripts/generateManufacturingImage.bash +++ b/Bootloader/Scripts/generateManufacturingImage.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Combines a given bootloader image and firmware image into a single firmware binary # Manufacturing deliverable diff --git a/Bootloader/Scripts/ledTest.bash b/Bootloader/Scripts/ledTest.bash index 07aa9d8..9c8565f 100644 --- a/Bootloader/Scripts/ledTest.bash +++ b/Bootloader/Scripts/ledTest.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash printf "led\r" > /dev/ttyACM0 diff --git a/Bootloader/Scripts/swdLoad.bash b/Bootloader/Scripts/swdLoad.bash index 12b1e9b..6c333bf 100755 --- a/Bootloader/Scripts/swdLoad.bash +++ b/Bootloader/Scripts/swdLoad.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Loads firmware image using an SWD Flasher # Uses MCHCK ruby flasher toolchain # NOTE: Only tested with a buspirate on Linux diff --git a/Keyboards/cmake.bash b/Keyboards/cmake.bash index 3a1b6e4..9587abe 100644 --- a/Keyboards/cmake.bash +++ b/Keyboards/cmake.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is bash lib file for the convenience build scripts # Don't call this script directly # Jacob Alexander 2015 diff --git a/Keyboards/ergodox.bash b/Keyboards/ergodox.bash index b07eb16..85f85a2 100755 --- a/Keyboards/ergodox.bash +++ b/Keyboards/ergodox.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is a build script template # These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) # Jacob Alexander 2015 diff --git a/Keyboards/infinity.bash b/Keyboards/infinity.bash index bc3c0ac..b790dd5 100755 --- a/Keyboards/infinity.bash +++ b/Keyboards/infinity.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is a build script template # These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) # Jacob Alexander 2015 diff --git a/Keyboards/template.bash b/Keyboards/template.bash index b1e876f..c522726 100755 --- a/Keyboards/template.bash +++ b/Keyboards/template.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is a build script template # These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) # Jacob Alexander 2015 diff --git a/Keyboards/whitefox.bash b/Keyboards/whitefox.bash index c5ff835..049986a 100755 --- a/Keyboards/whitefox.bash +++ b/Keyboards/whitefox.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This is a build script template # These build scripts are just a convenience for configuring your keyboard (less daunting than CMake) # Jacob Alexander 2015 diff --git a/Lib/CMake/sizeCalculator b/Lib/CMake/sizeCalculator index affb163..b0ab2e6 100755 --- a/Lib/CMake/sizeCalculator +++ b/Lib/CMake/sizeCalculator @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #| Jacob Alexander 2014 #| Arg List #| 1 - size binary (e.g. avr-size) diff --git a/Lib/CMake/writer b/Lib/CMake/writer index 23f94dd..a5eb27b 100755 --- a/Lib/CMake/writer +++ b/Lib/CMake/writer @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #| Jacob Alexander 2014 #| Arg List #| 1 - File to write to (e.g. final_chip) diff --git a/LoadFile/load.dfu b/LoadFile/load.dfu index d99c5e6..5c7719c 100755 --- a/LoadFile/load.dfu +++ b/LoadFile/load.dfu @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Convenience script for loading firmware onto a dfu type device # By default, initiates dfu-util diff --git a/LoadFile/load.teensy b/LoadFile/load.teensy index 751a97f..b86dd11 100755 --- a/LoadFile/load.teensy +++ b/LoadFile/load.teensy @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Convenience script for loading firmware onto a teensy type device # By default, initiates teensy-load-cli diff --git a/LoadFile/winload.teensy b/LoadFile/winload.teensy index 1d86daf..4928197 100755 --- a/LoadFile/winload.teensy +++ b/LoadFile/winload.teensy @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Convenience script for loading firmware onto a teensy type device # By default, initiates teensy-load-cli diff --git a/Scan/ISSILed/exampleAPI.bash b/Scan/ISSILed/exampleAPI.bash index 5d66c37..be869fa 100755 --- a/Scan/ISSILed/exampleAPI.bash +++ b/Scan/ISSILed/exampleAPI.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # ISSILed # Virtual Serial Port API Example # Jacob Alexander 2015 diff --git a/Scan/STLcd/exampleAPI.bash b/Scan/STLcd/exampleAPI.bash index 8c2dda5..c2a611e 100755 --- a/Scan/STLcd/exampleAPI.bash +++ b/Scan/STLcd/exampleAPI.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # STLcd # Virtual Serial Port API Example # Jacob Alexander 2015 diff --git a/buildall.bash b/buildall.bash index dd3a7cc..4f5aaa9 100755 --- a/buildall.bash +++ b/buildall.bash @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash ###| Builder Script |### # # Builds all permutations of modules From ccf4f34e928afd88ee3dd34e8248ce04d48dad63 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Mon, 26 Oct 2015 17:55:41 -0700 Subject: [PATCH 52/79] Write whole debug cli command to history Previously the command was being modified in place in order to find the command name. This was happening before saving to the history. Fixes #70 --- Debug/cli/cli.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Debug/cli/cli.c b/Debug/cli/cli.c index 149d12d..5c83ee6 100644 --- a/Debug/cli/cli.c +++ b/Debug/cli/cli.c @@ -159,15 +159,12 @@ void CLI_process() } else { - // Only do command-related stuff if there was actually a command - // Avoids clogging command history with blanks + // Add the command to the history + CLI_saveHistory( CLILineBuffer ); // Process the current line buffer CLI_commandLookup(); - // Add the command to the history - CLI_saveHistory( CLILineBuffer ); - // Keep the array circular, discarding the older entries if ( CLIHistoryTail < CLIHistoryHead ) CLIHistoryHead = ( CLIHistoryHead + 1 ) % CLIMaxHistorySize; @@ -425,6 +422,11 @@ inline void CLI_saveHistory( char *buff ) return; } + // Don't write empty lines to the history + const char *cursor = buff; + while (*cursor == ' ') { cursor++; } // advance past the leading whitespace + if (*cursor == '\0') { return ; } + // Copy the line to the history int i; for (i = 0; i < CLILineBufferCurrent; i++) From 11a44f0ea1964cd8f0ec9c99ad7b18460402cfc3 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 1 Nov 2015 17:19:09 -0800 Subject: [PATCH 53/79] Adding comment about using Pillow instead of PIL --- Scan/STLcd/bitmap2Struct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/STLcd/bitmap2Struct.py b/Scan/STLcd/bitmap2Struct.py index dcf30c6..f0790a2 100755 --- a/Scan/STLcd/bitmap2Struct.py +++ b/Scan/STLcd/bitmap2Struct.py @@ -19,7 +19,7 @@ import sys from array import * -from PIL import Image +from PIL import Image # Use pillow instead of PIL, it works with Python 3 # Convenience class to deal with converting images to a C array From cd01bfe0ed0406225e4b39a5ab249aca0870c6e1 Mon Sep 17 00:00:00 2001 From: Joshua Flanagan Date: Tue, 10 Nov 2015 10:32:06 -0600 Subject: [PATCH 54/79] Stop requiring editing of example scripts The example scripts include hardcoded values that do not work for everyone. Instead of requiring the files to be edited (and dirtying the git tree), allow them to take command-line arguments. Also adds better guidance for Mac OSX virtual serial ports. --- Scan/ISSILed/exampleAPI.bash | 10 ++++++++-- Scan/STLcd/bitmap2Struct.py | 5 ++++- Scan/STLcd/exampleAPI.bash | 10 ++++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Scan/ISSILed/exampleAPI.bash b/Scan/ISSILed/exampleAPI.bash index 5d66c37..91eeebf 100755 --- a/Scan/ISSILed/exampleAPI.bash +++ b/Scan/ISSILed/exampleAPI.bash @@ -3,9 +3,15 @@ # Virtual Serial Port API Example # Jacob Alexander 2015 +if [ $# -eq 0 ]; then + echo "You must specify your virtual serialport. (/dev/ttyACM0 on linux, /dev/cu.usbmodemXXXX on OSX)" + echo " ex: $0 /dev/ttyACM0" + exit 1 +fi # XXX Set this to match your virtual serialport -# TODO Show examples for Mac OSX and Cygwin/Windows -SERIALPORT=/dev/ttyACM0 +# TODO Show examples for Cygwin/Windows +# For Mac OSX it will be something like /dev/cu.usbmodem1413 (number may differ) +SERIALPORT=$1 # NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer # Generally this just means commands will get ignored diff --git a/Scan/STLcd/bitmap2Struct.py b/Scan/STLcd/bitmap2Struct.py index dcf30c6..4e682ca 100755 --- a/Scan/STLcd/bitmap2Struct.py +++ b/Scan/STLcd/bitmap2Struct.py @@ -110,7 +110,10 @@ class STLcdGraphic: return display -filename = "ic_logo_lcd.bmp" +filename = sys.argv[1] +if filename is None: + print( "You must specify a bitmap filename. Try './bitmap2Struct.py ic_logo_lcd.bmp'" ) + sys.exit( 1 ) max_height = 32 max_width = 128 x_offset = 0 diff --git a/Scan/STLcd/exampleAPI.bash b/Scan/STLcd/exampleAPI.bash index 8c2dda5..dfce9d1 100755 --- a/Scan/STLcd/exampleAPI.bash +++ b/Scan/STLcd/exampleAPI.bash @@ -3,9 +3,15 @@ # Virtual Serial Port API Example # Jacob Alexander 2015 +if [ $# -eq 0 ]; then + echo "You must specify your virtual serialport. (/dev/ttyACM0 on linux, /dev/cu.usbmodemXXXX on OSX)" + echo " ex: $0 /dev/ttyACM0" + exit 1 +fi # XXX Set this to match your virtual serialport -# TODO Show examples for Mac OSX and Cygwin/Windows -SERIALPORT=/dev/ttyACM0 +# TODO Show example for Cygwin/Windows +# For Mac OSX it will be something like /dev/cu.usbmodem1413 (number may differ) +SERIALPORT=$1 # NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer # Generally this just means commands will get ignored From 862e7ea39d05660b740941c9ea72b1bc4e7ccaff Mon Sep 17 00:00:00 2001 From: Kevin Frei Date: Sat, 2 Jan 2016 17:43:05 -0800 Subject: [PATCH 55/79] Fix a handful of infinite loops that occur if you have more than 254 macros --- Macro/PartialMap/macro.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index e861f0e..dc51751 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -135,7 +135,7 @@ uint16_t macroStepCounter = 0; // Key Trigger List Buffer and Layer Cache // The layer cache is set on press only, hold and release events refer to the value set on press TriggerGuide macroTriggerListBuffer[ MaxScanCode ]; -uint8_t macroTriggerListBufferSize = 0; +var_uint_t macroTriggerListBufferSize = 0; var_uint_t macroTriggerListLayerCache[ MaxScanCode ]; // Pending Trigger Macro Index List @@ -557,7 +557,7 @@ inline void Macro_interconnectAdd( void *trigger_ptr ) // 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++ ) + for ( var_uint_t c = 0; c < macroInterconnectCacheSize; c++ ) { // Check if the same ScanCode if ( macroInterconnectCache[ c ].scanCode == trigger->scanCode ) @@ -699,7 +699,7 @@ inline void Macro_appendResultMacroToPendingList( const TriggerMacro *triggerMac uint8_t scanCode = ((TriggerGuide*)&triggerMacro->guide[ pos - TriggerGuideSize ])->scanCode; // Lookup scanCode in buffer list for the current state and stateType - for ( uint8_t keyIndex = 0; keyIndex < macroTriggerListBufferSize; keyIndex++ ) + for ( var_uint_t keyIndex = 0; keyIndex < macroTriggerListBufferSize; keyIndex++ ) { if ( macroTriggerListBuffer[ keyIndex ].scanCode == scanCode ) { @@ -905,7 +905,7 @@ TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex ) TriggerMacroVote vote = TriggerMacroVote_Invalid; // Iterate through the key buffer, comparing to each key in the combo - for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ ) + for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ ) { // Lookup key information TriggerGuide *keyInfo = ¯oTriggerListBuffer[ key ]; @@ -1065,7 +1065,7 @@ inline ResultMacroEval Macro_evalResultMacro( var_uint_t resultMacroIndex ) inline void Macro_updateTriggerMacroPendingList() { // Iterate over the macroTriggerListBuffer to add any new Trigger Macros to the pending list - for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ ) + for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ ) { // TODO LED States // TODO Analog Switches @@ -1586,7 +1586,7 @@ void cliFunc_macroList( char* args ) info_msg("Pending Key Events: "); printInt16( (uint16_t)macroTriggerListBufferSize ); print(" : "); - for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ ) + for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ ) { printHex( macroTriggerListBuffer[ key ].scanCode ); print(" "); From e6437d603fc62e312d8615801e48f66a36a1b367 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 13 Jan 2016 15:03:29 -0800 Subject: [PATCH 56/79] Adding comment for the Teensy 3.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f14bbd..dcb0c94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set( CHIP # "at90usb1286" # Teensy++ 2.0 (avr) # "mk20dx128" # Teensy 3.0 (arm) "mk20dx128vlf5" # McHCK mk20dx128vlf5 -# "mk20dx256" # Teensy 3.1 (arm) +# "mk20dx256" # Teensy 3.1,3.2 (arm) # "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 CACHE STRING "Microcontroller Chip" ) From 52c8ffc964c20b20c6b8e6a3b28eac62c5d5326b Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 13 Jan 2016 15:04:45 -0800 Subject: [PATCH 57/79] Updating README for Teensy 3.2 support --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 7039d59..9e0d5c4 100644 --- a/README.markdown +++ b/README.markdown @@ -39,7 +39,7 @@ Supported Microcontrollers * Teensy 2.0 (Partial) * Teensy 2.0++ * Teensy 3.0 -* Teensy 3.1 +* Teensy 3.1/3.2 * mk20dx128vlf5 * mk20dx256vlh7 From 8c858e4483b61b0622e3663647a881d0a3150473 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Wed, 27 Jan 2016 20:41:15 -0800 Subject: [PATCH 58/79] Setting WhiteFox LEDs as defaulting to on --- Scan/WhiteFox/defaultMap.kll | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll index 798a0c7..6a4e641 100644 --- a/Scan/WhiteFox/defaultMap.kll +++ b/Scan/WhiteFox/defaultMap.kll @@ -102,28 +102,28 @@ ISSILedMask1 = " # # Each LED channel supports 256 levels (8-bit control) # By default, LEDs are set to 0 brightness -ISSILedBrightness1 = " -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ -"; - -# Full brightness example #ISSILedBrightness1 = " -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -#0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ #"; +# Full brightness example +ISSILedBrightness1 = " +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + From b1dec678233618542abbdc8f7fe896af3637be0a Mon Sep 17 00:00:00 2001 From: "Ryan S. Brown" Date: Sat, 6 Feb 2016 21:06:08 -0500 Subject: [PATCH 59/79] Ensure directories can only be made with printable characters In situations where `ls` colors directories incorrectly, the `$module` variable contains unprintable characters. This causes directories to be impossible to `cd` into normally, and is generally a pain. --- buildall.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/buildall.bash b/buildall.bash index 4f5aaa9..a8c393b 100755 --- a/buildall.bash +++ b/buildall.bash @@ -31,7 +31,8 @@ main() { # Create permutation directories # Then run cmake, and run each build permutation # Keeping track of how many builds failed/passed - for module in $scanModules; do + for mod in $scanModules; do + module=$(tr -dc "[:print:]" <<< "$mod") # Create directory, but do not error if it exists already mkdir -p build/$module cd build/$module From 75832a17b763eb7a894bfa9b95c589bc4f42ada6 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 6 Feb 2016 18:06:37 -0800 Subject: [PATCH 60/79] Initial code for MD1_1 - IC60 /w Single color LEDs - Requires a different matrix configuration so it's incompatible with the old IC60 layout --- Scan/MD1_1/defaultMap.kll | 134 ++++++++++++++++++++++++++++++ Scan/MD1_1/matrix.h | 56 +++++++++++++ Scan/MD1_1/pinout | 93 +++++++++++++++++++++ Scan/MD1_1/scan_loop.c | 168 ++++++++++++++++++++++++++++++++++++++ Scan/MD1_1/scan_loop.h | 48 +++++++++++ Scan/MD1_1/setup.cmake | 33 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 Scan/MD1_1/defaultMap.kll create mode 100644 Scan/MD1_1/matrix.h create mode 100644 Scan/MD1_1/pinout create mode 100644 Scan/MD1_1/scan_loop.c create mode 100644 Scan/MD1_1/scan_loop.h create mode 100644 Scan/MD1_1/setup.cmake diff --git a/Scan/MD1_1/defaultMap.kll b/Scan/MD1_1/defaultMap.kll new file mode 100644 index 0000000..df51d82 --- /dev/null +++ b/Scan/MD1_1/defaultMap.kll @@ -0,0 +1,134 @@ +Name = MD1_1; +Version = 0.3d; +Author = "HaaTa (Jacob Alexander) 2014-2016"; +KLL = 0.3c; + +# Modified Date +Date = 2016-02-06; + + +S0x00 : U"Esc"; +S0x01 : U"1"; +S0x02 : U"2"; +S0x03 : U"3"; +S0x04 : U"4"; +S0x05 : U"5"; +S0x06 : U"6"; +S0x07 : U"7"; +S0x08 : U"8"; +S0x09 : U"9"; +S0x0A : U"0"; +S0x0B : U"Minus"; +S0x0C : U"Equal"; +S0x0D : U"Backslash"; +S0x0E : U"Backtick"; +S0x0F : U"Tab"; +S0x10 : U"Q"; +S0x11 : U"W"; +S0x12 : U"E"; +S0x13 : U"R"; +S0x14 : U"T"; +S0x15 : U"Y"; +S0x16 : U"U"; +S0x17 : U"I"; +S0x18 : U"O"; +S0x19 : U"P"; +S0x1A : U"LBrace"; +S0x1B : U"RBrace"; +S0x1C : U"Backspace"; +S0x1D : U"Ctrl"; +S0x1E : U"A"; +S0x1F : U"S"; +S0x20 : U"D"; +S0x21 : U"F"; +S0x22 : U"G"; +S0x23 : U"H"; +S0x24 : U"J"; +S0x25 : U"K"; +S0x26 : U"L"; +S0x27 : U"Semicolon"; +S0x28 : U"Quote"; +S0x29 : U"Enter"; +S0x2A : U"LShift"; +S0x2B : U"Z"; +S0x2C : U"X"; +S0x2D : U"C"; +S0x2E : U"V"; +S0x2F : U"B"; +S0x30 : U"N"; +S0x31 : U"M"; +S0x32 : U"Comma"; +S0x33 : U"Period"; +S0x34 : U"Slash"; +S0x35 : U"RShift"; +S0x36 : U"Function1"; # Fun key +S0x37 : U"Function2"; # Left Blank Key +S0x38 : U"LAlt"; +S0x39 : U"LGui"; +S0x3A : U"Space"; +S0x3B : U"RGui"; +S0x3C : U"RAlt"; +S0x3D : U"Function3"; # Right Blank Key 1 +S0x3E : U"Function4"; # Right Blank Key 2 + + +# Custom Action Examples + +# Example capability, prints to cli +action1 => CustomAction_action1_capability(); # No arguments + +# Blocks given USB Code, must be used with blockLink +# Simple example, supports only blocking a single key at a time +# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h +blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument +blockKey => CustomAction_blockKey_capability( usbCode : 1 ); + + + +# Defines available to the MD1_1 Scan Module + +# LED Default Enable Mask Override +# +# Each LED is represented by a single bit +# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details +ISSILedMask1 = " + 0xFF, 0x00, /* C1-1 -> C1-16 */ + 0xFF, 0x00, /* C2-1 -> C2-16 */ + 0xFF, 0x00, /* C3-1 -> C3-16 */ + 0xFF, 0x00, /* C4-1 -> C4-16 */ + 0xFF, 0x00, /* C5-1 -> C5-16 */ + 0xFF, 0x00, /* C6-1 -> C6-16 */ + 0xFF, 0x00, /* C7-1 -> C7-16 */ + 0x7F, 0x00, /* C8-1 -> C8-16 */ + 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + +# LED Brightness Override +# +# Each LED channel supports 256 levels (8-bit control) +# By default, LEDs are set to 0 brightness +#ISSILedBrightness1 = " +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +#"; + +# Full brightness example +ISSILedBrightness1 = " +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +"; + diff --git a/Scan/MD1_1/matrix.h b/Scan/MD1_1/matrix.h new file mode 100644 index 0000000..ca33a52 --- /dev/null +++ b/Scan/MD1_1/matrix.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2014-2016 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Project Includes +#include + + + +// ----- Matrix Definition ----- + +// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 +// Not all chips have access to all of these pins (most don't have 160 pins :P) +// +// NOTE: +// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down +// Checking this is completely on the ownness of the user + +// MD1 +// +// Columns (Strobe) +// PTB0..3,16,17 +// PTC4,5 +// PTD0 +// +// Rows (Sense) +// PTD1..7 + +// Define Rows (Sense) and Columns (Strobes) +GPIO_Pin Matrix_cols[] = { gpio(C,0), gpio(C,1), gpio(C,2), gpio(C,3), gpio(C,4), gpio(C,5), gpio(C,6), gpio(C,7), gpio(D,0) }; +GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; + +// Define type of scan matrix +Config Matrix_type = Config_Pulldown; + diff --git a/Scan/MD1_1/pinout b/Scan/MD1_1/pinout new file mode 100644 index 0000000..4b40fe9 --- /dev/null +++ b/Scan/MD1_1/pinout @@ -0,0 +1,93 @@ +Pin Usage +========= + +mk20dx128vlf5 + + ---- +|Keys| + ---- + +* Strobe (Columns) + +TODO + + +* Sense (Rows) + +PTD1 +PTD2 +PTD3 +PTD4 +PTD5 +PTD6 +PTD7 + + + --- +|I2C| + --- + +* IS31FL3731C + +PTB0 - SCL0 (add header pin, label as SCL0) +PTB1 - SDA0 (add header pin, label as SDA0) +PTB17 - INTB Chip 1 +PTB16 - SDB (tied to all Chips, hardware shutdown) + + + ----- +|Debug| + ----- + +* SWD + +PTA0 (Pull-down) +PTA3 (Pull-up) + +* LEDs + +PTA19 (LED only for PCB, not McHCK) (XTAL) + +* UARTs + +PTA1 - RX0 +PTA2 - TX0 + +* Tag Connect + +1 - Vdd +5 +2 - PTA3 / SWD_IO +3 - Vss / Gnd +4 - PTA0 / SWD_CLK +5 - +5V +6 - PTA2 / TRACE_SWO +7 - N/C +8 - PTA1 / JTAG_TDI +9 - N/C +10 - Reset_b + + + ------ +|Unused| + ------ + +* GPIO + +PTA1 (Not broken out on PCB, available on McHCK) (Pull-up) +PTA2 (") +PTA4 (Pull-up) +PTA18 (EXTAL) + +PTC0 +PTC1 +PTC2 +PTC3 +PTC6 +PTC7 + +* Analog + +ADC0_DP0 +ADC0_DM0 + + diff --git a/Scan/MD1_1/scan_loop.c b/Scan/MD1_1/scan_loop.c new file mode 100644 index 0000000..74218a0 --- /dev/null +++ b/Scan/MD1_1/scan_loop.c @@ -0,0 +1,168 @@ +/* Copyright (C) 2014,2016 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include +#include +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Function Declarations ----- + +// ----- Variables ----- + +// Number of scans since the last USB send +uint16_t Scan_scanCount = 0; + + + +// ----- Functions ----- + +// Setup +inline void Scan_setup() +{ + // Setup GPIO pins for matrix scanning + Matrix_setup(); + + // Setup ISSI chip to control the leds + LED_setup(); + + // Reset scan count + Scan_scanCount = 0; +} + + +// Main Detection Loop +inline uint8_t Scan_loop() +{ + Matrix_scan( Scan_scanCount++ ); + + // Process any LED events + LED_scan(); + + return 0; +} + + +// Signal from Macro Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithMacro( uint8_t sentKeys ) +{ +} + + +// Signal from Output Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithOutput( uint8_t sentKeys ) +{ + // Reset scan loop indicator (resets each key debounce state) + // TODO should this occur after USB send or Macro processing? + Scan_scanCount = 0; +} + + + +// ----- Capabilities ----- + +// Custom capability examples +// Refer to kll.h in Macros/PartialMap for state and stateType information +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + // XXX This is required for debug cli to give you a list of capabilities + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_action1_capability()"); + return; + } + + // Prints Action1 info message to the debug cli + info_print("Action1"); +} + +uint8_t CustomAction_blockHold_storage = 0; +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockHold_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // We only care about normal keys + if ( stateType == 0x00 ) + { + // Block given key if we're in the "Press" or "Hold" state + if ( ( state == 0x01 || state == 0x02 ) + && CustomAction_blockHold_storage == 0 ) + { + CustomAction_blockHold_storage = key; + info_msg("Blocking Key: "); + printHex( key ); + print( NL ); + } + // Release if in the "Off" or "Release" state and we're blocking + else if ( ( state == 0x00 || state == 0x03 ) + && key == CustomAction_blockHold_storage ) + { + info_msg("Unblocking Key: "); + printHex( CustomAction_blockHold_storage ); + print( NL ); + CustomAction_blockHold_storage = 0; + } + } +} + +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockKey_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // If key is not blocked, process + if ( key != CustomAction_blockHold_storage ) + { + extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + Output_usbCodeSend_capability( state, stateType, &key ); + } +} + diff --git a/Scan/MD1_1/scan_loop.h b/Scan/MD1_1/scan_loop.h new file mode 100644 index 0000000..0c89838 --- /dev/null +++ b/Scan/MD1_1/scan_loop.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Functions ----- + +// Functions to be called by main.c +void Scan_setup( void ); +uint8_t Scan_loop( void ); + +// Call-backs +void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module +void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + + +// ----- Capabilities ----- + +// Example capabilities +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + diff --git a/Scan/MD1_1/setup.cmake b/Scan/MD1_1/setup.cmake new file mode 100644 index 0000000..5ca7607 --- /dev/null +++ b/Scan/MD1_1/setup.cmake @@ -0,0 +1,33 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2014,2016 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Submodules +# + +AddModule ( Scan ISSILed ) +AddModule ( Scan MatrixARM ) + + +### +# Module C files +# + +set ( Module_SRCS + scan_loop.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + From 5f530b524845293c6b8a4e553e98bf75b2b1ad57 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 8 Feb 2016 08:28:38 -0800 Subject: [PATCH 61/79] Update README.markdown --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 9e0d5c4..a7802f9 100644 --- a/README.markdown +++ b/README.markdown @@ -84,6 +84,7 @@ Contact If you really need to get a hold of HaaTa, email is best: `haata@kiibohd.com` IRC is likely faster though. +`#input.club@irc.freenode.net` `#geekhack@irc.freenode.net` `#deskthority@irc.freenode.net` From 1fd19c48eac0d7fd8834aa91783385c2844dca9a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 11 Feb 2016 22:56:25 -0800 Subject: [PATCH 62/79] Changed name from MD1_1 to MD1.1 --- Scan/{MD1_1 => MD1.1}/defaultMap.kll | 2 +- Scan/{MD1_1 => MD1.1}/matrix.h | 0 Scan/{MD1_1 => MD1.1}/pinout | 0 Scan/{MD1_1 => MD1.1}/scan_loop.c | 0 Scan/{MD1_1 => MD1.1}/scan_loop.h | 0 Scan/{MD1_1 => MD1.1}/setup.cmake | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename Scan/{MD1_1 => MD1.1}/defaultMap.kll (99%) rename Scan/{MD1_1 => MD1.1}/matrix.h (100%) rename Scan/{MD1_1 => MD1.1}/pinout (100%) rename Scan/{MD1_1 => MD1.1}/scan_loop.c (100%) rename Scan/{MD1_1 => MD1.1}/scan_loop.h (100%) rename Scan/{MD1_1 => MD1.1}/setup.cmake (100%) diff --git a/Scan/MD1_1/defaultMap.kll b/Scan/MD1.1/defaultMap.kll similarity index 99% rename from Scan/MD1_1/defaultMap.kll rename to Scan/MD1.1/defaultMap.kll index df51d82..f60a4ed 100644 --- a/Scan/MD1_1/defaultMap.kll +++ b/Scan/MD1.1/defaultMap.kll @@ -1,4 +1,4 @@ -Name = MD1_1; +Name = MD1.1; Version = 0.3d; Author = "HaaTa (Jacob Alexander) 2014-2016"; KLL = 0.3c; diff --git a/Scan/MD1_1/matrix.h b/Scan/MD1.1/matrix.h similarity index 100% rename from Scan/MD1_1/matrix.h rename to Scan/MD1.1/matrix.h diff --git a/Scan/MD1_1/pinout b/Scan/MD1.1/pinout similarity index 100% rename from Scan/MD1_1/pinout rename to Scan/MD1.1/pinout diff --git a/Scan/MD1_1/scan_loop.c b/Scan/MD1.1/scan_loop.c similarity index 100% rename from Scan/MD1_1/scan_loop.c rename to Scan/MD1.1/scan_loop.c diff --git a/Scan/MD1_1/scan_loop.h b/Scan/MD1.1/scan_loop.h similarity index 100% rename from Scan/MD1_1/scan_loop.h rename to Scan/MD1.1/scan_loop.h diff --git a/Scan/MD1_1/setup.cmake b/Scan/MD1.1/setup.cmake similarity index 100% rename from Scan/MD1_1/setup.cmake rename to Scan/MD1.1/setup.cmake From 6687470ae7f9163353991d93136eb2c1da9b8e86 Mon Sep 17 00:00:00 2001 From: CryHam Date: Fri, 19 Feb 2016 18:10:25 +0100 Subject: [PATCH 63/79] Added support for ghosting matrices and code for elimination. To use define GHOST in matrix.h, see example in Scan/CK3 --- Scan/CK3/defaultMap.kll | 85 +++++++++++++++ Scan/CK3/matrix.h | 53 +++++++++ Scan/CK3/pinout | 88 +++++++++++++++ Scan/CK3/prototype.kll | 73 +++++++++++++ Scan/CK3/scan_loop.c | 204 +++++++++++++++++++++++++++++++++++ Scan/CK3/scan_loop.h | 48 +++++++++ Scan/CK3/setup.cmake | 32 ++++++ Scan/MatrixARM/matrix_scan.c | 120 ++++++++++++++++++++- Scan/MatrixARM/matrix_scan.h | 10 ++ 9 files changed, 712 insertions(+), 1 deletion(-) create mode 100644 Scan/CK3/defaultMap.kll create mode 100644 Scan/CK3/matrix.h create mode 100644 Scan/CK3/pinout create mode 100644 Scan/CK3/prototype.kll create mode 100644 Scan/CK3/scan_loop.c create mode 100644 Scan/CK3/scan_loop.h create mode 100644 Scan/CK3/setup.cmake diff --git a/Scan/CK3/defaultMap.kll b/Scan/CK3/defaultMap.kll new file mode 100644 index 0000000..d821d95 --- /dev/null +++ b/Scan/CK3/defaultMap.kll @@ -0,0 +1,85 @@ +Name = CK3; +Version = 0.3; +Author = "Crystal Hammer 2016"; +KLL = 0.3c; + +# Modified Date +Date = 2016-02-19; + + +S0x00 : U"Esc"; +S0x01 : U"1"; +S0x02 : U"2"; +S0x03 : U"3"; +S0x04 : U"4"; +S0x05 : U"5"; +S0x06 : U"6"; +S0x07 : U"7"; +S0x08 : U"8"; +S0x09 : U"9"; +S0x0A : U"0"; +S0x0B : U"Minus"; +S0x0C : U"Equal"; +S0x0D : U"Backslash"; +S0x0E : U"Backtick"; +S0x0F : U"Tab"; +S0x10 : U"Q"; +S0x11 : U"W"; +S0x12 : U"E"; +S0x13 : U"R"; +S0x14 : U"T"; +S0x15 : U"Y"; +S0x16 : U"U"; +S0x17 : U"I"; +S0x18 : U"O"; +S0x19 : U"P"; +S0x1A : U"LBrace"; +S0x1B : U"RBrace"; +S0x1C : U"Backspace"; +S0x1D : U"Ctrl"; +S0x1E : U"A"; +S0x1F : U"S"; +S0x20 : U"D"; +S0x21 : U"F"; +S0x22 : U"G"; +S0x23 : U"H"; +S0x24 : U"J"; +S0x25 : U"K"; +S0x26 : U"L"; +S0x27 : U"Semicolon"; +S0x28 : U"Quote"; +S0x29 : U"Enter"; +S0x2A : U"LShift"; +S0x2B : U"Z"; +S0x2C : U"X"; +S0x2D : U"C"; +S0x2E : U"V"; +S0x2F : U"B"; +S0x30 : U"N"; +S0x31 : U"M"; +S0x32 : U"Comma"; +S0x33 : U"Period"; +S0x34 : U"Slash"; +S0x35 : U"RShift"; +S0x36 : U"Function1"; # Fun key +S0x37 : U"Function2"; # Left Blank Key +S0x38 : U"LAlt"; +S0x39 : U"LGui"; +S0x3A : U"Space"; +S0x3B : U"RGui"; +S0x3C : U"RAlt"; +S0x3D : U"Function3"; # Right Blank Key 1 +S0x3E : U"Function4"; # Right Blank Key 2 + + +# Custom Action Examples + +# Example capability, prints to cli +action1 => CustomAction_action1_capability(); # No arguments + +# Blocks given USB Code, must be used with blockLink +# Simple example, supports only blocking a single key at a time +# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h +blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument +blockKey => CustomAction_blockKey_capability( usbCode : 1 ); + diff --git a/Scan/CK3/matrix.h b/Scan/CK3/matrix.h new file mode 100644 index 0000000..28bd3b0 --- /dev/null +++ b/Scan/CK3/matrix.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Project Includes +#include + + + +// ----- Matrix Definition ----- + +// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 +// Not all chips have access to all of these pins (most don't have 160 pins :P) +// +// NOTE: +// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down +// Checking this is completely on the ownness of the user + +// +// Columns (Strobe) // PTB0..3,16,17 PTC4,5 PTD0 +// Rows (Sense) // PTD1..7 + +// Define Rows (Sense) and Columns (Strobes) +GPIO_Pin Matrix_cols[] = { gpio(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,6), gpio(D,0) }; +GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; + +// Define type of scan matrix +Config Matrix_type = Config_Pulldown; + + +// define this if your matrix has ghosting (i.e. regular keyboard without diodes) +#define GHOST diff --git a/Scan/CK3/pinout b/Scan/CK3/pinout new file mode 100644 index 0000000..a72c0e6 --- /dev/null +++ b/Scan/CK3/pinout @@ -0,0 +1,88 @@ +Pin Usage +========= + +mk20dx128vlf5 + + ---- +|Keys| + ---- + +* Strobe (Columns) + +PTB0 +PTB1 +PTB2 +PTB3 +PTB16 +PTB17 +PTC4 +PTC5 +PTD0 + + +* Sense (Rows) + +PTD1 +PTD2 +PTD3 +PTD4 +PTD5 +PTD6 +PTD7 + + + ----- +|Debug| + ----- + +* SWD + +PTA0 (Pull-down) +PTA3 (Pull-up) + +* LEDs + +PTA19 (LED only for PCB, not McHCK) (XTAL) + +* UARTs + +PTA1 - RX0 +PTA2 - TX0 + +* Tag Connect + +1 - Vdd +5 +2 - PTA3 / SWD_IO +3 - Vss / Gnd +4 - PTA0 / SWD_CLK +5 - +5V +6 - PTA2 / TRACE_SWO +7 - N/C +8 - PTA1 / JTAG_TDI +9 - N/C +10 - Reset_b + + + ------ +|Unused| + ------ + +* GPIO + +PTA1 (Not broken out on PCB, available on McHCK) (Pull-up) +PTA2 (") +PTA4 (Pull-up) +PTA18 (EXTAL) + +PTC0 +PTC1 +PTC2 +PTC3 +PTC6 +PTC7 + +* Analog + +ADC0_DP0 +ADC0_DM0 + diff --git a/Scan/CK3/prototype.kll b/Scan/CK3/prototype.kll new file mode 100644 index 0000000..64fe862 --- /dev/null +++ b/Scan/CK3/prototype.kll @@ -0,0 +1,73 @@ +Name = MD1; +Version = 0.2; +Author = "HaaTa (Jacob Alexander) 2014"; +KLL = 0.3; + +# Modified Date +Date = 2014-09-14; + + +S0x00 : U"Esc"; +S0x01 : U"1"; +S0x02 : U"2"; +S0x03 : U"3"; +S0x04 : U"4"; +S0x05 : U"5"; +S0x06 : U"6"; +S0x07 : U"7"; +S0x08 : U"8"; +S0x09 : U"9"; +S0x0A : U"0"; +S0x0B : U"Minus"; +S0x0C : U"Equal"; +S0x0D : U"Backslash"; +S0x0E : U"Tab"; +S0x0F : U"Q"; +S0x10 : U"W"; +S0x11 : U"E"; +S0x12 : U"R"; +S0x13 : U"T"; +S0x14 : U"Y"; +S0x15 : U"U"; +S0x16 : U"I"; +S0x17 : U"O"; +S0x18 : U"P"; +S0x19 : U"LBrace"; +S0x1A : U"RBrace"; +S0x1B : U"Backspace"; +S0x1C : U"Ctrl"; +S0x1D : U"A"; +S0x1E : U"S"; +S0x1F : U"D"; +S0x20 : U"F"; +S0x21 : U"G"; +S0x22 : U"H"; +S0x23 : U"J"; +S0x24 : U"K"; +S0x25 : U"L"; +S0x26 : U"Semicolon"; +S0x27 : U"Quote"; +S0x28 : U"Enter"; +S0x29 : U"LShift"; +S0x2A : U"Z"; +S0x2B : U"X"; +S0x2C : U"C"; +S0x2D : U"V"; +S0x2E : U"B"; +S0x2F : U"N"; +S0x30 : U"M"; +S0x31 : U"Comma"; +S0x32 : U"Period"; +S0x33 : U"Slash"; +S0x34 : U"RShift"; +S0x35 : U"Function1"; # Fun key +S0x36 : U"Function2"; # Left Blank Key +S0x37 : U"LAlt"; +S0x38 : U"LGui"; +S0x39 : U"Space"; +S0x3A : U"RGui"; +S0x3B : U"RAlt"; +S0x3C : U"Function3"; # Right Blank Key 1 +S0x3D : U"Function4"; # Right Blank Key 2 +S0x3E : U"BackTick"; + diff --git a/Scan/CK3/scan_loop.c b/Scan/CK3/scan_loop.c new file mode 100644 index 0000000..22d43c2 --- /dev/null +++ b/Scan/CK3/scan_loop.c @@ -0,0 +1,204 @@ +/* Copyright (C) 2014 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Function Declarations ----- + +// CLI Functions +void cliFunc_echo( char* args ); + + + +// ----- Variables ----- + +// Scan Module command dictionary +CLIDict_Entry( echo, "Example command, echos the arguments." ); + +CLIDict_Def( scanCLIDict, "Scan Module Commands" ) = { + CLIDict_Item( echo ), + { 0, 0, 0 } // Null entry for dictionary end +}; + +// Number of scans since the last USB send +uint16_t Scan_scanCount = 0; + + + +// ----- Functions ----- + +// Setup +inline void Scan_setup() +{ + // Register Scan CLI dictionary + CLI_registerDictionary( scanCLIDict, scanCLIDictName ); + + // Setup GPIO pins for matrix scanning + Matrix_setup(); + + // Reset scan count + Scan_scanCount = 0; +} + + +// Main Detection Loop +inline uint8_t Scan_loop() +{ + Matrix_scan( Scan_scanCount++ ); + + return 0; +} + + +// Signal from Macro Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithMacro( uint8_t sentKeys ) +{ +} + + +// Signal from Output Module that all keys have been processed (that it knows about) +inline void Scan_finishedWithOutput( uint8_t sentKeys ) +{ + // Reset scan loop indicator (resets each key debounce state) + // TODO should this occur after USB send or Macro processing? + Scan_scanCount = 0; +} + + + +// ----- Capabilities ----- + +// Custom capability examples +// Refer to kll.h in Macros/PartialMap for state and stateType information +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + // XXX This is required for debug cli to give you a list of capabilities + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_action1_capability()"); + return; + } + + // Prints Action1 info message to the debug cli + info_print("Action1"); +} + +uint8_t CustomAction_blockHold_storage = 0; +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockHold_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // We only care about normal keys + if ( stateType == 0x00 ) + { + // Block given key if we're in the "Press" or "Hold" state + if ( ( state == 0x01 || state == 0x02 ) + && CustomAction_blockHold_storage == 0 ) + { + CustomAction_blockHold_storage = key; + info_msg("Blocking Key: "); + printHex( key ); + print( NL ); + } + // Release if in the "Off" or "Release" state and we're blocking + else if ( ( state == 0x00 || state == 0x03 ) + && key == CustomAction_blockHold_storage ) + { + info_msg("Unblocking Key: "); + printHex( CustomAction_blockHold_storage ); + print( NL ); + CustomAction_blockHold_storage = 0; + } + } +} + +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("CustomAction_blockKey_capability(usbCode)"); + return; + } + + // Retrieve 8-bit argument + uint8_t key = args[0]; + + // If key is not blocked, process + if ( key != CustomAction_blockHold_storage ) + { + extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + Output_usbCodeSend_capability( state, stateType, &key ); + } +} + + + +// ----- CLI Command Functions ----- + +// XXX Just an example command showing how to parse arguments (more complex than generally needed) +void cliFunc_echo( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // Parse args until a \0 is found + while ( 1 ) + { + print( NL ); // No \r\n by default after the command is entered + + curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + break; + + // Print out the arg + dPrint( arg1Ptr ); + } +} + diff --git a/Scan/CK3/scan_loop.h b/Scan/CK3/scan_loop.h new file mode 100644 index 0000000..0c89838 --- /dev/null +++ b/Scan/CK3/scan_loop.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2014-2015 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Functions ----- + +// Functions to be called by main.c +void Scan_setup( void ); +uint8_t Scan_loop( void ); + +// Call-backs +void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module +void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module + + +// ----- Capabilities ----- + +// Example capabilities +void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + diff --git a/Scan/CK3/setup.cmake b/Scan/CK3/setup.cmake new file mode 100644 index 0000000..d40a338 --- /dev/null +++ b/Scan/CK3/setup.cmake @@ -0,0 +1,32 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2014 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Submodules +# + +AddModule ( Scan MatrixARM ) + + +### +# Module C files +# + +set ( Module_SRCS + scan_loop.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index a9018df..03a4148 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -70,6 +70,15 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { // Debounce Array KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ]; +// Ghost Arrays +#ifdef GHOST +KeyGhost Matrix_ghostArray[ Matrix_colsNum * Matrix_rowsNum ]; + +uint8_t col_use[Matrix_colsNum], row_use[Matrix_rowsNum]; // used count +uint8_t col_ghost[Matrix_colsNum], row_ghost[Matrix_rowsNum]; // marked as having ghost if 1 +#endif + + // Matrix debug flag - If set to 1, for each keypress the scan code is displayed in hex // If set to 2, for each key state change, the scan code is displayed along with the state uint8_t matrixDebugMode = 0; @@ -111,10 +120,17 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) { case Type_StrobeOn: *GPIO_PSOR |= (1 << gpio.pin); + #ifdef GHOST + *GPIO_PDDR |= (1 << gpio.pin); // output + #endif break; case Type_StrobeOff: *GPIO_PCOR |= (1 << gpio.pin); + #ifdef GHOST + // Ghosting martix needs to put not used (off) strobes in high impedance state + *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state + #endif break; case Type_StrobeSetup: @@ -206,6 +222,11 @@ void Matrix_setup() Matrix_scanArray[ item ].activeCount = 0; Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state Matrix_scanArray[ item ].prevDecisionTime = 0; + #ifdef GHOST + Matrix_ghostArray[ item ].prev = KeyState_Off; + Matrix_ghostArray[ item ].cur = KeyState_Off; + Matrix_ghostArray[ item ].saved = KeyState_Off; + #endif } // Clear scan stats counters @@ -372,12 +393,14 @@ void Matrix_scan( uint16_t scanNum ) erro_print("Matrix scan bug!! Report me!"); break; } - + // Update decision time state->prevDecisionTime = currentTime; // Send keystate to macro module + #ifndef GHOST Macro_keyState( key, state->curState ); + #endif // Matrix Debug, only if there is a state change if ( matrixDebugMode && state->curState != state->prevState ) @@ -403,6 +426,101 @@ void Matrix_scan( uint16_t scanNum ) Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOff ); } + + // Matrix ghosting check and elimination + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +#ifdef GHOST + // strobe = column, sense = row + + // Count (rows) use for columns + //print("C "); + for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) + { + uint8_t used = 0; + for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) + { + uint8_t key = Matrix_colsNum * row + col; + KeyState *state = &Matrix_scanArray[ key ]; + if ( keyOn(state->curState) ) + used++; + } + //printInt8(used); + col_use[col] = used; + col_ghost[col] = 0; // clear + } + + // Count (columns) use for rows + //print(" R "); + for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) + { + uint8_t used = 0; + for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) + { + uint8_t key = Matrix_colsNum * row + col; + KeyState *state = &Matrix_scanArray[ key ]; + if ( keyOn(state->curState) ) + used++; + } + //printInt8(used); + row_use[row] = used; + row_ghost[row] = 0; // clear + } + + // Check if matrix has ghost + // Happens when key is pressed and some other key is pressed in same row and another in same column + //print(" G "); + for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) + { + for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) + { + uint8_t key = Matrix_colsNum * row + col; + KeyState *state = &Matrix_scanArray[ key ]; + if ( keyOn(state->curState) && col_use[col] >= 2 && row_use[row] >= 2 ) + { + // mark col and row as having ghost + col_ghost[col] = 1; + row_ghost[row] = 1; + //print(" "); printInt8(col); print(","); printInt8(row); + } + } + } + //print( NL ); + + // Send keys + for ( uint8_t col = 0; col < Matrix_colsNum; col++ ) + { + for ( uint8_t row = 0; row < Matrix_rowsNum; row++ ) + { + uint8_t key = Matrix_colsNum * row + col; + KeyState *state = &Matrix_scanArray[ key ]; + KeyGhost *st = &Matrix_ghostArray[ key ]; + + // col or row is ghosting (crossed) + uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0; + + st->prev = st->cur; // previous + // save state if no ghost or outside ghosted area + if ( ghost == 0 ) + st->saved = state->curState; // save state if no ghost + // final + // use saved state if ghosting, or current if not + st->cur = ghost > 0 ? st->saved : state->curState; + + // Send keystate to macro module + KeyPosition k = !st->cur + ? (!st->prev ? KeyState_Off : KeyState_Release) + : ( st->prev ? KeyState_Hold : KeyState_Press); + //if (!st->cur && !st->prev) k = KeyState_Off; else + //if ( st->cur && st->prev) k = KeyState_Hold; else + //if ( st->cur && !st->prev) k = KeyState_Press; else + //if (!st->cur && st->prev) k = KeyState_Release; + Macro_keyState( key, k ); + } + } +#endif + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + // State Table Output Debug if ( matrixDebugStateCounter > 0 ) { diff --git a/Scan/MatrixARM/matrix_scan.h b/Scan/MatrixARM/matrix_scan.h index 810e6d9..ce09bf1 100644 --- a/Scan/MatrixARM/matrix_scan.h +++ b/Scan/MatrixARM/matrix_scan.h @@ -139,6 +139,16 @@ typedef struct KeyState { uint8_t prevDecisionTime; } __attribute__((packed)) KeyState; +// Ghost Element, after ghost detection/cancelation +typedef struct KeyGhost { + KeyPosition prev; + KeyPosition cur; + KeyPosition saved; // state before ghosting +} __attribute__((packed)) KeyGhost; + +// utility +inline uint8_t keyOn(/*KeyPosition*/uint8_t st) +{ return (st == KeyState_Press || st == KeyState_Hold) ? 1 : 0; } // ----- Functions ----- From 57a75851e29756ed36251b114e2b3b3630bb8121 Mon Sep 17 00:00:00 2001 From: CryHam Date: Sat, 20 Feb 2016 08:33:39 +0100 Subject: [PATCH 64/79] Minor styling fixes. Renamed define to GHOSTING_MATRIX. Deleted unused files from CK3. --- Scan/CK3/matrix.h | 5 +- Scan/CK3/pinout | 88 ------------------------------------ Scan/CK3/prototype.kll | 73 ------------------------------ Scan/MatrixARM/matrix_scan.c | 14 +++--- Scan/MatrixARM/matrix_scan.h | 6 ++- 5 files changed, 14 insertions(+), 172 deletions(-) delete mode 100644 Scan/CK3/pinout delete mode 100644 Scan/CK3/prototype.kll diff --git a/Scan/CK3/matrix.h b/Scan/CK3/matrix.h index 28bd3b0..1a2be2e 100644 --- a/Scan/CK3/matrix.h +++ b/Scan/CK3/matrix.h @@ -49,5 +49,6 @@ GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5) Config Matrix_type = Config_Pulldown; -// define this if your matrix has ghosting (i.e. regular keyboard without diodes) -#define GHOST +// Define this if your matrix has ghosting (i.e. regular keyboard without diodes) +// this will enable the anti-ghosting code +#define GHOSTING_MATRIX diff --git a/Scan/CK3/pinout b/Scan/CK3/pinout deleted file mode 100644 index a72c0e6..0000000 --- a/Scan/CK3/pinout +++ /dev/null @@ -1,88 +0,0 @@ -Pin Usage -========= - -mk20dx128vlf5 - - ---- -|Keys| - ---- - -* Strobe (Columns) - -PTB0 -PTB1 -PTB2 -PTB3 -PTB16 -PTB17 -PTC4 -PTC5 -PTD0 - - -* Sense (Rows) - -PTD1 -PTD2 -PTD3 -PTD4 -PTD5 -PTD6 -PTD7 - - - ----- -|Debug| - ----- - -* SWD - -PTA0 (Pull-down) -PTA3 (Pull-up) - -* LEDs - -PTA19 (LED only for PCB, not McHCK) (XTAL) - -* UARTs - -PTA1 - RX0 -PTA2 - TX0 - -* Tag Connect - -1 - Vdd +5 -2 - PTA3 / SWD_IO -3 - Vss / Gnd -4 - PTA0 / SWD_CLK -5 - +5V -6 - PTA2 / TRACE_SWO -7 - N/C -8 - PTA1 / JTAG_TDI -9 - N/C -10 - Reset_b - - - ------ -|Unused| - ------ - -* GPIO - -PTA1 (Not broken out on PCB, available on McHCK) (Pull-up) -PTA2 (") -PTA4 (Pull-up) -PTA18 (EXTAL) - -PTC0 -PTC1 -PTC2 -PTC3 -PTC6 -PTC7 - -* Analog - -ADC0_DP0 -ADC0_DM0 - diff --git a/Scan/CK3/prototype.kll b/Scan/CK3/prototype.kll deleted file mode 100644 index 64fe862..0000000 --- a/Scan/CK3/prototype.kll +++ /dev/null @@ -1,73 +0,0 @@ -Name = MD1; -Version = 0.2; -Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3; - -# Modified Date -Date = 2014-09-14; - - -S0x00 : U"Esc"; -S0x01 : U"1"; -S0x02 : U"2"; -S0x03 : U"3"; -S0x04 : U"4"; -S0x05 : U"5"; -S0x06 : U"6"; -S0x07 : U"7"; -S0x08 : U"8"; -S0x09 : U"9"; -S0x0A : U"0"; -S0x0B : U"Minus"; -S0x0C : U"Equal"; -S0x0D : U"Backslash"; -S0x0E : U"Tab"; -S0x0F : U"Q"; -S0x10 : U"W"; -S0x11 : U"E"; -S0x12 : U"R"; -S0x13 : U"T"; -S0x14 : U"Y"; -S0x15 : U"U"; -S0x16 : U"I"; -S0x17 : U"O"; -S0x18 : U"P"; -S0x19 : U"LBrace"; -S0x1A : U"RBrace"; -S0x1B : U"Backspace"; -S0x1C : U"Ctrl"; -S0x1D : U"A"; -S0x1E : U"S"; -S0x1F : U"D"; -S0x20 : U"F"; -S0x21 : U"G"; -S0x22 : U"H"; -S0x23 : U"J"; -S0x24 : U"K"; -S0x25 : U"L"; -S0x26 : U"Semicolon"; -S0x27 : U"Quote"; -S0x28 : U"Enter"; -S0x29 : U"LShift"; -S0x2A : U"Z"; -S0x2B : U"X"; -S0x2C : U"C"; -S0x2D : U"V"; -S0x2E : U"B"; -S0x2F : U"N"; -S0x30 : U"M"; -S0x31 : U"Comma"; -S0x32 : U"Period"; -S0x33 : U"Slash"; -S0x34 : U"RShift"; -S0x35 : U"Function1"; # Fun key -S0x36 : U"Function2"; # Left Blank Key -S0x37 : U"LAlt"; -S0x38 : U"LGui"; -S0x39 : U"Space"; -S0x3A : U"RGui"; -S0x3B : U"RAlt"; -S0x3C : U"Function3"; # Right Blank Key 1 -S0x3D : U"Function4"; # Right Blank Key 2 -S0x3E : U"BackTick"; - diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 03a4148..90343fe 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -71,7 +71,7 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ]; // Ghost Arrays -#ifdef GHOST +#ifdef GHOSTING_MATRIX KeyGhost Matrix_ghostArray[ Matrix_colsNum * Matrix_rowsNum ]; uint8_t col_use[Matrix_colsNum], row_use[Matrix_rowsNum]; // used count @@ -120,14 +120,14 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) { case Type_StrobeOn: *GPIO_PSOR |= (1 << gpio.pin); - #ifdef GHOST + #ifdef GHOSTING_MATRIX *GPIO_PDDR |= (1 << gpio.pin); // output #endif break; case Type_StrobeOff: *GPIO_PCOR |= (1 << gpio.pin); - #ifdef GHOST + #ifdef GHOSTING_MATRIX // Ghosting martix needs to put not used (off) strobes in high impedance state *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state #endif @@ -222,7 +222,7 @@ void Matrix_setup() Matrix_scanArray[ item ].activeCount = 0; Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state Matrix_scanArray[ item ].prevDecisionTime = 0; - #ifdef GHOST + #ifdef GHOSTING_MATRIX Matrix_ghostArray[ item ].prev = KeyState_Off; Matrix_ghostArray[ item ].cur = KeyState_Off; Matrix_ghostArray[ item ].saved = KeyState_Off; @@ -393,12 +393,12 @@ void Matrix_scan( uint16_t scanNum ) erro_print("Matrix scan bug!! Report me!"); break; } - + // Update decision time state->prevDecisionTime = currentTime; // Send keystate to macro module - #ifndef GHOST + #ifndef GHOSTING_MATRIX Macro_keyState( key, state->curState ); #endif @@ -429,7 +429,7 @@ void Matrix_scan( uint16_t scanNum ) // Matrix ghosting check and elimination // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -#ifdef GHOST +#ifdef GHOSTING_MATRIX // strobe = column, sense = row // Count (rows) use for columns diff --git a/Scan/MatrixARM/matrix_scan.h b/Scan/MatrixARM/matrix_scan.h index ce09bf1..8b9cee7 100644 --- a/Scan/MatrixARM/matrix_scan.h +++ b/Scan/MatrixARM/matrix_scan.h @@ -146,9 +146,11 @@ typedef struct KeyGhost { KeyPosition saved; // state before ghosting } __attribute__((packed)) KeyGhost; -// utility +// utility inline uint8_t keyOn(/*KeyPosition*/uint8_t st) -{ return (st == KeyState_Press || st == KeyState_Hold) ? 1 : 0; } +{ + return (st == KeyState_Press || st == KeyState_Hold) ? 1 : 0; +} // ----- Functions ----- From 8dbba83942ec97f5ba74cfc8e9e4f884441525f4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 20 Feb 2016 13:27:49 -0800 Subject: [PATCH 65/79] Debug code for interconnect cable debugging --- Scan/UARTConnect/connect_scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 1d08777..55f6619 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -1139,6 +1139,7 @@ void Connect_scan() } // Limit how often we do cable checks + //uint32_t time_compare = 0x007; // Used for debugging cables -HaaTa uint32_t time_compare = 0x7FF; // Must be all 1's, 0x3FF is valid, 0x4FF is not uint32_t current_time = systick_millis_count; if ( Connect_lastCheck != current_time From e761960acaa5c83b8b68f0deae9232c9f4bcf11c Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 21 Feb 2016 14:19:52 -0800 Subject: [PATCH 66/79] Setting bootloader max power to 100 mA - This amount of current is guaranteed by the USB spec before enumeration - Generally the bootloader doesn't need nearly this much, but to be safe --- Bootloader/dfu.desc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Bootloader/dfu.desc.c b/Bootloader/dfu.desc.c index dc11fef..a0ce1f8 100644 --- a/Bootloader/dfu.desc.c +++ b/Bootloader/dfu.desc.c @@ -1,5 +1,5 @@ // Originally Generated from MCHCK Toolkit -/* Copyright (c) Jacob Alexander 2014-2015 +/* Copyright (c) Jacob Alexander 2014-2016 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ static const struct usb_config_1 usb_config_1 = { .bConfigurationValue = 1, .iConfiguration = 0, .one = 1, - .bMaxPower = 100 + .bMaxPower = 50 }, .usb_function_0 = { .iface = { From 46765e85c57e19b89754f4f9c26c8f18b35148e5 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 21 Feb 2016 19:56:52 -0800 Subject: [PATCH 67/79] Adding dynamic USB power support - Each scan module now has a current change callback which passes the available current as a parameter - No longer attempts to use the max 500 mA immediately, starts with 100 mA then goes to 500 mA after enumeration - If enumeration fails due to bMaxPower of 500 mA, then attempt again at 100 mA (might also be possible to go even lower to 20 mA in certain cases) - Now working with the Apple Ipad (no over-power messages) - Fixed Wake-up behaviour on Apple Ipad (and likely other iOS devices) - More effecient set_feature/clear_feature handling (device handler) - Initial power handling via Interconnect (still needs work to get it more dynamic) --- Output/pjrcUSB/arm/usb_desc.c | 6 +- Output/pjrcUSB/arm/usb_desc.h | 4 +- Output/pjrcUSB/arm/usb_dev.c | 121 ++++++++++++++++++++++++++++++-- Output/pjrcUSB/arm/usb_dev.h | 1 + Output/pjrcUSB/output_com.c | 80 ++++++++++++++++++++- Output/pjrcUSB/output_com.h | 10 ++- Output/usbMuxUart/output_com.c | 80 ++++++++++++++++++++- Scan/ISSILed/led_scan.c | 30 +++++++- Scan/ISSILed/led_scan.h | 4 +- Scan/KType/scan_loop.c | 13 +++- Scan/KType/scan_loop.h | 8 ++- Scan/MD1.1/scan_loop.c | 12 +++- Scan/MD1.1/scan_loop.h | 4 +- Scan/MD1/scan_loop.c | 11 ++- Scan/MD1/scan_loop.h | 4 +- Scan/MDErgo1/scan_loop.c | 14 +++- Scan/MDErgo1/scan_loop.h | 8 ++- Scan/MatrixARM/matrix_scan.c | 25 ++++--- Scan/MatrixARM/matrix_scan.h | 4 +- Scan/STLcd/lcd_scan.c | 10 ++- Scan/STLcd/lcd_scan.h | 4 +- Scan/UARTConnect/connect_scan.c | 31 +++++++- Scan/UARTConnect/connect_scan.h | 4 +- Scan/WhiteFox/scan_loop.c | 12 +++- Scan/WhiteFox/scan_loop.h | 4 +- 25 files changed, 463 insertions(+), 41 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index b7cb735..1d9a939 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2013-2015) + * Modified by Jacob Alexander (2013-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -451,7 +451,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { 1, // bConfigurationValue 0, // iConfiguration 0xA0, // bmAttributes - 250, // bMaxPower + 250, // bMaxPower - Entry Index 8 // --- Keyboard HID --- Boot Mode Keyboard Interface // - 9 bytes - @@ -695,6 +695,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { SYS_CTRL_INTERVAL, // bInterval }; +uint8_t *usb_bMaxPower = &config_descriptor[8]; + // ----- String Descriptors ----- diff --git a/Output/pjrcUSB/arm/usb_desc.h b/Output/pjrcUSB/arm/usb_desc.h index 33c6589..0e769a1 100644 --- a/Output/pjrcUSB/arm/usb_desc.h +++ b/Output/pjrcUSB/arm/usb_desc.h @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2013-2015) + * Modified by Jacob Alexander (2013-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -137,3 +137,5 @@ extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS]; extern const usb_descriptor_list_t usb_descriptor_list[]; +extern uint8_t *usb_bMaxPower; + diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 782f3ac..c0e4566 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modifications by Jacob Alexander (2013-2015) + * Modifications by Jacob Alexander (2013-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -168,6 +168,9 @@ volatile uint8_t usb_reboot_timer = 0; static uint8_t reply_buffer[8]; +static uint8_t power_neg_delay; +static uint32_t power_neg_time; + // ----- Functions ----- @@ -188,6 +191,34 @@ static void endpoint0_transmit( const void *data, uint32_t len ) ep0_tx_bdt_bank ^= 1; } +// Used to check any USB state changes that may not have a proper interrupt +// Called once per scan loop, should take minimal processing time or it may affect other modules +void usb_device_check() +{ + // Check to see if we're still waiting for the next USB request after Get Configuration Descriptor + // If still waiting, restart the USB initialization with a lower power requirement + if ( power_neg_delay ) + { + // Check if 100 ms has elapsed + if ( systick_millis_count - power_neg_time > 100 ) + { + // Update bMaxPower + // The value set is in increments of 2 mA + // So 50 * 2 mA = 100 mA + // XXX Currently only transitions to 100 mA + // It may be possible to transition down again to 20 mA + *usb_bMaxPower = 50; + + // Re-initialize USB + power_neg_delay = 0; + usb_configuration = 0; // Clear USB configuration if we have one + USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect + delay(10); // Delay is necessary to simulate disconnect + usb_init(); + } + } +} + static void usb_setup() { const uint8_t *data = NULL; @@ -199,6 +230,13 @@ static void usb_setup() const uint8_t *cfg; int i; + // If another request is made, disable the power negotiation check + // See GET_DESCRIPTOR - Configuration + if ( power_neg_delay ) + { + power_neg_delay = 0; + } + switch ( setup.wRequestAndType ) { case 0x0500: // SET_ADDRESS @@ -212,6 +250,10 @@ static void usb_setup() Output_Available = usb_configuration; reg = &USB0_ENDPT1; cfg = usb_endpoint_config_table; + + // Now configured so we can utilize bMaxPower now + Output_update_usb_current( *usb_bMaxPower * 2 ); + // clear all BDT entries, free any allocated memory... for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ ) { @@ -324,9 +366,27 @@ static void usb_setup() goto send; case 0x0100: // CLEAR_FEATURE (device) + switch ( setup.wValue ) + { + // CLEAR_FEATURE(DEVICE_REMOTE_WAKEUP) + // See SET_FEATURE(DEVICE_REMOTE_WAKEUP) for details + case 0x1: + goto send; + } + + warn_msg("SET_FEATURE - Device wValue("); + printHex( setup.wValue ); + print( ")" NL ); + endpoint0_stall(); + return; + case 0x0101: // CLEAR_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa - warn_print("CLEAR_FEATURE - Device/Interface"); + warn_msg("CLEAR_FEATURE - Interface wValue("); + printHex( setup.wValue ); + print(") wIndex("); + printHex( setup.wIndex ); + print( ")" NL ); endpoint0_stall(); return; @@ -342,9 +402,30 @@ static void usb_setup() goto send; case 0x0300: // SET_FEATURE (device) + switch ( setup.wValue ) + { + // SET_FEATURE(DEVICE_REMOTE_WAKEUP) + // XXX: Only used to confirm Remote Wake + // Used on Mac OSX and Windows not on Linux + // Good post on the behaviour: + // http://community.silabs.com/t5/8-bit-MCU/Remote-wakeup-HID/m-p/74957#M30802 + case 0x1: + goto send; + } + + warn_msg("SET_FEATURE - Device wValue("); + printHex( setup.wValue ); + print( ")" NL ); + endpoint0_stall(); + return; + case 0x0301: // SET_FEATURE (interface) // TODO: Currently ignoring, perhaps useful? -HaaTa - warn_print("SET_FEATURE - Device/Interface"); + warn_msg("SET_FEATURE - Interface wValue("); + printHex( setup.wValue ); + print(") wIndex("); + printHex( setup.wIndex ); + print( ")" NL ); endpoint0_stall(); return; @@ -385,6 +466,27 @@ static void usb_setup() { datalen = list->length; } + + // XXX Power negotiation hack -HaaTa + // Some devices such as the Apple Ipad do not support bMaxPower greater than 100 mA + // However, there is no provision in the basic USB 2.0 stack for power negotiation + // To get around this: + // * Attempt to set bMaxPower to 500 mA first + // * If more than 100 ms passes since retrieving a Get Configuration Descriptor + // (Descriptor with bMaxPower in it) + // * Change usb_bMaxPower to 50 (100 mA) + // * Restart the USB init process + // According to notes online, it says that some Apple devices can only do 20 mA + // However, in my testing this hasn't been the case + // (you can also draw as much current as you want if you just lie in the descriptor :P) + // If this becomes an issue we can use this hack a second time to negotiate down to 20 mA + // (which should be fine for just the mcu) + if ( setup.wValue == 0x0200 && setup.wIndex == 0x0 ) + { + power_neg_delay = 1; + power_neg_time = systick_millis_count; + } + #if UART_DEBUG print("Desc found, "); printHex32( (uint32_t)data ); @@ -862,6 +964,11 @@ void usb_rx_memory( usb_packet_t *packet ) void usb_tx( uint32_t endpoint, usb_packet_t *packet ) { + // Since we are transmitting data, USB will be brought out of sleep/suspend + // if it's in that state + // Use the currently set descriptor value + Output_update_usb_current( *usb_bMaxPower * 2 ); + bdt_t *b = &table[ index( endpoint, TX, EVEN ) ]; uint8_t next; @@ -1161,9 +1268,12 @@ restart: USB0_ISTAT = USB_ISTAT_ERROR; } + // USB Host signalling device to enter 'sleep' state + // The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms if ( (status & USB_ISTAT_SLEEP /* 10 */ ) ) { - //serial_print("sleep\n"); + info_print("Host has requested USB sleep/suspend state"); + Output_update_usb_current( 100 ); // Set to 100 mA USB0_ISTAT = USB_ISTAT_SLEEP; } } @@ -1220,6 +1330,9 @@ uint8_t usb_init() // enable d+ pullup USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; + // Do not check for power negotiation delay until Get Configuration Descriptor + power_neg_delay = 0; + return 1; } diff --git a/Output/pjrcUSB/arm/usb_dev.h b/Output/pjrcUSB/arm/usb_dev.h index 0f445de..827f843 100644 --- a/Output/pjrcUSB/arm/usb_dev.h +++ b/Output/pjrcUSB/arm/usb_dev.h @@ -81,6 +81,7 @@ static inline uint32_t usb_rx_byte_count(uint32_t endpoint) } void usb_device_reload(); +void usb_device_check(); extern void usb_serial_flush_callback(); diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 2e97e42..b18bbdb 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2015 by Jacob Alexander +/* Copyright (C) 2011-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -137,6 +137,14 @@ volatile uint8_t Output_Available = 0; // 1 - Debug enabled uint8_t Output_DebugMode = 0; +// mA - Set by outside module if not using USB (i.e. Interconnect) +// Generally set to 100 mA (low power) or 500 mA (high power) +uint16_t Output_ExtCurrent_Available = 0; + +// mA - Set by USB module (if exists) +// Initially 100 mA, but may be negotiated higher (e.g. 500 mA) +uint16_t Output_USBCurrent_Available = 0; + // ----- Capabilities ----- @@ -535,6 +543,10 @@ inline void Output_setup() // USB Data Send inline void Output_send() { + // USB status checks + // Non-standard USB state manipulation, usually does nothing + usb_device_check(); + // Boot Mode Only, unset stale keys if ( USBKeys_Protocol == 0 ) for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) @@ -614,6 +626,72 @@ inline void Output_softReset() } +// Update USB current (mA) +// Triggers power change event +void Output_update_usb_current( unsigned int current ) +{ + // Only signal if changed + if ( current == Output_USBCurrent_Available ) + return; + + // Update USB current + Output_USBCurrent_Available = current; + + unsigned int total_current = Output_current_available(); + info_msg("USB Available Current Changed. Total Available: "); + printInt32( total_current ); + print(" mA" NL); + + // Send new total current to the Scan Modules + Scan_currentChange( Output_current_available() ); +} + + +// Update external current (mA) +// Triggers power change event +void Output_update_external_current( unsigned int current ) +{ + // Only signal if changed + if ( current == Output_ExtCurrent_Available ) + return; + + // Update external current + Output_ExtCurrent_Available = current; + + unsigned int total_current = Output_current_available(); + info_msg("External Available Current Changed. Total Available: "); + printInt32( total_current ); + print(" mA" NL); + + // Send new total current to the Scan Modules + Scan_currentChange( Output_current_available() ); +} + + +// Power/Current Available +unsigned int Output_current_available() +{ + unsigned int total_current = 0; + + // Check for USB current source + total_current += Output_USBCurrent_Available; + + // Check for external current source + total_current += Output_ExtCurrent_Available; + + // XXX If the total available current is still 0 + // Set to 100 mA, which is generally a safe assumption at startup + // before we've been able to determine actual available current + if ( total_current == 0 ) + { + total_current = 100; + } + + return total_current; +} + + + // ----- CLI Command Functions ----- void cliFunc_kbdProtocol( char* args ) diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index c82ed98..2448683 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2015 by Jacob Alexander +/* Copyright (C) 2013-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -82,6 +82,8 @@ extern volatile uint8_t Output_Available; // 0 - Output module not fully functi extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled +extern uint16_t Output_ExtCurrent_Available; // mA - Set by outside module if not using USB (i.e. Interconnect) + // ----- Functions ----- @@ -97,6 +99,12 @@ void Output_softReset(); // Relies on USB serial module unsigned int Output_availablechar(); +// Returns the total mA available (total, if used in a chain, each device will have to use a slice of it) +unsigned int Output_current_available(); + +void Output_update_external_current( unsigned int current ); +void Output_update_usb_current( unsigned int current ); + int Output_getchar(); int Output_putchar( char c ); int Output_putstr( char* str ); diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 44c5b49..55c9553 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -143,6 +143,14 @@ volatile uint8_t Output_Available = 0; // 1 - Debug enabled uint8_t Output_DebugMode = 0; +// mA - Set by outside module if not using USB (i.e. Interconnect) +// Generally set to 100 mA (low power) or 500 mA (high power) +uint16_t Output_ExtCurrent_Available = 0; + +// mA - Set by USB module (if exists) +// Initially 100 mA, but may be negotiated higher (e.g. 500 mA) +uint16_t Output_USBCurrent_Available = 0; + // ----- Capabilities ----- @@ -544,6 +552,10 @@ inline void Output_setup() // USB Data Send inline void Output_send() { + // USB status checks + // Non-standard USB state manipulation, usually does nothing + usb_device_check(); + // Boot Mode Only, unset stale keys if ( USBKeys_Protocol == 0 ) for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) @@ -641,6 +653,72 @@ inline void Output_softReset() } +// Update USB current (mA) +// Triggers power change event +void Output_update_usb_current( unsigned int current ) +{ + // Only signal if changed + if ( current == Output_USBCurrent_Available ) + return; + + // Update USB current + Output_USBCurrent_Available = current; + + unsigned int total_current = Output_current_available(); + info_msg("USB Available Current Changed. Total Available: "); + printInt32( total_current ); + print(" mA" NL); + + // Send new total current to the Scan Modules + Scan_currentChange( Output_current_available() ); +} + + +// Update external current (mA) +// Triggers power change event +void Output_update_external_current( unsigned int current ) +{ + // Only signal if changed + if ( current == Output_ExtCurrent_Available ) + return; + + // Update external current + Output_ExtCurrent_Available = current; + + unsigned int total_current = Output_current_available(); + info_msg("External Available Current Changed. Total Available: "); + printInt32( total_current ); + print(" mA" NL); + + // Send new total current to the Scan Modules + Scan_currentChange( Output_current_available() ); +} + + +// Power/Current Available +unsigned int Output_current_available() +{ + unsigned int total_current = 0; + + // Check for USB current source + total_current += Output_USBCurrent_Available; + + // Check for external current source + total_current += Output_ExtCurrent_Available; + + // XXX If the total available current is still 0 + // Set to 100 mA, which is generally a safe assumption at startup + // before we've been able to determine actual available current + if ( total_current == 0 ) + { + total_current = 100; + } + + return total_current; +} + + + // ----- CLI Command Functions ----- void cliFunc_kbdProtocol( char* args ) diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index 8a92b76..609f2d7 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -406,8 +406,14 @@ inline void LED_setup() // Set default brightness LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 ); - // Disable Software shutdown of ISSI chip - LED_writeReg( 0x0A, 0x01, 0x0B ); + // Do not disable software shutdown of ISSI chip unless current is high enough + // Require at least 150 mA + // May be enabled/disabled at a later time + if ( Output_current_available() >= 150 ) + { + // Disable Software shutdown of ISSI chip + LED_writeReg( 0x0A, 0x01, 0x0B ); + } } @@ -644,6 +650,24 @@ inline uint8_t LED_scan() } +// Called by parent Scan Module whenver the available current has changed +// current - mA +void LED_currentChange( unsigned int current ) +{ + // TODO dim LEDs in low power mode instead of shutting off + if ( current < 150 ) + { + // Enabled Software shutdown of ISSI chip + LED_writeReg( 0x0A, 0x00, 0x0B ); + } + else + { + // Disable Software shutdown of ISSI chip + LED_writeReg( 0x0A, 0x01, 0x0B ); + } +} + + // ----- Capabilities ----- diff --git a/Scan/ISSILed/led_scan.h b/Scan/ISSILed/led_scan.h index 71d8e80..545b8b9 100644 --- a/Scan/ISSILed/led_scan.h +++ b/Scan/ISSILed/led_scan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,3 +28,5 @@ void LED_setup(); uint8_t LED_scan(); +void LED_currentChange( unsigned int current ); + diff --git a/Scan/KType/scan_loop.c b/Scan/KType/scan_loop.c index 7999853..4e52706 100644 --- a/Scan/KType/scan_loop.c +++ b/Scan/KType/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -97,3 +97,14 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys ) Scan_scanCount = 0; } + +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Connect_currentChange( current ); + Matrix_currentChange( current ); + LED_currentChange( current ); +} + diff --git a/Scan/KType/scan_loop.h b/Scan/KType/scan_loop.h index 17a06fc..b18a0ca 100644 --- a/Scan/KType/scan_loop.h +++ b/Scan/KType/scan_loop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,10 +31,12 @@ // ----- Functions ----- // Functions to be called by main.c -void Scan_setup( void ); -uint8_t Scan_loop( void ); +void Scan_setup(); +uint8_t Scan_loop(); // Call-backs void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + diff --git a/Scan/MD1.1/scan_loop.c b/Scan/MD1.1/scan_loop.c index 74218a0..3b2bad1 100644 --- a/Scan/MD1.1/scan_loop.c +++ b/Scan/MD1.1/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014,2016 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,6 +90,16 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys ) } +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Matrix_currentChange( current ); + LED_currentChange( current ); +} + + // ----- Capabilities ----- diff --git a/Scan/MD1.1/scan_loop.h b/Scan/MD1.1/scan_loop.h index 0c89838..339ede5 100644 --- a/Scan/MD1.1/scan_loop.h +++ b/Scan/MD1.1/scan_loop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,8 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + // ----- Capabilities ----- diff --git a/Scan/MD1/scan_loop.c b/Scan/MD1/scan_loop.c index 22d43c2..d9348e1 100644 --- a/Scan/MD1/scan_loop.c +++ b/Scan/MD1/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -175,6 +175,15 @@ void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t } +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Matrix_currentChange( current ); +} + + // ----- CLI Command Functions ----- diff --git a/Scan/MD1/scan_loop.h b/Scan/MD1/scan_loop.h index 0c89838..339ede5 100644 --- a/Scan/MD1/scan_loop.h +++ b/Scan/MD1/scan_loop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,8 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + // ----- Capabilities ----- diff --git a/Scan/MDErgo1/scan_loop.c b/Scan/MDErgo1/scan_loop.c index d5e97e5..e80119b 100644 --- a/Scan/MDErgo1/scan_loop.c +++ b/Scan/MDErgo1/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -102,3 +102,15 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys ) Scan_scanCount = 0; } + +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Connect_currentChange( current ); + Matrix_currentChange( current ); + LED_currentChange( current ); + LCD_currentChange( current ); +} + diff --git a/Scan/MDErgo1/scan_loop.h b/Scan/MDErgo1/scan_loop.h index 17a06fc..b18a0ca 100644 --- a/Scan/MDErgo1/scan_loop.h +++ b/Scan/MDErgo1/scan_loop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,10 +31,12 @@ // ----- Functions ----- // Functions to be called by main.c -void Scan_setup( void ); -uint8_t Scan_loop( void ); +void Scan_setup(); +uint8_t Scan_loop(); // Call-backs void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 90343fe..017161d 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -428,7 +428,7 @@ void Matrix_scan( uint16_t scanNum ) // Matrix ghosting check and elimination - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #ifdef GHOSTING_MATRIX // strobe = column, sense = row @@ -465,7 +465,7 @@ void Matrix_scan( uint16_t scanNum ) row_use[row] = used; row_ghost[row] = 0; // clear } - + // Check if matrix has ghost // Happens when key is pressed and some other key is pressed in same row and another in same column //print(" G "); @@ -494,10 +494,10 @@ void Matrix_scan( uint16_t scanNum ) uint8_t key = Matrix_colsNum * row + col; KeyState *state = &Matrix_scanArray[ key ]; KeyGhost *st = &Matrix_ghostArray[ key ]; - + // col or row is ghosting (crossed) uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0; - + st->prev = st->cur; // previous // save state if no ghost or outside ghosted area if ( ghost == 0 ) @@ -505,9 +505,9 @@ void Matrix_scan( uint16_t scanNum ) // final // use saved state if ghosting, or current if not st->cur = ghost > 0 ? st->saved : state->curState; - + // Send keystate to macro module - KeyPosition k = !st->cur + KeyPosition k = !st->cur ? (!st->prev ? KeyState_Off : KeyState_Release) : ( st->prev ? KeyState_Hold : KeyState_Press); //if (!st->cur && !st->prev) k = KeyState_Off; else @@ -518,7 +518,7 @@ void Matrix_scan( uint16_t scanNum ) } } #endif - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // State Table Output Debug @@ -567,6 +567,15 @@ void Matrix_scan( uint16_t scanNum ) } +// Called by parent scan module whenever the available current changes +// current - mA +void Matrix_currentChange( unsigned int current ) +{ + // TODO - Any potential power savings? +} + + + // ----- CLI Command Functions ----- void cliFunc_matrixDebug ( char* args ) diff --git a/Scan/MatrixARM/matrix_scan.h b/Scan/MatrixARM/matrix_scan.h index 8b9cee7..3a8f0e2 100644 --- a/Scan/MatrixARM/matrix_scan.h +++ b/Scan/MatrixARM/matrix_scan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -158,3 +158,5 @@ inline uint8_t keyOn(/*KeyPosition*/uint8_t st) void Matrix_setup(); void Matrix_scan( uint16_t scanNum ); +void Matrix_currentChange( unsigned int current ); + diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index c4bf080..1dd9126 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 by Jacob Alexander +/* Copyright (C) 2015-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -346,6 +346,14 @@ inline uint8_t LCD_scan() } +// Signal from parent Scan Module that available current has changed +// current - mA +void LCD_currentChange( unsigned int current ) +{ + // TODO - Power savings? +} + + // ----- Capabilities ----- diff --git a/Scan/STLcd/lcd_scan.h b/Scan/STLcd/lcd_scan.h index 36884a2..096107b 100644 --- a/Scan/STLcd/lcd_scan.h +++ b/Scan/STLcd/lcd_scan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 by Jacob Alexander +/* Copyright (C) 2015-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,3 +28,5 @@ void LCD_setup(); uint8_t LCD_scan(); +void LCD_currentChange( unsigned int current ); + diff --git a/Scan/UARTConnect/connect_scan.c b/Scan/UARTConnect/connect_scan.c index 55f6619..4c56c3c 100644 --- a/Scan/UARTConnect/connect_scan.c +++ b/Scan/UARTConnect/connect_scan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -470,6 +470,14 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8 } else { + // Lower current requirement during errors + // USB minimum + // Only if this is not the master node + if ( Connect_id != 0 ) + { + Output_update_external_current( 100 ); + } + Connect_cableFaultsMaster++; Connect_cableOkMaster = 0; print(" Master "); @@ -489,6 +497,12 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8 } else { + // If we already have an Id, then set max current again + if ( Connect_id != 255 && Connect_id != 0 ) + { + // TODO reset to original negotiated current + Output_update_external_current( 500 ); + } Connect_cableChecksMaster++; } } @@ -560,6 +574,14 @@ uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint // Send reponse back to master Connect_send_IdReport( id ); + // Node now enumerated, set external power to USB Max + // Only set if this is not the master node + // TODO Determine power slice for each node as part of protocol + if ( Connect_id != 0 ) + { + Output_update_external_current( 500 ); + } + // Propogate next Id if the connection is ok if ( Connect_cableOkSlave ) { @@ -1177,6 +1199,13 @@ void Connect_scan() } +// Called by parent Scan module whenever the available current changes +void Connect_currentChange( unsigned int current ) +{ + // TODO - Any potential power saving here? +} + + // ----- CLI Command Functions ----- diff --git a/Scan/UARTConnect/connect_scan.h b/Scan/UARTConnect/connect_scan.h index cdd7ed0..1d87dfd 100644 --- a/Scan/UARTConnect/connect_scan.h +++ b/Scan/UARTConnect/connect_scan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -167,3 +167,5 @@ void Connect_scan(); void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ); void Connect_send_RemoteCapability( uint8_t id, uint8_t capabilityIndex, uint8_t state, uint8_t stateType, uint8_t numArgs, uint8_t *args ); +void Connect_currentChange( unsigned int current ); + diff --git a/Scan/WhiteFox/scan_loop.c b/Scan/WhiteFox/scan_loop.c index 16cefa2..56fa995 100644 --- a/Scan/WhiteFox/scan_loop.c +++ b/Scan/WhiteFox/scan_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,3 +90,13 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys ) Scan_scanCount = 0; } + +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Matrix_currentChange( current ); + LED_currentChange( current ); +} + diff --git a/Scan/WhiteFox/scan_loop.h b/Scan/WhiteFox/scan_loop.h index 17a06fc..9e9a8f1 100644 --- a/Scan/WhiteFox/scan_loop.h +++ b/Scan/WhiteFox/scan_loop.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,3 +38,5 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + From f57e069bb9d00b8bf59c2388a922a85d2e30ec66 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 23 Feb 2016 14:35:08 -0800 Subject: [PATCH 68/79] As per request of original author, updating license to MIT --- Scan/DPH/scan_loop.c | 29 +++++++++++++++++------------ Scan/DPH/scan_loop.h | 25 +++++++++++++++---------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Scan/DPH/scan_loop.c b/Scan/DPH/scan_loop.c index 1a0176c..5d8d832 100644 --- a/Scan/DPH/scan_loop.c +++ b/Scan/DPH/scan_loop.c @@ -1,18 +1,23 @@ -/* Copyright (C) 2011-2013 by Joseph Makuch - * Additions by Jacob Alexander (2013-2014) +/* Copyright (C) 2011-2013 by Joseph Makuch (jmakuch+f@gmail.com) + * Additions by Jacob Alexander (2013-2014) (haata@kiibohd.com) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ // ----- Includes ----- diff --git a/Scan/DPH/scan_loop.h b/Scan/DPH/scan_loop.h index 83a9a1b..234b959 100644 --- a/Scan/DPH/scan_loop.h +++ b/Scan/DPH/scan_loop.h @@ -1,17 +1,22 @@ /* Copyright (C) 2013-2015 by Jacob Alexander * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ #pragma once From 88670ac72f51e5f1f68b72ca300bdb0c999a37f7 Mon Sep 17 00:00:00 2001 From: CryHam Date: Tue, 1 Mar 2016 19:38:43 +0100 Subject: [PATCH 69/79] Changed CK3 matrix scan to Config_Pullup, inverted rows and columns Added STROBE_DELAY define in matrix.h All keys scan codes now in defaultMap.kll --- Scan/CK3/defaultMap.kll | 193 ++++++++++++++++++++++------------- Scan/CK3/matrix.h | 46 ++++++--- Scan/MatrixARM/matrix_scan.c | 34 ++++-- 3 files changed, 177 insertions(+), 96 deletions(-) diff --git a/Scan/CK3/defaultMap.kll b/Scan/CK3/defaultMap.kll index d821d95..30de5d0 100644 --- a/Scan/CK3/defaultMap.kll +++ b/Scan/CK3/defaultMap.kll @@ -1,85 +1,132 @@ Name = CK3; Version = 0.3; Author = "Crystal Hammer 2016"; -KLL = 0.3c; +KLL = 0.3d; # Modified Date -Date = 2016-02-19; +Date = 2016-03-01; + +# this is nearly the default map + +S0x0F : U"Esc"; +S0x8C : U"F1"; +S0x8B : U"F2"; +S0x67 : U"F3"; +S0x0D : U"F4"; +S0x6E : U"F5"; +S0x06 : U"F6"; +S0x5F : U"F7"; +S0x83 : U"F8"; +S0x7F : U"F9"; +S0x6D : U"F10"; +S0x01 : U"F11"; +S0x13 : U"F12"; +S0x6F : U"PrintScreen"; +S0x4B : U"ScrollLock"; +S0x4A : U"Pause"; +S0x39 : U"F16"; + +S0x8D : U"BackTick"; +S0x7B : U"1"; +S0x7A : U"2"; +S0x79 : U"3"; +S0x74 : U"4"; +S0x86 : U"5"; +S0x85 : U"6"; +S0x73 : U"7"; +S0x72 : U"8"; +S0x71 : U"9"; +S0x6C : U"0"; +S0x7E : U"-"; +S0x84 : U"="; +S0x5B : U"Backspace"; -S0x00 : U"Esc"; -S0x01 : U"1"; -S0x02 : U"2"; -S0x03 : U"3"; -S0x04 : U"4"; -S0x05 : U"5"; -S0x06 : U"6"; -S0x07 : U"7"; -S0x08 : U"8"; -S0x09 : U"9"; -S0x0A : U"0"; -S0x0B : U"Minus"; -S0x0C : U"Equal"; -S0x0D : U"Backslash"; -S0x0E : U"Backtick"; -S0x0F : U"Tab"; -S0x10 : U"Q"; -S0x11 : U"W"; -S0x12 : U"E"; -S0x13 : U"R"; -S0x14 : U"T"; -S0x15 : U"Y"; -S0x16 : U"U"; -S0x17 : U"I"; -S0x18 : U"O"; -S0x19 : U"P"; -S0x1A : U"LBrace"; -S0x1B : U"RBrace"; -S0x1C : U"Backspace"; -S0x1D : U"Ctrl"; -S0x1E : U"A"; -S0x1F : U"S"; -S0x20 : U"D"; -S0x21 : U"F"; -S0x22 : U"G"; -S0x23 : U"H"; -S0x24 : U"J"; -S0x25 : U"K"; -S0x26 : U"L"; -S0x27 : U"Semicolon"; -S0x28 : U"Quote"; -S0x29 : U"Enter"; -S0x2A : U"LShift"; -S0x2B : U"Z"; -S0x2C : U"X"; -S0x2D : U"C"; -S0x2E : U"V"; -S0x2F : U"B"; -S0x30 : U"N"; -S0x31 : U"M"; -S0x32 : U"Comma"; -S0x33 : U"Period"; -S0x34 : U"Slash"; -S0x35 : U"RShift"; -S0x36 : U"Function1"; # Fun key -S0x37 : U"Function2"; # Left Blank Key -S0x38 : U"LAlt"; -S0x39 : U"LGui"; -S0x3A : U"Space"; -S0x3B : U"RGui"; -S0x3C : U"RAlt"; -S0x3D : U"Function3"; # Right Blank Key 1 -S0x3E : U"Function4"; # Right Blank Key 2 +S0x69 : U"Tab"; +S0x57 : U"Q"; +S0x56 : U"W"; +S0x55 : U"E"; +S0x50 : U"R"; +S0x62 : U"T"; +S0x61 : U"Y"; +S0x4F : U"U"; +S0x4E : U"I"; +S0x4D : U"O"; +S0x48 : U"P"; +S0x5A : U"["; +S0x60 : U"]"; +S0x37 : U"\"; +S0x68 : U"CapsLock"; +S0x45 : U"A"; +S0x44 : U"S"; +S0x43 : U"D"; +S0x3E : U"F"; +S0x08 : U"G"; +S0x07 : U"H"; +S0x3D : U"J"; +S0x3C : U"K"; +S0x3B : U"L"; +S0x36 : U";"; +S0x00 : U"'"; +S0x25 : U"Enter"; -# Custom Action Examples +S0x5E : U"LShift"; +S0x33 : U"Z"; +S0x32 : U"X"; +S0x31 : U"C"; +S0x2C : U"V"; +S0x1A : U"B"; +S0x19 : U"N"; +S0x2B : U"M"; +S0x2A : U","; +S0x29 : U"."; +S0x12 : U"/"; +S0x3A : U"RShift"; -# Example capability, prints to cli -action1 => CustomAction_action1_capability(); # No arguments +# bottom +S0x80 : U"LCtrl"; +S0x6A : U"LGui"; +S0x0E : U"LAlt"; +S0x03 : U"LAlt"; +S0x09 : U"Space"; +S0x15 : U"RAlt"; +S0x17 : U"RGui"; +S0x88 : U"RCtrl"; +S0x87 : U"RCtrl"; -# Blocks given USB Code, must be used with blockLink -# Simple example, supports only blocking a single key at a time -# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h -blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument -blockKey => CustomAction_blockKey_capability( usbCode : 1 ); +# middle right column, custom +S0x8A : U"Esc"; +S0x89 : U"Backspace"; +S0x77 : U"Enter"; +S0x78 : U"RShift"; +# arrows +S0x1E : U"Left"; +S0x0C : U"Up"; +S0x1B : U"Down"; +S0x1C : U"Right"; +# S0x1C : U"RCtrl"; + +# numpad +S0x2D : U"NumLock"; +S0x2E : U"P/"; +S0x2F : U"P*"; +S0x1D : U"P-"; + +S0x51 : U"P7"; +S0x52 : U"P8"; +S0x53 : U"P9"; +S0x54 : U"P+"; + +S0x63 : U"P4"; +S0x64 : U"P5"; +S0x65 : U"P6"; + +S0x3F : U"P1"; +S0x40 : U"P2"; +S0x41 : U"P3"; +S0x42 : U"PEnter"; + +S0x0A : U"P0"; +S0x0B : U"P."; diff --git a/Scan/CK3/matrix.h b/Scan/CK3/matrix.h index 1a2be2e..7f6632d 100644 --- a/Scan/CK3/matrix.h +++ b/Scan/CK3/matrix.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2015 by Jacob Alexander +/* Copyright (C) 2014-2016 by Jacob Alexander, Crystal Hammer * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,28 +27,42 @@ #include - // ----- Matrix Definition ----- +// CK3 +// Columns (Strobe) 18 +// Rows (Sense) 8 -// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31 -// Not all chips have access to all of these pins (most don't have 160 pins :P) -// -// NOTE: -// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down -// Checking this is completely on the ownness of the user +// This is the default map of just A4Tech KX-100 matrix +// scan codes for keys are defined in defaultMap.kll +/* + 1| 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + - + 1 Mcmp Bstp Esc \ F4 Up Del Ins Spc G H F6 == Vol- AltL xx F11 ' + 2 Calc ExA4 ExC2 ExE2 ExE1 <- Sub -> Dn B N ExC1 Apps Mnxt AltR xx F12 / + 3 Mstp Bbck Z X C Mpau Mul Div NumL V M , . Vol+ xx CtrR Ent \ + 4 GuiR Bfwd A S D Ent PgDn Dn End F J K L ShiR xx == \ ; + 5 xx Mail Q W E Add PgUp Up Home R U I O xx ScrL Paus ExE3 P + 6 ExB1 GuiL Tab Caps F3 RB~ -> Del <- T Y ] F7 ShiL == Pwr Back [ + 7 xx Bsch 1 2 3 End PgDn xx Pwr 4 7 8 9 Msel Ptr F5 F10 0 + 8 Bhom Vmut `~ F1 F2 Home PgUp Ins Del 5 6 = F8 Mprv == CtrL F9 - -// -// Columns (Strobe) // PTB0..3,16,17 PTC4,5 PTD0 -// Rows (Sense) // PTD1..7 - -// Define Rows (Sense) and Columns (Strobes) -GPIO_Pin Matrix_cols[] = { gpio(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,6), gpio(D,0) }; -GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) }; + rows - columns | + 1 3 5 7 1 3 5 7 9 11 13 15 17 + 2 4 6 8 2 4 6 8 10 12 14 16 18 connectors, PCB view +*/ +GPIO_Pin Matrix_cols[] = { + gpio(B,16), gpio(B,17), gpio(D,0), gpio(A,12), gpio(A,13), gpio(D,7), gpio(D,4), gpio(D,2), gpio(D,3), + gpio(C,2), gpio(C,1), gpio(D,6), gpio(D,5), gpio(B,2), gpio(B,3), gpio(B,1), gpio(B,0), gpio(C,0) }; +GPIO_Pin Matrix_rows[] = { + gpio(C,10), gpio(C,11), gpio(B,18), gpio(A,4), gpio(A,5), gpio(B,19), gpio(C,9), gpio(C,8) }; // Define type of scan matrix -Config Matrix_type = Config_Pulldown; +Config Matrix_type = Config_Pullup; // Define this if your matrix has ghosting (i.e. regular keyboard without diodes) // this will enable the anti-ghosting code #define GHOSTING_MATRIX + +// delay in microseconds before and after each strobe change during matrix scan +#define STROBE_DELAY 10 diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 90343fe..6693143 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -30,6 +30,7 @@ #include #include #include +#include // Local Includes #include "matrix_scan.h" @@ -110,7 +111,9 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) // Assumes 0x40 between GPIO Port registers and 0x1000 between PORT pin registers // See Lib/mk20dx.h volatile unsigned int *GPIO_PDDR = (unsigned int*)(&GPIOA_PDDR) + gpio_offset; + #ifndef GHOSTING_MATRIX volatile unsigned int *GPIO_PSOR = (unsigned int*)(&GPIOA_PSOR) + gpio_offset; + #endif volatile unsigned int *GPIO_PCOR = (unsigned int*)(&GPIOA_PCOR) + gpio_offset; volatile unsigned int *GPIO_PDIR = (unsigned int*)(&GPIOA_PDIR) + gpio_offset; volatile unsigned int *PORT_PCR = (unsigned int*)(&PORTA_PCR0) + port_offset; @@ -119,23 +122,30 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) switch ( type ) { case Type_StrobeOn: - *GPIO_PSOR |= (1 << gpio.pin); #ifdef GHOSTING_MATRIX - *GPIO_PDDR |= (1 << gpio.pin); // output + *GPIO_PCOR |= (1 << gpio.pin); + *GPIO_PDDR |= (1 << gpio.pin); // output, low + #else + *GPIO_PSOR |= (1 << gpio.pin); #endif break; case Type_StrobeOff: - *GPIO_PCOR |= (1 << gpio.pin); #ifdef GHOSTING_MATRIX // Ghosting martix needs to put not used (off) strobes in high impedance state *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state #endif + *GPIO_PCOR |= (1 << gpio.pin); break; case Type_StrobeSetup: + #ifdef GHOSTING_MATRIX + *GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state + *GPIO_PCOR |= (1 << gpio.pin); + #else // Set as output pin *GPIO_PDDR |= (1 << gpio.pin); + #endif // Configure pin with slow slew, high drive strength and GPIO mux *PORT_PCR = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); @@ -154,7 +164,11 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type ) break; case Type_Sense: + #ifdef GHOSTING_MATRIX // inverted + return *GPIO_PDIR & (1 << gpio.pin) ? 0 : 1; + #else return *GPIO_PDIR & (1 << gpio.pin) ? 1 : 0; + #endif case Type_SenseSetup: // Set as input pin @@ -294,9 +308,19 @@ void Matrix_scan( uint16_t scanNum ) // For each strobe, scan each of the sense pins for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ ) { + #ifdef STROBE_DELAY + uint32_t start = micros(); + while ((micros() - start) < STROBE_DELAY); + #endif + // Strobe Pin Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOn ); + #ifdef STROBE_DELAY + start = micros(); + while ((micros() - start) < STROBE_DELAY); + #endif + // Scan each of the sense pins for ( uint8_t sense = 0; sense < Matrix_rowsNum; sense++ ) { @@ -510,10 +534,6 @@ void Matrix_scan( uint16_t scanNum ) KeyPosition k = !st->cur ? (!st->prev ? KeyState_Off : KeyState_Release) : ( st->prev ? KeyState_Hold : KeyState_Press); - //if (!st->cur && !st->prev) k = KeyState_Off; else - //if ( st->cur && st->prev) k = KeyState_Hold; else - //if ( st->cur && !st->prev) k = KeyState_Press; else - //if (!st->cur && st->prev) k = KeyState_Release; Macro_keyState( key, k ); } } From 602b48253870caf8523598097fd55150aa0e8080 Mon Sep 17 00:00:00 2001 From: CryHam Date: Tue, 1 Mar 2016 21:00:23 +0100 Subject: [PATCH 70/79] Updated CK3 with Scan_currentChange (copy from MD1). --- Scan/CK3/scan_loop.c | 9 +++++++++ Scan/CK3/scan_loop.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/Scan/CK3/scan_loop.c b/Scan/CK3/scan_loop.c index 22d43c2..b4c8c99 100644 --- a/Scan/CK3/scan_loop.c +++ b/Scan/CK3/scan_loop.c @@ -175,6 +175,15 @@ void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t } +// Signal from the Output Module that the available current has changed +// current - mA +void Scan_currentChange( unsigned int current ) +{ + // Indicate to all submodules current change + Matrix_currentChange( current ); +} + + // ----- CLI Command Functions ----- diff --git a/Scan/CK3/scan_loop.h b/Scan/CK3/scan_loop.h index 0c89838..3c543ea 100644 --- a/Scan/CK3/scan_loop.h +++ b/Scan/CK3/scan_loop.h @@ -38,6 +38,8 @@ uint8_t Scan_loop( void ); void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module +void Scan_currentChange( unsigned int current ); // Called by Output Module + // ----- Capabilities ----- From 074134c47442fa28559598209e3d7d3f30326177 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 1 Mar 2016 19:35:21 -0800 Subject: [PATCH 71/79] Fixing potential WF LED issue - Added fix for USB Current Change * If called during interrupt, could hang the I2C bus * Delaying I2C writes till scan loop --- Scan/ISSILed/led_scan.c | 33 +++++++++++++++++++-------------- Scan/WhiteFox/defaultMap.kll | 4 ++-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index 609f2d7..a091b86 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -639,12 +639,26 @@ uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ) // LED State processing loop +unsigned int LED_currentEvent = 0; inline uint8_t LED_scan() { + // Check for current change event + if ( LED_currentEvent ) + { + // TODO dim LEDs in low power mode instead of shutting off + if ( LED_currentEvent < 150 ) + { + // Enable Software shutdown of ISSI chip + LED_writeReg( 0x0A, 0x00, 0x0B ); + } + else + { + // Disable Software shutdown of ISSI chip + LED_writeReg( 0x0A, 0x01, 0x0B ); + } - // I2C Busy - // S & I2C_S_BUSY - //I2C_S_BUSY + LED_currentEvent = 0; + } return 0; } @@ -654,17 +668,8 @@ inline uint8_t LED_scan() // current - mA void LED_currentChange( unsigned int current ) { - // TODO dim LEDs in low power mode instead of shutting off - if ( current < 150 ) - { - // Enabled Software shutdown of ISSI chip - LED_writeReg( 0x0A, 0x00, 0x0B ); - } - else - { - // Disable Software shutdown of ISSI chip - LED_writeReg( 0x0A, 0x01, 0x0B ); - } + // Delay action till next LED scan loop (as this callback sometimes occurs during interrupt requests) + LED_currentEvent = current; } diff --git a/Scan/WhiteFox/defaultMap.kll b/Scan/WhiteFox/defaultMap.kll index 6a4e641..037319b 100644 --- a/Scan/WhiteFox/defaultMap.kll +++ b/Scan/WhiteFox/defaultMap.kll @@ -95,7 +95,7 @@ ISSILedMask1 = " 0xFF, 0x00, /* C6-1 -> C6-16 */ 0xFF, 0x00, /* C7-1 -> C7-16 */ 0xFF, 0x00, /* C8-1 -> C8-16 */ - 0xFE, 0x00, /* C9-1 -> C9-16 */ + 0xFF, 0x00, /* C9-1 -> C9-16 */ "; # LED Brightness Override @@ -124,6 +124,6 @@ ISSILedBrightness1 = " 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */ -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */ "; From c5aed6cb17124b09939ca7037c288e517a66918f Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 3 Mar 2016 20:40:01 -0800 Subject: [PATCH 72/79] Adding convenience symlinks to the udev rules --- 98-kiibohd.rules | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/98-kiibohd.rules b/98-kiibohd.rules index d00a8b2..955bc13 100644 --- a/98-kiibohd.rules +++ b/98-kiibohd.rules @@ -3,9 +3,9 @@ ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}= ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" # Kiibohd Serial Interface -KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" -KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" -KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666", +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666" # Kiibohd Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" # DFU Bootloader (MCHCK) @@ -16,4 +16,6 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", MODE:="066 ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b007", MODE:="0666" +# Kiibohd Force Gauge +SUBSYSTEM=="tty", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", GROUP="users", MODE="0666", SYMLINK+="force" From 0102d05c8698a33c18b997fe166ca19fa358253e Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 4 Mar 2016 00:23:48 -0800 Subject: [PATCH 73/79] Fixing clang compilation and supporting clang-tidy - clang.c includes necessary functions to make clang compiler work (tested on teensy 3.1) - Added support code to generate a compile_commands.json for clang-tidy * Updates the symlink whenever cmake or make is called (Unix OSs only) --- .clang-tidy | 16 ++++++++++++ .gitignore | 1 + CMakeLists.txt | 18 ++++++++----- Lib/CMake/arm.cmake | 9 ++++++- Lib/CMake/build.cmake | 20 ++++++++++++++ Lib/clang.c | 61 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 .clang-tidy create mode 100644 Lib/clang.c diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..8ae1316 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,16 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +User: hyatt +CheckOptions: + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' +... + diff --git a/.gitignore b/.gitignore index 7a86e68..574420d 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ tags CMakeFiles CMakeCache.txt cmake_install.cmake +compile_commands.json # External Repos # ################## diff --git a/CMakeLists.txt b/CMakeLists.txt index dcb0c94..ec9fb62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller |### # -# Jacob Alexander 2011-2015 +# Jacob Alexander 2011-2016 # Due to this file's usefulness: # # Released into the Public Domain @@ -25,7 +25,8 @@ set( CHIP "mk20dx128vlf5" # McHCK mk20dx128vlf5 # "mk20dx256" # Teensy 3.1,3.2 (arm) # "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 - CACHE STRING "Microcontroller Chip" ) + CACHE STRING "Microcontroller Chip" +) @@ -33,13 +34,14 @@ set( CHIP # Compiler Selection # -#| *** EXPERIMENTAL *** -#| Stick with gcc unless you know what you're doing +#| gcc has been tested much more (and will likely give smaller binaries) +#| clang does work though #| Currently only arm is supported with clang set( COMPILER "gcc" # arm-none-eabi-gcc / avr-gcc - Default # "clang" # arm-none-eabi - CACHE STRING "Compiler Type" ) + CACHE STRING "Compiler Type" +) @@ -72,11 +74,13 @@ set( MacroModule "PartialMap" ##| Sends the current list of usb key codes through USB HID set( OutputModule "pjrcUSB" - CACHE STRING "Output Module" ) + CACHE STRING "Output Module" +) ##| Debugging source to use, each module has it's own set of defines that it sets set( DebugModule "full" - CACHE STRING "Debug Module" ) + CACHE STRING "Debug Module" +) diff --git a/Lib/CMake/arm.cmake b/Lib/CMake/arm.cmake index be04de2..31fe0cd 100644 --- a/Lib/CMake/arm.cmake +++ b/Lib/CMake/arm.cmake @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller |### # -# Jacob Alexander 2011-2014 +# Jacob Alexander 2011-2016 # Due to this file's usefulness: # # Released into the Public Domain @@ -111,6 +111,13 @@ set( COMPILER_SRCS Lib/delay.c ) +#| Clang needs a few more functions for linking +if ( "${COMPILER}" MATCHES "clang" ) + set( COMPILER_SRCS ${COMPILER_SRCS} + Lib/clang.c + ) +endif () + message( STATUS "Compiler Source Files:" ) message( "${COMPILER_SRCS}" ) diff --git a/Lib/CMake/build.cmake b/Lib/CMake/build.cmake index b3209bf..de58ea0 100644 --- a/Lib/CMake/build.cmake +++ b/Lib/CMake/build.cmake @@ -135,3 +135,23 @@ elseif ( DEFINED TEENSY ) endif() endif() + + +### +# Compiler Command Generation +# + +#| Generate list of compiler commands for clang-tidy usage +set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) + +#| Make sure symlink exists (for convenience) +if ( UNIX ) + # Make sure symlink is created immediately + execute_process ( COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/. ) + + # Also update before each build + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/. + ) +endif () + diff --git a/Lib/clang.c b/Lib/clang.c new file mode 100644 index 0000000..f502409 --- /dev/null +++ b/Lib/clang.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2016 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +// This file adds various functions that clang doesn't link properly +// AFAIK, clang doesn't have an elegant solution for this, so this is what we gotta do... + +// ----- Includes ----- + +// Compiler Includes +#include + + +void __aeabi_memcpy( void *dest, const void *src, size_t n ) +{ + (void)memcpy(dest, src, n); +} + +void __aeabi_memcpy4( void *dest, const void *src, size_t n ) +{ + memcpy(dest, src, n); +} + +void __aeabi_memclr( void *dest, size_t n ) +{ + memset(dest, 0, n); +} + +void __aeabi_memclr4( void *dest, size_t n ) +{ + memset(dest, 0, n); +} + +void __aeabi_memmove( void *dest, const void *src, size_t n ) +{ + (void)memmove(dest, src, n); +} + +void __aeabi_memset( void *s, size_t n, int c ) +{ + (void)memset(s, c, n); +} + From 3c9a97d51a2f3b94168e46ff1524ceec63703eff Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 21 Mar 2016 00:43:19 -0700 Subject: [PATCH 74/79] Adding basic mouse button support - Full Mouse support will have to wait for KLL 0.6 * This will include dynamic HID descriptor generation for many wheels and axis depending on the KLL needs - HID descriptor is currently limited to 8 buttons - Technically mouse movement also works (tested by accident), but it's disable for now (needs some API thought) - Adding additional udev rules - Added KRO mode default define --- 98-kiibohd.rules | 6 +++ Output/pjrcUSB/arm/usb_desc.c | 11 ++--- Output/pjrcUSB/arm/usb_mouse.c | 84 ++++++++++++++++++++++++--------- Output/pjrcUSB/arm/usb_mouse.h | 13 ++--- Output/pjrcUSB/capabilities.kll | 15 ++++-- Output/pjrcUSB/output_com.c | 75 +++++++++++++++++++++++++---- Output/pjrcUSB/output_com.h | 3 ++ 7 files changed, 155 insertions(+), 52 deletions(-) diff --git a/98-kiibohd.rules b/98-kiibohd.rules index 955bc13..3dccd01 100644 --- a/98-kiibohd.rules +++ b/98-kiibohd.rules @@ -2,20 +2,26 @@ ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666" + # Kiibohd Serial Interface KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666", KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666" KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666" + # Kiibohd Device SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666" + # DFU Bootloader (MCHCK) ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", MODE:="0666" + # Kiibohd DFU Bootloader ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{MTP_NO_PROBE}="1" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b007", MODE:="0666" + # Kiibohd Force Gauge SUBSYSTEM=="tty", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", GROUP="users", MODE="0666", SYMLINK+="force" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666" diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 1d9a939..02ffd5d 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -314,22 +314,17 @@ static uint8_t mouse_report_desc[] = { 0xa1, 0x02, // Collection (Logical) 0x09, 0x01, // Usage (Pointer) - // Buttons (5 bits) + // Buttons (8 bits) 0xa1, 0x00, // Collection (Physical) - Buttons 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (Button 1) - 0x29, 0x05, // Usage Maximum (Button 5) + 0x29, 0x08, // Usage Maximum (Button 8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) - 0x95, 0x05, // Report Count (5) + 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs) - // Padding (3 bits) - 0x75, 0x03, // Report Size (3) - 0x95, 0x01, // Report Count (1) - 0x81, 0x03, // Input (Cnst,Var,Abs) - // Pointer (16 bits) 0x05, 0x01, // Usage PAGE (Generic Desktop) 0x09, 0x30, // Usage (X) diff --git a/Output/pjrcUSB/arm/usb_mouse.c b/Output/pjrcUSB/arm/usb_mouse.c index 2b1dc72..43a6f50 100644 --- a/Output/pjrcUSB/arm/usb_mouse.c +++ b/Output/pjrcUSB/arm/usb_mouse.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2015) + * Modified by Jacob Alexander (2015-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -115,38 +115,78 @@ // ----- Variables ----- -// which buttons are currently pressed -uint8_t usb_mouse_buttons_state=0; +static uint8_t transmit_previous_timeout = 0; -static uint16_t usb_mouse_resolution_x=DEFAULT_XRES; -static uint16_t usb_mouse_resolution_y=DEFAULT_YRES; -static uint16_t usb_mouse_position_x=DEFAULT_XRES/2; -static uint16_t usb_mouse_position_y=DEFAULT_YRES/2; -static uint32_t usb_mouse_scale_x=DEFAULT_XSCALE; -static uint32_t usb_mouse_scale_y=DEFAULT_YSCALE; -static uint32_t usb_mouse_offset_x=DEFAULT_XSCALE/2-1; -static uint32_t usb_mouse_offset_y=DEFAULT_YSCALE/2-1; +// which buttons are currently pressed +uint8_t usb_mouse_buttons_state = 0; + +static uint16_t usb_mouse_resolution_x = DEFAULT_XRES; +static uint16_t usb_mouse_resolution_y = DEFAULT_YRES; +static uint16_t usb_mouse_position_x = DEFAULT_XRES / 2; +static uint16_t usb_mouse_position_y = DEFAULT_YRES / 2; +static uint32_t usb_mouse_scale_x = DEFAULT_XSCALE; +static uint32_t usb_mouse_scale_y = DEFAULT_YSCALE; +static uint32_t usb_mouse_offset_x = DEFAULT_XSCALE / 2 - 1; +static uint32_t usb_mouse_offset_y = DEFAULT_YSCALE / 2 - 1; // ----- Functions ----- -// Set the mouse buttons. To create a "click", 2 calls are needed, -// one to push the button down and the second to release it -int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) +// Process pending mouse commands +// XXX Missing mouse movement and wheels +// Proper support will require KLL generation of the USB descriptors +// Similar support will be required for joystick control +void usb_mouse_send() { - uint8_t mask=0; + uint32_t wait_count = 0; + usb_packet_t *tx_packet; - if (left) mask |= 1; - if (middle) mask |= 4; - if (right) mask |= 2; - usb_mouse_buttons_state = mask; - return usb_mouse_move(0, 0, 0); + // Wait till ready + while ( 1 ) + { + if ( !usb_configuration ) + { + erro_print("USB not configured..."); + return; + } + + // Attempt to acquire a USB packet for the mouse endpoint + if ( usb_tx_packet_count( MOUSE_ENDPOINT ) < TX_PACKET_LIMIT ) + { + tx_packet = usb_malloc(); + if ( tx_packet ) + break; + } + + if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout ) + { + transmit_previous_timeout = 1; + warn_print("USB Transmit Timeout..."); + return; + } + yield(); + } + + transmit_previous_timeout = 0; + + // Prepare USB Mouse Packet + // TODO Document each byte + // TODO Dynamically generate this code based on KLL requirements + *(tx_packet->buf + 0) = USBMouse_Buttons; + *(tx_packet->buf + 1) = 0; + *(tx_packet->buf + 2) = 0; + *(tx_packet->buf + 3) = 0; + *(tx_packet->buf + 4) = 0; + tx_packet->len = 5; + usb_tx( MOUSE_ENDPOINT, tx_packet ); + + // Clear status and state + USBMouse_Buttons = 0; + USBMouse_Changed = 0; } -static uint8_t transmit_previous_timeout=0; - // Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. int usb_mouse_move(int8_t x, int8_t y, int8_t wheel) { diff --git a/Output/pjrcUSB/arm/usb_mouse.h b/Output/pjrcUSB/arm/usb_mouse.h index ffa9fe2..397d967 100644 --- a/Output/pjrcUSB/arm/usb_mouse.h +++ b/Output/pjrcUSB/arm/usb_mouse.h @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modified by Jacob Alexander (2015) + * Modified by Jacob Alexander (2015-2016) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -43,16 +43,11 @@ // ----- Functions ----- +// Proces pending mouse commands +void usb_mouse_send(); + // TODO - More generic -int usb_mouse_buttons( uint8_t left, uint8_t middle, uint8_t right ); int usb_mouse_move( int8_t x, int8_t y, int8_t wheel ); int usb_mouse_position( uint16_t x, uint16_t y ); void usb_mouse_screen_size( uint16_t width, uint16_t height, uint8_t mac ); -extern uint8_t usb_mouse_buttons_state; - -// TODO - Move -#define MOUSE_LEFT 1 -#define MOUSE_MIDDLE 4 -#define MOUSE_RIGHT 2 -#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) diff --git a/Output/pjrcUSB/capabilities.kll b/Output/pjrcUSB/capabilities.kll index 7646625..960c246 100644 --- a/Output/pjrcUSB/capabilities.kll +++ b/Output/pjrcUSB/capabilities.kll @@ -1,10 +1,10 @@ Name = pjrcUSBCapabilities; -Version = 0.6; -Author = "HaaTa (Jacob Alexander) 2014-2015"; -KLL = 0.3c; +Version = 0.7; +Author = "HaaTa (Jacob Alexander) 2014-2016"; +KLL = 0.3d; # Modified Date -Date = 2015-08-21; +Date = 2016-03-20; # Output capabilities @@ -12,6 +12,7 @@ consCtrlOut => Output_consCtrlSend_capability( consCode : 2 ); noneOut => Output_noneSend_capability(); sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 ); usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); +mouseOut => Output_usbMouse_capability( mouseCode : 2 ); # Configuration capabilities kbdProtocolBoot => Output_kbdProtocolBoot_capability(); @@ -21,6 +22,12 @@ kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); keyboardLocale => KeyboardLocale_define; keyboardLocale = 0; +# Default KRO Mode +# Set to 0 for Boot Mode (6KRO) +# Set to 1 for NKRO Mode (default) +usbProtocol => USBProtocol_define; +usbProtocol = 1; + # Bootloader Mode capability # XXX # By default this is disabled on purpose diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index b18bbdb..37389cb 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -37,8 +37,12 @@ #include "arm/usb_dev.h" #include "arm/usb_keyboard.h" #include "arm/usb_serial.h" +#include "arm/usb_mouse.h" #endif +// KLL +#include + // Local Includes #include "output_com.h" @@ -47,14 +51,15 @@ // ----- Macros ----- // Used to build a bitmap lookup table from a byte addressable array -#define byteLookup( byte ) case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \ - case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \ - case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \ - case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \ - case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \ - case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \ - case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \ - case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break +#define byteLookup( byte ) \ + case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \ + case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \ + case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \ + case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \ + case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \ + case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \ + case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \ + case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break @@ -111,15 +116,21 @@ uint8_t USBKeys_SentCLI = 0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t USBKeys_LEDs = 0; +// Currently pressed mouse buttons, bitmask, 0 represents no buttons pressed +volatile uint16_t USBMouse_Buttons = 0; + // Protocol setting from the host. // 0 - Boot Mode // 1 - NKRO Mode (Default, unless set by a BIOS or boot interface) -volatile uint8_t USBKeys_Protocol = 1; +volatile uint8_t USBKeys_Protocol = USBProtocol_define; // Indicate if USB should send update // OS only needs update if there has been a change in state USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; +// Indicate if USB should send update +uint8_t USBMouse_Changed = 0; + // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed uint8_t USBKeys_Idle_Config = 125; @@ -505,6 +516,48 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg Output_firmwareReload(); } +// Sends a mouse command over the USB Output buffer +// XXX This function *will* be changing in the future +// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5) +// Argument #1: USB Mouse Button # +void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_usbMouse(mouseButton)"); + return; + } + + // Determine which mouse button was sent + // The USB spec defines up to a max of 0xFFFF buttons + // The usual are: + // 1 - Button 1 - (Primary) + // 2 - Button 2 - (Secondary) + // 3 - Button 3 - (Tertiary) + uint16_t mouse_button = *(uint16_t*)(&args[0]); + + // If set to zero, ignore + if ( mouse_button == 0 ) + return; + + // Adjust for bit shift + mouse_button -= 1; + + // Only send mouse button if in press or hold state + if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBMouse_Buttons &= ~(1 << mouse_button); + } + else + { + USBMouse_Buttons |= (1 << mouse_button); + } + + // TODO Add more states when adding full support + USBMouse_Changed = 1; +} + // ----- Functions ----- @@ -552,6 +605,10 @@ inline void Output_send() for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) USBKeys_Keys[c] = 0; + // Process mouse actions + while ( USBMouse_Changed ) + usb_mouse_send(); + // Send keypresses while there are pending changes while ( USBKeys_Changed ) usb_keyboard_send(); diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index 2448683..abb8124 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -72,11 +72,14 @@ extern uint16_t USBKeys_ConsCtrl; // 1KRO container for Consumer Contro extern volatile uint8_t USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode +extern volatile uint16_t USBMouse_Buttons; // Bitmask for mouse buttons + // Misc variables (XXX Some are only properly utilized using AVR) extern uint8_t USBKeys_Idle_Config; extern uint8_t USBKeys_Idle_Count; extern USBKeyChangeState USBKeys_Changed; +extern uint8_t USBMouse_Changed; extern volatile uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working From 18aef02a1feaf1e3f49085cc82e36221039530b4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 21 Mar 2016 22:23:57 -0700 Subject: [PATCH 75/79] Adding relative movement mouse key support - Still very basic (lots of room for improvement) - Capability format will likely change at some point - 16 bit movement control, however repeat rate limits usability (will need KLL 0.4 to make better) --- Output/pjrcUSB/arm/usb_desc.c | 22 ++++++++++-------- Output/pjrcUSB/arm/usb_mouse.c | 14 +++++------ Output/pjrcUSB/capabilities.kll | 6 ++--- Output/pjrcUSB/output_com.c | 41 ++++++++++++++++++++++++--------- Output/pjrcUSB/output_com.h | 14 +++++++++-- 5 files changed, 64 insertions(+), 33 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_desc.c b/Output/pjrcUSB/arm/usb_desc.c index 02ffd5d..b0be2a0 100644 --- a/Output/pjrcUSB/arm/usb_desc.c +++ b/Output/pjrcUSB/arm/usb_desc.c @@ -309,32 +309,33 @@ static uint8_t sys_ctrl_report_desc[] = { static uint8_t mouse_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) - 0xa1, 0x01, // Collection (Application) + 0xA1, 0x01, // Collection (Application) 0x09, 0x02, // Usage (Mouse) - 0xa1, 0x02, // Collection (Logical) + 0xA1, 0x02, // Collection (Logical) 0x09, 0x01, // Usage (Pointer) - // Buttons (8 bits) - 0xa1, 0x00, // Collection (Physical) - Buttons + // Buttons (16 bits) + 0xA1, 0x00, // Collection (Physical) - Buttons 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (Button 1) - 0x29, 0x08, // Usage Maximum (Button 8) + 0x29, 0x10, // Usage Maximum (Button 16) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) - 0x95, 0x08, // Report Count (8) + 0x95, 0x10, // Report Count (16) 0x81, 0x02, // Input (Data,Var,Abs) - // Pointer (16 bits) + // Pointer (32 bits) 0x05, 0x01, // Usage PAGE (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7f, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8) + 0x16, 0x01, 0x80, // Logical Minimum (-32 767) + 0x26, 0xFF, 0x7F, // Logical Maximum (32 767) + 0x75, 0x10, // Report Size (16) 0x95, 0x02, // Report Count (2) 0x81, 0x06, // Input (Data,Var,Rel) + /* // Vertical Wheel // - Multiplier (2 bits) 0xa1, 0x02, // Collection (Logical) @@ -377,6 +378,7 @@ static uint8_t mouse_report_desc[] = { 0x81, 0x06, // Input (Data,Var,Rel) 0xc0, // End Collection - Horizontal Wheel + */ 0xc0, // End Collection - Buttons 0xc0, // End Collection - Mouse Logical 0xc0 // End Collection - Mouse Application diff --git a/Output/pjrcUSB/arm/usb_mouse.c b/Output/pjrcUSB/arm/usb_mouse.c index 43a6f50..5de7712 100644 --- a/Output/pjrcUSB/arm/usb_mouse.c +++ b/Output/pjrcUSB/arm/usb_mouse.c @@ -171,18 +171,18 @@ void usb_mouse_send() transmit_previous_timeout = 0; // Prepare USB Mouse Packet - // TODO Document each byte // TODO Dynamically generate this code based on KLL requirements - *(tx_packet->buf + 0) = USBMouse_Buttons; - *(tx_packet->buf + 1) = 0; - *(tx_packet->buf + 2) = 0; - *(tx_packet->buf + 3) = 0; - *(tx_packet->buf + 4) = 0; - tx_packet->len = 5; + uint16_t *packet_data = (uint16_t*)(&tx_packet->buf[0]); + packet_data[0] = USBMouse_Buttons; + packet_data[1] = USBMouse_Relative_x; + packet_data[2] = USBMouse_Relative_y; + tx_packet->len = 6; usb_tx( MOUSE_ENDPOINT, tx_packet ); // Clear status and state USBMouse_Buttons = 0; + USBMouse_Relative_x = 0; + USBMouse_Relative_y = 0; USBMouse_Changed = 0; } diff --git a/Output/pjrcUSB/capabilities.kll b/Output/pjrcUSB/capabilities.kll index 960c246..c83f910 100644 --- a/Output/pjrcUSB/capabilities.kll +++ b/Output/pjrcUSB/capabilities.kll @@ -1,10 +1,10 @@ Name = pjrcUSBCapabilities; -Version = 0.7; +Version = 0.8; Author = "HaaTa (Jacob Alexander) 2014-2016"; KLL = 0.3d; # Modified Date -Date = 2016-03-20; +Date = 2016-03-21; # Output capabilities @@ -12,7 +12,7 @@ consCtrlOut => Output_consCtrlSend_capability( consCode : 2 ); noneOut => Output_noneSend_capability(); sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 ); usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); -mouseOut => Output_usbMouse_capability( mouseCode : 2 ); +mouseOut => Output_usbMouse_capability( mouseCode : 2, relative_x : 2, relative_y : 2 ); # Configuration capabilities kbdProtocolBoot => Output_kbdProtocolBoot_capability(); diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 37389cb..39ee0b0 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -119,6 +119,10 @@ volatile uint8_t USBKeys_LEDs = 0; // Currently pressed mouse buttons, bitmask, 0 represents no buttons pressed volatile uint16_t USBMouse_Buttons = 0; +// Relative mouse axis movement, stores pending movement +volatile uint16_t USBMouse_Relative_x = 0; +volatile uint16_t USBMouse_Relative_y = 0; + // Protocol setting from the host. // 0 - Boot Mode // 1 - NKRO Mode (Default, unless set by a BIOS or boot interface) @@ -129,7 +133,7 @@ volatile uint8_t USBKeys_Protocol = USBProtocol_define; USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; // Indicate if USB should send update -uint8_t USBMouse_Changed = 0; +USBMouseChangeState USBMouse_Changed = 0; // the idle configuration, how often we send the report to the // host (ms * 4) even when it hasn't changed @@ -519,13 +523,15 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg // Sends a mouse command over the USB Output buffer // XXX This function *will* be changing in the future // If you use it, be prepared that your .kll files will break in the future (post KLL 0.5) -// Argument #1: USB Mouse Button # +// Argument #1: USB Mouse Button (16 bit) +// Argument #2: USB X Axis (16 bit) relative +// Argument #3: USB Y Axis (16 bit) relative void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { // Display capability name if ( stateType == 0xFF && state == 0xFF ) { - print("Output_usbMouse(mouseButton)"); + print("Output_usbMouse(mouseButton,relX,relY)"); return; } @@ -537,25 +543,38 @@ void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args // 3 - Button 3 - (Tertiary) uint16_t mouse_button = *(uint16_t*)(&args[0]); - // If set to zero, ignore - if ( mouse_button == 0 ) - return; + // X/Y Relative Axis + uint16_t mouse_x = *(uint16_t*)(&args[2]); + uint16_t mouse_y = *(uint16_t*)(&args[4]); // Adjust for bit shift - mouse_button -= 1; + uint16_t mouse_button_shift = mouse_button - 1; // Only send mouse button if in press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state { - USBMouse_Buttons &= ~(1 << mouse_button); + // Release + if ( mouse_button ) + USBMouse_Buttons &= ~(1 << mouse_button_shift); } else { - USBMouse_Buttons |= (1 << mouse_button); + // Press or hold + if ( mouse_button ) + USBMouse_Buttons |= (1 << mouse_button_shift); + + if ( mouse_x ) + USBMouse_Relative_x = mouse_x; + if ( mouse_y ) + USBMouse_Relative_y = mouse_y; } - // TODO Add more states when adding full support - USBMouse_Changed = 1; + // Trigger updates + if ( mouse_button ) + USBMouse_Changed |= USBMouseChangeState_Buttons; + + if ( mouse_x || mouse_y ) + USBMouse_Changed |= USBMouseChangeState_Relative; } diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index abb8124..36369eb 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -56,6 +56,14 @@ typedef enum USBKeyChangeState { USBKeyChangeState_All = 0x7F, } USBKeyChangeState; +// Allows for selective USB descriptor pushes +// However, in most cases everything is updated for each packet push +typedef enum USBMouseChangeState { + USBMouseChangeState_None = 0x00, + USBMouseChangeState_Buttons = 0x01, + USBMouseChangeState_Relative = 0x02, +} USBMouseChangeState; + // ----- Variables ----- @@ -73,13 +81,15 @@ extern uint16_t USBKeys_ConsCtrl; // 1KRO container for Consumer Contro extern volatile uint8_t USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode extern volatile uint16_t USBMouse_Buttons; // Bitmask for mouse buttons +extern volatile uint16_t USBMouse_Relative_x; +extern volatile uint16_t USBMouse_Relative_y; // Misc variables (XXX Some are only properly utilized using AVR) extern uint8_t USBKeys_Idle_Config; extern uint8_t USBKeys_Idle_Count; -extern USBKeyChangeState USBKeys_Changed; -extern uint8_t USBMouse_Changed; +extern USBKeyChangeState USBKeys_Changed; +extern USBMouseChangeState USBMouse_Changed; extern volatile uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working From bfaed8f58ce8aaa307dee2c4500fee426170b8ed Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 22 Mar 2016 19:51:43 -0700 Subject: [PATCH 76/79] Move matrix information to a cli command --- Scan/MatrixARM/matrix_scan.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index bbce1df..7d8897b 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -52,6 +52,7 @@ nat_ptr_t Matrix_divCounter = 0; // CLI Functions void cliFunc_matrixDebug( char* args ); +void cliFunc_matrixInfo( char* args ); void cliFunc_matrixState( char* args ); @@ -60,10 +61,12 @@ void cliFunc_matrixState( char* args ); // Scan Module command dictionary CLIDict_Entry( matrixDebug, "Enables matrix debug mode, prints out each scan code." NL "\t\tIf argument \033[35mT\033[0m is given, prints out each scan code state transition." ); +CLIDict_Entry( matrixInfo, "Print info about the configured matrix." ); CLIDict_Entry( matrixState, "Prints out the current scan table N times." NL "\t\t \033[1mO\033[0m - Off, \033[1;33mP\033[0m - Press, \033[1;32mH\033[0m - Hold, \033[1;35mR\033[0m - Release, \033[1;31mI\033[0m - Invalid" ); CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = { CLIDict_Item( matrixDebug ), + CLIDict_Item( matrixInfo ), CLIDict_Item( matrixState ), { 0, 0, 0 } // Null entry for dictionary end }; @@ -204,30 +207,18 @@ void Matrix_setup() // Register Matrix CLI dictionary CLI_registerDictionary( matrixCLIDict, matrixCLIDictName ); - info_msg("Columns: "); - printHex( Matrix_colsNum ); - // Setup Strobe Pins for ( uint8_t pin = 0; pin < Matrix_colsNum; pin++ ) { Matrix_pin( Matrix_cols[ pin ], Type_StrobeSetup ); } - print( NL ); - info_msg("Rows: "); - printHex( Matrix_rowsNum ); - // Setup Sense Pins for ( uint8_t pin = 0; pin < Matrix_rowsNum; pin++ ) { Matrix_pin( Matrix_rows[ pin ], Type_SenseSetup ); } - print( NL ); - info_msg("Max Keys: "); - printHex( Matrix_maxKeys ); - print( NL ); - // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ ) { @@ -598,7 +589,22 @@ void Matrix_currentChange( unsigned int current ) // ----- CLI Command Functions ----- -void cliFunc_matrixDebug ( char* args ) +void cliFunc_matrixInfo( char* args ) +{ + print( NL ); + info_msg("Columns: "); + printHex( Matrix_colsNum ); + + print( NL ); + info_msg("Rows: "); + printHex( Matrix_rowsNum ); + + print( NL ); + info_msg("Max Keys: "); + printHex( Matrix_maxKeys ); +} + +void cliFunc_matrixDebug( char* args ) { // Parse number from argument // NOTE: Only first argument is used @@ -632,7 +638,7 @@ void cliFunc_matrixDebug ( char* args ) printInt8( matrixDebugMode ); } -void cliFunc_matrixState ( char* args ) +void cliFunc_matrixState( char* args ) { // Parse number from argument // NOTE: Only first argument is used From 0ffd8739789b2c87b41aea0666f2028bd7e807f8 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 30 Apr 2016 10:32:19 -0700 Subject: [PATCH 77/79] Change the target chip --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec9fb62..e1d4f4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,9 @@ set( CHIP # "at90usb646" # Teensy++ 1.0 (avr) # "at90usb1286" # Teensy++ 2.0 (avr) # "mk20dx128" # Teensy 3.0 (arm) - "mk20dx128vlf5" # McHCK mk20dx128vlf5 +# "mk20dx128vlf5" # McHCK mk20dx128vlf5 # "mk20dx256" # Teensy 3.1,3.2 (arm) -# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 + "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 CACHE STRING "Microcontroller Chip" ) From ccfe28a1d756fa4cec4aa3c316ad51f29b25db7a Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 30 Apr 2016 11:01:56 -0700 Subject: [PATCH 78/79] Use MDErgo1 for the Scan Module --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1d4f4b..f6c5ef1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ include( initialize ) #| Please look at the {Scan,Macro,Output,Debug} for information on the modules and how to create new ones ##| Deals with acquiring the keypress information and turning it into a key index -set( ScanModule "MD1" +set( ScanModule "MDErgo1" CACHE STRING "Scan Module" ) ##| Provides the mapping functions for DefaultMap and handles any macro processing before sending to the OutputModule From 1585940b80f6ea709547d685daae3f3bd6fc040b Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 30 Apr 2016 13:22:39 -0700 Subject: [PATCH 79/79] Add Layouts directory to the search path for BaseMap and PartialMap Oh. And reformat part of the file because tabs are of the devil. --- Lib/CMake/kll.cmake | 130 +++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 36802e4..dce9f17 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -20,22 +20,22 @@ if ( "${MacroModule}" STREQUAL "PartialMap" ) # if ( NOT EXISTS "${PROJECT_SOURCE_DIR}/kll/kll.py" ) - message ( STATUS "Downloading latest kll version:" ) + message ( STATUS "Downloading latest kll version:" ) - # Make sure git is available - find_package ( Git REQUIRED ) + # Make sure git is available + find_package ( Git REQUIRED ) - # Clone kll git repo - execute_process ( COMMAND ${GIT_EXECUTABLE} clone https://github.com/kiibohd/kll.git - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - ) + # Clone kll git repo + execute_process ( COMMAND ${GIT_EXECUTABLE} clone https://github.com/kiibohd/kll.git + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + ) elseif ( REFRESH_KLL ) # Otherwise attempt to update the repo - message ( STATUS "Checking for latest kll version:" ) + message ( STATUS "Checking for latest kll version:" ) - # Clone kll git repo - execute_process ( COMMAND ${GIT_EXECUTABLE} pull --rebase - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/kll - ) + # Clone kll git repo + execute_process ( COMMAND ${GIT_EXECUTABLE} pull --rebase + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/kll + ) endif () # kll/kll.py exists @@ -48,8 +48,8 @@ endif () # kll/kll.py exists #| Add each of the detected capabilities.kll foreach ( filename ${ScanModule_KLL} ${MacroModule_KLL} ${OutputModule_KLL} ${DebugModule_KLL} ) - set ( BaseMap_Args ${BaseMap_Args} ${filename} ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) + set ( BaseMap_Args ${BaseMap_Args} ${filename} ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) endforeach () #| If set BaseMap cannot be found, use default map @@ -57,65 +57,71 @@ 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 - if ( NOT EXISTS ${pathname}/${MAP}.kll ) - set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll ) - elseif ( EXISTS "${pathname}/${MAP}.kll" ) - set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${MAP}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${MAP}.kll ) - else () - message ( FATAL " Could not find '${MAP}.kll' BaseMap in Scan module directory" ) - endif () + # Only check the Scan Module for BaseMap .kll files, default to defaultMap.kll + if ( NOT EXISTS ${pathname}/${MAP}.kll ) + set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll ) + elseif ( EXISTS "${pathname}/${MAP}.kll" ) + set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${MAP}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${MAP}.kll ) + else () + message ( FATAL " Could not find '${MAP}.kll' BaseMap in Scan module directory" ) + endif () endforeach () #| Configure DefaultMap if specified if ( NOT "${DefaultMap}" STREQUAL "" ) - set ( DefaultMap_Args -d ) + set ( DefaultMap_Args -d ) - string ( REPLACE " " ";" MAP_LIST ${DefaultMap} ) # Change spaces to semicolons - foreach ( MAP ${MAP_LIST} ) - # Check if kll file is in build directory, otherwise default to layout directory - if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP}.kll" ) - set ( DefaultMap_Args ${DefaultMap_Args} ${MAP}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP}.kll ) - elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll" ) - set ( DefaultMap_Args ${DefaultMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) - else () - message ( FATAL " Could not find '${MAP}.kll' DefaultMap" ) - endif () - endforeach () + string ( REPLACE " " ";" MAP_LIST ${DefaultMap} ) # Change spaces to semicolons + foreach ( MAP ${MAP_LIST} ) + # Check if kll file is in build directory, otherwise default to layout directory + if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP}.kll" ) + set ( DefaultMap_Args ${DefaultMap_Args} ${MAP}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP}.kll ) + elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll" ) + set ( DefaultMap_Args ${DefaultMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll ) + elseif ( EXISTS "${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll" ) + set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll ) + else () + message ( FATAL " Could not find '${MAP}.kll' DefaultMap" ) + endif () + endforeach () endif () #| Configure PartialMaps if specified if ( NOT "${PartialMaps}" STREQUAL "" ) - # For each partial layer - foreach ( MAP ${PartialMaps} ) - set ( PartialMap_Args ${PartialMap_Args} -p ) + # For each partial layer + foreach ( MAP ${PartialMaps} ) + set ( PartialMap_Args ${PartialMap_Args} -p ) - # Combine each layer - string ( REPLACE " " ";" MAP_LIST ${MAP} ) # Change spaces to semicolons - foreach ( MAP_PART ${MAP_LIST} ) - # Check if kll file is in build directory, otherwise default to layout directory - if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP_PART}.kll" ) - set ( PartialMap_Args ${PartialMap_Args} ${MAP_PART}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP_PART}.kll ) - elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll" ) - set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) - else () - message ( FATAL " Could not find '${MAP_PART}.kll' PartialMap" ) - endif () - endforeach () - endforeach () + # Combine each layer + string ( REPLACE " " ";" MAP_LIST ${MAP} ) # Change spaces to semicolons + foreach ( MAP_PART ${MAP_LIST} ) + # Check if kll file is in build directory, otherwise default to layout directory + if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP_PART}.kll" ) + set ( PartialMap_Args ${PartialMap_Args} ${MAP_PART}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP_PART}.kll ) + elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll" ) + set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll ) + elseif ( EXISTS "${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll" ) + set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll ) + else () + message ( FATAL " Could not find '${MAP_PART}.kll' PartialMap" ) + endif () + endforeach () + endforeach () endif () #| Print list of layout sources used message ( STATUS "Detected Layout Files:" ) foreach ( filename ${KLL_DEPENDS} ) - message ( "${filename}" ) + message ( "${filename}" ) endforeach () @@ -133,15 +139,15 @@ set ( kll_output --outputs ${kll_outputname} ) #| KLL Cmd set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} ) add_custom_command ( OUTPUT ${kll_outputname} - COMMAND ${kll_cmd} - DEPENDS ${KLL_DEPENDS} - COMMENT "Generating KLL Layout" + COMMAND ${kll_cmd} + DEPENDS ${KLL_DEPENDS} + COMMENT "Generating KLL Layout" ) #| KLL Regen Convenience Target add_custom_target ( kll_regen - COMMAND ${kll_cmd} - COMMENT "Re-generating KLL Layout" + COMMAND ${kll_cmd} + COMMENT "Re-generating KLL Layout" ) #| Append generated file to required sources so it becomes a dependency in the main build