3 Copyright (C) Dean Camera, 2012.
5 dean [at] fourwalledcubicle [dot] com
10 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
31 #define __INCLUDE_FROM_USB_DRIVER
32 #include "../../Core/USBMode.h"
34 #if defined(USB_CAN_BE_DEVICE)
36 #define __INCLUDE_FROM_CDC_DRIVER
37 #define __INCLUDE_FROM_CDC_DEVICE_C
38 #include "CDCClassDevice.h"
40 void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
42 if (!(Endpoint_IsSETUPReceived()))
45 if (USB_ControlRequest
.wIndex
!= CDCInterfaceInfo
->Config
.ControlInterfaceNumber
)
48 switch (USB_ControlRequest
.bRequest
)
50 case CDC_REQ_GetLineEncoding
:
51 if (USB_ControlRequest
.bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_CLASS
| REQREC_INTERFACE
))
53 Endpoint_ClearSETUP();
55 while (!(Endpoint_IsINReady()));
57 Endpoint_Write_32_LE(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
);
58 Endpoint_Write_8(CDCInterfaceInfo
->State
.LineEncoding
.CharFormat
);
59 Endpoint_Write_8(CDCInterfaceInfo
->State
.LineEncoding
.ParityType
);
60 Endpoint_Write_8(CDCInterfaceInfo
->State
.LineEncoding
.DataBits
);
63 Endpoint_ClearStatusStage();
67 case CDC_REQ_SetLineEncoding
:
68 if (USB_ControlRequest
.bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_CLASS
| REQREC_INTERFACE
))
70 Endpoint_ClearSETUP();
72 while (!(Endpoint_IsOUTReceived()))
74 if (USB_DeviceState
== DEVICE_STATE_Unattached
)
78 CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
= Endpoint_Read_32_LE();
79 CDCInterfaceInfo
->State
.LineEncoding
.CharFormat
= Endpoint_Read_8();
80 CDCInterfaceInfo
->State
.LineEncoding
.ParityType
= Endpoint_Read_8();
81 CDCInterfaceInfo
->State
.LineEncoding
.DataBits
= Endpoint_Read_8();
84 Endpoint_ClearStatusStage();
86 EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo
);
90 case CDC_REQ_SetControlLineState
:
91 if (USB_ControlRequest
.bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_CLASS
| REQREC_INTERFACE
))
93 Endpoint_ClearSETUP();
94 Endpoint_ClearStatusStage();
96 CDCInterfaceInfo
->State
.ControlLineStates
.HostToDevice
= USB_ControlRequest
.wValue
;
98 EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo
);
102 case CDC_REQ_SendBreak
:
103 if (USB_ControlRequest
.bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_CLASS
| REQREC_INTERFACE
))
105 Endpoint_ClearSETUP();
106 Endpoint_ClearStatusStage();
108 EVENT_CDC_Device_BreakSent(CDCInterfaceInfo
, (uint8_t)USB_ControlRequest
.wValue
);
115 bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
117 memset(&CDCInterfaceInfo
->State
, 0x00, sizeof(CDCInterfaceInfo
->State
));
119 CDCInterfaceInfo
->Config
.DataINEndpoint
.Type
= EP_TYPE_BULK
;
120 CDCInterfaceInfo
->Config
.DataOUTEndpoint
.Type
= EP_TYPE_BULK
;
121 CDCInterfaceInfo
->Config
.NotificationEndpoint
.Type
= EP_TYPE_INTERRUPT
;
123 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo
->Config
.DataINEndpoint
, 1)))
126 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo
->Config
.DataOUTEndpoint
, 1)))
129 if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo
->Config
.NotificationEndpoint
, 1)))
135 void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
137 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
140 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
141 CDC_Device_Flush(CDCInterfaceInfo
);
145 uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
,
146 const char* const String
)
148 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
149 return ENDPOINT_RWSTREAM_DeviceDisconnected
;
151 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataINEndpoint
.Address
);
152 return Endpoint_Write_Stream_LE(String
, strlen(String
), NULL
);
155 uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
,
156 const char* const Buffer
,
157 const uint16_t Length
)
159 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
160 return ENDPOINT_RWSTREAM_DeviceDisconnected
;
162 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataINEndpoint
.Address
);
163 return Endpoint_Write_Stream_LE(Buffer
, Length
, NULL
);
166 uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
,
169 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
170 return ENDPOINT_RWSTREAM_DeviceDisconnected
;
172 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataINEndpoint
.Address
);
174 if (!(Endpoint_IsReadWriteAllowed()))
180 if ((ErrorCode
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
)
184 Endpoint_Write_8(Data
);
185 return ENDPOINT_READYWAIT_NoError
;
188 uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
190 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
191 return ENDPOINT_RWSTREAM_DeviceDisconnected
;
195 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataINEndpoint
.Address
);
197 if (!(Endpoint_BytesInEndpoint()))
198 return ENDPOINT_READYWAIT_NoError
;
200 bool BankFull
= !(Endpoint_IsReadWriteAllowed());
206 if ((ErrorCode
= Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError
)
212 return ENDPOINT_READYWAIT_NoError
;
215 uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
217 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
220 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataOUTEndpoint
.Address
);
222 if (Endpoint_IsOUTReceived())
224 if (!(Endpoint_BytesInEndpoint()))
231 return Endpoint_BytesInEndpoint();
240 int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
242 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
245 int16_t ReceivedByte
= -1;
247 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.DataOUTEndpoint
.Address
);
249 if (Endpoint_IsOUTReceived())
251 if (Endpoint_BytesInEndpoint())
252 ReceivedByte
= Endpoint_Read_8();
254 if (!(Endpoint_BytesInEndpoint()))
261 void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
)
263 if ((USB_DeviceState
!= DEVICE_STATE_Configured
) || !(CDCInterfaceInfo
->State
.LineEncoding
.BaudRateBPS
))
266 Endpoint_SelectEndpoint(CDCInterfaceInfo
->Config
.NotificationEndpoint
.Address
);
268 USB_Request_Header_t Notification
= (USB_Request_Header_t
)
270 .bmRequestType
= (REQDIR_DEVICETOHOST
| REQTYPE_CLASS
| REQREC_INTERFACE
),
271 .bRequest
= CDC_NOTIF_SerialState
,
272 .wValue
= CPU_TO_LE16(0),
273 .wIndex
= CPU_TO_LE16(0),
274 .wLength
= CPU_TO_LE16(sizeof(CDCInterfaceInfo
->State
.ControlLineStates
.DeviceToHost
)),
277 Endpoint_Write_Stream_LE(&Notification
, sizeof(USB_Request_Header_t
), NULL
);
278 Endpoint_Write_Stream_LE(&CDCInterfaceInfo
->State
.ControlLineStates
.DeviceToHost
,
279 sizeof(CDCInterfaceInfo
->State
.ControlLineStates
.DeviceToHost
),
284 #if defined(FDEV_SETUP_STREAM)
285 void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
,
288 *Stream
= (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar
, CDC_Device_getchar
, _FDEV_SETUP_RW
);
289 fdev_set_udata(Stream
, CDCInterfaceInfo
);
292 void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t
* const CDCInterfaceInfo
,
295 *Stream
= (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar
, CDC_Device_getchar_Blocking
, _FDEV_SETUP_RW
);
296 fdev_set_udata(Stream
, CDCInterfaceInfo
);
299 static int CDC_Device_putchar(char c
,
302 return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t
*)fdev_get_udata(Stream
), c
) ? _FDEV_ERR
: 0;
305 static int CDC_Device_getchar(FILE* Stream
)
307 int16_t ReceivedByte
= CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t
*)fdev_get_udata(Stream
));
309 if (ReceivedByte
< 0)
315 static int CDC_Device_getchar_Blocking(FILE* Stream
)
317 int16_t ReceivedByte
;
319 while ((ReceivedByte
= CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t
*)fdev_get_udata(Stream
))) < 0)
321 if (USB_DeviceState
== DEVICE_STATE_Unattached
)
324 CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t
*)fdev_get_udata(Stream
));
332 // cppcheck-suppress unusedFunction
333 void CDC_Device_Event_Stub(void)