SPI slave always returns -ETIMEDOUT

Hi,

I am working on SPI master-slave application, as in, on one BL653 I am running SPI master driver, I am able to observe the waveforms for clock and data transfer from master on USB logic analyzer.

But I am facing an issue with the BL653 board which is running SPI slave code, basically, for slave under main my code is as below:

	m_spi_cfg->operation |= SPI_WORD_SET(8);

	m_rx_bufs->buf = &data;
	m_rx_bufs->len = sizeof(data);

	m_rx_set_buff->buffers = m_rx_bufs;
	m_rx_set_buff->count = 1;

	if ((m_spi_dev) != nullptr)
	{
		l_nStatus = spi_read(m_spi_dev, m_spi_cfg, m_rx_set_buff);
		printk("Received data : %u : %d\n",data,l_nStatus);
		if (l_nStatus != SUCCESS)
		{
			return ERR;
		}
	}

Here spi_read always returns -116, that is  -ETIMEDOUT.

My device binding, spi slave configurations and wiring with spi master are in order.

But I do not understand why slave driver always returns -ETIMEDOUT.

I traced the flow of execution all the way to the source of the error and here is what I found

spi_read( ) -> transceive (in file "spi_nrfx_spis.c") -> spi_context_wait_for_completion( in file "spi_context.h") -> and the source of error is as attached in the below snap in #else part 

Without debug mode as well I am getting the same -ETIMEDOUT.

Kindly suggest on if I have missed out on configuring something.


Thanks,

