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

📄 mp3srial.c

📁 Frank s MP3 Player Source Files
💻 C
📖 第 1 页 / 共 3 页
字号:
    *AVR_DDRD  = *AVR_DDRD & 0x7F;
	*AVR_DDRF  = *AVR_DDRF & 0xE1;				/* All IDE pins are now inputs - bus is free */
	
	*AVR_DDRE  = *AVR_DDRE & 0xFB;				/* Now safe to enable Cypress USB chip */
                                                /* (pullup on enable line now pulls it high) */

	*AVR_PORTE = *AVR_PORTE & 0xF7;				/* ST MP3 codec reset (ie sound stopped) */

	/* put an appropriate message on the LCD display */
	LCD_init();						            /* clear the display */
	UART1_TxCharWaitC(0x5c);
	UART1_TxCharWaitC(0x42);
	UART1_TxCharWaitC(0x20);
	UART1_TxCharWaitC(0x21);				    /* put cursor on start of 2nd row */
	uart1_putwaitPROGstr(PSTR("    USB Port In Use"));	/* write message on that row */
	UART1_TxCharWaitC(0x5c);
	UART1_TxCharWaitC(0x42);
	UART1_TxCharWaitC(0x20);
	UART1_TxCharWaitC(0x23);				    /* put cursor on start of 4th row */	
	uart1_putwaitPROGstr(PSTR(" Player restarts after   USB cable unplugged."));
		
	/* send a message out the debug port */
	uart0_putwaitPROGstr(PSTR("\r\n\n\nUSB port in use.\r\n"));
	uart0_putwaitPROGstr(PSTR("Player restarts when USB unplugged.\r\n\n"));

    // Zero the directory cluster number in eeprom as the current directory may have been deleted.
    // This will trigger a return to the root directory, recount of files, etc at power-up
   	EEPROM_Write (DIRcluster0, 0);
   	EEPROM_Write (DIRcluster1, 0);
   	EEPROM_Write (DIRcluster2, 0);
   	EEPROM_Write (DIRcluster3, 0);

	while (*AVR_PINE & 0x40);					/* wait until USB cable unplugged */

	/* send a message out the debug port */
	uart0_putwaitPROGstr(PSTR("USB port unplugged. Restarting player.\r\n\n"));	

	Delayms(100);								/* ensure USB chip finished doing its thing */
	ResetAVR();									/* reset the player */
}





/******************************************************************************
    
    TWI (I2C) Port Handling Routines
    This port used for sending initial configuration data to the STA013 codec
    Routine is slow - it waits for TWI status bits; it does not return to main
    loop while executing. So be aware that if you use this routine whilst
    a track is playing, 
                  
******************************************************************************/

u08 sta013_writeTWI (u08 waddr, u08 wdata)
/* Writes a single byte to the TWI interface of the ST codec chip */
/* We're passed in the address and the byte to write to that address */
/* Returns an error code if a problem occurs. */
/* The basic 5-step sequence of events is: */
/*  1. Start condition */
/*  2. Send the TWI address of the sta013 indicating a write, ie 0x86 */
/*  3. Send the address of the sta013 register we want to write to, ie waddr */
/*  4. Send the data byte to the sta013, ie wdata */
/*  5. Stop condition */
{

	/* print the codec write data values to the screen - debug only */
	// UART_TxCharWaitC('\r');
	// UART_TxCharWaitC('\n');
	// UART_PutHexWaitC(waddr);
	// UART_TxCharWaitC(' ');
	// UART_PutHexWaitC(wdata);
	// UART_TxCharWaitC(' ');
	/* end debug printing section */

	*TWI_TWCR = 0xA4;						/* initiate start condition */
	while ((*TWI_TWCR & 0x80) != 0x80);		/* wait until high bit set indicating start has been sent */
	if ((*TWI_TWSR & 0xF8) != 0x08) return TWI_write_start_fail;	/* report error if start condition failed */
	
	*TWI_TWDR = 0x86;
	*TWI_TWCR = 0x84;						/* inform sta013 we want to write to it */
	while ((*TWI_TWCR & 0x80) != 0x80);		/* wait until high bit set indicating 0x86 has been sent */
	if ((*TWI_TWSR & 0xF8) != 0x18) return TWI_write_0x86_fail;		/* report error if writing 0x86 failed */

	*TWI_TWDR = waddr;
	*TWI_TWCR = 0x84;						/* give sta013 the internal address we want to write to */
	while ((*TWI_TWCR & 0x80) != 0x80);		/* wait until high bit set indicating waddr has been sent */
	if ((*TWI_TWSR & 0xF8) != 0x28) return TWI_write_waddr_fail;	/* report error if writing waddr failed */	

	*TWI_TWDR = wdata;
	*TWI_TWCR = 0x84;						/* give sta013 the internal address we want to write to */
	while ((*TWI_TWCR & 0x80) != 0x80);		/* wait until high bit set indicating wdata has been sent */
	if ((*TWI_TWSR & 0xF8) != 0x28) return TWI_write_wdata_fail;	/* report error if writing waddr failed */

	*TWI_TWCR = 0x94;						/* transmit stop condition */

	return TWI_write_OK;
}




/******************************************************************************
    
    SPI Port Handling Routines
    This port used for sending MP3 files to the STA013 codec
                  
******************************************************************************/

void FeedSTcodec(void)
/* This routine reads data out of the MP3 Data queue and feeds it to the ST MP3 codec chip. */
/* The ST MP3 codec data request line is on Port E bit 5. High means it wants data. */
/* This function also monitors its command byte (FeedSTcodec_Command) so that it will not feed */
/* the codec chip any data if the user command is STOP. */
{
	u08 mp3data;
	
	if (FeedSTcodec_Command == FSC_Cmd_Stop) 		/* exit if we're told to stop */
		return;
	
	
	/* debug only */
	// for (mp3data=0; mp3data<100; mp3data++)
	// 	 Q_read_C ((u08*)&MP3DATAQ[0]);
	/* end debug section */
	
	// debug only - return if data q empty
	// if (Q_CheckEmptyC((u08*)&MP3DATAQ[0]) == Q_empty)  return;
	// end debug
	
	
	while (*AVR_PINE & 0x20) {						/* while MP3 codec wants data ... */
		mp3data = Q_read_C ((u08*)&MP3DATAQ[0]);	/*  try to read a byte from the data queue */
		if (ReadQstatus != Q_OK) return;			/*  exit if queue read returned q empty */
		while (!(*AVR_SPSR & 0x80));				/*  wait until SPI port ready for new byte */
		*AVR_SPDR = mp3data;						/*  give byte to MP3 codec through SPI port */
	}
}




/******************************************************************************
    
    Other Routines
    Not directly affecting the various serial ports, but related to or called
    by those routines.
                  
******************************************************************************/


void SwitchOff (void)
/* This routine is called by HandleButtons when the On/Off button is pressed, ie the 
user is switching the unit off. This routine does a bunch of calls to shut the player 
down, then goes into a loop when it sits waiting for the On/Off button to be pressed 
again, waiting for the unit to be switched on. */
{
	*AVR_PORTE = *AVR_PORTE & 0xF7;				/* put STA013 codec in reset */

	UART1_TxCharWaitC(0x5c);
	UART1_TxCharWaitC(0x40);
	UART1_TxCharWaitC(32);
	UART1_TxCharWaitC(0x30);					/* clear lcd display */

	LED_OFF();
    LCD_LIGHT_OFF();                            // turn off LED & LCD backlight

	IDE_Standby();		    					/* allow the drive to auto power-down */

    ButtonPress = 0;                            // clear out the previous ON/OFF button press
    while (ButtonPress != BUT_ONOFF)
        IR_CheckTimeout();                      // wait until on/off button pressed (on) again
                                                // either by pushbutton or IR remote control
    ResetAVR();
}



void PrintStackPointer (void)
// As you might guess from the function name, this routine prints the value of the
// stack pointer out the debug port (using slow 'wait' routines).
{
	u08		*memptr, i;
		
	memptr = (u08*)(((*AVR_SPH)<<8) | *AVR_SPL);		// copy stackpointer to memptr
	
	uart0_putwaitPROGstr(PSTR("Stack Pointer value: $"));	
	UART_PutHexWaitC(*AVR_SPH);
	UART_PutHexWaitC(*AVR_SPL);
	uart0_putwaitPROGstr(PSTR("\n\r"));
	
	uart0_putwaitPROGstr(PSTR("Stack dump: $ "));
	for (i=RAMEND-(u16)memptr; i; i--) {
		UART_PutHexWaitC(*++memptr);
		UART_TxCharWaitC(' ');
	}
	uart0_putwaitPROGstr(PSTR("\n\r"));	
}



