📄 yampp7_usb.c
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and
** Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-7/USB - main file
**
** File yampp7_usb.c
**
*************************************************************************
**
** This file is part of the yampp system.
**
** This program 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.
**
*************************************************************************
**
** Revision History
**
** when what who why
**
** 2002-09-13 0.9 Jesper
-initial test release
** 2002-09-22 1.0 MIS
-change automatic power off time to 2 minutes (in stop mode)
-added card present checking, if no card present or card removed - go to sleep mode
-added LED output on PB0
-changed wakeup from sleep - now we must press and hold "Play" key for two seconds
-added some beeps and blinks
-added beep during playlist change. Playlist <TOTAL> have different tone from other.
-added little delay in keypress checking for avoid accidental key pressing.
-added FastForward, Random, Loudness and Repeat functions.
-all functions is handled by 4 keys, layout is depending on playing state.
-added trap for vs1001 lockup if MP3 has garbage
-added manual power off -> longpress STOP key in Stop mode.
-added auto power of from pause state after 30 minutes
-added battery level monitoring.
-added battery charge indicator. See README.TXT for details.
** 2002-09-25 1.10 MIS
-added true random function (max 1024 songs in playlist)
** 2002-10-04 1.11 MIS
-added card removing checking during pause and stop mode
-code speed-up and cleaning
-added configurable CF standby time (in Constants.h)
** 2002-10-07 1.12 MIS
-added keyboard locking functions with autolock. See README.TXT for details.
** 2002-10-09 1.13 MIS
-fixed accidentally bootloader entering during keyboard locking
-fixed accidentally change song after keyboard unlocking
-added beep for manual lock/unlock confirmation (may be off in Constants.h)
-added autolock turn ON/OFF while normal operation (if enabled)
** 2002-10-14 1.20 MIS
-beta version, added suport for Nokia LCD (not public)
** 2002-10-18 to1.45 MIS
-most bugfix (not public)
** 2002-10-20 2.00 MIS
-Public beta version of y7 firmware with LCD support.
** 2002-10-21 2.10 MIS
-added total song time displaying.
-minior bugfix.
** 2002-10-23 2.11 MIS
-some improvements and bugfixes in displaying functions
-bugfix in next playlist change. Stack overvriting generate this problem.
-little change in keylock icons
** 2002-10-29 2.12 MIS
-eeprom is written only before power-off or USB connect, for extend eeprom life.
-added suport for card-specific graphical logo.
-bugfix in battery charge indication during stop.
-bugfix in artist name displaying if name is short.
-bugfix in fast forward volume decrease.
** 2002-10-30 2.13 MIS
-added support for national characters displaying
** 2002-11-02 2.14 MIS
-added support for vs1001 equalizer
-some memory usage fixes
** 2002-11-05 2.15 MIS -changed scroll routines
** 2002-11-23 2.16 MIS -fixed card removing checking
-fixed "MENU" text length
-fixed battery level monitoring
-fixed randomizer
-alternate scroll is back
** 2002-12-18 2.17 MIS
-added remain song time displaying
** 2003-01-13 2.18 MIS
-added compatibility with new versions of GCC
-some menu functionality extensions
-removed uart calls
-removed not used beep calls
-some code optimisations
** 2003-02-23 2.20 MIS
-added MMC card support
-added support for new version of VS1001 equalizer library with 12 presets
-changes in ATA library
-many code optimisations
-fixed contrast setting
** 2003-03-18 2.21 jesper
- modifications for new Rev. D board.
- charge input changed to PE1 instead of PE2
- expanded contrast range
** 2003-03-19 2.22 MIS -small fixes in jesper modifications
-bugfix in processing garbaged song
-support for any old and a new Rev D board (see Constants.h)
** 2003-05-18 2.23 MIS -added balance control
-enabled playlist change during STOP state
-added info about backlight mode
-code size optimization
-some bugfix in visualisation, charging control ect.
** 2003-07-14 2.25b1 MIS -Sources changed for compilation with AVR-GCC 3.3 !!!
-added new optional "PREVOUS" key functionality (work like in normal CD players).
-fixed problems with some large CF cards
-fixed problems with yamppLink conect/disconnect on MMC cards.
-fixed Pause Mode
** 2003-08-08 2.25b2 nilrog -fixed playlists handling by changing the "get_offset_entry" function.
MIS -adding way to fix the CF card reset after card inserting problem solving.
** 2004-01-18 2.28 MIS -added support for native mode of AtMega162 with crystal about 6-14MHz.
This cause speed up file transfer to about 400kb/s (at 14.318Mhz)
-removed not used Uart and Base libraries code and not used part in usb.c file.
-added confirmation before card formatting.
-fixed low battery checking
-fixed startup without card
-speedup MMC card write
** 2004-05-20 2.29 MIS -added 6 backlight modes with dimmer in M162 mode
-fixed VS1001 hardware reset if VS not respond
-Fixed "Browse list" function.
-Fixed MMC library
** 2004-10-08 2.30 Nilrog -fixed repeat one song function
MIS -fixed MMC size and name detection
-fixed standby high current consumption with some MMC cards
** 2005-03-17 2.40 jesper -fixed compatibility with new AVR-GCC 3.4.x
-added some fixes from version 3.50
** 2005-03-21 2.41 MIS -fixed MMC support
** 2005-03-31 2.42 MIS -fixed eeprom download procedure. In v2.41 downloading national chars not work.
** 2005-05-27 2.43 MIS -added support for true battery voltage measuring
** 2005-06-01 2.44 MIS -added song and artist name scrolling during songs browsing
-added current song info in menu
-code size optimization
*********************************************************************** */
#include "yampp7_usb.h"
#define YAMPP_FIRMWARE_VERSION_MAJOR 2
#define YAMPP_FIRMWARE_VERSION_MINOR 44
#define DISK_LAYOUT_VERSION_MAJOR 1
#define DISK_LAYOUT_VERSION_MINOR 0
// The CPU is running with a 4.0 MHz (M161 CPU) or 4-15MHz (M162 CPU) clock
#if (GCC_VERSION < 3004)
char firmware_scan_tag[] __attribute__ ((progmem)) = "yfwTAG";
char model_txt[] __attribute__ ((progmem)) = "yampp-7";
char date_txt[] __attribute__ ((progmem)) = __DATE__" / "__TIME__;
char version_txt[] __attribute__ ((progmem)) = "2.44";
#else
char version_txt[] __attribute__ ((progmem)) = "2.44";
char date_txt[] __attribute__ ((progmem)) = __DATE__" / "__TIME__;
char model_txt[] __attribute__ ((progmem)) = "yampp-7";
char firmware_scan_tag[] __attribute__ ((progmem)) = "yfwTAG";
#endif
//------------------------------------------------------------------------------------------
extern u08 card_sbuf[512];
//------------------------------------------------------------------------------------------
void idle(void);
void next_song(u08 mode);
u08 BatteryMeasure(void);
void set_cpu_speed(u08 speed);
event_e menu_event;
u08 isPlaying; // Playing status
u08 usb_play; // usb playing status
u08 bLoudness; // Loudness modificator
u08 bRandom; // Random modificator
u08 Repeat; // Repeat mode modificator
u08 keylock; // Keylock status
u08 autolock; // Autolock ON/OFF
u08 lobatt; // Battery status
u08 timemode; // Remain time modificator
u08 light_mode; // LCD backlight mode
u08 volume; // Volume level
s08 balance; // Balance
u08 vol_decrease; // Modificator for fast forward function
u16 ClusterCount; // Counter for Fast Forward calculations
u16 addtime; // for Fast Forward time calculation
u16 curPlaylist; // Current playlist number
u16 curIndex; // Current song number inside playlist
u32 filesize; // size of file to play (divided by 32)
u32 fileplayed; // amount of played data (divided by 32)
u16 bitrate; // song bitrate for fast forward time calculation
u16 songtime;
u08 info_flag;
u08 logo;
volatile u08 time_flag; // general time counter
volatile u08 scroll_flag; // scrolling flag
volatile u08 light_time; // LCD backlight time
volatile u16 sleepcount; // counter for automatic power off
volatile u16 lobatt_time; // counter for low battery checking
volatile u16 keylock_time; // automatic keylock timer
u16 vs1001_fw; // Pointer into vs1001 additional firmware pointer
u08 *outptr; // pointer for sending data to vs1001
u08 ARTISTNAME_BUF[48]; // buffer for artist name scrolling
u08 SONGNAME_BUF[55]; // buffer for title name scrolling
u08 *artistname = (u08*)ARTISTNAME_BUF; // pointer to artistname buffer
u08 *titlename = (u08*)SONGNAME_BUF; // pointer to songname buffer
u08 scroll_length; // size of scroll data
u08 scroll_length_2; // size of scroll data 2
u08 scroll_pos; // current position in scroll string
u08 scroll_pos_2; // current position in scroll string 2
#ifdef ALTERNATE_SCROLL
u08 scroll_dir, scroll_dir_2;
u08 scrollP, scrollP_2;
#endif
u08 fn0[] __attribute__ ((progmem)) = "Song Info";
u08 fn1[] __attribute__ ((progmem)) = "Find Song";
u08 fn2[] __attribute__ ((progmem)) = "Next Playlist";
u08 fn3[] __attribute__ ((progmem)) = "Prev Playlist";
u08 fn4[] __attribute__ ((progmem)) = "Random";
u08 fn5[] __attribute__ ((progmem)) = "Repeat Mode";
u08 fn6[] __attribute__ ((progmem)) = "Balance";
u08 fn7[] __attribute__ ((progmem)) = "Loudness";
u08 fn8[] __attribute__ ((progmem)) = "Time Mode";
u08 fn9[] __attribute__ ((progmem)) = "LCD Contrast";
u08 fn10[] __attribute__ ((progmem)) = "Autolock Keys";
#if (BACKLIGHT_TIME != 0)
u08 fn11[] __attribute__ ((progmem)) = "BacklightMode";
u08 *function_name[] __attribute__ ((progmem)) = {
(u08*)&fn0,(u08*)&fn1,(u08*)&fn2,(u08*)&fn3,(u08*)&fn4,(u08*)&fn5,(u08*)&fn6,(u08*)&fn7,(u08*)&fn8,(u08*)&fn9,(u08*)&fn10,(u08*)&fn11};
#else
u08 *function_name[] __attribute__ ((progmem)) = {
(u08*)&fn0,(u08*)&fn1,(u08*)&fn2,(u08*)&fn3,(u08*)&fn4,(u08*)&fn5,(u08*)&fn6,(u08*)&fn7,(u08*)&fn8,(u08*)&fn9,(u08*)&fn10};
#endif
//---------------------------------------------------------------------------
u08 CARD_SW_Reset2(void) // ATA Reset
{
#ifdef MMC_CARD
if(MMC_Check())
{
if(! MMC_Reset())
return 0;
}
return 1;
#else
u16 timeout = 5000; // timeout = 500ms
WriteBYTE(ATAPI_DevCtrl, 0x06); // SRST and nIEN bits
delay10(); // 10uS delay
WriteBYTE(ATAPI_DevCtrl, 0x02); // nIEN bit
delay10(); // 10 uS delay
while ((ATA_ReadStat() & 0xC0) != SR_DRDY) // Wait for DRDY and !BUSY
{
if (--timeout == 0) // Timeout check
return (0); // Return with ERROR
delay100(); // 100 uS delay
}
if (ReadBYTE(ATA_Sector) != 1) // Checking for RESET signature
return (0); // Return with ERROR
return 1;
#endif
}
//----------------------------------------------------------------------------
#define EVENT_QUEUE_SIZE 4
volatile event_e event_queue[EVENT_QUEUE_SIZE];
volatile u08 event_queue_head = 0;
volatile u08 event_queue_tail = 0;
void set_event(event_e e)
{
event_queue[event_queue_head] = e;
event_queue_head = (event_queue_head + 1) % EVENT_QUEUE_SIZE;
}
event_e check_event(void)
{
event_e tmp = EV_IDLE;
//
// check queue
//
if (event_queue_head != event_queue_tail)
{
tmp = event_queue[event_queue_tail];
event_queue_tail = (event_queue_tail + 1) % EVENT_QUEUE_SIZE;
}
return tmp;
}
event_e get_event(void)
{
//
// let the system have it's time
//
idle();
return check_event();
}
//--------------------------------------------------------------------------
// States for M162 mode M161 mode
//
// 0 Always OFF Always OFF
// 1 OFF/DIMM OFF/ON
// 2 OFF/ON Always ON
// 3 Always DIMM not allowed
// 4 DIMM/ON not allowed
// 5 Always ON not allowed
#if (BACKLIGHT_TIME != 0)
void backlight_off(void)
{
#if defined (__AVR_ATmega162__)
if(light_mode < 3) // OFF state
OCR0 = 0;
else if(light_mode < 5)
OCR0 = BL_DIMMLEVEL; // DIM state
#else
if(light_mode < 2)
PORTB &= ~_BV(LED_PIN); // OFF state
#endif
}
void backlight_on(void)
{
light_time = 0;
#if defined (__AVR_ATmega162__)
if(light_mode > 3 || light_mode == 2)
OCR0 = 0xff; // ON state
else if(light_mode != 0)
OCR0 = BL_DIMMLEVEL; // DIMM state
#else
if(light_mode != 0)
PORTB |= _BV(LED_PIN); // ON state
#endif
}
#endif // BACKLIGHT_TIME != 0
//--------------------------------------------------------------------------
//
// External INT2 (Play key)
//
__attribute__ ((naked)) // Disable registers PUSH / PULL into stack (code size optimisation)
SIGNAL(SIG_INTERRUPT2) // Need this for wake up from sleep
{
asm volatile ("reti");
}
//--------------------------------------------------------------------------
#define TI1_V ((u16)-(F_CPU / 2560))
SIGNAL(SIG_OVERFLOW1) // timer 1 overflow every 100 mS
{
TCNT1 = TI1_V; // reload timer
time_flag++; // general time counter
scroll_flag++;
nKeyTime++; // counter for keyboard
lobatt_time++; // counter for low battery routine
sleepcount++; // sleep counter
#if (BACKLIGHT_TIME != 0)
if (light_time != 255)
{
if (++light_time > BACKLIGHT_TIME)
{
light_time = 255;
// backlight_off(); // backlight OFF
asm volatile ("call backlight_off"); // code size optimisation
}
}
#endif
if (isPlaying && keylock==0 && autolock)
{
if (keylock_time <= AUTOLOCK_TIME+20)
keylock_time++;
else
{
keylock = 1;
#if (BACKLIGHT_TIME == 0)
PORTB |= _BV(LED_PIN);
#endif
}
}
}
//--------------------------------------------------------------------------
void LoudSet(void)
{
if (vs1001_fw)
{
if(bLoudness)
{
vs1001_write(0x0A,vs1001_fw);
vs1001_write(0x0D,0);
vs1001_write(0x0D,bLoudness);
}
else
{
vs1001_write(0x0D,0);
vs1001_write(0x0A,0);
}
}
else
vs1001_write(VS1001_MODE, 0x0080 * (bLoudness != 0)); // write bit SM_BASS to VS1001K
vs1001_setvolume(volume,balance);
}
//--------------------------------------------------------------------------
static u08 buf[] __attribute__ ((progmem)) = {0x53, 0xEF, 0x6E, 0x45, 0x78, 0x69, 0x74};
void beep(u08 freq, u16 time)
{
u08 i;
vs1001_write(0x0D,0);
vs1001_write(0x0A,0);
if (isPlaying)
{
addtime += vs1001_read(VS1001_PLAYTIME);
vs1001_reset();
}
vs1001_setvolume(volume+24,balance); // -12dB
#if (BACKLIGHT_TIME == 0)
PORTB |= _BV(LED_PIN); // LED on
#endif
vs1001_nulls(8);
for (i=0;i<3;i++) // beep on
vs1001_send_data(pgm_read_byte(&buf[i]));
vs1001_send_data(freq);
vs1001_nulls(4);
delayms(time);
for (i=3;i<7;i++) // sine OFF
vs1001_send_data(pgm_read_byte(&buf[i]));
vs1001_nulls(4);
#if (BACKLIGHT_TIME == 0)
PORTB &= ~_BV(LED_PIN); // LED Off
#endif
LoudSet(); // restore Loudness settings and Volume
}
//--------------------------------------------------------------------------
void send_sinewave_beeps(void)
{
u08 j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -