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
  • 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
  • Not fixed yest , when i am reading i2c reguster it leads to -5 error 

  • #include <zephyr/kernel.h>
    #include <zephyr/drivers/i2c.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include "codec_header.h"



    #define CODEC_ADDR 0x18 // i2c slave adress
    //#define MAX_ADDR 0x55
    #define RESET_NODE DT_NODELABEL(led0) // for codec reset pin
    #define PWM_NODE  DT_NODELABEL(led1) // for timer toggle pin
    #define DPPI_CH    0
    #define GPIOTE_CH  0

    static const struct gpio_dt_spec codec_reset_pin = GPIO_DT_SPEC_GET(DT_NODELABEL(codec_reset), gpios);

    static const struct i2c_dt_spec dev_i2c =I2C_DT_SPEC_GET(DT_NODELABEL(audiocodec));
    //static const struct  i2c_dt_spec *dev_i2c=DEVICE_DT_GET(DT_NODELABEL(audiocodec));

    //static const struct device *dev_i2c = DEVICE_DT_GET(DT_NODELABEL(i2c22));

    //static const struct gpio_dt_spec max_reset_pin = GPIO_DT_SPEC_GET(DT_NODELABEL(max_reset), gpios); // for max reset pin

    //static const struct gpio_dt_spec mfin_reset_pin = GPIO_DT_SPEC_GET(DT_NODELABEL(mfin_pin), gpios);// for mfin pin




    /**
     * Register declaration
     */

    const register_value REGISTER_DATA[] = {
        //          # reg[0][0]   = 0x00   ; Select Page 0
        {0, 0x00},
        //          # reg[0][1]   = 0x01   ; S/W Reset
        {1, 0x01},
        //          # reg[0][4]   = 0x03   ; PLL_CLKIN = MCLK = 4 MHz., CODEC_CLKIN = PLL_CLCK
        {4, 0x03},
        //          # reg[0][5]   = 0xD4   ; PLL Power up, P = 5, R = 4
        {5, 0xD4},
        //          # reg[0][6]   = 0x20   ; J = 32
        {6, 0x20},
        //          # reg[0][7]   = 0x00   ; D = 0000, D(13:8) = 0
        {7, 0x00},
        //          # reg[0][8]   = 0x00   ; D(7:0) = 0
        {8, 0x00},
        //          # reg[0][27]  = 0x0C   ; Mode = I2S, wordlength = 16, output mode
        {27, 0x0C},
        //          # reg[0][11]  = 0x84   ; DAC Powerup NDAC = 4 (DAC_MAC_CLK = 102.4 MHz/4 = 25.6 MHz.)
        {11, 0x84},
        //          # reg[0][12]  = 0x99   ; DAC Powerup MDAC = 25  (DAC_MOD_CLK = 25.6/ 25 = 1.024 MHz.)
        {12, 0x99},
        //          # reg[0][14]  = 0x80   ;  DOSR = 128 (ADC Fs = 1.024 / 128 = 8.0 KHz.)
        {14, 0x80},
        //          # reg[0][18]  = 0x84   ; ADC Powerup NADC = 4 (ADC_MAC_CLK = 102.4 MHz/4 = 25.6 MHz.)
        {18, 0x84},
        //          # reg[0][19]  = 0x99   ; ADC Powerup MADC = 25 (ADC_MOD_CLK = 25.6 MHz/25 = 1.024 MHz.)
        {19, 0x99},
        //          # reg[0][20]  = 0x80   ; AOSR = 20 (ADC Fs = 1.024 / 128 = 8.0 KHz.)
        {20, 0x80},
        //          # reg[0][29]  = 0X01   ; DAC_MOD_CLOCK
        {29, 0x01},
        //          # reg[0][30]  = 0x84   ; BCLK N-divider, BCLK divider N = 4
        {30, 0x84},
        //          # reg[0][0]   = 0x01   ; Select Page 1
        {0, 0x01},
        //          # reg[1][46]  = 0x0B   ; MICBIAS always on, MICBIAS = 2.5V
        {46, 0x0A},
        //          # reg[1][48]  = 0x40   ; MICLP is selected for left of Mic PGA P @ 10k input impedance
        {48, 0x40},
        //          # reg[1][49]  = 0x40   ; CM is selected for right of Mic PGA M @ 10k input impedance
        {49, 0x40},
        //          # reg[1][47]  = 0x0    ; MIC PGA ;  db
        {47, 0x00},
        //          # reg[0][0]   = 0x00   ; Select Page 0
        {0, 0x00},
        //          # reg[0][81]  = 0x80   ; Powerup ADC channel (soft step enable)
        {81, 0x80},
        //          # reg[0][83]  = 0x00   ; ADC volume = 0dB
        {83, 0x00},
        //           reg[0][82]  = 0x00   ; Unmute ADC channel
        {82, 0x00},

    };

    // const struct device *dev_i2c = DEVICE_DT_GET(DT_NODELABEL(i2c22)); // i2c


    static const struct gpio_dt_spec rst = GPIO_DT_SPEC_GET(RESET_NODE, gpios); // for reset pin
    static const struct gpio_dt_spec pwm_Tim = GPIO_DT_SPEC_GET(PWM_NODE, gpios); // for reset pin

    const size_t REGISTER_LEN = sizeof(REGISTER_DATA) / sizeof(register_value);

    uint32_t cfg = I2C_MODE_CONTROLLER | I2C_SPEED_SET(I2C_SPEED_STANDARD); // configration of i2c
    void TIMER22_IRQHandler();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

    /**
     * @brief codec_i2c_write
     * @param
     * device tree
     * adress
     * buffer
     * length of message
     */
    static int codec_i2c_write(const struct device *dev,
                               uint8_t addr, uint8_t *buf, uint32_t len)
    {
        struct i2c_msg msg = {
            .buf = buf,
            .len = len,
            .flags = I2C_MSG_WRITE | I2C_MSG_STOP,
        };

        return i2c_transfer(dev, &msg, 2, addr);
    }
    /**
     *
     */
    static int codec_i2c_write_read(const struct device *dev,
                                    uint16_t addr,
                                    const void *write_buf, size_t num_write,
                                    void *read_buf, size_t num_read)
    {

        struct i2c_msg msg[2];
        // printf("address...%x",addr);
        msg[0].buf = (uint8_t *)write_buf;
        msg[0].len = num_write;
        msg[0].flags = I2C_MSG_WRITE;

        msg[1].buf = (uint8_t *)read_buf;
        msg[1].len = num_read;
        msg[1].flags = I2C_MSG_READ | I2C_MSG_STOP;

        // return i2c_transfer(dev, &msg[0], 2, addr);
        return i2c_write_read_dt(&dev_i2c, write_buf, num_write, read_buf, num_read);
    }

    // reset pin
    void codec_reset_pulse(void)
    {
         int ret;

        ret=gpio_pin_set_dt(&codec_reset_pin, 1);
        k_msleep(10);

        // HIGH → reset released
        ret=gpio_pin_set_dt(&codec_reset_pin, 0);
        k_msleep(20); //20

        return 0;
       
    }

    /**
     * brief@
     * param@
     */

    // static int codec_write_register(uint8_t page, uint8_t reg, uint8_t val)
    // {
    //     static uint8_t last_page = 0xFF; // invalid page at start
    //     uint8_t tx_buf[2];
    //     uint8_t red_buff[2];
    //     int err;

    //     // Only update page register if page actually changed
    //     if (page != last_page)
    //     {
    //         tx_buf[0] = 0x00; // Page Select Register
    //         tx_buf[1] = page;

    //        //err = codec_i2c_write(&dev_i2c, CODEC_ADDR, tx_buf, 2);
    //        err=i2c_write_read_dt(&dev_i2c,tx_buf,2,red_buff,2);
    //        k_msleep(5);
    //         if (err)
    //         {
    //             printk("I2C: page switch failed (page=%u) err=%d\n", page, err);
    //             return err;
    //         }

    //         last_page = page; // update page tracking
    //         k_msleep(2);      // small delay for codec stability
    //     }

    //     // Now write the actual register
    //     tx_buf[0] = reg;
    //     tx_buf[1] = val;
    //     err=i2c_write_read_dt(&dev_i2c,tx_buf,2,red_buff,2);
    //     if (err)
    //     {
    //         printk("I2C: reg write ....read ...failed (p=%u reg=0x%02X val=0x%02X) err=%d\n",
    //                page, reg, val, err);
    //     }
       

    //      printk("I2C: reg write ....read ...succc ( reg=0x%02X val=0x%02X) err=%d\n  read_buff[0]=0x%02X   read_buff[1]=0x%02X ",
    //                page, reg, val, err,red_buff[0], red_buff[1]);
    //     return err;
    // }
    // static int codec_write_register(uint8_t page, uint8_t reg, uint8_t val)
    // {
    //     static uint8_t last_page = 0xFF;
    //     uint8_t tx_buf[2];
    //     int err;

    //     /* Page select: WRITE ONLY */
    //     if (page != last_page) {
    //         tx_buf[0] = 0x00;   // page register
    //         tx_buf[1] = page;

    //         err = i2c_write_dt(&dev_i2c, tx_buf, 2);
    //         if (err) {
    //             printk("I2C: page switch failed page=%u err=%d\n", page, err);
    //             return err;
    //         }

    //         last_page = page;
    //         k_msleep(2);
    //     }

    //     /* Register write: WRITE ONLY */
    //     tx_buf[0] = reg;
    //     tx_buf[1] = val;

    //     err = i2c_write_dt(&dev_i2c, tx_buf, 2);
    //     if (err) {
    //         printk("I2C: reg write failed p=%u reg=0x%02X err=%d\n",
    //                page, reg, err);
    //     }

    //     return err;
    // }

    static int codec_reg_write(uint8_t reg, uint8_t val)
    {
        uint8_t buf[2] = { reg, val };

        return i2c_write_dt(&dev_i2c, buf, sizeof(buf));
    }


    static int codec_write_register(uint8_t page, uint8_t reg, uint8_t val)
    {
        static uint8_t last_page = 0xFF;
        int err;

        // Page select (WRITE ONLY)
        if (page != last_page)
        {
            err = codec_reg_write(0x00, page);
            if (err)
            {
                printk("Page select failed: %d\n", err);
                return err;
            }
            last_page = page;

            k_msleep(2);
        }

        /* Register write (WRITE ONLY) */
        err = codec_reg_write(reg, val);
        if (err)
        {
            printk("Reg write failed p=%u r=0x%02X\n", page, reg);
        }

        return err;
    }


    static int codec_write_table(const register_value *table, size_t len)
    {
        uint8_t page = 0;
        int err;

        for (size_t i = 0; i < len; i++)
        {
            if (table[i].reg_no == 0x00)
            {
                page = table[i].reg_value;

                continue;
            }

            err = codec_write_register(page,
                                       table[i].reg_no,
                                       table[i].reg_value);
            if (err)
            {
                printk("Table write failed at %zu\n", i);
                return err;
            }

            k_msleep(1);
        }

        return 0;
    }

    /**
     *
     */

    // static int codec_write_table(const register_value *table, size_t len)
    // {
    //     uint8_t current_page = 0x00;
    //     //uint8_t read_buff=0;
    //     int err;
     

    //     for (size_t i = 0; i < len; i++)
    //     {
    //         uint8_t reg = table[i].reg_no;
    //         uint8_t val = table[i].reg_value;

    //         // Page change
    //         if (reg == 0x00)
    //         {
    //             current_page = val;
    //             k_msleep(1);
    //             continue;
    //         }

    //         // Normal register write on current page
    //         err = codec_write_register(current_page, reg, val);
    //         if (err)
    //         {
    //             printf("fail.......reg=0x%02X val=0x%02X err=%d\n", reg, val, err);
    //             return err;
    //         }  

    //         printf("reg=0x%02X val=0x%02X err=%d\n", reg, val, err);
             

    //         k_msleep(10);
    //     }

    //     return 0;
    // }


    // static bool codec_probe(void)
    // {
     
    //     uint8_t reg0[2] = {0x00,0x00};
    //     uint8_t read_back = 0;
    //      int err;

    //     err= i2c_write_read_dt(&dev_i2c, &reg0, 2, &read_back, 1);
    //    // k_msleep(5);
    //     if (err)
    //     {
    //         printk("I2C probe failed err=%d\n", err);
    //         return false;
    //     }

    //     printk("Codec responded: reg0 = 0x%02X\n", read_back);

    //     return true;
    // }


    static int codec_reg_read(uint8_t reg, uint8_t *val)
    {
        return i2c_write_read_dt(&dev_i2c,
                                 &reg, 1,
                                 val, 1);
    }

    //test
    static void codec_i2c_stress_test(void)
    {
        uint8_t val;

        for (int i = 0; i < 10000; i++) {
            if (codec_reg_read(0x00, &val))
            {
                printk("I2C error at iteration %d\n", i);
                return;
            }
        }

        printk("I2C stress test PASSED\n");
    }



    static bool codec_probe(void)
    {
        uint8_t val;

        if (codec_reg_read(0x00, &val))
        {
            printk("Codec probe failed\n");
            return false;
        }

        printk("Codec responded, reg0 = 0x%02X\n", val);
        return true;
    }


    // read command
    int read_eg(void)
    {
        int ret;
        uint8_t reg = 0xD4;
        uint8_t val = 0;

        ret = i2c_write_read_dt(&dev_i2c,
                                &reg, 2,
                                &val, 2);
        if (ret)
        {
            printk("I2C read failed reg 0x%02x err %d\n", reg, ret);
            return ret;
        }

        printk("Read reg 0x%02x = 0x%02x\n", reg, val);

        return 0;
    }

    int codec_hw_reset(void)
     {
        int ret;

        ret=gpio_pin_set_dt(&codec_reset_pin, 1);
        k_msleep(10);

        /* HIGH → reset released */
        ret=gpio_pin_set_dt(&codec_reset_pin, 0);
        k_msleep(20);


        return 0;
    }

    // static int codec_i2c_config(void)
    // {
    //     if (!device_is_ready(dev_i2c.bus))
    //     {
    //         printk("Error: I2C bus %s is not ready!\n", dev_i2c.bus->name);
    //         return -1;
    //     }
       

    //     printk("I2C bus ready, addr=0x%02x\n", dev_i2c.addr); //dev_i2c.addr
     

    //     return 0;
    // }

    static int codec_gpios_config(void)
    {
        int ret;

        if (!gpio_is_ready_dt(&codec_reset_pin))
        {
            printk("Error: Codec reset pin not ready\n");
            return -1;
        }
        ret=gpio_pin_configure_dt(&codec_reset_pin,
                                    GPIO_OUTPUT_ACTIVE |
                                    GPIO_ACTIVE_LOW);
       
        if (ret < 0)
        {
            printk("Error %d: Failed to configure codec reset pin\n", ret);
            return -1;
        }

        return 0;
    }

    // int codec_init(void)
    // {
       
    //     //
    //     int ret;

    //     ret = codec_gpios_config();
    //     if (ret != 0)
    //     {
    //         return ret;
    //     }

    //     ret = codec_i2c_config();
    //     if (ret != 0)
    //     {
    //         return ret;
    //     }

    //     ret = codec_hw_reset();
    //     if (ret != 0)
    //     {
    //         return ret;
    //     }
    //     k_msleep(20);
    //     read_eg();

    //     return 0;
    // }


    //

    /**
     * i2c_init()
     *
     */
    int i2c_init_codec()
    {
        int err;

        int ret;

        ret = codec_gpios_config();
        k_msleep(20);

        if (ret)
        {
            return ret;
        }

        if (!device_is_ready(dev_i2c.bus))
        {
            printk("I2C bus %s is not ready!\n", dev_i2c.bus->name);
            return -1;
        }
        k_msleep(20);
        printk("I2C bus ready, addr=0x%02x\n",dev_i2c.addr);

       
        // reset pin config
        codec_reset_pulse();

        /*codec address check*/
        if (!codec_probe())
        {
            printk("Codec not found on I2C address 0x%02X\n", CODEC_ADDR);
            return -EIO;
        }

       
        printk("Writing codec register table...\n");

        err = codec_write_table(REGISTER_DATA, REGISTER_LEN);

        if (err)
        {
            printk("Codec register table FAILED: %d\n", err);
            return err;
        }

        k_msleep(20);

        codec_i2c_stress_test();

        printk("Codec init DONE.\n");

        printk("I2C ready\n");
        return 0;
    }

    // // Timer start
    // void start_timer(void)
    // {
    //     gpio_pin_configure_dt(&pwm_Tim, GPIO_OUTPUT_INACTIVE);
    //     gpio_pin_set_dt(&pwm_Tim, 0);

    //     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->EVENTS_COMPARE[0] = 0;
    //     NRF_TIMER22->EVENTS_COMPARE[1] = 0;

    //     // 16 MHz → 62.5 ns per tick
    //     NRF_TIMER22->CC[0] = 2;   // 125 ns
    //     NRF_TIMER22->CC[1] = 4;   // 250 ns

    //     NRF_TIMER22->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Msk;

    //     NRF_TIMER22->INTENSET =
    //         TIMER_INTENSET_COMPARE0_Msk |
    //         TIMER_INTENSET_COMPARE1_Msk;

    //     IRQ_CONNECT(TIMER22_IRQn, 0,
    //                 TIMER22_IRQHandler, NULL, 0);

    //     NVIC_ClearPendingIRQ(TIMER22_IRQn);
    //     irq_enable(TIMER22_IRQn);

    //     NRF_TIMER22->TASKS_START = 1;
    // }

    // void TIMER22_IRQHandler(void)
    // {
    //     if (NRF_TIMER22->EVENTS_COMPARE[0]) {
    //         NRF_TIMER22->EVENTS_COMPARE[0] = 0;
    //         gpio_pin_set_dt(&pwm_Tim, 1);
    //     }

    //     if (NRF_TIMER22->EVENTS_COMPARE[1]) {
    //         NRF_TIMER22->EVENTS_COMPARE[1] = 0;
    //         gpio_pin_set_dt(&pwm_Tim, 0);
    //     }
    // }

    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;
    }
  • I2c register Read is happen only when used debugger step in to option , otherwise it leads to -5 error

Reply Children
No Data
Related