Unable to replace the buttons with BLE webapp buttons on example "\ncs\v2.3.0\zephyr\samples\drivers\i2s\echo"

Hi, 

I'm learing how the i2s streaming works using the example "echo" under  "ncs\v2.3.0\zephyr\samples\drivers\i2s\echo". I have a prototype board with nRF5340 and the audio amplifier device "https://www.ti.com/product/TAS6584-Q1" that uses i2s for streaming and i2c for volume control. 

The echo example comes with buttons interrupts to start and stop the streams which is working. I'm trying to replace those hardware buttons with a digital buttons. I have added BLE with a custom service and characteristics. I have developed a small webapp with start and stop buttons where the characteristics is written with single byte that nRF5340 will be interrupted and process the byte (for example 1 as start and 0 as stop).

The problem is while I'm running the stream in a while loop without delay, I',m unable to receive the BLE charac write interrupts.

The main function having this for loop.

    for (;;) {
        k_sem_take(&toggle_transfer, K_FOREVER);

        if (!prepare_transfer(i2s_dev_rx, i2s_dev_tx)) {
            return;
        }

        if (!trigger_command(i2s_dev_rx, i2s_dev_tx,
                     I2S_TRIGGER_START)) {
            return;
        }

        printk("Streams started\n");

        while (k_sem_take(&toggle_transfer, K_NO_WAIT) != 0) {
            void *mem_block;
            uint32_t block_size;
            int ret;

            ret = i2s_read(i2s_dev_rx, &mem_block, &block_size);
            if (ret < 0) {
                printk("Failed to read data: %d\n", ret);
                break;
            }

            process_block_data(mem_block, SAMPLES_PER_BLOCK);

            ret = i2s_write(i2s_dev_tx, mem_block, block_size);
            if (ret < 0) {
                printk("Failed to write data: %d\n", ret);
                break;
            }
        }

        if (!trigger_command(i2s_dev_rx, i2s_dev_tx,
                     I2S_TRIGGER_DROP)) {
            return;
        }

        printk("Streams stopped\n");
    }
}

BLE write interrupts will give the semaphore.

static ssize_t writeButton(struct bt_conn *conn, const struct bt_gatt_attr *attr,
        const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
    k_sem_give(&toggle_transfer, K_FOREVER);
    return len;
}

The issue is that the code works only for starting the streaming, and unable to write a BLE characteristiscs after that. Having a small delay using k_usleep(100) will cause i2s_write function error with -5 and the debug prints says " <err> i2s_nrfx: data_handler: Next buffers not supplied on time"

Looks like the BLE characteristics can not be written while the main function is having an infinite loop with no sleep time. I have also moved the streaming logic to a workQ with lowest priority (8) and still having the same issue.

I request you to please look into my issue and suggest a work around.

Related