1 #include <stddef.h>
2 #include <mdk/nrf52840_bitfields.h>
3 #include "nrf52840.h"
4 #include "usb_def.h"
5 #include "usb_dc.h"
6 #include "usbd_core.h"
7 
8 #ifndef USBD_CONFIG_ISO_IN_ZLP
9 #define USBD_CONFIG_ISO_IN_ZLP 0
10 #endif
11 
12 /*!< The default platform is NRF52840 */
13 #define NRF52_SERIES
14 /*!< Ep nums */
15 #define EP_NUMS 9
16 /*!< Ep mps */
17 #define EP_MPS 64
18 /*!< Nrf5x special */
19 #define EP_ISO_NUM 8
20 
21 /*!< USBD peripheral address base */
22 #define NRF_USBD_BASE 0x40027000UL
23 /*!< Clock peripheral address base */
24 #define NRF_CLOCK_BASE 0x40000000UL
25 
26 #define USBD_IRQn 39
27 
28 #ifndef EP_ISO_MPS
29 #define EP_ISO_MPS 64
30 #endif
31 
32 #define CHECK_ADD_IS_RAM(address) ((((uint32_t)address) & 0xE0000000u) == 0x20000000u) ? 1 : 0
33 
34 /**
35  * @brief   Endpoint information structure
36  */
37 typedef struct _usbd_ep_info
38 {
39   uint16_t mps;       /*!< Maximum packet length of endpoint */
40   uint8_t eptype;     /*!< Endpoint Type */
41   uint8_t ep_stalled; /* Endpoint stall flag */
42   uint8_t ep_enable;  /* Endpoint enable */
43   uint8_t *xfer_buf;
44   uint32_t xfer_len;
45   uint32_t actual_xfer_len;
46   uint8_t ep_buffer[EP_MPS];
47   /*!< Other endpoint parameters that may be used */
48   volatile uint8_t is_using_dma;
49   volatile uint8_t add_flag;
50 } usbd_ep_info;
51 
52 /*!< nrf52840 usb */
53 struct _nrf52840_core_prvi
54 {
55   uint8_t address;               /*!< address */
56   usbd_ep_info ep_in[EP_NUMS];   /*!< ep in */
57   usbd_ep_info ep_out[EP_NUMS];  /*!< ep out */
58   struct usb_setup_packet setup; /*!< Setup package that may be used in interrupt processing (outside the protocol stack) */
59   volatile uint8_t dma_running;
60   int8_t in_count;
61   volatile uint8_t iso_turn;
62   volatile uint8_t iso_tx_is_ready;
63   /**
64    * For nrf5x, easydma will not move the setup packet into RAM.
65    * We use a flag bit to judge whether the host sends setup,
66    * and then notify usbd_ep_read to and from the register to read the setup package
67    */
68   volatile uint8_t is_setup_packet;
69 } usb_dc_cfg;
70 
usb_dc_low_level_pre_init(void)71 __WEAK void usb_dc_low_level_pre_init(void)
72 {
73 }
74 
usb_dc_low_level_post_init(void)75 __WEAK void usb_dc_low_level_post_init(void)
76 {
77 }
78 
usb_dc_low_level_deinit(void)79 __WEAK void usb_dc_low_level_deinit(void)
80 {
81 }
82 
83 
84 /**@brief Usbds the set remote wakeup.
85  *
86  * @param[in] busid do not used
87  *
88  * @retval
89  */
usbd_set_remote_wakeup(uint8_t busid)90 int usbd_set_remote_wakeup (uint8_t busid)
91 {
92     //TOGGLE_GPIOA9();
93     //#TASK 1.唤醒使能+挂起标志+休眠标志
94     // USB->CNTR |= (uint16_t)USB_CNTR_RESUME;
95     return -1;
96 }
97 
98 /**
99  * @brief            Get setup package
100  * @pre              None
101  * @param[in]        setup Pointer to the address where the setup package is stored
102  * @retval           None
103  */
get_setup_packet(struct usb_setup_packet * setup)104 static inline void get_setup_packet(struct usb_setup_packet *setup)
105 {
106   setup->bmRequestType = (uint8_t)(NRF_USBD->BMREQUESTTYPE);
107   setup->bRequest = (uint8_t)(NRF_USBD->BREQUEST);
108   setup->wIndex = (uint16_t)(NRF_USBD->WINDEXL | ((NRF_USBD->WINDEXH) << 8));
109   setup->wLength = (uint16_t)(NRF_USBD->WLENGTHL | ((NRF_USBD->WLENGTHH) << 8));
110   setup->wValue = (uint16_t)(NRF_USBD->WVALUEL | ((NRF_USBD->WVALUEH) << 8));
111 }
112 
113 /**
114  * @brief            Set tx easydma
115  * @pre              None
116  * @param[in]        ep      End point address
117  * @param[in]        ptr     Data ram ptr
118  * @param[in]        maxcnt  Max length
119  * @retval           None
120  */
nrf_usbd_ep_easydma_set_tx(uint8_t ep,uint32_t ptr,uint32_t maxcnt)121 static void nrf_usbd_ep_easydma_set_tx(uint8_t ep, uint32_t ptr, uint32_t maxcnt)
122 {
123   uint8_t epid = USB_EP_GET_IDX(ep);
124   if (epid == EP_ISO_NUM)
125   {
126     NRF_USBD->ISOIN.PTR = ptr;
127     NRF_USBD->ISOIN.MAXCNT = maxcnt;
128     return;
129   }
130   NRF_USBD->EPIN[epid].PTR = ptr;
131   NRF_USBD->EPIN[epid].MAXCNT = maxcnt;
132 }
133 
134 /**
135  * @brief            Set rx easydma
136  * @pre              None
137  * @param[in]        ep      End point address
138  * @param[in]        ptr     Data ram ptr
139  * @param[in]        maxcnt  Max length
140  * @retval           None
141  */
nrf_usbd_ep_easydma_set_rx(uint8_t ep,uint32_t ptr,uint32_t maxcnt)142 static void nrf_usbd_ep_easydma_set_rx(uint8_t ep, uint32_t ptr, uint32_t maxcnt)
143 {
144   uint8_t epid = USB_EP_GET_IDX(ep);
145   if (epid == EP_ISO_NUM)
146   {
147     NRF_USBD->ISOOUT.PTR = ptr;
148     NRF_USBD->ISOOUT.MAXCNT = maxcnt;
149     return;
150   }
151   NRF_USBD->EPOUT[epid].PTR = ptr;
152   NRF_USBD->EPOUT[epid].MAXCNT = maxcnt;
153 }
154 
155 /**@brief Usbds the set address.
156  *
157  * @param[in] usbid   do not used
158  * @param[in] address 8-bit valid address
159  *
160  * @retval >=0 success otherwise failureSet addressNone
161  */
usbd_set_address(uint8_t usbid,const uint8_t address)162 int usbd_set_address(uint8_t usbid, const uint8_t address)
163 {
164   if (address == 0)
165   {
166     /*!< init 0 address */
167   }
168   else
169   {
170     /*!< For non-0 addresses, write the address to the register in the state phase of setting the address */
171   }
172 
173   NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE;
174   NRF_USBD->EVENTS_USBEVENT = 0;
175 
176   NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk;
177   /*!< nothing to do, handled by hardware; but don't STALL */
178   usb_dc_cfg.address = address;
179   return 0;
180 }
181 
usbd_get_port_speed(const uint8_t port)182 uint8_t usbd_get_port_speed(const uint8_t port)
183 {
184     return USB_SPEED_FULL;
185 }
186 
187 /**@brief Usbds the ep open.
188  *
189  * @param[in] busid  do not used
190  * @param[in] ep_cfg Endpoint configuration structure pointer
191  *
192  * @retval >=0 success otherwise failureOpen endpointNone
193  */
usbd_ep_open(uint8_t busid,const struct usb_endpoint_descriptor * ep_cfg)194 int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep_cfg)
195 {
196   /*!< ep id */
197   uint8_t epid = USB_EP_GET_IDX(ep_cfg->bEndpointAddress);
198   /*!< ep max packet length */
199   uint16_t mps = ep_cfg->wMaxPacketSize;
200   if (USB_EP_DIR_IS_IN(ep_cfg->bEndpointAddress))
201   {
202     /*!< In */
203     usb_dc_cfg.ep_in[epid].mps = mps;
204     usb_dc_cfg.ep_in[epid].eptype = ep_cfg->bmAttributes;
205     usb_dc_cfg.ep_in[epid].ep_enable = true;
206     /*!< Open ep */
207     if (ep_cfg->bmAttributes != USB_ENDPOINT_TYPE_ISOCHRONOUS)
208     {
209       /*!< Enable endpoint interrupt */
210       NRF_USBD->INTENSET = (1 << (USBD_INTEN_ENDEPIN0_Pos + epid));
211       /*!< Enable the in endpoint host to respond when sending in token */
212       NRF_USBD->EPINEN |= (1 << (epid));
213       __ISB();
214       __DSB();
215     }
216     else
217     {
218       NRF_USBD->EVENTS_ENDISOIN = 0;
219       /*!< SPLIT ISO buffer when ISO OUT endpoint is already opened. */
220       if (usb_dc_cfg.ep_out[EP_ISO_NUM].mps)
221         NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN;
222 
223       /*!< Clear SOF event in case interrupt was not enabled yet. */
224       if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0)
225         NRF_USBD->EVENTS_SOF = 0;
226 
227       /*!< Enable SOF and ISOIN interrupts, and ISOIN endpoint. */
228       NRF_USBD->INTENSET = USBD_INTENSET_ENDISOIN_Msk | USBD_INTENSET_SOF_Msk;
229       NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk;
230     }
231   }
232   else if (USB_EP_DIR_IS_OUT(ep_cfg->bEndpointAddress))
233   {
234     /*!< Out */
235     usb_dc_cfg.ep_out[epid].mps = mps;
236     usb_dc_cfg.ep_out[epid].eptype = ep_cfg->bmAttributes;
237     usb_dc_cfg.ep_out[epid].ep_enable = true;
238     /*!< Open ep */
239     if (ep_cfg->bmAttributes != USB_ENDPOINT_TYPE_ISOCHRONOUS)
240     {
241       NRF_USBD->INTENSET = (1 << (USBD_INTEN_ENDEPOUT0_Pos + epid));
242       NRF_USBD->EPOUTEN |= (1 << (epid));
243       __ISB();
244       __DSB();
245       /*!< Write any value to SIZE register will allow nRF to ACK/accept data */
246       NRF_USBD->SIZE.EPOUT[epid] = 0;
247     }
248     else
249     {
250       /*!< SPLIT ISO buffer when ISO IN endpoint is already opened. */
251       if (usb_dc_cfg.ep_in[EP_ISO_NUM].mps)
252         NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN;
253 
254       /*!< Clear old events */
255       NRF_USBD->EVENTS_ENDISOOUT = 0;
256 
257       /*!< Clear SOF event in case interrupt was not enabled yet. */
258       if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0)
259         NRF_USBD->EVENTS_SOF = 0;
260 
261       /*!< Enable SOF and ISOOUT interrupts, and ISOOUT endpoint. */
262       NRF_USBD->INTENSET = USBD_INTENSET_ENDISOOUT_Msk | USBD_INTENSET_SOF_Msk;
263       NRF_USBD->EPOUTEN |= USBD_EPOUTEN_ISOOUT_Msk;
264     }
265   }
266 
267   /*!< Clear stall and reset DataToggle */
268   NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | (ep_cfg->bEndpointAddress);
269   NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | (ep_cfg->bEndpointAddress);
270 
271   __ISB();
272   __DSB();
273 
274   return 0;
275 }
276 
277 /**@brief Usbds the ep close.
278  *
279  * @param[in] busid do not used
280  * @param[in] ep    ep : Endpoint address
281  *
282  * @retval >=0 success otherwise failureClose endpointNone
283  */
usbd_ep_close(uint8_t busid,const uint8_t ep)284 int usbd_ep_close(uint8_t busid, const uint8_t ep)
285 {
286   /*!< ep id */
287   uint8_t epid = USB_EP_GET_IDX(ep);
288   if (epid != EP_ISO_NUM)
289   {
290 
291     if (USB_EP_DIR_IS_OUT(ep))
292     {
293       usb_dc_cfg.ep_out[epid].ep_enable = false;
294       NRF_USBD->INTENCLR = (1 << (USBD_INTEN_ENDEPOUT0_Pos + epid));
295       NRF_USBD->EPOUTEN &= ~(1 << (epid));
296     }
297     else
298     {
299       usb_dc_cfg.ep_in[epid].ep_enable = false;
300       NRF_USBD->INTENCLR = (1 << (USBD_INTEN_ENDEPIN0_Pos + epid));
301       NRF_USBD->EPINEN &= ~(1 << (epid));
302     }
303   }
304   else
305   {
306     /*!< ISO EP */
307     if (USB_EP_DIR_IS_OUT(ep))
308     {
309       usb_dc_cfg.ep_out[epid].ep_enable = false;
310       usb_dc_cfg.ep_out[EP_ISO_NUM].mps = 0;
311       NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOOUT_Msk;
312       NRF_USBD->EPOUTEN &= ~USBD_EPOUTEN_ISOOUT_Msk;
313       NRF_USBD->EVENTS_ENDISOOUT = 0;
314     }
315     else
316     {
317       usb_dc_cfg.ep_in[epid].ep_enable = false;
318       usb_dc_cfg.ep_in[EP_ISO_NUM].mps = 0;
319       NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOIN_Msk;
320       NRF_USBD->EPINEN &= ~USBD_EPINEN_ISOIN_Msk;
321     }
322     /*!< One of the ISO endpoints closed, no need to split buffers any more. */
323     NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir;
324     /*!< When both ISO endpoint are close there is no need for SOF any more. */
325     if (usb_dc_cfg.ep_in[EP_ISO_NUM].mps + usb_dc_cfg.ep_out[EP_ISO_NUM].mps == 0)
326     {
327       NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk;
328     }
329   }
330   __ISB();
331   __DSB();
332 
333   return 0;
334 }
335 
336 /**
337  * @brief Setup in ep transfer setting and start transfer.
338  *
339  * This function is asynchronous.
340  * This function is similar to uart with tx dma.
341  *
342  * This function is called to write data to the specified endpoint. The
343  * supplied usbd_endpoint_callback function will be called when data is transmitted
344  * out.
345  *
346  * @param[in]  busid     do not used
347  * @param[in]  ep        Endpoint address corresponding to the one
348  *                       listed in the device configuration table
349  * @param[in]  data      Pointer to data to write
350  * @param[in]  data_len  Length of the data requested to write. This may
351  *                       be zero for a zero length status packet.
352  * @return 0 on success, negative errno code on fail.
353  */
usbd_ep_start_write(uint8_t busid,const uint8_t ep,const uint8_t * data,uint32_t data_len)354 int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
355 {
356   uint8_t ep_idx = USB_EP_GET_IDX(ep);
357 
358   if (!data && data_len)
359   {
360     return -1;
361   }
362   if (!usb_dc_cfg.ep_in[ep_idx].ep_enable)
363   {
364     return -2;
365   }
366   if ((uint32_t)data & 0x03)
367   {
368     return -3;
369   }
370 
371   usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
372   usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
373   usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
374 
375   if (data_len == 0)
376   {
377     /*!< write 0 len data */
378     nrf_usbd_ep_easydma_set_tx(ep_idx, (uint32_t)NULL, 0);
379     NRF_USBD->TASKS_STARTEPIN[ep_idx] = 1;
380   }
381   else
382   {
383     /*!< Not zlp */
384     data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
385     if (!CHECK_ADD_IS_RAM(data))
386     {
387       /*!< Data is not in ram */
388       /*!< Memcpy data to ram */
389       memcpy(usb_dc_cfg.ep_in[ep_idx].ep_buffer, data, data_len);
390       nrf_usbd_ep_easydma_set_tx(ep_idx, (uint32_t)usb_dc_cfg.ep_in[ep_idx].ep_buffer, data_len);
391     }
392     else
393     {
394       nrf_usbd_ep_easydma_set_tx(ep_idx, (uint32_t)data, data_len);
395     }
396     /**
397      * Note that starting DMA transmission is to transmit data to USB peripherals,
398      * and then wait for the host to get it
399      */
400     /*!< Start dma transfer */
401     if (ep_idx != EP_ISO_NUM)
402     {
403       NRF_USBD->TASKS_STARTEPIN[ep_idx] = 1;
404     }
405     else
406     {
407       // NRF_USBD->TASKS_STARTISOIN = 1;
408       usb_dc_cfg.iso_tx_is_ready = 1;
409     }
410   }
411   return 0;
412 }
413 
414 /**
415  * @brief Setup out ep transfer setting and start transfer.
416  *
417  * This function is asynchronous.
418  * This function is similar to uart with rx dma.
419  *
420  * This function is called to read data to the specified endpoint. The
421  * supplied usbd_endpoint_callback function will be called when data is received
422  * in.
423  *
424  * @param[in]  busid     do not used
425  * @param[in]  ep        Endpoint address corresponding to the one
426  *                       listed in the device configuration table
427  * @param[in]  data      Pointer to data to read
428  * @param[in]  data_len  Max length of the data requested to read.
429  *
430  * @return 0 on success, negative errno code on fail.
431  */
usbd_ep_start_read(uint8_t busid,const uint8_t ep,uint8_t * data,uint32_t data_len)432 int     usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
433 {
434   uint8_t ep_idx = USB_EP_GET_IDX(ep);
435 
436   if (!data && data_len)
437   {
438     return -1;
439   }
440   if (!usb_dc_cfg.ep_out[ep_idx].ep_enable)
441   {
442     return -2;
443   }
444   if ((uint32_t)data & 0x03)
445   {
446     return -3;
447   }
448 
449   usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
450   usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
451   usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
452 
453   if (data_len == 0)
454   {
455     return 0;
456   }
457   else
458   {
459     data_len = MIN(data_len, usb_dc_cfg.ep_out[ep_idx].mps);
460     if (!CHECK_ADD_IS_RAM(data))
461     {
462       /*!< Data address is not in ram */
463       // TODO:
464     }
465     else
466     {
467       if (ep_idx == 0)
468       {
469         NRF_USBD->TASKS_EP0RCVOUT = 1;
470       }
471       nrf_usbd_ep_easydma_set_rx(ep_idx, (uint32_t)data, data_len);
472     }
473   }
474   return 0;
475 }
476 
477 /**
478  * @brief            Endpoint setting pause
479  * @pre              None
480  * @param[in]        busid     do not used
481  * @param[in]        ep : Endpoint address
482  * @retval           >=0 success otherwise failure
483  */
usbd_ep_set_stall(uint8_t busid,const uint8_t ep)484 int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
485 {
486   /*!< ep id */
487   uint8_t epid = USB_EP_GET_IDX(ep);
488   if (epid == 0)
489   {
490     NRF_USBD->TASKS_EP0STALL = 1;
491   }
492   else if (epid != EP_ISO_NUM)
493   {
494     NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | (ep);
495   }
496   __ISB();
497   __DSB();
498   return 0;
499 }
500 
501 /**
502  * @brief            Endpoint clear pause
503  * @pre              None
504  * @param[in]        busid     do not used
505  * @param[in]        ep : Endpoint address
506  * @retval           >=0 success otherwise failure
507  */
usbd_ep_clear_stall(uint8_t usbid,const uint8_t ep)508 int usbd_ep_clear_stall(uint8_t usbid, const uint8_t ep)
509 {
510   /*!< ep id */
511   uint8_t epid = USB_EP_GET_IDX(ep);
512 
513   if (epid != 0 && epid != EP_ISO_NUM)
514   {
515     /**
516      * reset data toggle to DATA0
517      * First write this register with VALUE=Nop to select the endpoint, then either read it to get the status from
518      * VALUE, or write it again with VALUE=Data0 or Data1
519      */
520     NRF_USBD->DTOGGLE = ep;
521     NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep;
522 
523     /*!< Clear stall */
524     NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep;
525 
526     /*!< Write any value to SIZE register will allow nRF to ACK/accept data */
527     if (USB_EP_DIR_IS_OUT(ep))
528       NRF_USBD->SIZE.EPOUT[epid] = 0;
529 
530     __ISB();
531     __DSB();
532   }
533 
534   return 0;
535 }
536 
537 /**
538  * @brief            Check endpoint status
539  * @pre              None
540  * @param[in]        busid     do not used
541  * @param[in]        ep : Endpoint address
542  * @param[out]       stalled : Outgoing endpoint status
543  * @retval           >=0 success otherwise failure
544  */
usbd_ep_is_stalled(uint8_t busid,const uint8_t ep,uint8_t * stalled)545 int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
546 {
547   return 0;
548 }
549 
550 /**
551  * @brief            USB initialization
552  * @pre              None
553  * @param[in]        busid     do not used
554  * @retval           >=0 success otherwise failure
555  */
usb_dc_init(uint8_t busid)556 int usb_dc_init(uint8_t busid)
557 {
558   /*!< dc init */
559   usb_dc_low_level_pre_init();
560 
561   memset(&usb_dc_cfg, 0, sizeof(usb_dc_cfg));
562   /*!< Clear USB Event Interrupt */
563   NRF_USBD->EVENTS_USBEVENT = 0;
564   NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE;
565 
566   /*!< Reset interrupt */
567   NRF_USBD->INTENCLR = NRF_USBD->INTEN;
568   NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk |
569                        USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk | USBD_INTEN_STARTED_Msk;
570 
571   usb_dc_low_level_post_init();
572   return 0;
573 }
574 
575 /**
576  * @brief            USB deinit
577  * @pre              None
578  * @param[in]        busid     do not used
579  * @retval           >=0 success otherwise failure
580  */
usb_dc_deinit(uint8_t busid)581 int usb_dc_deinit(uint8_t busid)
582 {
583   /*!< dc deinit */
584   return 0;
585 }
586 
587 /**
588  * @brief            USB interrupt processing function
589  * @pre              None
590  * @param[in]        None
591  * @retval           None
592  */
USBD_IRQHandler(uint8_t busid)593 void USBD_IRQHandler(uint8_t busid)
594 {
595   uint32_t const inten = NRF_USBD->INTEN;
596   uint32_t int_status = 0;
597   volatile uint32_t usb_event = 0;
598   volatile uint32_t *regevt = &NRF_USBD->EVENTS_USBRESET;
599 
600   /*!< Traverse USB events */
601   for (uint8_t i = 0; i < USBD_INTEN_EPDATA_Pos + 1; i++)
602   {
603     if ((inten & (1 << i)) && regevt[i])
604     {
605       int_status |= (1 << (i));
606       /*!< event clear */
607       regevt[i] = 0;
608       __ISB();
609       __DSB();
610     }
611   }
612 
613   /*!< bit 24 */
614   if (int_status & USBD_INTEN_EPDATA_Msk)
615   {
616     /*!< out ep */
617     for (uint8_t ep_out_ct = 1; ep_out_ct <= 7; ep_out_ct++)
618     {
619       if ((NRF_USBD->EPDATASTATUS) & (1 << (16 + ep_out_ct)))
620       {
621         NRF_USBD->EPDATASTATUS |= (1 << (16 + ep_out_ct));
622         /*!< The data arrives at the usb fifo, starts the dma transmission, and transfers it to the user ram  */
623         NRF_USBD->TASKS_STARTEPOUT[ep_out_ct] = 1;
624       }
625     }
626     /*!< in ep */
627     for (uint8_t ep_in_ct = 1; ep_in_ct <= 7; ep_in_ct++)
628     {
629       if ((NRF_USBD->EPDATASTATUS) & (1 << (0 + ep_in_ct)))
630       {
631         /*!< in ep tranfer to host successfully */
632         NRF_USBD->EPDATASTATUS |= (1 << (0 + ep_in_ct));
633         if (usb_dc_cfg.ep_in[ep_in_ct].xfer_len > usb_dc_cfg.ep_in[ep_in_ct].mps)
634         {
635           /*!< Need start in again */
636           usb_dc_cfg.ep_in[ep_in_ct].xfer_buf += usb_dc_cfg.ep_in[ep_in_ct].mps;
637           usb_dc_cfg.ep_in[ep_in_ct].xfer_len -= usb_dc_cfg.ep_in[ep_in_ct].mps;
638           usb_dc_cfg.ep_in[ep_in_ct].actual_xfer_len += usb_dc_cfg.ep_in[ep_in_ct].mps;
639           if (usb_dc_cfg.ep_in[ep_in_ct].xfer_len > usb_dc_cfg.ep_in[ep_in_ct].mps)
640           {
641             nrf_usbd_ep_easydma_set_tx(ep_in_ct, (uint32_t)usb_dc_cfg.ep_in[ep_in_ct].xfer_buf, usb_dc_cfg.ep_in[ep_in_ct].mps);
642           }
643           else
644           {
645             nrf_usbd_ep_easydma_set_tx(ep_in_ct, (uint32_t)usb_dc_cfg.ep_in[ep_in_ct].xfer_buf, usb_dc_cfg.ep_in[ep_in_ct].xfer_len);
646           }
647           NRF_USBD->TASKS_STARTEPIN[ep_in_ct] = 1;
648         }
649         else
650         {
651           usb_dc_cfg.ep_in[ep_in_ct].actual_xfer_len += usb_dc_cfg.ep_in[ep_in_ct].xfer_len;
652           usb_dc_cfg.ep_in[ep_in_ct].xfer_len = 0;
653           usbd_event_ep_in_complete_handler(0, ep_in_ct | 0x80, usb_dc_cfg.ep_in[ep_in_ct].actual_xfer_len);
654         }
655       }
656     }
657   }
658 
659   /*!< bit 23 */
660   if (int_status & USBD_INTEN_EP0SETUP_Msk)
661   {
662     /* Setup */
663     /*!< Storing this setup package will help the following procedures */
664     get_setup_packet(&(usb_dc_cfg.setup));
665     /*!< Nrf52840 will set the address automatically by hardware,
666          so the protocol stack of the address setting command sent by the host does not need to be processed */
667 
668     if (usb_dc_cfg.setup.wLength == 0)
669     {
670       NRF_USBD->TASKS_EP0STATUS = 1;
671     }
672 
673     if (usb_dc_cfg.setup.bRequest != USB_REQUEST_SET_ADDRESS)
674     {
675       usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&(usb_dc_cfg.setup));
676     }
677   }
678 
679   /*!< bit 22 */
680   if (int_status & USBD_INTEN_USBEVENT_Msk)
681   {
682     usb_event = NRF_USBD->EVENTCAUSE;
683     NRF_USBD->EVENTCAUSE = usb_event;
684     if (usb_event & USBD_EVENTCAUSE_SUSPEND_Msk)
685     {
686       NRF_USBD->LOWPOWER = 1;
687       /*!<  */
688     }
689     if (usb_event & USBD_EVENTCAUSE_RESUME_Msk)
690     {
691       /*!<  */
692     }
693     if (usb_event & USBD_EVENTCAUSE_USBWUALLOWED_Msk)
694     {
695       NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume;
696       NRF_USBD->TASKS_DPDMDRIVE = 1;
697       /**
698        * There is no Resume interrupt for remote wakeup, enable SOF for to report bus ready state
699        * Clear SOF event in case interrupt was not enabled yet.
700        */
701       if ((NRF_USBD->INTEN & USBD_INTEN_SOF_Msk) == 0)
702         NRF_USBD->EVENTS_SOF = 0;
703       NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk;
704     }
705   }
706 
707   /*!< bit 21 */
708   if (int_status & USBD_INTEN_SOF_Msk)
709   {
710     bool iso_enabled = false;
711     /*!< ISOOUT: Transfer data gathered in previous frame from buffer to RAM */
712     if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk)
713     {
714       iso_enabled = true;
715       /*!< If ZERO bit is set, ignore ISOOUT length */
716       if ((NRF_USBD->SIZE.ISOOUT) & USBD_SIZE_ISOOUT_ZERO_Msk)
717       {
718       }
719       else
720       {
721         /*!< Trigger DMA move data from Endpoint -> SRAM */
722         NRF_USBD->TASKS_STARTISOOUT = 1;
723         /*!< EP_ISO_NUM out using dma */
724         usb_dc_cfg.ep_out[EP_ISO_NUM].is_using_dma = 1;
725       }
726     }
727 
728     /*!< ISOIN: Notify client that data was transferred */
729     if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk)
730     {
731       iso_enabled = true;
732       if (usb_dc_cfg.iso_tx_is_ready == 1)
733       {
734         usb_dc_cfg.iso_tx_is_ready = 0;
735         NRF_USBD->TASKS_STARTISOIN = 1;
736       }
737     }
738 
739     if (!iso_enabled)
740     {
741       /**
742        * ISO endpoint is not used, SOF is only enabled one-time for remote wakeup
743        * so we disable it now
744        */
745       NRF_USBD->INTENCLR = USBD_INTENSET_SOF_Msk;
746     }
747   }
748 
749   /*!< bit 20 */
750   if (int_status & USBD_INTEN_ENDISOOUT_Msk)
751   {
752     if (usb_dc_cfg.ep_out[EP_ISO_NUM].is_using_dma == 1)
753     {
754       usb_dc_cfg.ep_out[EP_ISO_NUM].is_using_dma = 0;
755       uint32_t read_count = NRF_USBD->SIZE.ISOOUT;
756       usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_buf += read_count;
757       usb_dc_cfg.ep_out[EP_ISO_NUM].actual_xfer_len += read_count;
758       usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_len -= read_count;
759 
760       if ((read_count < usb_dc_cfg.ep_out[EP_ISO_NUM].mps) || (usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_len == 0))
761       {
762         usbd_event_ep_out_complete_handler(0, ((EP_ISO_NUM)&0x7f), usb_dc_cfg.ep_out[EP_ISO_NUM].actual_xfer_len);
763       }
764       else
765       {
766         if (usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_len > usb_dc_cfg.ep_out[EP_ISO_NUM].mps)
767         {
768           nrf_usbd_ep_easydma_set_rx(((EP_ISO_NUM)&0x7f), (uint32_t)usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_buf, usb_dc_cfg.ep_out[EP_ISO_NUM].mps);
769         }
770         else
771         {
772           nrf_usbd_ep_easydma_set_rx(((EP_ISO_NUM)&0x7f), (uint32_t)usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_buf, usb_dc_cfg.ep_out[EP_ISO_NUM].xfer_len);
773         }
774       }
775     }
776   }
777 
778   /**
779    * Traverse ordinary out endpoint events, starting from endpoint 1 to endpoint 7,
780    * and end 0 for special processing
781    */
782   for (uint8_t offset = 0; offset < 7; offset++)
783   {
784     if (int_status & (USBD_INTEN_ENDEPOUT1_Msk << offset))
785     {
786       /*!< Out 'offset' transfer complete */
787       uint32_t read_count = NRF_USBD->SIZE.EPOUT[offset + 1];
788       usb_dc_cfg.ep_out[offset + 1].xfer_buf += read_count;
789       usb_dc_cfg.ep_out[offset + 1].actual_xfer_len += read_count;
790       usb_dc_cfg.ep_out[offset + 1].xfer_len -= read_count;
791 
792       if ((read_count < usb_dc_cfg.ep_out[offset + 1].mps) || (usb_dc_cfg.ep_out[offset + 1].xfer_len == 0))
793       {
794         usbd_event_ep_out_complete_handler(0, ((offset + 1) & 0x7f), usb_dc_cfg.ep_out[offset + 1].actual_xfer_len);
795       }
796       else
797       {
798         if (usb_dc_cfg.ep_out[offset + 1].xfer_len > usb_dc_cfg.ep_out[offset + 1].mps)
799         {
800           nrf_usbd_ep_easydma_set_rx(((offset + 1) & 0x7f), (uint32_t)usb_dc_cfg.ep_out[offset + 1].xfer_buf, usb_dc_cfg.ep_out[offset + 1].mps);
801         }
802         else
803         {
804           nrf_usbd_ep_easydma_set_rx(((offset + 1) & 0x7f), (uint32_t)usb_dc_cfg.ep_out[offset + 1].xfer_buf, usb_dc_cfg.ep_out[offset + 1].xfer_len);
805         }
806       }
807     }
808   }
809 
810   /*!< bit 12 */
811   if (int_status & USBD_INTEN_ENDEPOUT0_Msk)
812   {
813     uint32_t read_count = NRF_USBD->SIZE.EPOUT[0];
814     usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
815     usb_dc_cfg.ep_out[0].xfer_len -= read_count;
816 
817     if (usb_dc_cfg.ep_out[0].xfer_len == 0)
818     {
819       /*!< Enable the state phase of endpoint 0 */
820       NRF_USBD->TASKS_EP0STATUS = 1;
821     }
822 
823     usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
824   }
825 
826   /*!< bit 11 */
827   if (int_status & USBD_INTEN_ENDISOIN_Msk)
828   {
829   }
830 
831   /*!< bit 10 */
832   if (int_status & USBD_INTEN_EP0DATADONE_Msk)
833   {
834     switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT)
835     {
836     case 1:
837       /*!< IN */
838       if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps)
839       {
840         usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
841         usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
842         usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
843       }
844       else
845       {
846         usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
847         usb_dc_cfg.ep_in[0].xfer_len = 0;
848         /*!< Enable the state phase of endpoint 0 */
849         usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
850         NRF_USBD->TASKS_EP0STATUS = 1;
851       }
852       break;
853     case 0:
854       if (usb_dc_cfg.setup.bRequest != USB_REQUEST_SET_ADDRESS)
855       {
856         /*!< The data arrives at the usb fifo, starts the dma transmission, and transfers it to the user ram  */
857         NRF_USBD->TASKS_STARTEPOUT[0] = 1;
858       }
859       break;
860     }
861   }
862 
863   /**
864    * Traversing ordinary in endpoint events, starting from endpoint 1 to endpoint 7,
865    * endpoint 0 special processing
866    */
867   for (uint8_t offset = 0; offset < 7; offset++)
868   {
869     if (int_status & (USBD_INTEN_ENDEPIN1_Msk << offset))
870     {
871       /*!< DMA move data completed */
872     }
873   }
874 
875   /*!< bit 1 */
876   if (int_status & USBD_INTEN_STARTED_Msk)
877   {
878     /*!< Easy dma start transfer data */
879   }
880 
881   /*!< bit 2 */
882   if (int_status & USBD_INTEN_ENDEPIN0_Msk)
883   {
884     /*!< EP0 IN DMA move data completed */
885   }
886 
887   /*!< bit 0 */
888   if (int_status & USBD_INTEN_USBRESET_Msk)
889   {
890     NRF_USBD->EPOUTEN = 1UL;
891     NRF_USBD->EPINEN = 1UL;
892 
893     for (int i = 0; i < 8; i++)
894     {
895       NRF_USBD->TASKS_STARTEPIN[i] = 0;
896       NRF_USBD->TASKS_STARTEPOUT[i] = 0;
897     }
898 
899     NRF_USBD->TASKS_STARTISOIN = 0;
900     NRF_USBD->TASKS_STARTISOOUT = 0;
901 
902     /*!< Clear USB Event Interrupt */
903     NRF_USBD->EVENTS_USBEVENT = 0;
904     NRF_USBD->EVENTCAUSE |= NRF_USBD->EVENTCAUSE;
905 
906     /*!< Reset interrupt */
907     NRF_USBD->INTENCLR = NRF_USBD->INTEN;
908     NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk |
909                          USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk | USBD_INTEN_STARTED_Msk;
910 
911     usbd_event_reset_handler(0);
912   }
913 }
914 
915 /**
916  * Errata: USB cannot be enabled.
917  */
chyu_nrf52_errata_187(void)918 static bool chyu_nrf52_errata_187(void)
919 {
920 #ifndef NRF52_SERIES
921   return false;
922 #else
923 #if defined(NRF52820_XXAA) || defined(DEVELOP_IN_NRF52820) || defined(NRF52833_XXAA) || defined(DEVELOP_IN_NRF52833) || defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
924   uint32_t var1 = *(uint32_t *)0x10000130ul;
925   uint32_t var2 = *(uint32_t *)0x10000134ul;
926 #endif
927 #if defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
928   if (var1 == 0x08)
929   {
930     switch (var2)
931     {
932     case 0x00ul:
933       return false;
934     case 0x01ul:
935       return true;
936     case 0x02ul:
937       return true;
938     case 0x03ul:
939       return true;
940     default:
941       return true;
942     }
943   }
944 #endif
945 #if defined(NRF52833_XXAA) || defined(DEVELOP_IN_NRF52833)
946   if (var1 == 0x0D)
947   {
948     switch (var2)
949     {
950     case 0x00ul:
951       return true;
952     case 0x01ul:
953       return true;
954     default:
955       return true;
956     }
957   }
958 #endif
959 #if defined(NRF52820_XXAA) || defined(DEVELOP_IN_NRF52820)
960   if (var1 == 0x10)
961   {
962     switch (var2)
963     {
964     case 0x00ul:
965       return true;
966     case 0x01ul:
967       return true;
968     case 0x02ul:
969       return true;
970     default:
971       return true;
972     }
973   }
974 #endif
975   return false;
976 #endif
977 }
978 
979 /**
980  * Errata: USBD might not reach its active state.
981  */
chyu_nrf52_errata_171(void)982 static bool chyu_nrf52_errata_171(void)
983 {
984 #ifndef NRF52_SERIES
985   return false;
986 #else
987 #if defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
988   uint32_t var1 = *(uint32_t *)0x10000130ul;
989   uint32_t var2 = *(uint32_t *)0x10000134ul;
990 #endif
991 #if defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
992   if (var1 == 0x08)
993   {
994     switch (var2)
995     {
996     case 0x00ul:
997       return true;
998     case 0x01ul:
999       return true;
1000     case 0x02ul:
1001       return true;
1002     case 0x03ul:
1003       return true;
1004     default:
1005       return true;
1006     }
1007   }
1008 #endif
1009   return false;
1010 #endif
1011 }
1012 
1013 /**
1014  * Errata: ISO double buffering not functional.
1015  */
chyu_nrf52_errata_166(void)1016 static bool chyu_nrf52_errata_166(void)
1017 {
1018 #ifndef NRF52_SERIES
1019   return false;
1020 #else
1021 #if defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
1022   uint32_t var1 = *(uint32_t *)0x10000130ul;
1023   uint32_t var2 = *(uint32_t *)0x10000134ul;
1024 #endif
1025 #if defined(NRF52840_XXAA) || defined(DEVELOP_IN_NRF52840)
1026   if (var1 == 0x08)
1027   {
1028     switch (var2)
1029     {
1030     case 0x00ul:
1031       return true;
1032     case 0x01ul:
1033       return true;
1034     case 0x02ul:
1035       return true;
1036     case 0x03ul:
1037       return true;
1038     default:
1039       return true;
1040     }
1041   }
1042 #endif
1043   return false;
1044 #endif
1045 }
1046 
1047 #ifdef SOFTDEVICE_PRESENT
1048 
1049 #include "nrf_mbr.h"
1050 #include "nrf_sdm.h"
1051 #include "nrf_soc.h"
1052 
1053 #ifndef SD_MAGIC_NUMBER
1054 #define SD_MAGIC_NUMBER 0x51B1E5DB
1055 #endif
1056 
is_sd_existed(void)1057 static inline bool is_sd_existed(void)
1058 {
1059   return *((uint32_t *)(SOFTDEVICE_INFO_STRUCT_ADDRESS + 4)) == SD_MAGIC_NUMBER;
1060 }
1061 
1062 /**
1063  * check if SD is existed and enabled
1064  */
is_sd_enabled(void)1065 static inline bool is_sd_enabled(void)
1066 {
1067   if (!is_sd_existed())
1068     return false;
1069 
1070   uint8_t sd_en = false;
1071   (void)sd_softdevice_is_enabled(&sd_en);
1072   return sd_en;
1073 }
1074 #endif
1075 
hfclk_running(void)1076 static bool hfclk_running(void)
1077 {
1078 #ifdef SOFTDEVICE_PRESENT
1079   if (is_sd_enabled())
1080   {
1081     uint32_t is_running = 0;
1082     (void)sd_clock_hfclk_is_running(&is_running);
1083     return (is_running ? true : false);
1084   }
1085 #endif
1086 
1087 #if defined(CLOCK_HFCLKSTAT_SRC_Xtal) || defined(__NRFX_DOXYGEN__)
1088   return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
1089          (CLOCK_HFCLKSTAT_STATE_Msk | (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos));
1090 #else
1091   return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
1092          (CLOCK_HFCLKSTAT_STATE_Msk | (CLOCK_HFCLKSTAT_SRC_HFXO << CLOCK_HFCLKSTAT_SRC_Pos));
1093 #endif
1094 }
1095 
1096 enum
1097 {
1098   NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /*!< HFCLK oscillator started. */
1099 };
1100 
1101 enum
1102 {
1103   NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /*!< Start HFCLK clock source. */
1104   NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP),   /*!< Stop HFCLK clock source. */
1105 };
1106 
hfclk_enable(void)1107 static void hfclk_enable(void)
1108 {
1109   /*!< already running, nothing to do */
1110   if (hfclk_running())
1111     return;
1112 
1113 #ifdef SOFTDEVICE_PRESENT
1114   if (is_sd_enabled())
1115   {
1116     (void)sd_clock_hfclk_request();
1117     return;
1118   }
1119 #endif
1120 
1121   *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + NRF_CLOCK_EVENT_HFCLKSTARTED)) = 0x0UL;
1122   volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + (uint32_t)NRF_CLOCK_EVENT_HFCLKSTARTED));
1123   (void)dummy;
1124   *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + NRF_CLOCK_TASK_HFCLKSTART)) = 0x1UL;
1125 }
1126 
hfclk_disable(void)1127 static void hfclk_disable(void)
1128 {
1129 #ifdef SOFTDEVICE_PRESENT
1130   if (is_sd_enabled())
1131   {
1132     (void)sd_clock_hfclk_release();
1133     return;
1134   }
1135 #endif
1136 
1137   *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + NRF_CLOCK_TASK_HFCLKSTOP)) = 0x1UL;
1138 }
1139 
1140 /**
1141  * Power & Clock Peripheral on nRF5x to manage USB
1142  * USB Bus power is managed by Power module, there are 3 VBUS power events:
1143  * Detected, Ready, Removed. Upon these power events, This function will
1144  * enable ( or disable ) usb & hfclk peripheral, set the usb pin pull up
1145  * accordingly to the controller Startup/Standby Sequence in USBD 51.4 specs.
1146  * Therefore this function must be called to handle USB power event by
1147  * - nrfx_power_usbevt_init() : if Softdevice is not used or enabled
1148  * - SoftDevice SOC event : if SD is used and enabled
1149  */
cherry_usb_hal_nrf_power_event(uint32_t event)1150 void cherry_usb_hal_nrf_power_event(uint32_t event)
1151 {
1152   enum
1153   {
1154     USB_EVT_DETECTED = 0,
1155     USB_EVT_REMOVED = 1,
1156     USB_EVT_READY = 2
1157   };
1158 
1159   switch (event)
1160   {
1161   case USB_EVT_DETECTED:
1162     if (!NRF_USBD->ENABLE)
1163     {
1164       /*!< Prepare for receiving READY event: disable interrupt since we will blocking wait */
1165       NRF_USBD->INTENCLR = USBD_INTEN_USBEVENT_Msk;
1166       NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk;
1167       __ISB();
1168       __DSB();
1169 
1170 #ifdef NRF52_SERIES /*!< NRF53 does not need this errata */
1171       /*!< ERRATA 171, 187, 166 */
1172       if (chyu_nrf52_errata_187())
1173       {
1174         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1175         {
1176           *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1177           *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1178           *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1179         }
1180         else
1181         {
1182           *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1183         }
1184       }
1185 
1186       if (chyu_nrf52_errata_171())
1187       {
1188         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1189         {
1190           *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1191           *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1192           *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1193         }
1194         else
1195         {
1196           *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1197         }
1198       }
1199 #endif
1200 
1201       /*!< Enable the peripheral (will cause Ready event) */
1202       NRF_USBD->ENABLE = 1;
1203       __ISB();
1204       __DSB();
1205 
1206       /*!< Enable HFCLK */
1207       hfclk_enable();
1208     }
1209     break;
1210 
1211   case USB_EVT_READY:
1212     /**
1213      * Skip if pull-up is enabled and HCLK is already running.
1214      * Application probably call this more than necessary.
1215      */
1216     if (NRF_USBD->USBPULLUP && hfclk_running())
1217       break;
1218 
1219     /*!< Waiting for USBD peripheral enabled */
1220     while (!(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE))
1221     {
1222     }
1223 
1224     NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk;
1225     __ISB();
1226     __DSB();
1227 
1228 #ifdef NRF52_SERIES
1229     if (chyu_nrf52_errata_171())
1230     {
1231       if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1232       {
1233         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1234         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1235         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1236       }
1237       else
1238       {
1239         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1240       }
1241     }
1242 
1243     if (chyu_nrf52_errata_187())
1244     {
1245       if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1246       {
1247         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1248         *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1249         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1250       }
1251       else
1252       {
1253         *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1254       }
1255     }
1256 
1257     if (chyu_nrf52_errata_166())
1258     {
1259       *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3;
1260       *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40;
1261 
1262       __ISB();
1263       __DSB();
1264     }
1265 #endif
1266 
1267     /*!< ISO buffer Lower half for IN, upper half for OUT */
1268     NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN;
1269 
1270     /*!< Enable bus-reset interrupt */
1271     NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk;
1272 
1273     /*!< Enable interrupt, priorities should be set by application */
1274     /*!< clear pending irq */
1275     NVIC->ICPR[(((uint32_t)USBD_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)USBD_IRQn) & 0x1FUL));
1276     /**
1277      * Don't enable USBD interrupt yet, if dcd_init() did not finish yet
1278      * Interrupt will be enabled by tud_init(), when USB stack is ready
1279      * to handle interrupts.
1280      */
1281     /*!< Wait for HFCLK */
1282     while (!hfclk_running())
1283     {
1284     }
1285 
1286     /*!< Enable pull up */
1287     NRF_USBD->USBPULLUP = 1;
1288     __ISB();
1289     __DSB();
1290     break;
1291 
1292   case USB_EVT_REMOVED:
1293     if (NRF_USBD->ENABLE)
1294     {
1295       /*!< Disable pull up */
1296       NRF_USBD->USBPULLUP = 0;
1297       __ISB();
1298       __DSB();
1299 
1300       /*!< Disable Interrupt */
1301       NVIC->ICER[(((uint32_t)USBD_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)USBD_IRQn) & 0x1FUL));
1302       __DSB();
1303       __ISB();
1304       /*!< disable all interrupt */
1305       NRF_USBD->INTENCLR = NRF_USBD->INTEN;
1306 
1307       NRF_USBD->ENABLE = 0;
1308       __ISB();
1309       __DSB();
1310       hfclk_disable();
1311     }
1312     break;
1313 
1314   default:
1315     break;
1316   }
1317 }