fix bug (wrong logic) with osal_task_delay in non OS configure
complete keyboard app with key state & event TODO handle & check for non-printable(control) keycode add unit test for osal_task_delay for non OS
This commit is contained in:
		| @@ -45,20 +45,30 @@ | ||||
| //--------------------------------------------------------------------+ | ||||
| // MACRO CONSTANT TYPEDEF | ||||
| //--------------------------------------------------------------------+ | ||||
| #define QUEUE_KEYBOARD_REPORT_DEPTH   5 | ||||
| #define QUEUE_KEYBOARD_REPORT_DEPTH   4 | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // INTERNAL OBJECT & FUNCTION DECLARATION | ||||
| //--------------------------------------------------------------------+ | ||||
| typedef enum { | ||||
|   KEY_STATE_PRESSED = 1, | ||||
|   KEY_STATE_HOLDING, | ||||
|   KEY_STATE_RELEASED | ||||
| }key_state_t; | ||||
|  | ||||
| typedef struct { | ||||
|   tusb_keyboard_report_t report; | ||||
|   key_state_t state[6]; | ||||
| } kbd_data_t; | ||||
|  | ||||
| OSAL_TASK_DEF(keyboard_task_def, "keyboard app", keyboard_app_task, 128, KEYBOARD_APP_TASK_PRIO); | ||||
| OSAL_QUEUE_DEF(queue_kbd_def, QUEUE_KEYBOARD_REPORT_DEPTH, kbd_data_t); | ||||
|  | ||||
| OSAL_QUEUE_DEF(queue_kbd_report, QUEUE_KEYBOARD_REPORT_DEPTH, tusb_keyboard_report_t); | ||||
| static osal_queue_handle_t q_kbd_report_hdl; | ||||
|  | ||||
| static osal_queue_handle_t queue_kbd_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 modifier, uint8_t keycode) ATTR_CONST ATTR_ALWAYS_INLINE; | ||||
| static inline void process_kbd_report_isr(tusb_keyboard_report_t const * report); | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // tinyusb callback (ISR context) | ||||
| @@ -68,7 +78,7 @@ void tusbh_hid_keyboard_isr(uint8_t dev_addr, uint8_t instance_num, tusb_event_t | ||||
|   switch(event) | ||||
|   { | ||||
|     case TUSB_EVENT_INTERFACE_OPEN: // application set-up | ||||
|       osal_queue_flush(q_kbd_report_hdl); | ||||
|       osal_queue_flush(queue_kbd_hdl); | ||||
|       tusbh_hid_keyboard_get_report(dev_addr, instance_num, (uint8_t*) &usb_keyboard_report); // first report | ||||
|     break; | ||||
|  | ||||
| @@ -77,7 +87,7 @@ void tusbh_hid_keyboard_isr(uint8_t dev_addr, uint8_t instance_num, tusb_event_t | ||||
|     break; | ||||
|  | ||||
|     case TUSB_EVENT_XFER_COMPLETE: | ||||
|       osal_queue_send(q_kbd_report_hdl, &usb_keyboard_report); | ||||
|       process_kbd_report_isr(&usb_keyboard_report); | ||||
|       tusbh_hid_keyboard_get_report(dev_addr, instance_num, (uint8_t*) &usb_keyboard_report); | ||||
|     break; | ||||
|  | ||||
| @@ -98,35 +108,27 @@ void keyboard_app_init(void) | ||||
|   memclr_(&usb_keyboard_report, sizeof(tusb_keyboard_report_t)); | ||||
|  | ||||
|   ASSERT( TUSB_ERROR_NONE == osal_task_create(&keyboard_task_def), (void) 0 ); | ||||
|   q_kbd_report_hdl = osal_queue_create(&queue_kbd_report); | ||||
|   ASSERT_PTR( q_kbd_report_hdl, (void) 0 ); | ||||
|   queue_kbd_hdl = osal_queue_create(&queue_kbd_def); | ||||
|   ASSERT_PTR( queue_kbd_hdl, (void) 0 ); | ||||
| } | ||||
|  | ||||
| //------------- main task -------------// | ||||
| 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; | ||||
|   kbd_data_t kbd_data; | ||||
|  | ||||
|   OSAL_TASK_LOOP_BEGIN | ||||
|  | ||||
|   osal_queue_receive(q_kbd_report_hdl, &kbd_report, OSAL_TIMEOUT_WAIT_FOREVER, &error); | ||||
|   osal_queue_receive(queue_kbd_hdl, &kbd_data, OSAL_TIMEOUT_WAIT_FOREVER, &error); | ||||
|  | ||||
|   //------------- example code ignore modifier key -------------// | ||||
|   for(uint8_t i=0; i<6; i++) | ||||
|   //------------- example code ignore control (non-printable) key affects -------------// | ||||
|   for(uint8_t i = 0; i < 6; i++) | ||||
|   { | ||||
|     if ( kbd_report.keycode[i] != prev_kbd_report.keycode[i] ) | ||||
|     if ( kbd_data.state[i] == KEY_STATE_PRESSED ) | ||||
|     { | ||||
|       if ( 0 != kbd_report.keycode[i]) // key pressed | ||||
|       { | ||||
|         printf("%c", keycode_to_ascii(kbd_report.modifier, kbd_report.keycode[i]) ); | ||||
|       }else | ||||
|       { | ||||
|         // key released | ||||
|       } | ||||
|       printf("%c", keycode_to_ascii(kbd_data.report.modifier, kbd_data.report.keycode[i]) ); | ||||
|     } | ||||
|     prev_kbd_report.keycode[i] = kbd_report.keycode[i]; | ||||
|   } | ||||
|  | ||||
|   OSAL_TASK_LOOP_END | ||||
| @@ -135,6 +137,46 @@ OSAL_TASK_FUNCTION( keyboard_app_task ) (void* p_task_para) | ||||
| //--------------------------------------------------------------------+ | ||||
| // HELPER | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // look up new key in previous keys | ||||
| static inline bool is_key_in_report_isr(tusb_keyboard_report_t const *p_report, uint8_t keycode, uint8_t modifier) | ||||
| { | ||||
|   for(uint8_t i=0; i<6; i++) | ||||
|   { | ||||
|     if (p_report->keycode[i] == keycode) | ||||
|     { | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| static inline void process_kbd_report_isr(tusb_keyboard_report_t const *p_new_report) | ||||
| { | ||||
|   static tusb_keyboard_report_t prev_report = { 0 }; // previous report to check key released | ||||
|   kbd_data_t kbd_data = { 0 }; | ||||
|  | ||||
|   for(uint8_t i=0; i<6; i++) | ||||
|   { | ||||
|     if ( p_new_report->keycode[i] ) | ||||
|     { | ||||
|       if ( is_key_in_report_isr(&prev_report, p_new_report->keycode[i], p_new_report->modifier) ) | ||||
|       { | ||||
|         kbd_data.state[i] =  KEY_STATE_HOLDING; // previously existed means holding | ||||
|       }else | ||||
|       { | ||||
|         kbd_data.state[i] = KEY_STATE_PRESSED;  // previously non-existed means released | ||||
|       } | ||||
|     } | ||||
|     // TODO example skips key released | ||||
|   } | ||||
|  | ||||
|   prev_report = *p_new_report; | ||||
|   kbd_data.report = *p_new_report; | ||||
|   osal_queue_send(queue_kbd_hdl, &kbd_data); | ||||
| } | ||||
|  | ||||
| static inline uint8_t keycode_to_ascii(uint8_t modifier, uint8_t keycode) | ||||
| { | ||||
|   // TODO max of keycode_ascii_tbl | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 hathach
					hathach