微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32--USB详细使用说明

STM32--USB详细使用说明

时间:11-27 来源:互联网 点击:

//程序会进入到这个函数里面

_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->

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top