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 Reply Children
  • #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

  • Hi

    Thanks for the update. I can see that I2C is still not stable in free-run. At this point, I won’t be able to help further until the I2C-only stress test (with I2S disabled) completes without -EIO.

    Best Regards,
    Syed Maysum

Related