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

📄 mp3srial.c

📁 Frank s MP3 Player Source Files
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
    
    Title:    Frank's MP3 Player serial routines in C
    Author:   Frank Van Hooft
    Date:     21 Aug 2004
    
    This file contains various C routines that perform any functions related
    to serial-type ports. This covers the ports:
    	UART0	(debug port)
    	UART1	(LCD display & pushbuttons)
    	TWI		(also called I2C, for ST MP3 codec chip control)
    	SPI		(used to send MP3 files to the codec chip)
    	USB		(handled by the Cypress chip - we just control its reset)
    	
    Initialization routines for these ports are in mp3init.c or in the 
    assmbler (.s) files.
                  
******************************************************************************/


/******************************************************************************
    
    UART0 Port Handling Routines
    This port is the debug RS232 port.
                  
******************************************************************************/

void uart0_putwaitstr(u08 *c)
/* copies a string held in SRAM (data memory) to the UART0  *SLOWLY*  */
/* by "owning" the UART and waiting until each char is sent before sending */
/* the next, bypassing the usual transmit queue. Very slow - use only for */
/* debug or in non-time-critical positions (eg initializations). */
{
    while (*c) {
        UART_TxCharWaitC(*c);
        c++;
    }
}


void uart0_putwaitPROGstr(u08 *c)
/* copies a string held in Flash (program memory) to the UART0  *SLOWLY*  */
/* by "owning" the UART and waiting until each char is sent before sending */
/* the next, bypassing the usual transmit queue. Very slow - use only for */
/* debug or in non-time-critical positions (eg initializations). */
{
    while (PRG_RDB(c)) {
        UART_TxCharWaitC(PRG_RDB(c));
        c++;
    }
}



SIGNAL(SIG_UART0_RECV)      
/* signal handler for receive complete interrupt from debug port */
/* This routine handles UART receive interrupts from UART 0 - the debug port */
// Used for debug purposes only
// Accepts single-character commands. They are:
//
//      ?   - help - print out this list of commands
//      e   - dump contents of Eeprom
//      d   - dump a bunch of Diskdrive information
//      h   - dump some debug information then Hang
// 		i   - enable dumping of IR remote-control period values during training
//		p   - test IDE Ports bits where possible. Harddisk must be unplugged.
//		t   - test the harddisk interface. Harddisk must be plugged in.
//		w   - perform repeated writes to the harddisk.
//		r   - perform repeated reads from the harddisk.
{
    switch (*AVR_UDR0) {

    case '?':
        PrintDebugCommands();
        break;

    case 'h':
        DumpAndHang();
        break;

    case 'e':
        DumpEEPROM();
        break;

    case 'd':
        PrintDebugInfo();
        break;

    case 'i':
        IRtrain_debug = 1;
        uart0_putwaitPROGstr(PSTR("IR debug flag set. (Power-off to clear.)\r\n"));
        break;
    
    case 'p':
        TestPortBits();
        break;
		
	case 't':
		TestHarddisk();
		break;

	case 'w':
		TestWriteHarddisk();
		break;

	case 'r':
		TestReadHarddisk();
		break;

    default:
        uart0_putwaitPROGstr(PSTR("\r\nUnknown command."));
        PrintDebugCommands();
        break;

    }
}





// PrintDebugCommands
//
// Prints the list of debug commands to the debug port.
void PrintDebugCommands(void)
{
    uart0_putwaitPROGstr(PSTR("\r\nDebug Port Commands are:\n\r\n")); 
    uart0_putwaitPROGstr(PSTR("?  - print these commands\r\n")); 
    uart0_putwaitPROGstr(PSTR("e  - dump contents of eeprom\r\n")); 
    uart0_putwaitPROGstr(PSTR("d  - dump some diskdrive debug information\r\n")); 
    uart0_putwaitPROGstr(PSTR("h  - dump some debug info (stack dump) then hang (processor stopped)\r\n"));
    uart0_putwaitPROGstr(PSTR("i  - enable dumping of IR remote-control period values during training\r\n"));
	uart0_putwaitPROGstr(PSTR("p  - test IDE Ports bits where possible. HARDDISK MUST BE UNPLUGGED.\r\n"));
	uart0_putwaitPROGstr(PSTR("t  - test the harddisk interface. Harddisk must be plugged in.\r\n"));
	uart0_putwaitPROGstr(PSTR("w  - Perform repeated writes to the harddisk.\r\n"));
	uart0_putwaitPROGstr(PSTR("r  - Perform repeated reads from the harddisk.\r\n"));
	uart0_putwaitPROGstr(PSTR("\r\n")); 
}





// DumpAndHang
//
// This routine prints out the debug port a bunch of debug information, then hangs (loops forever)
void DumpAndHang (void)
{
	u08		*memptr, i;
		
    // start of stack dump section
	memptr = (u08*)(((*AVR_SPH)<<8) | *AVR_SPL);		// copy stackpointer to memptr
	
	uart0_putwaitPROGstr(PSTR("\n\rStack Pointer value: $"));	
	UART_PutHexWaitC(*AVR_SPH);
	UART_PutHexWaitC(*AVR_SPL);
	uart0_putwaitPROGstr(PSTR("\n\r"));
	
	uart0_putwaitPROGstr(PSTR("Stack dump: $ "));
	for (i=18; i; i--) {
		UART_PutHexWaitC(*++memptr);
		UART_TxCharWaitC(' ');
	}
	uart0_putwaitPROGstr(PSTR("\n\r"));

	for (i=RAMEND-(u16)memptr; i; i--) {
		UART_PutHexWaitC(*++memptr);
		UART_TxCharWaitC(' ');
	}
	uart0_putwaitPROGstr(PSTR("\n\r"));
// End of stack dump code section
// first 2 bytes of 2nd line will be interrupt return address, in correct order (ie don't reverse bytes)

	UART_TxCharWaitC(*AVR_UDR0);			/* display received debug character on debug screen, clears interrupt */
	uart0_putwaitPROGstr(PSTR("Player halted.\r\n"));
    IDE_Standby();		    					/* allow the drive to auto power-down */
	while (1);
}




/******************************************************************************
    
    UART1 Port Handling Routines
    This port is used for sending text to the LCD for display, as well as 
    for receiving button keypress information.
                  
******************************************************************************/


SIGNAL(SIG_UART1_RECV)      
/* signal handler for receive complete interrupt from pushbuttons port */
/* This routine handles UART receive interrupts from UART 1 - the pushbuttons port */
// It reads out the received character and places it in ButtonPress.
// Note that the new buttonpress will overwrite any old one that may be present.
// Most functions, if responding to a buttonpress, will then zero ButtonPress so they
// don't erroneously respond again. This routine only accepts the ASCII
// characters A-z; everything else is discarded (it's a junk filter).
//
// The time the NEXT button was depressed (pressed down) is recorded, for use
// by the CycleStepSize function (in mp3pc.c).
{
    u08     rxchar;
    
    rxchar = (*(volatile u08*)U1DR);                // get the received character

    if ( (rxchar >= 'A') && (rxchar <= 'z') ) {
        // execute here if we have a valid new received character
        ButtonPress = rxchar;

        if (ButtonPress==BUT_NEXT_DN)
            StepSizeStartTime = Tick100ms;          // remember time that NEXT button was depressed
    }
}


void uart1_putwaitstr(u08 *c)
/* copies a string held in SRAM (data memory) to the UART1  *SLOWLY*  */
/* by "owning" the UART and waiting until each char is sent before sending */
/* the next, bypassing the usual transmit queue. Very slow - use only for */
/* debug or in non-time-critical positions (eg initializations). */
{
    while (*c) {
        UART1_TxCharWaitC(*c);
        c++;
    }
}


void uart1_putwaitPROGstr(u08 *c)
/* copies a string held in Flash (program memory) to the UART1  *SLOWLY*  */
/* by "owning" the UART and waiting until each char is sent before sending */
/* the next, bypassing the usual transmit queue. Very slow - use only for */
/* debug or in non-time-critical positions (eg initializations). */
{
    while (PRG_RDB(c)) {
        UART1_TxCharWaitC(PRG_RDB(c));
        c++;
    }
}



