22
33// / @brief Default constructor for CustomGPIO.
44// / Initializes rollover period and state variables.
5- CustomGPIO::CustomGPIO () {}
5+ CustomGPIO::CustomGPIO () {
6+ // State Machine
7+ // clang-format off
8+ gpio_sm = {
9+ State::OFF,
10+ { // Entry definition: (TargetState, GuardFunction, ActionFunction, Injection)
11+ { State::OFF, {}, actionOff (), {} },
12+ { State::LOW_INACTIVE, {}, {}, {} },
13+ { State::HIGH_INACTIVE, {}, {}, {} },
14+ },
15+ { // Transition definition: (CurrentState, Event, NextState, GuardFunction, ActionFunction, Injection)
16+ { State::ON, Event::OFF, State::OFF, {}, actionOff (), {} },
17+ { State::OFF, Event::ON, State::ON, {}, actionOn (), {} },
18+ { State::ON, Event::TOGGLE, State::OFF, {}, actionToggle (), {} },
19+ { State::OFF, Event::TOGGLE, State::ON, {}, actionToggle (), {} },
20+ { State::LOW_INACTIVE, Event::POLL, State::LOW_SETTLING, guardLowSense (), {}, {} },
21+ { State::LOW_SETTLING, Event::POLL, State::LOW_ACTIVE, guardStable (), {}, {} },
22+ { State::LOW_ACTIVE, Event::POLL, State::LOW_INACTIVE, {}, guardHighSense (), {} },
23+ { State::HIGH_INACTIVE, Event::POLL, State::HIGH_SETTLING, guardHighSense (), {}, {} },
24+ { State::HIGH_SETTLING, Event::POLL, State::HIGH_ACTIVE, guardStable (), {}, {} },
25+ { State::HIGH_ACTIVE, Event::POLL, State::HIGH_INACTIVE, {}, guardLowSense (), {} },
26+ }
27+ };
28+ // clang-format on
29+ }
630
731// / @brief Constructor with custom debounce period.
832// / @param value Number of ticks for stable state detection.
9- CustomGPIO::CustomGPIO (uint16_t value ) { m_roll_period = value ; }
33+ CustomGPIO::CustomGPIO (uint16_t PollPeriod ) { roll_period = PollPeriod ; }
1034
1135// / @brief Destructor for CustomGPIO.
1236CustomGPIO::~CustomGPIO () {}
1337
1438// / @brief Configure the GPIO port and pin for this instance.
1539// / @param port Pointer to the GPIO port (e.g., GPIOA).
1640// / @param pin GPIO pin identifier (e.g., GPIO_PIN_0).
17- void CustomGPIO::setPort (GPIO_TypeDef *port , uint16_t pin ) {
18- m_port = port ;
19- m_pin = pin ;
41+ void CustomGPIO::setPort (GPIO_TypeDef *Port , uint16_t Pin ) {
42+ port = Port ;
43+ pin = Pin ;
2044}
2145
2246// / @brief Set the GPIO pin to a high logic level.
23- void CustomGPIO::on () { HAL_GPIO_WritePin (m_port, m_pin, GPIO_PIN_SET ); }
47+ void CustomGPIO::on () { gpio_sm. triggerEvent (Event::ON ); }
2448
2549// / @brief Set the GPIO pin to a low logic level.
26- void CustomGPIO::off () { HAL_GPIO_WritePin (m_port, m_pin, GPIO_PIN_RESET ); }
50+ void CustomGPIO::off () { gpio_sm. triggerEvent (Event::OFF ); }
2751
2852// / @brief Toggle the current state of the GPIO pin.
29- void CustomGPIO::toggle () { HAL_GPIO_TogglePin (m_port, m_pin ); }
53+ void CustomGPIO::toggle () { gpio_sm. triggerEvent (Event::TOGGLE ); }
3054
31- // / @brief Debounce scheduler for active-low inputs.
32- // / Monitors pin for stable falling-edge and marks press event.
33- // / @note Call periodically to update internal status.
34- void CustomGPIO::schedulerLowActive () {
35- if (m_stable) {
36- if (!HAL_GPIO_ReadPin (m_port, m_pin))
37- m_stable = false ;
38- else
39- m_roll_timer = 0 ;
55+ bool CustomGPIO::getStatus () {
56+ if (gpio_sm.currentState == State::ON) {
57+ return true ;
58+ } else if (gpio_sm.currentState == State::LOW_ACTIVE) {
59+ return true ;
60+ } else if (gpio_sm.currentState == State::HIGH_ACTIVE) {
61+ return true ;
4062 }
63+ return false ;
64+ }
4165
42- else if ( HAL_GPIO_ReadPin (m_port, m_pin) || ++m_roll_timer > m_roll_period) {
43- m_stable = true ;
44- m_pressed = true ;
45- m_roll_timer = m_roll_period * 0.8 ;
46- }
66+ // / @brief Scheduler for state-driven GPIO updates.
67+ void CustomGPIO::scheduler () { gpio_sm. triggerEvent (Event::POLL); }
68+
69+ Action CustomGPIO::actionOn () {
70+ return [ this ]() { HAL_GPIO_WritePin (port, pin, GPIO_PIN_SET); };
4771}
4872
49- // / @brief Debounce scheduler for active-high inputs.
50- // / Monitors pin for stable rising-edge and marks press event.
51- // / @note Call periodically to update internal status.
52- void CustomGPIO::schedulerHighActive () {
53- if (m_stable) {
54- if (HAL_GPIO_ReadPin (m_port, m_pin))
55- m_stable = false ;
56- else
57- m_roll_timer = 0 ;
58- }
73+ Action CustomGPIO::actionOff () {
74+ return [this ]() { HAL_GPIO_WritePin (port, pin, GPIO_PIN_RESET); };
75+ }
5976
60- else if (!HAL_GPIO_ReadPin (m_port, m_pin) || ++m_roll_timer > m_roll_period) {
61- m_stable = true ;
62- m_pressed = true ;
63- m_roll_timer = m_roll_period * 0.8 ;
64- }
77+ Action CustomGPIO::actionToggle () {
78+ return [this ]() { HAL_GPIO_TogglePin (port, pin); };
6579}
6680
67- // / @brief Retrieve and clear the press event flag.
68- // / @return true if a press event was detected since last call; false otherwise.
69- bool CustomGPIO::getStatus () {
70- if (m_pressed) {
71- m_pressed = !m_pressed;
72- return true ;
73- } else
74- return false ;
81+ Guard CustomGPIO::guardLowSense () {
82+ return [this ]() { return !HAL_GPIO_ReadPin (port, pin); };
83+ }
84+
85+ Guard CustomGPIO::guardHighSense () {
86+ return [this ]() { return HAL_GPIO_ReadPin (port, pin); };
87+ }
88+
89+ Guard CustomGPIO::guardStable () {
90+ return [this ]() {
91+ if (roll_timer++ > roll_period) {
92+ roll_timer = 0 ;
93+ return true ;
94+ } else {
95+ return false ;
96+ }
97+ };
7598}
0 commit comments