Introduction:
I am working on my first project based on NRF processor. It is also my first time working on Zephyr RTOS. I have spent a couple of days watching various videos to familiarize myself with how things are done but I still find difficult to understand the whole device tree principle.
I thought the fastest way to get going is to quickly create a simple i2c driver to poll temperature/humidity data from the SHT40 sensor that I have available at hand. As a reference, I use the example project for SHT3Xd that I found on the zephyr git: (https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/sensor/sht3xd/src/main.c)
Information:
HW used: NRF52DK (https://www.nordicsemi.com/Products/Development-hardware/nrf52-dk)
IDE used: VS Code with nRF Connect for VS Code extension
NRF Connect SDK used: v2.4.0
In the C:\nrf\v2.4.0\zephyr\boards\arm\nrf52dk_nrf52832\nrf52dk_nrf52832.dts the i2c is defined:
arduino_i2c: &i2c0 { compatible = "nordic,nrf-twi"; status = "okay"; pinctrl-0 = <&i2c0_default>; pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; }; &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"; };
From what I understand, in the my project overlay file I can then expand the i2c0 or i2c1 by adding:
&i2c1 { sht3xd@44 { compatible = "sensirion,sht3xd"; reg = <0x44>; }; };
This tells the device tree that I am going to connect some external I2C device to the i2c1 bus. Is my understanding correct?
In my code, I call:
int main(void) { const struct device *const dev = DEVICE_DT_GET_ONE(sensirion_sht3xd); int rc; if (!device_is_ready(dev)) { printf("Device %s is not ready\n", dev->name); return 0; } return 0; }
C:\nrf\v2.4.0\zephyr\include\zephyr\device.h:84:41: error: '__device_dts_ord_104' undeclared here (not in a function); did you mean '__device_dts_ord_14'?
- Where are the SCL/SDA pins defined? I cannot see the pins defined in the C:\nrf\v2.4.0\zephyr\boards\arm\nrf52dk_nrf52832\nrf52dk_nrf52832.dts. The i2c0 and i2c1 does not even have scl and sda property. How to define scl and sda pins for my particular application and how does the zephyr example project know which I2C pins to use?
- In the device tree compatible property sht3x zephyr example they use compatible = "sensirion,sht3xd";, Can I make up my own custom name for it? For example: compatible = "my_i2c_sensor,sht40";
- I can see that the Zephyr sht3x example is using functions such as sensor_attr_set, sensor_trigger_set, sensor_sample_fetch, sensor_channel_get and others to get the information from the i2c device. It seems to be unnecessary complex. For example, I have recently written STH40 driver for the ESP32 microcontroller and it looks something like:
esp_err_t Measure_temp_humidity(){ uint8_t read_buffer[6]; uint8_t write_command[1] = {0xFD}; // request temp_humid_high_precision i2c_master_write_to_device(I2C_MASTER_NUM, 0x44, &write_command, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); // send request vTaskDelay(20 / portTICK_PERIOD_MS); // wait for 20ms i2c_master_read_from_device(I2C_MASTER_NUM,0x44,&read_buffer,6,I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); }