📄 text2.c
字号:
#include "REGSND1.h"
#define Rdiv 11
//USB寄存器设置相关的宏定义
#define PLLRES (0x1<<3) //PLLCON
#define PLLEN (0x1<<1)
#define USBE (0x1<<7) //USBCON
#define EEOFINT (0x1<<4)
#define FEN (0x1<<7)
#define FADDEN (0x1)
#define CONFG (0x1<<1)
#define DIR (0x1<<7) //UEPSTAX
#define RXOUTB1 (0x1<<6)
#define STALLRQ (0x1<<5)
#define TXRDY (0x1<<4)
#define STLCRC (0x1<<3)
#define RXSETUP (0x1<<2)
#define RXOUTB0 (0x1<<1)
#define TXCMP (0x1<<0)
//USB 请求的bRequert的含意宏
#define get_status 0x00 //取得状态
#define clear_feature 0x01 //清除特性
#define reserved 0x02 //保留
#define set_feature 0x03 //设置特性
#define set_address 0x05 //设置地址
#define get_descriptor 0x06 //取得描述符
#define get_configuration 0x08 //取得配置
#define set_configuration 0x09 //设置配置
#define get_interface 0x0a //取得接口
#define set_interface 0x0b //设置接口
void ReadPage(unsigned int block,unsigned int page) ;
unsigned char WritePage(unsigned int block,unsigned int page) ;
unsigned char flash_era(unsigned int blok,unsigned int pge );
/**---------------------------------------------------------------------------------
----------------------------------------------------------------------------------**/
void AtmelUSBInit() //用于USB的PLL时钟20M晶振时如下设置
{
int data i;
PLLNDIV = 0x04; //设置PLL时钟
PLLCON |= (0x3&Rdiv)<<6;
PLLRDIV = (0x3ff&Rdiv)>>2;
USBCLK=0;
PLLCON&=(~PLLRES); //使能PLL
PLLCON|=PLLEN;
USBCON&=(~USBE); //关闭USB并复位USB
for(i=0;i<3000;i++); //等待PLL工作稳定
USBCON|=USBE; //开启USB控制器
}
void EpEnable(void) //初始化USB端点
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
UEPRST=0x07; UEPRST= 0x00;
UEPIEN=0x07; USBIEN|=EEOFINT;
USBADDR=FEN;
}
unsigned char ReadEp(unsigned char EpNum,unsigned char *Data) //读取端口数据
{
unsigned char data i=0;
UEPNUM=EpNum; //指端口号
while(i < UBYCTLX) //读数据到缓冲//UBYCTX得到数据长度
{
Data[i++]=UEPDATX;
}
UEPSTAX&=~(RXOUTB0|RXOUTB1|RXSETUP); //清除相关位
return(i);
}
void WriteEp(unsigned char EpNum,unsigned char nLength,unsigned char *Data) //写端口数据
{
unsigned char data i=0;
UEPNUM=EpNum; //选择端口
UEPSTAX|=DIR; //控制方向
while(nLength--) UEPDATX=Data[i++]; //写入FIFO
UEPSTAX|=TXRDY; //开始发送
while(!(UEPSTAX&TXCMP)) ;
UEPSTAX&=(~(TXCMP)); //清除TXCMP
}
//-------------以下用于对端点进行处理
void Set_Address(unsigned char EpNum) //设置USB地址1-127
{
WriteEp(0,0,0); //在Status阶段过后才能改变设备地址
USBADDR|=EpNum;
USBADDR|=FEN; //设置地址
USBCON|=FADDEN; //地址使能
}
//设备描述符
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 //recerive 500ma
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
};
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); //取配置描述符
}
void Set_Configuration(unsigned char wValue) //设置配置
{
if(wValue == 0)
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
USBCON&=(~CONFG);
WriteEp(0,0,0); //状态传送阶段之前完成指定操作
}
else if(wValue == 1)
{
UEPNUM=0x00; UEPCONX=0x80;
UEPNUM=0x01; UEPCONX=0x86;
UEPNUM=0x02; UEPCONX=0x82;
USBCON|=CONFG;
WriteEp(0,0,0); //状态传送阶段之前完成指定操作
}
}
void Ep0() //????????? //---端点0处理主函数
{
unsigned char data DT[32]={0,};
unsigned char data i;
P4_5 = 0 ;
i = ReadEp(0,DT);
if (((DT[0] & 0x60)==0) && i)
{
switch (DT[1])
{
case set_address :Set_Address(DT[2]); break; //设置地址
case get_descriptor :Get_Descriptor(DT[3],DT[6]); break; //取描述符
case set_configuration :Set_Configuration(DT[2]); break; //设置配置
default :; break;
}
}
else if(DT[0]==0xa1) //非标准USB请求
{
WriteEp(0,0,0);
}
P4_5 = 1;
}
/******************************************************************************/
/** 以下为利用Bulk_Only传输协议的函数部分 **/
/******************************************************************************/
unsigned char data bulk_CSW[]={0x55,0x53,0x42,0x53, // bytes 4 dCSWSignature
0x00,0x00,0x00,0x00, //bytes 4 dCSWTag
0x00,0x00,0x00,0x00, //bytes 4 dDataResiduce
0x00}; //bCSWStatus 00=good state.
typedef struct _STRUCT_CBW
{
unsigned char CBWCB[12]; //for UFI Command all have 12bit
} struct_CBW;
struct_CBW data bulk_CBW;
void WriteEpBulk(unsigned char EpNum,unsigned char nLength,unsigned char *Data)
{
unsigned char data i;
UEPNUM=EpNum; //---设置端点号
UEPSTAX|=DIR; //...设置为In模式
for(i=0;i<nLength;i++) UEPDATX=Data[i]; //---填缓冲区
UEPSTAX|=TXRDY; //---发送数据
}
void TransmitCSW() //向Host返回CSW
{
WriteEpBulk(1, sizeof(bulk_CSW), bulk_CSW);
while(!(UEPSTAX&TXCMP)) ;
UEPSTAX&=(~(TXCMP)); //清除TXCMP
UEPINT = 0;
}
void main_txdone() //数据发送完毕给出回复
{
UEPSTAX&=(~(TXCMP)); //清除TXCMP
TransmitCSW();
}
//////////////////////////////////有关输出端点的调用//////////////////////////////////////////////
#define Inquiry 0x12
#define Mode_Sense 0x1A
#define Read10 0x28
#define Read_Capacity 0x25
#define Read_Format_Capacities 0x23
#define Test_Unit_Ready 0x00
#define Verify 0x2F
#define Write10 0x2A
#define Medium_Removal 0x1E
#define SCSI_MSPGCD_TPP 0x1C
#define SCSI_MSPGCD_RETALL 0x3F
//SCSI-Inquiry命令的返回数据
code unsigned char B_InquiryData[] = {
0x00, //Direct Access Device
0x80, //RMB
0x00, //ISO/ECMA/ANSI
0x01, //Response Data Format
0x1f, //Additional Length
0x00, //Reserved
0x00, //Reserved
0x00, //Reserved
'U', 'E', 'S', 'T', 'C', '-', 'Z', 'H', //Vendor Information
'a', 'n', 'g', ' ', 'T', 'i', 'a', 'n', ' ', 'y', 'i',' ', 'V', '1', '.', '0', //Product Identification
0, 0, 0, 0}; //Product Revision Level n.nn
//SCSI-Read_Format_capacities命令的返回数据
code unsigned char B_Read_Format_capacities[] = {0x00, 0x00, 0x00, 0x10, //capacity list header
0x00, 0x00, 0x07, 0xf5, 0x01, 0x00, 0x02, 0x00, //capacity descriptor
//Number of Blocks =2037,unformatted media,blocklength = 512Bytes
0x00, 0x00, 0x07, 0xfd, 0x00, 0x00, 0x02, 0x00 //Formattable Capacity Descriptors
};
//SCSI-Read_Capacity命令的返回数据
code unsigned char B_Read_Capacity[] = {
0x00, 0x00, 0xfe, 0xa0, //Last Logical Block Address for 32MB
0x00, 0x00, 0x02, 0x00 //block length in bytes
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_ALL[] = {0x0b, 0x00, //Mode Data Length
0x00, 0x08, 0x00, 0x00,
0x7d, 0, 0, 0, 0x02, 0x00
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_TPP[] = {0xf0, 0x00, //Mode Data Length
05, 00, 00, 00, 00, 0x0b, 00, 00, 00, 00, 0x24, 00, 00, 00, 00, 00
};
//SCSI-Mode_Sense命令的返回数据
code unsigned char B_Mode_Sense_ZERO[] = {0x00, 0x06, //Mode Data Length
0x00, //Medium Type Code
0, //write enabled
0, 0, 0, 0 //reserved
};
void SCSI_Mode_Sense()
{
if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP) //Page Code=Timer and Potect Page
{WriteEpBulk(1, sizeof(B_Mode_Sense_TPP), B_Mode_Sense_TPP);}
else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL) //Page Code=All
{WriteEpBulk(1, sizeof(B_Mode_Sense_ALL), B_Mode_Sense_ALL);}
else {WriteEpBulk(1, sizeof(B_Mode_Sense_ZERO), B_Mode_Sense_ZERO);}
}
void SCSI_Read_Format_Capacities()
{
if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)return;
WriteEpBulk(1, sizeof(B_Read_Format_capacities), B_Read_Format_capacities);
}
extern void ReadFlash();
extern void WriteFlash();
void SCSI_Read10()
{
union
{
unsigned long Block;
unsigned char Addr[4];
}data BLK;
unsigned char length; //传输的簇数
//将起始地址变换为K9F5608适合的模式;
// BLK.Addr[0] = bulk_CBW.CBWCB[2];
// BLK.Addr[1] = bulk_CBW.CBWCB[3];
BLK.Addr[2] = bulk_CBW.CBWCB[4];
BLK.Addr[3] = bulk_CBW.CBWCB[5];
//将扇区数填入计数变量每循环一次读出一扇区的值;
// PG.Addr[0] = bulk_CBW.CBWCB[7];
// PG.Addr[1] = bulk_CBW.CBWCB[8];
length = bulk_CBW.CBWCB[8];
flash_era(length,(BLK.Addr[2]*256+BLK.Addr[3] ) );
WritePage(length,(BLK.Addr[2]*256+BLK.Addr[3] )) ;
while(length>0)
{
ReadPage( length ,((BLK.Addr[2])*(256)+BLK.Addr[3] ));
length--; //传输的簇数减1
//flash的页地址加1
}
TransmitCSW(); //返回CSW
}
void delay() //延时20us
{
unsigned char data i=20;
while(i-->0);
}
#define BuffBlock (0xc0) //缓冲区为从偶数块开始的连续两个Block 这里定为2046和2047两个Block
void main_rxdone()
{
unsigned char data i;
unsigned char data Buf[64];
i = ReadEp(2,Buf); //读出端点数据
//指示灯亮
bulk_CSW[4] = Buf[4]; bulk_CSW[5] = Buf[5]; bulk_CSW[6] = Buf[6]; bulk_CSW[7] = Buf[7];
for(i=0;i<12;i++) bulk_CBW.CBWCB[i] = Buf[i+15];
switch(bulk_CBW.CBWCB[0])
{
case Inquiry :WriteEpBulk(1,36,B_InquiryData);break;
case Mode_Sense :SCSI_Mode_Sense(); break;
case Read10 :SCSI_Read10(); break;
case Read_Capacity :WriteEpBulk(1, sizeof(B_Read_Capacity), B_Read_Capacity);break;
case Read_Format_Capacities :SCSI_Read_Format_Capacities(); break;
case Test_Unit_Ready :TransmitCSW(); break;
case Verify :TransmitCSW(); break;
// case Write10 :SCSI_Write10(); break;
case Medium_Removal :TransmitCSW(); break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -