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

SPI Master Example on nRF52 DK consistently fails

I'm trying the example in the SDK v0.9.1: examples\spi_master

When I load the project, build it, and debug it, all that happens is that it goes into a failed state where the error handler just does nothing:

void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
    UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR));
    for (;;)
    {
        // No implementation needed.
    }
}

When I place a break point in this error handler, it always breaks, as if the program will always produce an error condition, no matter what. From my diagnostics it appears that a call to the nrf_delay_ms() function that may cause it, but can't be certain.

Why is this happening? One would suspect that example code provided would not produce a persistent error like this.

I am using SPI0 configured as (in nrf_drv_config.h):

#if (SPI0_ENABLED == 1)
#define SPI0_USE_EASY_DMA 0
#define SPI0_CONFIG_SCK_PIN         4 
#define SPI0_CONFIG_MOSI_PIN        29
#define SPI0_CONFIG_MISO_PIN        28
#define SPI0_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW

Does anyone else have this behavior with this example?

  • Hi

    I just tested the example myself and I see something similar. I'm not sure if it is the exact same problem though.

    EDIT: First, remember that you will need to wire MOSI to MISO. The example is transmitting bytes out on MOSI and at the same time it receives the same sequence of bytes on MISO. Then the example is comparing the transmitted bytes to the received bytes and if they are not the same your example will assert and stop running.

    Second, what I discovered was that in nrf_drv_config.h all three SPI instances are enabled by default:

    #define SPI0_ENABLED 1
    [...]
    #define SPI1_ENABLED 1
    [...]
    #define SPI2_ENABLED 1
    

    This caused the switch_state() state machine in the example to transmit two bursts of data sequentially on each SPI instance. For this to work you will need to connect MOSI to MISO on all three SPI instances and I had only hooked up MOSI to MISO on SPI0. Otherwise these lines in spi_master_1_event_handler() will assert:

    result = check_buf_equal(m_tx_data_spi, m_rx_data_spi, TX_RX_MSG_LENGTH);
    APP_ERROR_CHECK_BOOL(result) 
    

    Defining SPI1_ENABLED and SPI2_ENABLED as 0, effectively disabling SPI1 & 2, solved the problem for me. After testing it I realized that it is actually documented here.

  • Hi Martin,

    Thanks for the response. I have the other SPI instances disabled already. In nrf_drv_config.h:

    /* SPI */
    #define SPI0_ENABLED 1
    
    #if (SPI0_ENABLED == 1)
    #define SPI0_USE_EASY_DMA 0
    //for DK w/ AS3911 Dev Kit
    #define SPI0_CONFIG_SCK_PIN         4 
    #define SPI0_CONFIG_MOSI_PIN        29
    #define SPI0_CONFIG_MISO_PIN        28
    #define SPI0_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW
    
    #define SPI0_INSTANCE_INDEX 0
    #endif
    
    #define SPI1_ENABLED 0
    
    #if (SPI1_ENABLED == 1)
    #define SPI1_USE_EASY_DMA 0
    
    #define SPI1_CONFIG_SCK_PIN         2
    #define SPI1_CONFIG_MOSI_PIN        3
    #define SPI1_CONFIG_MISO_PIN        4
    #define SPI1_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW
    
    #define SPI1_INSTANCE_INDEX (SPI0_ENABLED)
    #endif
    
    #define SPI2_ENABLED 0
    
    #if (SPI2_ENABLED == 1)
    #define SPI2_USE_EASY_DMA 0
    
    #define SPI2_CONFIG_SCK_PIN         2
    #define SPI2_CONFIG_MOSI_PIN        3
    #define SPI2_CONFIG_MISO_PIN        4
    #define SPI2_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW
    
    #define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED)
    #endif
    

    Now what I can see from that other post is that I must wire the MISO-MOSI, which I don't have, so that could also be it. I am actually trying to communicate with a peripheral, so is that what is causing this problem?

  • Yes, you will need to wire MOSI to MISO. The example is transmitting bytes out on MOSI and at the same time it receives the same sequence of bytes on MISO. Then the example is comparing the transmitted bytes to the received bytes and if they are not the same your example will assert and stop running.

Related