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