hello,
We have a project that uses sound for distance measurement.
When I upgraded from NCSv3.0.0 to NCSv3.2.1, I encountered a problem where the i2s function stopped working.
The following is the driver code for NCSv3.0.0.Can be used normally.
Main process: i2s_init()--->Enable the register clock---->enable PA---->k_sleep(250)---->start_i2s()---->handle---->set_next_buf()--->handle---->set_next_buf() .... --->stop_i2s()
Since this sound is an ultrasonic wave, when played directly, there will be a "pop" sound. Therefore, I need to first turn on the i2s clock and reduce this "pop" sound.
#define I2S_DATA_BLOCK_WORDS 192
static void i2s_comp_handler(nrfx_i2s_buffers_t const *released_bufs, uint32_t status)
{
if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED)) {
// printk("i2s No buffer stop : %d\n", status);
return;
}
uint32_t *next_tx_buf = NULL;
if (released_bufs->p_tx_buffer == m_buffer_tx[0]) {
next_tx_buf = m_buffer_tx[0];
} else if (released_bufs->p_tx_buffer == m_buffer_tx[1]) {
next_tx_buf = m_buffer_tx[1];
}
if(!released_bufs->p_tx_buffer) {
next_tx_buf = m_buffer_tx[1];
}
current_buf += 1;
//Put the data from bpsk_tata into m_buffer_tx[0] or m_buffer_tx[1]
singleGetAudioDataToTxBuf(bpsk_tata, m_buffer_tx[0], m_buffer_tx[1], current_buf);
const nrfx_i2s_buffers_t next_buffers = {
.p_rx_buffer = NULL,
.p_tx_buffer = next_tx_buf,
.buffer_size = I2S_DATA_BLOCK_WORDS,
};
(void)nrfx_i2s_next_buffers_set(&i2s_inst, &next_buffers);
}
void audio_i2s_init(void)
{
int ret;
ret = pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(I2S_NL), PINCTRL_STATE_DEFAULT);
if (ret != 0) {
printk("Failed to apply pinctrl state: %d\n", ret);
return;
}
IRQ_CONNECT(DT_IRQN(I2S_NL), DT_IRQ(I2S_NL, priority), nrfx_isr, nrfx_i2s_20_irq_handler, 0);
irq_enable(DT_IRQN(I2S_NL));
ret = nrfx_i2s_init(&i2s_inst, &cfg, i2s_comp_handler);
if (ret != 0) {
printk("Failed to initialize I2S: %d\n", ret);
return;
}
printk("i2s initialize (%d)\r\n",ret);
}
void i2s_codec_thread(void)
{
audio_i2s_init();
for (;;) {
k_sem_take(&i2s_sync_sem, K_FOREVER);
NRF_I2S20->ENABLE = 1; // First, turn on the clock stabilization PA
NRF_I2S20->TASKS_START = 1;
pf_gpio_write(GPIO_PA, 1);
k_sleep(K_MSEC(250));
current_buf += 1;
//Put the data from bpsk_tata into m_buffer_tx[0]
singleGetAudioDataToTxBuf(bpsk_tata, m_buffer_tx[0], m_buffer_tx[1], current_buf);
const nrfx_i2s_buffers_t initial_buffers = {
.p_rx_buffer = NULL,
.p_tx_buffer = m_buffer_tx[0],
.buffer_size = (I2S_DATA_BLOCK_WORDS)};
// Send real data
ret = nrfx_i2s_start(&i2s_inst, &initial_buffers, 0);
if (ret != 0) {
printk("Failed to start I2S: %d\n", ret);
}
do
{
__WFE();
__SEV();
__WFE();
} while (current_buf < BLOCKS_TO_TRANSFER);
nrfx_i2s_stop(&i2s_inst);
}
}
When upgrading to NCSv3.2.1,Performing this operation will cause the system to crash.
The cause of the system crash:call (void)nrfx_i2s_next_buffers_set(&i2s_inst, &next_buffers);
ASSERTION FAIL [p_cb->state == NRFX_DRV_STATE_POWERED_ON] @ WEST_TOPDIR/modules/hal/nordic/nrfx/drivers/src/nrfx_i2s.c:385
At this moment p_cb->state=1
I tried to stop manipulating the registers. Instead, I played a silent segment first and then switched to the actual data. This way, the system no longer crashed. However, this had an impact on the accuracy of my distance measurement.
I hope that the NCSv3.2.1 version can solve my problem.
Look forward to your reply!
Thanks