mirror of https://github.com/XIVN1987/DAPLink
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
12 KiB
501 lines
12 KiB
/********************************** (C) COPYRIGHT ******************************* |
|
* File Name : usb_prop.c |
|
* Author : WCH |
|
* Version : V1.0.0 |
|
* Date : 2021/08/08 |
|
* Description : All processing related to Virtual Com Port Demo |
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*******************************************************************************/ |
|
#include <stdlib.h> |
|
#include "usb_lib.h" |
|
#include "usb_conf.h" |
|
#include "usb_prop.h" |
|
#include "usb_desc.h" |
|
#include "usb_pwr.h" |
|
|
|
#include "vcom_serial.h" |
|
|
|
uint8_t Request = 0; |
|
|
|
volatile uint8_t HID_Idle_Value[2] = {0}; |
|
volatile uint8_t HID_Protocol_Value[2] = {0}; |
|
|
|
DEVICE Device_Table = |
|
{ |
|
EP_NUM, |
|
1 |
|
}; |
|
|
|
DEVICE_PROP Device_Property = |
|
{ |
|
USBD_init, |
|
USBD_Reset, |
|
USBD_Status_In, |
|
USBD_Status_Out, |
|
USBD_Data_Setup, |
|
USBD_NoData_Setup, |
|
USBD_Get_Interface_Setting, |
|
USBD_GetDeviceDescriptor, |
|
USBD_GetConfigDescriptor, |
|
USBD_GetStringDescriptor, |
|
0, |
|
USB_MAX_EP0_SZ |
|
}; |
|
|
|
USER_STANDARD_REQUESTS User_Standard_Requests = |
|
{ |
|
USBD_GetConfiguration, |
|
USBD_SetConfiguration, |
|
USBD_GetInterface, |
|
USBD_SetInterface, |
|
USBD_GetStatus, |
|
USBD_ClearFeature, |
|
USBD_SetEndPointFeature, |
|
USBD_SetDeviceFeature, |
|
USBD_SetDeviceAddress |
|
}; |
|
|
|
ONE_DESCRIPTOR Device_Descriptor = |
|
{ |
|
(uint8_t*)USBD_DeviceDescriptor, |
|
USBD_SIZE_DEVICE_DESC |
|
}; |
|
|
|
ONE_DESCRIPTOR Config_Descriptor = |
|
{ |
|
(uint8_t*)USBD_ConfigDescriptor, |
|
USBD_SIZE_CONFIG_TOTAL |
|
}; |
|
|
|
ONE_DESCRIPTOR String_Descriptor[4] = |
|
{ |
|
{(uint8_t*)USBD_StringLangID, USBD_SIZE_STRING_LANGID}, |
|
{(uint8_t*)USBD_StringVendor, USBD_SIZE_STRING_VENDOR}, |
|
{(uint8_t*)USBD_StringProduct,USBD_SIZE_STRING_PRODUCT}, |
|
{(uint8_t*)USBD_StringSerial, USBD_SIZE_STRING_SERIAL} |
|
}; |
|
|
|
ONE_DESCRIPTOR Report_Descriptor[1] = |
|
{ |
|
{(uint8_t*)USBD_HidRepDesc, USBD_SIZE_REPORT_DESC}, |
|
}; |
|
|
|
ONE_DESCRIPTOR Hid_Descriptor[1] = |
|
{ |
|
{(uint8_t*)&USBD_ConfigDescriptor[93], 0x09}, |
|
}; |
|
/********************************************************************* |
|
* @fn USBD_SetConfiguration. |
|
* |
|
* @brief Update the device state to configured. |
|
* |
|
* @return None. |
|
*/ |
|
void USBD_SetConfiguration(void) |
|
{ |
|
DEVICE_INFO *pInfo = &Device_Info; |
|
|
|
if (pInfo->Current_Configuration != 0) |
|
{ |
|
bDeviceState = CONFIGURED; |
|
} |
|
} |
|
|
|
/******************************************************************************* |
|
* @fn USBD_SetDeviceAddress. |
|
* |
|
* @brief Update the device state to addressed. |
|
* |
|
* @return None. |
|
*/ |
|
void USBD_SetDeviceAddress (void) |
|
{ |
|
bDeviceState = ADDRESSED; |
|
} |
|
|
|
|
|
/********************************************************************* |
|
* @fn USBD_SetDeviceFeature. |
|
* |
|
* @brief SetDeviceFeature Routine. |
|
* |
|
* @return none |
|
*/ |
|
void USBD_SetDeviceFeature (void) |
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
/********************************************************************* |
|
* @fn USBD_ClearFeature. |
|
* |
|
* @brief ClearFeature Routine. |
|
* |
|
* @return none |
|
*/ |
|
void USBD_ClearFeature(void) |
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************* |
|
* @fn USBD_Status_In. |
|
* |
|
* @brief USBD Status In Routine. |
|
* |
|
* @return None. |
|
*/ |
|
void USBD_Status_In(void) |
|
{ |
|
uint32_t Request_No = pInformation->USBbRequest; |
|
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) |
|
{ |
|
if (Request_No == CDC_SET_LINE_CODING) |
|
{ |
|
VCOM_LineCoding(&LineCfg); |
|
} |
|
} |
|
} |
|
|
|
/******************************************************************************* |
|
* @fn USBD_Status_Out |
|
* |
|
* @brief USBD Status OUT Routine. |
|
* |
|
* @return None. |
|
*/ |
|
void USBD_Status_Out(void) |
|
{ |
|
|
|
} |
|
|
|
/******************************************************************************* |
|
* @fn USBD_init. |
|
* |
|
* @brief init routine. |
|
* |
|
* @return None. |
|
*/ |
|
void USBD_init(void) |
|
{ |
|
uint8_t i; |
|
|
|
pInformation->Current_Configuration = 0; |
|
PowerOn(); |
|
for (i=0;i<8;i++) _SetENDPOINT(i,_GetENDPOINT(i) & 0x7F7F & EPREG_MASK);//all clear |
|
_SetISTR((uint16_t)0x00FF);//all clear |
|
USB_SIL_Init(); |
|
bDeviceState = UNCONNECTED; |
|
|
|
USB_Port_Set(DISABLE, DISABLE); |
|
Delay_Ms(20); |
|
USB_Port_Set(ENABLE, ENABLE); |
|
} |
|
|
|
/******************************************************************************* |
|
* @fn USBD_Reset |
|
* |
|
* @brief USBD reset routine |
|
* |
|
* @return none |
|
*/ |
|
void USBD_Reset(void) |
|
{ |
|
pInformation->Current_Configuration = 0; |
|
pInformation->Current_Feature = USBD_ConfigDescriptor[7]; |
|
pInformation->Current_Interface = 0; |
|
|
|
SetBTABLE(BTABLE_ADDRESS); |
|
|
|
/* Initialize Endpoint 0 */ |
|
SetEPType(ENDP0, EP_CONTROL); |
|
SetEPTxAddr(ENDP0, ENDP0_TXADDR); |
|
SetEPRxAddr(ENDP0, ENDP0_RXADDR); |
|
SetEPTxCount(ENDP0, Device_Property.MaxPacketSize); |
|
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); |
|
SetEPTxStatus(ENDP0, EP_TX_STALL); |
|
SetEPRxStatus(ENDP0, EP_RX_VALID); |
|
_ClearDTOG_RX(ENDP0); |
|
_ClearDTOG_TX(ENDP0); |
|
|
|
/* Initialize Endpoint 1 */ |
|
SetEPType(ENDP1, EP_INTERRUPT); |
|
SetEPTxAddr(ENDP1, ENDP1_TXADDR); |
|
SetEPRxAddr(ENDP1, ENDP1_RXADDR); |
|
SetEPTxCount(ENDP1, HID_INT_IN_SZ); |
|
SetEPRxCount(ENDP1, HID_INT_OUT_SZ); |
|
SetEPTxStatus(ENDP1, EP_TX_NAK); |
|
SetEPRxStatus(ENDP1, EP_RX_VALID); |
|
_ClearDTOG_TX(ENDP1); |
|
_ClearDTOG_RX(ENDP1); |
|
|
|
/* Initialize Endpoint 2 */ |
|
SetEPType(ENDP2, EP_INTERRUPT); |
|
SetEPTxAddr(ENDP2, ENDP2_TXADDR); |
|
SetEPTxCount(ENDP2, CDC_INT_IN_SZ); |
|
SetEPTxStatus(ENDP2, EP_TX_NAK); |
|
SetEPRxStatus(ENDP2, EP_RX_DIS); |
|
_ClearDTOG_TX(ENDP1); |
|
|
|
/* Initialize Endpoint 3 */ |
|
SetEPType(ENDP3, EP_BULK); |
|
SetEPTxAddr(ENDP3, ENDP3_TXADDR); |
|
SetEPRxAddr(ENDP3, ENDP3_RXADDR); |
|
SetEPTxCount(ENDP3, CDC_BULK_IN_SZ); |
|
SetEPRxCount(ENDP3, CDC_BULK_OUT_SZ); |
|
SetEPTxStatus(ENDP3, EP_TX_NAK); |
|
SetEPRxStatus(ENDP3, EP_RX_VALID); |
|
_ClearDTOG_TX(ENDP3); |
|
_ClearDTOG_RX(ENDP3); |
|
|
|
SetDeviceAddress(0); |
|
|
|
bDeviceState = ATTACHED; |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_GetDeviceDescriptor. |
|
* |
|
* @brief Gets the device descriptor. |
|
* |
|
* @param Length. |
|
* |
|
* @return The address of the device descriptor. |
|
*/ |
|
uint8_t *USBD_GetDeviceDescriptor(uint16_t Length) |
|
{ |
|
return Standard_GetDescriptorData(Length, &Device_Descriptor); |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_GetConfigDescriptor. |
|
* |
|
* @brief get the configuration descriptor. |
|
* |
|
* @param Length. |
|
* |
|
* @return The address of the configuration descriptor. |
|
*/ |
|
uint8_t *USBD_GetConfigDescriptor(uint16_t Length) |
|
{ |
|
return Standard_GetDescriptorData(Length, &Config_Descriptor); |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_GetStringDescriptor |
|
* |
|
* @brief Gets the string descriptors according to the needed index |
|
* |
|
* @param Length. |
|
* |
|
* @return The address of the string descriptors. |
|
*/ |
|
uint8_t *USBD_GetStringDescriptor(uint16_t Length) |
|
{ |
|
uint8_t wValue0 = pInformation->USBwValue0; |
|
|
|
if (wValue0 > 4) |
|
{ |
|
return NULL; |
|
} |
|
else |
|
{ |
|
return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]); |
|
} |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_GetReportDescriptor |
|
* |
|
* @brief Gets the report descriptors according to the needed index |
|
* |
|
* @param Length. |
|
* |
|
* @return The address of the device descriptor. |
|
*/ |
|
uint8_t *USBD_GetReportDescriptor(uint16_t Length) |
|
{ |
|
return Standard_GetDescriptorData(Length, &Report_Descriptor[0]); |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_GetHidDescriptor |
|
* |
|
* @brief Gets the report descriptors according to the needed index |
|
* |
|
* @param Length. |
|
* |
|
* @return The address of the device descriptor. |
|
*/ |
|
uint8_t *USBD_GetHidDescriptor(uint16_t Length) |
|
{ |
|
return Standard_GetDescriptorData(Length, &Hid_Descriptor[0]); |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_Get_Interface_Setting. |
|
* |
|
* @brief test the interface and the alternate setting according to the |
|
* supported one. |
|
* |
|
* @param Interface - interface number. |
|
* AlternateSetting - Alternate Setting number. |
|
* |
|
* @return USB_UNSUPPORT or USB_SUCCESS. |
|
*/ |
|
RESULT USBD_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting) |
|
{ |
|
if (AlternateSetting > 0) |
|
{ |
|
return USB_UNSUPPORT; |
|
} |
|
else if (Interface > 1) |
|
{ |
|
return USB_UNSUPPORT; |
|
} |
|
|
|
return USB_SUCCESS; |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USB_CDC_GetLineCoding. |
|
* |
|
* @brief send the linecoding structure to the PC host. |
|
* |
|
* @param Length |
|
* |
|
* @return Inecoding structure base address. |
|
*/ |
|
uint8_t *USB_CDC_GetLineCoding( uint16_t Length ) |
|
{ |
|
if( Length == 0 ) |
|
{ |
|
pInformation->Ctrl_Info.Usb_wLength = 7; |
|
return( NULL ); |
|
} |
|
return (uint8_t *)&LineCfg; |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USB_CDC_SetLineCoding. |
|
* |
|
* @brief Set the linecoding structure fields. |
|
* |
|
* @param Length |
|
* |
|
* @return Inecoding structure base address. |
|
*/ |
|
uint8_t *USB_CDC_SetLineCoding( uint16_t Length ) |
|
{ |
|
if( Length == 0 ) |
|
{ |
|
pInformation->Ctrl_Info.Usb_wLength = 7; |
|
return( NULL ); |
|
} |
|
return (uint8_t *)&LineCfg; |
|
} |
|
|
|
|
|
/********************************************************************* |
|
* @fn USBD_Data_Setup |
|
* |
|
* @brief handle the data class specific requests |
|
* |
|
* @param Request Nb. |
|
* |
|
* @return USB_UNSUPPORT or USB_SUCCESS. |
|
*/ |
|
RESULT USBD_Data_Setup(uint8_t RequestNo) |
|
{ |
|
uint32_t Request_No; |
|
uint8_t *(*CopyRoutine)(uint16_t); |
|
uint8_t wValue1; |
|
Request_No = pInformation->USBbRequest; |
|
CopyRoutine = NULL; |
|
wValue1 = pInformation->USBwValue1; |
|
if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) |
|
{ |
|
if (wValue1 == HID_REPORT_DESCRIPTOR) |
|
{ |
|
CopyRoutine = USBD_GetReportDescriptor; |
|
} |
|
else if (wValue1 == HID_DESCRIPTOR) |
|
{ |
|
CopyRoutine = USBD_GetHidDescriptor; |
|
} |
|
if (CopyRoutine) |
|
{ |
|
pInformation->Ctrl_Info.CopyData = CopyRoutine; |
|
(*CopyRoutine)(0); |
|
} |
|
else |
|
{ |
|
return USB_UNSUPPORT; |
|
} |
|
|
|
} |
|
else if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) |
|
{ |
|
if (Request_No == CDC_GET_LINE_CODING) |
|
{ |
|
CopyRoutine = &USB_CDC_GetLineCoding; |
|
} |
|
else if (Request_No == CDC_SET_LINE_CODING) |
|
{ |
|
CopyRoutine = &USB_CDC_SetLineCoding; |
|
} |
|
else |
|
{ |
|
return USB_UNSUPPORT; |
|
} |
|
} |
|
if (CopyRoutine) |
|
{ |
|
pInformation->Ctrl_Info.CopyData = CopyRoutine; |
|
pInformation->Ctrl_Info.Usb_wOffset = 0; |
|
(*CopyRoutine)( 0 ); |
|
} |
|
else |
|
{ |
|
return( USB_UNSUPPORT ); |
|
} |
|
return USB_SUCCESS; |
|
} |
|
|
|
/********************************************************************* |
|
* @fn USBD_NoData_Setup. |
|
* |
|
* @brief handle the no data class specific requests. |
|
* |
|
* @param Request Nb. |
|
* |
|
* @return USB_UNSUPPORT or USB_SUCCESS. |
|
*/ |
|
RESULT USBD_NoData_Setup(uint8_t RequestNo) |
|
{ |
|
uint32_t Request_No = pInformation->USBbRequest; |
|
|
|
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) |
|
{ |
|
if (Request_No == CDC_SET_LINE_CTLSTE) |
|
{ |
|
|
|
} |
|
else if (Request_No == CDC_SEND_BREAK) |
|
{ |
|
|
|
} |
|
else |
|
{ |
|
return USB_UNSUPPORT; |
|
} |
|
} |
|
return USB_SUCCESS; |
|
}
|
|
|