📄 yampp7_usb.c
字号:
void idle(void)
{
static u08 iconflash = 1;
wdt_reset(); // reset the watchdog
usb_handler();
if(usb_link == 0) // usb link disables other control
{
set_cpu_speed(CLKDIV); // CPU clock = XTAL / M162CLKDIV
if (isPlaying) // only during playing
check_keylock();
else
keylock = 0;
if (!keylock) // if keylock active
get_key(); // check keyboard
}
else
return;
u08 charging = IsCharging(); // check charging status
if (isPlaying)
{
sleepcount = 0; // power off blocking
feed_audio_data();
if (vol_decrease && (time_flag == 4)) // If fast forward volume downed
{
vs1001_setvolume(volume,balance); // Restore volume
vol_decrease = 0;
}
//------------------------ LCD VISUALISATION ----------------------------
if (scroll_flag >= SCROLL_SPEED && info_flag < 3)
{
u08 nTemp;
scroll_flag = 0;
//
// scrolling artist
if (scroll_length > 15)
{
lcd_color(colors[ARTIST_NAME], colors[ARTIST_NAME+16]);
lcd_gotoxy(4, ARTIST_NAME_YPOS);
for (nTemp = 0; nTemp < 15; nTemp++)
#ifdef ALTERNATE_SCROLL
lcd_putchar(artistname[scroll_pos + nTemp]);
if (scroll_pos + 15 == scroll_length)
scroll_dir -= 2;
if (scroll_pos == 0)
scroll_dir++;
scroll_pos += ((signed char)scroll_dir / (10/SCROLL_SPEED));
#else //ALTERNATE_SCROLL
lcd_putchar(artistname[(scroll_pos + nTemp) % scroll_length]);
#endif
feed_audio_data();
}
//
// scrolling name
if (scroll_length_2 > 15)
{
lcd_color(colors[SONG_NAME], colors[SONG_NAME+16]);
lcd_gotoxy(4, SONG_NAME_YPOS);
for (nTemp = 0; nTemp < 15; nTemp++)
#ifdef ALTERNATE_SCROLL
lcd_putchar(titlename[scroll_pos_2 + nTemp]);
if (scroll_pos_2 + 15 == scroll_length_2)
scroll_dir_2 -= 2;
if (scroll_pos_2 == 0)
scroll_dir_2++;
scroll_pos_2 += ((signed char)scroll_dir_2 / (10/SCROLL_SPEED));
#else //ALTERNATE_SCROLL
lcd_putchar(titlename[(scroll_pos_2 + nTemp) % scroll_length_2]);
#endif
feed_audio_data();
}
#ifndef ALTERNATE_SCROLL
scroll_pos++;
scroll_pos_2++;
#endif
}
if (time_flag >= 5 && info_flag < 3)
{
if(bLoudness)
vs1001_write(0x0D,bLoudness); // Rewrite loudness settings
// if VS1001 do selfreset
//
// display bar function
register u08 nSteps = (u08)((fileplayed * (PROGRESS_BAR_LEN+2)) / filesize);
lcd_gotoxy(PROGRESS_BAR_XPOS, PROGRESS_BAR_YPOS);
union u16convert Data;
Data.bytes.high = colors[PROGRESS_BAR];
Data.bytes.low = colors[PROGRESS_BAR+1];
lcd_bar((PROGRESS_BAR_LEN<<8) | nSteps, Data.value);
//
// printing song time
lcd_color(colors[SONG_TIME], colors[SONG_TIME+16]);
lcd_gotoxy(SONG_TIME_XPOS, SONG_TIME_YPOS); // time display position
u16 wPlayTime = vs1001_read(VS1001_PLAYTIME) + addtime;
if (timemode == 1)
{
wPlayTime = songtime - wPlayTime; // calculate time remain
if ((s16)wPlayTime < 0)
wPlayTime = 0;
}
printf("%3u:%02u", wPlayTime / 60, wPlayTime % 60); // print time on LCD
if (timemode == 1)
{
lcd_gotoxy(SONG_TIME_XPOS + 8*(wPlayTime < 600), SONG_TIME_YPOS);
lcd_putchar('-');
}
if(info_flag < 2)
{
status_display();
if (charging) // charging in progress ?
{
lobatt = 0;
lobatt_time = 0;
iconflash = !iconflash;
if (iconflash)
lcd_icon(11,4); // battery charging icon 1
else
lcd_icon(12,4); // battery charging icon 2
}
}
if (!info_flag)
time_flag = 0;
}
if((time_flag > 30) && (menu_event != EV_IDLE)) // display overvrite timer ends
{
info_flag = 0; // enable status updating
menu_event = EV_IDLE;
Playlist_name(); // show Playlist name
}
//------------------------ LCD VISUALISATION END -------------------------
}//if (isPlaying)
else
{
if (charging) // charging in progress ?
{
sleepcount = 0; // power off blocking
lobatt = 0; // clear low battery status
lobatt_time = 0; // clear low battery timer
if(!info_flag) // not in menu
{
if (time_flag % 10 == 4)
{
lcd_gotoxy(BATTCHARGE_TEXT_XPOS, BATTCHARGE_TEXT_YPOS);
lcd_color(colors[BATTCHARGE_TEXT], colors[BATTCHARGE_TEXT+16]);
_p_puts(Charge_txt);
lcd_icon(11,4); // battery charging icon 1
}
if (time_flag % 10 == 9)
lcd_icon(12,4); // battery charging icon 2
}
}
if (!menu_event)
{
MCUCR = 0xA0; // choose idle mode
asm volatile ("sleep"); // go to sleep
asm volatile ("nop");
wdt_reset(); // reset the watchdog
}
if (sleepcount > DEEP_SLEEP_TIMEOUT)
PowerOff(); // Go to power off procedure and off player
if (! CARD_SW_Reset2()) // if card removed
PowerOff(); // power off
if (time_flag >= 30)
{
if (menu_event || (lobatt_time < 50 && !charging))
set_event(EV_STOP); // if auto menu exit or end of battery charge
else
status_display();
menu_event = EV_IDLE;
time_flag = 0;
}
}
BatteryMeasure();
if (lobatt == 2)
{
u16 off_time = lobatt_time;
if ((off_time % 600) == 10) //beeps in one minute interval
{
beep(SINE_2000,80);
lcd_clricon(LOBAT_ALERT);
_p_puts(Lobatt_txt);
info_flag = 2; //denny status line displaying
}
if ((off_time % 600) == 50)
{
info_flag = 0; //allow status line displaying
lcd_clricon(LOBAT_ALERT);
clr_icon_cache();
}
if (off_time > 6050) //and power off after 10 minutes
{
send_sinewave_beeps();
PowerOff();
}
}
}
void play_song(void)
{
YADL_SONG_BASE_ENTRY *pEntry = get_song_entry(get_offset_entry(curIndex));
if(pEntry->state != YADL_STATE_READY) // check for valid song entry
{
lcd_color(colors[LOBATT_TEXT], colors[LOBATT_TEXT+16]);
lcd_clrline(BATTCHARGE_TEXT_YPOS);
_p_puts(BaseErr_txt);
beep(SINE_500,500);
delayms(2000);
send_sinewave_beeps();
set_event(EV_STOP);
return;
}
addtime = 0;
bitrate = ((pEntry->bitrate) & 0x7fff); // get bitrate and mask VBR signature (MSB)
strcpy(artistname, pEntry->artist);
scroll_length = strlen(artistname);
#ifndef ALTERNATE_SCROLL
if (scroll_length > 16)
{
strcat(artistname, " >> "); // add ' >> ' sign
scroll_length += 4;
}
#endif
//
// calc number of VS1001 blocks
//
filesize = pEntry->length / 32;
fileplayed = 0;
ClusterCount = 0; // Reset Cluster counter
//
// preload buffers
//
init_load_sectors(pEntry->start);
outptr = SectorBuffer;
//
// start playing the song
//
isPlaying = 1;
vs1001_reset();
LoudSet();
if (!info_flag)
Playlist_name();
}
void next_playlist(void)
{
YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist);
if(pListEntry->next_playlist != (u16)-1) // check for next playlist number
curPlaylist = pListEntry->next_playlist;
else
curPlaylist++;
if((curPlaylist == (u16)-1) || (curPlaylist >= playlist_qty))
curPlaylist = 0;
pListEntry = get_pl_entry(curPlaylist);
InitRnd(); // init randomizer table
curIndex = (bRandom) ? do_rand(pListEntry->entry_qty) : 0;
}
void prev_playlist(void)
{
if(--curPlaylist == (u16)-1) // playlist down
curPlaylist = playlist_qty - 1; // go to last playlist
YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist); // update playlist data
InitRnd();
curIndex = (bRandom) ? do_rand(pListEntry->entry_qty) : pListEntry->entry_qty-1;
}
void next_song(u08 mode)
{
YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist);
if (Repeat == 3 && mode == 0) // repeat one song
goto GO_PLAY;
if (mode == 2)
{
#ifdef NEW_PREW
if(ClusterCount)
goto GO_PLAY;
else
#endif
curIndex = (bRandom) ? do_rand(pListEntry->entry_qty) : curIndex-1;
}
else
curIndex = (bRandom) ? do_rand(pListEntry->entry_qty) : curIndex+1;
if (curIndex < (pListEntry->entry_qty)) // if not End of playlist
goto GO_PLAY;
else
{
InitRnd(); // init randomizer table
if(Repeat == 2) // repeat playlist
{
if (bRandom)
curIndex = do_rand(pListEntry->entry_qty);
else
curIndex = 0;
goto GO_PLAY;
}
if(Repeat == 0)
{
set_event(EV_STOP); // normal play, stop after end of playlist
return;
}
if(Repeat == 1 || Repeat == 3) // normal play and repeat one song, next playlist after end of playlist
{ // fixed by Roger Nilson
if (mode == 2)
prev_playlist();
else
next_playlist();
GO_PLAY: play_song();
}
}
}
//----------------------------------------------------------------------------
void set_contrast(void)
{
event_e event = EV_IDLE;
u08 contrast = eeprom_rb(EEPROM_LCD_CONTRAST);
lcd_image(5); // Contrast menu image
info_flag = 3;
union u16convert Data;
goto SETC;
while(1)
{
wdt_reset(); // reset the watchdog
time_flag = 0;
sleepcount = 0; // power off blocking
event = get_event();
switch(event)
{
default:
case EV_IDLE:
break;
case EV_UP:
case EV_NEXT:
if (contrast < 0x40)
contrast++;
goto SETC;
case EV_DOWN:
case EV_PREV:
if (contrast > 0x10)
contrast--;
SETC:
lcd_gotoxy(CONTRAST_BAR_XPOS, CONTRAST_BAR_YPOS);
Data.bytes.high = colors[CONTRAST_BAR];
Data.bytes.low = colors[CONTRAST_BAR+1];
lcd_bar(0x60<<8 | (2*(contrast-0x10)), Data.value);
lcd_contrast(contrast);
break;
case EV_STOP:
eeprom_wb(EEPROM_LCD_CONTRAST,contrast);
set_event(EV_STOP);
return;
}
event = EV_IDLE;
}
}
void set_cpu_speed(u08 speed)
{
asm volatile("ldi r25, 128");
asm volatile("cli");
asm volatile("sts 0x61, r25");
asm volatile("sts 0x61, r24");
asm volatile("sei");
}
//----------------------------------------------------------------------------
// Main part
//----------------------------------------------------------------------------
int main(void)
{
//------------------------------
// Initialize
//------------------------------
//////////////////////////////////////////////////////////////////
// B - Port
//////////////////////////////////////////////////////////////////
PORTB = 0x0A;
DDRB = 0xff;
// cbi(PORTB,LED_PIN);
// sbi(DDRB, LED_PIN); // pin PB0 is output for LED or backlight
// sbi(PORTB,RESET_PIN); // RESET- hi
// sbi(DDRB, RESET_PIN); // pin PB1 is output, RESET-
// PB2 is BSYNC pin to VS1001
// PB3 is MP3 signal to VS1001 and battery monitor input
// PB4 is SCE signal for LCD dosplay
// PB5 (MOSI) is used for SPI
// PB6 (MISO) is used for SPI
// PB7 (SCK) is used for SPI
//////////////////////////////////////////////////////////////////
// D - Port
//////////////////////////////////////////////////////////////////
PORTD = 0xFF; // activate pullups
DDRD = 0xC0;
// pin PD0 is DREQ input
// pin PD1, PD4 and PD5 is keyboard input, enable pullup
// PD2 and PD3 are RXF and TXE input pins from FTDI
// PD6 and PD7 are WR and RD signals for CF and FTDI chip.
//////////////////////////////////////////////////////////////////
// E - Port
//////////////////////////////////////////////////////////////////
sbi(PORTE,BUTTON_1); // pin PE0 is keyboard input, enable pullup
#ifndef PCB_REV_D
cbi(CHARGE_DDR,CHARGE_PIN); // set pin as input
sbi(CHARGE_PORT,CHARGE_PIN); // activate pullup
#endif
EMCUCR = 0;
set_cpu_speed(CLKDIV); // CPU clock = XTAL / M162CLKDIV
// eg about 4-8MHz
OCR0 = 0; // PWM duty = 0%
TCCR0 = (1<<WGM00) | (1<<COM01) | (1<<CS01) | (1<<CS00); // Timer 0 normal PWM mode, CLK/64
MCUCR = (1<<SRE); // enable external SRAM
delayms(50);
usb_init();
wdt_enable(7);
//
// setup timer1 for a 100mS periodic interrupt
//
TCCR1A = 0;
TCCR1B = 4; // prescaler /256 tPeriod = 32 uS
TCNT1 = (u16)-(F_CPU / 2560); // load counter value
sbi(TIMSK, TOIE1); // enable timer1 interrupt
// setup some buffers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -