📄 transfer.c
字号:
#define TRANSFER_GLOBALS
#include "config.h"
INT8U Control_Setup( USB_Device_Request *dev_req,
endpoint_info *epi_ptr)
{
INT8U uc_SetupBuf[8];
INT8U uc_Data0Addr;
INT8U uc_Intr;
INT8U uc_Result;
INT8U uc_Timeout;
uc_Timeout = 0;
uc_Data0Addr = EP0_Buf;
uc_SetupBuf[0] = dev_req->bmRequestType;
uc_SetupBuf[1] = dev_req->bRequest;
uc_SetupBuf[2] = (INT8U)(dev_req->wValue);
uc_SetupBuf[3] = (INT8U)(dev_req->wValue>>8);
uc_SetupBuf[4] = (INT8U)(dev_req->wIndex);
uc_SetupBuf[5] = (INT8U)(dev_req->wIndex>>8);
uc_SetupBuf[6] = (INT8U)(dev_req->wLength);
uc_SetupBuf[7] = (INT8U)(dev_req->wLength>>8);
SL811BufWrite(uc_Data0Addr, uc_SetupBuf, 8);
SL811Write(EP0Status,((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_SETUP)); // PID + EP address
SL811Write(EP0Counter,epi_ptr->dvi_ptr->address); // USB address
SL811Write(EP0Address, uc_Data0Addr); // buffer address, start with "data0"
SL811Write(EP0XferLen, 8); // data transfer length
SL811Write(IntStatus, INT_CLEAR); // clear interrupt status
SL811Write(EP0Control, sDATA0_WR); // Enable ARM and USB transfer start here
WaitForOver:
while(1) {
uc_Intr = SL811Read(IntStatus); // wait for interrupt to be done, and
if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE)) // proceed to parse result from slave
{ // device.
return 0xff; // flag true, so that main loop will
} // know this condition and exit gracefully
if(uc_Intr & USB_A_DONE)
break; // interrupt done !!!
}
SL811Write(IntStatus, INT_CLEAR);
USB_Delay(50);
uc_Result = SL811Read(EP0Status);
if (uc_Result & EP0_ACK) {
return 0;
}
if (uc_Result & EP0_STALL) {
return 0;
}
if (uc_Result & EP0_NAK) {
if (++uc_Timeout >= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
if (uc_Result & EP0_TIMEOUT) {
if (++uc_Timeout >= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
return 0xff;
}
INT8U Control_Out( INT8U *data_ptr,
INT16U size,
endpoint_info *epi_ptr)
{
INT8U uc_Data0Addr;
INT8U uc_Data1Addr;
INT8U uc_TranLen;
INT8U uc_UnTranLen;
INT8U uc_Cmd;
INT8U uc_Result;
INT8U uc_Timeout;
INT8U uc_Intr;
//INT8U uc_BufLen;
INT8U uc_Addr;
INT8U uc_Toggle;
uc_Timeout = 0;
uc_Toggle = 1;
uc_Data0Addr = EP0_Buf;
uc_Data1Addr = uc_Data0Addr+ epi_ptr->endpoint_descriptor.wMaxPacketSize;
uc_Addr = uc_Data1Addr;
uc_TranLen = m_MIN(epi_ptr->endpoint_descriptor.wMaxPacketSize, size);
uc_Cmd = sDATA0_WR|0x40;
SL811BufWrite(uc_Addr, data_ptr, uc_TranLen);
SL811Write(EP0Status, ((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_OUT)); // PID + EP address
SL811Write(EP0Counter, epi_ptr->dvi_ptr->address); // USB address
SL811Write(EP0Address, uc_Addr); // buffer address, start with "data0"
SL811Write(EP0XferLen, uc_TranLen); // data transfer length
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
SL811Write(EP0Control, uc_Cmd); // Enable ARM and USB transfer start here
WaitForOver:
while(1) {
uc_Intr = SL811Read(IntStatus); // wait for interrupt to be done, and
if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE)) // proceed to parse result from slave
{ // device.
return 0xff; // flag true, so that main loop will
} // know this condition and exit gracefully
if(uc_Intr & USB_A_DONE)
break; // interrupt done !!!
}
SL811Write(IntStatus, INT_CLEAR);
USB_Delay(50);
uc_Result = SL811Read(EP0Status);
uc_UnTranLen = SL811Read(EP0Counter);
if (uc_Result & EP0_ACK) {
size -= uc_TranLen;
data_ptr += uc_TranLen;
uc_Toggle = !uc_Toggle;
if (size) {
uc_Addr = (uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr;
uc_TranLen = m_MIN(size, epi_ptr->endpoint_descriptor.wMaxPacketSize);
uc_Cmd ^= 0x40;
uc_Cmd |= 0x20;
SL811BufWrite(uc_Addr, data_ptr, uc_TranLen);
SL811Write(EP0XferLen, uc_TranLen);
SL811Write(EP0Address, uc_Addr);
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, uc_Cmd);
goto WaitForOver;
}
else {
return 0;
}
}
if (uc_Result & EP0_STALL) {
return 0;
}
if (uc_Result & EP0_NAK) {
if (++uc_Timeout >= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
if (uc_Result & EP0_TIMEOUT) {
if (++uc_Timeout>= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
return 0xff;
}
INT8U Control_In( INT8U *data_ptr,
INT16U size,
endpoint_info *epi_ptr)
{
INT8U uc_Data0Addr;
INT8U uc_Data1Addr;
INT8U uc_TranLen;
INT8U uc_UnTranLen;
INT8U uc_Cmd;
INT8U uc_Result;
INT8U uc_Timeout;
INT8U uc_Intr;
//INT8U uc_BufLen;
INT8U uc_Addr;
INT8U uc_Toggle;
uc_Timeout = 0;
uc_Toggle = 1;
uc_Data0Addr = EP0_Buf;
uc_Data1Addr = uc_Data0Addr+ epi_ptr->endpoint_descriptor.wMaxPacketSize;
uc_Addr = uc_Data1Addr;
uc_TranLen = m_MIN(epi_ptr->endpoint_descriptor.wMaxPacketSize, size);
uc_Cmd = sDATA0_RD|0x40;
SL811Write(EP0Status, ((epi_ptr->endpoint_descriptor.bEndpointAddress&0x0F)|PID_IN)); // PID + EP address
SL811Write(EP0Counter, epi_ptr->dvi_ptr->address); // USB address
SL811Write(EP0Address, uc_Addr); // buffer address, start with "data0"
SL811Write(EP0XferLen, uc_TranLen); // data transfer length
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
SL811Write(EP0Control, uc_Cmd); // Enable ARM and USB transfer start here
WaitForOver:
while(1) {
uc_Intr = SL811Read(IntStatus); // wait for interrupt to be done, and
if((uc_Intr & USB_RESET) || (uc_Intr & INSERT_REMOVE)) // proceed to parse result from slave
{ // device.
return 0xff; // flag true, so that main loop will
} // know this condition and exit gracefully
if(uc_Intr & USB_A_DONE)
break; // interrupt done !!!
}
SL811Write(IntStatus, INT_CLEAR);
USB_Delay(50);
uc_Result = SL811Read(EP0Status);
uc_UnTranLen = SL811Read(EP0Counter);
if (uc_Result & EP0_ACK) {
SL811BufRead(((uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr), data_ptr, uc_TranLen);
data_ptr += uc_TranLen;
size -= uc_TranLen;
uc_Toggle = !uc_Toggle;
if (size) {
uc_Addr = (uc_Toggle&1)?uc_Data1Addr:uc_Data0Addr;
uc_TranLen = m_MIN(size, epi_ptr->endpoint_descriptor.wMaxPacketSize);
uc_Cmd ^= 0x40;
uc_Cmd |= 0x20;
SL811Write(EP0XferLen, uc_TranLen);
SL811Write(EP0Address, uc_Addr);
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, uc_Cmd);
goto WaitForOver;
}
else {
return 0;
}
}
if (uc_Result & EP0_STALL) {
return 0;
}
if (uc_Result & EP0_NAK) {
if (++uc_Timeout >= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
if (uc_Result & EP0_TIMEOUT) {
if (++uc_Timeout>= TIMEOUT_RETRY) {
return 0xff;
}
SL811Write(IntStatus, INT_CLEAR);
SL811Write(EP0Control, sDATA0_WR);
goto WaitForOver;
}
// EP0_OVERFLOW, EP0_ERROR, EP0_SEQUENCE, EP0_SETUP
return 0xff;
}
INT16U Control_Transfer( USB_Device_Request *dev_req,
device_instance *dvi_ptr,
INT8U *data_ptr )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -