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

📄 32musb.c

📁 这个是一个完整的MP3项目
💻 C
字号:
/*
* Copyright (c) 2004,北京博创兴业科技有限公司
* All rights reserved.
* 
* 文件名称:32MUSB.c
* 文件标识:32MUSB
* 摘    要:主函数
* 
* 当前版本:2.0
* 作    者:Kent
* 完成日期:2004年5月20日
*
* 取代版本:1.1 
* 原作者  :Frank
* 完成日期:2003年8月10日
*/

#include "REGSND1.H"
#include "atmelusbci.h"
#include "uart.h"
#include "usbdisk.h"
#include "bulk_only.h"
#include "fat16.h"
#include "flash.h"

//int m=0;
extern unsigned char bulk_CSW[];
extern unsigned char bulk_state;//记录USB传输过程中传输状态
//extern unsigned char Bulk_Out_Buf[];//Bulk-Out端点缓存区
extern unsigned char Page_Buf[];//页(扇区)缓存区 
extern unsigned char FirstTransaction;
extern unsigned char *BulkPoint;
extern unsigned char *BulkStartPoint;
//设备描述符
code unsigned char Device_Descriptor[18] = {
								    	 0x12,			//0x12
										 0x01,              //DEVICE descriptor
										 0x10, 0x01,         //spec rev level (BCD) 1.0
										 0x0,              //device class
										 0x0,              //device subclass
										 0x0,              //device protocol
										 0x20,              //max packet size
										 0x05, 0x82,         //National's vendor ID
										 0x00, 0x11,         //National's product ID  
										 0x00, 0x00,         //National's revision ID  
										 0,                 //index of manuf. string   
										 0,                 //index of prod.  string  
										 0,                 //index of ser. # string   
										 0x01               //number of configs. 	
									};
//配置描述符
code unsigned char Configuration_Descriptor_All[32] = {

									    9,//Size of Descriptor in Bytes
									    2,//Configuration Descriptor (0x02)
									    0x20,//Total length in bytes of data returned  LSB
										0x00,//MSB
										1,//Number of Interfaces
										1,//Value to use as an argument to select this configuration
									    0,//Index of String Descriptor describing this configuration
										0x80,
										0xfa,//Maximum Power Consumption in 2mA units 
									
									    9,
									    4,
									    0,//the index of the interface descriptor Number of Interface
									    0,//Value used to select alternative setting
										2,//EndPoint Number Used in this Descriptor
										8,//Class Code (Assigned by USB Org)
										6,	//interface subclass1=RBC,2=SFF,3=QIC,4=UFI,5=SFF,6=SCSI
										0x50,//bulk 0nly Transport
										0,//Index of String Descriptor Describing this interface

										 //Bulk-in Endpoint
										 0x07,              //length of this desc.   
										 0x05,              //ENDPOINT descriptor TYPE
										 0x81,              //address (IN) Endpoint 4 84
										 0x02,              //attributes  (BULK)    
										 0x40, 0x00,         //max packet size (64)
										 0x0,              //Does not apply to Bulk endpoints
							
										 //Bulk-out Endpoint
										 0x07,              //length of this desc.   
										 0x05,              //ENDPOINT descriptor TYPE
										 0x02,              //address (OUT) Endpoint 5 05
										 0x02,              //attributes  (BULK)
										 0x40, 0x00,         //max packet size (64)
										 0x0             //Does not apply to Bulk endpoints
										};

//用于存放歌曲列表的数组
unsigned char SONG[88] = {'M', 'O', 'O', 'N', ' ', ' ', ' ', ' ', 'T', 'X', 'T'};

//MP3有关的变量*********************
#define VOLUME		1
#define EFFECTION	2
#define SELECTSONG	3
#define PLAY		1
#define STOP		0
unsigned char CurrentFun = SELECTSONG;
unsigned char PlayState = STOP;
unsigned char ChangeSong = 0;

unsigned char NowPlaying = 0;
unsigned char NumofSong = 0;
extern long int DataRead;
//***************************

//USB DISK 
//读端点数据
unsigned char ReadEp(unsigned char EpNum, unsigned char *Data)
{
	unsigned char i = 0, nLength;
	UEPNUM = EpNum;//指向相应端点
	BulkStartPoint = Data;
	nLength = UBYCTX;//读取端点数据长度

	while (nLength--) 
	{ 
		if (UEPNUM == 2) 
		{
			*(BulkPoint++) = UEPDATX;
			i++;
		}
		else
		{
			Data[i++] = UEPDATX;//*printuf("%x ",Data[i]);*/}//依次读取端点收到的数据
		}
	}

	UEPSTAX &= ~(RXOUTB0 | RXOUTB1 | RXSETUP);//清中断标志
	return (i);//返回读取到的数据的长度
}

//向端点0写数据
void WriteEp(unsigned char EpNum, unsigned char nLength, unsigned char *Data)
{
	unsigned char i=0;

	UEPNUM = EpNum;//指向相应端点
	UEPSTAX |= DIR;//设置方向为写

	while (nLength--) 
	{
		UEPDATX = Data[i++];//将数据写入端点
	}

	UEPSTAX |= TXRDY;//发送数据Sending the data,this action will switch between bank0 and bank1

	while (!(UEPSTAX & TXCMP)) ;//等待发送完成

	UEPSTAX &= (~(TXCMP));//清中断标志clear TXCMP
}

//写Bulk端点
void WriteEpBulk(unsigned char EpNum, unsigned char nLength, unsigned char *Data)
{
	unsigned char i;

	UEPNUM = EpNum;//指向相应端点
	UEPSTAX |= DIR;//设置方向为写Set for status of a Control In transaction

	for (i=0; i<nLength; i++) 
	{
		UEPDATX = Data[i];//将数据写入端点
	}

	UEPSTAX |= TXRDY;//发送数据Sending the data,this action will switch between bank0 and bank1
	
}

void Get_Status()
{
	printu("Get_Status");
} 

void Clear_Feature()
{
	printu("Clear_Feature");
}

void Set_Feature()
{
	printu("Set_Feature");
} 

void Set_Address(unsigned char EpNum)
{
//	unsigned char Test[] = {0};
	WriteEp(0, 0, 0);//在Status阶段过后才能改变设备地址

	USBADDR |= EpNum;//设置地址
	USBADDR |= FEN;//地址使能
	USBCON |= FADDEN;

//	printuf("\nSet_Address : %x\n", USBADDR);
} 

void Get_Descriptor(unsigned char DesType, unsigned char nLength)
{
	if (DesType == 0x01) 
	{
		WriteEp(0, 18, Device_Descriptor);//提供设备描述符
	}
	if ((DesType == 0x02) && (nLength == 0x09))
	{
		WriteEp(0, 9, Configuration_Descriptor_All);//提供配置描述符
	}
	//提供全部描述符
	if ((DesType == 0x02) && (nLength == 0xff)) 
	{ 
		WriteEp(0, 32, Configuration_Descriptor_All);
		WriteEp(0, 2, &Device_Descriptor[4]);
	}
	//提供全部描述符
	if ((DesType == 0x02) && (nLength == 0x20))
	{
		WriteEp(0, 32, Configuration_Descriptor_All);
	}

//		printu("Get_Descriptor\n");
}

void Get_Configuration()
{
	printu("Get_Configuration");
}

void Set_Configuration(unsigned char wValue)
{

	if (wValue == 0) 
	{
	/* put device in unconfigured state */
		 /* Disable all endpoints but EPP0. *///init_unconfig

 		UEPNUM = 0x00;//Ep0 as control Endpoint
		UEPCONX = 0x80;
	
		UEPNUM = 0x01;//Ep1 as Bulk-in Endpoint
		UEPCONX = 0x86;
	
		UEPNUM = 0x02;//Ep2 as Bulk-out Endpoint
		UEPCONX = 0x82;

//		WriteEp(0, &Device_Descriptor[4], 2);
		USBCON &= (~CONFG);
		WriteEp(0, 0, 0);//状态传送阶段之前完成指定操作

	}
	else if (wValue == 1) {
	/* Configure device */
		/* Enable generic/iso endpoints. init_config*/

		UEPNUM = 0x00;//Ep0 as control Endpoint
		UEPCONX = 0x80;
	
		UEPNUM = 0x01;//Ep1 as Bulk-in Endpoint
		UEPCONX = 0x86;
	
		UEPNUM = 0x02;//Ep2 as Bulk-out Endpoint
		UEPCONX = 0x82;


		USBCON |= CONFG;
		WriteEp(0, 0, 0);//状态传送阶段之前完成指定操作

	}
//	printu("Set_Configuration ");
}

void Get_Interface()
{
	printu("Get_Interface");
}

void Set_Interface()
{
	WriteEp(0, 0, 0);
	printu("Set_Interface ");
}

void Ep0Int()
{
	unsigned char i, j;
	unsigned char ControlData[32] = {0, };

	i = ReadEp(0, ControlData);//读端点0
	P3_5 = 0;//USB通信指示灯点亮
	j = ControlData[0] & 0x60;//过滤端点0数据
	if ((j == 0) && i)
	{//如果为标准USB请求
		switch (ControlData[1])
		{//分别按请求类别进行处理
			case get_status			:	Get_Status(); break;
			case clear_feature 		:	Clear_Feature(); break;

			case set_feature		:	Set_Feature(); break;

			case set_address		:	Set_Address(ControlData[2]); break;
			case get_descriptor		:	Get_Descriptor(ControlData[3], ControlData[6]); break;

			case get_configuration	:	Get_Configuration(); break;
			case set_configuration	:	Set_Configuration(ControlData[2]); break;
			case get_interface		:	Get_Interface(); break;
			case set_interface		:	Set_Interface(); break;
			default					:	Reserved(); break;
		}
	}
	else if (ControlData[0] == 0xa1)
	{//特殊请求,特殊处理,直接返回Status
		WriteEp(0, 0, 0);
	}
	
	P3_5 = 1;//USB通信指示灯关闭

}

//Bulk-In端点处理
void main_txdone()
{
	unsigned char i;

//	printuf("Bulk_State : %x\n", bulk_state);
	P3_5 = 0;////USB通信指示灯点亮

	UEPSTAX &= (~(TXCMP));//清中断标志位clear TXCMP
	switch (bulk_state)
	{//按不同的传输状态,进行不同的后续处理
		case BULK_DATA_TRANS :
			TransDataGoOn();
			break;
		case BULK_DATA_END :
			UEPNUM = 1;//指向相应端点
			UEPSTAX |= DIR;//设置方向为写Set for status of a Control In transaction

			for (i=0; i<13; i++) 
			{
				UEPDATX = bulk_CSW[i];//将数据写入端点
			}

			UEPSTAX |= TXRDY;//发送数据Sending the data,this action will switch between bank0 and bank1
	
			bulk_state = BULK_CSW_END;					//置传输状态。

			break;
		case BULK_REQEST_TRANS :
			TransRequestGoOn();
			break;
		case BULK_CSW_END :
			break;
		default :	return;
	}

	P3_5 = 1;//USB通信指示灯关闭
}

//Bulk-Out端点处理
void main_rxdone()
{

	unsigned char nLength;
//	printu("\nmain_rxdone ");
//	P3_5 = 0;//USB通信指示灯点亮
	//ReadEp(2, Bulk_Out_Buf);//读取端点2
//	ReadEp(2, BulkPoint);//读取端点2


	UEPNUM = 2;//指向相应端点
	BulkStartPoint = BulkPoint;
	nLength = UBYCTX;//读取端点数据长度

	while (nLength--)
	{
		*(BulkPoint++) = UEPDATX;
	}
					
//	UEPSTAX &= ~(RXOUTB0 | RXOUTB1 | RXSETUP);//清中断标志
	UEPSTAX &= 0xb9;//清中断标志

	//printuf("%x", *BulkStartPoint);
	if ((bulk_state != BULK_DATA_RECIEVE) && (*BulkStartPoint == 0x55)) 
	{
		InterpretCBW();//判断是否为命令数据
		BulkPoint = BulkStartPoint;
	}
	else if (BulkPoint == Page_Buf + 512)
	{
		Trans_Data2PC();//为普通数据时转向数据接收处理程序
	}
//	P3_5 = 1;//USB通信指示灯关闭

}

void Reserved()
{
	printuf("Undefined Interrupt Occured : %x\n", UEPINT);
}
//END OF USB DISK

void main()
{

//	int i, j;
	printu("UP-TECH MP3 USB Disk test!\n");
	P4_4 |= 1;//USBLED off
	P4_5 &= 0;	//P3_3=0 LCD Power off, P3_3=1 LCD Power on

	printu("Entering USB...\n");//输出进入U盘功能的信息
	AtmelUSBInit(4, 11, 0);//PLL时钟配置,
	EpEnable();//端点初始化
	UEPNUM = 0;//指向端点0
	BulkPoint = Page_Buf;

	while (1)
	{//轮询,检查相应端点是否有中断产生
		//if(){BulkPoint=Page_Buf;i=0;}
		if (UEPINT & EP1INT) 
		{
			main_txdone();//Bulk-Out端点处理
		}

		if (UEPINT & EP2INT) 
		{
			main_rxdone();//Bulk-In端点处理
		}

		if (UEPINT & EP0INT) 
		{
			Ep0Int();//端点0处理
		}
							
		UEPINT=0;//清中断状态寄存器
	}

}		


⌨️ 快捷键说明

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