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

📄 yampp7_usb.c

📁 yampp 7 USB firmware v 2.44 checked, working, latest
💻 C
📖 第 1 页 / 共 5 页
字号:

/************************************************************************
*				FORMAT NEW DISK				*
*************************************************************************/

u08 format_new_disk(void)
{
	YADL_ROOT_SECTOR *pBoot;					// Boot Sector struct
	u32 sectors;

#ifndef MMC_CARD

	IDENTIFY_DATA *pID;	
	u08 i,c;
	u08 tmpSectorBuffer[sizeof(pID->ModelNumber)];

	// first get some drive data
	CARD_Identify();
	
	// flip and save the ModelNumber data
	pID = (IDENTIFY_DATA *) SectorBuffer;
	strncpy(tmpSectorBuffer,(u08*)pID->ModelNumber,sizeof(pID->ModelNumber));
	for (i=0;i<sizeof(pID->ModelNumber);i+=2)
	{
		c = tmpSectorBuffer[i];
		tmpSectorBuffer[i] = tmpSectorBuffer[i+1];
		tmpSectorBuffer[i+1] = c;
	}
	tmpSectorBuffer[sizeof(pID->ModelNumber)] = 0;			// terminate entry
	
	// get max sectors (disk size)
	sectors = pID->UserAddressableSectors;

#else

	u08 tmpSectorBuffer[8];
	MMC_Name();
	strncpy(tmpSectorBuffer, SectorBuffer, 7);
	tmpSectorBuffer[7] = 0;					// terminate entry
	sectors = MMC_Capacity();

#endif

	// clear buffer
	pBoot = (YADL_ROOT_SECTOR *) SectorBuffer;		// use temp buffer for room
	strcpy_P(pBoot->model,firmware_scan_tag);		// for compiler warning supression...
								// I don't know why, but it decrease code size too
	memset(pBoot,0,512);				

// section 1
	strncpy(pBoot->id,"YADL",4);
	pBoot->disk_size = sectors;
	pBoot->unmount_state = YADL_STATE_NEW;
	pBoot->media_type = YADL_MEDIA_FLASH;

	pBoot->disk_version_major = DISK_LAYOUT_VERSION_MAJOR;
	pBoot->disk_version_minor = DISK_LAYOUT_VERSION_MINOR;

	strcpy_P(pBoot->model,model_txt);	// yampp model name

	// copy the ModelNumber result from Identify Drive
	strcpy(pBoot->disk_info,tmpSectorBuffer);	

// section 2
	
	strcpy_P(pBoot->build_timestamp,date_txt);
	pBoot->build_timestamp[YADL_LEN_BUILD_TIMESTAMP-1] = 0;	// make sure it's terminated

	pBoot->firmware_version_major = YAMPP_FIRMWARE_VERSION_MAJOR;
	pBoot->firmware_version_minor = YAMPP_FIRMWARE_VERSION_MINOR;
	
// section 3	
// section 4
// section 5

	// write the sector
	// and return result
	
	return CARD_Write(YADL_SEC_ROOT);
}



//////////////////////////////////

u32 songbase_start;
u16 songbase_qty;			// number of songs
u32 fat_start;				// first fat sector
u32 sector_cluster_offset;		// add to cluster -> sector conversions
u32 playlist_start;			// first playlist sector
u16 playlist_qty;			// number of playlists

/////////////////////////////////

u32 MyCluster;				// current cluster number
u32 MySector = 2;			// current sector number
u16 SectorsLd;				// sectors in cluster counter

//
// return the next FAT in a chain
//

u32 next_fat(void)
{
	u32 fat_sector = fat_start + MyCluster / (SECTORSIZE / sizeof(CLUSTER));
	u16 fat_offset = MyCluster % (SECTORSIZE / sizeof(CLUSTER));
	while (CARD_Read(fat_sector))
	    	CARD_SW_Reset2();
	ClusterCount++;						// counter for F.Forward file sizing
	return ((CLUSTER*)SectorBuffer)[fat_offset];
}


void init_load_sectors(u32 cluster)
{
	MyCluster = cluster;
	MySector = sector_cluster_offset + YADL_SECTORS_PER_CLUSTER * MyCluster;
	SectorsLd = 0;
}


//
// load a bufferfull of data
//
void load_sector(void)
{
	if (SectorsLd == YADL_SECTORS_PER_CLUSTER)
		init_load_sectors(next_fat());
	while(CARD_Read(MySector))
	    	CARD_SW_Reset2();
	MySector++;
	SectorsLd++;
}

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

void init_stuff(void)
{
	u08 i,update = 0;
	YADL_ROOT_SECTOR *pRoot;				// Boot Sector struct
	pRoot = (YADL_ROOT_SECTOR *) SectorBuffer;		// Allocate room from the temp buffer

	while (CARD_Read(YADL_SEC_ROOT))			// read root sector
		CARD_SW_Reset2();

	if(pRoot->id[0] != 'Y' || pRoot->id[1] != 'A' || 
	   pRoot->id[2] != 'D' || pRoot->id[3] != 'L')		// YADL signature not found
	{
		lcd_clrscr();
		puts("Unknown Card,\nPress STOP for\nformat to YADL\n");
		static	u08 tones[]= {SINE_300,SINE_500,SINE_800,SINE_1000};
		for (i=0; i<4; i++)
		{		
			beep(tones[i],200);
			delayms(10);
		}
		do{
			get_key();
			i = check_event();
			wdt_reset();
		}while(i != EV_STOP);
		if(format_new_disk() == 0)			// format Card with YADL f.s.
		{
			puts("Formatting OK.");
			beep(SINE_1500,100);
		}
		else
		{
			puts("Format ERROR !");
			beep(SINE_500,200);
		}
		wdt_enable(6);					// time for text displaying
		while(1);					// reset player by watchdog
	}
	if(pRoot->firmware_version_major != YAMPP_FIRMWARE_VERSION_MAJOR)
	{
		pRoot->firmware_version_major = YAMPP_FIRMWARE_VERSION_MAJOR;
		update = 1;
	}
	if(pRoot->firmware_version_minor != YAMPP_FIRMWARE_VERSION_MINOR)
	{
		pRoot->firmware_version_minor = YAMPP_FIRMWARE_VERSION_MINOR;
		update = 1;
	}
	if(strcmp_P(pRoot->build_timestamp, date_txt))
	{
		strcpy_P(pRoot->build_timestamp, date_txt);
		update = 1;
	}
	if (update)
	{
		while(CARD_Write(YADL_SEC_ROOT))
		    	CARD_SW_Reset2();
		lcd_clrscr();
		puts("\nFirmware vers.n\ninfo updated!\n");
		delayms(100);
		beep(SINE_1500,80);
		beep(SINE_2000,80);
		delayms(1000);
	}

	sector_cluster_offset = pRoot->sector_cluster_offset;
	songbase_start 	= pRoot->songbase_start;			// SECTOR !!
	songbase_qty	= pRoot->songbase_qty;
	playlist_start 	= sector_cluster_offset + YADL_SECTORS_PER_CLUSTER * pRoot->playlist_start;	// SECTOR !!!
	playlist_qty 	= pRoot->playlist_qty;		
	fat_start 	= pRoot->fat_start;

	//
	// VS1001 User Software Loader
	//

	u32 app_start = pRoot->wasteland_start;
	vs1001_fw = 0;
	if (app_start != 0)
	{
		u16 *pData;
		pData = (u16*) SectorBuffer;
		CARD_Read(app_start);						// read first free sector
		if(*pData++ != 0x4679 || *pData++ != 0x776D)			// Firmware signature ('yFmw') not found
			return;							// exit
		u16 DataLen = *pData++;						// length of firmware in words (firmware only)
		vs1001_fw = *pData++;						// address to enter into VS1001 register A1ADDR
										// for application running.
		vs1001_write(7,vs1001_fw + 0x4000);				// write to VS1001 register WRAMADDR
		while(DataLen--)						// data length in words
		{
			if (pData == (u16*)(SectorBuffer+512))
			{
				app_start++;
				CARD_Read(app_start);				// read next sector with application datas
				pData = (u16*) SectorBuffer;			// new start address
			}
			vs1001_write(6,*pData++);				// write firmware word to vs1001
		}
	}
}

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

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(CARD_Read(nCurSector))
		CARD_SW_Reset2();
	return &((YADL_PLAY_LIST_ENTRY *)SectorBuffer)[index % 8];
}

YADL_SONG_BASE_ENTRY *get_song_entry(u16 index)
{
	u32 nCurSector;
	
	nCurSector = songbase_start + (index >> 2);
	while(CARD_Read(nCurSector))
		CARD_SW_Reset2();
	return &((YADL_SONG_BASE_ENTRY *)SectorBuffer)[index % 4];
}


// Nilrog: Rewrote this function since it couldn't properly handle
//         the fact that a playlist can begin in one sector and the
//         index pointed to a position which was located in the next
//         sector.

u16 get_offset_entry(u16 index)
{
 	YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist);
 	FOFFSET offset = pListEntry->offset;
	
	/* calculate absolute position from start of playlistfile */
	u16 pos = offset + index * sizeof(u16);

	/* calculate if the current playlist position wraps into another sector */
	u08 wraps = pos / SECTORSIZE;

	/* calculate which sector to read */
	u32 nCurSector = playlist_start + wraps;

	/* if playlist wraps we need to re-calculate index and offset */
	if (wraps)
	{
		index = (pos - wraps * SECTORSIZE) / sizeof(u16);
		offset = 0;
	}
	/* if no wrap ocurred 'index' and 'offset' are clear to use as is */

 	while(CARD_Read(nCurSector))
 		CARD_SW_Reset2();
 
 	u16 *pList = (u16*) ( (u08*)SectorBuffer + offset);
 	return pList[index];
 }


//********************************************************************************
void scroll_init(u08 xpos)
{
	scroll_length = strlen(artistname);
	scroll_length_2 = strlen(titlename);
#ifndef ALTERNATE_SCROLL
	if (scroll_length > 14-xpos)
	{
		strcat(artistname, " >> ");			// add ' >> ' sign
		scroll_length += 4;		
	}

	if (scroll_length_2 > 14-xpos)
	{
		strcat(titlename, " >> ");			// add ' >> ' sign
		scroll_length_2 += 4;		
	}
#else
	scroll_dir = 0;
	scroll_dir_2 = 0;
	scrollP = 0;
	scrollP_2 = 0;
#endif
	scroll_pos = 0;
	scroll_pos_2 = 0;
	scroll_flag = 2;
}

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

void scroll_do(u08 xpos, u08 ypos)
{
	if (scroll_flag >= SCROLL_SPEED)
	{
		u08 nTemp;
#ifndef ALTERNATE_SCROLL
		static u08 scrollP;
		#define scrollP_2 scrollP
#endif
		scroll_flag = 0;
		//
		// scrolling artist and name

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

			if (scroll_pos + 14-xpos == 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(xpos, ypos+1);
		if (scroll_length_2 > 14-xpos)
		{
			lcd_data_o(titlename[scroll_pos_2 % scroll_length_2],scrollP_2);
			for (nTemp = 1; nTemp < 15-xpos; nTemp++)
#ifdef ALTERNATE_SCROLL
				lcd_putchar(titlename[scroll_pos_2 + nTemp]);

			if (scroll_pos_2 + 14-xpos == 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
		}
		else
			lcd_puts(titlename);


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

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

void Playlist_name(void)
{
	u08 *src;
	udiv_t divt;
	YADL_PLAY_LIST_ENTRY *pListEntry = get_pl_entry(curPlaylist);
	u16 tmp = (pListEntry->entry_qty);
	lcd_clrscr();
	lcd_invert();
	u08 j = strlen(pListEntry->name);
	if (j<14)
	{
		j = (14-j)*3;
		while(j--)
			lcd_wrdata(127);
	}
	lcd_puts(pListEntry->name);			// playlist name
	j=8;
	while(j--)
		lcd_putchar(' ');
	lcd_normal();

	YADL_SONG_BASE_ENTRY *pEntry = get_song_entry(get_offset_entry(curIndex));
	strcpy(artistname, pEntry->artist);
	strcpy(titlename, pEntry->title);
	src = titlename + strlen(titlename);
	*src++ = ' ';
	*src++ = '(';
	songtime = pEntry->play_time;
	divt = udiv(songtime, 600);
	u08 s = (u08)divt.quot % 10;
	if (s)
		*src++ = '0' + s;				// song time up to 99 min
	divt = udiv(divt.rem, 60);
	*src++ = '0' + (u08)divt.quot;
	*src++ = ':';
	divt = udiv(divt.rem, 10);
	*src++ = '0' + (u08)divt.quot;
	*src++ = '0' + (u08)divt.rem;			
	*src++ = ')';
	*src = 0;
	scroll_init(0);
	printf("\n%s    \n%s\n#%u/%u", pEntry->artist, titlename, curIndex+1, tmp);
	status_display();
	CARD_Read(MySector-1);
	time_flag = 5;
}

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

// this is in assembler procedure because c not propper handle 
// pointers array located in program memory (in this case)
u08* PRG_RDW(u08* addr)
{
	asm volatile ("movw r30,r24");
	asm volatile ("LPM  r24,Z+");
	asm volatile ("LPM  r25,Z");
	return addr;
}

#define SONGS_D	0
#define MENU_D	1

u16 browse_list(u16 index, u16 min, u16 max, u08 func)
{
	u08 i,j = 0;
	event_e event;
	while (1)
	{
		for (i=0; i < 2 + 2*func; i++)
		{
			if (func)
			{
				lcd_clrline(1 + i);
				if (index+i < max)
				{
					lcd_putchar((i==j) ? 0x18 : ' ');
	 				lcd_progputs(PRG_RDW((u08*)&function_name[index+i]));	// menu print on LCD
				}
			}
			else
			{
				lcd_clrline(2 + 2*i);
				lcd_clrline(1 + 2*i);
				if (index+i < max)
				{
					YADL_SONG_BASE_ENTRY *pEntry = get_song_entry(get_offset_entry(index+i));
					if( i==j )

⌨️ 快捷键说明

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