void DisplayUART1rx (void)
/* This TEST routine pulls characters out of the UART1 receive port and */
/* sends them to the UART0, ie the debug port. */
/* Useful for seeing the pushbutton codes. */
{

	if (!(*(volatile u08*)U1SR & 0x80))
		return;								/* exit if nothing received */
		
	UART_TxCharWaitC(*(volatile u08*)U1DR);	/* else read data register & give to uart0 */
	return;
}



void HandleButtons (void)
/* This is a main loop routine that responds to any pushbutton presses. Normally the */
/* ButtonPress variable contains 0, meaning no button pressed. If a button is pressed then */
/* we respond accordingly, and clear ButtonPress afterwards. */
// Note that the IR remote control receiver can also write these values into ButtonPress,
// thereby emulating a pushbutton press and causing the player to behave accordingly.
{
	switch (ButtonPress) {
    case 0:
        return;                             /* exit if no pushbutton pressed */

	case BUT_ONOFF:
		SwitchOff();						/* switch the player off - this routine never returns */
		break;

	case BUT_MODE:
        PC_Flag_Mode = ~PC_Flag_Mode;       // toggle value of playcontrol mode flag
        DisplayRandomRpt();                 // display update on lcd
		if (PC_Flag_Mode)   				/* if random mode switched on then... 	*/
			InitRandomVariables();			// initialise the playcontrol random variables
        else                                // else if random mode has just been switched off...
            StepSize = 1;                   // then set Stepsize back to 1 (normal stepping through tracks)
        break;

	case BUT_STOP:
		PC_Command = PC_Cmd_Stop;			/* Tell PlayControl to stop */
		break;

	case BUT_PLAY:
		PC_Command = PC_Cmd_Play;			/* Tell PlayControl to play */
		break;

	case BUT_REPEAT:
        PC_Flag_Repeat = ~PC_Flag_Repeat;   // toggle value of PC_Flag_Repeat
        DisplayRandomRpt();                 // display update on lcd
        break;

    case BUT_PREVIOUS:
 		PC_Command = PC_Cmd_Prev;			/* Tell PlayControl to go to the previous file */
		break;

	case BUT_NEXT_UP:
		PC_Command = PC_Cmd_Next;			/* Tell PlayControl to hop forward to the next file */
		break;

    case BUT_NEXT_DN:
        CycleStepSize();                    // CycleStepSize found in mp3pc.c
        return;                             // Return, not break, to ensure ButtonPress not cleared in this case,
                                            // as we need to keep re-executing this until a BUT_NEXT_UP occurs.
    case BUT_MENUSEL:
        MenuMain();                         // Menu functions
        break;

    case BUT_UP:
        PC_Command = PC_Cmd_Add10;          // While playing, up button steps forward 10 songs
        break;

    case BUT_RIGHT:
        PC_Command = PC_Cmd_Add100;         // While playing, right button steps forward 100 songs
        break;

    case BUT_DOWN:
        PC_Command = PC_Cmd_Bak10;          // While playing, down button steps backward 10 songs
        break;

    case BUT_LEFT:
        PC_Command = PC_Cmd_Bak100;         // While playing, left button steps backward 100 songs
        break;

	default:
		break;							    /* ignore received button character if we can't handle it */
	}

    ButtonPress = 0;                        // we're finished with this button push so delete it, otherwise
                                            // we'd do it all over again. And again. And again...
}




/******************************************************************************
    
    USB Port Handling Routines
                  
******************************************************************************/


SIGNAL(SIG_INTERRUPT6)
// Interrupt service routine for USB connect detect interrupt.
// It shuts down this player, sets all the IDE port pins to inputs, takes the
// Cypress USB chip out of "disabled" state, and then waits.
// (Cypress part enabled by making PE2 an input; external pull-up resistor then
// pulls the enable line active high. Disable Cypress USB by driving PE2 output low.)
// Once the USB connector is removed it resets this player, to allow playing to
// start all over again (after a full reset of this AVR device)
// USB connector status can be read on Port E bit 6 - low means unplugged,
// high means USB connector plugged in.
// For IDE pinout, see header of file ide.s
{

	*AVR_DDRA  = 0x00;                          
	*AVR_DDRB  = *AVR_DDRB & 0x1F;
	*AVR_DDRC  = 0x00;

⌨️ 快捷键说明

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