Clarification on SPI Transceive Timing in nRF Connect SDK for RHS2116 Integration

We are developing on the nRF52 Development Kit (nRF52 DK) for the nRF52832 SoC. Our application involves a 4-wire pipelined SPI communication with the Intan RHS2116 chip. According to the RHS2116 documentation (page 30, Picture 1), the SPI connection is configured such that the RHS2116 automatically outputs data two command cycles after a command is sent. This means that by the time we reach the 3rd command, there will be output data on MISO that we need to receive concurrently as the master (nRF52832) transmits the next command via MOSI.

Our challenge is with the nRF Connect SDK and Zephyr OS: specifically, it’s unclear from Zephyr’s SPI library documentation if the spi_transceive function performs read and write operations within the same command cycle, which is required to meet the pipelined data flow of the RHS2116.

Could you confirm if spi_transceive in the nRF Connect SDK supports simultaneous read/write operations in the same cycle? Additionally, if there are configurations or alternative methods recommended for achieving this synchronized SPI communication with the nRF52832, we would appreciate any guidance.

  • Hi Håkon,

    Manually configurating the CSN pin has solved the issue, and the small timing gaps in sclk doesn't seem to cause problems for data integrity.

    Here's the configuration in full:

    static uint8_t tx_buffer[4];
    static uint8_t rx_buffer[4] = {0x00, 0x00, 0x00, 0x00};
    
    struct device * spi_dev;
    
    static const struct spi_config spi_cfg = {
    	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB ,
    	.frequency = 20000000, //maximum frequency of 25MHz per intan rhs2116 specs
    	.slave = 0,
    	.cs = {
    			.gpio = GPIO_DT_SPEC_GET(SPI_DEV_NODE, cs_gpios),
    			.delay=0,
    		},
    };
    
    
    static void spi_init(void)
    {	
    	const char* const spiName = "SPI_1";
    	spi_dev = device_get_binding(spiName);
    	if (spi_dev == NULL) {
    		printk("Could not get %s device\n", spiName);
    		return;
    	}
    }
    
    const struct spi_buf tx_buf = {
            .buf = tx_buffer,
            .len = sizeof(tx_buffer)
    };
    const struct spi_buf_set tx = {
            .buffers = &tx_buf,
            .count = 1
    };
    
    const struct spi_buf rx_buf = {
            .buf = rx_buffer,
            .len = sizeof(rx_buffer),
    };
    const struct spi_buf_set rx = {
            .buffers = &rx_buf,
            .count = 1
    };

    Overlay:

    &spi1 {        
        compatible = "nordic,nrf-spi";                 // SPI controller, e.g., SPI1
        status = "okay";           // Enable this SPI controller
        pinctrl-0 = <&spi1_default>;
        pinctrl-1 = <&spi1_sleep>;
        pinctrl-names = "default", "sleep";
        cs-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; // Chip Select pin (CS), active low
        label = "SPI_1";
    
        
    };
    
    &pinctrl {
        spi1_default: spi1_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 28)>,					 
                        <NRF_PSEL(SPIM_MOSI, 0, 29)>,
                        <NRF_PSEL(SPIM_MISO, 0, 31)>;
            };
        };
        spi1_sleep: spi1_sleep {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 28)>,
                        <NRF_PSEL(SPIM_MOSI, 0, 29)>,
                        <NRF_PSEL(SPIM_MISO, 0, 31)>;
                low-power-enable;
            };
        };
    };

    Thank you for your help!

Related