Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
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

The application enters "app_error_fault_handler" after the GPIO wakeup

Greetings, 

I am running the "ble_app_template" example on my custom board using SDK v17.1.0. I am trying to figure out how to wake up the MCU from the SystemOFF sleep using a GPIO. 

Anyways, soon after generating a signal at my GPIO, the application enters the bsp_event_handler(), and breaks down immediately (ends up in the app_error_fault_handler() ). Im getting the following output in my Debug terminal:

<error> app: ERROR 8198 [Unknown error code] at D:\Nordic\nRF5_SDK_17.1.0\examples\MERS\MERS_ble_app_template\main.c:400
PC at: 0x0002F547
<error> app: End of error report

Why is that so? How to fix this?

Best,

Parents
  • Hello,

    I am running the "ble_app_template" example on my custom board using SDK v17.1.0. I am trying to figure out how to wake up the MCU from the SystemOFF sleep using a GPIO. 

    You can see a demonstration of how this could be done in the BLE app UART example - the sleep_mode_enter function prepares the device for sleep by setting up wake-up buttons and then enters SYSTEM_OFF sleep.

    breaks down immediately (ends up in the app_error_fault_handler() ). Im getting the following output in my Debug terminal:

    It seems to me that an unknown error code might have been passed to an APP_ERROR_CHECK, which usually is the case if a uninitialized err_code variable or otherwise invalid error code is passed to it.
    Could you share with me the entire function located at line 400 of main.c?
    Please use the Insert -> Code option when sharing code here on DevZone.

    Best regards,
    Karl

Reply
  • Hello,

    I am running the "ble_app_template" example on my custom board using SDK v17.1.0. I am trying to figure out how to wake up the MCU from the SystemOFF sleep using a GPIO. 

    You can see a demonstration of how this could be done in the BLE app UART example - the sleep_mode_enter function prepares the device for sleep by setting up wake-up buttons and then enters SYSTEM_OFF sleep.

    breaks down immediately (ends up in the app_error_fault_handler() ). Im getting the following output in my Debug terminal:

    It seems to me that an unknown error code might have been passed to an APP_ERROR_CHECK, which usually is the case if a uninitialized err_code variable or otherwise invalid error code is passed to it.
    Could you share with me the entire function located at line 400 of main.c?
    Please use the Insert -> Code option when sharing code here on DevZone.

    Best regards,
    Karl

Children
  • Hello Karl, nice to see you again! Thanks for offering to help.

    Could you share with me the entire function located at line 400 of main.c?

    Sure, here it is.

    static void sleep_mode_enter(void)
    {
        ret_code_t err_code;
    
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
        // Prepare wakeup buttons.
        err_code = bsp_btn_ble_sleep_mode_prepare();
        APP_ERROR_CHECK(err_code);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
    }

    Does it make sense to you? Btw, the program is behaving funny. I'm in the debug mode, and sometimes steps through the bsp_event_handler(), and sometimes it breaks down and ends up in the  app_error_fault_handler(). 

    Other topic: 

    the sleep_mode_enter function prepares the device for sleep by setting up wake-up buttons and then enters SYSTEM_OFF sleep.

    I was thinking about opening a new ticket, but since you mentioned it, I might ask here. 

    In many of your examples the buttons are initialized to wake up the MCU from the systemOFF mode, and I see it being done twice. Let's look at the ble_app_template:

    First time it is in the function buttons_leds_init -> bsp_init -> app_button_init -> nrf_drv_gpiote_in_init -> nrfx_gpiote_in_init -> nrf_gpio_cfg_input, where PIN_CNF register is defined. Somewhere along the way the SENSE flag is set by invoking GPIOTE_CONFIG_IN_SENSE_TOGGLE(false) function. So it seems that we're all set.

    Then again we have the function sleep_mode_enter -> bsp_btn_ble_sleep_mode_prepare -> bsp_wakeup_button_enable -> wakeup_button_cfg -> nrf_gpio_cfg_sense_set where we meddle with the PIN_CNF register again.

    Why do we do this? Is it really necessary to set PIN_CNF register twice? And why some examples, like pin_change_int, it has only been done once?

  • Hello again, Pero

    It is nice to see you too again! 

    Pero Krivic said:
    Thanks for offering to help.

    It is no problem, I am happy to help you!

    Pero Krivic said:
    Does it make sense to you? Btw, the program is behaving funny. I'm in the debug mode, and sometimes steps through the bsp_event_handler(), and sometimes it breaks down and ends up in the  app_error_fault_handler().

    Your function makes sense, absolutely!
    Which of the APP_ERROR_CHECK's here is line 400 of your main.c?
    You mention that you are in debug mode - does the device proceed to the app_error_fault_handler when you run the device without the debugger attached / outside a debug session?
    The sd_power_system_off function will return an error since the debugger does not allow the CPU to power off while it is monitoring it.
    If this happens in the bsp module, is it in a particular place it happens?

    Pero Krivic said:
    I was thinking about opening a new ticket, but since you mentioned it, I might ask here.

    Sure! Normally I would recommend that you open a new ticket for any issue that diverges from the issue described in the original ticket, but your questions here seems related.

    Pero Krivic said:
    Why do we do this? Is it really necessary to set PIN_CNF register twice? And why some examples, like pin_change_int, it has only been done once?

    It is not necessary to do this twice, no. If I am to speculate why it happens twice in some of the examples I would guess that it is done by the bsp module, in order ensure that the module has buttons enabled for wakeup, since the bsp module makes no assumptions about what is happening elsewhere in the application.

    The important part can be read about in the GPIO documentation:

    The PIN_CNF registers are retained registers. See POWER — Power supply chapter for more information about retained registers.

    You could read more about the possible wake-up sources in the SYSTEM_OFF documentation.

    Best regards,
    Karl

  • Which of the APP_ERROR_CHECK's here is line 400 of your main.c?
    You mention that you are in debug mode - does the device proceed to the app_error_fault_handler when you run the device without the debugger attached / outside a debug session?
    The sd_power_system_off function will return an error since the debugger does not allow the CPU to power off while it is monitoring it.

    You're right. In the run mode, the application runs without faults. And yes, the line 400 is the error check of sd_power_system_off(). So, I guess this is solved. 

    Nonetheless, I wanted to see if how the does the sleep mode work, so I added a little UART print in the function sleep_mode_enter(), like this:

    static void sleep_mode_enter(void)
    {   
        uint8_t i = 0;
        const char* sleep_banner = "\n\rEntering sleep mode";
        while(sleep_banner[i] != '\0'){
           while (app_uart_put(sleep_banner[i]) != NRF_SUCCESS);
           i++;
        }
    
        ret_code_t err_code;
    
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
        // Prepare wakeup buttons.
        err_code = bsp_btn_ble_sleep_mode_prepare();
        APP_ERROR_CHECK(err_code);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
    }
    

    Curiously, the string never gets printed out. Eventhough, the MCU goes to sleep and wakes up. Is there a reason why the uart_print never gets executed?

    Mind you, I'm using the same uart print function on other places in my code, and it really does get printed.

    Thanks for the explanation about the pin registers! 

Related