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.  

Parents
  • Hi

    If you just want to get I2C running you can do this quite easily, without making any changes to the device tree configuration. 

    I added a small example showing how to do this, based on the blinky sample in Zephyr:

    If you run this example with your I2C sensor connected it should print out the I2C address of your sensor, assuming everything is connected properly. 

    Best regards
    Torbjørn

Reply
  • Hi

    If you just want to get I2C running you can do this quite easily, without making any changes to the device tree configuration. 

    I added a small example showing how to do this, based on the blinky sample in Zephyr:

    If you run this example with your I2C sensor connected it should print out the I2C address of your sensor, assuming everything is connected properly. 

    Best regards
    Torbjørn

Children
No Data
Related