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

📄 zipamp.c

📁 &#8226 控制器(CPU): Atmel AT90S8515 AVR &#8226 MP3解码器: STA013 &#8226 音频 DAC: CS4334 &#8226 IDE 接口
💻 C
字号:
/*********************************************
ZipAmp

Author  	: Nasif Akand                     
Copyright	: (C) Nasif Akand 2003
Notice		:
		Copyright 2003 Nasif Akand (nasif@yifan.net)
		http://go.to/zipamp
		http://zipamp.virtualave.net

    		This file is part of ZipAmp MP3 software.

    		ZipAmp is free software; you can redistribute it and/or modify
    		it under the terms of the GNU General Public License as published by
    		the Free Software Foundation; either version 2 of the License, or
    		(at your option) any later version.

    		ZipAmp is distributed in the hope that it will be useful,
    		but WITHOUT ANY WARRANTY; without even the implied warranty of
    		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    		GNU General Public License for more details.

    		You should have received a copy of the GNU General Public License
    		along with this code; if not, write to the Free Software
    		Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Chip type           : AT90S8515
Clock frequency     : 12.00000 MHz
Memory model        : Small
Internal SRAM size  : 512 bytes
External SRAM size  : 0 byte
Data Stack size     : 64 bytes

Tested ATA Drive
Samsung SpinPoint SV3064D 30 GB

Test Drive Access Time:
 Track to Track : 	0.8 m/s
 Average 	:	9.0m/s
 Full Stroke 	: 	17 m/s 
 
Test Drive Playback:
Full speed MP3 playback at 320KBps. 
*********************************************/

#define DataReq	PINB.2        

#include <90s8515.h>	//8515 header file
#include <spi.h>	//Codevision spi 
#include "zfat.h"
#include "zata.h"
#include "ztype.h"
#include "zcontrol.h"
#include "zlcd.h"
#include <delay.h>	//Codevision delay
#include "i2c.h"


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void) 
{
 unsigned char in;
 #asm("cli");
 in=PINC;	//Read the input buttons
 in=~in;        //Invert them to see which one is high (thats the one pressed)

 while ((!PIND.2)); //wait until interrupt key released

 switch (in) {  	   

  //Case 1= STOP
  case 1: //play=0 is pause, play=1 is play, play=2 is stop

           play=2; 	//STOP
  	   STAPlay();   //Stop player
    	   UnBusy();	//Remove HD Busy light
  	   currentCluster=firstCluster; //Remember file start cluster
  	   clusterBufferReadPos=clusterBufferWritePos;	//Clear cluster buffer

  	   filePos=0; //Set filestart pos at beginning
  	   sectorPos=0;
  	   mp3Pos=0;        	   
  	  break;

  //Case 2= Play or Pause  	    	  
  case 2:  play=(~play) & 1; //Invert play. If play then pause, if pause then play
  	   STAPlay(); //Load command
  	  break;
	  
  //Case 4= 	  
  case 4: 
          if (currentFileNum<=1) currentFileNum=totalFiles-1;
          else currentFileNum=currentFileNum-2;
          dirReadOffset.fileNum=0; //To reread dir from start.

  	  break;

  case 8: currentFileNum+=advance; //FF
          if (currentFileNum>totalFiles) {
           currentFileNum=1;
           dirReadOffset.fileNum=0;
          } 
  	  break;

  case 16: filePos=FileSize;			//NEXT
  	   break;
  	  
  case 32:
  	  soundMode = (soundMode+1) & soundModeMask;  	  
  	  SetBassTreble();
  	  break;
  	    	   
  case 64: playMode = (playMode+1) & playModeMask;
           break;            
 };        
 
 intFlag=1;	//Set interrupt occured flag
}

/*
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
 printf("Entered Interrupt 2");
} */


// Declare your global variables here

void main(void)
{
// Declare your local variables here
byte temp; dword extension;             

// Input/Output Ports initialization
// Port A
DDRA=0x00;  //Start as Input port
PORTA=0x00; //Set to High-Z state

// Port B
DDRB=0xBB;  
PORTB=0x0B; //Enable Reset for STA013, Disable ATA IOR and IOW.

// Port C
DDRC=0xFF;  //Output port
PORTC=0x00; //Set 0

// Port D
DDRD=0xF2;  
PORTD=0x20; //Disable Latch and Buffer. Never pull PORTD.1 high, that will cause damage to STA013

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Output Compare
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 14318.180 kHz
// Mode: Output Compare
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
GIMSK=0x40;
MCUCR=0x00;
GIFR=0x40;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: Off
// UART Transmitter: On
                 

// UART Baud rate: 19200 at 14.3181
UCR=0x08;
UBRR=0x2E;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2460.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x50;

#asm("cli");

InitLCD();   
delay_ms(3000);
//DDRC=0x00;
//PORTC=0x00;


ATA_Init(); 
InitFAT();

currentFileNum=0;
temp=0;

//Find two required files in root dir ZIPAMP.SYS and ZIPAMP.CFG and save their LBA address
while ((temp<2)&&(getDirEntry(0)==1))  {
  extension = (*(dword *)fileExtension) & 0x00FFFFFF;
  //low-case z "logic AND" up-case Z =will equal up-case Z. Thus following checks for both 'z' and 'Z'
  if ((fileName[0] & 0x5A)==0x5A) { //if the name starts with Z then see if it is SYS or CFG file
   if (extension==0x00535953) { dirStackLBA=clust2LBA(currentCluster); temp++; } //ZIPAMP.SYS Stack file address
   if (extension==0x00474643) { cfgFileLBA=clust2LBA(currentCluster); temp++; } //ZIPAMP.CFG Config file address
  } 
 }                                              

 if (temp<2) Halt(4); //Missing SYS or CFG file.

STA013Setup();	 //Setup STA013 decoder.

currentFileNum=0; 
if (loadConfig()!=1) {//goto LOADED;
 while (getDirEntry(1)==1)  { //count # of MP3 files.
  totalFiles++; 
  gotoxy(3,0);
  writeNumber(totalFiles); 
 }
}

//gotoxy(3,0);
writestring(" Wait..");

dirReadOffset.fileNum=0;
SetSoundCg();    //Load Sound Mode character bars into LCD CGRAM.
play=1;          //ZipAmp will start playing after boot finish.
SetBassTreble(); //Setup Bass Treble registers in STA013.
SongSelect();
while (1) {  //Main loop

  key<<=1;
  if (key==0) key=1;
  PORTC=~key;
  DDRC=key;                           
  #asm("sei");      
                  
//Following "if" is True when INTR in NEXT, FF, PREV occurs. filePos and FileSize is set equal there.
//In first iteration, filePos will be greater than FileSize because STA013.BIN has been read to the finish,
//thus this becomes true.
  if (filePos>=FileSize) SongSelect(); //Song is selected when playing finished or NEXT/PREV button pressed

   if (intFlag) { //Interrupt occured and LCD display wasn't fixed, fix it.
    intFlag=0;
    printInfo();
   }

  while ((DataReq)&&(filePos<FileSize)) {
   if (mp3Pos==0) read();
   spi(sectorBuffer.data[mp3Pos++]);
   spi(sectorBuffer.data[mp3Pos++]);
  } 

    //If finished reading one cluster and head hasn't been moved
    if ((sectorPos==Sectors_Per_Cluster) && (headMoved==0)) {

      //if we have buffered next cluster then move head     
      if (readClusterBuffer()==1) ATA_Move_Head(clust2LBA(currentCluster));

      
      else { //we didn't buffer it, so find next cluster and move head
       currentCluster=findNextCluster();
       ATA_Move_Head(clust2LBA(currentCluster)); //Move head to read position
      }           
      //Reset all parameters
      sectorPos=0;
      readPos=0;  
      headMoved=1;
    }        
                   
    //if we have already moved head, then we can buffer next clusters
    else if ((readPos|DataReq)==0) {
      //check if datareq is set, if set then get out of buffering
      temp=sectorPos;
      if (writeClusterBuffer()==1) { //if buffering was successful then move head to original location.
       sectorPos=temp;
       ATA_Move_Head(clust2LBA(currentCluster)+sectorPos); //move head to the current reading cluster.
       headMoved=1;
       readPos=0;
      }     
    }
    
} // end of main loop


} //END.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -