reading data from a sensor that has no driver using TWI

Hello, I am trying to read data from the sensor using I2C, I have the nrf9160 on an Icarus board https://www.actinius.com/icarus.

I tried following this guide: https://devzone.nordicsemi.com/guides/nrf-connect-sdk-guides/b/peripherals/posts/twi-ic2-implementation-with-nrfx-twis-driver

but I ended up with a lot of errors when building 

  

main.c

#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <sys/printk.h>
#include <zephyr.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

const struct device *led_dev;

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0 ""
#define PIN 0
#define FLAGS 0
#endif

////////////////////////////////////////////////////////////

// TWI Test Configuration

////////////////////////////////////////////////////////////

#define ECHO_WRITES false
#define MSG_EXCHANGE_CNT 5
#define INFINITE_MSG_EXCHANGE false
#define TWI_LOOPBACK false
// In non-loopback mode, the tx message is unchanged.
// In loopback mode the rx buffer acts as both the tx and rx buffer. The rx buffer is updated with each read.

////////////////////////////////////////////////////////////

// Adding TWI Functionality

////////////////////////////////////////////////////////////

#define TWI_BUFFER_SIZE 14
/* static unsigned char i2c_tx_buffer[TWI_BUFFER_SIZE] = {'M', 'S', 'G', ' ', 'F', 'R', 'O', 'M', ' ', 'T', 'W', 'I', 'M', '\0'};
 */static unsigned char i2c_rx_buffer[TWI_BUFFER_SIZE] = "Begin Loopback";

// TWI Master Setup

#define MY_TWIM DT_NODELABEL(i2c2)
const struct device *nrfx_twis_dev1;

static void twim_init(void)
{
	int config_result = false;

	nrfx_twis_dev1 = device_get_binding(DT_LABEL(MY_TWIM));

	if (nrfx_twis_dev1 == NULL)
	{
		printk("\n\nI2C Slave: Device driver not found.\n");
	}
	else
	{
		printk("\nI2C device 1: %s\n", DT_PROP(DT_NODELABEL(twis_device1), label));

		config_result = i2c_configure(nrfx_twis_dev1, I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_MASTER);

		if (!config_result)
		{
			printk("I2C Master: Slave ADDR: 0x%x SCL: %d, SDA: %d, CLK(Hz): %u\n\n",
				   DT_REG_ADDR(DT_NODELABEL(twis_device1)),
				   DT_PROP(MY_TWIM, scl_pin),
				   DT_PROP(MY_TWIM, sda_pin),
				   DT_PROP(MY_TWIM, clock_frequency));
		}
		else
			printk("\n\nI2C: Configuration error code: %d\n", config_result);
	}
}

// TWI Master Write

/* void twi_write_tst(void)
{
	int rtn_code = 0;
	uint8_t incr = 0;
	bool loopback = TWI_LOOPBACK;

	if (nrfx_twis_dev1 != NULL)
	{
		// printk("\nTWIM TX/writing.");
		if (!loopback)
		{ // write repeated default message
			rtn_code = i2c_write(nrfx_twis_dev1, i2c_tx_buffer, sizeof(i2c_tx_buffer), DT_REG_ADDR(DT_NODELABEL(twis_device1)));
		}
		else
		{ // use read buffer as write buffer
			rtn_code = i2c_write(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR(DT_NODELABEL(twis_device1)));
		}

		if (ECHO_WRITES && (rtn_code == 0))
		{
			printk("\nTWIM TX:");
			while (incr < TWI_BUFFER_SIZE)
				printk("%c", i2c_rx_buffer[incr++]);
			printk("\n");
		} // rtn_code == 0

		if (rtn_code)
		{
			printk("twi return code %u\n\n", rtn_code);
		}
	}
	else // twis_dev1 == NULL
		printk("TWIS device is not initialized correctly.\n");
} */

void twi_read_tst(void)
{
	int rtn_code = 0;
	uint8_t incr = 0;

	if (nrfx_twis_dev1 != NULL)
	{
		// printk("\nTWIM RX/reading -->");
		rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer),DT_REG_ADDR( DT_PATH(i2c2,cd30_61) ) );

		if (rtn_code == 0)
		{
			printk("TWIM RX:");
			while (incr < TWI_BUFFER_SIZE)
			{
				printk("%c", i2c_rx_buffer[incr++]);
			};
			printk("\n");
		}

		if (rtn_code)
			printk("twi return code %u\n\n", rtn_code);
	}
	else // twim_dev1 == NULL
		printk("TWI is not initialized correctly.\n");
}

void main(void)
{
	uint16_t twi_test_cnt = MSG_EXCHANGE_CNT;
	bool led_is_on = true;
	uint32_t ret;

	led_dev = device_get_binding(LED0);
	if (led_dev == NULL)
	{
		return;
	}

	ret = gpio_pin_configure(led_dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
	if (ret < 0)
	{
		return;
	}

	twim_init();

	while (1)
	{

		gpio_pin_set(led_dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;

		if ((twi_test_cnt) || (INFINITE_MSG_EXCHANGE))
		{
			
			twi_read_tst();

			if (twi_test_cnt)
			{
				twi_test_cnt--;
			}

			if ((!twi_test_cnt) && (!INFINITE_MSG_EXCHANGE))
			{
				printk("\n\nTo rerun this test, reset the master.\n\n");
			}
		}

		k_msleep(SLEEP_TIME_MS);
	}
}

actinuos_icarus_ns.overlay

&i2c2 {

	compatible = "nordic,nrf-twim";

	status = "okay";

	clock-frequency = <I2C_BITRATE_STANDARD>;
	/* other property settings can go here */

	
	twis_device1: scd30@61 {				/* e */
		// device compatible				/* f */
		label = "scd30";	/* g */
       	reg = <0x61>;						/* h */
   	};
};

log:

C:\Users\alnag\Desktop\Work\blinky-TWIM>west build -b actinius_icarus_ns
[0/1] Re-running CMake...
Including boilerplate (Zephyr base (cached)): C:/Users/alnag/ncs/v1.9.1/zephyr/cmake/app/boilerplate.cmake
-- Application: C:/Users/alnag/Desktop/Work/blinky-TWIM
-- Zephyr version: 2.7.99 (C:/Users/alnag/ncs/v1.9.1/zephyr), build: v2.7.99-ncs1-1
-- Found west (found suitable version "0.12.0", minimum required is "0.7.1")
-- Board: actinius_icarus_ns
-- Cache files will be written to: C:/Users/alnag/ncs/v1.9.1/zephyr/.cache
-- Found dtc: C:/Users/alnag/ncs/v1.9.1/toolchain/opt/bin/dtc.exe (found suitable version "1.4.7", minimum required is "1.4.6")
-- Found toolchain: gnuarmemb (c:/Users/alnag/ncs/v1.9.1/toolchain/opt)
-- Found BOARD.dts: C:/Users/alnag/ncs/v1.9.1/zephyr/boards/arm/actinius_icarus/actinius_icarus_ns.dts
-- Found devicetree overlay: c:/Users/alnag/Desktop/Work/blinky-TWIM/actinius_icarus_ns.overlay
-- Generated zephyr.dts: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/include/generated/device_extern.h
-- Including generated dts.cmake file: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/dts.cmake
Parsing C:/Users/alnag/ncs/v1.9.1/zephyr/Kconfig
Loaded configuration 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/.config'
No change to configuration in 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/.config'
No change to Kconfig header in 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/include/generated/autoconf.h'
C:\Users\alnag\ncs\v1.9.1\toolchain\opt\bin\arm-none-eabi-gdb.exe: warning: Couldn't determine a path for the index cache directory.
Changed board to secure actinius_icarus (NOT NS)

=== child image spm -  begin ===
loading initial cache file C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/child_image_preload.cmake
Including boilerplate (Zephyr base (cached)): C:/Users/alnag/ncs/v1.9.1/zephyr/cmake/app/boilerplate.cmake
-- Application: C:/Users/alnag/ncs/v1.9.1/nrf/samples/spm
-- Zephyr version: 2.7.99 (C:/Users/alnag/ncs/v1.9.1/zephyr), build: v2.7.99-ncs1-1
-- Found west (found suitable version "0.12.0", minimum required is "0.7.1")
-- Board: actinius_icarus
-- Cache files will be written to: C:/Users/alnag/ncs/v1.9.1/zephyr/.cache
-- Found dtc: C:/Users/alnag/ncs/v1.9.1/toolchain/opt/bin/dtc.exe (found suitable version "1.4.7", minimum required is "1.4.6")
-- Found toolchain: gnuarmemb (c:/Users/alnag/ncs/v1.9.1/toolchain/opt)
-- Found BOARD.dts: C:/Users/alnag/ncs/v1.9.1/zephyr/boards/arm/actinius_icarus/actinius_icarus.dts
-- Generated zephyr.dts: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/zephyr.dts
-- Generated devicetree_unfixed.h: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/include/generated/devicetree_unfixed.h
-- Generated device_extern.h: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/include/generated/device_extern.h
-- Including generated dts.cmake file: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/dts.cmake
Parsing C:/Users/alnag/ncs/v1.9.1/zephyr/Kconfig
Loaded configuration 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/.config'
No change to configuration in 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/.config'
No change to Kconfig header in 'C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm/zephyr/include/generated/autoconf.h'
C:\Users\alnag\ncs\v1.9.1\toolchain\opt\bin\arm-none-eabi-gdb.exe: warning: Couldn't determine a path for the index cache directory.
CMake Warning at C:/Users/alnag/ncs/v1.9.1/zephyr/CMakeLists.txt:1687 (message):
  __ASSERT() statements are globally ENABLED


-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/alnag/Desktop/Work/blinky-TWIM/build/spm
=== child image spm -  end ===

Dropping partition 'nrf_modem_lib_trace' since its size is 0.
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/alnag/Desktop/Work/blinky-TWIM/build
[0/136] Performing build step for 'spm_subimage'
[213/221] Linking C executable zephyr\zephyr_pre0.elf

[216/221] Linking C executable zephyr\zephyr_pre1.elf

[221/221] Linking C executable zephyr\zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:         64 KB        64 KB    100.00%
            SRAM:       12008 B        32 KB     36.65%
        IDT_LIST:          0 GB         2 KB      0.00%
[44/134] Building C object CMakeFiles/app.dir/src/main.c.obj
FAILED: CMakeFiles/app.dir/src/main.c.obj
C:\Users\alnag\ncs\v1.9.1\toolchain\opt\bin\arm-none-eabi-gcc.exe -DBUILD_VERSION=v2.7.99-ncs1-1 -DEXT_API_MAGIC=0x281ee6de,0xb845acea,23298 -DFIRMWARE_INFO_MAGIC=0x281ee6de,0x8fcebb4c,23298 -DKERNEL -DNRF9160_XXAA -DNRF_SKIP_FICR_NS_COPY_TO_RAM -DNRF_TRUSTZONE_NONSECURE -DUSE_PARTITION_MANAGER=1 -D_FORTIFY_SOURCE=2 -D__PROGRAM_START -D__ZEPHYR__=1 -IC:/Users/alnag/ncs/v1.9.1/zephyr/include -Izephyr/include/generated -IC:/Users/alnag/ncs/v1.9.1/zephyr/soc/arm/nordic_nrf/nrf91 -IC:/Users/alnag/ncs/v1.9.1/zephyr/soc/arm/nordic_nrf/common/. -IC:/Users/alnag/ncs/v1.9.1/nrf/include -IC:/Users/alnag/ncs/v1.9.1/modules/hal/cmsis/CMSIS/Core/Include -IC:/Users/alnag/ncs/v1.9.1/modules/hal/nordic/nrfx -IC:/Users/alnag/ncs/v1.9.1/modules/hal/nordic/nrfx/drivers/include -IC:/Users/alnag/ncs/v1.9.1/modules/hal/nordic/nrfx/mdk -IC:/Users/alnag/ncs/v1.9.1/zephyr/modules/hal_nordic/nrfx/. -IC:/Users/alnag/ncs/v1.9.1/nrfxlib/nrf_modem/include -isystem C:/Users/alnag/ncs/v1.9.1/zephyr/lib/libc/minimal/include -isystem c:/users/alnag/ncs/v1.9.1/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/include -isystem c:/users/alnag/ncs/v1.9.1/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/include-fixed -Os -imacros C:/Users/alnag/Desktop/Work/blinky-TWIM/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m33 -mthumb -mabi=aapcs -mfp16-format=ieee -imacros C:/Users/alnag/ncs/v1.9.1/zephyr/include/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-main -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-asynchronous-unwind-tables -fno-pie -fno-pic -fno-strict-overflow -fno-reorder-functions -fno-defer-pop -fmacro-prefix-map=C:/Users/alnag/Desktop/Work/blinky-TWIM=CMAKE_SOURCE_DIR -fmacro-prefix-map=C:/Users/alnag/ncs/v1.9.1/zephyr=ZEPHYR_BASE -fmacro-prefix-map=C:/Users/alnag/ncs/v1.9.1=WEST_TOPDIR -ffunction-sections -fdata-sections -std=c99 -nostdinc -MD -MT CMakeFiles/app.dir/src/main.c.obj -MF CMakeFiles\app.dir\src\main.c.obj.d -o CMakeFiles/app.dir/src/main.c.obj -c ../src/main.c
In file included from C:/Users/alnag/ncs/v1.9.1/zephyr/include/arch/arm/aarch32/arch.h:20,
                 from C:/Users/alnag/ncs/v1.9.1/zephyr/include/arch/cpu.h:19,
                 from C:/Users/alnag/ncs/v1.9.1/zephyr/include/kernel_includes.h:33,
                 from C:/Users/alnag/ncs/v1.9.1/zephyr/include/kernel.h:17,
                 from C:/Users/alnag/ncs/v1.9.1/zephyr/include/init.h:11,
                 from C:/Users/alnag/ncs/v1.9.1/zephyr/include/device.h:29,
                 from ../src/main.c:7:
../src/main.c: In function 'twi_read_tst':
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:81:17: error: 'DT_N_S_i2c2_S_cd30_61_REG_IDX_0_VAL_ADDRESS' undeclared (first use in this function); did you mean 'DT_N_S_cpus_S_cpu_0_REG_IDX_0_VAL_ADDRESS'?
   81 | #define DT_ROOT DT_N
      |                 ^~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3022:24: note: in definition of macro 'DT_CAT'
 3022 | #define DT_CAT(a1, a2) a1 ## a2
      |                        ^~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:1717:30: note: in expansion of macro 'DT_REG_ADDR_BY_IDX'
 1717 | #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0)
      |                              ^~~~~~~~~~~~~~~~~~
../src/main.c:136:76: note: in expansion of macro 'DT_REG_ADDR'
  136 |   rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer),DT_REG_ADDR( DT_PATH(i2c2,cd30_61) ) );
      |                                                                            ^~~~~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/sys/util_internal.h:98:26: note: in expansion of macro 'UTIL_PRIMITIVE_CAT'
   98 | #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
      |                          ^~~~~~~~~~~~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3004:2: note: in expansion of macro 'UTIL_CAT'
 3004 |  UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
      |  ^~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3004:11: note: in expansion of macro 'DT_ROOT'
 3004 |  UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
      |           ^~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:129:22: note: in expansion of macro 'DT_PATH_INTERNAL'
  129 | #define DT_PATH(...) DT_PATH_INTERNAL(__VA_ARGS__)
      |                      ^~~~~~~~~~~~~~~~
