[tuxdroid-svn] r489 - firmware/tuxaudio/branches/audio_cleanup
Status: Beta
Brought to you by:
ks156
From: Paul_R <c2m...@c2...> - 2007-09-06 11:58:07
|
Author: Paul_R Date: 2007-09-06 13:58:06 +0200 (Thu, 06 Sep 2007) New Revision: 489 Modified: firmware/tuxaudio/branches/audio_cleanup/flash.c firmware/tuxaudio/branches/audio_cleanup/flash.h firmware/tuxaudio/branches/audio_cleanup/main.c firmware/tuxaudio/branches/audio_cleanup/spi.c Log: The functions to write in the flash memory has been changed. The programming sequence has been splitted. A state machine control the all the process. ASM code has been removed. INT0 routine is now correctly executed... Modified: firmware/tuxaudio/branches/audio_cleanup/flash.c =================================================================== --- firmware/tuxaudio/branches/audio_cleanup/flash.c 2007-09-06 11:35:14 UTC (rev 488) +++ firmware/tuxaudio/branches/audio_cleanup/flash.c 2007-09-06 11:58:06 UTC (rev 489) @@ -31,52 +31,55 @@ void erase_flash(void); unsigned char read_data(unsigned char ad2, unsigned char ad1, unsigned char ad0); -void programmingAudio(void); +//void programmingAudio(void); void unprotect_sector(unsigned char ad2, unsigned char ad1, unsigned char ad0); void playingAudio(unsigned char nsound); void stopPlayingAudio(void); +uint8_t flash_state; + unsigned char read_status(void) { unsigned char status; - PORTB &= ~0x02; // Chip Select + PORTB &= ~0x02; /* Chip Select */ - spiSend(0x05); // Send Read Status Command - status = spiSend(0x00); // Read status on spi + spiSend(0x05); /* Send Read Status Command */ - PORTB |= 0x02; // Chip Deselect + status = spiSend(0x00); /* Read status on spi */ + PORTB |= 0x02; /* Chip Deselect */ + return status; } void write_enable(void) { - PORTB &= ~0x02; // Chip Select + PORTB &= ~0x02; /* Chip Select */ - spiSend(0x06); // Send Write Enable Command + spiSend(0x06); /* Send Write Enable Command */ - PORTB |= 0x02; // Chip Deselect + PORTB |= 0x02; /* Chip Deselect */ } void write_disable(void) { - PORTB &= ~0x02; // Chip Select + PORTB &= ~0x02; /* Chip Select */ - spiSend(0x04); // Send Write Disable Command + spiSend(0x04); /* Send Write Disable Command */ - PORTB |= 0x02; // Chip Deselect + PORTB |= 0x02; /* Chip Deselect */ } void write_status(unsigned char status) { - PORTB &= ~0x02; // Chip Select + PORTB &= ~0x02; /* Chip Select */ - spiSend(0x01); // Send Write Status Command - spiSend(status); // Send status + spiSend(0x01); /* Send Write Status Command */ + spiSend(status); /* Send status */ - PORTB |= 0x02; // Chip Deselect + PORTB |= 0x02; /* Chip Deselect */ } @@ -126,8 +129,6 @@ spiSend(0xC7); // Send Erase Bulk command PORTB |= 0x02; // Chip Deselect - - while (read_status() != 0x10) ; // Wait Bulk Erase Cycle } void program_flash(unsigned char ad2, unsigned char ad1, unsigned char ad0, @@ -165,10 +166,16 @@ return data1; } -void programmingAudio(void) +/** + * \ingroup flash + * \brief Erase the flash memory. + * This funtion perform a full erase of the flash memory. + */ + + +unsigned char ad0, ad1, ad2, i, j; +void erasingFlash(void) { - unsigned char ad0, ad1, ad2, i, j; - TCCR0A = 0x00; // Desactivate PWM TCCR0B = 0x00; OCR0A = 0x00; @@ -176,62 +183,92 @@ TWCR = (TWCR & TWCR_CMD_MASK) & ~_BV(TWIE); // Desactivate I2C - // Deactivate all interrupt - resetFifo(&PWMFifo); /* Reinitialise the PWM fifo */ programmingFlash = 1; // Set the flag to suspend the task - // First step ERASE FLASH erase_flash(); // Erase the flash +} +/** + * \ingroup flash + * \brief Write the number of sound to be stored. + * This function store the first TOC byte (numSound), received with the flash + * program command, at the first memory adress. + */ - // Second step WRITE FIRST BYTE OF TOC +void programmingNumSound(void) +{ program_flash(0x00, 0x00, 0x00, numSound); // Write first byte of the TOC - // Third step WRITE TOC + ad0 = 0x01; // Init TOC address ad1 = 0x00; ad2 = 0x00; - for (i = 0; i <= numSound; i++) // Writing TOC + i = 0; +} +/** + * \ingroup flash + * \brief Write the TOC in the memory. + * This function store the the indexes into the memory. + */ + +void programmingToc(void) +{ + TOCRX = 0; + flash_state = 0; + for (j = 0; j < 3; j++) { - while (!TOCRX) ; // Wait TOC address incomming - TOCRX = 0; // Reset TOC incomming flag + program_flash(ad2, ad1, ad0, TOCadress[j]); + ad0++; // Increment new adress + if (ad0 == 0x00) + ad1++; + } + i++; - for (j = 0; j < 3; j++) - { - program_flash(ad2, ad1, ad0, TOCadress[j]); - ad0++; // Increment new adress - if (ad0 == 0x00) - ad1++; - } + if (i == numSound + 1) + { + ad[0] = TOCadress[2]; // Save final addres + ad[1] = TOCadress[1]; + ad[2] = TOCadress[0]; + + ad2 = 0x00; // Init sound address + ad1 = 0x04; + ad0 = 0x00; + + flash_state = 1; } +} - ad[0] = TOCadress[2]; // Save final addres - ad[1] = TOCadress[1]; - ad[2] = TOCadress[0]; - - // Fourth step WRITE SOUND - ad2 = 0x00; // Init sound address - ad1 = 0x04; - ad0 = 0x00; +void initSoundProgramming (void) +{ + flash_state = 0; write_enable(); PORTB &= ~0x02; // Chip Select spiSend(0xAF); // Send Sequencial Program Command spiSend(ad2); // Send Address spiSend(ad1); spiSend(ad0); - while (1) // Send first byte into the page flash + + while (!spi_start) // Send first byte into the page flash { if (!isFifoEmpty(&PWMFifo)) // Fifo not empty { spiSend(pullFifo(&PWMFifo)); // Write data in flash ad0++; - break; // End of firt command + flash_state = 1; // End of firt command + break; } + else + flash_state = 0; } PORTB |= 0x02; // Chip Deselect - while (read_status() != 0x52) ; // Wait Page Program Cycle - while (1) +} + +void soundProgramming(void) +{ + flash_state = 0; + // Fourth step WRITE SOUND + while (!spi_start) { if (!isFifoEmpty(&PWMFifo)) // Fifo not empty { @@ -248,20 +285,26 @@ } while (read_status() != 0x52) ; // Wait Page Program Cycle } + + /* Check for the last sound byte */ if (ad2 == ad[2]) { if (ad1 == ad[1]) { if (ad0 == ad[0]) { + flash_state = 1; break; // Stop programming flash } } } } +} +void endProgramming (void) +{ write_disable(); // Disable wrtie flash - + flash_state = 0; TCCR0A = 0x23; // Reactivate PWM TCCR0B = 0x09; OCR0A = 249; /* we need TOP=250 to get a 8kHz sampling frequency */ @@ -269,8 +312,6 @@ TWCR = (TWCR & TWCR_CMD_MASK) | _BV(TWIE); // Reactivate I2C - // Reactivate all interrupt - programmingFlash = 0; // Reset the flag to suspend the task } Modified: firmware/tuxaudio/branches/audio_cleanup/flash.h =================================================================== --- firmware/tuxaudio/branches/audio_cleanup/flash.h 2007-09-06 11:35:14 UTC (rev 488) +++ firmware/tuxaudio/branches/audio_cleanup/flash.h 2007-09-06 11:58:06 UTC (rev 489) @@ -19,6 +19,22 @@ /* $Id: */ +/** \defgroup flash Flash memory + \ingroup flash + + This module control all the functions to read / write the flash memory. +*/ + +/** \file flash.h + \ingroup flash +*/ +/** \file flash.c + \ingroup flash +*/ + + + + #ifndef FLASH_H #define FLASH_H @@ -29,10 +45,18 @@ extern void erase_flash(void); extern unsigned char read_data(unsigned char ad2, unsigned char ad1, unsigned char ad0); -extern void programmingAudio(void); +//extern void programmingAudio(void); extern void unprotect_sector(unsigned char ad2, unsigned char ad1, unsigned char ad0); extern void playingAudio(unsigned char nsound); extern void stopPlayingAudio(void); +extern void erasingFlash(void); +extern void programmingNumSound(void); +extern void programmingToc(void); +extern void initSoundProgramming(void); +extern void soundProgramming(void); +extern void endProgramming(void); + +extern uint8_t flash_state; #endif Modified: firmware/tuxaudio/branches/audio_cleanup/main.c =================================================================== --- firmware/tuxaudio/branches/audio_cleanup/main.c 2007-09-06 11:35:14 UTC (rev 488) +++ firmware/tuxaudio/branches/audio_cleanup/main.c 2007-09-06 11:58:06 UTC (rev 489) @@ -39,6 +39,7 @@ * Version number */ +uint8_t f_state = 0; #define CPU_NUMBER TUXAUDIO_CPU_NUM /* audio CPU */ const author_t author __attribute__ ((section("version.3"))) = { @@ -122,7 +123,7 @@ */ #define DBG_STACK 1 -void SIG_INTERRUPT0(void) __attribute__ ((signal, naked)); +//void SIG_INTERRUPT0(void) __attribute__ ((signal, naked)); #if (DBG_STACK) /* @@ -169,6 +170,7 @@ else unmute_amp(); } + else if (audioBuf[0] == SLEEP_CMD) { pre_sleep_delay = 30; /* handle sleep in its own function */ @@ -194,10 +196,12 @@ { /* param: command[1] : number of sounds */ numSound = command[1]; - programmingAudio(); + f_state = 0; + erasingFlash(); } else if (command[0] == STORE_INDEX_CMD) { + /* param: command[1] : lower address byte */ /* command[2] : middle address byte */ /* command[3] : higher address byte */ @@ -205,6 +209,7 @@ TOCadress[1] = command[2]; // Medium address TOCadress[0] = command[1]; // Lower address TOCRX = 1; // Set TOC incoming flag + command[0] = 0; } /* Version */ @@ -235,6 +240,12 @@ command[3] = battery_level; pushCommands(command); /* push the command set on the filo stack */ } +#define ERASE_STATE 0 +#define FIRST_PROG_STATE 1 +#define PROG_TOC_STATE 2 +#define INIT_SOUND_PROG_STATE 3 +#define SOUND_PROG_STATE 4 +#define END_STATE 5 int main(void) { @@ -277,7 +288,7 @@ while (1) /* Inifinite main loop */ { - asm volatile ("SPITRANSACTION: \n\t"); + // asm volatile ("SPITRANSACTION: \n\t"); sei(); // Reactivate global interrupt in case of flash programmation if (!flashPlay) @@ -290,90 +301,125 @@ if (programmingFlash) // Restora all the context for flash programming { - asm volatile ("cli \n\t" "ldi r24, 0x00 \n\t" // SPCR=0x00; // Reset SPI to avoy any trace of previous transactions - "out 0x2c, r24 \n\t" "ldi r24, 0x50 \n\t" // SPCR=0x50; - "out 0x2c, r24 \n\t" "pop r31 \n\t" // Restore all the context - "pop r30 \n\t" "pop r29 \n\t" "pop r28 \n\t" "pop r27 \n\t" "pop r26 \n\t" "pop r25 \n\t" "pop r23 \n\t" "pop r22 \n\t" "pop r21 \n\t" "pop r20 \n\t" "pop r19 \n\t" "pop r18 \n\t" "pop r17 \n\t" "pop r16 \n\t" "pop r15 \n\t" "pop r14 \n\t" "pop r13 \n\t" "pop r12 \n\t" "pop r11 \n\t" "pop r10 \n\t" "pop r9 \n\t" "pop r8 \n\t" "pop r7 \n\t" "pop r6 \n\t" "pop r5 \n\t" "pop r4 \n\t" "pop r3 \n\t" "pop r2 \n\t" "pop r24 \n\t" "pop r0 \n\t" "out 0x3f, r0 \n\t" // Restore SREG - "pop r0 \n\t" "pop r1 \n\t" "sbi 0x05, 0 \n\t" // PORTB |= 0x01; // Set the HOLD signal - "sei \n\t" "reti \n\t"); + SPCR = 0x00; + SPCR = 0X50; + PORTB |= 0x01; + if (f_state == ERASE_STATE) + { + if (read_status() == 0x10) + f_state ++; + } + else if (f_state == FIRST_PROG_STATE) + { + programmingNumSound(); + f_state ++; + } + else if (f_state == PROG_TOC_STATE) + { + if (TOCRX) + programmingToc(); + if (flash_state) + f_state ++; + } + else if (f_state == INIT_SOUND_PROG_STATE) + { + initSoundProgramming(); + if (flash_state) + f_state ++; + } + if (f_state == SOUND_PROG_STATE) + { + soundProgramming(); + + if (flash_state) + f_state ++; + } + else if (f_state == END_STATE) + { + endProgramming(); + f_state = 0; + } } - - if (flashPlay) + else { - cli(); - if (!isFifoFull(&PWMFifo)) + if (flashPlay) { - PORTB |= 0x01; // Set the HOLD signal - sound = spiSend(0x00); // Wait response - PORTB &= ~0x01; // Reset the HOLD signal - sound = sound >> audioLevel; - pushFifo(&PWMFifo, sound); + cli(); + if (!isFifoFull(&PWMFifo)) + { + PORTB |= 0x01; // Set the HOLD signal + sound = spiSend(0x00); // Wait response + PORTB &= ~0x01; // Reset the HOLD signal + sound = sound >> audioLevel; + pushFifo(&PWMFifo, sound); - ad[2]++; // Increment address for next play - if (ad[2] == 0) - { - ad[1]++; - if (ad[1] == 0) + ad[2]++; // Increment address for next play + if (ad[2] == 0) { - ad[0]++; - if (ad[0] == 0x08) // Address overflow - stopPlayingAudio(); + ad[1]++; + if (ad[1] == 0) + { + ad[0]++; + if (ad[0] == 0x08) // Address overflow + stopPlayingAudio(); + } } + if (ad[0] == ad[3]) // Test end of sound + if (ad[1] == ad[4]) + if (ad[2] == ad[5]) + stopPlayingAudio(); } - if (ad[0] == ad[3]) // Test end of sound - if (ad[1] == ad[4]) - if (ad[2] == ad[5]) - stopPlayingAudio(); + sei(); } - sei(); - } - if (sendSensorsFlag) - { - sendSensorsFlag = 0; - if (pre_sleep_delay > 1) - /* There's a delay before the sleep function is actually called - * otherwise other commands on the stack can't be executed */ - pre_sleep_delay--; - /* stop sending sensor status in sleep as the i2C should be - * stopped at this time */ - else - sendSensors(); - /* wait for all status to be sent before going to sleep */ - /* TODO fix these conditions for the sleep */ - //if (isFifoEmpty(statusFifo)) + if (sendSensorsFlag) + { + sendSensorsFlag = 0; + if (pre_sleep_delay > 1) + /* There's a delay before the sleep function is actually called + * otherwise other commands on the stack can't be executed */ + pre_sleep_delay--; + /* stop sending sensor status in sleep as the i2C should be + * stopped at this time */ + else + sendSensors(); + /* wait for all status to be sent before going to sleep */ + /* TODO fix these conditions for the 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 volatile j; + if (power_on_reset_delay) /* XXX to move to a proper loop or timer after or before main() */ + { + uint8_t volatile j; - DDRD |= 0x02; - for (j = 0; j < 0xFF; j++) ; - power_on_reset_delay--; - if (!power_on_reset_delay) - { - /* Set the microphone power */ DDRD |= 0x02; + for (j = 0; j < 0xFF; j++) ; + power_on_reset_delay--; + if (!power_on_reset_delay) + { + /* Set the microphone power */ + DDRD |= 0x02; + } + else + DDRD &= ~0x02; } - else - DDRD &= ~0x02; } - } - sendCommands(); /* Send commands on I2C */ - if (audioBufIdx) - audioIntParser(); + sendCommands(); /* Send commands on I2C */ - /* Send information to the computer. */ - if (info_flg) - send_info(); + if (audioBufIdx) + audioIntParser(); - /* Sleep mode */ - if (pre_sleep_delay == 1) - sleep(); + /* Send information to the computer. */ + if (info_flg) + send_info(); + + /* Sleep mode */ + if (pre_sleep_delay == 1) + sleep(); + } } } @@ -441,24 +487,13 @@ //OCR0A = 250; // Normal operation for ADC sampling if FIFO Adaptative is on } } - if (--sendSensorsCmpt == 0) + if (--sendSensorsCmpt == 0) sendSensorsFlag = 1; /* send status to the behavioural CPU, 8KHz divided by 256 lead to a status sent each 32ms */ } } // External Interrupt 0 service routine PD2 -void SIG_INTERRUPT0(void) +ISR(SIG_INTERRUPT0) { - asm volatile ("push r1 \n\t" "push r0 \n\t" "in r0, 0x3f \n\t" // Save SREG - "push r0 \n\t" "eor r1, r1 \n\t" "push r24 \n\t" "lds r24, programmingFlash \n\t" // if (programmingFlash) - "and r24, r24 \n\t" // { - "breq SETFLAGINT \n\t" "push r2 \n\t" // Save all the context - "push r3 \n\t" // Executing time of all push guarantee that spi transaction is correctly finish - "push r4 \n\t" "push r5 \n\t" "push r6 \n\t" "push r7 \n\t" "push r8 \n\t" "push r9 \n\t" "push r10 \n\t" "push r11 \n\t" "push r12 \n\t" "push r13 \n\t" "push r14 \n\t" "push r15 \n\t" "push r16 \n\t" "push r17 \n\t" "push r18 \n\t" "push r19 \n\t" "push r20 \n\t" "push r21 \n\t" "push r22 \n\t" "push r23 \n\t" "push r25 \n\t" "push r26 \n\t" "push r27 \n\t" "push r28 \n\t" "push r29 \n\t" "push r30 \n\t" "push r31 \n\t" "ldi r24, 0x01 \n\t" // spi_start = 1; // Set the flag SPI ready from RF - "sts spi_start, r24 \n\t" "cbi 0x05, 0 \n\t" // PORTB &= ~0x01; // Reset the HOLD signal - "rjmp SPITRANSACTION \n\t" // } - "SETFLAGINT: \n\t" // else - "ldi r24, 0x01 \n\t" // spi_start = 1; // Set the flag SPI ready from RF - "sts spi_start, r24 \n\t" "pop r24 \n\t" "pop r0 \n\t" - "out 0x3f, r0 \n\t" "pop r0 \n\t" "pop r1 \n\t" "reti \n\t"); + spi_start = 1; } Modified: firmware/tuxaudio/branches/audio_cleanup/spi.c =================================================================== --- firmware/tuxaudio/branches/audio_cleanup/spi.c 2007-09-06 11:35:14 UTC (rev 488) +++ firmware/tuxaudio/branches/audio_cleanup/spi.c 2007-09-06 11:58:06 UTC (rev 489) @@ -35,7 +35,8 @@ spi_count = 0; // Reset spi counter spi_slave = HEADERS; // Set state machine spi_master = HEADERM; - + if (programmingFlash) + PORTB &= ~0x01; // Reset SPI to fix strange bug on the spi SPCR = 0x50; SPSR = 0x00; |