📄 fatyampp.c
字号:
case CMD_VOLDOWN: delayms(100); case CMD_PREV: if (locktime > 0) locktime--; break; } lcd_gotoxy(2,3); if (locktime > 0) { utoa(locktime, ibuf, 10); lcd_putchar(' '); lcd_puts(ibuf); lcd_putchar(' '); lcd_progputs(PSTR("sec. ")); } if (locktime == 0) lcd_progputs(PSTR(" off ")); } eeprom_wb(EE_LOCKTIME, locktime); lcd_clrscr();}unsigned char get_key(){ const char cmdtbl[4] = {CMD_PLAY, CMD_STOP, CMD_NEXT, CMD_PREV}; const char cmdlongtbl[4] = {0, 0, 0, 0}; const char cmdholdtbl[4] = {CMD_MENU, CMD_OFF, CMD_VOLUP, CMD_VOLDOWN}; unsigned char reskey; reskey = 0; if (lastkey == WAIT_RELEASE) { if (bit_is_set(PINE, PINE0) && bit_is_set(PIND, PIND1) && bit_is_set(PIND, PIND4) && bit_is_set(PIND, PIND5)) { lastkey = 0; } return (0); } if (lastkey == BUTTON_LOCK) { if (keytime > 3) { if (locked) { locktimer = 0; locked = 0; } else locked = 1; lastkey = WAIT_RELEASE; return (0); } } else if (lastkey != 0) { if (bit_is_set(PINE, PINE0) && bit_is_set(PIND, PIND1) && bit_is_set(PIND, PIND4) && bit_is_set(PIND, PIND5)) { if (keytime > 0 && keytime < 10) reskey = cmdtbl[lastkey-1];// if (keytime > 10 && keytime < 20)// reskey = cmdlongtbl[lastkey-1]; } if ((keytime > 17) || (locked && (keytime > 25)) || (locked && voltimer)) { reskey = cmdholdtbl[lastkey-1]; } } if (voltimer) { if (reskey == CMD_NEXT) reskey = CMD_VOLUP; if (reskey == CMD_PREV) reskey = CMD_VOLDOWN; } if (lastkey == 0) keytime = 0; if (lastkey && voltimer && !reskey) voltimer = 19; lastkey = 0; if (bit_is_clear(PIND, PIND1) && bit_is_clear(PIND, PIND5)) lastkey = BUTTON_LOCK; else { if (bit_is_clear(PINE, PINE0)) lastkey = BUTTON_PLAY; if (bit_is_clear(PIND, PIND4)) lastkey = BUTTON_REW; if (bit_is_clear(PIND, PIND5)) lastkey = BUTTON_FF; if (bit_is_clear(PIND, PIND1)) lastkey = BUTTON_STOP; } if (locked && (reskey != CMD_VOLUP && reskey != CMD_VOLDOWN)) reskey = 0; if (reskey != 0) { locktimer = 0; backlight_on(); } if (reskey == 0 && remote_key != 0) { switch (remote_key) { case 3: reskey = CMD_PREV; break; case 2: reskey = CMD_NEXT; break; case 4: if (is_playing == PLAY) reskey = CMD_STOP; else reskey = CMD_PLAY; break; } remote_key = 0; } return reskey;}void play_file(unsigned int startcl, unsigned long length){ if (is_playing == PLAY) return; if (is_playing == PAUSE) { is_playing = PLAY; return; } played = 0; // reset play status vars playcl = startcl; // startcluster of song playlength = length; // how many bytes to play? is_playing = PLAY; // we are playing... vs1001_reset(loudness);}void check_battery(){ unsigned char contrast; cli(); // block interrupts during battery measure cbi(PORTB, PB3); // PB3 as analog comparator input cbi(DDRB, PB3); // for battery level measure delay(500); if (bit_is_set(ACSR,ACO)) // low battery {// if (!lobatt)// { lobatt = 1;// } } else lobatt = 0;// else if (lobatt == 1) // if some scratches on input// {// lobatt = 0;//// } batt_timer = 0; sbi(PORTB, PB3); // re-enable pullup sbi(DDRB, PB3); // PB3 as output (VS1001 CS) sei(); // re-enable interrupts}void initialize() // self-explaining, isn't it?{ unsigned int i; char contrast; wdt_disable(); outp(0x00, DDRA); // enable pullups on outp(0xFF, PORTA); // CF address port outp(0xFF, DDRC); // CF addres port outp(0xF0, PORTC); // set to high 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- cbi(PORTB, RESET_PIN); // perform a device reset on the vs1001 delayms(50); sbi(PORTB, RESET_PIN);#ifdef REMOTE sbi(MCUCR, ISC11); // INT1 on falling edge (remote control) cbi(MCUCR, ISC10); sbi(GICR, INT1); // enable interrupt INT1 outp(0xF7,PORTD); // activate pullups#else outp(0xFF,PORTD);#endif outp(0xC0,DDRD); cbi (DDRE, PINE0); sbi(PORTE,PINE0); // pin PE0 is keyboard input, enable pullup cbi(DDRE,PINE1); // set pin as input sbi(PORTE,PINE1); // activate pullup cbi(SFIOR, PUD); //Pullups Enable outp(0x40,ACSR); // enable analog comparator with internal 1.1 V reference outp(0, TCCR1A); outp(4, TCCR1B); // prescaler /256 tPeriod = 32 uS outp(TI1_H, TCNT1H); // load counter value hi outp(TI1_L, TCNT1L); // load counter value lo sbi(TIMSK, TOIE1); // enable timer1 interrupt outp(0x00, OCR0); outp((1<<WGM00) | (1 << COM01) | (1 << CS01), TCCR0); // Timer 0 normal PWM mode, CLK/8 read_eeprom_settings(); contrast = eeprom_rb(EE_CONTRAST); if (contrast < 20 || contrast > 0x58) contrast = 0x40; lcd_init(0); lcd_clrscr(); lcd_contrast(contrast); // max: 0x58 vs1001_init_io(); vs1001_setcomp(F_VS1001); vs1001_reset(loudness); vs1001_vol = 0; vs1001_setvolume(volume,0); vs1001_nulls(8); send_sinewave_beeps(); i = 5; // sometimes CF doesn't respond properly while (get_cf_parms() && i) // on first attempt { i--; delayms(100); } if ((i == 0) || (maxsect == 0) || (heads == 0) || (sectors_per_track == 0)) // read cf parameters { beep(62,1000); power_down(); } delayms(10); CFWriteAdr(CF_SECCOUNT, 2); // Standby Timer to 50 ms CFWriteAdr(CF_STACOM, 0xE3); // execute IDLE CFWaitReady();/* if (bit_is_clear(PIND, PIND4) && bit_is_clear(PIND, PIND5)) // top buttons pressed during reset { lcd_clrscr(); lcd_gotoxy(2,2); lcd_progputs(PSTR("release\n buttons")); while (bit_is_clear(PIND, PIND4) || bit_is_clear(PIND, PIND5)); prepare_flash(); // update the player firmware }*/ dir_finished = 0; playlistcl = 0xffff; dircluster = (eeprom_rb(EE_DIRCLUSTER) << 8) + eeprom_rb(EE_DIRCLUSTER+1); if (dircluster = 0xffff) dircluster = 0; actfilenum = get_next_direntry(dircluster, 0, 1, TYPE_M3U, NOID3); if (actfilenum == 0xffff) { playlistcl = actfilenum; actfilenum = (eeprom_rb(EE_FILENR) << 8) + eeprom_rb(EE_FILENR+1); actfilenum--; if (actfilenum > 512) actfilenum = 0; actfilenum = get_next_direntry(dircluster, actfilenum, 1, TYPE_MP3, DOID3); } else { playlistdirid = actfilenum; playlistcl = filecluster; playlistlength = dirfilesize; playlistptr = 0; playlistid = 0; }/* if ( actfilenum == 0xffff); { beep(64,3000); power_down(); }*/ lastcmd = CMD_STOP; lastkey = 0; keytime = 0; locktimer = 0; locked = 0; remote_key = 0; artalbdir = titledir = 1; artalbpos = titlepos = 0; scrolltimer = SCROLLSPEED; is_playing = 0; // play status sleeptimer = 0; // timer for auto sleep mode sei(); // global interrupt enable}void write_eeprom_data(){ 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(){/* the values are saved by default on power off* so it's safe here just to change the variables */ loudness = eeprom_rb(EE_LOUDNESS); if (loudness > 1) loudness = 1; 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); 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); if (timedisp > 1) timedisp = 1; blmode = eeprom_rb(EE_BLMODE); if (blmode > 5) blmode = 3;}void beep(unsigned char freq, unsigned int time){ unsigned char i; 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); wdt_reset(); for (j=0;j<3;j++) { beep(62,80); delayms(80); }}void playloop(){ unsigned int count; if (volume != vs1001_vol) // volume changed? { vs1001_setvolume(volume, balance); // volume setting vs1001_vol = volume; delay(5); } if (played >= playlength) // song end? { is_playing = 0; lcd_update=1; return; } if (played == 0) // new song... { cc = 0; // cluster count CFReadSector(data + ((unsigned long) playcl) * secpercluster); // read first sector playsec = secbuf; vs1001_reset(loudness); vs1001_nulls(20); vs1001_setvolume(volume,balance); delay(5); } 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? { wdt_reset(); playcl = (unsigned int) get_next_cluster(playcl); cc = 0; } wdt_reset(); CFReadSector(data + ((unsigned long) playcl * secpercluster + cc)); // read next sector playsec = secbuf; // & sector buffer count--; } } if (!count) { wdt_reset(); cbi(PORTB, RESET_PIN); delayms(50); sbi(PORTB, RESET_PIN); wdt_reset(); 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(); backlight_on();// wdt_enable(WDTO_250MS); wdt_disable(); while(1) { wdt_reset(); if (is_playing == PLAY) playloop(); cmd = get_key(); switch (cmd) { case CMD_PLAY: if (!is_playing) { if (attrib & 0x10) { strncpy(dirname, filename,15); dirname[16]='\0'; dircluster = filecluster; actfilenum = get_next_direntry(dircluster, 0,1, TYPE_MP3, DOID3); } else { beep(61,100); delayms(50);// vs1001_reset(loudness);// delayms(5); lastcmd = CMD_PLAY; play_file(filecluster, dirfilesize); } } else { if (is_playing == PLAY) { is_playing = PAUSE; } else if (is_playing == PAUSE) { is_playing = PLAY; } } break; case CMD_NEXT: beep(61,50); delayms(1); beep(61,50); delayms(1); i = TYPE_ANY; if (is_playing) i = TYPE_MP3; count = actfilenum; if (playlistcl != 0xffff) { 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? } break; case CMD_PREV: beep(61,50); delayms(1); beep(61,50); delayms(1); i = TYPE_ANY; if (is_playing) i = TYPE_MP3; if (playlistcl != 0xffff) { do { playlistid = get_next_playlist_entry(1, -1); } while (playlistid == 0xfe); if (playlistid == 0xff) { playlistptr = playlistlength; 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, 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? } break; case CMD_STOP: 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)) { lcd_clrscr(); count = actfilenum; if (playmode==1) play_file(filecluster, dirfilesize); else { if (playlistcl != 0xffff) { 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, TYPE_MP3, DOID3); } while ((attrib & 0x10) && (actfilenum != 0xffff)); } if (actfilenum == 0xffff) { actfilenum = get_next_direntry(dircluster, 0, 1, TYPE_MP3, DOID3); if (playmode == 0) { dir_finished=1; lastcmd = CMD_STOP; } else { play_file(filecluster, dirfilesize); } } else play_file(filecluster, dirfilesize); } } if (sleeptimer > 3000) { power_down(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -