1 /*
2  * Copyright (c) 2016 - 2025, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <nrfx.h>
35 
36 #if NRFX_CHECK(NRFX_USBD_ENABLED)
37 
38 #include <nrfx_usbd.h>
39 #include "nrfx_usbd_errata.h"
40 #include <string.h>
41 
42 #define NRFX_LOG_MODULE USBD
43 #include <nrfx_log.h>
44 
45 #ifndef NRFX_USBD_EARLY_DMA_PROCESS
46 /* Try to process DMA request when endpoint transmission has been detected
47  * and just after last EasyDMA has been processed.
48  * It speeds up the transmission a little (about 10% measured)
49  * with a cost of more CPU power used.
50  */
51 #define NRFX_USBD_EARLY_DMA_PROCESS 1
52 #endif
53 
54 #ifndef NRFX_USBD_STARTED_EV_ENABLE
55 #define NRFX_USBD_STARTED_EV_ENABLE    0
56 #endif
57 
58 #ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
59 /*
60  * Respond to an IN token on ISO IN endpoint with ZLP when no data is ready.
61  */
62 #define NRFX_USBD_CONFIG_ISO_IN_ZLP  0
63 #endif
64 
65 #ifndef NRFX_USBD_ISO_DEBUG
66 /* Also generate information about ISOCHRONOUS events and transfers.
67  * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this
68  * option generates a lot of useless messages. */
69 #define NRFX_USBD_ISO_DEBUG 1
70 #endif
71 
72 #ifndef NRFX_USBD_FAILED_TRANSFERS_DEBUG
73 /* Also generate debug information for failed transfers.
74  * It might be useful but may generate a lot of useless debug messages
75  * in some library usages (for example when transfer is generated and the
76  * result is used to check whatever endpoint was busy. */
77 #define NRFX_USBD_FAILED_TRANSFERS_DEBUG 1
78 #endif
79 
80 #ifndef NRFX_USBD_DMAREQ_PROCESS_DEBUG
81 /* Generate additional messages that mark the status inside
82  * @ref usbd_dmareq_process.
83  * It is useful to debug library internals but may generate a lot of
84  * useless debug messages. */
85 #define NRFX_USBD_DMAREQ_PROCESS_DEBUG 1
86 #endif
87 
88 #ifndef NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211
89 /* Anomaly 211 - Device remains in SUSPEND too long when host resumes
90    a bus activity (sending SOF packets) without a RESUME condition. */
91 #define NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 0
92 #endif
93 
94 /**
95  * @defgroup nrfx_usbd_int USB Device driver internal part
96  * @internal
97  * @ingroup nrfx_usbd
98  *
99  * This part contains auxiliary internal macros, variables and functions.
100  * @{
101  */
102 
103 /**
104  * @brief Assert endpoint number validity.
105  *
106  * Internal macro to be used during program creation in debug mode.
107  * Generates assertion if endpoint number is not valid.
108  *
109  * @param ep Endpoint number to validity check.
110  */
111 #define NRFX_USBD_ASSERT_EP_VALID(ep) NRFX_ASSERT(                               \
112     ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT ))  \
113     ||                                                                           \
114     (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \
115 );
116 
117 /**
118  * @brief Lowest position of bit for IN endpoint.
119  *
120  * The first bit position corresponding to IN endpoint.
121  * @sa ep2bit bit2ep
122  */
123 #define NRFX_USBD_EPIN_BITPOS_0   0
124 
125 /**
126  * @brief Lowest position of bit for OUT endpoint.
127  *
128  * The first bit position corresponding to OUT endpoint
129  * @sa ep2bit bit2ep
130  */
131 #define NRFX_USBD_EPOUT_BITPOS_0  16
132 
133 /**
134  * @brief Input endpoint bits mask.
135  */
136 #define NRFX_USBD_EPIN_BIT_MASK (0xFFFFU << NRFX_USBD_EPIN_BITPOS_0)
137 
138 /**
139  * @brief Output endpoint bits mask.
140  */
141 #define NRFX_USBD_EPOUT_BIT_MASK (0xFFFFU << NRFX_USBD_EPOUT_BITPOS_0)
142 
143 /**
144  * @brief Isochronous endpoint bit mask
145  */
146 #define USBD_EPISO_BIT_MASK \
147     ((1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT8)) | \
148      (1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN8)))
149 
150 /**
151  * @brief Auxiliary macro to change EP number into bit position.
152  *
153  * This macro is used by @ref ep2bit function but also for statically check
154  * the bitpos values integrity during compilation.
155  *
156  * @param[in] ep Endpoint number.
157  * @return Endpoint bit position.
158  */
159 #define NRFX_USBD_EP_BITPOS(ep) \
160     ((NRF_USBD_EPIN_CHECK(ep) ? NRFX_USBD_EPIN_BITPOS_0 : NRFX_USBD_EPOUT_BITPOS_0) \
161      + NRF_USBD_EP_NR_GET(ep))
162 
163 /**
164  * @brief Helper macro for creating an endpoint transfer event.
165  *
166  * @param[in] name     Name of the created transfer event variable.
167  * @param[in] endpoint Endpoint number.
168  * @param[in] ep_stat  Endpoint state to report.
169  *
170  * @return Initialized event constant variable.
171  */
172 #define NRFX_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \
173     const nrfx_usbd_evt_t name = {                          \
174         NRFX_USBD_EVT_EPTRANSFER,                           \
175         .data = {                                           \
176             .eptransfer = {                                 \
177                     .ep = endpont,                          \
178                     .status = ep_stat                       \
179             }                                               \
180         }                                                   \
181     }
182 
183 /* Check it the bit positions values match defined DATAEPSTATUS bit positions */
184 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN1)  == USBD_EPDATASTATUS_EPIN1_Pos );
185 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN2)  == USBD_EPDATASTATUS_EPIN2_Pos );
186 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN3)  == USBD_EPDATASTATUS_EPIN3_Pos );
187 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN4)  == USBD_EPDATASTATUS_EPIN4_Pos );
188 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN5)  == USBD_EPDATASTATUS_EPIN5_Pos );
189 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN6)  == USBD_EPDATASTATUS_EPIN6_Pos );
190 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN7)  == USBD_EPDATASTATUS_EPIN7_Pos );
191 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos);
192 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos);
193 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos);
194 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos);
195 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos);
196 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos);
197 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos);
198 
199 
200 /**
201  * @brief Current driver state.
202  */
203 static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
204 
205 /**
206  * @brief Event handler for the driver.
207  *
208  * Event handler that would be called on events.
209  *
210  * @note Currently it cannot be null if any interrupt is activated.
211  */
212 static nrfx_usbd_event_handler_t m_event_handler;
213 
214 /**
215  * @brief Detected state of the bus.
216  *
217  * Internal state changed in interrupts handling when
218  * RESUME or SUSPEND event is processed.
219  *
220  * Values:
221  * - true  - bus suspended
222  * - false - ongoing normal communication on the bus
223  *
224  * @note This is only the bus state and does not mean that the peripheral is in suspend state.
225  */
226 static volatile bool m_bus_suspend;
227 
228 /**
229  * @brief Internal constant that contains interrupts disabled in suspend state.
230  *
231  * Internal constant used in @ref nrfx_usbd_suspend_irq_config and @ref nrfx_usbd_active_irq_config
232  * functions.
233  */
234 static const uint32_t m_irq_disabled_in_suspend =
235     NRF_USBD_INT_ENDEPIN0_MASK    |
236     NRF_USBD_INT_EP0DATADONE_MASK |
237     NRF_USBD_INT_ENDEPOUT0_MASK   |
238     NRF_USBD_INT_EP0SETUP_MASK    |
239     NRF_USBD_INT_DATAEP_MASK;
240 
241 /**
242  * @brief Direction of last received Setup transfer.
243  *
244  * This variable is used to redirect internal setup data event
245  * into selected endpoint (IN or OUT).
246  */
247 static nrfx_usbd_ep_t m_last_setup_dir;
248 
249 /**
250  * @brief Mark endpoint readiness for DMA transfer.
251  *
252  * Bits in this variable are cleared and set in interrupts.
253  * 1 means that endpoint is ready for DMA transfer.
254  * 0 means that DMA transfer cannot be performed on selected endpoint.
255  */
256 static uint32_t m_ep_ready;
257 
258 /**
259  * @brief Mark endpoint with prepared data to transfer by DMA.
260  *
261  * This variable can be from any place in the code (interrupt or main thread).
262  * It would be cleared only from USBD interrupt.
263  *
264  * Mask prepared USBD data for transmission.
265  * It is cleared when no more data to transmit left.
266  */
267 static nrfx_atomic_t m_ep_dma_waiting;
268 
269 /**
270  * @brief Current EasyDMA state.
271  *
272  * Single flag, updated only inside interrupts, that marks current EasyDMA state.
273  * In USBD there is only one DMA channel working in background, and new transfer
274  * cannot be started when there is ongoing transfer on any other channel.
275  */
276 static bool m_dma_pending;
277 
278 /**
279  * @brief Tracks whether total bytes transferred by DMA is even or odd.
280  */
281 static uint8_t m_dma_odd;
282 
283 /**
284  * @brief First time enabling after reset. Used in nRF52 errata 223.
285  */
286 static bool m_first_enable = true;
287 
288 /**
289  * @brief The structure that would hold transfer configuration to every endpoint
290  *
291  * The structure that holds all the data required by the endpoint to proceed
292  * with LIST functionality and generate quick callback directly when data
293  * buffer is ready.
294  */
295 typedef struct
296 {
297     nrfx_usbd_handler_t   handler;         //!< Handler for current transfer, function pointer.
298     void *                p_context;       //!< Context for transfer handler.
299     size_t                transfer_cnt;    //!< Number of transferred bytes in the current transfer.
300     uint16_t              max_packet_size; //!< Configured endpoint size.
301     nrfx_usbd_ep_status_t status;          //!< NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY - this one is calculated.
302 } usbd_ep_state_t;
303 
304 /**
305  * @brief The array of transfer configurations for the endpoints.
306  *
307  * The status of the transfer on each endpoint.
308  */
309 static struct
310 {
311     usbd_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints.
312     usbd_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints.
313 } m_ep_state;
314 
315 /**
316  * @brief Status variables for integrated feeders.
317  *
318  * Current status for integrated feeders (IN transfers).
319  * Integrated feeders are used for default transfers:
320  * 1. Simple RAM transfer.
321  * 2. Simple flash transfer.
322  * 3. RAM transfer with automatic ZLP.
323  * 4. Flash transfer with automatic ZLP.
324  */
325 nrfx_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT];
326 
327 /**
328  * @brief Status variables for integrated consumers.
329  *
330  * Current status for integrated consumers.
331  * Currently one type of transfer is supported:
332  * 1. Transfer to RAM.
333  *
334  * Transfer is finished automatically when received data block is smaller
335  * than the endpoint buffer or all the required data is received.
336  */
337 nrfx_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT];
338 
339 
340 /**
341  * @brief Buffer used to send data directly from FLASH.
342  *
343  * This is internal buffer that would be used to emulate the possibility
344  * to transfer data directly from FLASH.
345  * We do not have to care about the source of data when calling transfer functions.
346  *
347  * We do not need more buffers that one, because only one transfer can be pending
348  * at once.
349  */
350 static uint32_t m_tx_buffer[NRFX_CEIL_DIV(
351     NRFX_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))];
352 
353 /* Early declaration. Documentation above definition. */
354 static void usbd_dmareq_process(void);
355 
356 
357 /**
358  * @brief Change endpoint number to endpoint event code.
359  *
360  * @param ep Endpoint number.
361  *
362  * @return Connected endpoint event code.
363  *
364  * Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE <<.
365  */
nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep)366 static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep)
367 {
368     NRFX_USBD_ASSERT_EP_VALID(ep);
369 
370     static const nrf_usbd_event_t epin_endev[] =
371     {
372         NRF_USBD_EVENT_ENDEPIN0,
373         NRF_USBD_EVENT_ENDEPIN1,
374         NRF_USBD_EVENT_ENDEPIN2,
375         NRF_USBD_EVENT_ENDEPIN3,
376         NRF_USBD_EVENT_ENDEPIN4,
377         NRF_USBD_EVENT_ENDEPIN5,
378         NRF_USBD_EVENT_ENDEPIN6,
379         NRF_USBD_EVENT_ENDEPIN7,
380         NRF_USBD_EVENT_ENDISOIN0
381     };
382     static const nrf_usbd_event_t epout_endev[] =
383     {
384         NRF_USBD_EVENT_ENDEPOUT0,
385         NRF_USBD_EVENT_ENDEPOUT1,
386         NRF_USBD_EVENT_ENDEPOUT2,
387         NRF_USBD_EVENT_ENDEPOUT3,
388         NRF_USBD_EVENT_ENDEPOUT4,
389         NRF_USBD_EVENT_ENDEPOUT5,
390         NRF_USBD_EVENT_ENDEPOUT6,
391         NRF_USBD_EVENT_ENDEPOUT7,
392         NRF_USBD_EVENT_ENDISOOUT0
393     };
394 
395     return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)];
396 }
397 
398 
399 /**
400  * @brief Get interrupt mask for selected endpoint.
401  *
402  * @param[in] ep Endpoint number.
403  *
404  * @return Interrupt mask related to the EasyDMA transfer end for the
405  *         chosen endpoint.
406  */
nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep)407 static inline uint32_t nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep)
408 {
409     NRFX_USBD_ASSERT_EP_VALID(ep);
410 
411     static const uint8_t epin_bitpos[] =
412     {
413         USBD_INTEN_ENDEPIN0_Pos,
414         USBD_INTEN_ENDEPIN1_Pos,
415         USBD_INTEN_ENDEPIN2_Pos,
416         USBD_INTEN_ENDEPIN3_Pos,
417         USBD_INTEN_ENDEPIN4_Pos,
418         USBD_INTEN_ENDEPIN5_Pos,
419         USBD_INTEN_ENDEPIN6_Pos,
420         USBD_INTEN_ENDEPIN7_Pos,
421         USBD_INTEN_ENDISOIN_Pos
422     };
423     static const uint8_t epout_bitpos[] =
424     {
425         USBD_INTEN_ENDEPOUT0_Pos,
426         USBD_INTEN_ENDEPOUT1_Pos,
427         USBD_INTEN_ENDEPOUT2_Pos,
428         USBD_INTEN_ENDEPOUT3_Pos,
429         USBD_INTEN_ENDEPOUT4_Pos,
430         USBD_INTEN_ENDEPOUT5_Pos,
431         USBD_INTEN_ENDEPOUT6_Pos,
432         USBD_INTEN_ENDEPOUT7_Pos,
433         USBD_INTEN_ENDISOOUT_Pos
434     };
435 
436     return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)];
437 }
438 
439 /**
440  * @name Integrated feeders and consumers
441  *
442  * Internal, default functions for transfer processing.
443  * @{
444  */
445 
446 /**
447  * @brief Integrated consumer to RAM buffer.
448  *
449  * @param p_next    See @ref nrfx_usbd_consumer_t documentation.
450  * @param p_context See @ref nrfx_usbd_consumer_t documentation.
451  * @param ep_size   See @ref nrfx_usbd_consumer_t documentation.
452  * @param data_size See @ref nrfx_usbd_consumer_t documentation.
453  *
454  * @retval true  Continue transfer.
455  * @retval false This was the last transfer.
456  */
nrfx_usbd_consumer(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size,size_t data_size)457 bool nrfx_usbd_consumer(
458     nrfx_usbd_ep_transfer_t * p_next,
459     void * p_context,
460     size_t ep_size,
461     size_t data_size)
462 {
463     nrfx_usbd_transfer_t * p_transfer = (nrfx_usbd_transfer_t *)p_context;
464     NRFX_ASSERT(ep_size >= data_size);
465     NRFX_ASSERT((p_transfer->p_data.rx == NULL) ||
466         nrfx_is_in_ram(p_transfer->p_data.rx));
467 
468     size_t size = p_transfer->size;
469     if (size < data_size)
470     {
471         NRFX_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size);
472         /* Buffer size to small */
473         p_next->size = 0;
474         p_next->p_data = p_transfer->p_data;
475     }
476     else
477     {
478         p_next->size = data_size;
479         p_next->p_data = p_transfer->p_data;
480         size -= data_size;
481         p_transfer->size = size;
482         p_transfer->p_data.addr += data_size;
483     }
484     return (ep_size == data_size) && (size != 0);
485 }
486 
487 /**
488  * @brief Integrated feeder from RAM source.
489  *
490  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
491  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
492  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
493  *
494  * @retval true  Continue transfer.
495  * @retval false This was the last transfer.
496  */
nrfx_usbd_feeder_ram(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)497 bool nrfx_usbd_feeder_ram(
498     nrfx_usbd_ep_transfer_t * p_next,
499     void * p_context,
500     size_t ep_size)
501 {
502     nrfx_usbd_transfer_t * p_transfer = (nrfx_usbd_transfer_t *)p_context;
503     NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));
504 
505     size_t tx_size = p_transfer->size;
506     if (tx_size > ep_size)
507     {
508         tx_size = ep_size;
509     }
510 
511     p_next->p_data = p_transfer->p_data;
512     p_next->size = tx_size;
513 
514     p_transfer->size -= tx_size;
515     p_transfer->p_data.addr += tx_size;
516 
517     return (p_transfer->size != 0);
518 }
519 
520 /**
521  * @brief Integrated feeder from RAM source with ZLP.
522  *
523  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
524  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
525  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
526  *
527  * @retval true  Continue transfer.
528  * @retval false This was the last transfer.
529  */
nrfx_usbd_feeder_ram_zlp(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)530 bool nrfx_usbd_feeder_ram_zlp(
531     nrfx_usbd_ep_transfer_t * p_next,
532     void * p_context,
533     size_t ep_size)
534 {
535     nrfx_usbd_transfer_t * p_transfer = (nrfx_usbd_transfer_t *)p_context;
536     NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));
537 
538     size_t tx_size = p_transfer->size;
539     if (tx_size > ep_size)
540     {
541         tx_size = ep_size;
542     }
543 
544     p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx;
545     p_next->size = tx_size;
546 
547     p_transfer->size -= tx_size;
548     p_transfer->p_data.addr += tx_size;
549 
550     return (tx_size != 0);
551 }
552 
553 /**
554  * @brief Integrated feeder from a flash source.
555  *
556  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
557  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
558  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
559  *
560  * @retval true  Continue transfer.
561  * @retval false This was the last transfer.
562  */
nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)563 bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
564 {
565     nrfx_usbd_transfer_t * p_transfer = (nrfx_usbd_transfer_t *)p_context;
566     NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));
567 
568     size_t tx_size  = p_transfer->size;
569     void * p_buffer = nrfx_usbd_feeder_buffer_get();
570 
571     if (tx_size > ep_size)
572     {
573         tx_size = ep_size;
574     }
575 
576     NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE);
577     memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
578 
579     p_next->p_data.tx = p_buffer;
580     p_next->size = tx_size;
581 
582     p_transfer->size -= tx_size;
583     p_transfer->p_data.addr += tx_size;
584 
585     return (p_transfer->size != 0);
586 }
587 
588 /**
589  * @brief Integrated feeder from a flash source with ZLP.
590  *
591  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
592  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
593  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
594  *
595  * @retval true  Continue transfer.
596  * @retval false This was the last transfer.
597  */
nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)598 bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
599 {
600     nrfx_usbd_transfer_t * p_transfer = (nrfx_usbd_transfer_t *)p_context;
601     NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));
602 
603     size_t tx_size  = p_transfer->size;
604     void * p_buffer = nrfx_usbd_feeder_buffer_get();
605 
606     if (tx_size > ep_size)
607     {
608         tx_size = ep_size;
609     }
610 
611     NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE);
612 
613     if (tx_size != 0)
614     {
615         memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
616         p_next->p_data.tx = p_buffer;
617     }
618     else
619     {
620         p_next->p_data.tx = NULL;
621     }
622     p_next->size = tx_size;
623 
624     p_transfer->size -= tx_size;
625     p_transfer->p_data.addr += tx_size;
626 
627     return (tx_size != 0);
628 }
629 
630 /** @} */
631 
632 /**
633  * @brief Change Driver endpoint number to HAL endpoint number.
634  *
635  * @param ep Driver endpoint identifier.
636  *
637  * @return Endpoint identifier in HAL.
638  *
639  * @sa nrfx_usbd_ep_from_hal
640  */
ep_to_hal(nrfx_usbd_ep_t ep)641 static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep)
642 {
643     NRFX_USBD_ASSERT_EP_VALID(ep);
644     return (uint8_t)ep;
645 }
646 
647 /**
648  * @brief Generate start task number for selected endpoint index.
649  *
650  * @param ep Endpoint number.
651  *
652  * @return Task for starting EasyDMA transfer on selected endpoint.
653  */
task_start_ep(nrfx_usbd_ep_t ep)654 static inline nrf_usbd_task_t task_start_ep(nrfx_usbd_ep_t ep)
655 {
656     NRFX_USBD_ASSERT_EP_VALID(ep);
657     return (nrf_usbd_task_t)(
658         (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) +
659         (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t)));
660 }
661 
662 /**
663  * @brief Access selected endpoint state structure.
664  *
665  * Function used to change or just read the state of selected endpoint.
666  * It is used for internal transmission state.
667  *
668  * @param ep Endpoint number.
669  */
ep_state_access(nrfx_usbd_ep_t ep)670 static inline usbd_ep_state_t* ep_state_access(nrfx_usbd_ep_t ep)
671 {
672     NRFX_USBD_ASSERT_EP_VALID(ep);
673     return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) +
674         NRF_USBD_EP_NR_GET(ep));
675 }
676 
677 /**
678  * @brief Change endpoint number to bit position.
679  *
680  * Bit positions are defined the same way as they are placed in DATAEPSTATUS register,
681  * but bits for endpoint 0 are included.
682  *
683  * @param ep Endpoint number.
684  *
685  * @return Bit position related to the given endpoint number.
686  *
687  * @sa bit2ep
688  */
ep2bit(nrfx_usbd_ep_t ep)689 static inline uint8_t ep2bit(nrfx_usbd_ep_t ep)
690 {
691     NRFX_USBD_ASSERT_EP_VALID(ep);
692     return (uint8_t)NRFX_USBD_EP_BITPOS(ep);
693 }
694 
695 /**
696  * @brief Change bit position to endpoint number.
697  *
698  * @param bitpos Bit position.
699  *
700  * @return Endpoint number corresponding to given bit position.
701  *
702  * @sa ep2bit
703  */
bit2ep(uint8_t bitpos)704 static inline nrfx_usbd_ep_t bit2ep(uint8_t bitpos)
705 {
706     NRFX_STATIC_ASSERT(NRFX_USBD_EPOUT_BITPOS_0 > NRFX_USBD_EPIN_BITPOS_0);
707     return (nrfx_usbd_ep_t)((bitpos >= NRFX_USBD_EPOUT_BITPOS_0) ?
708         NRF_USBD_EPOUT(bitpos - NRFX_USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos));
709 }
710 
711 /**
712  * @brief Mark that EasyDMA is working.
713  *
714  * Internal function to set the flag informing about EasyDMA transfer pending.
715  * This function is called always just after the EasyDMA transfer is started.
716  */
usbd_dma_pending_set(void)717 static inline void usbd_dma_pending_set(void)
718 {
719     if (nrfx_usbd_errata_199())
720     {
721         *((volatile uint32_t *)0x40027C1C) = 0x00000082;
722     }
723     m_dma_pending = true;
724 }
725 
726 /**
727  * @brief Mark that EasyDMA is free.
728  *
729  * Internal function to clear the flag informing about EasyDMA transfer pending.
730  * This function is called always just after the finished EasyDMA transfer is detected.
731  */
usbd_dma_pending_clear(void)732 static inline void usbd_dma_pending_clear(void)
733 {
734     if (nrfx_usbd_errata_199())
735     {
736         *((volatile uint32_t *)0x40027C1C) = 0x00000000;
737     }
738     m_dma_pending = false;
739 }
740 
741 /**
742  * @brief Start selected EasyDMA transmission.
743  *
744  * This is internal auxiliary function.
745  * No checking is made if EasyDMA is ready for new transmission.
746  *
747  * @param[in] ep Number of endpoint for transmission.
748  *               If it is OUT endpoint transmission would be directed from endpoint to RAM.
749  *               If it is in endpoint transmission would be directed from RAM to endpoint.
750  */
usbd_dma_start(nrfx_usbd_ep_t ep)751 static inline void usbd_dma_start(nrfx_usbd_ep_t ep)
752 {
753     nrf_usbd_task_trigger(NRF_USBD, task_start_ep(ep));
754 }
755 
nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config)756 void nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config)
757 {
758     nrf_usbd_isoinconfig_set(NRF_USBD, config);
759 }
760 
nrfx_usbd_isoinconfig_get(void)761 nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void)
762 {
763     return nrf_usbd_isoinconfig_get(NRF_USBD);
764 }
765 
766 /**
767  * @brief Abort pending transfer on selected endpoint.
768  *
769  * @param ep Endpoint number.
770  *
771  * @note
772  * This function locks interrupts that may be costly.
773  * It is good idea to test if the endpoint is still busy before calling this function:
774  * @code
775    (m_ep_dma_waiting & (1U << ep2bit(ep)))
776  * @endcode
777  * This function would check it again, but it makes it inside critical section.
778  */
usbd_ep_abort(nrfx_usbd_ep_t ep)779 static inline void usbd_ep_abort(nrfx_usbd_ep_t ep)
780 {
781     NRFX_CRITICAL_SECTION_ENTER();
782 
783     usbd_ep_state_t * p_state = ep_state_access(ep);
784 
785     if (NRF_USBD_EPOUT_CHECK(ep))
786     {
787         /* Host -> Device */
788         if ((~m_ep_dma_waiting) & (1U << ep2bit(ep)))
789         {
790             /* If the bit in m_ep_dma_waiting in cleared - nothing would be
791              * processed inside transfer processing */
792             nrfx_usbd_transfer_out_drop(ep);
793         }
794         else
795         {
796             p_state->handler.consumer = NULL;
797             m_ep_dma_waiting &= ~(1U << ep2bit(ep));
798             m_ep_ready &= ~(1U << ep2bit(ep));
799         }
800         /* Aborted */
801         p_state->status = NRFX_USBD_EP_ABORTED;
802     }
803     else
804     {
805         if(!NRF_USBD_EPISO_CHECK(ep))
806         {
807             /* Workaround: Disarm the endpoint if there is any data buffered. */
808             if(ep != NRFX_USBD_EPIN0)
809             {
810                 *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
811                 uint8_t temp = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
812                 temp |= (1U << 1);
813                 *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
814                 (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
815             }
816             else
817             {
818                 *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7B4;
819                 uint8_t temp = (uint8_t)*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804));
820                 temp |= (1U << 2);
821                 *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) |= temp;
822                 (void)(*((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)));
823             }
824         }
825         if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep)))
826         {
827             /* Device -> Host */
828             m_ep_dma_waiting &= ~(1U << ep2bit(ep));
829             m_ep_ready       |=   1U << ep2bit(ep) ;
830 
831             p_state->handler.feeder = NULL;
832             p_state->status = NRFX_USBD_EP_ABORTED;
833             NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_ABORTED);
834             m_event_handler(&evt);
835         }
836     }
837     NRFX_CRITICAL_SECTION_EXIT();
838 }
839 
nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep)840 void nrfx_usbd_ep_abort(nrfx_usbd_ep_t ep)
841 {
842     usbd_ep_abort(ep);
843 }
844 
845 
846 /**
847  * @brief Abort all pending endpoints.
848  *
849  * Function aborts all pending endpoint transfers.
850  */
usbd_ep_abort_all(void)851 static void usbd_ep_abort_all(void)
852 {
853     uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & NRFX_USBD_EPOUT_BIT_MASK);
854     while (0 != ep_waiting)
855     {
856         uint8_t bitpos = (uint8_t)NRF_CTZ(ep_waiting);
857         if (!NRF_USBD_EPISO_CHECK(bit2ep(bitpos)))
858         {
859             usbd_ep_abort(bit2ep(bitpos));
860         }
861         ep_waiting &= ~(1U << bitpos);
862     }
863 
864     m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0);
865 }
866 
867 /**
868  * @brief Force the USBD interrupt into pending state.
869  *
870  * This function is used to force USBD interrupt to be processed right now.
871  * It makes it possible to process all EasyDMA access on one thread priority level.
872  */
usbd_int_rise(void)873 static inline void usbd_int_rise(void)
874 {
875     NRFX_IRQ_PENDING_SET(USBD_IRQn);
876 }
877 
878 /**
879  * @name USBD interrupt runtimes.
880  *
881  * Interrupt runtimes that would be vectorized using @ref m_isr.
882  * @{
883  */
884 
ev_usbreset_handler(void)885 static void ev_usbreset_handler(void)
886 {
887     m_bus_suspend = false;
888     m_last_setup_dir = NRFX_USBD_EPOUT0;
889 
890     const nrfx_usbd_evt_t evt = {
891             .type = NRFX_USBD_EVT_RESET
892     };
893 
894     m_event_handler(&evt);
895 }
896 
ev_started_handler(void)897 static void ev_started_handler(void)
898 {
899 #if NRFX_USBD_STARTED_EV_ENABLE
900     // Handler not used by the stack.
901     // May be used for debugging.
902 #endif
903 }
904 
905 /**
906  * @brief Handler for EasyDMA event without endpoint clearing.
907  *
908  * This handler would be called when EasyDMA transfer for endpoints that does not require clearing.
909  * All in endpoints are cleared automatically when new EasyDMA transfer is initialized.
910  * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler.
911  *
912  * @param[in] ep Endpoint number.
913  */
nrf_usbd_ep0in_dma_handler(void)914 static inline void nrf_usbd_ep0in_dma_handler(void)
915 {
916     const nrfx_usbd_ep_t ep = NRFX_USBD_EPIN0;
917     NRFX_LOG_DEBUG("USB event: DMA ready IN0");
918     usbd_dma_pending_clear();
919 
920     usbd_ep_state_t * p_state = ep_state_access(ep);
921     if (NRFX_USBD_EP_ABORTED == p_state->status)
922     {
923         /* Clear transfer information just in case */
924         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
925     }
926     else if (p_state->handler.feeder == NULL)
927     {
928         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
929     }
930     else
931     {
932         /* Nothing to do */
933     }
934 }
935 
936 /**
937  * @brief Handler for EasyDMA event without endpoint clearing.
938  *
939  * This handler would be called when EasyDMA transfer for endpoints that does not require clearing.
940  * All in endpoints are cleared automatically when new EasyDMA transfer is initialized.
941  * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler.
942  *
943  * @param[in] ep Endpoint number.
944  */
nrf_usbd_epin_dma_handler(nrfx_usbd_ep_t ep)945 static inline void nrf_usbd_epin_dma_handler(nrfx_usbd_ep_t ep)
946 {
947     NRFX_LOG_DEBUG("USB event: DMA ready IN: %x", ep);
948     NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep));
949     NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep));
950     NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
951     usbd_dma_pending_clear();
952 
953     usbd_ep_state_t * p_state = ep_state_access(ep);
954     if (NRFX_USBD_EP_ABORTED == p_state->status)
955     {
956         /* Clear transfer information just in case */
957         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
958     }
959     else if (p_state->handler.feeder == NULL)
960     {
961         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
962     }
963     else
964     {
965         /* Nothing to do */
966     }
967 }
968 
969 /**
970  * @brief Handler for EasyDMA event from in isochronous endpoint.
971  */
nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep)972 static inline void nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep)
973 {
974     if (NRFX_USBD_ISO_DEBUG)
975     {
976         NRFX_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep);
977     }
978     NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep));
979     NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep));
980     usbd_dma_pending_clear();
981 
982     usbd_ep_state_t * p_state = ep_state_access(ep);
983     if (NRFX_USBD_EP_ABORTED == p_state->status)
984     {
985         /* Clear transfer information just in case */
986         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
987     }
988     else if (p_state->handler.feeder == NULL)
989     {
990         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
991         /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished in this moment */
992         NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
993         m_event_handler(&evt);
994     }
995     else
996     {
997         /* Nothing to do */
998     }
999 }
1000 
1001 /**
1002  * @brief Handler for EasyDMA event for OUT endpoint 0.
1003  *
1004  * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer.
1005  * It cannot be cleared when required transfer is finished because it means the same that accepting the comment.
1006  */
nrf_usbd_ep0out_dma_handler(void)1007 static inline void nrf_usbd_ep0out_dma_handler(void)
1008 {
1009     const nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT0;
1010     NRFX_LOG_DEBUG("USB event: DMA ready OUT0");
1011     usbd_dma_pending_clear();
1012 
1013     usbd_ep_state_t * p_state = ep_state_access(ep);
1014     if (NRFX_USBD_EP_ABORTED == p_state->status)
1015     {
1016         /* Clear transfer information just in case */
1017         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
1018     }
1019     else if (p_state->handler.consumer == NULL)
1020     {
1021         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
1022         /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
1023         NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
1024         m_event_handler(&evt);
1025     }
1026     else
1027     {
1028         nrfx_usbd_setup_data_clear();
1029     }
1030 }
1031 
1032 /**
1033  * @brief Handler for EasyDMA event from endpoinpoint that requires clearing.
1034  *
1035  * This handler would be called when EasyDMA transfer for OUT endpoint has been finished.
1036  *
1037  * @param[in] ep Endpoint number.
1038  */
nrf_usbd_epout_dma_handler(nrfx_usbd_ep_t ep)1039 static inline void nrf_usbd_epout_dma_handler(nrfx_usbd_ep_t ep)
1040 {
1041     NRFX_LOG_DEBUG("DMA ready OUT: %x", ep);
1042     NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep));
1043     NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep));
1044     NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
1045     usbd_dma_pending_clear();
1046 
1047     usbd_ep_state_t * p_state = ep_state_access(ep);
1048     if (NRFX_USBD_EP_ABORTED == p_state->status)
1049     {
1050         /* Clear transfer information just in case */
1051         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
1052     }
1053     else if (p_state->handler.consumer == NULL)
1054     {
1055         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
1056         /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
1057         NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
1058         m_event_handler(&evt);
1059     }
1060     else
1061     {
1062         /* Nothing to do */
1063     }
1064 
1065 #if NRFX_USBD_EARLY_DMA_PROCESS
1066     /* Speed up */
1067     usbd_dmareq_process();
1068 #endif
1069 }
1070 
1071 /**
1072  * @brief Handler for EasyDMA event from out isochronous endpoint.
1073  */
nrf_usbd_epoutiso_dma_handler(nrfx_usbd_ep_t ep)1074 static inline void nrf_usbd_epoutiso_dma_handler(nrfx_usbd_ep_t ep)
1075 {
1076     if (NRFX_USBD_ISO_DEBUG)
1077     {
1078         NRFX_LOG_DEBUG("DMA ready ISOOUT: %x", ep);
1079     }
1080     NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep));
1081     usbd_dma_pending_clear();
1082 
1083     usbd_ep_state_t * p_state = ep_state_access(ep);
1084     if (NRFX_USBD_EP_ABORTED == p_state->status)
1085     {
1086         /* Nothing to do - just ignore */
1087     }
1088     else if (p_state->handler.consumer == NULL)
1089     {
1090         (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
1091         /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
1092         NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
1093         m_event_handler(&evt);
1094     }
1095     else
1096     {
1097         /* Nothing to do */
1098     }
1099 }
1100 
1101 
ev_dma_epin0_handler(void)1102 static void ev_dma_epin0_handler(void)  { nrf_usbd_ep0in_dma_handler(); }
ev_dma_epin1_handler(void)1103 static void ev_dma_epin1_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN1 ); }
ev_dma_epin2_handler(void)1104 static void ev_dma_epin2_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN2 ); }
ev_dma_epin3_handler(void)1105 static void ev_dma_epin3_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN3 ); }
ev_dma_epin4_handler(void)1106 static void ev_dma_epin4_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN4 ); }
ev_dma_epin5_handler(void)1107 static void ev_dma_epin5_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN5 ); }
ev_dma_epin6_handler(void)1108 static void ev_dma_epin6_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN6 ); }
ev_dma_epin7_handler(void)1109 static void ev_dma_epin7_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN7 ); }
ev_dma_epin8_handler(void)1110 static void ev_dma_epin8_handler(void)  { nrf_usbd_epiniso_dma_handler(NRFX_USBD_EPIN8 ); }
1111 
ev_dma_epout0_handler(void)1112 static void ev_dma_epout0_handler(void) { nrf_usbd_ep0out_dma_handler(); }
ev_dma_epout1_handler(void)1113 static void ev_dma_epout1_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT1); }
ev_dma_epout2_handler(void)1114 static void ev_dma_epout2_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT2); }
ev_dma_epout3_handler(void)1115 static void ev_dma_epout3_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT3); }
ev_dma_epout4_handler(void)1116 static void ev_dma_epout4_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT4); }
ev_dma_epout5_handler(void)1117 static void ev_dma_epout5_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT5); }
ev_dma_epout6_handler(void)1118 static void ev_dma_epout6_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT6); }
ev_dma_epout7_handler(void)1119 static void ev_dma_epout7_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT7); }
ev_dma_epout8_handler(void)1120 static void ev_dma_epout8_handler(void) { nrf_usbd_epoutiso_dma_handler(NRFX_USBD_EPOUT8); }
1121 
ev_sof_handler(void)1122 static void ev_sof_handler(void)
1123 {
1124     nrfx_usbd_evt_t evt =  {
1125             NRFX_USBD_EVT_SOF,
1126             .data = { .sof = { .framecnt = (uint16_t)nrf_usbd_framecntr_get(NRF_USBD) }}
1127     };
1128 
1129     /* Process isochronous endpoints */
1130     uint32_t iso_ready_mask = (1U << ep2bit(NRFX_USBD_EPIN8));
1131     if (nrf_usbd_episoout_size_get(NRF_USBD, NRFX_USBD_EPOUT8) != NRF_USBD_EPISOOUT_NO_DATA)
1132     {
1133         iso_ready_mask |= (1U << ep2bit(NRFX_USBD_EPOUT8));
1134     }
1135     m_ep_ready |= iso_ready_mask;
1136 
1137     m_event_handler(&evt);
1138 }
1139 
1140 /**
1141  * @brief React on data transfer finished.
1142  *
1143  * Auxiliary internal function.
1144  * @param ep     Endpoint number.
1145  * @param bitpos Bit position for selected endpoint number.
1146  */
usbd_ep_data_handler(nrfx_usbd_ep_t ep,uint8_t bitpos)1147 static void usbd_ep_data_handler(nrfx_usbd_ep_t ep, uint8_t bitpos)
1148 {
1149     NRFX_LOG_DEBUG("USBD event: EndpointData: %x", ep);
1150     /* Mark endpoint ready for next DMA access */
1151     m_ep_ready |= (1U << bitpos);
1152 
1153     if (NRF_USBD_EPIN_CHECK(ep))
1154     {
1155         /* IN endpoint (Device -> Host) */
1156 
1157         /* Secure against the race condition that occurs when an IN transfer is interrupted
1158          * by an OUT transaction, which in turn is interrupted by a process with higher priority.
1159          * If the IN events ENDEPIN and EPDATA arrive during that high priority process,
1160          * the OUT handler might call usbd_ep_data_handler without calling
1161          * nrf_usbd_epin_dma_handler (or nrf_usbd_ep0in_dma_handler) for the IN transaction.
1162          */
1163         if (nrf_usbd_event_get_and_clear(NRF_USBD, nrfx_usbd_ep_to_endevent(ep)))
1164         {
1165             if (ep != NRFX_USBD_EPIN0)
1166             {
1167                 nrf_usbd_epin_dma_handler(ep);
1168             }
1169             else
1170             {
1171                 nrf_usbd_ep0in_dma_handler();
1172             }
1173         }
1174 
1175         if (0 == (m_ep_dma_waiting & (1U << bitpos)))
1176         {
1177             NRFX_LOG_DEBUG("USBD event: EndpointData: In finished");
1178             /* No more data to be send - transmission finished */
1179             NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
1180             m_event_handler(&evt);
1181         }
1182     }
1183     else
1184     {
1185         /* OUT endpoint (Host -> Device) */
1186         if (0 == (m_ep_dma_waiting & (1U << bitpos)))
1187         {
1188             NRFX_LOG_DEBUG("USBD event: EndpointData: Out waiting");
1189             /* No buffer prepared - send event to the application */
1190             NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_WAITING);
1191             m_event_handler(&evt);
1192         }
1193     }
1194 }
1195 
ev_setup_data_handler(void)1196 static void ev_setup_data_handler(void)
1197 {
1198     usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir));
1199 }
1200 
ev_setup_handler(void)1201 static void ev_setup_handler(void)
1202 {
1203     NRFX_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )",
1204         nrf_usbd_setup_bmrequesttype_get(NRF_USBD),
1205         nrf_usbd_setup_brequest_get(NRF_USBD),
1206         nrf_usbd_setup_wvalue_get(NRF_USBD),
1207         nrf_usbd_setup_windex_get(NRF_USBD),
1208         nrf_usbd_setup_wlength_get(NRF_USBD));
1209     uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD);
1210 
1211     if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK))
1212         & (1U <<ep2bit(m_last_setup_dir)))
1213     {
1214         NRFX_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0");
1215         usbd_ep_abort(m_last_setup_dir);
1216     }
1217 
1218     m_last_setup_dir =
1219         ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) ==
1220          (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) ?
1221         NRFX_USBD_EPOUT0 : NRFX_USBD_EPIN0;
1222 
1223     (void)(NRFX_ATOMIC_FETCH_AND(
1224         &m_ep_dma_waiting,
1225         ~((1U << ep2bit(NRFX_USBD_EPOUT0)) | (1U << ep2bit(NRFX_USBD_EPIN0)))));
1226     m_ep_ready |= 1U << ep2bit(NRFX_USBD_EPIN0);
1227 
1228 
1229     const nrfx_usbd_evt_t evt = {
1230             .type = NRFX_USBD_EVT_SETUP
1231     };
1232     m_event_handler(&evt);
1233 }
1234 
ev_usbevent_handler(void)1235 static void ev_usbevent_handler(void)
1236 {
1237     uint32_t event = nrf_usbd_eventcause_get_and_clear(NRF_USBD);
1238 
1239     if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK)
1240     {
1241         NRFX_LOG_DEBUG("USBD event: ISOOUTCRC");
1242         /* Currently no support */
1243     }
1244     if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK)
1245     {
1246         NRFX_LOG_DEBUG("USBD event: SUSPEND");
1247         m_bus_suspend = true;
1248         const nrfx_usbd_evt_t evt = {
1249                 .type = NRFX_USBD_EVT_SUSPEND
1250         };
1251         m_event_handler(&evt);
1252     }
1253     if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK)
1254     {
1255         NRFX_LOG_DEBUG("USBD event: RESUME");
1256         m_bus_suspend = false;
1257         const nrfx_usbd_evt_t evt = {
1258                 .type = NRFX_USBD_EVT_RESUME
1259         };
1260         m_event_handler(&evt);
1261     }
1262     if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK)
1263     {
1264         NRFX_LOG_DEBUG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active");
1265         if (m_bus_suspend)
1266         {
1267             NRFX_ASSERT(!nrf_usbd_lowpower_check(NRF_USBD));
1268             m_bus_suspend = false;
1269 
1270             nrf_usbd_dpdmvalue_set(NRF_USBD, NRF_USBD_DPDMVALUE_RESUME);
1271             nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_DRIVEDPDM);
1272 
1273             const nrfx_usbd_evt_t evt = {
1274                     .type = NRFX_USBD_EVT_WUREQ
1275             };
1276             m_event_handler(&evt);
1277         }
1278     }
1279 }
1280 
ev_epdata_handler(void)1281 static void ev_epdata_handler(void)
1282 {
1283     /* Get all endpoints that have acknowledged transfer */
1284     uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear(NRF_USBD);
1285     NRFX_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus);
1286 
1287     /* All finished endpoint have to be marked as busy */
1288     while (dataepstatus)
1289     {
1290         uint8_t bitpos    = (uint8_t)NRF_CTZ(dataepstatus);
1291         nrfx_usbd_ep_t ep = bit2ep(bitpos);
1292         dataepstatus &= ~(1UL << bitpos);
1293 
1294         (void)(usbd_ep_data_handler(ep, bitpos));
1295     }
1296     if (NRFX_USBD_EARLY_DMA_PROCESS)
1297     {
1298         /* Speed up */
1299         usbd_dmareq_process();
1300     }
1301 }
1302 
1303 /**
1304  * @brief Function to select the endpoint to start.
1305  *
1306  * Function that realizes algorithm to schedule right channel for EasyDMA transfer.
1307  * It gets a variable with flags for the endpoints currently requiring transfer.
1308  *
1309  * @param[in] req Bit flags for channels currently requiring transfer.
1310  *                Bits 0...8 used for IN endpoints.
1311  *                Bits 16...24 used for OUT endpoints.
1312  * @note
1313  * This function would be never called with 0 as a @c req argument.
1314  * @return The bit number of the endpoint that should be processed now.
1315  */
usbd_dma_scheduler_algorithm(uint32_t req)1316 static uint8_t usbd_dma_scheduler_algorithm(uint32_t req)
1317 {
1318     /* Only prioritized scheduling mode is supported. */
1319     return (uint8_t)NRF_CTZ(req);
1320 }
1321 
1322 /**
1323  * @brief Get the size of isochronous endpoint.
1324  *
1325  * The size of isochronous endpoint is configurable.
1326  * This function returns the size of isochronous buffer taking into account
1327  * current configuration.
1328  *
1329  * @param[in] ep Endpoint number.
1330  *
1331  * @return The size of endpoint buffer.
1332  */
usbd_ep_iso_capacity(nrfx_usbd_ep_t ep)1333 static inline size_t usbd_ep_iso_capacity(nrfx_usbd_ep_t ep)
1334 {
1335     (void)ep;
1336     nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get(NRF_USBD);
1337     if (NRF_USBD_ISOSPLIT_HALF == split)
1338     {
1339         return NRFX_USBD_ISOSIZE / 2;
1340     }
1341     return NRFX_USBD_ISOSIZE;
1342 }
1343 
1344 /**
1345  * @brief Process all DMA requests.
1346  *
1347  * Function that have to be called from USBD interrupt handler.
1348  * It have to be called when all the interrupts connected with endpoints transfer
1349  * and DMA transfer are already handled.
1350  */
usbd_dmareq_process(void)1351 static void usbd_dmareq_process(void)
1352 {
1353     if (!m_dma_pending)
1354     {
1355         uint32_t req;
1356         while (0 != (req = m_ep_dma_waiting & m_ep_ready))
1357         {
1358             uint8_t pos;
1359             if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST && ((req & USBD_EPISO_BIT_MASK) != 0))
1360             {
1361                 pos = usbd_dma_scheduler_algorithm(req & USBD_EPISO_BIT_MASK);
1362             }
1363             else
1364             {
1365                 pos = usbd_dma_scheduler_algorithm(req);
1366             }
1367             nrfx_usbd_ep_t ep = bit2ep(pos);
1368             usbd_ep_state_t * p_state = ep_state_access(ep);
1369 
1370             nrfx_usbd_ep_transfer_t transfer;
1371             bool continue_transfer;
1372 
1373             NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) ==
1374                 offsetof(usbd_ep_state_t, handler.consumer));
1375             NRFX_ASSERT((p_state->handler.feeder) != NULL);
1376 
1377             if (NRF_USBD_EPIN_CHECK(ep))
1378             {
1379                 /* Device -> Host */
1380                 continue_transfer = p_state->handler.feeder(
1381                     &transfer,
1382                     p_state->p_context,
1383                     p_state->max_packet_size);
1384 
1385                 if (!continue_transfer)
1386                 {
1387                     p_state->handler.feeder = NULL;
1388                 }
1389             }
1390             else
1391             {
1392                 /* Host -> Device */
1393                 const size_t rx_size = nrfx_usbd_epout_size_get(ep);
1394                 continue_transfer = p_state->handler.consumer(
1395                     &transfer,
1396                     p_state->p_context,
1397                     p_state->max_packet_size,
1398                     rx_size);
1399 
1400                 if (transfer.p_data.rx == NULL)
1401                 {
1402                     /* Dropping transfer - allow processing */
1403                     NRFX_ASSERT(transfer.size == 0);
1404                 }
1405                 else if (transfer.size < rx_size)
1406                 {
1407                     NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
1408                     p_state->status = NRFX_USBD_EP_OVERLOAD;
1409                     (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << pos)));
1410                     NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OVERLOAD);
1411                     m_event_handler(&evt);
1412                     /* This endpoint will not be transmitted now, repeat the loop */
1413                     continue;
1414                 }
1415                 else
1416                 {
1417                     /* Nothing to do - only check integrity if assertions are enabled */
1418                     NRFX_ASSERT(transfer.size == rx_size);
1419                 }
1420 
1421                 if (!continue_transfer)
1422                 {
1423                     p_state->handler.consumer = NULL;
1424                 }
1425             }
1426 
1427             usbd_dma_pending_set();
1428             m_ep_ready &= ~(1U << pos);
1429             if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
1430             {
1431                 NRFX_LOG_DEBUG(
1432                     "USB DMA process: Starting transfer on EP: %x, size: %u",
1433                     ep,
1434                     transfer.size);
1435             }
1436             /* Update number of currently transferred bytes */
1437             p_state->transfer_cnt += transfer.size;
1438             /* Start transfer to the endpoint buffer */
1439             nrf_usbd_ep_easydma_set(NRF_USBD, ep, transfer.p_data.addr, (uint32_t)transfer.size);
1440 
1441             usbd_dma_start(ep);
1442             /* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer.
1443              * This is quick fix to maintain stability of the stack.
1444              * It cost some performance but makes stack stable. */
1445             while (!nrf_usbd_event_check(NRF_USBD, nrfx_usbd_ep_to_endevent(ep)))
1446             {
1447                 /* Empty */
1448             }
1449             /* DMA finished, track if total bytes transferred is even or odd */
1450             m_dma_odd ^= nrf_usbd_ep_amount_get(NRF_USBD, ep) & 1;
1451 
1452             if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
1453             {
1454                 NRFX_LOG_DEBUG("USB DMA process - finishing");
1455             }
1456             /* Transfer started - exit the loop */
1457             break;
1458         }
1459     }
1460     else
1461     {
1462         if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
1463         {
1464             NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy");
1465         }
1466     }
1467 }
1468 
1469 /**
1470  * @brief Wait for a specified eventcause and clear it afterwards.
1471  */
usbd_eventcause_wait_and_clear(nrf_usbd_eventcause_mask_t eventcause)1472 static inline void usbd_eventcause_wait_and_clear(nrf_usbd_eventcause_mask_t eventcause)
1473 {
1474     while (0 == (eventcause & nrf_usbd_eventcause_get(NRF_USBD)))
1475     {
1476         /* Empty loop */
1477     }
1478     nrf_usbd_eventcause_clear(NRF_USBD, eventcause);
1479 }
1480 
1481 /**
1482  * @brief Begin errata 171.
1483  */
usbd_errata_171_begin(void)1484 static inline void usbd_errata_171_begin(void)
1485 {
1486     NRFX_CRITICAL_SECTION_ENTER();
1487     if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1488     {
1489         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1490         *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1491         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1492     }
1493     else
1494     {
1495         *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1496     }
1497     NRFX_CRITICAL_SECTION_EXIT();
1498 }
1499 
1500 /**
1501  * @brief End errata 171.
1502  */
usbd_errata_171_end(void)1503 static inline void usbd_errata_171_end(void)
1504 {
1505     NRFX_CRITICAL_SECTION_ENTER();
1506     if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1507     {
1508         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1509         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1510         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1511     }
1512     else
1513     {
1514         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1515     }
1516     NRFX_CRITICAL_SECTION_EXIT();
1517 }
1518 
1519 /**
1520  * @brief Begin erratas 187 and 211.
1521  */
usbd_errata_187_211_begin(void)1522 static inline void usbd_errata_187_211_begin(void)
1523 {
1524     NRFX_CRITICAL_SECTION_ENTER();
1525     if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1526     {
1527         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1528         *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1529         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1530     }
1531     else
1532     {
1533         *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1534     }
1535     NRFX_CRITICAL_SECTION_EXIT();
1536 }
1537 
1538 /**
1539  * @brief End erratas 187 and 211.
1540  */
usbd_errata_187_211_end(void)1541 static inline void usbd_errata_187_211_end(void)
1542 {
1543     NRFX_CRITICAL_SECTION_ENTER();
1544     if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1545     {
1546         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1547         *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1548         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1549     }
1550     else
1551     {
1552         *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1553     }
1554     NRFX_CRITICAL_SECTION_EXIT();
1555 }
1556 
1557 /**
1558  * @brief Enable USBD peripheral.
1559  */
usbd_enable(void)1560 static void usbd_enable(void)
1561 {
1562     if (nrfx_usbd_errata_187())
1563     {
1564         usbd_errata_187_211_begin();
1565     }
1566 
1567     if (nrfx_usbd_errata_171())
1568     {
1569         usbd_errata_171_begin();
1570     }
1571 
1572     /* Enable the peripheral */
1573     nrf_usbd_enable(NRF_USBD);
1574 
1575     /* Waiting for peripheral to enable, this should take a few us */
1576     usbd_eventcause_wait_and_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
1577 
1578     if (nrfx_usbd_errata_171())
1579     {
1580         usbd_errata_171_end();
1581     }
1582 
1583     if (nrfx_usbd_errata_187())
1584     {
1585         usbd_errata_187_211_end();
1586     }
1587 }
1588 /** @} */
1589 
1590 /**
1591  * @brief USBD interrupt service routines.
1592  *
1593  */
1594 static const nrfx_irq_handler_t m_isr[] =
1595 {
1596     [USBD_INTEN_USBRESET_Pos   ] = ev_usbreset_handler,
1597     [USBD_INTEN_STARTED_Pos    ] = ev_started_handler,
1598     [USBD_INTEN_ENDEPIN0_Pos   ] = ev_dma_epin0_handler,
1599     [USBD_INTEN_ENDEPIN1_Pos   ] = ev_dma_epin1_handler,
1600     [USBD_INTEN_ENDEPIN2_Pos   ] = ev_dma_epin2_handler,
1601     [USBD_INTEN_ENDEPIN3_Pos   ] = ev_dma_epin3_handler,
1602     [USBD_INTEN_ENDEPIN4_Pos   ] = ev_dma_epin4_handler,
1603     [USBD_INTEN_ENDEPIN5_Pos   ] = ev_dma_epin5_handler,
1604     [USBD_INTEN_ENDEPIN6_Pos   ] = ev_dma_epin6_handler,
1605     [USBD_INTEN_ENDEPIN7_Pos   ] = ev_dma_epin7_handler,
1606     [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler,
1607     [USBD_INTEN_ENDISOIN_Pos   ] = ev_dma_epin8_handler,
1608     [USBD_INTEN_ENDEPOUT0_Pos  ] = ev_dma_epout0_handler,
1609     [USBD_INTEN_ENDEPOUT1_Pos  ] = ev_dma_epout1_handler,
1610     [USBD_INTEN_ENDEPOUT2_Pos  ] = ev_dma_epout2_handler,
1611     [USBD_INTEN_ENDEPOUT3_Pos  ] = ev_dma_epout3_handler,
1612     [USBD_INTEN_ENDEPOUT4_Pos  ] = ev_dma_epout4_handler,
1613     [USBD_INTEN_ENDEPOUT5_Pos  ] = ev_dma_epout5_handler,
1614     [USBD_INTEN_ENDEPOUT6_Pos  ] = ev_dma_epout6_handler,
1615     [USBD_INTEN_ENDEPOUT7_Pos  ] = ev_dma_epout7_handler,
1616     [USBD_INTEN_ENDISOOUT_Pos  ] = ev_dma_epout8_handler,
1617     [USBD_INTEN_SOF_Pos        ] = ev_sof_handler,
1618     [USBD_INTEN_USBEVENT_Pos   ] = ev_usbevent_handler,
1619     [USBD_INTEN_EP0SETUP_Pos   ] = ev_setup_handler,
1620     [USBD_INTEN_EPDATA_Pos     ] = ev_epdata_handler
1621 };
1622 
1623 /**
1624  * @name Interrupt handlers
1625  *
1626  * @{
1627  */
nrfx_usbd_irq_handler(void)1628 void nrfx_usbd_irq_handler(void)
1629 {
1630     const uint32_t enabled = nrf_usbd_int_enable_get(NRF_USBD);
1631     uint32_t to_process = enabled;
1632     uint32_t active = 0;
1633 
1634     /* Check all enabled interrupts */
1635     while (to_process)
1636     {
1637         uint8_t event_nr = (uint8_t)NRF_CTZ(to_process);
1638         if (nrf_usbd_event_get_and_clear(NRF_USBD,
1639                                          (nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr)))
1640         {
1641             active |= 1UL << event_nr;
1642         }
1643         to_process &= ~(1UL << event_nr);
1644     }
1645 
1646     /* Process the active interrupts */
1647     bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK);
1648     active &= (uint32_t)~NRF_USBD_INT_EP0SETUP_MASK;
1649 
1650     while (active)
1651     {
1652         uint8_t event_nr = (uint8_t)NRF_CTZ(active);
1653         m_isr[event_nr]();
1654         active &= ~(1UL << event_nr);
1655     }
1656     usbd_dmareq_process();
1657 
1658     if (setup_active)
1659     {
1660         m_isr[USBD_INTEN_EP0SETUP_Pos]();
1661     }
1662 }
1663 
1664 /** @} */
1665 /** @} */
1666 
nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler)1667 nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler)
1668 {
1669     NRFX_ASSERT(event_handler);
1670 
1671     if (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED)
1672     {
1673 #if NRFX_API_VER_AT_LEAST(3, 2, 0)
1674         return NRFX_ERROR_ALREADY;
1675 #else
1676         return NRFX_ERROR_INVALID_STATE;
1677 #endif
1678     }
1679 
1680     m_event_handler = event_handler;
1681     m_drv_state = NRFX_DRV_STATE_INITIALIZED;
1682 
1683     uint8_t n;
1684     for (n = 0; n < NRF_USBD_EPIN_CNT; ++n)
1685     {
1686         nrfx_usbd_ep_t ep = NRFX_USBD_EPIN(n);
1687         nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
1688             (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
1689         usbd_ep_state_t * p_state = ep_state_access(ep);
1690         p_state->status = NRFX_USBD_EP_OK;
1691         p_state->handler.feeder = NULL;
1692         p_state->transfer_cnt = 0;
1693     }
1694     for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n)
1695     {
1696         nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT(n);
1697         nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
1698             (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
1699         usbd_ep_state_t * p_state = ep_state_access(ep);
1700         p_state->status = NRFX_USBD_EP_OK;
1701         p_state->handler.consumer = NULL;
1702         p_state->transfer_cnt = 0;
1703     }
1704 
1705     return NRFX_SUCCESS;
1706 }
1707 
nrfx_usbd_uninit(void)1708 void nrfx_usbd_uninit(void)
1709 {
1710     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
1711 
1712     m_event_handler = NULL;
1713     m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
1714     return;
1715 }
1716 
nrfx_usbd_init_check(void)1717 bool nrfx_usbd_init_check(void)
1718 {
1719     return (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);
1720 }
1721 
nrfx_usbd_enable(void)1722 void nrfx_usbd_enable(void)
1723 {
1724     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
1725 
1726     /* Prepare for READY event receiving */
1727     nrf_usbd_eventcause_clear(NRF_USBD, NRF_USBD_EVENTCAUSE_READY_MASK);
1728 
1729     usbd_enable();
1730 
1731     if (nrfx_usbd_errata_223() && m_first_enable)
1732     {
1733          nrf_usbd_disable(NRF_USBD);
1734 
1735          usbd_enable();
1736 
1737          m_first_enable = false;
1738     }
1739 
1740 #if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211
1741     if (nrfx_usbd_errata_187() || nrfx_usbd_errata_211())
1742 #else
1743     if (nrfx_usbd_errata_187())
1744 #endif
1745     {
1746         usbd_errata_187_211_begin();
1747     }
1748 
1749     if (nrfx_usbd_errata_166())
1750     {
1751         *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x800)) = 0x7E3;
1752         *((volatile uint32_t *)((uint32_t)(NRF_USBD) + 0x804)) = 0x40;
1753         __ISB();
1754         __DSB();
1755     }
1756 
1757     nrf_usbd_isosplit_set(NRF_USBD, NRF_USBD_ISOSPLIT_HALF);
1758 
1759     if (NRFX_USBD_CONFIG_ISO_IN_ZLP)
1760     {
1761         nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA);
1762     }
1763     else
1764     {
1765         nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP);
1766     }
1767 
1768     m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0);
1769     m_ep_dma_waiting = 0;
1770     m_dma_odd = 0;
1771     usbd_dma_pending_clear();
1772     m_last_setup_dir = NRFX_USBD_EPOUT0;
1773 
1774     m_drv_state = NRFX_DRV_STATE_POWERED_ON;
1775 
1776 #if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211
1777     if (nrfx_usbd_errata_187() && !nrfx_usbd_errata_211())
1778 #else
1779     if (nrfx_usbd_errata_187())
1780 #endif
1781     {
1782         usbd_errata_187_211_end();
1783     }
1784 }
1785 
nrfx_usbd_disable(void)1786 void nrfx_usbd_disable(void)
1787 {
1788     NRFX_ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);
1789 
1790     /* Stop just in case */
1791     nrfx_usbd_stop();
1792 
1793     /* Disable all parts */
1794     nrf_usbd_int_disable(NRF_USBD, nrf_usbd_int_enable_get(NRF_USBD));
1795     if (m_dma_odd)
1796     {
1797         /* Prevent invalid bus request after next USBD enable by ensuring
1798          * that total number of bytes transferred by DMA is even. */
1799         nrf_usbd_event_clear(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0);
1800         nrf_usbd_ep_easydma_set(NRF_USBD, NRFX_USBD_EPIN0, (uint32_t)&m_dma_odd, 1);
1801         usbd_dma_start(NRFX_USBD_EPIN0);
1802         while (!nrf_usbd_event_check(NRF_USBD, NRF_USBD_EVENT_ENDEPIN0))
1803         {}
1804         m_dma_odd = 0;
1805     }
1806     nrf_usbd_disable(NRF_USBD);
1807     usbd_dma_pending_clear();
1808     m_drv_state = NRFX_DRV_STATE_INITIALIZED;
1809 
1810 #if NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211
1811     if (nrfx_usbd_errata_211())
1812     {
1813         usbd_errata_187_211_end();
1814     }
1815 #endif
1816 }
1817 
nrfx_usbd_start(bool enable_sof)1818 void nrfx_usbd_start(bool enable_sof)
1819 {
1820     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
1821     m_bus_suspend = false;
1822 
1823     uint32_t ints_to_enable =
1824        NRF_USBD_INT_USBRESET_MASK     |
1825 #if NRFX_USBD_STARTED_EV_ENABLE
1826        NRF_USBD_INT_STARTED_MASK      |
1827 #endif
1828        NRF_USBD_INT_ENDEPIN0_MASK     |
1829        NRF_USBD_INT_EP0DATADONE_MASK  |
1830        NRF_USBD_INT_ENDEPOUT0_MASK    |
1831        NRF_USBD_INT_USBEVENT_MASK     |
1832        NRF_USBD_INT_EP0SETUP_MASK     |
1833        NRF_USBD_INT_DATAEP_MASK;
1834 
1835    if (enable_sof)
1836    {
1837        ints_to_enable |= NRF_USBD_INT_SOF_MASK;
1838    }
1839 
1840    /* Enable all required interrupts */
1841    nrf_usbd_int_enable(NRF_USBD, ints_to_enable);
1842 
1843    /* Enable interrupt globally */
1844    NRFX_IRQ_PRIORITY_SET(USBD_IRQn, NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY);
1845    NRFX_IRQ_ENABLE(USBD_IRQn);
1846 
1847    /* Enable pullups */
1848    nrf_usbd_pullup_enable(NRF_USBD);
1849 }
1850 
nrfx_usbd_stop(void)1851 void nrfx_usbd_stop(void)
1852 {
1853     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
1854 
1855     /* Clear interrupt */
1856     NRFX_IRQ_PENDING_CLEAR(USBD_IRQn);
1857 
1858     if (NRFX_IRQ_IS_ENABLED(USBD_IRQn))
1859     {
1860         /* Abort transfers */
1861         usbd_ep_abort_all();
1862 
1863         /* Disable pullups */
1864         nrf_usbd_pullup_disable(NRF_USBD);
1865 
1866         /* Disable interrupt globally */
1867         NRFX_IRQ_DISABLE(USBD_IRQn);
1868 
1869         /* Disable all interrupts */
1870         nrf_usbd_int_disable(NRF_USBD, ~0U);
1871     }
1872 }
1873 
nrfx_usbd_is_initialized(void)1874 bool nrfx_usbd_is_initialized(void)
1875 {
1876     return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED);
1877 }
1878 
nrfx_usbd_is_enabled(void)1879 bool nrfx_usbd_is_enabled(void)
1880 {
1881     return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON);
1882 }
1883 
nrfx_usbd_is_started(void)1884 bool nrfx_usbd_is_started(void)
1885 {
1886     return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn));
1887 }
1888 
nrfx_usbd_suspend(void)1889 bool nrfx_usbd_suspend(void)
1890 {
1891     bool suspended = false;
1892 
1893     NRFX_CRITICAL_SECTION_ENTER();
1894     if (m_bus_suspend)
1895     {
1896         if (!(nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK))
1897         {
1898             nrf_usbd_lowpower_enable(NRF_USBD);
1899             if (nrf_usbd_eventcause_get(NRF_USBD) & NRF_USBD_EVENTCAUSE_RESUME_MASK)
1900             {
1901                 nrf_usbd_lowpower_disable(NRF_USBD);
1902             }
1903             else
1904             {
1905                 suspended = true;
1906             }
1907         }
1908     }
1909     NRFX_CRITICAL_SECTION_EXIT();
1910 
1911     return suspended;
1912 }
1913 
nrfx_usbd_wakeup_req(void)1914 bool nrfx_usbd_wakeup_req(void)
1915 {
1916     bool started = false;
1917 
1918     NRFX_CRITICAL_SECTION_ENTER();
1919     if (m_bus_suspend && nrf_usbd_lowpower_check(NRF_USBD))
1920     {
1921         nrf_usbd_lowpower_disable(NRF_USBD);
1922         started = true;
1923 
1924         if (nrfx_usbd_errata_171())
1925         {
1926             if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1927             {
1928                 *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1929                 *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1930                 *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1931             }
1932             else
1933             {
1934                 *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1935             }
1936 
1937         }
1938     }
1939     NRFX_CRITICAL_SECTION_EXIT();
1940 
1941     return started;
1942 }
1943 
nrfx_usbd_suspend_check(void)1944 bool nrfx_usbd_suspend_check(void)
1945 {
1946     return nrf_usbd_lowpower_check(NRF_USBD);
1947 }
1948 
nrfx_usbd_suspend_irq_config(void)1949 void nrfx_usbd_suspend_irq_config(void)
1950 {
1951     nrf_usbd_int_disable(NRF_USBD, m_irq_disabled_in_suspend);
1952 }
1953 
nrfx_usbd_active_irq_config(void)1954 void nrfx_usbd_active_irq_config(void)
1955 {
1956     nrf_usbd_int_enable(NRF_USBD, m_irq_disabled_in_suspend);
1957 }
1958 
nrfx_usbd_bus_suspend_check(void)1959 bool nrfx_usbd_bus_suspend_check(void)
1960 {
1961     return m_bus_suspend;
1962 }
1963 
nrfx_usbd_force_bus_wakeup(void)1964 void nrfx_usbd_force_bus_wakeup(void)
1965 {
1966     m_bus_suspend = false;
1967 }
1968 
nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep,uint16_t size)1969 void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size)
1970 {
1971     /* Only the power of 2 size allowed for Control Endpoints */
1972     NRFX_ASSERT((((size & (size - 1)) == 0) || (NRF_USBD_EP_NR_GET(ep) != 0)));
1973     /* Only non zero size allowed for Control Endpoints */
1974     NRFX_ASSERT((size != 0) || (NRF_USBD_EP_NR_GET(ep) != 0));
1975     /* Packet size cannot be higher than maximum buffer size */
1976     NRFX_ASSERT((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) ||
1977                 (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRFX_USBD_EPSIZE)));
1978 
1979     usbd_ep_state_t * p_state = ep_state_access(ep);
1980     p_state->max_packet_size = size;
1981 }
1982 
nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep)1983 uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep)
1984 {
1985     usbd_ep_state_t const * p_state = ep_state_access(ep);
1986     return p_state->max_packet_size;
1987 }
1988 
nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep)1989 bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep)
1990 {
1991     return nrf_usbd_ep_enable_check(NRF_USBD, ep_to_hal(ep));
1992 }
1993 
nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep)1994 void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep)
1995 {
1996     nrf_usbd_int_enable(NRF_USBD, nrfx_usbd_ep_to_int(ep));
1997 
1998     if (nrf_usbd_ep_enable_check(NRF_USBD, ep))
1999     {
2000         return;
2001     }
2002     nrf_usbd_ep_enable(NRF_USBD, ep_to_hal(ep));
2003     if ((NRF_USBD_EP_NR_GET(ep) != 0) &&
2004         NRF_USBD_EPOUT_CHECK(ep) &&
2005         !NRF_USBD_EPISO_CHECK(ep))
2006     {
2007         NRFX_CRITICAL_SECTION_ENTER();
2008         nrfx_usbd_transfer_out_drop(ep);
2009         m_ep_dma_waiting &= ~(1U << ep2bit(ep));
2010         NRFX_CRITICAL_SECTION_EXIT();
2011     }
2012 }
2013 
nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep)2014 void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep)
2015 {
2016     usbd_ep_abort(ep);
2017     nrf_usbd_ep_disable(NRF_USBD, ep_to_hal(ep));
2018     nrf_usbd_int_disable(NRF_USBD, nrfx_usbd_ep_to_int(ep));
2019 }
2020 
nrfx_usbd_ep_default_config(void)2021 void nrfx_usbd_ep_default_config(void)
2022 {
2023     nrf_usbd_int_disable(NRF_USBD, NRF_USBD_INT_ENDEPIN1_MASK  |
2024                                    NRF_USBD_INT_ENDEPIN2_MASK  |
2025                                    NRF_USBD_INT_ENDEPIN3_MASK  |
2026                                    NRF_USBD_INT_ENDEPIN4_MASK  |
2027                                    NRF_USBD_INT_ENDEPIN5_MASK  |
2028                                    NRF_USBD_INT_ENDEPIN6_MASK  |
2029                                    NRF_USBD_INT_ENDEPIN7_MASK  |
2030                                    NRF_USBD_INT_ENDISOIN0_MASK |
2031                                    NRF_USBD_INT_ENDEPOUT1_MASK |
2032                                    NRF_USBD_INT_ENDEPOUT2_MASK |
2033                                    NRF_USBD_INT_ENDEPOUT3_MASK |
2034                                    NRF_USBD_INT_ENDEPOUT4_MASK |
2035                                    NRF_USBD_INT_ENDEPOUT5_MASK |
2036                                    NRF_USBD_INT_ENDEPOUT6_MASK |
2037                                    NRF_USBD_INT_ENDEPOUT7_MASK |
2038                                    NRF_USBD_INT_ENDISOOUT0_MASK
2039     );
2040     nrf_usbd_int_enable(NRF_USBD, NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK);
2041     nrf_usbd_ep_default_config(NRF_USBD);
2042 }
2043 
nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep,nrfx_usbd_transfer_t const * p_transfer)2044 nrfx_err_t nrfx_usbd_ep_transfer(
2045     nrfx_usbd_ep_t               ep,
2046     nrfx_usbd_transfer_t const * p_transfer)
2047 {
2048     nrfx_err_t ret;
2049     const uint8_t ep_bitpos = ep2bit(ep);
2050 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2051     char * p_mode = "";
2052 #endif
2053 
2054     NRFX_ASSERT(NULL != p_transfer);
2055 
2056     NRFX_CRITICAL_SECTION_ENTER();
2057     /* Setup data transaction can go only in one direction at a time */
2058     if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
2059     {
2060         ret = NRFX_ERROR_INVALID_ADDR;
2061     }
2062     else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
2063     {
2064         /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */
2065         ret = NRFX_ERROR_BUSY;
2066     }
2067     else
2068     {
2069         usbd_ep_state_t * p_state =  ep_state_access(ep);
2070         /* Prepare transfer context and handler description */
2071         nrfx_usbd_transfer_t * p_context;
2072         if (NRF_USBD_EPIN_CHECK(ep))
2073         {
2074             p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep);
2075             if (nrfx_is_in_ram(p_transfer->p_data.tx))
2076             {
2077                 /* RAM */
2078                 if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG))
2079                 {
2080                     p_state->handler.feeder = nrfx_usbd_feeder_ram;
2081 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2082                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2083                     {
2084                         p_mode = "RAM";
2085                     }
2086 #endif
2087                 }
2088                 else
2089                 {
2090                     p_state->handler.feeder = nrfx_usbd_feeder_ram_zlp;
2091 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2092                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2093                     {
2094                         p_mode = "RAM_ZLP";
2095                     }
2096 #endif
2097                 }
2098             }
2099             else
2100             {
2101                 /* Flash */
2102                 if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG))
2103                 {
2104                     p_state->handler.feeder = nrfx_usbd_feeder_flash;
2105 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2106                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2107                     {
2108                         p_mode = "FLASH";
2109                     }
2110 #endif
2111                 }
2112                 else
2113                 {
2114                     p_state->handler.feeder = nrfx_usbd_feeder_flash_zlp;
2115 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2116                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2117                     {
2118                         p_mode = "FLASH_ZLP";
2119                     }
2120 #endif
2121                 }
2122             }
2123         }
2124         else
2125         {
2126             p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep);
2127             NRFX_ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx)));
2128             p_state->handler.consumer = nrfx_usbd_consumer;
2129         }
2130         *p_context = *p_transfer;
2131         p_state->p_context = p_context;
2132 
2133         p_state->transfer_cnt = 0;
2134         p_state->status    =  NRFX_USBD_EP_OK;
2135         m_ep_dma_waiting   |= 1U << ep_bitpos;
2136         ret = NRFX_SUCCESS;
2137         usbd_int_rise();
2138     }
2139     NRFX_CRITICAL_SECTION_EXIT();
2140 
2141     if ((ret == NRFX_SUCCESS) &&
2142         (NRFX_USBD_ISO_DEBUG || !NRF_USBD_EPISO_CHECK(ep)))
2143     {
2144 #if NRFX_USBD_CONFIG_LOG_LEVEL > 3
2145         NRFX_LOG_DEBUG("Transfer called on endpoint %x, size: %u, mode: %s", ep, p_transfer->size, p_mode);
2146 #endif
2147     }
2148     else if (NRFX_USBD_FAILED_TRANSFERS_DEBUG &&
2149              (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
2150     {
2151         if (ret == NRFX_ERROR_BUSY)
2152         {
2153             NRFX_LOG_DEBUG("Transfer failed: EP is busy");
2154         }
2155         else if (ret == NRFX_ERROR_INVALID_ADDR)
2156         {
2157             NRFX_LOG_DEBUG("Transfer failed: Invalid EP");
2158         }
2159     }
2160 
2161     return ret;
2162 }
2163 
nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep,nrfx_usbd_handler_desc_t const * p_handler)2164 nrfx_err_t nrfx_usbd_ep_handled_transfer(
2165     nrfx_usbd_ep_t                   ep,
2166     nrfx_usbd_handler_desc_t const * p_handler)
2167 {
2168     nrfx_err_t ret;
2169     const uint8_t ep_bitpos = ep2bit(ep);
2170     NRFX_ASSERT(NULL != p_handler);
2171 
2172     NRFX_CRITICAL_SECTION_ENTER();
2173     /* Setup data transaction can go only in one direction at a time */
2174     if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
2175     {
2176         ret = NRFX_ERROR_INVALID_ADDR;
2177     }
2178     else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
2179     {
2180         /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */
2181         ret = NRFX_ERROR_BUSY;
2182     }
2183     else
2184     {
2185         /* Transfer can be configured now */
2186         usbd_ep_state_t * p_state =  ep_state_access(ep);
2187 
2188         p_state->transfer_cnt = 0;
2189         p_state->handler   = p_handler->handler;
2190         p_state->p_context = p_handler->p_context;
2191         p_state->status    =  NRFX_USBD_EP_OK;
2192         m_ep_dma_waiting   |= 1U << ep_bitpos;
2193 
2194         ret = NRFX_SUCCESS;
2195         usbd_int_rise();
2196     }
2197     NRFX_CRITICAL_SECTION_EXIT();
2198 
2199     if ((ret == NRFX_SUCCESS) &&
2200         (NRFX_USBD_ISO_DEBUG || !NRF_USBD_EPISO_CHECK(ep)))
2201     {
2202         NRFX_LOG_DEBUG("Transfer called on endpoint %x, mode: Handler", ep);
2203     }
2204     else if (NRFX_USBD_FAILED_TRANSFERS_DEBUG &&
2205              (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
2206     {
2207         if (ret == NRFX_ERROR_BUSY)
2208         {
2209             NRFX_LOG_DEBUG("Transfer failed: EP is busy");
2210         }
2211         else if (ret == NRFX_ERROR_INVALID_ADDR)
2212         {
2213             NRFX_LOG_DEBUG("Transfer failed: Invalid EP");
2214         }
2215     }
2216 
2217     return ret;
2218 }
2219 
nrfx_usbd_feeder_buffer_get(void)2220 void * nrfx_usbd_feeder_buffer_get(void)
2221 {
2222     return m_tx_buffer;
2223 }
2224 
nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep,size_t * p_size)2225 nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t * p_size)
2226 {
2227     nrfx_usbd_ep_status_t ret;
2228 
2229     usbd_ep_state_t const * p_state = ep_state_access(ep);
2230     NRFX_CRITICAL_SECTION_ENTER();
2231     *p_size = p_state->transfer_cnt;
2232     ret = (p_state->handler.consumer == NULL) ? p_state->status : NRFX_USBD_EP_BUSY;
2233     NRFX_CRITICAL_SECTION_EXIT();
2234     return ret;
2235 }
2236 
nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep)2237 size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep)
2238 {
2239     return nrf_usbd_epout_size_get(NRF_USBD, ep_to_hal(ep));
2240 }
2241 
nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep)2242 bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep)
2243 {
2244     return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep2bit(ep))));
2245 }
2246 
nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep)2247 void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep)
2248 {
2249     NRFX_LOG_DEBUG("USB: EP %x stalled.", ep);
2250     nrf_usbd_ep_stall(NRF_USBD, ep_to_hal(ep));
2251 }
2252 
nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep)2253 void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep)
2254 {
2255     if (NRF_USBD_EPOUT_CHECK(ep) && nrfx_usbd_ep_stall_check(ep))
2256     {
2257         nrfx_usbd_transfer_out_drop(ep);
2258     }
2259     nrf_usbd_ep_unstall(NRF_USBD, ep_to_hal(ep));
2260 }
2261 
nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep)2262 bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep)
2263 {
2264     return nrf_usbd_ep_is_stall(NRF_USBD, ep_to_hal(ep));
2265 }
2266 
nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep)2267 void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep)
2268 {
2269     nrf_usbd_dtoggle_set(NRF_USBD, ep, NRF_USBD_DTOGGLE_DATA0);
2270 }
2271 
nrfx_usbd_setup_get(nrfx_usbd_setup_t * p_setup)2272 void nrfx_usbd_setup_get(nrfx_usbd_setup_t * p_setup)
2273 {
2274     memset(p_setup, 0, sizeof(nrfx_usbd_setup_t));
2275     p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(NRF_USBD);
2276     p_setup->bRequest      = nrf_usbd_setup_brequest_get(NRF_USBD);
2277     p_setup->wValue        = nrf_usbd_setup_wvalue_get(NRF_USBD);
2278     p_setup->wIndex        = nrf_usbd_setup_windex_get(NRF_USBD);
2279     p_setup->wLength       = nrf_usbd_setup_wlength_get(NRF_USBD);
2280 }
2281 
nrfx_usbd_setup_data_clear(void)2282 void nrfx_usbd_setup_data_clear(void)
2283 {
2284     nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0RCVOUT);
2285 }
2286 
nrfx_usbd_setup_clear(void)2287 void nrfx_usbd_setup_clear(void)
2288 {
2289     NRFX_LOG_DEBUG(">> ep0status >>");
2290     nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STATUS);
2291 }
2292 
nrfx_usbd_setup_stall(void)2293 void nrfx_usbd_setup_stall(void)
2294 {
2295     NRFX_LOG_DEBUG("Setup stalled.");
2296     nrf_usbd_task_trigger(NRF_USBD, NRF_USBD_TASK_EP0STALL);
2297 }
2298 
nrfx_usbd_last_setup_dir_get(void)2299 nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void)
2300 {
2301     return m_last_setup_dir;
2302 }
2303 
nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)2304 void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)
2305 {
2306     NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep));
2307 
2308     NRFX_CRITICAL_SECTION_ENTER();
2309     m_ep_ready &= ~(1U << ep2bit(ep));
2310     if (!NRF_USBD_EPISO_CHECK(ep))
2311     {
2312         nrf_usbd_epout_clear(NRF_USBD, ep);
2313     }
2314     NRFX_CRITICAL_SECTION_EXIT();
2315 }
2316 
2317 #endif // NRFX_CHECK(NRFX_USBD_ENABLED)
2318