Hello everyone,
I am working on an nRF52-DK and getting familiar with Zephyr.
In this process, I am trying to connect with the sensor API with a "fake" sensor whose driver just throws random values. So I am just exploring the possibilities.
On the main application, no matter what I do, I keep getting NULL when calling device_get_binding(DT_LABEL(MY_DEVICE));
Here is the main:
#define MY_DEVICE DT_PATH(soc, i2c_40003000, sens123_23)
#if !DT_NODE_HAS_STATUS(MY_DEVICE, okay)
#error "Node is disabled"
#endif
#if !DT_NODE_HAS_PROP(MY_DEVICE, reg)
#error "Device does not have reg properties"
#endif
const struct device *dev;
void main(void)
{
/* Get the device */
dev = device_get_binding(DT_LABEL(MY_DEVICE));
if (dev == NULL) {
/* No such node, or the node does not have status "okay". */
printk("\nError: no device found.\n");
return;
}
while(1)
{
k_sleep(K_MSEC(1000));
}
}
Here is the "fake" sensor driver:
#define DT_DRV_COMPAT nec_sens123
struct sens123_data {
const struct device *i2c;
uint16_t a_sample;
uint16_t b_sample;
};
static int sens123_sample_fetch(const struct device *dev,
enum sensor_channel chan)
{
struct sens123_data *drv_data = dev->data;
uint8_t buf[4] = {1, 2, 3, 4};
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
drv_data->a_sample = (buf[0] << 8) + buf[1];
drv_data->b_sample = (buf[2] << 8) + buf[3];
return 0;
}
static int sens123_channel_get(const struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct sens123_data *drv_data = dev->data;
uint64_t tmp;
/* val = -40 + 165 * sample / 2^16 */
tmp = (uint64_t)drv_data->a_sample * 165U;
val->val1 = (int32_t)(tmp >> 16) - 40;
val->val2 = ((tmp & 0xFFFF) * 1000000U) >> 16;
return 0;
}
static const struct sensor_driver_api sens123_driver_api = {
.sample_fetch = &sens123_sample_fetch,
.channel_get = &sens123_channel_get,
};
static int sens123_init(const struct device *dev)
{
return 0;
}
static struct sens123_data sens123_data;
/*
DEVICE_DEFINE(DT_DRV_COMPAT, DT_INST_LABEL(0), sens123_init, NULL, &sens123_data,
NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
&sens123_driver_api);
*/
DEVICE_DT_INST_DEFINE(0, &sens123_init, device_pm_control_nop,
&sens123_data, NULL, POST_KERNEL,
CONFIG_SENSOR_INIT_PRIORITY, &sens123_driver_api);
The device tree is based on the nRF52DK-nrf52832, and I added an overlay:
&i2c0{
sens123@23 {
compatible = "nec,sens123";
label = "SENS123";
reg = < 0x23 >;
};
};
I put a basic .yaml binding in the zephyr/dts/binding/sensor folder, with the appropriate name. And here is the prj.conf:
CONFIG_LOG=y CONFIG_I2C=y CONFIG_SENSOR=y CONFIG_SENS123=y
In the app folder, I have a folder called drivers. Then a folder called sens123 with the sens123.c inside. At all levels, I put the appropriate Kconfig and CMakeLists.txt.*
I am certainly missing something very basic but, for the life of me, I can't figure out what.
I would be very grateful for any help you can bring me. Feel free to ask me about any additionnal information you may need.
Best regards,