void PrintDebugInfo (void)
// Prints a bunch of disk-related debug info out the debug port, slowly.
// ie it uses the xxWaitxx functions, to avoid overflowing the uart tx q.
{
    u08     linecnt, i, j;
    u16     temp;

    
	uart0_putwaitPROGstr(PSTR("\r\nDISKDRIVE DEBUG INFORMATION\r\n"));		/* debug port message */

	uart0_putwaitPROGstr(PSTR("Findfile current directory cluster: $"));
	UART_PutHexWaitC((u08)(FINDFILE_CLUS>>24));
	UART_PutHexWaitC((u08)(FINDFILE_CLUS>>16));
	UART_PutHexWaitC((u08)(FINDFILE_CLUS>>8));
	UART_PutHexWaitC((u08) FINDFILE_CLUS);
	uart0_putwaitPROGstr(PSTR("\r\n"));	

	uart0_putwaitPROGstr(PSTR("Findfile current offset into this cluster: $"));
	UART_PutHexWaitC((u08)(FINDFILE_OFSET>>8));
	UART_PutHexWaitC((u08) FINDFILE_OFSET);
	uart0_putwaitPROGstr(PSTR("\r\n"));	
	
	uart0_putwaitPROGstr(PSTR("Streamfile State: $"));
	UART_PutHexWaitC(STREAMFILE_ST);
	uart0_putwaitPROGstr(PSTR("\r\n"));

	uart0_putwaitPROGstr(PSTR("CalcNextCluster State: $"));
	UART_PutHexWaitC(CALNXCL_ST);
	uart0_putwaitPROGstr(PSTR("\r\n"));

	uart0_putwaitPROGstr(PSTR("CalcNextCluster sector it's seeking to: $"));
	UART_PutHexWaitC((u08)(CALNXCL_SN>>24));
	UART_PutHexWaitC((u08)(CALNXCL_SN>>16));	
	UART_PutHexWaitC((u08)(CALNXCL_SN>>8));		
	UART_PutHexWaitC((u08) CALNXCL_SN);
	uart0_putwaitPROGstr(PSTR("\r\n"));

	uart0_putwaitPROGstr(PSTR("SeekSector State: $"));
	UART_PutHexWaitC(SEEKSECT_ST);
	uart0_putwaitPROGstr(PSTR("\r\n"));
	
	uart0_putwaitPROGstr(PSTR("Drive status register: $"));
	UART_PutHexWaitC(IDE_read8_C(0x7f));
	uart0_putwaitPROGstr(PSTR("\r\n"));	
	
	uart0_putwaitPROGstr(PSTR("Drive error register: $"));
	UART_PutHexWaitC(IDE_read8_C(0x4f));
	uart0_putwaitPROGstr(PSTR("\r\n"));
	
	uart0_putwaitPROGstr(PSTR("Sectors per cluster: $"));
	UART_PutHexWaitC(SEC_PER_CLUS);
	uart0_putwaitPROGstr(PSTR("\r\n"));

	uart0_putwaitPROGstr(PSTR("FAT start sector: $"));
	UART_PutHexWaitC((u08)(FAT_START_SEC>>8));	
	UART_PutHexWaitC((u08) FAT_START_SEC);
	uart0_putwaitPROGstr(PSTR("\r\n"));

	uart0_putwaitPROGstr(PSTR("DIR start sector: $"));
	UART_PutHexWaitC((u08)(DIR_START_SEC>>24));
	UART_PutHexWaitC((u08)(DIR_START_SEC>>16));	
	UART_PutHexWaitC((u08)(DIR_START_SEC>>8));		
	UART_PutHexWaitC((u08) DIR_START_SEC);
	uart0_putwaitPROGstr(PSTR("\r\n"));
	
	uart0_putwaitPROGstr(PSTR("FeedSTcodec_Command: $"));
	UART_PutHexWaitC(FeedSTcodec_Command);
	uart0_putwaitPROGstr(PSTR("\r\n"));	

	uart0_putwaitPROGstr(PSTR("File Number: $"));
	UART_PutHexWaitC((u08)(FileNumber>>8));	
	UART_PutHexWaitC((u08) FileNumber);
	uart0_putwaitPROGstr(PSTR("\r\n"));

    // print out a bunch of Boot Sector Boot Paramer Block Data
    while ( SeekSectorC(63, 1) != SeekSect_Done);     // seek drive to start of BPB sector
    // Drive is seeked to that sector. Now do a bunch of reads from the drive's data register
    // and print out the results on the debug port.
    uart0_putwaitPROGstr(PSTR("\r\nDump of the drive's Boot Parameter Block:\r\n")); 
    while ( IDE_read8_C(0x7f) & 0x80 );             // wait until drive says it's not busy (wait for top bit to clear)
    linecnt = 16;
    while (linecnt--) {
        // print 4 bytes separated by spaces, 4 times (separated by 2 spaces)
        i = 4;
        while (i--) {           // outer loop
            j = 2;
            while (j--) {       // inner loop
                temp = IDE_read16_C(0x47);          // get 16-bit word from drive data register
                UART_PutHexWaitC( (u08)temp );      // print low byte to debug port
                uart0_putwaitPROGstr(PSTR(" "));    // followed by a space
                UART_PutHexWaitC( (u08)(temp>>8) ); // print high byte to debug port
                uart0_putwaitPROGstr(PSTR(" "));    // followed by a space                
            }        
            uart0_putwaitPROGstr(PSTR(" "));        // extra space between groups of 4 bytes
        }
        uart0_putwaitPROGstr(PSTR("\r\n"));         // end of line CR/LF
    }
    uart0_putwaitPROGstr(PSTR("\r\n"));             // extra CR/LF at end of BPB data dump


    DumpDirectory();                            // dump some data out of the current directory
    IDE_Standby();		    					/* allow the drive to auto power-down */
}





