📄 slave.c
字号:
/////////////////////////////////////
#include "..\inc\common.h"
#include "..\inc\SL811.H"
#include "..\inc\sl811_slave.H"
#include "..\inc\TPBULK.H"
#include "..\inc\HAL.H"
//#include "hpi32.H"
#include "fat32.H"
#include "..\inc\hpi.H"
#include "..\inc\fat.H"
#include "..\Target\44blib.H"
#include "..\target\44b.h"
BYTE flags_slave;
//WORD len_req; // length of data for EP0
WORD sof_cnt; // 1ms counter
BYTE ep1_toggle; // EP1 DATA toggle state
//BYTE in_buffer_idx; // EP0 IN data buffer tracking
BYTE Slave_USBaddr; // USB device address
BYTE Slave_ConfigVal; // Device configuration value
BYTE Slave_Protocol; // HID device protocol status
BYTE Slave_IdleRate; // HID device idle rate value
BYTE Slave_RemoteWU; // Device remote wakeup stats
BYTE Slave_inEPstall; // EP0 ~ EP7's IN stall status
BYTE Slave_outEPstall; // EP0 ~ EP7's OUT stall status
BYTE Slave_IfcAlt[8]; // 8 interface(Ep0~7) contain alternate setting value
BYTE BUS_POWERED; // Bus powered device
SetupPKG dReq; // Setup token struct
WORD len_req; // length of data for EP0
BYTE in_buffer_idx; // EP0 IN data buffer tracking
BYTE IN_NULL; // EP0's IN null packet transmission
BYTE IN_EXACT; // EP0's IN data length requested is extact of EP0_LEN
void enumerate_default(void);
void enumerate_mouse(void);
void sl811_slave_init(void);
void sl811s_init_v(void);
void EP0A_OUT_Arm(BYTE len);
int ep0_isr(void);
void EP0A_IN_Arm(BYTE buf_adr, BYTE len, BYTE seq);
int ep1_isr(void);
int sof_isr(void);
extern int SL811_Memtest(void);
void * function_slave[][2]=
{
(void *)enumerate_default, "枚举为自定义的USB设备 ",
(void *)enumerate_mouse, "枚举为鼠标 ",
0,0
};
void sl811_slave(void)
{
BYTE int_status;
unsigned int temp;
sl811_slave_init();
/* while(TRUE)
{
//--------------------------------------------
// USB-Specific Tasks
//--------------------------------------------
int_status = SL811Read(IntStatus);
if(int_status & 0x40)// wait for USB Reset interrupt
sl811s_init_v();
else if(int_status & 0x01) // wait for EP0 interrupt
ep0_isr();
else if(int_status & 0x02) // wait for EP1 interrupt
ep1_isr();
else if(int_status & 0x20) // wait for SOF interrupt
sof_isr();
//--------------------------------------------
// Application-Specific Tasks (every 5msec)
//--------------------------------------------
// if(timeout && enum_done) // do some task now
//{
// audio_key_scan(); // Audio Keys Scan
// internet_key_scan(); // Internet Keys Scan
// timeout = 0;
//}
}*/
Uart_Printf("\nPress any key to exit\n");
do{}while(!(rUTRSTAT0 & 0x1)); //Receive data read
temp=RdURXH0();
}
void sl811_slave_init(void)
{
unsigned int j;
rPDATB = 0x7df; //m/s == 1 (slave)
rPDATF=0x6f; //
// for(i=0;i<50000;i++)
for(j=0;j<500;j++);
rPDATF=0xff; // reset
SL811Write(cSOFcnt,0x0f); //config slave mode 20071114
SL811_Memtest(); //
rPDATF=0x6f; //
// for(i=0;i<50000;i++)
for(j=0;j<500;j++);
rPDATF=0xff; // reset
SL811Write(IntEna,0x00); //enable usb reset interrupt
DelayMs(100);
SL811Write(0x07,0x00);
SL811Write(0x01,0x40); //setup usb address
SL811Write(0x12,0x40); //setup transfer length
SL811Write(0x00,0x03);
//endpoint 1 set a:
SL811Write(0x11,0x60);
SL811Write(0x12,0x40);
SL811Write(0x10,0x03);
//edpoint 2 set a and b
SL811Write(0x21,0x80);
SL811Write(0x29,0xc0);
SL811Write(0x22,0x40);
SL811Write(0x10,0x03);
SL811Write(0x06,0x67); // interrupt enable for endpoint 0,1,2,sof and usb reset
SL811Write(0x05,0x01); //enable usb transfer
SL811Write(0x0d,0xff); //clear interrupt status
Uart_Printf("\nSL811 Slave 初始化完毕 请连接USB主设备 ");
}
//*****************************************************************************************
// SL811S variables initialization
//*****************************************************************************************
void sl811s_init_v(void)
{
int i;
flags_slave = 0; // clear flag
sof_cnt = 0; // sof counter equal zero
ep1_toggle = 0; // ep1 toggle state
//----------------------------
// SL811S-Specific
//----------------------------
BUS_POWERED = 1; // define as a bus powered device
Slave_USBaddr = 0; // set to default USB address zero
Slave_ConfigVal = 0; // default device config value
Slave_Protocol = 0; // HID class default boot protocol
Slave_IdleRate = 0; // HID class default idle rate
Slave_RemoteWU = 0; // device remote wakeup support
Slave_inEPstall = 0; // EP0 ~ EP7's IN
Slave_outEPstall = 0; // EP0 ~ EP7's OUT
for(i=0;i<8;i++) // reset alternate setting
Slave_IfcAlt[i] = 0;
for(i=0;i<64;i++) // clear EP0 Buffer
SL811Write(0x40+i,0);
for(i=0;i<2;i++) // clear EP1 Buffer
SL811Write(0x80+i,0);
SL811Write(0x07,0x00); // usb address
SL811Write(IntEna,0x63); // enable SOF, EP0, EP1, USB Reset interrupts
SL811Write(IntStatus,0xFF); // clear all interrupts
EP0A_OUT_Arm(64); // ready to receive from host
Uart_Printf("\n加载USB参数 ");
}
void enumerate_default(void)
{
}
void enumerate_mouse(void)
{
}
//*****************************************************************************************
// EP0's SETUP/OUT Token Arming (using Set A)
//*****************************************************************************************
void EP0A_OUT_Arm(BYTE len)
{
SL811Write(0x01,0x40); // ep0 address buffer start adress
SL811Write(0x02,len); // max length of transfer allowed
SL811Write(0x00,0x03); // armed to receive from host
}
//*****************************************************************************************
// EP0 interrupt service routine
//*****************************************************************************************
int ep0_isr(void)
{
BYTE status, byte_rx, len_xfr;
BYTE data_seq, req_type;
SL811Write(IntStatus,0x01); // clear EP0 interrupt
status = SL811Read(0x03); // get packet status
byte_rx = SL811Read(0x02) - SL811Read(0x04); // get no. of bytes received
// for OUT data from host
Uart_Printf("\nstatus:%d ",status);
//----------------------------------------------------------------------------------------
// ACK received
//----------------------------------------------------------------------------------------
if(status & 0x01)
{
Uart_Printf("标志1\n");
//----------------------------------------------------------------
// Set newly assigned USB address
//----------------------------------------------------------------
if(Slave_USBaddr)
{ // if new USB address was assigned,
SL811Write(0x07,Slave_USBaddr); // communicate all USB transaction
Slave_USBaddr = 0; // using this new address.
}
//================================================================
// SETUP's ACKed
//================================================================
if(status & 0x10)
{
SL811BufRead(0x40, (BYTE*)&dReq, byte_rx); // capture SETUP data request
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
switch (req_type) // Parse bmRequest Type
{
//---------------------------------------------------------------------
// Standard USB Requests
//---------------------------------------------------------------------
case 0x00:
switch (dReq.bRequest) // Parse bRequest
{
case GET_DESCRIPTOR:
switch ((BYTE)dReq.wValue) // Parse wValue
{
case DEVICE:
SL811BufWrite(0x40,(BYTE*)Dev_Descp,18); // load Device Descp
len_req = (len_req>=18) ? 18:len_req; // get exact data length
break;
case CONFIGURATION:
SL811BufWrite(0x40,(BYTE*)Cfg_Descp,34); // load Config Descp
len_req = (len_req>=34) ? 34:len_req; // get exact data length
break;
case 0x21://HID_DEV:
SL811BufWrite(0x40,(BYTE*)Cfg_Descp+18,9);// load HID Class Descp
len_req = (len_req>=9) ? 9:len_req; // get exact data length
break;
case 0x22://HID_REPORT:
SL811BufWrite(0x40,(BYTE*)Rep_Descp,57); // load Report Descp
len_req = (len_req>=57) ? 57:len_req; // get exact data length
break;
case STRING:
switch(dReq.wValue>>8) // get string index
{
case 0x00: SL811BufWrite(0x40,(BYTE*)LangString,LangString[0]);
len_req = (len_req>=LangString[0]) ? LangString[0]:len_req;
break;
case 0x01: SL811BufWrite(0x40,(BYTE*)MfgString,MfgString[0]);
len_req = (len_req>=MfgString[0]) ? MfgString[0]:len_req;
break;
case 0x02: SL811BufWrite(0x40,(BYTE*)ProdString,ProdString[0]);
len_req = (len_req>=ProdString[0]) ? ProdString[0]:len_req;
break;
}
break;
}
if (len_req == WordSwap(dReq.wLength)) // if requested length is equal to the
IN_EXACT = TRUE; // exact length of descriptor, set IN_EXACT
// is use during IN-NULL pkt trasnmission
len_xfr = (len_req>=64) ? 64:(BYTE)len_req; // get current IN transfer length
EP0A_IN_Arm(0x40,len_xfr,1); // Arm IN response, start with DATA1 seq
in_buffer_idx += len_xfr; // update to next muliple buffer location
len_req -= len_xfr; // update data length for current transfer
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -