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

After addition SPI to softdevice, some unknown error happened. Even the circulation in main function didn't work?

Hi,

I just want to add SPI to my BLE project to read some data from my gyro, but after spi's addition, the code doesn't work normally anymore. I print a log in the cycle of main function, after add spi, the circulation in main function just cycle limited times.

Before adding spi, i've defined a timer and timerout handler existed, but after spi's addition, the code can't enter the " timerout_handler" function, because i found some logs i've defined in " timerout_handler"  didn't print and display.

main function:

timer_handler:

Settings related to spi:

the LOG sequence: it stop print when "i" in increase to 35

If anyone have some opinions ?

best regards,

jerry

Parents Reply Children
  • Hi, 

    I didn't use SES, i used KEIL5. So far,I can't find wherer it hangs. 

    I used the "ble_app_template"  example,  and i used the spi example in SDK 15.0,  the picture below.

    Is there any problem that i use spi example instead of spi_master?

    Here is the main fuction:

    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
        log_init();   
        timers_init();
        buttons_leds_init(&erase_bonds);
    	 
        power_management_init();
        ble_stack_init();
        gap_params_init();
    	
    	
        gatt_init();
        advertising_init();
        services_init();
        conn_params_init();
        peer_manager_init();
    
        // Start execution.
        NRF_LOG_INFO("Template example started.");
    	
        nrf_gpio_cfg_output(11);
        spi_init();
    		NRF_LOG_INFO("spi init");
    		spi_enable();
    		NRF_LOG_INFO("spi enable");
    		ICM_init();
    		NRF_LOG_INFO("ICM init");
        advertising_start(erase_bonds);
    
    		 
      
        // Enter main loop.
        for (;;)
        {
    			i++;
            NRF_LOG_INFO("while cycle");
    			NRF_LOG_INFO("i=%d\n",i);
    			
            idle_state_handle();
    			nrf_delay_ms(10);
        }
    		
    }
    

    timer handler:(the "data_upload_immediate()" function was used to send some data)

    static void timer_timeout_handler1(void* p_context)
    {
    	NRF_LOG_INFO("timerout_handler");
    	UNUSED_PARAMETER(p_context);
    	int32_t temp;
    	uint8_t value[2];
    	uint8_t* icm_x_acc;	
    	temp=temp_read()/4;
    	
    	value[0]='0'+temp/10;
    	value[1]='0'+(temp%10)/1;
    	
    	NRF_LOG_INFO("the tenth place is£º%c\n",value[0]);
      NRF_LOG_INFO("the ones place is£º%c\n",value[1]);
    	
      icm_x_acc[0]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_H);//0x43
    	icm_x_acc[1]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_L);
    	NRF_LOG_INFO("ACCEL_XOUT_H is£º%x\n",icm_x_acc[0]);
      NRF_LOG_INFO("ACCEL_XOUT_L is£º%x\n",icm_x_acc[1]);
          if(connect_flag==1)
    			{
    	      err_code22=data_upload_immediate(m_conn_handle, &m_lbs,value);
         
    			}
    			else if(connect_flag==0)
    			{nrf_gpio_pin_toggle(11);}
    	
    }

    data_upload_immediate():

    uint32_t data_upload_immediate(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t*data)
    {
        ble_gatts_hvx_params_t params;
        uint16_t len = 2;
    
    
        memset(&params, 0, sizeof(params));
        params.type   = BLE_GATT_HVX_NOTIFICATION;
        params.handle = p_lbs->data_upload_char_handles.value_handle;
        params.p_data = data;
        params.p_len  = &len;
    
        return sd_ble_gatts_hvx(conn_handle, &params);
    }

    settings related to spi:

    void spi_init()
    	{
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
        spi_config.miso_pin = SPI_MISO_PIN;
        spi_config.mosi_pin = SPI_MOSI_PIN;
        spi_config.sck_pin  = SPI_SCK_PIN;
    		spi_config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;         
        spi_config.orc          = 0xFF;                             
        spi_config.frequency    = NRF_DRV_SPI_FREQ_8M;               
        spi_config.mode         = NRF_DRV_SPI_MODE_3;          
        spi_config.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

  • This is a bug:

      uint8_t* icm_x_acc;	
    
      icm_x_acc[0]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_H);//0x43
      icm_x_acc[1]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_L);

    The pointer is uninitialised, so a memory corruption is inevitable. Try this:

    static uint8_t SomeBuffer[2];
    
      uint8_t* icm_x_acc = SomeBuffer;	
    
      icm_x_acc[0]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_H);//0x43
      icm_x_acc[1]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_L);
    
    or
    
      uint8_t icm_x_acc[2];	
    
      icm_x_acc[0]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_H);//0x43
      icm_x_acc[1]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_L);

  • Hi,

    yes, it is a bug. But after i fixed it, the code still went wrong.

    I found once i add the code below to "timeout_handler" , it went wrong. 

    icm_x_acc[0]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_H);//0x43
    	icm_x_acc[1]=ICM_Get_Accelerometer(ICM20602_ACCEL_XOUT_L);
    	NRF_LOG_INFO("ACCEL_XOUT_H is£º%x\n",icm_x_acc[0]);
      NRF_LOG_INFO("ACCEL_XOUT_L is£º%x\n",icm_x_acc[1]);

    However, if i annotate these, everything work well. I guess  it didn't get the acceleration??so the code hangs?

  • First try moving that code to the main() loop and just set a flag in the timeout handler; when the flag is set execute those lines and clear the flag ready for the next set. That avoids all the myriad interrupt level issues, and also improves the handler efficiency.

    As an aside, "ACCEL_XOUT_L is£º%x\n" is suspicious; isn't "ACCEL_XOUT_L is %x\n" what you intended? Note that %x expects a 16-bit value, so even better typecast the values to 16-bit (that latter is probably not an issue, but worth correcting).

      NRF_LOG_INFO("ACCEL_XOUT_H is %x\n",(uint16_t)icm_x_acc[0]);
      NRF_LOG_INFO("ACCEL_XOUT_L is %x\n",(uint16_t)icm_x_acc[1]);

  • Hi, 

    yeah, i've tried the way you said, but it was so strange, the code seemed that it didn't go to timeout_handler and even there were no logs printed out , just like the code was a mess. 

    So i annotated the  "application_timers_start();", just moving the  acceleration_read code to main() loop,

    this time, there were logs printed, but the logs was also a mess. Details were here.

    If you have any suggestions, it would be ok .thanks.

    Jerry

Related