Ubaid

  • Hello,

    Also adding my overlay file details for your reference:

    &spi1 {
    	compatible = "nordic,nrf-spis";
    	status = "okay";
    	sck-pin = <41>;
    	mosi-pin = <40>;
    	miso-pin = <4>;
    	cs-gpios = <&gpio1 23 0>;
    	csn-pin = <23>;
    	def-char = <0xFF>;
    };

    Kindly suggest,

    Thanks

  • Hi,

    Can you share the rest of the source code, and your prj.conf file?

    Where are you calling the spi_read() function?

    Are the CSN pin connected and toggling as expected?

    Best regards,
    Jørgen

  • Hello Jørgen,

    Thank you so much, Master's signals I am able to observe on USB logic analyzer, CLK, MOSI & CS (all three),

    as in below snap, cs stays low for 26micro secs during which master board is sending data:


    Roughly below is my slave code Jørgen, running on another board:

    #define SPI_DEVICE_NAME_P1 DT_LABEL(DT_NODELABEL(spi1))
    const device *m_spi_dev;
    struct spi_config *m_spi_cfg = new spi_config();
    void main(void)
    {
    
    	uint8_t spi_channel = 1;
    	bool is_master;
    
    	uint8_t port = 0;
    	uint8_t pin = 23;
    	uint32_t flag = GPIO_ACTIVE_LOW;//GPIO_OUTPUT_ACTIVE;
    	
        m_spi_dev = device_get_binding(SPI_DEVICE_NAME_P1);
        
        m_spi_cfg->frequency =  4000000;
        m_spi_cfg->operation |= SPI_OP_MODE_SLAVE;
        m_spi_cfg->slave = 1;
        m_spi_cfg->operation |= SPI_WORD_SET(8);
        
        const struct device	*gpio_dev = device_get_binding("GPIO_0");
        uint8_t gpio_pin_t = 23;
        uint8_t gpio_dt_flags_t = GPIO_ACTIVE_LOW;
        
        gpio_pin_configure(gpio_dev, gpio_pin_t, GPIO_INPUT | gpio_dt_flags_t);
        
        static uint8_t rx_buffer[1];
        struct spi_buf rx_buf = {
    .buf = rx_buffer,
    .len = sizeof(rx_buffer),
    };	
    
    const struct spi_buf_set rx = {
    .buffers = &rx_buf,
    .count = 1
    };
        
        while(true)
        {
        	l_nStatus = spi_read(m_spi_dev, m_spi_cfg, &rx);
    		printk("RX recv: %u : %d \n", rx_buffer[0],l_nStatus);
    		if (l_nStatus != SUCCESS)
    		{
    			return ERR;
    		}
            
        }
        
        }
        
        

    prj.conf:

    #C++ support configs
    CONFIG_CPLUSPLUS=y
    CONFIG_NEWLIB_LIBC=y
    CONFIG_LIB_CPLUSPLUS=y
    CONFIG_HEAP_MEM_POOL_SIZE=16348
    CONFIG_OPENOCD_SUPPORT=n
    
    #SPI
    CONFIG_SPI=y
    CONFIG_SPI_SLAVE=y
    CONFIG_LOG=y
    #CONFIG_SPI_ASYNC=y

    overlay:

    &spi1 {
    	compatible = "nordic,nrf-spis";
    	status = "okay";
    	sck-pin = <41>;
    	mosi-pin = <40>;
    	miso-pin = <4>;
    	cs-gpios = <&gpio0 23 0>;
    	csn-pin = <23>;
        def-char = <0xFF>;
    };



    Now with this code I am getting prints for:

    -ETIMEDOUT

    or 

    -EIO

    Being generated from adc_context.h

  • Hello ,

    Are the CSN pin connected and toggling as expected?


    I have uploaded the code and csn pin states on a logic analyser in the case:

    https://devzone.nordicsemi.com/f/nordic-q-a/83616/using-spi_write-spi_read-not-behaving-the-same-as-spi_transceive-for-spi-data-in-provided-spi-sample

    Same problem yet, 

    I have tried everything, yet no progress, can you kindly help out on why I am unable to receive data on slave board.


    Thanks,

    Ubaid

  • Hello   ,

    Clearly master board it is doing, I think something with slave board or slave pin out config.


    Can you have a look at slave code, config and kindlu suggest, as in below.
     

    SLAVE:************************************

    I am using  second board to run as a Slave, an nrf52833_dk,
    It's project is as follows:

    Code:

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    #include <string.h>
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/spi.h>
    
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    
    #define SPI_SLAVE_BUS_NAME     			DT_INST_0_NORDIC_NRF_SPIS_LABEL
    #define SPI_SLAVE_GPIOS_NAME    		DT_ALIAS_GPIO_0_LABEL
    #define SPI_SLAVE_GPIO_IRQ_PIN  		DT_ALIAS_SPI_0_CSN_PIN
    
    #define STACKSIZE 1024
    #define PRIORITY 99
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    void spi_slave_init(void);
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    int spi_slave_write(struct device * spi, 
                        struct spi_config * spi_cfg,
                        uint16_t * data)
    {
        struct spi_buf bufs = {
                .buf = data,
                .len = 2
        };
        struct spi_buf_set tx = {
            .buffers = &bufs
        };
        
        tx.count = 1;
    
        return spi_write(spi, spi_cfg, &tx);
    }
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    int spi_slave_read(struct device * spi, 
                       struct spi_config * spi_cfg,
                       uint16_t * data)
    {
        struct spi_buf bufs = {
                .buf = data,
                .len = 2
        };
        struct spi_buf_set rx = {
            .buffers = &bufs
        };
        
        rx.count = 1;
    
        return spi_read(spi, spi_cfg, &rx);
    }
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    void spi_slave_init(void)
    {
        struct device * spi;
        struct spi_config spi_cfg;
    
        uint16_t tx_data = 0x5678;
        uint16_t rx_data = 0;
    
        printk("SPI Slave example application\n");
    
        printk("rx_data buffer at %p\n", &rx_data);
    
        spi = device_get_binding("SPI_0");
        if (!spi) {
            printk("Could not find SPI driver\n");
            return;
        }
    
        /*
         *  SPI controller configuration structure for the nRF52 series.
         *
         *  param frequency is the bus frequency in hertz
         *  param operation is a bit field with the following parts:
         *
         *     operational mode  [ 0 ]       - master or slave.
         *     mode              [ 1 : 3 ]   - Polarity, phase and loop mode.
         *     transfer          [ 4 ]       - LSB or MSB first.
         *     word_size         [ 5 : 10 ]  - Size of a data frame in bits.
         *     lines             [ 11 : 12 ] - MISO lines: Single/Dual/Quad/Octal.
         *     cs_hold           [ 13 ]      - Hold on the CS line if possible.
         *     lock_on           [ 14 ]      - Keep resource locked for the caller.
         *     cs_active_high    [ 15 ]      - Active high CS logic.
         *
         *  param slave is the slave number from 0 to host controller slave limit.
         *  param cs is a valid pointer on a struct spi_cs_control is CS line is
         *        emulated through a gpio line, or NULL otherwise.
         */
    
        /* Note: Implicid Mode-0; e.g. CPOL=0, CPHA=0 -- the only mode supported */
        /* Note: The nRF52 series doesn't support CS pin configuration */
    
        memset(&spi_cfg, 0, sizeof(spi_cfg));
    
        spi_cfg.operation = SPI_WORD_SET(8) | SPI_OP_MODE_SLAVE;
        spi_cfg.frequency = 1000000;
        spi_cfg.slave = 1;
    
        printk("%s: slave config @ %p:"
                " wordsize(%u), mode(%u/%u/%u)\n", __func__, &spi_cfg,
                SPI_WORD_SIZE_GET(spi_cfg.operation),
                (SPI_MODE_GET(spi_cfg.operation) & SPI_MODE_CPOL) ? 1 : 0,
                (SPI_MODE_GET(spi_cfg.operation) & SPI_MODE_CPHA) ? 1 : 0,
                (SPI_MODE_GET(spi_cfg.operation) & SPI_MODE_LOOP) ? 1 : 0);
    
        while (1) {
            spi_slave_read(spi, &spi_cfg, &rx_data);
    
            if (rx_data == 0x1234) {
                spi_slave_write(spi, &spi_cfg, &tx_data);
            }
            printk("Received: 0x%04X -- %s\n", rx_data,
                   (rx_data == 0x1234) ? "ok" : "wrong"); 
        }
    }
    
    
    /*---------------------------------------------------------------------------*/
    /*                                                                           */
    /*---------------------------------------------------------------------------*/
    void spi_slave_thread(void * id, void * unused1, void * unused2)
    {
        printk("%s\n", __func__);
    
        spi_slave_init();
    
        while (1) { /* spin */}
    }
    
    K_THREAD_DEFINE(spi_slave_id, STACKSIZE, spi_slave_thread, 
                    NULL, NULL, NULL, PRIORITY, 0, 0);

    nrf52833dk_nrf52833.overlay:

    /*
    * Copyright (c) 2019 Callender-Consulting, LLC
    *
    * SPDX-License-Identifier: Apache-2.0
    */
    &spi0 {
    compatible = "nordic,nrf-spis";
    status = "okay";
    sck-pin = <27>;
    mosi-pin = <26>;
    miso-pin = <29>;
    csn-pin = <1>;
    def-char = <0xFF>;
    };

    prj.conf:

    # nothing here
    CONFIG_DEBUG=y
    CONFIG_GPIO=y
    CONFIG_SPI=y
    CONFIG_SPI_SLAVE=y
    CONFIG_PRINTK=y

    Hardware connections:

    SCLK : M-41 : S-27
    MOSI : M-40 : S-26

    MISO : M-04 : S-29

    CS :     M-23 : S-1


    Kindly suggest where i can look for further, I have evaluated everything yet to no avail 

    Thanks

Related