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; }
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])); } } } }