16
16
17
17
#include " USBPhyHw.h"
18
18
19
+ #include " platform/mbed_critical.h"
20
+
19
21
#include " nrf_clock.h"
20
22
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
+ */
21
44
#define MAX_PACKET_SIZE_SETUP NRF_DRV_USBD_EPSIZE
22
45
#define MAX_PACKET_NON_ISO NRF_DRV_USBD_EPSIZE
23
46
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
@@ -79,11 +102,6 @@ void USBPhyHw::init(USBPhyEvents *events) {
79
102
ret = nrf_drv_power_init (NULL );
80
103
APP_ERROR_CHECK (ret);
81
104
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
-
87
105
// Register callback for USB Power events
88
106
static const nrf_drv_power_usbevt_config_t config = { .handler =
89
107
power_usb_event_handler };
@@ -94,13 +112,17 @@ void USBPhyHw::init(USBPhyEvents *events) {
94
112
ret = nrf_drv_usbd_init (usbd_event_handler);
95
113
APP_ERROR_CHECK (ret);
96
114
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
+
97
119
// Store a reference to this instance
98
120
instance = this ;
99
121
100
122
// Enable IRQ
101
123
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
104
126
}
105
127
106
128
void USBPhyHw::deinit () {
@@ -109,10 +131,13 @@ void USBPhyHw::deinit() {
109
131
// Disable the USB Device driver
110
132
ret_code_t ret = nrf_drv_usbd_uninit ();
111
133
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 ();
113
138
114
- // Clear the instance pointer?
115
- // instance = 0;
139
+ // Clear the instance pointer
140
+ instance = 0 ;
116
141
}
117
142
118
143
bool USBPhyHw::powered () {
@@ -142,7 +167,7 @@ void USBPhyHw::connect() {
142
167
143
168
if (nrf_drv_power_usbstatus_get () == NRF_DRV_POWER_USB_STATE_READY
144
169
&& !nrf_drv_usbd_is_started ())
145
- nrf_drv_usbd_start (false ); // nrf_drv_usbd_start( true);
170
+ nrf_drv_usbd_start (true );
146
171
}
147
172
}
148
173
@@ -152,8 +177,8 @@ void USBPhyHw::disconnect() {
152
177
153
178
if (nrf_drv_usbd_is_started ())
154
179
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 ();
157
182
}
158
183
159
184
void USBPhyHw::configure () {
@@ -214,20 +239,30 @@ const usb_ep_table_t *USBPhyHw::endpoint_table() {
214
239
}
215
240
216
241
uint32_t USBPhyHw::ep0_set_max_packet (uint32_t max_packet) {
242
+ disable_usb_interrupts ();
243
+
217
244
if (max_packet > MAX_PACKET_SIZE_SETUP)
218
245
max_packet = MAX_PACKET_SIZE_SETUP;
219
246
220
247
nrf_drv_usbd_ep_max_packet_size_set (NRF_DRV_USBD_EPOUT0, max_packet);
221
248
nrf_drv_usbd_ep_max_packet_size_set (NRF_DRV_USBD_EPIN0, max_packet);
249
+
250
+ enable_usb_interrupts ();
251
+
222
252
return max_packet;
223
253
}
224
254
225
255
// read setup packet
226
256
void USBPhyHw::ep0_setup_read_result (uint8_t *buffer, uint32_t size) {
257
+
258
+ disable_usb_interrupts ();
259
+
227
260
if (size > sizeof (this ->setup_buf )) {
228
261
size = sizeof (this ->setup_buf );
229
262
}
230
263
memcpy (buffer, &this ->setup_buf , size);
264
+
265
+ enable_usb_interrupts ();
231
266
}
232
267
233
268
void USBPhyHw::ep0_read (uint8_t *data, uint32_t size) {
@@ -454,10 +489,10 @@ void USBPhyHw::process() {
454
489
events->power (false );
455
490
break ;
456
491
case NRF_DRV_POWER_USB_EVT_READY:
457
- if (this ->connect_enabled ) {
492
+ // if(this->connect_enabled) { // Not really necessary (only happens after enabled)
458
493
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
+ // }
461
496
break ;
462
497
default :
463
498
ASSERT (false );
@@ -468,7 +503,7 @@ void USBPhyHw::process() {
468
503
usb_event_type = USB_HW_EVENT_NONE;
469
504
470
505
// Re-enable interrupt
471
- NVIC_ClearPendingIRQ (USBD_IRQn);
506
+ // NVIC_ClearPendingIRQ(USBD_IRQn);
472
507
enable_usb_interrupts ();
473
508
}
474
509
@@ -541,7 +576,6 @@ static void power_usb_event_handler(nrf_drv_power_usb_evt_t event) {
541
576
542
577
static void usbd_event_handler (nrf_drv_usbd_evt_t const * const p_event) {
543
578
if (instance) {
544
- NVIC_DisableIRQ (USBD_IRQn);
545
579
// Pass the event on to the USBPhyHW instance
546
580
instance->_usb_event_handler (p_event);
547
581
}
0 commit comments