i2S is gave after 1 to 6 index transmission get error code 11 why this happen ??

/*
 * Copyright 2023 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2s.h>
#include <zephyr/drivers/gpio.h>
#include <stdio.h>
#include "codec_header.h"



#define SAMPLE_NO   64
#define CHANNELS    2
#define NUM_BLOCKS  4


/* BLOCK_SIZE in bytes */
#define BLOCK_SIZE (CHANNELS * SAMPLE_NO * sizeof(int16_t))

const struct device *dev_i2s = DEVICE_DT_GET(DT_NODELABEL(i2s20));

/* Stereo interleaved buffers */
static int16_t tx_block[NUM_BLOCKS][CHANNELS * SAMPLE_NO];



/* Sine wave table */
static const int16_t sine[SAMPLE_NO] = {
     3211,  6392,  9511, 12539, 15446, 18204, 20787, 23169,
    25329, 27244, 28897, 30272, 31356, 32137, 32609, 32767,
    32609, 32137, 31356, 30272, 28897, 27244, 25329, 23169,
    20787, 18204, 15446, 12539,  9511,  6392,  3211,     0,
    -3212, -6393, -9512,-12540,-15447,-18205,-20788,-23170,
   -25330,-27245,-28898,-30273,-31357,-32138,-32610,-32767,
   -32610,-32138,-31357,-30273,-28898,-27245,-25330,-23170,
   -20788,-18205,-15447,-12540, -9512, -6393, -3212,    -1
};





static void fill_buf(int16_t *buf, int shift)
{
    for (int i = 0; i < SAMPLE_NO; i++) {
        buf[2 * i]     = sine[i] >> shift;                 /* Left */
        buf[2 * i + 1] = sine[(i + SAMPLE_NO / 4) % SAMPLE_NO] >> shift; /* Right */
    }
}

int main(void)
{
    struct i2s_config i2s_cfg;
    int ret;

    printk("=== System start ===\n");

   // POWER-UP DELAY
    k_msleep(300);
    // provide mclk clock
    //mclk_timer();

    // INIT I2C
    ret = i2c_init_codec();
    if (ret)
    {
        printk("Codec I2C init failed (%d). STOP.\n", ret);
        while (1)
        {
            k_sleep(K_FOREVER);
        }
    }
    printk("Codec I2C init OK\n");

    // CHECK I2S DEVICE
    if (!device_is_ready(dev_i2s)) {
        printk("I2S device not ready\n");
        return -ENODEV;
    }

    // CONFIGURE I2S
    memset(&i2s_cfg, 0, sizeof(i2s_cfg));

    i2s_cfg.word_size = 16;
    i2s_cfg.channels = CHANNELS;
    i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
    i2s_cfg.frame_clk_freq = 8000;
    i2s_cfg.block_size = BLOCK_SIZE;
    i2s_cfg.timeout =1000;
    i2s_cfg.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER;

    ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg);
    if (ret)
    {
        printk("I2S configure failed (%d)\n", ret);
        return ret;
    }

    printk("I2S configured.........\n");

    // PREPARE AUDIO BUFFERS
    for (int i = 0; i < NUM_BLOCKS; i++)
    {
        fill_buf(tx_block[i], i % 3);
    }

    // QUEUE BUFFERS BEFORE START
    ret = i2s_write(dev_i2s, tx_block[0], BLOCK_SIZE);

    ret |= i2s_write(dev_i2s, tx_block[1], BLOCK_SIZE);

    if (ret)
    {
        printk("I2S write failed (%d)\n", ret);
        return ret;
    }

    printk("Initial TX buffers queued\n");

    // NOW START I2S -lrck
    ret = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_START);
    if (ret)
    {
        printk("I2S start failed (%d)\n", ret);
        return ret;
    }

    printk("I2S started successfully\n");

 // remaining buffer
    int idx = 2;
    while (1)
    {
        ret = i2s_write(dev_i2s, tx_block[idx % NUM_BLOCKS], BLOCK_SIZE);
       // ret = i2s_write(dev_i2s, tx_block[idx % NUM_BLOCKS], BLOCK_SIZE);
        if (ret == 0)
        {
            idx++;
            k_msleep(1);
        }
        else if (ret == -EAGAIN)
        {
            i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
            i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_START);
            k_msleep(2);
        }
        else
        {
            printk("I2S write error (%d)\n", ret);
            break;
        }
    }
   printk("i2s_write.............");
    return 0;
}


 ovelay file 

