1 /*----------------------------------------------------------------------------
3 *----------------------------------------------------------------------------
5 * Purpose: USB Communication Device Class User module
7 *----------------------------------------------------------------------------
8 * This software is supplied "AS IS" without any warranties, express,
9 * implied or statutory, including but not limited to the implied
10 * warranties of fitness for purpose, satisfactory quality and
11 * noninfringement. Keil extends you a royalty-free right to reproduce
12 * and distribute executable files created using this software for use
13 * on NXP Semiconductors LPC microcontroller devices only. Nothing else
14 * gives you the right to use this software.
16 * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
17 *---------------------------------------------------------------------------*/
19 #include "lpc_types.h"
30 unsigned char BulkBufIn [USB_CDC_BUFSIZE]; // Buffer to store USB IN packet
31 unsigned char BulkBufOut [USB_CDC_BUFSIZE]; // Buffer to store USB OUT packet
32 unsigned char NotificationBuf [10];
34 CDC_LINE_CODING CDC_LineCoding = {9600, 0, 0, 8};
35 unsigned short CDC_SerialState = 0x0000;
36 unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
38 /*----------------------------------------------------------------------------
39 We need a buffer for incomming data on USB port because USB receives
40 much faster than UART transmits
41 *---------------------------------------------------------------------------*/
43 #define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2)
44 // large enough for file transfer
45 #define CDC_BUF_MASK (CDC_BUF_SIZE-1ul)
47 /* Buffer read / write macros */
48 #define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)
49 #define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))
50 #define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])
51 #define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx)
52 #define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1)
53 #define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))
57 typedef struct __CDC_BUF_T {
58 unsigned char data[CDC_BUF_SIZE];
63 CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
65 /*----------------------------------------------------------------------------
66 read data from CDC_OutBuf
67 *---------------------------------------------------------------------------*/
68 int CDC_RdOutBuf (char *buffer, const int *length) {
69 int bytesToRead, bytesRead;
71 /* Read *length bytes, block if *bytes are not avaialable */
72 bytesToRead = *length;
73 bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
74 bytesRead = bytesToRead;
77 // ... add code to check for underrun
79 while (bytesToRead--) {
80 *buffer++ = CDC_BUF_RD(CDC_OutBuf);
85 /*----------------------------------------------------------------------------
86 write data to CDC_OutBuf
87 *---------------------------------------------------------------------------*/
88 int CDC_WrOutBuf (const char *buffer, int *length) {
89 int bytesToWrite, bytesWritten;
91 // Write *length bytes
92 bytesToWrite = *length;
93 bytesWritten = bytesToWrite;
96 // ... add code to check for overwrite
98 while (bytesToWrite) {
99 CDC_BUF_WR(CDC_OutBuf, *buffer++); // Copy Data to buffer
103 return (bytesWritten);
106 /*----------------------------------------------------------------------------
107 check if character(s) are available at CDC_OutBuf
108 *---------------------------------------------------------------------------*/
109 int CDC_OutBufAvailChar (int *availChar) {
111 *availChar = CDC_BUF_COUNT(CDC_OutBuf);
115 /* end Buffer handling */
118 /*----------------------------------------------------------------------------
120 Initializes the data structures and serial port
123 *---------------------------------------------------------------------------*/
124 void CDC_Init (char portNum ) {
129 ser_InitPort0 (CDC_LineCoding.dwDTERate,
130 CDC_LineCoding.bDataBits,
131 CDC_LineCoding.bParityType,
132 CDC_LineCoding.bCharFormat);
137 ser_InitPort1 (CDC_LineCoding.dwDTERate,
138 CDC_LineCoding.bDataBits,
139 CDC_LineCoding.bParityType,
140 CDC_LineCoding.bCharFormat);
143 CDC_SerialState = CDC_GetSerialState();
145 CDC_BUF_RESET(CDC_OutBuf);
149 /*----------------------------------------------------------------------------
150 CDC SendEncapsulatedCommand Request Callback
151 Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
152 Parameters: None (global SetupPacket and EP0Buf)
153 Return Value: TRUE - Success, FALSE - Error
154 *---------------------------------------------------------------------------*/
155 uint32_t CDC_SendEncapsulatedCommand (void) {
161 /*----------------------------------------------------------------------------
162 CDC GetEncapsulatedResponse Request Callback
163 Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
164 Parameters: None (global SetupPacket and EP0Buf)
165 Return Value: TRUE - Success, FALSE - Error
166 *---------------------------------------------------------------------------*/
167 uint32_t CDC_GetEncapsulatedResponse (void) {
169 /* ... add code to handle request */
174 /*----------------------------------------------------------------------------
175 CDC SetCommFeature Request Callback
176 Called automatically on CDC Set_COMM_FATURE Request
177 Parameters: FeatureSelector
178 Return Value: TRUE - Success, FALSE - Error
179 *---------------------------------------------------------------------------*/
180 uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector) {
182 /* ... add code to handle request */
187 /*----------------------------------------------------------------------------
188 CDC GetCommFeature Request Callback
189 Called automatically on CDC Get_COMM_FATURE Request
190 Parameters: FeatureSelector
191 Return Value: TRUE - Success, FALSE - Error
192 *---------------------------------------------------------------------------*/
193 uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector) {
195 /* ... add code to handle request */
200 /*----------------------------------------------------------------------------
201 CDC ClearCommFeature Request Callback
202 Called automatically on CDC CLEAR_COMM_FATURE Request
203 Parameters: FeatureSelector
204 Return Value: TRUE - Success, FALSE - Error
205 *---------------------------------------------------------------------------*/
206 uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector) {
208 /* ... add code to handle request */
213 /*----------------------------------------------------------------------------
214 CDC SetLineCoding Request Callback
215 Called automatically on CDC SET_LINE_CODING Request
216 Parameters: none (global SetupPacket and EP0Buf)
217 Return Value: TRUE - Success, FALSE - Error
218 *---------------------------------------------------------------------------*/
219 uint32_t CDC_SetLineCoding (void) {
221 CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0)
225 CDC_LineCoding.bCharFormat = EP0Buf[4];
226 CDC_LineCoding.bParityType = EP0Buf[5];
227 CDC_LineCoding.bDataBits = EP0Buf[6];
232 ser_InitPort1 (CDC_LineCoding.dwDTERate,
233 CDC_LineCoding.bDataBits,
234 CDC_LineCoding.bParityType,
235 CDC_LineCoding.bCharFormat);
239 ser_InitPort0 (CDC_LineCoding.dwDTERate,
240 CDC_LineCoding.bDataBits,
241 CDC_LineCoding.bParityType,
242 CDC_LineCoding.bCharFormat);
248 /*----------------------------------------------------------------------------
249 CDC GetLineCoding Request Callback
250 Called automatically on CDC GET_LINE_CODING Request
251 Parameters: None (global SetupPacket and EP0Buf)
252 Return Value: TRUE - Success, FALSE - Error
253 *---------------------------------------------------------------------------*/
254 uint32_t CDC_GetLineCoding (void) {
256 EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF;
257 EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF;
258 EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;
259 EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;
260 EP0Buf[4] = CDC_LineCoding.bCharFormat;
261 EP0Buf[5] = CDC_LineCoding.bParityType;
262 EP0Buf[6] = CDC_LineCoding.bDataBits;
268 /*----------------------------------------------------------------------------
269 CDC SetControlLineState Request Callback
270 Called automatically on CDC SET_CONTROL_LINE_STATE Request
271 Parameters: ControlSignalBitmap
272 Return Value: TRUE - Success, FALSE - Error
273 *---------------------------------------------------------------------------*/
274 uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) {
276 /* ... add code to handle request */
281 /*----------------------------------------------------------------------------
282 CDC SendBreak Request Callback
283 Called automatically on CDC Set_COMM_FATURE Request
284 Parameters: 0xFFFF start of Break
286 0x#### Duration of Break
287 Return Value: TRUE - Success, FALSE - Error
288 *---------------------------------------------------------------------------*/
289 uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
291 /* ... add code to handle request */
296 /*----------------------------------------------------------------------------
297 CDC_BulkIn call on DataIn Request
300 *---------------------------------------------------------------------------*/
301 void CDC_BulkIn(void) {
302 int numBytesRead, numBytesAvail;
304 ser_AvailChar (&numBytesAvail);
306 // ... add code to check for overwrite
308 numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);
311 if (numBytesRead > 0) {
312 USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
320 /*----------------------------------------------------------------------------
321 CDC_BulkOut call on DataOut Request
324 *---------------------------------------------------------------------------*/
325 void CDC_BulkOut(void) {
328 // get data from USB into intermediate buffer
329 numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]);
331 // ... add code to check for overwrite
333 // store data in a buffer to transmit it over serial interface
334 CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead);
339 /*----------------------------------------------------------------------------
340 Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
342 Return Value: SerialState as defined in usbcdc11.pdf
343 *---------------------------------------------------------------------------*/
344 unsigned short CDC_GetSerialState (void) {
348 ser_LineState (&temp);
350 if (temp & 0x8000) CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER;
351 if (temp & 0x2000) CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER;
352 if (temp & 0x0010) CDC_SerialState |= CDC_SERIAL_STATE_BREAK;
353 if (temp & 0x4000) CDC_SerialState |= CDC_SERIAL_STATE_RING;
354 if (temp & 0x0008) CDC_SerialState |= CDC_SERIAL_STATE_FRAMING;
355 if (temp & 0x0004) CDC_SerialState |= CDC_SERIAL_STATE_PARITY;
356 if (temp & 0x0002) CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;
358 return (CDC_SerialState);
362 /*----------------------------------------------------------------------------
363 Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
364 *---------------------------------------------------------------------------*/
365 void CDC_NotificationIn (void) {
367 NotificationBuf[0] = 0xA1; // bmRequestType
368 NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE)
369 NotificationBuf[2] = 0x00; // wValue
370 NotificationBuf[3] = 0x00;
371 NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first)
372 NotificationBuf[5] = 0x00;
373 NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
374 NotificationBuf[7] = 0x00;
375 NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
376 NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF;
378 USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification