Author: jaguarondi
Date: 2008-08-19 16:43:58 +0200 (Tue, 19 Aug 2008)
New Revision: 1555
Modified:
firmware/tuxaudio/branches/demo/Makefile
firmware/tuxaudio/branches/demo/flash.c
firmware/tuxaudio/branches/demo/flash.h
firmware/tuxaudio/branches/demo/main.c
firmware/tuxaudio/branches/demo/parser.c
firmware/tuxaudio/branches/demo/varis.c
firmware/tuxaudio/branches/demo/varis.h
Log:
* Added playback capability and fixes a few things in recording. Seems to work
now.
Usage:
- send the erase command:
tux.cmd.raw(0x54,0,0,0) # ERASE
- you can now test your sequence, tux will react noramlly except buttons
are inactive.
- send the STORE command:
tux.cmd.raw(0x52,0,0,0) # STORE
- play your sequence, tux will stay inactive but will record everything,
sound, tts and commands
- send the STOP command:
tux.cmd.raw(0x53,0,0,0) # STOP
Playback will start immediately. If you hit the end of the storage before
sending STOP, a STOP is stored automatically. Playback will start and tux
will behave strangely as the end of your sequence (which is still playing)
will be mixed with the beginning of the playback.
Modified: firmware/tuxaudio/branches/demo/Makefile
===================================================================
--- firmware/tuxaudio/branches/demo/Makefile 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/Makefile 2008-08-19 14:43:58 UTC (rev
1555)
@@ -187,7 +187,7 @@
# Programming
prog: $(PROJECT).hex
- tuxup $(PROJECT).hex $(PROJECT).eep
+ tuxup -kr $(PROJECT).hex $(PROJECT).eep
progisp: $(PROJECT).hex $(PROJECT).eep
$(AVRDUDE) -p $(MCU) -c jtag2isp -P usb -B 10 -e -U
flash:w:$(PROJECT).hex -U eeprom:w:$(PROJECT).eep
Modified: firmware/tuxaudio/branches/demo/flash.c
===================================================================
--- firmware/tuxaudio/branches/demo/flash.c 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/flash.c 2008-08-19 14:43:58 UTC (rev
1555)
@@ -31,16 +31,8 @@
#include "common/api.h"
/* Declarations */
-static void init_programming(uint8_t adi0, uint8_t adi1, uint8_t adi2, uint8_t
data);
-static void playInit(uint8_t const nsound);
-static void playingSound(void);
-static void stopPlaying(void);
-
-uint8_t flash_state;
uint8_t soundNum;
-static uint8_t count, ad0, ad1;
-
/**
* \ingroup flash
\brief Check if the flash is programmed or not.
@@ -48,53 +40,19 @@
uint8_t checkFlashState(void)
{
- if (read_data(0x00, 0x00, 0x01) == 0xFF)
+ if (read_data(0x00, 0x00, 0x00) == 0xFF)
return 0;
else
return 1;
}
-/**
- * \ingroup flash
- \brief Store a sound in the memory.
+bool static first_read = true;
- This function contain 5 states :
-
- DETECT_INDEXES : Detect if the memory is empty or not, and determine where
the sound must be stored.
-
- PROG_INIT : Start the programmation cycle with the indexes determinated in
the first state.
-
- PROGRAMMING : Program the memory with the sound byte received by the RF.
-
- PROG_TOC : If the programming sequence is finished, the indexes are written.
-
- PROG_END : Restore the context.
-
- \note Each sound starts at the first byte of a 4kB block. To do this, the
- lower address byte is reset, and the medium address byte is incremented.
-
-*/
-
#define FLASH_CMD_SIZE 5
#define FLASH_CMD 0x00
-void programming(void)
-{
- uint8_t cmd[CMD_SIZE+1] = {FLASH_CMD};
- if (flashPlay || (ad[0] == 0x07 && ad[1] == 0xFF))
- /* Last block of the flash, stop here */
- {
- /* XXX write the end of sequence command at the end of the flash */
- queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, FLASH_FULL, 1, 0);
- queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, ad[0], ad[1], ad[2]);
- programmingFlash = 0;
- flashPlay = 1;
- return;
- }
-
- /* Store commands in flash */
- while (pop_core_cmd(&cmd[1]))
- {
+static void store_flash_cmd(uint8_t *cmd)
+{
uint8_t i;
for (i=0; i<CMD_SIZE+1; i++)
{
@@ -113,8 +71,35 @@
while (read_status() & BUSY) ;
}
queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, cmd[1], cmd[2], cmd[3]);
+}
+
+void programming(void)
+{
+ uint8_t cmd[CMD_SIZE+1] = {FLASH_CMD};
+
+ TIMSK0 = 0x00;
+
+ /* Store commands in flash */
+ while (pop_core_cmd(&cmd[1]))
+ {
+ store_flash_cmd(cmd);
}
+ /* Check for stop condition */
+ if (flashPlay || (ad[0] == 0x07 && ad[1] == 0xFF))
+ {
+ cmd[1] = END_CMD;
+ store_flash_cmd(cmd);
+ queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, ad[0], ad[1], ad[2]);
+ first_read = true;
+ queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, FLASH_FULL, 1, 0);
+ TIMSK0 = 0x01;
+ write_disable();
+ programmingFlash = 0;
+ flashPlay = 1;
+ return;
+ }
+
/* Store sound in flash */
while (!spi_start)
{
@@ -148,7 +133,7 @@
}
/**
- * \ingroup flash
+ \ingroup flash
\brief Erase the flash memory.
The first step is to send the command to erase the flash.
@@ -172,220 +157,70 @@
queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, STANDBY, 0, 0);
TIMSK0 = 0x01;
FifoClear(PWMFifo);
- /* Initialize the flash address */
- init_programming(0, 0, 0, 0);
- ad[0] = 0x00;
- ad[1] = 0x00;
- ad[2] = 0x01;
}
}
/**
- * \ingroup flash
- \brief This function is used to play a sound from the flash memory.
+ \ingroup flash
+ \brief Plays the sequence recorded in flash.
+ */
- The first step (playInit) is to initialize the flash memory with the
selected sound to play.
- Many tests are made to ensure that the sound to play exist, the indexes are
correct, etc.
-
- The second step (playingSound) is to fill the fifo with the sound's bytes,
and to verify the addresses.
- */
-
-
void playSound(void)
{
- if (flash_state)
- playInit(soundToPlay);
- else
- playingSound();
-}
+ uint8_t cmd[CMD_SIZE];
-/* Static functions */
-/**
- * \ingroup flash
- \brief This function is used to init the memory to play a sound.
- \param nsound Track number to be played.
-
- To prevent bugs, some verifications are made :
- - check if the sound to play exist
- - check if the sound to play is not null
- - check if the indexes are correct. (the address exist, and the start and
end indexes are not the same.
-
- If these conditions are respected, the memory is initialised with the
first sound's byte address.
- The next index is stored to identify the end of the sound track.
-*/
-
-static void playInit(uint8_t const nsound)
-{
- uint8_t i;
-
- if (numSound == 0x00) /* if unprogrammed we have 0xFF stored in flash */
+ if (first_read)
{
- flashPlay = 0;
- soundToPlay = 0;
- return;
+ first_read = false;
+ flash_unselect();
+ flash_enable();
+ flash_select(); // Chip Select
+ spiSend(READ_ARRAY_LOW_F); // Send Read Page Command
+ spiSend(0); // Send Address
+ spiSend(0);
+ spiSend(1);
+ queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, 0xFF, 0xFF, 0xFF);
+ queue_rf_cmd_p(STATUS_AUDIO_CMD, 1, 0, 0);
+ OCR0A = 250; // Normal operation for PWM if fifo
adaptative is on
}
- if (!nsound || (nsound > numSound)) /* check the limits */
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- }
- count = 1;
- ad1 = 0x00;
- ad0 = 0x01;
- while (count != nsound) // Compute address
+ bool exit = false;
+ while (!exit && !spi_start && !FifoFull(PWMFifo))
{
- for (i = 0; i < 3; i++)
+ uint8_t data;
+ data = spiSend(0x00); // Wait response
+ /* Parse commands */
+ if (data == FLASH_CMD)
{
- ad0++;
- if (ad0 == 0)
- ad1++;
- }
- count++;
- }
- flash_select(); // Chip Select
- spiSend(READ_ARRAY_LOW_F); // Send Read Page Command
- spiSend(0x00); // Send Address
- spiSend(ad1);
- spiSend(ad0);
-
- for (i = 0; i < 6; i++)
- {
- ad[i] = spiSend(NOP); // Read start and stop sound address
- }
- if (nsound > 1)
- {
- ad[1] += 0x10;
- ad[1] &= ~0x0F;
- if (ad[1] == 0)
- ad[0] ++;
- ad[2] = 0;
- }
-
- flash_unselect(); // Chip Deselect
-
- /* Check addresses */
- if (ad[0] > TOP_A2)
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- } /* don't read outside the flash */
- if (ad[3] > TOP_A2)
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- } /* don't read outside the flash */
- if ((ad[0] == 0) && (ad[1] < 0x04))
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- } /* minimum index not respected */
- if ((ad[4] == 0) && (ad[5] < 0x04))
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- } /* minimum index not respected */
- if (ad[3] < ad[0])
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- } /* check that the stop index is greater than the start index */
- else if (ad[3] == ad[0])
- {
- if (ad[4] < ad[1])
- {
- flashPlay = 0;
- soundToPlay = 0;
- return;
- }
- else if (ad[4] == ad[1])
- {
- if (ad[5] <= ad[2])
+ cmd[0] = spiSend(0);
+ cmd[1] = spiSend(0);
+ cmd[2] = spiSend(0);
+ cmd[3] = spiSend(0);
+ queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, cmd[0], cmd[1], cmd[2]);
+ if (cmd[0] == END_CMD)
{
- flashPlay = 0;
- soundToPlay = 0;
- return;
+ first_read = true;
+ exit = true;
}
- }
- }
- FifoClear(PWMFifo);
- flash_select(); // Chip Select
-
- spiSend(0x03); // Send Read Page Command
- spiSend(ad[0]); // Send Address
- spiSend(ad[1]);
- spiSend(ad[2]);
-
- OCR0A = 250; // Normal operation for PWM if fifo adaptative
is on
- flash_state = 0;
- queue_rf_cmd_p(STATUS_AUDIO_CMD, numSound, 0, 0);
-}
-
-/* Static functions */
-/**
- * \ingroup flash
- \brief Read the flash memory and fill the fifo.
-
- This function reads bytes into the flash memory and fill the fifo.
- When the last byte is read, the sound play's sequence is stopped.
- */
-
-static void playingSound(void)
-{
- uint8_t sound;
- while (!spi_start && !FifoFull(PWMFifo))
- {
- sound = spiSend(0x00); // Wait response
- sound = sound >> audioLevel;
- FifoPut(PWMFifo, sound);
-
- ad[2]++; // Increment address for next play
- if (ad[2] == 0)
- {
- ad[1]++;
- if (ad[1] == 0)
+ else if (cmd[0] == WAIT_CMD)
{
- ad[0]++;
- if (ad[0] == 0x08) // Address overflow
- {
- stopPlaying();
- break;
- }
+ silence = (cmd[2]<<8) + cmd[1];
+ exit = true;
}
+ else
+ {
+ queue_core_cmd(cmd);
+ }
}
- if (ad[0] == ad[3]) // Test end of sound
- if (ad[1] == ad[4])
- if (ad[2] == ad[5])
- {
- stopPlaying();
- break;
- }
+ else
+ {
+ FifoPut(PWMFifo, data);
+ }
}
}
-/* Static functions */
/**
* \ingroup flash
- \brief Stop the play sequence.
-
- */
-static void stopPlaying(void)
-{
- soundToPlay = 0;
- flashPlay = 0;
- queue_rf_cmd_p(STATUS_AUDIO_CMD, 0, 0, 0);
- PORTB |= 0x01; // Set the HOLD signal
- PORTB |= 0x02; // Chip Deselect
-}
-
-/**
- * \ingroup flash
\brief Init the programming sequence
To perform a sequential programming, the first step is to send the correct
OP
@@ -394,14 +229,20 @@
This function perform the first step.
*/
-static void init_programming(uint8_t adi0, uint8_t adi1, uint8_t adi2, uint8_t
data)
+void init_programming(void)
{
write_enable();
flash_select();
spiSend(SEQU_PROGRAM);
- spiSend(adi0);
- spiSend(adi1);
- spiSend(adi2);
- spiSend(data);
+ spiSend(0);
+ spiSend(0);
+ spiSend(0);
+ /* Save '0' at first position to indicate flash has a record */
+ spiSend(0);
flash_unselect(); // Chip Deselect
+ first_read = true;
+ /* Start recording at position 1 */
+ ad[0] = 0;
+ ad[1] = 0;
+ ad[2] = 1;
}
Modified: firmware/tuxaudio/branches/demo/flash.h
===================================================================
--- firmware/tuxaudio/branches/demo/flash.h 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/flash.h 2008-08-19 14:43:58 UTC (rev
1555)
@@ -68,6 +68,7 @@
*/
/* @} */
+extern void init_programming(void);
extern void programming(void);
extern void playSound(void);
extern void erase(void);
Modified: firmware/tuxaudio/branches/demo/main.c
===================================================================
--- firmware/tuxaudio/branches/demo/main.c 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/main.c 2008-08-19 14:43:58 UTC (rev
1555)
@@ -173,7 +173,7 @@
/* Send commands to I2C, otherwise get new status from tuxcore */
communication_task();
- if (flashPlay)
+ if (flashPlay && !silence)
playSound();
}
@@ -239,54 +239,23 @@
*/
ISR(SIG_OVERFLOW0)
{
+ uint8_t static silence_prescale = 0;
- ADCSRA |= 0x40; // ADC started at XXX a laisser la ??
- if (--sampling_pwm == 0) /* timer 0 is clocked at 32KHz so we divide it
by 4 to get 8KHz */
+ if (--sampling_pwm == 0) /* timer 0 is clocked at 32KHz so we divide it by
4 to get 8KHz */
{
- sampling_pwm = 0x04; /* reinit counter */
+ sampling_pwm = 0x04; /* reinit counter */
-#ifndef MIC_GAIN
-#define MIC_GAIN 0 /* default value if not declared in the makefile */
-#endif
-#if (MIC_GAIN == 6)
- /* MEDIUM GAIN MODE */
- uint8_t tmp;
-
- /* Audio in: microphone */
- tmp = ADCL;
- tmp = tmp >> 1;
- if (!(ADCH & 0x01)) /* AND the 9th bit then add 0x80 is equivalent to
AND the complement of the 9th bit */
- tmp |= 0x80;
- FifoPut(ADCFifo, tmp);
- /* HIGH GAIN MODE */
-#elif (MIC_GAIN == 12)
- uint8_t tmp;
-
- tmp = ADCL + 0x80;
- FifoPut(ADCFifo, tmp);
- asm volatile ("lds __tmp_reg__, %0"::"M" (_SFR_MEM_ADDR(ADCH))); /*
ADCH needs to be read for the next acquisition */
-#else /* (MIC_GAIN == 0) or anything else */
- /* LOW GAIN MODE */
- if (ADCH == 0) /* XXX RF looses connection if too much '0' are
sent, but the noise should normally be enough to avoid that */
- FifoPut(ADCFifo, 0x01);
- else
- FifoPut(ADCFifo, ADCH);
-#endif
-
- if (!FifoGet(PWMFifo, (uint8_t *)&OCR0B)) /* set the sample value to
timer pulse width */
- {
- if (tuxaudio_config.automute) /* XXX mute functions should not
be called here each time a sample is placed, this is silly */
- unmute_amp();
- }
- else
- {
- if (tuxaudio_config.automute)
- mute_amp();
- }
+ FifoGet(PWMFifo, (uint8_t *)&OCR0B); /* set the sample value to timer
pulse width */
/* XXX we should move this timer away from here */
/* send status to the behavioural CPU, 8KHz divided by 256 lead to a
* status sent each 32ms */
if (--sendSensorsCmpt == 0)
sendSensorsFlag = 1;
+ if (silence_prescale-- == 0)
+ {
+ silence_prescale = 32;
+ if (silence)
+ silence--;
+ }
}
}
Modified: firmware/tuxaudio/branches/demo/parser.c
===================================================================
--- firmware/tuxaudio/branches/demo/parser.c 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/parser.c 2008-08-19 14:43:58 UTC (rev
1555)
@@ -67,10 +67,10 @@
else if (cmd[0] == STORE_SOUND_CMD)
{
flashPlay = 0;
- flash_state = 1; /* Erasing flash flag */
programmingFlash = 1; /* Set the flag to enter programming sequence */
queue_rf_cmd_p(STATUS_FLASH_PROG_CMD, IN_PROGRESS, 1, 0);
initCommunicationBuffers();
+ init_programming();
}
else if (cmd[0] == ERASE_FLASH_CMD)
{
Modified: firmware/tuxaudio/branches/demo/varis.c
===================================================================
--- firmware/tuxaudio/branches/demo/varis.c 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/varis.c 2008-08-19 14:43:58 UTC (rev
1555)
@@ -24,6 +24,7 @@
// PWM Variable
unsigned char sampling_pwm = 0x04;
+uint16_t silence;
// SPI Variable
volatile unsigned char spi_enable = 1;
Modified: firmware/tuxaudio/branches/demo/varis.h
===================================================================
--- firmware/tuxaudio/branches/demo/varis.h 2008-08-19 06:43:31 UTC (rev
1554)
+++ firmware/tuxaudio/branches/demo/varis.h 2008-08-19 14:43:58 UTC (rev
1555)
@@ -26,6 +26,7 @@
// PWM Variable
extern unsigned char sampling_pwm;
+extern uint16_t silence;
// SPI Variable
extern volatile unsigned char spi_enable;
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Tux-droid-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tux-droid-svn