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

📄 vs1011e_v1_01.c

📁 LPC2300 MP3 Player code
💻 C
字号:
#include "app_config.h"

//SCI Registers
#define VS_SCI_MODE		0x00	//RW	Mode control
#define VS_SCI_STATUS	0x01	//RW	Status
#define VS_SCI_BASS		0x02	//RW	Built-in bass enhancer
#define VS_SCI_CLOCKF	0x03	//RW	Clock freq+doubler
#define VS_SCI_DEC_TIME	0x04	//R		Decode time in seconds 
#define VS_SCI_AUDATA	0x05	//RW	Misc. audio data
#define VS_SCI_WRAM		0x06	//RW	RAM write
#define VS_SCI_WRAMADDR	0x07	//RW	Base address for RAM write
#define VS_SCI_HDAT0	0x08	//R		Stream header data 0
#define VS_SCI_HDAT1	0x09	//R		Stream header data 1
#define VS_SCI_AIADDR	0x0A	//RW	Start address of application
#define VS_SCI_VOL		0x0B	//RW	Volume control
#define VS_SCI_AICTRL0	0x0C	//RW	Application control register 0
#define VS_SCI_AICTR11	0x0D	//RW	Application control register 1
#define VS_SCI_AICTRL2	0x0E	//RW	Application control register 2
#define VS_SCI_AICTRL3	0x0F	//RW	Application control register 3

#define VS_INS_WRITE	0x02
#define VS_INS_READ		0x03

#define VS_SPI_WIDTH	8

#ifndef VS_SPI_CLK_DIV
#define VS_SPI_CLK_DIV	8
#endif

#define VSSPIInit()		SPIMasterEnable(VS_SPI,SPI_RIS_FIRST,SPI_SAM_FIRST,VS_SPI_CLK_DIV,0,0,VS_SPI_WIDTH - 1); 

typedef enum
{
	MP3_FLAG_NULL = 0,
	MP3_FLAG_START,
	MP3_FLAG_NORMAL,
	MP3_FLAG_STOP,
	MP3_FLAG_JUMP,
	MP3_FLAG_PAUSE,
	MP3_FLAG_MUTE,
	MP3_FLAG_NEXT
} mp3_flag_t;

mp3_flag_t mp3_flag = MP3_FLAG_NULL;

extern void delay_1ms(unsigned int n);

void VSSCITransfer(unsigned int len, unsigned char *spi_buf);
void VSSCIWrite(unsigned char ad, unsigned short data);
unsigned short VSSCIRead(unsigned char ad);

char mp3_file_name[128];
unsigned char mp3_buf[MP3_LOAD_SIZE];
unsigned int mp3_buf_p;
File mp3_file;
DirList mp3_list;
char mp3_dir[128];

extern EmbeddedFileSystem efs;
extern DirList list;
extern char current_dir[128];

unsigned char file_end = 0;
unsigned char vol_l = 80;
unsigned char vol_r = 80;

unsigned long audio_buf_address = 0;
unsigned char playing_flag = 0;
unsigned char play_all = 0;
unsigned char jump_percent = 0;

//void VSSDITransfer(unsigned int len, unsigned char *spi_buf);

void VSReset(void)
{
	Clrb(VS_RST_PRTC,VS_RST_PIN);
	delay_1ms(500);
	Setb(VS_RST_PRTS,VS_RST_PIN);
	delay_1ms(100);
}

void VSInit(void)
{
	unsigned char spi_buf[4];
	spi_buf[0] = 0;
	spi_buf[1] = 0;
	spi_buf[2] = 0;
	spi_buf[3] = 0;

	Orb(VS_CS_DPRT,VS_CS_PIN);
	Setb(VS_CS_PRTS,VS_CS_PIN);
	Orb(VS_RST_DPRT,VS_RST_PIN);
	Clrb(VS_RST_PRTC,VS_RST_PIN);
	Orb(VS_DCS_DPRT,VS_DCS_PIN);
	Setb(VS_DCS_PRTS,VS_DCS_PIN);

	VSReset();

	VSSCIWrite(VS_SCI_MODE,0x0804); //soft reset, set to new mode and disable layer 1-2
	delay_1ms(1);
	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
	//VSSCIWrite(VS_SCI_CLOCKF,); //set if the clock is other than 24.576MHz
	//delay_1ms(1);
	//while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
	VSAudioSetVolume(vol_l,vol_r);

	if ((VSSCIRead(VS_SCI_STATUS) >> 4) == 2)
	{
		saystr("\r\nVS1011E found\r\n");
	}
	else
	{
		saystr("\r\nVS1011E not found\r\n");
	}

	VSSDITransfer(4,spi_buf);

}

void VSSCITransfer(unsigned int len, unsigned char *spi_buf)
{
	VSSPIInit();
	
	Clrb(VS_CS_PRTC,VS_CS_PIN);
	
	SPIMasterTransfer2(VS_SPI,len,spi_buf);
	
	Setb(VS_CS_PRTS,VS_CS_PIN);
	
	SPIMasterDisable(VS_SPI);
}

void VSSCIWrite(unsigned char ad, unsigned short data)
{
	unsigned char spi_buf[4];
	spi_buf[0] = VS_INS_WRITE;
	spi_buf[1] = ad;
	spi_buf[2] = data >> 8;
	spi_buf[3] = data;

	VSSCITransfer(4,spi_buf);
}

unsigned short VSSCIRead(unsigned char ad)
{
	unsigned char spi_buf[4];
	unsigned short data = 0x00;

	spi_buf[0] = VS_INS_READ;
	spi_buf[1] = ad;

	VSSCITransfer(4,spi_buf);

	data = spi_buf[2] << 8;
	data |= spi_buf[3];

	return (data);
}

void VSSDITransfer(unsigned int len, unsigned char *spi_buf)
{
	VSSPIInit();
	
	Clrb(VS_DCS_PRTC,VS_DCS_PIN);
	
	SPIMasterTransfer2(VS_SPI,len,spi_buf);
	
	Setb(VS_DCS_PRTS,VS_DCS_PIN);
	
	SPIMasterDisable(VS_SPI);
}

void VSSineTest(void)
{
	unsigned char spi_buf[8];

	spi_buf[0] = 0x53;
	spi_buf[1] = 0xEF;
	spi_buf[2] = 0x6E;
	spi_buf[3] = 126; //5168 Hz
	spi_buf[4] = 0x00;
	spi_buf[5] = 0x00;
	spi_buf[6] = 0x00;
	spi_buf[7] = 0x00;

	VSSCIWrite(VS_SCI_MODE,0x0820); //enable SDI tests
	delay_1ms(1);
	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));

	VSSDITransfer(8, spi_buf);

	delay_1ms(500);

	spi_buf[0] = 0x45;
	spi_buf[1] = 0x78;
	spi_buf[2] = 0x69;
	spi_buf[3] = 0x74;
	spi_buf[4] = 0x00;
	spi_buf[5] = 0x00;
	spi_buf[6] = 0x00;
	spi_buf[7] = 0x00;

	VSSDITransfer(8, spi_buf);

	VSSCIWrite(VS_SCI_MODE,0x0800); //disable SDI tests
}

void VSAudioPlayAll(char *dir_name)
{
	unsigned char i = 0;

	while (dir_name[i])
	{
		mp3_dir[i] = dir_name[i];
		i++;
	}
	mp3_dir[i] = 0;

	if (ls_openDir(&mp3_list, &(efs.myFs) , mp3_dir) != 0)
	{
		return;
	}

	mp3_flag = MP3_FLAG_NEXT;
	playing_flag = 1;
	play_all = 1;
}

void VSAudioPlay(char *file_name, char *dir_name)
{
	unsigned char i = 0;
	unsigned char j = 0;

	while (dir_name[i]) //search for \0
	{
		mp3_file_name[i] = dir_name[i];
		mp3_dir[i] = dir_name[i];
		i++;
	}
	mp3_dir[i] = 0;

	if (i > 1) //file in root don't need '/'
	{
		mp3_file_name[i] = '/';
		i++;
	}
	else
	{
		i = 0;
	}

	while (file_name[j])
	{
		mp3_file_name[i] = file_name[j];
		i++;
		j++;
	}
	mp3_file_name[i] = 0;

	mp3_flag = MP3_FLAG_START;
	playing_flag = 1;
}

void VSAudioSend(void)
{
	unsigned int res;
	while (Rdb(VS_DREQ_PINP,VS_DREQ_PIN) && (mp3_buf_p < MP3_LOAD_SIZE))
	{
		VSSDITransfer(16,mp3_buf+mp3_buf_p);
		mp3_buf_p += 16;
	}
	if (mp3_buf_p >= MP3_LOAD_SIZE)
	{
		mp3_buf_p = 0;
		if (!file_end)
		{
			SDSPIInit();
			res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
			if (res != MP3_LOAD_SIZE)
			{
				file_end = 1;	
			}
		}
		else
		{
			mp3_flag = MP3_FLAG_STOP;
		}
	}
	while (Rdb(VS_DREQ_PINP,VS_DREQ_PIN) && (mp3_buf_p < MP3_LOAD_SIZE))
	{
		VSSDITransfer(16,mp3_buf+mp3_buf_p);
		mp3_buf_p += 16;
	}
}

void VSAudioTask(void)
{
	char next_file_name[LIST_MAXLENFILENAME];
	unsigned char i;
	unsigned int res;
	unsigned long buf;
	if (playing_flag)
	{
		switch (mp3_flag)
		{
			case MP3_FLAG_START :
				AppSDInit();
				res = file_fopen(&mp3_file, &efs.myFs, mp3_file_name, 'r');
				if (res != 0)
				{
					mp3_flag = MP3_FLAG_STOP;
				}
				else
				{
					mp3_buf_p = 0;
					mp3_flag = MP3_FLAG_NULL;
					file_end = 0;
					res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
					VSAudioSend();
				}
				break;
			case MP3_FLAG_STOP :
				file_fclose(&mp3_file);
				if (play_all)
				{
					mp3_flag = MP3_FLAG_NEXT;
				}
				else
				{
					fs_umount(&efs.myFs);
					playing_flag = 0;
					mp3_flag = MP3_FLAG_NULL;
				}
				break;
			case MP3_FLAG_JUMP :
				SDSPIInit();
				file_fclose(&mp3_file);
				res = file_fopen(&mp3_file, &efs.myFs, mp3_file_name, 'r');
				if (res != 0)
				{
					mp3_flag = MP3_FLAG_STOP;
				}
				else
				{
					buf = (mp3_file.FileSize*jump_percent)/100; //get jump size
					mp3_file.FilePtr = buf;
					mp3_buf_p = 0;
					mp3_flag = MP3_FLAG_NULL;
					file_end = 0;
					res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
					VSAudioSend();
				}
				break;
			case MP3_FLAG_PAUSE :
				break;
			case MP3_FLAG_MUTE :
				VSAudioSend();
				break;
			case MP3_FLAG_NEXT :
				SDSPIInit();
				file_fclose(&mp3_file);
				res = ls_getNext(&mp3_list);
				if (res == 0)
				{
					mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-1] = '\0';
					if (((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-4]) == 'M') &&
						((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-3]) == 'P') &&
						((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-2]) == '3'))
					{
						i = 0;
						while (mp3_list.currentEntry.FileName[i] != ' ')
						{
							next_file_name[i] = mp3_list.currentEntry.FileName[i];
							i++;
							if(i==8) //File name=8;
								break;
						}
						next_file_name[i] = '.';
						i++;
						next_file_name[i] = 'M';
						i++;
						next_file_name[i] = 'P';
						i++;
						next_file_name[i] = '3';
						i++;
						next_file_name[i] = 0;

						VSAudioPlay(next_file_name,mp3_dir);
						//saystr(mp3_list.currentEntry.FileName);
						//mp3_flag = MP3_FLAG_STOP;
					}

				}				
				else
				{
					if (ls_openDir(&mp3_list, &(efs.myFs) , mp3_dir) != 0)
					{
						mp3_flag = MP3_FLAG_STOP;
					}
				}
				break;
			default :
				VSAudioSend();
				break;
		}
	}
}

void VSAudioCmd(char cmd, unsigned char para)
{
	if (!playing_flag)
	{
		saystr("\r\nNo playing file\r\n");
		return;
	}
	switch (cmd)
	{
		case 'N' : //Next
			mp3_flag = MP3_FLAG_NEXT;
			break;
		case 'S' : //Stop
			mp3_flag = MP3_FLAG_STOP;
			play_all = 0;
			break;
		case 'J' : //Jump
			mp3_flag = MP3_FLAG_JUMP;
			jump_percent = para;
			if (jump_percent > 99)
				jump_percent = 99;
			break;
		case 'P' : //Pause
			mp3_flag = MP3_FLAG_PAUSE;
			break;
		case 'C' : //Continue
			mp3_flag = MP3_FLAG_NULL;
			break;
		case 'M' : //Mute
			VSSCIWrite(VS_SCI_VOL,0xFEFE);
			delay_1ms(1);
			while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
			break;
		case 'L' : //sound enable
			VSAudioSetVolume(vol_l,vol_r);
			break;
		case 'U' : //volume Up
			VSAudioSetVolume(vol_l+5,vol_r+5);
			break;
		case 'D' : //volume Down
			VSAudioSetVolume(vol_l-5,vol_r-5);
			break;
		case 'V' : //set Volume
			if (para > 99)
				para = 99;
			VSAudioSetVolume(para,para);
			break;
	}
}

void VSAudioSetVolume(unsigned char new_vol_l, unsigned char new_vol_r)
{
	unsigned short buf;
	vol_l = new_vol_l;
	vol_r = new_vol_r;

	buf = 0xFE - (vol_l << 8)/100;
	buf = buf << 8;
	buf |= 0xFE - (vol_r << 8)/100;
		
	VSSCIWrite(VS_SCI_VOL,buf); //decrese 32 dB for both left and right
	delay_1ms(1);
	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
}

void VSTest(void)
{
	VSSineTest();
}

unsigned char VSIsPlaying(void)
{
	return (playing_flag);
}

unsigned char VSGetTrackPosition(void)
{
	unsigned long current_ptr,file_size;

	file_size = mp3_file.FileSize >> 10; //divide with 1KB
	current_ptr = mp3_file.FilePtr >> 10; //divide with 1KB

	return (current_ptr*100/file_size);
}

⌨️ 快捷键说明

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