📄 level2.c
字号:
/* FileName: Level2.c */
#include "io51.h"
#include "usb_def.h"
extern interrupt void T0_int(void);
extern interrupt void EX0_int(void);
/* the external variable used in level2.c */
extern unsigned char intstat;
extern unsigned char sofstat;
extern unsigned char ep0stat;
/* the variable defined in level2.c */
unsigned char ep1_squ;
unsigned char data_flag;
/* the function defined in level2.c */
unsigned char set_cmd(unsigned char,unsigned char*);
unsigned char get_desc(unsigned char,unsigned char *, unsigned char*);
unsigned char send_data(unsigned char,unsigned char *, unsigned char*);
unsigned char get_data(unsigned char, unsigned char*);
/* the external function defined in level1.c */
extern void host_blk_write(unsigned char, unsigned char *, unsigned char);
extern void host_blk_read(unsigned char, unsigned char *, unsigned char);
extern void reset_root_hub(void);
extern void host_init(void);
extern void host_int(void);
extern void send_setup(unsigned char, unsigned char,unsigned char *);
extern void xfer_data(unsigned char, unsigned char, unsigned char,unsigned char, unsigned char);
extern void sof_emit(void);
extern unsigned char crc5(unsigned int crc_input);
/* the external function defined in level0.c */
extern void write_host_addr(unsigned char addr);
extern void write_host_data(unsigned char datum);
extern unsigned char read_host_data(void);
extern void i_write_host_addr(unsigned char addr);
extern void i_write_host_data(unsigned char datum);
extern unsigned char i_read_host_data(void);
extern void enable_tmr(void);
extern void disable_tmr(void);
extern void delay ( unsigned int cnt);
extern void i_delay ( unsigned int cnt);
/*****************************************************************************
This function sends a no data stage USB control transfer
Input: device's address, USB device request
Return: 1 -- success, 0 -- fail
*****************************************************************************/
unsigned char set_cmd(unsigned char dev,unsigned char *buf)
{
unsigned char cnt, time_out;
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
send_setup(dev, 0, buf); /* send setup packet*/
time_out = TIME_OUT;
while((!ep0stat) && time_out--)
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
}
write_host_addr(EP0A_STS);
write_host_data(0);
}
if(!(ep0stat & EPSTS_ACK))
return(0); /* no ACK from dev*/
/* delay(200); */
cnt = 3; ep0stat = 0;
enable_tmr();
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
xfer_data(dev, 0, 0, DATA_IN, DATA1);
time_out = TIME_OUT;
while((!ep0stat) && time_out--)
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK))
return(0); /* fail*/
return(1); /* success */
}
/*****************************************************************************
This function sends a control read transfer
Input: device's address, USB device request,
pointer of buf to store the read in descriptor
Return: length of the device descriptor or data. 0 if fails
*****************************************************************************/
unsigned char get_desc(unsigned char dev,unsigned char *cmd,unsigned char *buf)
{
unsigned char cnt, time_out;
unsigned char byteCnt;
unsigned char dataLen;
unsigned char numbytes;
unsigned char Ctl_squ;
unsigned char null_tm;
/* send SETUP packet and DATA0 packet*/
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
send_setup(dev, 0, cmd); /* sends a SETUP packet*/
time_out = TIME_OUT;
while((!ep0stat) && time_out--)
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7; /* clear sequence bit*/
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0); /* no ACK from dev*/
/* read in data from dev */
byteCnt = 0;
dataLen = (unsigned char) cmd[6];
null_tm = 0;
if (dataLen > 8)
numbytes = 8;
else
numbytes = dataLen;
Ctl_squ = DATA0;
/* read in data until done */
do {
delay(150);
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
xfer_data(dev, 0, numbytes, DATA_IN, Ctl_squ);
time_out = TIME_OUT;
while((!ep0stat) && time_out--) /* wait for xfer done interrupt*/
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7;
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0);
enable_tmr();
sofstat = 0;
while(!sofstat);
disable_tmr();
host_blk_read(EP0_BUF + 3, buf + byteCnt, numbytes);
enable_tmr();
if (byteCnt == 0)
{
if (*buf < dataLen)
{
dataLen = *buf; /* buffer size reduced */
null_tm = 1; /* null terminator may needed*/
}
}
byteCnt += numbytes;
null_tm &= 0xFD; /* clear null terminater expected*/
if (dataLen == 8)
null_tm = null_tm << 1; /* null terminator expected*/
if (dataLen >= numbytes)
{
dataLen = dataLen - numbytes;
if (dataLen > 8)
numbytes = 8;
else
numbytes = dataLen;
}
else
dataLen = 0;
if (Ctl_squ == DATA0)
Ctl_squ = DATA1;
else
Ctl_squ = DATA0;
} while ((dataLen != 0) | (null_tm > 1));
/* send status out to device, indicating end of data phase*/
delay(200);
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
xfer_data(dev, 0, 0, DATA_OUT, DATA1); /* status out*/
time_out = TIME_OUT;
while((!ep0stat) && time_out--) /* wait for xfer done interrupt*/
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7; /* clear setup flag*/
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0);
return(byteCnt);
}
/*****************************************************************************
This function sends a control write transfer
Input: device's address
device's end point
data length
data buffer
Return: 1 if succeed, 0 if fails
*****************************************************************************/
unsigned char send_data(unsigned char dev,unsigned char *cmd,unsigned char* buf)
{
unsigned char cnt, dataLen, time_out;
/* send SETUP packet and DATA0 packet*/
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
send_setup(dev, 0, cmd); /* sends a SETUP packet*/
time_out = TIME_OUT;
while((!ep0stat) && time_out--)
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7; /* clear sequence bit*/
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0); /* no ACK from dev*/
/* copy data to SL11H data buffer*/
dataLen = cmd[6];
host_blk_write(EP0_BUF+3, buf, dataLen);
/* send OUT packet and DATA0 packet*/
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
xfer_data(dev, 0, dataLen, DATA_OUT, DATA1);
time_out = TIME_OUT;
while((!ep0stat) && time_out--) /* wait for xfer done interrupt*/
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7;
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0);
/* get empty data from device for status in*/
cnt = 3; ep0stat = 0;
while(!(ep0stat & EPSTS_ACK) && cnt--)
{
intstat = 0;
xfer_data(dev, 0, 0, DATA_IN, DATA1); /* status in*/
time_out = TIME_OUT;
while((!ep0stat) && time_out--) /* wait for xfer done interrupt*/
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7; /* clear setup flag*/
}
write_host_addr(EP0A_STS);
write_host_data(0);
enable_tmr();
}
if(!(ep0stat & EPSTS_ACK)) return(0);
return(1);
}
/*****************************************************************************
This function initial a endpoint 1 interrupt IN transfer for polling data
Input: device's address, buffer length, pointer of buffer
Return: 1 if success, 0 if fails
*****************************************************************************/
unsigned char get_data(unsigned char len,unsigned char *buf)
{
unsigned char cnt, time_out;
/* read in data from dev*/
cnt = 3; ep0stat = 0;
while(!(ep0stat & 0x41) && cnt--)
{
intstat = 0;
time_out = TIME_OUT;
xfer_data(2, 1, len, DATA_IN, ep1_squ);
while((!ep0stat) && time_out--)
{
write_host_addr(EP0A_STS);
ep0stat = read_host_data();
ep0stat &= 0xF7; /* clear sequence bit*/
}
write_host_addr(EP0A_STS);
write_host_data(0);
/* delay(50); */
enable_tmr();
}
/*
if (ep1_squ == DATA0)
ep1_squ = DATA1;
else
ep1_squ = DATA0;
*/
data_flag = 0;
if(ep0stat & EPSTS_NAK)
return(1); /* no ACK from dev*/
if(!(ep0stat & EPSTS_ACK))
return(0); /* no ACK from dev*/
/* wait for xfer done interrupt*/
disable_tmr();
host_blk_read(EP0_BUF + 3, buf, len);
enable_tmr();
data_flag = 1;
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -