STM32 USB HOST 移植HOST TMC 相关协议步骤,
1.修改一份正常通讯的USB HOST ,简单入手从USB CDC,
* @brief CDC_ClassRequest
* The function is responsible for handling CDC Class requests
* for CDC class.
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status :Response for USB Set Protocol request
*/
static USBH_Status CDC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_HOST *pphost = phost;
USBH_Status status = USBH_BUSY;
USBH_Status ClassReqStatus = USBH_BUSY;
switch(CDC_ReqState)
{
case TMC_GET_CAPABILITIES:
/*Issue the get line coding request*/
ClassReqStatus = TMC_GET_Capbilites(pdev, phost);
if( ClassReqStatus == USBH_OK )
{ /*Change the state */
CDC_ReqState = TMC_INTIT_CLEAR ;
}
break;
case TMC_REN_CTRL:
/*Issue the get line coding request*/
// ClassReqStatus = TMC_GET_Capbilites(pdev, phost);
// if( ClassReqStatus == USBH_OK )
// { /*Change the state */
// ClassReqStatus = TMC_initclear
// }
break;
case TMC_INTIT_CLEAR:
/*Issue the get line coding request*/
ClassReqStatus = TMC_initclear (pdev, phost);
if( ClassReqStatus == USBH_OK )
{ /*Change the state */
CDC_ReqState = TMC_CHECK_CLEAR;
}
break;
case TMC_CHECK_CLEAR:
/*Issue the get line coding request*/
ClassReqStatus = TMC_Checkclear(pdev, phost);
if( ClassReqStatus == USBH_OK )
{ /*Change the state */
status = USBH_OK;
//CDC_ReqState = TMC_ERROR_STATE;
}
break;
case TMC_ERROR_STATE:
//ClassReqStatus = TMC__clear_out_ep();
ClassReqStatus = USBH_ClrFeature(pdev, phost, 0x00, pphost->Control.hc_num_out);
if(ClassReqStatus == USBH_OK )
{
/*Change the state to waiting*/
//CDC_ReqState = TMC_GET_CAPABILITIES ;
status = USBH_OK;
}
break;
default:;
break;
}
return status;
}
/**
* @brief CDC_Handle
* The function is for managing state machine for CDC data transfers
* @param pdev: Selected device
* @param hdev: Selected device property
* @retval USBH_Status
*/
/*
在main 中回调,HOST_CLASS;
case HOST_CLASS:
process class state machine machine
status = phost->class_cb->Machine(pdev, phost); --> CDC_Handle
USBH_ErrorHandle(phost, status);
*/
static USBH_Status CDC_Handle(USB_OTG_CORE_HANDLE *pdev ,
void *phost)
{
USBH_Status status = USBH_OK;
USBH_HOST *pphost = phost;
/* Call Application process */
pphost->usr_cb->UserApplication();
/*Handle the transmission */
CDC_ProcessTransmission(pdev, pphost);
/*Always send in packet to device*/
CDC_ProcessReception(pdev, pphost);
return status;
}
/**
* @brief The function is responsible for sending data to the device
* @param pdev: Selected device
* @retval None
*/
void CDC_ProcessTransmission(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
static uint32_t len ;
URB_STATE URB_StatusTx = URB_IDLE;
URB_StatusTx = HCD_GetURB_State(pdev , TMC_Machine.CDC_DataItf.hc_num_out);
switch(CDC_TxParam.CDCState)
{
case CDC_IDLE:
break;
case CDC_SEND_DATA:
if(( URB_StatusTx == URB_DONE ) || (URB_StatusTx == URB_IDLE))
{
/*Check the data length is more then the TMC_Machine.CDC_DataItf.CDC_DataItf.length */
if(CDC_TxParam.DataLength > TMC_Machine.CDC_DataItf.length)
{
len = TMC_Machine.CDC_DataItf.length ;
/*Send the data */
USBH_BulkSendData (pdev,
CDC_TxParam.pRxTxBuff,
len ,
TMC_Machine.CDC_DataItf.hc_num_out);
}
else
{
len = CDC_TxParam.DataLength ;
/*Send the remaining data */
USBH_BulkSendData (pdev,
CDC_TxParam.pRxTxBuff,
len,
TMC_Machine.CDC_DataItf.hc_num_out);
}
CDC_TxParam.CDCState = CDC_DATA_SENT;
}
break;
case CDC_DATA_SENT:
/*Check the status done for transmssion*/
if(URB_StatusTx == URB_DONE )
{
/*Point to next chunc of data*/
CDC_TxParam.pRxTxBuff += len ;
/*decrease the data length*/
CDC_TxParam.DataLength -= len;
if(CDC_TxParam.DataLength == 0)
{
CDC_TxParam.CDCState = CDC_IDLE;
}
else
{
CDC_TxParam.CDCState = CDC_SEND_DATA;
}
}
else if( URB_StatusTx == URB_NOTREADY )
{
/*Send the same data */
USBH_BulkSendData (pdev,
(CDC_TxParam.pRxTxBuff),
len,
TMC_Machine.CDC_DataItf.hc_num_out);
}
break;
default:
break;
}
}
2.添加TMC_ClassRequest 相关请求协议文挡,
typedef struct usb_tmc_get_capabilities_response
{
uint8_t USBTMC_status;
uint8_t reserved0;
uint16_t bcdUSBTMC;
uint8_t interface_capabilities; /* bitmap! */
uint8_t device_capabilities; /* bitmap! */
uint8_t reserved1[6];
uint8_t reserved_subclass[12];
}USBTMC_GetCapres_t;
#define USB_CLASS_APPLICATION 0xfe
#define USB_APPLICATION_SUBCLASS_TMC 0x03
/* Table 44 */
#define USB_TMC_PROTOCOL_NONE 0
#define USB_TMC_PROTOCOL_USB488 1
/* USB TMC Class Specific Requests, Table 15 sec 4.2.1 */
/* These are all required */
#define USB_TMC_REQ_INITIATE_ABORT_BULK_OUT 1
#define USB_TMC_REQ_CHECK_ABORT_BULK_OUT_STATUS 2
#define USB_TMC_REQ_INITIATE_ABORT_BULK_IN 3
#define USB_TMC_REQ_CHECK_ABORT_BULK_IN_STATUS 4
#define USB_TMC_REQ_INITIATE_CLEAR 5
#define USB_TMC_REQ_CHECK_CLEAR_STATUS 6
#define USB_TMC_REQ_GET_CAPABILITIES 7
#define USB_TMC_REQ_INDICATOR_PULSE 64 /* optional */
#define USB_TMC_REQ_READ_STATUS_BYTE 128
#define USB_TMC_REQ_REN_CONTROL 160
#define USB_TMC_REQ_GO_TO_LOCAL 161
#define USB_TMC_REQ_LOCAL_LOCKOUT 162
/* USB TMC status values Table 16 */
#define USB_TMC_STATUS_SUCCESS 1
#define USB_TMC_STATUS_PENDING 2
#define USB_TMC_STATUS_FAILED 0x80
#define USB_TMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81
#define USB_TMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82
#define USB_TMC_STATUS_SPLIT_IN_PROGRESS 0x83
#define USB_TMC_INTERFACE_CAPABILITY_INDICATOR_PULSE (1<<2)
#define USB_TMC_INTERFACE_CAPABILITY_TALK_ONLY (1<<1)
#define USB_TMC_INTERFACE_CAPABILITY_LISTEN_ONLY (1<<0)
#define USB_TMC_DEVICE_CAPABILITY_TERMCHAR (1<<0)
typedef struct usb_tmc_bulk_header {
uint8_t MsgID;
uint8_t bTag;
uint8_t bTagInverse;
uint8_t reserved;
//4
union {
struct _dev_dep_msg_out {
uint32_t transferSize;
uint8_t bmTransferAttributes;
uint8_t reserved[3];
} dev_dep_msg_out;
struct _req_dev_dep_msg_in {
uint32_t transferSize;
uint8_t bmTransferAttributes;
uint8_t TermChar;
uint8_t reserved[2];
} req_dev_dep_msg_in;
struct _dev_dep_msg_in {
uint32_t transferSize;
uint8_t bmTransferAttributes;
uint8_t reserved[3];
} dev_dep_msg_in;
struct _vendor_specific_out {
uint32_t transferSize;
uint8_t reserved[4];
} vendor_specific_out;
struct _req_vendor_specific_in {
uint32_t transferSize;
uint8_t reserved[4];
} req_vendor_specific_in;
struct _vendor_specific_in {
uint32_t transferSize;
uint8_t reserved[4];
} vendor_specific_in;
uint8_t raw[8];
} command_specific;
//8 12个
}USBTMC_Header_t;
/* Table 2, MsgId values */
//#define USB_TMC_MSGID_OUT_DEV_DEP_MSG_OUT 1
//#define USB_TMC_MSGID_OUT_REQUEST_DEV_DEP_MSG_IN 2
//#define USB_TMC_MSGID_IN_DEV_DEP_MSG_IN 2
#define USBTMC_MSG_OUT 1
#define USBTMC_OUT_REQUEST_MSG_IN 2
#define USBTMC_IN__MSG_IN 2
/* 3-125 Reserved for USBTMC */
#define USB_TMC_MSGID_OUT_VENDOR_SPECIFIC_OUT 126
#define USB_TMC_MSGID_OUT_REQUEST_VENDOR_SPECIFIC_IN 127
#define USB_TMC_MSGID_IN_VENDOR_SPECIFIC_IN 127
#define USB_TMC_MSGID_OUT_TRIGGER 128 // usb488.2子集用
/* 128-255 Reserved for USBTMC subclass and VISA */
/* long lines are gross, but consistent naming wins? */
#define USB_TMC_BULK_HEADER_BMTRANSFER_ATTRIB_EOM (1<<0)
#define USB_TMC_BULK_HEADER_BMTRANSFER_ATTRIB_TERMCHAR (1<<1)
3. 通过串口发送命令测试,测试仪器为一泰克示波器