&pinctrl {
    i2c21_default: i2c22_default {
        group1 {
            psels =
                    <NRF_PSEL(TWIM_SCL, 1, 12)>,
                    <NRF_PSEL(TWIM_SDA, 1, 13)>;
                    bias-pull-up;
                   
        };
    };

    i2c21_sleep: i2c22_sleep {
        group1 {
            psels = <NRF_PSEL(TWIM_SCL, 1,12)>,
                    <NRF_PSEL(TWIM_SDA, 1, 13)>;
                    low-power-enable;
        };
    };

    i2s20_default: i2s20_default {
        group1 {
            psels = <NRF_PSEL(I2S_SDIN, 1, 6)>, <NRF_PSEL(I2S_SCK_S, 1, 3)>;
        };
    };

    i2s20_sleep: i2s20_sleep {
        group1 {
            psels = <NRF_PSEL(I2S_SDIN, 1, 6)>,
                    <NRF_PSEL(I2S_SDOUT, 1, 5)>,
                    <NRF_PSEL(I2S_SCK_S, 1, 3)>,
                    <NRF_PSEL(I2S_MCK, 1, 4)>,
                    <NRF_PSEL(I2S_LRCK_M, 1, 14)>;
        };
    };


};

&i2c21 {
    status = "disabled";
    pinctrl-0 = <&i2c22_default>;
    pinctrl-1 = <&i2c22_sleep>;
    pinctrl-names = "default", "sleep";

    audiocodec: audiocodec@18 {
        compatible = "i2c-device";
        status = "okay";
        reg = < 0x18 >;
    };
};

&i2s20 {
    status = "okay";
    pinctrl-0 = <&i2s20_default>;
    pinctrl-1 = <&i2s20_sleep>;
    pinctrl-names = "default", "sleep";
};



/ {
     custom_pins{
        compatible = "gpio-keys";

        codec_reset: codec-reset-node {
            gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
            label = "Codec Reset Pin";
        };
    };
};



&i2c21 {
    status = "okay";
};

/ {
    button0: button_0 {
        compatible = "gpio-keys";
        button0_key: button0_key {
            gpios = <&gpio1 15 0>;
            label = "MCUBoot Button";
        };
    };
    leds {
        compatible = "gpio-leds";

        led0: led_0 {
            gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
            label = "User LED 0";
        };
    };
   
       

};

&uart20 {
    status = "okay";
};

&uart20_default {
    group1 {
        psels = <NRF_PSEL(UART_TX, 1, 8)>, <NRF_PSEL(UART_RX, 1, 7)>;
    };
};


/delete-node/ &{/pin-controller/i2c22_default/group2/};

&i2c22 {
    status = "disabled";
};

/delete-node/ &button0;
/delete-node/ &{/pin-controller/i2s20_default/group5/};
/delete-node/ &{/pin-controller/i2s20_default/group2/};
/delete-node/ &{/pin-controller/i2s20_default/group4/};
/delete-node/ &{/pin-controller/i2s20_default/group3/};
 should i implement mclk clock seprate in code ??  
OK
[00:06:49.411,024] <inf> i2s_nrfx: I2S MCK frequency: 256000, actual PCM rate: 8000
  • external clcok is use, 4mhz generated here , after thata i2c write is prorper niw and but i2s is failed 

  • /*
     * Codec-style I2S SLAVE playback (continuous)
     * Stable design for nRF54L15 + external codec
     *
     * SPDX-License-Identifier: Apache-2.0
     */

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/i2s.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/iterable_sections.h>
    #include "codec/codec.h"

    /* ================= CONFIG ================= */

    #define I2S_NODE DT_NODELABEL(i2s20)

    /* Audio format */
    #define SAMPLE_RATE_HZ     8000
    #define SAMPLE_BIT_WIDTH   16
    #define CHANNELS           2

    /* 100 ms audio block */
    #define SAMPLES_PER_BLOCK  (SAMPLE_RATE_HZ / 10)   /* 800 frames */
    #define BYTES_PER_SAMPLE   sizeof(int16_t)
    #define BLOCK_SIZE         (SAMPLES_PER_BLOCK * CHANNELS * BYTES_PER_SAMPLE)

    /* Buffering */
    #define INIT_BLOCKS        6
    #define BLOCK_COUNT        (INIT_BLOCKS + 6)
    #define TIMEOUT_MS         2000

    /* ================= DEVICE ================= */

    static const struct device *i2s_dev = DEVICE_DT_GET(I2S_NODE);

    /* ================= SINE LUT ================= */
    /* Small lookup table – expanded into big buffers */

    static const int16_t sine_lut[] = {
         3211,  6392,  9511, 12539, 15446, 18204, 20787, 23169,
        25329, 27244, 28897, 30272, 31356, 32137, 32609, 32767,
        -3212, -6393, -9512,-12540,-15447,-18205,-20788,-23170,
       -25330,-27245,-28898,-30273,-31357,-32138,-32610,-32767
    };

    /* ================= MEM SLAB ================= */

    K_MEM_SLAB_DEFINE_IN_SECT_STATIC(
        tx_mem_slab,
        __nocache,
        BLOCK_SIZE,
        BLOCK_COUNT,
        4
    );

    /* ================= HELPERS ================= */

    static void fill_audio_block(int16_t *buf)
    {
        int lut_len = ARRAY_SIZE(sine_lut);

        for (int i = 0; i < SAMPLES_PER_BLOCK; i++) {
            int16_t s = sine_lut[i % lut_len];
            buf[2 * i]     = s;   /* Left */
            buf[2 * i + 1] = s;   /* Right */
        }
    }

    /* ================= MAIN ================= */

    int main(void)
    {
        struct i2s_config cfg;
        void *block;
        int ret;
        int queued = 0;

        printk("Codec-style I2S SLAVE (continuous)\n");

        /* Start external clocks + codec */
        ret = pwm_4mhz();
        if (ret < 0) {
            printk("MCLK start failed\n");
            return ret;
        }

        ret = i2c_init_codec();
        if (ret < 0) {
            printk("Codec init failed\n");
            return ret;
        }

        if (!device_is_ready(i2s_dev)) {
            printk("I2S device not ready\n");
            return -ENODEV;
        }

        /* -------- I2S CONFIG (SLAVE) -------- */
        cfg.word_size      = SAMPLE_BIT_WIDTH;
        cfg.channels       = CHANNELS;
        cfg.format         = I2S_FMT_DATA_FORMAT_I2S;
        cfg.options        = I2S_OPT_FRAME_CLK_SLAVE |
                             I2S_OPT_BIT_CLK_SLAVE;
        cfg.frame_clk_freq = SAMPLE_RATE_HZ;
        cfg.block_size     = BLOCK_SIZE;
        cfg.mem_slab       = &tx_mem_slab;
        cfg.timeout        = TIMEOUT_MS;

        ret = i2s_configure(i2s_dev, I2S_DIR_TX, &cfg);
        if (ret < 0)
        {
            printk("I2S configure failed: %d\n", ret);
            return ret;
        }

        /* -------- Prefill buffers BEFORE START -------- */
        for (int i = 0; i < INIT_BLOCKS; i++)
        {
            ret = k_mem_slab_alloc(&tx_mem_slab, &block, K_FOREVER);
            if (ret < 0)
            {
                printk("Slab alloc failed\n");
                return ret;
            }

            fill_audio_block((int16_t *)block);

            ret = i2s_write(i2s_dev, block, BLOCK_SIZE);
            printk("fill_audio_block %d buffers\n", (int16_t *)block);
            if (ret == -EAGAIN) {
            printk("TX queue full after %d buffers\n", queued);
            k_mem_slab_free(&tx_mem_slab, block);
            break;
        }
        if (ret < 0) {
            printk("i2s_write failed: %d\n", ret);
            return ret;
        }

        queued++;
        }

        /* -------- START ONCE -------- */
        ret = i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_START);
        if (ret < 0)
        {
            printk("I2S START failed: %d\n", ret);
            return ret;
        }

        printk("Playback running...\n");

        /* -------- Continuous refill (safe) -------- */
        // while (1) {
        //     void *released;

        //     if (i2s_buf_read(i2s_dev, &released, NULL) == 0 && released)
        //     {
        //         fill_audio_block((int16_t *)released);
        //         i2s_write(i2s_dev, released, BLOCK_SIZE);
               
         
        //     }
        // }
       while (1) {
        void *released;
        size_t size;

        int r = i2s_buf_read(i2s_dev, &released, &size);

        if (r == 0 && released) {
            printk("TX buffer completed\n");

            fill_audio_block((int16_t *)released);
            i2s_write(i2s_dev, released, BLOCK_SIZE);
        } else if (r == -EAGAIN) {
            /* No completed buffer yet – this is normal */
            k_msleep(1);
        } else {
            printk("i2s_buf_read error: %d\n", r);
            break;
        }
    }

       
    }
Related