../src/main.c:136:89: note: in expansion of macro 'DT_PATH'
  136 |   rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer),DT_REG_ADDR( DT_PATH(i2c2,cd30_61) ) );
      |                                                                                         ^~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:81:17: note: each undeclared identifier is reported only once for each function it appears in
   81 | #define DT_ROOT DT_N
      |                 ^~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3022:24: note: in definition of macro 'DT_CAT'
 3022 | #define DT_CAT(a1, a2) a1 ## a2
      |                        ^~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:1717:30: note: in expansion of macro 'DT_REG_ADDR_BY_IDX'
 1717 | #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0)
      |                              ^~~~~~~~~~~~~~~~~~
../src/main.c:136:76: note: in expansion of macro 'DT_REG_ADDR'
  136 |   rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer),DT_REG_ADDR( DT_PATH(i2c2,cd30_61) ) );
      |                                                                            ^~~~~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/sys/util_internal.h:98:26: note: in expansion of macro 'UTIL_PRIMITIVE_CAT'
   98 | #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
      |                          ^~~~~~~~~~~~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3004:2: note: in expansion of macro 'UTIL_CAT'
 3004 |  UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
      |  ^~~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:3004:11: note: in expansion of macro 'DT_ROOT'
 3004 |  UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
      |           ^~~~~~~
