forked from GabyGold67/ButtonToSwitch_STM32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathButtonToSwitch_STM32.h
1848 lines (1790 loc) · 114 KB
/
ButtonToSwitch_STM32.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**
******************************************************************************
* @file : ButtonToSwitch_STM32.h
* @brief : Header file for the ButtonToSwitch_STM32 library classes
*
* @details The library builds several switch mechanisms replacements out of simple
* push buttons or **similar equivalent digital signal inputs**.
* By using just a push button (a.k.a. momentary switches or momentary buttons,
* **Momentary Push Buttons** or _**MPB**_ for short from here on) the classes
* implemented in this library will manage, calculate and update different
* parameters to **generate the embedded behavior of standard electromechanical
* switches**.
*
* @author : Gabriel D. Goldman
* @version v4.0.2
* @date : Created on: 06/11/2023
* : Last modification: 28/08/2024
* @copyright GPL-3.0 license
*
******************************************************************************
* @attention This library was developed as part of the refactoring process for
* an industrial machines security enforcement and control (hardware & firmware
* update). As such every class included complies **AT LEAST** with the
* provision of the attributes and methods to make the hardware & firmware
* replacement transparent to the controlled machines. Generic use attribute
* and methods were added to extend the usability to other projects and
* application environments, but no fitness nor completeness of those are given
* but for the intended refactoring project.
*
* **Use this library under your own responsibility**
*
******************************************************************************
*/
#ifndef _BUTTONTOSWITCH_STM32_H_
#define _BUTTONTOSWITCH_STM32_H_
#include <stdint.h>
#include <string>
#include <stdio.h>
//===========================>> Next lines included for developing purposes, corresponding headers must be provided for the production platform/s
#ifndef MCU_SPEC
#ifndef __STM32F4xx_HAL_H
#include "stm32f4xx_hal.h"
#endif
//This depends on the existence of #define HAL_GPIO_MODULE_ENABLED in stm32f4xx_hal_conf.h which is included in stm32f4xx_hal.h
#ifndef __STM32F4xx_HAL_GPIO_H
#include "stm32f4xx_hal_gpio.h"
#endif
#endif
//===========================>> Previous lines included for developing purposes, corresponding headers must be provided for the production platform/s
//===========================>> BEGIN libraries used to avoid CMSIS wrappers
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
//===========================>> END libraries used to avoid CMSIS wrappers
#define _HwMinDbncTime 20 // Documented minimum wait time for a MPB signal to stabilize to consider it pressed or released (in milliseconds)
#define _StdPollDelay 10 // Reasonable time between polls for MPBs switches (in milliseconds)
#define _MinSrvcTime 100 // Minimum valid time value for service/active time for Time Latched MPBs to avoid stability issues relating to debouncing, releasing and other timed events
#define _InvalidPinNum 0xFFFF // Value to give as "yet to be defined", the "Valid pin number" range and characteristics are development platform and environment dependable
/*---------------- xTaskNotify() mechanism related constants, argument structs, information packing and unpacking BEGIN -------*/
const uint8_t IsOnBitPos {0};
const uint8_t IsEnabledBitPos{1};
const uint8_t PilotOnBitPos{2};
const uint8_t WrnngOnBitPos{3};
const uint8_t IsVoidedBitPos{4};
const uint8_t IsOnScndryBitPos{5};
const uint8_t OtptCurValBitPos{16};
#ifndef MPBOTPTS_T
#define MPBOTPTS_T
/**
* @brief Type to hold the complete set of output attribute flags from any DbncdMPBttn class and subclasses object.
*
* Only two members (isOn and isEnabled) are relevant to all classes, the rest of the members might be relevant for one or more of the classes.
* The type is provided as a standard return value for the decoding of the 32-bit notification value provided by the use of the xTaskNotify() inter-task mechanism. See setTaskToNotify(const TaskHandle_t) for more information.
*/
struct MpbOtpts_t{
bool isOn;
bool isEnabled;
bool pilotOn;
bool wrnngOn;
bool isVoided;
bool isOnScndry;
uint16_t otptCurVal;
};
#endif
/*---------------- xTaskNotify() mechanism related constants, argument structs, information packing and unpacking END -------*/
#ifndef GPIOPINID_T
#define GPIOPINID_T
/**
* @brief Type used to keep GPIO pin identification as a single parameter, independently of the platform requirements.
*
* GPIO pin identification is hardware and development environment framework dependents, for some platforms it needs one, some two, some more parameters, and each one of these parameters' type depends once again on the platform. This type is provided to define each pin referenced as a single parameter for class methods and attributes declarations, as platform independent as possible.
*
* @struct gpioPinId_t
*/
struct gpioPinId_t{ //
GPIO_TypeDef* portId; /**< The port identification as a pointer to a GPIO_TypeDef information structure*/
uint16_t pinNum; /**< The number of the port pin represented as a single-bit mask with the set bit position indicating the pin number*/
};
#endif //GPIOPINID_T
// Definition workaround to let a function/method return value to be a function pointer
typedef void (*fncPtrType)();
typedef fncPtrType (*ptrToTrnFnc)();
//===========================>> BEGIN General use function prototypes
uint8_t singleBitPosNum(uint16_t mask);
MpbOtpts_t otptsSttsUnpkg(uint32_t pkgOtpts);
//===========================>> END General use function prototypes
//===========================>> BEGIN General use Global variables
//===========================>> END General use Global variables
//==========================================================>> Classes declarations BEGIN
/**
* @brief Base class, models a Debounced Momentary Push Button (**D-MPB**).
*
* This class provides the resources needed to process a momentary digital input signal -as the one provided by a MPB (Momentary Push Button)- returning a clean signal to be used as a switch, implementing the needed services to replace a wide range of physical related switch characteristics: Debouncing, deglitching, disabling.
*
* More physical switch situations can be emulated, like temporarily disconnecting it (isDisabled=true and isOnDisabled=false), short circuiting it (isDisabled=true and isOnDisabled=true) and others.
*
* @class DbncdMPBttn
*/
class DbncdMPBttn {
protected:
enum fdaDmpbStts {
stOffNotVPP,
stOffVPP,
stOn,
stOnVRP,
stDisabled
};
const unsigned long int _stdMinDbncTime {_HwMinDbncTime};
GPIO_TypeDef* _mpbttnPort{};
uint16_t _mpbttnPin{};
bool _pulledUp{};
bool _typeNO{};
unsigned long int _dbncTimeOrigSett{};
unsigned long int _dbncRlsTimerStrt{0};
unsigned long int _dbncRlsTimeTempSett{0};
unsigned long int _dbncTimerStrt{0};
unsigned long int _dbncTimeTempSett{0};
void (*_fnWhnTrnOff)() {nullptr};
void (*_fnWhnTrnOn)() {nullptr};
bool _isEnabled{true};
volatile bool _isOn{false};
bool _isOnDisabled{false};
volatile bool _isPressed{false};
fdaDmpbStts _mpbFdaState {stOffNotVPP};
TimerHandle_t _mpbPollTmrHndl {NULL};
std::string _mpbPollTmrName {""};
volatile bool _outputsChange {false};
bool _prssRlsCcl{false};
unsigned long int _strtDelay {0};
bool _sttChng {true};
TaskHandle_t _taskToNotifyHndl {NULL};
TaskHandle_t _taskWhileOnHndl{NULL};
volatile bool _validDisablePend{false};
volatile bool _validEnablePend{false};
volatile bool _validPressPend{false};
volatile bool _validReleasePend{false};
void clrSttChng();
const bool getIsPressed() const;
static void mpbPollCallback(TimerHandle_t mpbTmrCb);
virtual uint32_t _otptsSttsPkg(uint32_t prevVal = 0);
void _setIsEnabled(const bool &newEnabledValue);
void setSttChng();
void _turnOff();
void _turnOn();
virtual void updFdaState();
bool updIsPressed();
virtual bool updValidPressesStatus();
public:
/**
* @brief Default class constructor
*
*/
DbncdMPBttn();
/**
* @brief Class constructor
*
* @param mpbttnPort GPIO port identification of the input signal pin
* @param mpbttnPin Pin id number of the input signal pin
* @param pulledUp (Optional) boolean, indicates if the input pin must be configured as INPUT_PULLUP (true, default value), or INPUT_PULLDOWN (false), to calculate correctly the expected voltage level in the input pin. The pin is configured by the constructor so no previous programming is needed. The pin must be free to be used as a digital input, and must be a pin with an internal pull-up circuit, as not every GPIO pin has the option.
* @param typeNO (Optional) boolean, indicates if the MPB is a Normally Open (NO) switch (true, default value), or Normally Closed (NC) (false), to calculate correctly the expected level of voltage indicating the MPB is pressed.
* @param dbncTimeOrigSett (Optional) unsigned long integer (uLong), indicates the time (in milliseconds) to wait for a stable input signal before considering the MPB to be pressed (or not pressed). If no value is passed the constructor will assign the minimum value provided in the class, that is 20 milliseconds as it is an empirical value obtained in various published tests.
*
*/
DbncdMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0);
/**
* @brief Class constructor
*
* @param mpbttnPinStrct GPIO port and Pin identification defined as a single gpioPinId_t parameter.
*
* For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*
*/
DbncdMPBttn(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0);
/**
* @brief Default virtual destructor
*
*/
virtual ~DbncdMPBttn();
/**
* @brief Attaches the instantiated object to a timer that monitors the input pins and updates the object status.
*
* The frequency of the periodic monitoring is passed as a parameter in milliseconds, and is a value that must be small (frequent) enough to keep the object updated, but not so frequent that wastes resources from other tasks. A default value is provided based on empirical results obtained in various published tests.
*
* @param pollDelayMs (Optional) unsigned long integer (ulong), the time between polls in milliseconds.
*
* @return Boolean indicating if the object could be attached to a timer.
* @retval true: the object could be attached to a timer -or it was already attached to a timer when the method was invoked-.
* @retval false: the object could not create the needed timer, or the object could not be attached to it.
*/
virtual bool begin(const unsigned long int &pollDelayMs = _StdPollDelay);
/**
* @brief Clears and resets flags, timers and counters modified through the object's signals processing.
*
* Resets object's attributes to initialization values to safely resume operations, either after pausing the timer, enabling the object after disabling it or any disruptive activity that might generate unexpected distorsions. This avoids risky behavior of the object due to dangling flags or partially ran time counters.
*
* @param clrIsOn Optional boolean value, indicates if the _isOn flag must be included to be cleared:
*
* - true (default value) includes the isOn flag.
* - false excludes the isOn flag.
*/
void clrStatus(bool clrIsOn = true);
/**
* @brief Disables the input signal processing, ignoring the changes of its values.
*
* Invoking the disable() method sends a message to the object requesting it to enter the **Disabled state**. Due to security and stability of the object's behavior the message will not be processed at every stage of the input signals detection and output computations, but in every safe and stable stage. When the message is processed the object will:
* - Stop all input signal reading.
* - Stop any new output flag computation.
* - Reset all output flag values.
* - Force the isOn flag according to the **isOnDisabled** flag setting.
* - Keep this **Disabled state** behavior until an enabling message is received through an **enable()** method.
*/
void disable();
/**
* @brief Enables the input signal processing.
*
* Invoking the enable() method on a object in **Disabled state** sends it a message requesting to resume it's normal operation. The execution of the re-enabling of the object implies:
* - Resuming all input signals reading.
* - Resuming all output flag computation from the "fresh startup" state, including clearing the **isOn state**
* - Due to strict security enforcement the object will not be allowed to enter the **Enabled state** if the MPB was pressed when the enable message was received and until a MPB release is efectively detected.
*/
void enable();
/**
* @brief Detaches the object from the timer that monitors the input pins, compute and updates the object's status. The timer daemon entry is deleted for the object.
*
* The immediate detachment of the object from the timer that keeps it's state updated implies that the object's state will be kept, whatever that state is it. If a certain status is preferred some of the provided methods should be used for that including clrStatus(), resetFda(), disable(), setIsOnDisabled(), etc. Also consider that if a task is set to be executed while the object is in **On state**, the **end()** invocation wouldn't affect that task execution state.
*
* @return Boolean indicating the success of the operation
* @retval true: the object detachment procedure and timer entry removal was successful.
* @retval false: the object detachment and/or entry removal was rejected by the O.S..
*/
bool end();
/**
* @brief Returns the current debounce time set for the object.
*
* The original value for the debouncing process used at instantiation time might be changed with the **setDbncTime(const unsigned long int)** or with the **resetDbncTime()** methods. This method gets the current value of the attribute in use.
*
* @return The current debounce time in milliseconds
*/
const unsigned long int getCurDbncTime() const;
/**
* @brief Returns the function that is set to execute every time the object **enters** the **Off State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOffPtr()** method.
*
* @return A function pointer to the function set to execute every time the object enters the **Off State**.
* @retval nullptr if there is no function set to execute when the object enters the **Off State**.
*
* @warning The function code execution will become part of the list of procedures the object executes when it entering the **Off State**, including the modification of affected attribute flags, suspending the execution of the task running while in **On State** and others. Making the function code too time demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOff();
/**
* @brief Returns the function that is set to execute every time the object **enters** the **On State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOnPtr()** method.
*
* @return A function pointer to the function set to execute every time the object enters the **On State**.
* @retval nullptr if there is no function set to execute when the object enters the **On State**.
*
* * @warning The function code execution will become part of the list of procedures the object executes when it entering the **On State**, including the modification of affected attribute flags, suspending the execution of the task running while in **On State** and others. Making the function code too time demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOn();
/**
* @brief Returns the value of the isEnabled attribute flag, indicating the **Enabled** or **Disabled** status of the object.
*
* The isEnabled flag might be modified by the enable() and the disable() methods.
*
* @retval true: the object is in **Enabled state**.
* @retval false: The object is in **Disabled state**.
*/
const bool getIsEnabled() const;
/**
* @brief Returns the value of the **isOn** attribute flag.
*
* The **isOn** attribute flag is the fundamental attribute of the object, it might be considered the "Raison d'etre" of all this classes design: the isOn signal is not just the detection of an expected voltage value at a mcu pin, but the combination of that voltage level, filtered and verified, for a determined period of time and until a new event modifies that situation. While other mechanism are provided to execute code when the status of the object changes, all but the **isOn** flag value update are optionally executed.
*
* @retval true: The object is in **On state**.
* @retval false: The object is in **Off state**.
*/
const bool getIsOn () const;
/**
* @brief Returns the value of the **isOnDisabled** attribute flag.
*
* When instantiated the class, the object is created in **Enabled state**. That might be changed when needed.
* In the **Disabled state** the input signals for the MPB are not processed, and the output will be set to the **On state** or the **Off state** depending on this flag's value.
* The reasons to disable the ability to change the output, and keep it on either state until re-enabled are design and use dependent.
* The flag value might be changed by the use of the setIsOnDisabled() method.
*
* @retval true: the object is configured to be set to the **On state** while it is in **Disabled state**.
* @retval false: the object is configured to be set to the **Off state** while it is in **Disabled state**.
*/
const bool getIsOnDisabled() const;
/**
* @brief Returns the relevant attribute flags values for the object state encoded as a 32 bits value, required to pass current state of the object to another thread/task managing the outputs
*
* The inter-tasks communication mechanisms implemented on the class includes a xTaskNotify() that works as a light-weigh mailbox, unblocking the receiving tasks and sending to it a 32_bit value notification. This function returns the relevant attribute flags values encoded in a 32 bit value, according the provided encoding described.
*
* @return A 32-bit unsigned value representing the attribute flags current values.
*/
const uint32_t getOtptsSttsPkgd();
/**
* @brief Returns the value of the **outputsChange** attribute flag.
*
* The instantiated objects include attributes linked to their computed state, which represent the behavior expected from their respective electromechanical simulated counterparts.
* When any of those attributes values change, the **outputsChange** flag is set. The flag only signals changes have happened -not which flags, nor how many times changes have taken place- since the last **outputsChange** flag reset.
* The **outputsChange** flag must be reset (or set if desired) through the setOutputsChange() method.
*
* @retval true: any of the object's behavior flags have changed value since last time **outputsChange** flag was reseted.
* @retval false: no object's behavior flags have changed value since last time **outputsChange** flag was reseted.
*/
const bool getOutputsChange() const;
/**
* @brief Returns the current value of strtDelay attribute.
*
* Returns the current value of time used by the object to rise the isOn flag, after the debouncing process ends, in milliseconds. If the MPB is released before completing the debounce **and** the strtDelay time, no press will be detected by the object, and the isOn flag will not be affected. The original value for the delay process used at instantiation time might be changed with the setStrtDelay() method, so this method is provided to get the current value in use.
*
* @return The current strtDelay time in milliseconds.
*
* @attention The strtDelay attribute is forced to a 0 ms value at instantiation of DbncdMPBttn class objects, and no setter mechanism is provided in this class. The inherited DbncdDlydMPBttn class objects (and all it's subclasses) constructor includes a parameter to initialize the strtDelay value, and a method to set that attribute to a new value.
*/
unsigned long int getStrtDelay();
/**
* @brief Returns the task to be notified by the object when its output flags changes.
*
* The task handle of the task to be notified by the object when its **outputsChange** attribute flag is set (see getOutputsChange()) holds a **NULL** when the object is created. A valid task's TaskHandle_t value might be set by using the setTaskToNotify() method, and even set back to **NULL** to disable the task notification mechanism.
*
* @return TaskHandle_t value of the task to be notified of the outputs change.
* @retval NULL: there is no task configured to be notified of the outputs change.
*
* @note The notification is done through a **direct to task notification** using the **xTaskNotify()** RTOS macro, the notification includes passing the notified task a 32-bit notification value.
*/
const TaskHandle_t getTaskToNotify() const;
/**
* @brief Returns the task to be run (resumed) while the object is in the **On state**.
*
* Returns the task handle of the task to be **resumed** every time the object enters the **On state**, and will be **paused** when the object enters the **Off state**. This task execution mechanism dependent of the **On state** extends the concept of the **Switch object** far away of the simple turning On/Off a single hardware signal, attaching to it all the task execution capabilities of the MCU.
*
* @return The TaskHandle_t value of the task to be resumed while the object is in **On state**.
* @retval NULL if there is no task configured to be resumed while the object is in **On state**.
*
* @warning Free-RTOS has no mechanism implemented to notify a task that it is about to be set in **paused** state, so there is no way to that task to ensure it will be set to pause in an orderly fashion. The task to be designated to be used by this mechanism has to be task that can withstand being interrupted at any point of it's execution, and be restarted from that same point next time the **isOn** flag is set. For tasks that might need attaching resources or other issues every time it is resumed and releasing resources of any kind before being **paused**, using the function attached by using **setFnWhnTrnOnPtr()** to gain control of the resources before resuming a task, and the function attached by using **setFnWhnTrnOffPtr()** to release the resources and pause the task in an orderly fashion, or use those functions to manage a binary semaphore for managing the execution of a task.
*/
const TaskHandle_t getTaskWhileOn();
/**
* @brief Initializes an object instantiated by the default constructor
*
* All the parameters correspond to the non-default constructor of the class, DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*/
bool init(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0);
/**
* @brief Initializes an object instantiated by the default constructor
*
* All the parameters correspond to the non-default constructor of the class, DbncdMPBttn(gpioPinId_t, const bool, const bool, const unsigned long int)
*/
bool init(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0);
/**
* @brief Pauses the software timer updating the computation of the object's internal flags value.
*
* The immediate stop of the timer that keeps the object's state updated implies that the object's state will be kept, whatever that state is it. The same consideration as the end() method applies referring to options to modify the state in which the object will be while in the **Pause state**.
*
* @retval true: the object's timer could be stopped by the O.S.(or it was already stopped).
* @retval false: the object's timer couldn't be stopped by the O.S..
*/
bool pause();
/**
* @brief Resets the debounce process time of the object to the value used at instantiation.
*
* The debounce process time used at instantiation might be changed with the setDbncTime() as needed, as many times as needed. This method reverts the value to the instantiation time value. In case the value was not specified at instantiation time the default debounce time value will be used.
*/
void resetDbncTime();
/**
* @brief Resets the MPB behavior automaton to it's **Initial** or **Start State**
*
* This method is provided for security and for error handling purposes, so that in case of unexpected situations detected, the driving **Deterministic Finite Automaton** used to compute the MPB objects states might be reset to it's initial state to safely restart it, usually as part of an **Error Handling** procedure.
*/
void resetFda();
/**
* @brief Restarts the software timer updating the calculation of the object internal flags.
*
* The timer will stop calling the functions for computing the flags values after calling the **pause()** method and will not be updated until the timer is restarted with this method.
*
* @retval true: the object's timer could be restarted by the O.S..
* @retval false: the object's timer couldn't be restarted by the O.S..
*
* @warning This method will restart the inactive timer after a **pause()** method. If the object's timer was modified by an **end()* method then a **begin()** method will be needed to restart it's timer.
*/
bool resume();
/**
* @brief Sets the debounce time.
*
* Sets a new time for the debouncing period. The value must be equal or greater than the minimum empirical value set as a property for all the classes, 20 milliseconds, that value is defined in the _HwMinDbncTime constant. A long debounce time will produce a delay in the press event generation, making it less "responsive".
*
* @param newDbncTime unsigned long integer, the new debounce value for the object.
*
* @return A boolean indicating if the debounce time setting was successful.
* @retval true: the new value is in the accepted range, the attribute value is updated.
* @retval false: the value was out of the accepted range, no change was made.
*/
bool setDbncTime(const unsigned long int &newDbncTime);
/**
* @brief Sets the function that will be called to execute every time the object **enters** the **Off State**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOff)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOff Function pointer to the function intended to be called when the object **enters** the **Off State**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOffPtr(void(*newFnWhnTrnOff)());
/**
* @brief Sets the function that will be called to execute every time the object **enters** the **On State**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOff)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOn: function pointer to the function intended to be called when the object **enters** the **On State**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOnPtr(void (*newFnWhnTrnOn)());
/**
* @brief Sets the value of the **isOnDisabled** flag.
*
* When instantiated the class, the object is created in **Enabled state**. That might be changed as needed.
* While in the **Disabled state** the input signals for the MPB are not processed, and the output will be set to the **On state** or the **Off state** depending on this flag value.
*
* @note The reasons to disable the ability to change the output, and keep it on either state until re-enabled are design and use dependent, being an obvious one security reasons, disabling the ability of the users to manipulate the switch while keeping the desired **On/Off state**. A simple example would be to keep a light on in a place where a meeting is taking place, disabling the lights switches and keeping the **On State**. Another obvious one would be to keep a machine off while servicing it's internal mechanisms, disabling the possibility of turning it on.
*
* @warning If the method is invoked while the object is disabled, and the **isOnDisabled** attribute flag is changed, then the **isOn** attribute flag will have to change accordingly. Changing the **isOn** flag value implies that **all** the implemented mechanisms related to the change of the **isOn** attribute flag value will be invoked.
*/
void setIsOnDisabled(const bool &newIsOnDisabled);
/**
* @brief Sets the value of the attribute flag indicating if a change took place in any of the output attribute flags (IsOn included).
*
* The usual path for the **outputsChange** flag is to be set by any method changing an output attribute flag, the callback function signaled to take care of the hardware actions because of this changes clears back **outputsChange** after taking care of them. In the unusual case the developer wants to "intercept" this sequence, this method is provided to set (true) or clear (false) outputsChange value.
*
* @param newOutputChange The new value to set the **outputsChange** flag to.
*/
void setOutputsChange(bool newOutputChange);
/**
* @brief Sets the pointer to the task to be notified by the object when its output attribute flags changes.
*
* When the object is created, this value is set to **NULL**, and a valid TaskHandle_t value might be set by using this method. The task notifying mechanism will not be used while the task handle keeps the **NULL** value, in which case the solution implementation will have to use any of the other provided mechanisms to test the object status, and act accordingly. After the TaskHandle value is set it might be changed to point to other task. If at the point this method is invoked the attribute holding the pointer was not NULL, the method will suspend the pointed task before proceeding to change the attribute value. The method does not provide any verification mechanism to ensure the passed parameter is a valid task handle nor the state of the task the passed pointer might be.
*
* @param newTaskHandle A valid task handle of an actual existent task/thread running.
*
* @note As simple as this mechanism is, it's an un-expensive effective solution in terms of resources involved. As a counterpart it's use must be limited to clearly defined implementations, as no value passing mechanism is provided, so global variables will be the easiest way to go, either for the instantiated MPB, or for the relevant attribute flags values copied to global variables, as the case of **isON**, **isEnabled** and others in the case of more complex subclasses.
*/
void setTaskToNotify(const TaskHandle_t &newTaskHandle);
/**
* @brief Sets the task to be run while the object is in the **On state**.
*
* Sets the task handle of the task to be **resumed** when the object enters the **On state**, and will be **paused** when the object enters the **Off state**. This task execution mechanism dependent of the **On state** extends the concept of the **Switch object** far away of the simple turning On/Off a single hardware signal, attaching to it all the task execution capabilities of the MCU.
*
* If the existing value for the task handle was not NULL before the invocation, the method will verify the Task Handle was pointing to a deleted or suspended task, in which case will proceed to **suspend** that task before changing the Task Handle to the new provided value.
*
* Setting the value to NULL will disable the task execution mechanism.
*
*@note The method does not implement any task handle validation for the new task handle, a valid handle to a valid task is assumed as parameter.
*
* @note Consider the implications of the task that's going to get suspended every time the MPB goes to the **Off state**, so that the the task to be run might be interrupted at any point of its execution. This implies that the task must be designed with that consideration in mind to avoid dangerous situations generated by a task not completely done when suspended.
*
* @warning Take special consideration about the implications of the execution **priority** of the task to be executed while the MPB is in **On state** and its relation to the priority of the calling task, as it might affect the normal execution of the application.
*/
virtual void setTaskWhileOn(const TaskHandle_t &newTaskHandle);
};
//==========================================================>>
/**
* @brief Models a Debounced Delayed MPB (**DD-MPB**).
*
* The **Debounced Delayed Momentary Button**, keeps the ON state since the moment the signal is stable (debouncing process), plus a delay added, and until the moment the push button is released. The reasons to add the delay are design related and are usually used to avoid unintentional presses, or to give some equipment (load) that needs time between repeated activations the benefit of the pause. If the push button is released before the debounce and delay times configured are reached, no press is registered at all. The delay time in this class as in the other that implement it, might be zero (0), defined by the developer and/or modified in runtime.
*
* @note If the **delay** attribute is set to 0, the resulting object of this class is equivalent in functionality to a **DbncdMPBttn** class object.
*
* @class DbncdDlydMPBttn
*/
class DbncdDlydMPBttn: public DbncdMPBttn{
public:
/**
* @brief Default constructor
*
*/
DbncdDlydMPBttn();
/**
* @brief Class constructor
*
* @param strtDelay Sets the initial value for the **strtDelay** attribute.
*
* @note For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*
* @note If the **delay** attribute is set to 0, the resulting object is equivalent in functionality to a **DbncdMPBttn** class object.
*/
DbncdDlydMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Class constructor
*
* @param strtDelay See DbncdDlydMPBttn(gpioPinId_t, const bool, const bool, const unsigned long int, const unsigned long int)
*
* @note For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*
* @note If the **delay** attribute is set to 0, the resulting object is equal in functionality to a **DbncdMPBttn** class object.
*/
DbncdDlydMPBttn(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
*
* @brief see DbncdMPBttn::init(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*/
bool init(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
*
* @brief see DbncdMPBttn::init(gpioPinId_t, const bool, const bool, const unsigned long int)
*/
bool init(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Sets a new value to the **delay** attribute
*
* @param newStrtDelay New value for the **delay** attribute in milliseconds.
*
* @note Setting the delay attribute to 0 makes the instantiated object act exactly as a Debounced MPB (D-MPB)
* @warning: Using very high **delay** values is valid but might make the system seem less responsive, be aware of how it will affect the user experience.
*/
void setStrtDelay(const unsigned long int &newStrtDelay);
};
//==========================================================>>
/**
* @brief Abstract class, base to model Latched Debounced Delayed MPBs (**LDD-MPB**).
*
* **Latched DD-MPB** are MPBs whose distinctive characteristic is that implement switches that keep the ON state since the moment the input signal is stable (debouncing + Delay process), and keeps the ON state after the MPB is released and until an event un-latches them, setting them free to move to the **Off State**.
* The un-latching mechanisms include but are not limited to: same MPB presses, timers, other MPB presses, other GPIO external un-latch signals or the use of the public method unlatch().
* The different un-latching events defines the sub-classes of the LDD-MPB class.
*
* @attention The range of signals accepted by the instantiated objects to execute the unlatch process is diverse, and their nature and characteristics might affect the expected switch behavior. While some of the signals might be instantaneous, meaning that the **start of the unlatch signal** is coincidental with the **end of the unlatch signal**, some others might extend the time between both ends. To accommodate the logic required by each subclass the **_unlatch_** process is then split into two stages:
* 1. Validated Unlatch signal (or Validated Unlatch signal start).
* 2. Validated Unlatch Release signal (or Validated Unlatch signal end).
* The class provides methods to generate the signals independently of the designated signal sources to modify the instantiated object behavior if needed by the design requirements, Validated Unlatch signal (see LtchMPBttn::setUnlatchPend(const bool), Validated Unlatch Release signal (see LtchMPBttn::setUnlatchRlsPend(const bool), or to **set** both flags to generate an unlatch (see LtchMPBttn::unlatch().
*
* @warning Generating the unlatach related flags independently of the unlatch signals provided by the LDD-MPB subclasses might result in unexpected behavior, which might generate the locking of the object with it's unexpected consequences.
*
* @class LtchMPBttn
*/
class LtchMPBttn: public DbncdDlydMPBttn{
protected:
enum fdaLmpbStts {
stOffNotVPP,
stOffVPP,
stOnNVRP,
stOnVRP,
stLtchNVUP,
stLtchdVUP,
stOffVUP,
stOffNVURP,
stOffVURP,
stDisabled
};
bool _isLatched{false};
fdaLmpbStts _mpbFdaState {stOffNotVPP};
bool _trnOffASAP{true};
volatile bool _validUnlatchPend{false};
volatile bool _validUnlatchRlsPend{false};
static void mpbPollCallback(TimerHandle_t mpbTmrCbArg);
virtual void stDisabled_In(){};
virtual void stDisabled_Out(){};
virtual void stLtchNVUP_Do(){};
virtual void stOffNotVPP_In(){};
virtual void stOffNotVPP_Out(){};
virtual void stOffNVURP_Do(){};
virtual void stOffVPP_Out(){};
virtual void stOffVURP_Out(){};
virtual void stOnNVRP_Do(){};
virtual void updFdaState();
virtual void updValidUnlatchStatus() = 0;
public:
/**
* @brief Class constructor
*
* @note For the parameters see DbncdDlydMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int, const unsigned long int)
*/
LtchMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Class constructor
*
* @param mpbttnPinStrct GPIO port and Pin identification defined as a single gpioPinId_t parameter.
*
* For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*/
LtchMPBttn(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief See DbncdMPBttn::begin(const unsigned long int)
*/
virtual bool begin(const unsigned long int &pollDelayMs = _StdPollDelay);
/**
* @brief See DbncdMPBttn::clrStatus(bool)
*/
void clrStatus(bool clrIsOn = true);
/**
* @brief Returns the value of the isLatched attribute flag, indicating the **Latched** or **Unlatched** condition of the object.
*
* The isLatched flag is automatically updated periodically by the timer that calculates the object state.
*
* @retval true: the object is in **Latched condition**.
* @retval false: The object is in **Unlatched condition**.
*/
const bool getIsLatched() const;
/**
* @brief Returns the value of the trnOffASfAP class attribute flag.
*
* As described in the class characteristics the unlatching process comprises two stages, Validated Unlatch Signal and Validates unlatch Release Signal, that might be generated simultaneously or separated in time. The **trnOffASAP** attribute flag sets the behavior of the MPB in the second case.
* - If the **trnOffASAP** attribute flag is set (true) the **isOn** flag will be reseted as soon as the **Validated Unlatch Signal** is detected
* - If the **trnOffASAP** flag is reset (false) the **isOn** flag will be reseted only when the **Validated Unlatch Release signal** is detected.
*
* @return The current value of the trnOffASAP attribute flag.
*/
bool getTrnOffASAP();
/**
* @brief Returns the value of the validUnlatchPending attribute
*
* The validUnlatchPending holds the existence of a still to be processed confirmed unlatch signal. Getting it's current value makes possible taking actions before the unlatch process is started or even discard it completely by using the setUnlatchPend(const bool) method.
*
* @return The current value of the validUnlatchPending attribute.
*/
const bool getUnlatchPend() const;
/**
* @brief Returns the value of the validUnlatchReleasePending attribute
*
* The validUnlatchReleasePending holds the existence of a still to be processed confirmed unlatch released signal. Getting it's current value makes possible taking actions before the unlatch process ends or even discard it completely by using the setUnlatchRlsPend(const bool) method.
*
* @return The current value of the validUnlatchReleasePending attribute.
*/
const bool getUnlatchRlsPend() const;
/**
* @brief See DbncdMPBttn::resetFda()
*/
bool resetFda();
/**
* @brief Sets the value of the trnOffASAP attribute flag.
*
* @param newVal New value for the trnOffASAP attribute
*/
void setTrnOffASAP(const bool &newVal);
/**
* @brief Sets the value of the validUnlatchPending attribute
*
* By setting the value of the validUnlatchPending it's possible to modify the current MPB status by generating an unlatch signal or by canceling an existent unlatch signal.
*
* @param newVal New value for the validUnlatchPending attribute
*/
void setUnlatchPend(const bool &newVal);
/**
* @brief Sets the value of the validUnlatchRlsPending attribute
*
* By setting the value of the validUnlatchPending and validUnlatchReleasePending flags it's possible to modify the current MPB status by generating an unlatch signal or by canceling an existent unlatch signal.
*
* @param newVal New value for the validUnlatchReleasePending attribute
*/
void setUnlatchRlsPend(const bool &newVal);
/**
* @brief Sets the values of the flags needed to unlatch a latched MPB
*
* By setting the values of the validUnlatchPending **and** validUnlatchReleasePending flags it's possible to modify the current MPB status by generating an unlatch signal.
*
* @retval true the object was latched and the unlatch flags were set.
* @retval false the object was not latched, no unlatch flags were set.
*
* @note Setting the values of the validUnlatchPending and validUnlatchReleasePending flags does not implicate immediate unlatching the MPB but providing the unlatching signals. The unlatching signals will be processed by the MPB according to it's embedded behavioral pattern. For example, the signals will be processed if the MPB is in Enabled state and latched, but will be ignored if the MPB is disabled.
*/
bool unlatch();
};
//==========================================================>>
/**
* @brief Models a Toggle Latch DD-MPB, a.k.a. a Toggle Switch (**ToLDD-MPB**).
*
* The **Toggle switch** keeps the ON state since the moment the signal is stable (debouncing + delay process), and keeps the ON state after the push button is released and until it is pressed once again. So this simulates a simple On-Off switch like the one used to turn on/off a room light. The included methods lets the designer define the unlatch event as the instant the MPB is started to be pressed for the second time or when the MPB is released from that second press.
*
* @class TgglLtchMPBttn
*/
class TgglLtchMPBttn: public LtchMPBttn{
protected:
virtual void stOffNVURP_Do();
virtual void updValidUnlatchStatus();
public:
/**
* @brief Class constructor
*
* @note For the parameters see DbncdDlydMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int, const unsigned long int)
*/
TgglLtchMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Class constructor
*
* @param mpbttnPinStrct GPIO port and Pin identification defined as a single gpioPinId_t parameter.
* For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*/
TgglLtchMPBttn(gpioPinId_t mpbttnPinStrct, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
};
//==========================================================>>
/**
* @brief Models a Timer Latch DD-MPB, a.k.a. Timer Switch (**TiLDD-MPB**).
*
* The **Timer switch** keeps the **On state** since the moment the signal is stable (debouncing + delay process), and until the unlatch signal is provided by a preset timer **started immediately after** the MPB has passed the debounce & delay process.
* The time count down might be reseted by pressing the MPB before the timer expires by optionally configuring the object to do so with the provided method.
* The total count-down time might be changed by using a provided method.
*
* class TmLtchMPBttn
*/
class TmLtchMPBttn: public LtchMPBttn{
protected:
bool _tmRstbl {true};
unsigned long int _srvcTime {};
unsigned long int _srvcTimerStrt{0};
virtual void stOffNotVPP_Out();
virtual void stOffVPP_Out();
virtual void updValidUnlatchStatus();
public:
/**
* @brief Class constructor
*
* @param srvcTime The service time (time to keep the **isOn** attribute flag raised).
*
* @note For the other parameters see DbncdDlydMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int, const unsigned long int)
*/
TmLtchMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const unsigned long int &srvcTime, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Class constructor
*
* @param mpbttnPinStrct GPIO port and Pin identification defined as a single gpioPinId_t parameter.
* @param srvcTime The service time (time to keep the **isOn** attribute flag raised).
*
* @note For the rest of the parameters see DbncdMPBttn(GPIO_TypeDef*, const uint16_t, const bool, const bool, const unsigned long int)
*/
TmLtchMPBttn(gpioPinId_t mpbttnPinStrct, const unsigned long int &srvcTime, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief see DbncdMPBttn::clrStatus(bool)
*/
void clrStatus(bool clrIsOn = true);
/**
* @brief Returns the configured Service Time.
*
* @return The current Service Time setting in milliseconds
*/
const unsigned long int getSrvcTime() const;
/**
* @brief Sets a new value to the Service Time attribute
*
* @param newSrvcTime New value for the Service Time attribute
*
* @note To ensure a safe and predictable behavior from the instantiated objects a minimum Service Time setting guard is provided, ensuring data and signals processing are completed before unlatching process is enforced by the timer. The guard is set by the defined _MinSrvcTime constant.
*
* @retval true if the newSrvcTime parameter is equal to or greater than the minimum setting guard, the new value is set.
* @retval false The newSrvcTime parameter is less than the minimum setting guard, the srvcTime attribute was not changed.
*/
bool setSrvcTime(const unsigned long int &newSrvcTime);
/**
* @brief Configures the timer for the Service Time to be reseted before it reaches unlatching time.
*
* If the isResetable attribute flag is cleared the MPB will return to **Off state** when the Service Time is reached no matter if the MPB was pressed again during the service time period. If the attribute flag is set, pressing the MPB (debounce and delay times enforced) while on the **On state** resets the timer, starting back from 0. The reseting might be repeated as many times as desired.
*
* @param newIsRstbl The new setting for the isResetable flag.
*/
void setTmerRstbl(const bool &newIsRstbl);
};
//==========================================================>>
/**
* @brief Models a Hinted Timer Latch DD-MPB, a.k.a. Staircase Switch (**HTiLDD-MPB**).
*
* The **Staircase switch** keeps the ON state since the moment the signal is stable (debouncing + delay process), and until the unlatch signal is provided by a preset timer **started immediately after** the MPB has passed the debounce & delay process.
* A warning flag might be configured to raise when the time left to keep the ON signal is close to expiration, based on a configurable percentage of the total Service Time.
* The time count down might be reseted by pressing the MPB before the timer expires by optionally configuring the object to do so with the provided method.
* A **Pilot Signal** attribute flag is included to emulate completely the staircase switches, that might be activated while the MPB is in **Off state**, by optionally configuring the object to do so with the provided method. This might be considered just a perk as it's not much more than the **isOn** flag negated output, but gives the advantage of freeing the designer of additional coding.
*
* class HntdTmLtchMPBttn
*/
class HntdTmLtchMPBttn: public TmLtchMPBttn{
protected:
void (*_fnWhnTrnOffPilot)() {nullptr};
void (*_fnWhnTrnOffWrnng)() {nullptr};
void (*_fnWhnTrnOnPilot)() {nullptr};
void (*_fnWhnTrnOnWrnng)() {nullptr};
bool _keepPilot{false};
volatile bool _pilotOn{false};
unsigned long int _wrnngMs{0};
volatile bool _wrnngOn {false};
unsigned int _wrnngPrctg {0};
bool _validWrnngSetPend{false};
bool _validWrnngResetPend{false};
bool _validPilotSetPend{false};
bool _validPilotResetPend{false};
static void mpbPollCallback(TimerHandle_t mpbTmrCbArg);
uint32_t _otptsSttsPkg(uint32_t prevVal = 0);
virtual void stDisabled_In();
virtual void stLtchNVUP_Do();
virtual void stOffNotVPP_In();
virtual void stOffVPP_Out();
virtual void stOnNVRP_Do();
void _turnOffPilot();
void _turnOffWrnng();
void _turnOnPilot();
void _turnOnWrnng();
bool updPilotOn();
bool updWrnngOn();
public:
/**
* @brief Class constructor
*
* @param wrnngPrctg Time **before expiration** of service time that the warning flag must be set. The time is expressed as a percentage of the total service time so it's a value in the 0 <= wrnngPrctg <= 100 range.
*
* For the rest of the parameters see TmLtchMPBttn(GPIO_TypeDef*, const uint16_t, const unsigned long int, const bool, const bool, const unsigned long int, const unsigned long int)
*/
HntdTmLtchMPBttn(GPIO_TypeDef* mpbttnPort, const uint16_t &mpbttnPin, const unsigned long int &actTime, const unsigned int &wrnngPrctg = 0, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief Class constructor
*
* @param wrnngPrctg Time **before expiration** of service time that the warning flag must be set. The time is expressed as a percentage of the total service time so it's a value in the 0 <= wrnngPrctg <= 100 range.
*
* For the rest of the parameters see TmLtchMPBttn(gpioPinId_t, const unsigned long int, const bool, const bool, const unsigned long int, const unsigned long int)
*/
HntdTmLtchMPBttn(gpioPinId_t mpbttnPinStrct, const unsigned long int &actTime, const unsigned int &wrnngPrctg = 0, const bool &pulledUp = true, const bool &typeNO = true, const unsigned long int &dbncTimeOrigSett = 0, const unsigned long int &strtDelay = 0);
/**
* @brief See DbncdMPBttn::begin(const unsigned long int)
*/
virtual bool begin(const unsigned long int &pollDelayMs = _StdPollDelay);
/**
* @brief see DbncdMPBttn::clrStatus(bool)
*/
void clrStatus(bool clrIsOn = true);
/**
* @brief Returns the function that is set to execute every time the object's **Pilot** attribute flag **enters** the **Off State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOffPilotPtr()** method.
*
* @return A function pointer to the function set to execute every time the object's Pilot is set to the **Off State**.
* @retval nullptr if there is no function set to execute when the object's Pilot enters the **Off State**.
*
* @warning The function code execution will become part of the list of procedures the object executes when it enters the **Pilot Off State**, including the modification of affected attribute flags. Making the function code too time-demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOffPilot();
/**
* @brief Returns the function that is set to execute every time the object's **Warning** attribute flag **enters** the **Off State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOffWrnngPtr()** method.
*
* @return A function pointer to the function set to execute every time the object's Warning is set to the **Off State**.
* @retval nullptr if there is no function set to execute when the object's Warning enters the **Off State**.
*
* @warning The function code execution will become part of the list of procedures the object executes when it enters the **Warning Off State**, including the modification of affected attribute flags. Making the function code too time-demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOffWrnng();
/**
* @brief Returns the function that is set to execute every time the object's **Pilot** attribute flag **enters** the **On State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOnPilotPtr()** method.
*
* @return A function pointer to the function set to execute every time the object's Pilot is set to the **On State**.
* @retval nullptr if there is no function set to execute when the object's Pilot enters the **On State**.
*
* @warning The function code execution will become part of the list of procedures the object executes when it enters the **Pilot On State**, including the modification of affected attribute flags. Making the function code too time-demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOnPilot();
/**
* @brief Returns the function that is set to execute every time the object's **Warning** attribute flag **enters** the **On State**.
*
* The function to be executed is an attribute that might be modified by the **setFnWhnTrnOnWarnngPtr()** method.
*
* @return A function pointer to the function set to execute every time the object's Warning is set to the **On State**.
* @retval nullptr if there is no function set to execute when the object's Warning enters the **On State**.
*
* @warning The function code execution will become part of the list of procedures the object executes when it enters the **Warning On State**, including the modification of affected attribute flags. Making the function code too time-demanding must be handled with care, using alternative execution schemes, for example the function might resume a independent task that suspends itself at the end of its code, to let a new function calling event resume it once again.
*/
fncPtrType getFnWhnTrnOnWrnng();
/**
* @brief Returns the current value of the pilotOn attribute flag.
*
* The pilotOn flag will be set when the isOn attribute flag is reset (~isOn), while the keepPilot attribute is set. If the keepPilot attribute is false the pilotOn will keep reset independently of the isOn flag value.
*
* @return The current value of the pilotOn flag
* @retval true: the pilotOn flag value is true
* @retval false: the pilotOn flag value is false
*/
const bool getPilotOn() const;
/**
* @brief Returns the current value of the warningOn attribute flag.
*
* The warningOn flag will be set when the configured service time (to keep the ON signal set) is close to expiration, based on a configurable percentage of the total Service time.
*
* @return The current value of the warningOn attribute flag.
*
* @note As there is no configuration setting to keep the warning flag from working, the way to force the flag to stay set or stay reset is by configuring the accepted limits:
* - 0: Will keep the warningOn flag always false (i.e. will turn to true 0 ms before reaching the end of Service Time).
* - 100: Will keep the warningOn flag always true (i.e. will turn to true for the 100% of the Service Time).
*/
const bool getWrnngOn() const;
/**
* @brief Sets the function that will be called to execute every time the object's **Pilot** is **reset**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOff)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOff Function pointer to the function intended to be called when the object's **Pilot** is **reset**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOffPilotPtr(void(*newFnWhnTrnOff)());
/**
* @brief Sets the function that will be called to execute every time the object's **Warning** is **reset**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOff)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOff Function pointer to the function intended to be called when the object's **Warning** is **reset**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOffWrnngPtr(void(*newFnWhnTrnOff)());
/**
* @brief Sets the function that will be called to execute every time the object's **Pilot** is **set**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOn)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOn: function pointer to the function intended to be called when the object's **Pilot is set**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOnPilotPtr(void(*newFnWhnTrnOn)());
/**
* @brief Sets the function that will be called to execute every time the object's **Wrnng** is **set**.
*
* The function to be executed must be of the form **void (*newFnWhnTrnOn)()**, meaning it must take no arguments and must return no value, it will be executed only once by the object (recursion must be handled with the usual precautions). When instantiated the attribute value is set to **nullptr**.
*
* @param newFnWhnTrnOn: function pointer to the function intended to be called when the object's **Wrnng** is **set**. Passing **nullptr** as parameter deactivates the function execution mechanism.
*/
void setFnWhnTrnOnWrnngPtr(void(*newFnWhnTrnOn)());
/**
* @brief Sets the configuration of the keepPilot service attribute.
*
* @param newKeepPilot The new setting for the keepPilot service attribute.
*/
void setKeepPilot(const bool &newKeepPilot);
/**
* @brief See TmLtchMPBttn::setSrvcTime(const unsigned long int)
*
* @note As the warningOn attribute flag behavior is based on a percentage of the service time setting, changing the value of that service time implies changing the time amount for the warning signal service, recalculating such time as the set percentage of the new service time.
*/
bool setSrvcTime(const unsigned long int &newActTime);
/**
* @brief Sets the value for the percentage of service time for calculating the warningOn flag value.
*
* The amount of **time before expiration** of service time that the warning flag must be set is defined as a percentage of the total service time so it's a value in the 0 <= wrnngPrctg <= 100 range.
*
* @param newWrnngPrctg The new percentage of service time value used to calculate the time before service time expiration to set the warningOn flag.
*
* @return Success changing the percentage to a new value
* @retval true the value was within range, the new value is set
* @retval false the value was outside range, the value change was dismissed.
*/
bool setWrnngPrctg (const unsigned int &newWrnngPrctg);
};
//==========================================================>>
/**
* @brief Models an External Unlatch LDD-MPB, a.k.a. Emergency Latched Switch (**XULDD-MPB**)
*
* The **External released toggle switch** (a.k.a. Emergency latched), keeps the On state since the moment the signal is stable (debounced & delayed), and until an external signal is received. This kind of switch is used when an "abnormal situation" demands the push of the switch On, but a higher authority is needed to reset it to Off from a different signal source. The **On State** will then not only start a response to the exception arisen, but will be kept to flag the triggering event.