[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

  • Hi,

     

    This is your current DT setup:

    &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>;
      };

     

    You should move the non-standard SPI properties to your sensor definition, ie:

    &spi3 {
      status = "okay";
      compatible = "nordic,nrf-spim";
      ...
    
    
      ssd1333: ssd1333@0 {
          compatible = "solomon,ssd1333";
          ...
          reset-pin = < &gpio0 28 GPIO_ACTIVE_LOW >;
          data-ctrl-pin = <&gpio0 30 GPIO_ACTIVE_LOW>;
      };

     

    Similar to how it's done in ssd1306:

    https://github.com/nrfconnect/sdk-zephyr/blob/v3.1.99-ncs1-rc1/boards/shields/ssd1306/ssd1306_128x64_spi.overlay#L29-L30

     

    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)?

    spi3 is 32M capable, but I would strongly recommend that you test on lower speeds to ensure that your driver works first.

    32M speed also has strict requirements wrt. pcb trace length and the GPIOs used needs to be set in high-drive (configured in NRF_Px->PIN_CNF[] register)

       

    Kind regards,

    Håkon

  • 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)

  • Hi,

     

    It is hard to test on my end, as you're developing your own driver, and I do not have the build artifacts to look at.

    What you can try is to rather address the variable like this and see if this helps?

    DT_PROP(DT_NODELABEL(ssd1333), width)

     

    Kind regards,

    Håkon

Related