Example #1
0
nrfx_err_t nrfx_i2s_next_buffers_set(nrfx_i2s_buffers_t const * p_buffers)
{
    NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_POWERED_ON);
    NRFX_ASSERT(p_buffers);

    nrfx_err_t err_code;

    if (!m_cb.buffers_needed)
    {
        err_code = NRFX_ERROR_INVALID_STATE;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    if (((p_buffers->p_rx_buffer != NULL)
         && !nrfx_is_in_ram(p_buffers->p_rx_buffer))
        ||
        ((p_buffers->p_tx_buffer != NULL)
         && !nrfx_is_in_ram(p_buffers->p_tx_buffer)))
    {
        err_code = NRFX_ERROR_INVALID_ADDR;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    if (m_cb.use_tx)
    {
        NRFX_ASSERT(p_buffers->p_tx_buffer != NULL);
        nrf_i2s_tx_buffer_set(NRF_I2S, p_buffers->p_tx_buffer);
    }
    if (m_cb.use_rx)
    {
        NRFX_ASSERT(p_buffers->p_rx_buffer != NULL);
        nrf_i2s_rx_buffer_set(NRF_I2S, p_buffers->p_rx_buffer);
    }

    m_cb.next_buffers   = *p_buffers;
    m_cb.buffers_needed = false;

    return NRFX_SUCCESS;
}
Example #2
0
void I2S_IRQHandler(void)
{
    uint32_t const * p_data_received = NULL;
    uint32_t       * p_data_to_send  = NULL;

    if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD))
    {
        nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD);
        NRF_LOG_DEBUG("Event: %s.",
            (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_TXPTRUPD));

        // If transmission is not enabled, but for some reason the TXPTRUPD
        // event has been generated, just ignore it.
        if (m_cb.p_tx_buffer != NULL)
        {
            uint32_t * p_tx_buffer_next;
            if (nrf_i2s_tx_buffer_get(NRF_I2S) == m_cb.p_tx_buffer)
            {
                p_tx_buffer_next = m_cb.p_tx_buffer + m_cb.buffer_half_size;
            }
            else
            {
                p_tx_buffer_next = m_cb.p_tx_buffer;
            }
            nrf_i2s_tx_buffer_set(NRF_I2S, p_tx_buffer_next);

            m_cb.tx_ready = true;

            // Now the part of the buffer that we've configured as "next" should
            // be filled by the application with proper data to be sent;
            // the peripheral is sending data from the other part of the buffer
            // (but it will finish soon...).
            p_data_to_send = p_tx_buffer_next;

        }
    }

    if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD))
    {
        nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD);
        NRF_LOG_DEBUG("Event: %s.",
            (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_RXPTRUPD));

        // If reception is not enabled, but for some reason the RXPTRUPD event
        // has been generated, just ignore it.
        if (m_cb.p_rx_buffer != NULL)
        {
            uint32_t * p_rx_buffer_next;
            if (nrf_i2s_rx_buffer_get(NRF_I2S) == m_cb.p_rx_buffer)
            {
                p_rx_buffer_next = m_cb.p_rx_buffer + m_cb.buffer_half_size;
            }
            else
            {
                p_rx_buffer_next = m_cb.p_rx_buffer;
            }
            nrf_i2s_rx_buffer_set(NRF_I2S, p_rx_buffer_next);

            m_cb.rx_ready = true;

            // The RXPTRUPD event is generated for the first time right after
            // the transfer is started. Since there is no data received yet at
            // this point we only update the buffer pointer (it is done above),
            // there is no callback to the application.
            // [for synchronized mode this has to be handled differently -
            //  see below]
            if (m_cb.just_started && !m_cb.synchronized_mode)
            {
                m_cb.just_started = false;
            }
            else
            {
                // The RXPTRUPD event indicates that from now on the peripheral
                // will be filling the part of the buffer that was pointed at
                // the time the event has been generated, hence now we can let
                // the application process the data stored in the other part of
                // the buffer - the one that we've just set to be filled next.
                p_data_received = p_rx_buffer_next;
            }
        }
    }

    // Call the data handler passing received data to the application and/or
    // requesting data to be sent.
    if (!m_cb.synchronized_mode)
    {
        if ((p_data_received != NULL) || (p_data_to_send != NULL))
        {
            if (p_data_received != NULL)
            {
                NRF_LOG_DEBUG("Rx data:");
                NRF_LOG_HEXDUMP_DEBUG(p_data_received,
                    m_cb.buffer_half_size * sizeof(p_data_received[0]));
            }
            m_cb.handler(p_data_received, p_data_to_send,
                m_cb.buffer_half_size);
            if (p_data_to_send != NULL)
            {
                NRF_LOG_DEBUG("Tx data:");
                NRF_LOG_HEXDUMP_DEBUG(p_data_to_send,
                    m_cb.buffer_half_size * sizeof(p_data_to_send[0]));
            }
        }
    }
    // In the synchronized mode wait until the events for both RX and TX occur.
    // And ignore the initial occurrences of these events, since they only
    // indicate that the transfer has started - no data is received yet at
    // that moment, so we have got nothing to pass to the application.
    else
    {
        if (m_cb.rx_ready && m_cb.tx_ready)
        {
            m_cb.rx_ready = false;
            m_cb.tx_ready = false;

            if (m_cb.just_started)
            {
                m_cb.just_started = false;
            }
            else
            {
                NRF_LOG_DEBUG("Rx data:");
                NRF_LOG_HEXDUMP_DEBUG(nrf_i2s_rx_buffer_get(NRF_I2S),
                    m_cb.buffer_half_size * sizeof(p_data_to_send[0]));
                m_cb.handler(nrf_i2s_rx_buffer_get(NRF_I2S),
                             nrf_i2s_tx_buffer_get(NRF_I2S),
                             m_cb.buffer_half_size);
                NRF_LOG_DEBUG("Tx data:");
                NRF_LOG_HEXDUMP_DEBUG(nrf_i2s_tx_buffer_get(NRF_I2S),
                    m_cb.buffer_half_size * sizeof(p_data_to_send[0]));
            }
        }
    }
}