整个枚举过程 更加简单,明了,移植更加方便
stm32_ucos_ch340.rar
(382.76 KB)
核心代码如下void JkData_Setup0(USB_REQ *pReq)
{
INT8U err;
//printf("r:%02X%04X%02X\r\n",pReq->USBbRequest,pReq->USBwValues,pReq->USBwLengths);
if (pReq->USBbRequest == GET_DESCRIPTOR)
{
ONE_DESCRIPTOR *pDescriptor=NULL;//=(ONE_DESCRIPTOR*)&Device_Descriptor;
if ( (pReq->USBbmRequestType& (REQUEST_TYPE | RECIPIENT)) == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
switch(pReq->USBwValues>>8)
{
case DEVICE_DESCRIPTOR:
pDescriptor=(ONE_DESCRIPTOR*)&Device_Descriptor;
break;
case CONFIG_DESCRIPTOR:
pDescriptor=(ONE_DESCRIPTOR*)&Config_Descriptor;
break;
case STRING_DESCRIPTOR:
pDescriptor=(ONE_DESCRIPTOR*)&String_Descriptor[pReq->USBwValues&0xff];
break;
}
err=SendEp0Data(pDescriptor->Descriptor,pReq->USBwLengths,pDescriptor->Descriptor_Size);
}
}
else if(pReq->USBbRequest == SET_ADDRESS)
{
//返回一个空回复,作为事务的状态回复
if(SendEp0Data(NULL,0,0)==OS_NO_ERR)
SetDeviceAddress(pReq->USBwValues&0xff);
}
else if(pReq->USBbRequest==SET_CONFIGURATION)
{
//返回一个空回复,作为事务的状态回复
SendEp0Data(NULL,0,0);
usbConfig=pReq->USBwValues;
}
else
Ep0SetupCustom(pReq);
}
INT8U SetupHandle(void)
{
USB_REQ req;
INT8U *pBuf = PMAAddr + (INT8U *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
req.USBbmRequestType=*pBuf++;
req.USBbRequest=*pBuf++;
pBuf+=2;
req.USBwValues=pBuf[0]+((INT16U)pBuf[1]<<8);
pBuf+=4;
req.USBwIndexs=pBuf[0]+((INT16U)pBuf[1]<<8);
pBuf+=4;
req.USBwLengths=pBuf[0]+((INT16U)pBuf[1]<<8);
JkData_Setup0(&req);
return 1;
}
/*---- U S B T A S K ----
【功能】:将usb
的端点0的控制中断,描述符上移动到这里来,让代码更加清晰,这里是尝试移植stm32的虚拟串口的
【参数】:****
【返回】:****
【说明】:****
--------------作者:卢杰西 2021年1月23日17:12:35--------------------------------*/
void UsbTask(void *pt)
{
INT8U err;
INT32U msg;
CREATE_SMSG(OSQUsbEP0, 10);
InitUsb();
while(1)
{
msg=(INT32U)OSQPend(OSQUsbEP0,0,&err);
if ((msg & EP_CTR_TX) != 0)
{
SetEPRxValid(ENDP0);
}
else if ((msg &EP_SETUP) != 0)
{
SetupHandle();
}
else if ((msg & EP_CTR_RX) != 0)
{
SetEPRxValid(ENDP0);
}
}
}
|