/*
 * Copyright (c) 2016 - 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 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 the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <nrfx.h>

#if NRFX_CHECK(NRFX_USBD_ENABLED)

#include <nrfx_usbd.h>
#include "nrfx_usbd_errata.h"
#include <nrfx_systick.h> /* Marker to delete when not required anymore: >> NRFX_USBD_ERRATA_ENABLE << */
#include <string.h>

#define NRFX_LOG_MODULE USBD
#include <nrfx_log.h>

#ifndef NRFX_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 NRFX_USBD_EARLY_DMA_PROCESS 1
#endif

#ifndef NRFX_USBD_PROTO1_FIX_DEBUG
/* Debug information when events are fixed*/
#define NRFX_USBD_PROTO1_FIX_DEBUG 1
#endif

#define NRFX_USBD_LOG_PROTO1_FIX_PRINTF(...)                           \
    do{                                                                \
        if (NRFX_USBD_PROTO1_FIX_DEBUG){ NRFX_LOG_DEBUG(__VA_ARGS__); }\
    } while (0)

#ifndef NRFX_USBD_STARTED_EV_ENABLE
#define NRFX_USBD_STARTED_EV_ENABLE    0
#endif

#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
/*
 * Respond to an IN token on ISO IN endpoint with ZLP when no data is ready.
 * NOTE: This option does not work on Engineering A chip.
 */
#define NRFX_USBD_CONFIG_ISO_IN_ZLP  0
#endif

#ifndef NRFX_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 NRFX_USBD_ISO_DEBUG 1
#endif

#ifndef NRFX_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 NRFX_USBD_FAILED_TRANSFERS_DEBUG 1
#endif

#ifndef NRFX_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 NRFX_USBD_DMAREQ_PROCESS_DEBUG 1
#endif


/**
 * @defgroup nrfx_usbd_int USB Device driver internal part
 * @internal
 * @ingroup nrfx_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 NRFX_USBD_ASSERT_EP_VALID(ep) NRFX_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 NRFX_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 NRFX_USBD_EPOUT_BITPOS_0  16

/**
 * @brief Input endpoint bits mask.
 */
#define NRFX_USBD_EPIN_BIT_MASK (0xFFFFU << NRFX_USBD_EPIN_BITPOS_0)

/**
 * @brief Output endpoint bits mask.
 */
#define NRFX_USBD_EPOUT_BIT_MASK (0xFFFFU << NRFX_USBD_EPOUT_BITPOS_0)

/**
 * @brief Isochronous endpoint bit mask
 */
#define USBD_EPISO_BIT_MASK \
    ((1U << NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT8)) | \
     (1U << NRFX_USBD_EP_BITPOS(NRFX_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 NRFX_USBD_EP_BITPOS(ep) \
    ((NRF_USBD_EPIN_CHECK(ep) ? NRFX_USBD_EPIN_BITPOS_0 : NRFX_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 NRFX_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \
    const nrfx_usbd_evt_t name = {                          \
        NRFX_USBD_EVT_EPTRANSFER,                           \
        .data = {                                           \
            .eptransfer = {                                 \
                    .ep = endpont,                          \
                    .status = ep_stat                       \
            }                                               \
        }                                                   \
    }

/* Check it the bit positions values match defined DATAEPSTATUS bit positions */
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN1)  == USBD_EPDATASTATUS_EPIN1_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN2)  == USBD_EPDATASTATUS_EPIN2_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN3)  == USBD_EPDATASTATUS_EPIN3_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN4)  == USBD_EPDATASTATUS_EPIN4_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN5)  == USBD_EPDATASTATUS_EPIN5_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN6)  == USBD_EPDATASTATUS_EPIN6_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPIN7)  == USBD_EPDATASTATUS_EPIN7_Pos );
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos);
NRFX_STATIC_ASSERT(NRFX_USBD_EP_BITPOS(NRFX_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos);


/**
 * @brief Current driver state.
 */
static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;

/**
 * @brief Event handler for the driver.
 *
 * Event handler that would be called on events.
 *
 * @note Currently it cannot be null if any interrupt is activated.
 */
static nrfx_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 nrfx_usbd_suspend_irq_config and @ref nrfx_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 nrfx_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: >> NRFX_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
{
    nrfx_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.
    nrfx_usbd_ep_status_t status;          //!< NRFX_SUCCESS or error code, never NRFX_ERROR_BUSY - this one is calculated.
} usbd_ep_state_t;

/**
 * @brief The array of transfer configurations for the endpoints.
 *
 * The status of the transfer on each endpoint.
 */
static struct
{
    usbd_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints.
    usbd_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.
 */
nrfx_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.
 */
nrfx_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[NRFX_CEIL_DIV(
    NRFX_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: >> NRFX_USBD_ERRATA_ENABLE <<.
 */
static inline nrf_usbd_event_t nrfx_usbd_ep_to_endevent(nrfx_usbd_ep_t ep)
{
    NRFX_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 nrfx_usbd_ep_to_int(nrfx_usbd_ep_t ep)
{
    NRFX_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 nrfx_usbd_consumer_t documentation.
 * @param p_context See @ref nrfx_usbd_consumer_t documentation.
 * @param ep_size   See @ref nrfx_usbd_consumer_t documentation.
 * @param data_size See @ref nrfx_usbd_consumer_t documentation.
 *
 * @retval true  Continue transfer.
 * @retval false This was the last transfer.
 */
bool nrfx_usbd_consumer(
    nrfx_usbd_ep_transfer_t * p_next,
    void * p_context,
    size_t ep_size,
    size_t data_size)
{
    nrfx_usbd_transfer_t * p_transfer = p_context;
    NRFX_ASSERT(ep_size >= data_size);
    NRFX_ASSERT((p_transfer->p_data.rx == NULL) ||
        nrfx_is_in_ram(p_transfer->p_data.rx));

    size_t size = p_transfer->size;
    if (size < data_size)
    {
        NRFX_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.addr += data_size;
    }
    return (ep_size == data_size) && (size != 0);
}

/**
 * @brief Integrated feeder from RAM source.
 *
 * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
 * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
 * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
 *
 * @retval true  Continue transfer.
 * @retval false This was the last transfer.
 */
bool nrfx_usbd_feeder_ram(
    nrfx_usbd_ep_transfer_t * p_next,
    void * p_context,
    size_t ep_size)
{
    nrfx_usbd_transfer_t * p_transfer = p_context;
    NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));

    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.addr += tx_size;

    return (p_transfer->size != 0);
}

/**
 * @brief Integrated feeder from RAM source with ZLP.
 *
 * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
 * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
 * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
 *
 * @retval true  Continue transfer.
 * @retval false This was the last transfer.
 */
bool nrfx_usbd_feeder_ram_zlp(
    nrfx_usbd_ep_transfer_t * p_next,
    void * p_context,
    size_t ep_size)
{
    nrfx_usbd_transfer_t * p_transfer = p_context;
    NRFX_ASSERT(nrfx_is_in_ram(p_transfer->p_data.tx));

    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.addr += tx_size;

    return (tx_size != 0);
}

/**
 * @brief Integrated feeder from a flash source.
 *
 * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
 * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
 * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
 *
 * @retval true  Continue transfer.
 * @retval false This was the last transfer.
 */
bool nrfx_usbd_feeder_flash(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
{
    nrfx_usbd_transfer_t * p_transfer = p_context;
    NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));

    size_t tx_size  = p_transfer->size;
    void * p_buffer = nrfx_usbd_feeder_buffer_get();

    if (tx_size > ep_size)
    {
        tx_size = ep_size;
    }

    NRFX_ASSERT(tx_size <= NRFX_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.addr += tx_size;

    return (p_transfer->size != 0);
}

/**
 * @brief Integrated feeder from a flash source with ZLP.
 *
 * @param[out]    p_next    See @ref nrfx_usbd_feeder_t documentation.
 * @param[in,out] p_context See @ref nrfx_usbd_feeder_t documentation.
 * @param[in]     ep_size   See @ref nrfx_usbd_feeder_t documentation.
 *
 * @retval true  Continue transfer.
 * @retval false This was the last transfer.
 */
bool nrfx_usbd_feeder_flash_zlp(nrfx_usbd_ep_transfer_t * p_next, void * p_context, size_t ep_size)
{
    nrfx_usbd_transfer_t * p_transfer = p_context;
    NRFX_ASSERT(!nrfx_is_in_ram(p_transfer->p_data.tx));

    size_t tx_size  = p_transfer->size;
    void * p_buffer = nrfx_usbd_feeder_buffer_get();

    if (tx_size > ep_size)
    {
        tx_size = ep_size;
    }

    NRFX_ASSERT(tx_size <= NRFX_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.addr += 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 nrfx_usbd_ep_from_hal
 */
static inline uint8_t ep_to_hal(nrfx_usbd_ep_t ep)
{
    NRFX_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(nrfx_usbd_ep_t ep)
{
    NRFX_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_ep_state_t* ep_state_access(nrfx_usbd_ep_t ep)
{
    NRFX_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(nrfx_usbd_ep_t ep)
{
    NRFX_USBD_ASSERT_EP_VALID(ep);
    return NRFX_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 nrfx_usbd_ep_t bit2ep(uint8_t bitpos)
{
    NRFX_STATIC_ASSERT(NRFX_USBD_EPOUT_BITPOS_0 > NRFX_USBD_EPIN_BITPOS_0);
    return (nrfx_usbd_ep_t)((bitpos >= NRFX_USBD_EPOUT_BITPOS_0) ?
        NRF_USBD_EPOUT(bitpos - NRFX_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 (nrfx_usbd_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 (nrfx_usbd_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(nrfx_usbd_ep_t ep)
{
    nrf_usbd_task_trigger(task_start_ep(ep));
}

void nrfx_usbd_isoinconfig_set(nrf_usbd_isoinconfig_t config)
{
    nrf_usbd_isoinconfig_set(config);
}

nrf_usbd_isoinconfig_t nrfx_usbd_isoinconfig_get(void)
{
    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(nrfx_usbd_ep_t ep)
{
    NRFX_CRITICAL_SECTION_ENTER();

    usbd_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 */
            nrfx_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 = NRFX_USBD_EP_ABORTED;
    }
    else
    {
        if(!NRF_USBD_EPISO_CHECK(ep))
        {
            /* Workaround: Disarm the endpoint if there is any data buffered. */
            if(ep != NRFX_USBD_EPIN0)
            {
                *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7B6 + (2u * (NRF_USBD_EP_NR_GET(ep) - 1));
                uint8_t temp = *((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
                temp |= (1U << 1);
                *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) |= temp;
                (void)(*((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;
                (void)(*((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 = NRFX_USBD_EP_ABORTED;
            NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_ABORTED);
            m_event_handler(&evt);
        }
    }
    NRFX_CRITICAL_SECTION_EXIT();
}

void nrfx_usbd_ep_abort(nrfx_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 & NRFX_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) << NRFX_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)
{
    NRFX_IRQ_PENDING_SET(USBD_IRQn);
}

/**
 * @name USBD interrupt runtimes.
 *
 * Interrupt runtimes that would be vectorized using @ref m_isr.
 * @{
 */

static void ev_usbreset_handler(void)
{
    m_bus_suspend = false;
    m_last_setup_dir = NRFX_USBD_EPOUT0;

    const nrfx_usbd_evt_t evt = {
            .type = NRFX_USBD_EVT_RESET
    };

    m_event_handler(&evt);
}

static void ev_started_handler(void)
{
#if NRFX_USBD_STARTED_EV_ENABLE
    // Handler not used by the stack.
    // May be used for debugging.
#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 nrfx_usbd_ep_t ep = NRFX_USBD_EPIN0;
    NRFX_LOG_DEBUG("USB event: DMA ready IN0");
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Clear transfer information just in case */
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else if (p_state->handler.feeder == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_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(nrfx_usbd_ep_t ep)
{
    NRFX_LOG_DEBUG("USB event: DMA ready IN: %x", ep);
    NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep));
    NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep));
    NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Clear transfer information just in case */
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else if (p_state->handler.feeder == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else
    {
        /* Nothing to do */
    }
}

/**
 * @brief Handler for EasyDMA event from in isochronous endpoint.
 */
static inline void nrf_usbd_epiniso_dma_handler(nrfx_usbd_ep_t ep)
{
    if (NRFX_USBD_ISO_DEBUG)
    {
        NRFX_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep);
    }
    NRFX_ASSERT(NRF_USBD_EPIN_CHECK(ep));
    NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep));
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Clear transfer information just in case */
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else if (p_state->handler.feeder == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_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 */
        NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_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 nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT0;
    NRFX_LOG_DEBUG("USB event: DMA ready OUT0");
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Clear transfer information just in case */
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else if (p_state->handler.consumer == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_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 */
        NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
        m_event_handler(&evt);
    }
    else
    {
        nrfx_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(nrfx_usbd_ep_t ep)
{
    NRFX_LOG_DEBUG("DMA ready OUT: %x", ep);
    NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep));
    NRFX_ASSERT(!NRF_USBD_EPISO_CHECK(ep));
    NRFX_ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Clear transfer information just in case */
        (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
    }
    else if (p_state->handler.consumer == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_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 */
        NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
        m_event_handler(&evt);
    }
    else
    {
        /* Nothing to do */
    }

#if NRFX_USBD_EARLY_DMA_PROCESS
    /* Speed up */
    usbd_dmareq_process();
#endif
}

/**
 * @brief Handler for EasyDMA event from out isochronous endpoint.
 */
static inline void nrf_usbd_epoutiso_dma_handler(nrfx_usbd_ep_t ep)
{
    if (NRFX_USBD_ISO_DEBUG)
    {
        NRFX_LOG_DEBUG("DMA ready ISOOUT: %x", ep);
    }
    NRFX_ASSERT(NRF_USBD_EPISO_CHECK(ep));
    usbd_dma_pending_clear();

    usbd_ep_state_t * p_state = ep_state_access(ep);
    if (NRFX_USBD_EP_ABORTED == p_state->status)
    {
        /* Nothing to do - just ignore */
    }
    else if (p_state->handler.consumer == NULL)
    {
        (void)(NRFX_ATOMIC_FETCH_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 */
        NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_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(NRFX_USBD_EPIN1 ); }
static void ev_dma_epin2_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN2 ); }
static void ev_dma_epin3_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN3 ); }
static void ev_dma_epin4_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN4 ); }
static void ev_dma_epin5_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN5 ); }
static void ev_dma_epin6_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN6 ); }
static void ev_dma_epin7_handler(void)  { nrf_usbd_epin_dma_handler(NRFX_USBD_EPIN7 ); }
static void ev_dma_epin8_handler(void)  { nrf_usbd_epiniso_dma_handler(NRFX_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(NRFX_USBD_EPOUT1); }
static void ev_dma_epout2_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT2); }
static void ev_dma_epout3_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT3); }
static void ev_dma_epout4_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT4); }
static void ev_dma_epout5_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT5); }
static void ev_dma_epout6_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT6); }
static void ev_dma_epout7_handler(void) { nrf_usbd_epout_dma_handler(NRFX_USBD_EPOUT7); }
static void ev_dma_epout8_handler(void) { nrf_usbd_epoutiso_dma_handler(NRFX_USBD_EPOUT8); }

static void ev_sof_handler(void)
{
    nrfx_usbd_evt_t evt =  {
            NRFX_USBD_EVT_SOF,
            .data = { .sof = { .framecnt = nrf_usbd_framecntr_get() }}
    };

    /* Process isochronous endpoints */
    uint32_t iso_ready_mask = (1U << ep2bit(NRFX_USBD_EPIN8));
    if (nrf_usbd_episoout_size_get(NRFX_USBD_EPOUT8) != NRF_USBD_EPISOOUT_NO_DATA)
    {
        iso_ready_mask |= (1U << ep2bit(NRFX_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(nrfx_usbd_ep_t ep, uint8_t bitpos)
{
    NRFX_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)))
        {
            NRFX_LOG_DEBUG("USBD event: EndpointData: In finished");
            /* No more data to be send - transmission finished */
            NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OK);
            m_event_handler(&evt);
        }
    }
    else
    {
        /* OUT endpoint (Host -> Device) */
        if (0 == (m_ep_dma_waiting & (1U << bitpos)))
        {
            NRFX_LOG_DEBUG("USBD event: EndpointData: Out waiting");
            /* No buffer prepared - send event to the application */
            NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_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)
{
    NRFX_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) & NRFX_USBD_EPIN_BIT_MASK))
        & (1U <<ep2bit(m_last_setup_dir)))
    {
        NRFX_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0");
        usbd_ep_abort(m_last_setup_dir);
    }

    m_last_setup_dir =
        ((bmRequestType & USBD_BMREQUESTTYPE_DIRECTION_Msk) == 
         (USBD_BMREQUESTTYPE_DIRECTION_HostToDevice << USBD_BMREQUESTTYPE_DIRECTION_Pos)) ?
        NRFX_USBD_EPOUT0 : NRFX_USBD_EPIN0;

    (void)(NRFX_ATOMIC_FETCH_AND(
        &m_ep_dma_waiting,
        ~((1U << ep2bit(NRFX_USBD_EPOUT0)) | (1U << ep2bit(NRFX_USBD_EPIN0)))));
    m_ep_ready |= 1U << ep2bit(NRFX_USBD_EPIN0);


    const nrfx_usbd_evt_t evt = {
            .type = NRFX_USBD_EVT_SETUP
    };
    m_event_handler(&evt);
}

static void ev_usbevent_handler(void)
{
    uint32_t event = nrf_usbd_eventcause_get_and_clear();

    if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK)
    {
        NRFX_LOG_DEBUG("USBD event: ISOOUTCRC");
        /* Currently no support */
    }
    if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK)
    {
        NRFX_LOG_DEBUG("USBD event: SUSPEND");
        m_bus_suspend = true;
        const nrfx_usbd_evt_t evt = {
                .type = NRFX_USBD_EVT_SUSPEND
        };
        m_event_handler(&evt);
    }
    if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK)
    {
        NRFX_LOG_DEBUG("USBD event: RESUME");
        m_bus_suspend = false;
        const nrfx_usbd_evt_t evt = {
                .type = NRFX_USBD_EVT_RESUME
        };
        m_event_handler(&evt);
    }
    if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK)
    {
        NRFX_LOG_DEBUG("USBD event: WUREQ (%s)", m_bus_suspend ? "In Suspend" : "Active");
        if (m_bus_suspend)
        {
            NRFX_ASSERT(!nrf_usbd_lowpower_check());
            m_bus_suspend = false;

            nrf_usbd_dpdmvalue_set(NRF_USBD_DPDMVALUE_RESUME);
            nrf_usbd_task_trigger(NRF_USBD_TASK_DRIVEDPDM);

            const nrfx_usbd_evt_t evt = {
                    .type = NRFX_USBD_EVT_WUREQ
            };
            m_event_handler(&evt);
        }
    }
}

static void ev_epdata_handler(void)
{
    /* Get all endpoints that have acknowledged transfer */
    uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear();
    if (nrfx_usbd_errata_104())
    {
        dataepstatus |= (m_simulated_dataepstatus &
            ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0)));
        m_simulated_dataepstatus &=
             ((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0));
    }
    NRFX_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus);

    /* All finished endpoint have to be marked as busy */
    while (dataepstatus)
    {
        uint8_t bitpos    = __CLZ(__RBIT(dataepstatus));
        nrfx_usbd_ep_t ep = bit2ep(bitpos);
        dataepstatus &= ~(1UL << bitpos);

        (void)(usbd_ep_data_handler(ep, bitpos));
    }
    if (NRFX_USBD_EARLY_DMA_PROCESS)
    {
        /* Speed up */
        usbd_dmareq_process();
    }
}

/**
 * @brief Function to select the endpoint to start.
 *
 * Function that realizes algorithm to schedule right channel for EasyDMA transfer.
 * It gets a variable with flags for the endpoints currently requiring transfer.
 *
 * @param[in] req Bit flags for channels currently requiring transfer.
 *                Bits 0...8 used for IN endpoints.
 *                Bits 16...24 used for OUT endpoints.
 * @note
 * This function would be never called with 0 as a @c req argument.
 * @return The bit number of the endpoint that should be processed now.
 */
