New non-working skeleton for apps
This commit is contained in:
parent
a264f05e07
commit
0002eb48e7
|
@ -11,10 +11,10 @@ FUSES = lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0x01:m
|
|||
SRC=$(wildcard lib/*.c apps/*.c *.c)
|
||||
OBJECTS= $(SRC:.c=.o)
|
||||
LSTFILES= $(SRC:.c=.lst)
|
||||
HEADERS=$(wildcard lib/*.h *.h)
|
||||
HEADERS=$(wildcard */*/*.h */*.h *.h)
|
||||
|
||||
# Compiler Options
|
||||
GCFLAGS = -ffreestanding -std=gnu99 -mmcu=$(MCU) $(OPTIMIZATION) -Wl,-gc-sections -nostdlib -I.
|
||||
GCFLAGS = -ffreestanding -std=gnu99 -mmcu=$(MCU) $(OPTIMIZATION) -Wl,-gc-sections -nostdlib -I. -Iinclude
|
||||
# Warnings
|
||||
GCFLAGS += -Wstrict-prototypes -Wundef -Wall -Wextra -Wunreachable-code
|
||||
# Optimizazions
|
||||
|
|
31
firmware/apps/blinker.c
Normal file
31
firmware/apps/blinker.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||
#include <util/delay.h>
|
||||
|
||||
#include <pentabug/app.h>
|
||||
#include <pentabug/lifecycle.h>
|
||||
|
||||
static void init(void) {
|
||||
PIND |= 1 << 4;
|
||||
DDRD |= 1 << 4;
|
||||
|
||||
_delay_ms(2000);
|
||||
}
|
||||
|
||||
static void blinker(void) {
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < 5; ++i) {
|
||||
PORTD |= 1 << 4;
|
||||
_delay_ms(800);
|
||||
|
||||
PORTD &= ~(1 << 4);
|
||||
_delay_ms(200);
|
||||
}
|
||||
|
||||
stop_app();
|
||||
}
|
||||
|
||||
REGISTER(blinker, init, NULL);
|
24
firmware/include/pentabug/app.h
Normal file
24
firmware/include/pentabug/app.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef APP_H
|
||||
#define APP_H
|
||||
|
||||
#define MAX_APPS 8
|
||||
|
||||
#define REG(run) REGISTER(run, NULL, NULL);
|
||||
#define REGISTER(_run, _init, _cleanup) static void __init(void) __attribute__ ((naked, used, section (".init8"))); \
|
||||
void __init(void) { \
|
||||
uint8_t i = 0; \
|
||||
while(apps[i].run) ++i; \
|
||||
apps[i].run = _run; \
|
||||
apps[i].init = _init; \
|
||||
apps[i].cleanup = _cleanup; \
|
||||
}
|
||||
|
||||
struct app_t {
|
||||
void (*run)(void);
|
||||
void (*init)(void);
|
||||
void (*cleanup)(void);
|
||||
};
|
||||
|
||||
extern struct app_t apps[MAX_APPS];
|
||||
|
||||
#endif /* APP_H */
|
34
firmware/include/pentabug/lifecycle.h
Normal file
34
firmware/include/pentabug/lifecycle.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef LIFECYCLE_H
|
||||
#define LIFECYCLE_H
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern jmp_buf app_jmp_buf;
|
||||
extern uint8_t should_stop;
|
||||
|
||||
// initialize lifecycle, stopped if return != 0
|
||||
inline static int enter_app(void) {
|
||||
should_stop = 0;
|
||||
return setjmp(app_jmp_buf);
|
||||
}
|
||||
|
||||
// stop the running app
|
||||
inline static void stop_app(void) {
|
||||
longjmp(app_jmp_buf, 1);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
// request to stop the app later
|
||||
inline static void request_stop_app(void) {
|
||||
should_stop = 1;
|
||||
}
|
||||
|
||||
// stop app if previously requested
|
||||
inline static void test_stop_app(void) {
|
||||
if(should_stop) {
|
||||
stop_app();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LIFECYCLE_H */
|
3
firmware/lib/app.c
Normal file
3
firmware/lib/app.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include <pentabug/app.h>
|
||||
|
||||
struct app_t apps[MAX_APPS];
|
4
firmware/lib/lifecycle.c
Normal file
4
firmware/lib/lifecycle.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include <pentabug/lifecycle.h>
|
||||
|
||||
jmp_buf app_jmp_buf;
|
||||
uint8_t should_stop;
|
220
firmware/main.c
220
firmware/main.c
|
@ -1,172 +1,78 @@
|
|||
#include <inttypes.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||
#include <util/delay.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
#include <avr/io.h>
|
||||
|
||||
#define ever (;;) /* awesomnes++ */
|
||||
#include <pentabug/app.h>
|
||||
#include <pentabug/lifecycle.h>
|
||||
|
||||
#include "lib/usart.h"
|
||||
#include "lib/bughal.h"
|
||||
#include "lib/util.h"
|
||||
#include "lib/music.h"
|
||||
static inline void reset_hw(void) {
|
||||
DDRB = 0;
|
||||
DDRC = 0;
|
||||
DDRD = 0;
|
||||
|
||||
#include "lib/apps.h"
|
||||
PORTB = 0;
|
||||
PORTC = 0;
|
||||
PORTD = 0;
|
||||
|
||||
mode_fun mode_funs[MAX_FUNS] = { NULL };
|
||||
uint8_t mode_num = 0;
|
||||
PINB = 0;
|
||||
PINC = 0;
|
||||
PIND = 0;
|
||||
}
|
||||
|
||||
/*specialmodes, not in normal mode loop*/
|
||||
#define MODE_PWDN mode_num //go to sleep
|
||||
|
||||
uint8_t OpMode = 0;
|
||||
uint8_t NextMode = 0;
|
||||
|
||||
uint8_t mode_uninitialized = true;
|
||||
uint8_t mode_last_tick = false;
|
||||
|
||||
/*check if mode should be changed (one of the buttons long pressed)*/
|
||||
void modeswitch_poll(void)
|
||||
{
|
||||
if (btn_state(BTNST_LUP, BTN_LEFT)) {
|
||||
//opmode --
|
||||
NextMode = OpMode <= 0 ? mode_num - 1 : OpMode - 1;
|
||||
button_clear(BTN_LEFT);
|
||||
}
|
||||
if (btn_state(BTNST_LUP, BTN_RIGHT)) {
|
||||
//opmode ++
|
||||
NextMode = (OpMode +1) % mode_num;
|
||||
button_clear(BTN_RIGHT);
|
||||
}
|
||||
if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
|
||||
btn_state(BTNST_LDN, BTN_LEFT) ) {
|
||||
NextMode = MODE_PWDN;
|
||||
static inline void run_app(struct app_t* app) {
|
||||
if(enter_app()) {
|
||||
// this is the exit
|
||||
if(app->cleanup) {
|
||||
app->cleanup();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void do_powerDown(void)
|
||||
{
|
||||
static timer_t mytimer;
|
||||
static uint8_t pwdn_state;
|
||||
static bool ledRon;
|
||||
uint8_t oldreg;
|
||||
if (mode_uninitialized) {
|
||||
mode_uninitialized = false;
|
||||
pwdn_state = 0;
|
||||
timer_set(&mytimer, 5);
|
||||
set_motor(MOTOR_OFF);
|
||||
ledRon = true;
|
||||
};
|
||||
if (timer_expired(&mytimer)) {
|
||||
switch (pwdn_state) {
|
||||
case 0:
|
||||
if (ledRon) {
|
||||
led_on(LED_L);
|
||||
led_off(LED_R);
|
||||
} else {
|
||||
led_off(LED_L);
|
||||
led_on(LED_R);
|
||||
};
|
||||
ledRon = !ledRon;
|
||||
timer_set(&mytimer, 6);
|
||||
if ((btn_state(BTNST_SUP, BTN_RIGHT)
|
||||
|| btn_state(BTNST_LUP, BTN_RIGHT))
|
||||
&& (btn_state(BTNST_SUP, BTN_LEFT)
|
||||
|| btn_state(BTNST_LUP, BTN_LEFT))) {
|
||||
//both buttons released
|
||||
led_off(LED_L | LED_R);
|
||||
pwdn_state = 1;
|
||||
timer_set(&mytimer, 10);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
music_setNote(NOTE_A, 4);
|
||||
timer_set(&mytimer, 10);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 2:
|
||||
music_setNote(NOTE_F, 4);
|
||||
timer_set(&mytimer, 5);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 3:
|
||||
music_setNote(NOTE_D, 3);
|
||||
timer_set(&mytimer, 15);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 4:
|
||||
music_setNote(NOTE_PAUSE, 4);
|
||||
timer_set(&mytimer, 1);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 5: //now we can really power down
|
||||
// lets switch everything off
|
||||
oldreg = PCMSK2;
|
||||
PCIFR = 0;
|
||||
PCICR |= (1<<PCIE2);
|
||||
PCMSK2 |= 3; //PCINT16 PCINT17
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sei();
|
||||
sleep_cpu();
|
||||
PCICR &= ~(1<<PCIE2);
|
||||
sleep_disable();
|
||||
PCMSK2 = oldreg;
|
||||
NextMode = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
} //end switch
|
||||
|
||||
} //end timer expired
|
||||
} // end do_powerDown
|
||||
|
||||
|
||||
ISR(PCINT2_vect){ ; }
|
||||
|
||||
|
||||
void __attribute__ ((noreturn)) main(void)
|
||||
{
|
||||
/* hardware initialisation: */
|
||||
init_leds();
|
||||
init_buzzr();
|
||||
init_switch();
|
||||
USART0_Init();
|
||||
init_motor();
|
||||
/* software initialisation */
|
||||
timer_init();
|
||||
music_init();
|
||||
|
||||
/* here the show begins: */
|
||||
sei();
|
||||
for ever {
|
||||
//main polling loop;
|
||||
button_poll();
|
||||
|
||||
if(OpMode < mode_num) {
|
||||
modeswitch_poll();
|
||||
}
|
||||
|
||||
if (OpMode != NextMode){
|
||||
mode_last_tick = true;
|
||||
if(app->init) {
|
||||
app->init();
|
||||
}
|
||||
|
||||
if(OpMode < mode_num) {
|
||||
mode_funs[OpMode]();
|
||||
} else {
|
||||
do_powerDown();
|
||||
}
|
||||
|
||||
if (OpMode != NextMode){
|
||||
mode_last_tick = false;
|
||||
mode_uninitialized = true;
|
||||
OpMode = NextMode;
|
||||
}
|
||||
for(;;) {
|
||||
app->run();
|
||||
test_stop_app();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint8_t app_index = 0;
|
||||
int8_t direction = 1;
|
||||
|
||||
// we need to get real fast (8MHz) to handle 38kHz IR frequency ...
|
||||
|
||||
CLKPR = 0b10000000;
|
||||
CLKPR = 0b00000000;
|
||||
|
||||
// cycle through apps
|
||||
|
||||
for(;;) {
|
||||
reset_hw();
|
||||
|
||||
run_app(&apps[app_index]);
|
||||
|
||||
for(;;);
|
||||
|
||||
if(direction > 0) {
|
||||
app_index++;
|
||||
|
||||
if(apps[app_index].run == NULL) {
|
||||
app_index = 0;
|
||||
}
|
||||
} else {
|
||||
if(app_index == 0) {
|
||||
app_index = MAX_APPS - 1;
|
||||
while(apps[app_index].run == NULL) --app_index;
|
||||
} else {
|
||||
app_index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
79
old_firmware/Makefile
Normal file
79
old_firmware/Makefile
Normal file
|
@ -0,0 +1,79 @@
|
|||
PROJECT=pentabug
|
||||
|
||||
OPTIMIZATION = -Os
|
||||
MCU = atmega88pa
|
||||
F_CPU = 8000000
|
||||
QUARZ = 8MHZ
|
||||
FUSES = lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0x01:m
|
||||
|
||||
#########################################################################
|
||||
|
||||
SRC=$(wildcard lib/*.c apps/*.c *.c)
|
||||
OBJECTS= $(SRC:.c=.o)
|
||||
LSTFILES= $(SRC:.c=.lst)
|
||||
HEADERS=$(wildcard lib/*.h *.h)
|
||||
|
||||
# Compiler Options
|
||||
GCFLAGS = -ffreestanding -std=gnu99 -mmcu=$(MCU) $(OPTIMIZATION) -Wl,-gc-sections -nostdlib -I.
|
||||
# Warnings
|
||||
GCFLAGS += -Wstrict-prototypes -Wundef -Wall -Wextra -Wunreachable-code
|
||||
# Optimizazions
|
||||
GCFLAGS += -fsingle-precision-constant -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -fno-builtin -ffunction-sections -fno-common -fdata-sections
|
||||
# Debug stuff
|
||||
GCFLAGS += -Wa,-adhlns=$(<:.c=.lst),-gstabs -g
|
||||
|
||||
GCFLAGS += -DF_CPU=$(F_CPU) -DQUARZ=$(QUARZ)
|
||||
|
||||
LDFLAGS = -mmcu=$(MCU) $(OPTIMIZATION) -gc-sections
|
||||
|
||||
|
||||
# Paths
|
||||
GCC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
REMOVE = rm -f
|
||||
SIZE = avr-size
|
||||
AVRDUDE = avrdude
|
||||
|
||||
#########################################################################
|
||||
|
||||
all: $(PROJECT).hex Makefile
|
||||
@$(SIZE) --mcu=$(MCU) --format=avr $(PROJECT).elf
|
||||
|
||||
$(PROJECT).hex: $(PROJECT).elf Makefile
|
||||
@echo " \033[1;34mOBJCOPY\033[0m $(PROJECT).elf -> $(PROJECT).hex"
|
||||
@$(OBJCOPY) -O ihex -R .eeprom $(PROJECT).elf $(PROJECT).hex
|
||||
|
||||
$(PROJECT).elf: $(OBJECTS) Makefile
|
||||
@echo " \033[1;34mLink \033[0m (\033[1;33m $(OBJECTS)\033[0m) -> $(PROJECT).elf"
|
||||
@$(GCC) $(OBJECTS) $(LDFLAGS) -o $(PROJECT).elf
|
||||
|
||||
clean:
|
||||
$(REMOVE) $(OBJECTS)
|
||||
$(REMOVE) $(LSTFILES)
|
||||
$(REMOVE) $(PROJECT).hex
|
||||
$(REMOVE) $(PROJECT).elf
|
||||
|
||||
#########################################################################
|
||||
|
||||
%.o: %.c Makefile $(HEADERS)
|
||||
@echo " \033[1;34mCompile\033[0m $<"
|
||||
@$(GCC) $(GCFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
#########################################################################
|
||||
|
||||
fuse:
|
||||
$(AVRDUDE) -p m88 -F -c usbtiny -v -v -U $(FUSES)
|
||||
|
||||
flash: $(PROJECT).hex Makefile
|
||||
$(AVRDUDE) -p m88 -F -c usbtiny -B 1 -U flash:w:$(PROJECT).hex
|
||||
|
||||
fljohn: $(PROJECT).hex Makefile
|
||||
$(AVRDUDE) -p m88 -F -P /dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0 -c stk500v2 -v -v -U flash:w:$(PROJECT).hex
|
||||
|
||||
flsmart: $(PROJECT).hex Makefile
|
||||
$(AVRDUDE) -p m88 -F -P /dev/ttyUSB0 -c stk500v2 -v -v -U flash:w:$(PROJECT).hex
|
||||
|
||||
|
||||
.PHONY : clean all fuse flash fljohn
|
||||
|
24
old_firmware/README.md
Normal file
24
old_firmware/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
## Firmware
|
||||
|
||||
This firmware is to be flashed to the atmega88 of the pentabug.
|
||||
The Makefile supports 2 different ways of flashing the firmware image:
|
||||
|
||||
### the serial bootloader way
|
||||
|
||||
With the
|
||||
|
||||
make serflash
|
||||
|
||||
target of the Makefile You can flash the microcontroler via the serial bootloader that is part of the initial firmware.
|
||||
|
||||
|
||||
### the isp way
|
||||
|
||||
With the
|
||||
|
||||
make flash
|
||||
|
||||
target of the Makefile you can flash the microcontroler via an isp programmer.
|
||||
Adjust the avrdude settings to Your programmers needs beforehand.
|
||||
|
||||
|
172
old_firmware/main.c
Normal file
172
old_firmware/main.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include <inttypes.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
#define __DELAY_BACKWARD_COMPATIBLE__
|
||||
#include <util/delay.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define ever (;;) /* awesomnes++ */
|
||||
|
||||
#include "lib/usart.h"
|
||||
#include "lib/bughal.h"
|
||||
#include "lib/util.h"
|
||||
#include "lib/music.h"
|
||||
|
||||
#include "lib/apps.h"
|
||||
|
||||
mode_fun mode_funs[MAX_FUNS] = { NULL };
|
||||
uint8_t mode_num = 0;
|
||||
|
||||
/*specialmodes, not in normal mode loop*/
|
||||
#define MODE_PWDN mode_num //go to sleep
|
||||
|
||||
uint8_t OpMode = 0;
|
||||
uint8_t NextMode = 0;
|
||||
|
||||
uint8_t mode_uninitialized = true;
|
||||
uint8_t mode_last_tick = false;
|
||||
|
||||
/*check if mode should be changed (one of the buttons long pressed)*/
|
||||
void modeswitch_poll(void)
|
||||
{
|
||||
if (btn_state(BTNST_LUP, BTN_LEFT)) {
|
||||
//opmode --
|
||||
NextMode = OpMode <= 0 ? mode_num - 1 : OpMode - 1;
|
||||
button_clear(BTN_LEFT);
|
||||
}
|
||||
if (btn_state(BTNST_LUP, BTN_RIGHT)) {
|
||||
//opmode ++
|
||||
NextMode = (OpMode +1) % mode_num;
|
||||
button_clear(BTN_RIGHT);
|
||||
}
|
||||
if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
|
||||
btn_state(BTNST_LDN, BTN_LEFT) ) {
|
||||
NextMode = MODE_PWDN;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void do_powerDown(void)
|
||||
{
|
||||
static timer_t mytimer;
|
||||
static uint8_t pwdn_state;
|
||||
static bool ledRon;
|
||||
uint8_t oldreg;
|
||||
if (mode_uninitialized) {
|
||||
mode_uninitialized = false;
|
||||
pwdn_state = 0;
|
||||
timer_set(&mytimer, 5);
|
||||
set_motor(MOTOR_OFF);
|
||||
ledRon = true;
|
||||
};
|
||||
if (timer_expired(&mytimer)) {
|
||||
switch (pwdn_state) {
|
||||
case 0:
|
||||
if (ledRon) {
|
||||
led_on(LED_L);
|
||||
led_off(LED_R);
|
||||
} else {
|
||||
led_off(LED_L);
|
||||
led_on(LED_R);
|
||||
};
|
||||
ledRon = !ledRon;
|
||||
timer_set(&mytimer, 6);
|
||||
if ((btn_state(BTNST_SUP, BTN_RIGHT)
|
||||
|| btn_state(BTNST_LUP, BTN_RIGHT))
|
||||
&& (btn_state(BTNST_SUP, BTN_LEFT)
|
||||
|| btn_state(BTNST_LUP, BTN_LEFT))) {
|
||||
//both buttons released
|
||||
led_off(LED_L | LED_R);
|
||||
pwdn_state = 1;
|
||||
timer_set(&mytimer, 10);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
music_setNote(NOTE_A, 4);
|
||||
timer_set(&mytimer, 10);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 2:
|
||||
music_setNote(NOTE_F, 4);
|
||||
timer_set(&mytimer, 5);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 3:
|
||||
music_setNote(NOTE_D, 3);
|
||||
timer_set(&mytimer, 15);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 4:
|
||||
music_setNote(NOTE_PAUSE, 4);
|
||||
timer_set(&mytimer, 1);
|
||||
pwdn_state++;
|
||||
break;
|
||||
case 5: //now we can really power down
|
||||
// lets switch everything off
|
||||
oldreg = PCMSK2;
|
||||
PCIFR = 0;
|
||||
PCICR |= (1<<PCIE2);
|
||||
PCMSK2 |= 3; //PCINT16 PCINT17
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sei();
|
||||
sleep_cpu();
|
||||
PCICR &= ~(1<<PCIE2);
|
||||
sleep_disable();
|
||||
PCMSK2 = oldreg;
|
||||
NextMode = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
} //end switch
|
||||
|
||||
} //end timer expired
|
||||
} // end do_powerDown
|
||||
|
||||
|
||||
ISR(PCINT2_vect){ ; }
|
||||
|
||||
|
||||
void __attribute__ ((noreturn)) main(void)
|
||||
{
|
||||
/* hardware initialisation: */
|
||||
init_leds();
|
||||
init_buzzr();
|
||||
init_switch();
|
||||
USART0_Init();
|
||||
init_motor();
|
||||
/* software initialisation */
|
||||
timer_init();
|
||||
music_init();
|
||||
|
||||
/* here the show begins: */
|
||||
sei();
|
||||
for ever {
|
||||
//main polling loop;
|
||||
button_poll();
|
||||
|
||||
if(OpMode < mode_num) {
|
||||
modeswitch_poll();
|
||||
}
|
||||
|
||||
if (OpMode != NextMode){
|
||||
mode_last_tick = true;
|
||||
}
|
||||
|
||||
if(OpMode < mode_num) {
|
||||
mode_funs[OpMode]();
|
||||
} else {
|
||||
do_powerDown();
|
||||
}
|
||||
|
||||
if (OpMode != NextMode){
|
||||
mode_last_tick = false;
|
||||
mode_uninitialized = true;
|
||||
OpMode = NextMode;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user