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

Use SPI to interface to SDcard under Zephyr

I'm attempting to connect an SDcard (micro SD) to an nRF52840-DK via a breadboard setup.   I'm running Zephyr and it appears that configuration is to be performed via device-tree.  I'm following one of the examples in the samples/subsys/fs/fat_fs directory.   I created a .overlay file with the following entry:

&spi2 {
  status = "okay";
  sck-pin = <33>; /* Port1, Pin1 */
  mosi-pin = <34>; /* Port1, Pin2 */
  miso-pin = <35>; /* Port1, Pin3 */
  cs-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* Port1 Pin4 */
  sdhc0: sdhc@0 {
    compatible = "zephyr,mmc-spi-slot";
    reg = <0>;
    status = "okay";
    label = "SDHC0";
    spi-max-frequency = <24000000>;
  };
};

Using a logic analyzer, I can see the SCK and MOSI pins change as expected, but the CS pin is stuck HIGH.  

Setting a breakpoint in initialization shows that the SPI SS pin has a value of 0xff (meaning it is unassigned). 

Searching further, it appears that the .ss_pin is hard-coded to "NOT_USED" in spi_nrfx_spi.c (line 378).   I'm not sure how the .ss (chip-select) pin is to be assigned in the Zephyr device-tree environment given this.  (I know how to set these pins up if configuring the SPI manually, but I got the impression that it is recommended that Zephyr use device-tree (.dts and .overlay files).

Thanks!

Edit:   I got a response on Zephyr/Slack that verified that the .overlay entry is correct.

However, it still doesn't work.   Tracing execution, I found that the existence of a CS GPIO is checked at line 842 of disk_access_spi_sdhc.c    Stepping through this code, it looks like data->cs.gpio_dev is assigned 0x0 at line 843.   The other entries of the cs structure appear to be correct.   Looking at zephyr.dts (in the build directory), it looks like @gpio0 and @gpio1 are both defined.

I need to understand why "device_get_binding(DT_SPI_DEV_CS_GPIOS_LABEL(SPI_SDHC_NODE))" is not returning a valid value.   But I can't find the definition of the macro DT_SPI_DEV_CS_GPIOS_LABEL...

Thanks...

Parents
  • Try setting CONFIG_GPIO=y in the prj.conf file

    The definition fo the macro DT_SPI_DEV_CS_GPIOS_LABEL is inside \zephyr\include\devicetree\spi.h


    I think device_get_binding(DT_SPI_DEV_CS_GPIOS_LABEL(SPI_SDHC_NODE)) gets converted into device_get_binding("GPIO_1"). You could try to call this direcly to se if this "device" is actually correctly set up. In order for this to succeed, gpio1 needs to get added into the device tree (it seems like this is okay for you since you found it in zephyr.dts) and the driver needs to get set up as well (set CONFIG_GPIO=y), which will define an init function (DEVICE_DT_DEFINE-->gpio_nrfx_init()). If the init function is not called or fails, the device will be declared not ready and the call to device_get_binding will fail.

    This is how I remembered how it worked, hopefully I got it correct :P 

    Best regards,

    Simon

  • Hi Simon,

    Thanks!   Adding CONFIG_GPIO=y   to prj.conf solved it.

    While it works, I still couldn't find the definition of DT_GPIO_LABEL_BY_IDX() which is in the define of DT_SPI_DEV_CS_GPIOS_LABEL()     (in devicetree/spi.h)  Yet it compiles!!   So it must be somewhere!

    I'm also confused when to use CONFIG statements vs defining things via device tree...   

    Thanks for your help!!!

  • CktDesigner said:
    While it works, I still couldn't find the definition of DT_GPIO_LABEL_BY_IDX() which is in the define of DT_SPI_DEV_CS_GPIOS_LABEL()     (in devicetree/spi.h)  Yet it compiles!!   So it must be somewhere!

    DT_GPIO_LABEL_BY_IDX is defined at zephyr\include\devicetree\gpio.h. I would recommend you to download Visual Studio Code, which allows you to open the whole NCS and search for variables/functions/macros etc.. If you install Kconfig for the Zephyr Project and DeviceTree for the Zephyr Project you can use "Show Definition" to see where it's defined. As a sidenote, you could also open a Terminal in VS Code and do the actual development in the editor.

    CktDesigner said:
    I'm also confused when to use CONFIG statements vs defining things via device tree...   

    Stuff that is defined in the device tree has to do with hardware and hardware configuration. E.g. SDA and SCL pins, what UART baud rate to use, pins for LEDs and buttons and so on. The CONFIG statements are used for configuring everything else, what drivers an libraries and drivers to use and to enable other firmware specific features.

    Best regards,

    Simon

  • Ok, thanks...   I've been using Segger Embedded Studio...

    Thanks for your assistance!

Reply Children
No Data
Related