// DumpDirectory
//
// This routine prints to the debug port the first directory record in the current directory
// Use only when debugging - because it takes over the diskdrive it'll disrupt anything currently playing.
u08 DumpDirectory (void)
{
    u08     linecnt, i, j;


    // Ensure StreamFileC stopped
   	STREAMFILE_CMD = StreamFile_Cmd_Stop;                       // command StreamFileC to STOP
    StreamFileC();
   	while (STREAMFILE_ST!=StreamFile_St_Idle) StreamFileC();    // wait until StreamFileC idle

    // Ensure MP3dataQ empty
    Q_clear_C((u08*)&MP3DATAQ[0]);

    // Command StreamFileC to stream current directory into the MP3dataQ
    STREAMFILE_FILESZ   = 0xFFFFFFF;		            // huge "file size"
    STREAMFILE_CLUS     = CURRENT_DIRCL;			    // cluster number for start of current directory
    STREAMFILE_QPOINTER = &MP3DATAQ[0];					// point StreamFile to the MP3 Data queue
    STREAMFILE_CMD      = StreamFile_Cmd_Stream;        // command StreamFileC to start streaming
    StreamFileC();    
    StreamFileC();

    // Wait until 32 bytes in queue. If StreamFileC goes idle, return.
    while ( Q_HowMuchDataC((u08*)&MP3DATAQ[0]) < 32 ) {
        StreamFileC();
        if ( (STREAMFILE_ST==StreamFile_St_Idle) && (Q_HowMuchDataC((u08*)&MP3DATAQ[0])<32) )
            return 1;
    }

    // We now have 32 bytes in the queue; a directory entry's worth. Read them out of 
    // the queue, printing them to the debug port. Each line prints 16 bytes.
    uart0_putwaitPROGstr(PSTR("\r\nFirst 32-byte record in current directory:\r\n")); 
    linecnt = 2;
    while (linecnt--) {
        // print 4 bytes separated by spaces, 4 times (separated by 2 spaces)
        i = 4;
        while (i--) {           // outer loop
            j = 4;
            while (j--) {       // inner loop
                UART_PutHexWaitC( Q_read_C((u08*)&MP3DATAQ[0]) );   // print byte to debug port
                uart0_putwaitPROGstr(PSTR(" "));                    // followed by a space
            }        
            uart0_putwaitPROGstr(PSTR(" "));        // extra space between groups of 4 bytes
        }
        uart0_putwaitPROGstr(PSTR("\r\n"));         // end of line CR/LF
    }
    uart0_putwaitPROGstr(PSTR("\r\n"));             // extra CR/LF at end of directory data dump


⌨️ 快捷键说明

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