From 546f2a1165555819bf3ef09fe1afcfbcbb084dd9 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Jul 2018 00:10:22 +0700 Subject: [PATCH] nrf52840 example work with boot keyboard --- examples/device/nrf52840/src/main.c | 35 ++++++++---- hw/bsp/board.h | 1 - hw/bsp/pca10056/board_pca10056.c | 84 +++++++++++++++++++++-------- 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/examples/device/nrf52840/src/main.c b/examples/device/nrf52840/src/main.c index 04d07f0a..cc18cce2 100644 --- a/examples/device/nrf52840/src/main.c +++ b/examples/device/nrf52840/src/main.c @@ -106,10 +106,29 @@ void usb_hid_task(void) { if ( !tud_hid_keyboard_busy() ) { - static bool toggle = false; // send either A or B + // Poll every 10ms + static tu_timeout_t tm = { .start = 0, .interval = 10 }; - tud_hid_keyboard_send_char( toggle ? 'A' : 'B' ); - toggle = !toggle; + if ( !tu_timeout_expired(&tm) ) return; // not enough time + tu_timeout_reset(&tm); + + uint32_t bt = board_buttons(); + + if ( bt ) + { + uint8_t keycode[6] = { 0 }; + + for(uint8_t i=0; i < 6; i++) + { + if ( bt & (1 << i) ) keycode[i] = HID_KEY_A + i; + } + + tud_hid_keyboard_send_keycode(0, keycode); + }else + { + // Null means empty (all zeroes) report + tud_hid_keyboard_send_report(NULL); + } } if ( !tud_hid_mouse_busy() ) @@ -143,15 +162,11 @@ void tud_cdc_rx_cb(uint8_t itf) //--------------------------------------------------------------------+ void led_blinking_task(void) { - enum { BLINK_INTEVAL = 1000 }; - + static tu_timeout_t tm = { .start = 0, .interval = 1000 }; // Blink every 1000 ms static bool led_state = false; - static uint32_t last_blink = 0; - // not enough time - if ( last_blink + BLINK_INTEVAL > tusb_hal_millis() ) return; - - last_blink += BLINK_INTEVAL; + if ( !tu_timeout_expired(&tm) ) return; // not enough time + tu_timeout_reset(&tm); board_led_control(BOARD_LED0, led_state); led_state = 1 - led_state; // toggle diff --git a/hw/bsp/board.h b/hw/bsp/board.h index 827f22d7..f9007992 100644 --- a/hw/bsp/board.h +++ b/hw/bsp/board.h @@ -150,7 +150,6 @@ static inline void board_led_off(uint32_t led_id) board_led_control(led_id, false); } - /** \brief Get the current state of the buttons on the board * \return Bitmask where a '1' means active (pressed), a '0' means inactive. */ diff --git a/hw/bsp/pca10056/board_pca10056.c b/hw/bsp/pca10056/board_pca10056.c index 7b7a43b6..85e32cf2 100644 --- a/hw/bsp/pca10056/board_pca10056.c +++ b/hw/bsp/pca10056/board_pca10056.c @@ -44,10 +44,16 @@ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ #define LED_1 13 + #define LED_STATE_ON 0 #define LED_STATE_OFF (1-LED_STATE_ON) +uint8_t _button_pins[] = { 11, 12, 24, 25 }; + +#define BOARD_BUTTON_COUNT arrcount_(_button_pins) + + /*------------------------------------------------------------------*/ /* TUSB HAL MILLISECOND *------------------------------------------------------------------*/ @@ -60,44 +66,72 @@ void SysTick_Handler (void) uint32_t tusb_hal_millis(void) { - //#define tick2ms(tck) ( ( ((uint64_t)(tck)) * 1000) / configTICK_RATE_HZ ) - //return tick2ms( app_timer_cnt_get() ); - return board_tick2ms(system_ticks); } /*------------------------------------------------------------------*/ /* BOARD API *------------------------------------------------------------------*/ + +/* tinyusb function that handles power event (detected, ready, removed) + * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. + */ +extern void tusb_hal_nrf_power_event(uint32_t event); + void board_init(void) { // Config clock source: XTAL or RC in sdk_config.h NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); NRF_CLOCK->TASKS_LFCLKSTART = 1UL; + // LED nrf_gpio_cfg_output(LED_1); -#ifdef SOFTDEVICE_PRESENT - // TODO support Softdevice config -#else - // Softdevice is not present, init power module and register tusb power event function - // for vusb detect, ready, removed - extern void tusb_hal_nrf_power_event(uint32_t event); - - // Power module init - const nrfx_power_config_t pwr_cfg = { 0 }; - nrfx_power_init(&pwr_cfg); - - // USB Power detection - const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; - nrfx_power_usbevt_init(&config); - - nrfx_power_usbevt_enable(); -#endif + // Button + for(uint8_t i=0; i no event generated + // We need to invoke the handler based on the status initially + uint32_t usb_reg; + +#ifdef SOFTDEVICE_PRESENT + uint8_t sd_en = false; + (void) sd_softdevice_is_enabled(&sd_en); + + if ( sd_en ) { + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); + + sd_power_usbregstatus_get(&usb_reg); + }else +#else + { + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + usb_reg = NRF_POWER->USBREGSTATUS; + } +#endif + + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + } + + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) { + tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); + } } void board_led_control(uint32_t led_id, bool state) @@ -108,7 +142,15 @@ void board_led_control(uint32_t led_id, bool state) uint32_t board_buttons(void) { - return 0; + uint32_t ret = 0; + + for(uint8_t i=0; i