New non-working skeleton for apps

This commit is contained in:
Thammi 2013-08-26 01:08:00 +02:00
parent a264f05e07
commit 0002eb48e7
35 changed files with 439 additions and 162 deletions

View File

@ -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
View 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);

View 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 */

View 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
View File

@ -0,0 +1,3 @@
#include <pentabug/app.h>
struct app_t apps[MAX_APPS];

4
firmware/lib/lifecycle.c Normal file
View File

@ -0,0 +1,4 @@
#include <pentabug/lifecycle.h>
jmp_buf app_jmp_buf;
uint8_t should_stop;

View File

@ -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
View 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
View 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
View 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;
}
}
}