📄 usb.c
字号:
//ep0 setup and control transfer
//ep1 bulk in
//ep2 bulk out
//Write Cycle Time for Auto Inc Mode Writes is 150 ns minimum.
//address will take effect after 85ns when address was written.
//extbank0's width was defined as 32bits
#include "vd.h"
#include "usb.h"
#define USB_ADDR_BASE 0x7fc0000
#define USB_ADDR_ADDR (*(volatile unsigned *)(USB_ADDR_BASE)) //writing pointer for instruction
#define USB_ADDR_DATA (*(volatile unsigned *)(USB_ADDR_BASE+0x4)) //writing pointer for data
#define max 8192
typedef struct
{
B8 bmRequest; // SETUP Token Protocol
B8 bRequest;
B16 wValue;
B16 wIndex;
B16 wLength;
} SetupPKG, *pSetupPKG;
extern void uartpush(char data[]);
extern B32 ltoa(B32 value,char data[],B32 radix);
void usb_init(void);
void USBReset(void);
B32 USBMemTest(void);
void USBBufRead(B8 addr, B8 *s, B8 c);
B8 USBRead(B8 addr);
void USBBufWrite(B8 addr, B8 *s, B8 c);
void USBWrite(B8 addr, B8 data);
void Delayms(B32 time);
void usb_main(void);
B16 WordSwap(B16 input);
void sl811s_init(void);
void EP0A_IN_Arm(B8 buf_adr, B8 len, B8 seq);
void EP0A_OUT_Arm(B8 len);
void EP1A_IN_Arm(B8 buf_adr, B8 len, B8 seq);
void EP2A_OUT_Arm(B8 len,B8 seq);
void ep0_isr(void);
void ep1_isr(void);
void ep2_isr(void);
void sof_isr(void);
void bufscan(void);
SetupPKG dReq; // Setup token struct
B8 Slave_USBaddr; // USB device address
B8 Slave_ConfigVal; // Device configuration value
B8 Slave_Protocol; // HID device protocol status
B8 Slave_IdleRate; // HID device idle rate value
B8 Slave_RemoteWU; // Device remote wakeup stats
B8 Slave_inEPstall; // EP0 ~ EP7's IN stall status
B8 Slave_outEPstall; // EP0 ~ EP7's OUT stall status
B8 Slave_IfcAlt[MAXIFCNUM];// 8 interface(Ep0~7) contain alternate setting value
B16 len_req; // length of data for EP0
B16 sof_cnt; // 1ms counter
B8 ep1_toggle; // EP1 DATA toggle state
B8 ep2_toggle; // EP2 DATA toggle state
B16 in_buffer_idx; // EP0 IN data buffer tracking
B8 flags; // Flag Bitmap
B8 dev_first; // status for 8-byte EP0 transfer
B8 timeout; // time out for debounce
B8 enum_done; // end of enum, (end of report descp)
B8 Toggle_SW; // Toggle switch
B8 IN_NULL; // EP0's IN null packet transmission
B8 IN_EXACT; // EP0's IN data length requested is extact of EP0_LEN
B8 BUS_POWERED; // Bus powered device
B8 UsbBuf_T[max][65]; //buffer for in data.the first byte was for the packet data numbers,0=null, max=64;
B8 UsbBuf_R[max][65]; //buffer for out data.
B8 UsbBuf_C; //buffer for control transfer,just for out from host
B8 PacketShift_T0; //0 for head,and 1 for tail
B8 PacketShift_T1;
B8 PacketShift_R0;
B8 PacketShift_R1;
B8 EP1_BUF_Full; //if 0 mean empty,else mean full
//*****************************************************************************************
// USB Basic Function
//*****************************************************************************************
void Delayms(B32 time)
{
B32 i,j;
for(j=0;j<time;j++)
for(i=0;i<10000;i++);
}
void USBWrite(B8 addr, B8 data)
{
USB_ADDR_ADDR=(B32)addr;
__asm
{
NOP
NOP
NOP
NOP
NOP
NOP
}
USB_ADDR_DATA=(B32)data;
}
void USBBufWrite(B8 addr, B8 *s, B8 c)
{
if(c==0) return;
USB_ADDR_ADDR=(B32)addr;
while (c--)
{
__asm
{
NOP
NOP
NOP
}
USB_ADDR_DATA=(B32)*s++;
}
}
B8 USBRead(B8 addr)
{
USB_ADDR_ADDR=(B32)addr;
__asm
{
NOP
NOP
NOP
NOP
NOP
NOP
}
return ((B8)USB_ADDR_DATA);
}
void USBBufRead(B8 addr, B8 *s, B8 c)
{
if(c==0) return;
USB_ADDR_ADDR=(B32)addr;
while (c--)
{
__asm
{
NOP
NOP
NOP
}
*s++ = (B8)USB_ADDR_DATA;
}
}
//*****************************************************************************************
// USB Mem Test
//*****************************************************************************************
B32 USBMemTest()
{
char data[64];
B16 errors=0,i;
uartpush("\tUSB Memory test started!\n\r ");
for (i = EP0Buf; i < cMemEnd; i++) // addr = data
USBWrite(i,i);
for (i = EP0Buf; i < cMemEnd; i++) // verify data
{
if ((B8)i!=USBRead((B8)i))
errors++;
USBWrite((B8)i, (B8)~i);
if ((B8)~i!=USBRead((B8)i))
errors++;
}
// auto increment: addr = data
for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
USB_ADDR_DATA=(B32)i;
// auto: addr = data
for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
{
if ((B8)i != (B8)USB_ADDR_DATA)
errors++;
}
// clear all SL811H/SL11H Memory
for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
USB_ADDR_DATA=0;
uartpush("\tMemory test done ,");
ltoa(errors,data,10);
uartpush(data);
uartpush(" errors was found!\n\r");
return (B32)errors; // Return number of error
}
//*****************************************************************************************
// USB Reset
//*****************************************************************************************
void USBReset()
{
B8 tmp;
uartpush("USBReset();\n\r");
tmp = USBRead(CtrlReg); // Read Control Status
USBWrite(CtrlReg,tmp|8); // Setup USB Reset
Delayms(250);
USBWrite(CtrlReg,tmp|0x18); // su suspend/resume, reset
Delayms(150);
USBWrite(CtrlReg,tmp|8); // Setup USB Reset
Delayms(10); // Delay 10 ms
USBWrite(CtrlReg,tmp); // enable USB
}
//*****************************************************************************************
//USB init to slave
//*****************************************************************************************
void usb_init()
{
B32 temp;
char data[256];
temp=EXTACON0_C;
temp=temp&0xffff0000;
temp=temp|0x00000841;
EXTACON0_C=temp; //set EXTACON0 mode--tACS1=0cycle tACC1=4cycle tCOS1=1cycle tCOH1=1cycle
uartpush("usb_init();\n\r");
temp=USBRead(0x0e);
ltoa(temp,data,16);
uartpush("##########hw_version=0x");
uartpush(data);
uartpush("\n\r");
//Write value “0x00” to register 0FH
USBWrite(0x0f,0x00);
//Memory Test
USBMemTest();
//Reset chip
USBWrite(IntEna,0x40); // enable USB Reset interrupt
USBWrite(CtrlReg,0x01); // enable USB, FullSpeed
USBWrite(IntStatus,0xFF); // clear all interrupts
/*
//USBReset();
//Disable Interrupt Enable
//Write value “0x00” to register 06H
USBWrite(0x06,0x00);
//Setup USB Address
//Write value “0x00” to register 07H
USBWrite(0x0f,0x00);
//Setup endpoint 0 address starts at 0x40
//Write value “0x40’ to register 01H
USBWrite(0x01,0x40);
//Setup transfer length of endpoint 0 //改
//Write value “0x40” to register 02H
USBWrite(0x02,0x40);
//Set Arm and direction bit
//Write value “0x03” to register 00H
USBWrite(0x00,0x03);
//Endpoint 1 Set A:
//Setup address Endpoint 1 starts at 0x60
//Write value “0x60” to register 11H
USBWrite(0x11,0x60);
//Setup endpoint 1 transfer length
//Write value “0x40” to register 12H
USBWrite(0x12,0x40);
//Set Arm and direction bit
//Write value “0x03” to register 10H
USBWrite(0x10,0x03);
//Endpoint 2 Set A and B:
//Setup Endpoint2A address starts at 0x80
//Write value “0x80” to register 21H
USBWrite(0x21,0x80);
//Setup Endpoint2B address starts at 0xC0
//Write value “0xC0” to register 29H
USBWrite(0x29,0xc0);
//Setup Endpoint2A transfer length
//Write value “0x40” to register 22H
USBWrite(0x22,0x40);
//Setup Endpoint2B transfer length //改??
//Write value “0x40” to register 2AH
USBWrite(0x2a,0x40);
//Set Arm and direction bit //改
//Write value “0x03” to register 20H
USBWrite(0x20,0x03);
//Interrupt Enable for Endpoint 0, 1, 2, SOF and USB reset
//Write value “0x67” to register 06H
USBWrite(0x06,0x67);
//Enable USB Transfer
//Write value “0x01” to register 05H
USBWrite(0x05,0x01);
//Clear Interrupt Status
//Write value “0xFF” to register 0DH
USBWrite(0x0d,0xff);
*/
}
////////////////////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************
// EP0 interrupt service routine
//*****************************************************************************************
void ep0_isr(void)
{
B8 status, byte_rx, len_xfr;
B8 data_seq, req_type;
char data[256];
uartpush("ep0_isr();\n\r");
USBWrite(IntStatus,EP0_DONE); // clear EP0 interrupt
status = USBRead(EP0AStatus); // get packet status
//ltoa(status,data,16);
//uartpush("####EP0A_status=0x");
//uartpush(data);
//uartpush("\n\r");
byte_rx = USBRead(EP0AXferLen) - USBRead(EP0ACounter); // get no. of bytes received
// for OUT data from host
//----------------------------------------------------------------------------------------
// ACK received
//----------------------------------------------------------------------------------------
if(status & EP_ACK)
{
//uartpush("__ACK received!\n\r");
//----------------------------------------------------------------
// Set newly assigned USB address
//----------------------------------------------------------------
if(Slave_USBaddr)
{ // if new USB address was assigned,
//uartpush("____Set newly assigned USB address!\n\r");
USBWrite(USBAddress,Slave_USBaddr); // communicate all USB transaction
Slave_USBaddr = 0; // using this new address.
}
//================================================================
// SETUP's ACKed
//================================================================
if(status & EP_SETUP)
{
//uartpush("____SETUP's ACKed!\n\r");
USBBufRead(EP0A_Slave_Buf, (B8*)&dReq, byte_rx); // capture SETUP data request
//----------------------------------------
//例程的B16和ARM的组织形式相反
//----------------------------------------
dReq.wValue=WordSwap(dReq.wValue); //edit by chendong at 2004-07-15 10:30
//The wValue field specifies the descriptor type in the high byte and the descriptor index in the low byte
dReq.wIndex=WordSwap(dReq.wIndex);
dReq.wLength=WordSwap(dReq.wLength);
//////////////////////////////////////////////////////////
len_req = WordSwap(dReq.wLength); // len_req = actual requested length
in_buffer_idx = 0; // reset buffer locatio indexing
IN_NULL = FALSE; // these are for IN-NULL packet
IN_EXACT = FALSE; // transfer condition
req_type = (dReq.bmRequest&0x60)>>5; // decode for Std,Class,Vendor type
//-------------------------------------------------------------------------------
//send debug data back to the pc through uart
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -