initial check in based on SVN revision 575
This commit is contained in:
413
source/USB/usbComms.c
Normal file
413
source/USB/usbComms.c
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* usbComms.c
|
||||
*
|
||||
* Created on: May 17, 2023
|
||||
* Author: Brian.Bailey
|
||||
*/
|
||||
|
||||
/*
|
||||
* USB Comms
|
||||
* Data is received by APP_and placed in rxBuffer[]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
//Drivers
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_debug_console.h"
|
||||
#include "pin_mux.h"
|
||||
#include "clock_config.h"
|
||||
#include "board.h"
|
||||
|
||||
//Application Includes
|
||||
#include "virtual_com.h"
|
||||
#include "flashUpdate.h"
|
||||
#include "bootloader.h"
|
||||
#include "eeprom.h"
|
||||
#include "System/system.h"
|
||||
#include "frq.h"
|
||||
#include "hwFixes.h"
|
||||
|
||||
#include "usbComms.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define USB_DETECT_PORT 1 //USB VBUS on GPIO1_6. Not sure we can read this
|
||||
#define USB_DETECT_PIN 6
|
||||
|
||||
|
||||
#define CR '\r' //carriage return
|
||||
#define LF '\n' //line feed
|
||||
#define null 0 //NULL is defined at (void *)0 so it causes errors
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
USB_t usb;
|
||||
extern SYSTEM_DATA_t sys;
|
||||
|
||||
|
||||
extern BL_DATA_t blData;
|
||||
extern usb_cdc_vcom_struct_t s_cdcVcom;
|
||||
extern uint8_t frq_update_flag;
|
||||
extern HARDWARE_FIX_t hwf;
|
||||
|
||||
|
||||
|
||||
//temp storage for string data
|
||||
uint8_t usbTempString[USB_RX_BUFFER_SIZE];
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Functions
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Public Functions
|
||||
******************************************************************************/
|
||||
|
||||
uint8_t USB_IsConnected(void)
|
||||
{
|
||||
return GPIO_PinRead(GPIO, USB_DETECT_PORT, USB_DETECT_PIN);
|
||||
}
|
||||
|
||||
|
||||
/* Process incoming USB string
|
||||
* Commands are LF terminated ASCII text
|
||||
* @param size number of bytes to process
|
||||
*/
|
||||
void USB_ProcessString(uint32_t size)
|
||||
{
|
||||
//operates on usb.rxDataBuffer[]
|
||||
//index is usb.rxCommandIndex
|
||||
|
||||
uint32_t usbBusyCount = 0;
|
||||
|
||||
usb.rxStringReceived = false;
|
||||
for(uint32_t i = 0; i < size; i++) //Look for LF character in rxDataBuffer
|
||||
{
|
||||
if(LF == usb.rxDataBuffer[i])
|
||||
{
|
||||
|
||||
usb.rxDataBuffer[i] = 0; //replace LF with NULL to terminate string
|
||||
usb.rxStringReceived = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(usb.rxStringReceived)
|
||||
{
|
||||
//Process the command
|
||||
USB_ProcessCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
//This is an error. search the ringbuffer for the next LF and throw away everything before it.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Incoming USB commands
|
||||
*/
|
||||
void USB_ProcessCommand(void)
|
||||
{
|
||||
if(USB_CommandCompare("dID")) //device ID
|
||||
{
|
||||
USB_SendString("UM_TX");
|
||||
}
|
||||
else if(USB_CommandPrefixCompare("p"))
|
||||
{
|
||||
USB_ProcessProgramCommand();
|
||||
}
|
||||
else if(USB_CommandPrefixCompare("s"))
|
||||
{
|
||||
USB_ProcessSystemCommand();
|
||||
}
|
||||
else if(USB_CommandPrefixCompare("f"))
|
||||
{
|
||||
USB_ProcessFrequencyCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Bad Command
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Program commands
|
||||
*/
|
||||
void USB_ProcessProgramCommand(void)
|
||||
{
|
||||
if (USB_CommandCompare("pLoaderRunRequest")) //Request bootloader run
|
||||
{
|
||||
blData.loaderRunRequest = 1;
|
||||
EE_WriteMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest);
|
||||
|
||||
//TESTING: Verify write
|
||||
EE_ReadMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest);
|
||||
|
||||
if(blData.loaderRunRequest == 1)
|
||||
{
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("pProgramSetup,")) //Program setup information - RX can ONLY update the bootloader at 0x6000 0000
|
||||
{
|
||||
FU_ProgramSetup(usb.rxDataBuffer);
|
||||
}
|
||||
else if(USB_CommandCompare("pVerifyImage")) //verify image in FLASH - compare hashes
|
||||
{
|
||||
FU_VerifyImage();
|
||||
}
|
||||
else if(USB_CommandCompare("pReset"))
|
||||
{
|
||||
FU_ResetProcessor();
|
||||
}
|
||||
else if (USB_CommandCompare("pClearProgramFlag"))
|
||||
{
|
||||
blData.transmitterProgrammed = false;
|
||||
EE_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed);
|
||||
|
||||
//TESTING: Verify write
|
||||
EE_ReadMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed);
|
||||
|
||||
if(blData.transmitterProgrammed == false)
|
||||
{
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
|
||||
}
|
||||
else if (USB_CommandCompare("pEraseAllData")) //Erase settings and factory data. Leave bootloader data
|
||||
{
|
||||
EE_EraseAllData(); // Erase EEPROM data
|
||||
|
||||
USB_SendString(ACK);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process System commands
|
||||
*/
|
||||
void USB_ProcessSystemCommand(void)
|
||||
{
|
||||
static uint8_t *p; //pointer for strtok - static so it doesn't get optimized out.
|
||||
|
||||
if (USB_CommandPrefixCompare("sSetMfg,"))
|
||||
{
|
||||
p = strtok(usb.rxDataBuffer, ","); //points to command
|
||||
p = strtok(null, ","); //points to arg
|
||||
strncpy(sys.manufacturer, p, SYS_INFO_LENGTH);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("sSetModelNumber,"))
|
||||
{
|
||||
char* token = strtok(usb.rxDataBuffer, ",");
|
||||
token = strtok(null, ","); //points to arg
|
||||
strncpy(sys.modelNumber, token, SYS_INFO_LENGTH);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("sSetModelName,"))
|
||||
{
|
||||
char* token = strtok(usb.rxDataBuffer, ",");
|
||||
token = strtok(null, ","); //points to arg
|
||||
strncpy(sys.modelName, token, SYS_INFO_LENGTH);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("sSetSerial,"))
|
||||
{
|
||||
char* token = strtok(usb.rxDataBuffer, ",");
|
||||
token = strtok(null, ","); //points to arg
|
||||
strncpy(sys.serialNumber, token, SYS_INFO_LENGTH);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("sSetMfgDate,"))
|
||||
{
|
||||
char* token = strtok(usb.rxDataBuffer, ",");
|
||||
token = strtok(null, ","); //points to arg
|
||||
strncpy(sys.mfgDate, token, SYS_INFO_LENGTH);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("sSetHourCount,"))
|
||||
{
|
||||
//do nothing
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if(USB_CommandPrefixCompare("sSetMainPcbaPN,"))
|
||||
{
|
||||
char* token = strtok(usb.rxDataBuffer, ",");
|
||||
token = strtok(null, ","); //points to arg
|
||||
hwf.mainPcbaPN = atoi(token);
|
||||
EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN);
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandCompare("sSaveSettings"))
|
||||
{
|
||||
//Save settings data
|
||||
EE_SaveData();
|
||||
frq_update_flag = false;
|
||||
Change_To_Next_BC_Freq();
|
||||
USB_SendString(ACK);
|
||||
|
||||
}
|
||||
else if (USB_CommandCompare("sGetSwVersion"))
|
||||
{
|
||||
USB_SendString(SW_VERSION);
|
||||
}
|
||||
else if (USB_CommandCompare("sGetMfg"))
|
||||
{
|
||||
USB_SendString(sys.manufacturer);
|
||||
}
|
||||
else if (USB_CommandCompare("sGetModelNumber"))
|
||||
{
|
||||
USB_SendString(sys.modelNumber);
|
||||
}
|
||||
else if (USB_CommandCompare("sGetModelName"))
|
||||
{
|
||||
USB_SendString(sys.modelName);
|
||||
}
|
||||
else if (USB_CommandCompare("sGetSerial"))
|
||||
{
|
||||
USB_SendString(sys.serialNumber);
|
||||
}
|
||||
else if (USB_CommandCompare("sGetMfgDate"))
|
||||
{
|
||||
USB_SendString(sys.mfgDate);
|
||||
}
|
||||
else if(USB_CommandCompare("sGetMainPcbaPN"))
|
||||
{
|
||||
sprintf(usbTempString, "%d", hwf.mainPcbaPN);
|
||||
USB_SendString(usbTempString);
|
||||
}
|
||||
else if(USB_CommandCompare("sGetbootloaderVerion"))
|
||||
{
|
||||
sprintf(usbTempString, "%d", sys.bootloaderVersion);
|
||||
USB_SendString(usbTempString);
|
||||
}
|
||||
|
||||
else //Unknown command
|
||||
{
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process Frequency Commands
|
||||
*/
|
||||
void USB_ProcessFrequencyCommand(void)
|
||||
{
|
||||
static uint8_t *p; //pointer for strtok - static so it doesn't get optimized out.
|
||||
if (USB_CommandPrefixCompare("fAdd,"))
|
||||
{
|
||||
//Add a frequency to FreqArray[]
|
||||
|
||||
//Parse message
|
||||
p = strtok(usb.rxDataBuffer, ","); //points to "fAdd"
|
||||
p = strtok(null, ","); //frequency
|
||||
uint32_t frequency = atoi(p);
|
||||
p = strtok(null, ","); //type
|
||||
uint32_t type = atoi(p);
|
||||
p = strtok(null, ","); //enabled
|
||||
uint32_t enabled = atoi(p);
|
||||
p = strtok(null, ","); //inMenu
|
||||
uint32_t inMenu = atoi(p);
|
||||
|
||||
FREQ_AddFrequency(frequency, enabled, inMenu, type);
|
||||
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandCompare("fClear"))
|
||||
{
|
||||
//Clear the frequency list
|
||||
frq_update_flag = true;
|
||||
|
||||
FREQ_ClearFrequencies();
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandCompare("fSave"))
|
||||
{
|
||||
//Save frequency data to EEPROM
|
||||
EE_SaveData();
|
||||
USB_SendString(ACK);
|
||||
}
|
||||
else if (USB_CommandCompare("fGetNum")) //Get number of frequencies in the receiver
|
||||
{
|
||||
sprintf(usbTempString, "%d", FREQ_GetNumFrequencies());
|
||||
USB_SendString(usbTempString);
|
||||
}
|
||||
else if (USB_CommandPrefixCompare("fGet,")) //Get string representing a single frequency
|
||||
{
|
||||
|
||||
p = strtok(usb.rxDataBuffer, ","); //points to "fGet"
|
||||
p = strtok(null, ","); //index
|
||||
uint32_t index = atoi(p);
|
||||
|
||||
FREQUENCY_t frq = FREQ_GetFreqByIndex(index);
|
||||
sprintf(usbTempString, "%d,%d,%d,%d", frq.frequency1, 0, frq.enabled, 1); //FREQ_TYPE-t always 0, inMenu always 1
|
||||
USB_SendString(usbTempString);
|
||||
|
||||
|
||||
}
|
||||
else //Unknown command
|
||||
{
|
||||
USB_SendString(NAK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return true if str matches data in usb.rxDataBuffer
|
||||
*/
|
||||
bool USB_CommandCompare(uint8_t *str)
|
||||
{
|
||||
return (0 == strncmp(str, usb.rxDataBuffer, USB_RX_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
/* Compare str to contents of usb.rxDataBuffer
|
||||
* Return true if str matches data in usb.rxDataBuffer
|
||||
*/
|
||||
bool USB_CommandPrefixCompare(uint8_t *str)
|
||||
{
|
||||
return (0 == strncmp(str, usb.rxDataBuffer, strlen(str)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
73
source/USB/usbComms.h
Normal file
73
source/USB/usbComms.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* usbComms.h
|
||||
*
|
||||
* Created on: May 17, 2023
|
||||
* Author: Brian.Bailey
|
||||
*/
|
||||
|
||||
#ifndef COMMS_USBCOMMS_H_
|
||||
#define COMMS_USBCOMMS_H_
|
||||
|
||||
#include "virtual_com.h" //required for USB_RX_BUFFER_SIZE
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define USB_RX_BUFFER_SIZE 512 //Size of rxDataBuffer in bytes (same size as USB_DATA_BUFFER)
|
||||
|
||||
#define ACK "ACK"
|
||||
#define NAK "NAK"
|
||||
#define OK "ACK"
|
||||
#define NO "NAK"
|
||||
|
||||
//Packet Mode
|
||||
#define USB_PACKET_START_BYTE 0xA5 //start byte
|
||||
#define USB_PACKET_HEADER_SIZE 3 //header size in bytes
|
||||
#define USB_PACKET_MAX_LENGTH 63 //503 //max length of packet including header
|
||||
#define USB_PACKET_MAX_PAYLOAD 60 //500 //max bytes for packet payload
|
||||
|
||||
#define USB_PACKET_HEADER_OFFSET 0 //header byte offset
|
||||
#define USB_PACKET_LENGTH_H_OFFSET 1 //packet size high byte offset
|
||||
#define USB_PACKET_LENGTH_L_OFFSET 2 //packet size low byte offset
|
||||
#define USB_PACKET_PAYLOAD_OFFSET 3 //payload byte offset
|
||||
|
||||
//PACKET FORMAT:
|
||||
//PACKET_START byte
|
||||
//Size byte high - Size of packet including header
|
||||
//Size byte low
|
||||
//Payload
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rxDataBuffer[USB_RX_BUFFER_SIZE]; //buffer for received data (copied from rxBuffer)
|
||||
uint32_t rxDataIndex; //index in rxDataBuffer
|
||||
bool rxStringReceived; //string received and ready to process
|
||||
|
||||
bool programMode; //USB program mode: use packet format
|
||||
|
||||
uint32_t sendErrorCount; //number of times USB_SendString() has failed to send
|
||||
bool initialized;
|
||||
}USB_t;
|
||||
|
||||
|
||||
|
||||
uint8_t USB_IsConnected(void);
|
||||
|
||||
void USB_ProcessString(uint32_t size);
|
||||
void USB_ProcessCommand(void);
|
||||
void USB_ProcessProgramCommand(void);
|
||||
void USB_ProcessSystemCommand(void);
|
||||
void USB_ProcessFrequencyCommand(void);
|
||||
|
||||
bool USB_CommandCompare(uint8_t *str);
|
||||
bool USB_CommandPrefixCompare(uint8_t *str);
|
||||
|
||||
void USB_Send(uint8_t * data);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* COMMS_USBCOMMS_H_ */
|
||||
157
source/USB/usb_device_config.h
Normal file
157
source/USB/usb_device_config.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 - 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_DEVICE_CONFIG_H_
|
||||
#define _USB_DEVICE_CONFIG_H_
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @addtogroup usb_device_configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @name Hardware instance define
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief KHCI instance count */
|
||||
#define USB_DEVICE_CONFIG_KHCI (0U)
|
||||
|
||||
/*! @brief EHCI instance count */
|
||||
#define USB_DEVICE_CONFIG_EHCI (0U)
|
||||
|
||||
/*! @brief LPC USB IP3511 FS instance count */
|
||||
#define USB_DEVICE_CONFIG_LPCIP3511FS (1U) //12Mbps, NXP driver - Default setup uses this
|
||||
|
||||
/*! @brief LPC USB IP3511 HS instance count */
|
||||
#define USB_DEVICE_CONFIG_LPCIP3511HS (0U) //480Mbps, NXP driver
|
||||
|
||||
/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/
|
||||
#define USB_DEVICE_CONFIG_NUM \
|
||||
(USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name class instance define
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief HID instance count */
|
||||
#define USB_DEVICE_CONFIG_HID (0U)
|
||||
|
||||
/*! @brief CDC ACM instance count */
|
||||
#define USB_DEVICE_CONFIG_CDC_ACM (1U)
|
||||
|
||||
/*! @brief MSC instance count */
|
||||
#define USB_DEVICE_CONFIG_MSC (0U)
|
||||
|
||||
/*! @brief Audio instance count */
|
||||
#define USB_DEVICE_CONFIG_AUDIO (0U)
|
||||
|
||||
/*! @brief PHDC instance count */
|
||||
#define USB_DEVICE_CONFIG_PHDC (0U)
|
||||
|
||||
/*! @brief Video instance count */
|
||||
#define USB_DEVICE_CONFIG_VIDEO (0U)
|
||||
|
||||
/*! @brief CCID instance count */
|
||||
#define USB_DEVICE_CONFIG_CCID (0U)
|
||||
|
||||
/*! @brief Printer instance count */
|
||||
#define USB_DEVICE_CONFIG_PRINTER (0U)
|
||||
|
||||
/*! @brief DFU instance count */
|
||||
#define USB_DEVICE_CONFIG_DFU (0U)
|
||||
|
||||
/* @} */
|
||||
|
||||
/*! @brief Whether device is self power. 1U supported, 0U not supported */
|
||||
#define USB_DEVICE_CONFIG_SELF_POWER (1U)
|
||||
|
||||
/*! @brief How many endpoints are supported in the stack. */
|
||||
#define USB_DEVICE_CONFIG_ENDPOINTS (4U)
|
||||
|
||||
/*! @brief Whether the device task is enabled. */
|
||||
#define USB_DEVICE_CONFIG_USE_TASK (0U)
|
||||
|
||||
/*! @brief How many the notification message are supported when the device task is enabled. */
|
||||
#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U)
|
||||
|
||||
/*! @brief Whether test mode enabled. */
|
||||
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U)
|
||||
|
||||
/*! @brief Whether device CV test is enabled. */
|
||||
#define USB_DEVICE_CONFIG_CV_TEST (0U)
|
||||
|
||||
/*! @brief Whether device compliance test is enabled. If the macro is enabled,
|
||||
the test mode and CV test macroes will be set.*/
|
||||
#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (0U)
|
||||
|
||||
#if ((defined(USB_DEVICE_CONFIG_COMPLIANCE_TEST)) && (USB_DEVICE_CONFIG_COMPLIANCE_TEST > 0U))
|
||||
|
||||
/*! @brief Undefine the macro USB_DEVICE_CONFIG_USB20_TEST_MODE. */
|
||||
#undef USB_DEVICE_CONFIG_USB20_TEST_MODE
|
||||
/*! @brief Undefine the macro USB_DEVICE_CONFIG_CV_TEST. */
|
||||
#undef USB_DEVICE_CONFIG_CV_TEST
|
||||
|
||||
/*! @brief enable the test mode. */
|
||||
#define USB_DEVICE_CONFIG_USB20_TEST_MODE (1U)
|
||||
|
||||
/*! @brief enable the CV test */
|
||||
#define USB_DEVICE_CONFIG_CV_TEST (1U)
|
||||
|
||||
#endif
|
||||
|
||||
#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
|
||||
|
||||
/*! @brief The MAX buffer length for the KHCI DMA workaround.*/
|
||||
#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U)
|
||||
#endif
|
||||
|
||||
#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
|
||||
/*! @brief How many the DTD are supported. */
|
||||
#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U)
|
||||
|
||||
/*! @brief Whether the EHCI ID pin detect feature enabled. */
|
||||
#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U)
|
||||
#endif
|
||||
|
||||
/*! @brief Whether the keep alive feature enabled. */
|
||||
#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U)
|
||||
|
||||
/*! @brief Whether the transfer buffer is cache-enabled or not. */
|
||||
#ifndef USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE
|
||||
#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
|
||||
#endif
|
||||
/*! @brief Whether the low power mode is enabled or not. */
|
||||
#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U)
|
||||
|
||||
#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
|
||||
/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */
|
||||
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
|
||||
|
||||
/*! @brief Whether LPM is supported. 1U supported, 0U not supported */
|
||||
#define USB_DEVICE_CONFIG_LPM_L1 (0U)
|
||||
#else
|
||||
/*! @brief The device remote wakeup is unsupported. */
|
||||
#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U)
|
||||
#endif
|
||||
|
||||
/*! @brief Whether the device detached feature is enabled or not. */
|
||||
#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U)
|
||||
|
||||
/*! @brief Whether handle the USB bus error. */
|
||||
#define USB_DEVICE_CONFIG_ERROR_HANDLING (0U)
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /* _USB_DEVICE_CONFIG_H_ */
|
||||
514
source/USB/usb_device_descriptor.c
Normal file
514
source/USB/usb_device_descriptor.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016, 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include "usb_device_config.h"
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
#include "usb_device_class.h"
|
||||
#include "usb_device_cdc_acm.h"
|
||||
|
||||
#include "usb_device_descriptor.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/* Define endpoint for communication class */
|
||||
usb_device_endpoint_struct_t g_UsbDeviceCdcVcomCicEndpoints[USB_CDC_VCOM_ENDPOINT_CIC_COUNT] = {
|
||||
{
|
||||
USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_INTERRUPT,
|
||||
FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
|
||||
FS_CDC_VCOM_INTERRUPT_IN_INTERVAL,
|
||||
},
|
||||
};
|
||||
|
||||
/* Define endpoint for data class */
|
||||
usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[USB_CDC_VCOM_ENDPOINT_DIC_COUNT] = {
|
||||
{
|
||||
USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_BULK,
|
||||
FS_CDC_VCOM_BULK_IN_PACKET_SIZE,
|
||||
0U,
|
||||
},
|
||||
{
|
||||
USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
|
||||
USB_ENDPOINT_BULK,
|
||||
FS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
|
||||
0U,
|
||||
}};
|
||||
|
||||
/* Define interface for communication class */
|
||||
usb_device_interface_struct_t g_UsbDeviceCdcVcomCommunicationInterface[] = {{0,
|
||||
{
|
||||
USB_CDC_VCOM_ENDPOINT_CIC_COUNT,
|
||||
g_UsbDeviceCdcVcomCicEndpoints,
|
||||
},
|
||||
NULL}};
|
||||
|
||||
/* Define interface for data class */
|
||||
usb_device_interface_struct_t g_UsbDeviceCdcVcomDataInterface[] = {{0,
|
||||
{
|
||||
USB_CDC_VCOM_ENDPOINT_DIC_COUNT,
|
||||
g_UsbDeviceCdcVcomDicEndpoints,
|
||||
},
|
||||
NULL}};
|
||||
|
||||
/* Define interfaces for virtual com */
|
||||
usb_device_interfaces_struct_t g_UsbDeviceCdcVcomInterfaces[USB_CDC_VCOM_INTERFACE_COUNT] = {
|
||||
{USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, USB_CDC_VCOM_COMM_INTERFACE_INDEX,
|
||||
g_UsbDeviceCdcVcomCommunicationInterface,
|
||||
sizeof(g_UsbDeviceCdcVcomCommunicationInterface) / sizeof(usb_device_interface_struct_t)},
|
||||
{USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, USB_CDC_VCOM_DATA_INTERFACE_INDEX,
|
||||
g_UsbDeviceCdcVcomDataInterface, sizeof(g_UsbDeviceCdcVcomDataInterface) / sizeof(usb_device_interface_struct_t)},
|
||||
};
|
||||
|
||||
/* Define configurations for virtual com */
|
||||
usb_device_interface_list_t g_UsbDeviceCdcVcomInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] = {
|
||||
{
|
||||
USB_CDC_VCOM_INTERFACE_COUNT,
|
||||
g_UsbDeviceCdcVcomInterfaces,
|
||||
},
|
||||
};
|
||||
|
||||
/* Define class information for virtual com */
|
||||
usb_device_class_struct_t g_UsbDeviceCdcVcomConfig = {
|
||||
g_UsbDeviceCdcVcomInterfaceList,
|
||||
kUSB_DeviceClassTypeCdc,
|
||||
USB_DEVICE_CONFIGURATION_COUNT,
|
||||
};
|
||||
|
||||
/* Define device descriptor */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceDescriptor[] = {
|
||||
/* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_LENGTH_DEVICE,
|
||||
/* DEVICE Descriptor Type */
|
||||
USB_DESCRIPTOR_TYPE_DEVICE,
|
||||
/* USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). */
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION),
|
||||
/* Class code (assigned by the USB-IF). */
|
||||
USB_DEVICE_CLASS,
|
||||
/* Subclass code (assigned by the USB-IF). */
|
||||
USB_DEVICE_SUBCLASS,
|
||||
/* Protocol code (assigned by the USB-IF). */
|
||||
USB_DEVICE_PROTOCOL,
|
||||
/* Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) */
|
||||
USB_CONTROL_MAX_PACKET_SIZE,
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_VID),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_VID), /* Vendor ID (assigned by the USB-IF) */
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_PID),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_PID), /* Product ID (assigned by the manufacturer) */
|
||||
/* Device release number in binary-coded decimal */
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_DEMO_BCD_VERSION),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_DEMO_BCD_VERSION),
|
||||
/* Index of string descriptor describing manufacturer */
|
||||
0x01,
|
||||
/* Index of string descriptor describing product */
|
||||
0x02,
|
||||
/* Index of string descriptor describing the device's serial number */
|
||||
0x00,
|
||||
/* Number of possible configurations */
|
||||
USB_DEVICE_CONFIGURATION_COUNT,
|
||||
};
|
||||
|
||||
/* Define configuration descriptor */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceConfigurationDescriptor[] = {
|
||||
/* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_LENGTH_CONFIGURE,
|
||||
/* CONFIGURATION Descriptor Type */
|
||||
USB_DESCRIPTOR_TYPE_CONFIGURE,
|
||||
/* Total length of data returned for this configuration. */
|
||||
USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_ENDPOINT),
|
||||
USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_ENDPOINT),
|
||||
/* Number of interfaces supported by this configuration */
|
||||
USB_CDC_VCOM_INTERFACE_COUNT,
|
||||
/* Value to use as an argument to the SetConfiguration() request to select this configuration */
|
||||
USB_CDC_VCOM_CONFIGURE_INDEX,
|
||||
/* Index of string descriptor describing this configuration */
|
||||
0,
|
||||
/* Configuration characteristics D7: Reserved (set to one) D6: Self-powered D5: Remote Wakeup D4...0: Reserved
|
||||
(reset to zero) */
|
||||
(USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) |
|
||||
(USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) |
|
||||
(USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT),
|
||||
/* Maximum power consumption of the USB * device from the bus in this specific * configuration when the device is
|
||||
fully * operational. Expressed in 2 mA units * (i.e., 50 = 100 mA). */
|
||||
USB_DEVICE_MAX_POWER,
|
||||
|
||||
/* Communication Interface Descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_COMM_INTERFACE_INDEX, 0x00,
|
||||
USB_CDC_VCOM_ENDPOINT_CIC_COUNT, USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL,
|
||||
0x00, /* Interface Description String Index*/
|
||||
|
||||
/* CDC Class-Specific descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC, /* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
|
||||
USB_CDC_HEADER_FUNC_DESC, 0x10,
|
||||
0x01, /* USB Class Definitions for Communications the Communication specification version 1.10 */
|
||||
|
||||
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG, /* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
|
||||
USB_CDC_CALL_MANAGEMENT_FUNC_DESC,
|
||||
0x01, /*Bit 0: Whether device handle call management itself 1, Bit 1: Whether device can send/receive call
|
||||
management information over a Data Class Interface 0 */
|
||||
0x01, /* Indicates multiplexed commands are handled via data interface */
|
||||
|
||||
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT, /* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
|
||||
USB_CDC_ABSTRACT_CONTROL_FUNC_DESC,
|
||||
0x06, /* Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and
|
||||
Get_Comm_Feature 0, Bit 1: Whether device supports the request combination of Set_Line_Coding,
|
||||
Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1, Bit ... */
|
||||
|
||||
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC, /* Size of this descriptor in bytes */
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */
|
||||
USB_CDC_UNION_FUNC_DESC, 0x00, /* The interface number of the Communications or Data Class interface */
|
||||
0x01, /* Interface number of subordinate interface in the Union */
|
||||
|
||||
/*Notification Endpoint descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_INTERRUPT, USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), FS_CDC_VCOM_INTERRUPT_IN_INTERVAL,
|
||||
|
||||
/* Data Interface Descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_DATA_INTERFACE_INDEX, 0x00,
|
||||
USB_CDC_VCOM_ENDPOINT_DIC_COUNT, USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL,
|
||||
0x00, /* Interface Description String Index*/
|
||||
|
||||
/*Bulk IN Endpoint descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */
|
||||
|
||||
/*Bulk OUT Endpoint descriptor */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
|
||||
USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */
|
||||
};
|
||||
|
||||
/* Define string descriptor */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceString0[] = {2U + 2U, USB_DESCRIPTOR_TYPE_STRING, 0x09, 0x04};
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceString1[] = {
|
||||
2U + 2U * 18U, USB_DESCRIPTOR_TYPE_STRING,
|
||||
'N', 0x00U,
|
||||
'X', 0x00U,
|
||||
'P', 0x00U,
|
||||
' ', 0x00U,
|
||||
'S', 0x00U,
|
||||
'E', 0x00U,
|
||||
'M', 0x00U,
|
||||
'I', 0x00U,
|
||||
'C', 0x00U,
|
||||
'O', 0x00U,
|
||||
'N', 0x00U,
|
||||
'D', 0x00U,
|
||||
'U', 0x00U,
|
||||
'C', 0x00U,
|
||||
'T', 0x00U,
|
||||
'O', 0x00U,
|
||||
'R', 0x00U,
|
||||
'S', 0x00U,
|
||||
};
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
#if 1 //Changed Descriptor
|
||||
uint8_t g_UsbDeviceString2[] = {2U + 2U * 16U, USB_DESCRIPTOR_TYPE_STRING,
|
||||
'U', 0,
|
||||
'M', 0,
|
||||
'A', 0,
|
||||
'G', 0,
|
||||
' ', 0,
|
||||
'T', 0,
|
||||
'R', 0,
|
||||
'A', 0,
|
||||
'N', 0,
|
||||
'S', 0,
|
||||
'M', 0,
|
||||
'I', 0,
|
||||
'T', 0,
|
||||
'T', 0,
|
||||
'E', 0,
|
||||
'R', 0};
|
||||
|
||||
#else
|
||||
uint8_t g_UsbDeviceString2[] = {2U + 2U * 20U, USB_DESCRIPTOR_TYPE_STRING,
|
||||
'M', 0,
|
||||
'C', 0,
|
||||
'U', 0,
|
||||
' ', 0,
|
||||
'V', 0,
|
||||
'I', 0,
|
||||
'R', 0,
|
||||
'T', 0,
|
||||
'U', 0,
|
||||
'A', 0,
|
||||
'L', 0,
|
||||
' ', 0,
|
||||
'C', 0,
|
||||
'O', 0,
|
||||
'M', 0,
|
||||
' ', 0,
|
||||
'D', 0,
|
||||
'E', 0,
|
||||
'M', 0,
|
||||
'O', 0};
|
||||
#endif
|
||||
|
||||
uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {g_UsbDeviceString0, g_UsbDeviceString1,
|
||||
g_UsbDeviceString2};
|
||||
|
||||
/* Define string descriptor size */
|
||||
uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = {
|
||||
sizeof(g_UsbDeviceString0), sizeof(g_UsbDeviceString1), sizeof(g_UsbDeviceString2)};
|
||||
usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = {{
|
||||
g_UsbDeviceStringDescriptorArray,
|
||||
g_UsbDeviceStringDescriptorLength,
|
||||
(uint16_t)0x0409,
|
||||
}};
|
||||
|
||||
usb_language_list_t g_UsbDeviceLanguageList = {
|
||||
g_UsbDeviceString0,
|
||||
sizeof(g_UsbDeviceString0),
|
||||
g_UsbDeviceLanguage,
|
||||
USB_DEVICE_LANGUAGE_COUNT,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief USB device get device descriptor function.
|
||||
*
|
||||
* This function gets the device descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param deviceDescriptor The pointer to the device descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle,
|
||||
usb_device_get_device_descriptor_struct_t *deviceDescriptor)
|
||||
{
|
||||
deviceDescriptor->buffer = g_UsbDeviceDescriptor;
|
||||
deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE;
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB device get configuration descriptor function.
|
||||
*
|
||||
* This function gets the configuration descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param configurationDescriptor The pointer to the configuration descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceGetConfigurationDescriptor(
|
||||
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor)
|
||||
{
|
||||
if (USB_CDC_VCOM_CONFIGURE_INDEX > configurationDescriptor->configuration)
|
||||
{
|
||||
configurationDescriptor->buffer = g_UsbDeviceConfigurationDescriptor;
|
||||
configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL;
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB device get string descriptor function.
|
||||
*
|
||||
* This function gets the string descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param stringDescriptor Pointer to the string descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle,
|
||||
usb_device_get_string_descriptor_struct_t *stringDescriptor)
|
||||
{
|
||||
if (stringDescriptor->stringIndex == 0U)
|
||||
{
|
||||
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageString;
|
||||
stringDescriptor->length = g_UsbDeviceLanguageList.stringLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t languageId = 0U;
|
||||
uint8_t languageIndex = USB_DEVICE_STRING_COUNT;
|
||||
|
||||
for (; languageId < USB_DEVICE_LANGUAGE_COUNT; languageId++)
|
||||
{
|
||||
if (stringDescriptor->languageId == g_UsbDeviceLanguageList.languageList[languageId].languageId)
|
||||
{
|
||||
if (stringDescriptor->stringIndex < USB_DEVICE_STRING_COUNT)
|
||||
{
|
||||
languageIndex = stringDescriptor->stringIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (USB_DEVICE_STRING_COUNT == languageIndex)
|
||||
{
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageList[languageId].string[languageIndex];
|
||||
stringDescriptor->length = g_UsbDeviceLanguageList.languageList[languageId].length[languageIndex];
|
||||
}
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB device set speed function.
|
||||
*
|
||||
* This function sets the speed of the USB device.
|
||||
*
|
||||
* Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match
|
||||
* current speed.
|
||||
* As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and
|
||||
* KHCI.
|
||||
* When the EHCI is enabled, the application needs to call this function to update device by using current speed.
|
||||
* The updated information includes endpoint max packet size, endpoint interval, etc.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed)
|
||||
{
|
||||
usb_descriptor_union_t *ptr1;
|
||||
usb_descriptor_union_t *ptr2;
|
||||
int i;
|
||||
|
||||
ptr1 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[0]);
|
||||
ptr2 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1]);
|
||||
|
||||
while (ptr1 < ptr2)
|
||||
{
|
||||
if (ptr1->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
(USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
(USB_CDC_VCOM_BULK_IN_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
|
||||
(USB_CDC_VCOM_BULK_OUT_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
(USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
(USB_CDC_VCOM_BULK_IN_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
|
||||
(USB_CDC_VCOM_BULK_OUT_ENDPOINT ==
|
||||
(ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)))
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr1 = (usb_descriptor_union_t *)((uint8_t *)ptr1 + ptr1->common.bLength);
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_CDC_VCOM_ENDPOINT_CIC_COUNT; i++)
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
|
||||
g_UsbDeviceCdcVcomCicEndpoints[i].interval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
|
||||
g_UsbDeviceCdcVcomCicEndpoints[i].interval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < USB_CDC_VCOM_ENDPOINT_DIC_COUNT; i++)
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
if (g_UsbDeviceCdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
|
||||
{
|
||||
g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_UsbDeviceCdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
|
||||
{
|
||||
g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
206
source/USB/usb_device_descriptor.h
Normal file
206
source/USB/usb_device_descriptor.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _USB_DEVICE_DESCRIPTOR_H_
|
||||
#define _USB_DEVICE_DESCRIPTOR_H_ 1
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#define USB_DEVICE_SPECIFIC_BCD_VERSION (0x0200)
|
||||
#define USB_DEVICE_DEMO_BCD_VERSION (0x0101U)
|
||||
|
||||
#define USB_DEVICE_VID (0x1FC9U)
|
||||
#define USB_DEVICE_PID (0x8310U)
|
||||
|
||||
/* Communication Class Codes */
|
||||
#define CDC_COMM_CLASS (0x02)
|
||||
/* Data Class Codes */
|
||||
#define CDC_DATA_CLASS (0x0A)
|
||||
|
||||
/* Communication Class SubClass Codes */
|
||||
#define USB_CDC_DIRECT_LINE_CONTROL_MODEL (0x01)
|
||||
#define USB_CDC_ABSTRACT_CONTROL_MODEL (0x02)
|
||||
#define USB_CDC_TELEPHONE_CONTROL_MODEL (0x03)
|
||||
#define USB_CDC_MULTI_CHANNEL_CONTROL_MODEL (0x04)
|
||||
#define USB_CDC_CAPI_CONTROL_MOPDEL (0x05)
|
||||
#define USB_CDC_ETHERNET_NETWORKING_CONTROL_MODEL (0x06)
|
||||
#define USB_CDC_ATM_NETWORKING_CONTROL_MODEL (0x07)
|
||||
#define USB_CDC_WIRELESS_HANDSET_CONTROL_MODEL (0x08)
|
||||
#define USB_CDC_DEVICE_MANAGEMENT (0x09)
|
||||
#define USB_CDC_MOBILE_DIRECT_LINE_MODEL (0x0A)
|
||||
#define USB_CDC_OBEX (0x0B)
|
||||
#define USB_CDC_ETHERNET_EMULATION_MODEL (0x0C)
|
||||
|
||||
/* Communication Class Protocol Codes */
|
||||
#define USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL (0x00) /*also for Data Class Protocol Code */
|
||||
#define USB_CDC_AT_250_PROTOCOL (0x01)
|
||||
#define USB_CDC_AT_PCCA_101_PROTOCOL (0x02)
|
||||
#define USB_CDC_AT_PCCA_101_ANNEX_O (0x03)
|
||||
#define USB_CDC_AT_GSM_7_07 (0x04)
|
||||
#define USB_CDC_AT_3GPP_27_007 (0x05)
|
||||
#define USB_CDC_AT_TIA_CDMA (0x06)
|
||||
#define USB_CDC_ETHERNET_EMULATION_PROTOCOL (0x07)
|
||||
#define USB_CDC_EXTERNAL_PROTOCOL (0xFE)
|
||||
#define USB_CDC_VENDOR_SPECIFIC (0xFF) /*also for Data Class Protocol Code */
|
||||
|
||||
/* Data Class Protocol Codes */
|
||||
#define USB_CDC_PYHSICAL_INTERFACE_PROTOCOL (0x30)
|
||||
#define USB_CDC_HDLC_PROTOCOL (0x31)
|
||||
#define USB_CDC_TRANSPARENT_PROTOCOL (0x32)
|
||||
#define USB_CDC_MANAGEMENT_PROTOCOL (0x50)
|
||||
#define USB_CDC_DATA_LINK_Q931_PROTOCOL (0x51)
|
||||
#define USB_CDC_DATA_LINK_Q921_PROTOCOL (0x52)
|
||||
#define USB_CDC_DATA_COMPRESSION_V42BIS (0x90)
|
||||
#define USB_CDC_EURO_ISDN_PROTOCOL (0x91)
|
||||
#define USB_CDC_RATE_ADAPTION_ISDN_V24 (0x92)
|
||||
#define USB_CDC_CAPI_COMMANDS (0x93)
|
||||
#define USB_CDC_HOST_BASED_DRIVER (0xFD)
|
||||
#define USB_CDC_UNIT_FUNCTIONAL (0xFE)
|
||||
|
||||
/* Descriptor SubType in Communications Class Functional Descriptors */
|
||||
#define USB_CDC_HEADER_FUNC_DESC (0x00)
|
||||
#define USB_CDC_CALL_MANAGEMENT_FUNC_DESC (0x01)
|
||||
#define USB_CDC_ABSTRACT_CONTROL_FUNC_DESC (0x02)
|
||||
#define USB_CDC_DIRECT_LINE_FUNC_DESC (0x03)
|
||||
#define USB_CDC_TELEPHONE_RINGER_FUNC_DESC (0x04)
|
||||
#define USB_CDC_TELEPHONE_REPORT_FUNC_DESC (0x05)
|
||||
#define USB_CDC_UNION_FUNC_DESC (0x06)
|
||||
#define USB_CDC_COUNTRY_SELECT_FUNC_DESC (0x07)
|
||||
#define USB_CDC_TELEPHONE_MODES_FUNC_DESC (0x08)
|
||||
#define USB_CDC_TERMINAL_FUNC_DESC (0x09)
|
||||
#define USB_CDC_NETWORK_CHANNEL_FUNC_DESC (0x0A)
|
||||
#define USB_CDC_PROTOCOL_UNIT_FUNC_DESC (0x0B)
|
||||
#define USB_CDC_EXTENSION_UNIT_FUNC_DESC (0x0C)
|
||||
#define USB_CDC_MULTI_CHANNEL_FUNC_DESC (0x0D)
|
||||
#define USB_CDC_CAPI_CONTROL_FUNC_DESC (0x0E)
|
||||
#define USB_CDC_ETHERNET_NETWORKING_FUNC_DESC (0x0F)
|
||||
#define USB_CDC_ATM_NETWORKING_FUNC_DESC (0x10)
|
||||
#define USB_CDC_WIRELESS_CONTROL_FUNC_DESC (0x11)
|
||||
#define USB_CDC_MOBILE_DIRECT_LINE_FUNC_DESC (0x12)
|
||||
#define USB_CDC_MDLM_DETAIL_FUNC_DESC (0x13)
|
||||
#define USB_CDC_DEVICE_MANAGEMENT_FUNC_DESC (0x14)
|
||||
#define USB_CDC_OBEX_FUNC_DESC (0x15)
|
||||
#define USB_CDC_COMMAND_SET_FUNC_DESC (0x16)
|
||||
#define USB_CDC_COMMAND_SET_DETAIL_FUNC_DESC (0x17)
|
||||
#define USB_CDC_TELEPHONE_CONTROL_FUNC_DESC (0x18)
|
||||
#define USB_CDC_OBEX_SERVICE_ID_FUNC_DESC (0x19)
|
||||
|
||||
/* usb descriptor length */
|
||||
#define USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL (sizeof(g_UsbDeviceConfigurationDescriptor))
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC (5)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG (5)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT (4)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC (5)
|
||||
|
||||
/* Configuration, interface and endpoint. */
|
||||
#define USB_DEVICE_CONFIGURATION_COUNT (1)
|
||||
#define USB_DEVICE_STRING_COUNT (3)
|
||||
#define USB_DEVICE_LANGUAGE_COUNT (1)
|
||||
|
||||
#define USB_CDC_VCOM_CONFIGURE_INDEX (1)
|
||||
|
||||
#define USB_CDC_VCOM_ENDPOINT_CIC_COUNT (1)
|
||||
#define USB_CDC_VCOM_ENDPOINT_DIC_COUNT (2)
|
||||
#define USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT (1)
|
||||
#define USB_CDC_VCOM_BULK_IN_ENDPOINT (2)
|
||||
#define USB_CDC_VCOM_BULK_OUT_ENDPOINT (3)
|
||||
#define USB_CDC_VCOM_INTERFACE_COUNT (2)
|
||||
#define USB_CDC_VCOM_COMM_INTERFACE_INDEX (0)
|
||||
#define USB_CDC_VCOM_DATA_INTERFACE_INDEX (1)
|
||||
|
||||
/* Packet size. */
|
||||
#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16)
|
||||
#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16)
|
||||
#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x07) /* 2^(7-1) = 8ms */
|
||||
#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x08)
|
||||
#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE (512)
|
||||
#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE (64)
|
||||
#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE (512)
|
||||
#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE (64)
|
||||
|
||||
/* String descriptor length. */
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING0 (sizeof(g_UsbDeviceString0))
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING1 (sizeof(g_UsbDeviceString1))
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING2 (sizeof(g_UsbDeviceString2))
|
||||
|
||||
#define USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE (0x24)
|
||||
#define USB_DESCRIPTOR_TYPE_CDC_CS_ENDPOINT (0x25)
|
||||
|
||||
/* Class code. */
|
||||
#define USB_DEVICE_CLASS (0x02)
|
||||
#define USB_DEVICE_SUBCLASS (0x00)
|
||||
#define USB_DEVICE_PROTOCOL (0x00)
|
||||
|
||||
#define USB_DEVICE_MAX_POWER (0x32)
|
||||
|
||||
#define USB_CDC_VCOM_CIC_CLASS (CDC_COMM_CLASS)
|
||||
#define USB_CDC_VCOM_CIC_SUBCLASS (USB_CDC_ABSTRACT_CONTROL_MODEL)
|
||||
#define USB_CDC_VCOM_CIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL)
|
||||
|
||||
#define USB_CDC_VCOM_DIC_CLASS (CDC_DATA_CLASS)
|
||||
#define USB_CDC_VCOM_DIC_SUBCLASS (0x00)
|
||||
#define USB_CDC_VCOM_DIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL)
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief USB device set speed function.
|
||||
*
|
||||
* This function sets the speed of the USB device.
|
||||
*
|
||||
* Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match
|
||||
* current speed.
|
||||
* As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and
|
||||
* KHCI.
|
||||
* When the EHCI is enabled, the application needs to call this function to update device by using current speed.
|
||||
* The updated information includes endpoint max packet size, endpoint interval, etc.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
extern usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed);
|
||||
/*!
|
||||
* @brief USB device get device descriptor function.
|
||||
*
|
||||
* This function gets the device descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param deviceDescriptor The pointer to the device descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
extern usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle,
|
||||
usb_device_get_device_descriptor_struct_t *deviceDescriptor);
|
||||
/*!
|
||||
* @brief USB device get string descriptor function.
|
||||
*
|
||||
* This function gets the string descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param stringDescriptor Pointer to the string descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle,
|
||||
usb_device_get_string_descriptor_struct_t *stringDescriptor);
|
||||
/*!
|
||||
* @brief USB device get configuration descriptor function.
|
||||
*
|
||||
* This function gets the configuration descriptor of the USB device.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param configurationDescriptor The pointer to the configuration descriptor structure.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
extern usb_status_t USB_DeviceGetConfigurationDescriptor(
|
||||
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor);
|
||||
#endif /* _USB_DEVICE_DESCRIPTOR_H_ */
|
||||
673
source/USB/virtual_com.c
Normal file
673
source/USB/virtual_com.c
Normal file
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 - 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_debug_console.h"
|
||||
#include "pin_mux.h"
|
||||
#include "clock_config.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "usb_device_config.h"
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
#include "usb_device_class.h"
|
||||
#include "usb_device_cdc_acm.h"
|
||||
#include "usb_device_ch9.h"
|
||||
|
||||
#include "usb_device_descriptor.h"
|
||||
#include "virtual_com.h"
|
||||
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
|
||||
#include "fsl_sysmpu.h"
|
||||
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
|
||||
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
#include "usb_phy.h"
|
||||
#endif
|
||||
#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)
|
||||
extern uint8_t USB_EnterLowpowerMode(void);
|
||||
#endif
|
||||
#include "fsl_power.h"
|
||||
|
||||
//Application Includes
|
||||
#include "flashUpdate.h"
|
||||
#include "usbComms.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define CR '\r' //carriage return
|
||||
#define LF '\n' //line feed
|
||||
#define null 0 //NULL is defined at (void *)0 so it causes errors
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
void BOARD_InitHardware(void);
|
||||
void USB_DeviceClockInit(void);
|
||||
void USB_DeviceIsrEnable(void);
|
||||
#if USB_DEVICE_CONFIG_USE_TASK
|
||||
void USB_DeviceTaskFn(void *deviceHandle);
|
||||
#endif
|
||||
|
||||
void BOARD_DbgConsole_Deinit(void);
|
||||
void BOARD_DbgConsole_Init(void);
|
||||
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);
|
||||
|
||||
|
||||
#if 0 //Trying to fix project after adding, then removing FLASHIAP driver. Makes no difference
|
||||
extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
|
||||
extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
//Application
|
||||
extern USB_t usb;
|
||||
|
||||
|
||||
extern usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[];
|
||||
extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig;
|
||||
/* Data structure of virtual com device */
|
||||
usb_cdc_vcom_struct_t s_cdcVcom;
|
||||
|
||||
/* Line coding of cdc device */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
|
||||
/* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
|
||||
(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};
|
||||
|
||||
/* Abstract state of cdc device */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
|
||||
(STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
|
||||
|
||||
/* Country code of cdc device */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
|
||||
(COUNTRY_SETTING >> 8U) & 0x00FFU};
|
||||
|
||||
/* CDC ACM information */
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static usb_cdc_acm_info_t s_usbCdcAcmInfo;
|
||||
/* Data buffer for receiving and sending*/
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t rxBuffer[USB_BUFFER_SIZE];
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t txBuffer[USB_BUFFER_SIZE];
|
||||
volatile static uint32_t rxDataSize = 0;
|
||||
volatile static uint32_t txDataSize = 0;
|
||||
|
||||
/* USB device class information */
|
||||
static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{
|
||||
USB_DeviceCdcVcomCallback,
|
||||
0,
|
||||
&g_UsbDeviceCdcVcomConfig,
|
||||
}};
|
||||
|
||||
/* USB device class configuration information */
|
||||
static usb_device_class_config_list_struct_t s_cdcAcmConfigList = {
|
||||
s_cdcAcmConfig,
|
||||
USB_DeviceCallback,
|
||||
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)
|
||||
volatile static uint8_t s_waitForDataReceive = 0;
|
||||
volatile static uint8_t s_comOpen = 0;
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void USB0_IRQHandler(void)
|
||||
{
|
||||
USB_DeviceLpcIp3511IsrFunction(s_cdcVcom.deviceHandle);
|
||||
}
|
||||
|
||||
void USB_DeviceClockInit(void)
|
||||
{
|
||||
/* enable USB IP clock */
|
||||
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf));
|
||||
}
|
||||
void USB_DeviceIsrEnable(void)
|
||||
{
|
||||
uint8_t irqNumber;
|
||||
|
||||
uint8_t usbDeviceIP3511Irq[] = USB_IRQS;
|
||||
irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Fs0];
|
||||
|
||||
/* Install isr, set priority, and enable IRQ. */
|
||||
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
|
||||
EnableIRQ((IRQn_Type)irqNumber);
|
||||
}
|
||||
#if USB_DEVICE_CONFIG_USE_TASK
|
||||
void USB_DeviceTaskFn(void *deviceHandle)
|
||||
{
|
||||
USB_DeviceLpcIp3511TaskFunction(deviceHandle);
|
||||
}
|
||||
#endif
|
||||
/*!
|
||||
* @brief CDC class specific callback function.
|
||||
*
|
||||
* This function handles the CDC class specific requests.
|
||||
*
|
||||
* @param handle The CDC ACM class handle.
|
||||
* @param event The CDC ACM class event type.
|
||||
* @param param The parameter of the class specific request.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param)
|
||||
{
|
||||
uint32_t len;
|
||||
uint8_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)))
|
||||
{
|
||||
/* If the last packet is the size of endpoint, then send also zero-ended packet,
|
||||
** meaning that we want to inform the host that we do not have any additional
|
||||
** data, so it can flush the output.
|
||||
*/
|
||||
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)))
|
||||
{
|
||||
/* User: add your own code for send complete event */
|
||||
/* Schedule buffer for next receive event */
|
||||
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
|
||||
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))
|
||||
{
|
||||
rxDataSize = epCbParam->length;
|
||||
|
||||
#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 (!rxDataSize)
|
||||
{
|
||||
/* Schedule buffer for next receive event */
|
||||
error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
|
||||
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) = COMM_FEATURE_DATA_SIZE;
|
||||
}
|
||||
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue)
|
||||
{
|
||||
*(acmReqParam->buffer) = s_countryCode;
|
||||
*(acmReqParam->length) = COMM_FEATURE_DATA_SIZE;
|
||||
}
|
||||
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;
|
||||
/* activate/deactivate Tx carrier */
|
||||
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;
|
||||
}
|
||||
|
||||
/* activate carrier and DTE. Com port of terminal tool running on PC is open now */
|
||||
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
|
||||
{
|
||||
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
|
||||
}
|
||||
/* Com port of terminal tool running on PC is closed now */
|
||||
else
|
||||
{
|
||||
acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
|
||||
}
|
||||
|
||||
/* Indicates to DCE if DTE is present or not */
|
||||
acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? 1 : 0;
|
||||
|
||||
/* Initialize the serial state buffer */
|
||||
acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
|
||||
acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */
|
||||
acmInfo->serialStateBuf[2] = 0x00; /* wValue */
|
||||
acmInfo->serialStateBuf[3] = 0x00;
|
||||
acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
|
||||
acmInfo->serialStateBuf[5] = 0x00;
|
||||
acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
|
||||
acmInfo->serialStateBuf[7] = 0x00;
|
||||
/* Notify to host the line state */
|
||||
acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex;
|
||||
/* Lower byte of UART BITMAP */
|
||||
uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
|
||||
uartBitmap[0] = acmInfo->uartState & 0xFFu;
|
||||
uartBitmap[1] = (acmInfo->uartState >> 8) & 0xFFu;
|
||||
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;
|
||||
}
|
||||
|
||||
/* Update status */
|
||||
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
|
||||
{
|
||||
/* To do: CARRIER_ACTIVATED */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* To do: CARRIER_DEACTIVATED */
|
||||
}
|
||||
if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
|
||||
{
|
||||
/* DTE_ACTIVATED */
|
||||
if (1 == s_cdcVcom.attach)
|
||||
{
|
||||
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
|
||||
{
|
||||
/* DTE_DEACTIVATED */
|
||||
if (1 == s_cdcVcom.attach)
|
||||
{
|
||||
s_cdcVcom.startTransactions = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceCdcEventSendBreak:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB device callback function.
|
||||
*
|
||||
* This function handles the usb device specific requests.
|
||||
*
|
||||
* @param handle The USB device handle.
|
||||
* @param event The USB device event type.
|
||||
* @param param The parameter of the device specific request.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
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;
|
||||
s_cdcVcom.currentConfiguration = 0U;
|
||||
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
|
||||
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
|
||||
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
|
||||
if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &s_cdcVcom.speed))
|
||||
{
|
||||
USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceEventSetConfiguration:
|
||||
if (0U == (*temp8))
|
||||
{
|
||||
s_cdcVcom.attach = 0;
|
||||
s_cdcVcom.currentConfiguration = 0U;
|
||||
}
|
||||
else if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
|
||||
{
|
||||
s_cdcVcom.attach = 1;
|
||||
s_cdcVcom.currentConfiguration = *temp8;
|
||||
/* Schedule buffer for receive */
|
||||
USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer,
|
||||
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* Get device string descriptor request */
|
||||
error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Application initialization function.
|
||||
*
|
||||
* This function initializes the application.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void USB_Init(void)
|
||||
{
|
||||
if(usb.initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
usb.initialized = true;
|
||||
|
||||
USB_DeviceClockInit();
|
||||
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
|
||||
SYSMPU_Enable(SYSMPU, 0);
|
||||
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
|
||||
|
||||
usb.rxDataIndex = 0;
|
||||
|
||||
s_cdcVcom.speed = USB_SPEED_FULL;
|
||||
s_cdcVcom.attach = 0;
|
||||
s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL;
|
||||
s_cdcVcom.deviceHandle = NULL;
|
||||
|
||||
if (kStatus_USB_Success != USB_DeviceClassInit(CONTROLLER_ID, &s_cdcAcmConfigList, &s_cdcVcom.deviceHandle))
|
||||
{
|
||||
//usb_echo("USB device init failed\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_echo("USB device CDC virtual com demo\r\n");
|
||||
s_cdcVcom.cdcAcmHandle = s_cdcAcmConfigList.config->classHandle;
|
||||
}
|
||||
|
||||
USB_DeviceIsrEnable();
|
||||
|
||||
/*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/
|
||||
SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
|
||||
USB_DeviceRun(s_cdcVcom.deviceHandle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Application task function.
|
||||
*
|
||||
* This function runs the task for application.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void USB_Update(void)
|
||||
{
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
|
||||
{
|
||||
/* User Code */
|
||||
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
|
||||
if ((0 != rxDataSize) && (USB_CANCELLED_TRANSFER_LENGTH != rxDataSize))
|
||||
{
|
||||
|
||||
usb.rxDataIndex = 0;
|
||||
|
||||
//copy to rxDataBuffer for processing
|
||||
for (int32_t i = 0; i < rxDataSize; i++)
|
||||
{
|
||||
usb.rxDataBuffer[usb.rxDataIndex++] = rxBuffer[i];
|
||||
}
|
||||
uint32_t tempDataSize = rxDataSize; //temp variable to pass to USB_ProcessData()
|
||||
rxDataSize = 0;
|
||||
|
||||
if(usb.programMode) //ProgramMode = send data for write to FLASH
|
||||
{
|
||||
FU_WriteProgramDataToFLASH();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Process String
|
||||
USB_ProcessString(tempDataSize);
|
||||
}
|
||||
|
||||
}
|
||||
#if 0 //Transmit
|
||||
if (txDataSize)
|
||||
{
|
||||
uint32_t size = txDataSize;
|
||||
txDataSize = 0;
|
||||
|
||||
error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size);
|
||||
|
||||
if (error != kStatus_USB_Success)
|
||||
{
|
||||
/* Failure to send Data Handling code here */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//Send data to via USB
|
||||
void USB_SendString(uint8_t * str)
|
||||
{
|
||||
if(!s_cdcVcom.attach) //exit if USB not connected
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t length = strlen(str);
|
||||
|
||||
if(length > USB_BUFFER_SIZE - 1) //allow for LF char
|
||||
{
|
||||
return; //TODO: handle this better. Use a txRingbuffer
|
||||
}
|
||||
|
||||
//copy data to txBuffer
|
||||
memcpy(txBuffer, str, length);
|
||||
txBuffer[length++] = CR; //append CR for realterm
|
||||
txBuffer[length++] = LF; //append LF for windows
|
||||
txDataSize = length;
|
||||
|
||||
#if 1 //Send data
|
||||
|
||||
//Wait for USB ready
|
||||
while(!((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))); //TODO: make this not block forever
|
||||
|
||||
uint32_t size = txDataSize;
|
||||
txDataSize = 0;
|
||||
|
||||
usb_status_t error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size);
|
||||
if (error != kStatus_USB_Success)
|
||||
{
|
||||
/* Failure to send Data Handling code here */
|
||||
|
||||
usb.sendErrorCount++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if 0 //main function from example
|
||||
int main(void)
|
||||
{
|
||||
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
|
||||
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
|
||||
BOARD_InitPins();
|
||||
BOARD_BootClockPLL150M();
|
||||
CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */
|
||||
BOARD_InitDebugConsole();
|
||||
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*Turn on USB Phy */
|
||||
|
||||
USB_Init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
USB_Update();
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
107
source/USB/virtual_com.h
Normal file
107
source/USB/virtual_com.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _USB_CDC_VCOM_H_
|
||||
#define _USB_CDC_VCOM_H_ 1
|
||||
|
||||
|
||||
|
||||
#include "usb_device_config.h"
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
#include "usb_device_class.h"
|
||||
#include "usb_device_cdc_acm.h"
|
||||
#include "usb_device_ch9.h"
|
||||
|
||||
#include "usb_device_descriptor.h"
|
||||
#include "virtual_com.h"
|
||||
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
|
||||
#define CONTROLLER_ID kUSB_ControllerEhci0
|
||||
#define USB_BUFFER_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
||||
|
||||
#endif
|
||||
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
|
||||
#define CONTROLLER_ID kUSB_ControllerKhci0
|
||||
#define USB_BUFFER_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
||||
|
||||
#endif
|
||||
#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
|
||||
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0
|
||||
#define USB_BUFFER_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
|
||||
#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0
|
||||
#define USB_BUFFER_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
||||
#endif
|
||||
|
||||
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
|
||||
/* Currently configured line coding */
|
||||
#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)
|
||||
|
||||
/* Communications feature */
|
||||
#define COMM_FEATURE_DATA_SIZE (0x02)
|
||||
#define STATUS_ABSTRACT_STATE (0x0000)
|
||||
#define COUNTRY_SETTING (0x0000)
|
||||
|
||||
/* Notification of serial state */
|
||||
#define NOTIF_PACKET_SIZE (0x08)
|
||||
#define UART_BITMAP_SIZE (0x02)
|
||||
#define NOTIF_REQUEST_TYPE (0xA1)
|
||||
|
||||
/* Define the types for application */
|
||||
typedef struct _usb_cdc_vcom_struct
|
||||
{
|
||||
usb_device_handle deviceHandle; /* USB device handle. */
|
||||
class_handle_t cdcAcmHandle; /* USB CDC ACM class handle. */
|
||||
volatile uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */
|
||||
uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */
|
||||
volatile uint8_t
|
||||
startTransactions; /* A flag to indicate whether a CDC device is ready to transmit and receive data. */
|
||||
uint8_t currentConfiguration; /* Current configuration value. */
|
||||
uint8_t currentInterfaceAlternateSetting[USB_CDC_VCOM_INTERFACE_COUNT]; /* Current alternate setting value for each
|
||||
interface. */
|
||||
} usb_cdc_vcom_struct_t;
|
||||
|
||||
/* Define the information relates to abstract control model */
|
||||
typedef struct _usb_cdc_acm_info
|
||||
{
|
||||
uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE]; /* Serial state buffer of the CDC device to notify the
|
||||
serial state to host. */
|
||||
uint8_t dtePresent; /* A flag to indicate whether DTE is present. */
|
||||
uint16_t breakDuration; /* Length of time in milliseconds of the break signal */
|
||||
uint8_t dteStatus; /* Status of data terminal equipment */
|
||||
uint8_t currentInterface; /* Current interface index. */
|
||||
uint16_t uartState; /* UART state of the CDC device. */
|
||||
} usb_cdc_acm_info_t;
|
||||
|
||||
|
||||
void USB_Init(void);
|
||||
void USB_Update(void);
|
||||
|
||||
void USB_SendString(uint8_t * str);
|
||||
|
||||
#if 0 //TESTING - definitions for USB functions
|
||||
void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _USB_CDC_VCOM_H_ */
|
||||
Reference in New Issue
Block a user