📄 vcomsys.c
字号:
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright (c) Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "Driver\DrvUSB.h"
#include "USB\VCOMSys.h"
#include "VCOM_API.h"
//#define DEBUG
#ifdef DEBUG
# define DBG_PRINTF printf
#else
# define DBG_PRINTF(...)
#endif
#define Maximum(a,b) ((a)>(b) ? (a) : (b))
#define Minimum(a,b) ((a)<(b) ? (a) : (b))
/* Endpoint description */
S_DRVUSB_EP_CTRL sEpDescription[] =
{
{CTRL_EP_NUM | EP_INPUT, VCOM_CTRL_MXPLD, NULL},
{CTRL_EP_NUM | EP_OUTPUT, VCOM_CTRL_MXPLD, NULL},
{BULK_IN_EP_NUM | EP_INPUT, BULK_EP_MXPLD, NULL},
{BULK_OUT_EP_NUM| EP_OUTPUT, BULK_EP_MXPLD, NULL},
{INT_IN_EP_NUM | EP_INPUT, INT_EP_MXPLD, NULL},
{0,0,0}
};
/* Bus event call back functions */
S_DRVUSB_EVENT_PROCESS g_sBusOps[6] =
{
{NULL, NULL}, /* Attach event callback */
{NULL, NULL}, /* Detach event callback */
{DrvUSB_BusResetCallback, &gsVcomDevice}, /* Bus reset event callback */
{NULL, NULL}, /* Bus suspend event callback */
{NULL, NULL}, /* Bus resume event callback */
{DrvUSB_CtrlSetupAck, &gsVcomDevice}, /* Setup event callback */
};
/* USB event call back functions */
S_DRVUSB_EVENT_PROCESS g_sUsbOps[12] =
{
{DrvUSB_CtrlDataInAck, &gsVcomDevice},
{DrvUSB_CtrlDataOutAck, &gsVcomDevice},
{VCOM_BulkInAckCallback, &gsVcomDevice},
{NULL, NULL},
{NULL, NULL},
{VCOM_BulkOutAckCallback, &gsVcomDevice},
{VCOM_IntInAckCallback, &gsVcomDevice},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
};
/* ctrl pipe call back. */
/* it will be call by DrvUSB_CtrlSetupAck, DrvUSB_CtrlDataInAck and DrvUSB_CtrlDataOutAck */
/* if in ack handler and out ack handler is 0, default handler will be called */
S_DRVUSB_CTRL_CALLBACK_ENTRY g_asCtrlCallbackEntry[] = {
//request type,command ,setup ack handler , in ack handler ,out ack handler, parameter
{REQ_STANDARD, SET_ADDRESS, DrvUSB_CtrlSetupSetAddress, DrvUSB_CtrlDataInSetAddress, 0, &gsVcomDevice},
{REQ_STANDARD, CLEAR_FEATURE, DrvUSB_CtrlSetupClearSetFeature, 0, 0, &gsVcomDevice},
{REQ_STANDARD, SET_FEATURE, DrvUSB_CtrlSetupClearSetFeature, 0, 0, &gsVcomDevice},
{REQ_STANDARD, GET_CONFIGURATION, DrvUSB_CtrlSetupGetConfiguration, 0, 0, &gsVcomDevice},
{REQ_STANDARD, GET_STATUS, DrvUSB_CtrlSetupGetStatus, 0, 0, &gsVcomDevice},
{REQ_STANDARD, GET_INTERFACE, DrvUSB_CtrlSetupGetInterface, 0, 0, &gsVcomDevice},
{REQ_STANDARD, SET_INTERFACE, DrvUSB_CtrlSetupSetInterface, 0, 0, &gsVcomDevice},
{REQ_STANDARD, GET_DESCRIPTOR, VCOM_CtrlSetupGetDescriptor, VCOM_CtrlDataInGetDescriptor, 0, &gsVcomDevice},
{REQ_STANDARD, SET_CONFIGURATION, VCOM_CtrlSetupSetConfiguration, 0, 0, &gsVcomDevice},
{REQ_CLASS, SET_LINE_CODE, VCOM_SetLineCoding, 0, VCOM_SetLineCodingDataOut, &gsVcomDevice},
{REQ_CLASS, GET_LINE_CODE, VCOM_GetLineCoding, 0, 0, &gsVcomDevice},
{REQ_CLASS, SET_CONTROL_LINE_STATE, VCOM_CtrlLineState, 0, 0, &gsVcomDevice}
};
S_VCOM_DEVICE gsVcomDevice;
//the structure registered to USB driver
S_DRVUSB_CLASS sVcomClass =
{
(void*)&gsVcomDevice,
NULL,
NULL
};
/* Line coding structure
0-3 dwDTERate Data terminal rate (baudrate), in bits per second
4 bCharFormat Stop bits: 0 - 1 Stop bit, 1 - 1.5 Stop bits, 2 - 2 Stop bits
5 bParityType Parity: 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space
6 bDataBits Data bits: 5, 6, 7, 8, 16 */
typedef struct {
uint32_t u32DTERate; /* Baud rate */
uint8_t u8CharFormat; /* stop bit */
uint8_t u8ParityType; /* parity */
uint8_t u8DataBits; /* data bits */
} S_VCOM_LINE_CODING;
//S_VCOM_LINE_CODING gLineCoding = {0};
S_VCOM_LINE_CODING gLineCoding = {115200, 0, 0, 8}; /* Baud rate : 115200 */
/* Stop bit */
/* parity */
/* data bits */
uint16_t gCtrlSignal = 0; /* BIT0: DTR(Data Terminal Ready) , BIT1: RTS(Request To Send) */
/* To handle the data transfer size > maximum packet size */
static uint16_t gu16TransferLen = 0;
static uint16_t gu16PacketLen = 0;
static uint16_t gu16TransferIndex = 0;
/*---------------------------------------------------------------------------------------------------------*/
/* Function: VCOM_CtrlDataInGetDescriptor */
/* */
/* Parameters: */
/* pVoid - [in], A pointer to USB class device structure (gsVcomDevice). */
/* */
/* Returns: */
/* None */
/* */
/* Description: */
/* The USB get descriptor data in event callback function. */
/*---------------------------------------------------------------------------------------------------------*/
void VCOM_CtrlDataInGetDescriptor(void* pVoid)
{
S_DRVUSB_DEVICE *psDevice = &gsUsbDevice;
if (psDevice->au8Setup[0] & 0x80)
{
if(gu16TransferLen)
{
if(gu16TransferLen >= gu16PacketLen)
{
DrvUSB_DataIn(0, gau8ConfigDescriptor + gu16TransferIndex, gu16PacketLen);
gu16TransferLen -= gu16PacketLen;
gu16TransferIndex += gu16PacketLen;
}
else
{
DrvUSB_DataIn(0, gau8ConfigDescriptor + gu16TransferIndex, gu16TransferLen);
gu16TransferLen = 0;
}
if (gu16TransferLen == 0)
_DRVUSB_TRIG_EP(1, 0x00); //Ctl data out
}
else
{
_DRVUSB_TRIG_EP(1, 0x00);
}
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: VCOM_CtrlSetupGetDescriptor */
/* */
/* Parameters: */
/* pVoid - [in], A pointer to USB class device structure (gsVcomDevice). */
/* */
/* Returns: */
/* None */
/* */
/* Description: */
/* The USB get descriptor event callback function. */
/*---------------------------------------------------------------------------------------------------------*/
void VCOM_CtrlSetupGetDescriptor(void* pVoid)
{
S_VCOM_DEVICE *psVcomDevice = (S_VCOM_DEVICE *)pVoid;
S_DRVUSB_DEVICE *psDevice = (S_DRVUSB_DEVICE *)psVcomDevice->device;
uint16_t u16Len, u16ConfigLen;
u16Len = 0;
u16Len = psDevice->au8Setup[7];
u16Len <<= 8;
u16Len += psDevice->au8Setup[6];
switch (psDevice->au8Setup[3])
{
/* Get Device Descriptor */
case DESC_DEVICE:
{
u16Len = Minimum(u16Len, LEN_DEVICE);
DrvUSB_DataIn(0, psVcomDevice->au8DeviceDescriptor, u16Len);
break;
}
/* Get Configuration Descriptor */
case DESC_CONFIG:
{
u16ConfigLen = psVcomDevice->au8ConfigDescriptor[3];
u16ConfigLen <<= 8;
u16ConfigLen |= psVcomDevice->au8ConfigDescriptor[2];
gu16TransferLen = Minimum(u16Len, u16ConfigLen);
gu16PacketLen = 64;
gu16TransferIndex = 0;
if(gu16TransferLen > gu16PacketLen)
{
DrvUSB_DataIn(0, psVcomDevice->au8ConfigDescriptor + gu16TransferIndex, gu16PacketLen);
gu16TransferLen -= gu16PacketLen;
gu16TransferIndex += gu16PacketLen;
}
else
{
DrvUSB_DataIn(0, psVcomDevice->au8ConfigDescriptor + gu16TransferIndex, gu16TransferLen);
gu16TransferLen = 0;
}
break;
}
/* Get String Descriptor */
case DESC_STRING:
{
/* Get Language */
if (psDevice->au8Setup[2] == 0)
{
u16Len = Minimum(u16Len, 4);
DrvUSB_DataIn(0, gau8StringLang, u16Len);
}
else
{
/* Get String Descriptor */
switch (psDevice->au8Setup[2])
{
case 1:
u16Len = Minimum(u16Len, psVcomDevice->sVendorStringDescriptor[0]);
DrvUSB_DataIn(0, (const uint8_t *)psVcomDevice->sProductStringDescriptor, u16Len);
break;
case 2:
u16Len = Minimum(u16Len, psVcomDevice->sProductStringDescriptor[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -