⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 an_gen_6x8_1_c_listing.c

📁 CMX618/CMX638声码器操作源码
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -