Modularize modes to apps

This commit is contained in:
Thammi 2012-10-11 18:59:09 +02:00
parent 619ba7d955
commit 657e55074b
9 changed files with 412 additions and 322 deletions

View File

@ -8,7 +8,7 @@ FUSES = lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0x01:m
######################################################################### #########################################################################
SRC=$(wildcard lib/*.c *.c) SRC=$(wildcard lib/*.c *.c apps/*.c)
OBJECTS= $(SRC:.c=.o) OBJECTS= $(SRC:.c=.o)
LSTFILES= $(SRC:.c=.lst) LSTFILES= $(SRC:.c=.lst)
HEADERS=$(wildcard lib/*.h *.h) HEADERS=$(wildcard lib/*.h *.h)

55
firmware/apps/blink.c Normal file
View File

@ -0,0 +1,55 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
/**
* just blink mode
* - left/right button switch motor off/on
*/
static void blink(void)
{
static timer_t mytimer;
static bool blink;
if (mode_uninitialized) {
init_leds();
mode_uninitialized = false;
music_setNote(NOTE_PAUSE, 4); //mute
set_motor(MOTOR_OFF);
timer_set(&mytimer, 10);
blink = false;
}
if (timer_expired(&mytimer)) {
if (!blink) {
/*lets blink*/
led_on(LED_L | LED_R);
timer_set(&mytimer, 1);
blink = true;
} else {
/*stop blink*/
led_off(LED_L | LED_R);
timer_set(&mytimer, 123);
blink = false;
}
}//end if timer_expired
if (btn_state(BTNST_SUP, BTN_LEFT)) {
button_clear(BTN_LEFT);
set_motor(MOTOR_OFF);
}
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
button_clear(BTN_RIGHT);
set_motor(MOTOR_ON);
}
}
REGISTER(blink)

63
firmware/apps/crazy.c Normal file
View File

@ -0,0 +1,63 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
/**
* crazymoves mode
* - play random sounds and move in random fashion
*/
static void crazy(void)
{
static timer_t mytimer;
uint8_t max = 50;
uint8_t min = 5;
uint16_t maxfreq = 5000;
uint16_t minfreq = 1000;
if (mode_uninitialized) {
mode_uninitialized = false;
music_setNote(NOTE_PAUSE, 4); //mute
timer_set(&mytimer, 10);
init_leds();
led_off(LED_L | LED_R);
set_motor(MOTOR_OFF);
}
if (timer_expired(&mytimer)) {
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); //mute
/*set random led*/
switch (rand() % 4) {
case 0: led_on(LED_L); break;
case 1: led_on(LED_R); break;
case 2: led_on(LED_L | LED_R); break;
default: led_off(LED_L | LED_R); break;
};
/*decide if to switch motor on (40% chance)*/
if (rand() % 5 > 2)
set_motor(MOTOR_ON);
/*decide if to play sound (70% chance)*/
if (rand() % 10 > 2) {
music_setNote((rand() % (maxfreq - minfreq)) + minfreq,
0);
}
timer_set(&mytimer, (rand() % (max - min)) + min);
}//end if timer_expired
/*deinialisation */
if (mode_last_tick) {
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); //mute
}
}
REGISTER(crazy)

View File

@ -0,0 +1,32 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
#include "../lib/synth.h"
/**
* do crazy synthesizer mode
*
*/
static void crazy_synth(void)
{
/* initialisation required */
if (mode_uninitialized) {
mode_uninitialized = false;
synth_init();
}
/*deinialisation required */
if (mode_last_tick) {
synth_deinit();
}
return;
}
REGISTER(crazy_synth)

57
firmware/apps/geiger.c Normal file
View File

