[nRF52840] SPI data control pin definition (.dts)

Hi,

I'm porting my SSD1333 (Solomon IC for OLED displays) code driver to Zephyr OS drivers for ease of use along with LVGL (going from `<nrfx_spim.h>` to `<drivers/spi.h>`).

Actually, I want to know if there is way of defining custom bindings so I can define a Data Control pin into SPI device tree definition that I can retrieve from the driver code ?

Here is the current progress:

.dts file of project that wish to use this driver

&spi3 {
  status = "okay";
  device_type = "spi";
  compatible = "nordic,nrf-spim";
  sck-pin = < 5 >;
  mosi-pin = < 32 >;
  data-ctrl-pin = <&gpio0 30 GPIO_ACTIVE_LOW>;
  clock-frequency = <8000000>;
  cs-pin = < &gpio1 8 GPIO_ACTIVE_LOW >;
  reset-pin = < &gpio0 28 GPIO_ACTIVE_LOW >;

  ssd1333: ssd1333@0 {
      compatible = "solomon,ssd1333";
      status = "okay";
      reg = < 0x0 >;
      label = "OLED_DISPLAY";
      spi-max-frequency = < 0x16e3600 >;
      width = <160>;
      height = <128>;
  };
};

ssd1333.c driver definition - extraction of dts configuration :

#define DT_DRV_COMPAT solomon_ssd1333

// [Driver display's API methods definition]

static const struct ssd1333_config ssd1333_config = {
#if DT_INST_ON_BUS(0, i2c)
  .bus = I2C_DT_SPEC_INST_GET(0),
#elif DT_INST_ON_BUS(3, spi)
  .bus = SPI_DT_SPEC_INST_GET(
    3, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0),
  .dc_gpio = GPIO_DT_SPEC_INST_GET(0, data_ctrl_pin),
  .mosi_gpio = GPIO_DT_SPEC_INST_GET_OR(0, mosi_pin, { 0 })
  .sck_gpio = GPIO_DT_SPEC_INST_GET_OR(0, sck_pin, { 0 })
  .cs_gpio = GPIO_DT_SPEC_INST_GET_OR(0, cs_pin, { 0 })
#endif
  .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(0, reset_pin, { 0 })
};

For now, the following error comes up:

devicetree error: 'data-ctrl-pin' appears in /soc/spi@4002f000 in /Users/x/developpement/Quantum/build/zephyr/zephyr.dts.pre, but is not declared in 'properties:' in /opt/nordic/ncs/v2.0.2/zephyr/dts/bindings/spi/nordic,nrf-spim.yaml
CMake Error at /opt/nordic/ncs/v2.0.2/zephyr/cmake/modules/dts.cmake:213 (message):
  gen_defines.py failed with return code: 1

Also, if I use this spi3 on nRF52840 that way, will I be able to set the max 32MHz clock over SPI (and Easy DMA but I think not)?

Finally, if you have tips or you think I'm going on the wrong way, let me know !

Thanks for your time.

FYI, I'm following the ssd1306 sample from nordic/ncs/v2.0.2/zephyr/drivers/display

