EVE 1.0
key.h
Go to the documentation of this file.
1 #ifndef DRIVER_KEY_H
2 #define DRIVER_KEY_H
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2015, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief Interface for Key driver in key.c.
36  *
37  * @author AMO, Jetro AS
38  */ /******************************************************************/
39 
40 #include <core/mwork.h>
41 #include <sys/process.h>
42 #include <sys/event-base.h>
43 #include <lib/assert.h>
44 
45 /**
46  * \defgroup key Keypad driver
47  * \ingroup abstract
48  * \{
49  *
50  * This driver supports key debounce functionality if KEY_ENABLED is set true.
51  * The function KeyInterruptEnable() must be called to enables interrupts for all keys.
52  *
53  * The number of scanned keys is given by NUMBER_OF_KEYS.
54  * Key debounce time is given by KEY_PRELL_TIME.
55  * When debouncing the interval is given by SCAN_KEY_INTERVAL.
56  * The keys are read by the inline function ReadKeyInput().
57  *
58  * The following events are sent:
59  * - The event KEY_PRESSED with keynumber (indexed from 0)
60  * is sent when a key is detected pressed
61  * - The event KEY_RELEASED with keynumber (indexed from 0)
62  * is sent when a key is detected released and a combi event has not been sent
63  * which involves this key.
64  * - The event COMBI_KEY_RELEASED with keynumber (indexed from 0)
65  * is sent when a key is detected released and a combi event has been sent
66  * which involves this key, and COMBI_KEY_RELEASE_ENABLED = TRUE.
67  *
68  * It is possible to send a repeated event when a key has been pressed
69  * for a given time. The event can be repeated at a given interval.
70  * This functionality is enabled if REPEAT_KEY_ENABLED is set true:
71  * The number of repeated keys is given by NUMBER_OF_REPEAT_KEYS.
72  * Repeat function is configured in table "struct key_repeat_t ConfigKeyRepeat[]" in Board.c
73  * The following events are sent:
74  * - After key has been pressed in "Step1Time" time,
75  * the event KEY_REPEAT1 with keynumber (indexed from 0) is sent each "RepeatTime" time
76  * - The following function is enabled if REPEAT_KEY_STEP2_ENABLED is set true:
77  * - After key has been pressed in "Step2Time" time,
78  * the event KEY_REPEAT2 with keynumber (indexed from 0) is sent each "RepeatTime" time
79  *
80  * It is possible to send a event when a combination of one or more keys
81  * have been pressed for a given time.
82  * This functionality is enabled if COMBI_KEYS_ENABLED is set true:
83  * The number of combi keys groups is given by NUMBER_OF_COMBI_GROUPS.
84  * Combi function is configured in table "struct key_combi_t ConfigKeyCombi[]" in Board.c
85  * The following events are sent:
86  * - After given time the event COMBI_KEY_PRESSED with combi key group number (indexed from 0) is sent
87  *
88  * All events are sent to process defined by KEY_SIGNAL_RECEIVER
89  ***********************************************************************/
90 
91 /***********************************************************************
92  * Global definitions
93 ***********************************************************************/
94 
95 /** @brief The structure defines key repeat parameters. */
97 {
98  uint8_t KeyIndex; //!< Index 0-31 for actual repeat key
99  uint16_t RepeatTime; //!< Number of repeat scans (wanted repeat time in ms / SCAN_KEY_INTERVAL)
100  uint16_t Step1Time; //!< Number of step1 scans (wanted step1 time in ms / SCAN_KEY_INTERVAL), must be > RepeatTime
101  uint16_t Step2Time; //!< Number of step2 scans (wanted step2 time in ms / SCAN_KEY_INTERVAL), must be > Step1Time
102 };
103 
104 /** @brief The structure defines combi key parameters.
105  * Note that it is possible to define individual debounce time for each group.
106  * Thus it is also the way to define an individual key with debouncing which
107  * differs from default KEY_PRELL_TIME : just define a "group of 1 key.
108  */
110 {
111  uint32_t Keys; //!< Bit positions = key number
112  uint16_t Time; //!< Number of debounce scans (wanted debounce time in ms / SCAN_KEY_INTERVAL)
113 };
114 
115 /** @brief Event numbers being sent to the application process.
116  * Event's void *data field contains key number.
117  */
119 {
120  KEY_PRESSED = EVENT_BASE_KEY_START, //!< Key was pressed
121  KEY_RELEASED, //!< Key was released
122  KEY_REPEAT1, //!< Key press repeat after Step1Time
123  KEY_REPEAT2, //!< Key press repeat after Step2Time
124  COMBI_KEY_PRESSED, //!< Key combination was pressed
125  COMBI_KEY_RELEASED, //!< Key combination was released
126  EVENT_KEY__LAST //!< Gives the size of allocated event numbers
127 };
128 CTASSERT(EVENT_KEY__LAST <= EVENT_BASE_KEY_END + 1);
129 
130 
131 /**
132  * \name Functions called from application programs
133  * \{
134  */
135 
136 /**********************************************************************/
137 /**
138  * @brief Start Keys scanning.
139  *
140  * Only used if KEYS_HAVE_NO_INTERRUPT = true
141  ***********************************************************************/
142 extern void StartKeyScan(void);
143 
144 /**********************************************************************/
145 /**
146  * @brief This callback function must be called when a key interrupt is received
147  * by the platform.
148  *
149  * Only used if KEYS_HAVE_NO_INTERRUPT == false
150  ***********************************************************************/
151 extern void KeyInterruptCb(void);
152 
153 /**********************************************************************/
154 /**
155  * @brief Sets key debounce time. Default time is KEY_PRELL_TIME.
156  *
157  * @param Time New debounce time in ms
158  ***********************************************************************/
159 extern void KeyDebounceTimeSet(uint16_t Time);
160 
161 /**********************************************************************/
162 /**
163  * @brief Returns status of debounced key.
164  *
165  * @param KeyIndex key number from 0 to (NUMBER_OF_KEYS - 1)
166  * @return true if key pressed, else false
167  ***********************************************************************/
168 bool KeyStatusGet(uint8_t KeyIndex);
169 
170 /** \} */
171 
172 /** \name Application' keypad configuration and supplied functions.
173  * \{
174  * The following is the keypad driver setup for application's board.h and
175  * board.c files.
176  */
177 
178 #ifdef KEY_DRIVER_DOXYGEN
179 
180 #define KEY_ENABLED true/false //! Turn platform Keyboard support ON/OFF
181 #define KEYS_HAVE_NO_INTERRUPT true/false //! If true, driver uses polling instead of IRQ
182 #define REPEAT_KEY_ENABLED true/false //! Set to true to enable key repeat feature
183 #define REPEAT_KEY_STEP2_ENABLED true/false //! Set to true to enable repeat step 2 (2nd timing between key presses)
184 #define COMBI_KEYS_ENABLED true/false //! Set to true to enable combi keys (key groups)
185 #define COMBI_KEY_RELEASE_ENABLED true/false //! Set to true to get events on combi keys release
186 
187 #define NUMBER_OF_KEYS <N> //! Total number of individual keys in the system (1-32)
188 #define NUMBER_OF_REPEAT_KEYS <N> //! Number of keys with repeating function (length of \ref ConfigKeyRepeat array)
189 #define NUMBER_OF_COMBI_GROUPS <N> //! Number of key groups with combi function (length of \ref ConfigKeyCombi array)
190 
191 #define KEY_SIGNAL_RECEIVER <struct process *p> //! Pointer to a Contiki process - key related events receiver
192 #define SCAN_KEY_INTERVAL <T> //! Key polling interval in ms (for polling mode KEYS_HAVE_NO_INTERRUPT == true and for debouncing in all modes)
193 #define KEY_PRELL_TIME <T> //! Default key debouncing time in ms
194 
195 
196 /** @brief User defined array of \ref key_repeat_t structures defines key repeat parameters. */
197 struct key_repeat_t ConfigKeyRepeat[NUMBER_OF_REPEAT_KEYS];
198 
199 /** @brief User defined array of \ref key_combi_t structures defines combi key groups parameters. */
200 struct key_combi_t ConfigKeyCombi[NUMBER_OF_COMBI_GROUPS];
201 
202 #endif // KEY_DRIVER_DOXYGEN
203 
204 
205 /**********************************************************************/
206 /**
207  * @brief Application supplied board-specific callback function for reading
208  * key inputs.
209  *
210  * The driver calls this function in order to get current keys
211  * status. It is an application responsibility to map actual internal GPIO or
212  * GPIO extender port pins to an int32_t array of bits used as key status in
213  * the driver.
214  *
215  * Example for 2 inverted keys (pressing connects to ground) supporting
216  * press/release event generation:
217  * \code
218  * #define KEY0 0
219  * #define KEY1 1
220  * uint32_t LastReadKeyInput;
221  * static __inline uint32_t ReadKeyInput(void)
222  * {
223  * uint32_t KeyInput, KeyData;
224  * LastReadKeyInput = KeyInput = ~GpioPortGet(); // Pins are inverted!
225  * KeyData = ((KeyInput >> KEY0_PIN_NUMBERn) & 1) << KEY0;
226  * KeyData |= ((KeyInput >> KEY1_PIN_NUMBERn) & 1) << KEY1;
227  * return KeyData;
228  * }
229  * \endcode
230  *
231  * @return Keys bitmask. Each bit represents a key and settled if the
232  * key is currently pressed, cleared if released.
233  ***********************************************************************/
234 static __inline uint32_t ReadKeyInput(void);
235 
236 /**********************************************************************/
237 /**
238  * @brief Application supplied board-specific callback function to enable or
239  * disable HW interrupts for all keys.
240  *
241  * This function must be called by application to enable interrupts in interrupt
242  * mode (KEYS_HAVE_NO_INTERRUPT == false) before the driver starts to work.
243  *
244  * While working the driver uses the function. When a key is pressed/released,
245  * the key interrupt will disable further key interrupts, and starts the key
246  * debounce scheduler. The interrupts will be re-enabled again when the
247  * scheduler is not active.
248  *
249  * Only used if KEYS_HAVE_NO_INTERRUPT = false.
250  *
251  * Example for 2 inverted keys (pressing connects to ground) supporting
252  * press/release event generation:
253  * \code
254  * uint32_t LastReadKeyInput;
255  * void KeyInterruptEnable(bool Enable)
256  * {
257  * enum irq_mode_t NewMode;
258  * NewMode = (LastReadKeyInput & (1 << KEY0_PIN_NUMBERn)) ? IRQ_MODE_RISING : IRQ_MODE_FALLING;
259  * IrqEnableInternal(KEY0_PIN_NUMBERn, Enable ? NewMode : IRQ_MODE_DISABLED);
260  * NewMode = (LastReadKeyInput & (1 << KEY1_PIN_NUMBERn)) ? IRQ_MODE_RISING : IRQ_MODE_FALLING;
261  * IrqEnableInternal(KEY1_PIN_NUMBERn, Enable ? NewMode : IRQ_MODE_DISABLED);
262  * }
263  * \endcode
264  *
265  * @param Enable true to enable interrupts, false to disable interrupts
266  ***********************************************************************/
267 void KeyInterruptEnable(bool Enable);
268 
269 /** \} */
270 
271 /** \} key */
272 
273 #endif //DRIVER_KEY_H
Header file for the EVE millisecond-scale work scheduling.
Key combination was pressed.
Definition: key.h:124
uint32_t Keys
Bit positions = key number.
Definition: key.h:111
key_events_t
Event numbers being sent to the application process. Event&#39;s void *data field contains key number...
Definition: key.h:118
Key was released.
Definition: key.h:121
uint8_t KeyIndex
Index 0-31 for actual repeat key.
Definition: key.h:98
void KeyInterruptCb(void)
This callback function must be called when a key interrupt is received by the platform.
uint16_t Step2Time
Number of step2 scans (wanted step2 time in ms / SCAN_KEY_INTERVAL), must be > Step1Time.
Definition: key.h:101
Key press repeat after Step1Time.
Definition: key.h:122
struct key_combi_t ConfigKeyCombi[NUMBER_OF_COMBI_GROUPS]
User defined array of key_combi_t structures defines combi key groups parameters. ...
Definition: key.h:200
void KeyDebounceTimeSet(uint16_t Time)
Sets key debounce time. Default time is KEY_PRELL_TIME.
Key press repeat after Step2Time.
Definition: key.h:123
static __inline uint32_t ReadKeyInput(void)
Application supplied board-specific callback function for reading key inputs.
bool KeyStatusGet(uint8_t KeyIndex)
Returns status of debounced key.
The structure defines combi key parameters. Note that it is possible to define individual debounce ti...
Definition: key.h:109
The structure defines key repeat parameters.
Definition: key.h:96
Key was pressed.
Definition: key.h:120
Key combination was released.
Definition: key.h:125
void StartKeyScan(void)
Start Keys scanning.
struct key_repeat_t ConfigKeyRepeat[NUMBER_OF_REPEAT_KEYS]
User defined array of key_repeat_t structures defines key repeat parameters.
Definition: key.h:197
Gives the size of allocated event numbers.
Definition: key.h:126
uint16_t Time
Number of debounce scans (wanted debounce time in ms / SCAN_KEY_INTERVAL)
Definition: key.h:112
uint16_t Step1Time
Number of step1 scans (wanted step1 time in ms / SCAN_KEY_INTERVAL), must be > RepeatTime.
Definition: key.h:100
uint16_t RepeatTime
Number of repeat scans (wanted repeat time in ms / SCAN_KEY_INTERVAL)
Definition: key.h:99
void KeyInterruptEnable(bool Enable)
Application supplied board-specific callback function to enable or disable HW interrupts for all keys...