How to implement SPIM in net core (nRF5340) - No SPI signal detedted

Hi there,

I have a problem to implement the SPIM in the Network core. I cannot detect any signal from SPI_SCK & SPI_MOSI by oscilloscope and logic analyzer (no signal from other two pins SS & MISO either)
Is there anything I need to configure to enable the SPIM in Network node?

I flashed the "peripheral_uart" example code to nrf5340,
And I wrote a simple code to test the SPIM functionality (signal output in SCK and MOSI)
It is the main.c for network core.

Here's my code:

main.c

#include <zephyr.h>
#include <sys/printk.h>
#include <logging/log.h>

#include "spi_driver.h"
// #include "Adafruit_NeoPixel.h"
#include <logging/log.h>

#define API_LOG_NAME ReaderAPI
LOG_MODULE_REGISTER(API_LOG_NAME);

void main(void)
{
	LOG_INF("Hello!\n");

        int inx = 0;
        spi_open(4000000);

        k_msleep(1000);

        nrf_spi_write("hello",5);

        while(1){
          //LOG_INF("Hello World!%d\n",inx++);
          k_msleep(500);
        }
}

spi_driver.c

#include "spi_driver.h"
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


#include <zephyr.h>
#include <device.h>
#include "hal/nrf_gpio.h"
#include <devicetree.h>
#include <drivers/gpio.h>
#include <logging/log.h>
#include <drivers/spi.h>

uint32_t default_clock_freq_hz = 8000000u;

#define SPI_DEVICE_NAME "SPI_0"
#define PIN_SPIM_CS     16
#define DELAY_SPI_CS_ACTIVE_US 3
#define TEST_STRING     "Nordic"

const struct device *spi_dev;

struct spi_cs_control *cs_ctrl = 
          &(struct spi_cs_control){
                   .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
                   .delay    = DELAY_SPI_CS_ACTIVE_US,
                   .gpio_pin = PIN_SPIM_CS,
                   .gpio_dt_flags = GPIO_ACTIVE_LOW
          };


int spi_data_exchange(void* tx_buff, size_t length)
{
  int err;
  struct spi_config spi_cfg={0};

  spi_cfg.frequency = default_clock_freq_hz;
  spi_cfg.operation = SPI_WORD_SET(8)|!SPI_MODE_CPOL | SPI_MODE_CPHA|SPI_TRANSFER_MSB;

  spi_cfg.cs = cs_ctrl;

  struct spi_buf spi_buf[1] = {
          {
            .buf = tx_buff,
            .len = length,
          }
  };

  const struct spi_buf_set tx_set = {
          .buffers = spi_buf,
          .count = 1,
  };

  int i = 0;
  do{
   err = spi_transceive(spi_dev,&spi_cfg,&tx_set,NULL);
  }while(i--);
  if(err){
    printk("spi transcation failed err %d",err);
  }
  else{
    return tx_set.buffers->len;
  }
  return err;
}

int32_t spi_read_data(void* rx_buff, size_t length)
{
 int err;
  struct spi_config spi_cfg={0};

  spi_cfg.frequency = default_clock_freq_hz;
  spi_cfg.operation = SPI_WORD_SET(8)|!SPI_MODE_CPOL | SPI_MODE_CPHA|SPI_TRANSFER_MSB;

  struct spi_cs_control *cs_ctrl = 
          &(struct spi_cs_control){
                   .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
                   .delay    = DELAY_SPI_CS_ACTIVE_US,
                   .gpio_pin = PIN_SPIM_CS,
                   .gpio_dt_flags = GPIO_ACTIVE_LOW
          };
  spi_cfg.cs = cs_ctrl;
 
  struct spi_buf spi_rxbuf[1] = {
          {
            .buf = rx_buff,
            .len = length,
          }
  };

  const struct spi_buf_set rx_set = {
          .buffers = spi_rxbuf,
          .count   = 1,
  };

  do{
    err = spi_transceive(spi_dev,&spi_cfg,NULL,&rx_set);
  }while(0);

  if(err){
    return 0;
  }else{
    return rx_set.buffers->len;
  }
}

int32_t nrf_spi_read(void* rx_buff, size_t length)
{
  int ret;
  ret = spi_read_data(rx_buff,length);
  return ret;
}

int32_t nrf_spi_write(const void* tx_buff, size_t length)
{
  int ret;
  ret = spi_data_exchange(tx_buff,length);
  return ret;
}

int32_t spi_open(uint32_t clock_freq_hz)
{
  default_clock_freq_hz = clock_freq_hz;


  spi_dev = device_get_binding(SPI_DEVICE_NAME);
  if(!spi_dev){          
    return -1;
  }
  return 0;

}
void spi_close(void)
{
  /*do nothing*/
}

prj.conf

#spi
CONFIG_SPI=y
CONFIG_NRFX_SPIM=y
CONFIG_NRFX_SPIM0=y


#include NEWLIB_LIBC for math.h
CONFIG_NEWLIB_LIBC=y

CONFIG_UART_CONSOLE=n
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

nrf5340dk_nrf5340_cpunet.overlay

&spi0 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	
	sck-pin = <30>;
	mosi-pin = <42>;
	miso-pin = <10>;
	clock-frequency = <4000000>;
	
};

&uart0 {
	status = "disabled";
};

After flashed,the RTT always display " <err> spi_nrfx_spim: Timeout waiting for transfer complete"message,

How do I adjust my code?Or where can I find the network core SPIM's samples?

  • Hi,

    Which version of the nRF Connect SDK are you using?

    What is flashed to the application core?

    Try this:

    Remove the lines in your overlay where you change the pins and use the default pins, 45, 46 and 47. These correspond to P1.13, P1.14 and P1.15.

    Do a pristine build of your network core application and flash it to the network core.

    Build the empty_app_core sample found at nrf/samples/nrf5340/empty_app_core and flash it to the application core.

    Flashing the network core before the application core is important.

    Then see what you get on the pins and in the log.

  • Hi,

    Thanks for your quick reply.

    My nRF Connect SDK is v1.8.0.I tried your suggestion and removed part of spi0 content in overlay file. Before burning the network core program, I burned the program "empty_app_core" to the application core, but SPI still did not work. The following is the log information:

  • Hi,

    Thanks for your help,The problem has been solved,I made a mistake just now. When removing the spi Pin setting in Overlay file, the enable of spi0 was also commented out. Now SPI0 can output signal normally. The GPIO and UART of the application core are also required for the application.

Related