📄 microyampp.c
字号:
} if (actfilenum != 0xffff) actfilenum = get_next_direntry(dircluster, actfilenum, 0, TYPE_ANY, DOID3); // update filename / id3 info}// r24 = divisorvoid set_cpu_speed(unsigned char speed){// asm volatile("ldi r25, 128");// asm volatile("cli");// asm volatile("sts 0x61, r25");// asm volatile("sts 0x61, r24");// asm volatile("sei");}void write_eeprom_data(){// settings are read before saving to extend eeprom life - // only changed values are stored to eeprom unsigned long tmp; cli(); if (eeprom_rb(EE_VOLUME) != volume) // has setting been changed? eeprom_wb(EE_VOLUME, volume); tmp = (eeprom_rb(EE_FILENR) << 8) + eeprom_rb(EE_FILENR+1); if (tmp != actfilenum) { eeprom_wb(EE_FILENR, (unsigned char) (actfilenum >> 8)); eeprom_wb(EE_FILENR+1, (unsigned char) (actfilenum & 0xff)); } tmp = (eeprom_rb(EE_DIRCLUSTER) << 8) + eeprom_rb(EE_DIRCLUSTER+1); if (tmp != dircluster) { eeprom_wb(EE_DIRCLUSTER, (unsigned char) (dircluster >> 8)); eeprom_wb(EE_DIRCLUSTER+1, (unsigned char) (dircluster & 0xff)); } if (eeprom_rb(EE_LOUDNESS) != loudness) eeprom_wb(EE_LOUDNESS, loudness); if (eeprom_rb(EE_BLTIME) != bltime) eeprom_wb(EE_BLTIME, bltime); if (eeprom_rb(EE_TIMEDISP) != timedisp) eeprom_wb(EE_TIMEDISP, timedisp); if (eeprom_rb(EE_BLMODE) != blmode) eeprom_wb(EE_BLMODE, blmode); while (!eeprom_is_ready()) { asm volatile ("nop" ::); } sei();}void read_eeprom_settings(){ loudness = eeprom_rb(EE_LOUDNESS); if (loudness > 1) loudness = 1; // loudness setting volume = eeprom_rb(EE_VOLUME); // initial vs1001 volume setting if (volume == 0xff) volume = 0x40; bltime = eeprom_rb(EE_BLTIME); // backlight time setting if (bltime > 21) bltime = 20; locktime = eeprom_rb(EE_LOCKTIME); // autolock timer if (locktime > 21) locktime = 20; playmode = eeprom_rb(EE_PLAYMODE); if (playmode>2) // insane value, set to repeat off playmode = 0; timedisp = eeprom_rb(EE_TIMEDISP); // time display mode if (timedisp > 1) timedisp = 1; blmode = eeprom_rb(EE_BLMODE); // backlight mode if (blmode > 5) blmode = 3;}void beep(unsigned char freq, unsigned int time){ unsigned char i; set_cpu_speed(CLKDIV); if (is_playing==1) { vs1001_nulls(4); vs1001_reset(loudness); delayms(10); } vs1001_setvolume(volume+24,balance); // -12dB vs1001_nulls(8); for (i=0;i<3;i++) // beep on vs1001_send_data(PRG_RDB(&buf[i])); vs1001_send_data(freq); vs1001_nulls(4); delayms(time); for (i=3;i<7;i++) // sine OFF vs1001_send_data(PRG_RDB(&buf[i])); vs1001_nulls(4); vs1001_reset(loudness); vs1001_setvolume(volume,balance);}void send_sinewave_beeps(void){ unsigned char j; delayms(100); for (j=0;j<3;j++) { beep(62,80); delayms(80); }}void playloop(){ unsigned int count; set_cpu_speed(CLKDIV); // lower cpu speed ReadSector(data + ((unsigned long) playcl * secpercluster + cc)); // read sector if (volume != vs1001_vol) // volume changed? { vs1001_setvolume(volume, balance); // volume setting vs1001_vol = volume; delay10(); } if (played >= playlength) // song end? { is_playing = 0; lcd_update=1; return; } if (played == 0) // new song... { set_cpu_speed(0); // fast cpu speed for cf reading cc = 0; // cluster count ReadSector(data + ((unsigned long) playcl) * secpercluster); // read first sector playsec = secbuf; vs1001_reset(loudness); vs1001_nulls(20); vs1001_setvolume(volume,balance); delay10(); set_cpu_speed(CLKDIV); // lower cpu speed } count = 0xff; while ((bit_is_set(PIND, PD0)) && count) // as long as VS1001 DREQ is high... { wdt_reset(); vs1001_send32(playsec); // send data to VS1001 playsec += 32; // advance data pointer played += 32; if (playsec==(secbuf+512)) // sector end? { cc++; if (cc==secpercluster) // next cluster? { playcl = (unsigned int) get_next_cluster(playcl); cc = 0; } ReadSector(data + ((unsigned long) playcl * secpercluster + cc)); // read next sector playsec = secbuf; // & sector buffer count--; } } if (!count) // to prevent vs1001 hangup { cbi(PORTB, RESET_PIN); delayms(50); sbi(PORTB, RESET_PIN); vs1001_init_io(); vs1001_setcomp(F_VS1001); vs1001_reset(loudness); delayms(10); vs1001_setvolume(volume,0); }}int main (void){ unsigned int count; unsigned int i; initialize(); wdt_enable(WDTO_2S); // enable watchdog timer, 500ms while(1) { wdt_reset(); // reset watchdog if (is_playing == PLAY) playloop(); cmd = get_key(); switch (cmd) { case CMD_PLAY: if (!is_playing) // still playing? { set_cpu_speed(0); set_background_image(PLAY_IMG); if (attrib & 0x10) // selected entry is a directory { strncpy(dirname, filename,15); dirname[16]='\0'; dircluster = filecluster; // step into the directory actfilenum = get_next_direntry(dircluster, 0,1, TYPE_MP3, DOID3); } else // not a dir, start playing that file { beep(61,100); delayms(50);// vs1001_reset(loudness);// delayms(5); lastcmd = CMD_PLAY; play_file(filecluster, dirfilesize); } set_cpu_speed(CLKDIV); } else { if (is_playing == PLAY) { is_playing = PAUSE; } else if (is_playing == PAUSE) { is_playing = PLAY; } } break; case CMD_NEXT: // next song set_cpu_speed(0); beep(61,50); delayms(1); beep(61,50); delayms(1); i = TYPE_ANY; if (is_playing) i = TYPE_MP3; // we're playing, only mp3s please count = actfilenum; if (playlistcl != 0xffff) // we're playing a playlist { do { playlistid = get_next_playlist_entry(1, 1); } while (playlistid == 0xfe); if (playlistid == 0xff) { playlistptr = 0; playlistid = get_next_playlist_entry(1, 1); } } else { do { actfilenum = get_next_direntry(dircluster, actfilenum, 1, i, DOID3); } while ((is_playing && (attrib & 0x10)) && (actfilenum != 0xffff)); if (actfilenum == 0xffff) { dir_finished=1; actfilenum = get_next_direntry(dircluster, count, 0, i, DOID3); } } if (is_playing && !(attrib & 0x10)) { played = 0; // reset play status var's playcl = filecluster; // startcluster of song playlength = dirfilesize; // how many bytes to play? } set_cpu_speed(CLKDIV); break; case CMD_PREV: // previous song set_cpu_speed(0); beep(61,50); delayms(1); beep(61,50); delayms(1); i = TYPE_ANY; // show even playlist while not playing if (is_playing) i = TYPE_MP3; // we're playing, so fetch only mp3 songs if (playlistcl != 0xffff) // playlist? { do { playlistid = get_next_playlist_entry(1, -1); // get previous pl entry } while (playlistid == 0xfe); if (playlistid == 0xff) // restart if on top { playlistptr = playlistlength; playlistid = get_next_playlist_entry(1, -1); } } else // no playlist, file browsing { do { actfilenum = get_next_direntry(dircluster, actfilenum, -1, i, DOID3); } while ((is_playing && (attrib & 0x10)) && (actfilenum != 0xffff)); if (actfilenum == 0xffff) { dir_finished=1; actfilenum = get_next_direntry(dircluster, 0, 1, i, DOID3); } } if (is_playing && !(attrib & 0x10)) { played = 0; // reset play status var's playcl = filecluster; // startcluster of song playlength = dirfilesize; // how many bytes to play? } set_cpu_speed(CLKDIV); break; case CMD_STOP: set_background_image(STOP_IMG); played = playlength; lastcmd = CMD_STOP; beep(62,150); is_playing = 0; break; case CMD_OFF: power_down(); break; case CMD_VOLDOWN: if (voltimer < 18) { if (volume < 0xff) { volume+=0x06; if (volume >= 0xf9) volume=0xff; } voltimer = 20; } break; case CMD_VOLUP: if (voltimer < 18) { if (volume > 0) volume-=0x06; if (volume < 0x06) volume=0; voltimer = 20; } break; case CMD_MENU: browse_menu(); break; } if ((!is_playing) && (lastcmd == CMD_PLAY)) { set_cpu_speed(0); count = actfilenum; if (playmode == REPEAT_ONE) play_file(filecluster, dirfilesize); else { if (playlistcl != 0xffff) // are we playing m3u playlist? { do { playlistid = get_next_playlist_entry(1, 1); // fetch next pl entry } while (playlistid == 0xfe); if (playlistid == 0xff) { playlistptr = 0; // end of pl, start from beginning playlistid = get_next_playlist_entry(1, 1); } } else // no playlist, directory mode { do { actfilenum = get_next_direntry(dircluster, actfilenum, 1, TYPE_MP3, DOID3); } while ((attrib & 0x10) && (actfilenum != 0xffff)); } if (actfilenum == 0xffff) { actfilenum = get_next_direntry(dircluster, 0, 1, TYPE_MP3, DOID3); if (playmode == REPEAT_OFF) // no repeat { dir_finished=1; lastcmd = CMD_STOP; } else { play_file(filecluster, dirfilesize); } } else play_file(filecluster, dirfilesize); } set_cpu_speed(CLKDIV); } if (sleeptimer > 3000) // nothing to do for such a long time { power_down(); // so I'll go to sleep now! } if (lcd_upd>LCDUPDATEFREQ) { update_display(); lcd_upd=0; } if ((batt_timer > 1) && !(lastcmd == SLEEP)) check_battery(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -