📄 yampp7_usb.c
字号:
/************************************************************************
* 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 + -