STM32 USB HOST CDC 驱动CH340

cpp 复制代码
/**
  * @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 枚举成功

cpp 复制代码
/**
  * @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*/

}

}

相关推荐
迷雾漫步者39 分钟前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-1 小时前
验证码机制
前端·后端
xlsw_1 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹2 小时前
基于java的改良版超级玛丽小游戏
java
燃先生._.2 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭2 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫3 小时前
泛型(2)
java
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论