diff --git a/src/hal/components/momentary2nist.comp b/src/hal/components/momentary2nist.comp new file mode 100644 index 00000000000..5eac156fd76 --- /dev/null +++ b/src/hal/components/momentary2nist.comp @@ -0,0 +1,77 @@ +component momentary2nist "momentary button to nist logic"; + +description +""" +Momentary2nist can be used with a momentary push button +to control a device that has separate on and off inputs +and an is-on output. +A debounce delay in cycles can be set for 'in'. (default = 2) + +* On a rising edge on pin *in* when *is-on* is low: It sets *on* until *is-on* becomes high. +* On a rising edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low. + +.... +       ┐     ┌─────xxxxxxxxxxxx┐           ┌─────xxxxxxxxxxxx┐ +in   : └─────┘     xxxxxxxxxxxx└───────────┘     xxxxxxxxxxxx└───── + +       ┐     ┌───────────┐ +on   : └─────┘           └───────────────────────────────────────── + +       ┐                                   ┌───────────┐ +off  : └───────────────────────────────────┘           └─────────── + +       ┐                 ┌─────────────────────────────┐ +is-on: └─────────────────┘                             └─────────── +.... + +"""; + +pin in bit in "momentary button in"; +pin in bit is_on "current state of device"; +pin in unsigned debounce = 2 "debounce delay for 'in'-pin in cycles"; +pin out bit on "turn device on"; +pin out bit off "turn device off"; +variable int debounce_cntr; +variable unsigned debounce_set; +variable int state; + +option period no; +function _; +license "GPL"; +author "David Mueller"; +;; +FUNCTION(_) { + + if (( debounce < 1 ) || ( debounce > 10000 )) { + debounce_set = 2; /* set a sane value */ + } else { + debounce_set = debounce; + } + + if (in && state == 0 ) { /* input has changed from debounced 0 -> 1 */ + debounce_cntr++; + if ( debounce_cntr >= (int)debounce_set ) { + if (!is_on) { /* turn ON if it's off */ + on=1; + off=0; + } else { /* turn OFF if it's on */ + on=0; + off=1; + } + state = 1; + debounce_cntr = 0; + } + } else if (!in && state == 1) { /* input has changed from debounced 1 -> 0 */ + debounce_cntr++; + if ( debounce_cntr >= (int)debounce_set ) { + state = 0; + debounce_cntr = 0; + } + } else if ((!is_on && off) || (is_on && on)) { /* reset outputs once device has switched*/ + on = 0; + off = 0; + debounce_cntr = 0; + } else { + debounce_cntr = 0; + } +} diff --git a/src/hal/components/toggle2nist.comp b/src/hal/components/toggle2nist.comp index df002e2bf36..02d9ea776c7 100644 --- a/src/hal/components/toggle2nist.comp +++ b/src/hal/components/toggle2nist.comp @@ -2,17 +2,17 @@ component toggle2nist "toggle button to nist logic"; description """ -Toggle2nist can be used with a momentary push button +Toggle2nist can be used with a latching push button to control a device that has separate on and off inputs and an is-on output. A debounce delay in cycles can be set for 'in'. (default = 2) * On a rising edge on pin *in* when *is-on* is low: It sets *on* until *is-on* becomes high. -* On a rising edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low. +* On a falling edge on pin *in* when *is-on* is high: It sets *off* until *is-on* becomes low. .... -       ┐     ┌─────xxxxxxxxxxxx┐           ┌─────xxxxxxxxxxxx┐ -in   : └─────┘     xxxxxxxxxxxx└───────────┘     xxxxxxxxxxxx└───── +       ┐     ┌─────────────────────────────┐ +in   : └─────┘                             └───────────────────────        ┐     ┌───────────┐ on   : └─────┘           └───────────────────────────────────────── @@ -26,7 +26,7 @@ is-on: └─────────────────┘        """; -pin in bit in "momentary button in"; +pin in bit in "toggle button in"; pin in bit is_on "current state of device"; pin in unsigned debounce = 2 "debounce delay for 'in'-pin in cycles"; pin out bit on "turn device on"; @@ -38,7 +38,7 @@ variable int state; option period no; function _; license "GPL"; -author "Anders Wallin, David Mueller"; +author "Anders Wallin"; ;; FUNCTION(_) { @@ -54,9 +54,6 @@ FUNCTION(_) { if (!is_on) { /* turn ON if it's off */ on=1; off=0; - } else { /* turn OFF if it's on */ - on=0; - off=1; } state = 1; debounce_cntr = 0; @@ -64,6 +61,10 @@ FUNCTION(_) { } else if (!in && state == 1) { /* input has changed from debounced 1 -> 0 */ debounce_cntr++; if ( debounce_cntr >= (int)debounce_set ) { + if (is_on) { /* turn OFF if it's on */ + on=0; + off=1; + } state = 0; debounce_cntr = 0; }