cancel
Showing results for 
Search instead for 
Did you mean: 

Receiving a NMAK when reading out WhoAmI register - lsm6dsox

ReginaA101
Associate

Hi everyone,

I am currently trying to get a lsm6dsox to interface with a Nordic nRF52833 board using i2c communication. I am looking to read accelerometer/gyro values.

I am able to write to the sensor but I am unable to read from the sensor without receiving a NMAK. 

I am using the STEVAL-MKI217V1 adapter board to connect to my nRF52833.

I have connected the VDD/VDDIO pins to VCC, my SCL/SDA pins to the pins I configured for i2c communication, I have connected CS to VDD, GND pins to GND, and SDO to ground. 

This is my result from the Logic analyzer

 
Screenshot 2025-02-28 175333.png

This is my source code:

Main.c:

/*
 * Copyright (c) 2020 Yestin Sun
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>

static inline float out_ev(struct sensor_value *val)
{
    return (val->val1 + (float)val->val2 / 1000000);
}

static void fetch_and_display(const struct device *dev)
{
    struct sensor_value x, y, z;
    static int trig_cnt;

    trig_cnt++;

    /* lsm6dso accel */
    sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ);
    sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &x);
    sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &y);
    sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &z);

    printf("accel x:%f ms/2 y:%f ms/2 z:%f ms/2\n",
            (double)out_ev(&x), (double)out_ev(&y), (double)out_ev(&z));

    /* lsm6dso gyro */
    sensor_sample_fetch_chan(dev, SENSOR_CHAN_GYRO_XYZ);
    sensor_channel_get(dev, SENSOR_CHAN_GYRO_X, &x);
    sensor_channel_get(dev, SENSOR_CHAN_GYRO_Y, &y);
    sensor_channel_get(dev, SENSOR_CHAN_GYRO_Z, &z);

    printf("gyro x:%f rad/s y:%f rad/s z:%f rad/s\n",
            (double)out_ev(&x), (double)out_ev(&y), (double)out_ev(&z));

    printf("trig_cnt:%d\n\n", trig_cnt);
}

static int set_sampling_freq(const struct device *dev)
{
    int ret = 0;
    struct sensor_value odr_attr;

    /* set accel/gyro sampling frequency to 12.5 Hz */
    odr_attr.val1 = 12.5;
    odr_attr.val2 = 0;

    ret = sensor_attr_set(dev, SENSOR_CHAN_ACCEL_XYZ,
            SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr);
    if (ret != 0) {
        printf("Cannot set sampling frequency for accelerometer.\n");
        return ret;
    }

    ret = sensor_attr_set(dev, SENSOR_CHAN_GYRO_XYZ,
            SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr);
    if (ret != 0) {
        printf("Cannot set sampling frequency for gyro.\n");
        return ret;
    }

    return 0;
}

#ifdef CONFIG_LSM6DSO_TRIGGER
static void trigger_handler(const struct device *dev,
                const struct sensor_trigger *trig)
{
    fetch_and_display(dev);
}

static void test_trigger_mode(const struct device *dev)
{
    struct sensor_trigger trig;

    if (set_sampling_freq(dev) != 0)
        return;

    trig.type = SENSOR_TRIG_DATA_READY;
    trig.chan = SENSOR_CHAN_ACCEL_XYZ;

    if (sensor_trigger_set(dev, &trig, trigger_handler) != 0) {
        printf("Could not set sensor type and channel\n");
        return;
    }
}

#else
static void test_polling_mode(const struct device *dev)
{
    if (set_sampling_freq(dev) != 0) {
        return;
    }

    while (1) {
        fetch_and_display(dev);
        k_sleep(K_MSEC(1000));
    }
}
#endif

int main(void)
{
    const struct device *const dev = DEVICE_DT_GET_ONE(st_lsm6dso);

    if (!device_is_ready(dev)) {
        printk("%s: device not ready.\n", dev->name);
        return 0;
    }

#ifdef CONFIG_LSM6DSO_TRIGGER
    printf("Testing LSM6DSO sensor in trigger mode.\n\n");
    test_trigger_mode(dev);
#else
    printf("Testing LSM6DSO sensor in polling mode.\n\n");
    test_polling_mode(dev);
#endif
    return 0;
}
 
Overlay file:
#include <zephyr/dt-bindings/sensor/lsm6dso.h>
&i2c0 {
    status = "okay";
    compatible = "nordic,nrf-twim";
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    lsm6dsox:lsm6dsox@6A {
        compatible = "st,lsm6dso";
        status = "ok";
        label = "LSM6DSO";
        reg = <0x6A>;
        accel-odr = <LSM6DSO_DT_ODR_1Hz6>;
    };
};
&pinctrl {
    i2c0_default: i2c0_default {
        group1  {
            psels = <NRF_PSEL(TWIM_SCL, 0, 27)>, <NRF_PSEL(TWIM_SDA, 0, 26)>;
            bias-pull-up;
        };
    };

    i2c0_sleep: i2c0_sleep {
        group1  {
            psels = <NRF_PSEL(TWIM_SCL, 0, 27)>,
                    <NRF_PSEL(TWIM_SDA, 0, 26)>;
            low-power-enable;
        };
    };
};
 
Is there something I am missing to ensure that I can read via i2c?
I appreciate anyone's help as I am very stuck on this.
Thanks,
Regina
0 REPLIES 0