STM32--USB详细使用说明
//程序会进入到这个函数里面
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
else if ((wEPVal & EP_CTR_RX) != 0)
{
_ClearEP_CTR_RX(ENDP0);
Out0_Process();//处理OUT事件
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
}
}
else//如果是除端点0以外的端点
{
wEPVal = _GetENDPOINT(EPindex);//得到相应端点寄存器值
if ((wEPVal & EP_CTR_RX) != 0)//检测正确接收标志 PC-USB OUT int
{
_ClearEP_CTR_RX(EPindex);//清除相应的标志
(*pEpInt_OUT[EPindex-1])();//调用OUT int服务功能
}
if ((wEPVal & EP_CTR_TX) != 0)//检测正确发送标志 USB-PC IN int
{
_ClearEP_CTR_TX(EPindex);//清除相应的标志
(*pEpInt_IN[EPindex-1])();//调用IN int服务功能
}
}
}
}
usb_coer.c的文件里面,主要是得到主机发来的标准请求命令
uint8_t Setup0_Process(void)
{
union
{
uint8_t* b;
uint16_t* w;
} pBuf;
#ifdef STM32F10X_CL
USB_OTG_EP *ep;
uint16_t offset = 0;
ep = PCD_GetOutEP(ENDP0);
pBuf.b = ep->xfer_buff;
#else
uint16_t offset = 1;
//得到接受缓冲区地址寄存器地址
pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2);
#endif
if (pInformation->ControlState != PAUSE)
{
pInformation->USBbmRequestType = *pBuf.b++;
pInformation->USBbRequest = *pBuf.b++;
pBuf.w += offset;
pInformation->USBwValue = ByteSwap(*pBuf.w++);
pBuf.w += offset;
pInformation->USBwIndex = ByteSwap(*pBuf.w++);
pBuf.w += offset;
pInformation->USBwLength = *pBuf.w;
}
pInformation->ControlState = SETTING_UP;
if (pInformation->USBwLength == 0)
{
NoData_Setup0();
}
else
{
Data_Setup0();//由于是有数据的传输,所有要进入到这个函数
}
return Post0_Process();
}
usb_core.c的文件里面,这里只是选取了GET DESCRIPTOR
的程序部分,其他的部分删除了
void Data_Setup0(void)
{
uint8_t *(*CopyRoutine)(uint16_t);
RESULT Result;
uint32_t Request_No = pInformation->USBbRequest;
uint32_t Related_Endpoint, Reserved;
uint32_t wOffset, Status;
CopyRoutine = NULL;
wOffset = 0;
//看标准请求码格式就知道了
if (Request_No == GET_DESCRIPTOR)
{
//pInformation->USBbmRequestType是下面的两种 标准请求或设备请求
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
uint8_t wValue1 = pInformation->USBwValue1;//高一字节得到描述表种类 一共有5种
if (wValue1 == DEVICE_DESCRIPTOR)//设备描述
{
CopyRoutine = pProperty->GetDeviceDescriptor;
}
else if (wValue1 == CONFIG_DESCRIPTOR)
{
CopyRoutine = pProperty->GetConfigDescriptor;//配置描述
}
else if (wValue1 == STRING_DESCRIPTOR)
{
CopyRoutine = pProperty->GetStringDescriptor;//字符串描述
}
}
}
if (CopyRoutine)
{
pInformation->Ctrl_Info.Usb_wOffset = wOffset;//本子程序的wOffset是0
pInformation->Ctrl_Info.CopyData = CopyRoutine;//使指针pInformation->Ctrl_Info.CopyData指向CopyRoutine
(*CopyRoutine)(0);//第一次执行时Length=0 返回的是有效数据的长度 存储到pInformation->Ctrl_Info.Usb_wLength
Result = USB_SUCCESS;
}
else
{//如果标准请求不存在 看类 厂商请求中是否有
Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
if (Result == USB_NOT_READY)
{
pInformation->ControlState = PAUSE;
return;
}
}
if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)//如果字符的长度是0xffff
{
pInformation->ControlState = PAUSE;
return;
}
if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
{
pInformation->ControlState = STALLED;
return;
}
if (ValBit(pInformation->USBbmRequestType, 7))//D7表示数据传输方向 1:设备向主机
{
__IO uint32_t wLength = pInformation->USBwLength;
//设置使其为USB主机设置的长度 本程序HID 鼠标 pProperty->MaxPacketSize是0x40
if (pInformation->Ctrl_Info.Usb_wLength > wLength)//字符的长度大于主机要求的长度
{
pInformation->Ctrl_Info.Usb_wLength = wLength;
//将其设置为主机要求的
}
else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)//字符的长度小于主机要求的
{
if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) //如果字符的长度长度小于每包数据最大字节数
{
Data_Mul_MaxPacketSize = FALSE;
}
else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)//如果是其整数倍
{
Data_Mul_MaxPacketSize = TRUE;
}
}
pInformation->Ctrl_Info.PacketSize = pProperty->
STM32USB使用说 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)