Migrating to SDK 2.0.0 caused my CS pin to stop working on my SPI

Was using SDK 1.9.1 up till now, but I migrated to SDK 2.0.0 and I changed my overlay file to add the pin control stuff.  I have a nrf5340 and use the app_ns board config.

This is the overlay file


&pinctrl {

    spi2_default: spi2_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 26)>,
                <NRF_PSEL(SPIM_MISO, 0, 10)>,
                <NRF_PSEL(SPIM_MOSI, 1, 5)>;
        };
    };

    spi2_sleep: spi2_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 26)>,
                <NRF_PSEL(SPIM_MISO, 0, 10)>,
                <NRF_PSEL(SPIM_MOSI, 1, 5)>;
            low-power-enable;
        };
    };

};

&spi2 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    pinctrl-0 = <&spi2_default>;
    pinctrl-1 = <&spi2_sleep>;
    pinctrl-names = "default", "sleep";
    cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};

This is a C file

static const struct device * spi_dev;

static struct spi_cs_control spi_cs = {
    .gpio_dev = NULL,
    .gpio_pin = 25,
    .gpio_dt_flags = GPIO_ACTIVE_LOW,
    .delay = 0,
  };

static struct spi_config spi_cfg = {
  .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,// |
        // SPI_MODE_CPOL | SPI_MODE_CPHA,
  .frequency = 8000000,
  .slave = 0,
  .cs = &spi_cs,
};
spi_dev = device_get_binding("SPI_2");

    int err;
    static uint8_t tx_buffer[3];
    static uint8_t rx_buffer[3];
    const struct spi_buf tx_buf = {
        .buf = tx_buffer,
        .len = sizeof(tx_buffer)
    };
    const struct spi_buf_set tx = {
        .buffers = &tx_buf,
        .count = 1
    };

    struct spi_buf rx_buf = {
        .buf = rx_buffer,
        .len = sizeof(rx_buffer),
    };
    const struct spi_buf_set rx = {
        .buffers = &rx_buf,
        .count = 1
    };

    tx_buffer[0] = 0x00;
    tx_buffer[1] = 0x80; // write
    rx_buffer[2] = 0x00;
err = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);

So that code used to make the CS line work during communication.  The 1.9.1 overlay file used to look like this

&spi2 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    sck-pin = <26>;
    mosi-pin = <37>;
    miso-pin = <10>;
    cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};

And I took away the pin config lines for the new pin control stuff. 

Any idea what I'm doing wrong or what I'm missing?  I watch the pins on a logic analyzer and the CS line gets configured and goes high and then never goes low. 

Also

I was looking through here

https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.0.0/zephyr/hardware/peripherals/spi.html

 

And saw this

struct spi_cs_controlÁ

#include <spi.h>

SPI Chip Select control structure.

This can be used to control a CS line via a GPIO line, instead of using the controller inner CS logic.

 

So I can use the controller inner CS logic?  How do I do that?  Was I always using the GPIO line?  

Parents
  • So I think I found the answer on my own. 

    This seems to work, I have commended out the old stuff and left in the new stuff


    static struct spi_cs_control spi_cs = {
        // this is the new hottness
        .gpio.pin = 18,
        .gpio.dt_flags = GPIO_ACTIVE_LOW,

        // below is the old depricated way
        // .gpio_dev = NULL,
        // .gpio_pin = 18,
        // .gpio_dt_flags = GPIO_ACTIVE_LOW,
        // .delay = 0,
      };
        // old and busted
        //spi_cs.gpio_dev = gpioPort0;
        // new hottness
        spi_cs.gpio.port = gpioPort0;

    This is from SPI.H

    struct spi_cs_control {
        /**
         * GPIO devicetree specification of CS GPIO.
         * The device pointer can be set to NULL to fully inhibit CS control if
         * necessary. The GPIO flags GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be
         * equivalent to SPI_CS_ACTIVE_HIGH/SPI_CS_ACTIVE_LOW options in struct
         * spi_config.
         */
        union {
            struct gpio_dt_spec gpio;
            struct {
                const struct device *gpio_dev __deprecated;
                gpio_pin_t gpio_pin __deprecated;
                gpio_dt_flags_t gpio_dt_flags __deprecated;
            };
        };
        /**
         * Delay in microseconds to wait before starting the
         * transmission and before releasing the CS line.
         */
        uint32_t delay;
    };

    And this is from GPIO.H

    /**
     * @brief Container for GPIO pin information specified in devicetree
     *
     * This type contains a pointer to a GPIO device, pin number for a pin
     * controlled by that device, and the subset of pin configuration
     * flags which may be given in devicetree.
     *
     * @see GPIO_DT_SPEC_GET_BY_IDX
     * @see GPIO_DT_SPEC_GET_BY_IDX_OR
     * @see GPIO_DT_SPEC_GET
     * @see GPIO_DT_SPEC_GET_OR
     */
    struct gpio_dt_spec {
        /** GPIO device controlling the pin */
        const struct device *port;
        /** The pin's number on the device */
        gpio_pin_t pin;
        /** The pin's configuration flags as specified in devicetree */
        gpio_dt_flags_t dt_flags;
    };

    I think they want us to use the gpio_dt_spec struct from now on, not the old structure in that union.

  • Thank you for this!

    I've had this on my todo list because they removed gpio_dev in 2.1.0 and I didn't notice that all I had to do was this one line change.

    "port" is a bad name for a device

    THANK YOU!

Reply Children
No Data
Related