📄 usb_drv.c
字号:
#include "usb_cfg.h"
#include "usb_def.h"
#include "usb_reg.h"
#include "at89x52.h"
#include "stdio.h"
#include "disk_cfg.h"
#include "INTRINS.H"
#define nop _nop_()
#define uint unsigned int
#define uchar unsigned char
/*_____ M A C R O S ________________________________________________________*/
#define FLUSHTX0 {write_usb(TXC0,FLUSH);}
/* Flush and disable the USB TX1 **************************************/
#define FLUSHTX1 {write_usb(TXC1,FLUSH);}
/* Flush and disable the USB TX2 **************************************/
#define FLUSHTX2 {write_usb(TXC2,FLUSH);}
/* Flush and disable the USB TX3 **************************************/
#define FLUSHTX3 {write_usb(TXC3,FLUSH);}
/* Flush and disable the USB RX0 **************************************/
#define FLUSHRX0 {write_usb(RXC0,FLUSH);}
/* Flush and disable the USB RX1 **************************************/
#define FLUSHRX1 {write_usb(RXC1,FLUSH);}
/* Flush and disable the USB RX2 **************************************/
#define FLUSHRX2 {write_usb(RXC2,FLUSH);}
/* Flush and disable the USB RX3 **************************************/
#define FLUSHRX3 {write_usb(RXC3,FLUSH);}
/* Send data to TXD0 ****************************/
#define send_desc_to_TXD0 \
for(desc_idx=0;desc_idx<EP_CONTROL_LENGTH&&desc_idx<data_to_transfer;desc_idx++) \
{ \
TXD0=*pbuffer++; \
} \
if(data_to_transfer>EP_CONTROL_LENGTH) \
{ \
data_to_transfer-=EP_CONTROL_LENGTH; \
} \
else \
{ \
data_to_transfer=0; \
} \
/* store the status byte in FIFO0 for the chosen endpoint *************/
#define EPSTATUS(ep) \
case ep: \
if (stalled^(1<<ep)) write_usb(TXD0,1); else write_usb(TXD0,0);\
break;
/* enable TX0, using the appropriate DATA PID *************************/
#define TXEN0_PID \
{ if(dta_pid0) write_usb(TXC0,TX_TOGL+TX_EN); /*DATA1*/\
else write_usb(TXC0,TX_EN); /*DATA0*/\
dta_pid0=!dta_pid0;}
/* enable TX1, using the appropriate DATA PID, but not toggling it ****/
#define TXEN1_PID_NO_TGL \
{ if(dta_pid1) write_usb(TXC1,TX_TOGL+TX_LAST+TX_EN); /*DATA1*/\
else write_usb(TXC1,TX_LAST+TX_EN); } /*DATA0*/
#define TXEN1_PID \
{ TXEN1_PID_NO_TGL; \
dta_pid1=!dta_pid1;}
/* enable TX2, using the appropriate DATA PID, but not toggling it ****/
#define TXEN2_PID_NO_TGL \
{ if(dta_pid2) write_usb(TXC2,TX_TOGL+TX_LAST+TX_EN); /*DATA1*/\
else write_usb(TXC2,TX_LAST+TX_EN); } /*DATA0*/
#define TXEN2_PID \
{ TXEN2_PID_NO_TGL; \
dta_pid2=!dta_pid2;}
/* enable TX3, using the appropriate DATA PID, but not toggling it ****/
#define TXEN3_PID_NO_TGL \
{ if(dta_pid3) write_usb(TXC3,TX_TOGL+TX_LAST+TX_EN); /*DATA1*/\
else write_usb(TXC3,TX_LAST+TX_EN); } /*DATA0*/
#define TXEN3_PID \
{ TXEN3_PID_NO_TGL; \
dta_pid3=!dta_pid3;}
#define write_usb(USB_REG,i) USB_REG=i
#define read_usb(USB_REG) USB_REG
/*Fuction declare*******************************/
extern void DelaymS(uint i);
void rx_0();
void rx_1();
void rx_2();
void rx_3();
void tx_0();
void tx_1();
void tx_2();
void tx_3();
void usb_alt();
void nak0();
void nakO1();
void nakI1();
void nak2();
void nak3();
void usb_get_descriptor();
void usb_set_configuration();
void usb_clear_feature();
void usb_set_feature();
void usb_get_status();
void usb_mass_storage_get_lun();
void usb_mass_storage_reset();
/*global ver define *********************/
uchar rxstat;
uchar txstat;
uchar desc_idx;
uchar evnt;
uchar usb_buf[64];
char bdata dtapid; /* PID related status*/
sbit dta_pid0= dtapid^0;
sbit dta_pid1= dtapid^1;
sbit dta_pid2= dtapid^2;
sbit dta_pid3= dtapid^3;
char bdata stalled; /* indicate the stall status of endpoints0-6 */
sbit stall_ep0 = stalled^0;
sbit stall_ep1 = stalled^1;
sbit stall_ep2 = stalled^2;
sbit stall_ep3 = stalled^3;
sbit stall_ep4 = stalled^4;
sbit stall_ep5 = stalled^5;
sbit stall_ep6 = stalled^6;
uchar bmRequestType;
uchar bmRequest;
uchar data_to_transfer;
uchar code *pbuffer;
uchar zero_packet_flag;
uchar usb_cfg;
uchar flag;
void usb_init()
{
usb_cfg=0;
data_to_transfer=0;
pbuffer=NULL;
zero_packet_flag=FALSE;
RST=0;
DelaymS(100);
RST=1;
DelaymS(100);
write_usb(MCNTRL,SRST); //reset
while( read_usb(MCNTRL) & SRST);//wait for reset finish
write_usb(MCNTRL,INT_L_P + VGE );//power on 3.3V
write_usb(MAMSK, 0); // disable all ints
/*set up interrupt masks ****************************************/
write_usb(NAKMSK,NAK_O0+NAK_O1+NAK_I1); /*NAK evnts*/
write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3); /*TX events*/
write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3); /*RX events*/
//write_usb(ALTMSK,SD3+RESET_A); /*ALT evnts*/
/*this is modified in the */
/*suspend-resume routines */
/*so if any change is made*/
/*here it needs to be ref-*/
/*lected there too. */
write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
write_usb(DMAMASK, 0);
/*set default address, enable EP0 only **************************/
write_usb(FAR,AD_EN+0);
write_usb(EPC0, 0x00);
/*enable the receiver and go operational ************************/
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*enable the receiver */
write_usb(NFSR,OPR_ST); /*go operational */
write_usb(MCNTRL,INT_L_P+NAT+VGE); /*set NODE ATTACH */
}
void usb_isr()interrupt 0
{
evnt=read_usb(MAEV);
if (evnt & RX_EV)
{
evnt=read_usb(RXEV); /*check the RX events */
if (evnt&RXFIFO0) rx_0(); /*endpoint 0 */
else if (evnt&RXFIFO1) rx_1(); /*endpoint 2 */
else if (evnt&RXFIFO2) rx_2(); /*endpoint 4 */
else if (evnt&RXFIFO3) rx_3(); /*endpoint 6 */
else /*some other RX event */
{
}
}
else if (evnt & TX_EV)
{
evnt=read_usb(TXEV); /*check the TX events */
if (evnt&TXFIFO0) tx_0(); /*endpoint 0 */
else if (evnt&TXFIFO1) tx_1(); /*endpoint 1 */
else if (evnt&TXFIFO2) tx_2(); /*endpoint 3 */
else if (evnt&TXFIFO3) tx_3(); /*endpoint 5 */
else /*some other TX event */
{
}
}
else if (evnt & ALT) usb_alt(); /*alternate event? */
else if (evnt & NAK)
{
evnt=read_usb(NAKEV); /*check the NAK events */
if (evnt & NAK_O0) nak0(); /*endpoint 0 */
else if (evnt & NAK_O1) nakO1(); /*endpoint 2 */
else if (evnt & NAK_I1) nakI1();
else if (evnt & NAK_O2) nak2(); /*endpoint 4 */
else if (evnt & NAK_O3) nak3(); /*endpoint 6 */
else /*some other TX event */
{
}
}
else /*spurious event! */
{
}
}
void rx_0()
{
rxstat=read_usb(RXS0); /*get receiver status */
/*is this a setup packet? ***************************************/
if(rxstat & SETUP_R)
{
data_to_transfer=0;
pbuffer=NULL;
zero_packet_flag=FALSE;
/*read data payload into buffer then flush/disble the RX ****/
for(desc_idx=0; desc_idx<8; desc_idx++)
{
usb_buf[desc_idx] = read_usb(RXD0);
}
FLUSHRX0; /*make sure the RX is off */
FLUSHTX0; /*make sure the TX is off */
TI=1;printf("\n");
for(desc_idx=0; desc_idx<8; desc_idx++)
{
printf("%2.2X,", (uint)usb_buf[desc_idx]);
}
bmRequestType=usb_buf[0];
bmRequest=usb_buf[1];
if ((usb_buf[0]&0x60)==0x00) /*if a standard request */
{
switch (usb_buf[1]) /*find request target */
{
case GET_STATUS:
usb_get_status();
break;
case CLEAR_FEATURE:
usb_clear_feature();
break;
case SET_FEATURE:
usb_set_feature();
break;
case SET_ADDRESS:
/*set and enable new address for endpoint 0, but set*/
/*DEF too, so new address doesn't take effect until */
/*the handshake completes */
write_usb(EPC0,DEF);
write_usb(FAR,usb_buf[2] | AD_EN);
break;
case GET_DESCRIPTOR:
usb_get_descriptor();
break;
case GET_CONFIGURATION:
write_usb(TXD0,usb_cfg);/*load the config value */
break;
case SET_CONFIGURATION:
usb_set_configuration();
break;
case GET_MAX_LUN:
write_usb(TXD0,MS_MAX_LUN);
break;
case MASS_STORAGE_RESET:
usb_mass_storage_reset();
break;
default: /*unsupported standard req*/
//write_usb(EPC0,STALL);
break;
}
}
else /*if a non-standard req. */
{
//write_usb(EPC0,STALL);
}
/*the following is done for all setup packets. Note that if*/
/*no data was stuffed into the FIFO, the result of the fol- */
/*lowing will be a zero-length response. */
dta_pid0=1; /*enable the TX (DATA1) */
TXEN0_PID;
}
/*if not a setup packet, it must be an OUT packet ***************/
else
{
if (data_to_transfer>0||zero_packet_flag==TRUE) /*get_descr status stage? */
{
/*test for errors (zero length, correct PID) */
if ((rxstat& 0x5F)!=0x10) /*length error?? */
{
}
data_to_transfer=0; /*exit get_descr mode */
zero_packet_flag=FALSE;
FLUSHTX0; /*flush TX0 and disable */
}
FLUSHRX0; /*make sure the RX is off */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
//test_b= 0;
/*we do this stuff for all rx_0 events **************************/
}
void usb_get_descriptor()
{
uchar string_type;
uchar descriptor_type;
uchar wLength;
data_to_transfer=0;
pbuffer=NULL;
zero_packet_flag=FALSE;
string_type = usb_buf[2]; /* read LSB of wValue */
descriptor_type = usb_buf[3]; /* read MSB of wValue */
wLength=usb_buf[6];
switch (descriptor_type)
{
case DEVICE:
data_to_transfer = sizeof (usb_device_descriptor);
pbuffer = &(usb_device_descriptor.bLength);
break;
case CONFIGURATION:
data_to_transfer = sizeof (usb_configuration);
pbuffer = &(usb_configuration.cfg.bLength);
break;
case STRING:
switch (string_type)
{
case LANG_ID:
data_to_transfer = sizeof (usb_language);
pbuffer = &(usb_language.bLength);
break;
case MAN_INDEX:
data_to_transfer = sizeof (usb_manufacturer);
pbuffer = &(usb_manufacturer.bLength);
break;
case PROD_INDEX:
data_to_transfer = sizeof (usb_product);
pbuffer = &(usb_product.bLength);
break;
case SN_INDEX:
data_to_transfer = sizeof (usb_serial_number);
pbuffer = &(usb_serial_number.bLength);
break;
default:
//write_usb(EPC0,STALL);
break;
}
default:
//write_usb(EPC0,STALL);
break;
}
if(wLength>data_to_transfer)
{
if((data_to_transfer % EP_CONTROL_LENGTH) == 0)
{
zero_packet_flag=TRUE;
}
else
{
zero_packet_flag=FALSE;
}
}
else
{
data_to_transfer=wLength;
}
send_desc_to_TXD0;
}
void usb_set_configuration()
{
usb_cfg = usb_buf[2]; /*set the configuration # */
if (usb_cfg>0) /*set the configuration */
{
dtapid = 0; /*FIRST PID is DATA0 */
stalled = 0; /*nothing stalled */
dta_pid1=1;
FLUSHTX1; /*flush TX1 and disable */
write_usb(EPC1,EP_EN+01); /*enable EP1 at adr 1 */
FLUSHRX1; /*flush RX1 and disable */
write_usb(EPC2,EP_EN+02); /*enable EP2 at adr 2 */
write_usb(RXC1,RX_EN); /*enable RX1 */
FLUSHTX2; /*flush TX1 and disable */
write_usb(EPC3,EP_EN+03); /*enable EP1 at adr 1 */
FLUSHRX2; /*flush RX1 and disable */
write_usb(EPC4,EP_EN+04); /*enable EP2 at adr 2 */
write_usb(RXC2,RX_EN); /*enable RX1 */
FLUSHTX3; /*flush TX1 and disable */
write_usb(EPC5,EP_EN+05); /*enable EP1 at adr 1 */
FLUSHRX3; /*flush RX1 and disable */
write_usb(EPC6,EP_EN+06); /*enable EP2 at adr 2 */
write_usb(RXC3,RX_EN); /*enable RX1 */
}
else /*unconfigure the device */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -