Hi everyone,
I started to develop an application on the nRF52840 DK in Visual Studio Code and I have trouble to communicate with my sensor via I2C.
The major issue is that i'm a newbie in Zephyr and the sensor i selected isn't quite popular so there isn't a lot of documentation online and no drivers available in the Zephyr driver database.
I use the LSM6DSV16X by STm, I've at first tested the sensor on arduino with the example provided by STm and it worked.
I tried to communicate via the sensor directly without drivers but I have trouble understanding the i2c_write and i2c_read function on Zephyr. If i understand well i don't need to change anything in the devicetree since i'm not using drivers. Is that correct ?
Here is my main :
/* * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <zephyr/drivers/i2c.h> #include <zephyr/drivers/gpio.h> /* 1000 msec = 1 sec */ #define SLEEP_TIME_MS 1000 #define LSM16_I2C_ADD 0x6B // I2c adress according to datasheet #define LSM16_ACC_L_X 0x28 // 8-bit register that store the Low part of the acceleration following X axe. #define LSM16_ACC_H_X 0x29 // 8-bit register that store the High part of the acceleration following X axe. #define I2C_NODE DT_NODELABEL(i2c0) static const struct device *i2c_Mydevice = DEVICE_DT_GET(I2C_NODE); static uint8_t i2c_buffer[2] = {}; // function to combine the High and low register of my sensor uint16_t combineRegister(uint8_t upperBytes, uint8_t lowerBytes); void main(void) { int error; uint16_t accx = 10; if(!device_is_ready(i2c_Mydevice)) { printk("I2C_device not ready\n"); return; } while (1) { i2c_buffer[0] = LSM16_ACC_L_X ; i2c_buffer[1] = LSM16_ACC_H_X ; do { // Test de d'écriture du bus I2C error = i2c_write(i2c_Mydevice, i2c_buffer, 1, LSM16_I2C_ADD); if (error<0) {printk("LSM16 write failure : %d\n", error); break;} // Test de lecture du bus I2C error = i2c_read(i2c_Mydevice, i2c_buffer , 1 , LSM16_I2C_ADD); if (error<0) {printk("LSM16 read failure : %d\n", error); break;} accx = combineRegister(i2c_buffer[0], i2c_buffer[1]); printk("Value of Accx = %d\n", accx); } while (false); k_msleep(SLEEP_TIME_MS); } } // function to combine the High and low register of my sensor uint16_t combineRegister(uint8_t upperBytes, uint8_t lowerBytes) { uint16_t accX_combined = 0; printk(" valeur de upper %d valeur de lower %d \n", upperBytes, lowerBytes); accX_combined = upperBytes << 8 | lowerBytes; return accX_combined; }
I've enable the I2C in the prj.conf file and included the driver for I2C in my main code but I'm stuck. I think I managed to communicate with my sensor since this :
doesn't provide me error when my sensor is connected.
prj.conf code :
CONFIG_GPIO=y CONFIG_I2C=y CONFIG_CBPRINTF_FP_SUPPORT=y
So I have the following questions :
- Do I need to use the standard 'C' driver library provided by STm avaible here https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm6dsv16x_STdC in order to simply get data from the registers of my sensor. Or can I get those data via the standard function in Zephyr
- If I need to use drivers how do I add them to zephyr ?
Hope my issue isn't to trivial but I'm really stuck and I can't find anything on the web :(.
Thanks in advance
Best regards.