From f5641c807e28cc8a4c6a7a1baac552dd84a4d1f4 Mon Sep 17 00:00:00 2001 From: Stefan Dorn Date: Sun, 12 Jun 2016 03:08:50 +0100 Subject: [PATCH] some cleanup --- src/keyboard/controller.c | 1283 ++++++++++++++++++------------------- src/keyboard/controller.h | 129 ++-- 2 files changed, 673 insertions(+), 739 deletions(-) diff --git a/src/keyboard/controller.c b/src/keyboard/controller.c index ca37930..3de11d3 100644 --- a/src/keyboard/controller.c +++ b/src/keyboard/controller.c @@ -286,83 +286,82 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { #define SET |= #define CLEAR &=~ -#define _teensypin_write(register, operation, pin_letter, pin_number) \ - do { \ - ((register##pin_letter) operation (1<<(pin_number))); \ - _delay_us(1); /* allow pins time to stabilize */ \ - } while(0) -#define teensypin_write(register, operation, pin) \ - _teensypin_write(register, operation, pin) +#define _teensypin_write(register, operation, pin_letter, pin_number) \ + do { \ + ((register##pin_letter)operation(1 << (pin_number))); \ + _delay_us(1); /* allow pins time to stabilize */ \ + } while (0) +#define teensypin_write(register, operation, pin) \ + _teensypin_write(register, operation, pin) -#define _teensypin_read(pin_letter, pin_number) \ - ((PIN##pin_letter) & (1<<(pin_number))) -#define teensypin_read(pin) \ - _teensypin_read(pin) +#define _teensypin_read(pin_letter, pin_number) \ + ((PIN##pin_letter) & (1 << (pin_number))) +#define teensypin_read(pin) _teensypin_read(pin) -#define teensypin_write_all_unused(register, operation) \ - do { \ - teensypin_write(register, operation, UNUSED_0); \ - teensypin_write(register, operation, UNUSED_1); \ - teensypin_write(register, operation, UNUSED_2); \ - teensypin_write(register, operation, UNUSED_3); \ - teensypin_write(register, operation, UNUSED_4); } \ - while(0) +#define teensypin_write_all_unused(register, operation) \ + do { \ + teensypin_write(register, operation, UNUSED_0); \ + teensypin_write(register, operation, UNUSED_1); \ + teensypin_write(register, operation, UNUSED_2); \ + teensypin_write(register, operation, UNUSED_3); \ + teensypin_write(register, operation, UNUSED_4); \ + } while (0) -#define teensypin_write_all_row(register, operation) \ - do { \ - teensypin_write(register, operation, ROW_0); \ - teensypin_write(register, operation, ROW_1); \ - teensypin_write(register, operation, ROW_2); \ - teensypin_write(register, operation, ROW_3); \ - teensypin_write(register, operation, ROW_4); \ - teensypin_write(register, operation, ROW_5); } \ - while(0) +#define teensypin_write_all_row(register, operation) \ + do { \ + teensypin_write(register, operation, ROW_0); \ + teensypin_write(register, operation, ROW_1); \ + teensypin_write(register, operation, ROW_2); \ + teensypin_write(register, operation, ROW_3); \ + teensypin_write(register, operation, ROW_4); \ + teensypin_write(register, operation, ROW_5); \ + } while (0) -#define teensypin_write_all_column(register, operation) \ - do { \ - teensypin_write(register, operation, COLUMN_7); \ - teensypin_write(register, operation, COLUMN_8); \ - teensypin_write(register, operation, COLUMN_9); \ - teensypin_write(register, operation, COLUMN_A); \ - teensypin_write(register, operation, COLUMN_B); \ - teensypin_write(register, operation, COLUMN_C); \ - teensypin_write(register, operation, COLUMN_D); } \ - while(0) +#define teensypin_write_all_column(register, operation) \ + do { \ + teensypin_write(register, operation, COLUMN_7); \ + teensypin_write(register, operation, COLUMN_8); \ + teensypin_write(register, operation, COLUMN_9); \ + teensypin_write(register, operation, COLUMN_A); \ + teensypin_write(register, operation, COLUMN_B); \ + teensypin_write(register, operation, COLUMN_C); \ + teensypin_write(register, operation, COLUMN_D); \ + } while (0) /* * update macros */ -#define update_rows_for_column(matrix, column) \ - do { \ - /* set column low (set as output) */ \ - teensypin_write(DDR, SET, COLUMN_##column); \ - /* read rows 0..5 and update matrix */ \ - matrix[0x0][0x##column] = ! teensypin_read(ROW_0); \ - matrix[0x1][0x##column] = ! teensypin_read(ROW_1); \ - matrix[0x2][0x##column] = ! teensypin_read(ROW_2); \ - matrix[0x3][0x##column] = ! teensypin_read(ROW_3); \ - matrix[0x4][0x##column] = ! teensypin_read(ROW_4); \ - matrix[0x5][0x##column] = ! teensypin_read(ROW_5); \ - /* set column hi-Z (set as input) */ \ - teensypin_write(DDR, CLEAR, COLUMN_##column); \ - } while(0) +#define update_rows_for_column(matrix, column) \ + do { \ + /* set column low (set as output) */ \ + teensypin_write(DDR, SET, COLUMN_##column); \ + /* read rows 0..5 and update matrix */ \ + matrix[0x0][0x##column] = !teensypin_read(ROW_0); \ + matrix[0x1][0x##column] = !teensypin_read(ROW_1); \ + matrix[0x2][0x##column] = !teensypin_read(ROW_2); \ + matrix[0x3][0x##column] = !teensypin_read(ROW_3); \ + matrix[0x4][0x##column] = !teensypin_read(ROW_4); \ + matrix[0x5][0x##column] = !teensypin_read(ROW_5); \ + /* set column hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, COLUMN_##column); \ + } while (0) -#define update_columns_for_row(matrix, row) \ - do { \ - /* set row low (set as output) */ \ - teensypin_write(DDR, SET, ROW_##row); \ - /* read columns 7..D and update matrix */ \ - matrix[0x##row][0x7] = ! teensypin_read(COLUMN_7); \ - matrix[0x##row][0x8] = ! teensypin_read(COLUMN_8); \ - matrix[0x##row][0x9] = ! teensypin_read(COLUMN_9); \ - matrix[0x##row][0xA] = ! teensypin_read(COLUMN_A); \ - matrix[0x##row][0xB] = ! teensypin_read(COLUMN_B); \ - matrix[0x##row][0xC] = ! teensypin_read(COLUMN_C); \ - matrix[0x##row][0xD] = ! teensypin_read(COLUMN_D); \ - /* set row hi-Z (set as input) */ \ - teensypin_write(DDR, CLEAR, ROW_##row); \ - } while(0) +#define update_columns_for_row(matrix, row) \ + do { \ + /* set row low (set as output) */ \ + teensypin_write(DDR, SET, ROW_##row); \ + /* read columns 7..D and update matrix */ \ + matrix[0x##row][0x7] = !teensypin_read(COLUMN_7); \ + matrix[0x##row][0x8] = !teensypin_read(COLUMN_8); \ + matrix[0x##row][0x9] = !teensypin_read(COLUMN_9); \ + matrix[0x##row][0xA] = !teensypin_read(COLUMN_A); \ + matrix[0x##row][0xB] = !teensypin_read(COLUMN_B); \ + matrix[0x##row][0xC] = !teensypin_read(COLUMN_C); \ + matrix[0x##row][0xD] = !teensypin_read(COLUMN_D); \ + /* set row hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, ROW_##row); \ + } while (0) // ---------------------------------------------------------------------------- @@ -370,131 +369,132 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { * - success: 0 */ uint8_t teensy_init(void) { - // CPU speed : should match F_CPU in makefile - #if F_CPU != 16000000 - #error "Expecting different CPU frequency" - #endif - CPU_PRESCALE(CPU_16MHz); + // CPU speed : should match F_CPU in makefile +#if F_CPU != 16000000 +#error "Expecting different CPU frequency" +#endif + CPU_PRESCALE(CPU_16MHz); - // onboard LED - // (tied to GND for hardware convenience) - DDRD &= ~(1<<6); // set D(6) as input - PORTD &= ~(1<<6); // set D(6) internal pull-up disabled + // onboard LED + // (tied to GND for hardware convenience) + DDRD &= ~(1 << 6); // set D(6) as input + PORTD &= ~(1 << 6); // set D(6) internal pull-up disabled - // (tied to Vcc for hardware convenience) - DDRB &= ~(1<<4); // set B(4) as input - PORTB &= ~(1<<4); // set B(4) internal pull-up disabled + // (tied to Vcc for hardware convenience) + DDRB &= ~(1 << 4); // set B(4) as input + PORTB &= ~(1 << 4); // set B(4) internal pull-up disabled - // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") - _kb_led_all_off(); // (just to put the pins in a known state) - TCCR1A = 0b10101001; // set and configure fast PWM - TCCR1B = 0b00001001; // set and configure fast PWM + // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") + TCCR1A = 0b10101001; // set and configure fast PWM + TCCR1B = 0b00001001; // set and configure fast PWM - // I2C (TWI) - twi_init(); // on pins D(1,0) + // I2C (TWI) + twi_init(); // on pins D(1,0) - // unused pins - teensypin_write_all_unused(DDR, CLEAR); // set as input - teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled + // unused pins + teensypin_write_all_unused(DDR, CLEAR); // set as input + teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled - // rows and columns - teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z) - teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) - #if TEENSY__DRIVE_ROWS - teensypin_write_all_row(PORT, CLEAR); // pull-up disabled - teensypin_write_all_column(PORT, SET); // pull-up enabled - #elif TEENSY__DRIVE_COLUMNS - teensypin_write_all_row(PORT, SET); // pull-up enabled - teensypin_write_all_column(PORT, CLEAR); // pull-up disabled - #endif + // rows and columns + teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z) + teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) +#if TEENSY__DRIVE_ROWS + teensypin_write_all_row(PORT, CLEAR); // pull-up disabled + teensypin_write_all_column(PORT, SET); // pull-up enabled +#elif TEENSY__DRIVE_COLUMNS + teensypin_write_all_row(PORT, SET); // pull-up enabled + teensypin_write_all_column(PORT, CLEAR); // pull-up disabled +#endif - return 0; // success + return 0; // success } /* returns * - success: 0 */ #if KB_ROWS != 6 || KB_COLUMNS != 14 - #error "Expecting different keyboard dimensions" +#error "Expecting different keyboard dimensions" #endif uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { - #if TEENSY__DRIVE_ROWS - update_columns_for_row(matrix, 0); - update_columns_for_row(matrix, 1); - update_columns_for_row(matrix, 2); - update_columns_for_row(matrix, 3); - update_columns_for_row(matrix, 4); - update_columns_for_row(matrix, 5); - #elif TEENSY__DRIVE_COLUMNS - update_rows_for_column(matrix, 7); - update_rows_for_column(matrix, 8); - update_rows_for_column(matrix, 9); - update_rows_for_column(matrix, A); - update_rows_for_column(matrix, B); - update_rows_for_column(matrix, C); - update_rows_for_column(matrix, D); - #endif +#if TEENSY__DRIVE_ROWS + update_columns_for_row(matrix, 0); + update_columns_for_row(matrix, 1); + update_columns_for_row(matrix, 2); + update_columns_for_row(matrix, 3); + update_columns_for_row(matrix, 4); + update_columns_for_row(matrix, 5); +#elif TEENSY__DRIVE_COLUMNS + update_rows_for_column(matrix, 7); + update_rows_for_column(matrix, 8); + update_rows_for_column(matrix, 9); + update_rows_for_column(matrix, A); + update_rows_for_column(matrix, B); + update_rows_for_column(matrix, C); + update_rows_for_column(matrix, D); +#endif - return 0; // success + return 0; // success } // ---------------------------------------------------------------------------- void twi_init(void) { - // set the prescaler value to 0 - TWSR &= ~( (1<= NUM_DESC_LIST) { + UECONX = (1 << STALLRQ) | (1 << EPEN); // stall + return; + } + desc_val = pgm_read_word(list); + if (desc_val != wValue) { + list += sizeof(struct descriptor_list_struct); + continue; + } + list += 2; + desc_val = pgm_read_word(list); + if (desc_val != wIndex) { + list += sizeof(struct descriptor_list_struct) - 2; + continue; + } + list += 2; + desc_addr = (const uint8_t *)pgm_read_word(list); + list += 2; + desc_length = pgm_read_byte(list); + break; + } + len = (wLength < 256) ? wLength : 255; + if (len > desc_length) + len = desc_length; + do { + // wait for host ready for IN packet + do { + i = UEINTX; + } while (!(i & ((1 << TXINI) | (1 << RXOUTI)))); + if (i & (1 << RXOUTI)) + return; // abort + // send IN packet + n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE; + for (i = n; i; i--) { + UEDATX = pgm_read_byte(desc_addr++); + } + len -= n; + usb_send_in(); + } while (len || n == ENDPOINT0_SIZE); + return; + } + if (bRequest == SET_ADDRESS) { + usb_send_in(); + usb_wait_in_ready(); + UDADDR = wValue | (1 << ADDEN); + return; + } + if (bRequest == SET_CONFIGURATION && bmRequestType == 0) { + usb_configuration = wValue; + usb_send_in(); + cfg = endpoint_config_table; + for (i = 1; i < 5; i++) { + UENUM = i; + en = pgm_read_byte(cfg++); + UECONX = en; + if (en) { + UECFG0X = pgm_read_byte(cfg++); + UECFG1X = pgm_read_byte(cfg++); + } + } + UERST = 0x1E; + UERST = 0; + return; + } + if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) { + usb_wait_in_ready(); + UEDATX = usb_configuration; + usb_send_in(); + return; + } + + if (bRequest == GET_STATUS) { + usb_wait_in_ready(); + i = 0; +#ifdef SUPPORT_ENDPOINT_HALT + if (bmRequestType == 0x82) { + UENUM = wIndex; + if (UECONX & (1 << STALLRQ)) + i = 1; UENUM = 0; - intbits = UEINTX; - if (intbits & (1<= NUM_DESC_LIST) { - UECONX = (1< desc_length) len = desc_length; - do { - // wait for host ready for IN packet - do { - i = UEINTX; - } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { - usb_send_in(); - UENUM = i; - if (bRequest == SET_FEATURE) { - UECONX = (1<> 8); - keyboard_idle_count = 0; - usb_send_in(); - return; - } - if (bRequest == HID_SET_PROTOCOL) { - keyboard_protocol = wValue; - usb_send_in(); - return; - } - } - } - } - UECONX = (1<= 1 && i <= MAX_ENDPOINT) { + usb_send_in(); + UENUM = i; + if (bRequest == SET_FEATURE) { + UECONX = (1 << STALLRQ) | (1 << EPEN); + } else { + UECONX = (1 << STALLRQC) | (1 << RSTDT) | (1 << EPEN); + UERST = (1 << i); + UERST = 0; + } + return; + } + } +#endif + if (wIndex == KEYBOARD_INTERFACE) { + if (bmRequestType == 0xA1) { + if (bRequest == HID_GET_REPORT) { + usb_wait_in_ready(); + UEDATX = keyboard_modifier_keys; + UEDATX = 0; + for (i = 0; i < 6; i++) { + UEDATX = keyboard_keys[i]; + } + usb_send_in(); + return; + } + if (bRequest == HID_GET_IDLE) { + usb_wait_in_ready(); + UEDATX = keyboard_idle_config; + usb_send_in(); + return; + } + if (bRequest == HID_GET_PROTOCOL) { + usb_wait_in_ready(); + UEDATX = keyboard_protocol; + usb_send_in(); + return; + } + } + if (bmRequestType == 0x21) { + if (bRequest == HID_SET_REPORT) { + usb_wait_receive_out(); + keyboard_leds = UEDATX; + usb_ack_out(); + usb_send_in(); + return; + } + if (bRequest == HID_SET_IDLE) { + keyboard_idle_config = (wValue >> 8); + keyboard_idle_count = 0; + usb_send_in(); + return; + } + if (bRequest == HID_SET_PROTOCOL) { + keyboard_protocol = wValue; + usb_send_in(); + return; + } + } + } + } + UECONX = (1 << STALLRQ) | (1 << EPEN); // stall } -int8_t usb_extra_send(uint8_t report_id, uint16_t data) -{ - uint8_t intr_state, timeout; +int8_t usb_extra_send(uint8_t report_id, uint16_t data) { + uint8_t intr_state, timeout; - if (!usb_configured()) return -1; - intr_state = SREG; - cli(); - UENUM = EXTRA_ENDPOINT; - timeout = UDFNUML + 50; - while (1) { - // are we ready to transmit? - if (UEINTX & (1<>8)&0xFF; + UEDATX = report_id; + UEDATX = data & 0xFF; + UEDATX = (data >> 8) & 0xFF; - UEINTX = 0x3A; - SREG = intr_state; - return 0; + UEINTX = 0x3A; + SREG = intr_state; + return 0; } -int8_t usb_extra_consumer_send() -{ - int result = 0; - // don't resend the same key repeatedly if held, only send it once. - if (consumer_key != last_consumer_key) { - result = usb_extra_send(REPORT_ID_CONSUMER, consumer_key); - if (result == 0) { - last_consumer_key = consumer_key; - } - } - return result; +int8_t usb_extra_consumer_send() { + int result = 0; + // don't resend the same key repeatedly if held, only send it once. + if (consumer_key != last_consumer_key) { + result = usb_extra_send(REPORT_ID_CONSUMER, consumer_key); + if (result == 0) { + last_consumer_key = consumer_key; + } + } + return result; } diff --git a/src/keyboard/controller.h b/src/keyboard/controller.h index 0ba1529..4dbd6ae 100644 --- a/src/keyboard/controller.h +++ b/src/keyboard/controller.h @@ -38,14 +38,13 @@ * #define TEENSY__DRIVE_ROWS 1 * #define MCP23018__DRIVE_ROWS 1 */ -#define TEENSY__DRIVE_ROWS 0 -#define MCP23018__DRIVE_ROWS 0 -#define TEENSY__DRIVE_COLUMNS 1 -#define MCP23018__DRIVE_COLUMNS 1 - -#define KB_ROWS 6 // must match real life -#define KB_COLUMNS 14 // must match real life +#define TEENSY__DRIVE_ROWS 0 +#define MCP23018__DRIVE_ROWS 0 +#define TEENSY__DRIVE_COLUMNS 1 +#define MCP23018__DRIVE_COLUMNS 1 +#define KB_ROWS 6 // must match real life +#define KB_COLUMNS 14 // must match real life // -------------------------------------------------------------------- @@ -66,48 +65,6 @@ uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); // -------------------------------------------------------------------- -#define _kb_led_1_on() (DDRB |= (1<<5)) -#define _kb_led_1_off() (DDRB &= ~(1<<5)) -#define _kb_led_1_set(n) (OCR1A = (uint8_t)(n)) -#define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) - -#define _kb_led_2_on() (DDRB |= (1<<6)) -#define _kb_led_2_off() (DDRB &= ~(1<<6)) -#define _kb_led_2_set(n) (OCR1B = (uint8_t)(n)) -#define _kb_led_2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) - -#define _kb_led_3_on() (DDRB |= (1<<7)) -#define _kb_led_3_off() (DDRB &= ~(1<<7)) -#define _kb_led_3_set(n) (OCR1C = (uint8_t)(n)) -#define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF)) - - -#define _kb_led_all_on() do { \ - _kb_led_1_on(); \ - _kb_led_2_on(); \ - _kb_led_3_on(); \ - } while(0) - -#define _kb_led_all_off() do { \ - _kb_led_1_off(); \ - _kb_led_2_off(); \ - _kb_led_3_off(); \ - } while(0) - -#define _kb_led_all_set(n) do { \ - _kb_led_1_set(n); \ - _kb_led_2_set(n); \ - _kb_led_3_set(n); \ - } while(0) - -#define _kb_led_all_set_percent(n) do { \ - _kb_led_1_set_percent(n); \ - _kb_led_2_set_percent(n); \ - _kb_led_3_set_percent(n); \ - } while(0) - -// -------------------------------------------------------------------- - #define TWI_FREQ 400000 void twi_init (void); @@ -118,8 +75,8 @@ uint8_t twi_read (uint8_t * data); // -------------------------------------------------------------------- -void usb_init(void); // initialize everything -uint8_t usb_configured(void); // is the USB port configured +void usb_init(void); // initialize everything +uint8_t usb_configured(void); // is the USB port configured int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); int8_t usb_keyboard_send(void); @@ -137,52 +94,52 @@ extern uint16_t consumer_key; // Everything below this point is only intended for usb_serial.c -#define EP_TYPE_CONTROL 0x00 -#define EP_TYPE_BULK_IN 0x81 -#define EP_TYPE_BULK_OUT 0x80 -#define EP_TYPE_INTERRUPT_IN 0xC1 -#define EP_TYPE_INTERRUPT_OUT 0xC0 -#define EP_TYPE_ISOCHRONOUS_IN 0x41 -#define EP_TYPE_ISOCHRONOUS_OUT 0x40 +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 -#define EP_SINGLE_BUFFER 0x02 -#define EP_DOUBLE_BUFFER 0x06 +#define EP_SINGLE_BUFFER 0x02 +#define EP_DOUBLE_BUFFER 0x06 -#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ - ((s) == 32 ? 0x20 : \ - ((s) == 16 ? 0x10 : \ - 0x00))) +#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ + ((s) == 32 ? 0x20 : \ + ((s) == 16 ? 0x10 : \ + 0x00))) -#define MAX_ENDPOINT 4 +#define MAX_ENDPOINT 4 #define LSB(n) (n & 255) #define MSB(n) ((n >> 8) & 255) -#define HW_CONFIG() (UHWCON = 0x01) -#define PLL_CONFIG() (PLLCSR = 0x12) -#define USB_CONFIG() (USBCON = ((1<