您好!
我想在 TM4C123gxl 评估板上测试一个添加了 DFU 的 CDC 类器件。 我根据提供的示例代码准备了以下代码。 我遇到的第一个问题是 Putty 终端无法连接到与设备关联的虚拟 COM 端口。 设备管理器显示有 COM 端口。 请告诉我我在这里发生了什么错误吗?
注:
我删除了与 CDC 配置相关的对 UART 的99%引用。 我以这种方式修改了 USB_DEV_serial 示例、它工作正常。
谢谢、
Dhammika
//***************************************************************************** // // usb_dev_serial.c - Main routines for the USB CDC serial example. // // Copyright (c) 2012-2020 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of revision 2.2.0.295 of the EK-TM4C123GXL Firmware Package. // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include "inc/hw_ints.h" #include "inc/hw_nvic.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_uart.h" #include "inc/hw_sysctl.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/timer.h" #include "driverlib/uart.h" #include "driverlib/usb.h" #include "usblib/usblib.h" #include "usblib/usbcdc.h" #include "usblib/usb-ids.h" #include "usblib/device/usbdevice.h" #include "usblib/device/usbdcdc.h" #include "usblib/device/usbdcomp.h" #include "usblib/device/usbddfu-rt.h" #include "utils/ustdlib.h" #include "usb_serial_structs.h" #include "utils/uartstdio.h" //***************************************************************************** // //! \addtogroup example_list //! <h1>USB Serial Device (usb_dev_serial)</h1> //! //! This example application turns the evaluation kit into a virtual serial //! port when connected to the USB host system. The application supports the //! USB Communication Device Class, Abstract Control Model to redirect UART0 //! traffic to and from the USB host system. //! //! Assuming you installed TivaWare in the default directory, a driver //! information (INF) file for use with Windows XP, Windows Vista, Windows 7, //! and Windows 10 can be found in C:/TivaWare_C_Series-x.x/windows_drivers. //! For Windows 2000, the required INF file is in //! C:/TivaWare_C_Series-x.x/windows_drivers/win2K. // //***************************************************************************** //***************************************************************************** // // Note: // // This example is intended to run on Tiva C Series evaluation kit hardware // where the UARTs are wired solely for TX and RX, and do not have GPIOs // connected to act as handshake signals. As a result, this example mimics // the case where communication is always possible. It reports DSR, DCD // and CTS as high to ensure that the USB host recognizes that data can be // sent and merely ignores the host's requested DTR and RTS states. "TODO" // comments in the code indicate where code would be required to add support // for real handshakes. // //***************************************************************************** //***************************************************************************** // // Configuration and tuning parameters. // //***************************************************************************** //***************************************************************************** // // The system tick rate expressed both as ticks per second and a millisecond // period. // //***************************************************************************** #define SYSTICKS_PER_SECOND 100 #define SYSTICK_PERIOD_MS (1000 / SYSTICKS_PER_SECOND) //***************************************************************************** // // Variables tracking transmit and receive counts. // //***************************************************************************** volatile uint32_t g_ui32UARTTxCount = 0; volatile uint32_t g_ui32UARTRxCount = 0; #ifdef DEBUG uint32_t g_ui32UARTRxErrors = 0; #endif //***************************************************************************** // // The base address, peripheral ID and interrupt ID of the UART that is to // be redirected. // //***************************************************************************** //***************************************************************************** // // Flag indicating whether or not we are currently sending a Break condition. // //***************************************************************************** static bool g_bSendingBreak = false; //***************************************************************************** // // Global system tick counter // //***************************************************************************** volatile uint32_t g_ui32SysTickCount = 0; //***************************************************************************** // // Flags used to pass commands from interrupt context to the main loop. // //***************************************************************************** #define COMMAND_PACKET_RECEIVED 0x00000001 #define COMMAND_STATUS_UPDATE 0x00000002 volatile uint32_t g_ui32Flags = 0; char *g_pcStatus; //***************************************************************************** // // Global flag indicating that a USB configuration has been set. // //***************************************************************************** static volatile bool g_bUSBConfigured = false; //***************************************************************************** // // Flag used to tell the main loop that it's time to pass control back to the // boot loader for an update. // //***************************************************************************** volatile bool g_bUpdateSignalled; //***************************************************************************** // // A flag used to indicate whether or not we are currently connected to the USB // host. // //***************************************************************************** volatile bool g_bConnected; //***************************************************************************** // // Internal function prototypes. // //***************************************************************************** static void USBUARTPrimeTransmit(uint32_t ui32Base); static void CheckForSerialStateChange(const tUSBDCDCDevice *psDevice, int32_t i32Errors); static void SetControlLineState(uint16_t ui16State); //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { while(1) { } } #endif //***************************************************************************** // // Interrupt handler for the system tick counter. // //***************************************************************************** void SysTickIntHandler(void) { // // Update our system time. // g_ui32SysTickCount++; } //***************************************************************************** // // Set the state of the RS232 RTS and DTR signals. // //***************************************************************************** static void SetControlLineState(uint16_t ui16State) { // // TODO: If configured with GPIOs controlling the handshake lines, // set them appropriately depending upon the flags passed in the wValue // field of the request structure passed. // } #if 1 //***************************************************************************** // // Set the communication parameters to use on the UART. // //***************************************************************************** static bool SetLineCoding(tLineCoding *psLineCoding) { uint32_t ui32Config; bool bRetcode; // // Assume everything is OK until we detect any problem. // bRetcode = true; // // Word length. For invalid values, the default is to set 8 bits per // character and return an error. // switch(psLineCoding->ui8Databits) { case 5: { ui32Config = UART_CONFIG_WLEN_5; break; } case 6: { ui32Config = UART_CONFIG_WLEN_6; break; } case 7: { ui32Config = UART_CONFIG_WLEN_7; break; } case 8: { ui32Config = UART_CONFIG_WLEN_8; break; } default: { ui32Config = UART_CONFIG_WLEN_8; bRetcode = false; break; } } // // Parity. For any invalid values, we set no parity and return an error. // switch(psLineCoding->ui8Parity) { case USB_CDC_PARITY_NONE: { ui32Config |= UART_CONFIG_PAR_NONE; break; } case USB_CDC_PARITY_ODD: { ui32Config |= UART_CONFIG_PAR_ODD; break; } case USB_CDC_PARITY_EVEN: { ui32Config |= UART_CONFIG_PAR_EVEN; break; } case USB_CDC_PARITY_MARK: { ui32Config |= UART_CONFIG_PAR_ONE; break; } case USB_CDC_PARITY_SPACE: { ui32Config |= UART_CONFIG_PAR_ZERO; break; } default: { ui32Config |= UART_CONFIG_PAR_NONE; bRetcode = false; break; } } // // Stop bits. Our hardware only supports 1 or 2 stop bits whereas CDC // allows the host to select 1.5 stop bits. If passed 1.5 (or any other // invalid or unsupported value of ui8Stop, we set up for 1 stop bit but // return an error in case the caller needs to Stall or otherwise report // this back to the host. // switch(psLineCoding->ui8Stop) { // // One stop bit requested. // case USB_CDC_STOP_BITS_1: { ui32Config |= UART_CONFIG_STOP_ONE; break; } // // Two stop bits requested. // case USB_CDC_STOP_BITS_2: { ui32Config |= UART_CONFIG_STOP_TWO; break; } // // Other cases are either invalid values of ui8Stop or values that we // cannot support so set 1 stop bit but return an error. // default: { ui32Config |= UART_CONFIG_STOP_ONE; bRetcode = false; break; } } #if 0 // // Set the UART mode appropriately. // MAP_UARTConfigSetExpClk(USB_UART_BASE, MAP_SysCtlClockGet(), psLineCoding->ui32Rate, ui32Config); #endif // // Let the caller know if we had a problem or not. // return(bRetcode); } //***************************************************************************** // // Get the communication parameters in use on the UART. // //***************************************************************************** static void GetLineCoding(tLineCoding *psLineCoding) { uint32_t ui32Config; uint32_t ui32Rate; #if 0 // // Get the current line coding set in the UART. // MAP_UARTConfigGetExpClk(USB_UART_BASE, MAP_SysCtlClockGet(), &ui32Rate, &ui32Config); psLineCoding->ui32Rate = ui32Rate; #endif // // Translate the configuration word length field into the format expected // by the host. // switch(ui32Config & UART_CONFIG_WLEN_MASK) { case UART_CONFIG_WLEN_8: { psLineCoding->ui8Databits = 8; break; } case UART_CONFIG_WLEN_7: { psLineCoding->ui8Databits = 7; break; } case UART_CONFIG_WLEN_6: { psLineCoding->ui8Databits = 6; break; } case UART_CONFIG_WLEN_5: { psLineCoding->ui8Databits = 5; break; } } // // Translate the configuration parity field into the format expected // by the host. // switch(ui32Config & UART_CONFIG_PAR_MASK) { case UART_CONFIG_PAR_NONE: { psLineCoding->ui8Parity = USB_CDC_PARITY_NONE; break; } case UART_CONFIG_PAR_ODD: { psLineCoding->ui8Parity = USB_CDC_PARITY_ODD; break; } case UART_CONFIG_PAR_EVEN: { psLineCoding->ui8Parity = USB_CDC_PARITY_EVEN; break; } case UART_CONFIG_PAR_ONE: { psLineCoding->ui8Parity = USB_CDC_PARITY_MARK; break; } case UART_CONFIG_PAR_ZERO: { psLineCoding->ui8Parity = USB_CDC_PARITY_SPACE; break; } } // // Translate the configuration stop bits field into the format expected // by the host. // switch(ui32Config & UART_CONFIG_STOP_MASK) { case UART_CONFIG_STOP_ONE: { psLineCoding->ui8Stop = USB_CDC_STOP_BITS_1; break; } case UART_CONFIG_STOP_TWO: { psLineCoding->ui8Stop = USB_CDC_STOP_BITS_2; break; } } } #endif //***************************************************************************** // // This is the callback from the USB DFU runtime interface driver. // // \param pvCBData is ignored by this function. // \param ui32Event is one of the valid events for a DFU device. // \param ui32MsgParam is defined by the event that occurs. // \param pvMsgData is a pointer to data that is defined by the event that // occurs. // // This function will be called to inform the application when a change occurs // during operation as a DFU device. Currently, the only event passed to this // callback is USBD_DFU_EVENT_DETACH which tells the recipient that they should // pass control to the boot loader at the earliest, non-interrupt context // point. // // \return This function will return 0. // //***************************************************************************** uint32_t DFUDetachCallback(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgData, void *pvMsgData) { if(ui32Event == USBD_DFU_EVENT_DETACH) { // // Set the flag that the main loop uses to determine when it is time // to transfer control back to the boot loader. Note that we // absolutely DO NOT call USBDDFUUpdateBegin() here since we are // currently in interrupt context and this would cause bad things to // happen (and the boot loader to not work). // g_bUpdateSignalled = true; } return(0); } //***************************************************************************** // // Handles CDC driver notifications related to control and setup of the device. // // \param pvCBData is the client-supplied callback pointer for this channel. // \param ui32Event identifies the event we are being notified about. // \param ui32MsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to perform control-related // operations on behalf of the USB host. These functions include setting // and querying the serial communication parameters, setting handshake line // states and sending break conditions. // // \return The return value is event-specific. // //***************************************************************************** uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { uint32_t ui32IntsOff; tUSBDCDCDevice * pCDCDevice; pCDCDevice = (tUSBDCDCDevice *)pvCBData; // Which event are we being asked to process? switch(ui32Event) { // We are connected to a host and communication is now possible. case USB_EVENT_CONNECTED: g_bUSBConfigured = true; g_bConnected = true; // Flush our buffers. USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); // Tell the main loop to update the display. ui32IntsOff = MAP_IntMasterDisable(); g_pcStatus = "Connected"; g_ui32Flags |= COMMAND_STATUS_UPDATE; if(!ui32IntsOff) { MAP_IntMasterEnable(); } break; // The host has disconnected. case USB_EVENT_DISCONNECTED: g_bUSBConfigured = false; g_bConnected = false; ui32IntsOff = MAP_IntMasterDisable(); g_pcStatus = "Disconnected"; g_ui32Flags |= COMMAND_STATUS_UPDATE; if(!ui32IntsOff) { MAP_IntMasterEnable(); } break; #if 1 // Return the current serial communication parameters. // We do not need this since there is no UART - Dhammika case USBD_CDC_EVENT_GET_LINE_CODING: GetLineCoding(pvMsgData); break; // Set the current serial communication parameters. // We do not need this since there is no UART - Dhammika case USBD_CDC_EVENT_SET_LINE_CODING: SetLineCoding(pvMsgData); break; // Set the current serial communication parameters. case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE: SetControlLineState((uint16_t)ui32MsgValue); break; #endif // Ignore SUSPEND and RESUME for now. case USB_EVENT_SUSPEND: case USB_EVENT_RESUME: break; // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. default: #ifdef DEBUG while(1); #else break; #endif } return(0); } //***************************************************************************** // // Handles CDC driver notifications related to the transmit channel (data to // the USB host). // // \param ui32CBData is the client-supplied callback pointer for this channel. // \param ui32Event identifies the event we are being notified about. // \param ui32MsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to notify us of any events // related to operation of the transmit data channel (the IN channel carrying // data to the USB host). // // \return The return value is event-specific. // //***************************************************************************** uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { // Which event have we been sent? switch(ui32Event) { case USB_EVENT_TX_COMPLETE: // Since we are using the USBBuffer, we don't need to do anything // here. break; // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. default: #ifdef DEBUG while(1); #else break; #endif } return(0); } //***************************************************************************** // // Handles CDC driver notifications related to the receive channel (data from // the USB host). // // \param ui32CBData is the client-supplied callback data value for this channel. // \param ui32Event identifies the event we are being notified about. // \param ui32MsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to notify us of any events // related to operation of the receive data channel (the OUT channel carrying // data from the USB host). // // \return The return value is event-specific. // //***************************************************************************** uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { uint32_t ui32Count; uint32_t ui32Read, ui32Space; uint8_t ui8Char; // Which event are we being sent? switch(ui32Event) { // A new packet has been received. case USB_EVENT_RX_AVAILABLE: { // How much space do we have in the buffer? ui32Space = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer); // Read data from the USB until there is none left or we run // out of space in our Tx buffer. while(ui32Space) { // Read the USB buffer if(USBBufferRead((tUSBBuffer *)&g_sRxBuffer, &ui8Char, 1)) { // Write the rceived character back into Tx buffer USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)&ui8Char, 1); // Decrement the number of bytes we know the buffer can accept. ui32Space--; // Update our count of bytes received via the USB. g_ui32UARTRxCount++; } else break; } break; } // We are being asked how much unprocessed data we have still to // process. We send 0 if USB Tx buffer can take data case USB_EVENT_DATA_REMAINING: { USBBufferFlush((tUSBBuffer *)&g_sTxBuffer); return(0); } // We are being asked to provide a buffer into which the next packet // can be read. We do not support this mode of receiving data so let // the driver know by returning 0. The CDC driver should not be sending // this message but this is included just for illustration and // completeness. case USB_EVENT_REQUEST_BUFFER: { return(0); } // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. default: #ifdef DEBUG while(1); #else break; #endif } return(0); } //***************************************************************************** // // This is the main application entry function. // //***************************************************************************** int main(void) { uint32_t ui32TxCount; uint32_t ui32RxCount; uint32_t ui32SysClock; // Enable lazy stacking for interrupt handlers. This allows floating-point // instructions to be used within interrupt handlers, but at the expense of // extra stack usage. MAP_FPULazyStackingEnable(); // Set the clocking to run from the PLL at 50MHz MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); ui32SysClock = MAP_SysCtlClockGet(); // Configure the required pins for USB operation. MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); MAP_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_5 | GPIO_PIN_4); // Enable the GPIO port that is used for the on-board LED. MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Enable the GPIO pins for the LED (PF2 & PF3). MAP_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3|GPIO_PIN_2); // Not configured initially. g_bUSBConfigured = false; // TODO: Add code to configure handshake GPIOs if required. // Enable the system tick. MAP_SysTickPeriodSet(ui32SysClock / SYSTICKS_PER_SECOND); MAP_SysTickIntEnable(); MAP_SysTickEnable(); // Initialize the transmit and receive buffers. USBBufferInit(&g_sTxBuffer); USBBufferInit(&g_sRxBuffer); // Set the USB stack mode to Device mode with VBUS monitoring. USBStackModeSet(0, eUSBModeForceDevice, 0); //---------------------------------------------------------- // Initialize each of the device instances that will form our composite // USB device. USBDCDCCompositeInit(0, &g_sCDCDevice, &(g_sCompDevice.psDevices[0])); USBDDFUCompositeInit(0, &g_sDFUDevice, &(g_sCompDevice.psDevices[1])); // Pass the USB library our device information, initialize the USB // controller and connect the device to the bus. void *pvCompositeInstance = USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_BUFFER_SIZE, g_pui8DescriptorBuffer); //----------------------------------------------------------- // Clear our local byte counters. ui32RxCount = 0; ui32TxCount = 0; // Main application loop. while(!g_bUpdateSignalled) { // Wait for USB configuration to complete. while(!g_bConnected) { } // Now keep processing the mouse as long as the host is connected and // we've not been told to prepare for a firmware upgrade. while(g_bConnected && !g_bUpdateSignalled) { // Have we been asked to update the status display? if(g_ui32Flags & COMMAND_STATUS_UPDATE) { // // Clear the command flag // MAP_IntMasterDisable(); g_ui32Flags &= ~COMMAND_STATUS_UPDATE; MAP_IntMasterEnable(); } // // Has there been any transmit traffic since we last checked? // if(ui32TxCount != g_ui32UARTTxCount) { // // Turn on the Green LED. // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3); // // Delay for a bit. // SysCtlDelay(MAP_SysCtlClockGet() / 3 / 20); // // Turn off the Green LED. // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0); // // Take a snapshot of the latest transmit count. // ui32TxCount = g_ui32UARTTxCount; } // // Has there been any receive traffic since we last checked? // if(ui32RxCount != g_ui32UARTRxCount) { // // Turn on the Blue LED. // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); // // Delay for a bit. // SysCtlDelay(MAP_SysCtlClockGet() / 3 / 20); // // Turn off the Blue LED. // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0); // // Take a snapshot of the latest receive count. // ui32RxCount = g_ui32UARTRxCount; } } } // Terminate the USB device and detach from the bus. // USBDCompositeTerm(pvCompositeInstance); USBDCDTerm(0); // Disable all interrupts. MAP_IntMasterDisable(); // Disable SysTick and its interrupt. MAP_SysTickIntDisable(); MAP_SysTickDisable(); // Disable all processor interrupts. Instead of disabling them one at a // time, a direct write to NVIC is done to disable all peripheral // interrupts. HWREG(NVIC_DIS0) = 0xffffffff; HWREG(NVIC_DIS1) = 0xffffffff; HWREG(NVIC_DIS2) = 0xffffffff; HWREG(NVIC_DIS3) = 0xffffffff; HWREG(NVIC_DIS4) = 0xffffffff; // // Enable and reset the USB peripheral. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0); MAP_USBClockEnable(USB0_BASE, 4, USB_CLOCK_INTERNAL); // // Wait for about a second. // MAP_SysCtlDelay(ui32SysClock / 3); // // Re-enable interrupts at the NVIC level. // MAP_IntMasterEnable(); // // Call the USB boot loader. // ROM_UpdateUSB(0); // // Should never get here, but just in case. // while(1) { } }
//***************************************************************************** // // usb_serial_structs.c - Data structures defining this CDC USB device. // // Copyright (c) 2012-2020 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. // // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. // // This is part of revision 2.2.0.295 of the EK-TM4C123GXL Firmware Package. // //***************************************************************************** #include <stdint.h> #include <stdbool.h> #include "inc/hw_types.h" #include "driverlib/usb.h" #include "usblib/usblib.h" #include "usblib/usbcdc.h" #include "usblib/usb-ids.h" #include "usblib/device/usbdevice.h" #include "usblib/device/usbdcdc.h" #include "usb_serial_structs.h" //***************************************************************************** // // The languages supported by this device. // //***************************************************************************** const uint8_t g_pui8LangDescriptor[] = { 4, USB_DTYPE_STRING, USBShort(USB_LANG_EN_US) }; //***************************************************************************** // // The manufacturer string. // //***************************************************************************** const uint8_t g_pui8ManufacturerString[] = { (17 + 1) * 2, USB_DTYPE_STRING, 'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0, 't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0, }; //***************************************************************************** // // The product string. // //***************************************************************************** const uint8_t g_pui8ProductString[] = { 2 + (16 * 2), USB_DTYPE_STRING, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0 }; //***************************************************************************** // // The serial number string. // //***************************************************************************** const uint8_t g_pui8SerialNumberString[] = { 2 + (8 * 2), USB_DTYPE_STRING, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0 }; //***************************************************************************** // // The control interface description string. // //***************************************************************************** const uint8_t g_pui8ControlInterfaceString[] = { 2 + (21 * 2), USB_DTYPE_STRING, 'A', 0, 'C', 0, 'M', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0, 'r', 0, 'o', 0, 'l', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0 }; //***************************************************************************** // // The configuration description string. // //***************************************************************************** const uint8_t g_pui8ConfigString[] = { 2 + (26 * 2), USB_DTYPE_STRING, 'S', 0, 'e', 0, 'l', 0, 'f', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0, 'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0, 'o', 0, 'n', 0 }; //***************************************************************************** // // The descriptor string table. // //***************************************************************************** const uint8_t * const g_ppui8StringDescriptors[] = { g_pui8LangDescriptor, g_pui8ManufacturerString, g_pui8ProductString, g_pui8SerialNumberString, g_pui8ControlInterfaceString, g_pui8ConfigString }; #define NUM_STRING_DESCRIPTORS (sizeof(g_ppui8StringDescriptors) / \ sizeof(uint8_t *)) //***************************************************************************** // // CDC device callback function prototypes. // //***************************************************************************** uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData); uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData); uint32_t ControlHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData); //***************************************************************************** // // The CDC device initialization and customization structures. In this case, // we are using USBBuffers between the CDC device class driver and the // application code. The function pointers and callback data values are set // to insert a buffer in each of the data channels, transmit and receive. // // With the buffer in place, the CDC channel callback is set to the relevant // channel function and the callback data is set to point to the channel // instance data. The buffer, in turn, has its callback set to the application // function and the callback data set to our CDC instance structure. // //***************************************************************************** tUSBDCDCDevice g_sCDCDevice = { USB_VID_TI_1CBE, USB_PID_SERIAL, 500, USB_CONF_ATTR_SELF_PWR, ControlHandler, (void *)&g_sCDCDevice, USBBufferEventCallback, (void *)&g_sRxBuffer, USBBufferEventCallback, (void *)&g_sTxBuffer, g_ppui8StringDescriptors, NUM_STRING_DESCRIPTORS }; //***************************************************************************** // // Receive buffer (from the USB perspective). // //***************************************************************************** uint8_t g_pui8USBRxBuffer[UART_BUFFER_SIZE]; tUSBBuffer g_sRxBuffer = { false, // This is a receive buffer. RxHandler, // pfnCallback (void *)&g_sCDCDevice, // Callback data is our device pointer. USBDCDCPacketRead, // pfnTransfer USBDCDCRxPacketAvailable, // pfnAvailable (void *)&g_sCDCDevice, // pvHandle g_pui8USBRxBuffer, // pui8Buffer UART_BUFFER_SIZE, // ui32BufferSize }; //***************************************************************************** // // Transmit buffer (from the USB perspective). // //***************************************************************************** uint8_t g_pui8USBTxBuffer[UART_BUFFER_SIZE]; tUSBBuffer g_sTxBuffer = { true, // This is a transmit buffer. TxHandler, // pfnCallback (void *)&g_sCDCDevice, // Callback data is our device pointer. USBDCDCPacketWrite, // pfnTransfer USBDCDCTxPacketAvailable, // pfnAvailable (void *)&g_sCDCDevice, // pvHandle g_pui8USBTxBuffer, // pui8Buffer UART_BUFFER_SIZE, // ui32BufferSize }; //***************************************************************************** // // The DFU runtime interface initialization and customization structures // //***************************************************************************** tUSBDDFUDevice g_sDFUDevice = { DFUDetachCallback, (void *)&g_sDFUDevice }; //**************************************************************************** // // The number of device class instances that this composite device will // use. // //**************************************************************************** #define NUM_DEVICES 2 //**************************************************************************** // // The array of devices supported by this composite device. // //**************************************************************************** tCompositeEntry g_psCompDevices[NUM_DEVICES]; //**************************************************************************** // // Additional workspace required by the composite driver to hold a lookup // table allowing mapping of composite interface and endpoint numbers to // individual device class instances. // //**************************************************************************** uint32_t g_pui32CompWorkspace[NUM_DEVICES]; //**************************************************************************** // // The instance data for this composite device. // //**************************************************************************** tCompositeInstance g_sCompInstance; //**************************************************************************** // // Allocate the Device Data for the top level composite device class. // //**************************************************************************** tUSBDCompositeDevice g_sCompDevice = { // Stellaris VID. USB_VID_TI_1CBE, // PID. USB_PID_SERIAL, // This is in milliamps. 500, // Bus powered device. USB_CONF_ATTR_SELF_PWR, // Device event handler function pointer (receives connect, disconnect // and other device-level notifications). ControlHandler, // The string table. g_ppui8StringDescriptors, NUM_STRING_DESCRIPTORS, // The Composite device array. NUM_DEVICES, g_psCompDevices, }; //**************************************************************************** // // A buffer into which the composite device can write the combined config // descriptor. // //**************************************************************************** uint8_t g_pui8DescriptorBuffer[DESCRIPTOR_BUFFER_SIZE];