BGM111 button press detection with interrupts - C project

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja Employee</font></font> </a> arkalvac ‎12-12-2016 09:37 AM - edited ‎01-31-2017 08:09 AM

 

This example project demonstrates how to use interrupts to detect button presses. The example is written for BGM111 development kit in C language with Bluetooth SDK v2.0.1. The BGScript version of this project can be found at:

http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/BGScript-BGM111-button-press-detection...

 

The example differentiates 3 kind of button presses:

  • short (press and release within a defined short interval)
  • long (press and release over a defined short interval)
  • double click (two presses within a defined short interval)

 

The button presses generate external stack events (gecko_evt_system_external_signal), which can be handled by the user on demand. In the example log messages are sent to UART using UARTDRV.

 

Since UARTDRV uses interrupts as well, an interrupt dispatcher is used instead of writing interrupt handlers. This is implemented in gpiointerrupt.c

 

The interrupts are enabled for both rising and falling edges by:

GPIO_ExtIntConfig(gpioPortF,6,0,true,true,true);

GPIO_ExtIntConfig(gpioPortF,7,1,true,true,true);

And the callback functions are set by 

GPIOINT_CallbackRegister(6,handle_button_change);

GPIOINT_CallbackRegister(7,handle_button_change);

Note, that the dispatcher uses pin numbers, no interrupt handler numbers, so in this case the 3rd parameter of GPIO_ExtIntConfig(...) is practically not used.

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

Comments
by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> klangdon79
on ‎01-25-2017 04:13 PM

One issue with this approach is that you lose any timestamp of when the interrupt happened inside the handling of the external_signal. If you instead configure the interrupts with gecko_config and use bgapi_hardware_init, you can get the interrupts with timestamp into the hardware_interrupt event.

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Legend Employee</font></font> </a> JaakkoV
on ‎03-13-2017 08:45 AM

@klangdon79 the event evt_hardware_interrupt is deprecated starting from SDK v2.3.0. Most of the HW related BGAPI calls are marked deprecated (ADC, GPIO, interrupts). It is better to handle the HW peripherals directly using emlib or emdrv.