正点原子IM6基于SDK2.2 > USB替代串口
#include "fsl_iomuxc.h"
#include "fsl_uart.h"
#include "usb_device_config.h"
#include "usb.h"
#include "usb_misc.h"
#include "usb_osa.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_cdc_acm.h"
#include "usb_device_dci.h"
#include "usb_device_descriptor.h"
#include "usb_phy.h"
#include "td_usb_s_com.h"
#include "td_ledkeybeep.h"
#include "td_lcd_ui_manager.h"
#define Usb1Ep0In USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)
#define Usb1Ep0Out USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)
#define Usb1EpXIn(x) (x | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
#define Usb1EpXOut(x) (x | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
typedef struct _usb_cdc_vcom_struct
{
usb_device_handle deviceHandle;
class_handle_t cdcAcmHandle;
volatile uint8_t attach;
uint8_t speed;
volatile uint8_t startTransactions;
uint8_t currentConfiguration;
uint8_t currentInterfaceAlternateSetting[USB_CDC_VCOM_INTERFACE_COUNT];
} usb_cdc_vcom_struct_t;
typedef struct _usb_cdc_acm_info
{
uint8_t serialStateBuf[8 + 2];
bool dtePresent;
uint16_t breakDuration;
uint8_t dteStatus;
uint8_t currentInterface;
uint16_t uartState;
} usb_cdc_acm_info_t;
volatile static uint32_t s_recvSize = 0;
volatile static uint32_t s_sendSize = 0;
USB_DATA_ALIGNMENT static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0};
USB_DATA_ALIGNMENT USB_RAM_ADDRESS_NONCACHEREG(static uint8_t s_currRecvBuf[512]);
USB_DATA_ALIGNMENT USB_RAM_ADDRESS_NONCACHEREG(static uint8_t s_currSendBuf[512]);
#define COMM_FEATURE_DATA_SIZE (0x02)
#define STATUS_ABSTRACT_STATE (0x0000)
#define COUNTRY_SETTING (0x0000)
#define NOTIF_PACKET_SIZE (0x08)
#define UART_BITMAP_SIZE (0x02)
#define NOTIF_REQUEST_TYPE (0xA1)
#define LINE_CODING_SIZE (0x07)
#define LINE_CODING_DTERATE (115200)
#define LINE_CODING_CHARFORMAT (0x00)
#define LINE_CODING_PARITYTYPE (0x00)
#define LINE_CODING_DATABITS (0x08)
static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
(LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
(LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
LINE_CODING_CHARFORMAT,
LINE_CODING_PARITYTYPE,
LINE_CODING_DATABITS};
static uint8_t s_abstractState[2] = {(0 >> 0U) & 0x00FFU, (0 >> 8U) & 0x00FFU};
static uint8_t s_countryCode[2] = {(0 >> 0U) & 0x00FFU, (0 >> 8U) & 0x00FFU};
extern usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[];
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig;
static usb_cdc_vcom_struct_t s_cdcVcom;
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig;
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param);
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{
USB_DeviceCdcVcomCallback, 0, &g_UsbDeviceCdcVcomConfig,
}};
static usb_device_class_config_list_struct_t s_cdcAcmConfigList = {
s_cdcAcmConfig, USB_DeviceCallback, 1,
};
static void USBHS_IRQHandler(uint32_t giccIar, void *param);
void TD_USBSCom_Init(void)
{
SystemInstallIrqHandler(USB_OTG1_IRQn, USBHS_IRQHandler, NULL);
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
usb_phy_config_struct_t phyConfig = { 0x0CU, 0x06U, 0x06U, };
usb_status_t error = (usb_status_t)USB_EhciPhyInit(kUSB_ControllerEhci0, 0, &phyConfig);
if (kStatus_USB_Success != error)
{
USB_EhciPhyDeinit(kUSB_ControllerEhci0);
return;
}
s_cdcVcom.speed = USB_SPEED_FULL;
s_cdcVcom.attach = 0;
s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL;
s_cdcVcom.deviceHandle = NULL;
error = USB_DeviceClassInit(kUSB_ControllerEhci0, &s_cdcAcmConfigList, &s_cdcVcom.deviceHandle);
if (kStatus_USB_Success != error) return;
s_cdcVcom.cdcAcmHandle = s_cdcAcmConfigList.config->classHandle;
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority(USB_OTG1_IRQn, 3);
#else
NVIC_SetPriority(USB_OTG1_IRQn, 3);
#endif
EnableIRQ(USB_OTG1_IRQn);
USB_DeviceRun(s_cdcVcom.deviceHandle);
usb_echo("11start\r\n");
}
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_Error;
uint16_t *temp16 = (uint16_t *)param;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
s_cdcVcom.attach = 0;
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
if (kStatus_USB_Success == USB_DeviceClassGetSpeed(kUSB_ControllerEhci0, &s_cdcVcom.speed))
{
USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
}
#endif
}
break;
case kUSB_DeviceEventSetConfiguration:
if (param)
{
s_cdcVcom.attach = 1;
usb_echo("attach\r\n");
s_cdcVcom.currentConfiguration = *temp8;
if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
{
USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
}
}
break;
case kUSB_DeviceEventSetInterface:
if (s_cdcVcom.attach)
{
uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);
uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);
if (interface < USB_CDC_VCOM_INTERFACE_COUNT)
{
s_cdcVcom.currentInterfaceAlternateSetting[interface] = alternateSetting;
}
}
break;
case kUSB_DeviceEventGetConfiguration:
break;
case kUSB_DeviceEventGetInterface:
break;
case kUSB_DeviceEventGetDeviceDescriptor:
if (param)
{
error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetConfigurationDescriptor:
if (param)
{
error = USB_DeviceGetConfigurationDescriptor(handle,
(usb_device_get_configuration_descriptor_struct_t *)param);
}
break;
case kUSB_DeviceEventGetStringDescriptor:
if (param)
{
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
}
break;
default:
break;
}
return error;
}
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param)
{
uint32_t len;
uint16_t *uartBitmap;
usb_device_cdc_acm_request_param_struct_t *acmReqParam;
usb_device_endpoint_callback_message_struct_t *epCbParam;
usb_status_t error = kStatus_USB_Error;
usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param;
epCbParam = (usb_device_endpoint_callback_message_struct_t *)param;
switch (event)
{
case kUSB_DeviceCdcEventSendResponse:
{
if ((epCbParam->length != 0) && (!(epCbParam->length % g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize)))
{
error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
}
else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0)))
{
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
#endif
}
}
else
{
}
}
break;
case kUSB_DeviceCdcEventRecvResponse:
{
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
s_recvSize = epCbParam->length;
usb_echo("4444232\r\n");
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
s_waitForDataReceive = 0;
USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
#endif
if (!s_recvSize)
{
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
#endif
}
}
}
break;
case kUSB_DeviceCdcEventSerialStateNotif:
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSendEncapsulatedCommand:
break;
case kUSB_DeviceCdcEventGetEncapsulatedResponse:
break;
case kUSB_DeviceCdcEventSetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_abstractState;
}
else
{
*(acmReqParam->length) = 0;
}
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_countryCode;
}
else
{
*(acmReqParam->length) = 0;
}
}
else
{
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventGetCommFeature:
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = s_abstractState;
*(acmReqParam->length) = 2;
}
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
{
*(acmReqParam->buffer) = s_countryCode;
*(acmReqParam->length) = 2;
}
else
{
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventClearCommFeature:
break;
case kUSB_DeviceCdcEventGetLineCoding:
*(acmReqParam->buffer) = s_lineCoding;
*(acmReqParam->length) = LINE_CODING_SIZE;
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSetLineCoding:
{
if (1 == acmReqParam->isSetup)
{
*(acmReqParam->buffer) = s_lineCoding;
}
else
{
*(acmReqParam->length) = 0;
}
}
error = kStatus_USB_Success;
break;
case kUSB_DeviceCdcEventSetControlLineState:
{
s_usbCdcAcmInfo.dteStatus = acmReqParam->setupValue;
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
}
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
else
{
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
}
acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE;
acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE;
acmInfo->serialStateBuf[2] = 0x00;
acmInfo->serialStateBuf[3] = 0x00;
acmInfo->serialStateBuf[4] = 0x00;
acmInfo->serialStateBuf[5] = 0x00;
acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE;
acmInfo->serialStateBuf[7] = 0x00;
acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex;
uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
*uartBitmap = acmInfo->uartState;
len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState)
{
error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
if (kStatus_USB_Success != error)
{
usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
}
((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1;
}
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
{
}
else
{
}
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
{
if (1 == s_cdcVcom.attach)
{
usb_echo("start1\r\n");
s_cdcVcom.startTransactions = 1;
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
s_waitForDataReceive = 1;
USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
s_comOpen = 1;
usb_echo("USB_APP_CDC_DTE_ACTIVATED\r\n");
#endif
}
}
else
{
if (1 == s_cdcVcom.attach)
{
usb_echo("start1\r\n");
s_cdcVcom.startTransactions = 0;
}
}
}
break;
case kUSB_DeviceCdcEventSendBreak:
break;
default:
break;
}
return error;
}
/***************************************************************************************************************************
说明:将窄字节变成宽字节
****************************************************************************************************************************/
static unsigned char CopyCharToWord(unsigned char* pch,unsigned short* pwd,unsigned char len)
{
unsigned char lenth = 2 + len * 2;
*pwd++ = (0x03 << 8) | (2 + len * 2);//生成长度和字符串描述表标记
while(len--) *pwd++ = *pch++;
return lenth;
}
/**********************************************************************************
串口命令处理
**********************************************************************************/
extern void USB_DeviceEhciIsrFunction(void *deviceHandle);
void USBHS_IRQHandler(uint32_t giccIar, void *param)
{
USB_DeviceEhciIsrFunction(s_cdcVcom.deviceHandle);
}
/**********************************************************************************
串口命令处理
**********************************************************************************/
void TD_USBSCom_Server(void)
{
usb_status_t error = kStatus_USB_Error;
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
usb_echo("ttt\r\n");
/* User Code */
if ((0 != s_recvSize) && (0xFFFFFFFFU != s_recvSize))
{
int32_t i;
/* Copy Buffer to Send Buff */
for (i = 0; i < s_recvSize; i++)
{
s_currSendBuf[s_sendSize++] = s_currRecvBuf[i];
}
s_recvSize = 0;
usb_echo("resesss\r\n");
}
if (s_sendSize)
{
uint32_t size = s_sendSize;
s_sendSize = 0;
error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);
if (error != kStatus_USB_Success)
{
/* Failure to send Data Handling code here */
}
}
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
if ((s_waitForDataReceive))
{
if (s_comOpen == 1)
{
/* Wait for all the packets been sent during opening the com port. Otherwise these packets may
* wake up the system.
*/
usb_echo("Waiting to enter lowpower ...\r\n");
for (uint32_t i = 0U; i < 16000000U; ++i)
{
__ASM("NOP"); /* delay */
}
s_comOpen = 0;
}
usb_echo("Enter lowpower\r\n");
BOARD_DbgConsole_Deinit();
USB0->INTEN &= ~USB_INTEN_TOKDNEEN_MASK;
SMC_SetPowerModeVlps(SMC);
s_waitForDataReceive = 0;
USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
BOARD_DbgConsole_Init();
usb_echo("Exit lowpower\r\n");
}
#endif
}
}
/**********************************************************************************
单独线程方式运行
**********************************************************************************/
void TD_USBSCom_Run(void)
{
TD_USBSCom_Init();
while(1) TD_USBSCom_Server();
}