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

📄 yampp3_usb.c

📁 老外个人做的MP3/优盘。使用ATMEL MEGA系列的MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (nCurSector != nLastSector)
	{
		while(ATA_Read(nCurSector,2,(u08*)LO_CACHE))
			ATA_SW_Reset2();
		nLastSector = nCurSector;
	}

	u16 *pList = (u16*) ( (u08*)LO_CACHE + offset);  // again put offset here as it needs not to begin on sector boundary
	index = index % (SECTORSIZE/sizeof(u16));        // cut off rest of index that already is in other sectors
	return pList[index];
}

/****************************************************************************************/

#else // Not Sattelite

/****************************************************************************************/

YADL_PLAY_LIST_ENTRY *get_pl_entry(u16 index)
{
	u32 nCurSector;
	
	//
	// find (and load) correct playlist sector
	//

	nCurSector =  playlist_start + (index >> 3);	// 64 bytes per one playlist entry
	while(ATA_Read(nCurSector,1,(u08*)PL_CACHE))
		ATA_SW_Reset2();
	return &((YADL_PLAY_LIST_ENTRY *)PL_CACHE)[index % 8];
}

/****************************************************************************************/

YADL_SONG_BASE_ENTRY *get_song_entry(u16 index)
{
	u32 nCurSector;
	
	nCurSector = songbase_start + (index >> 2);
	while(ATA_Read(nCurSector,1,(u08*)SE_CACHE))
		ATA_SW_Reset2();
	return &((YADL_SONG_BASE_ENTRY *)SE_CACHE)[index % 4];
}

/****************************************************************************************/

u16 get_offset_entry(u16 index, u16 Playlist)
{
	YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(Playlist);
	FOFFSET offset = pListEntry->offset;

	// first compute desired start sector
	u32 nCurSector = playlist_start + (offset / SECTORSIZE) + (index * sizeof(u16) / SECTORSIZE);

	offset = offset % SECTORSIZE;		 // cut offset to rest inside one sector

	while(ATA_Read(nCurSector,2,(u08*)LO_CACHE))
		ATA_SW_Reset2();

	u16 *pList = (u16*) ( (u08*)LO_CACHE + offset);  // again put offset here as it needs not to begin on sector boundary
	index = index % (SECTORSIZE/sizeof(u16));        // cut off rest of index that already is in other sectors
	return pList[index];
}

#endif //Sattelite
/****************************************************************************************/

void pl_disp(u16 index, u08 sel)
{
	YADL_PLAY_LIST_ENTRY *pEntry = get_pl_entry(index);
	if (index < playlist_qty)
	{
		Vlcd_puts(pEntry->name);					// print on LCD
#ifdef ENABLE_UART
		if(sel)								// if current index
			uprintf("\rPlaylist: %s     ",pEntry->name);		// print on terminal
#endif
	}
}

/****************************************************************************************/

void se_disp(u16 index, u08 sel)
{
	YADL_SONG_BASE_ENTRY *pEntry = get_song_entry(index);
	if (index < songbase_qty)
	{
		Vlcd_puts(pEntry->artist);
		Vlcd_putchar('\n');
#ifdef GRAPH_LCD
		Vlcd_putchar((sel) ? 0x1f : ' ');
#else
		Vlcd_putchar((sel) ? '~' : ' ');
#endif
		Vlcd_puts(pEntry->title);			// print title
#ifdef ENABLE_UART
		if (sel)
			uprintf("\rSong: %s / %s     ",pEntry->artist,pEntry->title);
#endif
	}
}

/****************************************************************************************/

void lo_disp(u16 index, u08 sel)
{
	se_disp(get_offset_entry(index,selected_Playlist),sel);
}

/****************************************************************************************/

void menu_disp(u16 index, u08 sel)
{
	extern u08 *function_name[];
	Vlcd_progputs(function_name[index]);		// print on LCD
}

/****************************************************************************************/

u16 browse_list(u16 index, u16 min, u16 max, void (*disp)(u16, u08))
{
	u08 i,j = 0;
	event_e event = 0;
#ifdef NUMERICAL_KEYS
	extern u08 number_key;
	u16 number = 0;
#endif
#if(LCD_TYPE == 8)
	lcd_clrline(7);
#endif
	u08 k = (*disp == lo_disp) ? LCD_LINES/2 : LCD_LINES;
	while (1)
	{
		for (i=0; i < k; i++)
		{
			idle();
#ifdef GRAPH_LCD
			if (k == LCD_LINES/2)
				lcd_clrline(i*2 + 2);
			lcd_clrline(i * (1+(*disp == lo_disp))+1);
			Vlcd_putchar((i==j) ? 0x1f : ' ');
#else
			if (k == LCD_LINES/2)
				lcd_clrline(i*2 + 1);
			lcd_clrline(i * (1+(*disp == lo_disp)));
			Vlcd_putchar((i==j) ? '~' : ' ');
#endif
			disp(index+i,(i==j));
		}							// is current and valid

#ifdef NUMERICAL_KEYS
 #ifdef GRAPH_LCD
		Vlcd_gotoxy(LCD_LINE_LENGTH-5,LCD_LINES+1);		// Number print position
		if (number)						// if valid number
			lprintf("%5u", number);				// Print actual number value
		else
			Vlcd_progputs(PSTR("     "));			// Clear printed value if error or timeout
 #else
		Vlcd_gotoxy(LCD_LINE_LENGTH-5,LCD_LINES-1);		// Number print position
		if (number)						// if valid number
			lprintf("%5u", number);				// Print actual number value
 #endif
#endif // NUMERICAL_KEYS						// but if number is valid, selected item

		do 
		{
			time_flag = 0;
			event = get_event();
			switch (event)
			{
#ifdef ROTTARY_CONTROL
				case EV_DOWN:
#else
				case EV_NEXT:
				case EV_FFWD:
				case EV_UP:
#endif
					if ( index+j > min )
					{
						if(j)
							 j--;
						else
							index--;
					}
					else event = EV_IDLE;
					break;
#ifdef ROTTARY_CONTROL
				case EV_UP:
#else
				case EV_PREV:
				case EV_FREW:
				case EV_DOWN:
#endif
					if ( index+j+1 < max )
					{
						if(j < k - 1)
							j++;
						else
							index++;
					}
					else event = EV_IDLE;
					break;
				case EV_PLAY:
					return index+j;

				case EV_STOP:
					return -1;
#ifdef NUMERICAL_KEYS
				case EV_NUMBER:
					number = ((number*10)+number_key);	// Calculate new number
					if (number <= max)			// If valid
					{
						if (number > min)		// Validation for minimum
						{
							j=0;
							index = number-1;	// select and display selected item
						}
					}
					else 	number = 0;			// clear bad number

					nKeyTime = 0;
					break;
#endif
			}
#ifdef NUMERICAL_KEYS
			if (nKeyTime > 15 && number)		// number entering timeout (1.5 sec)
			{
				number = 0;
				event = EV_LASTEVENT; 		// for display update
			}
#endif
		}
		while (event == EV_IDLE);
	}
}


/****************************************************************************************/

void lcd_centerprint(u08 y, u08 *data, u08 mode)
{
	u08 i,j;
#ifdef GRAPH_LCD
	if(mode%2 == 0)
		Vlcd_invert();
#endif
	Vlcd_gotoxy(0,y);
	i = (mode<2) ? strlen_P(data) : strlen(data);
	if(i < LCD_LINE_LENGTH)
	{
		j = (LCD_LINE_LENGTH-i);
#ifdef GRAPH_LCD
		if (j%2 == 1)
		{
			i = 3;
			while(i--)
				Vlcd_wrdata((mode%2 == 0) ? 127 : 0);
		}
#endif
		j /= 2;
		for(i=0; i<j; i++)
#ifdef GRAPH_LCD
			Vlcd_putchar(' ');
#else
			Vlcd_putchar('-');
#endif
	}
	else j=0;

	if (mode<2)
		Vlcd_progputs(data);
	else
		Vlcd_puts(data);

	for(i=0; i<=j; i++)
#ifdef GRAPH_LCD
		Vlcd_putchar(' ');
		Vlcd_normal();
#else
		Vlcd_putchar('-');
#endif
}


u08 browse_playlist(void)
{
	Send_state(STATE_PL_SELECT);
#ifdef GRAPH_LCD
	lcd_centerprint(0, PSTR("SELECT LIST"),0);
#endif
	if (curPlaylist == 0xffff)
		curPlaylist = 0;
	selected_Playlist = browse_list(curPlaylist, 0, playlist_qty, pl_disp);
	if (selected_Playlist != 0xffff)
		return 0;
	return 1;
}


/****************************************************************************************/

u16 browse_songs(void)
{
	Send_state(STATE_SO_SELECT);
#ifdef GRAPH_LCD
	lcd_centerprint(0, PSTR("SELECT SONG"),0);
#endif
	YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(selected_Playlist);
	u16 entry_qty = pListEntry->entry_qty;
	return (browse_list((curPlaylist == selected_Playlist) ? curIndex : 0, 0, entry_qty, lo_disp));
}


/****************************************************************************************/

u16 browse_menu(void)
{
	Send_state(STATE_MENU);
#ifdef GRAPH_LCD
	lcd_centerprint(0, PSTR("- M E N U -"),0);
#endif


#ifdef FOUR_KEYS_CONTROL
	return (browse_list((menu_event) ? menu_event-1 : 2, 2, 14, menu_disp));
#else
	return (browse_list((menu_event) ? menu_event-1 : 8, 8, 14, menu_disp));
#endif
}


/****************************************************************************************/


void lcd_frame(void)				// show song info and progressbar frame
{
#ifdef GRAPH_LCD
	if(isPlaying && info_flag < 3)
	{
		Vlcd_clrscr();
		lcd_centerprint(0,scroll_line,2);
#if(LCD_TYPE == 7)
		lprintf("\n%s    \n%s\n#%u/%u", artistname, titlename, curIndex+1, ListQty);
#else
		Vlcd_putchar('\n');
		if(scroll_length <= LCD_LINE_LENGTH)
		{
			Vlcd_progputs(PSTR("Now playing:\n"));
			Vlcd_puts(artistname);
		}
		else
		{
			Vlcd_puts(artistname);
			Vlcd_putchar('\n');
			Vlcd_puts(artistname + LCD_LINE_LENGTH);
		}
		Vlcd_putchar('\n');
		Vlcd_puts(titlename);
		if(scroll_length_2 > LCD_LINE_LENGTH)
		{
			Vlcd_putchar('\n');
			Vlcd_puts(titlename + LCD_LINE_LENGTH);
		}
		Vlcd_gotoxy(0,6);
		lprintf("PL:%u/%u\nSO:%u/%u", curPlaylist+1, playlist_qty, curIndex+1, ListQty);
#endif
		status_display();
		time_flag = 5;				// provide fast display refresh
		OldSteps = -1;
		OldPlayTime = -1;
	}
	else
		set_event(EV_STOP);

#else // not GRAPH_LCD

#if (LCD_LINES != 2)
	if(isPlaying && info_flag < 3)
	{
		Vlcd_clrscr();
		lcd_centerprint(0,scroll_line,2);
		Vlcd_putchar('\n');
		Vlcd_puts(artistname);
		Vlcd_putchar('\n');
		Vlcd_puts(titlename);
	}

#endif //(LCD_LINES == 4)

	if(isPlaying && !info_flag)
	{
#ifndef SATTELITE
		u08 i;
		Vlcd_command(0x48);			// start definition of CG-RAM from char code 1

		for (i = 0; i < 7; i++)
			lcd_data1f();			// value for full bar char (1)
		lcd_data00();				// cursor line

		lcd_data1f();				// empty bar definition (2) (frame)
		for (i = 0; i < 5; i++)
			lcd_data00();
		lcd_data1f();
		lcd_data00();				// cursor line

		lcd_data1f();				// empty ended bar definition (3) (frame end)
		for (i = 0; i < 5; i++)
			Vlcd_data(0x01);
		lcd_data1f();
		lcd_data00();				// cursor line

		Vlcd_gotoxy(0, LCD_LINES -1);		// progressbar position

		for (i=0; i< (LCD_STEPS / 5) - 1; i++)	// display progress bar outline
			Vlcd_putchar(2);	
		
		Vlcd_putchar(3);			// end of progressbar

#endif // SATTELITE
		time_flag = 5;				// provide fast display refresh
		OldSteps = -1;
		OldPlayTime = -1;
	}
#endif // GRAPH_LCD
	Send_state(STATE_RETURN);
}


//
// Run this as often as possible
// preferably every time around the main loop
//
void idle(void)
{
	usb_handler();
	if(usb_link == 0)					// usb link disables other control
		control_handler();
#ifdef SATTELITE
	else if(scroll_time >= 30)
	{
		uart_pc1(SAT_CMD_MARKER);
		uart_pc1(SAT_LINKHOLDER);
		scroll_time = 0;
	}
#endif

	//	
	//
	//
	if (isPlaying)
	{

#ifdef VOL_UP_RAMP
		volatile u08 otim;
		if (volume_ramp != 0 && scroll_time != otim)
		{
			if(otim%2 == 1)
			{
				volume_ramp--;			// increase volume
				setvolume(volume);		// update volume
			}
			otim = scroll_time;
		}
#endif

		//
		// time to update a buffer ?
		//
		if (updbuf && (!usb_play))
		{
			load_sectors(updbuf);
			updbuf = (u08 *) 0;				// mark as done
		}
#ifdef FAST_IDLE_DISK
		else
		{	
			if (isPlaying)
				ATA_Read(MySector, 1, (u08*) BBK_MEMORY);
		}
#endif	
		// pump some data to the decoder
		
		while (bit_is_set(PINB, PB2) && (!updbuf))		// while DREQ is hi 
		{							// and buffer no need reload
			//send data on SPI bus
			vs1001_send32(outptr);
			outptr += 32;

			// check for buffer wrap
			if (outptr == buffer2)				// buffer 1 empty
			{
				updbuf = buffer1;			// buffer 1 need reload
				if (usb_play)
					usb_response(0);
			}
			else if (outptr == buffer3)			// buffer 2 empty
			{
				updbuf = buffer2;			// buffer 2 need reload

⌨️ 快捷键说明

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