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

Error 8 (0x8): GATT CONN TIMEOUT on nRF52805

Hi, I used nRF52805 module BC805M on my customized board. I can only make the BLE connection for a few seconds or minutes. Then, the connection will be lost. Here are the Mobile nRF Connect error log and BLE sniffer log (in zip file): 

7444.20210706 BLE CONN TIMEOUT.zip

After reading some threads [1] [2] [3], I guess it's the clock issue? Because this board datasheet says "Both 32 MHz main crystal and load capacitors are inside the module. You can enable an internal RC oscillator for sleep clock or install an external 32.768 sleep crystal." Here are my BLE and clock configurations. 

//  --------------------- In main.c  ---------------------
#define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#define APP_ADV_DURATION                0                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(30, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */

#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

#define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */

#define SAADC_SAMPLES_IN_BUFFER         2
#define SAADC_SAMPLE_RATE               20                                         /**< SAADC sample rate in ms. */               






// --------------------- In sdk_config.h  ---------------------
// <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
 
// <0=> NRF_CLOCK_LF_SRC_RC 
// <1=> NRF_CLOCK_LF_SRC_XTAL 
// <2=> NRF_CLOCK_LF_SRC_SYNTH 

#ifndef NRF_SDH_CLOCK_LF_SRC
#define NRF_SDH_CLOCK_LF_SRC 0
#endif

// <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
#define NRF_SDH_CLOCK_LF_RC_CTIV 16
#endif

// <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
// <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
// <i>  if the temperature has not changed.

#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
#endif

// <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
 
// <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
// <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
// <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
// <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
// <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
// <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
// <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
// <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
// <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
// <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
// <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 

#ifndef NRF_SDH_CLOCK_LF_ACCURACY
#define NRF_SDH_CLOCK_LF_ACCURACY 1
#endif


Thanks in advance! 

  • Hi,

    I could not see anything obvious from the sniffer log. Could you check that all sdk_config entries are configured to use the RC?

    • NRFX_CLOCK_CONFIG_LF_SRC
    • CLOCK_CONFIG_LF_SRC
    • NRF_SDH_CLOCK_LF_SRC

    Also, could you try to get an application log? i.e. do you know if here are any errors or asserts in the application once it is disconnected?

  • Thanks run_ar, Yes, all above 3 parameters are 0 (RC ocillator)

    • NRFX_CLOCK_CONFIG_LF_SRC = 0
    • CLOCK_CONFIG_LF_SRC = 0
    • NRF_SDH_CLOCK_LF_SRC = 0

    I'm using a 400kHz TWI master, 2 ADC channels and BLE (i.e. Send TWI and ADC data via BLE). Although I could connect and see all data on the nRF Connect mobile App, BLE will disconnect in a few seconds. 

    __STATIC_INLINE void data_handler(uint16_t data1, uint16_t data2)
    {
         // Same data calculations and filters
    }
    
    
    .
    .
    .
    
    
    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;
            uint16_t bytes_to_send;
         
            // set buffers
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    						
            // Get 2 ADC values
            adc_data_1 = p_event->data.done.p_buffer[0];
            adc_data_2 = p_event->data.done.p_buffer[1];
    
            // convert ADC raw data to the real data
    
            uint8_t nus_string[100];
            bytes_to_send = sprintf(nus_string,"\%.2f     %.2f    %.2f", adc_data_converted_1, adc_data_converted_2, twi_data1);
            
            err_code = ble_nus_data_send(&m_nus, nus_string, &bytes_to_send, m_conn_handle);
            if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_NOT_FOUND))
            {
                APP_ERROR_CHECK(err_code);
            }
    	
            m_adc_evt_counter++;
        }
    }

    Here is nRF Connect Mobile App debug log: 

    Log 2021-07-08 16_47_39.txt

    Using the above code, BLE works fine if I only send ADC data (doesn't include TWI data). Why is that, please? What's the solution? Thank you! 

  • Hi,

    Thank you for the nRF connect log, Unfortunately it only shows me that there is a timeout, so it doesn't tell me anything about what is happening in the application. Could you capture an application log? or could you connect a debugger and check if you are getting any application errors? reboots? or any other issues?

    could you provide a project for recreating the issue? or the part of the code where you try to send TWI data?

  • Hi run_ar, thank you very much for your support.

    1) 

    I have 2 PCB boards: 1 board has the nRF52805, another PCB has TWI sensors. I'm using 2 ADC and 1 TWI and BLE. 

    2)

    For the application log, do you mean to use RTT Viewer? I have enabled RTT and LOG functions in sdk_config.h, but nothing shows on the RTT Viewer.

    (Note: Because it's a BLE application, we cannot use SEGGER debugger function)

    What do you mean by "debugger"? 

    3) 

    Because I don't have an external clock on my PCB, so I used the internal RC oscillator (32.768kHz). However, in my code, I used:

    SAADC_SAMPLE_RATE = 20ms  (Will it has an accuracy issue? I guess not, right?)

    many types of BLE intervals = 64ms, 20ms, 30ms, etc (Will it has an accuracy issue? I guess not, right?)

    timer_config.frequency = NRF_TIMER_FREQ_31250Hz; (Will it has an accuracy issue? I guess not, right?)

    TWI uses 400kHz clock (Higher frequency than RC oscillator, I guess it causes the code issue)

    And in future, I will use 14-bit oversampling for 2 SAADC. 

    Could I solve the above clock issues with internal clocks? 

    Thanks again! 

  • Hi,

    A good tip for debugging is to add the debug flag to preprocessor symbols and place a breakpoint in the app_error_fault_handler, that way you can see if there are any app errors.

    As for the lfrc, I think using the LFRC should be fine. The TWI clock is derived from the HFXO, but you might want to start the hfxo manually (by calling sd_clock_hfclk_request) for TWI, if not the SD might toggle it on/off (I am not to familiar with the driver, so it might be doing that already, but good to check).

    Fyi, we are beginning summer vacations, so you might get longer response times. I will be ooo for the next 4 weeks, you might want to open a new case if you cannot see any asserts.

Related