Using Push Buttons

Description

This example describes how to use push buttons in a Bluetooth project. To give a simple example, a Bluetooth advertisement is started upon pressing a button and is stopped upon releasing it.

A button press/release generates an external interrupt in the MCU. As usual, heavy functionality is not implemented in the interrupt handler. Instead, the application is notified that a button was pressed. In a Bluetooth application, this notification can be done by calling gecko_external_signal(). This function will push an evt_system_external_signal event in the Bluetooth event queue (along with a 32 bit bitmap to signal 32 different event type). This event can then be handled as any Bluetooth event.

The interrupts can be enabled for both rising and falling edges by:

GPIO_ExtIntConfig(button_port, button_pin, button_pin, true, true, true);

To make development easier, the example uses gpiointerrupt.c which allows implementing callback functions for button events, instead of directly using the GPIO interrupt handler. Callback functions can be set for any button with the following function:

GPIOINT_CallbackRegister(button_pin, button_callback);

Note, that gpiointerrupt.c uses pin numbers to differentiate interrupts. As a result, you cannot define different callback functions for pins with the same pin number (e.g., for PA5 and PC5).

The rising/falling edge can be differentiated by reading the state of the GPIO pins in the callback function.

static void button_callback(const uint8_t pin)
{
  if (pin == BSP_BUTTON0_PIN) {
    /* when input is high, the button was released */
    if (GPIO_PinInGet(BSP_BUTTON0_PORT,BSP_BUTTON0_PIN)) {
        gecko_external_signal(BUTTON_RELEASED);
    }
    /* when input is low, the button was pressed*/
    else {
        gecko_external_signal(BUTTON_PRESSED);
    }
  }
}

Finally, the external signal event can be handled in the Bluetooth event handler:

    case gecko_evt_system_external_signal_id:
      if (evt->data.evt_system_external_signal.extsignals & BUTTON_PRESSED) {
          //...
      }
      if (evt->data.evt_system_external_signal.extsignals & BUTTON_RELEASED) {
          //...
      }
      break;

Setting up

  1. Create a new SOC-Empty project for your target device

  2. Copy gpiointerrupt.c from C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\<version>\platform\emdrv\gpiointerrupt\src into your project (under /platform/emdrv/gpiointerrupt/src).

  3. Copy the attached app.c file into your project.

  4. Build and flash the project to your target.

Usage

  1. Start EFR Connect app on your smart phone.

  2. Choose Bluetooth Browser and scan for nearby devices. You should not see your device advertising.

  3. Press and hold PB0 on your WSTK.

  4. Meanwhile, refresh the list of scanned devices in the EFR Connect app. Now, your device should appear on the list (as Empty Example).

  5. Release PB0 on WSTK.

  6. Refresh the list of scanned devices in the EFR Connect app. Your device should disappear.

    Your device may still appear on the list due to caching but you can't connect to it.

Source