diff --git a/demos/host/src/keyboard_app.c b/demos/host/src/keyboard_app.c index e6096d51..169f1bc6 100644 --- a/demos/host/src/keyboard_app.c +++ b/demos/host/src/keyboard_app.c @@ -58,7 +58,7 @@ static osal_queue_handle_t q_kbd_report_hdl; static tusb_keyboard_report_t usb_keyboard_report TUSB_CFG_ATTR_USBRAM; // only convert a-z (case insensitive) + 0-9 -static inline uint8_t keycode_to_ascii(uint8_t keycode) ATTR_CONST ATTR_ALWAYS_INLINE; +static inline uint8_t keycode_to_ascii(uint8_t modifier, uint8_t keycode) ATTR_CONST ATTR_ALWAYS_INLINE; //--------------------------------------------------------------------+ // tinyusb callback (ISR context) @@ -106,39 +106,40 @@ void keyboard_app_init(void) OSAL_TASK_FUNCTION( keyboard_app_task ) (void* p_task_para) { tusb_error_t error; + static tusb_keyboard_report_t prev_kbd_report = { 0 }; // previous report to check key released tusb_keyboard_report_t kbd_report; OSAL_TASK_LOOP_BEGIN osal_queue_receive(q_kbd_report_hdl, &kbd_report, OSAL_TIMEOUT_WAIT_FOREVER, &error); - bool has_key = false; + //------------- example code ignore modifier key -------------// for(uint8_t i=0; i<6; i++) { - if ( kbd_report.keycode[i] != 0 ) + if ( kbd_report.keycode[i] != prev_kbd_report.keycode[i] ) { - printf("%c", keycode_to_ascii(kbd_report.keycode[i])); - has_key = true; + if ( 0 != kbd_report.keycode[i]) // key pressed + { + printf("%c", keycode_to_ascii(kbd_report.modifier, kbd_report.keycode[i]) ); + }else + { + // key released + } } + prev_kbd_report.keycode[i] = kbd_report.keycode[i]; } - if (has_key) - printf("\n"); - - memclr_(&kbd_report, sizeof(tusb_keyboard_report_t) ); - OSAL_TASK_LOOP_END } //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ -static inline uint8_t keycode_to_ascii(uint8_t keycode) +static inline uint8_t keycode_to_ascii(uint8_t modifier, uint8_t keycode) { - return - ( KEYBOARD_KEYCODE_a <= keycode && keycode <= KEYBOARD_KEYCODE_z) ? ( (keycode - KEYBOARD_KEYCODE_a) + 'a' ) : - ( KEYBOARD_KEYCODE_1 <= keycode && keycode < KEYBOARD_KEYCODE_0) ? ( (keycode - KEYBOARD_KEYCODE_1) + '1' ) : - ( KEYBOARD_KEYCODE_0 == keycode) ? '0' : 'x'; + // TODO max of keycode_ascii_tbl + return keycode > 128 ? 0 : + hid_keycode_to_ascii_tbl [modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT) ? 1 : 0] [keycode]; } #endif diff --git a/demos/host/src/main.c b/demos/host/src/main.c index aee0474d..a88573fb 100644 --- a/demos/host/src/main.c +++ b/demos/host/src/main.c @@ -76,6 +76,10 @@ OSAL_TASK_DEF(led_blinking_task_def, "led blinking", led_blinking_task, 128, LED int main(void) { board_init(); + + // print_greeting(); TODO uart output before freeRTOS scheduler start will lead to hardfault + // find a way to fix this as tusb_init can output to uart when an error occurred + tusb_init(); //------------- application task init -------------// @@ -95,6 +99,7 @@ int main(void) #elif TUSB_CFG_OS == TUSB_OS_NONE print_greeting(); + while (1) { tusb_task_runner(); @@ -122,7 +127,7 @@ int main(void) void print_greeting(void) { printf("\r\n\ ---------------------------------------------------------------------\ +--------------------------------------------------------------------\r\n\ - Host Demo (a tinyusb example)\r\n\ - if you find any bugs or get any questions, feel free to file an\r\n\ - issue at https://github.com/hathach/tinyusb\r\n\ diff --git a/tinyusb/class/hid.h b/tinyusb/class/hid.h index 2bd98ac5..632ab2cd 100644 --- a/tinyusb/class/hid.h +++ b/tinyusb/class/hid.h @@ -77,6 +77,7 @@ enum { typedef ATTR_PREPACKED struct ATTR_PACKED { uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */ uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */ + uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */ uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */ uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */ @@ -132,15 +133,101 @@ enum { KEYBOARD_MODIFIER_RIGHTGUI = BIT_(7) }; -enum -{ - KEYBOARD_KEYCODE_a = 0x04, - KEYBOARD_KEYCODE_z = 0x1d, +#define HID_KEYCODE_TABLE(ENTRY) \ + ENTRY( 0x04, 'a', 'A' )\ + ENTRY( 0x05, 'b', 'B' )\ + ENTRY( 0x06, 'c', 'C' )\ + ENTRY( 0x07, 'd', 'D' )\ + ENTRY( 0x08, 'e', 'E' )\ + ENTRY( 0x09, 'f', 'F' )\ + ENTRY( 0x0a, 'g', 'G' )\ + ENTRY( 0x0b, 'h', 'H' )\ + ENTRY( 0x0c, 'i', 'I' )\ + ENTRY( 0x0d, 'j', 'J' )\ + ENTRY( 0x0e, 'k', 'K' )\ + ENTRY( 0x0f, 'l', 'L' )\ + \ + ENTRY( 0x10, 'm', 'M' )\ + ENTRY( 0x11, 'n', 'N' )\ + ENTRY( 0x12, 'o', 'O' )\ + ENTRY( 0x13, 'p', 'P' )\ + ENTRY( 0x14, 'q', 'Q' )\ + ENTRY( 0x15, 'r', 'R' )\ + ENTRY( 0x16, 's', 'S' )\ + ENTRY( 0x17, 't', 'T' )\ + ENTRY( 0x18, 'u', 'U' )\ + ENTRY( 0x19, 'v', 'V' )\ + ENTRY( 0x1a, 'w', 'W' )\ + ENTRY( 0x1b, 'x', 'X' )\ + ENTRY( 0x1c, 'y', 'Y' )\ + ENTRY( 0x1d, 'z', 'Z' )\ + ENTRY( 0x1e, '1', '!' )\ + ENTRY( 0x1f, '2', '@' )\ + \ + ENTRY( 0x20, '3', '#' )\ + ENTRY( 0x21, '4', '$' )\ + ENTRY( 0x22, '5', '%' )\ + ENTRY( 0x23, '6', '^' )\ + ENTRY( 0x24, '7', '&' )\ + ENTRY( 0x25, '8', '*' )\ + ENTRY( 0x26, '9', '(' )\ + ENTRY( 0x27, '0', ')' )\ + ENTRY( 0x28, '\r', '\r' )\ + ENTRY( 0x29, '\e', '\e' )\ + ENTRY( 0x2a, '\b', '\b' )\ + ENTRY( 0x2b, '\t', '\t' )\ + ENTRY( 0x2c, ' ', ' ' )\ + ENTRY( 0x2d, '-', '_' )\ + ENTRY( 0x2e, '=', '+' )\ + ENTRY( 0x2f, '[', '{' )\ + \ + ENTRY( 0x30, ']', '}' )\ + ENTRY( 0x31, '\\', '|' )\ + ENTRY( 0x32, '#', '~' ) /* TODO non-US keyboard */ \ + ENTRY( 0x33, ';', ':' )\ + ENTRY( 0x34, '\'', '\"' )\ + ENTRY( 0x35, 0, 0 )\ + ENTRY( 0x36, ',', '<' )\ + ENTRY( 0x37, '.', '>' )\ + ENTRY( 0x38, '/', '?' )\ + ENTRY( 0x39, 0, 0 ) /* TODO CapsLock, non-locking key implementation*/ \ + \ + ENTRY( 0x54, '/', '/' )\ + ENTRY( 0x55, '*', '*' )\ + ENTRY( 0x56, '-', '-' )\ + ENTRY( 0x57, '+', '+' )\ + ENTRY( 0x58, '\r', '\r' )\ + ENTRY( 0x59, '1', 0 ) /* numpad1 & end */ \ + ENTRY( 0x5a, '2', 0 )\ + ENTRY( 0x5b, '3', 0 )\ + ENTRY( 0x5c, '4', 0 )\ + ENTRY( 0x5d, '5', '5' )\ + ENTRY( 0x5e, '6', 0 )\ + ENTRY( 0x5f, '7', 0 )\ + ENTRY( 0x60, '8', 0 )\ + ENTRY( 0x61, '9', 0 )\ + ENTRY( 0x62, '0', 0 )\ + ENTRY( 0x63, '0', 0 )\ + \ + ENTRY( 0x67, '=', '=' )\ - KEYBOARD_KEYCODE_1 = 0x1e, - KEYBOARD_KEYCODE_0 = 0x27 - // TODO complete keycode table -}; +// TODO HID complete keycode table + +//enum +//{ +// KEYBOARD_KEYCODE_A = 0x04, +// KEYBOARD_KEYCODE_Z = 0x1d, +// +// KEYBOARD_KEYCODE_1 = 0x1e, +// KEYBOARD_KEYCODE_0 = 0x27, +// +// KEYBOARD_KEYCODE_ENTER = 0x28, +// KEYBOARD_KEYCODE_ESCAPE = 0x29, +// KEYBOARD_KEYCODE_BACKSPACE = 0x2a, +// KEYBOARD_KEYCODE_TAB = 0x2b, +// KEYBOARD_KEYCODE_SPACEBAR = 0x2c, +// +//}; /** * \brief Local Country code for HID diff --git a/tinyusb/class/hid_host.c b/tinyusb/class/hid_host.c index 412465b5..3d668340 100644 --- a/tinyusb/class/hid_host.c +++ b/tinyusb/class/hid_host.c @@ -111,6 +111,16 @@ tusb_error_t hidh_interface_get_report(uint8_t dev_addr, uint8_t * const report, //--------------------------------------------------------------------+ #if TUSB_CFG_HOST_HID_KEYBOARD +#define EXPAND_KEYCODE_TO_ASCII(keycode, ascii, shift_modified) \ + [0][keycode] = ascii,\ + [1][keycode] = shift_modified,\ + +// TODO size of table should be a macro for application to check boundary +uint8_t const hid_keycode_to_ascii_tbl[2][128] = +{ + HID_KEYCODE_TABLE(EXPAND_KEYCODE_TO_ASCII) +}; + STATIC_ hidh_interface_info_t keyboard_data[TUSB_CFG_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1 //------------- KEYBOARD PUBLIC API (parameter validation required) -------------// diff --git a/tinyusb/class/hid_host.h b/tinyusb/class/hid_host.h index 82004b18..bacf6658 100644 --- a/tinyusb/class/hid_host.h +++ b/tinyusb/class/hid_host.h @@ -65,6 +65,9 @@ bool tusbh_hid_keyboard_is_supported(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT; tusb_error_t tusbh_hid_keyboard_get_report(uint8_t dev_addr, uint8_t instance_num, uint8_t * const report) ATTR_WARN_UNUSED_RESULT; tusb_interface_status_t tusbh_hid_keyboard_status(uint8_t dev_addr, uint8_t instance_num) ATTR_WARN_UNUSED_RESULT; + +uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if build failed without KEYBOARD enabled + //------------- Application Callback -------------// void tusbh_hid_keyboard_isr(uint8_t dev_addr, uint8_t instance_num, tusb_event_t event) ATTR_WEAK; diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h index cf10a63f..061f08ab 100644 --- a/tinyusb/common/errors.h +++ b/tinyusb/common/errors.h @@ -59,21 +59,21 @@ #define ERROR_STRING(x) #x, #define ERROR_TABLE(ENTRY) \ - ENTRY(TUSB_ERROR_NONE)\ - ENTRY(TUSB_ERROR_INVALID_PARA)\ - ENTRY(TUSB_ERROR_DEVICE_NOT_READY)\ - ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY)\ - ENTRY(TUSB_ERROR_HCD_FAILED)\ - ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND)\ - ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG)\ - ENTRY(TUSB_ERROR_OSAL_TIMEOUT)\ - ENTRY(TUSB_ERROR_OSAL_WAITING) /* only used by OSAL_NONE in the subtask */ \ - ENTRY(TUSB_ERROR_OSAL_TASK_FAILED)\ - ENTRY(TUSB_ERROR_OSAL_TASK_CREATE_FAILED)\ - ENTRY(TUSB_ERROR_OSAL_QUEUE_FAILED)\ - ENTRY(TUSB_ERROR_OSAL_SEMAPHORE_FAILED)\ - ENTRY(TUSB_ERROR_EHCI_NOT_ENOUGH_QTD)\ - ENTRY(TUSB_ERROR_FAILED)\ + ENTRY(TUSB_ERROR_NONE )\ + ENTRY(TUSB_ERROR_INVALID_PARA )\ + ENTRY(TUSB_ERROR_DEVICE_NOT_READY )\ + ENTRY(TUSB_ERROR_INTERFACE_IS_BUSY )\ + ENTRY(TUSB_ERROR_HCD_FAILED )\ + ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND )\ + ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG )\ + ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\ + ENTRY(TUSB_ERROR_OSAL_WAITING ) /* only used by OSAL_NONE in the subtask */ \ + ENTRY(TUSB_ERROR_OSAL_TASK_FAILED )\ + ENTRY(TUSB_ERROR_OSAL_TASK_CREATE_FAILED )\ + ENTRY(TUSB_ERROR_OSAL_QUEUE_FAILED )\ + ENTRY(TUSB_ERROR_OSAL_SEMAPHORE_FAILED )\ + ENTRY(TUSB_ERROR_EHCI_NOT_ENOUGH_QTD )\ + ENTRY(TUSB_ERROR_FAILED )\ /** \enum tusb_error_t