C:/Users/alnag/ncs/v1.9.1/zephyr/include/devicetree.h:129:22: note: in expansion of macro 'DT_PATH_INTERNAL'
  129 | #define DT_PATH(...) DT_PATH_INTERNAL(__VA_ARGS__)
      |                      ^~~~~~~~~~~~~~~~
../src/main.c:136:89: note: in expansion of macro 'DT_PATH'
  136 |   rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer),DT_REG_ADDR( DT_PATH(i2c2,cd30_61) ) );
      |                                                                                         ^~~~~~~
[53/134] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sched.c.obj
ninja: build stopped: subcommand failed.
FATAL ERROR: command exited with status 1: 'C:\Users\alnag\ncs\v1.9.1\toolchain\opt\bin\cmake.EXE' --build 'C:\Users\alnag\Desktop\Work\blinky-TWIM\build'

here is the project if someone to try bulding for themself.  

7026.blinky-TWIM.zip

Parents Reply Children
  • Hi 

    thanks for your continuous support, I tried the hex and the decimal representation it looks like this!

    kind regards 

    Saed

  • Hi Saed

    Can you show me the code you used to produce this printout?

    I don't see "0x" printed anywhere, so I must assume you didn't copy my code exactly.

    Best regards
    Torbjørn

  • hi, 

    I have attached a new code where I write commands to the sensor to start the measurement and get results, unfortunately, all that I get is 0xff 0xff 0xac

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    #include <sys/printk.h>
    #include <zephyr.h>
    
    
    
    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS 10000
    
    /* The devicetree node identifier for the "led0" alias. */
    #define LED0_NODE DT_ALIAS(led0)
    
    const struct device *led_dev;
    
    #if DT_NODE_HAS_STATUS(LED0_NODE, okay)
    #define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)
    #define PIN DT_GPIO_PIN(LED0_NODE, gpios)
    #define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
    #else
    /* A build error here means your board isn't set up to blink an LED. */
    #error "Unsupported board: led0 devicetree alias is not defined"
    #define LED0 ""
    #define PIN 0
    #define FLAGS 0
    #endif
    
    ////////////////////////////////////////////////////////////
    
    // TWI Test Configuration
    
    ////////////////////////////////////////////////////////////
    
    #define ECHO_WRITES true
    #define MSG_EXCHANGE_CNT 5
    #define INFINITE_MSG_EXCHANGE false
    #define TWI_LOOPBACK false
    // In non-loopback mode, the tx message is unchanged.
    // In loopback mode the rx buffer acts as both the tx and rx buffer. The rx buffer is updated with each read.
    
    ////////////////////////////////////////////////////////////
    
    // Adding TWI Functionality
    
    ////////////////////////////////////////////////////////////
    
    #define TWI_BUFFER_SIZE 18
     
    static const uint8_t readCommand[] = {0x03,0x00} ;
    static const uint8_t dataReady[] = {0x02,0x02} ;
    static const uint8_t triggerContinuousMeasurement[2] = {0x00,0x10} ;
    static const uint8_t deactivateASC[] = {0x53, 0x06, 0x00, 0x00 } ;
    static const uint8_t activateASC[2] = {0x53, 0x06 } ;
    static const uint8_t getASC[] = {0x53, 0x06 } ;
    static const uint8_t softRest[] = {0xD3,0x04} ;															
    static const uint8_t framewareVersion[] = {0xD1,0x00} ;		 		
    
    //5sec
    
    static uint8_t i2c_rx_buffer [TWI_BUFFER_SIZE];
    
    // TWI Master Setup
    
    #define MY_TWIM DT_NODELABEL(i2c2)
    const struct device *nrfx_twis_dev1;
    
    
    static void twim_init(void)
    {
    	int config_result = false;
     
    
    	nrfx_twis_dev1 = device_get_binding(DT_LABEL(MY_TWIM));
    	printk("\n\nI2C Slave: Device driver not found.\n");
    	if (nrfx_twis_dev1 == NULL)
    	{
    		printk("\n\nI2C Slave: Device driver not found.\n");
    	}
    	else
    	{
    		printk("\nI2C device 1: %s\n", DT_PROP(DT_NODELABEL(twis_device1), label));
    
    		config_result = i2c_configure(nrfx_twis_dev1, I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_MASTER);
    
    		if (!config_result)
    		{
    			printk("I2C Master: Slave ADDR: 0x%x SCL: %d, SDA: %d, CLK(Hz): %u\n\n",
    				   DT_REG_ADDR(DT_NODELABEL(twis_device1)),
    				   DT_PROP(MY_TWIM, scl_pin),
    				   DT_PROP(MY_TWIM, sda_pin),
    				   DT_PROP(MY_TWIM, clock_frequency));
    		}
    		else
    			printk("\n\nI2C: Configuration error code: %d\n", config_result);
    			
    	}
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // TWI Master Write
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    void twi_write_tst()
    {
    	int rtn_code = 0;
    	uint8_t incr = 0;
         
    
    	if (nrfx_twis_dev1 != NULL)
    	{
    		 printk("\nTWIM TX/writing.");
    	 
    		  // write repeated default message
    			rtn_code = i2c_write(nrfx_twis_dev1, activateASC ,2, DT_REG_ADDR(DT_NODELABEL(twis_device1)));
    		 	printk("\nTWIM TX/writing ----->        rtn_code: %d",rtn_code);
    	 
    		if (ECHO_WRITES && (rtn_code == 0))
    		{/* 
    			printk("\nTWIM TX:");
    			while (incr < 2)
    				printk("| 0x%.2x |", buffur[incr++]);
    			printk("\n"); */
    		} // rtn_code == 0
    
    		if (rtn_code)
    		{
    			printk("twi return code %u\n\n", rtn_code);
    		}
    	}
    	else // twis_dev1 == NULL
    		printk("TWIS device is not initialized correctly.\n");
    } 
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Checking if data is ready or not 
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    uint8_t getReadyStatus(void)
    {	
    
    	// printk("\n GETTING READY STATUS!! ");
    	int rtn_code = 0;
    	uint8_t incr = 0;
    
    
    	if (nrfx_twis_dev1 != NULL)
    	{
    		// printk("\nTWIM TX/writing.");
    	 
    		  // write repeated default message
    			rtn_code = i2c_write(nrfx_twis_dev1, dataReady , 2 , DT_REG_ADDR(DT_NODELABEL(twis_device1)));
    		 	 // printk("\nTWIM TX/writing  /dataReady/ -----> rtn_code: %d",rtn_code);
    	 
    		/* if (ECHO_WRITES && (rtn_code == 0))
    		{
    			printk("\nTWIM TX:");
    			while (incr < 2)
    				printk("|  %d  |", dataReady[incr++]);
    			printk("\n");
    		} // rtn_code == 0
     */
    		/* if (rtn_code)
    		{
    			printk("twi return code %u\n\n", rtn_code);
    		} */
    	}
    	else // twis_dev1 == NULL
    	//	printk("TWIS device is not initialized correctly.\n");
    
        rtn_code = 0;
    	incr = 0;
    	k_msleep(5);	
    	if (nrfx_twis_dev1 != NULL)
    	{
    		
    	//	printk("\nTWIM RX/reading -->");
    		rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
    		
    
    		/* print the result */
    
    		if (rtn_code == 0)
    		{
    	/* 		printk("TWIM RX:");
    			while (incr < TWI_BUFFER_SIZE)
    			{
    				printk(" | %d  | ", i2c_rx_buffer[incr++]);
    			};
    			printk("\n");
    			 */
    			 
    		}
    
    		if (rtn_code)  printk("twi return code %u\n\n", rtn_code);
    	}
    	else // twim_dev1 == NULL
    		printk("TWI is not initialized correctly.\n");
    
    return i2c_rx_buffer[1] ;
    
    } 
    
    void twi_read_tst(void)
    {
    	int rtn_code = 0;
    	uint8_t incr = 0;
    
    	if (nrfx_twis_dev1 != NULL)
    	{
    		
    		printk("\nTWIM RX/reading -->");
    		rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
    		
    
    		/* print the result */
    
    		if (rtn_code == 0)
    		{
    			printk("TWIM RX:");
    			while (incr < TWI_BUFFER_SIZE)
    			{
    				printk(" | 0x%.2x  | ", i2c_rx_buffer[incr++]);
    			};
    			printk("\n");
    		}
    
    		if (rtn_code)  printk("twi return code %u\n\n", rtn_code);
    	}
    	else // twim_dev1 == NULL
    		printk("TWI is not initialized correctly.\n");
    }
    
    void main(void)
    {
    	uint16_t twi_test_cnt = MSG_EXCHANGE_CNT;
    	bool led_is_on = true;
    	uint32_t ret;
    
    	led_dev = device_get_binding(LED0);
    	if (led_dev == NULL)
    	{
    		return;
    	}
    
    	ret = gpio_pin_configure(led_dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
    	if (ret < 0)
    	{
    		return;
    	}
    
    	twim_init();
    	k_msleep(2000);
    	i2c_write(nrfx_twis_dev1,softRest,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) )	;
    	k_msleep(2000);
    
    	int rtn_code = 5;
    	int	incr = 0 ;
    	i2c_write(nrfx_twis_dev1,triggerContinuousMeasurement,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) )	;
    	k_msleep(2000);
    	i2c_write(nrfx_twis_dev1,activateASC,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
    	k_msleep(2000);
    	i2c_write(nrfx_twis_dev1,dataReady,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
    	k_msleep(2000);
    	i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
     	while (1)
    	{
    
    		gpio_pin_set(led_dev, PIN, (int)led_is_on);
    		led_is_on = !led_is_on;
    
    		if ((twi_test_cnt) || (INFINITE_MSG_EXCHANGE))
    		{		
    			incr = 0 ;
    			// i2c_write_read(nrfx_twis_dev1, DT_REG_ADDR(DT_NODELABEL(twis_device1)),readCommand,2,i2c_rx_buffer,18);
    			i2c_write(nrfx_twis_dev1,readCommand,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
    			i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
     			while (incr < 18)
    			printk("| 0x%.2x |", i2c_rx_buffer[incr++]);
    			printk("\n"); 
    			
    			
    		}
    		k_msleep(10000);
    	}
    }

    blinky-TWIM3.zip

  • Hi 

    Assuming your sensor expects a typical write -> repeated start -> read pattern where you first write the command and then immediately read out the response, then you should use the i2c_write_read(..) function.

    Issuing separate i2c_write(..) and i2c_read(..) calls will most likely not have the same effect, since they will be interpreted by the sensor as two separate commands. 

    Best regards
    Torbjørn 

  • Hi, in the code I posted you can see that I have I2c_write_read() commented, that is because I tried using it as well, did not work with any command, however, I was able to get the frameware version ---> page 17 using separate I2C_write() then read, according to the scd30 Zephyr example:

     https://github.com/Sensirion/embedded-common/blob/1ac7c72c895d230c6f1375865f3b7161ce6b665a/hw_i2c/sample-implementations/zephyr_user_space/sensirion_hw_i2c_implementation.c

    when trying to write (Get measurement interval for example (page9)  ) I always get the deafult interval for the sensor which is 2 sec, although I just used command (set Interval) to change it 4 sec!

    when trying to get ( dataReady) it always returns 0  although I have already sent (triggerContinuous Measurement

    I don't understand where is the problem

Related