📄 32musb.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 + -