Skip to content

Commit c006888

Browse files
committed
Reviewing functions. Added critical sections to some functions that access state information.
1 parent f000538 commit c006888

File tree

1 file changed

+52
-18
lines changed

1 file changed

+52
-18
lines changed

usb/device/targets/TARGET_NORDIC/TARGET_MCU_NRF52840/USBPhy_Nordic.cpp

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,31 @@
1616

1717
#include "USBPhyHw.h"
1818

19+
#include "platform/mbed_critical.h"
20+
1921
#include "nrf_clock.h"
2022

23+
/*
24+
* TODO list for nRF52840 USBD driver
25+
*
26+
* 1.) Properly enable/disable start-of-frame interrupt.
27+
*
28+
* Description: Currently, start-of-frame interrupts are masked by a flag at this layer
29+
* but still cause the processor to be interrupted for no purpose.
30+
*
31+
* The Nordic driver requires you to call nrf_drv_start(bool)
32+
* with a boolean flag indicating whether it should enable start-of-frame
33+
* interrupts or not. From the datasheet it seems to be possible to
34+
* enable/disable SoF interrupts on the fly, but the fact that they
35+
* force you to make the SoF decision during "start" makes me suspicious
36+
* the underlying driver may manage/use the SoF flag in other ways.
37+
*
38+
* Next steps: Investigate how the SoF flag is used during "nrf_drv_start" and
39+
* determine if enabling/disabling this interrupt would cause internal problems
40+
* with the Nordic USBD driver
41+
*
42+
*
43+
*/
2144
#define MAX_PACKET_SIZE_SETUP NRF_DRV_USBD_EPSIZE
2245
#define MAX_PACKET_NON_ISO NRF_DRV_USBD_EPSIZE
2346
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
@@ -79,11 +102,6 @@ void USBPhyHw::init(USBPhyEvents *events) {
79102
ret = nrf_drv_power_init(NULL);
80103
APP_ERROR_CHECK(ret);
81104

82-
/* Configure selected size of the packed on EP0 */
83-
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, MAX_PACKET_SIZE_SETUP);
84-
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, MAX_PACKET_SIZE_SETUP);
85-
86-
87105
// Register callback for USB Power events
88106
static const nrf_drv_power_usbevt_config_t config = { .handler =
89107
power_usb_event_handler };
@@ -94,13 +112,17 @@ void USBPhyHw::init(USBPhyEvents *events) {
94112
ret = nrf_drv_usbd_init(usbd_event_handler);
95113
APP_ERROR_CHECK(ret);
96114

115+
/* Configure selected size of the packed on EP0 */
116+
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, MAX_PACKET_SIZE_SETUP);
117+
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, MAX_PACKET_SIZE_SETUP);
118+
97119
// Store a reference to this instance
98120
instance = this;
99121

100122
// Enable IRQ
101123
NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_IRQHandler);
102-
NVIC_SetPriority(USBD_IRQn, 7);
103-
NVIC_EnableIRQ(USBD_IRQn);
124+
//NVIC_SetPriority(USBD_IRQn, 7);
125+
//NVIC_EnableIRQ(USBD_IRQn); // This is handled by the Nordic driver
104126
}
105127

106128
void USBPhyHw::deinit() {
@@ -109,10 +131,13 @@ void USBPhyHw::deinit() {
109131
// Disable the USB Device driver
110132
ret_code_t ret = nrf_drv_usbd_uninit();
111133
APP_ERROR_CHECK(ret);
112-
NVIC_DisableIRQ(USBD_IRQn);
134+
//NVIC_DisableIRQ(USBD_IRQn); // This is handled by the Nordic driver
135+
136+
// Disable the power peripheral driver
137+
nrf_drv_power_uninit();
113138

114-
// Clear the instance pointer?
115-
//instance = 0;
139+
// Clear the instance pointer
140+
instance = 0;
116141
}
117142

118143
bool USBPhyHw::powered() {
@@ -142,7 +167,7 @@ void USBPhyHw::connect() {
142167

143168
if(nrf_drv_power_usbstatus_get() == NRF_DRV_POWER_USB_STATE_READY
144169
&& !nrf_drv_usbd_is_started())
145-
nrf_drv_usbd_start(false);//nrf_drv_usbd_start(true);
170+
nrf_drv_usbd_start(true);
146171
}
147172
}
148173

@@ -152,8 +177,8 @@ void USBPhyHw::disconnect() {
152177

153178
if(nrf_drv_usbd_is_started())
154179
nrf_drv_usbd_stop();
155-
// if(nrf_drv_usbd_is_enabled())
156-
// nrf_drv_usbd_disable();
180+
if(nrf_drv_usbd_is_enabled())
181+
nrf_drv_usbd_disable();
157182
}
158183

159184
void USBPhyHw::configure() {
@@ -214,20 +239,30 @@ const usb_ep_table_t *USBPhyHw::endpoint_table() {
214239
}
215240

216241
uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet) {
242+
disable_usb_interrupts();
243+
217244
if (max_packet > MAX_PACKET_SIZE_SETUP)
218245
max_packet = MAX_PACKET_SIZE_SETUP;
219246

220247
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, max_packet);
221248
nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, max_packet);
249+
250+
enable_usb_interrupts();
251+
222252
return max_packet;
223253
}
224254

225255
// read setup packet
226256
void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size) {
257+
258+
disable_usb_interrupts();
259+
227260
if (size > sizeof(this->setup_buf)) {
228261
size = sizeof(this->setup_buf);
229262
}
230263
memcpy(buffer, &this->setup_buf, size);
264+
265+
enable_usb_interrupts();
231266
}
232267

233268
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) {
@@ -454,10 +489,10 @@ void USBPhyHw::process() {
454489
events->power(false);
455490
break;
456491
case NRF_DRV_POWER_USB_EVT_READY:
457-
if(this->connect_enabled) {
492+
//if(this->connect_enabled) { // Not really necessary (only happens after enabled)
458493
if(!nrf_drv_usbd_is_started())
459-
nrf_drv_usbd_start(false);//nrf_drv_usbd_start(true);
460-
}
494+
nrf_drv_usbd_start(true);
495+
//}
461496
break;
462497
default:
463498
ASSERT(false);
@@ -468,7 +503,7 @@ void USBPhyHw::process() {
468503
usb_event_type = USB_HW_EVENT_NONE;
469504

470505
// Re-enable interrupt
471-
NVIC_ClearPendingIRQ(USBD_IRQn);
506+
//NVIC_ClearPendingIRQ(USBD_IRQn);
472507
enable_usb_interrupts();
473508
}
474509

@@ -541,7 +576,6 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event) {
541576

542577
static void usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event) {
543578
if(instance) {
544-
NVIC_DisableIRQ(USBD_IRQn);
545579
// Pass the event on to the USBPhyHW instance
546580
instance->_usb_event_handler(p_event);
547581
}

0 commit comments

Comments
 (0)