[tuxdroid-svn] r405 - firmware/tuxaudio/trunk
Status: Beta
Brought to you by:
ks156
From: jaguarondi <c2m...@c2...> - 2007-06-19 16:41:51
|
Author: jaguarondi Date: 2007-06-19 18:41:46 +0200 (Tue, 19 Jun 2007) New Revision: 405 Modified: firmware/tuxaudio/trunk/communication.c firmware/tuxaudio/trunk/communication.h firmware/tuxaudio/trunk/main.c Log: * Added the sleep functions. The CPU now loads a low power configuration, goes to sleep and exits the sleep function from the head button interrupt. There's a delay around 1sec before the CPU enters sleep. This way it's possible to get some last commands from tuxcore. This should be changed in the future so that the sleep command is forwarded from tuxcore to tuxaudio only when the pre sleep sequence is finished, that makes more sense. * BUG: if a sound is already playing, we now wait until it's finished before starting the next one. Modified: firmware/tuxaudio/trunk/communication.c =================================================================== --- firmware/tuxaudio/trunk/communication.c 2007-06-19 16:27:52 UTC (rev 404) +++ firmware/tuxaudio/trunk/communication.c 2007-06-19 16:41:46 UTC (rev 405) @@ -80,6 +80,15 @@ , *statusFifo = &_statusBuf; /* + * Initializes (clear) the communication buffers + */ +void initCommunicationBuffers(void) +{ + resetFifo(commandFifo); + audioBufIdx = 0; +} + +/* * I2C communication initalisation * * Start the twi interface in the mode defined in i2c.h, set the receiver function and Modified: firmware/tuxaudio/trunk/communication.h =================================================================== --- firmware/tuxaudio/trunk/communication.h 2007-06-19 16:27:52 UTC (rev 404) +++ firmware/tuxaudio/trunk/communication.h 2007-06-19 16:41:46 UTC (rev 405) @@ -37,6 +37,7 @@ extern fifo_t *statusFifo; /* incomingBuf is used for commands received from the i2c and should be sent over the RF link */ void i2cCommunicationInit(void); +void initCommunicationBuffers(void); /* From RF to i2c */ void sendCommands(void); Modified: firmware/tuxaudio/trunk/main.c =================================================================== --- firmware/tuxaudio/trunk/main.c 2007-06-19 16:27:52 UTC (rev 404) +++ firmware/tuxaudio/trunk/main.c 2007-06-19 16:41:46 UTC (rev 405) @@ -23,6 +23,7 @@ #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <util/delay.h> +#include <avr/sleep.h> #include "init.h" #include "varis.h" @@ -38,7 +39,7 @@ * Version number */ -#define CPU_NUMBER TUXAUDIO_CPU_NUM /* audio CPU */ +#define CPU_NUMBER TUXAUDIO_CPU_NUM /* audio CPU */ const author_t author __attribute__ ((section("version.3"))) = { AUTHOR_CMD, AUTHOR_ID, 0}; @@ -48,8 +49,8 @@ const version_t tag_version __attribute__ ((section("version.1"))) = { VERSION_CMD, CPU_VER_JOIN(CPU_NUMBER, VER_MAJOR), VER_MINOR, VER_UPDATE}; -uint8_t info_flg = 0; /* indicates if version information should be sent */ -uint8_t sleep_flg = 0; /* set when sleep should be entered */ +static uint8_t info_flg = 0; /* indicates if version information should be sent */ +static uint8_t pre_sleep_delay = 0; /* set when sleep should be entered */ void send_info(void) { @@ -73,13 +74,47 @@ info_flg = 0; } +ISR(SIG_PIN_CHANGE1) +{ + /* Nothing to do here, it's just an interrupt set on the head button to + * wake-up from sleep */ + /* XXX This ISR is declared as I think any interrupt which doesn't have an + * interrupt vector initialized will do a reset or infinite loop, this + * needs to be checked */ +} + void sleep(void) { - if (isFifoEmpty(statusFifo)) /* waits for all status to be sent before going to sleep */ - { - sleep_flg = 0; - playingAudio(1); /* XXX debug */ - } + uint8_t PRR_bak; + + pre_sleep_delay = 0; + /* Set power savings configuration. */ + cli(); + PORTB = 0x80; + PORTC = 0; + PORTD = 0; + + PRR_bak = PRR; + PRR = _BV(PRTWI) | _BV(PRTIM2) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRADC); + + /* Sleep. */ + /* Set pin change interrupt on head button */ + PCMSK1 = 0x08; + PCIFR = _BV(PCIE1); + PCICR |= _BV(PCIE1); + + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_enable(); + sei(); + sleep_cpu(); + sleep_disable(); + + /* Re-configure in normal mode. */ + PCMSK1 = 0x00; + PRR = PRR_bak; + init_avr(); + initCommunicationBuffers(); + i2cCommunicationInit(); } /* @@ -120,8 +155,12 @@ /* param: audioBuf[1] : sound number */ /* audioBuf[2] : mic sound intensity */ { + /* postpone the command if a sound is already playing */ + if (flashPlay) + return; audioLevel = audioBuf[2]; - playingAudio(audioBuf[1]); // Play sound + //if (audioBuf[1] == 1) PORTC &= ~0x02; + playingAudio(audioBuf[1]); /* start playing the sound */ } else if (audioBuf[0] == MUTE_CMD) { @@ -132,15 +171,16 @@ } else if (audioBuf[0] == TEST_MODE_CMD) { - test_mode = audioBuf[2]; /* audio test mode is the second parameter */ + test_mode = audioBuf[2]; /* audio test mode is the second parameter */ } else if (audioBuf[0] == SLEEP_CMD) { - sleep_flg = 1; /* handle sleep in its own function */ + pre_sleep_delay = 30; /* handle sleep in its own function */ /* Forwards the command to the rf CPU */ + cli(); audioBuf[0] = SLEEP_ACK_CMD; /* go to sleep mode and acknowledge it */ - audioBuf[2] |= SLEEP_ACK_MK; - cli(); + audioBuf[3] = audioBuf[2]; /* move the sleep type to the last byte */ + audioBuf[2] = SLEEP_ACK_MK; i2cSlaveReceiveService(4, audioBuf); sei(); } @@ -295,7 +335,19 @@ if (sendSensorsFlag) { sendSensorsFlag = 0; - sendSensors(); + if (pre_sleep_delay > 1) + /* There's a delay before sleep is actually called otherwise + * some commands can't be executed */ + pre_sleep_delay--; + else + /* stop sending sensor status in sleep as the i2C should be + * stopped at this time */ + sendSensors(); + /* wait for all status to be sent before going to sleep */ + if (isFifoEmpty(statusFifo)) + /* wait for audio commands to be processed */ + if (!audioBufIdx && !flashPlay) + if (power_on_reset_delay) /* XXX to move to a proper loop or timer after or before main() */ { uint8_t tmp; @@ -398,13 +450,15 @@ // battery_level = PIND; sendSensors(); PORTD &= ~_BV(PD0); /* set the IR power low */ - test_mode = AT_AUDIOLINK; /* go to audio link mode */ + test_mode = AT_AUDIOLINK; /* go to audio link mode */ } if (info_flg) - send_info(); /* send information to the computer */ - if (sleep_flg) - sleep(); /* send information to the computer */ + send_info(); /* send information to the computer */ + + /* Sleep mode */ + if (pre_sleep_delay == 1) + sleep(); } } @@ -434,7 +488,7 @@ else { #ifndef MIC_GAIN -#define MIC_GAIN 0 /* default value if not declared in the makefile */ +#define MIC_GAIN 0 /* default value if not declared in the makefile */ #endif #if (MIC_GAIN == 6) /* MEDIUM GAIN MODE */ |