diff options
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r-- | tmk_core/protocol/adb.c | 256 | ||||
-rw-r--r-- | tmk_core/protocol/adb.h | 58 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/i2c_master.c | 3 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/i2c_master.h | 4 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/main_arm_atsam.c | 4 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/md_rgb_matrix.c | 86 | ||||
-rw-r--r-- | tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c | 8 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/main.c | 3 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 95 | ||||
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.h | 11 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 46 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/outputselect.h | 14 | ||||
-rw-r--r-- | tmk_core/protocol/m0110.c | 8 | ||||
-rw-r--r-- | tmk_core/protocol/ps2_mouse.c | 2 | ||||
-rw-r--r-- | tmk_core/protocol/usb_descriptor.c | 12 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/main.c | 7 | ||||
-rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 10 |
17 files changed, 413 insertions, 214 deletions
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index a23c919619..367f1b09fa 100644 --- a/tmk_core/protocol/adb.c +++ b/tmk_core/protocol/adb.c @@ -1,5 +1,5 @@ /* -Copyright 2011 Jun WAKO <wakojun@gmail.com> +Copyright 2011-19 Jun WAKO <wakojun@gmail.com> Copyright 2013 Shay Green <gblargg@gmail.com> This software is licensed with a Modified BSD License. @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. #include <avr/io.h> #include <avr/interrupt.h> #include "adb.h" +#include "print.h" // GCC doesn't inline functions normally #define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) @@ -59,7 +60,6 @@ static inline void place_bit1(void); static inline void send_byte(uint8_t data); static inline uint16_t wait_data_lo(uint16_t us); static inline uint16_t wait_data_hi(uint16_t us); -static inline uint16_t adb_host_dev_recv(uint8_t device); void adb_host_init(void) { ADB_PORT &= ~(1 << ADB_DATA_BIT); @@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); } * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> */ - -// ADB Bit Cells -// -// bit cell time: 70-130us -// low part of bit0: 60-70% of bit cell -// low part of bit1: 30-40% of bit cell -// -// bit cell time 70us 130us -// -------------------------------------------- -// low part of bit0 42-49 78-91 -// high part of bit0 21-28 39-52 -// low part of bit1 21-28 39-52 -// high part of bit1 42-49 78-91 -// -// -// bit0: -// 70us bit cell: -// ____________~~~~~~ -// 42-49 21-28 -// -// 130us bit cell: -// ____________~~~~~~ -// 78-91 39-52 -// -// bit1: -// 70us bit cell: -// ______~~~~~~~~~~~~ -// 21-28 42-49 -// -// 130us bit cell: -// ______~~~~~~~~~~~~ -// 39-52 78-91 -// -// [from Apple IIgs Hardware Reference Second Edition] - -enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 }; - -uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); } +uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } #ifdef ADB_MOUSE_ENABLE -void adb_mouse_init(void) { return; } +__attribute__((weak)) void adb_mouse_init(void) { return; } + +__attribute__((weak)) void adb_mouse_task(void) { return; } -uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } +uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } #endif -static inline uint16_t adb_host_dev_recv(uint8_t device) { - uint16_t data = 0; +// This sends Talk command to read data from register and returns length of the data. +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { + for (int8_t i = 0; i < len; i++) buf[i] = 0; + cli(); attention(); - send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) - place_bit0(); // Stopbit(0) + send_byte((addr << 4) | ADB_CMD_TALK | reg); + place_bit0(); // Stopbit(0) + // TODO: Service Request(Srq): + // Device holds low part of comannd stopbit for 140-260us + // + // Command: + // ......._ ______________________ ___ ............_ ------- + // | | | | | | | + // Command | | | | | Data bytes | | + // ........|___| | 140-260 |__| |_............|___| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // Command without data: + // ......._ __________________________ + // | | + // Command | | + // ........|___| | 140-260 | + // |stop0 | Tlt Stop-to-Start | + // + // Service Request: + // ......._ ______ ___ ............_ ------- + // | 140-260 | | | | | | + // Command | Service Request | | | | Data bytes | | + // ........|___________________| |__| |_............|___| + // |stop0 | |start1| |stop0 | + // ......._ __________ + // | 140-260 | + // Command | Service Request | + // ........|___________________| + // |stop0 | + // This can be happened? + // ......._ ______________________ ___ ............_ ----- + // | | | | | | 140-260 | + // Command | | | | | Data bytes | Service Request | + // ........|___| | 140-260 |__| |_............|_________________| + // |stop0 | Tlt Stop-to-Start |start1| |stop0 | + // + // "Service requests are issued by the devices during a very specific time at the + // end of the reception of the command packet. + // If a device in need of service issues a service request, it must do so within + // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." + // + // "A device sends a Service Request signal by holding the bus low during the low + // portion of the stop bit of any command or data transaction. The device must lengthen + // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." + // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored + xprintf("R"); sei(); - return -30; // something wrong + return 0; } if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) sei(); - return 0; // No data to send + return 0; // No data from device(not error); + } + + // start bit(1) + if (!wait_data_hi(40)) { + xprintf("S"); + sei(); + return 0; + } + if (!wait_data_lo(100)) { + xprintf("s"); + sei(); + return 0; } - uint8_t n = 17; // start bit + 16 data bits + uint8_t n = 0; // bit count do { + // + // |<- bit_cell_max(130) ->| + // | |<- lo ->| + // | | |<-hi->| + // _______ + // | | | + // | 130-lo | lo-hi | + // |________| | + // uint8_t lo = (uint8_t)wait_data_hi(130); - if (!lo) goto error; + if (!lo) goto error; // no more bit or after stop bit uint8_t hi = (uint8_t)wait_data_lo(lo); - if (!hi) goto error; + if (!hi) goto error; // stop bit extedned by Srq? - hi = lo - hi; - lo = 130 - lo; + if (n / 8 >= len) continue; // can't store in buf - data <<= 1; - if (lo < hi) { - data |= 1; - } else if (n == 17) { - sei(); - return -20; + buf[n / 8] <<= 1; + if ((130 - lo) < (lo - hi)) { + buf[n / 8] |= 1; } - } while (--n); - - // Stop bit can't be checked normally since it could have service request lenghtening - // and its high state never goes low. - if (!wait_data_hi(351) || wait_data_lo(91)) { - sei(); - return -21; - } - sei(); - return data; + } while (++n); error: sei(); - return -n; + return n / 8; } -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { +uint16_t adb_host_talk(uint8_t addr, uint8_t reg) { + uint8_t len; + uint8_t buf[8]; + len = adb_host_talk_buf(addr, reg, buf, 8); + if (len != 2) return 0; + return (buf[0] << 8 | buf[1]); +} + +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { cli(); attention(); - send_byte(cmd); - place_bit0(); // Stopbit(0) + send_byte((addr << 4) | ADB_CMD_LISTEN | reg); + place_bit0(); // Stopbit(0) + // TODO: Service Request _delay_us(200); // Tlt/Stop to Start place_bit1(); // Startbit(1) - send_byte(data_h); - send_byte(data_l); + for (int8_t i = 0; i < len; i++) { + send_byte(buf[i]); + // xprintf("%02X ", buf[i]); + } place_bit0(); // Stopbit(0); sei(); } +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { + uint8_t buf[2] = {data_h, data_l}; + adb_host_listen_buf(addr, reg, buf, 2); +} + +void adb_host_flush(uint8_t addr) { + cli(); + attention(); + send_byte((addr << 4) | ADB_CMD_FLUSH); + place_bit0(); // Stopbit(0) + _delay_us(200); // Tlt/Stop to Start + sei(); +} + // send state of LEDs void adb_host_kbd_led(uint8_t led) { - // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) - // send upper byte (not used) - // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: - adb_host_listen(0x2A, 0, led & 0x07); + // Listen Register2 + // upper byte: not used + // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock + adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); } #ifdef ADB_PSW_BIT @@ -327,7 +372,7 @@ Commands bits commands ------------------------------------------------------ - - - - - 0 0 0 0 Send Request(reset all devices) + - - - - 0 0 0 0 Send Reset(reset all devices) A A A A 0 0 0 1 Flush(reset a device) - - - - 0 0 1 0 Reserved - - - - 0 0 1 1 Reserved @@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2) | +----------------------------- Delete +------------------------------- Reserved +Address, Handler ID and bits(Register3) + 1514131211 . . 8 7 . . . . . . 0 + | | | | | | | | | | | | | | | | + | | | | | | | | +-+-+-+-+-+-+-+- Handler ID + | | | | +-+-+-+----------------- Address + | | | +------------------------- 0 + | | +--------------------------- Service request enable(1 = enabled) + | +----------------------------- Exceptional event(alwyas 1 if not used) + +------------------------------- 0 + +ADB Bit Cells + bit cell time: 70-130us + low part of bit0: 60-70% of bit cell + low part of bit1: 30-40% of bit cell + + bit cell time 70us 130us + -------------------------------------------- + low part of bit0 42-49 78-91 + high part of bit0 21-28 39-52 + low part of bit1 21-28 39-52 + high part of bit1 42-49 78-91 + + + bit0: + 70us bit cell: + ____________~~~~~~ + 42-49 21-28 + + 130us bit cell: + ____________~~~~~~ + 78-91 39-52 + + bit1: + 70us bit cell: + ______~~~~~~~~~~~~ + 21-28 42-49 + + 130us bit cell: + ______~~~~~~~~~~~~ + 39-52 78-91 + + [from Apple IIgs Hardware Reference Second Edition] + +Keyboard Handle ID + Apple Standard Keyboard M0116: 0x01 + Apple Extended Keyboard M0115: 0x02 + Apple Extended Keyboard II M3501: 0x02 + Apple Adjustable Keybaord: 0x10 + + http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 + END_OF_ADB */ diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h index 34cbcf7691..fe8becc2d5 100644 --- a/tmk_core/protocol/adb.h +++ b/tmk_core/protocol/adb.h @@ -1,5 +1,5 @@ /* -Copyright 2011 Jun WAKO <wakojun@gmail.com> +Copyright 2011-19 Jun WAKO <wakojun@gmail.com> This software is licensed with a Modified BSD License. All of this is supposed to be Free Software, Open Source, DFSG-free, @@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE. #define ADB_POWER 0x7F #define ADB_CAPS 0x39 +/* ADB commands */ +// Default Address +#define ADB_ADDR_0 0 +#define ADB_ADDR_DONGLE 1 +#define ADB_ADDR_KEYBOARD 2 +#define ADB_ADDR_MOUSE 3 +#define ADB_ADDR_TABLET 4 +#define ADB_ADDR_APPLIANCE 7 +#define ADB_ADDR_8 8 +#define ADB_ADDR_9 9 +#define ADB_ADDR_10 10 +#define ADB_ADDR_11 11 +#define ADB_ADDR_12 12 +#define ADB_ADDR_13 13 +#define ADB_ADDR_14 14 +#define ADB_ADDR_15 15 +// for temporary purpose, do not use for polling +#define ADB_ADDR_TMP 15 +#define ADB_ADDR_MOUSE_POLL 10 +// Command Type +#define ADB_CMD_RESET 0 +#define ADB_CMD_FLUSH 1 +#define ADB_CMD_LISTEN 8 +#define ADB_CMD_TALK 12 +// Register +#define ADB_REG_0 0 +#define ADB_REG_1 1 +#define ADB_REG_2 2 +#define ADB_REG_3 3 + +/* ADB keyboard handler id */ +#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */ +#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */ +#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */ +#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */ +#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */ +#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ +#define ADB_HANDLER_CLASSIC1_MOUSE 0x01 +#define ADB_HANDLER_CLASSIC2_MOUSE 0x02 +#define ADB_HANDLER_EXTENDED_MOUSE 0x04 +#define ADB_HANDLER_TURBO_MOUSE 0x32 + // ADB host void adb_host_init(void); bool adb_host_psw(void); +uint16_t adb_host_talk(uint8_t addr, uint8_t reg); +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void adb_host_flush(uint8_t addr); +void adb_host_kbd_led(uint8_t led); uint16_t adb_host_kbd_recv(void); uint16_t adb_host_mouse_recv(void); -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); -void adb_host_kbd_led(uint8_t led); -void adb_mouse_task(void); -void adb_mouse_init(void); + +// ADB Mouse +void adb_mouse_task(void); +void adb_mouse_init(void); diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c index d3319ab447..dda2f85b00 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ b/tmk_core/protocol/arm_atsam/i2c_master.c @@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers +DmacDescriptor dmac_desc; +DmacDescriptor dmac_desc_wb; + static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer static uint8_t i2c_led_q_s; // Start of circular buffer static uint8_t i2c_led_q_e; // End of circular buffer diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h index 44dbdfbffa..68773f213f 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ b/tmk_core/protocol/arm_atsam/i2c_master.h @@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # include "issi3733_driver.h" # include "config.h" -__attribute__((__aligned__(16))) DmacDescriptor dmac_desc; -__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; +extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc; +extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; uint8_t I2C3733_Init_Control(void); uint8_t I2C3733_Init_Drivers(void); diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index e10be52fb8..e4e79d3510 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -305,10 +305,6 @@ int main(void) { // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); } #endif // CONSOLE_ENABLE - - // Run housekeeping - housekeeping_task_kb(); - housekeeping_task_user(); } return 1; diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c index 0ea7e38395..609ae047e6 100644 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c +++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c @@ -15,16 +15,17 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "arm_atsam_protocol.h" -#include "led.h" -#include "rgb_matrix.h" -#include <string.h> -#include <math.h> - -#ifdef USE_MASSDROP_CONFIGURATOR +#ifdef RGB_MATRIX_ENABLE +# include "arm_atsam_protocol.h" +# include "led.h" +# include "rgb_matrix.h" +# include <string.h> +# include <math.h> + +# ifdef USE_MASSDROP_CONFIGURATOR __attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}}; static void md_rgb_matrix_config_override(int i); -#endif // USE_MASSDROP_CONFIGURATOR +# endif // USE_MASSDROP_CONFIGURATOR void SERCOM1_0_Handler(void) { if (SERCOM1->I2CM.INTFLAG.bit.ERROR) { @@ -58,17 +59,17 @@ RGB led_buffer[ISSI3733_LED_COUNT]; uint8_t gcr_desired; uint8_t gcr_actual; uint8_t gcr_actual_last; -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR uint8_t gcr_breathe; float breathe_mult; float pomod; -#endif +# endif -#define ACT_GCR_NONE 0 -#define ACT_GCR_INC 1 -#define ACT_GCR_DEC 2 +# define ACT_GCR_NONE 0 +# define ACT_GCR_INC 1 +# define ACT_GCR_DEC 2 -#define LED_GCR_STEP_AUTO 2 +# define LED_GCR_STEP_AUTO 2 static uint8_t gcr_min_counter; static uint8_t v_5v_cat_hit; @@ -78,11 +79,11 @@ void gcr_compute(void) { uint8_t action = ACT_GCR_NONE; uint8_t gcr_use = gcr_desired; -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR if (led_animation_breathing) { gcr_use = gcr_breathe; } -#endif +# endif // If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over if (v_5v < V5_CAT) { @@ -150,7 +151,7 @@ void gcr_compute(void) { gcr_actual -= LED_GCR_STEP_AUTO; gcr_min_counter = 0; -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR // If breathe mode is active, the top end can fluctuate if the host can not supply enough current // So set the breathe GCR to where it becomes stable if (led_animation_breathing == 1) { @@ -159,7 +160,7 @@ void gcr_compute(void) { // and the same would happen maybe one or two more times. Therefore I'm favoring // powering through one full breathe and letting gcr settle completely } -#endif +# endif } } } @@ -196,25 +197,25 @@ void md_rgb_matrix_prepare(void) { } } -void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) { +static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) { if (i < ISSI3733_LED_COUNT) { -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR md_rgb_matrix_config_override(i); -#else +# else led_buffer[i].r = r; led_buffer[i].g = g; led_buffer[i].b = b; -#endif +# endif } } -void led_set_all(uint8_t r, uint8_t g, uint8_t b) { +static void led_set_all(uint8_t r, uint8_t g, uint8_t b) { for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { led_set_one(i, r, g, b); } } -void init(void) { +static void init(void) { DBGC(DC_LED_MATRIX_INIT_BEGIN); issi3733_prepare_arrays(); @@ -227,16 +228,16 @@ void init(void) { DBGC(DC_LED_MATRIX_INIT_COMPLETE); } -void flush(void) { -#ifdef USE_MASSDROP_CONFIGURATOR +static void flush(void) { +# ifdef USE_MASSDROP_CONFIGURATOR if (!led_enabled) { return; } // Prevent calculations and I2C traffic if LED drivers are not enabled -#else +# else if (!sr_exp_data.bit.SDB_N) { return; } // Prevent calculations and I2C traffic if LED drivers are not enabled -#endif +# endif // Wait for previous transfer to complete while (i2c_led_q_running) { @@ -249,7 +250,7 @@ void flush(void) { *led_map[i].rgb.b = led_buffer[i].b; } -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR breathe_mult = 1; if (led_animation_breathing) { @@ -275,7 +276,7 @@ void flush(void) { pomod = (uint32_t)pomod % 10000; pomod /= 100.0f; -#endif // USE_MASSDROP_CONFIGURATOR +# endif // USE_MASSDROP_CONFIGURATOR uint8_t drvid; @@ -295,21 +296,21 @@ void md_rgb_matrix_indicators(void) { if (kbled && rgb_matrix_config.enable) { for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) { if ( -#if USB_LED_NUM_LOCK_SCANCODE != 255 +# if USB_LED_NUM_LOCK_SCANCODE != 255 (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) || -#endif // NUM LOCK -#if USB_LED_CAPS_LOCK_SCANCODE != 255 +# endif // NUM LOCK +# if USB_LED_CAPS_LOCK_SCANCODE != 255 (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) || -#endif // CAPS LOCK -#if USB_LED_SCROLL_LOCK_SCANCODE != 255 +# endif // CAPS LOCK +# if USB_LED_SCROLL_LOCK_SCANCODE != 255 (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) || -#endif // SCROLL LOCK -#if USB_LED_COMPOSE_SCANCODE != 255 +# endif // SCROLL LOCK +# if USB_LED_COMPOSE_SCANCODE != 255 (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) || -#endif // COMPOSE -#if USB_LED_KANA_SCANCODE != 255 +# endif // COMPOSE +# if USB_LED_KANA_SCANCODE != 255 (led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) || -#endif // KANA +# endif // KANA (0)) { if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) { led_buffer[i].r = 255 - led_buffer[i].r; @@ -327,7 +328,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .se = Legacy Lighting Support = ==============================================================================*/ -#ifdef USE_MASSDROP_CONFIGURATOR +# ifdef USE_MASSDROP_CONFIGURATOR // Ported from Massdrop QMK GitHub Repo // TODO?: wire these up to keymap.c @@ -469,4 +470,5 @@ static void md_rgb_matrix_config_override(int i) { led_buffer[i].b = (uint8_t)bo; } -#endif // USE_MASSDROP_CONFIGURATOR +# endif // USE_MASSDROP_CONFIGURATOR +#endif // RGB_MATRIX_ENABLE
\ No newline at end of file diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c index b43008cc5b..92b40b5b85 100644 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c +++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c @@ -15,9 +15,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifdef USE_MASSDROP_CONFIGURATOR +#ifdef RGB_MATRIX_ENABLE +# ifdef USE_MASSDROP_CONFIGURATOR -# include "md_rgb_matrix.h" +# include "md_rgb_matrix.h" // Teal <-> Salmon led_setup_t leds_teal_salmon[] = { @@ -96,4 +97,5 @@ void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_ye const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]); -#endif +# endif // USE_MASSDROP_CONFIGURATOR +#endif // RGB_MATRIX_ENABLE
\ No newline at end of file diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index e07c181fc8..63e4c99d21 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -163,6 +163,7 @@ int main(void) { keyboard_setup(); /* Init USB */ + usb_event_queue_init(); init_usb_driver(&USB_DRIVER); #ifdef MIDI_ENABLE @@ -221,6 +222,8 @@ int main(void) { /* Main loop */ while (true) { + usb_event_queue_task(); + #if !defined(NO_USB_STARTUP_CHECK) if (USB_DRIVER.state == USB_SUSPENDED) { print("[s]"); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index ad489fb916..8adecfa719 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -27,6 +27,7 @@ #include <ch.h> #include <hal.h> +#include <string.h> #include "usb_main.h" @@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = { * --------------------------------------------------------- */ +#define USB_EVENT_QUEUE_SIZE 16 +usbevent_t event_queue[USB_EVENT_QUEUE_SIZE]; +uint8_t event_queue_head; +uint8_t event_queue_tail; + +void usb_event_queue_init(void) { + // Initialise the event queue + memset(&event_queue, 0, sizeof(event_queue)); + event_queue_head = 0; + event_queue_tail = 0; +} + +static inline bool usb_event_queue_enqueue(usbevent_t event) { + uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE; + if (next == event_queue_tail) { + return false; + } + event_queue[event_queue_head] = event; + event_queue_head = next; + return true; +} + +static inline bool usb_event_queue_dequeue(usbevent_t *event) { + if (event_queue_head == event_queue_tail) { + return false; + } + *event = event_queue[event_queue_tail]; + event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE; + return true; +} + +static inline void usb_event_suspend_handler(void) { +#ifdef SLEEP_LED_ENABLE + sleep_led_enable(); +#endif /* SLEEP_LED_ENABLE */ +} + +static inline void usb_event_wakeup_handler(void) { + suspend_wakeup_init(); +#ifdef SLEEP_LED_ENABLE + sleep_led_disable(); + // NOTE: converters may not accept this + led_set(host_keyboard_leds()); +#endif /* SLEEP_LED_ENABLE */ +} + +void usb_event_queue_task(void) { + usbevent_t event; + while (usb_event_queue_dequeue(&event)) { + switch (event) { + case USB_EVENT_SUSPEND: + usb_event_suspend_handler(); + break; + case USB_EVENT_WAKEUP: + usb_event_wakeup_handler(); + break; + default: + // Nothing to do, we don't handle it. + break; + } + } +} + /* Handles the USB driver global events * TODO: maybe disable some things when connection is lost? */ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { @@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { osalSysUnlockFromISR(); return; case USB_EVENT_SUSPEND: -#ifdef SLEEP_LED_ENABLE - sleep_led_enable(); -#endif /* SLEEP_LED_ENABLE */ + usb_event_queue_enqueue(USB_EVENT_SUSPEND); /* Falls into.*/ case USB_EVENT_UNCONFIGURED: /* Falls into.*/ @@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { qmkusbWakeupHookI(&drivers.array[i].driver); chSysUnlockFromISR(); } - suspend_wakeup_init(); -#ifdef SLEEP_LED_ENABLE - sleep_led_disable(); - // NOTE: converters may not accept this - led_set(host_keyboard_leds()); -#endif /* SLEEP_LED_ENABLE */ + usb_event_queue_enqueue(USB_EVENT_WAKEUP); return; case USB_EVENT_STALLED: @@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) { void restart_usb_driver(USBDriver *usbp) { usbStop(usbp); usbDisconnectBus(usbp); + +#if USB_SUSPEND_WAKEUP_DELAY > 0 + // Some hubs, kvm switches, and monitors do + // weird things, with USB device state bouncing + // around wildly on wakeup, yielding race + // conditions that can corrupt the keyboard state. + // + // Pause for a while to let things settle... + wait_ms(USB_SUSPEND_WAKEUP_DELAY); +#endif + usbStart(usbp, &usbcfg); usbConnectBus(usbp); } @@ -806,7 +874,7 @@ void send_mouse(report_mouse_t *report) { } #else /* MOUSE_ENABLE */ -void send_mouse(report_mouse_t *report) { (void)report; } +void send_mouse(report_mouse_t *report) { (void)report; } #endif /* MOUSE_ENABLE */ /* --------------------------------------------------------- @@ -885,15 +953,8 @@ void console_task(void) { } while (size > 0); } -#else /* CONSOLE_ENABLE */ -int8_t sendchar(uint8_t c) { - (void)c; - return 0; -} #endif /* CONSOLE_ENABLE */ -void _putchar(char character) { sendchar(character); } - #ifdef RAW_ENABLE void raw_hid_send(uint8_t *data, uint8_t length) { // TODO: implement variable size packet diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h index eaa08d8f79..fb33c8cd0f 100644 --- a/tmk_core/protocol/chibios/usb_main.h +++ b/tmk_core/protocol/chibios/usb_main.h @@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp); void restart_usb_driver(USBDriver *usbp); /* --------------- + * USB Event queue + * --------------- + */ + +/* Initialisation of the FIFO */ +void usb_event_queue_init(void); + +/* Task to dequeue and execute any handlers for the USB events on the main thread */ +void usb_event_queue_task(void); + +/* --------------- * Keyboard header * --------------- */ diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 623aa33ff5..f1908b3d07 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() { */ void EVENT_USB_Device_WakeUp() { print("[W]"); +#if defined(NO_USB_STARTUP_CHECK) suspend_wakeup_init(); +#endif #ifdef SLEEP_LED_ENABLE sleep_led_disable(); @@ -669,9 +671,7 @@ static void send_keyboard(report_keyboard_t *report) { uint8_t timeout = 255; #ifdef BLUETOOTH_ENABLE - uint8_t where = where_to_send(); - - if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + if (where_to_send() == OUTPUT_BLUETOOTH) { # ifdef MODULE_ADAFRUIT_BLE adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); # elif MODULE_RN42 @@ -684,9 +684,6 @@ static void send_keyboard(report_keyboard_t *report) { serial_send(report->keys[i]); } # endif - } - - if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { return; } #endif @@ -727,9 +724,7 @@ static void send_mouse(report_mouse_t *report) { uint8_t timeout = 255; # ifdef BLUETOOTH_ENABLE - uint8_t where = where_to_send(); - - if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + if (where_to_send() == OUTPUT_BLUETOOTH) { # ifdef MODULE_ADAFRUIT_BLE // FIXME: mouse buttons adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons); @@ -744,9 +739,6 @@ static void send_mouse(report_mouse_t *report) { serial_send(report->h); // should try sending the wheel h here serial_send(0x00); # endif - } - - if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { return; } # endif @@ -805,9 +797,7 @@ static void send_system(uint16_t data) { static void send_consumer(uint16_t data) { #ifdef EXTRAKEY_ENABLE # ifdef BLUETOOTH_ENABLE - uint8_t where = where_to_send(); - - if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + if (where_to_send() == OUTPUT_BLUETOOTH) { # ifdef MODULE_ADAFRUIT_BLE adafruit_ble_send_consumer_key(data); # elif MODULE_RN42 @@ -821,9 +811,6 @@ static void send_consumer(uint16_t data) { serial_send(bitmap & 0xFF); serial_send((bitmap >> 8) & 0xFF); # endif - } - - if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { return; } # endif @@ -1023,7 +1010,6 @@ static void setup_usb(void) { // for Console_Task USB_Device_EnableSOFEvents(); - print_set_sendchar(sendchar); } /** \brief Main @@ -1073,12 +1059,26 @@ int main(void) { print("Keyboard start.\n"); while (1) { #if !defined(NO_USB_STARTUP_CHECK) - while (USB_DeviceState == DEVICE_STATE_Suspended) { + if (USB_DeviceState == DEVICE_STATE_Suspended) { print("[s]"); - suspend_power_down(); - if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { - USB_Device_SendRemoteWakeup(); + while (USB_DeviceState == DEVICE_STATE_Suspended) { + suspend_power_down(); + if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { + USB_Device_SendRemoteWakeup(); + clear_keyboard(); + +# if USB_SUSPEND_WAKEUP_DELAY > 0 + // Some hubs, kvm switches, and monitors do + // weird things, with USB device state bouncing + // around wildly on wakeup, yielding race + // conditions that can corrupt the keyboard state. + // + // Pause for a while to let things settle... + wait_ms(USB_SUSPEND_WAKEUP_DELAY); +# endif + } } + suspend_wakeup_init(); } #endif diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h index 7f7ed00b95..c4548e1122 100644 --- a/tmk_core/protocol/lufa/outputselect.h +++ b/tmk_core/protocol/lufa/outputselect.h @@ -21,21 +21,11 @@ enum outputs { OUTPUT_NONE, OUTPUT_USB, - OUTPUT_BLUETOOTH, - - // backward compatibility - OUTPUT_USB_AND_BT + OUTPUT_BLUETOOTH }; -/** - * backward compatibility for BLUETOOTH_ENABLE, send to BT and USB by default - */ #ifndef OUTPUT_DEFAULT -# ifdef BLUETOOTH_ENABLE -# define OUTPUT_DEFAULT OUTPUT_USB_AND_BT -# else -# define OUTPUT_DEFAULT OUTPUT_AUTO -# endif +# define OUTPUT_DEFAULT OUTPUT_AUTO #endif void set_output(uint8_t output); diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c index b02a6933d2..64f2fa50ab 100644 --- a/tmk_core/protocol/m0110.c +++ b/tmk_core/protocol/m0110.c @@ -95,11 +95,11 @@ void m0110_init(void) { uint8_t data; m0110_send(M0110_MODEL); data = m0110_recv(); - print("m0110_init model: "); phex(data); print("\n"); + print("m0110_init model: "); print_hex8(data); print("\n"); m0110_send(M0110_TEST); data = m0110_recv(); - print("m0110_init test: "); phex(data); print("\n"); + print("m0110_init test: "); print_hex8(data); print("\n"); */ } @@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) { return 1; ERROR: print("m0110_send err: "); - phex(m0110_error); + print_hex8(m0110_error); print("\n"); _delay_ms(500); idle(); @@ -146,7 +146,7 @@ uint8_t m0110_recv(void) { return data; ERROR: print("m0110_recv err: "); - phex(m0110_error); + print_hex8(m0110_error); print("\n"); _delay_ms(500); idle(); diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c index 8df465026b..5415453a05 100644 --- a/tmk_core/protocol/ps2_mouse.c +++ b/tmk_core/protocol/ps2_mouse.c @@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) { static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) { if (!debug_mouse) return; print("ps2_mouse: ["); - phex(mouse_report->buttons); + print_hex8(mouse_report->buttons); print("|"); print_hex8((uint8_t)mouse_report->x); print(" "); diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 7ea4b2e37c..ba7760f283 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -116,19 +116,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { # endif HID_RI_USAGE(8, 0x01), // Pointer HID_RI_COLLECTION(8, 0x00), // Physical - // Buttons (5 bits) + // Buttons (8 bits) HID_RI_USAGE_PAGE(8, 0x09), // Button HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 - HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 + HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8 HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), - HID_RI_REPORT_COUNT(8, 0x05), + HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), - // Button padding (3 bits) - HID_RI_REPORT_COUNT(8, 0x01), - HID_RI_REPORT_SIZE(8, 0x03), - HID_RI_INPUT(8, HID_IOF_CONSTANT), // X/Y position (2 bytes) HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop @@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { .Type = DTYPE_Device }, .USBSpecification = VERSION_BCD(1, 1, 0), - + #if VIRTSER_ENABLE .Class = USB_CSCP_IADDeviceClass, .SubClass = USB_CSCP_IADDeviceSubclass, diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c index af64f4e561..4095979e93 100644 --- a/tmk_core/protocol/vusb/main.c +++ b/tmk_core/protocol/vusb/main.c @@ -95,12 +95,7 @@ static void vusb_wakeup(void) { * * FIXME: Needs doc */ -static void setup_usb(void) { - initForUsbConnectivity(); - - // for Console_Task - print_set_sendchar(sendchar); -} +static void setup_usb(void) { initForUsbConnectivity(); } /** \brief Main * diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index a422903ccf..9362fbde78 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -444,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = { 0x85, REPORT_ID_MOUSE, // Report ID 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) - // Buttons (5 bits) + // Buttons (8 bits) 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) - 0x95, 0x05, // Report Count (5) + 0x95, 0x08, // Report Count (8) 0x75, 0x01, // Report Size (1) 0x81, 0x02, // Input (Data, Variable, Absolute) - // Button padding (3 bits) - 0x95, 0x01, // Report Count (1) - 0x75, 0x03, // Report Size (3) - 0x81, 0x03, // Input (Constant) // X/Y position (2 bytes) 0x05, 0x01, // Usage Page (Generic Desktop) |