13
13
#include " freertos/task.h"
14
14
#include " freertos/queue.h"
15
15
16
- #define ASYNC_EVENT_QUEUE_DEPTH 5
17
- #define SYNC_EVENT_QUEUE_DEPTH 10
16
+ #define ASYNC_EVENT_QUEUE_DEPTH 5 // This queue is service very quickly so can be short
17
+ #define SYNC_EVENT_QUEUE_DEPTH 10 // This queue is limited to mainloop frequency so actions can backup
18
18
19
- typedef void (*func_ptr_t )(void ); // Type def to faciliate manage pointers to external action functions
19
+ typedef void (*func_ptr_t )(void ); // Type def to faciliate manage pointers to external action functions
20
20
21
21
enum modes {
22
- Mode_Asynchronous, // All actions performed via Asynchronous RTOS queue
23
- Mode_Hybrid, // keyUp and keyDown performed by RTOS queue, remaining actions by Static Synchronous Queue.
24
- Mode_Synchronous // All actions performed by Static Synchronous Queue.
22
+ Mode_Asynchronous, // All actions performed via Asynchronous RTOS queue
23
+ Mode_Hybrid, // keyUp and keyDown performed by RTOS queue, remaining actions by Static Synchronous Queue.
24
+ Mode_Synchronous // All actions performed by Static Synchronous Queue.
25
25
};
26
26
27
27
enum events:uint8_t {
@@ -31,7 +31,7 @@ enum events:uint8_t {
31
31
Event_LongKeyPress,
32
32
Event_AutoRepeatPress,
33
33
Event_DoubleClick,
34
- NumEventTypes, // Not an event, but this value used to size the number of columns in event/action array.
34
+ NumEventTypes, // Not an event, but this value used to size the number of columns in event/action array.
35
35
Event_All
36
36
};
37
37
@@ -40,7 +40,7 @@ enum events:uint8_t {
40
40
// -- ----------------------------------------------------------------------------------------------------------------------
41
41
class InterruptButton {
42
42
private:
43
- enum buttonStates { // Enumeration to assist with program flow at state machine for reading button
43
+ enum buttonStates { // Enumeration to assist with program flow at state machine for reading button
44
44
Released,
45
45
ConfirmingPress,
46
46
Pressing,
@@ -49,93 +49,104 @@ class InterruptButton {
49
49
Releasing
50
50
};
51
51
52
- // Static class members shared by all instances of this object (common across all instances of the class)
52
+ // STATIC class members shared by all instances of this object (common across all instances of the class)
53
53
// ------------------------------------------------------------------------------------------------------
54
- static void readButton (void * arg); // Static function to read button state (must be static to bind to GPIO and timer ISR)
55
- static void longPressEvent (void *arg); // Wrapper / callback to excecute a longPress event
56
- static void autoRepeatPressEvent (void *arg); // Wrapper / callback to excecute a autoRepeatPress event
57
- static void doubleClickTimeout (void *arg); // Used to separate double-clicks from regular keyPress's
58
- static void startTimer (esp_timer_handle_t &timer, uint32_t duration_US, void (*callBack)(void * arg), InterruptButton* btn, const char *msg);
54
+ static void queueServicer (void * pvParams); // Function used as RTOS task to receive and process action from RTOS message queue.
55
+ static void readButton (void * arg); // function to read button state (must be static to bind to GPIO and timer ISR)
56
+ static void longPressEvent (void *arg); // Callback to excecute a longPress event, called by timer
57
+ static void autoRepeatPressEvent (void *arg); // Callback to excecute a autoRepeatPress event, called by timer
58
+ static void doubleClickTimeout (void *arg); // Callback used to separate double-clicks from regular keyPress's, called by timer
59
+ static void startTimer (esp_timer_handle_t &timer, // Helper func to start timer.
60
+ uint32_t duration_US,
61
+ void (*callBack)(void * arg),
62
+ InterruptButton* btn,
63
+ const char *msg);
59
64
static void killTimer (esp_timer_handle_t &timer); // Helper function to kill a timer
60
65
61
-
62
- static const uint8_t m_targetPolls = 10 ; // Desired number of polls required to debounce a button
63
- static bool m_classInitialised;
64
-
65
- static QueueHandle_t asyncEventQueue;
66
- static TaskHandle_t queueServicerHandle;
67
- static func_ptr_t syncEventQueue[];
68
- static bool m_firstButtonInitialised; // Used to block any further changes to m_numMenus
69
- static uint8_t m_numMenus; // Total number of menu sets, can be set by user, but only before initialising first button
70
- static uint8_t m_menuLevel; // Current menulevel for all buttons (global in class so common across all buttons)
71
- static modes m_mode;
66
+ static const uint8_t m_targetPolls = 10 ; // Desired number of polls required to debounce a button
67
+ static bool m_classInitialised; // Boolean flag to control class initialisation
68
+ static QueueHandle_t asyncEventQueue; // Pointer/handle to the RTOS message queue handling actions.
69
+ static TaskHandle_t queueServicerHandle; // Pointer/handle to the RTOS task that actions the RTOS Queue messages
70
+ static func_ptr_t syncEventQueue[]; // Array used as the Static Synchronous Event Queue
71
+ static bool m_firstButtonInitialised; // Used to block any further changes to m_numMenus
72
+ static uint8_t m_numMenus; // Total number of menu sets, can be set by user, but only before initialising first button
73
+ static uint8_t m_menuLevel; // Current menulevel for all buttons (global in class so common across all buttons)
74
+ static modes m_mode;
72
75
73
76
// Non-static instance specific member declarations
74
77
// ------------------------------------------------
75
- void initialiseInstance (void ); // Setup interrupts and event-action array
76
- bool m_thisButtonInitialised = false ; // Allows us to intialise when binding functions (ie detect if already done)
77
- volatile buttonStates m_state; // Instance specific state machine variable (intialised when intialising button)
78
- volatile bool m_wtgForDblClick = false ;
79
- esp_timer_handle_t m_buttonPollTimer; // Instance specific timer for button debouncing
80
- esp_timer_handle_t m_buttonLPandRepeatTimer; // Instance specific timer for button longPress and autoRepeat timing
81
- esp_timer_handle_t m_buttonDoubleClickTimer; // Instance specific timer for policing double-clicks
82
-
83
- uint8_t m_pressedState; // State of button when it is pressed (LOW or HIGH)
84
- gpio_num_t m_pin; // Button gpio
85
- gpio_mode_t m_pinMode; // GPIO mode: IDF's input/output mode
86
-
87
- volatile uint8_t m_doubleClickMenuLevel; // Stores current menulevel when possible double-click occurs ...
88
- // ... may have been changed by time we convert back to a regular keyPress if not double-click
89
- uint16_t m_pollIntervalUS, m_longKeyPressMS, m_autoRepeatMS, // Timing variables
90
- m_doubleClickMS;
78
+ void initialiseInstance (void ); // Setup interrupts and event-action array
79
+
80
+ bool m_thisButtonInitialised = false ; // Allows us to intialise when binding functions (ie detect if already done)
81
+ gpio_num_t m_pin; // Button gpio
82
+ uint8_t m_pressedState; // State of button when it is pressed (LOW or HIGH)
83
+ gpio_mode_t m_pinMode; // GPIO mode: IDF's input/output mode
84
+ volatile buttonStates m_state; // Instance specific state machine variable (intialised when intialising button)
85
+ volatile bool m_wtgForDblClick = false ;
86
+ esp_timer_handle_t m_buttonPollTimer; // Instance specific timer for button debouncing
87
+ esp_timer_handle_t m_buttonLPandRepeatTimer; // Instance specific timer for button longPress and autoRepeat timing
88
+ esp_timer_handle_t m_buttonDoubleClickTimer; // Instance specific timer for discerning double-clicks from regular keyPresses
89
+
90
+ volatile uint8_t m_doubleClickMenuLevel; // Stores current menulevel while differentiating between regular keyPress or a double-click
91
+ uint16_t m_pollIntervalUS; // Timing variables
92
+ uint16_t m_longKeyPressMS;
93
+ uint16_t m_autoRepeatMS;
94
+ uint16_t m_doubleClickMS;
91
95
92
- volatile bool m_longPress_preventKeyPress; // Boolean flag to prevent firing a keypress if a long press occurred (outside of polling fuction)
93
- volatile uint16_t m_validPolls = 0 , m_totalPolls = 0 ; // Variables to conduct debouncing algoritm
96
+ volatile bool m_longPress_preventKeyPress; // Boolean flag to prevent firing a keypress if a long press occurred (outside of polling fuction)
97
+ volatile uint16_t m_validPolls = 0 ; // Variables to conduct debouncing algoritm
98
+ volatile uint16_t m_totalPolls = 0 ;
94
99
95
- func_ptr_t ** eventActions = nullptr ; // Pointer to 2D array, event actions by row, menu levels by column.
96
- uint16_t eventMask = 0b0000010000111 ; // Default to keyUp, keyDown, and keyPress enabled, and no blanked disable
97
- // When binding functions, longKeyPress, autoKeyPresses, and double clicks are automatically enabled.
100
+ func_ptr_t ** eventActions = nullptr ; // Pointer to 2D array, event actions by row, menu levels by column.
101
+ uint16_t eventMask = 0b0000010000111 ; // Default to keyUp, keyDown, and keyPress enabled, and no blanked disable
102
+ // When binding functions, longKeyPress, autoKeyPresses, & double- clicks are automatically enabled.
98
103
99
104
public:
100
-
101
105
// Static class members shared by all instances of this object -----------------------
102
- static bool setMode (modes mode); // Toggle between Synchronous (Static Queue), Hybrid, or Asynchronous modes (RTOS Queue)
103
- static modes getMode (void );
104
- static void queueServicer (void * pvParams);
105
- static void processSyncEvents (void ); // Process Sync Events, called from main looop
106
- static void setMenuCount (uint8_t numberOfMenus); // Sets number of menus/pages that each button has (can only be done before intialising first button)
107
- static uint8_t getMenuCount (void ); // Retrieves total number of menus.
108
- static void setMenuLevel (uint8_t level); // Sets menu level across all buttons (ie buttons mean something different each page)
109
- static uint8_t getMenuLevel (); // Retrieves menu level
106
+ static bool setMode (modes mode); // Toggle between Synchronous (Static Queue), Hybrid, or Asynchronous modes (RTOS Queue)
107
+ static modes getMode (void );
108
+ static void processSyncEvents (void ); // Process Sync Events, called from main looop
109
+ static void setMenuCount (uint8_t numberOfMenus); // Sets number of menus/pages that each button has (can only be done before intialising first button)
110
+ static uint8_t getMenuCount (void ); // Retrieves total number of menus.
111
+ static void setMenuLevel (uint8_t level); // Sets menu level across all buttons (ie buttons mean something different each page)
112
+ static uint8_t getMenuLevel (); // Retrieves menu level
110
113
111
114
112
115
// Non-static instance specific member declarations ----------------------------------
113
- InterruptButton (uint8_t pin, uint8_t pressedState, gpio_mode_t pinMode = GPIO_MODE_INPUT, // Class Constructor
114
- uint16_t longKeyPressMS = 750 , uint16_t autoRepeatMS = 250 ,
115
- uint16_t doubleClickMS = 333 , uint32_t debounceUS = 8000 );
116
+ InterruptButton (uint8_t pin, // Class Constructor, pin to monitor
117
+ uint8_t pressedState, // State of the pin when pressed (HIGH or LOW)
118
+ gpio_mode_t pinMode = GPIO_MODE_INPUT,
119
+ uint16_t longKeyPressMS = 750 ,
120
+ uint16_t autoRepeatMS = 250 ,
121
+ uint16_t doubleClickMS = 333 ,
122
+ uint32_t debounceUS = 8000 );
116
123
~InterruptButton (); // Class Destructor
117
124
118
- void enableEvent (events event);
119
- void disableEvent (events event);
120
- bool eventEnabled (events event);
121
-
122
- void setLongPressInterval (uint16_t intervalMS); // Updates LongPress Interval
123
- uint16_t getLongPressInterval (void );
124
- void setAutoRepeatInterval (uint16_t intervalMS); // Updates autoRepeat Interval
125
- uint16_t getAutoRepeatInterval (void );
126
- void setDoubleClickInterval (uint16_t intervalMS); // Updates autoRepeat Interval
127
- uint16_t getDoubleClickInterval (void );
125
+ void enableEvent (events event); // Enable the event passed as argument (updates bitmask)
126
+ void disableEvent (events event); // Disable the event passed as argument (updates bitmask)
127
+ bool eventEnabled (events event); // Read bitmask and determine if event is enabled
128
+ void setLongPressInterval (uint16_t intervalMS); // Updates LongPress Interval
129
+ uint16_t getLongPressInterval (void );
130
+ void setAutoRepeatInterval (uint16_t intervalMS); // Updates autoRepeat Interval
131
+ uint16_t getAutoRepeatInterval (void );
132
+ void setDoubleClickInterval (uint16_t intervalMS); // Updates autoRepeat Interval
133
+ uint16_t getDoubleClickInterval (void );
128
134
129
135
130
136
// Routines to manage interface with external action functions associated with each event ---
131
- void bind (events event, uint8_t menuLevel, func_ptr_t action); // Used to bind/unbind action to an event at current m_menuLevel
132
- inline void bind ( events event, func_ptr_t action) { bind (event, m_menuLevel, action); }
133
-
134
- void unbind (events event, uint8_t menuLevel);
135
- inline void unbind (events event) { unbind (event, m_menuLevel); };
136
-
137
- void action (events event, uint8_t menuLevel, BaseType_t *pxHigherPriorityTaskWoken = nullptr ); // Helper function to simplify calling actions at specified menulevel (req'd for sync)
138
- inline void action (events event, BaseType_t *pxHigherPriorityTaskWoken = nullptr ) { action (event, m_menuLevel, pxHigherPriorityTaskWoken); };
137
+ void bind (events event, // Used to bind an action to an event at a given menulevel
138
+ uint8_t menuLevel,
139
+ func_ptr_t action);
140
+ inline void bind (events event, func_ptr_t action) { bind (event, m_menuLevel, action); } // Above function defaulting to current menulevel
141
+
142
+ void unbind (events event, // Used to unbind an action to an event at a given menulevel
143
+ uint8_t menuLevel);
144
+ inline void unbind (events event) { unbind (event, m_menuLevel); }; // Above function defaulting to current menulevel
145
+
146
+ void action (events event, // Helper function to simplify calling actions at specified menulevel
147
+ uint8_t menuLevel,
148
+ BaseType_t *pxHigherPriorityTaskWoken = nullptr );
149
+ inline void action (events event, BaseType_t *pxHigherPriorityTaskWoken = nullptr ) { action (event, m_menuLevel, pxHigherPriorityTaskWoken); };
139
150
};
140
151
141
152
#endif
0 commit comments