Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / examples / lock-app / efr32 / src / ButtonHandler.cpp
1 /*
2  *
3  *    Copyright (c) 2019 Google LLC.
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 #include "ButtonHandler.h"
20 #include "AppTask.h"
21
22 #include "AppConfig.h"
23
24 #include "bsp.h"
25 #include "gpiointerrupt.h"
26 #include "hal-config-board.h"
27
28 typedef struct ButtonArray
29 {
30     GPIO_Port_TypeDef port;
31     unsigned int pin;
32 } ButtonArray_t;
33
34 static const ButtonArray_t sButtonArray[BSP_BUTTON_COUNT] = BSP_BUTTON_INIT; // GPIO info for the 2 WDTK buttons.
35 TimerHandle_t buttonTimers[BSP_BUTTON_COUNT];                                // FreeRTOS timers used for debouncing
36 // buttons. Array to hold handles to
37 // the created timers.
38
39 void ButtonHandler::Init(void)
40 {
41     GpioInit();
42
43     // Create FreeRTOS sw timers for debouncing buttons.
44     for (uint8_t i = 0; i < BSP_BUTTON_COUNT; i++)
45     {
46         buttonTimers[i] = xTimerCreate("BtnTmr",                      // Just a text name, not used by the RTOS kernel
47                                        APP_BUTTON_DEBOUNCE_PERIOD_MS, // timer period
48                                        false,                         // no timer reload (==one-shot)
49                                        (void *) (int) i,              // init timer id = button index
50                                        TimerCallback                  // timer callback handler (all buttons use
51                                                                       // the same timer cn function)
52         );
53     }
54 }
55
56 void ButtonHandler::GpioInit(void)
57 {
58     // Set up button GPIOs to input with pullups.
59     for (uint8_t i = 0; i < BSP_BUTTON_COUNT; i++)
60     {
61         GPIO_PinModeSet(sButtonArray[i].port, sButtonArray[i].pin, gpioModeInputPull, 1);
62     }
63     // Set up interrupt based callback function - trigger on both edges.
64     GPIOINT_Init();
65     GPIOINT_CallbackRegister(sButtonArray[0].pin, Button0Isr);
66     GPIOINT_CallbackRegister(sButtonArray[1].pin, Button1Isr);
67     GPIO_IntConfig(sButtonArray[0].port, sButtonArray[0].pin, true, true, true);
68     GPIO_IntConfig(sButtonArray[1].port, sButtonArray[1].pin, true, true, true);
69
70     // Change GPIO interrupt priority (FreeRTOS asserts unless this is done here!)
71     NVIC_SetPriority(GPIO_EVEN_IRQn, 5);
72     NVIC_SetPriority(GPIO_ODD_IRQn, 5);
73 }
74
75 void ButtonHandler::Button0Isr(uint8_t pin)
76 {
77     // ISR for Button 0.
78     uint8_t btnIdx = 0;
79
80     if (pin == sButtonArray[btnIdx].pin)
81     {
82         EventHelper(btnIdx, true); // true== 'isr context'
83     }
84 }
85
86 void ButtonHandler::Button1Isr(uint8_t pin)
87 {
88     // ISR for Button 1.
89     uint8_t btnIdx = 1;
90
91     if (pin == sButtonArray[btnIdx].pin)
92     {
93         EventHelper(btnIdx, true); // true== 'isr context'
94     }
95 }
96
97 void ButtonHandler::EventHelper(uint8_t btnIdx, bool isrContext)
98 {
99     // May be called from Interrupt context so keep it short!
100
101     if (btnIdx < BSP_BUTTON_COUNT)
102     {
103         // Get buton gpio pin state.
104         bool gpioPinPressed = !GPIO_PinInGet(sButtonArray[btnIdx].port, sButtonArray[btnIdx].pin);
105
106         if (isrContext)
107         {
108             portBASE_TYPE taskWoken = pdFALSE; // For FreeRTOS timer (below).
109
110             // Start/restart the button debounce timer (Note ISR version of FreeRTOS
111             // api call here).
112             xTimerStartFromISR(buttonTimers[btnIdx], &taskWoken);
113
114             if (taskWoken != pdFALSE)
115             {
116                 taskYIELD();
117             }
118         }
119         else
120         {
121             // Called by debounce timer expiry (this indicates that button gpio
122             // is now stable).
123             // Note- NOT in isr context at this point.
124
125             // Notify AppTask of button state change.
126             GetAppTask().ButtonEventHandler(btnIdx, (gpioPinPressed) ? APP_BUTTON_PRESSED : APP_BUTTON_RELEASED);
127         }
128     }
129 }
130
131 void ButtonHandler::TimerCallback(TimerHandle_t xTimer)
132 {
133     // Get the button index of the expired timer and call button event helper.
134
135     uint32_t timerId;
136
137     timerId = (uint32_t) pvTimerGetTimerID(xTimer);
138     if (timerId < BSP_BUTTON_COUNT)
139     {
140         uint8_t btnIdx = timerId;
141         EventHelper(btnIdx, false); // false== 'not from isr context'
142     }
143 }