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

Parents
  • 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, 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);
    }

  • Hello,

    Thanks. So the p_new_conne_params pointer is NULL for some reason. That explains the hardfault at least. Please place a breakpoint in ble_conn_params.c::ble_evt_handler() to see if it gets called on the BLE_GAP_EVT_CONNECTED event.

Reply Children
Related