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

Reconnection failure after SAADC

We are now developing BLE ADC sender, using nRF5_SDK_14.0.0_3bcc1f7, and two nRF528322s (sender and reciever).

We send SAADC data via BLE, after that, we disconnect, and tried to reconnect, then "HardFault" happened.

Situation is as follow,

Reconnection event, "BLE_GAP_EVT_CONNECTED" is successfully happens, so connection process is thought to be finished.

SAADC process is made from \examples\peripherak\saadc.

Data from SAADC are saved in buffer memory (160x100) in interrupt process. And other function is reading this buffer and taking average of them, and is about to send them via BLE.

Sending packet data size is 143 bytes. Sending period is about 1 second. Data sending itself is successful.

Due to the situation above, we are now thinking problem is around buffer (160 x 100), but we don't think any relationship this buffer and BLE communication.

Do you have any good measure to handle this?

Part of our code below. 


/****************** Happening HardFault area****************************************/
......\pca10040\s132\arm5_no_packs\RTE\Device\nRF52832_xxAA\arm_startup_nrf52.s

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP

/****************** SAADC process ****************/
#define BUFF_SIZE 100
uint16_t send_data_buf[ BUFF_SIZE ][ SAMPLES_IN_BUFFER+2 ] ;//ling buffer
int buf_w_point=0;
int send_count = 0;//100sample a/d data counter
int ble_send_start = 0;
int count1 = 0;

static void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{

if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;

err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);

if (ad_tx_start_f == 1)
{
int i;
for (i = 0; i < SAMPLES_IN_BUFFER; i++)
{
send_data_buf[ buf_w_point ][ i ] = p_event->data.done.p_buffer[i];
}

send_count++;

send_data_buf[buf_w_point][SAMPLES_IN_BUFFER] = (uint16_t)m_adc_evt_counter;
send_data_buf[buf_w_point][SAMPLES_IN_BUFFER+1] = (uint16_t)send_count;
if(buf_w_point> (BUFF_SIZE-1))
{
buf_w_point=0;
}
else
{
buf_w_point++;
}
}
else
{
send_count = 0;
buf_w_point=0;
}

m_adc_evt_counter++;
now_buffer_pool_p = (uint16_t *)p_event->data.done.p_buffer;

}
}


/****************** Reading buffer process ****************/
if(send_count > 10)
{
//send_count--;
m=0;

param[2].uspoint = &adc_data[0];

for(i=0;i<100;i++)
{
total=0;
for(n=0;n<16;n++)
{
total += send_data_buf[ buf_r_point ][ m+n ];
}
//ave = total/16;
ave_too = total >> 4;
param[2].uspoint[i] = (uint16_t) ave_too;
m=m+16;

if(m>=160)
{
send_count--;
m=0;
if(buf_r_point> (BUFF_SIZE-1))
{
buf_r_point=0;
}
else
{
buf_r_point=buf_r_point+1;
}
}

}

  • Hi,

    Try to include the HardFault handling library into your project. This library may help you to determine where and why the exception occurred more easily. To use the library, you need to include source files listed below and also set HARDFAULT_HANDLER_ENABLED to '1' in sdk_config and include 'DEBUG' in the list of preprocessor symbols. 

    - hardfault_implementation.c

    - Select one of the three handler implementations based on the compiler you use: hardfault_handler_keil.c / hardfault_handler_iar.c / hardfault_handler_gcc.c 

  • Thank you for your reply. I submitted our code as you mentioned. How is this?

    /****************** Happening HardFault area****************************************/
    ......\pca10040\s132\arm5_no_packs\RTE\Device\nRF52832_xxAA\arm_startup_nrf52.s
    
    ; Dummy Exception Handlers (infinite loops which can be modified)
    
    NMI_Handler     PROC
                    EXPORT  NMI_Handler               [WEAK]
                    B       .
                    ENDP
    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler         [WEAK]
                    B       .
                    ENDP
    
    
    
    /****************** SAADC process ****************/
    #define BUFF_SIZE 100
    uint16_t send_data_buf[ BUFF_SIZE ][ SAMPLES_IN_BUFFER+2 ] ;//ling buffer
    int buf_w_point=0;
    int send_count = 0;//100sample a/d data counter  
    int ble_send_start = 0;
    int count1 = 0;
    
    static void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
    
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
           if (ad_tx_start_f == 1)
           {
    	   int i;
               for (i = 0; i < SAMPLES_IN_BUFFER; i++)
               {
    	       send_data_buf[ buf_w_point ][ i ] = p_event->data.done.p_buffer[i];
               }			
    
               send_count++;
    				
    	   send_data_buf[buf_w_point][SAMPLES_IN_BUFFER] = (uint16_t)m_adc_evt_counter;
    	   send_data_buf[buf_w_point][SAMPLES_IN_BUFFER+1] = (uint16_t)send_count;
               if(buf_w_point> (BUFF_SIZE-1))
               {  
                  buf_w_point=0; 
               } 
               else
               { 
                  buf_w_point++; 
               } 
            }  
            else
            {
               send_count = 0; 
               buf_w_point=0; 
            }
     
            m_adc_evt_counter++;
            now_buffer_pool_p = (uint16_t *)p_event->data.done.p_buffer;	
    
        }
    }
    
    
    /****************** Reading buffer process ****************/
            if(send_count > 10) 
            { 
                //send_count--; 
                m=0;
    							
                param[2].uspoint = &adc_data[0];
    
                for(i=0;i<100;i++) 
                { 
                    total=0; 
                    for(n=0;n<16;n++) 
                    {
                       total += send_data_buf[ buf_r_point ][ m+n ]; 
                    }
                    //ave = total/16; 
                    ave_too = total >> 4;
                    param[2].uspoint[i] = (uint16_t) ave_too; 
                    m=m+16;
     
                    if(m>=160) 
                    { 
                          send_count--; 
                          m=0;
                          if(buf_r_point> (BUFF_SIZE-1)) 
                          {
                             buf_r_point=0; 
                          }
                          else 
                          {
                             buf_r_point=buf_r_point+1; 
                          }
    								}
    							
    							}
    

  • Thank you for your reply, Vidar Berg,

    I will try your advice from now on, I will report you afterward.

  • I tried HardFault handling library. After that, I found figures(and address) below at Stack pointer.

    SP

    0x2000DCC0: 00000004 Flash
    0x2000DCC4: 022E022D Reserved
    0x2000DCC8: 0000022E Flash
    0x2000DCCC: 00029C24 Flash

    I checked these address data, but I cannot understand what is wrong.

    Do you have any ideas to?specify the reason of Hardfault from these values?

    I attached display hardcopy:
    and 0x00000004~0x00029C24 values

    And, about the situation when HardFault happened.
    When we tried to make reconnection, BLE event process is successfully done until "BLE_GAP_EVT_CONNECTED"'s break;
    Just after that, the HardFault looked happening.

    We think BLE reconnection is the problem itself, do you know the simillar situation when BLE connecting?

    /****************** Interrupt BLE event process ****************/
    int ble_connect_state=0;//20190312 y.t
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint32_t err_code;
    
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_HVN_TX_COMPLETE:// ack from central
                ble_gatts_evt_hvn_tx_complete_flag = 1; 
                break;
    			
            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected");
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                ble_connect_state=1;//20190312
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected");
                err_code = bsp_indication_set(BSP_INDICATE_IDLE);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                ble_connect_state=0;//20190312
                //sd_nvic_SystemReset();//201900926 for debug 
                break;
    
    
       ...
       ...
       ...
    
    
            default:
                // No implementation needed.
                break;
        }
    }

Related