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