21
21
22
22
#include " nrf_clock.h"
23
23
24
- /*
25
- * TODO list for nRF52840 USBD driver
26
- *
27
- * 1.) Properly enable/disable start-of-frame interrupt.
28
- *
29
- * Description: Currently, start-of-frame interrupts are masked by a flag at this layer
30
- * but still cause the processor to be interrupted for no purpose.
31
- *
32
- * The Nordic driver requires you to call nrf_drv_start(bool)
33
- * with a boolean flag indicating whether it should enable start-of-frame
34
- * interrupts or not. From the datasheet it seems to be possible to
35
- * enable/disable SoF interrupts on the fly, but the fact that they
36
- * force you to make the SoF decision during "start" makes me suspicious
37
- * the underlying driver may manage/use the SoF flag in other ways.
38
- *
39
- * Next steps: Investigate how the SoF flag is used during "nrf_drv_start" and
40
- * determine if enabling/disabling this interrupt would cause internal problems
41
- * with the Nordic USBD driver
42
- *
43
- *
44
- */
45
24
#define MAX_PACKET_SIZE_SETUP NRF_DRV_USBD_EPSIZE
46
25
#define MAX_PACKET_NON_ISO NRF_DRV_USBD_EPSIZE
47
26
#define MAX_PACKET_ISO NRF_DRV_USBD_ISOSIZE
@@ -67,19 +46,10 @@ void USBD_HAL_IRQHandler(void);
67
46
static USBPhyHw *instance = 0 ;
68
47
69
48
static volatile bool virtual_status_xfer_event;
70
- static volatile bool irq_already_pending;
71
49
72
50
static void usbd_event_handler (nrf_drv_usbd_evt_t const * const p_event);
73
51
static void power_usb_event_handler (nrf_drv_power_usb_evt_t event);
74
52
75
- #if USBD_DEBUG
76
-
77
- // Static array of saved events to track what happens
78
- static nrf_drv_usbd_evt_t debug_events[32 ];
79
- static uint8_t debug_evt_index = 0 ;
80
-
81
- #endif
82
-
83
53
USBPhy *get_usb_phy () {
84
54
static USBPhyHw usbphy;
85
55
return &usbphy;
@@ -127,22 +97,15 @@ void USBPhyHw::init(USBPhyEvents *events) {
127
97
instance = this ;
128
98
129
99
virtual_status_xfer_event = false ;
130
- irq_already_pending = false ;
131
100
132
101
/*
133
- * TODO - Configure ISOIN endpoint to respond with ZLP when
102
+ * Configure ISOIN endpoint to respond with ZLP when
134
103
* no data is ready to be sent
135
- *
136
- * This is a feature available in the Nordic SDK15.2
137
- * For now we just configure the appropriate register on initialization
138
104
*/
139
105
NRF_USBD->ISOINCONFIG |= 0x01 ; // set RESPONSE to 1 (respond with ZLP)
140
106
141
107
// Enable IRQ
142
- // NVIC_SetVector(USBD_IRQn, (uint32_t)USBD_IRQHandler);
143
108
NVIC_SetVector (USBD_IRQn, (uint32_t )USBD_HAL_IRQHandler);
144
- // NVIC_SetPriority(USBD_IRQn, 7);
145
- // NVIC_EnableIRQ(USBD_IRQn); // This is handled by the Nordic driver
146
109
}
147
110
148
111
void USBPhyHw::deinit () {
@@ -214,6 +177,7 @@ void USBPhyHw::sof_enable() {
214
177
// TODO - Enable SOF interrupt
215
178
// Can this safely be done if
216
179
// nrf_drv_usbd_start is called with SoF enabled?
180
+ // For now just mask the interrupt with a boolean flag
217
181
sof_enabled = true ;
218
182
}
219
183
@@ -304,8 +268,6 @@ void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) {
304
268
305
269
virtual_status_xfer_event = true ;
306
270
307
- irq_already_pending = NVIC_GetPendingIRQ (USBD_IRQn);
308
-
309
271
// Trigger an interrupt to process the virtual status event
310
272
NVIC_SetPendingIRQ (USBD_IRQn);
311
273
@@ -349,8 +311,6 @@ void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size) {
349
311
350
312
virtual_status_xfer_event = true ;
351
313
352
- irq_already_pending = NVIC_GetPendingIRQ (USBD_IRQn);
353
-
354
314
// Trigger an interrupt to process the virtual status event
355
315
NVIC_SetPendingIRQ (USBD_IRQn);
356
316
@@ -429,10 +389,7 @@ bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) {
429
389
}
430
390
431
391
void USBPhyHw::endpoint_abort (usb_ep_t endpoint) {
432
- nrf_drv_usbd_ep_t nrf_ep = get_nordic_endpoint (endpoint);
433
- // Don't call abort on ISO endpoints -- this will cause an ASSERT in the Nordic driver
434
- // if(nrf_ep != NRF_DRV_USBD_EPOUT8 && nrf_ep != NRF_DRV_USBD_EPIN8)
435
- nrf_drv_usbd_ep_abort (nrf_ep);
392
+ nrf_drv_usbd_ep_abort (get_nordic_endpoint (endpoint));
436
393
}
437
394
438
395
void USBPhyHw::process () {
@@ -604,7 +561,9 @@ void USBPhyHw::_reset(void)
604
561
605
562
usb_event_type = USB_HW_EVENT_NONE;
606
563
607
- // TODO - Clear all endpoint interrupts?
564
+ // Clear all endpoint interrupts
565
+ NVIC_ClearPendingIRQ (USBD_IRQn);
566
+ nrf_usbd_event_clear ((nrf_usbd_event_t )0x01FFFFFF );
608
567
}
609
568
610
569
void USBPhyHw::enable_usb_interrupts (void ) {
@@ -643,15 +602,15 @@ void USBD_HAL_IRQHandler(void)
643
602
if (virtual_status_xfer_event)
644
603
{
645
604
if (instance) {
605
+ // if(!irq_already_pending)
606
+ // return;
607
+
608
+ // irq_already_pending = false;
646
609
instance->_usb_virtual_status_event_handler ();
647
610
}
648
611
649
612
virtual_status_xfer_event = false ;
650
613
651
- if (!irq_already_pending)
652
- return ;
653
-
654
- irq_already_pending = false ;
655
614
}
656
615
// Call Nordic driver IRQ handler
657
616
USBD_IRQHandler ();
0 commit comments