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

nrf_gpio_pin_read returns wrong value

Hi, I am using nrf52832 development kit. MCU is waking up with two buttons and I put MCU to system off mode after successful data exchange or timeout. Init settings are like below:

#define PIN_UNLOCK_DOOR BSP_BUTTON_0
#define PIN_LOCK_DOOR 	BSP_BUTTON_1

static void buttons_init(void)
{

    ret_code_t err_code;

    //Initialize gpiote module
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    //Configure sense input pin to enable wakeup and interrupt on button press.
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);    
    in_config.pull = NRF_GPIO_PIN_PULLUP;                                           
    err_code = nrf_drv_gpiote_in_init(PIN_UNLOCK_DOOR, &in_config, in_pin_handler); 
    APP_ERROR_CHECK(err_code);                                                      
    nrf_drv_gpiote_in_event_enable(PIN_UNLOCK_DOOR, true);                          

    err_code = nrf_drv_gpiote_in_init(PIN_LOCK_DOOR, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(PIN_LOCK_DOOR, true);
}

To go to sleep I have to wait until user takes off his/her finger from button. In main function inside the while loop I use this code:

for(;;)
{
    if (goToSleepFlag == true && sleepStartedFlag == false && 
		nrf_gpio_pin_read(PIN_LOCK_DOOR) == 1 && 
		nrf_gpio_pin_read(PIN_UNLOCK_DOOR) == 1)
	{
		sleepStartedFlag = true;
		sd_power_system_off();
	}
	else
	{
		idle_state_handle();
	}

}

If user takes off his finger from button before goToSleepFlag becomes true it is working well and goes to sleep. goToSleepFlag becomes true after 2 seconds and when I press button more than two seconds then take off my finger it can't go to sleep. After pressing long time I release the button and press multiple times, it goes to interrupt handler every times but nrf_gpio_pin_read function can't detect pin is 1. I checked voltage and its 2.9 V but nrf_gpio_pin_read is still giving 0.

When I put there a log message it can detect pin state change and go to sleep when I release button, code is like this:

if (goToSleepFlag == true && sleepStartedFlag == false && 
	nrf_gpio_pin_read(PIN_LOCK_DOOR) == 1 && 
	nrf_gpio_pin_read(PIN_UNLOCK_DOOR) == 1)
{
	sleepStartedFlag = true;
	sd_power_system_off();
}
else
{
	idle_state_handle();
}


if (goToSleepFlag == true && sleepStartedFlag == false)
{
	NRF_LOG_INFO("a");
}

I put also __nop("nop") or bsp_board_led_on(BSP_BOARD_LED_3); instead of NRF_LOG but those didn't work. How can I solve this problem? Thanks.

  • Hi

    What GPIOs are you using as buttons here exactly? Also, is there a specific reason the sleepStartedFlag takes 2 seconds to become true? What does the device do if the button is held more than 2 seconds specifically? Does it go into the idle_state_handle(); or what? Please check out the Power Management example for details on how we recommend using buttons to go to system OFF mode.

    Best regards,

    Simon

  • #define PIN_UNLOCK_DOOR BSP_BUTTON_0
    #define PIN_LOCK_DOOR BSP_BUTTON_1

    This was in the code, I used dev kit buttons which are pin 13 and pin 14.

    2 seconds is timeout, if it can't finish it's tasks it is going to sleep.  

    Device only waits for button to be released. Until that time it is calling idle_state_handle();.

    I think so because NRF_LOG can print something to screen. I don't know if calling idle_state_handle(); is kind of sleep and it doesn't go out of idle_state_handle() until ble or nrf_log events come. I looked inside of idle_state_handle() and there is event wait function, So I shouldnt call idle_state_handle() or should I create fake events like timer? Is app_timer valid reason to go out of idle_state_handle() ? Because GPIO interrupt comes but it still can't go out of idle_state_handle() if it stucks in it otherwise nrf_gpio_pin_read() function returns wrong value. 

    Okay, thank you, I will check that example and apply same things. I will share results after I try.

  • When I have active app_timer my problem disappears.

  • Hi

    Yes, a timer event will be sufficient to wake the device once in idle_state_handle()/__WFE. 

    Best regards,

    Simon

Related