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

nRF51822 SPI master

Hi!

I have custom board with nRF51822 and I need to communicate with serial flash W25X40 using SPI master example with SoftDevice enabled (S110 is used). I worked with serial flashes before but didn't encountered the problems described below.

During debugging I figured out that after first execution of the spi_master_send_recv function all subsequent transfers use original values of the TX buffer.

Here's example that explains what I mean:

TX and RX buffers are declared as global arrays:

uint8_t tx_data[5] = {0x00, 0x00, 0x00, 0x00, 0x00}  // Transmit buffer
uint8_t rx_data[4]; // Receive buffer

Then after standard procedures I initialize SPI interface:

leds_init();
buttons_init();
ble_stack_init();

timers_init();
device_manager_init();
gap_params_init();
advertising_init();
services_init();
sensor_sim_init();
conn_params_init();

// Start execution.
application_timers_start();
advertising_start();	
spi_master_init(SPI_MASTER_0, spi_master_event_handler, false);

After that two transfers are being executed in endless loop, the first one reads chip info and the second should read one byte located at address 0x000000:

for (;; )
	{	
		tx_data[0] = 0x9F;
		spi_master_send_recv(SPI_MASTER_0, tx_data, 1, rx_data, 4);
		tx_data[0] = 0x03;
		spi_master_send_recv(SPI_MASTER_0, tx_data, 4, rx_data, 1);
		power_manage();			
	}

The first transfer returns correct values according to the datasheet. The problem I mentioned above is that the second transfer uses value 0x9F rather than 0x03 as if SPI master instance references to the saved copy of original array - this was revealed when I stepped in the function and watched actual TX buffer values.

So far I have two questions:

  1. How should I modify values of the TX buffer after first using of spi_master_send_recv function?
  2. Do I use spi_master_send_recv function correctly for reading data from serial flash?

Thanks!

Parents
  • Dmitry,

    The spi_master_send_recv function is non-blocking, it just kicks off the SPI hardware to start the transaction. When the transaction is completed, an interrupt will fire and call the event handler you passed to the spi_master_init function (in your case, spi_master_event_handler). You need to wait for the event hander to be called with the SPI_MASTER_EVT_TRANSFER_COMPLETED event type before calling spi_master_send_recv again with the new data.

    Alternatively, you can use the uint32_t return value of spi_master_send_recv to determine when data has been sent successfully. The function will return NRF_SUCCESS if the data was added to the SPI output correctly, or it will return NRF_ERROR_BUSY if a transaction is currently in progress and the data will not be sent.

  • Hi Nathan,

    Thanks for the reply.

    I added the feature you talk about but I guess the problem lies elsewhere. I've found a mistake but it doesn't solves the problem: when calling

    spi_master_send_recv(SPI_MASTER_0, tx_data, 4, rx_data, 1);
    

    I should use value 5 instead 4 because master latches transfer from slave during 5th byte. Accordingly RX buffer should have 5 elements instead 4 in my case.

    The issue which is still there is that spi_master_send_recv function changes TX buffer contents to the original value although new value is passed as an argument: in my case if step in the function during second call I observe that tx_data[0] assigned by 0x9F. This occurs when the following instruction has been called:

    volatile spi_master_instance_t * p_spi_instance = spi_master_get_instance(
        spi_master_hw_instance);
    

    Any thoughts?

Reply
  • Hi Nathan,

    Thanks for the reply.

    I added the feature you talk about but I guess the problem lies elsewhere. I've found a mistake but it doesn't solves the problem: when calling

    spi_master_send_recv(SPI_MASTER_0, tx_data, 4, rx_data, 1);
    

    I should use value 5 instead 4 because master latches transfer from slave during 5th byte. Accordingly RX buffer should have 5 elements instead 4 in my case.

    The issue which is still there is that spi_master_send_recv function changes TX buffer contents to the original value although new value is passed as an argument: in my case if step in the function during second call I observe that tx_data[0] assigned by 0x9F. This occurs when the following instruction has been called:

    volatile spi_master_instance_t * p_spi_instance = spi_master_get_instance(
        spi_master_hw_instance);
    

    Any thoughts?

Children
No Data
Related