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

SPI communication problem

Hello Slight smile

I'm using NRF52 PCA10040 board., SDK 15.2 libraries with GNU ARM GCC and Eclipse as an IDE developing FW on Windows10 x64.

I have been facing a problem trying to service external SPI flash memory (AT25SF041, but not only - you can read about it further). I'm not able to read memory ID registers. More precisely I got incorrect response from the memory.

I was trying few memory chips from different vendors with the same result. I have no such a problem using STM32L0 MCU. What is more interesting, I have been investigating SPI communication at electric signal level using DSO and both communication (using NRF52 and STm32) looks exactly the same with the difference that memory responds to ID request got from SMT32 with appropriate device ID data but on NRF52 request it sends incorrect response.

Has anyone ever met such a strange problem?

Here is the low-level code I've written for AT25SF041 driver:

#include "nrf_gpio.h"
#include "nrfx_spi.h"
 
#include "logger.h"
 
#define CS_PIN          28
#define SCK_PIN         29
#define MISO_PIN        30
#define MOSI_PIN        31
 
 
static const nrfx_spi_t _xSpiHandler = NRFX_SPI_INSTANCE(0);
static nrfx_spi_config_t _xSpiConfig = NRFX_SPI_DEFAULT_CONFIG;
 
static uint8_t _bIsInitialized = 0;
static volatile uint8_t _bTransferFinished;
 
static void prvvSpiEventHandler(nrfx_spi_evt_t const* aEvent, void* aContext)
{
    _bTransferFinished = 1;
}
 
void AT25SF041_vInitializeLL()
{
    if (_bIsInitialized)
    {
        return;
    }
 
    /** Set SPI pins n the configuration object and initialize interface. */
    _xSpiConfig.miso_pin = MISO_PIN;
    _xSpiConfig.mosi_pin = MOSI_PIN;
    _xSpiConfig.sck_pin = SCK_PIN;
    _xSpiConfig.ss_pin = NRFX_SPI_PIN_NOT_USED;
    _xSpiConfig.frequency = NRF_SPI_FREQ_125K ;
    _xSpiConfig.mode = NRF_SPI_MODE_0;
    nrfx_spi_init(&_xSpiHandler, &_xSpiConfig, &prvvSpiEventHandler, NULL);
 
    /** Prepare CS pin and set its state to HGH. */
    nrf_gpio_cfg_output(CS_PIN);
    nrf_gpio_pin_set(CS_PIN);
 
    _bIsInitialized = 1;
}
 
void AT25SF041_vSetCSActiveLL()
{
    nrf_gpio_pin_clear(CS_PIN);
}
 
void AT25SF041_vSetCSInactiveLL()
{
    nrf_gpio_pin_set(CS_PIN);
}
 
int8_t AT25SF041_bXferBytesLL(uint8_t* aTxBuf, uint8_t aTxLen, uint8_t* aRxBuf, uint8_t aRxLen)
{
    nrfx_spi_xfer_desc_t xferDesc = NRFX_SPI_XFER_TRX(aTxBuf, aTxLen, aRxBuf, aRxLen);
 
    AT25SF041_vSetCSActiveLL();
 
    _bTransferFinished = 0;
 
    nrfx_err_t error = nrfx_spi_xfer(&_xSpiHandler, &xferDesc, 0);
    if (error != NRFX_SUCCESS)
    {
        return -1;
    }
 
    while (!_bTransferFinished)
    {
    }
 
    AT25SF041_vSetCSInactiveLL();
 
    return 0;
}

  • Hi,

    What ID are you reading, and what do you expect? What parameters do you pass to the function AT25SF041_bXferBytesLL() when you want to read the ID?

    Best regards,
    Jørgen

  • Hi Jørgen,

    1. When I'm sending Read Manufacturer and Device (0x9F) command  I call transfer function using such a code:

    uint8_t txBuf[] =
    {
    	0x9F,
    	0xFF,
    	0xFF,
    	0xFF
    };
    
    uint8_t rxBuf[6] = { 0 };
    
    AT25SF041_bXferBytesLL(txBuf, 6, rxBuf, 6);


    But as can be seen on the screenshot below I got wrong answer (should be 0x1F 0x84 0x01).



    Doing the same with STM32 processor gives communication like on  screenshot below:



    2. When I'm sending Read ID (0x90) command I call transfer function using such a code:

    uint8_t txBuf[] =
    {
    	0x90,
    	0x00,
    	0x00,
    	0x00,
    	0xFF,
    	0xFF
    };
    uint8_t rxBuf[6] = { 0 };
    
    AT25SF041_bXferBytesLL(txBuf, 6, rxBuf, 6);


    And again the result is not as expected (should be 0x1F 0x12):



    When I use STM32 I get:




    My SPI configuration from sdk_config.h is as follows:

    // <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver
    //==========================================================
    #ifndef NRFX_SPI_ENABLED
    #define NRFX_SPI_ENABLED 1
    #endif
    // <q> NRFX_SPI0_ENABLED  - Enable SPI0 instance
     
    
    #ifndef NRFX_SPI0_ENABLED
    #define NRFX_SPI0_ENABLED 1
    #endif
    
    // <q> NRFX_SPI1_ENABLED  - Enable SPI1 instance
     
    
    #ifndef NRFX_SPI1_ENABLED
    #define NRFX_SPI1_ENABLED 0
    #endif
    
    // <q> NRFX_SPI2_ENABLED  - Enable SPI2 instance
     
    
    #ifndef NRFX_SPI2_ENABLED
    #define NRFX_SPI2_ENABLED 0
    #endif
    
    // <o> NRFX_SPI_MISO_PULL_CFG  - MISO pin pull configuration.
     
    // <0=> NRF_GPIO_PIN_NOPULL 
    // <1=> NRF_GPIO_PIN_PULLDOWN 
    // <3=> NRF_GPIO_PIN_PULLUP 
    
    #ifndef NRFX_SPI_MISO_PULL_CFG
    #define NRFX_SPI_MISO_PULL_CFG 1
    #endif
    
    // <o> NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
     
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    
    #ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY
    #define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
    #endif
    
    // <e> NRFX_SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
    //==========================================================
    #ifndef NRFX_SPI_CONFIG_LOG_ENABLED
    #define NRFX_SPI_CONFIG_LOG_ENABLED 0
    #endif
    // <o> NRFX_SPI_CONFIG_LOG_LEVEL  - Default Severity level
     
    // <0=> Off 
    // <1=> Error 
    // <2=> Warning 
    // <3=> Info 
    // <4=> Debug 
    
    #ifndef NRFX_SPI_CONFIG_LOG_LEVEL
    #define NRFX_SPI_CONFIG_LOG_LEVEL 3
    #endif
    
    // <o> NRFX_SPI_CONFIG_INFO_COLOR  - ANSI escape code prefix.
     
    // <0=> Default 
    // <1=> Black 
    // <2=> Red 
    // <3=> Green 
    // <4=> Yellow 
    // <5=> Blue 
    // <6=> Magenta 
    // <7=> Cyan 
    // <8=> White 
    
    #ifndef NRFX_SPI_CONFIG_INFO_COLOR
    #define NRFX_SPI_CONFIG_INFO_COLOR 0
    #endif
    
    // <o> NRFX_SPI_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
     
    // <0=> Default 
    // <1=> Black 
    // <2=> Red 
    // <3=> Green 
    // <4=> Yellow 
    // <5=> Blue 
    // <6=> Magenta 
    // <7=> Cyan 
    // <8=> White 
    
    #ifndef NRFX_SPI_CONFIG_DEBUG_COLOR
    #define NRFX_SPI_CONFIG_DEBUG_COLOR 0
    #endif
    
    // </e>
    
    // </e>


    Can you please help me somehow? The problem is that I have already tested three differen SPI FLASH chips and had preety same problems with each of them.

  • It looks like you are writing more bytes than necessary. If you want to write a single byte and receive 3 bytes after this, I would recommend using the following code:

    uint8_t txBuf[] =
    {
    	0x9F
    };
    
    uint8_t rxBuf[4] = { 0 };
    
    AT25SF041_bXferBytesLL(txBuf, 1, rxBuf, 4);

    The peripheral will send out "dummy bytes" to read the following bytes into the RX buffer, you just need to ignore the byte received while transmitting the first byte.

  • Hi  ,
    Unfortunatelly the result is exactly the same. Take a look on a screenshot below:

  • Can you try changing the NRFX_SPIM_MISO_PULL_CFG in sdk_config.h? It is strange that the device does not respond with the same output when it receive the same command on MOSI line.

Related