STM32 USB HOST CDC 驱动CH340
/**
* @brief Initialize the transmit and receive buffer and its parameter
* @param None
* @retval None
*/
static void CDC_InitTxRxParam(void)
{
/*Initialize the Transmit buffer and its parameter*/
CDC_TxParam.CDCState = CDC_IDLE;
CDC_TxParam.DataLength = 0;
CDC_TxParam.pRxTxBuff = TxBuf;
/*Initialize the Receive buffer and its parameter*/
CDC_RxParam.CDCState = CDC_IDLE;
CDC_RxParam.DataLength = 0;
CDC_RxParam.pFillBuff = RxBuf;
CDC_RxParam.pEmptyBuff = RxBuf;
CDC_RxParam.BufferLen = sizeof(RxBuf);
}
/**
* @brief This is a call back function from cdc core layer to redirect the
* received data on the user out put system
* @param cdc_Data: type of USBH_CDCXfer_TypeDef
* @retval None
*/
static void CDC_ReceiveData(CDC_Xfer_TypeDef *cdc_Data)
{
uint8_t *ptr;
if(cdc_Data->pEmptyBuff < cdc_Data->pFillBuff)
{
ptr = cdc_Data->pFillBuff;
*ptr = 0x00;
/* redirect the received data on the user out put system */
UserCb.Receive(cdc_Data->pEmptyBuff, cdc_Data->DataLength);
cdc_Data->pFillBuff = cdc_Data->pEmptyBuff ;
cdc_Data->DataLength = 0; /*Reset the data length to zero*/
}
}
/**
* @brief This function send data to the device.
* @param fileName : name of the file
* @retval the filestate will be returned
* FS_SUCCESS : returned to the parent function when the file length become to zero
*/
void CDC_SendData(uint8_t *data, uint16_t length)
{
if(CDC_TxParam.CDCState == CDC_IDLE)
{
CDC_TxParam.pRxTxBuff = data;
CDC_TxParam.DataLength = length;
CDC_TxParam.CDCState = CDC_SEND_DATA;
}
}
/**
* @brief This function send data to the device.
* @param fileName : name of the file
* @retval the filestate will be returned
* FS_SUCCESS : returned to the parent function when the file length become to zero
*/
void CDC_StartReception( USB_OTG_CORE_HANDLE *pdev)
{
RX_Enabled = 1;
}
/**
* @brief This function send data to the device.
* @param fileName : name of the file
* @retval the filestate will be returned
* FS_SUCCESS : returned to the parent function when the file length become to zero
*/
void CDC_StopReception( USB_OTG_CORE_HANDLE *pdev)
{
RX_Enabled = 0;
USB_OTG_HC_Halt(pdev, CDC_Machine.CDC_DataItf.hc_num_in);
USBH_Free_Channel (pdev,CDC_Machine.CDC_DataItf.hc_num_in);
}
初始化CDC 接口.修改相应的类接口和 通讯端点,让USB HOST 枚举成功
/**
* @brief CDC_InterfaceInit
* The function init the CDC class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status :Response for USB CDC driver intialization
*/
static USBH_Status CDC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
void *phost)
{
USBH_HOST *pphost = phost;
USBH_Status status = USBH_OK ;
int ret = 0x00;
/* Communication Interface */
if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == COMMUNICATION_DEVICE_CLASS_CODE)&& \
(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == ABSTRACT_CONTROL_MODEL) && \
(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == COMMON_AT_COMMAND))
{
/*Collect the notification endpoint address and length*/
CDC_Machine.CDC_CommItf.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress;
CDC_Machine.CDC_CommItf.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_CommItf.notificationEp =\
(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
}
ret = 0x01;
} else if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == CH340X_CLASS)&& \
(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == 0x01) && \
(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == 0x02)){
ret = 0x02;
/*Collect the notification endpoint address and length*/
CDC_Machine.CDC_CommItf.ep_addr = pphost->device_prop.Ep_Desc[0][2].bEndpointAddress;
CDC_Machine.CDC_CommItf.length = pphost->device_prop.Ep_Desc[0][2].wMaxPacketSize;
if(pphost->device_prop.Ep_Desc[0][2].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_CommItf.notificationEp =\
(pphost->device_prop.Ep_Desc[0][2].bEndpointAddress);
}
}else{
pphost->usr_cb->DeviceNotSupported();
//return USBH_NOT_SUPPORTED;
}
if(ret)
{
/*Allocate the length for host channel number in*/
CDC_Machine.CDC_CommItf.hc_num_in = USBH_Alloc_Channel(pdev,
CDC_Machine.CDC_CommItf.notificationEp );
/* Open channel for IN endpoint */
USBH_Open_Channel (pdev,
CDC_Machine.CDC_CommItf.hc_num_in,
pphost->device_prop.address,
pphost->device_prop.speed,
EP_TYPE_INTR,
CDC_Machine.CDC_CommItf.length);
}
ret = 0x00;
/* Data Interface */
if((pphost->device_prop.Itf_Desc[1].bInterfaceClass == DATA_INTERFACE_CLASS_CODE)&& \
(pphost->device_prop.Itf_Desc[1].bInterfaceSubClass == RESERVED) && \
(pphost->device_prop.Itf_Desc[1].bInterfaceProtocol == NO_CLASS_SPECIFIC_PROTOCOL_CODE))
{
/*Collect the class specific endpoint address and length*/
CDC_Machine.CDC_DataItf.ep_addr = pphost->device_prop.Ep_Desc[1][0].bEndpointAddress;
CDC_Machine.CDC_DataItf.length = pphost->device_prop.Ep_Desc[1][0].wMaxPacketSize;
if(pphost->device_prop.Ep_Desc[1][0].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[1][0].bEndpointAddress);
}
else
{
CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[1][0].bEndpointAddress);
}
if(pphost->device_prop.Ep_Desc[1][1].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[1][1].bEndpointAddress);
}
else
{
CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[1][1].bEndpointAddress);
}
ret =0x01;
}else if((pphost->device_prop.Itf_Desc[1].bInterfaceClass == 0)&& \
(pphost->device_prop.Itf_Desc[1].bInterfaceSubClass == 0) && \
(pphost->device_prop.Itf_Desc[1].bInterfaceProtocol == 0)){
/*Collect the class specific endpoint address and length*/
CDC_Machine.CDC_DataItf.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress;
CDC_Machine.CDC_DataItf.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
}
else
{
CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
}
if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
{
CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
}
else
{
CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
}
ret =0x02;
}
else
{
pphost->usr_cb->DeviceNotSupported();
}
通过调用往USB cdc设备发送数据。
void CDC_SendData(uint8_t *data, uint16_t length)
接收数据可以通过回调 内的 UserCb.Receive()读取数据
static void CDC_ReceiveData(CDC_Xfer_TypeDef *cdc_Data)
{
uint8_t *ptr;
if(cdc_Data->pEmptyBuff < cdc_Data->pFillBuff)
{
ptr = cdc_Data->pFillBuff;
*ptr = 0x00;
/* redirect the received data on the user out put system */
UserCb.Receive(cdc_Data->pEmptyBuff, cdc_Data->DataLength);
cdc_Data->pFillBuff = cdc_Data->pEmptyBuff ;
cdc_Data->DataLength = 0; /*Reset the data length to zero*/
}
}
原文地址:https://blog.csdn.net/li880wert/article/details/142332756
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!