Issue with reading WHO AM I Register of ICM20948 over SPI with nRF52832 and Zephyr

I am trying to read the WHO AM I register of an ICM20948 over SPI with nRF52832, but I am getting incorrect values.

I have tried different SPI modes, but none of them work. Later, I tried reading the same register to make sure the module is working with different controllers, and they worked, which means the module is functioning properly.

Instead of expected value 0xEA, I am getting 0xE0 or some other values.

// boards/nrf52dk_nrf52832.overlay

&i2c0 {	status = "disabled";};
&i2c1 {	status = "disabled";};
&spi1 {	status = "disabled";};

my_spi_master: &spi2 {
	compatible = "nordic,nrf-spi";
	status = "okay";
	pinctrl-0 = <&spi_master_default>;
	pinctrl-1 = <&spi_master_sleep>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
	reg_my_spi_master: spi-dev-a@0 {
		reg = <0>;
	};
};

&pinctrl {
	spi_master_default: spi_master_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 25)>,
					<NRF_PSEL(SPIM_MOSI, 0, 23)>,
					<NRF_PSEL(SPIM_MISO, 0, 24)>;
		};
	};

	spi_master_sleep: spi_master_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 25)>,
					<NRF_PSEL(SPIM_MOSI, 0, 23)>,
					<NRF_PSEL(SPIM_MISO, 0, 24)>;
			low-power-enable;
		};
	};
};

#define MY_SPI_MASTER DT_NODELABEL(my_spi_master)
#define MY_SPI_MASTER_CS_DT_SPEC SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master))
const struct device *spi_dev;

static struct spi_config spi_cfg = {
    // .operation = SPI_TRANSFER_MSB | SPI_WORD_SET(8), // spi mode 0
    // .operation = SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_MODE_CPHA, // spi mode 1
    // .operation = SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_MODE_CPOL, // spi mode 2
    .operation = SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_MODE_CPOL | SPI_MODE_CPHA, // spi mode 3
    .frequency = 4000000,
    .slave = 0,
    .cs = {.gpio = MY_SPI_MASTER_CS_DT_SPEC, .delay = 0},
};

void read_register(uint8_t reg, uint8_t *data, uint32_t size)
{
    uint8_t tx_buffer[1];
    uint8_t rx_buffer[size];
    struct spi_buf tx_buf, rx_buf;

    tx_buffer[0] = reg;

    tx_buf.buf = tx_buffer;
    tx_buf.len = 1;
    rx_buf.buf = rx_buffer;
    rx_buf.len = size;

    struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 };
    struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 };

    int ret = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
    if (ret) {
        printk("SPI read failed with error code %d\n", ret);
        return;
    }

    memcpy(data, rx_buffer, size);
}

void spi_init(void)
{
    spi_dev = DEVICE_DT_GET(MY_SPI_MASTER);

    if (!device_is_ready(spi_dev))
    {
        printk("SPI master device not ready!\n");
    }

    struct gpio_dt_spec spim_cs_gpio = MY_SPI_MASTER_CS_DT_SPEC;

    if (!device_is_ready(spim_cs_gpio.port))
    {
        printk("SPI master chip select device not ready!\n");
    }
}

int main(void)
{
    int err;

    spi_init();

    uint8_t reg;
    uint8_t data[2] = {0};

    reg = 0x00 | 0x80;

    read_register(reg, data, 2);
}

Also I am getting the following problem in overlay file but I am able to compile and run the code. I restarted the VS Code but the problem persists.

nRF Connect SDK v2.6.1. 

Related