This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF5340 - DAC driver in Zephyr

Hi,
to develop a device driver in Zephyr for TI DAC80501, a 16-bit DAC, I2C interface,
I have to
1. add the dts child node under the i2c controller node

  $i2c1 {
       dac80501@48 {
           compatible = "ti,dac80501";
           reg = <0x48>;
       };
  };
2. find a devicetree binding corresponding to the node's compatible property
3. write the driver in zephyr/drivers/adc/
Could anybody help me following through 2. and 3.
Thank you
Parents
  • Do you have any more specific questions regarding 1 and 2? How far have you come with the implementation?

    I would recommend reading Device Driver Model and understand that, which will give you a great starting point. Then I would look at the already present Sensor drivers and try to mirror them. E.g. if you use the adxl362 as a reference, look at the yaml file zephyr\dts\bindings\sensor\adi,adxl362.yaml, the driver in zephyr\drivers\sensor\adxl362 and the sample zephyr\samples\sensor\adxl362 which shows how to use that driver. The sample doesn't interract with the adxl362 driver directly but uses the Sensor Subsystem on top of that. Take a look at the figure below to see all the abstraction layers included:

    There may be some step-by-step tutorials on how to do this, but I couldn't find it after a quick search.

    Since this is a more Zephyr related question, you may get better help here:

    Best regards,

    Simon

Reply
  • Do you have any more specific questions regarding 1 and 2? How far have you come with the implementation?

    I would recommend reading Device Driver Model and understand that, which will give you a great starting point. Then I would look at the already present Sensor drivers and try to mirror them. E.g. if you use the adxl362 as a reference, look at the yaml file zephyr\dts\bindings\sensor\adi,adxl362.yaml, the driver in zephyr\drivers\sensor\adxl362 and the sample zephyr\samples\sensor\adxl362 which shows how to use that driver. The sample doesn't interract with the adxl362 driver directly but uses the Sensor Subsystem on top of that. Take a look at the figure below to see all the abstraction layers included:

    There may be some step-by-step tutorials on how to do this, but I couldn't find it after a quick search.

    Since this is a more Zephyr related question, you may get better help here:

    Best regards,

    Simon

Children
  • Hi Simon,

    I have a custom board based on nRF5340. I have SDA connected to pin P1.02 and SCL connected to pin P1.03.
    I've made some progress following your suggestions.

    1. The DTS section of the board looks like this

       &i2c1 {
          compatible = "nordic,nrf-twim";
          status = "okay";
          clock-frequency = <100000>;
          sda-pin = <33>;
          scl-pin = <34>;
          dac: dacx0501@48 {
             compatible = "ti,dacx0501";
             label = "DAC80501";
             reg = <0x48>;
          };
       };

    2. For the binding part I've added file /ncs/zephyr/dts/bindings/sensor/ti,dacx0501.yaml with content

       description: Texas Instruments 12/14/16-bit DAC (e.g. DAC80501)
       compatible: "ti,dacx0501"
       include: i2c-device.yaml

    (You might wander why to put a DAC into sensor branch. This is just a temporary measure.)

    3. For the driver part I've added files under /ncs/zephyr/drivers/sensors/dacx0501/

       dacx0501.c
       dacx0501.h
       Kconfig

    At the very first I2C reading from device

       if (i2c_read(drv_data->i2c, buf, 4, DT_INST_REG_ADDR(0)) < 0) {
          LOG_ERR("Failed to read sample data");
          return -EIO;
       }

    I get an error log message

       E: Error 195952641 occurred for message 0

    which correspondes to error number 0xBAE0000, or "NRFX_ERROR_DRV_TWI_ERR_ANACK".

    Can you figure out how to fix this ?

    Best Regards,
    Gabriele

  • Additional information you might find of worth

    DT_INST_REG_ADDR(0) expands to 72

    As for the zephyr configuration added to prj.conf

    CONFIG_I2C=y
    CONFIG_I2C_1=y
    CONFIG_SENSOR=y
    CONFIG_DACX0501=y

    Regards,
    Gabriele

  • My bad mistake! The correct gpio numbers are
    sda-pin = <34>;
    scl-pin = <35>;
    This issue is closed.

  • I've been working on adding a new sensor.

    This ticket has been very helpful.

    Just thought I should add for others that you'll also want to modify these files when adding a new sensor

    • \zephyr\drivers\sensor\CMakeLists.txt

    add_subdirectory_ifdef(CONFIG_<name of sensor>   <sensor directory>)

    • Add this to \zephyr\drivers\sensor\Kconfig

    source "drivers/sensor/<sensor directory>/Kconfig"
  • Thank you, I definitely agree with your remark.
    My device is a DAC, then putting the driver into <zephyr>/drivers/dac is more appropriate.
    Hereinafter the complete process
    1) Under <zephyr>/drivers/dac/ add files
     dac_dacx0501.c
     dac_dacx0501.h
     Kconfig.dacx0501
    2) In <zephyr>/drivers/dac/CMakeLists.txt add the line
     zephyr_library_sources_ifdef(CONFIG_DAC_DACX0501    dac_dacx0501.c)
    3) In <zephyr>/drivers/dac/Kconfig add the line
     source "drivers/dac/Kconfig.dacx0501"
    4) In dac_dacx0501.c implement the I2C read/write functions
     int dacx501_reg_read()  to read a register
     int dacx501_reg_write() to overwrite a register
     int dacx501_init()  to initialize the driver and the device
     int dacx501_channel_setup() the standard API to open a DAC channel (I have only one)
     int dacx501_write_value() the standard API to write a value to DAC
    As for the application side <src>/main.c
    5) Include
     #include <include/device.h>
     #include <dac.h>
    6) Retrieve the device structure for a the DAC driver by name using
     struct device* device_get_binding()
    7) Create the structure for specifying the configuration of the DAC channel
     struct dac_channel_cfg
    8) Use it to configure the DAC channel with
     int dac_channel_setup()
    9) Finally you are able to write data to the DAC using
     int dac_write_value()
    Gabriele
Related