pwdown still needs isr to wakeup.

put untested pdown code. please add pinchangeirq
for either button
This commit is contained in:
john stone 2012-10-11 14:44:38 +02:00
parent dc35106b07
commit bebc6f9925

View File

@ -1,5 +1,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#define __DELAY_BACKWARD_COMPATIBLE__ #define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h> #include <util/delay.h>
@ -24,7 +25,7 @@
#define MODE5 5 #define MODE5 5
#define NUM_MODES 6 #define NUM_MODES 6
//special modes, not in normal mode loop /*specialmodes, not in normal mode loop*/
#define MODE_PWDN 42 //go to sleep #define MODE_PWDN 42 //go to sleep
uint8_t OpMode = MODE1; uint8_t OpMode = MODE1;
@ -32,24 +33,23 @@ uint8_t NextMode = MODE1;
bool mode_uninitialized = true; bool mode_uninitialized = true;
// 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 = (0 == OpMode) ? (NUM_MODES - 1) : (OpMode - 1); NextMode = (OpMode -1) % NUM_MODES;
//mode_uninitialized = true;
button_clear(BTN_LEFT); button_clear(BTN_LEFT);
}; }
if (btn_state(BTNST_LUP, BTN_RIGHT)) { if (btn_state(BTNST_LUP, BTN_RIGHT)) {
//opmode + //opmode ++
//mode_uninitialized = true; NextMode = (OpMode +1) % NUM_MODES;
NextMode = ((NUM_MODES - 1) == OpMode) ? 0 : (OpMode + 1);
button_clear(BTN_RIGHT); button_clear(BTN_RIGHT);
}; }
if (btn_state(BTNST_LDN,BTN_RIGHT) && btn_state(BTNST_LDN,BTN_LEFT)){ if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
btn_state(BTNST_LDN, BTN_LEFT) ) {
NextMode = MODE_PWDN; NextMode = MODE_PWDN;
}; }
return; return;
} }
@ -64,14 +64,14 @@ void do_mode0(void)
static timer_t mytimer; static timer_t mytimer;
static uint16_t maxval; // maximum of ADC values read during the las timer interval 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 static uint16_t lastmaxval; // maximum of values during last timer interval
uint16_t curval; //current value on D5 (one pin of the piezo,the other is on GND) 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 signaling; // are we currently signaling (beeping, blinking etc...)
static bool sound_on; // should sound be on when signaling static bool sound_on; // should sound be on when signaling
static bool motor_on; // should motor be on when signaling static bool motor_on; // should motor be on when signaling
if (mode_uninitialized) { //init after mode change if (mode_uninitialized) { //init after mode change
maxval = 0; maxval = 0;
lastmaxval = 000; lastmaxval = 0;
mode_uninitialized = false; mode_uninitialized = false;
signaling = false; signaling = false;
sound_on = true; sound_on = true;
@ -80,12 +80,11 @@ void do_mode0(void)
init_leds(); init_leds();
timer_set(&mytimer, 10); timer_set(&mytimer, 10);
} }
/*single ADC measurement*/
// single ADC measurement
curval = ADCW; // read result curval = ADCW; // read result
maxval = (curval > maxval) ? curval : maxval; maxval = (curval > maxval) ? curval : maxval;
//check for Buttons /*check for Buttons*/
if (btn_state(BTNST_SUP, BTN_LEFT)) { if (btn_state(BTNST_SUP, BTN_LEFT)) {
button_clear(BTN_LEFT); button_clear(BTN_LEFT);
sound_on = !sound_on; sound_on = !sound_on;
@ -134,6 +133,7 @@ void do_mode0(void)
*/ */
void do_mode1(void) void do_mode1(void)
{ {
/* initialisation required */
if (mode_uninitialized) { if (mode_uninitialized) {
mode_uninitialized = false; mode_uninitialized = false;
synth_init(); synth_init();
@ -147,7 +147,6 @@ void do_mode1(void)
return; return;
} }
/** /**
* crazymoves mode * crazymoves mode
* - play random sounds and move in random fashion * - play random sounds and move in random fashion
@ -172,26 +171,18 @@ void do_mode2(void)
if (timer_expired(&mytimer)) { if (timer_expired(&mytimer)) {
set_motor(MOTOR_OFF); set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); //mute music_setNote(NOTE_PAUSE, 0); //mute
// set random led /*set random led*/
switch (rand() % 4) { switch (rand() % 4) {
case 0: case 0: led_on(LED_L); break;
led_on(LED_L); case 1: led_on(LED_R); break;
break; case 2: led_on(LED_L | LED_R); break;
case 1: default: led_off(LED_L | LED_R); break;
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) /*decide if to switch motor on (40% chance)*/
if (rand() % 5 > 2) if (rand() % 5 > 2)
set_motor(MOTOR_ON); set_motor(MOTOR_ON);
//decide if to play sound (70% chance) /*decide if to play sound (70% chance)*/
if (rand() % 10 > 2) { if (rand() % 10 > 2) {
music_setNote((rand() % (maxfreq - minfreq)) + minfreq, music_setNote((rand() % (maxfreq - minfreq)) + minfreq,
0); 0);
@ -208,7 +199,6 @@ void do_mode2(void)
} }
} }
/** /**
* just blink mode * just blink mode
* - left/right button switch motor off/on * - left/right button switch motor off/on
@ -228,12 +218,12 @@ void do_mode3(void)
if (timer_expired(&mytimer)) { if (timer_expired(&mytimer)) {
if (!blink) { if (!blink) {
//lets blink /*lets blink*/
led_on(LED_L | LED_R); led_on(LED_L | LED_R);
timer_set(&mytimer, 1); timer_set(&mytimer, 1);
blink = true; blink = true;
} else { } else {
//stop blink /*stop blink*/
led_off(LED_L | LED_R); led_off(LED_L | LED_R);
timer_set(&mytimer, 123); timer_set(&mytimer, 123);
blink = false; blink = false;
@ -253,8 +243,6 @@ void do_mode3(void)
} }
/** /**
* ggrbug mode * ggrbug mode
* - simulate geiger counter sounds * - simulate geiger counter sounds
@ -275,18 +263,12 @@ void do_mode4(void)
}; };
if (timer_expired(&mytimer)) { if (timer_expired(&mytimer)) {
if (!blink) { if (!blink) {
//lets blink /*lets blink*/
int i = (rand() % 3); int i = (rand() % 3);
switch (i) { switch (i) {
case 0: case 0: led_on(LED_L); break;
led_on(LED_L); case 1: led_on(LED_R); break;
break; default: led_on(LED_L | LED_R); break;
case 1:
led_on(LED_R);
break;
default:
led_on(LED_L | LED_R);
break;
}; };
if (rand() % 10 > 8) if (rand() % 10 > 8)
set_motor(MOTOR_ON); set_motor(MOTOR_ON);
@ -294,7 +276,7 @@ void do_mode4(void)
timer_set(&mytimer, 2); timer_set(&mytimer, 2);
blink = true; blink = true;
} else { } else {
//stop blink /*stop blink*/
led_off(LED_L | LED_R); led_off(LED_L | LED_R);
set_motor(MOTOR_OFF); set_motor(MOTOR_OFF);
music_setNote(NOTE_PAUSE, 0); music_setNote(NOTE_PAUSE, 0);
@ -319,10 +301,11 @@ void do_mode5(void)
ADMUX = (1 << REFS0); // use VCC reference ADMUX = (1 << REFS0); // use VCC reference
ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8 ADCSRA = (1 << ADPS1) | (1 << ADPS0); // prescaler F_CPU/8
ADCSRA |= (1 << ADEN); // ADC enable - turn it on ADCSRA |= (1 << ADEN); // ADC enable - turn it on
// do one conversion /*do one conversion*/
ADCSRA |= (1 << ADSC); ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC)) { while (ADCSRA & (1 << ADSC)) {
} //wait for conversion to end /*wait for conversion to end */
}
uint16_t __attribute__ ((unused)) dummy = ADCW; //read once uint16_t __attribute__ ((unused)) dummy = ADCW; //read once
timer_set(&mytimer, 10); timer_set(&mytimer, 10);
discharge = true; discharge = true;
@ -331,15 +314,15 @@ void do_mode5(void)
if (discharge) { if (discharge) {
DDRC |= (1 << PORTC0) | (1 << PORTC1) | //set LED Ports to output: DDRC |= (1 << PORTC0) | (1 << PORTC1) | //set LED Ports to output:
(1 << PORTC2) | (1 << PORTC3); (1 << PORTC2) | (1 << PORTC3);
// discharge /*discharge*/
PORTC = (PORTC & 0b11110000); PORTC = (PORTC & 0b11110000);
//set C0 and C2 to input (disable pullups) /*set C0 and C2 to input (disable pullups)*/
DDRC &= ~((1 << PORTC0) | (1 << PORTC2)); //set Led Ports to input DDRC &= ~((1 << PORTC0) | (1 << PORTC2)); //set Led Ports to input
//pull ups off /*pull ups off*/
PORTC &= ~((1 << PORTC0) | (1 << PORTC2)); PORTC &= ~((1 << PORTC0) | (1 << PORTC2));
discharge = false; discharge = false;
} else { } else {
// single measurement /*single measurement*/
ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0 ADMUX = (ADMUX & ~(0x1F)) | 0; // select channel 0
ADCSRA |= (1 << ADSC); // start single conversion ADCSRA |= (1 << ADSC); // start single conversion
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
@ -350,17 +333,23 @@ void do_mode5(void)
while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end while (ADCSRA & (1 << ADSC)) ; // wait for conversion to end
led2 = ADCW; // read result led2 = ADCW; // read result
#if 0 #if 0
USART0_putc('1');USART0_putc(':');USART0_put_uint16(led1);USART0_crlf(); USART0_putc('1');
USART0_putc('2');USART0_putc(':');USART0_put_uint16(led2);USART0_crlf(); USART0_putc(':');
USART0_put_uint16(led1);
USART0_crlf();
USART0_putc('2');
USART0_putc(':');
USART0_put_uint16(led2);
USART0_crlf();
#endif #endif
music_setNote(400 +((0x1ff - led1) + (0x1ff - led2)) * 5, 0); music_setNote(400 +
((0x1ff - led1) + (0x1ff - led2)) * 5, 0);
discharge = true; discharge = true;
} }
timer_set(&mytimer, 2); //relaunch timer timer_set(&mytimer, 2); //relaunch timer
} //end if timer_expired } //end if timer_expired
} //end mode5 } //end mode5
void do_powerDown(void) void do_powerDown(void)
{ {
static timer_t mytimer; static timer_t mytimer;
@ -376,43 +365,62 @@ void do_powerDown(void)
switch (pwdn_state) { switch (pwdn_state) {
case 0: case 0:
if (ledRon) { if (ledRon) {
led_on(LED_L);led_off(LED_R); led_on(LED_L);
led_off(LED_R);
} else { } else {
led_off(LED_L);led_on(LED_R); led_off(LED_L);
led_on(LED_R);
}; };
ledRon = !ledRon; ledRon = !ledRon;
timer_set(&mytimer, 6); 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))){ 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 //both buttons released
led_off(LED_L | LED_R); led_off(LED_L | LED_R);
pwdn_state = 1; pwdn_state = 1;
timer_set(&mytimer, 10); timer_set(&mytimer, 10);
} }
break; break;
case 1: music_setNote(NOTE_A, 4);timer_set(&mytimer,10);pwdn_state++;break; case 1:
case 2: music_setNote(NOTE_F, 4);timer_set(&mytimer,5);pwdn_state++;break; music_setNote(NOTE_A, 4);
case 3: music_setNote(NOTE_D, 3);timer_set(&mytimer,15);pwdn_state++;break; timer_set(&mytimer, 10);
case 4: music_setNote(NOTE_PAUSE, 4);timer_set(&mytimer,1);pwdn_state++;break; 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 case 5: //now we can really power down
// lets switch everything off // lets switch everything off
//TODO: find out how to do this
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
//meanwhile: switch back to normal operation (silent mode 2) sleep_enable();
sei();
sleep_cpu();
sleep_disable();
NextMode = MODE2; NextMode = MODE2;
break; break;
default: break; default:
break;
} //end switch } //end switch
} //end timer expired } //end timer expired
} // end do_powerDown } // end do_powerDown
void __attribute__ ((noreturn)) main(void) void __attribute__ ((noreturn)) main(void)
{ {
/* hardware initialisation: */ /* hardware initialisation: */
@ -425,14 +433,13 @@ void __attribute__ ((noreturn)) main(void)
timer_init(); timer_init();
music_init(); music_init();
/* here the show begins: */ /* here the show begins: */
sei(); sei();
for ever { for ever {
//main polling loop; //main polling loop;
button_poll(); button_poll();
if (OpMode != MODE_PWDN) modeswitch_poll(); //there is no way out of PWND modeswitch_poll();
switch (OpMode) { switch (OpMode) {
case MODE1 : do_mode1(); break ; case MODE1 : do_mode1(); break ;
case MODE2 : do_mode2(); break ; case MODE2 : do_mode2(); break ;
@ -442,9 +449,9 @@ void __attribute__ ((noreturn)) main(void)
case MODE_PWDN : do_powerDown(); break ; case MODE_PWDN : do_powerDown(); break ;
default : do_mode0(); break ; default : do_mode0(); break ;
} }
if (OpMode!=NextMode) mode_uninitialized = true; if (OpMode != NextMode){
mode_uninitialized = true;
OpMode = NextMode; OpMode = NextMode;
} }
} }
}