Parents
  • Thanks, applying this logic makes more sense :)

    But now, just another error comes up about the custom properties :

    In file included from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/arch/arm/aarch32/arch.h:20,
                     from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/arch/cpu.h:19,
                     from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/kernel_includes.h:33,
                     from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/kernel.h:17,
                     from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/init.h:11,
                     from /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/device.h:29,
                     from /opt/nordic/ncs/v2.0.2/zephyr/drivers/display/ssd1333.c:13:
    /opt/nordic/ncs/v2.0.2/zephyr/drivers/display/ssd1333.c: In function 'ssd1333_get_capabilities':
    /opt/nordic/ncs/v2.0.2/zephyr/include/zephyr/devicetree.h:305:40: error: 'DT_N_INST_3_solomon_ssd1333_P_width' undeclared (first use in this function)
      305 | #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat))
          | 

    On the related driver's function : 

    static void ssd1333_get_capabilities(const struct device *dev, struct display_capabilities *caps) {
      memset(caps, 0, sizeof(struct display_capabilities));
      caps->x_resolution = DT_INST_PROP(3, width);
      caps->y_resolution = DT_INST_PROP(3, height);
      caps->supported_pixel_formats = PIXEL_FORMAT_RGB_565;
      caps->current_pixel_format = PIXEL_FORMAT_RGB_565;
      caps->screen_info = 0;
      caps->current_orientation = DISPLAY_ORIENTATION_NORMAL;
    }

    I'm trying to see any difference between the ssd1306 sample but still can't find any :/

    Do you have an idea ? Where should I also define those ? 

    EDIT: I've changed slightly the driver file to align with the ssd16xx one and the error is gone for now :

    caps->x_resolution = config->width; // instead of DT_INST_PROP(0, width);...
    caps->y_resolution = config->height;

    Still others error but will go into it and let you know the final outcome Slight smile

  • Have you checked that "width" and "height" is described in your ssd1333-common.yaml file?

    Can you share your build-folder/zephyr/zephyr.dts file?

     

    Kind regards,

    Håkon

  • Sure, I've got an overlay file that describes:

    /*
    * nRF52840_dk      SSD1333 (160x128)
    * 
    * P0.28 (RESET)   RES
    * P0.30 (D5)      DC (DATA/CMD)
    * P0.5 (SCK)      SCL
    * P1.0 (MOSI)     SDA
    * P1.08 (CS)      SDA
    */
    
    / {
      chosen {
        zephyr,display = &ssd1333;
      };
    };
    
    &pinctrl {
     spi3_default: spi3_default {
       group1 {
         psels = <NRF_PSEL(SPIM_SCK, 0, 5)>,
           <NRF_PSEL(SPIM_MOSI, 0, 32)>,
           <NRF_PSEL(SPIM_MISO, 0, 31)>;
       };
     };
    
     spi3_sleep: spi3_sleep {
       group1 {
         psels = <NRF_PSEL(SPIM_SCK, 0, 5)>,
           <NRF_PSEL(SPIM_MOSI, 0, 32)>,
           <NRF_PSEL(SPIM_MISO, 0, 31)>;
         low-power-enable;
       };
     };
    };
    
    &spi3 {
      compatible = "nordic,nrf-spim";
      status = "okay";
      pinctrl-0 = <&spi3_default>;
      pinctrl-1 = <&spi3_sleep>;
      cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
      pinctrl-names = "default", "sleep";
    
      ssd1333: ssd1333@0 {
        compatible = "solomon,ssd1333";
        label = "SSD1333";
        spi-max-frequency = <20000000>;
        reg = <0>;
        cmd-data-pin = <&gpio0 30 GPIO_ACTIVE_LOW>;
        reset-pin = < &gpio0 28 GPIO_ACTIVE_LOW >;
        width = <160>;
        height = <128>;
        x-offset = <0>;
        y-offset = <0>;
        vcom = <0x19>;
        gctrl = <0x35>;
      };
    };

    Otherwise, I don't have any ssd1333-common.yaml file (as I don't see any on displays drivers and samples)

Reply
  • Sure, I've got an overlay file that describes:

    /*
    * nRF52840_dk      SSD1333 (160x128)
    * 
    * P0.28 (RESET)   RES
    * P0.30 (D5)      DC (DATA/CMD)
    * P0.5 (SCK)      SCL
    * P1.0 (MOSI)     SDA
    * P1.08 (CS)      SDA
    */
    
    / {
      chosen {
        zephyr,display = &ssd1333;
      };
    };
    
    &pinctrl {
     spi3_default: spi3_default {
       group1 {
         psels = <NRF_PSEL(SPIM_SCK, 0, 5)>,
           <NRF_PSEL(SPIM_MOSI, 0, 32)>,
           <NRF_PSEL(SPIM_MISO, 0, 31)>;
       };
     };
    
     spi3_sleep: spi3_sleep {
       group1 {
         psels = <NRF_PSEL(SPIM_SCK, 0, 5)>,
           <NRF_PSEL(SPIM_MOSI, 0, 32)>,
           <NRF_PSEL(SPIM_MISO, 0, 31)>;
         low-power-enable;
       };
     };
    };
    
    &spi3 {
      compatible = "nordic,nrf-spim";
      status = "okay";
      pinctrl-0 = <&spi3_default>;
      pinctrl-1 = <&spi3_sleep>;
      cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
      pinctrl-names = "default", "sleep";
    
      ssd1333: ssd1333@0 {
        compatible = "solomon,ssd1333";
        label = "SSD1333";
        spi-max-frequency = <20000000>;
        reg = <0>;
        cmd-data-pin = <&gpio0 30 GPIO_ACTIVE_LOW>;
        reset-pin = < &gpio0 28 GPIO_ACTIVE_LOW >;
        width = <160>;
        height = <128>;
        x-offset = <0>;
        y-offset = <0>;
        vcom = <0x19>;
        gctrl = <0x35>;
      };
    };

    Otherwise, I don't have any ssd1333-common.yaml file (as I don't see any on displays drivers and samples)

Children
Related