nrf52811 in SPI slave mode

Hello Team,

i have created a custom board of nrf52811 Soc and want to use  nrf52811 in slave mode with STM32 SPI masater.

i have created pinctrl.dtsi and dts file as per below images. is this a correct way to configure SPI0 in salve mode?

I am using nrf connect SDK version 2.5.2

i have questions about:

1. CS pin whether i can use cs pin in pinctrl file or i have to use it as a gpio? if yes how to configure it (GPIO PIN or GPIOTE pin) 

2. how to enable interrupt in spi slave mode to detect master has sent data

Any guidance, is greatly appreciated.

Parents
  • Hi,

    1. CS pin whether i can use cs pin in pinctrl file or i have to use it as a gpio? if yes how to configure it (GPIO PIN or GPIOTE pin) 

    The CS pin must be assigned in the SPIS HW peripheral when the SPI Master initiates a transfer, see the description of SPI slave operation in the nRF52811 Product Specifications.

    If you are using the nrfx_spis driver to configure the SPIS peripheral, it is not required to configure the CS pin in the devicetree/pinctrl, since the pin is set in the driver configuration struct. The devicetree/pinctrl nodes is used when Zephyr drivers are used to configure the peripheral. 

    If you have control of both sides of the SPI bus, you can technically configure the CS pin as a GPIO interrupt and send a "dummy" packet from the SPI Master to tell the slave to initialize the SPIS peripheral, but the current consumption by SPIS when CS pin is not asserted should not be quite low.

    2. how to enable interrupt in spi slave mode to detect master has sent data

    When you are using the nrfx_spis driver, the driver should enable the appropriate interrupts for you. Once a transfer have been completed, the driver will pass an event to the application event handler that was set during initialization.

    Best regards,
    Jørgen

  • Hi,

    From the error message, it looks like the pins are not configured for the SPIS in your devicetree. When using the Zephyr driver, you will need to define the pins in devicetree/overlay,

    Can you post the overlay file you are using when building your project?

    Best regards,
    Jørgen

Reply Children
  • Hello,

    I am able to resolve the error.

    i am not able to get control at  

    spi_slave_write_test_msg()
    The master code is tested and is working with NRF52811 in slave mode using  NRFX_SPI_DRIVER 
     
    In master code, SPI mode 0 is used with 1MHz frequency
    what could be the wrong in dts file or main file 
    My SPI slave configuration is:

    SPIS_SCK = p0.6
    SPIS_MOSI=  p0.9

    SPIS_MISO = P0.10
    SPIS_CSN = P0.12

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    //#include <zephyr/devicetree.h>
    //#include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/spi.h>
    
    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS   1000
    
    // SPI slave functionality
    static struct k_poll_signal spi_slave_done_sig = K_POLL_SIGNAL_INITIALIZER(spi_slave_done_sig);
    const struct device *spi_slave_dev = DEVICE_DT_GET(DT_NODELABEL(spi0));
    
    static const struct spi_config spi_slave_cfg = {
    	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
    				 SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_OP_MODE_SLAVE,
    	.frequency = 1000000, //4000000
    	.slave = 0,
    };
    
    static void spi_slave_init(void)
    {
    	if (!device_is_ready(spi_slave_dev)) {
             //  printk("spi slave device is not ready\n");
            }
    		else{
    			// printk("spi slave device is  ready\n");
    		}
    }
    
    static uint8_t slave_tx_buffer[8];
    static uint8_t slave_rx_buffer[8];
    
    static int spi_slave_write_test_msg(void)
    {
    	static uint8_t counter = 0;
    
    
    	const struct spi_buf s_tx_buf = {
    		.buf = slave_tx_buffer,
    		.len = sizeof(slave_tx_buffer)
    	};
    	const struct spi_buf_set s_tx = {
    		.buffers = &s_tx_buf,
    		.count = 7 //1
    	};
    
    	struct spi_buf s_rx_buf = {
    		.buf = slave_rx_buffer,
    		.len = sizeof(slave_rx_buffer),
    	};
    	const struct spi_buf_set s_rx = {
    		.buffers = &s_rx_buf,
    		.count = 7 //1
    	};
    
    	// Update the TX buffer with a rolling counter
    //	slave_tx_buffer[1] = counter++;
    	  memcpy(slave_tx_buffer, "Nordic",6);
    	//printk("SPI SLAVE TX: 0x%.2x, 0x%.2x\n", slave_tx_buffer[0], slave_tx_buffer[1]);
    
    	// Reset signal
    	k_poll_signal_reset(&spi_slave_done_sig);
    	
    	// Start transaction
    	int error = spi_transceive_async(spi_slave_dev, &spi_slave_cfg, &s_tx, &s_rx, &spi_slave_done_sig);
    	if(error != 0){
    		//printk("SPI slave transceive error: %i\n", error);
    		return error;
    	}
    	return 0;
    }
    
    static int spi_slave_check_for_message(void)
    {
    	int signaled, result;
    	k_poll_signal_check(&spi_slave_done_sig, &signaled, &result);
    	if(signaled != 0){
    		return 0;
    	}
    	else return -1;
    }
    
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    //static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    
    void main(void)
    {
    
    	spi_slave_init();
    
    //	printk("SPI master/slave example started\n");
    	
    //	spi_slave_write_test_msg();
    
    	while (1) {
    		
    	//	k_msleep(SLEEP_TIME_MS);
    
    		if(spi_slave_check_for_message() == 0){
    			// Print the last received data
    //			printk("SPI SLAVE RX: 0x%.2x, 0x%.2x\n", slave_rx_buffer[0], slave_rx_buffer[1]);
    			
    			// Prepare the next SPI slave transaction
    			spi_slave_write_test_msg();
    		}
    	}
    }
    emg_nrf52811-pinctrl.dtsiemg_nrf52811.dts6254.prj.conf

  • Hi,

    GPIOs P0.09 and P0.10 are by default assigned to the NFCT peripherals, as these are the dedicated antenna pins. To use these as GPIOs, you need to configure this in your devicetree:

    &uicr {
        nfct-pins-as-gpios;
    };

    Best regards,
    Jørgen

  • Hi 

    i added &uicr in my devicetree but still the control not comes to spi_slave_write_test_msg() function

    signaled value is 0 always

    did i configure  pinctrl.dtsi file  correct?

    did you find anything wrong in code ?

  • Can you upload your generated devicetree file (build/zephyr/zephyr.dts)? This should show if the pin configs are included correctly in the project.

    Did you check the pins with a logic analyzer/scope, to see if some/all pins are toggling as expected? If CS/SCK/MOSI toggles correctly, is there any response from the slave on the MISO pin?

Related