⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yampp7_usb.c

📁 yampp mp3 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
			// 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 (scroll_flag >= SCROLL_SPEED && info_flag < 2)
		{
			u08 nTemp;
#ifndef ALTERNATE_SCROLL
			static u08 scrollP;
			#define scrollP_2 scrollP
#endif
			scroll_flag = 0;
			//
			// scrolling artist and name

			if (scroll_length > 14)
			{
				lcd_gotoxy(0, 1);
				lcd_data_o(artistname[scroll_pos % scroll_length],scrollP);
				for (nTemp = 1; nTemp <  15; nTemp++)
#ifdef ALTERNATE_SCROLL
					lcd_putchar(artistname[scroll_pos + nTemp]);

				if (scroll_pos + 14 == scroll_length)
					scroll_dir -= 2;
				if (scroll_pos == 0 && scrollP == 0)
					scroll_dir++;

				scrollP += ((signed char)scroll_dir / (10/SCROLL_SPEED)) * SCROLL_STEP;
				if (scrollP == 6)
				{
					scrollP = 0;
					scroll_pos++;
				}
				if (scrollP > 127)
				{
					scrollP = 6 - SCROLL_STEP;
					scroll_pos--;
				}

#else //ALTERNATE_SCROLL
					lcd_putchar(artistname[(scroll_pos + nTemp) % scroll_length]);
#endif
			}

			lcd_gotoxy(0, 2);
			if (scroll_length_2 > 14)
			{
				lcd_data_o(titlename[scroll_pos_2 % scroll_length_2],scrollP_2);
				for (nTemp = 1; nTemp < 15; nTemp++)
#ifdef ALTERNATE_SCROLL
					lcd_putchar(titlename[scroll_pos_2 + nTemp]);

				if (scroll_pos_2 + 14 == scroll_length_2)
					scroll_dir_2 -= 2;
				if (scroll_pos_2 == 0 && scrollP_2 == 0)
					scroll_dir_2++;

				scrollP_2 += ((signed char)scroll_dir_2 / (10/SCROLL_SPEED)) * SCROLL_STEP;
				if (scrollP_2 == 6)
				{
					scrollP_2 = 0;
					scroll_pos_2++;
				}
				if (scrollP_2 > 127)
				{
					scrollP_2 = 6 - SCROLL_STEP;
					scroll_pos_2--;
				}
#else //ALTERNATE_SCROLL
					lcd_putchar(titlename[(scroll_pos_2 + nTemp) % scroll_length_2]);
#endif
				lcd_gotoxy(0,3);
				lcd_data('#');
			}
			else
				lcd_puts(titlename);

#ifndef ALTERNATE_SCROLL
			scrollP += SCROLL_STEP;
			if (scrollP == 6)
			{
				scrollP = 0;
				scroll_pos++;
				scroll_pos_2++;
			}
#endif
		}

		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);
			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 ?
			{
				lobatt = 0;
				lobatt_time = 0;
				ledflash = !ledflash;
				lcd_gotoxy(9,5);
				lcd_wrdata(0);
				if (ledflash)
					puts("  ");
				else
					puts("\xB\xC");
			}
			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 (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 = 0;				// clear low battery status
			lobatt_time = 0;			// clear low battery timer

			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
			{
				cbi(PORTB,LED_PIN);		// off
				ledflash = offtime;
			}
			else
			{
				sbi(PORTB,LED_PIN);		// on
				ledflash = ontime;
			}
		}
#endif
		if (!menu_event)
		{
			outp(0xA0,MCUCR);			// 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 && 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;
		}
	} 

	BatteryMeasure();
	
	u16 off_time = lobatt_time;
	if (lobatt == 2)
	{

#if (BACKLIGHT_TIME == 0)
		if (isPlaying && (off_time % 20) == 0)		// while playing
			cbi(PORTB,LED_PIN);			// and battery level is low

		if (isPlaying && (off_time % 20) == 10)		// led blinks
			sbi(PORTB,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
		{
			send_sinewave_beeps();
			PowerOff();
		}
	}
}

void play_song(void)
{
	isPlaying = 1;
	if (info_flag == 0)
		Playlist_name();

	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 += (inp(TCNT1H)<<8) + (inp(TCNT1L)) + 1;

	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 > 14)
	{
		strcat(artistname, " >> ");			// add ' >> ' sign
		scroll_length += 4;		
	}
#endif

	//
	// 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

	//
	// start playing the song
	//

#if (BACKLIGHT_TIME == 0)
	sbi(PORTB, LED_PIN);					// LED ON
#endif
	vs1001_reset(0);
	LoudSet();
}

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_clrscr();
	puts("Adjust contras\nt with volume \nkeys, STOP=End");
	lcd_gotoxy(2,3);
	lcd_bar((contrast-0x20),0x38);
	status_display();
	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 < 0x58)
					contrast++;
				goto SETC;

			case EV_DOWN:
			case EV_PREV:
				if (contrast > 0x20)
					contrast--;
SETC:
				lcd_gotoxy(2,3);
				lcd_bar((contrast-0x20),0x38);
				lcd_contrast(contrast);
				break;

			case EV_STOP:
				eeprom_wb(EEPROM_LCD_CONTRAST,contrast);
				lcd_clrscr();
				set_event(EV_STOP);
				return;
		}
		event = EV_IDLE;
	}
}

#if defined (__AVR_ATmega162__)
 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");
 }
#endif


//----------------------------------------------------------------------------
// Main part
//----------------------------------------------------------------------------
int main(void) 
{
 
 //------------------------------
 // Initialize 
 //------------------------------

//////////////////////////////////////////////////////////////////
// B - Port
//////////////////////////////////////////////////////////////////

	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 and RST pin to FTDI chip
	// PB3 is MP3 signal to VS1001
	// 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
//////////////////////////////////////////////////////////////////

	outp(0xFF,PORTD);	// activate pullups
	outp(0xC0,DDRD);
	// 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -