📄 an_gen_6x8_1_c_listing.c
字号:
// a packet of data is always ready when this routine is entered.)
//
// "e", "f" and "g" are the flash address bytes.
// Decode operation is complete when the decode addresses equal the encode addresses.
//********************************
{
unsigned char i;
//Write previously-read-out voice packet to CMX618 decoder
CSN=0; //start streaming C-BUS transaction
wr_byte(DECFRAME); //write address for ENCFRAME register
for(i=0; i<BYTELENGTH; ++i)
wr_byte(CMX618_data[i]);
CSN=1; //end streaming C-BUS transaction
//Read voice packet from flash
read_flash(DECODE_ADDRESS_HIGH, DECODE_ADDRESS_MID, DECODE_ADDRESS_LOW);
//Increment page address for next flash write
if(DECODE_ADDRESS_HIGH==0xFF) //if max address = 0xFF, error condition...turn on Red LED
RED_LED=ON;
if(DECODE_ADDRESS_LOW!=0xD8) //increment low address if not excessive
DECODE_ADDRESS_LOW=DECODE_ADDRESS_LOW + BYTELENGTH;
else //if low address is excessive, do the following...
{
if(DECODE_ADDRESS_MID<0xFF) //if mid address is not excessive (<255), increment mid and reset low
{
DECODE_ADDRESS_LOW=0;
DECODE_ADDRESS_MID++;
}
else //if mid is excessive, increment high and reset mid & low
{
DECODE_ADDRESS_LOW=0;
DECODE_ADDRESS_MID=0;
DECODE_ADDRESS_HIGH++;
}
}
//Check to see if decode complete
if((DECODE_ADDRESS_HIGH==ENCODE_ADDRESS_HIGH) &&
(DECODE_ADDRESS_MID==ENCODE_ADDRESS_MID) &&
(DECODE_ADDRESS_LOW==ENCODE_ADDRESS_LOW)) //does decode memory address match largest encode address?
decode_complete=1;
else
decode_complete=0;
}
//********************************
//FUNCTION:
void erase_flash(void)
//
//INPUTS: none
//
//OUTPUTS: none
//
//DESCRIPTION: Erase the flash chip.
// Write Enable is passed to flash to prepare it for erasing.
//
// Next, the Chip Erase instruction is passed to the flash. A 20sec timer is started
// to ensure that the Chip Erase actually completes.
//
// The "busy" bit in the flash's status register is checked to ensure the operation is complete.
//
// Control is then passed back to the calling routine.
//********************************
{
//"Write Enable" passed to flash in preparation for Chip Erase
SS=0;
spi_write(WRITE_ENABLE);
SS=1;
//"Chip Erase"
SS=0;
spi_write(CHIP_ERASE);
SS=1;
//Activate Timer 1 to prevent lockup during chip erase
TR1=1; //turn on Timer 1 for 20sec delay
timer1_expired=0;
timer1_counter=1000; //1000 x 20msec = 20sec
//Wait until Chip Erase finished (maximum time spec = 20s)
busy=1;
while(busy) //busy=1 means chip is busy
{
SS=0;
spi_write(READ_STATUS);
spi_data=spi_read();
SS=1;
if((spi_data & BUSY) == 0x00)
busy=0; //Chip Erase finished
else
busy=1; //Chip Erase not finished
if(timer1_expired==1)
{
RED_LED=ON;
busy=0;
}
}
TR1=0; //turn off timer used for Chip Erase
}
//********************************
//FUNCTION:
void program_flash(unsigned char add1, unsigned char add2, unsigned char add3)
//
//INPUTS: Flash address for programming, CMX618 encoded data (in global array variable)
//
//OUTPUTS: none
//
//DESCRIPTION: Performs Page Program of flash device.
// "Write Enable" is sent to flash in preparation for Page Program command.
//
// Next, "Page Program" instruction is passed to flash along with the two uppermost address bytes
// for the flash address to be programmed (least significant address byte = 0x00).
//
// The routine then waits for the page program instruction to finish. It takes approximately 1.5-3.0msec
// for this routine to complete.
//
// The status register in the flash has a "busy" bit to indicate when new commands can be received.
// Since this "erase routine is called every 60ms, it is presumed that the "page program" operation
// will be complete before the next "page program" is called.
//********************************
{
unsigned char i;
//"Write Enable" instruction
SS=0;
spi_write(WRITE_ENABLE);
SS=1;
//"Page Program" instruction
SS=0;
spi_write(PAGE_PROGRAM);
spi_write(add1);
spi_write(add2);
spi_write(add3);
for(i=0; i<BYTELENGTH; ++i)
spi_write(CMX618_data[i]);
SS=1;
// Flash Page 0 spans from 0x000000 to 0x0000FF (256 bytes)
// Flash Page 1 spans from 0x000100 to 0x0001FF
// Flash Page 2 spans from 0x000200 to 0x0002FF...
}
//********************************
//FUNCTION:
void read_flash(unsigned char m, unsigned char n, unsigned char p)
//
//INPUTS: Flash address to be read.
//
//OUTPUTS: none
//
//DESCRIPTION: Reads flash device.
// "Read Data" instruction is passed to the flash chip. Next, the three bytes corresponding to the desired
// memory location are passed to the flash chip.
// The flash clocks out the data and stores it in the global "char" array "CMX618_data".
//
//********************************
{
unsigned char i;
SS=0;
spi_write(READ_DATA);
spi_write(m);
spi_write(n);
spi_write(p);
for(i=0; i<BYTELENGTH; ++i)
CMX618_data[i]=spi_read();
SS=1;
}
//******************************************
// FUNCTION:
void wr_byte(unsigned char byte)
//
// PURPOSE: Write a single byte to the CMX618 CDATA pin.
//
// DESCRIPTION: This function takes in a single-byte corresponding to the
// value to be written to the CDATA line.
//
// A 'for' loop is started and the SCLK line is pulled low. The msb of the byte is obtained and
// written to CDATA. The byte is left-shifted one place and SCLK is pulled high to latch the bit
// into the CMX618. The 'for' loop iterates 7 more times to complete the byte write operation.
//
// This function does not return a variable.
//*******************************************
{
unsigned char i;
for(i=8; i!=0; i--)
{
SCLK=0;
if(byte & 0x80)
CDATA=1;
else
CDATA=0;
byte <<= 1;
SCLK=1;
}
}
//******************************************
// FUNCTION:
void wr1(unsigned char address, unsigned char databyte)
//
// PURPOSE: Write one byte to a CMX618 write register.
//
// DESCRIPTION: This function takes in two single-byte variables corresponding to the
// register address and register contents to be written to the CDATA line.
//
// CSN is taken low to start the C-BUS transaction. The address byte is written to the CDATA line,
// and then the register contents are written to CDATA. CSN is taken high to complete the C-BUS transaction.
//
// This function does not return a variable.
//*******************************************
{
CSN=0;
wr_byte(address);
wr_byte(databyte);
CSN=1;
}
//******************************************
// FUNCTION:
void wr2(unsigned char address, unsigned int dataword)
//
// PURPOSE: Write two bytes to a CMX618 write register.
//
// DESCRIPTION: This function takes in three variables; a single-byte variable corresponding to the
// register address, and a two-byte variable corresponding to the register contents, all of which
// will be written to the CDATA line.
//
// CSN is taken low to start the C-BUS transaction. The address byte is written to the CDATA line.
// The register contents are split into two single-byte variables, both of which are written to CDATA.
// CSN is then taken high to complete the C-BUS transaction.
//
// This function does not return a variable.
//*******************************************
{
unsigned char temp;
CSN=0;
wr_byte(address);
temp=dataword; //get LSB
dataword >>= 8; //shift most significant 8 bits down for MSB
wr_byte(dataword); //write MSB
wr_byte(temp); //write LSB
CSN=1;
}
//******************************************
// FUNCTION:
unsigned char rd_byte(void)
//
// PURPOSE: Read a single byte from the CMX618 RDATA pin.
//
// DESCRIPTION: This function does not take in a variable.
//
// The SCLK line is pulled low and a 'for' loop is started. The SCLK line is pulled high to
// latch out the latest data bit, and this bit is appended to any previously received bits.
// The received bits are left-shifted one place and SCLK is pulled low.
// The 'for' loop iterates 7 more times to complete the read operation.
//
// This function returns the received byte to the calling routine.
//*******************************************
{
unsigned char byte=0x00, i;
SCLK=0;
for(i=0; i<8; ++i)
{
byte <<= 1; //left-shift here due to decrementing operator
SCLK=1;
if(RDATA)
byte |= APPEND_ONE;
else
byte &= APPEND_ZERO;
SCLK=0;
}
return(byte);
}
//******************************************
// FUNCTION:
unsigned char rd1(unsigned char address)
//
// PURPOSE: Read a single byte from a CMX618 read register.
//
// DESCRIPTION: This function receives a variable corresponding to the register address to be read.
//
// The CSN line is pulled low to start the C-BUS transaction.
// The read register address is written to the CMX618, and then the register contents are read out.
// The C-BUS transaction ends when the CSN line is pulled high.
//
// This function returns the received byte to the calling routine.
//*******************************************
{
unsigned char rbyte;
CSN=0;
wr_byte(address);
rbyte=rd_byte();
CSN=1;
return(rbyte);
}
//******************************************
// FUNCTION:
unsigned int rd2(unsigned char address)
//
// PURPOSE: Read two bytes from a CMX618 read register.
//
// DESCRIPTION: This function receives a variable corresponding to the register address to be read.
//
// The CSN line is pulled low to start the C-BUS transaction.
// The read register address is written to the CMX618, and then the register contents are read out.
// The C-BUS transaction ends when the CSN line is pulled high.
//
// This function returns the received word (16 bits) to the calling routine.
//*******************************************
{
unsigned int rword=0x0000;
CSN=0;
wr_byte(address);
rword = rd_byte(); //8 bits returned into 16-bit variable (only least 8 significant bits copied)
rword <<= 8; //left shift bits into most significant position
rword |= rd_byte(); //append next 8 bits onto existing 16-bit variable
CSN=1;
return(rword);
}
//********************************
//FUNCTION:
void main()
//
//INPUTS: none
//
//OUTPUTS: none
//
//DESCRIPTION: Main Routine.
// On startup, the uC and CMX618 are initialized, and the program waits for ENCSWITCH press.
// After ENCSWITCH press, the CMX618 is placed into encode mode. When a CMX618 IRQ is detected,
// the CMX618 ISR calls "encode_process" and "program_flash" to write encoded voice data to flash.
//
// This process continues until the DECSWITCH is pressed, at which time the CMX618 is switched
// to decode mode. Data is then read from flash and supplied to the CMX618 decoder. An additional
// flash read is performed so that a packet of data will be ready at the next CMX618 decode IRQ.
// When a CMX618 IRQ is detected, the ISR calls "decode_process" and "read_flash" to pass voice data
// to the CMX618 decoder.
//
// When all of the encoded voice data has been read out of the flash, the CMX618 stops decoding and
// the routine enters a "do nothing" infinite loop.
//********************************
{
unsigned char i=0;
initialize_uC(); //initialize processor
erase_flash();
state=0; //configuration mode, prevents checking for VDA or VDW bits on CMX618 IRQ
initialize_618(); //initialize CMX618
LED1=ON;
while(ENCSWITCH);
//************** VOICE ENCODING ***********************//
wr2(IRQENAB, (RDY));
wr2(VCTRL, (ENC)); //turn on CMX618 encoder
while(!rdy); //Wait for service to complete...
rdy=0;
//NOTE: A check of SVCACK ($2E) b0 can be made at this point for debug purposes.
//SVCACK b0 only has meaning after a service has been performed and RDY has been asserted.
//If SVCACK b0 is not equal to 1 after RDY is asserted, an error has been made.
//In this case, a General Reset should be issued and device configuration restarted.
wr2(IRQENAB, (VDA));
state=1; //encode mode, prevents checking for RDY bit on CMX618 IRQ
LED2=ON;
CMX618IRQ=0; //clear flag that may have been set during configuration
while(DECSWITCH) //check for encode IRQs so long as DECSWITCH isn't pressed
{
if(CMX618IRQ)
{
encode_process();
CMX618IRQ=0;
}
}
//*************** VOICE DECODING ***********************//
while(1) //infinite loop, voice will playback forever
{
decode_complete=0; //reset flag for re-entry into routine
DECODE_ADDRESS_LOW=0x00; //reset flash address for decode reads for looping
DECODE_ADDRESS_MID=0x00;
DECODE_ADDRESS_HIGH=0x00;
state=0; //618 ISR: configuration mode, prevents checking for VDA or VDW bits
rdy=0;
wr2(IRQENAB, (RDY));
wr2(VCTRL, (DVDW | DEC));
while(!rdy); //Wait for service to complete...
rdy=0;
//NOTE: A check of SVCACK ($2E) b0 can be made at this point for debug purposes.
//SVCACK b0 only has meaning after a service has been performed and RDY has been asserted.
//If SVCACK b0 is not equal to 1 after RDY is asserted, an error has been made.
//In this case, a General Reset should be issued and device configuration restarted.
wr2(IRQENAB, (VDW));
state=2; //618 ISR: decode mode, prevents checking for RDY or VDA bits
//Read out 27 bytes from flash, increment flash address, pass data to CMX618 decoder
read_flash(DECODE_ADDRESS_HIGH, DECODE_ADDRESS_MID, DECODE_ADDRESS_LOW);
DECODE_ADDRESS_LOW = DECODE_ADDRESS_LOW + BYTELENGTH;
CSN=0;
wr_byte(DECFRAME);
for(i=0; i<BYTELENGTH; ++i)
wr_byte(CMX618_data[i]);
CSN=1;
//Read next 27 bytes from flash before the CMX618 needs it, then increment flash address.
read_flash(DECODE_ADDRESS_HIGH, DECODE_ADDRESS_MID, DECODE_ADDRESS_LOW);
DECODE_ADDRESS_LOW = DECODE_ADDRESS_LOW + BYTELENGTH;
CMX618IRQ=0; //clear flag
while(!decode_complete) //wait for decoding to complete
{
if(CMX618IRQ)
{
decode_process();
CMX618IRQ=0;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -