Trouble with Zephyr SPI slave

Hi,

I've got a two-processor board (i.e. another processor in addition to the two-core nrf5340) where the other processor is sending data to my nrf5340 via SPI. The Nordic is the SPI slave.

*Oh, I'm currently using SDK version 1.5.1. I tried upgrading to the current 1.7.0 but the peripheral_uart example (which I'm using as my starting point) doesn't compile in that version. I get an error about a missing psa_crypto_slot_manager file or something? For now I'm just going to proceed with my v1.5.1 project unless someone thinks my issue was fixed in a newer version.

I can see the data on my logic analyzer. The clock is pretty quick (6.5MHz) but it looks like it should work.

I'm getting NRFX_SPIS_XFER_DONE interrupts, but the rx_amount is always 0.

In chasing the problem I was concerned about making sure that the pin setup macros worked for GPIO on port 1 because my chip select pin is pin 1.02. I found that none of the PSEL registers for SPIS0_NS are getting set to what I want them to, and I assume this is the source of my problem.

Here's the current state of my code:

#define GPIO_PORT_1_OFFSET 32

#define PIN_SCK            12
#define PIN_MOSI           22
#define PIN_MISO           20
#define PIN_CSN            GPIO_PORT_1_OFFSET + 2

#define SPIS_NR            0     // Using SPI0

#define SPI_BUFFER_SIZE    256

//== Global Variables ========================================================
nrfx_spis_t spi_slave_instance = NRFX_SPIS_INSTANCE(SPIS_NR);

nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(PIN_SCK,PIN_MOSI,PIN_MISO,PIN_CSN);

uint8_t rx_buffer[SPI_BUFFER_SIZE];
uint8_t tx_buffer[SPI_BUFFER_SIZE];

//== Function prototypes =====================================================
void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context);

//============================================================================

//----------------------------------------------------------------------------
// Name  :
// Desc  :
// Ins   : none
// Outs  : none
//----------------------------------------------------------------------------
void spi_comms_init(void)
{
   int err;

    err = nrfx_spis_init(&spi_slave_instance, &spis_config, spis_event_handler, NULL);
    if(err != NRFX_SUCCESS){
        LOG_WRN("Error with init.\n");
    } else {
        LOG_WRN("SPIS started.\n");
    }

    err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
    if(err != NRFX_SUCCESS)
    {
        LOG_WRN("Error with setting.\n");
    }

    IRQ_DIRECT_CONNECT(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, 0, nrfx_spis_0_irq_handler, 0);
    irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn);
}


//----------------------------------------------------------------------------
// Name  :
// Desc  :
// Ins   : none
// Outs  : none
//----------------------------------------------------------------------------
void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context)
{
    int err;
    switch(p_event->evt_type){
        case NRFX_SPIS_XFER_DONE:
            if (p_event->rx_amount > 0)
            {
               LOG_INF("received 0x%02x 0x%02x 0x%02x 0x%02x\n", rx_buffer[0], rx_buffer[1], rx_buffer[2], rx_buffer[3]);
            }
            
            //LOG_INF("Rx bytes: %u\n", p_event->rx_amount);
            err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
            if(err != NRFX_SUCCESS){
                LOG_WRN("Error with setting.\n");
            }
            break;
        case NRFX_SPIS_BUFFERS_SET_DONE:
            //LOG_WRN("buffers set\n");
            break;
        case NRFX_SPIS_EVT_TYPE_MAX:
        
            break;
        default:
            ;
    }
}

I wondered if it would make a difference if I tried to assign my pins using the project overlay file, so I added a prj.overlay file as follows - no difference in behavior

&spi0 {
	compatible = "nordic,nrf52-spis";
	label = "SPI_0";
	status = "okay";
	mosi-pin = <22>;
	miso-pin = <20>;
	sck-pin  = <12>;
	csn-pin  = <34>;
	def-char = <0xFF>;
};

I stopped the debugger as soon as I get to main and those SPIS0_NS PSEL values are there as soon as I hit my breakpoint, and none of my SPI setup code changes them. I also tried changing my prj.overlay to assign completely different pin numbers and that has no effect either.

Any ideas?

Thanks!

Glen

Parents
  • Well now it's working and I'm not certain what I did to make it so. I did upgrade to the 1.7.0 SDK. Anyway here's the code now in case anyone else is trying to get the nrfx_spis driver going.

    //== Includes ================================================================
    
    #include <nrfx.h>
    #include <zephyr/types.h>
    #include <zephyr.h>
    #include <drivers/spi.h>
    #include <string.h>
    #include "spi_comms.h"
    #include <nrfx_spis.h>
    #include <logging/log.h>
    
    //== Definitions and Types ===================================================
    #define LOG_MODULE_NAME peripheral_SPI
    LOG_MODULE_REGISTER(LOG_MODULE_NAME);
    
    #define GPIO_PORT_1_OFFSET 32
    
    #define PIN_SCK            12
    #define PIN_MOSI           22
    #define PIN_MISO           20
    #define PIN_CSN            GPIO_PORT_1_OFFSET + 2
    
    #define SPIS_NR            0     // Using SPI0
    
    #define SPI_BUFFER_SIZE    255
    
    //== Global Variables ========================================================
    nrfx_spis_t spi_slave_instance = NRFX_SPIS_INSTANCE(SPIS_NR);
    
    nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(PIN_SCK,PIN_MOSI,PIN_MISO,PIN_CSN);
    
    uint8_t rx_buffer[SPI_BUFFER_SIZE];
    uint8_t tx_buffer[SPI_BUFFER_SIZE];
    
    //== Function prototypes =====================================================
    void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context);
    
    //============================================================================
    
    //----------------------------------------------------------------------------
    // Name  : spi_comms_init
    // Desc  : Configure the SPI slave device using the nrfx_spis driver
    // Ins   : none
    // Outs  : none
    //----------------------------------------------------------------------------
    void spi_comms_init(void)
    {
       int err;
    
       nrf_spis_disable(spi_slave_instance.p_reg);
    
       err = nrfx_spis_init(&spi_slave_instance, &spis_config, spis_event_handler, NULL);
       if(err != NRFX_SUCCESS)
       {
          LOG_WRN("Error with init.\n");
       } else 
       {
          LOG_WRN("SPIS started.\n");
       }
     
       err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
       if(err != NRFX_SUCCESS)
       {
           LOG_WRN("Error with setting.\n");
       }
    
       IRQ_DIRECT_CONNECT(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, 0, nrfx_spis_0_irq_handler, 0);
       irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn);
    }
    
    //----------------------------------------------------------------------------
    // Name  : spis_event_handler
    // Desc  : Callback function from the SPI driver
    // Ins   : Event pointer and an unused context pointer
    // Outs  : none
    //----------------------------------------------------------------------------
    void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context)
    {
       int err;
       switch(p_event->evt_type)
       {
          case NRFX_SPIS_XFER_DONE:
             if (p_event->rx_amount > 0)
             {
                LOG_INF("received 0x%02x 0x%02x 0x%02x 0x%02x...\n", rx_buffer[0], rx_buffer[1], rx_buffer[2], rx_buffer[3]);
             }
                
              //LOG_INF("Rx bytes: %u\n", p_event->rx_amount);
              err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
              if(err != NRFX_SUCCESS)
              {
                 LOG_WRN("Error with setting.\n");
              }
              break;
    
          case NRFX_SPIS_BUFFERS_SET_DONE:
             //LOG_WRN("buffers set\n");
             break;
    
          case NRFX_SPIS_EVT_TYPE_MAX:        
             break;
          
          default:
             ;
       }
    }
    

Reply
  • Well now it's working and I'm not certain what I did to make it so. I did upgrade to the 1.7.0 SDK. Anyway here's the code now in case anyone else is trying to get the nrfx_spis driver going.

    //== Includes ================================================================
    
    #include <nrfx.h>
    #include <zephyr/types.h>
    #include <zephyr.h>
    #include <drivers/spi.h>
    #include <string.h>
    #include "spi_comms.h"
    #include <nrfx_spis.h>
    #include <logging/log.h>
    
    //== Definitions and Types ===================================================
    #define LOG_MODULE_NAME peripheral_SPI
    LOG_MODULE_REGISTER(LOG_MODULE_NAME);
    
    #define GPIO_PORT_1_OFFSET 32
    
    #define PIN_SCK            12
    #define PIN_MOSI           22
    #define PIN_MISO           20
    #define PIN_CSN            GPIO_PORT_1_OFFSET + 2
    
    #define SPIS_NR            0     // Using SPI0
    
    #define SPI_BUFFER_SIZE    255
    
    //== Global Variables ========================================================
    nrfx_spis_t spi_slave_instance = NRFX_SPIS_INSTANCE(SPIS_NR);
    
    nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(PIN_SCK,PIN_MOSI,PIN_MISO,PIN_CSN);
    
    uint8_t rx_buffer[SPI_BUFFER_SIZE];
    uint8_t tx_buffer[SPI_BUFFER_SIZE];
    
    //== Function prototypes =====================================================
    void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context);
    
    //============================================================================
    
    //----------------------------------------------------------------------------
    // Name  : spi_comms_init
    // Desc  : Configure the SPI slave device using the nrfx_spis driver
    // Ins   : none
    // Outs  : none
    //----------------------------------------------------------------------------
    void spi_comms_init(void)
    {
       int err;
    
       nrf_spis_disable(spi_slave_instance.p_reg);
    
       err = nrfx_spis_init(&spi_slave_instance, &spis_config, spis_event_handler, NULL);
       if(err != NRFX_SUCCESS)
       {
          LOG_WRN("Error with init.\n");
       } else 
       {
          LOG_WRN("SPIS started.\n");
       }
     
       err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
       if(err != NRFX_SUCCESS)
       {
           LOG_WRN("Error with setting.\n");
       }
    
       IRQ_DIRECT_CONNECT(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn, 0, nrfx_spis_0_irq_handler, 0);
       irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_UARTE0_IRQn);
    }
    
    //----------------------------------------------------------------------------
    // Name  : spis_event_handler
    // Desc  : Callback function from the SPI driver
    // Ins   : Event pointer and an unused context pointer
    // Outs  : none
    //----------------------------------------------------------------------------
    void spis_event_handler(nrfx_spis_evt_t const *p_event, void *p_context)
    {
       int err;
       switch(p_event->evt_type)
       {
          case NRFX_SPIS_XFER_DONE:
             if (p_event->rx_amount > 0)
             {
                LOG_INF("received 0x%02x 0x%02x 0x%02x 0x%02x...\n", rx_buffer[0], rx_buffer[1], rx_buffer[2], rx_buffer[3]);
             }
                
              //LOG_INF("Rx bytes: %u\n", p_event->rx_amount);
              err = nrfx_spis_buffers_set(&spi_slave_instance, tx_buffer, sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
              if(err != NRFX_SUCCESS)
              {
                 LOG_WRN("Error with setting.\n");
              }
              break;
    
          case NRFX_SPIS_BUFFERS_SET_DONE:
             //LOG_WRN("buffers set\n");
             break;
    
          case NRFX_SPIS_EVT_TYPE_MAX:        
             break;
          
          default:
             ;
       }
    }
    

Children
Related