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

ERROR 4097 [Unknown error code] at nrf_sdh_enable_request

I am receiving "ERROR 4097 [Unknown error code]" returned upon calling nrf_sdh_enable_request. I found that ERROR 4097 corresponds to NRF_ERROR_SVC_HANDLER_MISSING from some other posts. I also found that this means that I'm using the wrong SoftDevice version. I'm using SDK v15.3.0 which has s132 6.1.1 to program an nRF521832. If this is not the right SoftDevice version, what is?

Also, why is my error handling not returning NRF_ERROR_SVC_HANDLER_MISSING directly? Why is it returning "ERROR 4097 [Unknown error code]" instead?

Some clarification: BLE was working well and this error was not showing until I integrated the GPIOTE example to my code to toggle a gpio at 2 MHz.

Thanks

  • Hello, 

    If this is not the right SoftDevice version, what is?

    Yes, you are using correct SoftDevice for the nRF52832: s132 v6.1.1

    I found that ERROR 4097 corresponds to NRF_ERROR_SVC_HANDLER_MISSING from some other posts.

     No, the error corresponds to:

    #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1)  ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).

    Your error 4097 = 0x1001 where NRF_ERROR_SDM_BASE_NUM  = 0x1000.

     From components\softdevice\s132\headers\nrf_sdm.h:

    /** @addtogroup NRF_SDM_FUNCTIONS Functions
     * @{ */
    
    /**@brief Enables the SoftDevice and by extension the protocol stack.
     *
     * @note Some care must be taken if a low frequency clock source is already running when calling this function:
     *       If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
     *       clock source will be started.
     *
     * @note This function has no effect when returning with an error.
     *
     * @post If return code is ::NRF_SUCCESS
     *       - SoC library and protocol stack APIs are made available.
     *       - A portion of RAM will be unavailable (see relevant SDS documentation).
     *       - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
     *       - Interrupts will not arrive from protected peripherals or interrupts.
     *       - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
     *       - Interrupt latency may be affected by the SoftDevice  (see relevant SDS documentation).
     *       - Chosen low frequency clock source will be running.
     *
     * @param p_clock_lf_cfg Low frequency clock source and accuracy.
                             If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
                             In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
     * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
     *
     * @retval ::NRF_SUCCESS
     * @retval ::NRF_ERROR_INVALID_ADDR  Invalid or NULL pointer supplied.
     * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
     * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
     * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
     */
    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
    

    Meaning:

    * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.


    Why is it returning "ERROR 4097 [Unknown error code]" instead?

     The reason for it returning an Unknown Error Code is due to the "Error code to string converter" not being optimal, where the retval above is not a part of the nrf_strerror_array[]. See components\libraries\strerror\nrf_strerror.c

    BLE was working well and this error was not showing until I integrated the GPIOTE example to my code to toggle a gpio at 2 MHz

     Can you provide some more information about your project? 

    Kind regards,
    Øyvind

  • I'm programming the nRF52 to interface with an AFE chip (that acquires sensor readings) through SPI and send the acquired sensor readings using BLE to an Android tablet. The AFE chip requires a 1 MHz clock. We decided to provide that using a GPIO pin toggled at 2 MHz. 


    The project was started off from the GPIOTE example where the 1 MHz clock was implemented then the SPI communication with the AFE chip and every thing was working well at that point. Lastly I developed the BLE feature using the template example and then tried to import the code into the main project. I later realized that it was a better idea to start with the BLE template example and import other features into that as it took some effort and time to setup the project for BLE. When I integrated the BLE code from the template example to the GPIOTE example I disabled the 1 MHz clock and SPI parts of the code - isolating problems. Now I'm at the point of adding back those features to the code, and starting with the 1MHz I'm getting the error I mentioned in my original post.

  • Kenan said:
    Now I'm at the point of adding back those features to the code, and starting with the 1MHz I'm getting the error I mentioned in my original post.

    As the previous post indicated,  the issue may be caused by your interrupt configuration.  Make sure that your interrupt priority is not using interrupt priority configured for SoftDevice; "The nRF52 SoC has eight configurable interrupt priorities ranging from 0 to 7 (with 0 being the highest priority)". 

    The SoftDevice reserves and uses the following priority levels, which must remain unused by the application programmer:

    • Level 0 is used for the SoftDevice's timing critical processing.
    • Level 1 is used for handling the memory isolation and run time protection, see Memory isolation and runtime protection.
    • Level 4 is used by higher-level deferrable tasks and the API functions executed as SVC interrupts.

    More information on the SoftDevice Interrupt model can be found here and have a look at the SoftDevice NVIC API. A similar case can be found here, although using S140.  

    Kind regards,
    Øyvind

  • Makes sense. How can I change the priority of the timer used in the GPIOTE example in the SDK?

  • In the NVIC API, you'll find the function sd_nvic_SetPriority.

    /**@brief Set Interrupt Priority.
     * @note Corresponds to NVIC_SetPriority in CMSIS.
     *
     * @pre IRQn is valid and not reserved by the stack.
     * @pre Priority is valid and not reserved by the stack.
     *
     * @param[in] IRQn      See the NVIC_SetPriority documentation in CMSIS.
     * @param[in] priority  A valid IRQ priority for use by the application.
     *
     * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
     * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
     * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
     */
    __STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);


    The relevant IRQ can be found in modules\nrfx\mdk\nrf52840.h.

    When initializing the Timer, call the SetPriority function with correct IRQ and priority level. There is no example of this in our SDK, but a similar basic example is available in CMSIS.

    As stated in the documentation, see NVIC_SetPriority in the ARM CMSIS Documentation for more information.

    Kind regards,
    Øyvind

Related