mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-12-18 13:39:42 +02:00
labsw/fw/labsw.c: improved debouncing and cleaned up button logic
This commit is contained in:
parent
165d799b17
commit
a400f9a018
123
labsw/fw/labsw.c
123
labsw/fw/labsw.c
@ -24,7 +24,60 @@
|
||||
int local = 1;
|
||||
|
||||
|
||||
#define DEBOUNCE_CYCLES 10
|
||||
/*
|
||||
* SDCC complains a lot about code that's unreachable due to constant
|
||||
* conditional expressions.
|
||||
*/
|
||||
|
||||
#pragma disable_warning 126 /* unreachable code */
|
||||
|
||||
|
||||
/* ----- Button debouncing ------------------------------------------------- */
|
||||
|
||||
|
||||
/* In the version of 2011-09-11, 10000 cycles are about 128 ms */
|
||||
|
||||
#define PREBOUNCE_CYCLES 2000
|
||||
#define POSTBOUNCE_CYCLES 5000
|
||||
|
||||
|
||||
#define TURN(ch, on) \
|
||||
do { \
|
||||
CH##ch##_RELAY = on; \
|
||||
CH##ch##_OPT = !on; \
|
||||
if (on) \
|
||||
LED(CH##ch, R); \
|
||||
else \
|
||||
LED(CH##ch, G); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DEBOUNCE(BUT, but) \
|
||||
do { \
|
||||
last_##but = but_##but; \
|
||||
if (postbounce_##but) { \
|
||||
postbounce_##but--; \
|
||||
break; \
|
||||
} \
|
||||
if (but_##but == !BUT_##BUT) { \
|
||||
prebounce_##but = 0; \
|
||||
break; \
|
||||
} \
|
||||
if (prebounce_##but != PREBOUNCE_CYCLES) { \
|
||||
prebounce_##but++; \
|
||||
break; \
|
||||
} \
|
||||
prebounce_##but = 0; \
|
||||
postbounce_##but = POSTBOUNCE_CYCLES; \
|
||||
but_##but = !but_##but; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define PRESSED(but) (but_##but && !last_##but)
|
||||
#define RELEASED(but) (!but_##but && last_##but)
|
||||
|
||||
|
||||
/* ----- LED and channel control ------------------------------------------- */
|
||||
|
||||
|
||||
#define IS_ON(ch) (CH##ch##_RELAY || !CH##ch##_OPT)
|
||||
@ -36,21 +89,15 @@ int local = 1;
|
||||
#define LED_G_COLOR_G 1
|
||||
#define LED_G_COLOR_OFF 0
|
||||
|
||||
|
||||
#define LED(ch, color) \
|
||||
do { \
|
||||
LED_##ch##_R = LED_R_COLOR_##color; \
|
||||
LED_##ch##_G = LED_G_COLOR_##color; \
|
||||
} while (0)
|
||||
|
||||
#define TURN(ch, on) \
|
||||
do { \
|
||||
CH##ch##_RELAY = on; \
|
||||
CH##ch##_OPT = !on; \
|
||||
if (on) \
|
||||
LED(CH##ch, R); \
|
||||
else \
|
||||
LED(CH##ch, G); \
|
||||
} while (0)
|
||||
|
||||
/* ----- I/O setup --------------------------------------------------------- */
|
||||
|
||||
|
||||
static void init_io(void)
|
||||
@ -78,11 +125,15 @@ static void init_io(void)
|
||||
}
|
||||
|
||||
|
||||
/* ----- Main loop --------------------------------------------------------- */
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int debounce_main = 0, last_main = 0, but_main = 0;
|
||||
int debounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
|
||||
int debounce_ch2 = 0, last_ch2 = 0, but_ch2 = 0;
|
||||
int prebounce_main = 0, postbounce_main = 0;
|
||||
int last_main = 0, but_main = 0;
|
||||
int prebounce_ch1 = 0, postbounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
|
||||
int prebounce_ch2 = 0, postbounce_ch2 = 0, last_ch2 = 0, but_ch2 = 0;
|
||||
init_io();
|
||||
|
||||
usb_init();
|
||||
@ -93,34 +144,15 @@ void main(void)
|
||||
TURN(2, 0);
|
||||
|
||||
while (1) {
|
||||
if (debounce_main)
|
||||
debounce_main--;
|
||||
else {
|
||||
last_main = but_main;
|
||||
but_main = !BUT_MAIN;
|
||||
if (last_main != but_main)
|
||||
debounce_main = DEBOUNCE_CYCLES;
|
||||
}
|
||||
DEBOUNCE(MAIN, main);
|
||||
DEBOUNCE(CH1, ch1);
|
||||
DEBOUNCE(CH2, ch2);
|
||||
|
||||
if (debounce_ch1)
|
||||
debounce_ch1--;
|
||||
else {
|
||||
last_ch1 = but_ch1;
|
||||
but_ch1 = !BUT_CH1;
|
||||
if (last_ch1 != but_ch1)
|
||||
debounce_ch1 = DEBOUNCE_CYCLES;
|
||||
}
|
||||
|
||||
if (debounce_ch2)
|
||||
debounce_ch2--;
|
||||
else {
|
||||
last_ch2 = but_ch2;
|
||||
but_ch2 = !BUT_CH2;
|
||||
if (last_ch2 != but_ch2)
|
||||
debounce_ch2 = DEBOUNCE_CYCLES;
|
||||
}
|
||||
|
||||
if (but_main && !last_main) {
|
||||
/*
|
||||
* Pressing MAIN forces local mode. Pressing it in local mode,
|
||||
* it turns off both front channels.
|
||||
*/
|
||||
if (PRESSED(main)) {
|
||||
if (local) {
|
||||
TURN(1, 0);
|
||||
TURN(2, 0);
|
||||
@ -128,6 +160,9 @@ void main(void)
|
||||
local = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update LEDs in local mode.
|
||||
*/
|
||||
if (local) {
|
||||
LED(MAIN, G);
|
||||
if (IS_ON(1))
|
||||
@ -140,10 +175,14 @@ void main(void)
|
||||
TURN(2, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* In local mode, buttons CH1 and CH2 toggle the respective
|
||||
* channel.
|
||||
*/
|
||||
if (local) {
|
||||
if (but_ch1 && !last_ch1)
|
||||
if (PRESSED(ch1))
|
||||
TURN(1, !IS_ON(1));
|
||||
if (but_ch2 && !last_ch2)
|
||||
if (PRESSED(ch2))
|
||||
TURN(2, !IS_ON(2));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user