📄 yampp7_usb.c
字号:
{
strcpy(artistname, pEntry->artist);
strcpy(titlename, pEntry->title);
scroll_init(1);
}
lcd_putchar((i==j) ? 0x18 : ' ');
lcd_puts(pEntry->artist);
lcd_putchar('\n');
lcd_putchar((i==j) ? 0x18 : ' ');
lcd_puts(pEntry->title); // print title
}
CARD_Read(MySector-1);
idle();
}
}
do
{
time_flag = 0;
sleepcount = 0; // power off blocking
event = get_event();
switch (event)
{
case EV_NEXT:
case EV_UP:
if ( index+j > min )
{
if(j)
j--;
else
index--;
}
break;
case EV_PREV:
case EV_DOWN:
if ( index+j+1 < max )
{
if(j < 2*func + 1)
j++;
else
index++;
}
break;
case EV_PLAY:
info_flag = 3;
return index+j;
case EV_STOP:
info_flag = 3;
return -1;
}
if (func == 0)
{
i = 2*j+1;
scroll_do(1, i);
lcd_gotoxy(0,i+1);
lcd_putchar(0x18);
if(j)
{
lcd_gotoxy(0,5);
if (bRandom)
{
lcd_invert();
lcd_wrdata(127);
}
else
{
lcd_wrdata(0);
}
lcd_putchar(1);
lcd_normal();
}
else
{
lcd_gotoxy(0,3);
lcd_putchar(' ');
}
}
}
while (event == EV_IDLE);
}
}
// ***************************************************************************************
u16 browse_songs(void)
{
lcd_gotoxy(0,0);
lcd_invert();
puts(" SELECT SONG: ");
lcd_normal();
YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist);
return (browse_list(curIndex, 0, pListEntry->entry_qty, SONGS_D));
}
/***********************************************************************************/
u16 browse_menu(void)
{
lcd_gotoxy(0,0);
lcd_invert();
u08 i = 3;
while(i--)
lcd_wrdata(127);
puts(" - M E N U - ");
lcd_normal();
return (browse_list(menu_event ? menu_event-1 : 0 , 0,11 + (BACKLIGHT_TIME != 0),MENU_D));
}
/***********************************************************************************/
#ifdef PCB_REV_D
u08 IsCharging(void)
{
u08 b = 0;
u08 c = MCUCR;
MCUCR = 0; // disable external memory interface
CHARGE_DDR &= ~ _BV(CHARGE_PIN); // set pin as input
CHARGE_PORT |= _BV(CHARGE_PIN); // activate pullup
delay10();
if (bit_is_clear(CHARGE_INP,CHARGE_PIN)) // if charging
b = 1;
MCUCR = c ; // restore control register setting
return b;
}
#else // PCB older than D
u08 IsCharging(void)
{
return (bit_is_clear(CHARGE_INP, CHARGE_PIN));
}
#endif // PCB_REV_D
u08 BatteryMeasure(void)
{
#ifdef BATT_MONITOR
u08 tmp;
static u08 valsum;
static u08 count;
#if defined (__AVR_ATmega162__)
set_cpu_speed(CLKDIV); // CPU clock = XTAL / M162CLKDIV
#endif
PORTB &= ~ _BV(PB3); // set PB3 to LOW state
delayms(5); // discharge capacitor
TCCR2 = 0; // Timer 2 OFF
TCNT2 = 0; // Clear Timer 2 value
cli();
TCCR2 = 5; // Start Timer 2 , prescaler / 128
DDRB &= ~ _BV(PB3); // PB3 = comparator input, Hi-Z
loop_until_bit_is_clear(ACSR,ACO); // wait for comparator output low state
TCCR2 = 0; // stop the timer 2
tmp = TCNT2; // read timer 2 value -> higher timer value is lower battery voltage
sei();
PORTB |= _BV(PB3); // set PB3 to output and HIGH
DDRB |= _BV(PB3);
#if (BATT_MAX != 0) && (BATT_MIN != 0)
if( tmp < BATT_MAX ) // if more than maximum voltage
valsum += 13;
else if( tmp > BATT_MIN) // if bellow minimum voltage
valsum += 0;
else
{
u16 v = (( (u16)BATT_MIN - tmp ) * 256) / ((u08)BATT_MIN - (u08)BATT_MAX);
valsum += (u16)(13*v / 256); // calculate battery status ( 0-12, 0=minimum, 12=maximum )
}
if( ++count >= 8 )
{
lobatt = valsum / 8;
count = 0;
valsum = 3;
}
#endif
// lcd_gotoxy(0,0);
// printf("%03u %02u %03u %u", tmp, lobatt, valsum, count);
return tmp;
#else
if (!IsCharging()) // no charging in progress
{
PORTB &= ~_BV(PB3); // PB3 as analog comparator input
DDRB &= ~_BV(PB3); // for battery level measure
delay100();
if (bit_is_set(ACSR,ACO)) // low battery
{
if (!lobatt)
{
lobatt = 1;
lobatt_time = 0;
}
else
lobatt = 2;
}
PORTB |= _BV(PB3);
DDRB |= _BV(PB3);
}
return 0;
#endif
}
//********************************************************************************
//
// Run this as often as possible
// preferably every time around the main loop
//
void idle(void)
{
static u08 ledflash = 1;
u08 ContWrites = 250; // counter for prevent infinite vs1001 writing
u08 offtime = 20;
#ifdef BATT_MONITOR
u08 ontime = (lobatt < 3) ? 8 : 1;
#else
u08 ontime = (lobatt > 1) ? 8 : 1;
#endif
wdt_reset(); // reset the watchdog
usb_handler();
if(usb_link == 0) // usb link disables other control
{
if (isPlaying) // && !sleepenabled) // only during playing
check_keylock();
else
keylock = 0;
if (!keylock) // if keylock active
get_key(); // check keyboard
}
else
return;
if (isPlaying)
{
sleepcount = 0; // power off blocking
// pump some data to the decoder
while (bit_is_set(PIND, DREQ_PIN)) // while DREQ is hi
{
vs1001_send32(outptr); // send data on SPI bus
outptr += 32; // advance data pointer
fileplayed++;
if (--ContWrites == 0) // if vs1001 needs to more data
{
wdt_reset(); // reset the watchdog
PORTB &= ~_BV(RESET_PIN); // VS1001 hardware reset
delayms(1);
PORTB |= _BV(RESET_PIN); // VS1001 reset
delayms(10);
vs1001_reset();
LoudSet();
ContWrites = 250;
break; // let's take some time for system
}
// check for buffer wrap
if ( outptr == (SectorBuffer+512) ) // buffer empty
{
outptr = SectorBuffer; // data pointer at begin of sector buffer
if (!usb_play)
load_sector(); // will load into SectorBuffer on YAMPP7
else
{
usb_response(0);
break;
}
}
// check if we're done
if (fileplayed >= filesize)
{
if (!usb_play)
isPlaying = 0; // the end is near
next_song(0);
return;
}
}
if (vol_decrease && (time_flag == 4)) // If fast forward volume downed
{
vs1001_setvolume(volume,balance); // Restore volume
vol_decrease = 0;
}
//------------------------ LCD VISUALISATION ----------------------------
if (time_flag >= 5 && info_flag < 2)
{
if(bLoudness)
vs1001_write(0x0D,bLoudness); // Rewrite loudness settings
// if VS1001 do selfreset
//
// display bar function
register u08 nSteps = (u08)((fileplayed * 82) / filesize);
lcd_gotoxy(0,4);
lcd_bar(nSteps,82);
BatteryMeasure();
status_display();
//
// printing song time
lcd_gotoxy(8,3); // 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(8 + (wPlayTime < 600),3);
lcd_putchar('-');
}
if (IsCharging()) // charging in progress ?
{
#ifndef BATT_MONITOR
lobatt = 0;
lobatt_time = 0;
#endif
ledflash = !ledflash;
lcd_gotoxy(9,5);
lcd_wrdata(0);
if (ledflash)
puts(" ");
else
puts("\xB\xC");
}
if (!info_flag)
time_flag = 0;
}
if(((s08)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(info_flag < 2)
{
scroll_do(0,1);
lcd_gotoxy(0,3);
lcd_data('#');
}
}//if (isPlaying)
else
{
if (IsCharging()) // charging in progress ?
{
sleepcount = 0; // power off blocking
ontime = 20; // LED 2 sec on / 0.2 sec off
offtime = 2; // until end charge.
lobatt_time = 0; // clear low battery timer
#ifndef BATT_MONITOR
lobatt = 0; // clear low battery status
#endif
if (time_flag % 10 == 0)
{
if(!info_flag) // not in menu
{
lcd_gotoxy(0,4);
puts("Battery charge");
}
lcd_gotoxy(9,5);
lcd_wrdata(0);
puts(" ");
}
if (time_flag % 10 == 5)
status_display();
}
#if (BACKLIGHT_TIME == 0)
if (ledflash-- == 0)
{
if (bit_is_set(PORTB,LED_PIN)) // LED Flashing
{
PORTB &= ~_BV(LED_PIN); // off
ledflash = offtime;
}
else
{
PORTB |= _BV(LED_PIN); // on
ledflash = ontime;
}
}
#endif
if (!menu_event)
{
MCUCR = 0xA0; // choose idle mode
asm volatile ("sleep"); // go to sleep
asm volatile ("nop");
wdt_reset(); // reset the watchdog
BatteryMeasure();
}
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 && offtime == 20))
set_event(EV_STOP); // if auto menu exit or end of battery charge
else
status_display();
menu_event = EV_IDLE;
time_flag = 0;
}
}
#ifdef BATT_MONITOR
if (lobatt < 3)
{
if ((lobatt_time % 600) == 10) // beeps in one minute interval
beep(SINE_2000,80);
if (lobatt == 0) // and power off if batt == 0
lobat_shutdown();
}
#else
u16 off_time = lobatt_time;
if (lobatt == 2)
{
#if (BACKLIGHT_TIME == 0)
if (isPlaying && (off_time % 20) == 0) // while playing
PORTB &= ~_BV(LED_PIN); // and battery level is low
if (isPlaying && (off_time % 20) == 10) // led blinks
PORTB |= _BV(LED_PIN);
#endif
if ((off_time % 600) == 10) // and beeps in one minute interval
beep(SINE_2000,80);
if (off_time > 6050) // and power off after 10 minutes
lobat_shutdown();
}
#endif
}
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
{
puts("\nSongBase Error !");
beep(SINE_500,500);
set_event(EV_STOP);
return;
}
// init randomizer from timer
seed += TCNT1;
addtime = 0;
bitrate = ((pEntry->bitrate) & 0x7fff); // get bitrate and mask VBR signature (MSB)
//
// calc number of VS1001 blocks
//
// u08 garbage = ((pEntry->bitrate & (~OPTION_BR_ID1_TAG)) != 0) ? 128 : 0;
// filesize = (pEntry->length - garbage) / 32;
// calculation number of blocks, 14 bit of
// bitrate indicate that file have ID3 tag
// and this may be excluded (last 128 bytes)
filesize = pEntry->length / 32;
fileplayed = 0;
ClusterCount = 0; // Reset Cluster counter
//
// preload buffers
//
init_load_sectors(pEntry->start);
// u08 i;
// for (i=0; i < (pEntry->start_offset / SECTORSIZE); i++)
// load_sector(); // skip first pEntry->start_offset of full buffers
outptr = SectorBuffer; // + (pEntry->start_offset % SECTORSIZE); // and rest of pEntry->start_offset
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -