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

📄 player.c

📁 这项工程将让您把自己的MP3播放器平台
💻 C
📖 第 1 页 / 共 2 页
字号:
//++
//player.c - system startup, POST, and initialization
//
// Copyright (C) 2005 by Spare Time Gizmos.  All rights reserved.
//
// This file is part of the Spare Time Gizmos' MP3 Player firmware.
//
// This firmware 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.
//
// This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA  02111-1307  USA
//
//DESCRIPTION:
//
//TODO:
//
// REVISION HISTORY:
// dd-mmm-yy    who     description
// 15-May-05    RLA     New file.
// 12-Oct-05	RLA	SDCC doesn't support printf precision for strings
//			The SDCC __DATE__ macro returns too many characters
//			On non-FAT volumes, don't display the volume label
//			Change calling sequences for FAT and CFCARD routines
// 15-Oct-05	RLA	Add VOLUME conditional
// 19-Oct-05	RLA	Call ResetMP3Decoder() to abort playing (when the knob
//			 is turned).  This avoids noise in the output.
//--

// Include files...
#include <stdio.h>		// needed so DBGOUT(()) can find printf!
#include <string.h>		// needed for memcpy(), memset(), et al...
#include "reg66x.h"		// declarations for Philips 89C66x processors
#include "standard.h"		// standard types - BYTE, WORD, BOOL, etc
#include "player.h"		// project wide (hardware configuration) declarations
#include "post.h"		// power on self test diagnostics
#include "debug.h"		// debuging (serial port output) routines
#include "timer.h"		// time keeping functions
#include "buffer.h"		// disk buffer management functions
#include "display.h"		// LCD/VFD display interface
#include "i2c.h"		// I2C driver functions
#include "sta013.h"		// STA013 MP3 decoder functions
#include "cfcard.h"		// compact flash card interface functions
#include "fat.h"		// FAT12/16 functions
#include "switches.h"		// user interface (rotary encoder) functions
#include "id3.h"		// ID3 tag definitions and functions

//   This is the copyright notice, version, and date for the software in plain
// ASCII.  Even though this only gets printed out in the debug version, it's
// always included to identify the ROM's contents...
PUBLIC char const code g_szFirmware[] =
  "MP3 Player Firmware " __DATE__ " " __TIME__;
PUBLIC char const code g_szCopyright[] =
  "Copyright (C) 2005 by Spare Time Gizmos.    All rights reserved.";



//++
//   This routine will show the copyright "screen" on the display.  It will
// pause for five seconds before returning...
//--
PRIVATE void ShowCopyright (void)
{
  ClearDisplay();
  DisplayTextAt(0, 0, COPYRIGHT_SYMBOL " SPARE TIME GIZMOS");
  DisplayTextAt(1, 0, "MP3 Player v%03u %04X", (WORD) VERSION, g_wROMChecksum);
  DisplayTextAt(2, 0, "   %1bdK RAM %2bdK ROM",
   (BYTE) ((RAMSize()+256) >> 10), (BYTE) (ROMSIZE >> 10));
  DisplayTextAt(3, 4, "%s", __DATE__);
  DelayMS(5000);
  //while (PUSH_BUTTON) ;
}

//++
//   This routine will clear the display and show the first three (of the four)
// lines that appear while we're playing an MP3.  These lines show the file name
// and (if the file has an ID3 tag) the artist and song name.  The remaining
// fourth line comes from ShowPlaybackStatus()...
//--
PRIVATE void ShowPlaybackNames (PXDIRENT pxDirEnt)
{
  ClearDisplay();
  //   If this file has an LFN (long file name) then show that on the first
  // line; otherwise the traditional 8.3 name will have to do.  Note that
  // we never show the .MP3 extension in any case - when all files are MP3,
  // why bother?
  if (strlen(g_szLongFileName) > 0) {
    DisplayTextAt(0,0,"%.20s", g_szLongFileName);
  } else {
    DisplayTextAt(0,0,"%8.8s.%3.3s", pxDirEnt->szFileName, pxDirEnt->szFileType);
  }
  //   Now open the file and attempt to read the ID3 tag.  If we get lucky and
  // find one, then use that to show the title and artist.
  if (ReadID3Tag(pxDirEnt)) {
    DisplayTextAt(1,0,"%.20s",g_szArtistName);
    DisplayTextAt(2,0,"%.20s",g_szTrackName);
  }
}

//++
//   And this routine will display the fourth line used while we're playing.
// This line shows the current running time (in mmm:ss), the MP3 bit rate
// (kbps) and the sampling frequency (kHz)...
//--
PRIVATE void ShowPlaybackStatus (BOOL fPaused)
{
  BYTE bSeconds;  WORD wMinutes;
  GetElapsedTime(wMinutes);
  bSeconds = (BYTE) (wMinutes % 60);  wMinutes /= 60;
  if (fPaused)
    DisplayTextAt(3,0,"%3u:%02bu    PAUSED    ", wMinutes, (BYTE) bSeconds);
  else
    DisplayTextAt(3,0,"%3u:%02bu %3ukbps %2bukHz", 
      wMinutes, (BYTE) bSeconds, GetMP3BitRate(), (BYTE) GetMP3SampleFrequency());
}


//++
//   Unfortunately, we don't support hot swapping of CF cards (the CF standard
// makes that pretty much impossible for any application that uses TrueIDE mode)
// so contrary to what its name might lead you to believe, this routine does NOT
// wait for a card to be inserted.  If one isn't already in there at power up,
// this routine just displays an error message and returns FALSE, and that will
// make the main program loop forever until the user reboots us.
//
//   If a CompactFlash card is inserted now, then this routine will initialize
// the IDE interface and attempt to find a FAT16 filesystem on it.  If we're
// successful it will display a brief status screen (for about 2 seconds) and
// then return TRUE; if the card can't be read or if it doesn't contain a FAT16
// file system, then an error message is displayed and FALSE results.
//--
PRIVATE BOOL IsCardReady (void)
{
  ClearDisplay();

  //   If there's no CF card in the socket now, then tell him to turn off the
  // power, insert one, and try again...
  if (!IsCardInserted()) {
    DBGOUT(("??IsCardReady: No card inserted ...\n"));
    //                   01234567890123456789
    DisplayStringAt(0,0,"???? NO CF CARD ????");
  //DisplayStringAt(1,0,"                    ");
    DisplayStringAt(2,0,"  insert card and   ");
    DisplayStringAt(3,0,"    cycle power     ");
    return FALSE;
  }

  //   Initialize the IDE interface.  If we can't, then either the card is bad
  // or he has tried to hot swap it (which prevents the card from going into
  // TrueIDE mode).  Either way he has to restart...
  if (!InitializeCard()) {
    DBGOUT(("??IsCardReady: Failed to initialize TrueIDE interface ...\n"));
    //                   01234567890123456789
    DisplayStringAt(0,0,"????? BAD CARD ?????");
  //DisplayStringAt(1,0,"                    ");
    DisplayStringAt(2,0,"unable to initialize");
    DisplayStringAt(3,0," TrueIDE interface  ");
    return FALSE;
  }

  //  Identify the card's manufacturer, type and size.  Mostly this is just for
  // show, but it does serve to verify that the card really is a Flash Memory
  // device (after all, it might be a modem or a network card or anything!)...
  if (!IdentifyCard()) {
    DBGOUT(("??IsCardReady: Unrecognized card \"%s\"\n", g_szCardName));
    //                   01234567890123456789
    DisplayStringAt(0,0,"????? BAD CARD ?????");
  //DisplayStringAt(1,0,"                    ");
    DisplayStringAt(2,0," unable to identify ");
    DisplayStringAt(3,0,"    card  type      ");
    return FALSE;
  }
  DisplayTextAt(0, 0, "%.20s", g_szCardName);
  DisplayTextAt(1, 0, "Type %04X Size %uMb", g_wCardAttributes, g_wCardSize);

  // Finally, try to find a file system that we can deal with...
  if (!InitializeFAT()) {
    DBGOUT(("??IsCardReady: Not a FAT16 file system \"%s\"\n", g_szSystemType));
    //                   01234567890123456789
    DisplayStringAt(2,0,"??? not a FAT16  ???");
    DisplayStringAt(3,0,"??? file system  ???");
    //DisplayTextAt(1, 10, "%s", g_szSystemType);
    return FALSE;
  }

  //   It's a good card and a good file system.  Find the volume label and
  // count the number of MP3 files in the root directory.  If there are no
  // MP3 files, then there's nothing we can do with this card!
  GetVolumeData();
  DisplayTextAt(2,0,"%11.11s", g_szVolumeLabel);
  if (g_wTotalMP3Files == 0) {
    //                   01234567890123456789
    DisplayStringAt(3,0,"??? no mp3 files ???");
    return FALSE;
  }    
  DisplayTextAt(3,0,"%u MP3 Files", g_wTotalMP3Files);

  // Delay a few moments so the user can read the screen and then return...
  DelayMS(5000);
  return TRUE;
}

//++
//   This routine will play one MP3 file given its directory entry.  Ordinarily
// it will play the entire file, beginning to end, and won't return until the
// end of file is reached.  A basic pause/resume function, using the push button,
// is implemented locally.  If, however, the rotary encoder is turned this
// routine will abort playback of the current file and return immediately.  It
// doesn't change the value of g_nEncoderCount in the process of doing this -
// it's up to the caller to notice that this value is non-zero and skip forward

⌨️ 快捷键说明

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