📄 yampp3.c
字号:
/*
Copyright (C) 2001 Jesper Hansen <jesperh@telia.com>.
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.
*/
/*
PIN assignements on test board
PA0-PA7 data bus 0..7 + Address 0..7
PC0-=C7 address 8..15
PB0 T0 DIOW
PB1 T1 DIOR
PB2 AIN0 DEMAND
PB3 AIN1 BSYNC
PB4 SS MP3
PB5 MOSI SO
PB6 MISO SI
PB7 SCK SCK
PD0 RxD RS-232
PD1 TxD RS-232
PD2 INT0 IR_INPUT
PD3 INT1 KEY_INPUT
PD4 T0
PD5 T1 LCD_ENABLE
PD6 WR RD
PD7 RD WR
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At 8MHz clock : 100 mS divisor 8bit overflow
tClk = 125 nS 200000 32 uS (31250 Hz)
tClk/8 = 1 uS 50000 128 uS (7812.5 Hz)
tClk/64 = 8 uS 12500 512 us (1953.125 Hz)
tClk/256 = 32 uS 3125 2048 uS
tClk/1024 = 128 uS 781.25 8192 uS
*/
#include <io.h>
#include <progmem.h>
#include <eeprom.h>
#include <signal.h>
#include <interrupt.h>
#include "types.h"
#include "uart.h"
#include "lcd.h"
#include "ata_if.h"
#include "delay.h"
#include "fat.h"
#include "mem.h"
#include "rec80.h"
#include "vs1001.h"
// eeprom positions
#define EEPROM_VOLUME 0x0010
#define EEPROM_AUTOPLAY 0x0011
#define EEPROM_SONGPOS 0x0012
/* another way
static u08 volume __attribute__ ( ( section(".eeprom") ) ) = 12; //-6dB
*/
#define HEXDUMP 1
extern u08 *SectorBuffer;
#ifdef HEXDUMP
void HexDump( u08 *buffer, u16 len )
{
u16 i,j,k = 0;
EOL();
for(i=0;i<len/16;i++,k+=16)
{
UART_Printfu16(k);
UART_SendByte(' ');
for(j=0;j<16;j++)
{
UART_Printfu08(buffer[i*16+j]);
UART_SendByte(' ');
}
PRINT(" ");
for(j=0;j<16;j++)
{
if (buffer[i*16+j] >= 0x20)
UART_SendByte(buffer[i*16+j]);
else
UART_SendByte('.');
}
EOL();
}
}
void sectordump(u32 sector)
{
ATA_Read_Sectors_LBA(DRIVE0,sector,1,SectorBuffer);
UART_Printfu32(sector);
HexDump(SectorBuffer, 512);
}
#endif
u08 scroll_length;
u08 scroll_pos = 0;
u08 scroll_flag = 0;
char *scroll_line;
u08 isPlaying = 0;
u08 *outptr;
u08 *buffer1;
u08 *buffer2;
u08 *buffer3;
u32 lbasector = 0;
u32 temp;
u08 *updbuf;
typedef enum
{
EV_IDLE,
EV_PLAY,
EV_STOP,
EV_NEXT,
EV_PREV,
EV_VOLUP,
EV_VOLDN,
EV_NEUTRAL,
// EV_MUTE,
EV_LASTEVENT
} event_e;
// prescaler set to 32 uS
// 3125 ticks = 100 mS
#define TI1_H (((u16)-3125) >> 8)
#define TI1_L (((u16)-3125) & 0xff )
volatile u16 p_time;
volatile u08 time_flag = 0;
SIGNAL(SIG_OVERFLOW1) //timer 1 overflow every 100 mS
{
p_time++;
time_flag++;
scroll_flag++;
outp(TI1_H, TCNT1H); //reload timer
outp(TI1_L, TCNT1L);
}
event_e get_char_event(void)
{
u08 c;
switch ((c = UART_ReceiveByte()))
{
#ifdef HEXDUMP
case '0' : case '1' : case '2' : case '3' : case '4' :
case '5' : case '6' : case '7' : case '8' : case '9' :
temp = temp*10 + c-'0';
break;
case 0x0d :
lbasector = temp;
temp = 0;
break;
case '+':
sectordump(++lbasector);
break;
case '-':
sectordump(--lbasector);
break;
#endif
case 'V' : return EV_VOLUP;
case 'v' : return EV_VOLDN;
case 'N' : return EV_NEUTRAL;
// case 'm' : return EV_MUTE;
case 'p' : return EV_PREV;
case 'n' : return EV_NEXT;
case 'g' : return EV_PLAY;
case 'G' : return EV_STOP;
default: return EV_IDLE;
}
return EV_IDLE;
}
event_e ir_event(void)
{
switch (get_rec80())
{
default:
case 0: return EV_IDLE;
case IR_PLAY: return EV_PLAY;
case IR_STOP: return EV_STOP;
case IR_PREV: return EV_PREV;
case IR_NEXT: return EV_NEXT;
case IR_VOLUP: return EV_VOLUP;
case IR_VOLDN: return EV_VOLDN;
}
}
//
// get a keyboard event
//
event_e get_key_event(void)
{
static u08 keydown = 0;
u08 i;
event_e event = EV_IDLE;
cbi(MCUCR, SRE); // disable EXTRAM
outp(0xff, PORTA-1); // set port as output
outp(0, PORTA); // set all pins to 0
asm volatile("nop"); // allow time for port to activate
if (keydown) // if a key was pressed earlier
{
// see if it has been released
if (bit_is_set(PIND,PD4)) // check bit
{
// no key is down
// return last key seen
switch (keydown)
{
case 1 : event = EV_STOP; break;
case 2 : event = EV_PLAY; break;
case 3 : event = EV_PREV; break;
case 4 : event = EV_NEXT; break;
}
keydown = 0;
}
}
else
{
if (bit_is_clear(PIND,PD4)) // check if a key is down
{
// a key is active, check which one
for (i=0;i<8;i++)
{
outp(~(1<<i), PORTA); // write bit mask
asm volatile("nop"); // wait a while
if (bit_is_clear(PIND,PD4)) // this bit ?
{
keydown = i+1; // store the key
break; // and exit
}
}
}
}
sbi(MCUCR, SRE); // enable RAM
return event;
}
void send_sinewave_beeps(void)
{
u08 i,j,buf[8];
// sine on
buf[0] = 0x53; buf[1] = 0xEF; buf[2] = 0x6E; buf[3] = 0x30;
// sine off
buf[4] = 0x45; buf[5] = 0x78; buf[6] = 0x69; buf[7] = 0x74;
for (j=0;j<3;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);
}
}
void userchars(void)
{
u08 c;
lcd_command(0x48); // start at 2'nd definable character
for (c=0;c<8;c++) lcd_data(0x10); // 1 bar
for (c=0;c<8;c++) lcd_data(0x18); // 2 bars
for (c=0;c<8;c++) lcd_data(0x1C); // 3 bars
for (c=0;c<8;c++) lcd_data(0x1E); // 4 bars
for (c=0;c<8;c++) lcd_data(0x1F); // 5 bars
// 2 more user definable characters possible
}
void setvolume(u08 v)
{
u08 c,a = 1;
vs_1001_setvolume(v,v);
eeprom_wb(EEPROM_VOLUME,v);
lcd_command(0x40);
for (c=0;c<8;c++)
{
if (v <= a)
lcd_data(0xff);
else
lcd_data(0x00);
a <<= 1;
}
}
void dispbar(u16 v)
{
// 8 bars of 5 steps each = 40 steps
u08 c,a;
a = v / 5; // # of full bars
lcd_gotoxy(0,1);
for (c=0;c<a;c++)
lcd_putchar(5);
lcd_putchar(1+ v % 5);
}
//
// random stuff
//
#define MY_RAND_MAX 65535
static u32 seed = 1;
u16 do_rand(u32 *ctx)
{
return ((*ctx = *ctx * 1103515245 + 12345) % ((u32)MY_RAND_MAX + 1));
}
u16 rand(void)
{
return do_rand(&seed);
}
//
// end random
//
//----------------------------------------------------------------------------
// Main part
//----------------------------------------------------------------------------
int main(void)
{
u16 i;
u08 c;
u08 *p, *q;
u16 dentry = 0;
u32 filesize = 0;
u08 volume = 12;
event_e event = EV_IDLE;
// u08 mute = 0;
u08 autoplay;
u16 barsize = 0;
u16 barstep = 0;
u16 filepos = 0;
u16 random = 1;
u16 last_song = 1;
//------------------------------
// Initialize
//------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -