xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_usbd.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1 /*
2  * Copyright (c) 2016 - 2018, 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 <nrfx_systick.h> /* Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE << */
39 #include <string.h>
40 
41 #define NRFX_LOG_MODULE USBD
42 #include <nrfx_log.h>
43 
44 #ifndef NRFX_USBD_EARLY_DMA_PROCESS
45 /* Try to process DMA request when endpoint transmission has been detected
46  * and just after last EasyDMA has been processed.
47  * It speeds up the transmission a little (about 10% measured)
48  * with a cost of more CPU power used.
49  */
50 #define NRFX_USBD_EARLY_DMA_PROCESS 1
51 #endif
52 
53 #ifndef NRFX_USBD_PROTO1_FIX_DEBUG
54 /* Debug information when events are fixed*/
55 #define NRFX_USBD_PROTO1_FIX_DEBUG 1
56 #endif
57 
58 #define NRFX_USBD_LOG_PROTO1_FIX_PRINTF(...)                           \
59     do{                                                                \
60         if (NRFX_USBD_PROTO1_FIX_DEBUG){ NRFX_LOG_DEBUG(__VA_ARGS__); }\
61     } while (0)
62 
63 #ifndef NRFX_USBD_STARTED_EV_ENABLE
64 #define NRFX_USBD_STARTED_EV_ENABLE    0
65 #endif
66 
67 #ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
68 #define NRFX_USBD_CONFIG_ISO_IN_ZLP  0
69 #endif
70 
71 #ifndef NRFX_USBD_ISO_DEBUG
72 /* Also generate information about ISOCHRONOUS events and transfers.
73  * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this
74  * option generates a lot of useless messages. */
75 #define NRFX_USBD_ISO_DEBUG 1
76 #endif
77 
78 #ifndef NRFX_USBD_FAILED_TRANSFERS_DEBUG
79 /* Also generate debug information for failed transfers.
80  * It might be useful but may generate a lot of useless debug messages
81  * in some library usages (for example when transfer is generated and the
82  * result is used to check whatever endpoint was busy. */
83 #define NRFX_USBD_FAILED_TRANSFERS_DEBUG 1
84 #endif
85 
86 #ifndef NRFX_USBD_DMAREQ_PROCESS_DEBUG
87 /* Generate additional messages that mark the status inside
88  * @ref usbd_dmareq_process.
89  * It is useful to debug library internals but may generate a lot of
90  * useless debug messages. */
91 #define NRFX_USBD_DMAREQ_PROCESS_DEBUG 1
92 #endif
93 
94 
95 /**
96  * @defgroup nrfx_usbd_int USB Device driver internal part
97  * @internal
98  * @ingroup nrfx_usbd
99  *
100  * This part contains auxiliary internal macros, variables and functions.
101  * @{
102  */
103 
104 /**
105  * @brief Assert endpoint number validity.
106  *
107  * Internal macro to be used during program creation in debug mode.
108  * Generates assertion if endpoint number is not valid.
109  *
110  * @param ep Endpoint number to validity check.
111  */
112 #define NRFX_USBD_ASSERT_EP_VALID(ep) NRFX_ASSERT(                               \
113     ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT ))  \
114     ||                                                                           \
115     (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \
116 );
117 
118 /**
119  * @brief Lowest position of bit for IN endpoint.
120  *
121  * The first bit position corresponding to IN endpoint.
122  * @sa ep2bit bit2ep
123  */
124 #define NRFX_USBD_EPIN_BITPOS_0   0
125 
126 /**
127  * @brief Lowest position of bit for OUT endpoint.
128  *
129  * The first bit position corresponding to OUT endpoint
130  * @sa ep2bit bit2ep
131  */
132 #define NRFX_USBD_EPOUT_BITPOS_0  16
133 
134 /**
135  * @brief Input endpoint bits mask.
136  */
137 #define NRFX_USBD_EPIN_BIT_MASK (0xFFFFU << NRFX_USBD_EPIN_BITPOS_0)
138 
139 /**
140  * @brief Output endpoint bits mask.
141  */
142 #define NRFX_USBD_EPOUT_BIT_MASK (0xFFFFU << NRFX_USBD_EPOUT_BITPOS_0)
143 
144 /**
145  * @brief Isochronous endpoint bit mask
146  */
147 #define USBD_EPISO_BIT_MASK \
148     ((1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT8)) | \
149      (1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN8)))
150 
151 /**
152  * @brief Auxiliary macro to change EP number into bit position.
153  *
154  * This macro is used by @ref ep2bit function but also for statically check
155  * the bitpos values integrity during compilation.
156  *
157  * @param[in] ep Endpoint number.
158  * @return Endpoint bit position.
159  */
160 #define NRFX_USBD_EP_BITPOS(ep) \
161     ((NRF_USBD_EPIN_CHECK(ep) ? NRFX_USBD_EPIN_BITPOS_0 : NRFX_USBD_EPOUT_BITPOS_0) \
162      + NRF_USBD_EP_NR_GET(ep))
163 
164 /**
165  * @brief Helper macro for creating an endpoint transfer event.
166  *
167  * @param[in] name     Name of the created transfer event variable.
168  * @param[in] endpoint Endpoint number.
169  * @param[in] ep_stat  Endpoint state to report.
170  *
171  * @return Initialized event constant variable.
172  */
173 #define NRFX_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \
174     const nrfx_usbd_evt_t name = {                          \
175         NRFX_USBD_EVT_EPTRANSFER,                           \
176         .data = {                                           \
177             .eptransfer = {                                 \
178                     .ep = endpont,                          \
179                     .status = ep_stat                       \
180             }                                               \
181         }                                                   \
182     }
183 
184 /* Check it the bit positions values match defined DATAEPSTATUS bit positions */
185 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN1)  == USBD_EPDATASTATUS_EPIN1_Pos );
186 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN2)  == USBD_EPDATASTATUS_EPIN2_Pos );
187 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN3)  == USBD_EPDATASTATUS_EPIN3_Pos );
188 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN4)  == USBD_EPDATASTATUS_EPIN4_Pos );
189 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN5)  == USBD_EPDATASTATUS_EPIN5_Pos );
190 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN6)  == USBD_EPDATASTATUS_EPIN6_Pos );
191 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN7)  == USBD_EPDATASTATUS_EPIN7_Pos );
192 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos);
193 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos);
194 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos);
195 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos);
196 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos);
197 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos);
198 NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos);
199 
200 
201 /**
202  * @brief Current driver state.
203  */
204 static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
205 
206 /**
207  * @brief Event handler for the driver.
208  *
209  * Event handler that would be called on events.
210  *
211  * @note Currently it cannot be null if any interrupt is activated.
212  */
213 static nrfx_usbd_event_handler_t m_event_handler;
214 
215 /**
216  * @brief Detected state of the bus.
217  *
218  * Internal state changed in interrupts handling when
219  * RESUME or SUSPEND event is processed.
220  *
221  * Values:
222  * - true  - bus suspended
223  * - false - ongoing normal communication on the bus
224  *
225  * @note This is only the bus state and does not mean that the peripheral is in suspend state.
226  */
227 static volatile bool m_bus_suspend;
228 
229 /**
230  * @brief Internal constant that contains interrupts disabled in suspend state.
231  *
232  * Internal constant used in @ref nrfx_usbd_suspend_irq_config and @ref nrfx_usbd_active_irq_config
233  * functions.
234  */
235 static const uint32_t m_irq_disabled_in_suspend =
236     NRF_USBD_INT_ENDEPIN0_MASK    |
237     NRF_USBD_INT_EP0DATADONE_MASK |
238     NRF_USBD_INT_ENDEPOUT0_MASK   |
239     NRF_USBD_INT_EP0SETUP_MASK    |
240     NRF_USBD_INT_DATAEP_MASK;
241 
242 /**
243  * @brief Direction of last received Setup transfer.
244  *
245  * This variable is used to redirect internal setup data event
246  * into selected endpoint (IN or OUT).
247  */
248 static nrfx_usbd_ep_t m_last_setup_dir;
249 
250 /**
251  * @brief Mark endpoint readiness for DMA transfer.
252  *
253  * Bits in this variable are cleared and set in interrupts.
254  * 1 means that endpoint is ready for DMA transfer.
255  * 0 means that DMA transfer cannot be performed on selected endpoint.
256  */
257 static uint32_t m_ep_ready;
258 
259 /**
260  * @brief Mark endpoint with prepared data to transfer by DMA.
261  *
262  * This variable can be from any place in the code (interrupt or main thread).
263  * It would be cleared only from USBD interrupt.
264  *
265  * Mask prepared USBD data for transmission.
266  * It is cleared when no more data to transmit left.
267  */
268 static uint32_t m_ep_dma_waiting;
269 
270 /**
271  * @brief Current EasyDMA state.
272  *
273  * Single flag, updated only inside interrupts, that marks current EasyDMA state.
274  * In USBD there is only one DMA channel working in background, and new transfer
275  * cannot be started when there is ongoing transfer on any other channel.
276  */
277 static bool m_dma_pending;
278 
279 /**
280  * @brief Simulated data EP status bits required for errata 104.
281  *
282  * Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE <<.
283  */
284 static uint32_t m_simulated_dataepstatus;
285 
286 /**
287  * @brief The structure that would hold transfer configuration to every endpoint
288  *
289  * The structure that holds all the data required by the endpoint to proceed
290  * with LIST functionality and generate quick callback directly when data
291  * buffer is ready.
292  */
293 typedef struct
294 {
295     nrfx_usbd_handler_t   handler;         //!< Handler for current transfer, function pointer.
296     void *                p_context;       //!< Context for transfer handler.
297     size_t                transfer_cnt;    //!< Number of transferred bytes in the current transfer.
298     uint16_t              max_packet_size; //!< Configured endpoint size.
299     nrfx_usbd_ep_status_t status;          //!< NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY - this one is calculated.
300 } usbd_ep_state_t;
301 
302 /**
303  * @brief The array of transfer configurations for the endpoints.
304  *
305  * The status of the transfer on each endpoint.
306  */
307 static struct
308 {
309     usbd_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints.
310     usbd_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints.
311 } m_ep_state;
312 
313 /**
314  * @brief Status variables for integrated feeders.
315  *
316  * Current status for integrated feeders (IN transfers).
317  * Integrated feeders are used for default transfers:
318  * 1. Simple RAM transfer.
319  * 2. Simple flash transfer.
320  * 3. RAM transfer with automatic ZLP.
321  * 4. Flash transfer with automatic ZLP.
322  */
323 nrfx_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT];
324 
325 /**
326  * @brief Status variables for integrated consumers.
327  *
328  * Current status for integrated consumers.
329  * Currently one type of transfer is supported:
330  * 1. Transfer to RAM.
331  *
332  * Transfer is finished automatically when received data block is smaller
333  * than the endpoint buffer or all the required data is received.
334  */
335 nrfx_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT];
336 
337 
338 /**
339  * @brief Buffer used to send data directly from FLASH.
340  *
341  * This is internal buffer that would be used to emulate the possibility
342  * to transfer data directly from FLASH.
343  * We do not have to care about the source of data when calling transfer functions.
344  *
345  * We do not need more buffers that one, because only one transfer can be pending
346  * at once.
347  */
348 static uint32_t m_tx_buffer[NRFX_CEIL_DIV(
349     NRFX_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))];
350 
351 /* Early declaration. Documentation above definition. */
352 static void usbd_dmareq_process(void);
353 
354 
355 /**
356  * @brief Change endpoint number to endpoint event code.
357  *
358  * @param ep Endpoint number.
359  *
360  * @return Connected endpoint event code.
361  *
362  * Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE <<.
363  */
nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep)364 static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep)
365 {
366     NRFX_USBD_ASSERT_EP_VALID(ep);
367 
368     static const nrf_usbd_event_t epin_endev[] =
369     {
370         NRF_USBD_EVENT_ENDEPIN0,
371         NRF_USBD_EVENT_ENDEPIN1,
372         NRF_USBD_EVENT_ENDEPIN2,
373         NRF_USBD_EVENT_ENDEPIN3,
374         NRF_USBD_EVENT_ENDEPIN4,
375         NRF_USBD_EVENT_ENDEPIN5,
376         NRF_USBD_EVENT_ENDEPIN6,
377         NRF_USBD_EVENT_ENDEPIN7,
378         NRF_USBD_EVENT_ENDISOIN0
379     };
380     static const nrf_usbd_event_t epout_endev[] =
381     {
382         NRF_USBD_EVENT_ENDEPOUT0,
383         NRF_USBD_EVENT_ENDEPOUT1,
384         NRF_USBD_EVENT_ENDEPOUT2,
385         NRF_USBD_EVENT_ENDEPOUT3,
386         NRF_USBD_EVENT_ENDEPOUT4,
387         NRF_USBD_EVENT_ENDEPOUT5,
388         NRF_USBD_EVENT_ENDEPOUT6,
389         NRF_USBD_EVENT_ENDEPOUT7,
390         NRF_USBD_EVENT_ENDISOOUT0
391     };
392 
393     return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)];
394 }
395 
396 
397 /**
398  * @brief Get interrupt mask for selected endpoint.
399  *
400  * @param[in] ep Endpoint number.
401  *
402  * @return Interrupt mask related to the EasyDMA transfer end for the
403  *         chosen endpoint.
404  */
nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep)405 static inline uint32_t nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep)
406 {
407     NRFX_USBD_ASSERT_EP_VALID(ep);
408 
409     static const uint8_t epin_bitpos[] =
410     {
411         USBD_INTEN_ENDEPIN0_Pos,
412         USBD_INTEN_ENDEPIN1_Pos,
413         USBD_INTEN_ENDEPIN2_Pos,
414         USBD_INTEN_ENDEPIN3_Pos,
415         USBD_INTEN_ENDEPIN4_Pos,
416         USBD_INTEN_ENDEPIN5_Pos,
417         USBD_INTEN_ENDEPIN6_Pos,
418         USBD_INTEN_ENDEPIN7_Pos,
419         USBD_INTEN_ENDISOIN_Pos
420     };
421     static const uint8_t epout_bitpos[] =
422     {
423         USBD_INTEN_ENDEPOUT0_Pos,
424         USBD_INTEN_ENDEPOUT1_Pos,
425         USBD_INTEN_ENDEPOUT2_Pos,
426         USBD_INTEN_ENDEPOUT3_Pos,
427         USBD_INTEN_ENDEPOUT4_Pos,
428         USBD_INTEN_ENDEPOUT5_Pos,
429         USBD_INTEN_ENDEPOUT6_Pos,
430         USBD_INTEN_ENDEPOUT7_Pos,
431         USBD_INTEN_ENDISOOUT_Pos
432     };
433 
434     return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)];
435 }
436 
437 /**
438  * @name Integrated feeders and consumers
439  *
440  * Internal, default functions for transfer processing.
441  * @{
442  */
443 
444 /**
445  * @brief Integrated consumer to RAM buffer.
446  *
447  * @param p_next    See @ref nrfx_usbd_consumer_t documentation.
448  * @param p_context See @ref nrfx_usbd_consumer_t documentation.
449  * @param ep_size   See @ref nrfx_usbd_consumer_t documentation.
450  * @param data_size See @ref nrfx_usbd_consumer_t documentation.
451  *
452  * @retval true  Continue transfer.
453  * @retval false This was the last transfer.
454  */
nrfx_usbd_consumer(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size,size_t data_size)455 bool nrfx_usbd_consumer(
456     nrfx_usbd_ep_transfer_t * p_next,
457     void * p_context,
458     size_t ep_size,
459     size_t data_size)
460 {
461     nrfx_usbd_transfer_t * p_transfer = p_context;
462     NRFX_ASSERT(ep_size >= data_size);
463     NRFX_ASSERT((p_transfer->p_data.rx == NULL) ||
464         nrfx_is_in_ram(p_transfer->p_data.rx));
465 
466     size_t size = p_transfer->size;
467     if (size < data_size)
468     {
469         NRFX_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size);
470         /* Buffer size to small */
471         p_next->size = 0;
472         p_next->p_data = p_transfer->p_data;
473     }
474     else
475     {
476         p_next->size = data_size;
477         p_next->p_data = p_transfer->p_data;
478         size -= data_size;
479         p_transfer->size = size;
480         p_transfer->p_data.addr += data_size;
481     }
482     return (ep_size == data_size) && (size != 0);
483 }
484 
485 /**
486  * @brief Integrated feeder from RAM source.
487  *
488  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
489  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
490  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
491  *
492  * @retval true  Continue transfer.
493  * @retval false This was the last transfer.
494  */
nrfx_usbd_feeder_ram(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)495 bool nrfx_usbd_feeder_ram(
496     nrfx_usbd_ep_transfer_t * p_next,
497     void * p_context,
498     size_t ep_size)
499 {
500     nrfx_usbd_transfer_t * p_transfer = p_context;
501     NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));
502 
503     size_t tx_size = p_transfer->size;
504     if (tx_size > ep_size)
505     {
506         tx_size = ep_size;
507     }
508 
509     p_next->p_data = p_transfer->p_data;
510     p_next->size = tx_size;
511 
512     p_transfer->size -= tx_size;
513     p_transfer->p_data.addr += tx_size;
514 
515     return (p_transfer->size != 0);
516 }
517 
518 /**
519  * @brief Integrated feeder from RAM source with ZLP.
520  *
521  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
522  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
523  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
524  *
525  * @retval true  Continue transfer.
526  * @retval false This was the last transfer.
527  */
nrfx_usbd_feeder_ram_zlp(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)528 bool nrfx_usbd_feeder_ram_zlp(
529     nrfx_usbd_ep_transfer_t * p_next,
530     void * p_context,
531     size_t ep_size)
532 {
533     nrfx_usbd_transfer_t * p_transfer = p_context;
534     NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));
535 
536     size_t tx_size = p_transfer->size;
537     if (tx_size > ep_size)
538     {
539         tx_size = ep_size;
540     }
541 
542     p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx;
543     p_next->size = tx_size;
544 
545     p_transfer->size -= tx_size;
546     p_transfer->p_data.addr += tx_size;
547 
548     return (tx_size != 0);
549 }
550 
551 /**
552  * @brief Integrated feeder from a flash source.
553  *
554  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
555  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
556  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
557  *
558  * @retval true  Continue transfer.
559  * @retval false This was the last transfer.
560  */
nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)561 bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
562 {
563     nrfx_usbd_transfer_t * p_transfer = p_context;
564     NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));
565 
566     size_t tx_size  = p_transfer->size;
567     void * p_buffer = nrfx_usbd_feeder_buffer_get();
568 
569     if (tx_size > ep_size)
570     {
571         tx_size = ep_size;
572     }
573 
574     NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE);
575     memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
576 
577     p_next->p_data.tx = p_buffer;
578     p_next->size = tx_size;
579 
580     p_transfer->size -= tx_size;
581     p_transfer->p_data.addr += tx_size;
582 
583     return (p_transfer->size != 0);
584 }
585 
586 /**
587  * @brief Integrated feeder from a flash source with ZLP.
588  *
589  * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
590  * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
591  * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
592  *
593  * @retval true  Continue transfer.
594  * @retval false This was the last transfer.
595  */
nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t * p_next,void * p_context,size_t ep_size)596 bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
597 {
598     nrfx_usbd_transfer_t * p_transfer = p_context;
599     NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));
600 
601     size_t tx_size  = p_transfer->size;
602     void * p_buffer = nrfx_usbd_feeder_buffer_get();
603 
604     if (tx_size > ep_size)
605     {
606         tx_size = ep_size;
607     }
608 
609     NRFX_ASSERT(tx_size <= NRFX_USBD_FEEDER_BUFFER_SIZE);
610 
611     if (tx_size != 0)
612     {
613         memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
614         p_next->p_data.tx = p_buffer;
615     }
616     else
617     {
618         p_next->p_data.tx = NULL;
619     }
620     p_next->size = tx_size;
621 
622     p_transfer->size -= tx_size;
623     p_transfer->p_data.addr += tx_size;
624 
625     return (tx_size != 0);
626 }
627 
628 /** @} */
629 
630 /**
631  * @brief Change Driver endpoint number to HAL endpoint number.
632  *
633  * @param ep Driver endpoint identifier.
634  *
635  * @return Endpoint identifier in HAL.
636  *
637  * @sa nrfx_usbd_ep_from_hal
638  */
ep_to_hal(nrfx_usbd_ep_t ep)639 static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep)
640 {
641     NRFX_USBD_ASSERT_EP_VALID(ep);
642     return (uint8_t)ep;
643 }
644 
645 /**
646  * @brief Generate start task number for selected endpoint index.
647  *
648  * @param ep Endpoint number.
649  *
650  * @return Task for starting EasyDMA transfer on selected endpoint.
651  */
task_start_ep(nrfx_usbd_ep_t ep)652 static inline nrf_usbd_task_t task_start_ep(nrfx_usbd_ep_t ep)
653 {
654     NRFX_USBD_ASSERT_EP_VALID(ep);
655     return (nrf_usbd_task_t)(
656         (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) +
657         (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t)));
658 }
659 
660 /**
661  * @brief Access selected endpoint state structure.
662  *
663  * Function used to change or just read the state of selected endpoint.
664  * It is used for internal transmission state.
665  *
666  * @param ep Endpoint number.
667  */
ep_state_access(nrfx_usbd_ep_t ep)668 static inline usbd_ep_state_t* ep_state_access(nrfx_usbd_ep_t ep)
669 {
670     NRFX_USBD_ASSERT_EP_VALID(ep);
671     return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) +
672         NRF_USBD_EP_NR_GET(ep));
673 }
674 
675 /**
676  * @brief Change endpoint number to bit position.
677  *
678  * Bit positions are defined the same way as they are placed in DATAEPSTATUS register,
679  * but bits for endpoint 0 are included.
680  *
681  * @param ep Endpoint number.
682  *
683  * @return Bit position related to the given endpoint number.
684  *
685  * @sa bit2ep
686  */
ep2bit(nrfx_usbd_ep_t ep)687 static inline uint8_t ep2bit(nrfx_usbd_ep_t ep)
688 {
689     NRFX_USBD_ASSERT_EP_VALID(ep);
690     return NRFX_USBD_EP_BITPOS(ep);
691 }
692 
693 /**
694  * @brief Change bit position to endpoint number.
695  *
696  * @param bitpos Bit position.
697  *
698  * @return Endpoint number corresponding to given bit position.
699  *
700  * @sa ep2bit
701  */
bit2ep(uint8_t bitpos)702 static inline nrfx_usbd_ep_t bit2ep(uint8_t bitpos)
703 {
704     NRFX_STATIC_ASSERT(NRFX_USBD_EPOUT_BITPOS_0 > NRFX_USBD_EPIN_BITPOS_0);
705     return (nrfx_usbd_ep_t)((bitpos >= NRFX_USBD_EPOUT_BITPOS_0) ?
706         NRF_USBD_EPOUT(bitpos - NRFX_USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos));
707 }
708 
709 /**
710  * @brief Mark that EasyDMA is working.
711  *
712  * Internal function to set the flag informing about EasyDMA transfer pending.
713  * This function is called always just after the EasyDMA transfer is started.
714  */
usbd_dma_pending_set(void)715 static inline void usbd_dma_pending_set(void)
716 {
717     if (nrfx_usbd_errata_199())
718     {
719         *((volatile uint32_t *)0x40027C1C) = 0x00000082;
720     }
721     m_dma_pending = true;
722 }
723 
724 /**
725  * @brief Mark that EasyDMA is free.
726  *
727  * Internal function to clear the flag informing about EasyDMA transfer pending.
728  * This function is called always just after the finished EasyDMA transfer is detected.
729  */
usbd_dma_pending_clear(void)730 static inline void usbd_dma_pending_clear(void)
731 {
732     if (nrfx_usbd_errata_199())
733     {
734         *((volatile uint32_t *)0x40027C1C) = 0x00000000;
735     }
736     m_dma_pending = false;
737 }
738 
739 /**
740  * @brief Start selected EasyDMA transmission.
741  *
742  * This is internal auxiliary function.
743  * No checking is made if EasyDMA is ready for new transmission.
744  *
745  * @param[in] ep Number of endpoint for transmission.
746  *               If it is OUT endpoint transmission would be directed from endpoint to RAM.
747  *               If it is in endpoint transmission would be directed from RAM to endpoint.
748  */
usbd_dma_start(nrfx_usbd_ep_t ep)749 static inline void usbd_dma_start(nrfx_usbd_ep_t ep)
750 {
751     nrf_usbd_task_trigger(task_start_ep(ep));
752 }
753 
nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config)754 void nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config)
755 {
756     NRFX_ASSERT(!nrfx_usbd_errata_type_52840_eng_a());
757     nrf_usbd_isoinconfig_set(config);
758 }
759 
nrfx_usbd_isoinconfig_get(void)760 nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void)
761 {
762     NRFX_ASSERT(!nrfx_usbd_errata_type_52840_eng_a());
763     return nrf_usbd_isoinconfig_get();
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 *)(NRF_USBD_BASE + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
811                 uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
812                 temp |= (1U << 1);
813                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp;
814                 (void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
815             }
816             else
817             {
818                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B4;
819                 uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
820                 temp |= (1U << 2);
821                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp;
822                 (void)(*((volatile uint32_t *)(NRF_USBD_BASE + 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 = __CLZ(__RBIT(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 = nrf_usbd_framecntr_get() }}
1127     };
1128 
1129     /* Process isochronous endpoints */
1130     uint32_t iso_ready_mask = (1U << ep2bit(NRFX_USBD_EPIN8));
1131     if (nrf_usbd_episoout_size_get(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         if (0 == (m_ep_dma_waiting & (1U << bitpos)))
1157         {
1158             NRFX_LOG_DEBUG("USBD event: EndpointData: In finished");
1159             /* No more data to be send - transmission finished */
1160             NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
1161             m_event_handler(&evt);
1162         }
1163     }
1164     else
1165     {
1166         /* OUT endpoint (Host -> Device) */
1167         if (0 == (m_ep_dma_waiting & (1U << bitpos)))
1168         {
1169             NRFX_LOG_DEBUG("USBD event: EndpointData: Out waiting");
1170             /* No buffer prepared - send event to the application */
1171             NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_WAITING);
1172             m_event_handler(&evt);
1173         }
1174     }
1175 }
1176 
ev_setup_data_handler(void)1177 static void ev_setup_data_handler(void)
1178 {
1179     usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir));
1180 }
1181 
ev_setup_handler(void)1182 static void ev_setup_handler(void)
1183 {
1184     NRFX_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )",
1185         nrf_usbd_setup_bmrequesttype_get(),
1186         nrf_usbd_setup_brequest_get(),
1187         nrf_usbd_setup_wvalue_get(),
1188         nrf_usbd_setup_windex_get(),
1189         nrf_usbd_setup_wlength_get());
1190     uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get();
1191 
1192     if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK))
1193         & (1U <<ep2bit(m_last_setup_dir)))
1194     {
1195         NRFX_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0");
1196         usbd_ep_abort(m_last_setup_dir);
1197     }
1198 
1199     m_last_setup_dir =
1200         ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) ==
1201          (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) ?
1202         NRFX_USBD_EPOUT0 : NRFX_USBD_EPIN0;
1203 
1204     (void)(NRFX_ATOMIC_FETCH_AND(
1205         &m_ep_dma_waiting,
1206         ~((1U << ep2bit(NRFX_USBD_EPOUT0)) | (1U << ep2bit(NRFX_USBD_EPIN0)))));
1207     m_ep_ready |= 1U << ep2bit(NRFX_USBD_EPIN0);
1208 
1209 
1210     const nrfx_usbd_evt_t evt = {
1211             .type = NRFX_USBD_EVT_SETUP
1212     };
1213     m_event_handler(&evt);
1214 }
1215 
ev_usbevent_handler(void)1216 static void ev_usbevent_handler(void)
1217 {
1218     uint32_t event = nrf_usbd_eventcause_get_and_clear();
1219 
1220     if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK)
1221     {
1222         NRFX_LOG_DEBUG("USBD event: ISOOUTCRC");
1223         /* Currently no support */
1224     }
1225     if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK)
1226     {
1227         NRFX_LOG_DEBUG("USBD event: SUSPEND");
1228         m_bus_suspend = true;
1229         const nrfx_usbd_evt_t evt = {
1230                 .type = NRFX_USBD_EVT_SUSPEND
1231         };
1232         m_event_handler(&evt);
1233     }
1234     if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK)
1235     {
1236         NRFX_LOG_DEBUG("USBD event: RESUME");
1237         m_bus_suspend = false;
1238         const nrfx_usbd_evt_t evt = {
1239                 .type = NRFX_USBD_EVT_RESUME
1240         };
1241         m_event_handler(&evt);
1242     }
1243     if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK)
1244     {
1245         NRFX_LOG_DEBUG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active");
1246         if (m_bus_suspend)
1247         {
1248             NRFX_ASSERT(!nrf_usbd_lowpower_check());
1249             m_bus_suspend = false;
1250 
1251             nrf_usbd_dpdmvalue_set(NRF_USBD_DPDMVALUE_RESUME);
1252             nrf_usbd_task_trigger(NRF_USBD_TASK_DRIVEDPDM);
1253 
1254             const nrfx_usbd_evt_t evt = {
1255                     .type = NRFX_USBD_EVT_WUREQ
1256             };
1257             m_event_handler(&evt);
1258         }
1259     }
1260 }
1261 
ev_epdata_handler(void)1262 static void ev_epdata_handler(void)
1263 {
1264     /* Get all endpoints that have acknowledged transfer */
1265     uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear();
1266     if (nrfx_usbd_errata_104())
1267     {
1268         dataepstatus |= (m_simulated_dataepstatus &
1269             ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0)));
1270         m_simulated_dataepstatus &=
1271              ((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0));
1272     }
1273     NRFX_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus);
1274 
1275     /* All finished endpoint have to be marked as busy */
1276     while (dataepstatus)
1277     {
1278         uint8_t bitpos    = __CLZ(__RBIT(dataepstatus));
1279         nrfx_usbd_ep_t ep = bit2ep(bitpos);
1280         dataepstatus &= ~(1UL << bitpos);
1281 
1282         (void)(usbd_ep_data_handler(ep, bitpos));
1283     }
1284     if (NRFX_USBD_EARLY_DMA_PROCESS)
1285     {
1286         /* Speed up */
1287         usbd_dmareq_process();
1288     }
1289 }
1290 
1291 /**
1292  * @brief Function to select the endpoint to start.
1293  *
1294  * Function that realizes algorithm to schedule right channel for EasyDMA transfer.
1295  * It gets a variable with flags for the endpoints currently requiring transfer.
1296  *
1297  * @param[in] req Bit flags for channels currently requiring transfer.
1298  *                Bits 0...8 used for IN endpoints.
1299  *                Bits 16...24 used for OUT endpoints.
1300  * @note
1301  * This function would be never called with 0 as a @c req argument.
1302  * @return The bit number of the endpoint that should be processed now.
1303  */
usbd_dma_scheduler_algorithm(uint32_t req)1304 static uint8_t usbd_dma_scheduler_algorithm(uint32_t req)
1305 {
1306     /* Only prioritized scheduling mode is supported. */
1307     return __CLZ(__RBIT(req));
1308 }
1309 
1310 /**
1311  * @brief Get the size of isochronous endpoint.
1312  *
1313  * The size of isochronous endpoint is configurable.
1314  * This function returns the size of isochronous buffer taking into account
1315  * current configuration.
1316  *
1317  * @param[in] ep Endpoint number.
1318  *
1319  * @return The size of endpoint buffer.
1320  */
usbd_ep_iso_capacity(nrfx_usbd_ep_t ep)1321 static inline size_t usbd_ep_iso_capacity(nrfx_usbd_ep_t ep)
1322 {
1323     (void)ep;
1324     nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get();
1325     if (NRF_USBD_ISOSPLIT_HALF == split)
1326     {
1327         return NRFX_USBD_ISOSIZE / 2;
1328     }
1329     return NRFX_USBD_ISOSIZE;
1330 }
1331 
1332 /**
1333  * @brief Process all DMA requests.
1334  *
1335  * Function that have to be called from USBD interrupt handler.
1336  * It have to be called when all the interrupts connected with endpoints transfer
1337  * and DMA transfer are already handled.
1338  */
usbd_dmareq_process(void)1339 static void usbd_dmareq_process(void)
1340 {
1341     if (!m_dma_pending)
1342     {
1343         uint32_t req;
1344         while (0 != (req = m_ep_dma_waiting & m_ep_ready))
1345         {
1346             uint8_t pos;
1347             if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST && ((req & USBD_EPISO_BIT_MASK) != 0))
1348             {
1349                 pos = usbd_dma_scheduler_algorithm(req & USBD_EPISO_BIT_MASK);
1350             }
1351             else
1352             {
1353                 pos = usbd_dma_scheduler_algorithm(req);
1354             }
1355             nrfx_usbd_ep_t ep = bit2ep(pos);
1356             usbd_ep_state_t * p_state = ep_state_access(ep);
1357 
1358             nrfx_usbd_ep_transfer_t transfer;
1359             bool continue_transfer;
1360 
1361             NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) ==
1362                 offsetof(usbd_ep_state_t, handler.consumer));
1363             NRFX_ASSERT((p_state->handler.feeder) != NULL);
1364 
1365             if (NRF_USBD_EPIN_CHECK(ep))
1366             {
1367                 /* Device -> Host */
1368                 continue_transfer = p_state->handler.feeder(
1369                     &transfer,
1370                     p_state->p_context,
1371                     p_state->max_packet_size);
1372 
1373                 if (!continue_transfer)
1374                 {
1375                     p_state->handler.feeder = NULL;
1376                 }
1377             }
1378             else
1379             {
1380                 /* Host -> Device */
1381                 const size_t rx_size = nrfx_usbd_epout_size_get(ep);
1382                 continue_transfer = p_state->handler.consumer(
1383                     &transfer,
1384                     p_state->p_context,
1385                     p_state->max_packet_size,
1386                     rx_size);
1387 
1388                 if (transfer.p_data.rx == NULL)
1389                 {
1390                     /* Dropping transfer - allow processing */
1391                     NRFX_ASSERT(transfer.size == 0);
1392                 }
1393                 else if (transfer.size < rx_size)
1394                 {
1395                     NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
1396                     p_state->status = NRFX_USBD_EP_OVERLOAD;
1397                     (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << pos)));
1398                     NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OVERLOAD);
1399                     m_event_handler(&evt);
1400                     /* This endpoint will not be transmitted now, repeat the loop */
1401                     continue;
1402                 }
1403                 else
1404                 {
1405                     /* Nothing to do - only check integrity if assertions are enabled */
1406                     NRFX_ASSERT(transfer.size == rx_size);
1407                 }
1408 
1409                 if (!continue_transfer)
1410                 {
1411                     p_state->handler.consumer = NULL;
1412                 }
1413             }
1414 
1415             usbd_dma_pending_set();
1416             m_ep_ready &= ~(1U << pos);
1417             if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
1418             {
1419                 NRFX_LOG_DEBUG(
1420                     "USB DMA process: Starting transfer on EP: %x, size: %u",
1421                     ep,
1422                     transfer.size);
1423             }
1424             /* Update number of currently transferred bytes */
1425             p_state->transfer_cnt += transfer.size;
1426             /* Start transfer to the endpoint buffer */
1427             nrf_usbd_ep_easydma_set(ep, transfer.p_data.addr, (uint32_t)transfer.size);
1428 
1429             if (nrfx_usbd_errata_104())
1430             {
1431                 uint32_t cnt_end = (uint32_t)(-1);
1432                 do
1433                 {
1434                     uint32_t cnt = (uint32_t)(-1);
1435                     do
1436                     {
1437                         nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED);
1438                         usbd_dma_start(ep);
1439                         nrfx_systick_delay_us(2);
1440                         ++cnt;
1441                     }while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED));
1442                     if (cnt)
1443                     {
1444                         NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   DMA restarted: %u times", cnt);
1445                     }
1446 
1447                     nrfx_systick_delay_us(30);
1448                     while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474))))
1449                     {
1450                         nrfx_systick_delay_us(2);
1451                     }
1452                     nrfx_systick_delay_us(1);
1453 
1454                     ++cnt_end;
1455                 } while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)));
1456                 if (cnt_end)
1457                 {
1458                     NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   DMA fully restarted: %u times", cnt_end);
1459                 }
1460             }
1461             else
1462             {
1463                 usbd_dma_start(ep);
1464                 /* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer.
1465                  * This is quick fix to maintain stability of the stack.
1466                  * It cost some performance but makes stack stable. */
1467                 while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)))
1468                 {
1469                     /* Empty */
1470                 }
1471             }
1472 
1473             if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
1474             {
1475                 NRFX_LOG_DEBUG("USB DMA process - finishing");
1476             }
1477             /* Transfer started - exit the loop */
1478             break;
1479         }
1480     }
1481     else
1482     {
1483         if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
1484         {
1485             NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy");
1486         }
1487     }
1488 }
1489 /** @} */
1490 
1491 /**
1492  * @brief USBD interrupt service routines.
1493  *
1494  */
1495 static const nrfx_irq_handler_t m_isr[] =
1496 {
1497     [USBD_INTEN_USBRESET_Pos   ] = ev_usbreset_handler,
1498     [USBD_INTEN_STARTED_Pos    ] = ev_started_handler,
1499     [USBD_INTEN_ENDEPIN0_Pos   ] = ev_dma_epin0_handler,
1500     [USBD_INTEN_ENDEPIN1_Pos   ] = ev_dma_epin1_handler,
1501     [USBD_INTEN_ENDEPIN2_Pos   ] = ev_dma_epin2_handler,
1502     [USBD_INTEN_ENDEPIN3_Pos   ] = ev_dma_epin3_handler,
1503     [USBD_INTEN_ENDEPIN4_Pos   ] = ev_dma_epin4_handler,
1504     [USBD_INTEN_ENDEPIN5_Pos   ] = ev_dma_epin5_handler,
1505     [USBD_INTEN_ENDEPIN6_Pos   ] = ev_dma_epin6_handler,
1506     [USBD_INTEN_ENDEPIN7_Pos   ] = ev_dma_epin7_handler,
1507     [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler,
1508     [USBD_INTEN_ENDISOIN_Pos   ] = ev_dma_epin8_handler,
1509     [USBD_INTEN_ENDEPOUT0_Pos  ] = ev_dma_epout0_handler,
1510     [USBD_INTEN_ENDEPOUT1_Pos  ] = ev_dma_epout1_handler,
1511     [USBD_INTEN_ENDEPOUT2_Pos  ] = ev_dma_epout2_handler,
1512     [USBD_INTEN_ENDEPOUT3_Pos  ] = ev_dma_epout3_handler,
1513     [USBD_INTEN_ENDEPOUT4_Pos  ] = ev_dma_epout4_handler,
1514     [USBD_INTEN_ENDEPOUT5_Pos  ] = ev_dma_epout5_handler,
1515     [USBD_INTEN_ENDEPOUT6_Pos  ] = ev_dma_epout6_handler,
1516     [USBD_INTEN_ENDEPOUT7_Pos  ] = ev_dma_epout7_handler,
1517     [USBD_INTEN_ENDISOOUT_Pos  ] = ev_dma_epout8_handler,
1518     [USBD_INTEN_SOF_Pos        ] = ev_sof_handler,
1519     [USBD_INTEN_USBEVENT_Pos   ] = ev_usbevent_handler,
1520     [USBD_INTEN_EP0SETUP_Pos   ] = ev_setup_handler,
1521     [USBD_INTEN_EPDATA_Pos     ] = ev_epdata_handler
1522 };
1523 
1524 /**
1525  * @name Interrupt handlers
1526  *
1527  * @{
1528  */
nrfx_usbd_irq_handler(void)1529 void nrfx_usbd_irq_handler(void)
1530 {
1531     const uint32_t enabled = nrf_usbd_int_enable_get();
1532     uint32_t to_process = enabled;
1533     uint32_t active = 0;
1534 
1535     /* Check all enabled interrupts */
1536     while (to_process)
1537     {
1538         uint8_t event_nr = __CLZ(__RBIT(to_process));
1539         if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr)))
1540         {
1541             active |= 1UL << event_nr;
1542         }
1543         to_process &= ~(1UL << event_nr);
1544     }
1545 
1546     if (nrfx_usbd_errata_104())
1547     {
1548         /* Event correcting */
1549         if ((!m_dma_pending) && (0 != (active & (USBD_INTEN_SOF_Msk))))
1550         {
1551             uint8_t usbi, uoi, uii;
1552             /* Testing */
1553             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
1554             uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1555             if (0 != uii)
1556             {
1557                 uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1558             }
1559 
1560             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
1561             uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1562             if (0 != uoi)
1563             {
1564                 uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1565             }
1566             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
1567             usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1568             if (0 != usbi)
1569             {
1570                 usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
1571             }
1572             /* Processing */
1573             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC;
1574             uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1575             if (0 != uii)
1576             {
1577                 uint8_t rb;
1578                 m_simulated_dataepstatus |= ((uint32_t)uii) << NRFX_USBD_EPIN_BITPOS_0;
1579                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
1580                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii;
1581                 rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1582                 NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   uii: 0x%.2x (0x%.2x)", uii, rb);
1583                 (void)rb;
1584             }
1585 
1586             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AD;
1587             uoi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1588             if (0 != uoi)
1589             {
1590                 uint8_t rb;
1591                 m_simulated_dataepstatus |= ((uint32_t)uoi) << NRFX_USBD_EPOUT_BITPOS_0;
1592                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
1593                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi;
1594                 rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1595                 NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   uoi: 0x%.2u (0x%.2x)", uoi, rb);
1596                 (void)rb;
1597             }
1598 
1599             *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AE;
1600             usbi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1601             if (0 != usbi)
1602             {
1603                 uint8_t rb;
1604                 if (usbi & 0x01)
1605                 {
1606                     active |= USBD_INTEN_EP0SETUP_Msk;
1607                 }
1608                 if (usbi & 0x10)
1609                 {
1610                     active |= USBD_INTEN_USBRESET_Msk;
1611                 }
1612                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
1613                 *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = usbi;
1614                 rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
1615                 NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   usbi: 0x%.2u (0x%.2x)", usbi, rb);
1616                 (void)rb;
1617             }
1618 
1619             if (0 != (m_simulated_dataepstatus &
1620                 ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0))))
1621             {
1622                 active |= enabled & NRF_USBD_INT_DATAEP_MASK;
1623             }
1624             if (0 != (m_simulated_dataepstatus &
1625                 ((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0))))
1626             {
1627                 if (0 != (enabled & NRF_USBD_INT_EP0DATADONE_MASK))
1628                 {
1629                     m_simulated_dataepstatus &=
1630                         ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0));
1631                     active |= NRF_USBD_INT_EP0DATADONE_MASK;
1632                 }
1633             }
1634         }
1635     }
1636 
1637     /* Process the active interrupts */
1638     bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK);
1639     active &= ~NRF_USBD_INT_EP0SETUP_MASK;
1640 
1641     while (active)
1642     {
1643         uint8_t event_nr = __CLZ(__RBIT(active));
1644         m_isr[event_nr]();
1645         active &= ~(1UL << event_nr);
1646     }
1647     usbd_dmareq_process();
1648 
1649     if (setup_active)
1650     {
1651         m_isr[USBD_INTEN_EP0SETUP_Pos]();
1652     }
1653 }
1654 
1655 /** @} */
1656 /** @} */
1657 
nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler)1658 nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler)
1659 {
1660     NRFX_ASSERT((nrfx_usbd_errata_type_52840_eng_a() ||
1661                  nrfx_usbd_errata_type_52840_eng_b() ||
1662                  nrfx_usbd_errata_type_52840_eng_c() ||
1663                  nrfx_usbd_errata_type_52840_eng_d())
1664                );
1665 
1666     NRFX_ASSERT(event_handler);
1667 
1668     if (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED)
1669     {
1670         return NRFX_ERROR_INVALID_STATE;
1671     }
1672 
1673     m_event_handler = event_handler;
1674     m_drv_state = NRFX_DRV_STATE_INITIALIZED;
1675 
1676     uint8_t n;
1677     for (n = 0; n < NRF_USBD_EPIN_CNT; ++n)
1678     {
1679         nrfx_usbd_ep_t ep = NRFX_USBD_EPIN(n);
1680         nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
1681             (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
1682         usbd_ep_state_t * p_state = ep_state_access(ep);
1683         p_state->status = NRFX_USBD_EP_OK;
1684         p_state->handler.feeder = NULL;
1685         p_state->transfer_cnt = 0;
1686     }
1687     for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n)
1688     {
1689         nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT(n);
1690         nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
1691             (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
1692         usbd_ep_state_t * p_state = ep_state_access(ep);
1693         p_state->status = NRFX_USBD_EP_OK;
1694         p_state->handler.consumer = NULL;
1695         p_state->transfer_cnt = 0;
1696     }
1697 
1698     return NRFX_SUCCESS;
1699 }
1700 
nrfx_usbd_uninit(void)1701 void nrfx_usbd_uninit(void)
1702 {
1703     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
1704 
1705     m_event_handler = NULL;
1706     m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
1707     return;
1708 }
1709 
nrfx_usbd_enable(void)1710 void nrfx_usbd_enable(void)
1711 {
1712     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
1713 
1714     /* Prepare for READY event receiving */
1715     nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
1716 
1717     if (nrfx_usbd_errata_187())
1718     {
1719         NRFX_CRITICAL_SECTION_ENTER();
1720         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1721         {
1722             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1723             *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1724             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1725         }
1726         else
1727         {
1728             *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
1729         }
1730         NRFX_CRITICAL_SECTION_EXIT();
1731     }
1732 
1733     if (nrfx_usbd_errata_171())
1734     {
1735         NRFX_CRITICAL_SECTION_ENTER();
1736         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1737         {
1738             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1739             *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1740             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1741         }
1742         else
1743         {
1744             *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1745         }
1746         NRFX_CRITICAL_SECTION_EXIT();
1747     }
1748 
1749     /* Enable the peripheral */
1750     nrf_usbd_enable();
1751     /* Waiting for peripheral to enable, this should take a few us */
1752     while (0 == (NRF_USBD_EVENTCAUSE_READY_MASK & nrf_usbd_eventcause_get()))
1753     {
1754         /* Empty loop */
1755     }
1756     nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
1757 
1758     if (nrfx_usbd_errata_171())
1759     {
1760         NRFX_CRITICAL_SECTION_ENTER();
1761         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1762         {
1763             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1764             *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1765             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1766         }
1767         else
1768         {
1769             *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1770         }
1771 
1772         NRFX_CRITICAL_SECTION_EXIT();
1773     }
1774 
1775     if (nrfx_usbd_errata_166())
1776     {
1777         *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3;
1778         *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40;
1779         __ISB();
1780         __DSB();
1781     }
1782 
1783     nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_HALF);
1784 
1785     if (NRFX_USBD_CONFIG_ISO_IN_ZLP)
1786     {
1787         nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA);
1788     }
1789     else
1790     {
1791         nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP);
1792     }
1793 
1794     m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0);
1795     m_ep_dma_waiting = 0;
1796     usbd_dma_pending_clear();
1797     m_last_setup_dir = NRFX_USBD_EPOUT0;
1798 
1799     m_drv_state = NRFX_DRV_STATE_POWERED_ON;
1800 
1801     if (nrfx_usbd_errata_187())
1802     {
1803         NRFX_CRITICAL_SECTION_ENTER();
1804         if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1805         {
1806             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1807             *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1808             *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1809         }
1810         else
1811         {
1812             *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
1813         }
1814         NRFX_CRITICAL_SECTION_EXIT();
1815     }
1816 }
1817 
nrfx_usbd_disable(void)1818 void nrfx_usbd_disable(void)
1819 {
1820     NRFX_ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);
1821 
1822     /* Stop just in case */
1823     nrfx_usbd_stop();
1824 
1825     /* Disable all parts */
1826     nrf_usbd_int_disable(nrf_usbd_int_enable_get());
1827     nrf_usbd_disable();
1828     usbd_dma_pending_clear();
1829     m_drv_state = NRFX_DRV_STATE_INITIALIZED;
1830 }
1831 
nrfx_usbd_start(bool enable_sof)1832 void nrfx_usbd_start(bool enable_sof)
1833 {
1834     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
1835     m_bus_suspend = false;
1836 
1837     uint32_t ints_to_enable =
1838        NRF_USBD_INT_USBRESET_MASK     |
1839        NRF_USBD_INT_STARTED_MASK      |
1840        NRF_USBD_INT_ENDEPIN0_MASK     |
1841        NRF_USBD_INT_EP0DATADONE_MASK  |
1842        NRF_USBD_INT_ENDEPOUT0_MASK    |
1843        NRF_USBD_INT_USBEVENT_MASK     |
1844        NRF_USBD_INT_EP0SETUP_MASK     |
1845        NRF_USBD_INT_DATAEP_MASK;
1846 
1847    if (enable_sof || nrfx_usbd_errata_104())
1848    {
1849        ints_to_enable |= NRF_USBD_INT_SOF_MASK;
1850    }
1851 
1852    /* Enable all required interrupts */
1853    nrf_usbd_int_enable(ints_to_enable);
1854 
1855    /* Enable interrupt globally */
1856    NRFX_IRQ_PRIORITY_SET(USBD_IRQn, NRFX_USBD_CONFIG_IRQ_PRIORITY);
1857    NRFX_IRQ_ENABLE(USBD_IRQn);
1858 
1859    /* Enable pullups */
1860    nrf_usbd_pullup_enable();
1861 }
1862 
nrfx_usbd_stop(void)1863 void nrfx_usbd_stop(void)
1864 {
1865     NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
1866 
1867     if (NRFX_IRQ_IS_ENABLED(USBD_IRQn))
1868     {
1869         /* Abort transfers */
1870         usbd_ep_abort_all();
1871 
1872         /* Disable pullups */
1873         nrf_usbd_pullup_disable();
1874 
1875         /* Disable interrupt globally */
1876         NRFX_IRQ_DISABLE(USBD_IRQn);
1877 
1878         /* Disable all interrupts */
1879         nrf_usbd_int_disable(~0U);
1880     }
1881 }
1882 
nrfx_usbd_is_initialized(void)1883 bool nrfx_usbd_is_initialized(void)
1884 {
1885     return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED);
1886 }
1887 
nrfx_usbd_is_enabled(void)1888 bool nrfx_usbd_is_enabled(void)
1889 {
1890     return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON);
1891 }
1892 
nrfx_usbd_is_started(void)1893 bool nrfx_usbd_is_started(void)
1894 {
1895     return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn));
1896 }
1897 
nrfx_usbd_suspend(void)1898 bool nrfx_usbd_suspend(void)
1899 {
1900     bool suspended = false;
1901 
1902     NRFX_CRITICAL_SECTION_ENTER();
1903     if (m_bus_suspend)
1904     {
1905         usbd_ep_abort_all();
1906 
1907         if (!(nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK))
1908         {
1909             nrf_usbd_lowpower_enable();
1910             if (nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK)
1911             {
1912                 nrf_usbd_lowpower_disable();
1913             }
1914             else
1915             {
1916                 suspended = true;
1917 
1918                 if (nrfx_usbd_errata_171())
1919                 {
1920                     if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1921                     {
1922                         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1923                         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1924                         *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1925                     }
1926                     else
1927                     {
1928                         *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
1929                     }
1930                 }
1931             }
1932         }
1933     }
1934     NRFX_CRITICAL_SECTION_EXIT();
1935 
1936     return suspended;
1937 }
1938 
nrfx_usbd_wakeup_req(void)1939 bool nrfx_usbd_wakeup_req(void)
1940 {
1941     bool started = false;
1942 
1943     NRFX_CRITICAL_SECTION_ENTER();
1944     if (m_bus_suspend && nrf_usbd_lowpower_check())
1945     {
1946         nrf_usbd_lowpower_disable();
1947         started = true;
1948 
1949         if (nrfx_usbd_errata_171())
1950         {
1951             if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
1952             {
1953                 *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1954                 *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1955                 *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
1956             }
1957             else
1958             {
1959                 *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
1960             }
1961 
1962         }
1963     }
1964     NRFX_CRITICAL_SECTION_EXIT();
1965 
1966     return started;
1967 }
1968 
nrfx_usbd_suspend_check(void)1969 bool nrfx_usbd_suspend_check(void)
1970 {
1971     return nrf_usbd_lowpower_check();
1972 }
1973 
nrfx_usbd_suspend_irq_config(void)1974 void nrfx_usbd_suspend_irq_config(void)
1975 {
1976     nrf_usbd_int_disable(m_irq_disabled_in_suspend);
1977 }
1978 
nrfx_usbd_active_irq_config(void)1979 void nrfx_usbd_active_irq_config(void)
1980 {
1981     nrf_usbd_int_enable(m_irq_disabled_in_suspend);
1982 }
1983 
nrfx_usbd_bus_suspend_check(void)1984 bool nrfx_usbd_bus_suspend_check(void)
1985 {
1986     return m_bus_suspend;
1987 }
1988 
nrfx_usbd_force_bus_wakeup(void)1989 void nrfx_usbd_force_bus_wakeup(void)
1990 {
1991     m_bus_suspend = false;
1992 }
1993 
nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep,uint16_t size)1994 void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size)
1995 {
1996     /* Only power of 2 size allowed */
1997     NRFX_ASSERT((size != 0) && (size & (size - 1)) == 0);
1998     /* Packet size cannot be higher than maximum buffer size */
1999     NRFX_ASSERT((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) ||
2000                 (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRFX_USBD_EPSIZE)));
2001 
2002     usbd_ep_state_t * p_state = ep_state_access(ep);
2003     p_state->max_packet_size = size;
2004 }
2005 
nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep)2006 uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep)
2007 {
2008     usbd_ep_state_t const * p_state = ep_state_access(ep);
2009     return p_state->max_packet_size;
2010 }
2011 
nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep)2012 bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep)
2013 {
2014     return nrf_usbd_ep_enable_check(ep_to_hal(ep));
2015 }
2016 
nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep)2017 void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep)
2018 {
2019     nrf_usbd_int_enable(nrfx_usbd_ep_to_int(ep));
2020 
2021     if (nrf_usbd_ep_enable_check(ep))
2022     {
2023         return;
2024     }
2025     nrf_usbd_ep_enable(ep_to_hal(ep));
2026     if ((NRF_USBD_EP_NR_GET(ep) != 0) &&
2027         NRF_USBD_EPOUT_CHECK(ep) &&
2028         !NRF_USBD_EPISO_CHECK(ep))
2029     {
2030         NRFX_CRITICAL_SECTION_ENTER();
2031         nrfx_usbd_transfer_out_drop(ep);
2032         m_ep_dma_waiting &= ~(1U << ep2bit(ep));
2033         NRFX_CRITICAL_SECTION_EXIT();
2034     }
2035 }
2036 
nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep)2037 void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep)
2038 {
2039     usbd_ep_abort(ep);
2040     nrf_usbd_ep_disable(ep_to_hal(ep));
2041     nrf_usbd_int_disable(nrfx_usbd_ep_to_int(ep));
2042 }
2043 
nrfx_usbd_ep_default_config(void)2044 void nrfx_usbd_ep_default_config(void)
2045 {
2046     nrf_usbd_int_disable(
2047         NRF_USBD_INT_ENDEPIN1_MASK  |
2048         NRF_USBD_INT_ENDEPIN2_MASK  |
2049         NRF_USBD_INT_ENDEPIN3_MASK  |
2050         NRF_USBD_INT_ENDEPIN4_MASK  |
2051         NRF_USBD_INT_ENDEPIN5_MASK  |
2052         NRF_USBD_INT_ENDEPIN6_MASK  |
2053         NRF_USBD_INT_ENDEPIN7_MASK  |
2054         NRF_USBD_INT_ENDISOIN0_MASK |
2055         NRF_USBD_INT_ENDEPOUT1_MASK |
2056         NRF_USBD_INT_ENDEPOUT2_MASK |
2057         NRF_USBD_INT_ENDEPOUT3_MASK |
2058         NRF_USBD_INT_ENDEPOUT4_MASK |
2059         NRF_USBD_INT_ENDEPOUT5_MASK |
2060         NRF_USBD_INT_ENDEPOUT6_MASK |
2061         NRF_USBD_INT_ENDEPOUT7_MASK |
2062         NRF_USBD_INT_ENDISOOUT0_MASK
2063     );
2064     nrf_usbd_int_enable(NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK);
2065     nrf_usbd_ep_all_disable();
2066 }
2067 
nrfx_usbd_ep_transfer(nrfx_usbd_ep_t ep,nrfx_usbd_transfer_t const * p_transfer)2068 nrfx_err_t nrfx_usbd_ep_transfer(
2069     nrfx_usbd_ep_t               ep,
2070     nrfx_usbd_transfer_t const * p_transfer)
2071 {
2072     nrfx_err_t ret;
2073     const uint8_t ep_bitpos = ep2bit(ep);
2074     NRFX_ASSERT(NULL != p_transfer);
2075 
2076     NRFX_CRITICAL_SECTION_ENTER();
2077     /* Setup data transaction can go only in one direction at a time */
2078     if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
2079     {
2080         ret = NRFX_ERROR_INVALID_ADDR;
2081         if (NRFX_USBD_FAILED_TRANSFERS_DEBUG &&
2082             (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
2083         {
2084             NRFX_LOG_DEBUG("Transfer failed: Invalid EPr\n");
2085         }
2086     }
2087     else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
2088     {
2089         /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */
2090         ret = NRFX_ERROR_BUSY;
2091         if (NRFX_USBD_FAILED_TRANSFERS_DEBUG)
2092         {
2093             NRFX_LOG_DEBUG("Transfer failed: EP is busy");
2094         }
2095     }
2096     else
2097     {
2098         usbd_ep_state_t * p_state =  ep_state_access(ep);
2099         /* Prepare transfer context and handler description */
2100         nrfx_usbd_transfer_t * p_context;
2101         if (NRF_USBD_EPIN_CHECK(ep))
2102         {
2103             p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep);
2104             if (nrfx_is_in_ram(p_transfer->p_data.tx))
2105             {
2106                 /* RAM */
2107                 if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG))
2108                 {
2109                     p_state->handler.feeder = nrfx_usbd_feeder_ram;
2110                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2111                     {
2112                         NRFX_LOG_DEBUG(
2113                             "Transfer called on endpoint %x, size: %u, mode: "
2114                             "RAM",
2115                             ep,
2116                             p_transfer->size);
2117                     }
2118                 }
2119                 else
2120                 {
2121                     p_state->handler.feeder = nrfx_usbd_feeder_ram_zlp;
2122                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2123                     {
2124                         NRFX_LOG_DEBUG(
2125                             "Transfer called on endpoint %x, size: %u, mode: "
2126                             "RAM_ZLP",
2127                             ep,
2128                             p_transfer->size);
2129                     }
2130                 }
2131             }
2132             else
2133             {
2134                 /* Flash */
2135                 if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG))
2136                 {
2137                     p_state->handler.feeder = nrfx_usbd_feeder_flash;
2138                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2139                     {
2140                         NRFX_LOG_DEBUG(
2141                             "Transfer called on endpoint %x, size: %u, mode: "
2142                             "FLASH",
2143                             ep,
2144                             p_transfer->size);
2145                     }
2146                 }
2147                 else
2148                 {
2149                     p_state->handler.feeder = nrfx_usbd_feeder_flash_zlp;
2150                     if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2151                     {
2152                         NRFX_LOG_DEBUG(
2153                             "Transfer called on endpoint %x, size: %u, mode: "
2154                             "FLASH_ZLP",
2155                             ep,
2156                             p_transfer->size);
2157                     }
2158                 }
2159             }
2160         }
2161         else
2162         {
2163             p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep);
2164             NRFX_ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx)));
2165             p_state->handler.consumer = nrfx_usbd_consumer;
2166         }
2167         *p_context = *p_transfer;
2168         p_state->p_context = p_context;
2169 
2170         p_state->transfer_cnt = 0;
2171         p_state->status    =  NRFX_USBD_EP_OK;
2172         m_ep_dma_waiting   |= 1U << ep_bitpos;
2173         ret = NRFX_SUCCESS;
2174         usbd_int_rise();
2175     }
2176     NRFX_CRITICAL_SECTION_EXIT();
2177     return ret;
2178 }
2179 
nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep,nrfx_usbd_handler_desc_t const * p_handler)2180 nrfx_err_t nrfx_usbd_ep_handled_transfer(
2181     nrfx_usbd_ep_t                   ep,
2182     nrfx_usbd_handler_desc_t const * p_handler)
2183 {
2184     nrfx_err_t ret;
2185     const uint8_t ep_bitpos = ep2bit(ep);
2186     NRFX_ASSERT(NULL != p_handler);
2187 
2188     NRFX_CRITICAL_SECTION_ENTER();
2189     /* Setup data transaction can go only in one direction at a time */
2190     if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
2191     {
2192         ret = NRFX_ERROR_INVALID_ADDR;
2193         if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
2194         {
2195             NRFX_LOG_DEBUG("Transfer failed: Invalid EP");
2196         }
2197     }
2198     else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
2199     {
2200         /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */
2201         ret = NRFX_ERROR_BUSY;
2202         if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
2203         {
2204             NRFX_LOG_DEBUG("Transfer failed: EP is busy");
2205         }
2206     }
2207     else
2208     {
2209         /* Transfer can be configured now */
2210         usbd_ep_state_t * p_state =  ep_state_access(ep);
2211 
2212         p_state->transfer_cnt = 0;
2213         p_state->handler   = p_handler->handler;
2214         p_state->p_context = p_handler->p_context;
2215         p_state->status    =  NRFX_USBD_EP_OK;
2216         m_ep_dma_waiting   |= 1U << ep_bitpos;
2217 
2218         ret = NRFX_SUCCESS;
2219         if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
2220         {
2221             NRFX_LOG_DEBUG("Transfer called on endpoint %x, mode: Handler", ep);
2222         }
2223         usbd_int_rise();
2224     }
2225     NRFX_CRITICAL_SECTION_EXIT();
2226     return ret;
2227 }
2228 
nrfx_usbd_feeder_buffer_get(void)2229 void * nrfx_usbd_feeder_buffer_get(void)
2230 {
2231     return m_tx_buffer;
2232 }
2233 
nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep,size_t * p_size)2234 nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t * p_size)
2235 {
2236     nrfx_usbd_ep_status_t ret;
2237 
2238     usbd_ep_state_t const * p_state = ep_state_access(ep);
2239     NRFX_CRITICAL_SECTION_ENTER();
2240     *p_size = p_state->transfer_cnt;
2241     ret = (p_state->handler.consumer == NULL) ? p_state->status : NRFX_USBD_EP_BUSY;
2242     NRFX_CRITICAL_SECTION_EXIT();
2243     return ret;
2244 }
2245 
nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep)2246 size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep)
2247 {
2248     return nrf_usbd_epout_size_get(ep_to_hal(ep));
2249 }
2250 
nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep)2251 bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep)
2252 {
2253     return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep2bit(ep))));
2254 }
2255 
nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep)2256 void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep)
2257 {
2258     NRFX_LOG_DEBUG("USB: EP %x stalled.", ep);
2259     nrf_usbd_ep_stall(ep_to_hal(ep));
2260 }
2261 
nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep)2262 void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep)
2263 {
2264     if (NRF_USBD_EPOUT_CHECK(ep) && nrfx_usbd_ep_stall_check(ep))
2265     {
2266         nrfx_usbd_transfer_out_drop(ep);
2267     }
2268     nrf_usbd_ep_unstall(ep_to_hal(ep));
2269 }
2270 
nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep)2271 bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep)
2272 {
2273     return nrf_usbd_ep_is_stall(ep_to_hal(ep));
2274 }
2275 
nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep)2276 void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep)
2277 {
2278     nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_DATA0);
2279 }
2280 
nrfx_usbd_setup_get(nrfx_usbd_setup_t * p_setup)2281 void nrfx_usbd_setup_get(nrfx_usbd_setup_t * p_setup)
2282 {
2283     memset(p_setup, 0, sizeof(nrfx_usbd_setup_t));
2284     p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get();
2285     p_setup->bRequest      = nrf_usbd_setup_brequest_get();
2286     p_setup->wValue        = nrf_usbd_setup_wvalue_get();
2287     p_setup->wIndex        = nrf_usbd_setup_windex_get();
2288     p_setup->wLength       = nrf_usbd_setup_wlength_get();
2289 }
2290 
nrfx_usbd_setup_data_clear(void)2291 void nrfx_usbd_setup_data_clear(void)
2292 {
2293     if (nrfx_usbd_errata_104())
2294     {
2295         /* For this fix to work properly, it must be ensured that the task is
2296          * executed twice one after another - blocking ISR. This is however a temporary
2297          * solution to be used only before production version of the chip. */
2298         uint32_t primask_copy = __get_PRIMASK();
2299         __disable_irq();
2300         nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
2301         nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
2302         __set_PRIMASK(primask_copy);
2303     }
2304     else
2305     {
2306         nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
2307     }
2308 }
2309 
nrfx_usbd_setup_clear(void)2310 void nrfx_usbd_setup_clear(void)
2311 {
2312     NRFX_LOG_DEBUG(">> ep0status >>");
2313     nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
2314 }
2315 
nrfx_usbd_setup_stall(void)2316 void nrfx_usbd_setup_stall(void)
2317 {
2318     NRFX_LOG_DEBUG("Setup stalled.");
2319     nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL);
2320 }
2321 
nrfx_usbd_last_setup_dir_get(void)2322 nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void)
2323 {
2324     return m_last_setup_dir;
2325 }
2326 
nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)2327 void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)
2328 {
2329     NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep));
2330 
2331     if (nrfx_usbd_errata_200())
2332     {
2333         NRFX_CRITICAL_SECTION_ENTER();
2334         m_ep_ready &= ~(1U << ep2bit(ep));
2335         *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
2336         *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
2337         (void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
2338         NRFX_CRITICAL_SECTION_EXIT();
2339     }
2340     else
2341     {
2342         NRFX_CRITICAL_SECTION_ENTER();
2343         m_ep_ready &= ~(1U << ep2bit(ep));
2344         if (!NRF_USBD_EPISO_CHECK(ep))
2345         {
2346             nrf_usbd_epout_clear(ep);
2347         }
2348         NRFX_CRITICAL_SECTION_EXIT();
2349     }
2350 }
2351 
2352 #endif // NRFX_CHECK(NRFX_USBD_ENABLED)
2353