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

Reset during connection setup

Hello,

i asked this quastion once in this thread: https://devzone.nordicsemi.com/f/nordic-q-a/32444/reset-on_ble_connect-when-button-event
I accepted the given answer but later i found out that the solution does not work. I rejected the answer, but i am afraid that nobody can see it anymore.
This is not intended as spamming and i apologize for the duplicate. I sum up the results of thread:

My problem is reproducable with this setup:

  • nRF5-DK with ble_blinky_example (central)
  • nRF5-DK with ble_blinky_example (peripheral)
  • Press Button1 immediately on the peripheral after connecting (LED2 lights up).
  • watch how the peripheral goes back to Advertising (resets)
  • Press Button1 after the Connection is established a while, everything works fine.
  • SDK 12.3 and Softdevice S130 2.0.1/ Softdevice S132 3.0.0

The problem is that pressing a button on the peripheral after connection setup causes a reset. It is shown in the video attached:

  • Peripheral left, central right.
  • First: in connection, everything fine. (Button press is indicated with a led).
  • Second: Switch off and on the peripheral (same with resetting  via IF BOOT/RESET). Press Button1 directly after connecting (LED2 lights up). Board goes back to advertising/resets.
  • Third: Wait after connection. Everything works fine. (Button press is indicated with a led)

If the button_event_handler() is empty, the devices stay connected. APP_ERROR_CHECK(err_code) causes the reset. NRF_LOG_INFO shows err_code = 13313 --> ERROR: fatal. If i comment the APP_ERROR_CHECK out, the connection stays (at least the led is still on). The first button presses are not detected, but the later ones.

In my application, i want to show that the device is in a connection so that the customer can start interacting. Therefore, i want to be sure that there is a valid connection when a led lights up.


Tried Solutions:
I tried to check if there is a valid connection-handle but that does not help. I dont know how to check for the other err_codes (13313).

static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
    uint32_t err_code;
    if(m_conn_handle != BLE_CONN_HANDLE_INVALID)        
    {
        switch (pin_no)
        {
            case LEDBUTTON_BUTTON_PIN:
                NRF_LOG_INFO("Send button state change.\r\n");
                err_code = ble_lbs_on_button_change(&m_lbs, button_action);
                NRF_LOG_INFO("Error Code: %d \r\n", err_code);    
                if (err_code != NRF_SUCCESS &&
                    err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                    err_code != NRF_ERROR_INVALID_STATE
                    )
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;

            default:
                APP_ERROR_HANDLER(pin_no);
                break;
        }
    }
}


I used a timer to delay the indication of the connection state. But that is kind of sloppy.

In on_ble_evt() a timer is started:

        case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected\r\n");
                err_code = app_timer_stop(m_adv_con_led_timer_id);
                APP_ERROR_CHECK(err_code);
                //bsp_board_led_on(CONNECTED_LED_PIN);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                err_code = app_timer_start(m_off_timer_id, APP_TIMER_TICKS(400, APP_TIMER_PRESCALER), NULL);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GAP_EVT_CONNECTED

And in the timer_handler, the state is indicated and the app_button module enabled:

                uint8_t  err_code = app_button_enable();
                APP_ERROR_CHECK(err_code);
                bsp_board_led_on(CONNECTED_LED_PIN);

Thank you very much in advance and kind regards

DanKa