@ -0,0 +1,57 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
#include "../lib/synth.h"
#include "../lib/usart.h"
/**
* ggrbug mode
* - simulate geiger counter sounds
*/
static void geiger(void)
{
uint8_t max = 200;
uint8_t min = 10;
static timer_t mytimer;
static bool blink;
if (mode_uninitialized) {
init_leds();
music_setNote(NOTE_PAUSE, 0);
mode_uninitialized = false;
timer_set(&mytimer, 10);
blink = false;
};
if (timer_expired(&mytimer)) {
if (!blink) {
/*lets blink*/
int i = (rand() % 3);
switch (i) {
case 0: led_on(LED_L); break;
case 1: led_on(LED_R); break;
default: led_on(LED_L | LED_R); break;
};
if (rand() % 10 > 8)
set_motor(MOTOR_ON);
music_setNote(NOTE_C, 5);
timer_set(&mytimer, 2);
blink = true;
} else {
/*stop blink*/
led_off(LED_L | LED_R);
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0);
timer_set(&mytimer, (rand() % (max - min)) + min);
blink = false;
}
}//end if timer_expired
}
REGISTER(geiger)

74
firmware/apps/led_sound.c Normal file
View File

@ -0,0 +1,74 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
#include "../lib/synth.h"
#include "../lib/usart.h"
static void led_sound(void)
{
static bool discharge;
static timer_t mytimer;
uint16_t led1;
uint16_t led2;
if (mode_uninitialized) {
mode_uninitialized = false;
set_motor(MOTOR_OFF);
ADMUX = (1 << REFS0); // use VCC reference
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
ADCSRA |= (1 << ADEN); // ADC enable - turn it on
/*do one conversion*/
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC)) {
/*wait for conversion to end */
}
uint16_t __attribute__ ((unused)) dummy = ADCW; //read once
timer_set(&mytimer, 10);
discharge = true;
}
if (timer_expired(&mytimer)) {
if (discharge) {
DDRC |= (1 << PORTC0) | (1 << PORTC1) | //set LED Ports to output:
(1 << PORTC2) | (1 << PORTC3);
/*discharge*/
PORTC = (PORTC & 0b11110000);
/*set C0 and C2 to input (disable pullups)*/
DDRC &= ~((1 << PORTC0) | (1 << PORTC2)); //set Led Ports to input
/*pull ups off*/
PORTC &= ~((1 << PORTC0) | (1 << PORTC2));
discharge = false;
} else {
/*single measurement*/
ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0
ADCSRA |= (1 << ADSC); // start single conversion
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
led1 = ADCW; // read result
ADMUX = (ADMUX & ~(0x1F)) | 2; // select channel 2
ADCSRA |= (1 << ADSC); // start single conversion
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
led2 = ADCW; // read result
#if 0
USART0_putc('1');
USART0_putc(':');
USART0_put_uint16(led1);
USART0_crlf();
USART0_putc('2');
USART0_putc(':');
USART0_put_uint16(led2);
USART0_crlf();
#endif
music_setNote(400 +
((0x1ff - led1) + (0x1ff - led2)) * 5, 0);
discharge = true;
}
timer_set(&mytimer, 2); //relaunch timer
} //end if timer_expired
} //end mode5
REGISTER(led_sound)

View File

@ -0,0 +1,86 @@
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include "../lib/apps.h"
#include "../lib/bughal.h"
#include "../lib/util.h"
#include "../lib/music.h"
#include "../lib/synth.h"
#include "../lib/usart.h"
/**
* sound detection mode
* beeps,blinks and moves when sound is detected
* - beep on/off left switch (short)
* - motor on/off right switch (short)
*/
static void sound_detection(void)
{
static timer_t mytimer;
static uint16_t maxval; // maximum of ADC values read during the las timer interval
static uint16_t lastmaxval; // maximum of values during last timer interval
uint16_t curval; // value on D5 (pin of piezo,the other is on GND)
static bool signaling; // are we currently signaling (beeping, blinking etc...)
static bool sound_on; // should sound be on when signaling
static bool motor_on; // should motor be on when signaling
if (mode_uninitialized) { //init after mode change
maxval = 0;
lastmaxval = 0;
mode_uninitialized = false;
signaling = false;
sound_on = true;
motor_on = true;
init_mic();
init_leds();
timer_set(&mytimer, 10);
}
/*single ADC measurement*/
curval = ADCW; // read result
maxval = (curval > maxval) ? curval : maxval;
/*check for Buttons*/
if (btn_state(BTNST_SUP, BTN_LEFT)) {
button_clear(BTN_LEFT);
sound_on = !sound_on;
}
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
button_clear(BTN_RIGHT);
motor_on = !motor_on;
}
if (timer_expired(&mytimer)) {
if (signaling) {
//turn off sound
music_setNote(NOTE_PAUSE, 0); //mute
set_motor(MOTOR_OFF);
//re-init mic
init_mic();
led_off(LED_R | LED_L);
timer_set(&mytimer, 1);
signaling = false;
lastmaxval = 10000;
} else { //sound was off wer're in measuring mode
if (maxval > lastmaxval) {
USART0_put_uint16(maxval);
USART0_crlf();
led_on(LED_R | LED_L);
init_buzzr(); //buzzr to output
if (sound_on)
music_setNote(NOTE_C, 5);
if (motor_on)
set_motor(MOTOR_ON);
signaling = true;
timer_set(&mytimer, 5); //sound duration
} else {
timer_set(&mytimer, 1);
}
lastmaxval = maxval;
maxval = 0;
}//end if soundon
}//end if timer_expired
} /* end mode0 */
REGISTER(sound_detection)