static uint8_t usbd_dma_scheduler_algorithm(uint32_t req)
{
    /* Only prioritized scheduling mode is supported. */
    return __CLZ(__RBIT(req));
}

/**
 * @brief Get the size of isochronous endpoint.
 *
 * The size of isochronous endpoint is configurable.
 * This function returns the size of isochronous buffer taking into account
 * current configuration.
 *
 * @param[in] ep Endpoint number.
 *
 * @return The size of endpoint buffer.
 */
static inline size_t usbd_ep_iso_capacity(nrfx_usbd_ep_t ep)
{
    (void)ep;
    nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get();
    if (NRF_USBD_ISOSPLIT_HALF == split)
    {
        return NRFX_USBD_ISOSIZE / 2;
    }
    return NRFX_USBD_ISOSIZE;
}

/**
 * @brief Process all DMA requests.
 *
 * Function that have to be called from USBD interrupt handler.
 * It have to be called when all the interrupts connected with endpoints transfer
 * and DMA transfer are already handled.
 */
static void usbd_dmareq_process(void)
{
    if (!m_dma_pending)
    {
        uint32_t req;
        while (0 != (req = m_ep_dma_waiting & m_ep_ready))
        {
            uint8_t pos;
            if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST && ((req & USBD_EPISO_BIT_MASK) != 0))
            {
                pos = usbd_dma_scheduler_algorithm(req & USBD_EPISO_BIT_MASK);
            }
            else
            {
                pos = usbd_dma_scheduler_algorithm(req);
            }
            nrfx_usbd_ep_t ep = bit2ep(pos);
            usbd_ep_state_t * p_state = ep_state_access(ep);

            nrfx_usbd_ep_transfer_t transfer;
            bool continue_transfer;

            NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) ==
                offsetof(usbd_ep_state_t, handler.consumer));
            NRFX_ASSERT((p_state->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 = nrfx_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 */
                    NRFX_ASSERT(transfer.size == 0);
                }
                else if (transfer.size < rx_size)
                {
                    NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
                    p_state->status = NRFX_USBD_EP_OVERLOAD;
                    (void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << pos)));
                    NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_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 */
                    NRFX_ASSERT(transfer.size == rx_size);
                }

                if (!continue_transfer)
                {
                    p_state->handler.consumer = NULL;
                }
            }

            usbd_dma_pending_set();
            m_ep_ready &= ~(1U << pos);
            if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
            {
                NRFX_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.addr, (uint32_t)transfer.size);

            if (nrfx_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);
                        nrfx_systick_delay_us(2);
                        ++cnt;
                    }while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED));
                    if (cnt)
                    {
                        NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   DMA restarted: %u times", cnt);
                    }

                    nrfx_systick_delay_us(30);
                    while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474))))
                    {
                        nrfx_systick_delay_us(2);
                    }
                    nrfx_systick_delay_us(1);

                    ++cnt_end;
                } while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)));
                if (cnt_end)
                {
                    NRFX_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(nrfx_usbd_ep_to_endevent(ep)))
                {
                    /* Empty */
                }
            }

            if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
            {
                NRFX_LOG_DEBUG("USB DMA process - finishing");
            }
            /* Transfer started - exit the loop */
            break;
        }
    }
    else
    {
        if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
        {
            NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy");
        }
    }
}
/** @} */

/**
 * @brief USBD interrupt service routines.
 *
 */
static const nrfx_irq_handler_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 nrfx_usbd_irq_handler(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 (nrfx_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) << NRFX_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));
                NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   uii: 0x%.2x (0x%.2x)", uii, rb);
                (void)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) << NRFX_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));
                NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   uoi: 0x%.2u (0x%.2x)", uoi, rb);
                (void)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));
                NRFX_USBD_LOG_PROTO1_FIX_PRINTF("   usbi: 0x%.2u (0x%.2x)", usbi, rb);
                (void)rb;
            }

            if (0 != (m_simulated_dataepstatus &
                ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0))))
            {
                active |= enabled & NRF_USBD_INT_DATAEP_MASK;
            }
            if (0 != (m_simulated_dataepstatus &
                ((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_USBD_EPIN_BITPOS_0))))
            {
                if (0 != (enabled & NRF_USBD_INT_EP0DATADONE_MASK))
                {
                    m_simulated_dataepstatus &=
                        ~((1U << NRFX_USBD_EPOUT_BITPOS_0) | (1U << NRFX_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]();
    }
}

/** @} */
/** @} */

nrfx_err_t nrfx_usbd_init(nrfx_usbd_event_handler_t event_handler)
{
    NRFX_ASSERT(event_handler);

    if (m_drv_state != NRFX_DRV_STATE_UNINITIALIZED)
    {
        return NRFX_ERROR_INVALID_STATE;
    }

    m_event_handler = event_handler;
    m_drv_state = NRFX_DRV_STATE_INITIALIZED;

    uint8_t n;
    for (n = 0; n < NRF_USBD_EPIN_CNT; ++n)
    {
        nrfx_usbd_ep_t ep = NRFX_USBD_EPIN(n);
        nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
            (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
        usbd_ep_state_t * p_state = ep_state_access(ep);
        p_state->status = NRFX_USBD_EP_OK;
        p_state->handler.feeder = NULL;
        p_state->transfer_cnt = 0;
    }
    for (n = 0; n < NRF_USBD_EPOUT_CNT; ++n)
    {
        nrfx_usbd_ep_t ep = NRFX_USBD_EPOUT(n);
        nrfx_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
            (NRFX_USBD_ISOSIZE / 2) : NRFX_USBD_EPSIZE);
        usbd_ep_state_t * p_state = ep_state_access(ep);
        p_state->status = NRFX_USBD_EP_OK;
        p_state->handler.consumer = NULL;
        p_state->transfer_cnt = 0;
    }

    return NRFX_SUCCESS;
}

void nrfx_usbd_uninit(void)
{
    NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);

    m_event_handler = NULL;
    m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
    return;
}

void nrfx_usbd_enable(void)
{
    NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);

    /* Prepare for READY event receiving */
    nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);

    if (nrfx_usbd_errata_187())
    {
        NRFX_CRITICAL_SECTION_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;
        }
        NRFX_CRITICAL_SECTION_EXIT();
    }
    
    if (nrfx_usbd_errata_171())
    {
        NRFX_CRITICAL_SECTION_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;
        }
        NRFX_CRITICAL_SECTION_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 (nrfx_usbd_errata_171())
    {
        NRFX_CRITICAL_SECTION_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;
        }

        NRFX_CRITICAL_SECTION_EXIT();
    }

    if (nrfx_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 (NRFX_USBD_CONFIG_ISO_IN_ZLP)
    {
        nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_ZERODATA);
    }
    else
    {
        nrfx_usbd_isoinconfig_set(NRF_USBD_ISOINCONFIG_NORESP);
    }

    m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << NRFX_USBD_EPIN_BITPOS_0);
    m_ep_dma_waiting = 0;
    usbd_dma_pending_clear();
    m_last_setup_dir = NRFX_USBD_EPOUT0;

    m_drv_state = NRFX_DRV_STATE_POWERED_ON;

    if (nrfx_usbd_errata_187())
    {
        NRFX_CRITICAL_SECTION_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;
        }
        NRFX_CRITICAL_SECTION_EXIT();
    }
}

void nrfx_usbd_disable(void)
{
    NRFX_ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);

    /* Stop just in case */
    nrfx_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;
}

void nrfx_usbd_start(bool enable_sof)
{
    NRFX_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 || nrfx_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, NRFX_USBD_CONFIG_IRQ_PRIORITY);
   NRFX_IRQ_ENABLE(USBD_IRQn);

   /* Enable pullups */
   nrf_usbd_pullup_enable();
}

void nrfx_usbd_stop(void)
{
    NRFX_ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);

    /* Clear interrupt */
    NRFX_IRQ_PENDING_CLEAR(USBD_IRQn);

    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 nrfx_usbd_is_initialized(void)
{
    return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED);
}

bool nrfx_usbd_is_enabled(void)
{
    return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON);
}

bool nrfx_usbd_is_started(void)
{
    return (nrfx_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn));
}

bool nrfx_usbd_suspend(void)
{
    bool suspended = false;

    NRFX_CRITICAL_SECTION_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;
            }
        }
    }
    NRFX_CRITICAL_SECTION_EXIT();

    return suspended;
}

bool nrfx_usbd_wakeup_req(void)
{
    bool started = false;

    NRFX_CRITICAL_SECTION_ENTER();
    if (m_bus_suspend && nrf_usbd_lowpower_check())
    {
        nrf_usbd_lowpower_disable();
        started = true;

        if (nrfx_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;
            }

        }
    }
    NRFX_CRITICAL_SECTION_EXIT();

    return started;
}

