📄 yampp3_usb.c
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and
** Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-3/USB - main file
**
** File yampp3_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-01 1.0 MIS -initial public release
** 2002-09-25 1.10 Jesper -solved problems with some IR remotes standard detection
** 2002-09-27 1.11 MIS -improved visualisation on 4 lines LCD's
** 2002-09-28 1.12 MIS -next visualisation improvements (see Constants.h)
** 2002-10-10 1.13 MIS -visualisation changes in MENU function
-added numeric volume level (in dB) on LCD longer than 16 chars.
-fixed sound breaking after exit from PAUSE state.
-added prevous playlist if mode=1 and you press PREVOUS key
** 2002-10-20 1.14 MIS -bugfix in playlist name displaying on 4 lines LCD
** 2002-10-21 1.15 MIS -added total song time displaying
** 2002-10-26 1.16 MIS -bugfix in volume indicator clearing
** 2002-11-02 1.17 MIS -added support for vs1001 equalizer running and settings
** 2002-11-08 1.20 MIS -added suport for graphics LCD display from Nokia GSM phones
** 2002-11-10 1.21 MIS -added bitrate displaying on graphisc LCD.
** -posibility to use bigger logo (84x40 pixels)
** -two versions of progresspar on graphisc LCD.
** -invert mode (negative image) on graphisc LCD.
** -some minor bugfixes.
** 2002-11-14 1.22 MIS -added national characters conversion in standard alphanumeric LCD's.
** 2002-12-18 1.23 MIS -added storing time mode into EEPROM.
** 2002-12-22 1.24 MIS -added support for older than K versions of VS1001.
** 2003-02-23 1.25 MIS -added support for new version of VS1001 equalizer library with 12 presets
** 2003-04-10 1.26 MIS -added balance control
-added quick equalizer ON/OFF function (from remote or local keyboard),
filter number is selectable from Menu and Remote.
-added Info about current song in EV_INFO event
-added auto accept selected song - during song browse, if current song ends.
-fixed progressbar flicker during fast rewind
-if 8 keys control is used -> removed not needed functions from Menu
-fixed bug in setup remote procedures
-code optimalisation
** 2003-06-15 1.27 MIS -added storing current position inside song after PAUSE and power-off
-added direct Playlist and Song number select in "Playlist" menu (numerical keys at remote).
-added volume ramp-up after startup the player with the autoplay.
-added new optional "PREVOUS" key functionality (work like in normal CD players).
-added compatibility for some extended RC-5 remotes.
-added volume level dB displaying on 16 chars line length LCD's.
-little ata procedures speed-up.
-fixed volume bug during fast forward and rewind.
-disable songbase and playlist caching for code space recovery (not needed anyway)
-some first attempt to Remote Yampp Sattelite Display support. Not finished yet.
** 2003-07-10 1.30b1 MIS -Sources changed for compilation with AVR-GCC 3.3 !!!
-fixed progressbar bug during fast forward and rewind after volume change.
-fixed uart info formating
-improved IR remote codes learning
-better IR remote autorepeat function
-finished full Remote Yampp Sattelite Display support.
-added support for Graphics 128x64 display.
-added support for Rottary Switch control.
** 2003-08-10 1.30b2 MIS -New autorepeat function not work on REC80 remotes. Revert to old and working.
-Fixed small displaying bug on 128x64 graphics LCD.
-Fixed volume bar on nokia LCD's.
*********************************************************************** */
#define YAMPP_FIRMWARE_VERSION_MAJOR 1
#define YAMPP_FIRMWARE_VERSION_MINOR 30
#define DISK_LAYOUT_VERSION_MAJOR 1
#define DISK_LAYOUT_VERSION_MINOR 0
static char firmware_scan_tag[] __attribute__ ((progmem)) = "yfwTAG";
static char model_txt[] __attribute__ ((progmem)) = "yampp-3/USB";
static char date_txt[] __attribute__ ((progmem)) = __DATE__" / "__TIME__;
static char version_txt[] __attribute__ ((progmem)) = "1.30";
/*
PIN assignements on the yampp3/USB board
PA0-PA7 data bus 0..7 + Address 0..7
PB0 T0 DIOW
PB1 T1 DIOR
PB2 AIN0 DREQ
PB3 AIN1 BSYNC
PB4 SS MP3
PB5 MOSI SO
PB6 MISO SI
PB7 SCK SCK
PC0-=C7 address 8..15
PD0 RxD RS-232/RS-485 RX
PD1 TxD RS-232/RS-485 TX
PD2 INT0 TX_ENABLE (alternatively KEY_INPUT2 or graphisc LCD C/D output)
PD3 INT1 KEY_INPUT
PD4 T0 TXE
PD5 T1 RXE
PD6 WR RD
PD7 RD WR
PE0 ICP IR-IN
PE1 ALE ALE
PE2 OC1B LCD_ENABLE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The CPU is running with a 7.3728 MHz clock
*/
#define _SFR_ASM_COMPAT 1
#include "yampp3_usb.h"
//------------------------------------------------------------------------------------------
// Amount of small steps in LCD play position bar
#define LCD_STEPS ((LCD_LINE_LENGTH - 6) * 5)
//------------------------------------------------------------------------------------------
void idle(void);
void next_song(u08 mode);
event_e menu_event;
u08 isPlaying; // playing status
#ifdef ENABLE_USB_PLAYING
u08 usb_play; // usb playing status
#else
#define usb_play 0
#endif
u08 bLoudness; // loudness modificator
u08 bRandom; // random modificator
u08 Repeat; // repeat modificator
u08 info_flag; // 0=enable display, 1,2=only scroll enabled, 3,4=disable update
u08 timemode; // normal or remain time displaying modificator
u08 volume; // volume level
s08 balance;
u08 vol_decrease; // modificator for fast forward and fast rewind functions
u16 BackStepPos; // Actual position in backstep tabele
u08 OldSteps; // For progressbar displaying
u08 *outptr; // pointer for sending data to vs1001
u08 *buffer1; // first play buffer begin pointer
u08 *buffer2; // second play buffer begin pointer
u08 *buffer3; // second play buffer end pointer
u08 *updbuf; // pointer for buffer updating
u32 filesize; // size of file to play (divided by 32)
u32 fileplayed; // amount of played data (divided by 32)
u16 songtime; // time of current song in seconds
u16 addtime; // time calculation helper for fast forward and fast rewind functions
u16 bitrate; // bitrate of current song
u16 ListQty; // numbers of songs inside playlist
u16 vs1001_fw; // VS1001 firmware address
u08 *artistname = (u08*)ARTISTNAME_BUF; // pointer to artistname buffer
u08 *titlename = (u08*)SONGNAME_BUF; // pointer to songname buffer
u08 *scroll_line = (u08*)SCROLL_LINE; // pointer to scroll line buffer
u08 scroll_length; // size of scroll data
u08 scroll_pos; // current position in scroll string
#ifdef ALTERNATE_SCROLL
u08 scroll_dir;
#endif
#ifdef VOL_UP_RAMP
u08 volume_ramp; // volume level multiplier at volume startup ramp
#endif
#if (LCD_LINES != 2)
u08 scroll_length_2; // size of scroll data 2
u08 scroll_pos_2; // current position in scroll string 2
#ifdef ALTERNATE_SCROLL
u08 scroll_dir_2;
#endif
#endif
#ifdef OLD_VS1001
u16 wPlayT;
#define playtime (wPlayT/10)
#else
#define playtime vs1001_read(VS1001_PLAYTIME)
#endif
u16 OldPlayTime;
//---------------------------------------------------------------------------
void ATA_SW_Reset2(void) // ATA Reset
{
WriteBYTE(ATAPI_DevCtrl, 0x06); // SRST and nIEN bits
delay10(); // 10uS delay
WriteBYTE(ATAPI_DevCtrl, 0x02); // nIEN bit
delay10(); // 10 uS delay
while ( (ATA_WaitBusy() & SR_DRDY) != SR_DRDY ); // Wait for DRDY
ATA_ReadStat();
}
void ATA_Standby(u08 time)
{
WriteBYTE(ATA_SectorCount, time); // time * 5 second (0=disable)
WriteBYTE(ATAPI_Cmd, 0xE3); // set standby timer and execute IDLE
ATA_WaitBusy();
}
//----------------------------------------------------------------------------
#define EVENT_QUEUE_SIZE 8
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 get_event(void)
{
event_e tmp = EV_IDLE;
//
// let the system have it's time
//
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;
}
//--------------------------------------------------------------------------
// prescaler set to 34.72 uS
// 2880 ticks = 100 mS
#define TI1_H (((u16)-(F_CPU / 2560)) >> 8)
#define TI1_L (((u16)-(F_CPU / 2560)) & 0xff )
volatile u08 time_flag; // counter for display refresh
volatile u08 scroll_time; // counter for scrolling refresh
SIGNAL(SIG_OVERFLOW1) // timer 1 overflow every 100 mS
{
time_flag++;
nKeyTime++; // counter for keyboard and IR functions
scroll_time++;
#ifdef OLD_VS1001
wPlayT++; // playing time counter for older than K versions of VS1001
#endif
outp(TI1_H, TCNT1H); // reload timer
outp(TI1_L, TCNT1L);
}
//--------------------------------------------------------------------------
#ifdef PWR_BEEPS
void send_sinewave_beeps(void)
{
u08 i,j=3;
static u08 buf[8] = { 0x53, 0xEF, 0x6E, 0x30, // sine on
0x45, 0x78, 0x69, 0x74}; // sine off
vs1001_nulls(4);
while(j--)
{
for (i=0;i<4;i++)
vs1001_send_data(buf[i]);
vs1001_nulls(4);
delayms(100);
for (i=4;i<8;i++)
vs1001_send_data(buf[i]);
vs1001_nulls(4);
delayms(100);
}
}
#endif
//--------------------------------------------------------------------------
#if !defined(SATTELITE) && (LCD_TYPE != 8)
void lcd_clrline(u08 line) // clear single line of LCD
{
register u08 i=LCD_LINE_LENGTH;
Vlcd_gotoxy(0,line);
while(i--)
Vlcd_putchar(' ');
Vlcd_gotoxy(0,line); // goto begin of line
}
#endif
//--------------------------------------------------------------------------
void LoudSet(void) // Equalizer mode setting
{
if (vs1001_fw) // If Equalizer loaded
{
if(bLoudness && bLoudness<128)
{
vs1001_write(0x0A,vs1001_fw); // Enable user code
vs1001_write(0x0D,0); // Reset EQ
vs1001_write(0x0D,bLoudness); // Set EQ characteristic
}
else
{
vs1001_write(0x0D,0); // Reset EQ
vs1001_write(0x0A,0); // Disable user code
}
}
else
vs1001_write(VS1001_MODE, 0x0080 * (bLoudness != 0)); // write bit SM_BASS to VS1001K
#ifdef VOL_UP_RAMP
vs1001_setvolume(volume + 2*volume_ramp, balance);
#else
vs1001_setvolume(volume,balance);
#endif
}
//--------------------------------------------------------------------------
#ifdef GRAPH_LCD
void Vlcd_wrdata0(void)
{
Vlcd_wrdata(0);
}
void status_display(void)
{
u08 i = 0;
#if(LCD_TYPE == 7)
Vlcd_gotoxy(0,LCD_LINES+1);
#else
Vlcd_gotoxy(13,LCD_LINES+1);
#endif
if (bRandom)
{
i=127;
Vlcd_invert();
}
Vlcd_wrdata(i);
Vlcd_progputs(PSTR("\x16\x17")); // Random signs
Vlcd_normal();
Vlcd_wrdata(i);
Vlcd_wrdata0();
Vlcd_putchar(Repeat + 0x18 - 1*(Repeat > 0)); // Repeat sign L
Vlcd_putchar(Repeat + 0x1b - 1*(Repeat > 1)); // Repeat sign R
#if(LCD_TYPE == 8)
Vlcd_gotoxy(19,7);
#else
Vlcd_wrdata0();
Vlcd_wrdata0();
#endif
Vlcd_putchar('L'); // EQ mode
if (bLoudness < 128)
Vlcd_putchar((bLoudness > 9) ? bLoudness + ('A'-10) : bLoudness + '0');
else
Vlcd_putchar('0');
#ifdef VOL_UP_RAMP
u08 v = volume+2*volume_ramp;
#else
u08v = volume;
#endif
#ifndef SATTELITE
#if(LCD_TYPE == 8)
Vlcd_gotoxy(13,6);
#endif
if (v < MIN_VOLUME)
{
for (i=0; i<((LCD_TYPE == 7) ? 16 : 23); i++) // Volume Bar
{
if(MIN_VOLUME - v >= i * VOL_STEP * NUM_VOL_STEPS / ((LCD_TYPE == 7) ? 16 : 22))
#if(LCD_TYPE == 7)
Vlcd_wrdata(0xff << (8 - (i+1)/2));
#else
Vlcd_wrdata((u08)(0xff << (8 - (i+1)/3)) >> 1);
#endif
else
Vlcd_wrdata0();
}
}
else
{
Vlcd_wrdata0();
Vlcd_putchar(0x1e); // speaker
Vlcd_wrdata0();
Vlcd_wrdata0();
Vlcd_putchar('x');
Vlcd_wrdata0();
Vlcd_wrdata0();
}
#else //SATTELITE
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_VOLUME);
uart_pc1(v);
uart_pc1(MIN_VOLUME);
uart_pc1(NUM_VOL_STEPS);
#endif
if (isPlaying && !info_flag)
{
i = (v > 19);
#if(LCD_TYPE == 7)
Vlcd_gotoxy(10-i,LCD_LINES+1);
#else
Vlcd_gotoxy(17-i,LCD_LINES);
#endif
if(i)
Vlcd_putchar(' ');
lprintf("%3uk",bitrate);
}
}
#else // Alphanumerics LCD's
void lcd_data00(void)
{
Vlcd_data(0x00);
}
void lcd_data1f(void)
{
Vlcd_data(0x1F);
}
#endif //GRAPH_LCD
//--------------------------------------------------------------------------
void setvolume(u08 v)
{
#ifdef VOL_UP_RAMP
v = v+2*volume_ramp;
#endif
vs1001_setvolume(v,balance);
#ifdef SATTELITE
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_VOLUME);
uart_pc1(v);
uart_pc1(MIN_VOLUME);
uart_pc1(NUM_VOL_STEPS);
#else
#ifndef GRAPH_LCD
u08 i,j; // volume indicator on alphanumeric LCD's
if(!usb_play)
{
Vlcd_command(0x40); // define of volume bar characters
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -