From 203bce7ae79ac63652c27aa26b3d480cd9c19cc0 Mon Sep 17 00:00:00 2001 From: Kamil Sroka Date: Fri, 22 Feb 2019 18:00:57 +0100 Subject: [PATCH] [nrf528xx] update usbd (#3618) --- third_party/NordicSemiconductor/Makefile.am | 5 +- .../dependencies/nrfx_glue.h | 74 +- .../dependencies/sdk_config.h | 7 + .../drivers/usbd/nrf_drv_usbd.c | 2415 ----------------- .../drivers/usbd/nrf_drv_usbd.h | 1182 ++------ .../drivers/usbd/nrf_drv_usbd_errata.h | 280 +- 6 files changed, 387 insertions(+), 3576 deletions(-) delete mode 100644 third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.c diff --git a/third_party/NordicSemiconductor/Makefile.am b/third_party/NordicSemiconductor/Makefile.am index 397028c91..c235011e4 100644 --- a/third_party/NordicSemiconductor/Makefile.am +++ b/third_party/NordicSemiconductor/Makefile.am @@ -112,10 +112,11 @@ NORDICSEMI_COMMON_SOURCES nrfx/drivers/src/nrfx_power.c \ nrfx/drivers/src/nrfx_systick.c \ nrfx/hal/nrf_nvmc.c \ + nrfx/soc/nrfx_atomic.c \ $(NULL) NORDICSEMI_USB_SOURCES = \ - drivers/usbd/nrf_drv_usbd.c \ + nrfx/drivers/src/nrfx_usbd.c \ libraries/atfifo/nrf_atfifo.c \ libraries/atomic/nrf_atomic.c \ libraries/usb/app_usbd.c \ @@ -361,6 +362,8 @@ noinst_HEADERS $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power_clock.h \ $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power.h \ $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_systick.h \ + $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_usbd.h \ + $(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/src/nrfx_usbd_errata.h \ $(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_clock.h \ $(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpio.h \ $(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpiote.h \ diff --git a/third_party/NordicSemiconductor/dependencies/nrfx_glue.h b/third_party/NordicSemiconductor/dependencies/nrfx_glue.h index af3ebf853..0a41b981a 100644 --- a/third_party/NordicSemiconductor/dependencies/nrfx_glue.h +++ b/third_party/NordicSemiconductor/dependencies/nrfx_glue.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA * * All rights reserved. * @@ -116,7 +116,6 @@ static inline void _NRFX_IRQ_PRIORITY_SET(IRQn_Type irq_number, #define NRFX_IRQ_ENABLE(irq_number) _NRFX_IRQ_ENABLE(irq_number) static inline void _NRFX_IRQ_ENABLE(IRQn_Type irq_number) { - NVIC_ClearPendingIRQ(irq_number); NVIC_EnableIRQ(irq_number); } @@ -207,6 +206,76 @@ static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) //------------------------------------------------------------------------------ +#include + +/** + * @brief Atomic 32 bit unsigned type. + */ +#define nrfx_atomic_t nrfx_atomic_u32_t + +/** + * @brief Stores value to an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value to store. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_STORE(p_data, value) nrfx_atomic_u32_fetch_store(p_data, value) + +/** + * @brief Performs logical OR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of OR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_OR(p_data, value) nrfx_atomic_u32_fetch_or(p_data, value) + +/** + * @brief Performs logical AND operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of AND operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_AND(p_data, value) nrfx_atomic_u32_fetch_and(p_data, value) + +/** + * @brief Performs logical XOR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of XOR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_XOR(p_data, value) nrfx_atomic_u32_fetch_xor(p_data, value) + +/** + * @brief Performs logical ADD operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of ADD operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_ADD(p_data, value) nrfx_atomic_u32_fetch_add(p_data, value) + +/** + * @brief Performs logical SUB operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of SUB operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_SUB(p_data, value) nrfx_atomic_u32_fetch_sub(p_data, value) + +//------------------------------------------------------------------------------ +#ifndef NRFX_CUSTOM_ERROR_CODES + #include /** * @brief When set to a non-zero value, this macro specifies that the @@ -236,6 +305,7 @@ typedef ret_code_t nrfx_err_t; #define NRFX_ERROR_DRV_TWI_ERR_ANACK NRF_ERROR_DRV_TWI_ERR_ANACK #define NRFX_ERROR_DRV_TWI_ERR_DNACK NRF_ERROR_DRV_TWI_ERR_DNACK +#endif // NRFX_CUSTOM_ERROR_CODES //------------------------------------------------------------------------------ #include diff --git a/third_party/NordicSemiconductor/dependencies/sdk_config.h b/third_party/NordicSemiconductor/dependencies/sdk_config.h index 86db33a64..e4f96c192 100644 --- a/third_party/NordicSemiconductor/dependencies/sdk_config.h +++ b/third_party/NordicSemiconductor/dependencies/sdk_config.h @@ -354,6 +354,13 @@ #define USBD_CONFIG_ISO_IN_ZLP 0 #endif +#define NRFX_USBD_ENABLED USBD_ENABLED +#define NRFX_USBD_POWER_DETECTION USBD_POWER_DETECTION +#define NRFX_USBD_CONFIG_IRQ_PRIORITY USBD_CONFIG_IRQ_PRIORITY +#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE USBD_CONFIG_DMASCHEDULER_MODE +#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST USBD_CONFIG_DMASCHEDULER_ISO_BOOST +#define NRFX_USBD_CONFIG_ISO_IN_ZLP USBD_CONFIG_ISO_IN_ZLP + // diff --git a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.c b/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.c deleted file mode 100644 index 114e0d4f9..000000000 --- a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.c +++ /dev/null @@ -1,2415 +0,0 @@ -/** - * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -#include "sdk_common.h" -#if NRF_MODULE_ENABLED(USBD) - -#include "nrf_drv_usbd.h" -#include "nrf.h" -#include "nrf_atomic.h" -#include "app_util_platform.h" -#include "nrf_delay.h" - -#include -#include -#include - -#define NRF_LOG_MODULE_NAME USBD - -#if USBD_CONFIG_LOG_ENABLED -#define NRF_LOG_LEVEL USBD_CONFIG_LOG_LEVEL -#define NRF_LOG_INFO_COLOR USBD_CONFIG_INFO_COLOR -#define NRF_LOG_DEBUG_COLOR USBD_CONFIG_DEBUG_COLOR -#else //USBD_CONFIG_LOG_ENABLED -#define NRF_LOG_LEVEL 0 -#endif //USBD_CONFIG_LOG_ENABLED -#include "nrf_log.h" -NRF_LOG_MODULE_REGISTER(); - -#ifndef NRF_DRV_USBD_EARLY_DMA_PROCESS -/* Try to process DMA request when endpoint transmission has been detected - * and just after last EasyDMA has been processed. - * It speeds up the transmission a little (about 10% measured) - * with a cost of more CPU power used. - */ -#define NRF_DRV_USBD_EARLY_DMA_PROCESS 1 -#endif - -#ifndef NRF_DRV_USBD_PROTO1_FIX_DEBUG -/* Debug information when events are fixed*/ -#define NRF_DRV_USBD_PROTO1_FIX_DEBUG 1 -#endif - -#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) \ - do{ \ - if (NRF_DRV_USBD_PROTO1_FIX_DEBUG){ NRF_LOG_DEBUG(__VA_ARGS__); }\ - } while (0) - -#ifndef NRF_DRV_USBD_STARTED_EV_ENABLE -#define NRF_DRV_USBD_STARTED_EV_ENABLE 0 -#endif - -#ifndef USBD_CONFIG_ISO_IN_ZLP -#define USBD_CONFIG_ISO_IN_ZLP 0 -#endif - -#ifndef NRF_USBD_ISO_DEBUG -/* Also generate information about ISOCHRONOUS events and transfers. - * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this - * option generates a lot of useless messages. */ -#define NRF_USBD_ISO_DEBUG 1 -#endif - -#ifndef NRF_USBD_FAILED_TRANSFERS_DEBUG -/* Also generate debug information for failed transfers. - * It might be useful but may generate a lot of useless debug messages - * in some library usages (for example when transfer is generated and the - * result is used to check whatever endpoint was busy. */ -#define NRF_USBD_FAILED_TRANSFERS_DEBUG 1 -#endif - -#ifndef NRF_USBD_DMAREQ_PROCESS_DEBUG -/* Generate additional messages that mark the status inside - * @ref usbd_dmareq_process. - * It is useful to debug library internals but may generate a lot of - * useless debug messages. */ -#define NRF_USBD_DMAREQ_PROCESS_DEBUG 1 -#endif - - -/** - * @defgroup nrf_drv_usbd_int USB Device driver internal part - * @internal - * @ingroup nrf_drv_usbd - * - * This part contains auxiliary internal macros, variables and functions. - * @{ - */ - -/** - * @brief Assert endpoint number validity - * - * Internal macro to be used during program creation in debug mode. - * Generates assertion if endpoint number is not valid. - * - * @param ep Endpoint number to validity check - */ -#define USBD_ASSERT_EP_VALID(ep) ASSERT( \ - ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT )) \ - || \ - (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \ -); - -/** - * @brief Lowest position of bit for IN endpoint - * - * The first bit position corresponding to IN endpoint. - * @sa ep2bit bit2ep - */ -#define USBD_EPIN_BITPOS_0 0 - -/** - * @brief Lowest position of bit for OUT endpoint - * - * The first bit position corresponding to OUT endpoint - * @sa ep2bit bit2ep - */ -#define USBD_EPOUT_BITPOS_0 16 - -/** - * @brief Input endpoint bits mask - */ -#define USBD_EPIN_BIT_MASK (0xFFFFU << USBD_EPIN_BITPOS_0) - -/** - * @brief Output endpoint bits mask - */ -#define USBD_EPOUT_BIT_MASK (0xFFFFU << USBD_EPOUT_BITPOS_0) - -/** - * @brief Isochronous endpoint bit mask - */ -#define USBD_EPISO_BIT_MASK \ - ((1U << USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT8)) | (1U << USBD_EP_BITPOS(NRF_DRV_USBD_EPIN8))) - -/** - * @brief Auxiliary macro to change EP number into bit position - * - * This macro is used by @ref ep2bit function but also for statically check - * the bitpos values integrity during compilation. - * - * @param[in] ep Endpoint number. - * @return Endpoint bit position. - */ -#define USBD_EP_BITPOS(ep) \ - ((NRF_USBD_EPIN_CHECK(ep) ? USBD_EPIN_BITPOS_0 : USBD_EPOUT_BITPOS_0) + NRF_USBD_EP_NR_GET(ep)) - -/** - * @brief Helper macro for creating an endpoint transfer event. - * - * @param[in] name Name of the created transfer event variable. - * @param[in] endpoint Endpoint number. - * @param[in] ep_stat Endpoint state to report. - * - * @return Initialized event constant variable. - */ -#define NRF_DRV_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ - const nrf_drv_usbd_evt_t name = { \ - NRF_DRV_USBD_EVT_EPTRANSFER, \ - .data = { \ - .eptransfer = { \ - .ep = endpont, \ - .status = ep_stat \ - } \ - } \ - } - -/* Check it the bit positions values match defined DATAEPSTATUS bit positions */ -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos ); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos); -STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos); - - -/** - * @name Internal auxiliary definitions for SETUP packet - * - * Definitions used to take out the information about last SETUP packet direction - * from @c bmRequestType. - * @{ - */ -/** The position of DIR bit in bmRequestType inside SETUP packet */ -#define USBD_DRV_REQUESTTYPE_DIR_BITPOS 7 -/** The mask of DIR bit in bmRequestType inside SETUP packet */ -#define USBD_DRV_REQUESTTYPE_DIR_MASK (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) -/** The value of DIR bit for OUT direction (Host -> Device) */ -#define USBD_DRV_REQUESTTYPE_DIR_OUT (0U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) -/** The value of DIR bit for IN direction (Device -> Host) */ -#define USBD_DRV_REQUESTTYPE_DIR_IN (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) -/** @} */ - -/** - * @brief Current driver state - */ -static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; - -/** - * @brief Event handler for the library - * - * Event handler that would be called on events. - * - * @note Currently it cannot be null if any interrupt is activated. - */ -static nrf_drv_usbd_event_handler_t m_event_handler; - -/** - * @brief Detected state of the bus - * - * Internal state changed in interrupts handling when - * RESUME or SUSPEND event is processed. - * - * Values: - * - true - bus suspended - * - false - ongoing normal communication on the bus - * - * @note This is only the bus state and does not mean that the peripheral is in suspend state. - */ -static volatile bool m_bus_suspend; - -/** - * @brief Internal constant that contains interrupts disabled in suspend state - * - * Internal constant used in @ref nrf_drv_usbd_suspend_irq_config and @ref nrf_drv_usbd_active_irq_config - * functions. - */ -static const uint32_t m_irq_disabled_in_suspend = - NRF_USBD_INT_ENDEPIN0_MASK | - NRF_USBD_INT_EP0DATADONE_MASK | - NRF_USBD_INT_ENDEPOUT0_MASK | - NRF_USBD_INT_EP0SETUP_MASK | - NRF_USBD_INT_DATAEP_MASK; - -/** - * @brief Direction of last received Setup transfer - * - * This variable is used to redirect internal setup data event - * into selected endpoint (IN or OUT). - */ -static nrf_drv_usbd_ep_t m_last_setup_dir; - -/** - * @brief Mark endpoint readiness for DMA transfer - * - * Bits in this variable are cleared and set in interrupts. - * 1 means that endpoint is ready for DMA transfer. - * 0 means that DMA transfer cannot be performed on selected endpoint. - */ -static uint32_t m_ep_ready; - -/** - * @brief Mark endpoint with prepared data to transfer by DMA - * - * This variable can be from any place in the code (interrupt or main thread). - * It would be cleared only from USBD interrupt. - * - * Mask prepared USBD data for transmission. - * It is cleared when no more data to transmit left. - */ -static uint32_t m_ep_dma_waiting; - -/** - * @brief Current EasyDMA state - * - * Single flag, updated only inside interrupts, that marks current EasyDMA state. - * In USBD there is only one DMA channel working in background, and new transfer - * cannot be started when there is ongoing transfer on any other channel. - */ -static bool m_dma_pending; - -/** - * @brief Simulated data EP status bits required for errata 104 - * - * Marker to delete when not required anymore: >> NRF_DRV_USBD_ERRATA_ENABLE << - */ -static uint32_t m_simulated_dataepstatus; - -/** - * @brief The structure that would hold transfer configuration to every endpoint - * - * The structure that holds all the data required by the endpoint to proceed - * with LIST functionality and generate quick callback directly when data - * buffer is ready. - */ -typedef struct -{ - nrf_drv_usbd_handler_t handler; //!< Handler for current transfer, function pointer - void * p_context; //!< Context for transfer handler - size_t transfer_cnt; //!< Number of transferred bytes in the current transfer - uint16_t max_packet_size; //!< Configured endpoint size - nrf_drv_usbd_ep_status_t status; //!< NRF_SUCCESS or error code, never NRF_ERROR_BUSY - this one is calculated -}usbd_drv_ep_state_t; - -/** - * @brief The array of transfer configurations for the endpoints. - * - * The status of the transfer on each endpoint. - */ -static struct -{ - usbd_drv_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints. - usbd_drv_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints. -}m_ep_state; - -/** - * @brief Status variables for integrated feeders. - * - * Current status for integrated feeders (IN transfers). - * Integrated feeders are used for default transfers: - * 1. Simple RAM transfer - * 2. Simple flash transfer - * 3. RAM transfer with automatic ZLP - * 4. Flash transfer with automatic ZLP - */ -nrf_drv_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; - -/** - * @brief Status variables for integrated consumers - * - * Current status for integrated consumers - * Currently one type of transfer is supported: - * 1. Transfer to RAM - * - * Transfer is finished automatically when received data block is smaller - * than the endpoint buffer or all the required data is received. - */ -nrf_drv_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; - - -/** - * @brief Buffer used to send data directly from FLASH - * - * This is internal buffer that would be used to emulate the possibility - * to transfer data directly from FLASH. - * We do not have to care about the source of data when calling transfer functions. - * - * We do not need more buffers that one, because only one transfer can be pending - * at once. - */ -static uint32_t m_tx_buffer[CEIL_DIV( - NRF_DRV_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))]; - - -/* Early declaration. Documentation above definition. */ -static void usbd_dmareq_process(void); - - -/** - * @brief Change endpoint number to endpoint event code - * - * @param ep Endpoint number - * - * @return Connected endpoint event code. - * - * Marker to delete when not required anymore: >> NRF_DRV_USBD_ERRATA_ENABLE << - */ -static inline nrf_usbd_event_t nrf_drv_usbd_ep_to_endevent(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - - static const nrf_usbd_event_t epin_endev[] = - { - NRF_USBD_EVENT_ENDEPIN0, - NRF_USBD_EVENT_ENDEPIN1, - NRF_USBD_EVENT_ENDEPIN2, - NRF_USBD_EVENT_ENDEPIN3, - NRF_USBD_EVENT_ENDEPIN4, - NRF_USBD_EVENT_ENDEPIN5, - NRF_USBD_EVENT_ENDEPIN6, - NRF_USBD_EVENT_ENDEPIN7, - NRF_USBD_EVENT_ENDISOIN0 - }; - static const nrf_usbd_event_t epout_endev[] = - { - NRF_USBD_EVENT_ENDEPOUT0, - NRF_USBD_EVENT_ENDEPOUT1, - NRF_USBD_EVENT_ENDEPOUT2, - NRF_USBD_EVENT_ENDEPOUT3, - NRF_USBD_EVENT_ENDEPOUT4, - NRF_USBD_EVENT_ENDEPOUT5, - NRF_USBD_EVENT_ENDEPOUT6, - NRF_USBD_EVENT_ENDEPOUT7, - NRF_USBD_EVENT_ENDISOOUT0 - }; - - return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; -} - - -/** - * @brief Get interrupt mask for selected endpoint - * - * @param[in] ep Endpoint number - * - * @return Interrupt mask related to the EasyDMA transfer end for the - * chosen endpoint. - */ -static inline uint32_t nrf_drv_usbd_ep_to_int(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - - static const uint8_t epin_bitpos[] = - { - USBD_INTEN_ENDEPIN0_Pos, - USBD_INTEN_ENDEPIN1_Pos, - USBD_INTEN_ENDEPIN2_Pos, - USBD_INTEN_ENDEPIN3_Pos, - USBD_INTEN_ENDEPIN4_Pos, - USBD_INTEN_ENDEPIN5_Pos, - USBD_INTEN_ENDEPIN6_Pos, - USBD_INTEN_ENDEPIN7_Pos, - USBD_INTEN_ENDISOIN_Pos - }; - static const uint8_t epout_bitpos[] = - { - USBD_INTEN_ENDEPOUT0_Pos, - USBD_INTEN_ENDEPOUT1_Pos, - USBD_INTEN_ENDEPOUT2_Pos, - USBD_INTEN_ENDEPOUT3_Pos, - USBD_INTEN_ENDEPOUT4_Pos, - USBD_INTEN_ENDEPOUT5_Pos, - USBD_INTEN_ENDEPOUT6_Pos, - USBD_INTEN_ENDEPOUT7_Pos, - USBD_INTEN_ENDISOOUT_Pos - }; - - return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)]; -} - -/** - * @name Integrated feeders and consumers - * - * Internal, default functions for transfer processing. - * @{ - */ - -/** - * @brief Integrated consumer to RAM buffer. - * - * @param p_next See @ref nrf_drv_usbd_consumer_t documentation. - * @param p_context See @ref nrf_drv_usbd_consumer_t documentation. - * @param ep_size See @ref nrf_drv_usbd_consumer_t documentation. - * @param data_size See @ref nrf_drv_usbd_consumer_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_drv_usbd_consumer( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size, - size_t data_size) -{ - nrf_drv_usbd_transfer_t * p_transfer = p_context; - ASSERT(ep_size >= data_size); - ASSERT((p_transfer->p_data.rx == NULL) || - nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr))); - - size_t size = p_transfer->size; - if (size < data_size) - { - NRF_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size); - /* Buffer size to small */ - p_next->size = 0; - p_next->p_data = p_transfer->p_data; - } - else - { - p_next->size = data_size; - p_next->p_data = p_transfer->p_data; - size -= data_size; - p_transfer->size = size; - p_transfer->p_data.ptr += data_size; - } - return (ep_size == data_size) && (size != 0); -} - -/** - * @brief Integrated feeder from RAM source. - * - * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_drv_usbd_feeder_ram( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size) -{ - nrf_drv_usbd_transfer_t * p_transfer = p_context; - ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr))); - - size_t tx_size = p_transfer->size; - if (tx_size > ep_size) - { - tx_size = ep_size; - } - - p_next->p_data = p_transfer->p_data; - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.ptr += tx_size; - - return (p_transfer->size != 0); -} - -/** - * @brief Integrated feeder from RAM source with ZLP. - * - * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_drv_usbd_feeder_ram_zlp( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size) -{ - nrf_drv_usbd_transfer_t * p_transfer = p_context; - ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr))); - - size_t tx_size = p_transfer->size; - if (tx_size > ep_size) - { - tx_size = ep_size; - } - - p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx; - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.ptr += tx_size; - - return (tx_size != 0); -} - -/** - * @brief Integrated feeder from a flash source. - * - * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_drv_usbd_feeder_flash( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size) -{ - nrf_drv_usbd_transfer_t * p_transfer = p_context; - ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr))); - - size_t tx_size = p_transfer->size; - void * p_buffer = nrf_drv_usbd_feeder_buffer_get(); - - if (tx_size > ep_size) - { - tx_size = ep_size; - } - - ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE); - memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); - - p_next->p_data.tx = p_buffer; - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.ptr += tx_size; - - return (p_transfer->size != 0); -} - -/** - * @brief Integrated feeder from a flash source with ZLP. - * - * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. - * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. - * - * @retval true Continue transfer. - * @retval false This was the last transfer. - */ -bool nrf_drv_usbd_feeder_flash_zlp( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size) -{ - nrf_drv_usbd_transfer_t * p_transfer = p_context; - ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr))); - - size_t tx_size = p_transfer->size; - void * p_buffer = nrf_drv_usbd_feeder_buffer_get(); - - if (tx_size > ep_size) - { - tx_size = ep_size; - } - - ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE); - - if (tx_size != 0) - { - memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); - p_next->p_data.tx = p_buffer; - } - else - { - p_next->p_data.tx = NULL; - } - p_next->size = tx_size; - - p_transfer->size -= tx_size; - p_transfer->p_data.ptr += tx_size; - - return (tx_size != 0); -} - -/** @} */ - -/** - * @brief Change Driver endpoint number to HAL endpoint number - * - * @param ep Driver endpoint identifier - * - * @return Endpoint identifier in HAL - * - * @sa nrf_drv_usbd_ep_from_hal - */ -static inline uint8_t ep_to_hal(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - return (uint8_t)ep; -} - -/** - * @brief Generate start task number for selected endpoint index - * - * @param ep Endpoint number - * - * @return Task for starting EasyDMA transfer on selected endpoint. - */ -static inline nrf_usbd_task_t task_start_ep(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - return (nrf_usbd_task_t)( - (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) + - (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); -} - -/** - * @brief Access selected endpoint state structure - * - * Function used to change or just read the state of selected endpoint. - * It is used for internal transmission state. - * - * @param ep Endpoint number - */ -static inline usbd_drv_ep_state_t* ep_state_access(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + - NRF_USBD_EP_NR_GET(ep)); -} - -/** - * @brief Change endpoint number to bit position - * - * Bit positions are defined the same way as they are placed in DATAEPSTATUS register, - * but bits for endpoint 0 are included. - * - * @param ep Endpoint number - * - * @return Bit position related to the given endpoint number - * - * @sa bit2ep - */ -static inline uint8_t ep2bit(nrf_drv_usbd_ep_t ep) -{ - USBD_ASSERT_EP_VALID(ep); - return USBD_EP_BITPOS(ep); -} - -/** - * @brief Change bit position to endpoint number - * - * @param bitpos Bit position - * - * @return Endpoint number corresponding to given bit position. - * - * @sa ep2bit - */ -static inline nrf_drv_usbd_ep_t bit2ep(uint8_t bitpos) -{ - STATIC_ASSERT(USBD_EPOUT_BITPOS_0 > USBD_EPIN_BITPOS_0); - return (nrf_drv_usbd_ep_t)((bitpos >= USBD_EPOUT_BITPOS_0) ? - NRF_USBD_EPOUT(bitpos - USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos)); -} - -/** - * @brief Mark that EasyDMA is working - * - * Internal function to set the flag informing about EasyDMA transfer pending. - * This function is called always just after the EasyDMA transfer is started. - */ -static inline void usbd_dma_pending_set(void) -{ - if (nrf_drv_usb_errata_199()) - { - *((volatile uint32_t *)0x40027C1C) = 0x00000082; - } - m_dma_pending = true; -} - -/** - * @brief Mark that EasyDMA is free - * - * Internal function to clear the flag informing about EasyDMA transfer pending. - * This function is called always just after the finished EasyDMA transfer is detected. - */ -static inline void usbd_dma_pending_clear(void) -{ - if (nrf_drv_usb_errata_199()) - { - *((volatile uint32_t *)0x40027C1C) = 0x00000000; - } - m_dma_pending = false; -} - -/** - * @brief Start selected EasyDMA transmission - * - * This is internal auxiliary function. - * No checking is made if EasyDMA is ready for new transmission. - * - * @param[in] ep Number of endpoint for transmission. - * If it is OUT endpoint transmission would be directed from endpoint to RAM. - * If it is in endpoint transmission would be directed from RAM to endpoint. - */ -static inline void usbd_dma_start(nrf_drv_usbd_ep_t ep) -{ - nrf_usbd_task_trigger(task_start_ep(ep)); -} - - -void nrf_drv_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config) -{ - ASSERT(!nrf_drv_usbd_errata_type_52840_eng_a()); - nrf_usbd_isoinconfig_set(config); -} - -nrf_usbd_isoinconfig_t nrf_drv_usbd_isoinconfig_get(void) -{ - ASSERT(!nrf_drv_usbd_errata_type_52840_eng_a()); - return nrf_usbd_isoinconfig_get(); -} - -/** - * @brief Abort pending transfer on selected endpoint - * - * @param ep Endpoint number. - * - * @note - * This function locks interrupts that may be costly. - * It is good idea to test if the endpoint is still busy before calling this function: - * @code - (m_ep_dma_waiting & (1U << ep2bit(ep))) - * @endcode - * This function would check it again, but it makes it inside critical section. - */ -static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep) -{ - CRITICAL_REGION_ENTER(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - - if (NRF_USBD_EPOUT_CHECK(ep)) - { - /* Host -> Device */ - if ((~m_ep_dma_waiting) & (1U << ep2bit(ep))) - { - /* If the bit in m_ep_dma_waiting in cleared - nothing would be - * processed inside transfer processing */ - nrf_drv_usbd_transfer_out_drop(ep); - } - else - { - p_state->handler.consumer = NULL; - m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - m_ep_ready &= ~(1U << ep2bit(ep)); - } - /* Aborted */ - p_state->status = NRF_USBD_EP_ABORTED; - } - else - { - if(!NRF_USBD_EPISO_CHECK(ep)) - { - if(ep != NRF_DRV_USBD_EPIN0) - { - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1)); //inxbsy - uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - temp |= (1U << 1); - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp; - UNUSED_VARIABLE(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - } - else - { - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B4; - uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - temp |= (1U << 2); - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp; - UNUSED_VARIABLE(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - } - } - - if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep))) - { - /* Device -> Host */ - m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - m_ep_ready |= 1U << ep2bit(ep) ; - - p_state->handler.feeder = NULL; - p_state->status = NRF_USBD_EP_ABORTED; - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_ABORTED); - m_event_handler(&evt); - } - } - CRITICAL_REGION_EXIT(); -} - -void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep) -{ - usbd_ep_abort(ep); -} - - -/** - * @brief Abort all pending endpoints - * - * Function aborts all pending endpoint transfers. - */ -static void usbd_ep_abort_all(void) -{ - uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & USBD_EPOUT_BIT_MASK); - while (0 != ep_waiting) - { - uint8_t bitpos = __CLZ(__RBIT(ep_waiting)); - if(!NRF_USBD_EPISO_CHECK(bit2ep(bitpos))) - { - usbd_ep_abort(bit2ep(bitpos)); - } - ep_waiting &= ~(1U << bitpos); - } - - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0); -} - -/** - * @brief Force the USBD interrupt into pending state - * - * This function is used to force USBD interrupt to be processed right now. - * It makes it possible to process all EasyDMA access on one thread priority level. - */ -static inline void usbd_int_rise(void) -{ - NVIC_SetPendingIRQ(USBD_IRQn); -} - -/** - * @name USBD interrupt runtimes - * - * Interrupt runtimes that would be vectorized using @ref m_ivec_isr - * @{ - */ - -static void ev_usbreset_handler(void) -{ - m_bus_suspend = false; - m_last_setup_dir = NRF_DRV_USBD_EPOUT0; - - const nrf_drv_usbd_evt_t evt = { - .type = NRF_DRV_USBD_EVT_RESET - }; - - m_event_handler(&evt); -} - -static void ev_started_handler(void) -{ -#if NRF_DRV_USBD_STARTED_EV_ENABLE - uint32_t epstatus = nrf_usbd_epstatus_get_and_clear(); - - /* All finished endpoint have to be marked as busy */ - // #warning Check this one - // ASSERT(epstatus == ((~m_ep_ready) & epstatus)); - while (epstatus) - { - uint8_t bitpos = __CLZ(__RBIT(epstatus)); - nrf_drv_usbd_ep_t ep = bit2ep(bitpos); - epstatus &= ~(1UL << bitpos); - - UNUSED_VARIABLE(ep); - } -#endif -} - -/** - * @brief Handler for EasyDMA event without endpoint clearing. - * - * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. - * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. - * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler - * - * @param[in] ep Endpoint number - */ -static inline void nrf_usbd_ep0in_dma_handler(void) -{ - const nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN0; - NRF_LOG_DEBUG("USB event: DMA ready IN0"); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Clear transfer information just in case */ - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else if (p_state->handler.feeder == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else - { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event without endpoint clearing. - * - * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. - * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. - * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler - * - * @param[in] ep Endpoint number - */ -static inline void nrf_usbd_epin_dma_handler(nrf_drv_usbd_ep_t ep) -{ - - NRF_LOG_DEBUG("USB event: DMA ready IN: %x", ep); - ASSERT(NRF_USBD_EPIN_CHECK(ep)); - ASSERT(!NRF_USBD_EPISO_CHECK(ep)); - ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Clear transfer information just in case */ - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else if (p_state->handler.feeder == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else - { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event from in isochronous endpoint - * - * @todo RK documentation - */ -static inline void nrf_usbd_epiniso_dma_handler(nrf_drv_usbd_ep_t ep) -{ - if (NRF_USBD_ISO_DEBUG) - { - NRF_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep); - } - ASSERT(NRF_USBD_EPIN_CHECK(ep)); - ASSERT(NRF_USBD_EPISO_CHECK(ep)); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Clear transfer information just in case */ - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else if (p_state->handler.feeder == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished in this moment */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); - m_event_handler(&evt); - } - else - { - /* Nothing to do */ - } -} - -/** - * @brief Handler for EasyDMA event for OUT endpoint 0. - * - * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer. - * It cannot be cleared when required transfer is finished because it means the same that accepting the comment. - */ -static inline void nrf_usbd_ep0out_dma_handler(void) -{ - const nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT0; - NRF_LOG_DEBUG("USB event: DMA ready OUT0"); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Clear transfer information just in case */ - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else if (p_state->handler.consumer == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); - m_event_handler(&evt); - } - else - { - nrf_drv_usbd_setup_data_clear(); - } -} - -/** - * @brief Handler for EasyDMA event from endpoinpoint that requires clearing. - * - * This handler would be called when EasyDMA transfer for OUT endpoint has been finished. - * - * @param[in] ep Endpoint number - * - */ -static inline void nrf_usbd_epout_dma_handler(nrf_drv_usbd_ep_t ep) -{ - NRF_LOG_DEBUG("USB drv: DMA ready OUT: %x", ep); - ASSERT(NRF_USBD_EPOUT_CHECK(ep)); - ASSERT(!NRF_USBD_EPISO_CHECK(ep)); - ASSERT(NRF_USBD_EP_NR_GET(ep) > 0); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Clear transfer information just in case */ - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - } - else if (p_state->handler.consumer == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); - m_event_handler(&evt); - } - else - { - /* Nothing to do */ - } - -#if NRF_DRV_USBD_EARLY_DMA_PROCESS - /* Speed up */ - usbd_dmareq_process(); -#endif -} - -/** - * @brief Handler for EasyDMA event from out isochronous endpoint - * - * @todo RK documentation - */ - -static inline void nrf_usbd_epoutiso_dma_handler(nrf_drv_usbd_ep_t ep) -{ - if (NRF_USBD_ISO_DEBUG) - { - NRF_LOG_DEBUG("USB drv: DMA ready ISOOUT: %x", ep); - } - ASSERT(NRF_USBD_EPISO_CHECK(ep)); - usbd_dma_pending_clear(); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - if (NRF_USBD_EP_ABORTED == p_state->status) - { - /* Nothing to do - just ignore */ - } - else if (p_state->handler.consumer == NULL) - { - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); - /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); - m_event_handler(&evt); - } - else - { - /* Nothing to do */ - } -} - - -static void ev_dma_epin0_handler(void) { nrf_usbd_ep0in_dma_handler(); } -static void ev_dma_epin1_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN1 ); } -static void ev_dma_epin2_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN2 ); } -static void ev_dma_epin3_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN3 ); } -static void ev_dma_epin4_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN4 ); } -static void ev_dma_epin5_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN5 ); } -static void ev_dma_epin6_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN6 ); } -static void ev_dma_epin7_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN7 ); } -static void ev_dma_epin8_handler(void) { nrf_usbd_epiniso_dma_handler(NRF_DRV_USBD_EPIN8 ); } - -static void ev_dma_epout0_handler(void) { nrf_usbd_ep0out_dma_handler(); } -static void ev_dma_epout1_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT1); } -static void ev_dma_epout2_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT2); } -static void ev_dma_epout3_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT3); } -static void ev_dma_epout4_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT4); } -static void ev_dma_epout5_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT5); } -static void ev_dma_epout6_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT6); } -static void ev_dma_epout7_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT7); } -static void ev_dma_epout8_handler(void) { nrf_usbd_epoutiso_dma_handler(NRF_DRV_USBD_EPOUT8); } - -static void ev_sof_handler(void) -{ - nrf_drv_usbd_evt_t evt = { - NRF_DRV_USBD_EVT_SOF, - .data = { .sof = { .framecnt = nrf_usbd_framecntr_get() }} - }; - - /* Process isochronous endpoints */ - uint32_t iso_ready_mask = (1U << ep2bit(NRF_DRV_USBD_EPIN8)); - if (nrf_usbd_episoout_size_get(NRF_DRV_USBD_EPOUT8) != NRF_USBD_EPISOOUT_NO_DATA) - { - iso_ready_mask |= (1U << ep2bit(NRF_DRV_USBD_EPOUT8)); - } - m_ep_ready |= iso_ready_mask; - - m_event_handler(&evt); -} - -/** - * @brief React on data transfer finished - * - * Auxiliary internal function. - * @param ep Endpoint number - * @param bitpos Bit position for selected endpoint number - */ -static void usbd_ep_data_handler(nrf_drv_usbd_ep_t ep, uint8_t bitpos) -{ - NRF_LOG_DEBUG("USBD event: EndpointData: %x", ep); - /* Mark endpoint ready for next DMA access */ - m_ep_ready |= (1U << bitpos); - - if (NRF_USBD_EPIN_CHECK(ep)) - { - /* IN endpoint (Device -> Host) */ - if (0 == (m_ep_dma_waiting & (1U << bitpos))) - { - NRF_LOG_DEBUG("USBD event: EndpointData: In finished"); - /* No more data to be send - transmission finished */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); - m_event_handler(&evt); - } - } - else - { - /* OUT endpoint (Host -> Device) */ - if (0 == (m_ep_dma_waiting & (1U << bitpos))) - { - NRF_LOG_DEBUG("USBD event: EndpointData: Out waiting"); - /* No buffer prepared - send event to the application */ - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_WAITING); - m_event_handler(&evt); - } - } -} - -static void ev_setup_data_handler(void) -{ - usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir)); -} - -static void ev_setup_handler(void) -{ - NRF_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )", - nrf_usbd_setup_bmrequesttype_get(), - nrf_usbd_setup_brequest_get(), - nrf_usbd_setup_wvalue_get(), - nrf_usbd_setup_windex_get(), - nrf_usbd_setup_wlength_get()); - uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get(); - - - if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U <handler.feeder) != NULL); - - if (NRF_USBD_EPIN_CHECK(ep)) - { - /* Device -> Host */ - continue_transfer = p_state->handler.feeder( - &transfer, - p_state->p_context, - p_state->max_packet_size); - - if (!continue_transfer) - { - p_state->handler.feeder = NULL; - } - } - else - { - /* Host -> Device */ - const size_t rx_size = nrf_drv_usbd_epout_size_get(ep); - continue_transfer = p_state->handler.consumer( - &transfer, - p_state->p_context, - p_state->max_packet_size, - rx_size); - - if (transfer.p_data.rx == NULL) - { - /* Dropping transfer - allow processing */ - ASSERT(transfer.size == 0); - } - else if (transfer.size < rx_size) - { - NRF_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size); - p_state->status = NRF_USBD_EP_OVERLOAD; - UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << pos))); - NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OVERLOAD); - m_event_handler(&evt); - /* This endpoint will not be transmitted now, repeat the loop */ - continue; - } - else - { - /* Nothing to do - only check integrity if assertions are enabled */ - ASSERT(transfer.size == rx_size); - } - - if (!continue_transfer) - { - p_state->handler.consumer = NULL; - } - } - - usbd_dma_pending_set(); - m_ep_ready &= ~(1U << pos); - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG( - "USB DMA process: Starting transfer on EP: %x, size: %u", - ep, - transfer.size); - } - /* Update number of currently transferred bytes */ - p_state->transfer_cnt += transfer.size; - /* Start transfer to the endpoint buffer */ - nrf_usbd_ep_easydma_set(ep, transfer.p_data.ptr, (uint32_t)transfer.size); - - if (nrf_drv_usbd_errata_104()) - { - uint32_t cnt_end = (uint32_t)(-1); - do - { - uint32_t cnt = (uint32_t)(-1); - do - { - nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED); - usbd_dma_start(ep); - nrf_delay_us(2); - ++cnt; - }while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED)); - if (cnt) - { - NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA restarted: %u times", cnt); - } - - nrf_delay_us(30); - while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474)))) - { - nrf_delay_us(2); - } - nrf_delay_us(1); - - ++cnt_end; - } while (!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep))); - if (cnt_end) - { - NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA fully restarted: %u times", cnt_end); - } - } - else - { - usbd_dma_start(ep); - /* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer. - * This is quick fix to maintain stability of the stack. - * It cost some performance but makes stack stable. */ - while (!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep))) - { - /* Empty */ - } - } - - if (NRF_USBD_DMAREQ_PROCESS_DEBUG) - { - NRF_LOG_DEBUG("USB DMA process - finishing"); - } - /* Transfer started - exit the loop */ - break; - } - } - else - { - if (NRF_USBD_DMAREQ_PROCESS_DEBUG) - { - NRF_LOG_DEBUG("USB DMA process - EasyDMA busy"); - } - } -} -/** @} */ - -typedef void (*nrf_drv_usbd_isr_t)(void); - -/** - * @brief USBD interrupt service runtimes - * - */ -static const nrf_drv_usbd_isr_t m_isr[] = -{ - [USBD_INTEN_USBRESET_Pos ] = ev_usbreset_handler, - [USBD_INTEN_STARTED_Pos ] = ev_started_handler, - [USBD_INTEN_ENDEPIN0_Pos ] = ev_dma_epin0_handler, - [USBD_INTEN_ENDEPIN1_Pos ] = ev_dma_epin1_handler, - [USBD_INTEN_ENDEPIN2_Pos ] = ev_dma_epin2_handler, - [USBD_INTEN_ENDEPIN3_Pos ] = ev_dma_epin3_handler, - [USBD_INTEN_ENDEPIN4_Pos ] = ev_dma_epin4_handler, - [USBD_INTEN_ENDEPIN5_Pos ] = ev_dma_epin5_handler, - [USBD_INTEN_ENDEPIN6_Pos ] = ev_dma_epin6_handler, - [USBD_INTEN_ENDEPIN7_Pos ] = ev_dma_epin7_handler, - [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler, - [USBD_INTEN_ENDISOIN_Pos ] = ev_dma_epin8_handler, - [USBD_INTEN_ENDEPOUT0_Pos ] = ev_dma_epout0_handler, - [USBD_INTEN_ENDEPOUT1_Pos ] = ev_dma_epout1_handler, - [USBD_INTEN_ENDEPOUT2_Pos ] = ev_dma_epout2_handler, - [USBD_INTEN_ENDEPOUT3_Pos ] = ev_dma_epout3_handler, - [USBD_INTEN_ENDEPOUT4_Pos ] = ev_dma_epout4_handler, - [USBD_INTEN_ENDEPOUT5_Pos ] = ev_dma_epout5_handler, - [USBD_INTEN_ENDEPOUT6_Pos ] = ev_dma_epout6_handler, - [USBD_INTEN_ENDEPOUT7_Pos ] = ev_dma_epout7_handler, - [USBD_INTEN_ENDISOOUT_Pos ] = ev_dma_epout8_handler, - [USBD_INTEN_SOF_Pos ] = ev_sof_handler, - [USBD_INTEN_USBEVENT_Pos ] = ev_usbevent_handler, - [USBD_INTEN_EP0SETUP_Pos ] = ev_setup_handler, - [USBD_INTEN_EPDATA_Pos ] = ev_epdata_handler -}; - -/** - * @name Interrupt handlers - * - * @{ - */ -void USBD_IRQHandler(void) -{ - const uint32_t enabled = nrf_usbd_int_enable_get(); - uint32_t to_process = enabled; - uint32_t active = 0; - - /* Check all enabled interrupts */ - while (to_process) - { - uint8_t event_nr = __CLZ(__RBIT(to_process)); - if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr))) - { - active |= 1UL << event_nr; - } - to_process &= ~(1UL << event_nr); - } - - if (nrf_drv_usbd_errata_104()) - { - /* Event correcting */ - if ((!m_dma_pending) && (0 != (active & (USBD_INTEN_SOF_Msk)))) - { - uint8_t usbi, uoi, uii; - /* Testing */ - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; - uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - if (0 != uii) - { - uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - } - - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA; - uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - if (0 != uoi) - { - uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - } - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB; - usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - if (0 != usbi) - { - usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - } - /* Processing */ - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC; - uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - if (0 != uii) - { - uint8_t rb; - m_simulated_dataepstatus |= ((uint32_t)uii) << USBD_EPIN_BITPOS_0; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii; - rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" uii: 0x%.2x (0x%.2x)", uii, rb); - } - - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AD; - uoi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - if (0 != uoi) - { - uint8_t rb; - m_simulated_dataepstatus |= ((uint32_t)uoi) << USBD_EPOUT_BITPOS_0; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi; - rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" uoi: 0x%.2u (0x%.2x)", uoi, rb); - } - - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AE; - usbi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - if (0 != usbi) - { - uint8_t rb; - if (usbi & 0x01) - { - active |= USBD_INTEN_EP0SETUP_Msk; - } - if (usbi & 0x10) - { - active |= USBD_INTEN_USBRESET_Msk; - } - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = usbi; - rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); - NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" usbi: 0x%.2u (0x%.2x)", usbi, rb); - } - - if (0 != (m_simulated_dataepstatus & - ~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0)))) - { - active |= enabled & NRF_USBD_INT_DATAEP_MASK; - } - if (0 != (m_simulated_dataepstatus & - ((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0)))) - { - if (0 != (enabled & NRF_USBD_INT_EP0DATADONE_MASK)) - { - m_simulated_dataepstatus &= - ~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0)); - active |= NRF_USBD_INT_EP0DATADONE_MASK; - } - } - } - } - - /* Process the active interrupts */ - bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK); - active &= ~NRF_USBD_INT_EP0SETUP_MASK; - - while (active) - { - uint8_t event_nr = __CLZ(__RBIT(active)); - m_isr[event_nr](); - active &= ~(1UL << event_nr); - } - usbd_dmareq_process(); - - if (setup_active) - { - m_isr[USBD_INTEN_EP0SETUP_Pos](); - } -} - -/** @} */ -/** @} */ - -ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler) -{ - ASSERT((nrf_drv_usbd_errata_type_52840_eng_a() || - nrf_drv_usbd_errata_type_52840_eng_b() || - nrf_drv_usbd_errata_type_52840_eng_c() || - nrf_drv_usbd_errata_type_52840_eng_d()) - ); - - if (NULL == event_handler) - { - return NRF_ERROR_INVALID_PARAM; - } - if ( m_drv_state != NRFX_DRV_STATE_UNINITIALIZED) - { - return NRF_ERROR_INVALID_STATE; - } - - m_event_handler = event_handler; - m_drv_state = NRFX_DRV_STATE_INITIALIZED; - - uint8_t n; - for (n=0; nstatus = NRF_USBD_EP_OK; - p_state->handler.feeder = NULL; - p_state->transfer_cnt = 0; - } - for (n=0; nstatus = NRF_USBD_EP_OK; - p_state->handler.consumer = NULL; - p_state->transfer_cnt = 0; - } - - return NRF_SUCCESS; -} - -ret_code_t nrf_drv_usbd_uninit(void) -{ - if (m_drv_state != NRFX_DRV_STATE_INITIALIZED) - { - return NRF_ERROR_INVALID_STATE; - } - - m_event_handler = NULL; - m_drv_state = NRFX_DRV_STATE_UNINITIALIZED; - return NRF_SUCCESS; -} - -void nrf_drv_usbd_enable(void) -{ - ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED); - - /* Prepare for READY event receiving */ - nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); - - if (nrf_drv_usbd_errata_187()) - { - CRITICAL_REGION_ENTER(); - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006ED14)) = 0x00000003; - } - CRITICAL_REGION_EXIT(); - } - - if (nrf_drv_usbd_errata_171()) - { - CRITICAL_REGION_ENTER(); - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; - } - CRITICAL_REGION_EXIT(); - } - - /* Enable the peripheral */ - nrf_usbd_enable(); - /* Waiting for peripheral to enable, this should take a few us */ - while (0 == (NRF_USBD_EVENTCAUSE_READY_MASK & nrf_usbd_eventcause_get())) - { - /* Empty loop */ - } - nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); - - if (nrf_drv_usbd_errata_171()) - { - CRITICAL_REGION_ENTER(); - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; - } - - CRITICAL_REGION_EXIT(); - } - - if (nrf_drv_usbd_errata_166()) - { - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3; - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40; - __ISB(); - __DSB(); - } - - nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_HALF); - - if (USBD_CONFIG_ISO_IN_ZLP) - { - nrf_drv_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA); - } - else - { - nrf_drv_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP); - } - - m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0); - m_ep_dma_waiting = 0; - usbd_dma_pending_clear(); - m_last_setup_dir = NRF_DRV_USBD_EPOUT0; - - m_drv_state = NRFX_DRV_STATE_POWERED_ON; -} - -void nrf_drv_usbd_disable(void) -{ - ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED); - - /* Stop just in case */ - nrf_drv_usbd_stop(); - - /* Disable all parts */ - nrf_usbd_int_disable(nrf_usbd_int_enable_get()); - nrf_usbd_disable(); - usbd_dma_pending_clear(); - m_drv_state = NRFX_DRV_STATE_INITIALIZED; - - if (nrf_drv_usbd_errata_187()) - { - CRITICAL_REGION_ENTER(); - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006ED14)) = 0x00000000; - } - CRITICAL_REGION_EXIT(); - } -} - -void nrf_drv_usbd_start(bool enable_sof) -{ - ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); - m_bus_suspend = false; - - uint32_t ints_to_enable = - NRF_USBD_INT_USBRESET_MASK | - NRF_USBD_INT_STARTED_MASK | - NRF_USBD_INT_ENDEPIN0_MASK | - NRF_USBD_INT_EP0DATADONE_MASK | - NRF_USBD_INT_ENDEPOUT0_MASK | - NRF_USBD_INT_USBEVENT_MASK | - NRF_USBD_INT_EP0SETUP_MASK | - NRF_USBD_INT_DATAEP_MASK; - - if (enable_sof || nrf_drv_usbd_errata_104()) - { - ints_to_enable |= NRF_USBD_INT_SOF_MASK; - } - - /* Enable all required interrupts */ - nrf_usbd_int_enable(ints_to_enable); - - /* Enable interrupt globally */ - NRFX_IRQ_PRIORITY_SET(USBD_IRQn, USBD_CONFIG_IRQ_PRIORITY); - NRFX_IRQ_ENABLE(USBD_IRQn); - - /* Enable pullups */ - nrf_usbd_pullup_enable(); -} - -void nrf_drv_usbd_stop(void) -{ - ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON); - - if(NRFX_IRQ_IS_ENABLED(USBD_IRQn)) - { - /* Abort transfers */ - usbd_ep_abort_all(); - - /* Disable pullups */ - nrf_usbd_pullup_disable(); - - /* Disable interrupt globally */ - NRFX_IRQ_DISABLE(USBD_IRQn); - - /* Disable all interrupts */ - nrf_usbd_int_disable(~0U); - } -} - -bool nrf_drv_usbd_is_initialized(void) -{ - return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED); -} - -bool nrf_drv_usbd_is_enabled(void) -{ - return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON); -} - -bool nrf_drv_usbd_is_started(void) -{ - return (nrf_drv_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn)); -} - -bool nrf_drv_usbd_suspend(void) -{ - bool suspended = false; - - CRITICAL_REGION_ENTER(); - if (m_bus_suspend) - { - usbd_ep_abort_all(); - - if (!(nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK)) - { - nrf_usbd_lowpower_enable(); - if (nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK) - { - nrf_usbd_lowpower_disable(); - } - else - { - suspended = true; - - if (nrf_drv_usbd_errata_171()) - { - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006EC14)) = 0x00000000; - } - } - } - } - } - CRITICAL_REGION_EXIT(); - - return suspended; -} - -bool nrf_drv_usbd_wakeup_req(void) -{ - bool started = false; - - CRITICAL_REGION_ENTER(); - if (m_bus_suspend && nrf_usbd_lowpower_check()) - { - nrf_usbd_lowpower_disable(); - started = true; - - if (nrf_drv_usbd_errata_171()) - { - if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000) - { - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; - *((volatile uint32_t *)(0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0; - } - - } - } - CRITICAL_REGION_EXIT(); - - return started; -} - -bool nrf_drv_usbd_suspend_check(void) -{ - return nrf_usbd_lowpower_check(); -} - -void nrf_drv_usbd_suspend_irq_config(void) -{ - nrf_usbd_int_disable(m_irq_disabled_in_suspend); -} - -void nrf_drv_usbd_active_irq_config(void) -{ - nrf_usbd_int_enable(m_irq_disabled_in_suspend); -} - -bool nrf_drv_usbd_bus_suspend_check(void) -{ - return m_bus_suspend; -} - -void nrf_drv_usbd_force_bus_wakeup(void) -{ - m_bus_suspend = false; -} - -void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size) -{ - /* Only power of 2 size allowed */ - ASSERT((size != 0) && (size & (size - 1)) == 0); - /* Packet size cannot be higher than maximum buffer size */ - ASSERT( ( NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) - || - ((!NRF_USBD_EPISO_CHECK(ep)) && (size <= NRF_DRV_USBD_EPSIZE))); - - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - p_state->max_packet_size = size; -} - -uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep) -{ - usbd_drv_ep_state_t const * p_state = ep_state_access(ep); - return p_state->max_packet_size; -} - -bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep) -{ - return nrf_usbd_ep_enable_check(ep_to_hal(ep)); -} - -void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep) -{ - nrf_usbd_int_enable(nrf_drv_usbd_ep_to_int(ep)); - - if(nrf_usbd_ep_enable_check(ep)) - { - return; - } - nrf_usbd_ep_enable(ep_to_hal(ep)); - if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && (!NRF_USBD_EPISO_CHECK(ep))) - { - CRITICAL_REGION_ENTER(); - nrf_drv_usbd_transfer_out_drop(ep); - m_ep_dma_waiting &= ~(1U << ep2bit(ep)); - CRITICAL_REGION_EXIT(); - } -} - -void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep) -{ - usbd_ep_abort(ep); - nrf_usbd_ep_disable(ep_to_hal(ep)); - nrf_usbd_int_disable(nrf_drv_usbd_ep_to_int(ep)); -} - -void nrf_drv_usbd_ep_default_config(void) -{ - nrf_usbd_int_disable( - NRF_USBD_INT_ENDEPIN1_MASK | - NRF_USBD_INT_ENDEPIN2_MASK | - NRF_USBD_INT_ENDEPIN3_MASK | - NRF_USBD_INT_ENDEPIN4_MASK | - NRF_USBD_INT_ENDEPIN5_MASK | - NRF_USBD_INT_ENDEPIN6_MASK | - NRF_USBD_INT_ENDEPIN7_MASK | - NRF_USBD_INT_ENDISOIN0_MASK | - NRF_USBD_INT_ENDEPOUT1_MASK | - NRF_USBD_INT_ENDEPOUT2_MASK | - NRF_USBD_INT_ENDEPOUT3_MASK | - NRF_USBD_INT_ENDEPOUT4_MASK | - NRF_USBD_INT_ENDEPOUT5_MASK | - NRF_USBD_INT_ENDEPOUT6_MASK | - NRF_USBD_INT_ENDEPOUT7_MASK | - NRF_USBD_INT_ENDISOOUT0_MASK - ); - nrf_usbd_int_enable(NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK); - nrf_usbd_ep_all_disable(); -} - -ret_code_t nrf_drv_usbd_ep_transfer( - nrf_drv_usbd_ep_t ep, - nrf_drv_usbd_transfer_t const * const p_transfer) -{ - ret_code_t ret; - const uint8_t ep_bitpos = ep2bit(ep); - ASSERT(NULL != p_transfer); - - CRITICAL_REGION_ENTER(); - /* Setup data transaction can go only in one direction at a time */ - if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) - { - ret = NRF_ERROR_INVALID_ADDR; - if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) - { - NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EPr\n"); - } - } - else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos)) - { - /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */ - ret = NRF_ERROR_BUSY; - if (NRF_USBD_FAILED_TRANSFERS_DEBUG) - { - NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy"); - } - } - else - { - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - /* Prepare transfer context and handler description */ - nrf_drv_usbd_transfer_t * p_context; - if (NRF_USBD_EPIN_CHECK(ep)) - { - p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep); - if (nrfx_is_in_ram(p_transfer->p_data.tx)) - { - /* RAM */ - if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG)) - { - p_state->handler.feeder = nrf_drv_usbd_feeder_ram; - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG( - "USB driver: Transfer called on endpoint %x, size: %u, mode: " - "RAM", - ep, - p_transfer->size); - } - } - else - { - p_state->handler.feeder = nrf_drv_usbd_feeder_ram_zlp; - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG( - "USB driver: Transfer called on endpoint %x, size: %u, mode: " - "RAM_ZLP", - ep, - p_transfer->size); - } - } - } - else - { - /* Flash */ - if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG)) - { - p_state->handler.feeder = nrf_drv_usbd_feeder_flash; - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG( - "USB driver: Transfer called on endpoint %x, size: %u, mode: " - "FLASH", - ep, - p_transfer->size); - } - } - else - { - p_state->handler.feeder = nrf_drv_usbd_feeder_flash_zlp; - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG( - "USB driver: Transfer called on endpoint %x, size: %u, mode: " - "FLASH_ZLP", - ep, - p_transfer->size); - } - } - } - } - else - { - p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep); - ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx))); - p_state->handler.consumer = nrf_drv_usbd_consumer; - } - *p_context = *p_transfer; - p_state->p_context = p_context; - - p_state->transfer_cnt = 0; - p_state->status = NRF_USBD_EP_OK; - m_ep_dma_waiting |= 1U << ep_bitpos; - ret = NRF_SUCCESS; - usbd_int_rise(); - } - CRITICAL_REGION_EXIT(); - return ret; -} - -ret_code_t nrf_drv_usbd_ep_handled_transfer( - nrf_drv_usbd_ep_t ep, - nrf_drv_usbd_handler_desc_t const * const p_handler) -{ - ret_code_t ret; - const uint8_t ep_bitpos = ep2bit(ep); - ASSERT(NULL != p_handler); - - CRITICAL_REGION_ENTER(); - /* Setup data transaction can go only in one direction at a time */ - if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) - { - ret = NRF_ERROR_INVALID_ADDR; - if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) - { - NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EP"); - } - } - else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos)) - { - /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */ - ret = NRF_ERROR_BUSY; - if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))) - { - NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy");\ - } - } - else - { - /* Transfer can be configured now */ - usbd_drv_ep_state_t * p_state = ep_state_access(ep); - - p_state->transfer_cnt = 0; - p_state->handler = p_handler->handler; - p_state->p_context = p_handler->p_context; - p_state->status = NRF_USBD_EP_OK; - m_ep_dma_waiting |= 1U << ep_bitpos; - - ret = NRF_SUCCESS; - if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) - { - NRF_LOG_DEBUG("USB driver: Transfer called on endpoint %x, mode: Handler", ep); - } - usbd_int_rise(); - } - CRITICAL_REGION_EXIT(); - return ret; -} - -void * nrf_drv_usbd_feeder_buffer_get(void) -{ - return m_tx_buffer; -} - -ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size) -{ - ret_code_t ret; - - usbd_drv_ep_state_t const * p_state = ep_state_access(ep); - CRITICAL_REGION_ENTER(); - *p_size = p_state->transfer_cnt; - ret = (p_state->handler.consumer == NULL) ? p_state->status : NRF_ERROR_BUSY; - CRITICAL_REGION_EXIT(); - return ret; -} - -size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep) -{ - return nrf_usbd_epout_size_get(ep_to_hal(ep)); -} - -bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep) -{ - return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep2bit(ep)))); -} - -void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep) -{ - NRF_LOG_DEBUG("USB: EP %x stalled.", ep); - nrf_usbd_ep_stall(ep_to_hal(ep)); -} - -void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep) -{ - if (NRF_USBD_EPOUT_CHECK(ep) && nrf_drv_usbd_ep_stall_check(ep)) - { - nrf_drv_usbd_transfer_out_drop(ep); - } - nrf_usbd_ep_unstall(ep_to_hal(ep)); -} - -bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep) -{ - return nrf_usbd_ep_is_stall(ep_to_hal(ep)); -} - -void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep) -{ - nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_DATA0); -} - -void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup) -{ - memset(p_setup, 0, sizeof(nrf_drv_usbd_setup_t)); - p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(); - p_setup->bmRequest = nrf_usbd_setup_brequest_get(); - p_setup->wValue = nrf_usbd_setup_wvalue_get(); - p_setup->wIndex = nrf_usbd_setup_windex_get(); - p_setup->wLength = nrf_usbd_setup_wlength_get(); -} - -void nrf_drv_usbd_setup_data_clear(void) -{ - if (nrf_drv_usbd_errata_104()) - { - /* For this fix to work properly, it must be ensured that the task is - * executed twice one after another - blocking ISR. This is however a temporary - * solution to be used only before production version of the chip. */ - uint32_t primask_copy = __get_PRIMASK(); - __disable_irq(); - nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); - nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); - __set_PRIMASK(primask_copy); - } - else - { - nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); - } -} - -void nrf_drv_usbd_setup_clear(void) -{ - nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS); -} - -void nrf_drv_usbd_setup_stall(void) -{ - NRF_LOG_DEBUG("Setup stalled."); - nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL); -} - -nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void) -{ - return m_last_setup_dir; -} - -void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep) -{ - ASSERT(NRF_USBD_EPOUT_CHECK(ep)); - - if (nrf_drv_usbd_errata_200()) - { - CRITICAL_REGION_ENTER(); - m_ep_ready &= ~(1U << ep2bit(ep)); - *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep)); - *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0; - UNUSED_VARIABLE(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); - CRITICAL_REGION_EXIT(); - } - else - { - CRITICAL_REGION_ENTER(); - m_ep_ready &= ~(1U << ep2bit(ep)); - if (!NRF_USBD_EPISO_CHECK(ep)) - { - nrf_usbd_epout_clear(ep); - } - CRITICAL_REGION_EXIT(); - } -} - -#endif // NRF_MODULE_ENABLED(USBD) diff --git a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h b/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h index 60fba6add..427cc1da8 100644 --- a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h +++ b/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h @@ -1,948 +1,234 @@ -/** - * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_DRV_USBD_H__ -#define NRF_DRV_USBD_H__ - -#include "sdk_errors.h" -#include "nrf_usbd.h" -#include -#include -#include "app_util.h" -#include "nrf_drv_usbd_errata.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup nrf_drv_usbd USB Device HAL and driver - * @ingroup nrf_drivers - * @brief @tagAPI52840 USB Device APIs. - * @details The USB Device HAL provides basic APIs for accessing - * the registers of the USBD. - * The USB Device driver provides APIs on a higher level. - * - * @{ - */ - -/** - * @name Possible schemes of DMA scheduling - * - * Definition of available configuration constants used by DMA scheduler - * @{ - */ - /** - * @brief Highly prioritized access - * - * Endpoint with lower number has always higher priority and its data would - * be transfered first. - * OUT endpoints ale processed before IN endpoints - */ - #define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED 0 - - /** - * @brief Round robin scheme - * - * All endpoints are processed in round-robin scheme. - * It means that when one endpoint is processed next in order would be - * the nearest with lower number. - * When no endpoints with lower number requires processing - then - * all endpoints from 0 are tested. - */ - #define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN 1 - -/** @} */ - -/** - * @brief Number of bytes in the endpoint - * - * Constant that informs about endpoint size - */ -#define NRF_DRV_USBD_EPSIZE 64 - -/** - * @brief Number of bytes for isochronous endpoints - * - * Number of bytes for isochronous endpoints in total. - * This number would be shared between IN and OUT endpoint. - * It may be also assigned totaly to one endpoint. - * @sa nrf_usbd_isosplit_set - * @sa nrf_usbd_isosplit_get - */ -#define NRF_DRV_USBD_ISOSIZE 1024 - -/** - * @brief The size of internal feeder buffer. - * - * @sa nrf_drv_usbd_feeder_buffer_get - */ -#define NRF_DRV_USBD_FEEDER_BUFFER_SIZE NRF_DRV_USBD_EPSIZE - -/** - * @name Macros for creating endpoint identifiers - * - * Auxiliary macros to be used to create Endpoint identifier that is compatible - * with USB specification. - * @{ - */ - - /** - * @brief Create identifier for IN endpoint - * - * Simple macro to create IN endpoint identifier for given endpoint number. - * - * @param[in] n Endpoint number. - * - * @return Endpoint identifier that connects endpoint number and endpoint direction. - */ - #define NRF_DRV_USBD_EPIN(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPIN(n)) - /** - * @brief Create identifier for OUT endpoint - * - * Simple macro to create OUT endpoint identifier for given endpoint number. - * - * @param[in] n Endpoint number. - * - * @return Endpoint identifier that connects endpoint number and endpoint direction. - */ - #define NRF_DRV_USBD_EPOUT(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPOUT(n)) - -/** @} */ - -/** - * @brief Endpoint identifier - * - * Endpoint identifier used in the driver. - * This endpoint number is consistent with USB 2.0 specification. - */ -typedef enum -{ - NRF_DRV_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ - NRF_DRV_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ - NRF_DRV_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ - NRF_DRV_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ - NRF_DRV_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ - NRF_DRV_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ - NRF_DRV_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ - NRF_DRV_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ - NRF_DRV_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ - - NRF_DRV_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ - NRF_DRV_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ - NRF_DRV_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ - NRF_DRV_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ - NRF_DRV_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ - NRF_DRV_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ - NRF_DRV_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ - NRF_DRV_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ - NRF_DRV_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ -}nrf_drv_usbd_ep_t; - -/** - * @brief Events generated by the library - * - * Enumeration of possible events that may be generated by the library. - */ -typedef enum -{ - NRF_DRV_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected */ - NRF_DRV_USBD_EVT_RESET, /**< Reset condition on USB bus detected */ - NRF_DRV_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now */ - NRF_DRV_USBD_EVT_RESUME, /**< This device should resume from suspend now */ - NRF_DRV_USBD_EVT_WUREQ, /**< Wakeup request - the USBD peripheral is ready to generate WAKEUP signal after exiting low power mode. */ - NRF_DRV_USBD_EVT_SETUP, /**< Setup frame received and decoded */ - NRF_DRV_USBD_EVT_EPTRANSFER, /**< - * For Rx (OUT: Host->Device): - * 1. The packet has been received but there is no buffer prepared for transfer already. - * 2. Whole transfer has been finished - * - * For Tx (IN: Device->Host): - * The last packet from requested transfer has been transfered over USB bus and acknowledged - */ - NRF_DRV_USBD_EVT_CNT /**< Number of defined events */ -}nrf_drv_usbd_event_type_t; - -/** - * @brief Possible endpoint error codes - * - * Error codes that may be returned with @ref NRF_DRV_USBD_EVT_EPTRANSFER - */ -typedef enum -{ - NRF_USBD_EP_OK, /**< No error */ - NRF_USBD_EP_WAITING, /**< Data received, no buffer prepared already - waiting for configured transfer */ - NRF_USBD_EP_OVERLOAD, /**< Received number of bytes cannot fit given buffer - * This error would also be returned when next_transfer function has been defined - * but currently received data cannot fit completely in current buffer. - * No data split from single endpoint transmission is supported. - * - * When this error is reported - data is left inside endpoint buffer. - * Clear endpoint or prepare new buffer and read it. - */ - NRF_USBD_EP_ABORTED, /**< EP0 transfer can be aborted when new setup comes. - * Any other transfer can be aborted by USB reset or library stopping. - */ -}nrf_drv_usbd_ep_status_t; - - -/** - * @brief Event structure - * - * Structure passed to event handler - */ -typedef struct -{ - nrf_drv_usbd_event_type_t type; - union - { - struct{ - uint16_t framecnt; //!< Current value of frame counter - }sof; //!< Data aviable for @ref NRF_DRV_USBD_EVT_SOF - struct{ - nrf_drv_usbd_ep_t ep; //!< Endpoint number - }isocrc; - struct{ - nrf_drv_usbd_ep_t ep; //!< Endpoint number - nrf_drv_usbd_ep_status_t status; //!< Status for the endpoint - }eptransfer; - }data; -}nrf_drv_usbd_evt_t; - -/** - * @brief USBD event callback function type. - * - * @param[in] p_event Event information structure. - */ -typedef void (*nrf_drv_usbd_event_handler_t)(nrf_drv_usbd_evt_t const * const p_event); - -/** - * @brief Universal data pointer. - * - * Universal data pointer that can be used for any type of transfer. - */ -typedef union -{ - void const * tx; //!< Constant TX buffer pointer. - void * rx; //!< Writable RX buffer pointer. - uint32_t ptr; //!< Numeric value used internally by the library. -}nrf_drv_usbd_data_ptr_t; - -/** - * @brief Structure to be filled with information about the next transfer. - * - * This is used mainly for transfer feeders and consumers. - * It describes a single endpoint transfer and therefore the size of the buffer - * can never be higher than the endpoint size. - */ -typedef struct -{ - nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library. - size_t size; //!< Size of the requested transfer. -}nrf_drv_usbd_ep_transfer_t; - -/** - * @brief Flags for the current transfer. - * - * Flags configured for the transfer that can be merged using the bitwise 'or' operator (|). - */ -typedef enum -{ - NRF_DRV_USBD_TRANSFER_ZLP_FLAG = 1U << 0, //!< Add a zero-length packet. -}nrf_drv_usbd_transfer_flags_t; - -/** - * @brief Total transfer configuration. - * - * This structure is used to configure total transfer information. - * It is used by internal built-in feeders and consumers. - */ -typedef struct -{ - nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library. - size_t size; //!< Total size of the requested transfer. - uint32_t flags; //!< Transfer flags. - /**< Use the @ref nrf_drv_usbd_transfer_flags_t values. */ -}nrf_drv_usbd_transfer_t; - - -/** - * @brief Auxiliary macro for declaring IN transfer description with flags. - * - * The base macro for creating transfers with any configuration option. - * - * @param name Instance name. - * @param tx_buff Buffer to transfer. - * @param tx_size Transfer size. - * @param tx_flags Flags for the transfer (see @ref nrf_drv_usbd_transfer_flags_t). - * - * @return Configured variable with total transfer description. - */ -#define NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, tx_flags) \ - const nrf_drv_usbd_transfer_t name = { \ - .p_data = { .tx = (tx_buff) }, \ - .size = (tx_size), \ - .flags = (tx_flags) \ - } - -/** - * @brief Helper macro for declaring IN transfer description - * - * Normal transfer mode, no ZLP would be automatically generated. - * - * @sa nrf_drv_usbd_transfer_t - * @sa NRF_DRV_USBD_TRANSFER_IN_ZLP - * - * @param name Instance name - * @param tx_buff Buffer to transfer - * @param tx_size Transfer size - * - * @return Configured variable with total transfer description - * - */ -#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \ - NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, 0) - -/** - * @brief Helper macro for declaring IN transfer description - * - * ZLP mode - Zero Length Packet would be generated on the end of the transfer - * (always!). - * - * @sa nrf_drv_usbd_transfer_t - * @sa NRF_DRV_USBD_TRANSFER_IN - * - * @param name Instance name - * @param tx_buff Buffer to transfer - * @param tx_size Transfer size - * - * @return Configured variable with total transfer description - */ -#define NRF_DRV_USBD_TRANSFER_IN_ZLP(name, tx_buff, tx_size) \ - NRF_DRV_USBD_TRANSFER_IN_FLAGS( \ - name, \ - tx_buff, \ - tx_size, \ - NRF_DRV_USBD_TRANSFER_ZLP_FLAG) - -/** - * @brief Helper macro for declaring OUT transfer item (@ref nrf_drv_usbd_transfer_t) - * - * @param name Instance name - * @param rx_buff Buffer to transfer - * @param rx_size Transfer size - * */ -#define NRF_DRV_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \ - const nrf_drv_usbd_transfer_t name = { \ - .p_data = { .rx = (rx_buff) }, \ - .size = (rx_size), \ - .flags = 0 \ - } - -/** - * @brief USBD transfer feeder. - * - * Pointer for a transfer feeder. - * Transfer feeder is a feedback function used to prepare a single - * TX (Device->Host) endpoint transfer. - * - * The transfers provided by the feeder must be simple: - * - The size of the transfer provided by this function is limited to a single endpoint buffer. - * Bigger transfers are not handled automatically in this case. - * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before. - * - * @note - * This function may use @ref nrf_drv_usbd_feeder_buffer_get to gain a temporary buffer - * that can be used to prepare transfer. - * - * @param[out] p_next Structure with the data for the next transfer to be filled. - * Required only if the function returns true. - * @param[in,out] p_context Context variable configured with the transfer. - * @param[in] ep_size The endpoint size. - * - * @retval false The current transfer is the last one - you do not need to call - * the function again. - * @retval true There is more data to be prepared and when the current transfer - * finishes, the feeder function is expected to be called again. - */ -typedef bool (*nrf_drv_usbd_feeder_t)( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size); - -/** - * @brief USBD transfer consumer. - * - * Pointer for a transfer consumer. - * Transfer consumer is a feedback function used to prepare a single - * RX (Host->Device) endpoint transfer. - * - * The transfer must provide a buffer big enough to fit the whole data from the endpoint. - * Otherwise, the NRF_USBD_EP_OVERLOAD event is generated. - * - * @param[out] p_next Structure with the data for the next transfer to be filled. - * Required only if the function returns true. - * @param[in,out] p_context Context variable configured with the transfer. - * @param[in] ep_size The endpoint size. - * @param[in] data_size Number of received bytes in the endpoint buffer. - * - * @retval false Current transfer is the last one - you do not need to call - * the function again. - * @retval true There is more data to be prepared and when current transfer - * finishes, the feeder function is expected to be called again. - */ -typedef bool (*nrf_drv_usbd_consumer_t)( - nrf_drv_usbd_ep_transfer_t * p_next, - void * p_context, - size_t ep_size, - size_t data_size); - -/** - * @brief Universal transfer handler. - * - * Union with feeder and consumer function pointer. - */ -typedef union -{ - nrf_drv_usbd_feeder_t feeder; //!< Feeder function pointer. - nrf_drv_usbd_consumer_t consumer; //!< Consumer function pointer. -}nrf_drv_usbd_handler_t; - -/** - * @brief USBD transfer descriptor. - * - * Universal structure that may hold the setup for callback configuration for - * IN or OUT type of the transfer. - */ -typedef struct -{ - nrf_drv_usbd_handler_t handler; //!< Handler for the current transfer, function pointer. - void * p_context; //!< Context for the transfer handler. -}nrf_drv_usbd_handler_desc_t; - -/** - * @brief Setup packet structure - * - * Structure that contains interpreted SETUP packet. - */ -typedef struct -{ - uint8_t bmRequestType; //!< byte 0 - uint8_t bmRequest; //!< byte 1 - uint16_t wValue; //!< byte 2 - uint16_t wIndex; //!< byte 4, 5 - uint16_t wLength; //!< byte 6, 7 -}nrf_drv_usbd_setup_t; - -/** - * @brief Library initialization - * - * @param[in] event_handler Event handler provided by the user. - */ -ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler); - -/** - * @brief Library deinitialization - */ -ret_code_t nrf_drv_usbd_uninit(void); - -/** - * @brief Enable the USBD port - * - * After calling this function USBD peripheral would be enabled. - * The USB LDO would be enabled. - * Enabled USBD peripheral would request HFCLK. - * This function does not enable external oscillator, so if it is not enabled by other part of the - * program after enabling USBD driver HFINT would be used for the USBD peripheral. - * It is perfectly fine until USBD is started. See @ref nrf_drv_usbd_start. - * - * In normal situation this function should be called in reaction to USBDETECTED - * event from POWER peripheral. - * - * Interrupts and USB pins pull-up would stay disabled until @ref nrf_drv_usbd_start - * function is called. - */ -void nrf_drv_usbd_enable(void); - -/** - * @brief Disable the USBD port - * - * After calling this function USBD peripheral would be disabled. - * No events would be detected or processed by the library. - * Clock for the peripheral would be disconnected. - */ -void nrf_drv_usbd_disable(void); - -/** - * @brief Start USB functionality - * - * After calling this function USBD peripheral should be fully functional - * and all new incoming events / interrupts would be processed by the library. - * - * Also only after calling this function host sees new connected device. - * - * Call this function when USBD power LDO regulator is ready - on USBPWRRDY event - * from POWER peripheral. - * - * Before USBD interrupts are enabled, external HFXO is requested. - * - * @param enable_sof The flag that is used to enable SOF processing. - * If it is false, SOF interrupt is left disabled and will not be generated. - * This improves power saving if SOF is not required. - * - * @note If the isochronous endpoints are going to be used, - * it is required to enable the SOF. - * In other case any isochronous endpoint would stay busy - * after first transmission. - */ -void nrf_drv_usbd_start(bool enable_sof); - -/** - * @brief Stop USB functionality - * - * This function disables USBD pull-up and interrupts. - * - * The HFXO request is released in this function. - * - * @note - * This function can also be used to logically disconnect USB from the HOST that - * would force it to enumerate device after calling @ref nrf_drv_usbd_start. - */ -void nrf_drv_usbd_stop(void); - -/** - * @brief Check if driver is initialized - * - * @retval false Driver is not initialized - * @retval true Driver is initialized - */ -bool nrf_drv_usbd_is_initialized(void); - -/** - * @brief Check if driver is enabled - * - * @retval false Driver is disabled - * @retval true Driver is enabled - */ -bool nrf_drv_usbd_is_enabled(void); - -/** - * @brief Check if driver is started - * - * @retval false Driver is not started - * @retval true Driver is started (fully functional) - * @note The USBD peripheral interrupt state is checked - */ -bool nrf_drv_usbd_is_started(void); - -/** - * @brief Suspend USBD operation - * - * The USBD peripheral is forced to go into the low power mode. - * The function has to be called in the reaction to @ref NRF_DRV_USBD_EVT_SUSPEND event - * when the firmware is ready. - * - * After successful call of this function most of the USBD registers would be unavailable. - * - * @note Check returned value for the feedback if suspending was successful. - * - * @retval true USBD peripheral successfully suspended - * @retval false USBD peripheral was not suspended due to resume detection. - * - */ -bool nrf_drv_usbd_suspend(void); - -/** - * @brief Start wake up procedure - * - * The USBD peripheral is forced to quit the low power mode. - * After calling this function all the USBD registers would be available. - * - * The hardware starts measuring time when wake up is possible. - * This may take 0-5 ms depending on how long the SUSPEND state was kept on the USB line. - - * When NRF_DRV_USBD_EVT_WUREQ event is generated it means that Wake Up signaling has just been - * started on the USB lines. - * - * @note Do not expect only @ref NRF_DRV_USBD_EVT_WUREQ event. - * There always may appear @ref NRF_DRV_USBD_EVT_RESUME event. - * @note NRF_DRV_USBD_EVT_WUREQ event means that Remote WakeUp signal - * has just begun to be generated. - * This may take up to 20 ms for the bus to become active. - * - * @retval true WakeUp procedure started. - * @retval false No WakeUp procedure started - bus is already active. - */ -bool nrf_drv_usbd_wakeup_req(void); - -/** - * @brief Check if USBD is in SUSPEND mode - * - * @note This is the information about peripheral itself, not about the bus state. - * - * @retval true USBD peripheral is suspended - * @retval false USBD peripheral is active - */ -bool nrf_drv_usbd_suspend_check(void); - -/** - * @brief Enable only interrupts that should be processed in SUSPEND mode - * - * Auxiliary function to help with SUSPEND mode integration. - * It enables only the interrupts that can be properly processed without stable HFCLK. - * - * Normally all the interrupts are enabled. - * Use this function to suspend interrupt processing that may require stable HFCLK until the - * clock is enabled. - * - * @sa nrf_drv_usbd_active_irq_config - */ -void nrf_drv_usbd_suspend_irq_config(void); - -/** - * @brief Default active interrupt configuration - * - * Default interrupt configuration. - * Use in a pair with @ref nrf_drv_usbd_active_irq_config. - * - * @sa nrf_drv_usbd_suspend_irq_config - */ -void nrf_drv_usbd_active_irq_config(void); - -/** - * @brief Check the bus state - * - * This function checks if the bus state is suspended - * - * @note The value returned by this function changes on SUSPEND and RESUME event processing. - * - * @retval true USBD bus is suspended - * @retval false USBD bus is active - */ -bool nrf_drv_usbd_bus_suspend_check(void); - -/** - * @brief Force the bus state to active - */ -void nrf_drv_usbd_force_bus_wakeup(void); - -/** - * @brief Configure packet size that should be supported by the endpoint - * - * The real endpoint buffer size is always the same. - * This value sets max packet size that would be transmitted over the endpoint. - * This is required by the library - * - * @param[in] ep Endpoint number - * @param[in] size Required maximum packet size - * - * @note Endpoint size is always set to @ref NRF_DRV_USBD_EPSIZE or @ref NRF_DRV_USBD_ISOSIZE / 2 - * when @ref nrf_drv_usbd_ep_enable function is called. - */ -void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size); - -/** - * @brief Get configured endpoint packet size - * - * Function to get configured endpoint size on the buffer. - * - * @param[in] ep Endpoint number - * - * @return Maximum pocket size configured on selected endpoint - */ -uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep); - -/** - * @brief Check if the selected endpoint is enabled. - * - * @param ep Endpoint number to check. - * - * @retval true Endpoint is enabled. - * @retval false Endpoint is disabled. - */ -bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep); - -/** - * @brief Enable selected endpoint - * - * This function enables endpoint itself and its interrupts. - * @param ep Endpoint number to enable - * - * @note - * Max packet size is set to endpoint default maximum value. - * - * @sa nrf_drv_usbd_ep_max_packet_size_set - */ -void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep); - -/** - * @brief Disable selected endpoint - * - * This function disables endpoint itself and its interrupts. - * @param ep Endpoint number to disable - */ -void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep); - -/** - * @brief Disable all endpoints except for EP0 - * - * Disable all endpoints that can be disabled in USB device while it is still active. - */ -void nrf_drv_usbd_ep_default_config(void); - -/** - * @brief Start sending data over endpoint - * - * Function initializes endpoint transmission. - * This is asynchronous function - it finishes immediately after configuration - * for transmission is prepared. - * - * @note Data buffer pointed by p_data have to be kept active till - * @ref NRF_DRV_USBD_EVT_EPTRANSFER event is generated. - * - * @param[in] ep Endpoint number. - * For IN endpoint sending would be initiated. - * For OUT endpoint receiving would be initiated. - * @param[in] p_transfer - * - * @retval NRF_ERROR_BUSY Selected endpoint is pending. - * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. - * @retval NRF_ERROR_FORBIDDEN Endpoint stalled. - * @retval NRF_SUCCESS Transfer queued or started. - */ -ret_code_t nrf_drv_usbd_ep_transfer( - nrf_drv_usbd_ep_t ep, - nrf_drv_usbd_transfer_t const * const p_transfer); - -/** - * @brief Start sending data over the endpoint using the transfer handler function. - * - * This function initializes an endpoint transmission. - * Just before data is transmitted, the transfer handler - * is called and it prepares a data chunk. - * - * @param[in] ep Endpoint number. - * For an IN endpoint, sending is initiated. - * For an OUT endpoint, receiving is initiated. - * @param p_handler Transfer handler - feeder for IN direction and consumer for - * OUT direction. - * - * @retval NRF_ERROR_BUSY Selected endpoint is pending. - * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. - * @retval NRF_ERROR_FORBIDDEN Endpoint stalled. - * @retval NRF_SUCCESS Transfer queued or started. - */ -ret_code_t nrf_drv_usbd_ep_handled_transfer( - nrf_drv_usbd_ep_t ep, - nrf_drv_usbd_handler_desc_t const * const p_handler); - -/** - * @brief Get the temporary buffer to be used by the feeder. - * - * This buffer is used for TX transfers and it can be reused automatically - * when the transfer is finished. - * Use it for transfer preparation. - * - * May be used inside the feeder configured in @ref nrf_drv_usbd_ep_handled_transfer. - * - * @return Pointer to the buffer that can be used temporarily. - * - * @sa NRF_DRV_USBD_FEEDER_BUFFER_SIZE - */ -void * nrf_drv_usbd_feeder_buffer_get(void); - -/** - * @brief Get the information about last finished or current transfer - * - * Function returns the status of the last buffer set for transfer on selected endpoint. - * The status considers last buffer set by @ref nrf_drv_usbd_ep_transfer function or - * by transfer callback function. - * - * @param[in] ep Endpoint number. - * @param[out] p_size Information about the current/last transfer size. - * - * @retval NRF_SUCCESS Transfer already finished - * @retval NRF_ERROR_BUSY Ongoing transfer - * @retval NRF_ERROR_DATA_SIZE Too much of data received that cannot fit into buffer and cannot be splited into chunks. - * This may happen if buffer size is not a multiplication of endpoint buffer size. - */ -ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size); - -/** - * @brief Get number of received bytes - * - * Get the number of received bytes. - * The function behavior is undefined when called on IN endpoint. - * - * @param ep Endpoint number. - * - * @return Number of received bytes - */ -size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep); - -/** - * @brief Check if endpoint buffer is ready or is under USB IP control - * - * Function to test if endpoint is busy. - * Endpoint that is busy cannot be accessed by MCU. - * It means that: - * - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting - * to be received by the host. - * - IN (RX) endpoint: Endpoint is ready to receive data from the host - * and the endpoint does not have any data. - * When endpoint is not busy: - * - OUT (TX) endpoint: New data can be uploaded. - * - IN (RX) endpoint: New data can be downloaded using @ref nrf_drv_usbd_ep_transfer - * function. - */ -bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep); - -/** - * @brief Stall endpoint - * - * Stall endpoit to send error information during next transfer request from - * the host. - * - * @note To stall endpoint it is safer to use @ref nrf_drv_usbd_setup_stall - * @note Stalled endpoint would not be cleared when DMA transfer finishes. - * - * @param ep Endpoint number to stall - * - */ -void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep); - -/** - * @brief Clear stall flag on endpoint - * - * This function clears endpoint that is stalled. - * @note - * If it is OUT endpoint (receiving) it would be also prepared for reception. - * It means that busy flag would be set. - * @note - * In endpoint (transmitting) would not be cleared - it gives possibility to - * write new data before transmitting. - */ -void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep); - -/** - * @brief Check if endpoint is stalled - * - * This function gets stall state of selected endpoint - * - * @param ep Endpoint number to check - */ -bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep); - -/** - * @brief Clear current endpoint data toggle - * - * @param ep Endpoint number to clear - */ -void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep); - -/** - * @brief Get parsed setup data - * - * Function fills the parsed setup data structure. - * - * @param[out] p_setup Pointer to data structure that would be filled by - * parsed data. - */ -void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup); - -/** - * @brief Clear only for data transmission on setup endpoint - * - * This function may be called if any more data in control write transfer is expected. - * Clears only OUT endpoint to be able to take another OUT data token. - * It does not allow STATUS stage. - * @sa nrf_drv_usbd_setup_clear - */ -void nrf_drv_usbd_setup_data_clear(void); - -/** - * @brief Clear setup endpoint - * - * This function acknowledges setup when SETUP command was received and processed. - * It has to be called if no data respond for the SETUP command is sent. - */ -void nrf_drv_usbd_setup_clear(void); - -/** - * @brief Stall setup endpoint - * - * Mark and error on setup endpoint. - */ -void nrf_drv_usbd_setup_stall(void); - -/** -* @note -* This function locks interrupts that may be costly. -* It is good idea to test if the endpoint is still busy before calling this function: -* @code - (m_ep_dma_waiting & (1U << ep2bit(ep))) -* @endcode -* This function would check it again, but it makes it inside critical section. -*/ -void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep); - -/** - * @brief Get the information about expected transfer SETUP data direction - * - * Function returns the information about last expected transfer direction. - * - * @retval NRF_DRV_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data - * @retval NRF_DRV_USBD_EPIN0 Expecting IN (Device->Host) direction - */ -nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void); - -/** - * @brief Drop transfer on OUT endpoint - * - * @param[in] ep OUT endpoint ID - */ -void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* NRF_DRV_USBD_H__ */ +/*$$$LICENCE_NORDIC_STANDARD<2016>$$$*/ + +#ifndef NRF_DRV_USBD_H__ +#define NRF_DRV_USBD_H__ + +#include "nrfx.h" +#include "nrfx_usbd.h" +#include "nrf_drv_usbd_errata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_drv_usbd USBD driver - legacy layer + * @{ + * @ingroup nrf_usbd + * + * @brief @tagAPI52 Layer providing compatibility with the former API. + */ + +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED NRFX_USBD_DMASCHEDULER_PRIORITIZED +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN NRFX_USBD_DMASCHEDULER_ROUNDROBIN +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPSIZE NRFX_USBD_EPSIZE +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_ISOSIZE NRFX_USBD_ISOSIZE +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_FEEDER_BUFFER_SIZE NRFX_USBD_EPSIZE +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN NRFX_USBD_EPIN +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT NRFX_USBD_EPOUT + +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_ep_t nrf_drv_usbd_ep_t; +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT0 NRFX_USBD_EPOUT0 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT1 NRFX_USBD_EPOUT1 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT2 NRFX_USBD_EPOUT2 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT3 NRFX_USBD_EPOUT3 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT4 NRFX_USBD_EPOUT4 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT5 NRFX_USBD_EPOUT5 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT6 NRFX_USBD_EPOUT6 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT7 NRFX_USBD_EPOUT7 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPOUT8 NRFX_USBD_EPOUT8 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN0 NRFX_USBD_EPIN0 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN1 NRFX_USBD_EPIN1 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN2 NRFX_USBD_EPIN2 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN3 NRFX_USBD_EPIN3 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN4 NRFX_USBD_EPIN4 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN5 NRFX_USBD_EPIN5 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN6 NRFX_USBD_EPIN6 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN7 NRFX_USBD_EPIN7 +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EPIN8 NRFX_USBD_EPIN8 + +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_event_type_t nrf_drv_usbd_event_type_t; +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_SOF NRFX_USBD_EVT_SOF +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_RESET NRFX_USBD_EVT_RESET +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_SUSPEND NRFX_USBD_EVT_SUSPEND +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_RESUME NRFX_USBD_EVT_RESUME +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_WUREQ NRFX_USBD_EVT_WUREQ +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_SETUP NRFX_USBD_EVT_SETUP +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_EPTRANSFER NRFX_USBD_EVT_EPTRANSFER +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_EVT_CNT NRFX_USBD_EVT_CNT + +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_USBD_EP_OK NRFX_USBD_EP_OK +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_USBD_EP_WAITING NRFX_USBD_EP_WAITING +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_USBD_EP_OVERLOAD NRFX_USBD_EP_OVERLOAD +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_USBD_EP_ABORTED NRFX_USBD_EP_ABORTED + +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_ep_status_t nrf_drv_usbd_ep_status_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_evt_t nrf_drv_usbd_evt_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_event_handler_t nrf_drv_usbd_event_handler_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_data_ptr_t nrf_drv_usbd_data_ptr_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_ep_transfer_t nrf_drv_usbd_ep_transfer_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_transfer_flags_t nrf_drv_usbd_transfer_flags_t; +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_TRANSFER_ZLP_FLAG NRFX_USBD_TRANSFER_ZLP_FLAG + +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_transfer_t nrf_drv_usbd_transfer_t; + +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, tx_flags) \ + NRFX_USBD_TRANSFER_IN(name, tx_buff, tx_size, tx_flags) +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \ + NRFX_USBD_TRANSFER_IN(name, tx_buff, tx_size, 0) +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_TRANSFER_IN_ZLP(name, tx_buff, tx_size) \ + NRFX_USBD_TRANSFER_IN(name, tx_buff, tx_size, NRFX_USBD_TRANSFER_ZLP_FLAG) +/** @brief Type definition for forwarding the new implementation. */ +#define NRF_DRV_USBD_TRANSFER_OUT NRFX_USBD_TRANSFER_OUT + +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_feeder_t nrf_drv_usbd_feeder_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_consumer_t nrf_drv_usbd_consumer_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_handler_t nrf_drv_usbd_handler_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_handler_desc_t nrf_drv_usbd_handler_desc_t; +/** @brief Type definition for forwarding the new implementation. */ +typedef nrfx_usbd_setup_t nrf_drv_usbd_setup_t; + +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_init nrfx_usbd_init +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_enable nrfx_usbd_enable +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_disable nrfx_usbd_disable +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_start nrfx_usbd_start +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_stop nrfx_usbd_stop +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_is_initialized nrfx_usbd_is_initialized +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_is_enabled nrfx_usbd_is_enabled +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_is_started nrfx_usbd_is_started +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_suspend nrfx_usbd_suspend +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_wakeup_req nrfx_usbd_wakeup_req +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_suspend_check nrfx_usbd_suspend_check +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_suspend_irq_config nrfx_usbd_suspend_irq_config +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_active_irq_config nrfx_usbd_active_irq_config +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_force_bus_wakeup nrfx_usbd_force_bus_wakeup +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_bus_suspend_check nrfx_usbd_bus_suspend_check +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_max_packet_size_set nrfx_usbd_ep_max_packet_size_set +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_max_packet_size_get nrfx_usbd_ep_max_packet_size_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_enable_check nrfx_usbd_ep_enable_check +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_enable nrfx_usbd_ep_enable +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_disable nrfx_usbd_ep_disable +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_default_config nrfx_usbd_ep_default_config +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_transfer nrfx_usbd_ep_transfer +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_handled_transfer nrfx_usbd_ep_handled_transfer +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_feeder_buffer_get nrfx_usbd_feeder_buffer_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_status_get nrfx_usbd_ep_status_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_epout_size_get nrfx_usbd_epout_size_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_is_busy nrfx_usbd_ep_is_busy +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_stall nrfx_usbd_ep_stall +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_stall_clear nrfx_usbd_ep_stall_clear +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_stall_check nrfx_usbd_ep_stall_check +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_dtoggle_clear nrfx_usbd_ep_dtoggle_clear +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_setup_get nrfx_usbd_setup_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_setup_data_clear nrfx_usbd_setup_data_clear +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_setup_clear nrfx_usbd_setup_clear +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_setup_stall nrfx_usbd_setup_stall +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_ep_abort nrfx_usbd_ep_abort +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_last_setup_dir_get nrfx_usbd_last_setup_dir_get +/** @brief Type definition for forwarding the new implementation. */ +#define nrf_drv_usbd_transfer_out_drop nrfx_usbd_transfer_out_drop + +/** @brief Type definition for forwarding the new implementation. */ +static inline ret_code_t nrf_drv_usbd_uninit(void) +{ + nrfx_usbd_uninit(); + return NRF_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* NRF_DRV_USBD_H__ */ diff --git a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h b/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h index b204b43ad..00c589b67 100644 --- a/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h +++ b/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h @@ -1,210 +1,70 @@ -/** - * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_DRV_USBD_ERRATA_H__ -#define NRF_DRV_USBD_ERRATA_H__ - -#include -/** - * @defgroup nrf_drv_usbd_errata Functions to check if selected PAN is present in current chip - * @{ - * @ingroup nrf_drv_usbd - * - * Functions here are checking the presence of an error in current chip. - * The checking is done at runtime based on the microcontroller version. - * This file is subject to removal when nRF51840 prototype support is removed. - */ - -#ifndef NRF_DRV_USBD_ERRATA_ENABLE -/** - * @brief The constant that informs if errata should be enabled at all - * - * If this constant is set to 0, all the Errata bug fixes will be automatically disabled. - */ -#define NRF_DRV_USBD_ERRATA_ENABLE 1 -#endif - -/** - * @brief Internal auxiliary function to check if the program is running on NRF52840 chip - * @retval true It is NRF52480 chip - * @retval false It is other chip - */ -static inline bool nrf_drv_usbd_errata_type_52840(void) -{ - return (*(uint32_t *)0x10000130UL == 0x8UL); -} - -/** - * @brief Internal auxiliary function to check if the program is running on Engineering A revision - * @retval true It is NRF52480 chip and it is Engineering A revision - * @retval false It is other chip - */ -static inline bool nrf_drv_usbd_errata_type_52840_eng_a(void) -{ - return (nrf_drv_usbd_errata_type_52840() && (*(uint32_t *)0x10000134UL == 0x0UL)); -} - -/** - * @brief Internal auxiliary function to check if the program is running on Engineering B revision - * @retval true It is NRF52480 chip and it is Engineering B revision - * @retval false It is other chip - */ -static inline bool nrf_drv_usbd_errata_type_52840_eng_b(void) -{ - return (nrf_drv_usbd_errata_type_52840() && (*(uint32_t *)0x10000134UL == 0x1UL)); -} - -/** - * @brief Internal auxiliary function to check if the program is running on Engineering C revision - * @retval true It is NRF52480 chip and it is Engineering C revision - * @retval false It is other chip - */ -static inline bool nrf_drv_usbd_errata_type_52840_eng_c(void) -{ - return (nrf_drv_usbd_errata_type_52840() && (*(uint32_t *)0x10000134UL == 0x2UL)); -} - -/** - * @brief Internal auxiliary function to check if the program is running on Engineering D revision - * @retval true It is NRF52480 chip and it is Engineering D revision - * @retval false It is other chip - */ -static inline bool nrf_drv_usbd_errata_type_52840_eng_d(void) -{ - return (nrf_drv_usbd_errata_type_52840() && (*(uint32_t *)0x10000134UL == 0x3UL)); -} - -/** - * @brief Function to check if chip requires errata 104 - * - * Errata: USBD: EPDATA event is not always generated. - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_104(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_eng_a()); -} - -/** - * @brief Function to check if chip requires errata 154 - * - * Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task. - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_154(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_eng_a()); -} - -/** - * @brief Function to check if chip requires errata 166 - * - * Errata: ISO double buffering not functional - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_166(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && true); -} - -/** - * @brief Function to check if chip requires errata 171 - * - * Errata: USBD might not reach its active state. - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_171(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && true); -} - -/** - * @brief Function to check if chip requires errata 187 - * - * Errata: USB cannot be enabled - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_187(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && - (nrf_drv_usbd_errata_type_52840_eng_b() || - nrf_drv_usbd_errata_type_52840_eng_c() || - nrf_drv_usbd_errata_type_52840_eng_d()) - ); -} - -/** - * @brief Function to check if chip requires errata 199 - * - * Errata: USBD cannot receive tasks during DMA - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usb_errata_199(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && true); -} - -/** - * @brief Function to check if chip requires errata 200 - * - * Errata: SIZE.EPOUT not writable - * - * @retval true Errata should be implemented - * @retval false Errata should not be implemented - */ -static inline bool nrf_drv_usbd_errata_200(void) -{ - return (NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_eng_a()); -} - -/** @} */ -#endif /* NRF_DRV_USBD_ERRATA_H__ */ +/** + * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRF_DRV_USBD_ERRATA_H__ +#define NRF_DRV_USBD_ERRATA_H__ + +#include "nrfx.h" + +#ifndef NRFX_USBD_ERRATA_ENABLE + #ifdef NRF_DRV_USBD_ERRATA_ENABLE + #define NRFX_USBD_ERRATA_ENABLE NRF_DRV_USBD_ERRATA_ENABLE + #endif +#endif + +#include "../src/nrfx_usbd_errata.h" + +#ifndef NRF_DRV_USBD_ERRATA_ENABLE +#define NRF_DRV_USBD_ERRATA_ENABLE NRFX_USBD_ERRATA_ENABLE +#endif + +#define nrf_drv_usbd_errata_type_52840 nrfx_usbd_errata_type_52840 +#define nrf_drv_usbd_errata_type_52840_proto1 nrfx_usbd_errata_type_52840_proto1 +#define nrf_drv_usbd_errata_type_52840_fp1 nrfx_usbd_errata_type_52840_fp1 +#define nrf_drv_usbd_errata_type_52840_fp2 nrfx_usbd_errata_type_52840_fp2 +#define nrf_drv_usbd_errata_104 nrfx_usbd_errata_104 +#define nrf_drv_usbd_errata_154 nrfx_usbd_errata_154 +#define nrf_drv_usbd_errata_166 nrfx_usbd_errata_166 +#define nrf_drv_usbd_errata_171 nrfx_usbd_errata_171 +#define nrf_drv_usbd_errata_187 nrfx_usbd_errata_187 +#define nrf_drv_usbd_errata_sizeepout_rw nrfx_usbd_errata_sizeepout_rw +#define nrf_drv_usb_errata_199 nrfx_usb_errata_199 + +#endif /* NRF_DRV_USBD_ERRATA_H__ */