📄 yampp3.c
字号:
*dst++ = ' ';
lcd_puts(timestr); // display track number, x= 0 - 4
#if (LCD_LINE_LENGTH != 16)
lcd_putchar(' '); // space
#endif
lcd_puts(randstr); // display random status, x= 6 - 10
#if (LCD_LINE_LENGTH != 16)
lcd_putchar(' '); // space
#endif
lcd_puts(loudstr); // display loudness status, x= 12 - 16
#if (LCD_LINE_LENGTH != 16)
lcd_putchar(' '); // space
lcd_putchar(1); // speaker sign
#endif
#endif //(LCD_LINES == 4)
//--------------------------------------------------------------------------------------------------------------------
lcd_putchar(0); // Volume indicator on last position
#endif //ENABLE_LCD
nDispUpd = 0;
/*
#if ! ((F_VS1001 == (6144 + 0x8000)) || (F_VS1001 == 12288) || defined(OLD_VS1001))
if (vs1001_read(VS1001_CLOCKF) != F_VS1001) // check for self reset of vs1001
vs1001_reset(bLoudness); // soft resetting for right CLOCKF set
#endif
*/
} // if update time display
} // if (bPlaying)
} // while (true)
#endif // if not SETUP_REMOTE_CODES
}
// Auxillary functions definitions
// converts 16 bit unsigned integer to string
// str[] should be 6 bytes at least. Function can return value != str
// and you have to use it as a output value start
u08* unsigned2str(u16 track, u08 *str)
{
register u08 i=5;
udiv_t divt;
while(i--) *str++ = ' ';
*str = '\0';
divt.quot = track;
do {
divt = udiv(divt.quot, 10u);
*(--str) = '0' + (u08)divt.rem;
} while (divt.quot);
return str;
}
#ifdef ENABLE_NUMERIC
u16 Numb2Int() // Convert selected song number from string to integer
{
register u08 i;
u16 res = 0;
u16 p = 1;
for (i = pNum-number ; i>0 ; i--)
{
res += p * (number[i-1]-'0');
p *=10;
}
return res;
}
#endif
#ifdef OLD_VS1001
void BadHeadStrip(void) // Special MP3 header patch to strip all invalid headers
// not needed for VS1001K chip
{
u16 j;
for (j = 0; j < BUFFER_SIZE - 1; j++)
if ((*(u16*)&BUFFER1P[j] & 0xfeff) != 0xfaff)
BUFFER1P[j] = 0;
else
break;
// End of special header patch
}
#endif
#ifdef ENABLE_SERIAL
typedef struct pairUART // auxilliary structure for making
{ // of pairs table for select operator
u08 code, action;
} pairUART;
pairUART TableUART[] = {
{ 0, EV_IDLE },
{ 'g', EV_PLAY }, { 'G', EV_STOP },
{ 'p', EV_PREV }, { 'n', EV_NEXT },
{ 'P', EV_PREV10 }, { 'N', EV_NEXT10 },
{ 'V', EV_VOLUP }, { 'v', EV_VOLDN },
{ 'd', EV_NEXTD }, { 'D', EV_PREVD },
#ifdef ENABLE_NAVL
{ 'l', EV_NEXTL }, { 'L', EV_PREVL },
#endif
#ifdef FFWD_SEARCH
{ 'f', EV_FFWD },
#endif
#ifdef FREW_SEARCH
{ 'F', EV_FREW },
#endif
{ 'r', EV_RANDOM }, { 'b', EV_LOUDNESS},
{ 't', EV_REMAIN}
};
u08 get_char_event(void)
{
#ifdef HEXDUMP
static u32 dwLbaSector = 0;
static u32 dwTempAcc = 0;
#endif
register u08 i;
register u08 code = UART_ReceiveByte();
for (i = 0; i < sizeof(TableUART) / sizeof(TableUART[0]); i++)
if (TableUART[i].code == code)
return TableUART[i].action;
#ifdef HEXDUMP
if (code >= '0' && code <= '9')
dwTempAcc = dwTempAcc * 10 + code - '0';
if (code == 0x0d) // Enter
{
sectordump(dwLbaSector = dwTempAcc);
dwTempAcc = 0;
}
if (code == '+')
sectordump(++dwLbaSector);
if (code == '-')
sectordump(--dwLbaSector);
#endif // HEXDUMP
return EV_IDLE;
}
#endif // ENABLE_SERIAL
#ifdef ENABLE_IR
// get a remote control event
u16 TableIR[] = {IR_PLAY, IR_STOP, IR_NEXT, IR_PREV, IR_NEXT10, IR_PREV10, IR_VOLUP, IR_VOLDN, IR_NEXTD,
IR_PREVD, IR_FFWD, IR_FREW, IR_LOUDNESS, IR_RANDOM, IR_REMAIN, IR_NEXTL, IR_PREVL};
#ifdef ENABLE_NUMERIC
u16 NumTab[] = {IR_0, IR_1, IR_2, IR_3, IR_4, IR_5, IR_6, IR_7, IR_8, IR_9};
#endif
u08 ir_event(void)
{
static u16 Lcod;
u08 i;
u16 code = get_rec80();
if (Lcod == code && nKeyTime <= DOUBLE_TRAP) // Trap for some IR transmitters that fast repeat
return EV_IDLE; // code of pressed key
for (i = 0; i < (sizeof TableIR / sizeof TableIR[0]); i++)
if (TableIR[i] == code)
{
LastEvent = i+1; // Save last event
RET_LAST: nKeyTime = 0;
Lcod = code;
return LastEvent;
}
if (code == IR_RESET)
{
wdt_enable(0x01);
while(true); // Reset player by watchdog
}
#ifdef ENABLE_AUTOREPEAT
if ((nKeyTime >= 2) && (LastEvent == EV_VOLUP || LastEvent == EV_VOLDN ||
LastEvent == EV_FFWD || LastEvent == EV_FREW)) // Autorepeat feature on some keys
goto RET_LAST;
#endif
#ifdef ENABLE_NUMERIC
for (i=0; i<10; i++)
if (NumTab[i] == code) // Check for numeric keypress code
{
*pNum++ = i+'0'; // Add numeric key ascii character to string
*pNum = 0; // String end flag
LastEvent = EV_NUMBER;
goto RET_LAST;
}
#endif
return EV_IDLE;
}
#else
#define ir_event() EV_IDLE
#endif // ENABLE_IR
// get a keyboard event - edhanced by MIS
#ifdef ENABLE_LOCAL_KBD
u08 TableKbdShort[] = KBD_SHORT; // Key definitions moved to "Constants.h" file !!!
u08 TableKbdLong[] = KBD_LONG;
#endif
u08 get_key_event(void)
{
u08 event = EV_IDLE;
#ifdef ENABLE_LOCAL_KBD
static u08 keydown = 0;
register u08 i;
disable_ram(); // 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, PD3)) // check bit
{
// no key is down, return last key seen
if (nKeyTime < 8 && nKeyTime > 0) // max 0.8 sec for shortpress
event = TableKbdShort[keydown]; // short keypress event
keydown = 0;
}
else
if ((nKeyTime & 0x7F) >= 8) // long keypress ?
{
event = TableKbdLong[keydown]; // long keypress event
if (event == EV_VOLUP || event == EV_VOLDN ||
event == EV_FFWD || event == EV_FREW)
nKeyTime = 0x86; // 0.2 sec repeat time for volume and fast forward
else
nKeyTime = 0x82; // 0.6 sec repeat time
}
}
else
{
if (bit_is_clear(PIND, PD3)) // 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
asm volatile("nop");
if (bit_is_clear(PIND, PD3)) // this bit ?
{
keydown = i + 1; // store the key
nKeyTime = 0; // clear keypress timer
break; // and exit
}
}
}
}
enable_ram(); // enable ExtRAM
#endif
return event;
}
#ifdef PWR_BEEPS
void send_sinewave_beeps(void)
{
static u08 buf[] = {0x53,0xEF,0x6E,0x30,0x45,0x78,0x69,0x74};
register u08 i, j = 3;
while (j-- != 0)
{
for (i = 0; i < 4; i++)
vs1001_send_data(buf[i]);
vs1001_nulls(4);
delay10(10000); // delay 100ms
for (/*i = 4*/; i < 8; i++)
vs1001_send_data(buf[i]);
vs1001_nulls(4);
delay10(10000);
}
}
#endif
#ifdef ENABLE_LCD
void defchar(u08 dat)
{
register u08 i=5;
lcd_data(0x1f);
while (i--)
lcd_data(dat);
lcd_data(0x1f);
lcd_data(0x00); // cursor line
}
#endif
void setvolume(u08 v)
{
vs1001_setvolume(v, v);
eeprom_wb(EEPROM_VOLUME, v);
#ifdef ENABLE_LCD
register u08 i;
#ifndef PROGRESBAR_II
static u08 data[] = { 0x10, 0x18, 0x1C, 0x1E, 0x1F };
#endif
lcd_command(0x40);
for (i = 0; i < 8; i++)
{
if (v <= i * (VOL_STEP*(NUM_VOL_STEPS/8)))
#if (LCD_LINE_LENGTH == 16)
lcd_data((1 << ((10 - i) / 2)) - 1); // Volume idicator mod
#else
lcd_data(0x1f << ((i+1)*5 / 10)); // Volume idicator mod (reversed)
#endif
else
lcd_data(0);
}
#if (LCD_LINE_LENGTH != 16)
static u08 vsc[] = {0x03, 0x05, 0x19, 0x19, 0x19, 0x05, 0x03, 0x00}; // speaker sign
for (i=0; i < 8; i++)
lcd_data(vsc[i]); // load to CG_RAM char 1
#endif
#ifdef PROGRESBAR_II
lcd_command(0x80);
#else
lcd_command(0x50);
for (i = 0; i < 40; i++)
if ((i % 8) < 7)
lcd_data(data[i >> 3]); // eight times send each value
else
lcd_data(0);
#endif
#endif // ENABLE_LCD
}
#ifdef PROGRESBAR_II
void lcd_frame(void)
{
register u08 i = (LCD_STEPS / 5) - 1;
lcd_command(0x58); // start definition of CG-RAM from char code 3
defchar(0x1f); // full bar (3)
defchar(0x00); // empty bar (4)
defchar(0x01); // ended bar (5)
lcd_gotoxy(0, LCD_LINES / 4 + 1);
while (i--)
lcd_putchar(4);
lcd_putchar(5);
}
#endif
u08 barcalc(u08 dummy) // assembler optimized function to calculate progressbar position
{
// (u08)(LCD_STEPS * (dwPlayed>>8) / (dwFileSize>>8));
asm volatile ("mov r18, r24");
asm volatile ("clr r19");
asm volatile ("clr r20");
asm volatile ("clr r21");
asm volatile ("lds r22,(dwPlayed)+1");
asm volatile ("lds r23,(dwPlayed)+2");
asm volatile ("lds r24,(dwPlayed)+3");
asm volatile ("clr r25");
#ifdef YAMPP3USB
asm volatile ("call __mulsi3");
#else
asm volatile ("rcall __mulsi3");
#endif
asm volatile ("lds r18,(dwFileSize)+1");
asm volatile ("lds r19,(dwFileSize)+2");
asm volatile ("lds r20,(dwFileSize)+3");
asm volatile ("clr r21");
#ifdef YAMPP3USB
asm volatile ("call __udivmodsi4");
#else
asm volatile ("rcall __udivmodsi4");
#endif
asm volatile ("mov r24,r18");
return dummy;
}
void dispbar(void)
{
#ifdef ENABLE_LCD
register u08 i, a, nSteps;
#ifdef PROGRESBAR_II
nSteps = barcalc(LCD_STEPS-1);
a = i = nSteps / 5; // # of full bars
static u08 data[] = { 0x10, 0x18, 0x1C, 0x1E, 0x1F };
lcd_command(0x50);
defchar(data[nSteps % 5] | (a == (LCD_STEPS / 5) - 1));
lcd_gotoxy(0,LCD_LINES / 4 + 1);
while (i--)
lcd_putchar(3); // print full bars
if (a <= (LCD_STEPS / 5) - 1) // jman to fix display overwrite
lcd_putchar(2);
#else // PROGRESBAR_II
nSteps = barcalc(LCD_STEPS);
a = i = nSteps / 5; // # of full bars
lcd_gotoxy(0, LCD_LINES / 4 + 1); // line 2 or 3
while(i--)
lcd_putchar(6);
if (a <= (LCD_STEPS / 5) - 1) // jman to fix display overwrite
{
lcd_putchar(2 + nSteps % 5);
#ifdef FREW_SEARCH
if ( a < LCD_STEPS / 5)
lcd_putchar(32); // space
#endif
}
#endif // PROGRESBAR_II
#endif // ifdef ENABLE_LCD
}
void eeprom_ww(u08 address, u16 value)
{
union u16convert Data;
Data.value = value;
eeprom_wb(address, Data.bytes.low);
eeprom_wb(address + 1, Data.bytes.high);
}
#ifdef HEXDUMP
void HexDump(u08 *buffer, u16 len)
{
u16 i, j, k;
EOL();
for (i = 0, k = 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)
{
if (ATA_ReadLBA0(sector, 1, TMP_SECTOR) == 0)
{
UART_Printfu32(sector);
HexDump(TMP_SECTOR, BPS);
}
else
PRINT_p(PSTR("Dump failed\n"));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -