Struggling for several days to get SPI working w/ Zephyr

Hi, I can get ahold of the SPI device and call the spi_transceive function wihtout returning error codes.  Logic analyzer shows nothing happening, such as SCK clocking.  I am using the NRF52833-DK board.

In pj.conf:

CONFIG_SPI=y

In .dts:

can_spi: &spi1 {
    compatible = "nordic,nrf-spim";
    cs-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
    pinctrl-0 = <&spi1_default>;
    pinctrl-1 = <&spi1_sleep>;
    pinctrl-names = "default", "sleep";
};

&pinctrl {
    spi1_default: spi1_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 1, 1)>,
                <NRF_PSEL(SPIM_MISO, 1, 2)>,
                <NRF_PSEL(SPIM_MOSI, 1, 3)>;
        };
    };

    spi1_sleep: spi1_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 1, 1)>,
                <NRF_PSEL(SPIM_MISO, 1, 2)>,
                <NRF_PSEL(SPIM_MOSI, 1, 3)>;
            low-power-enable;
        };
    };
};
In C module for SPI transactions:

#include <stdint.h>
#include <string.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>                                                                                                                                                    
#include <zephyr/drivers/spi.h>
#include <zephyr/logging/log.h>

#include "spi_interface.h"

LOG_MODULE_REGISTER(spi_interface, LOG_LEVEL_INF);

static struct device * spi_dev;
static struct spi_buf tx_spi_buffer[1];
static struct spi_buf rx_spi_buffer[1];

static struct spi_config spi_cfg = {
    .frequency = 500000,
    .operation = SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
};

static const struct spi_buf_set api_tx_buff = { tx_spi_buffer, 1 };
static const struct spi_buf_set api_rx_buff = { rx_spi_buffer, 1 };

void spi_init(void)
{
    spi_dev = device_get_binding(DEVICE_DT_NAME(DT_NODELABEL(spi1)));

    if (spi_dev == NULL) {
        /* No such node, or the node does not have status "okay". */
        LOG_ERR("\nError: no device found.\n");
    }
    else if (!device_is_ready(spi_dev)) {
        LOG_ERR("\nError: Device \"%s\" is not ready; "
               "check the driver initialization logs for errors.\n",
               spi_dev->name);
    }
    else
    {
        LOG_INF("Found device \"%s\", getting sensor data\n", spi_dev->name);
    }
}

void spi_trx(uint8_t* tx_buf, uint8_t write_size, uint8_t* rx_buf, uint8_t read_size)
{
    tx_spi_buffer[0].buf = tx_buf;
    tx_spi_buffer[0].len = write_size;
 
    rx_spi_buffer[0].buf = rx_buf;
    rx_spi_buffer[0].len = read_size;

    int ret = spi_transceive(spi_dev,
                   &spi_cfg,
                   &api_tx_buff,
                   &api_rx_buff);

    if (ret < 0)
    {
        LOG_ERR("err code %d", ret);
    }
}
Parents Reply Children
  • Ben,

    bmalchow said:
    -Are you referring to the .ninja_log?  Will provide when certain.

    No, I am referring to the logger module that you are using in your code:

        if (ret < 0)
        {
            LOG_ERR("err code %d", ret);
        }

    Please see the documentation on Logging API. This will allow you to print issues into a UART terminal through the nRF52833DK.

    Have you tried going through our nRF Connect SDK Fundamentals course in DevAcademy?

    You could also look at this SPI master slave sample which my colleague Torbjørn has made.

    Kind regards,
    Øyvind

  • Oh, I missunderstood.  Yes, it is outputting a '0', which is success.  I am printing over UART to NRF console.  I'll have a look and get back.  Thanks!

  • Hi Øyvind,

    The sample project has been helpful!  I think I may have found an issue though.  I choose nrf52833dk_nrf52833 as my board as that is my dev board.  When making my overlay, all the references, such as &spi2, are referencing nrf52dk_nrf52832.dts.  Thi pins specified do not match the dev board I have so could this be a bug with nRF Connect?  I figured I'd ask.

    Aside from that, I cannot get the example to compile  I am getting this now:

    zephyr\include\zephyr\device.h:83:41: error: '__device_dts_ord_DT_N_NODELABEL_mcp2517fd_BUS_P_cs_gpios_IDX_DT_N_NODELABEL_mcp2517fd_REG_IDX_0_VAL_ADDRESS_PH_ORD' undeclared here (not in a function)
       83 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
          |                                         ^~~~~~~~~
    C:\Users\Bmalch01\ncs\v2.2.0\zephyr\include\zephyr\device.h:209:37: note: in expansion of macro 'DEVICE_NAME_GET'
      209 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
          |                                     ^~~~~~~~~~~~~~~
    C:\Users\Bmalch01\ncs\v2.2.0\zephyr\include\zephyr\device.h:226:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
      226 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))

    It cannot get a reference to the CS pin.  I had to add some tweaks to get the overlay to not have errors.  I'll highlight those:

    &pinctrl {
        spi0_default: spi0_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 31)>,
                        <NRF_PSEL(SPIM_MOSI, 0, 30)>,
                        <NRF_PSEL(SPIM_MISO, 0, 29)>;
            };
        };

        spi0_sleep: spi0_sleep {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 31)>,
                        <NRF_PSEL(SPIM_MOSI, 0, 30)>,
                        <NRF_PSEL(SPIM_MISO, 0, 29)>;
                low-power-enable;
            };
        };
    };

    can_spi: &spi0 {
        compatible = "nordic,nrf-spi";
        status = "okay";
        pinctrl-0 = <&spi1_default>;
        pinctrl-1 = <&spi1_sleep>;
        cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
        mcp2517fd: spi-dev-a@0 {
            //added this
    compatible = "spi-device";
            reg = <0>;
    //added this
            spi-max-frequency = < 500000 >;
        };
    };
  • Forgot to add this as it shows where the error is being generated:

    struct spi_cs_control spim_cs = {
        .gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(mcp2517fd)),
        .delay = 0,
    };
  • It looks like I missed some steps in West.  I think this can be closed and I have to go back and familiarize myself with the initial env. setup.  Thanks for the SPI example though!  It was useful.

Related