re-init usb hardware when enable/disable SD

This commit is contained in:
hathach 2019-01-30 14:13:07 +07:00
parent d1fb384a4a
commit 164e1e2341
3 changed files with 50 additions and 23 deletions

View File

@ -36,6 +36,8 @@
#include "py/runtime.h"
#include "shared-bindings/bleio/Adapter.h"
#include "supervisor/usb.h"
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
mp_raise_msg_varg(&mp_type_AssertionError,
translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc);
@ -47,9 +49,6 @@ STATIC uint32_t ble_stack_enable(void) {
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
};
// The SD takes over the POWER IRQ and will fail if the IRQ is already in use
nrfx_power_uninit();
uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler);
if (err_code != NRF_SUCCESS)
return err_code;
@ -101,9 +100,19 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) {
uint32_t err_code;
if (enabled) {
// The SD takes over the POWER module and will fail if the module is already in use.
// Occurs when USB is initialized previously
nrfx_power_uninit();
err_code = ble_stack_enable();
// Re-init USB hardware
init_usb_hardware();
} else {
err_code = sd_softdevice_disable();
// Re-init USB hardware
init_usb_hardware();
}
if (err_code != NRF_SUCCESS) {

View File

@ -36,9 +36,8 @@
#include "nrf_soc.h"
#endif
/* 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.
*/
// 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 init_usb_hardware(void) {
@ -46,10 +45,6 @@ void init_usb_hardware(void) {
// 2 is max priority (0, 1 are reserved for SD)
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;
(void) sd_softdevice_is_enabled(&sd_en);
@ -58,8 +53,6 @@ void init_usb_hardware(void) {
sd_power_usbdetected_enable(true);
sd_power_usbpwrrdy_enable(true);
sd_power_usbremoved_enable(true);
sd_power_usbregstatus_get(&usb_reg);
}else
#endif
{
@ -72,15 +65,5 @@ void init_usb_hardware(void) {
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);
}
}

View File

@ -32,8 +32,19 @@
#include "lib/utils/interrupt_char.h"
#include "lib/mp-readline/readline.h"
#include "nrfx_power.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h"
#include "nrf_soc.h"
#endif
#include "tusb.h"
// 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);
// Serial number as hex characters. This writes directly to the USB
// descriptor.
extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2];
@ -60,6 +71,30 @@ bool usb_enabled(void) {
void usb_init(void) {
init_usb_hardware();
// 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;
(void) sd_softdevice_is_enabled(&sd_en);
if ( sd_en ) {
sd_power_usbregstatus_get(&usb_reg);
}else {
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
load_serial_number();
tusb_init();
@ -74,7 +109,7 @@ void usb_init(void) {
}
void usb_background(void) {
if (tusb_inited()) {
if (usb_enabled()) {
tud_task();
tud_cdc_write_flush();
}