This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

FIRST_CONN_PARAMS_UPDATE_DELAY error

Hello, 

I crated a custom peripheral for my application, I took the code from the Blinky example and i changed the service.

I set the FIRST_CONN_PARAMS_UPDATE_DELAY parameter like this : 

#define FIRST_CONN_PARAMS_UPDATE_DELAY	APP_TIMER_TICKS(20000)					/**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (20 seconds). */

And the MIN_CONN_INTERVAL and MIN_CONN_INTERVAL like this : 

#define MIN_CONN_INTERVAL				MSEC_TO_UNITS(200, UNIT_1_25_MS)			/**< Minimum acceptable connection interval (100 = 100 ms). */
#define MAX_CONN_INTERVAL				MSEC_TO_UNITS(300, UNIT_1_25_MS)		/**< Maximum acceptable connection interval (300 = 300 ms). */

After 20s i Expect the Conn interval to be around 300ms afer 20s in order to save power, unfortunately after 20s the code crash and i have no idea where, i put logs to where i belive is the crash but i don't see anything.

			case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
			{
				NRF_LOG_INFO("BLE_GAP_EVT_PHY_UPDATE_REQUEST");
				ble_gap_phys_t const phys =
				{
					.rx_phys = BLE_GAP_PHY_AUTO,
					.tx_phys = BLE_GAP_PHY_AUTO,
				};
				err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
				APP_ERROR_CHECK(err_code);
			} break;

static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    ret_code_t err_code;

    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
				NRF_LOG_INFO("ble conn params failed");
        err_code = sd_ble_gap_disconnect(p_evt->conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
        //APP_ERROR_CHECK(err_code);
    }
		else
		{
			NRF_LOG_INFO("BLE_CONN_PARAMS_EVT_SUCCESS");
		}
}

I tried with those parameters : 

#define MIN_CONN_INTERVAL				MSEC_TO_UNITS(200, UNIT_1_25_MS)			/**< Minimum acceptable connection interval (8 = 100 ms). */
#define MAX_CONN_INTERVAL				MSEC_TO_UNITS(300, UNIT_1_25_MS)		/**< Maximum acceptable connection interval (150 = 200 ms). */

And it works fine but i don't belive there is an PHY update.

On the other hand the bliky example works fine.

What did i do wrong ? For the central i used NRF connect on my phone and with the PC connected to a dev bloard.

