Skip to content

Commit 164e1e2

Browse files
committed
re-init usb hardware when enable/disable SD
1 parent d1fb384 commit 164e1e2

3 files changed

Lines changed: 50 additions & 23 deletions

File tree

ports/nrf/common-hal/bleio/Adapter.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "py/runtime.h"
3737
#include "shared-bindings/bleio/Adapter.h"
3838

39+
#include "supervisor/usb.h"
40+
3941
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
4042
mp_raise_msg_varg(&mp_type_AssertionError,
4143
translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc);
@@ -47,9 +49,6 @@ STATIC uint32_t ble_stack_enable(void) {
4749
.accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
4850
};
4951

50-
// The SD takes over the POWER IRQ and will fail if the IRQ is already in use
51-
nrfx_power_uninit();
52-
5352
uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler);
5453
if (err_code != NRF_SUCCESS)
5554
return err_code;
@@ -101,9 +100,19 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) {
101100

102101
uint32_t err_code;
103102
if (enabled) {
103+
// The SD takes over the POWER module and will fail if the module is already in use.
104+
// Occurs when USB is initialized previously
105+
nrfx_power_uninit();
106+
104107
err_code = ble_stack_enable();
108+
109+
// Re-init USB hardware
110+
init_usb_hardware();
105111
} else {
106112
err_code = sd_softdevice_disable();
113+
114+
// Re-init USB hardware
115+
init_usb_hardware();
107116
}
108117

109118
if (err_code != NRF_SUCCESS) {

ports/nrf/supervisor/usb.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,15 @@
3636
#include "nrf_soc.h"
3737
#endif
3838

39-
/* tinyusb function that handles power event (detected, ready, removed)
40-
* We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
41-
*/
39+
// tinyusb function that handles power event (detected, ready, removed)
40+
// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
4241
extern void tusb_hal_nrf_power_event(uint32_t event);
4342

4443
void init_usb_hardware(void) {
4544

4645
// 2 is max priority (0, 1 are reserved for SD)
4746
NVIC_SetPriority(USBD_IRQn, 2);
4847

49-
// USB power may already be ready at this time -> no event generated
50-
// We need to invoke the handler based on the status initially
51-
uint32_t usb_reg;
52-
5348
#ifdef SOFTDEVICE_PRESENT
5449
uint8_t sd_en = false;
5550
(void) sd_softdevice_is_enabled(&sd_en);
@@ -58,8 +53,6 @@ void init_usb_hardware(void) {
5853
sd_power_usbdetected_enable(true);
5954
sd_power_usbpwrrdy_enable(true);
6055
sd_power_usbremoved_enable(true);
61-
62-
sd_power_usbregstatus_get(&usb_reg);
6356
}else
6457
#endif
6558
{
@@ -72,15 +65,5 @@ void init_usb_hardware(void) {
7265
nrfx_power_usbevt_init(&config);
7366

7467
nrfx_power_usbevt_enable();
75-
76-
usb_reg = NRF_POWER->USBREGSTATUS;
77-
}
78-
79-
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
80-
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
81-
}
82-
83-
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
84-
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
8568
}
8669
}

supervisor/shared/usb/usb.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,19 @@
3232
#include "lib/utils/interrupt_char.h"
3333
#include "lib/mp-readline/readline.h"
3434

35+
#include "nrfx_power.h"
36+
37+
#ifdef SOFTDEVICE_PRESENT
38+
#include "nrf_sdm.h"
39+
#include "nrf_soc.h"
40+
#endif
41+
3542
#include "tusb.h"
3643

44+
// tinyusb function that handles power event (detected, ready, removed)
45+
// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
46+
extern void tusb_hal_nrf_power_event(uint32_t event);
47+
3748
// Serial number as hex characters. This writes directly to the USB
3849
// descriptor.
3950
extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2];
@@ -60,6 +71,30 @@ bool usb_enabled(void) {
6071

6172
void usb_init(void) {
6273
init_usb_hardware();
74+
75+
// USB power may already be ready at this time -> no event generated
76+
// We need to invoke the handler based on the status initially
77+
uint32_t usb_reg;
78+
79+
#ifdef SOFTDEVICE_PRESENT
80+
uint8_t sd_en = false;
81+
(void) sd_softdevice_is_enabled(&sd_en);
82+
83+
if ( sd_en ) {
84+
sd_power_usbregstatus_get(&usb_reg);
85+
}else {
86+
usb_reg = NRF_POWER->USBREGSTATUS;
87+
}
88+
89+
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
90+
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
91+
}
92+
93+
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
94+
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
95+
}
96+
#endif
97+
6398
load_serial_number();
6499

65100
tusb_init();
@@ -74,7 +109,7 @@ void usb_init(void) {
74109
}
75110

76111
void usb_background(void) {
77-
if (tusb_inited()) {
112+
if (usb_enabled()) {
78113
tud_task();
79114
tud_cdc_write_flush();
80115
}

0 commit comments

Comments
 (0)