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

nrf9160 SPI slave issues (SDK version 1.4.0)

Hi,

I'm having problem using SPIS on nrf9160. The data/clock from master looks clean on scope, but 91 is not receiving the data. Interestingly, when I connect a debugger, SPIS signals transactions (LED toggles), but still no actual data is present in the buffer. My device tree looks like this (that's a custom board):

&spi2 { 
    compatible = "nordic,nrf-spis";
	status = "okay";
	sck-pin = <30>;
	mosi-pin = <29>;
	miso-pin = <28>;
	csn-pin = <27>;
	def-char = <0xFF>;
};

I'm quite confident the pins are right, verified this by using them as GPIO.

The code is:

#include <logging/log.h>

#include <zephyr.h>
#include <kernel.h>

#include <stdio.h>
#include <drivers/gpio.h>
#include <string.h>
#include <drivers/spi.h>

LOG_MODULE_REGISTER(SLM_MAIN, LOG_LEVEL_DBG);

const struct device *led_dev, *spis_dev;
struct spi_config spi_config = {
    .frequency = 1000000,
    .operation = SPI_OP_MODE_SLAVE | SPI_TRANSFER_LSB | ((8<<SPI_WORD_SIZE_SHIFT)&SPI_WORD_SIZE_MASK) | SPI_LINES_SINGLE,
    .slave = 0,
    .cs = NULL,
};

static char rxbuf[9];

void main(void) {
    printk("Hello, world!\n");
    led_dev = device_get_binding("GPIO_0");
    gpio_pin_configure(led_dev, 23, GPIO_OUTPUT);
    gpio_pin_set(led_dev, 23, 1);

    spis_dev = device_get_binding("SPI_2");

    rxbuf[8] = '\0';
    static struct spi_buf rxbuf_d = {.buf = rxbuf, .len = sizeof(rxbuf)-1};
    static struct spi_buf_set rxbufs = { .buffers = &rxbuf_d, .count = 1 };
    
    static struct k_poll_signal signal;
    k_poll_signal_init(&signal);
    static struct k_poll_event event = K_POLL_EVENT_INITIALIZER(
            K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &signal);
                
    for(;;) {
        printk("Trying to read..\n");

        signal.signaled = 0;
        event.state = K_POLL_STATE_NOT_READY;
        spi_read_async(spis_dev, &spi_config, &rxbufs, &signal);
        k_poll(&event, 1, K_FOREVER);
        
        printk("Got: %8s\n",rxbuf);
        gpio_pin_toggle(led_dev, 23);
    }
}

What I have tried so far:

  • Disconnect CSN pin (set it to 0x80000000) - no signal even if the debugger is connected.
  • Using spi2/spi3 - no change.
  • Using sync/async API - no change.

Ozone SPIS register dump (no CSN):

Level,Name,Value,Description
  2,SPIS2_NS,31 Registers,SPI Slave 4
   3,TASKS_ACQUIRE,0x00000000,Acquire SPI semaphore
   3,TASKS_RELEASE,0x00000000,Release SPI semaphore  enabling the SPI slave to acquire it
   3,SUBSCRIBE_ACQUIRE,0x00000000,Subscribe configuration for task ACQUIRE
   3,SUBSCRIBE_RELEASE,0x00000000,Subscribe configuration for task RELEASE
   3,EVENTS_END,0x00000000,Granted transaction completed
   3,EVENTS_ENDRX,0x00000000,End of RXD buffer reached
   3,EVENTS_ACQUIRED,0x00000000,Semaphore acquired
   3,PUBLISH_END,0x00000000,Publish configuration for event END
   3,PUBLISH_ENDRX,0x00000000,Publish configuration for event ENDRX
   3,PUBLISH_ACQUIRED,0x00000000,Publish configuration for event ACQUIRED
   3,SHORTS,0x00000004,Shortcuts between local events and tasks
   3,INTENSET,0x00000402,Enable interrupt
   3,INTENCLR,0x00000402,Disable interrupt
   3,SEMSTAT,0x00000000,Semaphore status register
   3,STATUS,0x00000000,Status from last transaction
   3,ENABLE,0x00000002,Enable SPI slave
   3,CONFIG,0x00000001,Configuration register
   3,DEF,0x000000FF,Default character. Character clocked out in case of an ignored transaction.
   3,ORC,0x000000FF,Over-read character
   3,SCK,0x0000001E,Pin select for SCK
   3,MISO,0x0000001C,Pin select for MISO signal
   3,MOSI,0x0000001D,Pin select for MOSI signal
   3,CSN,0xFFFFFFE0,Pin select for CSN signal
   3,PTR,0x20025B72,RXD data pointer
   3,MAXCNT,0x00000008,Maximum number of bytes in receive buffer
   3,AMOUNT,0x00000000,Number of bytes received in last granted transaction
   3,LIST,0x00000000,EasyDMA list type
   3,PTR,--------,TXD data pointer
   3,MAXCNT,--------,Maximum number of bytes in transmit buffer
   3,AMOUNT,--------,Number of bytes transmitted in last granted transaction
   3,LIST,--------,EasyDMA list type

And with CSN:

Level,Name,Value,Description
  2,SPIS2_NS,31 Registers,SPI Slave 4
   3,TASKS_ACQUIRE,0x00000000,Acquire SPI semaphore
   3,TASKS_RELEASE,0x00000000,Release SPI semaphore  enabling the SPI slave to acquire it
   3,SUBSCRIBE_ACQUIRE,0x00000000,Subscribe configuration for task ACQUIRE
   3,SUBSCRIBE_RELEASE,0x00000000,Subscribe configuration for task RELEASE
   3,EVENTS_END,0x00000001,Granted transaction completed
   3,EVENTS_ENDRX,0x00000001,End of RXD buffer reached
   3,EVENTS_ACQUIRED,0x00000001,Semaphore acquired
   3,PUBLISH_END,0x00000000,Publish configuration for event END
   3,PUBLISH_ENDRX,0x00000000,Publish configuration for event ENDRX
   3,PUBLISH_ACQUIRED,0x00000000,Publish configuration for event ACQUIRED
   3,SHORTS,0x00000004,Shortcuts between local events and tasks
   3,INTENSET,0x00000402,Enable interrupt
   3,INTENCLR,0x00000402,Disable interrupt
   3,SEMSTAT,0x00000001,Semaphore status register
   3,STATUS,0x00000000,Status from last transaction
   3,ENABLE,0x00000002,Enable SPI slave
   3,CONFIG,0x00000001,Configuration register
   3,DEF,0x000000FF,Default character. Character clocked out in case of an ignored transaction.
   3,ORC,0x000000FF,Over-read character
   3,SCK,0x0000001E,Pin select for SCK
   3,MISO,0x0000001C,Pin select for MISO signal
   3,MOSI,0x0000001D,Pin select for MOSI signal
   3,CSN,0x0000001B,Pin select for CSN signal
   3,PTR,0x20025B72,RXD data pointer
   3,MAXCNT,0x00000008,Maximum number of bytes in receive buffer
   3,AMOUNT,0x00000000,Number of bytes received in last granted transaction
   3,LIST,0x00000000,EasyDMA list type
   3,PTR,--------,TXD data pointer
   3,MAXCNT,--------,Maximum number of bytes in transmit buffer
   3,AMOUNT,--------,Number of bytes transmitted in last granted transaction
   3,LIST,--------,EasyDMA list type

Edit: updated to SDK version 15.99, no change.

Related