📄 mp3menus.c
字号:
/******************************************************************************
Title: Frank's MP3 Player Menu routines in C
Author: Frank Van Hooft
Date: 21 Aug 2004
This file contains menu-related routines, ie, the functions that are
executed when the user presses the MENU/SELECT pushbutton.
******************************************************************************/
/******************************************************************************
MenuMain
This is the "wrapper" menu routine, called when the menu button is
initially pressed. It scrolls through the available menu choices (which are
in a linked-list kind of arrangement), displaying their names, and calls
the one selected by the user.
It stops playing of the current track. Most menu items impact playing
anyway (by accessing the disk or whatever) so this is not a real limitation.
When a menu function is called, it is assured (by this MenuMain) that the entire
LCD is cleared and available for its use. Also it doesn't have to clean up the
LCD after it's finished, as this MenuMain will do that for it.
******************************************************************************/
void MenuMain (void)
{
PGM_VOID_P MenuPtr; // MenuPtr is used to point to current menu entry
FnPtr MenuFunction; // function pointer to execute for menu function
ButtonPress = 0; // clear out the pushbutton press that got us here
PlayControlStop(); // stop playing current track
// Display something helpful at the top of the LCD display
PositionLCDcursor(1, 1);
uart1_putwaitPROGstr(PSTR(" Menu Functions Up / Down / Select "));
// Make MenuPtr point to a menu structure (any one will do)
MenuPtr = (PGM_VOID_P)&m_array[1];
// Clear the display area used for the menus & menu functions (lines 3 through 8)
ClearLCDlines(3, 6);
// Display the name of the first menu item (first move cursor to start of 4th line)
PositionLCDcursor(4, 1);
uart1_putwaitPROGstr((u08*)pgm_read_word(MenuPtr+MenuString));
while (ButtonPress != BUT_MENUSEL) { // remain in this loop until a menu function has been selected
switch (ButtonPress) {
case BUT_ONOFF:
ButtonPress = 0;
SwitchOff(); /* switch the player off - this routine never returns */
break;
case BUT_UP:
ButtonPress = 0; // clear out the button press so we don't do this again
// clear out the old menu name on the LCD display
ClearLCDlines(3, 5);
// Point to previous menu record (ie previous in the linked list)
MenuPtr = (PGM_VOID_P)pgm_read_word(MenuPtr+PrevMenu);
// Display the name of our new menu item (first move cursor to start of 4th line)
PositionLCDcursor(4, 1);
uart1_putwaitPROGstr((u08*)pgm_read_word(MenuPtr+MenuString));
break;
case BUT_DOWN:
ButtonPress = 0; // clear out the button press so we don't do this again
// clear out the old menu name on the LCD display
ClearLCDlines(3, 5);
// Point to next menu record (ie next in the linked list)
MenuPtr = (PGM_VOID_P)pgm_read_word(MenuPtr+NextMenu);
// Display the name of our new menu item (first move cursor to start of 4th line)
PositionLCDcursor(4, 1);
uart1_putwaitPROGstr((u08*)pgm_read_word(MenuPtr+MenuString));
break;
}
}
// If we're here it's because the MENUSEL button was pressed, exiting us from the above switch statement,
// so execute that menu function. Then wrap-up & return to the player.
ButtonPress = 0; // clear out the button press that got us here
ClearLCDlines(1, 8); // blank all the LCD display lines
MenuFunction = (FnPtr)pgm_read_word(MenuPtr+MenuFn); // get address of the menu function
MenuFunction(); // and call it
// Clear display lines the menu function may've been using (1-8), display name & ready & Random/Repeat mode states
ClearLCDlines(1, 8);
DisplayName();
DisplayReady();
DisplayRandomRpt();
}
void NULLfunction (void)
// This function does nothing - it just returns.
{
}
/******************************************************************************
OutputLevel
This Menu-accessible routine allows the user to change the output level
(volume level) of the player.
The attenuation value for the STA013 codec is kept in eeprom. From a user
perspective "output level" or "volume level" is more intuitive, so that's
what this routine uses. Which is basically the reverse of attenuation.
******************************************************************************/
void OutputLevel (void)
{
u08 err,dispnum; // number to be displayed on-screen
PositionLCDcursor(1, 1); // place cursor at start of top display line
uart1_putwaitPROGstr(PSTR(" Change Output Level Up / Down / Select Default is 255 (maximum) "));
dispnum = 255 - eeprom_read_byte(STattenuation); // output level is reverse of attenuation (stored in eeprom)
PositionLCDcursor(5, 11); // place cursor in middle of of 5th display line
PrintASCIIword (dispnum, 1); // display output level number on lcd
while (ButtonPress != BUT_MENUSEL) { // loop until user presses SELECT key
switch (ButtonPress) {
case BUT_ONOFF:
ButtonPress = 0;
SwitchOff(); /* switch the player off - this routine never returns */
break;
case BUT_UP:
ButtonPress = 0; // clear out the button press so we don't do this again
if (dispnum < 255) dispnum++; // increment output level
ClearLCDlines(5, 1); // clear 5th line on lcd display
PositionLCDcursor(5, 11); // place cursor in middle of 5th display line
PrintASCIIword (dispnum, 1); // display output level number on lcd
break;
case BUT_DOWN:
ButtonPress = 0; // clear out the button press so we don't do this again
if (dispnum > 0) dispnum--; // deccrement output level
ClearLCDlines(5, 1); // clear 5th line on lcd display
PositionLCDcursor(5, 11); // place cursor in middle of 5th display line
PrintASCIIword (dispnum, 1); // display output level number on lcd
break;
}
}
// Now we have new output level in dispnum. Attenuation is reverse of this. Write it to eeprom & STA013.
dispnum = 255 - dispnum; // convert output level to an attenuation
EEPROM_Write(STattenuation, dispnum); // write attenuation figure to eeprom
err = sta013_writeTWI (0x46, dispnum); /* set attenuation for the STA013 left output channel */
if (err != TWI_write_OK) StopOnError(err + 80); /* report error if it occurs */
Delayms(1); /* waste a little time */
err = sta013_writeTWI (0x48, dispnum); /* set attenuation for the right output channel */
if (err != TWI_write_OK) StopOnError(err + 90); /* report error if it occurs */
}
/******************************************************************************
DisplayNumDirFiles
This Menu-accessible routine displays the number of MP3 files in the
current directory. It just reads the number from the eeprom & displays it.
It also displays the name of the current directory.
******************************************************************************/
void DisplayNumDirFiles (void)
{
u16 numfiles;
PositionLCDcursor(1, 1); // place cursor at start of top display line
uart1_putwaitPROGstr(PSTR("Number of MP3 files in current directory"));
GetCurrentDirName(); // get name of directory we're currently in
IDE_AutoPD(); // tell the drive to auto power-down
PositionLCDcursor(3, 1);
uart1_putwaitstr((u08*)&FINDFILE_RET_NAME[1]); // and print current directory name on LCD screen
PositionLCDcursor(5, 1);
uart1_putwaitPROGstr(PSTR("is: "));
numfiles = (((u16)EEPROM_ReadC(StoreNumFilesH))<<8) + (u16)EEPROM_ReadC(StoreNumFilesL); // get # from eeprom
PrintASCIIword(numfiles, 1); // print number on lcd
PositionLCDcursor(7, 1); // place cursor at start of 7th display line
uart1_putwaitPROGstr(PSTR("Press SELECT to exit."));
while (ButtonPress != BUT_MENUSEL); // wait for SELECT button to be pressed.
ButtonPress = 0; // clear out that button press. We're done.
}
/******************************************************************************
ChangeDir
This Menu-accessible routine allows the user to change the current directory.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -