00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00028 /* ---------------------------------------------------------------------------- */ 00029 /** \file */ 00030 /** \addtogroup usbd_composite_cdccdc 00031 *@{ 00032 */ 00033 /*--------------------------------------------------------------------------- 00034 * Headers 00035 *---------------------------------------------------------------------------*/ 00036 00037 /* GENERAL */ 00038 #include <USBLib_Trace.h> 00039 00040 /* USB */ 00041 #include "USBD.h" 00042 #include <USBD_HAL.h> 00043 #include <USBDDriver.h> 00044 00045 /* - DUALCDC */ 00046 #include <DUALCDCDDriver.h> 00047 00048 /*--------------------------------------------------------------------------- 00049 * Defines 00050 *---------------------------------------------------------------------------*/ 00051 00052 /** Number of CDC serial ports */ 00053 #define NUM_PORTS 2 00054 00055 /** Interface setting spaces (4 byte aligned) */ 00056 #define NUM_INTERFACES ((DUALCDCDDriverDescriptors_NUMINTERFACE+3)&0xFC) 00057 00058 /*--------------------------------------------------------------------------- 00059 * Types 00060 *---------------------------------------------------------------------------*/ 00061 00062 /** Dual-CDC-Serial device driver struct */ 00063 typedef struct _DualCdcdSerialDriver { 00064 /** CDC Serial Port List */ 00065 CDCDSerialPort cdcdSerialPort[NUM_PORTS]; 00066 } DualCdcdSerialDriver; 00067 00068 /*--------------------------------------------------------------------------- 00069 * Internal variables 00070 *---------------------------------------------------------------------------*/ 00071 00072 /** Dual CDC Serial device driver instance */ 00073 DualCdcdSerialDriver dualcdcdDriver; 00074 00075 /*--------------------------------------------------------------------------- 00076 * Internal functions 00077 *---------------------------------------------------------------------------*/ 00078 00079 /*--------------------------------------------------------------------------- 00080 * Exported functions 00081 *---------------------------------------------------------------------------*/ 00082 00083 /** 00084 * Initializes the USB device composite device driver. 00085 * \param pDescriptors Pointer to Descriptors list for CDC Serial Device. 00086 */ 00087 void DUALCDCDDriver_Initialize(const USBDDriverDescriptors *pDescriptors) 00088 { 00089 USBDDriver *pUsbd = USBD_GetDriver(); 00090 CDCDSerialPort *pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; 00091 00092 TRACE_INFO("DUALCDCDDriver_Initialize\n\r"); 00093 00094 pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; 00095 CDCDSerialPort_Initialize(pCdcd, pUsbd, 00096 0, 00097 0, 00098 DUALCDCDDriverDescriptors_INTERFACENUM0, 2); 00099 00100 pCdcd = &dualcdcdDriver.cdcdSerialPort[1]; 00101 CDCDSerialPort_Initialize(pCdcd, pUsbd, 00102 0, 00103 0, 00104 DUALCDCDDriverDescriptors_INTERFACENUM1, 2); 00105 00106 /* Initialize the standard USB driver */ 00107 USBDDriver_Initialize(pUsbd, 00108 pDescriptors, 00109 0); 00110 /* Initialize the USB driver */ 00111 USBD_Init(); 00112 } 00113 00114 /** 00115 * Invoked whenever the active configuration of device is changed by the 00116 * host. 00117 * \param cfgnum Configuration number. 00118 */ 00119 void DUALCDCDDriver_ConfigurationChangeHandler(uint8_t cfgnum) 00120 { 00121 CDCDSerialPort *pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; 00122 USBDDriver *pUsbd = pCdcd->pUsbd; 00123 USBConfigurationDescriptor *pDesc; 00124 USBGenericDescriptor *pD; 00125 uint32_t i, len; 00126 00127 if (cfgnum > 0) { 00128 00129 /* Parse endpoints for data & notification */ 00130 pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); 00131 00132 pD = (USBGenericDescriptor *)pDesc; 00133 len = pDesc->wTotalLength; 00134 00135 for (i = 0; i < NUM_PORTS; i ++) { 00136 pCdcd = &dualcdcdDriver.cdcdSerialPort[i]; 00137 pD = CDCDSerialPort_ParseInterfaces(pCdcd, pD, len); 00138 len = pDesc->wTotalLength - ((uint32_t)pD - (uint32_t)pDesc); 00139 } 00140 } 00141 } 00142 00143 00144 /** 00145 * Handles composite-specific USB requests sent by the host, and forwards 00146 * standard ones to the USB device driver. 00147 * \param request Pointer to a USBGenericRequest instance. 00148 */ 00149 void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request) 00150 { 00151 CDCDSerialPort *pCdcd = 0; 00152 USBDDriver *pUsbd = 0; 00153 uint32_t rc, i; 00154 00155 TRACE_INFO_WP("NewReq "); 00156 00157 for (i = 0; i < NUM_PORTS; i ++) { 00158 pCdcd = &dualcdcdDriver.cdcdSerialPort[i]; 00159 rc = CDCDSerialPort_RequestHandler(pCdcd, request); 00160 00161 if (rc == USBRC_SUCCESS) 00162 break; 00163 } 00164 00165 /* Not handled by CDC Serial */ 00166 if (rc != USBRC_SUCCESS) { 00167 if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { 00168 pUsbd = pCdcd->pUsbd; 00169 USBDDriver_RequestHandler(pUsbd, request); 00170 } else { 00171 TRACE_WARNING( 00172 "DUALCDCDDriver_RequestHandler: Unsupported request (%d,%d)\n\r", 00173 USBGenericRequest_GetType(request), 00174 USBGenericRequest_GetRequest(request)); 00175 USBD_Stall(0); 00176 } 00177 } 00178 00179 } 00180 00181 /** 00182 * Return CDCDSerialPort for serial port operations. 00183 * \param port Port number. 00184 */ 00185 CDCDSerialPort *DUALCDCDDriver_GetSerialPort(uint32_t port) 00186 { 00187 if (port < NUM_PORTS) 00188 return &dualcdcdDriver.cdcdSerialPort[port]; 00189 00190 return 0; 00191 } 00192 00193 /**@}*/ 00194