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

Hard Fault when peripheral MIN_CONN_INTERVAL and MAX_CONN_INTERVAL are reduced from 100-200 down to 50-100.

Hi, 

We've developed a custom board with buttons(peripheral) which will talk to another custom board operating as a repeater (central on one side to talk to our custom board and peripheral to talk an app). I have a state of the system which works well with the exception of latency of data transmission.

I'm trying to minimize the latency of the information sent from the custom board to the repeater, but keep getting faults (on the repeater) every time I load the custom peripheral board and press the buttons to send data to the repeater. The CONN_INTERVAL settings of the custom peripheral board that I've modified too and do not work are as follows: 

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)            /**< Minimum acceptable connection interval */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(50, UNIT_1_25_MS)            /**< Maximum acceptable connection interval*/  
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds). */

The settings on the custom repeater board has the following CONN_INTERVALs: **Note: I haven't modified this parameter from the original state when the peripheral CONN_INTERVALs were (100-200)

#define MIN_CONN_INTERVAL       MSEC_TO_UNITS(20, UNIT_1_25_MS)        /**< Minimum acceptable connection interval  */
#define MAX_CONN_INTERVAL       MSEC_TO_UNITS(50, UNIT_1_25_MS)        /**< Maximum acceptable connection interval  */
#define SLAVE_LATENCY           0                                       /**< Slave latency. */
#define CONN_SUP_TIMEOUT        MSEC_TO_UNITS(4000, UNIT_10_MS)         /**< Connection supervisory time-out (4 seconds). */

Why, when I decrease the peripheral connection intervals from 100-200 to 20-50, might the repeater crash? Is there something that could cause issues when data arrives to quickly? Is there another setting which may affect this behavior as well? Also, I tried 50-100 without any success. 

Any help is appreciated. 

Thanks!

  • Hello,

    If you set DEBUG or HARDFAULT_HANDLER define(s) you should be able to debug the line of code causing the error, for instance in app_error_fault_handler(). Typically it may be a good idea to enable some slave latency.

    Have you tried that?

    Best regards,
    Kenneth

  • Hello, 

    Yes, I've been using app_error_fault_handler(). Typically in other errors I'd just have to continue execution once the program reached the NRF_BREAKPOINT_COND to be able to see the line which is causing it. In this case however, everytime I reach the NRF_BREAKPOINT_COND and continue execution no additional information shows up. 

    This is the file location the program ends up in upon hard fault.

    /**
     * Copyright (c) 2016 - 2018, 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.
     *
     */
    #include "app_error.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "app_util_platform.h"
    #include "nrf_strerror.h"
    
    #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
    #include "nrf_sdm.h"
    #endif
    
    /*lint -save -e14 */
    /**
     * Function is implemented as weak so that it can be overwritten by custom application error handler
     * when needed.
     */
    __WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
        __disable_irq();
        NRF_LOG_FINAL_FLUSH();
    
    #ifndef DEBUG
        NRF_LOG_ERROR("Fatal error");
    #else
        switch (id)
        {
    #if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
            case NRF_FAULT_ID_SD_ASSERT:
                NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
                break;
            case NRF_FAULT_ID_APP_MEMACC:
                NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
                break;
    #endif
            case NRF_FAULT_ID_SDK_ASSERT:
            {
                assert_info_t * p_info = (assert_info_t *)info;
                NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
                              p_info->p_file_name,
                              p_info->line_num);
                break;
            }
            case NRF_FAULT_ID_SDK_ERROR:
            {
                error_info_t * p_info = (error_info_t *)info;
                NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x",
                              p_info->err_code,
                              nrf_strerror_get(p_info->err_code),
                              p_info->p_file_name,
                              p_info->line_num,
                              pc);
                 NRF_LOG_ERROR("End of error report");
                break;
            }
            default:
                NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
                break;
        }
    #endif
    
        NRF_BREAKPOINT_COND;
        // On assert, the system can only recover with a reset.
    
    #ifndef DEBUG
        NRF_LOG_WARNING("System reset");
        NVIC_SystemReset();
    #else
        app_error_save_and_stop(id, pc, info);
    #endif // DEBUG
    }
    /*lint -restore */
    

    In terms of slave latency, what will that assist with? I tried increasing this and it causes the program to fail on every button press (with the original 100-200 CONN_INTERVALs set). Keep in mind that this is a peripheral device talking to a repeater that has both a central and peripheral side.

    Thanks

  • There should be no need to set a breakpoint here, the code should in any case stop in app_error_save_and_stop() if DEBUG is used.

    I think you are somehow overflowing data buffers in your application here, and that is causing some kind of assert. For instance that the repeater are not able to catch up with the incoming data and forward it in time.

  • There is no breakpoint here, this is just where the assert stops. I played around with taking out some of the APP_ERROR_CHECK(err_code); statements in my main.c. I removed the one right around the point of re-sending my data along and it removed the assert issue. Now I have CONN_INTERVAL set to 20-50..much faster response. Not sure how much I lose by not having those statements in there, but the application works much better. 

    Thanks for the help!

Related