/**********************************************************************
* © 2007 Microchip Technology Inc.
*
* FileName: main.c
* Dependencies: Header (.h) files if applicable, see below
* Processor: dsPIC33FJ256GP506
* Compiler: MPLAB® C30 v3.00 or higher
*
************************************************************************/
#include <p33FJ256GP506.h>
#include "..\h\WM8510CodecDrv.h"
#include "..\h\sask.h"
#include "..\h\AT25F4096Drv.h"
#include "..\h\G711.h"
_FGS(GWRP_OFF & GCP_OFF);
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_ON & POSCMD_NONE);
_FWDT(FWDTEN_OFF);
//#define FRAME_SIZE 128 /* Each audio frame will have these many samples */
#define FRAME_SIZE 320 /* Each audio frame will have these many samples */
#define SPEECH_SEGMENT_SIZE 98049L /* Length of the intro message */
#define WRITE_START_ADDRESS 0x20000 /* Flash memory address for user */
/* Allocate memory for buffers and drivers */
int codecBuffer [WM8510DRV_DRV_BUFFER_SIZE];
int samples [FRAME_SIZE];
char encodedSamples [FRAME_SIZE];
int decodedSamples [FRAME_SIZE];
char flashMemoryBuffer [AT25F4096DRV_BUFFER_SIZE];
/* Instantiate the drivers */
WM8510Handle codec;
AT25F4096Handle flashMemoryHandle;
/* Create the driver handles */
WM8510Handle * codecHandle = &codec;
AT25F4096Handle *pFlashMemoryHandle = &flashMemoryHandle;
long currentReadAddress; /* This one tracks the intro message */
long currentWriteAddress; /* This one tracks the writes to flash */
long userPlaybackAddress; /* This one tracks user playback */
int record; /* If set means recording */
int playback; /* If set means playback is in progress */
int erasedBeforeRecord; /* If set means that erase before record*/
/* is complete */
long address; /* Used for erasing the flash */
int main(void)
{
/* Configure Oscillator to operate the device at 40MHz.
* Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
* Fosc= 7.37M*40/(2*2)=80Mhz for 7.37M input clock */
PLLFBD=41; /* M=39 */
CLKDIVbits.PLLPOST=0; /* N1=2 */
CLKDIVbits.PLLPRE=0; /* N2=2 */
OSCTUN=0;
__builtin_write_OSCCONH(0x01); /* Initiate Clock Switch to FRC with PLL*/
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0b01); /* Wait for Clock switch to occur */
while(!OSCCONbits.LOCK);
/* Initialize flags and address variables */
record = 0;
playback = 0;
currentReadAddress = 0;
currentWriteAddress = WRITE_START_ADDRESS;
userPlaybackAddress = WRITE_START_ADDRESS;
address = 0;
erasedBeforeRecord = 0;
/* Intialize the board and the drivers */
SASKInit();
WM8510Init(codecHandle,codecBuffer);
AT25F4096Init (pFlashMemoryHandle,flashMemoryBuffer); /* For the Flash */
/* Start the flash driver functions */
AT25F4096Start (pFlashMemoryHandle);
/* Start Audio input and output function */
WM8510Start(codecHandle);
/* Configure codec for 8K operation */
WM8510SampleRate8KConfig(codecHandle);
/* Main processing loop. Executed for every input and
* output frame */
while(1)
{
/* Obtaing the ADC samples */
while(WM8510IsReadBusy(codecHandle));
WM8510Read(codecHandle,samples,FRAME_SIZE);
// /* Playback the intro message if record or play functions are not active
// * Rewind the currentReadAddress if the message has reached the end */
// if(!record && !playback)
// {
// while(AT25F4096IsBusy(pFlashMemoryHandle));
// AT25F4096Read(pFlashMemoryHandle,currentReadAddress,encodedSamples,FRAME_SIZE);
// while(AT25F4096IsBusy(pFlashMemoryHandle));
// currentReadAddress += FRAME_SIZE;
// if(currentReadAddress >= SPEECH_SEGMENT_SIZE)
// {
// currentReadAddress = 0;
// }
// }
/* If record is enabled, encode the samples using G711.
* Store in flash. Erase flash before recording starts */
if(record == 1)
{
//
// if(erasedBeforeRecord == 0)
// {
// /* Stop the Audio input and output since this is a blocking
// * operation. Also rewind record and playback pointers to
// * start of the user flash area.*/
//
// WM8510Stop(codecHandle);
// currentWriteAddress = WRITE_START_ADDRESS;
// userPlaybackAddress = WRITE_START_ADDRESS;
// RED_LED = SASK_LED_ON;
// YELLOW_LED = SASK_LED_OFF;
//
// /* Erase the user area of the flash. The intro message is not erased */
// for(address = WRITE_START_ADDRESS; address < AT25F4096DRV_LAST_ADDRESS; address += 0x10000)
// {
// /* Erase each sector. Each sector is 0xFFFF long */
// AT25F4096IoCtl(pFlashMemoryHandle,AT25F4096DRV_WRITE_ENABLE,0);
// AT25F4096IoCtl(pFlashMemoryHandle,AT25F4096DRV_SECTOR_ERASE,(void *)&address);
// while(AT25F4096IsBusy(pFlashMemoryHandle));
// }
// RED_LED = SASK_LED_OFF;
//
// /* Since erase is complete, the next time the loop is executed
// * dont erase the flash. Start the audio input and output */
//
// erasedBeforeRecord = 1;
// WM8510Start(codecHandle);
// }
// else
// {
// /* Record the encoded audio frame. Yellow LED turns on when
// * when recording is being performed */
//
YELLOW_LED = SASK_LED_ON;
G711Lin2Ulaw(samples,encodedSamples,FRAME_SIZE); // HR: Turns on the buffering
// while(AT25F4096IsBusy(pFlashMemoryHandle));
// AT25F4096IoCtl(pFlashMemoryHandle,AT25F4096DRV_WRITE_ENABLE,0);
// AT25F4096Write(pFlashMemoryHandle,currentWriteAddress,encodedSamples,FRAME_SIZE);
// currentWriteAddress += FRAME_SIZE;
//
// if(currentWriteAddress >= AT25F4096DRV_LAST_ADDRESS)
// {
//
// YELLOW_LED = SASK_LED_OFF;
// erasedBeforeRecord = 0;
// record = 0;
// playback = 1;
// }
// }
//
}
/* If playback is enabled, then start playing back samples from the
* user area. Playback only till the last record address and then
* rewind to the start */
// if(playback == 1)
// {
// GREEN_LED = SASK_LED_ON;
// erasedBeforeRecord = 0;
// while(AT25F4096IsBusy(pFlashMemoryHandle));
// AT25F4096Read(pFlashMemoryHandle,userPlaybackAddress,encodedSamples,FRAME_SIZE);
// while(AT25F4096IsBusy(pFlashMemoryHandle));
//
// userPlaybackAddress += FRAME_SIZE;
//
// if(userPlaybackAddress >= currentWriteAddress)
// {
// userPlaybackAddress = WRITE_START_ADDRESS;
// }
// }
//
//
//
//
/* Decode the samples */
G711Ulaw2Lin (encodedSamples,decodedSamples, FRAME_SIZE);
/* Wait till the codec is available for a new frame */
// while(WM8510IsWriteBusy(codecHandle)); // HR: Aparrently not needed
/* Write the frame to the output */
WM8510Write (codecHandle,decodedSamples,FRAME_SIZE);
/* The CheckSwitch functions are defined in sask.c */
if((CheckSwitchS1()) == 1)
{
/* Toggle the record function and Yellow led.
* Rewind the intro message playback pointer.
* And if recording, disable playback.*/
record =1; // HR: Important to enable the "if" above
// currentReadAddress = 0;
// erasedBeforeRecord = 0;
if(record == 1)
{
// playback = 0;
GREEN_LED = SASK_LED_OFF;
// }
// else
// {
YELLOW_LED = SASK_LED_OFF;
}
}
if((CheckSwitchS2()) == 1)
{
/* Toggle the record function and AMBER led.
* Rewind the intro message playback pointer.
* And if recording, disable playback.*/
GREEN_LED ^=1;
// playback =1 ;
// userPlaybackAddress = WRITE_START_ADDRESS;
// currentReadAddress = 0;
// if(playback == 1)
// {
// record = 0;
YELLOW_LED = SASK_LED_OFF;
// }
}
}
}