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

GPIO does not sense button press

I have a project that uses the nRF51822_xxAA chip with a pull-up button connected to pin 9. Using a meter, I have verified that the pin drops low (0 V) when the button is pressed so I'm confident that the button hardware is working. However I get no response in the code. I have written a simple test program that also does not get any button input. The test project does not use the SoftDevice (to keep things simple) but my real project does use S110 SoftDevice. I'm using Keil as my dev system and I'm using SDK 10.0.0

I have tried several variants using app_gpio, nrf_drv_gpio, app_button, etc. Nothing seems to work.

Here is my code snippet:

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "app_gpiote.h"

#define BUTTON_0 	9		// pin 9

#define APP_GPIOTE_MAX_USERS    1

uint8_t button_state;

app_gpiote_user_id_t m_app_gpiote_my_id;

void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
    NVIC_SystemReset();
}

void gpiote_event_handler(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
{
    if (event_pins_high_to_low & (1 << BUTTON_0))
		button_state = true;
    
    if (event_pins_low_to_high & (1 << BUTTON_0))
		button_state = false;
}

/**
 * @brief Function for application main entry.
 */
int main(void)
{
    uint32_t err_code;

    nrf_gpio_cfg_sense_input(BUTTON_0, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    
    APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);    
    err_code = app_gpiote_user_register(&m_app_gpiote_my_id, (1 << BUTTON_0), (1 << BUTTON_0), gpiote_event_handler);
    APP_ERROR_CHECK(err_code);
    
    err_code = app_gpiote_user_enable(m_app_gpiote_my_id);
    APP_ERROR_CHECK(err_code);
	
    while(true)
    {
        nrf_delay_ms(500);
    }
}

I appreciate any help.

  • I have actually discovered what the problem what. It turns out the GPIOTE functions expect the internal pin number (i.e. P0_17) and not the physical pin number. In my case the physical pin number was 9 which internally was P0_17. Replacing the "9" with "17" allows it to get the button state. This is very confusing especially when you consider that other GPIO functionality want the physical pin numbers (i.e. UART).

  • Everything, including the UART and other drivers take the logical pin number, absolutely nothing takes the physical pin number. So you use the logical pin number everywhere, it's very consistent.

  • I have to disagree. I specify my UART connection (used by app_trace and the UART library) as follows:

    #define RX_PIN_NUMBER  56
    #define TX_PIN_NUMBER  54
    #define CTS_PIN_NUMBER 52
    #define RTS_PIN_NUMBER 50
    

    which are physical pins corresponding to logical P0_08, P0_22, P0_23, and P0_28. This is what I was talking about when I said things are not consistent. If everything used logical pins I would have had to use 8, 22, 23, and 28 but my UART works fine using physical pin numbers.

  • I can guarantee you with 100% certainly that the pin assignments everywhere are logical pins and not physical pins. Physical pin numbers are used nowhere except by the guy designing the circuit diagram.

    Firstly if that were not the case you'd have to recompile software depending on the actual chip package on the board, and you don't, as long as inputs and outputs are connected to the physical pin with the same logical assignment.

    If you look at the documentation for, for instance, the UART it specifies there that the pin number can be [0..31] or 0xffffffff for disconnect, 0-31, that's a logical pin number. You can't put 56 in there, it's not an allowed value.

    Your UART works by the fluke that the TX pin you specify, 54, when mod 32 == 22 which happens to be the actual logical TX pin. The rest of your pins are set to P24, P20 and P18, but having TX connected makes it appear to work.

  • That is pretty funny that it happened to work out that way. No wonder I was so confused. Thanks for clarifying that. It totally makes sense that it should use logical pins. I appreciate the clarification.

Related