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
  • Hi,

    Thanks to all for the answers.

    So far I couldn't resolve the issue but I've found another library which I used to implement all I need (erasing flash, reading and writing the data). The library is attached: spi_master.zip

    If someone is going to use the library do the following:

    1. Change pins definition in header file (CLK, MISO, MOSI, CS) according to your schematic design.

    2. Call spi_master_init from main file or from the library which is based on the library I've attached. For example, if SPI0 is used in the mode 0 with MSB first call the function:

      spi_base_address = spi_master_init(SPI0, SPI_MODE0, (bool)0);

    3. Use function spi_master_tx_rx to send/receive data. For example, in my case mentioned in the first post the code

      tx_data[0] = 0x9F;

      spi_master_tx_rx(spi_base_address, 4, (const uint8_t *)tx_data, rx_data);

    will return SPI flash ID in the rx_data array.

    Hope this helps.

    Regards, Dmitry.

Reply
  • Hi,

    Thanks to all for the answers.

    So far I couldn't resolve the issue but I've found another library which I used to implement all I need (erasing flash, reading and writing the data). The library is attached: spi_master.zip

    If someone is going to use the library do the following:

    1. Change pins definition in header file (CLK, MISO, MOSI, CS) according to your schematic design.

    2. Call spi_master_init from main file or from the library which is based on the library I've attached. For example, if SPI0 is used in the mode 0 with MSB first call the function:

      spi_base_address = spi_master_init(SPI0, SPI_MODE0, (bool)0);

    3. Use function spi_master_tx_rx to send/receive data. For example, in my case mentioned in the first post the code

      tx_data[0] = 0x9F;

      spi_master_tx_rx(spi_base_address, 4, (const uint8_t *)tx_data, rx_data);

    will return SPI flash ID in the rx_data array.

    Hope this helps.

    Regards, Dmitry.

Children
No Data
Related