21
firmware/lib/apps.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef APPS_H
#define APPS_H
#include <inttypes.h>
#define MAX_FUNS 16
#define REGISTER(fun) static void init(void) __attribute__ ((naked, used, section (".init8"))); \
void init(void) { \
mode_funs[mode_num] = fun; \
++mode_num; \
} \
typedef void (*mode_fun)(void);
extern mode_fun mode_funs[MAX_FUNS];
extern uint8_t mode_num;
extern uint8_t mode_uninitialized;
extern uint8_t mode_last_tick;
#endif /* APPS_H */

View File

@ -16,34 +16,31 @@
#include "lib/music.h" #include "lib/music.h"
#include "lib/synth.h" #include "lib/synth.h"
//operartion modes #include "lib/apps.h"
#define MODE0 0
#define MODE1 1 mode_fun mode_funs[MAX_FUNS] = { NULL };
#define MODE2 2 uint8_t mode_num = 0;
#define MODE3 3
#define MODE4 4
#define MODE5 5
#define NUM_MODES 6
/*specialmodes, not in normal mode loop*/ /*specialmodes, not in normal mode loop*/
#define MODE_PWDN 42 //go to sleep #define MODE_PWDN mode_num //go to sleep
uint8_t OpMode = MODE1; uint8_t OpMode = 0;
uint8_t NextMode = MODE1; uint8_t NextMode = 0;
bool mode_uninitialized = true; uint8_t mode_uninitialized = true;
uint8_t mode_last_tick = false;
/*check if mode should be changed (one of the buttons long pressed)*/ /*check if mode should be changed (one of the buttons long pressed)*/
void modeswitch_poll(void) void modeswitch_poll(void)
{ {
if (btn_state(BTNST_LUP, BTN_LEFT)) { if (btn_state(BTNST_LUP, BTN_LEFT)) {
//opmode -- //opmode --
NextMode = (OpMode -1) % NUM_MODES; NextMode = (OpMode -1) % mode_num;
button_clear(BTN_LEFT); button_clear(BTN_LEFT);
} }
if (btn_state(BTNST_LUP, BTN_RIGHT)) { if (btn_state(BTNST_LUP, BTN_RIGHT)) {
//opmode ++ //opmode ++
NextMode = (OpMode +1) % NUM_MODES; NextMode = (OpMode +1) % mode_num;
button_clear(BTN_RIGHT); button_clear(BTN_RIGHT);
} }
if ( btn_state(BTNST_LDN, BTN_RIGHT) && if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
@ -53,303 +50,6 @@ void modeswitch_poll(void)
return; return;
} }
/**
* sound detection mode
* beeps,blinks and moves when sound is detected
* - beep on/off left switch (short)
* - motor on/off right switch (short)
*/
void do_mode0(void)
{
static timer_t mytimer;
static uint16_t maxval; // maximum of ADC values read during the las timer interval
static uint16_t lastmaxval; // maximum of values during last timer interval
uint16_t curval; // value on D5 (pin of piezo,the other is on GND)
static bool signaling; // are we currently signaling (beeping, blinking etc...)
static bool sound_on; // should sound be on when signaling
static bool motor_on; // should motor be on when signaling
if (mode_uninitialized) { //init after mode change
maxval = 0;
lastmaxval = 0;
mode_uninitialized = false;
signaling = false;
sound_on = true;
motor_on = true;
init_mic();
init_leds();
timer_set(&mytimer, 10);
}
/*single ADC measurement*/
curval = ADCW; // read result
maxval = (curval > maxval) ? curval : maxval;
/*check for Buttons*/
if (btn_state(BTNST_SUP, BTN_LEFT)) {
button_clear(BTN_LEFT);
sound_on = !sound_on;
}
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
button_clear(BTN_RIGHT);
motor_on = !motor_on;
}
if (timer_expired(&mytimer)) {
if (signaling) {
//turn off sound
music_setNote(NOTE_PAUSE, 0); //mute
set_motor(MOTOR_OFF);
//re-init mic
init_mic();
led_off(LED_R | LED_L);
timer_set(&mytimer, 1);
signaling = false;
lastmaxval = 10000;
} else { //sound was off wer're in measuring mode
if (maxval > lastmaxval) {
USART0_put_uint16(maxval);
USART0_crlf();
led_on(LED_R | LED_L);
init_buzzr(); //buzzr to output
if (sound_on)
music_setNote(NOTE_C, 5);
if (motor_on)
set_motor(MOTOR_ON);
signaling = true;
timer_set(&mytimer, 5); //sound duration
} else {
timer_set(&mytimer, 1);
}
lastmaxval = maxval;
maxval = 0;
}//end if soundon
}//end if timer_expired
} /* end mode0 */
/**
* do crazy synthesizer mode
*
*/
void do_mode1(void)
{
/* initialisation required */
if (mode_uninitialized) {
mode_uninitialized = false;
synth_init();
}
/*deinialisation required */
if (OpMode != NextMode) {
synth_deinit();
}
return;
}
/**
* crazymoves mode
* - play random sounds and move in random fashion
*/
void do_mode2(void)
{
static timer_t mytimer;
uint8_t max = 50;
uint8_t min = 5;
uint16_t maxfreq = 5000;
uint16_t minfreq = 1000;
if (mode_uninitialized) {
mode_uninitialized = false;
music_setNote(NOTE_PAUSE, 4); //mute
timer_set(&mytimer, 10);
init_leds();
led_off(LED_L | LED_R);
set_motor(MOTOR_OFF);
}
if (timer_expired(&mytimer)) {
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); //mute
/*set random led*/
switch (rand() % 4) {
case 0: led_on(LED_L); break;
case 1: led_on(LED_R); break;
case 2: led_on(LED_L | LED_R); break;
default: led_off(LED_L | LED_R); break;
};
/*decide if to switch motor on (40% chance)*/
if (rand() % 5 > 2)
set_motor(MOTOR_ON);
/*decide if to play sound (70% chance)*/
if (rand() % 10 > 2) {
music_setNote((rand() % (maxfreq - minfreq)) + minfreq,
0);
}
timer_set(&mytimer, (rand() % (max - min)) + min);
}//end if timer_expired
/*deinialisation */
if (OpMode != NextMode) {
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); //mute
}
}
/**
* just blink mode
* - left/right button switch motor off/on
*/
void do_mode3(void)
{
static timer_t mytimer;
static bool blink;
if (mode_uninitialized) {
init_leds();
mode_uninitialized = false;
music_setNote(NOTE_PAUSE, 4); //mute
set_motor(MOTOR_OFF);
timer_set(&mytimer, 10);
blink = false;
}
if (timer_expired(&mytimer)) {
if (!blink) {
/*lets blink*/
led_on(LED_L | LED_R);
timer_set(&mytimer, 1);
blink = true;
} else {
/*stop blink*/
led_off(LED_L | LED_R);
timer_set(&mytimer, 123);
blink = false;
}
}//end if timer_expired
if (btn_state(BTNST_SUP, BTN_LEFT)) {
button_clear(BTN_LEFT);
set_motor(MOTOR_OFF);
}
if (btn_state(BTNST_SUP, BTN_RIGHT)) {
button_clear(BTN_RIGHT);
set_motor(MOTOR_ON);
}
}
/**
* ggrbug mode
* - simulate geiger counter sounds
*/
void do_mode4(void)
{
uint8_t max = 200;
uint8_t min = 10;
static timer_t mytimer;
static bool blink;
if (mode_uninitialized) {
init_leds();
music_setNote(NOTE_PAUSE, 0);
mode_uninitialized = false;
timer_set(&mytimer, 10);
blink = false;
};
if (timer_expired(&mytimer)) {
if (!blink) {
/*lets blink*/
int i = (rand() % 3);
switch (i) {
case 0: led_on(LED_L); break;
case 1: led_on(LED_R); break;
default: led_on(LED_L | LED_R); break;
};
if (rand() % 10 > 8)
set_motor(MOTOR_ON);
music_setNote(NOTE_C, 5);
timer_set(&mytimer, 2);
blink = true;
} else {
/*stop blink*/
led_off(LED_L | LED_R);
set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0);
timer_set(&mytimer, (rand() % (max - min)) + min);
blink = false;
}
}//end if timer_expired
}
void do_mode5(void)
{
static bool discharge;
static timer_t mytimer;
uint16_t led1;
uint16_t led2;
if (mode_uninitialized) {
mode_uninitialized = false;
set_motor(MOTOR_OFF);
ADMUX = (1 << REFS0); // use VCC reference
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
ADCSRA |= (1 << ADEN); // ADC enable - turn it on
/*do one conversion*/
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC)) {
/*wait for conversion to end */
}
uint16_t __attribute__ ((unused)) dummy = ADCW; //read once
timer_set(&mytimer, 10);
discharge = true;
}
if (timer_expired(&mytimer)) {
if (discharge) {
DDRC |= (1 << PORTC0) | (1 << PORTC1) | //set LED Ports to output:
(1 << PORTC2) | (1 << PORTC3);
/*discharge*/
PORTC = (PORTC & 0b11110000);
/*set C0 and C2 to input (disable pullups)*/
DDRC &= ~((1 << PORTC0) | (1 << PORTC2)); //set Led Ports to input
/*pull ups off*/
PORTC &= ~((1 << PORTC0) | (1 << PORTC2));
discharge = false;
} else {
/*single measurement*/
ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0
ADCSRA |= (1 << ADSC); // start single conversion
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
led1 = ADCW; // read result
ADMUX = (ADMUX & ~(0x1F)) | 2; // select channel 2
ADCSRA |= (1 << ADSC); // start single conversion
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
led2 = ADCW; // read result
#if 0
USART0_putc('1');
USART0_putc(':');
USART0_put_uint16(led1);
USART0_crlf();
USART0_putc('2');
USART0_putc(':');
USART0_put_uint16(led2);
USART0_crlf();
#endif
music_setNote(400 +
((0x1ff - led1) + (0x1ff - led2)) * 5, 0);
discharge = true;
}
timer_set(&mytimer, 2); //relaunch timer
} //end if timer_expired
} //end mode5
void do_powerDown(void) void do_powerDown(void)
{ {
static timer_t mytimer; static timer_t mytimer;
@ -411,7 +111,7 @@ void do_powerDown(void)
sei(); sei();
sleep_cpu(); sleep_cpu();
sleep_disable(); sleep_disable();
NextMode = MODE2; NextMode = 0;
break; break;
default: default:
break; break;
@ -440,16 +140,18 @@ void __attribute__ ((noreturn)) main(void)
button_poll(); button_poll();
modeswitch_poll(); modeswitch_poll();
switch (OpMode) {
case MODE1 : do_mode1(); break ;
case MODE2 : do_mode2(); break ;
case MODE3 : do_mode3(); break ;
case MODE4 : do_mode4(); break ;
case MODE5 : do_mode5(); break ;
case MODE_PWDN : do_powerDown(); break ;
default : do_mode0(); break ;
}
if (OpMode != NextMode){ 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; mode_uninitialized = true;
OpMode = NextMode; OpMode = NextMode;
} }