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

SPI when advertising not working

Hi 

I am using SPI to talk to an LIS2DH with an NRF51822. I have merged the SPI Master example with the ble_app_rscs example and as soon as the ble advertising begins, my SPI interrupts no longer work and I end up in the hard fault. I have changed the IRQ priority to high but it still does not work. 

I am using SDK8.0.0 - I know it's old, it's the only SDK version I could get to work with the free version of Keil. 

  • Try to use app_scheduler to differ interrupt processing. 

    void SchedIrqHandler(void * p_event_data, uint16_t event_size)
    
    {
    
    ...
    
    }
    
    
    
    void IRQ_Handler()
    
    {
    
        uint32 evt = 1;
    
        app_sched_event_put(&evt, sizeof(uint32_t), SchedIrqHandler);
    
    }
    
    

  • thanks. what would be the equivalent app_scheduler to use in SDK 8? 

  • actually I'm not sure if I'm setting this up right at all. here is my code: 

    spi_config() works fine when called the first two time in the main loop. once advertising_start() has been called it no longer works - to test I am simply trying to call the accelerometer data as part of the cadence measurement send: 

    int main(void)
    {
        uint32_t err_code;how to 
    	
        // Initialize.
        app_trace_init();
    		leds_init();
        ble_stack_init();
        device_manager_init();
        timers_init();
        APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
        err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
                            APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
                            NULL);
        APP_ERROR_CHECK(err_code);
        gap_params_init();
        advertising_init();
        services_init();
        sensor_simulator_init();
        conn_params_init();
    		spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
    		spi_config(); 
        // Start execution.
        application_timers_start();	
        advertising_start();
        // Enter main loop.
        for (;; )
        {
            power_manage(); 
        }
    }
    
    
    void spi_config(void)
    {
    		    // Setup bsp module.
       // bsp_configuration();
    	 
    
    		uint8_t tx_data[2] = {0x00, 0x00};  							// Transmit register
    		uint8_t rx_data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // Receive register
    
    
    			tx_data[0] = ( WHO_AM_I | 0x80 ); //Add the RW bit to the address.
    			m_transfer_completed   = false; 
    			nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
    			spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2); 
    
    			nrf_delay_ms(10); 
    	//write ctr_reg1
    			tx_data[0] = CTR_REG1; 
    			tx_data[1] = 0xFF;		//low power mode 
          m_transfer_completed   = false;
          nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
          spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2); 
    			nrf_delay_ms(10);
    		
    		//read it back
    			tx_data[0] = (CTR_REG1 | 0x80); 
    			tx_data[1] = 0x00;		
          m_transfer_completed   = false;
          nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
          spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2);  
    			nrf_delay_ms(10);
    		
    		//write ctr_reg4
    			tx_data[0] = CTR_REG4; 
    			tx_data[1] = 0x08;		//low power mode
          m_transfer_completed   = false;
          nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false); 
          spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2); 
    			nrf_delay_ms(10);
    			
    			//read it back
    			tx_data[0] = (CTR_REG4 | 0x80); 
    			tx_data[1] = 0x00;		//low power mode
          m_transfer_completed   = false;
          nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
          spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2); 
    
    			nrf_delay_ms(10);
    		
    		#ifdef SPI_TEST
    		while (true)
        {
    			tx_data[0] = (OUT_X_H_addr | 0xC0 );		//read bit set (bit 0) & increment registers (bit 1)  
    			tx_data[1] = 0x00;
          m_transfer_completed   = false;
          nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
          spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 7); 
    			nrf_delay_ms(500);
        }
    		#endif //SPI_TEST
    	
    }
    
    uint8_t get_acc_data(void)
    {
    			uint8_t tx_data[2] = {0x00, 0x00}; 																// Transmit register
    			uint8_t rx_data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // Receive register
    	
    //			tx_data[0] = (OUT_X_H_addr | 0xC0 );															//read bit set (bit 0) & increment registers (bit 1)  
    //			tx_data[1] = 0x00;
    //      m_transfer_completed   = false;
    //      nrf_delay_ms(1);
    //			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
    //      spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 7); 
    //			nrf_delay_ms(10);
    
    			tx_data[0] = ( WHO_AM_I | 0x80 ); //Add the RW bit to the address.
    			m_transfer_completed   = false;
    			//nrf_delay_ms(1);
    			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
    			spi_send_recv(SPI_MASTER_0, tx_data, rx_data, 2); 
    
    			//nrf_delay_ms(10); 
    			return rx_data[1];
    }
    
    

    then in ble_rscs.c: 

    uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement)
    {
        uint32_t err_code;
    		uint8_t tx_data[2] = {0x00, 0x00}; 							// Transmit register
    		uint8_t rx_data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // Receive register
    		
    		
        // Send value if connected and notifying
        if (p_rscs->conn_handle != BLE_CONN_HANDLE_INVALID)
        {
            uint8_t                encoded_rsc_meas[MAX_RSCM_LEN];
            uint16_t               len;
            uint16_t               hvx_len;
            ble_gatts_hvx_params_t hvx_params;
    
    				
    			
            len     = rsc_measurement_encode(p_rscs, p_measurement, encoded_rsc_meas);
            hvx_len = len;
    
            memset(&hvx_params, 0, sizeof(hvx_params));
    
            hvx_params.handle = p_rscs->meas_handles.value_handle;
            hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
            hvx_params.offset = 0;
            hvx_params.p_len  = &hvx_len;
    			
    				encoded_rsc_meas[0] = get_acc_data();
            hvx_params.p_data = encoded_rsc_meas;
    
    			
            err_code = sd_ble_gatts_hvx(p_rscs->conn_handle, &hvx_params);
            if ((err_code == NRF_SUCCESS) && (hvx_len != len))
            {
                err_code = NRF_ERROR_DATA_SIZE;
            }
        }
        else
        {
            err_code = NRF_ERROR_INVALID_STATE;
        }
    
        return err_code;
    }

  • It doesn't work after advertisement_start() is normal.  The spi_config is taking to much time.  Softdevice does like it.  There are also to many delays in your get_acc_data.  

Related