/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-11-25 chenyingchun first version */ #include #include "nrfx.h" #include "nrf_gpio.h" #include "nrfx_power.h" #include "nrfx_uarte.h" #include "device/usbd.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_sdm.h" #include "nrf_soc.h" #endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ void USBD_IRQHandler(void) { rt_interrupt_enter(); tud_int_handler(0); rt_interrupt_leave(); } /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ // 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 tud_board_init(void) { // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; // Use Internal OSC to compatible with all boards NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_RC; NRF_CLOCK->TASKS_LFCLKSTART = 1UL; //------------- USB -------------// #if TUSB_OPT_DEVICE_ENABLED // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice // 2 is highest for application NVIC_SetPriority(USBD_IRQn, 2); // USB power may already be ready at this time -> 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; 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 #endif { // Power module init const nrfx_power_config_t pwr_cfg = { 0 }; nrfx_power_init(&pwr_cfg); // Register tusb function as USB power handler // cause cast-function-type warning 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; } 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); #endif } #ifdef SOFTDEVICE_PRESENT // process SOC event from SD uint32_t proc_soc(void) { uint32_t soc_evt; uint32_t err = sd_evt_get(&soc_evt); if (NRF_SUCCESS == err) { /*------------- usb power event handler -------------*/ int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED: (soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY : (soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1; if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt); } return err; } uint32_t proc_ble(void) { // do nothing with ble return NRF_ERROR_NOT_FOUND; } void SD_EVT_IRQHandler(void) { // process BLE and SOC until there is no more events while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) { } } void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { (void) id; (void) pc; (void) info; } #endif