bool nrfx_usbd_suspend_check(void)
{
    return nrf_usbd_lowpower_check();
}

void nrfx_usbd_suspend_irq_config(void)
{
    nrf_usbd_int_disable(m_irq_disabled_in_suspend);
}

void nrfx_usbd_active_irq_config(void)
{
    nrf_usbd_int_enable(m_irq_disabled_in_suspend);
}

bool nrfx_usbd_bus_suspend_check(void)
{
    return m_bus_suspend;
}

void nrfx_usbd_force_bus_wakeup(void)
{
    m_bus_suspend = false;
}

void nrfx_usbd_ep_max_packet_size_set(nrfx_usbd_ep_t ep, uint16_t size)
{
    /* Only power of 2 size allowed */
    NRFX_ASSERT((size != 0) && (size & (size - 1)) == 0);
    /* Packet size cannot be higher than maximum buffer size */
    NRFX_ASSERT((NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) ||
                (!NRF_USBD_EPISO_CHECK(ep) && (size <= NRFX_USBD_EPSIZE)));

    usbd_ep_state_t * p_state = ep_state_access(ep);
    p_state->max_packet_size = size;
}

uint16_t nrfx_usbd_ep_max_packet_size_get(nrfx_usbd_ep_t ep)
{
    usbd_ep_state_t const * p_state = ep_state_access(ep);
    return p_state->max_packet_size;
}

bool nrfx_usbd_ep_enable_check(nrfx_usbd_ep_t ep)
{
    return nrf_usbd_ep_enable_check(ep_to_hal(ep));
}

void nrfx_usbd_ep_enable(nrfx_usbd_ep_t ep)
{
    nrf_usbd_int_enable(nrfx_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))
    {
        NRFX_CRITICAL_SECTION_ENTER();
        nrfx_usbd_transfer_out_drop(ep);
        m_ep_dma_waiting &= ~(1U << ep2bit(ep));
        NRFX_CRITICAL_SECTION_EXIT();
    }
}

void nrfx_usbd_ep_disable(nrfx_usbd_ep_t ep)
{
    usbd_ep_abort(ep);
    nrf_usbd_ep_disable(ep_to_hal(ep));
    nrf_usbd_int_disable(nrfx_usbd_ep_to_int(ep));
}

void nrfx_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();
}

nrfx_err_t nrfx_usbd_ep_transfer(
    nrfx_usbd_ep_t               ep,
    nrfx_usbd_transfer_t const * p_transfer)
{
    nrfx_err_t ret;
    const uint8_t ep_bitpos = ep2bit(ep);
    NRFX_ASSERT(NULL != p_transfer);

    NRFX_CRITICAL_SECTION_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 = NRFX_ERROR_INVALID_ADDR;
        if (NRFX_USBD_FAILED_TRANSFERS_DEBUG &&
            (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
        {
            NRFX_LOG_DEBUG("Transfer failed: Invalid EPr\n");
        }
    }
    else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
    {
        /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */
        ret = NRFX_ERROR_BUSY;
        if (NRFX_USBD_FAILED_TRANSFERS_DEBUG)
        {
            NRFX_LOG_DEBUG("Transfer failed: EP is busy");
        }
    }
    else
    {
        usbd_ep_state_t * p_state =  ep_state_access(ep);
        /* Prepare transfer context and handler description */
        nrfx_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 & NRFX_USBD_TRANSFER_ZLP_FLAG))
                {
                    p_state->handler.feeder = nrfx_usbd_feeder_ram;
                    if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
                    {
                        NRFX_LOG_DEBUG(
                            "Transfer called on endpoint %x, size: %u, mode: "
                            "RAM",
                            ep,
                            p_transfer->size);
                    }
                }
                else
                {
                    p_state->handler.feeder = nrfx_usbd_feeder_ram_zlp;
                    if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
                    {
                        NRFX_LOG_DEBUG(
                            "Transfer called on endpoint %x, size: %u, mode: "
                            "RAM_ZLP",
                            ep,
                            p_transfer->size);
                    }
                }
            }
            else
            {
                /* Flash */
                if (0 == (p_transfer->flags & NRFX_USBD_TRANSFER_ZLP_FLAG))
                {
                    p_state->handler.feeder = nrfx_usbd_feeder_flash;
                    if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
                    {
                        NRFX_LOG_DEBUG(
                            "Transfer called on endpoint %x, size: %u, mode: "
                            "FLASH",
                            ep,
                            p_transfer->size);
                    }
                }
                else
                {
                    p_state->handler.feeder = nrfx_usbd_feeder_flash_zlp;
                    if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
                    {
                        NRFX_LOG_DEBUG(
                            "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);
            NRFX_ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx)));
            p_state->handler.consumer = nrfx_usbd_consumer;
        }
        *p_context = *p_transfer;
        p_state->p_context = p_context;

        p_state->transfer_cnt = 0;
        p_state->status    =  NRFX_USBD_EP_OK;
        m_ep_dma_waiting   |= 1U << ep_bitpos;
        ret = NRFX_SUCCESS;
        usbd_int_rise();
    }
    NRFX_CRITICAL_SECTION_EXIT();
    return ret;
}

