CDCDSerialPort.c
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------------- */
2 /* Atmel Microcontroller Software Support */
3 /* SAM Software Package License */
4 /* ---------------------------------------------------------------------------- */
5 /* Copyright (c) 2015, Atmel Corporation */
6 /* */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without */
10 /* modification, are permitted provided that the following condition is met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, */
13 /* this list of conditions and the disclaimer below. */
14 /* */
15 /* Atmel's name may not be used to endorse or promote products derived from */
16 /* this software without specific prior written permission. */
17 /* */
18 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
19 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
21 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
22 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
24 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
25 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
26 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
28 /* ---------------------------------------------------------------------------- */
29 
38 /*------------------------------------------------------------------------------
39  * Headers
40  *------------------------------------------------------------------------------*/
41 
42 #include <CDCDSerialPort.h>
43 #include <CDCDescriptors.h>
44 #include <USBLib_Trace.h>
45 #include <board.h>
46 #include "../../libchip/include/usbhs.h"
47 /*------------------------------------------------------------------------------
48  * Types
49  *------------------------------------------------------------------------------*/
50 
52 typedef struct _CDCDParseData {
56  USBInterfaceDescriptor *pIfDesc;
57 
59 
60 /*------------------------------------------------------------------------------
61  * Internal variables
62  *------------------------------------------------------------------------------*/
63 
65 static CDCLineCoding lineCoding;
66 /*------------------------------------------------------------------------------
67  * Internal functions
68  *------------------------------------------------------------------------------*/
69 
75 static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc,
76  CDCDParseData *pArg)
77 {
78  CDCDSerialPort *pCdcd = pArg->pCdcd;
79 
80  /* Not a valid descriptor */
81  if (pDesc->bLength == 0)
82  return USBRC_PARAM_ERR;
83 
84  /* Find interface descriptor */
85  if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
86  USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor *)pDesc;
87 
88  /* Obtain interface from descriptor */
89  if (pCdcd->bInterfaceNdx == 0xFF) {
90  /* First interface is communication */
91  if (pIf->bInterfaceClass ==
93  pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
94  pCdcd->bNumInterface = 2;
95  }
96  /* Only data interface */
97  else if (pIf->bInterfaceClass == CDCDataInterfaceDescriptor_CLASS) {
98  pCdcd->bInterfaceNdx = pIf->bInterfaceNumber;
99  pCdcd->bNumInterface = 1;
100  }
101 
102  pArg->pIfDesc = pIf;
103  } else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber
104  && pCdcd->bInterfaceNdx + pCdcd->bNumInterface
105  > pIf->bInterfaceNumber)
106  pArg->pIfDesc = pIf;
107  }
108 
109  /* Parse valid interfaces */
110  if (pArg->pIfDesc == 0)
111  return 0;
112 
113  /* Find endpoint descriptors */
114  if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) {
115  USBEndpointDescriptor *pEp = (USBEndpointDescriptor *)pDesc;
116 
117  switch (pEp->bmAttributes & 0x3) {
119  if (pEp->bEndpointAddress & 0x80)
120  pCdcd->bIntInPIPE = pEp->bEndpointAddress & 0x7F;
121 
122  break;
123 
125  if (pEp->bEndpointAddress & 0x80)
126  pCdcd->bBulkInPIPE = pEp->bEndpointAddress & 0x7F;
127  else
128  pCdcd->bBulkOutPIPE = pEp->bEndpointAddress;
129  }
130  }
131 
132  if (pCdcd->bInterfaceNdx != 0xFF
133  && pCdcd->bBulkInPIPE != 0
134  && pCdcd->bBulkOutPIPE != 0)
135  return USBRC_FINISHED;
136 
137  return 0;
138 }
139 
147 {
148  uint32_t exec = 1;
149 
150  if (pCdcd->fEventHandler) {
151  uint32_t rc = pCdcd->fEventHandler(
153  (uint32_t)(&lineCoding),
154  pCdcd->pEventArg);
155 
156  if (rc == USBD_STATUS_SUCCESS) {
157  pCdcd->lineCoding.dwDTERate = lineCoding.dwDTERate;
158  pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat;
159  pCdcd->lineCoding.bParityType = lineCoding.bParityType;
160  pCdcd->lineCoding.bDataBits = lineCoding.bDataBits;
161  } else
162  exec = 0;
163  }
164 
165  if (exec)
166  USBD_Write(0, 0, 0, 0, 0);
167  else
168  USBD_Stall(0);
169 }
170 
176 {
177  TRACE_INFO_WP("sLineCoding ");
178 
179  USBD_Read(0,
180  (void *) & (lineCoding),
181  sizeof(CDCLineCoding),
183  (void *)pCdcd);
184 }
185 
192 {
193  TRACE_INFO_WP("gLineCoding ");
194 
195  USBD_Write(0,
196  (void *)&(pCdcd->lineCoding),
197  sizeof(CDCLineCoding),
198  0,
199  0);
200 }
201 
211  const USBGenericRequest *request)
212 {
213 #if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
214  uint8_t DTR, RTS;
215 
216  DTR = ((request->wValue & CDCControlLineState_DTR) > 0);
217  RTS = ((request->wValue & CDCControlLineState_RTS) > 0);
218  TRACE_INFO_WP("sControlLineState(%d, %d) ", DTR, RTS);
219 #endif
220 
221  pCdcd->bControlLineState = (uint8_t)request->wValue;
222  USBD_Write(0, 0, 0, 0, 0);
223 
224  if (pCdcd->fEventHandler)
226  (uint32_t)pCdcd->bControlLineState,
227  pCdcd->pEventArg);
228 }
229 
230 /*------------------------------------------------------------------------------
231  * Exported functions
232  *------------------------------------------------------------------------------*/
233 
244  USBDDriver *pUsbd,
245  CDCDSerialPortEventHandler fEventHandler,
246  void *pArg,
247  uint8_t firstInterface, uint8_t numInterface)
248 {
249  TRACE_INFO("CDCDSerialPort_Initialize\n\r");
250 
251  /* Initialize event handler */
252  pCdcd->fEventHandler = fEventHandler;
253  pCdcd->pEventArg = pArg;
254 
255  /* Initialize transfer callback */
256  pCdcd->fTransCLK = 0;
257  pCdcd->pTansArg = 0;
258 
259  /* Initialize USB Device Driver interface */
260  pCdcd->pUsbd = pUsbd;
261  pCdcd->bInterfaceNdx = firstInterface;
262  pCdcd->bNumInterface = numInterface;
263  pCdcd->bIntInPIPE = 0;
264  pCdcd->bBulkInPIPE = 0;
265  pCdcd->bBulkOutPIPE = 0;
266 
267  /* Initialize Abstract Control Model attributes */
268  pCdcd->bControlLineState = 0;
269  pCdcd->wSerialState = 0;
271  115200,
274  8);
275 }
276 
286 USBGenericDescriptor *CDCDSerialPort_ParseInterfaces(
288  USBGenericDescriptor *pDescriptors,
289  uint32_t dwLength)
290 {
291  CDCDParseData parseData;
292 
293  parseData.pCdcd = pCdcd;
294  parseData.pIfDesc = 0;
295 
297  pDescriptors, dwLength,
299  &parseData);
300 }
301 
302 
312  const USBGenericRequest *request)
313 {
315  return USBRC_PARAM_ERR;
316 
317  TRACE_INFO_WP("Cdcs ");
318 
319  /* Validate interface */
320  if (request->wIndex >= pCdcd->bInterfaceNdx &&
321  request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) {
322  } else
323  return USBRC_PARAM_ERR;
324 
325  /* Handle the request */
326  switch (USBGenericRequest_GetRequest(request)) {
327 
329 
330  _SetLineCoding(pCdcd);
331  break;
332 
334 
335  _GetLineCoding(pCdcd);
336  break;
337 
339 
340  _SetControlLineState(pCdcd, request);
341  break;
342 
343  default:
344 
345  return USBRC_PARAM_ERR;
346  }
347 
348  return USBRC_SUCCESS;
349 }
350 
364  void *pData, uint32_t dwSize,
365  TransferCallback fCallback, void *pArg)
366 {
367  if (pCdcd->bBulkOutPIPE == 0)
368  return USBRC_PARAM_ERR;
369 
370  return USBD_Read(pCdcd->bBulkOutPIPE,
371  pData, dwSize,
372  fCallback, pArg);
373 }
374 
375 
381 {
382  USBD_Write(pCdcd->bBulkInPIPE, 0, 0, pCdcd->fTransCLK, pCdcd->pTansArg);
383 }
384 
400  void *pData, uint32_t dwSize,
401  TransferCallback fCallback, void *pArg)
402 {
403  uint32_t result;
404  Usbhs *pUdp = USBHS;
405  uint32_t endpointSize;
406 
407  if (pCdcd->bBulkInPIPE == 0)
408  return USBRC_PARAM_ERR;
409 
410  endpointSize = USBHS_GetEpSize(pUdp, pCdcd->bBulkInPIPE);
411 
412  if (dwSize % endpointSize == 0) {
413  pCdcd->fTransCLK = fCallback;
414  pCdcd->pTansArg = pArg;
415  result = USBD_Write(pCdcd->bBulkInPIPE,
416  pData, dwSize,
417  (TransferCallback)_UsbDataSent_ZLP, (void *)pCdcd);
418  } else {
419  result = USBD_Write(pCdcd->bBulkInPIPE,
420  pData, dwSize,
421  fCallback, pArg);
422 
423  }
424 
425  return result;
426 }
427 
433 {
434  return pCdcd->bControlLineState;
435 }
436 
443  CDCLineCoding *pLineCoding)
444 {
445  if (pLineCoding) {
446  pLineCoding->dwDTERate = pCdcd->lineCoding.dwDTERate;
447  pLineCoding->bCharFormat = pCdcd->lineCoding.bCharFormat;
448  pLineCoding->bParityType = pCdcd->lineCoding.bParityType;
449  pLineCoding->bDataBits = pCdcd->lineCoding.bDataBits;
450  }
451 }
452 
458 {
459  return pCdcd->wSerialState;
460 }
461 
468  uint16_t wSerialState)
469 {
470  if (pCdcd->bIntInPIPE == 0)
471  return;
472 
473  /* If new state is different from previous one, send a notification to the
474  host */
475  if (pCdcd->wSerialState != wSerialState) {
476 
477  pCdcd->wSerialState = wSerialState;
478  USBD_Write(pCdcd->bIntInPIPE,
479  &(pCdcd->wSerialState),
480  2,
481  0,
482  0);
483 
484  /* Reset one-time flags */
490  }
491 }
492 
CDCDSerialPort * pCdcd
uint32_t CDCDSerialPort_Write(CDCDSerialPort *pCdcd, void *pData, uint32_t dwSize, TransferCallback fCallback, void *pArg)
__STATIC_INLINE uint32_t USBHS_GetEpSize(Usbhs *pUsbhs, uint8_t Ep)
#define USBGenericDescriptor_ENDPOINT
static void _UsbDataSent_ZLP(CDCDSerialPort *pCdcd)
#define USBEndpointDescriptor_INTERRUPT
uint16_t CDCDSerialPort_GetSerialState(const CDCDSerialPort *pCdcd)
#define CDCSerialState_BREAK
uint16_t wSerialState
void CDCDSerialPort_SetSerialState(CDCDSerialPort *pCdcd, uint16_t wSerialState)
uint8_t USBGenericRequest_GetType(const USBGenericRequest *request)
Definition: USBRequests.c:54
uint32_t CDCDSerialPort_RequestHandler(CDCDSerialPort *pCdcd, const USBGenericRequest *request)
USBDDriver * pUsbd
void CDCLineCoding_Initialize(CDCLineCoding *lineCoding, uint32_t bitrate, uint8_t stopbits, uint8_t parity, uint8_t databits)
Definition: CDCLineCoding.c:58
#define TRACE_INFO(...)
Definition: USBLib_Trace.h:166
static void _GetLineCoding(CDCDSerialPort *pCdcd)
USBInterfaceDescriptor * pIfDesc
#define CDCSerialState_FRAMING
uint8_t USBD_Stall(uint8_t bEndpoint)
Definition: USBD.c:427
#define CDCControlLineState_RTS
Definition: CDCRequests.h:91
static void _SetControlLineState(CDCDSerialPort *pCdcd, const USBGenericRequest *request)
static void _SetLineCoding(CDCDSerialPort *pCdcd)
uint8_t USBD_Read(uint8_t bEndpoint, void *pData, uint32_t dLength, TransferCallback fCallback, void *pArgument)
Definition: USBD.c:318
uint8_t CDCDSerialPort_GetControlLineState(const CDCDSerialPort *pCdcd)
#define USBHS
(USBHS ) Base Address
Definition: same70j19.h:508
uint8_t USBD_Write(uint8_t bEndpoint, const void *pData, uint32_t dLength, TransferCallback fCallback, void *pArgument)
Definition: USBD.c:191
Definition: m2m_wifi.h:117
#define CDCLineCoding_ONESTOPBIT
Definition: CDCRequests.h:102
void CDCDSerialPort_Initialize(CDCDSerialPort *pCdcd, USBDDriver *pUsbd, CDCDSerialPortEventHandler fEventHandler, void *pArg, uint8_t firstInterface, uint8_t numInterface)
uint32_t(* USBDescriptorParseFunction)(void *descriptor, void *parseArg)
#define CDCSerialState_OVERRUN
static CDCLineCoding lineCoding
CDCDSerialPortEventHandler fEventHandler
#define USBEndpointDescriptor_BULK
#define CDCLineCoding_NOPARITY
Definition: CDCRequests.h:119
uint8_t USBGenericRequest_GetRequest(const USBGenericRequest *request)
Definition: USBRequests.c:65
void(* TransferCallback)(void *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
Definition: USBD.h:200
void CDCDSerialPort_GetLineCoding(const CDCDSerialPort *pCdcd, CDCLineCoding *pLineCoding)
#define CDCSerialState_RINGSIGNAL
#define CDCControlLineState_DTR
Definition: CDCRequests.h:87
static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc, CDCDParseData *pArg)
#define CDCSerialState_PARITY
#define CDCDSerialPortEvent_SETCONTROLLINESTATE
uint32_t(* CDCDSerialPortEventHandler)(uint32_t dwEvent, uint32_t dwParam, void *pArguments)
#define USBGenericDescriptor_INTERFACE
struct _CDCDParseData CDCDParseData
static void _SetLineCodingCallback(CDCDSerialPort *pCdcd)
uint8_t bControlLineState
TransferCallback fTransCLK
USBGenericDescriptor * CDCDSerialPort_ParseInterfaces(CDCDSerialPort *pCdcd, USBGenericDescriptor *pDescriptors, uint32_t dwLength)
#define USBGenericRequest_CLASS
Definition: USBRequests.h:163
CDCLineCoding lineCoding
#define CDCDataInterfaceDescriptor_CLASS
#define CDCGenericRequest_SETLINECODING
Definition: CDCRequests.h:71
#define CDCGenericRequest_GETLINECODING
Definition: CDCRequests.h:73
#define CDCCommunicationInterfaceDescriptor_CLASS
#define CDCDSerialPortEvent_SETLINECODING
Standard board header file.
#define CDCGenericRequest_SETCONTROLLINESTATE
Definition: CDCRequests.h:75
#define USBD_STATUS_SUCCESS
Definition: USBD.h:100
#define TRACE_INFO_WP(...)
Definition: USBLib_Trace.h:167
USBGenericDescriptor * USBGenericDescriptor_Parse(const USBGenericDescriptor *descriptor, uint32_t totalLength, USBDescriptorParseFunction parseFunction, void *parseArg)
uint32_t CDCDSerialPort_Read(const CDCDSerialPort *pCdcd, void *pData, uint32_t dwSize, TransferCallback fCallback, void *pArg)


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04