1 /******************************************************************************
3 * Trennfix firmware - main.c
5 * Copyright (C) 2017 Philipp Hachtmann
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *****************************************************************************/
27 #include <avr/eeprom.h>
28 #include <avr/interrupt.h>
29 #include <avr/pgmspace.h>
31 #include <util/delay.h>
34 #include "mm_switch.h"
37 // #define DEBUG_TIMEOUT
39 #define MON_TIMEOUT(val) setpin(DRIVE, val)
41 #define MON_TIMEOUT(xx) ({0;})
47 OM_MOMENTARY
, /* on as long as "key on" pressed */
48 OM_DOUBLE
, /* On off with "on" and "off" keys */
49 OM_TOGGLE
, /* toggle on "key on" pressed */
50 OM_ERASED
= 0xff /* EEPROM erased, need setup */
55 LM_LEARN_ON_KEY
, /* Learn primary key */
56 LM_LEARN_OFF_KEY
, /* Learn secondary key, relevant for OM_DOUBLE */
57 LM_LEARN_INITIAL
, /* Learn initial pulse length, 10ms steps */
58 LM_LEARN_DUTY
, /* Learn duty cycle 0-10 */
59 LM_LEARN_OP_MODE
, /* Learn operation mode */
60 LM_END
, /* Only a label */
64 uint8_t magic
; /* Magic value */
70 uint8_t initial_pulse
; /* Lenghth of initial pulse in 10ms steps */
71 uint8_t on_duty_cycle
; /* Duty cycle for on. 0-10 */
74 static struct EEMEM config ee_config
;
75 static struct config config
;
76 static volatile enum learn_mode learn_mode
= LM_LEARN_ON_KEY
;
78 static void load_config(void)
80 eeprom_read_block(&config
, &ee_config
, sizeof(config
));
83 static void save_config(void)
85 eeprom_write_block(&config
, &ee_config
, sizeof(config
));
88 static volatile uint8_t drive_on
= 0;
92 static uint8_t btn_last
= 0;
93 mm_pinchange_handler();
95 if (BTN_PRESSED
&& !btn_last
) {
99 btn_last
= BTN_PRESSED
;
102 void mm_switch_command(uint8_t decoder
, uint8_t command
)
104 static uint8_t toggle_lock
= 0;
109 if ((decoder
== config
.decoder_on
) &&
110 (command
== config
.key_on
)) { /* Primary key pressed */
111 switch(config
.op_mode
) {
118 drive_on
= !drive_on
;
127 if ((decoder
== config
.decoder_on
) &&
128 (command
== 0)) { /* Primary key released */
129 switch(config
.op_mode
) {
141 if ((decoder
== config
.decoder_off
) &&
142 (command
== config
.key_off
)) { /* Secondary "off" key pressed */
143 switch(config
.op_mode
) {
156 case LM_LEARN_ON_KEY
:
158 config
.decoder_on
= decoder
;
159 config
.key_on
= command
;
161 if (config
.op_mode
== OM_DOUBLE
)
162 learn_mode
= LM_LEARN_OFF_KEY
;
168 case LM_LEARN_OFF_KEY
:
170 config
.decoder_off
= decoder
;
171 config
.key_off
= command
;
177 case LM_LEARN_INITIAL
:
185 if (config
.initial_pulse
>= 10)
186 config
.initial_pulse
-= 10;
188 config
.initial_pulse
= 0;
193 if (config
.initial_pulse
<= 245)
194 config
.initial_pulse
+= 10;
196 config
.initial_pulse
= 255;
213 if (config
.on_duty_cycle
> 0)
214 config
.on_duty_cycle
-= 1;
219 if (config
.on_duty_cycle
< 10)
220 config
.on_duty_cycle
+= 1;
230 case LM_LEARN_OP_MODE
:
233 config
.op_mode
= OM_MOMENTARY
;
238 config
.op_mode
= OM_DOUBLE
;
243 config
.op_mode
= OM_TOGGLE
;
256 /******************************************************************************
258 * main() - The main routine
263 uint8_t learn_mode_off
;
264 uint8_t drive_last
= 0;
265 uint8_t drive_slope
= 0;
271 if (config
.op_mode
== OM_ERASED
|| config
.magic
!= EE_MAGIC
) {
272 config
.magic
= EE_MAGIC
;
273 config
.op_mode
= OM_MOMENTARY
;
274 // config.decoder_on = 1;
275 // config.key_on = 1;
276 config
.decoder_off
= 1;
278 config
.initial_pulse
= 10;
279 config
.on_duty_cycle
= 5;
280 learn_mode
= LM_LEARN_ON_KEY
;
289 if (!drive_last
&& drive_on
)
293 drive_last
= drive_on
;
297 for (i
= 0; i
< config
.initial_pulse
; i
++) {
298 setpin(PIN_DRIVE
, 1);
303 for (i
= 0; i
< config
.on_duty_cycle
; i
++) {
304 setpin(PIN_DRIVE
, drive_on
);
308 for (i
= 0; i
< (10 - config
.on_duty_cycle
); i
++) {
309 setpin(PIN_DRIVE
, 0);
317 learn_mode_off
= !learn_mode
;
319 //if (drive_on || (learn_mode && learn_mode_off))
322 for (i
= 0; i
< learn_mode
; i
++) {
328 //if (drive_on || (learn_mode && learn_mode_off))
330 //if (drive_on || (learn_mode && learn_mode_off))
333 for (i
= 0; i
< 15 - learn_mode
; i
++) {
334 //if (drive_on || (learn_mode && learn_mode_off))
338 //if (drive_on || (learn_mode && learn_mode_off))
348 /******************************************************************************