Date:2011-09-11 18:03:20 (7 years 11 months ago)
Author:Werner Almesberger
Commit:a400f9a0183af4ddf565a2acb2b08d9418749224
Message:labsw/fw/labsw.c: improved debouncing and cleaned up button logic

Files: labsw/fw/labsw.c (6 diffs)

Change Details

labsw/fw/labsw.c
2424int local = 1;
2525
2626
27#define DEBOUNCE_CYCLES 10
27/*
28 * SDCC complains a lot about code that's unreachable due to constant
29 * conditional expressions.
30 */
31
32#pragma disable_warning 126 /* unreachable code */
33
34
35/* ----- Button debouncing ------------------------------------------------- */
36
37
38/* In the version of 2011-09-11, 10000 cycles are about 128 ms */
39
40#define PREBOUNCE_CYCLES 2000
41#define POSTBOUNCE_CYCLES 5000
42
43
44#define TURN(ch, on) \
45    do { \
46        CH##ch##_RELAY = on; \
47        CH##ch##_OPT = !on; \
48        if (on) \
49            LED(CH##ch, R); \
50        else \
51            LED(CH##ch, G); \
52    } while (0)
53
54
55#define DEBOUNCE(BUT, but) \
56    do { \
57        last_##but = but_##but; \
58        if (postbounce_##but) { \
59            postbounce_##but--; \
60            break; \
61        } \
62        if (but_##but == !BUT_##BUT) { \
63            prebounce_##but = 0; \
64            break; \
65        } \
66        if (prebounce_##but != PREBOUNCE_CYCLES) { \
67            prebounce_##but++; \
68            break; \
69        } \
70        prebounce_##but = 0; \
71        postbounce_##but = POSTBOUNCE_CYCLES; \
72        but_##but = !but_##but; \
73    } while (0)
74
75
76#define PRESSED(but) (but_##but && !last_##but)
77#define RELEASED(but) (!but_##but && last_##but)
78
79
80/* ----- LED and channel control ------------------------------------------- */
2881
2982
3083#define IS_ON(ch) (CH##ch##_RELAY || !CH##ch##_OPT)
...... 
3689#define LED_G_COLOR_G 1
3790#define LED_G_COLOR_OFF 0
3891
92
3993#define LED(ch, color) \
4094    do { \
4195        LED_##ch##_R = LED_R_COLOR_##color; \
4296        LED_##ch##_G = LED_G_COLOR_##color; \
4397    } while (0)
4498
45#define TURN(ch, on) \
46    do { \
47        CH##ch##_RELAY = on; \
48        CH##ch##_OPT = !on; \
49        if (on) \
50            LED(CH##ch, R); \
51        else \
52            LED(CH##ch, G); \
53    } while (0)
99
100/* ----- I/O setup --------------------------------------------------------- */
54101
55102
56103static void init_io(void)
...... 
78125}
79126
80127
128/* ----- Main loop --------------------------------------------------------- */
129
130
81131void main(void)
82132{
83    int debounce_main = 0, last_main = 0, but_main = 0;
84    int debounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
85    int debounce_ch2 = 0, last_ch2 = 0, but_ch2 = 0;
133    int prebounce_main = 0, postbounce_main = 0;
134    int last_main = 0, but_main = 0;
135    int prebounce_ch1 = 0, postbounce_ch1 = 0, last_ch1 = 0, but_ch1 = 0;
136    int prebounce_ch2 = 0, postbounce_ch2 = 0, last_ch2 = 0, but_ch2 = 0;
86137    init_io();
87138
88139    usb_init();
...... 
93144    TURN(2, 0);
94145
95146    while (1) {
96        if (debounce_main)
97            debounce_main--;
98        else {
99            last_main = but_main;
100            but_main = !BUT_MAIN;
101            if (last_main != but_main)
102                debounce_main = DEBOUNCE_CYCLES;
103        }
104
105        if (debounce_ch1)
106            debounce_ch1--;
107        else {
108            last_ch1 = but_ch1;
109            but_ch1 = !BUT_CH1;
110            if (last_ch1 != but_ch1)
111                debounce_ch1 = DEBOUNCE_CYCLES;
112        }
113
114        if (debounce_ch2)
115            debounce_ch2--;
116        else {
117            last_ch2 = but_ch2;
118            but_ch2 = !BUT_CH2;
119            if (last_ch2 != but_ch2)
120                debounce_ch2 = DEBOUNCE_CYCLES;
121        }
122
123        if (but_main && !last_main) {
147        DEBOUNCE(MAIN, main);
148        DEBOUNCE(CH1, ch1);
149        DEBOUNCE(CH2, ch2);
150
151        /*
152         * Pressing MAIN forces local mode. Pressing it in local mode,
153         * it turns off both front channels.
154         */
155        if (PRESSED(main)) {
124156            if (local) {
125157                TURN(1, 0);
126158                TURN(2, 0);
...... 
128160            local = 1;
129161        }
130162
163        /*
164         * Update LEDs in local mode.
165         */
131166        if (local) {
132167            LED(MAIN, G);
133168            if (IS_ON(1))
...... 
140175                TURN(2, 0);
141176        }
142177
178        /*
179         * In local mode, buttons CH1 and CH2 toggle the respective
180         * channel.
181         */
143182        if (local) {
144            if (but_ch1 && !last_ch1)
183            if (PRESSED(ch1))
145184                TURN(1, !IS_ON(1));
146            if (but_ch2 && !last_ch2)
185            if (PRESSED(ch2))
147186                TURN(2, !IS_ON(2));
148187        }
149188

Archive Download the corresponding diff file

Branches:
master



interactive