nrfx_err_t nrfx_usbd_ep_handled_transfer(
    nrfx_usbd_ep_t                   ep,
    nrfx_usbd_handler_desc_t const * p_handler)
{
    nrfx_err_t ret;
    const uint8_t ep_bitpos = ep2bit(ep);
    NRFX_ASSERT(NULL != p_handler);

    NRFX_CRITICAL_SECTION_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 = NRFX_ERROR_INVALID_ADDR;
        if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
        {
            NRFX_LOG_DEBUG("Transfer failed: Invalid EP");
        }
    }
    else if ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
    {
        /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */
        ret = NRFX_ERROR_BUSY;
        if (NRFX_USBD_FAILED_TRANSFERS_DEBUG && (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
        {
            NRFX_LOG_DEBUG("Transfer failed: EP is busy");
        }
    }
    else
    {
        /* Transfer can be configured now */
        usbd_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    =  NRFX_USBD_EP_OK;
        m_ep_dma_waiting   |= 1U << ep_bitpos;

        ret = NRFX_SUCCESS;
        if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
        {
            NRFX_LOG_DEBUG("Transfer called on endpoint %x, mode: Handler", ep);
        }
        usbd_int_rise();
    }
    NRFX_CRITICAL_SECTION_EXIT();
    return ret;
}

void * nrfx_usbd_feeder_buffer_get(void)
{
    return m_tx_buffer;
}

nrfx_usbd_ep_status_t nrfx_usbd_ep_status_get(nrfx_usbd_ep_t ep, size_t * p_size)
{
    nrfx_usbd_ep_status_t ret;

    usbd_ep_state_t const * p_state = ep_state_access(ep);
    NRFX_CRITICAL_SECTION_ENTER();
    *p_size = p_state->transfer_cnt;
    ret = (p_state->handler.consumer == NULL) ? p_state->status : NRFX_USBD_EP_BUSY;
    NRFX_CRITICAL_SECTION_EXIT();
    return ret;
}

size_t nrfx_usbd_epout_size_get(nrfx_usbd_ep_t ep)
{
    return nrf_usbd_epout_size_get(ep_to_hal(ep));
}

bool nrfx_usbd_ep_is_busy(nrfx_usbd_ep_t ep)
{
    return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & NRFX_USBD_EPIN_BIT_MASK)) & (1U << ep2bit(ep))));
}

void nrfx_usbd_ep_stall(nrfx_usbd_ep_t ep)
{
    NRFX_LOG_DEBUG("USB: EP %x stalled.", ep);
    nrf_usbd_ep_stall(ep_to_hal(ep));
}

void nrfx_usbd_ep_stall_clear(nrfx_usbd_ep_t ep)
{
    if (NRF_USBD_EPOUT_CHECK(ep) && nrfx_usbd_ep_stall_check(ep))
    {
        nrfx_usbd_transfer_out_drop(ep);
    }
    nrf_usbd_ep_unstall(ep_to_hal(ep));
}

bool nrfx_usbd_ep_stall_check(nrfx_usbd_ep_t ep)
{
    return nrf_usbd_ep_is_stall(ep_to_hal(ep));
}

void nrfx_usbd_ep_dtoggle_clear(nrfx_usbd_ep_t ep)
{
    nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_DATA0);
}

void nrfx_usbd_setup_get(nrfx_usbd_setup_t * p_setup)
{
    memset(p_setup, 0, sizeof(nrfx_usbd_setup_t));
    p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get();
    p_setup->bRequest      = 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 nrfx_usbd_setup_data_clear(void)
{
    if (nrfx_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 nrfx_usbd_setup_clear(void)
{
    NRFX_LOG_DEBUG(">> ep0status >>");
    nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
}

void nrfx_usbd_setup_stall(void)
{
    NRFX_LOG_DEBUG("Setup stalled.");
    nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL);
}

nrfx_usbd_ep_t nrfx_usbd_last_setup_dir_get(void)
{
    return m_last_setup_dir;
}

void nrfx_usbd_transfer_out_drop(nrfx_usbd_ep_t ep)
{
    NRFX_ASSERT(NRF_USBD_EPOUT_CHECK(ep));

    if (nrfx_usbd_errata_200())
    {
        NRFX_CRITICAL_SECTION_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;
        (void)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
        NRFX_CRITICAL_SECTION_EXIT();
    }
    else
    {
        NRFX_CRITICAL_SECTION_ENTER();
        m_ep_ready &= ~(1U << ep2bit(ep));
        if (!NRF_USBD_EPISO_CHECK(ep))
        {
            nrf_usbd_epout_clear(ep);
        }
        NRFX_CRITICAL_SECTION_EXIT();
    }
}

#endif // NRFX_CHECK(NRFX_USBD_ENABLED)
