This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

how to drive spi CS line low for 32 bits.

Hi,

Can you please direct me to the document that explains about generating more than 8 bits of clock in SPI and keeping CS line low for that entire period.

Also, if i have to send two 16bit data, would i have to send them in lots of 8bit ? or i can send them as 16bits using nrf_drv_spi_transfer API?

I am modifying the SPI example found under SDK15/example/peripheral/spi.

And i have to achieve the sequence attached in the image. 

Thank you  

  • Hi,

    You cannot switch mode just like that. However, I would assume that the slave device would not matter that there is a delay between the first 16 and last 16 bits, as the clock is anyway generated by the master. The idea is that after transmitting the first 16 bits you initialize the driver to use another mode and receives the 16 bits. It would stretch the transaction so that it looks something like this:

  • Thanks Einar for the explanation, 

    Is this the correct implementation to achieve what you showed in the diagram above ? 

                                                         nrf_drv_spi_transfer (spi, first 16bit data, 2, first 16bit data, 2);

                                                         unint spi

                                                         spi mode-> 3

                                                        nrf_drv_spi_transfer (spi, last 16bit data, 2, last 16bit data, 2);

    I am just confused with the length parameter. if I am specifying 2 bytes of length, will that mean that the CS line will go high after writing 2 bytes ? if that is true, then this implementation will obviously not work. 

    Regards,

  • Hi,

     

    The "nrf_drv_spi_transfer" function will set the CSN active prior to the first byte written. If you require the CSN pin to be kept low (ie: active), then you need to manually control the GPIO. This is done by setting "spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED", then controlling it manually in your own transfer function.

    Best regards,

    Håkon

  • is this the correct implementation ? 

    nrf_drv_spi_uninit(&spi);
    
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    spi_config.mode = NRF_DRV_SPI_MODE_2;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
    nrf_gpio_cfg_output(29);
    nrf_gpio_pin_clear(29);
    
    memset(m_rx_buf, 0, m_length);
    spi_xfer_done = false;
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf4, m_length1, m_rx_buf, m_length1));
    NRF_LOG_FLUSH();
    bsp_board_led_invert(3);
    // nrf_gpio_pin_set(BSP_BOARD_LED_0);
    nrf_delay_ms(200);
    
    nrf_drv_spi_uninit(&spi);
    
    nrf_drv_spi_config_t spi_config1 = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    spi_config.mode = NRF_DRV_SPI_MODE_3;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config1, spi_event_handler, NULL));
    
    
    nrf_gpio_pin_clear(29);
    
    memset(m_rx_buf, 0, m_length);
    spi_xfer_done = false;
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf5, m_length1, m_rx_buf, m_length1));
    NRF_LOG_FLUSH();
    bsp_board_led_invert(3);
    // nrf_gpio_pin_set(BSP_BOARD_LED_0);
    nrf_delay_ms(200);
    
    nrf_gpio_pin_set(29);

  • If GPIO 29 is your CSN, then it looks to be handled correctly. The delay calls are redundant, and can be removed.

    Are you able to communicate with the device? How does the scoped signals look?

Related