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

  • 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

Reply
  • 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

Children
No Data
Related