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 }