2012-07-17 01:05:27 +02:00
|
|
|
#include <inttypes.h>
|
|
|
|
#include <avr/io.h>
|
2012-10-11 14:44:38 +02:00
|
|
|
#include <avr/sleep.h>
|
2012-07-17 01:05:27 +02:00
|
|
|
#include <avr/interrupt.h>
|
2012-10-01 21:39:25 +02:00
|
|
|
#define __DELAY_BACKWARD_COMPATIBLE__
|
2012-07-17 01:05:27 +02:00
|
|
|
#include <util/delay.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "main.h"
|
2012-10-01 23:36:37 +02:00
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
#define ever (;;) /* awesomnes++ */
|
2012-10-10 04:15:06 +02:00
|
|
|
|
2012-09-02 21:53:11 +02:00
|
|
|
#include "lib/usart.h"
|
2012-09-02 23:49:57 +02:00
|
|
|
#include "lib/bughal.h"
|
2012-10-01 21:39:25 +02:00
|
|
|
#include "lib/util.h"
|
2012-10-03 23:41:15 +02:00
|
|
|
#include "lib/music.h"
|
2012-07-26 01:34:49 +02:00
|
|
|
|
2012-10-11 18:59:09 +02:00
|
|
|
#include "lib/apps.h"
|
|
|
|
|
|
|
|
mode_fun mode_funs[MAX_FUNS] = { NULL };
|
|
|
|
uint8_t mode_num = 0;
|
2012-10-03 23:41:15 +02:00
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
/*specialmodes, not in normal mode loop*/
|
2012-10-11 18:59:09 +02:00
|
|
|
#define MODE_PWDN mode_num //go to sleep
|
2012-10-11 00:29:15 +02:00
|
|
|
|
2012-10-11 18:59:09 +02:00
|
|
|
uint8_t OpMode = 0;
|
|
|
|
uint8_t NextMode = 0;
|
2012-10-10 04:15:06 +02:00
|
|
|
|
2012-10-11 18:59:09 +02:00
|
|
|
uint8_t mode_uninitialized = true;
|
|
|
|
uint8_t mode_last_tick = false;
|
2012-10-07 00:52:53 +02:00
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
/*check if mode should be changed (one of the buttons long pressed)*/
|
2012-10-10 04:15:06 +02:00
|
|
|
void modeswitch_poll(void)
|
|
|
|
{
|
2012-10-07 00:52:53 +02:00
|
|
|
if (btn_state(BTNST_LUP, BTN_LEFT)) {
|
2012-10-11 14:44:38 +02:00
|
|
|
//opmode --
|
2012-10-11 18:59:09 +02:00
|
|
|
NextMode = (OpMode -1) % mode_num;
|
2012-10-07 00:52:53 +02:00
|
|
|
button_clear(BTN_LEFT);
|
2012-10-11 14:44:38 +02:00
|
|
|
}
|
2012-10-07 00:52:53 +02:00
|
|
|
if (btn_state(BTNST_LUP, BTN_RIGHT)) {
|
2012-10-11 14:44:38 +02:00
|
|
|
//opmode ++
|
2012-10-11 18:59:09 +02:00
|
|
|
NextMode = (OpMode +1) % mode_num;
|
2012-10-07 00:52:53 +02:00
|
|
|
button_clear(BTN_RIGHT);
|
2012-10-11 14:44:38 +02:00
|
|
|
}
|
|
|
|
if ( btn_state(BTNST_LDN, BTN_RIGHT) &&
|
|
|
|
btn_state(BTNST_LDN, BTN_LEFT) ) {
|
2012-10-11 00:29:15 +02:00
|
|
|
NextMode = MODE_PWDN;
|
2012-10-11 14:44:38 +02:00
|
|
|
}
|
2012-10-07 00:52:53 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-11 00:29:15 +02:00
|
|
|
void do_powerDown(void)
|
|
|
|
{
|
|
|
|
static timer_t mytimer;
|
|
|
|
static uint8_t pwdn_state;
|
|
|
|
static bool ledRon;
|
|
|
|
if (mode_uninitialized) {
|
|
|
|
mode_uninitialized = false;
|
|
|
|
pwdn_state = 0;
|
2012-10-11 14:44:38 +02:00
|
|
|
timer_set(&mytimer, 5);
|
2012-10-11 00:29:15 +02:00
|
|
|
ledRon = true;
|
|
|
|
};
|
2012-10-11 14:44:38 +02:00
|
|
|
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
|
|
|
|
|
|
|
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
|
|
|
sleep_enable();
|
|
|
|
sei();
|
|
|
|
sleep_cpu();
|
|
|
|
sleep_disable();
|
2012-10-11 18:59:09 +02:00
|
|
|
NextMode = 0;
|
2012-10-11 14:44:38 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2012-10-11 00:29:15 +02:00
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
} //end switch
|
2012-10-11 00:29:15 +02:00
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
} //end timer expired
|
|
|
|
} // end do_powerDown
|
2012-10-11 00:29:15 +02:00
|
|
|
|
2012-10-10 05:12:38 +02:00
|
|
|
void __attribute__ ((noreturn)) main(void)
|
2012-10-10 04:15:06 +02:00
|
|
|
{
|
2012-08-27 09:43:42 +02:00
|
|
|
/* hardware initialisation: */
|
2012-09-02 23:49:57 +02:00
|
|
|
init_leds();
|
2012-09-06 23:09:20 +02:00
|
|
|
init_buzzr();
|
2012-10-01 21:39:25 +02:00
|
|
|
init_switch();
|
|
|
|
USART0_Init();
|
|
|
|
init_motor();
|
|
|
|
/* software initialisation */
|
|
|
|
timer_init();
|
2012-10-03 23:41:15 +02:00
|
|
|
music_init();
|
2012-10-01 21:39:25 +02:00
|
|
|
|
2012-10-10 04:15:06 +02:00
|
|
|
/* here the show begins: */
|
|
|
|
sei();
|
|
|
|
for ever {
|
2012-10-07 00:52:53 +02:00
|
|
|
//main polling loop;
|
2012-10-08 22:30:01 +02:00
|
|
|
button_poll();
|
2012-10-11 14:44:38 +02:00
|
|
|
modeswitch_poll();
|
|
|
|
|
2012-10-11 18:59:09 +02:00
|
|
|
if (OpMode != NextMode){
|
|
|
|
mode_last_tick = true;
|
2012-10-11 14:44:38 +02:00
|
|
|
}
|
2012-10-11 18:59:09 +02:00
|
|
|
|
|
|
|
if(OpMode < mode_num) {
|
|
|
|
mode_funs[OpMode]();
|
|
|
|
} else {
|
|
|
|
do_powerDown();
|
|
|
|
}
|
|
|
|
|
2012-10-11 14:44:38 +02:00
|
|
|
if (OpMode != NextMode){
|
2012-10-11 18:59:09 +02:00
|
|
|
mode_last_tick = false;
|
2012-10-11 14:44:38 +02:00
|
|
|
mode_uninitialized = true;
|
|
|
|
OpMode = NextMode;
|
2012-10-10 04:15:06 +02:00
|
|
|
}
|
|
|
|
}
|
2012-07-18 15:55:20 +02:00
|
|
|
}
|