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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 749 static inline void usbd_dma_start(nrfx_usbd_ep_t ep) 750 { 751 nrf_usbd_task_trigger(task_start_ep(ep)); 752 } 753 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 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 */ 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 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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 1102 static void ev_dma_epin0_handler(void) { nrf_usbd_ep0in_dma_handler(); } 1103 static void ev_dma_epin1_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN1 ); } 1104 static void ev_dma_epin2_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN2 ); } 1105 static void ev_dma_epin3_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN3 ); } 1106 static void ev_dma_epin4_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN4 ); } 1107 static void ev_dma_epin5_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN5 ); } 1108 static void ev_dma_epin6_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN6 ); } 1109 static void ev_dma_epin7_handler(void) { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN7 ); } 1110 static void ev_dma_epin8_handler(void) { nrf_usbd_epiniso_dma_handler(NRFX_USBD_EPIN8 ); } 1111 1112 static void ev_dma_epout0_handler(void) { nrf_usbd_ep0out_dma_handler(); } 1113 static void ev_dma_epout1_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT1); } 1114 static void ev_dma_epout2_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT2); } 1115 static void ev_dma_epout3_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT3); } 1116 static void ev_dma_epout4_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT4); } 1117 static void ev_dma_epout5_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT5); } 1118 static void ev_dma_epout6_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT6); } 1119 static void ev_dma_epout7_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT7); } 1120 static void ev_dma_epout8_handler(void) { nrf_usbd_epoutiso_dma_handler(NRFX_USBD_EPOUT8); } 1121 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 */ 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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 1883 bool nrfx_usbd_is_initialized(void) 1884 { 1885 return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED); 1886 } 1887 1888 bool nrfx_usbd_is_enabled(void) 1889 { 1890 return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON); 1891 } 1892 1893 bool nrfx_usbd_is_started(void) 1894 { 1895 return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn)); 1896 } 1897 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 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 1969 bool nrfx_usbd_suspend_check(void) 1970 { 1971 return nrf_usbd_lowpower_check(); 1972 } 1973 1974 void nrfx_usbd_suspend_irq_config(void) 1975 { 1976 nrf_usbd_int_disable(m_irq_disabled_in_suspend); 1977 } 1978 1979 void nrfx_usbd_active_irq_config(void) 1980 { 1981 nrf_usbd_int_enable(m_irq_disabled_in_suspend); 1982 } 1983 1984 bool nrfx_usbd_bus_suspend_check(void) 1985 { 1986 return m_bus_suspend; 1987 } 1988 1989 void nrfx_usbd_force_bus_wakeup(void) 1990 { 1991 m_bus_suspend = false; 1992 } 1993 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 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 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 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 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 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 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 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 2229 void * nrfx_usbd_feeder_buffer_get(void) 2230 { 2231 return m_tx_buffer; 2232 } 2233 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 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 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 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 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 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 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 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 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 2310 void nrfx_usbd_setup_clear(void) 2311 { 2312 NRFX_LOG_DEBUG(">> ep0status >>"); 2313 nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS); 2314 } 2315 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 2322 nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void) 2323 { 2324 return m_last_setup_dir; 2325 } 2326 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