Communication with a sensor not in the driver database with I2C on nRF52840 DK Zephyr.

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 :

error = i2c_write(i2c_Mydevice, i2c_buffer, 1, LSM16_I2C_ADD);          
            if (error<0)
                {printk("LSM16 write failure : %d\n", error); break;}

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. 

Parents Reply
  • Thank you for your answer i've tried to merge the folder and even replace the zephyr folder downloaded with the nRF toolchain manager with the repo you provide me. Unfortunately after doing so i couldn't create a new application, the blinky folder remain empty.. 

    I have also noticed that the version of the zephyr folder in the pull request isn't the same as my local zephyr version downloaded via the toolchain manager. 

    Is this possible that my nRF25840 SDK isn't compatible with a newer version of zephyr ?

    best regards.

Children
  • I have not verified the merge myself, so I am not sure if this is a straightforward merge. Instead of replacing the whole zephyr folder, just try replacing the folders and files that changed in the PR. Since this feature is still not in the upstream, it is still to be considered as experimental.

    Esbriven said:
    I have also noticed that the version of the zephyr folder in the pull request isn't the same as my local zephyr version downloaded via the toolchain manager

    I think replacing the whole zephyr folder might be an overkill, try replacing smaller units like files changed in this PR.

  • I would recommend that you use Git to pull the commits in question from that specific repo and merge them into your local repo instead. You are right in thinking that the nRF Connect SDK's version of Zephyr differs from the actual mainline Zephyr repo.

    To merge specific commits from another remote repository into your local repository, you can follow these general steps:

    1. Clone the remote repository: If you haven't already cloned the remote repository, start by cloning it to your local machine using the `git clone` command. For example:

    git clone <remote_repository_url>

    2. Navigate to your local repository: Move to the directory of your local repository using the `cd` command:


    cd <repository_directory>

    3. Add a remote reference to the other remote repository: This step is necessary to fetch the commits from the other remote repository. You can use the `git remote` command to add a remote reference. For example:


    git remote add <remote_name> <other_remote_repository_url>

    4. Fetch the remote commits: Fetch the commits from the other remote repository without automatically merging them into your current branch. Use the `git fetch` command with the remote reference you added in the previous step. For example:


    git fetch <remote_name>

    5. Create a new branch: Create a new branch in your local repository to merge the specific commits into. This step is optional if you want to merge the commits into an existing branch. You can use the `git branch` command to create a new branch. For example:


    git branch <new_branch_name>


    6. Switch to the new branch: Move to the newly created branch using the `git checkout` command. For example:

    git checkout <new_branch_name>

    7. Merge the specific commits: Finally, you can merge the specific commits from the other remote repository into your local repository. Use the `git merge` command followed by the commit hash or reference of the specific commit(s) you want to merge. For example:

    git merge <commit_hash>

    You can repeat this command to merge multiple specific commits.

    Remember to substitute the placeholders `<remote_repository_url>`, `<repository_directory>`, `<remote_name>`, `<other_remote_repository_url>`, `<new_branch_name>`, and `<commit_hash>` with the appropriate values for your scenario.

    These steps will help you selectively merge specific commits from another remote repository into your local repository.

Related