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
Parents
  • Hi,

    Thanks for the updates. I think we may be mixing a few different topics, so just to make sure I understand you correctly and can help in the right direction, could we first align on one thing? Could you please confirm what you want the nRF54L15 to do for the I2S clocks:

    1. Option A:
      The nRF54L15 should generate the I2S clocks (BCLK, LRCK, and MCK), and the codec should use those clocks.
    2. Option B:
      The nRF54L15 should work as an I2S slave, and the clocks (BCLK/LRCK/MCK) are provided by an external source or the codec.

    These two setups are configured very differently, so confirming this first will help avoid confusion. Once this is clear, we can then look at: the I2S -11 (-EAGAIN) messages, and the I2C -5 (I/O error) issue separately if it still happens.

    Thanks for confirming, and we’ll take it step by step from there. Regards,
    Syed Maysum

    1. Option B:
      The nRF54L15 should work as an I2S slave, and the clocks (BCLK/LRCK/MCK) are provided by an external source or the codec.  this one
  • #define DPPI_CH    0
    #define GPIOTE_CH  0
    static const struct gpio_dt_spec pwm_Tim = GPIO_DT_SPEC_GET(PWM_NODE, gpios); // for reset pin
    void start_timer(void)
    {
        // gpio comfigure
        gpio_pin_configure_dt(&pwm_Tim, GPIO_OUTPUT_INACTIVE);
        gpio_pin_set_dt(&pwm_Tim, 0);

        // port selection
        uint32_t port =
            (pwm_Tim.port == DEVICE_DT_GET(DT_NODELABEL(gpio1))) ? 1 : 0;


        // cofigure GPIOTE channel
        NRF_GPIOTE20->CONFIG[GPIOTE_CH] =
            (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
            (pwm_Tim.pin << GPIOTE_CONFIG_PSEL_Pos) |
            (port << GPIOTE_CONFIG_PORT_Pos) |
            (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
            (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);

        // Tiimer22 configuration
        NRF_TIMER22->MODE = TIMER_MODE_MODE_Timer;
        NRF_TIMER22->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
        NRF_TIMER22->PRESCALER = 0;   // 16 MHz
        NRF_TIMER22->TASKS_CLEAR = 1;

        NRF_TIMER22->CC[0] = 2;   // 125 ns toggle this time


        NRF_TIMER22->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;    // clear on compare1
     

        NRF_TIMER22->PUBLISH_COMPARE[0] =
            (DPPI_CH << TIMER_PUBLISH_COMPARE_CHIDX_Pos) |
            TIMER_PUBLISH_COMPARE_EN_Msk;                              // publish on compare0

        NRF_GPIOTE20->SUBSCRIBE_OUT[GPIOTE_CH] =
            (DPPI_CH << GPIOTE_SUBSCRIBE_OUT_CHIDX_Pos) |
            GPIOTE_SUBSCRIBE_OUT_EN_Msk;                       // subscribe to GPIOTE channel
         /// dppi comfiguation
        NRF_DPPIC20->CHENSET = (1UL << DPPI_CH);
        // timer22 start
        NRF_TIMER22->TASKS_START = 1;
    }  Timer is fluctuation - not pwm (square is produce) - 4mhz is produce but variation is there ..what will i do , amplitude is millivolt 
  • Hi

    I see you’re experimenting with generating a 4 MHz MCLK now. Just to make sure we’re aligned: I don’t yet have confirmation that the original I2C issue is resolved. Before we move further with MCLK/I2S, could you please confirm:

    1. Have the I2C read/write length issues been fixed (no 2-byte transfers into 1-byte variables, and i2c_write_dt() used for write-only operations)?
    2. With I2S disabled or disconnected, does an I2C free-run test (e.g. 10,000 register reads) complete with zero -EIO errors?

    Once that’s confirmed, we can continue with the MCLK/I2S part. Thanks

    Regards,
    Syed Maysum

  • CONFIG_PRINTK=y
    CONFIG_SERIAL=y
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_GPIO=y
    CONFIG_I2C=y
    CONFIG_I2S=y

    CONFIG_I2C_NRFX=y
    CONFIG_I2S_NRFX_TX_BLOCK_COUNT=8


    CONFIG_ASSERT=y
    CONFIG_FAULT_DUMP=2
    CONFIG_PRINTK=y
    CONFIG_LOG=y
    CONFIG_LOG_MODE_IMMEDIATE=y
Reply Children
No Data
Related