This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPI Master - Slave sample under zephyr

I can not get the SPI Slave function working on nRF52840 (nrf52840dk_nrf52840 board). My goal is to have spi0 as master and spi1 as slave.

By linking the MISO en MOSI lines, CS and clock lines, I want to send data from spi0 to spi1.

In the nrf52840dk_nrf52840.overlay I wrote:

&spi1 {
  compatible = "nordic,nrf-spis";
  label = "SPI_1";
  status = "okay";
  sck-pin = <31>;
  mosi-pin = <30>;
  miso-pin = <40>;
  csn-pin = <10>;
  def-char = <0xFF>;
};

&spi0 {
  compatible = "nordic,nrf-spim";
  label = "SPI_0";
  status = "okay";
  sck-pin = <27>; //p0.27
  mosi-pin = <26>; //p0.26
  miso-pin = <29>; //p0.29
};

In the pr.conf I wrote:

# adding SPI communication
CONFIG_SPI=y
CONFIG_SPI_SLAVE=y

In the main loop I wrote:

struct device * spi1;
struct device * spi0;
struct spi_config spi1_cfg;
struct spi_config spi0_cfg;

/* master buffers */
uint8_t spi0_rx_buffer[SPI_BUFFER_SIZE];
uint8_t spi0_tx_buffer[] = "Hello World";

struct spi_buf bufsm_r =
{
  .buf = &spi0_rx_buffer,
  .len = SPI_BUFFER_SIZE
};
struct spi_buf_set rxm =
{
  .buffers = &bufsm_r,
  .count = 1
};

struct spi_buf bufsm_t =
{
  .buf = &spi0_tx_buffer,
  .len = SPI_BUFFER_SIZE
};
struct spi_buf_set txm =
{
  .buffers = &bufsm_t,
  .count = 1
};

/* slaver buffers */
uint8_t spi1_rx_buffer[SPI_BUFFER_SIZE];
uint8_t spi1_tx_buffer[SPI_BUFFER_SIZE];

struct spi_buf bufss_r =
{
  .buf = &spi1_rx_buffer,
  .len = SPI_BUFFER_SIZE
};
struct spi_buf_set rxs =
{
  .buffers = &bufss_r,
  .count = 1
};

struct spi_buf bufss_t =
{
  .buf = &spi1_tx_buffer,
  .len = SPI_BUFFER_SIZE
};
struct spi_buf_set txs =
{
  .buffers = &bufss_t,
  .count = 1
};

#define CSN_PIN 11

int init_spi(void)
{
  csdev = device_get_binding("GPIO_0"); 
  if (!csdev) {
    printk("Could not find GPIO_0 driver\n");
    return -1;
  }
  gpio_pin_configure(csdev, CSN_PIN, GPIO_OUTPUT);
  gpio_pin_set(csdev, CSN_PIN, 1);

/* slave settings */
  spi1 = device_get_binding("SPI_1");
  if (!spi1) {
    printk("Could not find SPI 1 driver\n");
   return -1;
  }
  spi1_cfg.operation = SPI_WORD_SET(8) | SPI_OP_MODE_SLAVE;
  spi1_cfg.frequency = 1000000;

/* master settings */
  spi0 = device_get_binding("SPI_0");
  if (!spi0) {
    printk("Could not find SPI 0 driver\n");
    return -1;
  }

  spi0_cfg.operation = SPI_WORD_SET(8) | SPI_OP_MODE_MASTER;
  spi0_cfg.frequency = 1000000;


  rxm.count = 1;
  rxs.count = 1;

return 0;

}

void spi_slave_task(void)
{
  for( ; ; )
 {
   int rets = spi_transceive(spi1,&spi1_cfg,&txs,&rxs);
   LOG_INF("spi_transceive, slave mode reported %d",rets);
   if(rets > 0)
   {
     printk("Received: 0x%02X 0x%02X 0x%02X-- \n", spi1_rx_buffer[0],spi1_rx_buffer[1],spi1_rx_buffer[2]);
   }
 }
 k_msleep(10);
}

in the main loop, I just called 

...

  gpio_pin_set(csdev, CSN_PIN, 0);
  int retm = spi_transceive(spi0,&spi0_cfg,&txm,&rxm);
  gpio_pin_set(csdev, CSN_PIN, 1);
  LOG_INF("spi_transceive, master mode reported %d",retm);
  k_msleep(1000);

...

But in the slave task, I expected some data, however no data was received. Only  "Timeout waiting for transfer to complete"

Is there any hint how to get forward?

  • Hi,

    Based on the definitions found in zephyr\include\drivers\spi.h, you would need to make a change to your code

    struct spi_buf bufsm_r =
    {
    .buf = spi0_rx_buffer,
    .len = SPI_BUFFER_SIZE
    };

    Best regards,
    Dejan

  • Thanks for your reply.

    However, it is still not working for me.
    I try to start an receive action as soon as I see the chip select pin become active.
    The chip select pin (cs_active) is set by a GPIO interrupt and connected to a RPY acting as the SPI master.

    void spi_slave_task(void)
    {
        for( ; ; )
        {
            if(cs_active)
            {
                printk("chipselect_low detected\n"); 
                int rets = spi_transceive(spi1,&spi1_cfg,&txs,&rxs);
                LOG_INF("spi_transceive, slave mode reported %d",rets);
                if(rets > 0)
                {
                    printk("Received: 0x%02X 0x%02X 0x%02X-- \n", spi1_rx_buffer[0],spi1_rx_buffer[1],spi1_rx_buffer[2]); 
                }
                cs_active = 0;
            }
            k_msleep(1);
        }
    }

    Is there any SPI slave example available? The only examples I found are SPI master.
    Regards,
    Bob

  • Hi Bob,

    Please take a look at samples and this spi slave case.

    Best regards,
    Dejan

Related