mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-15 11:50:37 +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;
|
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)
|
#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_G 1
|
||||||
#define LED_G_COLOR_OFF 0
|
#define LED_G_COLOR_OFF 0
|
||||||
|
|
||||||
|
|
||||||
#define LED(ch, color) \
|
#define LED(ch, color) \
|
||||||
do { \
|
do { \
|
||||||
LED_##ch##_R = LED_R_COLOR_##color; \
|
LED_##ch##_R = LED_R_COLOR_##color; \
|
||||||
LED_##ch##_G = LED_G_COLOR_##color; \
|
LED_##ch##_G = LED_G_COLOR_##color; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TURN(ch, on) \
|
|
||||||
do { \
|
/* ----- I/O setup --------------------------------------------------------- */
|
||||||
CH##ch##_RELAY = on; \
|
|
||||||
CH##ch##_OPT = !on; \
|
|
||||||
if (on) \
|
|
||||||
LED(CH##ch, R); \
|
|
||||||
else \
|
|
||||||
LED(CH##ch, G); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
static void init_io(void)
|
static void init_io(void)
|
||||||
@ -78,11 +125,15 @@ static void init_io(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- Main loop --------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
int debounce_main = 0, last_main = 0, but_main = 0;
|
int prebounce_main = 0, postbounce_main = 0;
|
||||||
int debounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
|
int last_main = 0, but_main = 0;
|
||||||
int debounce_ch2 = 0, last_ch2 = 0, but_ch2 = 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();
|
init_io();
|
||||||
|
|
||||||
usb_init();
|
usb_init();
|
||||||
@ -93,34 +144,15 @@ void main(void)
|
|||||||
TURN(2, 0);
|
TURN(2, 0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (debounce_main)
|
DEBOUNCE(MAIN, main);
|
||||||
debounce_main--;
|
DEBOUNCE(CH1, ch1);
|
||||||
else {
|
DEBOUNCE(CH2, ch2);
|
||||||
last_main = but_main;
|
|
||||||
but_main = !BUT_MAIN;
|
|
||||||
if (last_main != but_main)
|
|
||||||
debounce_main = DEBOUNCE_CYCLES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debounce_ch1)
|
/*
|
||||||
debounce_ch1--;
|
* Pressing MAIN forces local mode. Pressing it in local mode,
|
||||||
else {
|
* it turns off both front channels.
|
||||||
last_ch1 = but_ch1;
|
*/
|
||||||
but_ch1 = !BUT_CH1;
|
if (PRESSED(main)) {
|
||||||
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) {
|
|
||||||
if (local) {
|
if (local) {
|
||||||
TURN(1, 0);
|
TURN(1, 0);
|
||||||
TURN(2, 0);
|
TURN(2, 0);
|
||||||
@ -128,6 +160,9 @@ void main(void)
|
|||||||
local = 1;
|
local = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update LEDs in local mode.
|
||||||
|
*/
|
||||||
if (local) {
|
if (local) {
|
||||||
LED(MAIN, G);
|
LED(MAIN, G);
|
||||||
if (IS_ON(1))
|
if (IS_ON(1))
|
||||||
@ -140,10 +175,14 @@ void main(void)
|
|||||||
TURN(2, 0);
|
TURN(2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In local mode, buttons CH1 and CH2 toggle the respective
|
||||||
|
* channel.
|
||||||
|
*/
|
||||||
if (local) {
|
if (local) {
|
||||||
if (but_ch1 && !last_ch1)
|
if (PRESSED(ch1))
|
||||||
TURN(1, !IS_ON(1));
|
TURN(1, !IS_ON(1));
|
||||||
if (but_ch2 && !last_ch2)
|
if (PRESSED(ch2))
|
||||||
TURN(2, !IS_ON(2));
|
TURN(2, !IS_ON(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user