summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-04-26 02:08:22 +0700
committerhathach <[email protected]>2013-04-26 02:08:22 +0700
commit33feba5cbc7a344f1bac67508e5658aa615e59bf (patch)
treea3833f483fa7d49af0b23799b9c1731a3733b9d0
parentc0104b996e9ea0c5c25861ccf24e0255431a8f9c (diff)
add hid_keycode_to_ascii_tbl for hid class
improve keyboard_app, should display all displayable characters improve the de-bouncing keyboard (still got some issues)
-rw-r--r--demos/host/src/keyboard_app.c31
-rw-r--r--demos/host/src/main.c7
-rw-r--r--tinyusb/class/hid.h103
-rw-r--r--tinyusb/class/hid_host.c10
-rw-r--r--tinyusb/class/hid_host.h3
-rw-r--r--tinyusb/common/errors.h30
6 files changed, 145 insertions, 39 deletions
diff --git a/demos/host/src/keyboard_app.c b/demos/host/src/keyboard_app.c
index e6096d514..169f1bc6d 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 aee0474d7..a88573fb3 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 2bd98ac5d..632ab2cd4 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 412465b5b..3d6683404 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 82004b180..bacf66588 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 cf10a63fa..061f08ab3 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