• Support
  • Device tree error undefined reference to `__device_dts_ord_127'

Hi there,

i have built a custom board in devicetree. I have based it off the nrf52840DK dts but added in a magnetometer:

s3_mini_v1.dts

`/*
 * Copyright (c) 2017 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "s3_mini_v1-pinctrl.dtsi"

 / {
	 model = "Nordic nRF52840 DK NRF52840";
	 compatible = "nordic,nrf52840-dk-nrf52840";
 
	 chosen {
		 zephyr,console = &uart0;
		 zephyr,shell-uart = &uart0;
		 zephyr,uart-mcumgr = &uart0;
		 zephyr,bt-mon-uart = &uart0;
		 zephyr,bt-c2h-uart = &uart0;
		 zephyr,sram = &sram0;
		 zephyr,flash = &flash0;
		 zephyr,code-partition = &slot0_partition;
		 zephyr,ieee802154 = &ieee802154;
	 };
 
	 leds {
		 compatible = "gpio-leds";
		 led0: led_0 {
			 gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
			 label = "Green LED 0";
		 };
		 led1: led_1 {
			 gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
			 label = "Green LED 1";
		 };
		 led2: led_2 {
			 gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
			 label = "Green LED 2";
		 };
		 led3: led_3 {
			 gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
			 label = "Green LED 3";
		 };
	 };
 
	 pwmleds {
		 compatible = "pwm-leds";
		 pwm_led0: pwm_led_0 {
			 pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
		 };
	 };
 
	 buttons {
		 compatible = "gpio-keys";
		 button0: button_0 {
			 gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			 label = "Push button switch 0";
		 };
		 button1: button_1 {
			 gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			 label = "Push button switch 1";
		 };
		 button2: button_2 {
			 gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			 label = "Push button switch 2";
		 };
		 button3: button_3 {
			 gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			 label = "Push button switch 3";
		 };
	 };
 
	//  arduino_header: connector {
	// 	 compatible = "arduino-header-r3";
	// 	 #gpio-cells = <2>;
	// 	 gpio-map-mask = <0xffffffff 0xffffffc0>;
	// 	 gpio-map-pass-thru = <0 0x3f>;
	// 	 gpio-map = <0 0 &gpio0 3 0>,	/* A0 */
	// 			<1 0 &gpio0 4 0>,	/* A1 */
	// 			<2 0 &gpio0 28 0>,	/* A2 */
	// 			<3 0 &gpio0 29 0>,	/* A3 */
	// 			<4 0 &gpio0 30 0>,	/* A4 */
	// 			<5 0 &gpio0 31 0>,	/* A5 */
	// 			<6 0 &gpio1 1 0>,	/* D0 */
	// 			<7 0 &gpio1 2 0>,	/* D1 */
	// 			<8 0 &gpio1 3 0>,	/* D2 */
	// 			<9 0 &gpio1 4 0>,	/* D3 */
	// 			<10 0 &gpio1 5 0>,	/* D4 */
	// 			<11 0 &gpio1 6 0>,	/* D5 */
	// 			<12 0 &gpio1 7 0>,	/* D6 */
	// 			<13 0 &gpio1 8 0>,	/* D7 */
	// 			<14 0 &gpio1 10 0>,	/* D8 */
	// 			<15 0 &gpio1 11 0>,	/* D9 */
	// 			<16 0 &gpio1 12 0>,	/* D10 */
	// 			<17 0 &gpio1 13 0>,	/* D11 */
	// 			<18 0 &gpio1 14 0>,	/* D12 */
	// 			<19 0 &gpio1 15 0>,	/* D13 */
	// 			<20 0 &gpio0 26 0>,	/* D14 */
	// 			<21 0 &gpio0 27 0>;	/* D15 */
	//  };
 
	 arduino_adc: analog-connector {
		 compatible = "arduino,uno-adc";
		 #io-channel-cells = <1>;
		 io-channel-map = <0 &adc 1>,	/* A0 = P0.3 = AIN1 */
				  <1 &adc 2>,	/* A1 = P0.4 = AIN2 */
				  <2 &adc 4>,	/* A2 = P0.28 = AIN4 */
				  <3 &adc 5>,	/* A3 = P0.29 = AIN5 */
				  <4 &adc 6>,	/* A4 = P0.30 = AIN6 */
				  <5 &adc 7>;	/* A5 = P0.31 = AIN7 */
	 };
 
	 /* These aliases are provided for compatibility with samples */
	 aliases {
		 led0 = &led0;
		 led1 = &led1;
		 led2 = &led2;
		 led3 = &led3;
		 pwm-led0 = &pwm_led0;
		 sw0 = &button0;
		 sw1 = &button1;
		 sw2 = &button2;
		 sw3 = &button3;
		 bootloader-led0 = &led0;
		 mcuboot-button0 = &button0;
		 mcuboot-led0 = &led0;
		 watchdog0 = &wdt0;
		 //spi-flash0 = &mx25r64;
		 magnetometer = &lsm303agr;
	 };
 };
 
 &adc {
	 status = "okay";
 };
 
 &gpiote {
	 status = "okay";
 };
 
 &gpio0 {
	 status = "okay";
 };
 
 &gpio1 {
	 status = "okay";
 };
 
 &uart0 {
	 compatible = "nordic,nrf-uarte";
	 status = "okay";
	 current-speed = <115200>;
	 pinctrl-0 = <&uart0_default>;
	 pinctrl-1 = <&uart0_sleep>;
	 pinctrl-names = "default", "sleep";
 };
 
 arduino_serial: &uart1 {
	 current-speed = <115200>;
	 pinctrl-0 = <&uart1_default>;
	 pinctrl-1 = <&uart1_sleep>;
	 pinctrl-names = "default", "sleep";
 };
 
 &i2c0 {
	compatible = "nordic,nrf-twi";
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;	
	pinctrl-names = "default", "sleep";	
	label = "I2C0";
    lsm303agr: gpio@19 {
		compatible = "rohm,bh1749";
		int-gpios = <&gpio0 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        reg = <0x19>;
		status = "okay";
		label = "lsm303";
		//interrupts = <1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };
};
 
 &i2c1 {
	 compatible = "nordic,nrf-twi";
	 /* Cannot be used together with spi1. */
	 /* status = "okay"; */
	 pinctrl-0 = <&i2c1_default>;
	 pinctrl-1 = <&i2c1_sleep>;
	 pinctrl-names = "default", "sleep";
 };
 
 &pwm0 {
	 status = "okay";
	 pinctrl-0 = <&pwm0_default>;
	 pinctrl-1 = <&pwm0_sleep>;
	 pinctrl-names = "default", "sleep";
 };
 
//  &spi0 {
// 	 compatible = "nordic,nrf-spi";
// 	 /* Cannot be used together with i2c0. */
// 	 /* status = "okay"; */
// 	 pinctrl-0 = <&spi0_default>;
// 	 pinctrl-1 = <&spi0_sleep>;
// 	 pinctrl-names = "default", "sleep";
//  };
 
//  &spi1 {
// 	 compatible = "nordic,nrf-spi";
// 	 status = "okay";
// 	 pinctrl-0 = <&spi1_default>;
// 	 pinctrl-1 = <&spi1_sleep>;
// 	 pinctrl-names = "default", "sleep";
//  };
 
//  &spi2 {
// 	 compatible = "nordic,nrf-spi";
// 	 status = "disabled";
// 	 pinctrl-0 = <&spi2_default>;
// 	 pinctrl-1 = <&spi2_sleep>;
// 	 pinctrl-names = "default", "sleep";
//  };
 
//  &qspi {
// 	 status = "okay";
// 	 pinctrl-0 = <&qspi_default>;
// 	 pinctrl-1 = <&qspi_sleep>;
// 	 pinctrl-names = "default", "sleep";
// 	 mx25r64: mx25r6435f@0 {
// 		 compatible = "nordic,qspi-nor";
// 		 reg = <0>;
// 		 /* MX25R64 supports only pp and pp4io */
// 		 writeoc = "pp4io";
// 		 /* MX25R64 supports all readoc options */
// 		 readoc = "read4io";
// 		 sck-frequency = <8000000>;
// 		 jedec-id = [c2 28 17];
// 		 sfdp-bfp = [
// 			 e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
// 			 ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
// 			 10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
// 			 30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
// 		 ];
// 		 size = <67108864>;
// 		 has-dpd;
// 		 t-enter-dpd = <10000>;
// 		 t-exit-dpd = <35000>;
// 	 };
//  };
 
//  arduino_spi: &spi3 {
// 	 status = "okay";
// 	// cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */
// 	 pinctrl-0 = <&spi3_default>;
// 	 pinctrl-1 = <&spi3_sleep>;
// 	 pinctrl-names = "default", "sleep";
//  };
 
 &ieee802154 {
	 status = "okay";
 };
 
 &flash0 {
 
	 partitions {
		 compatible = "fixed-partitions";
		 #address-cells = <1>;
		 #size-cells = <1>;
 
		 boot_partition: partition@0 {
			 label = "mcuboot";
			 reg = <0x00000000 0x0000C000>;
		 };
		 slot0_partition: partition@c000 {
			 label = "image-0";
			 reg = <0x0000C000 0x00076000>;
		 };
		 slot1_partition: partition@82000 {
			 label = "image-1";
			 reg = <0x00082000 0x00076000>;
		 };
 
		 /*
		  * The flash starting at 0x000f8000 and ending at
		  * 0x000fffff is reserved for use by the application.
		  */
 
		 /*
		  * Storage partition will be used by FCB/LittleFS/NVS
		  * if enabled.
		  */
		 storage_partition: partition@f8000 {
			 label = "storage";
			 reg = <0x000f8000 0x00008000>;
		 };
	 };
 };
 
 zephyr_udc0: &usbd {
	 compatible = "nordic,nrf-usbd";
	 status = "okay";
 };`

i am attempting to configure the magnetometer, however when ever i try to get the device instance for the magnetometer, i receive the following error at compilation.

\lsm303agr_m\src\main.c:120: undefined reference to__device_dts_ord_127′`

This only happens when i call any functions that require me to pass a device instance. I have tried referencing the magnetometer with different macros, but this has not fixed the issue. i can also return parameters such as ‘label’ or ‘status’ from the magnetometer but i cannot get the device instance. if i comment out the line:

if (!device_is_ready(m_lsm_dev))

and also:
i2c_reg_read_byte(m_lsm_dev, LSM_TWI_ADDR, 0X1E, &data);then it will compile.
main.c:

`/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/devicetree.h>
#include <zephyr/kernel.h>
#include "lsm303agr_reg.h"
#include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>
#include <inttypes.h>
#include <stdlib.h>


LOG_MODULE_REGISTER(foo, CONFIG_LOG_DEFAULT_LEVEL);
#define DT_DRV_COMPAT nordic_nrf_twi 
#define DT_I2C0_N DT_PATH(soc, i2c_40003000)
//#define gpio DT_PROP(DT_CHILD(LABEL, lsm303agr), label)
#define LSM_TWI_ADDR 0x19
////////////////////////////////////////////////////////
#define MAGNT DT_ALIAS(magnetometer)
#if !DT_NODE_HAS_STATUS(MAGNT, okay)
#error "Unsupported board: mag devicetree alias is not defined"
#endif

stmdev_ctx_t lsm_twi_rw;
char* labl = DT_PROP(MAGNT, label);

static const struct device* m_lsm_dev = DEVICE_DT_GET(MAGNT);
static struct gpio_callback lsm_cb;
static struct gpio_dt_spec lsmint = GPIO_DT_SPEC_GET_OR(MAGNT, int_gpios, {0});
lsm303agr_reg_t m_lsm_reg; 

//#define lsmint DT_PHANDLE(LSM, interrupts)

void init_lsm()
{
	uint8_t err, data;
	memset(&m_lsm_reg.cfg_reg_a_m , 0, sizeof(m_lsm_reg.cfg_reg_a_m ));

	m_lsm_reg.cfg_reg_a_m.comp_temp_en 				= true;
	m_lsm_reg.cfg_reg_a_m.lp 						= true;
	m_lsm_reg.cfg_reg_b_m.lpf 						= true;
	m_lsm_reg.cfg_reg_b_m.int_on_dataoff 			= true; 
	m_lsm_reg.cfg_reg_c_m.drdy_on_pin				= true;
	m_lsm_reg.cfg_reg_c_m.bdu						= true;
	m_lsm_reg.cfg_reg_a_m.md						= 0x03;
	m_lsm_reg.cfg_reg_a_m.odr						= LSM303AGR_MG_ODR_10Hz;
	i2c_reg_read_byte(m_lsm_dev, LSM_TWI_ADDR, 0X1E, &data);

	if (data != 0x40)
	{
		LOG_INF("WHOAMINOTFOUND");
		
	}

}

void lsm_set_rw()
{
	lsm_twi_rw.read_reg = i2c_write_read;
	lsm_twi_rw.write_reg = i2c_write;
	//lsm_twi_rw.handle = &m_lsm_dev;
}

void lsm_handler()
{
	LOG_INF("MAGREAD");
}

static void mag_handler()
{
	LOG_INF("MAG INT");
}

void main(void)
{

	uint8_t ret;
	LOG_INF("PIN = %u dt flags =%u Port = %u labl=%s", lsmint.pin, lsmint.dt_flags, lsmint.port, labl);
	const struct device *i2c_dev = DEVICE_DT_GET(DT_I2C0_N);

	if (!device_is_ready(m_lsm_dev)) 
	{
   		LOG_INF("Can't bind I2C device %s\n", m_lsm_dev);
    	return;
  	}

 	if (lsmint.port && !device_is_ready(lsmint.port)) {
		LOG_INF("Error %d: LED device %s is not ready; ignoring it\n",
		       ret, lsmint.port->name);
		lsmint.port = NULL;
	}
	if (lsmint.port) {
		ret = gpio_pin_configure_dt(&lsmint, GPIO_OUTPUT);
		if (ret != 0) {
			LOG_INF("Error %d: failed to configure LED device %s pin %d\n",
			       ret, lsmint.port->name, lsmint.pin);
			lsmint.port = NULL;
		} else {
			LOG_INF("Set up LED at %s pin %d\n", lsmint.port->name, lsmint.pin);
		}
	}


	ret = gpio_pin_interrupt_configure_dt(&lsmint,
					      GPIO_INT_EDGE_TO_ACTIVE);
	if (ret != 0) {
		LOG_INF("Error %d: failed to configure interrupt on %s pin %d\n",
			ret, lsmint.port->name, lsmint.pin);
		return;
	}
	gpio_init_callback(&lsm_cb, mag_handler, BIT(lsmint.pin));
	gpio_add_callback(lsmint.port, &lsm_cb);	

	//lsm_set_rw();
	init_lsm();
	//err_code = lsm303agr_twi_read(p_lsm303agr_m->p_i2c_instance, 0x1E, 0x4F, &data, sizeof(uint8_t));



	//lsm303agr_read_reg(&foo, 0, x, y);

}`

I have just used the ‘rohm,bh1749’ binding for the lsm303agr for now as a template binding as it a has ‘int-gpios’ property which as far as im aware is required to call GPIO_DT_SPEC_GET_OR. there is a LSM magnetometer binding, but it is for a slightly different model and has a property for ‘interrupts’ instead which seems to be an invalid syntax when calling GPIO_DT_SPEC_GET_OR.

Any help would me much appreciated.

    What does your project config look like kevinMoon? Did you enable I2C, and the driver library?

    Hi Jared, I2C is enabled, but im not so sure about the device driver lib. Ive had a quick look at other examples and i cant see any specific config the corresponds to that?

    `# choose RTT console
    CONFIG_UART_CONSOLE=n
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    
    # Config logger
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4
    CONFIG_SPI=n
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
    CONFIG_I2C=y
    CONFIG_PWM=y
    CONFIG_GPIO=y`

    Did you see this sample?

    zephyr/samples/sensor/lsm303dlhc

    I would try to replicate that as much as possible. It appears that there are no configuration variables to enable the specific driver. One thing I did notice is that your declaration is incorrect. It should be:

    &i2c0 {
    	status = "okay";
    	clock-frequency = <I2C_BITRATE_FAST>;
    
    	/* v1.5 variant 1 LSM303AGR */
    	lsm303agr_magn: lsm303agr-magn@1e {
    		compatible = "st,lis2mdl", "st,lsm303agr-magn";
    		status = "disabled";
    		reg = <0x1e>;
    		irq-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;	/* A3 */
    	};
    
    	lsm303agr_accel: lsm303agr-accel@19 {
    		compatible = "st,lis2dh", "st,lsm303agr-accel";
    		status = "disabled";
    		reg = <0x19>;
    		irq-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
    	};
    };

    Looks like the Microbit uses this same part. So I’d definitely check out any samples that use that board.

      Terms and Conditions | Privacy Policy