Parents
  • Hi Dan,

    It is quite easy to debug set a breakpoint at the app_error_handler and see which line caused this error.

    The answer I gave you in my last post is a fix for one bug we saw. And I realized it within few minutes of setting the breakpoint at everyplace in project that has NVIC_SystemReset();

    Please start your project in debug mode and see why the call stack when you see that your breakpoint is hit.

  • Hi Aryan,

    i am afraid i misunderstand you and/or need a little help. I started the project in debug mode (defined DEBUG and no optimazations) and set the breakpoint  app_error_handler() / app_error_save_and_stop in the app_error.c file.

    I get:

    • p_file_name = "main.c"
    • line_num = 501 --> that's the line where APP_ERROR_CHECK is called within the button_event_handler()
    • err_code = 13313 (0x3401):
      NRF_ERROR_STK_BASE (0x3000) + 0x400 -->
      NRF_GATTS_ERR_BASE (0x3400) + 1 -->
      BLE_GATTS_SYS_ATTR_MISSING (0x3401)

    So these are no new Information compared to NRF_LOG. Here is a screenshot:

    1. Could you please guide me where to place the breakpoints correctly?
    2. How do i check for BLE_GATTS_SYS_ATTR_MISSING equivalent to as we did for the invalid handle with if(m_conn_handle != BLE_CONN_HANDLE_INVALID)*?

    *even if i do not check for invalid handle, i get err_code = 13313.

    Thank your very much in advance

  • Hi Dan,

    This error is well documented and there is a thread here in devzone that will explain more about it. 

    You can read more about it here

    You need to add the below code in the ble event handler to fix this problem

    case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
            APP_ERROR_CHECK(err_code);

  • Thank you very much for your answer. The searching for 0x3401 helped me.

    I noticed that BLE_GATTS_EVT_SYS_ATTR_MISSING was already in on_ble_evt() and i never entered it:  

            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                // No system attributes have been stored.
                NRF_LOG_INFO("System Attribute missing \r\n");
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GATTS_EVT_SYS_ATTR_MISSING

    I added these lines at BLE_GAP_EVT_CONNECTED:

            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected\r\n");
                bsp_board_led_on(CONNECTED_LED_PIN);
                bsp_board_led_off(ADVERTISING_LED_PIN);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                
                // set system attributes
                NRF_LOG_INFO("Set system attributes\r\n");
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                
                err_code = app_button_enable();
                APP_ERROR_CHECK(err_code);
                break; // BLE_GAP_EVT_CONNECTED
    Now, the scenario above results NRF_ERROR_INVALID_STATE because the CCCD was not written. But i can check for that with adding BLE_GATTS_EVT_WRITE to on_ble_evt():

            case BLE_GATTS_EVT_WRITE:
                on_write(p_ble_evt);
                NRF_LOG_INFO("A Write Event \r\n");
                break; // BLE_GATTS_EVT_WRITE

    With on_write(..) to indicate that everything is set up and to enable the app_button:

    static void on_write(ble_evt_t * p_ble_evt)
    {
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; // Prüfen, ob CCCD beschrieben ist
        if ((p_evt_write->handle == m_lbs.button_char_handles.cccd_handle)){
            bsp_board_led_on(CONNECTED_LED_PIN);
            bsp_board_led_off(ADVERTISING_LED_PIN);
            err_code = app_button_enable();
            APP_ERROR_CHECK(err_code);
        }
    }

Reply
  • Thank you very much for your answer. The searching for 0x3401 helped me.

    I noticed that BLE_GATTS_EVT_SYS_ATTR_MISSING was already in on_ble_evt() and i never entered it:  

            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                // No system attributes have been stored.
                NRF_LOG_INFO("System Attribute missing \r\n");
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                break; // BLE_GATTS_EVT_SYS_ATTR_MISSING

    I added these lines at BLE_GAP_EVT_CONNECTED:

            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected\r\n");
                bsp_board_led_on(CONNECTED_LED_PIN);
                bsp_board_led_off(ADVERTISING_LED_PIN);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                
                // set system attributes
                NRF_LOG_INFO("Set system attributes\r\n");
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                
                err_code = app_button_enable();
                APP_ERROR_CHECK(err_code);
                break; // BLE_GAP_EVT_CONNECTED
    Now, the scenario above results NRF_ERROR_INVALID_STATE because the CCCD was not written. But i can check for that with adding BLE_GATTS_EVT_WRITE to on_ble_evt():

            case BLE_GATTS_EVT_WRITE:
                on_write(p_ble_evt);
                NRF_LOG_INFO("A Write Event \r\n");
                break; // BLE_GATTS_EVT_WRITE

    With on_write(..) to indicate that everything is set up and to enable the app_button:

    static void on_write(ble_evt_t * p_ble_evt)
    {
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; // Prüfen, ob CCCD beschrieben ist
        if ((p_evt_write->handle == m_lbs.button_char_handles.cccd_handle)){
            bsp_board_led_on(CONNECTED_LED_PIN);
            bsp_board_led_off(ADVERTISING_LED_PIN);
            err_code = app_button_enable();
            APP_ERROR_CHECK(err_code);
        }
    }

Children
No Data
Related