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

SPI Master initialization with BLE

Hi,

I've been trying to implement a SPI master module in the example ble_app_hrs_c_s120 on the nRF51 DK with nRF51422 (I copied the code of the example of spi_master in the BLE example).

It compiles without error nor warnings but doesn't work. After debugging, I found out that it's the configuration of the SPIM that causes a HardFault at the exact line :

// Configure SPI master.
spi_master_config_t spi_config = SPI_MASTER_INIT_DEFAULT;

The symbol is defined as :

#define SPI_MASTER_INIT_DEFAULT                                             \
{                                                                           \
    SPI_FREQUENCY_FREQUENCY_M1, /**< Serial clock frequency 1 Mbps. */      \
    SPI_PIN_DISCONNECTED,       /**< SCK pin DISCONNECTED. */               \
    SPI_PIN_DISCONNECTED,       /**< MISO pin DISCONNECTED. */              \
    SPI_PIN_DISCONNECTED,       /**< MOSI pin DISCONNECTED. */              \
    SPI_PIN_DISCONNECTED,       /**< Slave select pin DISCONNECTED. */      \
    APP_IRQ_PRIORITY_LOW,       /**< Interrupt priority LOW. */             \
    SPI_CONFIG_ORDER_LsbFirst,  /**< Bits order LSB. */                     \
    SPI_CONFIG_CPOL_ActiveHigh, /**< Serial clock polarity ACTIVEHIGH. */   \
    SPI_CONFIG_CPHA_Leading,    /**< Serial clock phase LEADING. */         \
    0                           /**< Don't disable all IRQs. */             \
};

I really can't figure out why it doesn't find the symbol. It's defined in spi_master.h that I included in the main.

The SD S120 is downloaded on the board and I use uvision 5.14 with the SDK 8.0.

Do you have any idea?

Thank you so much for your help, I'm stuck.

Yann

Parents
  • main.c

    The SPI interrupt priority is set to low (same as the UART perif.).

    Here is the function (located in spi_master.c) that causes the hardfault, exactly at the line

    	 APP_ERROR_CHECK(sd_nvic_EnableIRQ(p_spi_instance->irq_type));
    

    at the end of the function. Apparently it's when the softdevice is called to enable the SPI IRQ.

    uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance,
                                  uint8_t * const p_tx_buf, const uint16_t tx_buf_len,
                                  uint8_t * const p_rx_buf, const uint16_t rx_buf_len)
    {
        #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
    
        volatile spi_master_instance_t * p_spi_instance = spi_master_get_instance(
            spi_master_hw_instance);
        APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
    
        uint32_t err_code   = NRF_SUCCESS;
        uint16_t max_length = 0;
        
        uint8_t nested_critical_region = 0;
        
        //Check if disable all IRQs flag is set
        if (p_spi_instance->disable_all_irq)
        {
            //Disable interrupts.
            APP_ERROR_CHECK(sd_nvic_critical_region_enter(&nested_critical_region));
        }
        else
        {
            //Disable interrupt SPI.
            APP_ERROR_CHECK(sd_nvic_DisableIRQ(p_spi_instance->irq_type));
        }
    
        //Initialize and perform data transfer
        if (p_spi_instance->state == SPI_MASTER_STATE_IDLE)
        {
            max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len;
    
            if (max_length > 0)
            {
                p_spi_instance->state        = SPI_MASTER_STATE_BUSY;
                p_spi_instance->bytes_count  = 0;
                p_spi_instance->started_flag = false;
                p_spi_instance->max_length   = max_length;
    
                /* Initialize buffers */
                spi_master_buffer_init(p_tx_buf,
                                       tx_buf_len,
                                       &(p_spi_instance->p_tx_buffer),
                                       &(p_spi_instance->tx_length),
                                       &(p_spi_instance->tx_index));
                spi_master_buffer_init(p_rx_buf,
                                       rx_buf_len,
                                       &(p_spi_instance->p_rx_buffer),
                                       &(p_spi_instance->rx_length),
                                       &(p_spi_instance->rx_index));
    
                nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
                spi_master_send_initial_bytes(p_spi_instance);
            }
            else
            {
                err_code = NRF_ERROR_INVALID_PARAM;
            }
        }
        else
        {
            err_code = NRF_ERROR_BUSY;
        }
    		
        //Check if disable all IRQs flag is set.
        if (p_spi_instance->disable_all_irq)
        {   
            //Enable interrupts.
            APP_ERROR_CHECK(sd_nvic_critical_region_exit(nested_critical_region));
        }
        else
        {
            //Enable SPI interrupt.
    			  APP_ERROR_CHECK(sd_nvic_EnableIRQ(p_spi_instance->irq_type));
            
        }
    
        return err_code;
        #else
        return NRF_ERROR_NOT_SUPPORTED;
        #endif
    }
    
  • Seems strange, however I cannot know the reason for the hardfault unless I will be able to reproduce it myself and I do not have working setup to test this yet. I will try to reproduce this on monday.

Reply Children
No Data
Related