Error: nrfx_gpiote_input_configure() failed, errCode=0xbad0002

The first calling nrfx_gpiote_input_configure() in afe4900.c is successful. But the second calling nrfx_gpiote_input_configure() in button.c is failed. 

What is meaning of errCode=0xbad0002? How can I fix this issue?

00> *** Booting Zephyr OS build v3.2.99-ncs2 ***

00> Starting button Test example
00> configure AFE4900_RDY pin as input
00> configure AFE4900_RESET pin as output
00> configure POWER_UP pin as output
00> configure LED_G pin as output
00> set POWER_UP pin
00> clear AFE4900_RESET pin, 0
00> set AFE4900_RESET pin
00> I2C: Device is ready.
00> 0x39 0x35 0x50
00> Starting button Test example
00> device_is_ready() ok
00> btInit() e
00> bt_passkey_set(123456)
00> _btReady(0) e
00> Bluetooth initialized
00> _btReady(0) x
00> btInit() x
00> device_is_ready() ok
00> Error: nrfx_gpiote_input_configure() failed for button, errCode=0xbad0002

Parents
  • Hi,

    I have some questions:

    1. Can you specify which line and in what file it asserts when you call nrfx_gpiote_input_configure() for the second time? Use the debugger and take a screenshot of the call stack when it asserts. Can you share this screenshot?
    2. If you change the pins that you use, does it still return this error?
    3. It looks like you're getting NRFX_ERROR_NO_MEM, which indicates that there isn't any GPIOTE channels left for you to use. 

    regards

    Jared 

  • 1. line number 117 of button.c. I don't use debugger and I just use printk() to print error message.

    2. It still return this error.

    3. Why I got NRFX_ERROR_NO_MEM error with CONFIG_DEBUG=y but no NRFX_ERROR_NO_MEM error with CONFIG_DEBUG=n?   The source code are same for CONFIG_DEBUG=y and CONFIG_DEBUG=n.

  • /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <inttypes.h>
    #include <nrfx_gpiote.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/sys/printk.h>
    #include "button.h"
    #include "error.h"
    #include "led.h"
    #include "localtime.h"
    #include "nrf52832_board.h"
    #include "pwr_mgmt.h"
    
    #define BUTTON_TIMER_MSEC 10000
    
    /*
     * Get configuration from the devicetree alias. This is mandatory.
     */
    #define BOOT_BUTTON_NODE DT_ALIAS(sw0)
    
    #if !DT_NODE_HAS_STATUS(BOOT_BUTTON_NODE, okay)
    #error "Unsupported board: mcuboot-button0 devicetree alias is not defined"
    #endif
    
    LOG_MODULE_REGISTER(button);
    
    /*
     * Helper macro for initializing a gpio_dt_spec from the devicetree
     * with fallback values when the nodes are missing.
     */
    static const struct gpio_dt_spec _gButton   = GPIO_DT_SPEC_GET_OR(BOOT_BUTTON_NODE, gpios, {0});
    
    //static struct gpio_callback button_cb_data;
    
    static void _buttonHandler(struct k_timer *dummy) {
        printk("%" PRId64 "\n", k_uptime_get());
        ltPrintCurrentDatetime();
        int val = gpio_pin_get_dt(&_gButton);
        printk("val=%d, BUTTON_PRESS=%d\n", val, BUTTON_PRESS);
        if (val == BUTTON_PRESS) {
            const power_state_t state = pwrMgmtGetPowerState();
            if (state == POWER_STATE_DOWN) {
                printk("power up\n");
                pwrMgmtPowerUp();
                ledSetG();
            } else {
                printk("power down\n");
                pwrMgmtPowerDown();
            }
        }
    }
    
    K_TIMER_DEFINE(_gButtonTimer, _buttonHandler, NULL);
    
    static void _buttonPressed(nrfx_gpiote_pin_t     pin,
                              nrfx_gpiote_trigger_t trigger,
                              void *                p_context) {
    //void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
        printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
        printk("start a timer\n");
        ltPrintCurrentDatetime();
        printk("%" PRId64 "\n", k_uptime_get());
        k_timer_start(&_gButtonTimer, K_MSEC(BUTTON_TIMER_MSEC), K_NO_WAIT);
    }
    
    int buttonInit(void) {
        //int ret;
        nrfx_err_t errCode;
    
        //ledInit();
    
        if (!device_is_ready(_gButton.port)) {
            printk("Error: button device %s is not ready\n", _gButton.port->name);
            return ERROR_BUTTON_INITIALIZE_FAIL;
        }
    
        printk("device_is_ready() ok\n");
    #if 0
        nrfx_gpiote_in_config_t inConfig = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
        inConfig.sense = NRF_GPIOTE_POLARITY_LOTOHI;
        inConfig.pull  = NRF_GPIO_PIN_PULLDOWN; // interrpt: raising edge
        errCode = nrfx_gpiote_in_init(BUTTON_1, &inConfig, button_pressed);
        
        int val = gpio_pin_get_dt(&_gButton);
        printk("button state=%d\n", val);
        //if (val == BUTTON_PRESS) 
        {
            printk("start a timer\n");
            ltPrintCurrentDatetime();
            printk("%" PRId64 "\n", k_uptime_get());
            k_timer_start(&_gButtonTimer, K_MSEC(BUTTON_TIMER_MSEC), K_NO_WAIT);
        }
    #else
    	nrfx_gpiote_input_config_t inputConfig = {.pull = NRF_GPIO_PIN_PULLUP};
    	
    	uint8_t gpioteChannel;
    	errCode = nrfx_gpiote_channel_alloc(&gpioteChannel);
    	nrfx_gpiote_trigger_config_t triggerConfig = {
    		.trigger 		= NRFX_GPIOTE_TRIGGER_TOGGLE, 
    		.p_in_channel 	= &gpioteChannel
    	};
    
    	nrfx_gpiote_handler_config_t handleConfig = {
    		.handler 	= &_buttonPressed,
    		.p_context 	= NULL
    	};
    	
    	errCode = nrfx_gpiote_input_configure(_gButton.pin, &inputConfig, &triggerConfig, &handleConfig);
    	if (errCode != NRFX_SUCCESS) {
    		printk("Error: nrfx_gpiote_input_configure() failed for button, errCode=0x%x\n", errCode);
            return ERROR_BUTTON_INITIALIZE_FAIL;
    	}
    	
    	nrfx_gpiote_trigger_enable(_gButton.pin, true);
    
        printk("start a timer\n");
        ltPrintCurrentDatetime();
        printk("%" PRId64 "\n", k_uptime_get());
        k_timer_start(&_gButtonTimer, K_MSEC(BUTTON_TIMER_MSEC), K_NO_WAIT);
    #endif	
        return 0;
    }
    

  • Hi,

    What do I need to do to build the example successfully and reproduce the issue at my end?

    I tried building the minimal_log_button_2gpioe project in NCS v2.3.0 but it did not build successfully. Do I need to add something else?

    regards

    Jared 

  • Please follow the following procedure to build source code.

    1. Unzip minimal_log_button_2gpioe.zip to ncs/v2.3.0/nrf/samples folder.

    2. Unzip .custom_nrf52832.zip to ncs/v2.3.0/nrf/boards/arm folder.

    3. cd ncs/v2.3.0/nrf/samples

    4. west build -b custom_nrf52832

  • Hi,

    I'm able to reproduce the issue, and it seems that setting CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS to more than 1 in the prj.conf should mitigate the issue, even with CONFIG_DEBUG=y.

    I'm not quite sure exactly how but setting CONFIG_DEBUG=y will disable optimization which results in NRFX_ERROR_NO_MEM.

    Have you been able to reproduce it using the normal nRF52832 board not your custom nRF52832 board file?,

    regards

    Jared 

Reply
  • Hi,

    I'm able to reproduce the issue, and it seems that setting CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS to more than 1 in the prj.conf should mitigate the issue, even with CONFIG_DEBUG=y.

    I'm not quite sure exactly how but setting CONFIG_DEBUG=y will disable optimization which results in NRFX_ERROR_NO_MEM.

    Have you been able to reproduce it using the normal nRF52832 board not your custom nRF52832 board file?,

    regards

    Jared 

Children
Related