Thank you

  • I'm sorry on the second try i had there parameters :

    #define MIN_CONN_INTERVAL				MSEC_TO_UNITS(8, UNIT_1_25_MS)			/**< Minimum acceptable connection interval (8 = 8 ms). */
    #define MAX_CONN_INTERVAL				MSEC_TO_UNITS(150, UNIT_1_25_MS)		/**< Maximum acceptable connection interval (150 = 150 ms). */

  • Hello,

    Please add the DEBUG flag to your preprocessor list as explained in this post: https://devzone.nordicsemi.com/f/nordic-q-a/10729/my-device-is-freezing-and-restarting. This will make your program enter an infinite loop in the app error handler (see Error module) and let you read out the file name and line number of where the error occurred.

    Best regards,

    Vidar

  • Hello, i looked it up but it seems mu app_error is different 

    /**
     * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup app_error Common application error handler
     * @{
     * @ingroup app_common
     *
     * @brief Common application error handler.
     */
    
    #include "nrf.h"
    #include <stdio.h>
    #include "app_error.h"
    #include "nordic_common.h"
    #include "sdk_errors.h"
    
    /**@brief Function for error handling, which is called when an error has occurred.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of error.
     *
     * @param[in] error_code  Error code supplied to the handler.
     * @param[in] line_num    Line number where the handler is called.
     * @param[in] p_file_name Pointer to the file name.
     */
    void app_error_handler_bare(ret_code_t error_code)
    {
        error_info_t error_info =
        {
            .line_num    = 0,
            .p_file_name = NULL,
            .err_code    = error_code,
        };
    
        app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
    
        UNUSED_VARIABLE(error_info);
    }
    
    void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
    {
        /* static error variables - in order to prevent removal by optimizers */
        static volatile struct
        {
            uint32_t        fault_id;
            uint32_t        pc;
            uint32_t        error_info;
            assert_info_t * p_assert_info;
            error_info_t  * p_error_info;
            ret_code_t      err_code;
            uint32_t        line_num;
            const uint8_t * p_file_name;
        } m_error_data = {0};
    
        // The following variable helps Keil keep the call stack visible, in addition, it can be set to
        // 0 in the debugger to continue executing code after the error check.
        volatile bool loop = true;
        UNUSED_VARIABLE(loop);
    
        m_error_data.fault_id   = id;
        m_error_data.pc         = pc;
        m_error_data.error_info = info;
    
        switch (id)
        {
            case NRF_FAULT_ID_SDK_ASSERT:
                m_error_data.p_assert_info = (assert_info_t *)info;
                m_error_data.line_num      = m_error_data.p_assert_info->line_num;
                m_error_data.p_file_name   = m_error_data.p_assert_info->p_file_name;
                break;
    
            case NRF_FAULT_ID_SDK_ERROR:
                m_error_data.p_error_info = (error_info_t *)info;
                m_error_data.err_code     = m_error_data.p_error_info->err_code;
                m_error_data.line_num     = m_error_data.p_error_info->line_num;
                m_error_data.p_file_name  = m_error_data.p_error_info->p_file_name;
                break;
        }
    
        UNUSED_VARIABLE(m_error_data);
    
        // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
        __disable_irq();
        while (loop);
    
        __enable_irq();
    }
    

    maybe it's on an older SDK

    I always fall here in arm_startup_nrf52.s

    HardFault_Handler\
                    PROC
                    EXPORT  HardFault_Handler         [WEAK]
                    B       .
                    ENDP

  • Yes, looks like you are using an older SDK version. What version is it?

    Albin said:
    I always fall here in arm_startup_nrf52.s

    This means you are getting a hardfault exception, and not an assertion that will get you to the app error handler.

    Here is an appnote from Keil which explains how you can go about debugging a hardfault: https://www.keil.com/appnotes/files/apnt209.pdf. But before reading through all that, you may try to inspect the call stack view in Keil after you have reached the HardFault_Handler. It may show the function call that was executed when the fault occurred.

  • Hello, I am on SDK15.

    In the execution I se this :

    I tried to change the send_update_request function but even with NRF_LOG and breakpoints i can't get the actual error 

    static bool send_update_request(uint16_t conn_handle, ble_gap_conn_params_t * p_new_conn_params)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_conn_param_update(conn_handle, p_new_conn_params);
    		if(err_code == NRF_ERROR_INVALID_ADDR) 
    		{
    			NRF_LOG_INFO("NRF_ERROR_INVALID_ADDR");
    		}
    			
    		if (err_code == NRF_ERROR_INVALID_PARAM)
    		{
    			NRF_LOG_INFO("NRF_ERROR_INVALID_PARAM");
    		}
    		if (err_code == NRF_ERROR_INVALID_STATE)
    		{
    			NRF_LOG_INFO("NRF_ERROR_INVALID_STATE");
    		}
    		if (err_code == BLE_ERROR_INVALID_CONN_HANDLE) 
    		{
    			NRF_LOG_INFO("BLE_ERROR_INVALID_CONN_HANDLE");
    		}
    		if (err_code == NRF_ERROR_NO_MEM) 
    		{
    			NRF_LOG_INFO("NRF_ERROR_NO_MEM");
    		}
    		NRF_LOG_FLUSH();
        if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) // NRF_ERROR_BUSY means another conn_param_update request is pending.
        {
            send_error_evt(err_code);
        }
    
    		return true;
        return (err_code == NRF_SUCCESS);
    }

Related