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