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

Separate SPIM command to Rx and Tx

Hi

I using nRF52840-DK with 64 Mb external flash memory.

I'm using SPI interface for read / write command with the external flash.

When I'm using single command for write and read it working well 

uint8_t spi_tx_cmd[] = {CMD_REMS, 0x00, 0x00, CMD_REMS_ADDRESS_DEFAULT};  
uint8_t spi_rx_response[6];  
  
nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(spi_tx_cmd, sizeof(spi_tx_cmd), spi_rx_response, sizeof(spi_rx_response));  
nrfx_spim_xfer(&m_spim_mx, &xfer_desc, 0);  
  
manufacturer_id = spi_rx_response[4];  
device_id = spi_rx_response[5];  

but when I'm trying to separate the commands to write and then read, I don't receive an answer when reading


uint8_t spi_tx_cmd[] = {CMD_REMS, 0x00, 0x00, CMD_REMS_ADDRESS_DEFAULT};
uint8_t spi_rx_response[2];

nrfx_spim_xfer_desc_t xfer_desc_tx = NRFX_SPIM_XFER_TX(spi_tx_cmd, sizeof(spi_tx_cmd));
nrfx_spim_xfer(&m_spim_mx, &xfer_desc_tx, 0);
nrfx_spim_xfer_desc_t xfer_desc_rx = NRFX_SPIM_XFER_RX(spi_rx_response, sizeof(spi_rx_response));
nrfx_spim_xfer(&m_spim_mx, &xfer_desc_rx, 0);

manufacturer_id = spi_rx_response[0];
device_id = spi_rx_response[1];

Any suggestions why it may not work?

Thanks

  • Hello,

    Could you elaborate why you would like to do RX and TX in separate read write commands? Since SPI is full-duplex communication happens both ways simultaneously.
    Have you seen the SPIM API Reference for the nrfx_spim_xfer_rx and nrfx_spim_xfer_tx? These macros just set up descriptors for a single transfer instance and are meant for internal use only. My suggestion would be to use the nrfx_spim_xfer functions for doing transfers, like in your first code snippet.

    Best regards,
    Karl

  • Hi Karl,

    Thanks for your answer.

    I want to separate these commands for reading data from the flash, in case I want to read more than 255 bytes it limits me to send each time read command (like below), instead to send once the command and then read in loop the mount that was requested.

    uint8_t spi_tx_cmd[] = {CMD_READ, (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address >> 0) & 0xFF};
    uint8_t spi_rx_response[255];
    nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(spi_tx_cmd, sizeof(spi_tx_cmd), spi_rx_response, sizeof(spi_rx_response);
    nrfx_spim_xfer(&m_spim_mx, &xfer_desc, 0);

    my idea was to use somethink like that:

    void flash_read(uint32_t address, uint8_t *data_ptr, uint32_t data_length)
    {
    	uint8_t spi_tx_cmd[] = {CMD_READ, (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address >> 0) & 0xFF};
    
    	nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_RX(spi_tx_cmd, sizeof(spi_tx_cmd));
    	nrfx_spim_xfer(&m_spim_mx, &xfer_desc, 0);
    
    	while(data_length > 255)
    	{
    		nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_RX(data_ptr, 255);
    		nrfx_spim_xfer(&m_spim_mx, &xfer_desc, 0);
    		data_ptr += 255;
    		data_length -= 255;
    	}
    	nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_RX(data_ptr, data_length);
    	nrfx_spim_xfer(&m_spim_mx, &xfer_desc, 0);
    }

  • Hello Shai,

    Sorry for my late reply.

    shai.c said:
    in case I want to read more than 255 bytes it limits me to send each time read command

    Are you here referring to the RXD.MAXCNT limitation of the nRF52832?

    The nRF52840 DK, which you have tagged your post with, supports 16-bit MAXCNT, which in turn does not limit you to only receiving 255 bytes. The documentation for the SPIM MAXCNT registers of the nRF52840 can be seen here.

    So, if you set the MAXCNT sufficiently high enough you may receive the required number of bytes to your RAM, and then handle them as you would normally - instead of having to divide up your reads and handling.

    Could this resolve your issue?

    Best regards,
    Karl 

  • Thanks for your answer!

    I will test it again and will update

Related