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 "projectconfig.h"
29 unsigned char BulkBufIn
[64]; // Buffer to store USB IN packet
30 unsigned char BulkBufOut
[64]; // Buffer to store USB OUT packet
31 unsigned char NotificationBuf
[10];
33 CDC_LINE_CODING CDC_LineCoding
= {CFG_USBCDC_BAUDRATE
, 0, 0, 8};
34 unsigned short CDC_SerialState
= 0x0000;
35 unsigned short CDC_DepInEmpty
= 1; // Data IN EP is empty
37 /*----------------------------------------------------------------------------
38 We need a buffer for incomming data on USB port because USB receives
39 much faster than UART transmits
40 *---------------------------------------------------------------------------*/
42 #define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2)
43 // large enough for file transfer
44 #define CDC_BUF_MASK (CDC_BUF_SIZE-1ul)
46 /* Buffer read / write macros */
47 #define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)
48 #define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))
49 #define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])
50 #define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx)
51 #define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1)
52 #define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))
56 typedef struct __CDC_BUF_T
{
57 unsigned char data
[CDC_BUF_SIZE
];
58 volatile unsigned int wrIdx
;
59 volatile unsigned int rdIdx
;
62 CDC_BUF_T CDC_OutBuf
; // buffer for all CDC Out data
64 /*----------------------------------------------------------------------------
65 read data from CDC_OutBuf
66 *---------------------------------------------------------------------------*/
67 int CDC_RdOutBuf (char *buffer
, const int *length
) {
68 int bytesToRead
, bytesRead
;
70 /* Read *length bytes, block if *bytes are not avaialable */
71 bytesToRead
= *length
;
72 bytesToRead
= (bytesToRead
< (*length
)) ? bytesToRead
: (*length
);
73 bytesRead
= bytesToRead
;
76 // ... add code to check for underrun
78 while (bytesToRead
--) {
79 *buffer
++ = CDC_BUF_RD(CDC_OutBuf
);
84 /*----------------------------------------------------------------------------
85 write data to CDC_OutBuf
86 *---------------------------------------------------------------------------*/
87 int CDC_WrOutBuf (const char *buffer
, int *length
) {
88 int bytesToWrite
, bytesWritten
;
90 // Write *length bytes
91 bytesToWrite
= *length
;
92 bytesWritten
= bytesToWrite
;
95 // ... add code to check for overwrite
97 while (bytesToWrite
) {
98 CDC_BUF_WR(CDC_OutBuf
, *buffer
++); // Copy Data to buffer
102 return (bytesWritten
);
105 /*----------------------------------------------------------------------------
106 check if character(s) are available at CDC_OutBuf
107 *---------------------------------------------------------------------------*/
108 int CDC_OutBufAvailChar (int *availChar
) {
110 *availChar
= CDC_BUF_COUNT(CDC_OutBuf
);
114 /* end Buffer handling */
117 /*----------------------------------------------------------------------------
119 Initializes the data structures and serial port
122 *---------------------------------------------------------------------------*/
123 void CDC_Init (void) {
126 // ser_InitPort (CDC_LineCoding.dwDTERate,
127 // CDC_LineCoding.bDataBits,
128 // CDC_LineCoding.bParityType,
129 // CDC_LineCoding.bCharFormat);
132 CDC_SerialState
= CDC_GetSerialState();
134 CDC_BUF_RESET(CDC_OutBuf
);
136 // Initialise the CDC buffer. This is required to buffer outgoing
137 // data (MCU to PC) since data can only be sent 64 bytes per frame
138 // with at least 1ms between frames. To see how the buffer is used,
139 // see 'puts' in systeminit.c
144 /*----------------------------------------------------------------------------
145 CDC SendEncapsulatedCommand Request Callback
146 Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
147 Parameters: None (global SetupPacket and EP0Buf)
148 Return Value: TRUE - Success, FALSE - Error
149 *---------------------------------------------------------------------------*/
150 uint32_t CDC_SendEncapsulatedCommand (void) {
156 /*----------------------------------------------------------------------------
157 CDC GetEncapsulatedResponse Request Callback
158 Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
159 Parameters: None (global SetupPacket and EP0Buf)
160 Return Value: TRUE - Success, FALSE - Error
161 *---------------------------------------------------------------------------*/
162 uint32_t CDC_GetEncapsulatedResponse (void) {
164 /* ... add code to handle request */
169 /*----------------------------------------------------------------------------
170 CDC SetCommFeature Request Callback
171 Called automatically on CDC Set_COMM_FATURE Request
172 Parameters: FeatureSelector
173 Return Value: TRUE - Success, FALSE - Error
174 *---------------------------------------------------------------------------*/
175 uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector
) {
177 /* ... add code to handle request */
182 /*----------------------------------------------------------------------------
183 CDC GetCommFeature Request Callback
184 Called automatically on CDC Get_COMM_FATURE Request
185 Parameters: FeatureSelector
186 Return Value: TRUE - Success, FALSE - Error
187 *---------------------------------------------------------------------------*/
188 uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector
) {
190 /* ... add code to handle request */
195 /*----------------------------------------------------------------------------
196 CDC ClearCommFeature Request Callback
197 Called automatically on CDC CLEAR_COMM_FATURE Request
198 Parameters: FeatureSelector
199 Return Value: TRUE - Success, FALSE - Error
200 *---------------------------------------------------------------------------*/
201 uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector
) {
203 /* ... add code to handle request */
208 /*----------------------------------------------------------------------------
209 CDC SetLineCoding Request Callback
210 Called automatically on CDC SET_LINE_CODING Request
211 Parameters: none (global SetupPacket and EP0Buf)
212 Return Value: TRUE - Success, FALSE - Error
213 *---------------------------------------------------------------------------*/
214 uint32_t CDC_SetLineCoding (void) {
216 CDC_LineCoding
.dwDTERate
= (EP0Buf
[0] << 0)
220 CDC_LineCoding
.bCharFormat
= EP0Buf
[4];
221 CDC_LineCoding
.bParityType
= EP0Buf
[5];
222 CDC_LineCoding
.bDataBits
= EP0Buf
[6];
226 // ser_InitPort (CDC_LineCoding.dwDTERate,
227 // CDC_LineCoding.bDataBits,
228 // CDC_LineCoding.bParityType,
229 // CDC_LineCoding.bCharFormat);
234 /*----------------------------------------------------------------------------
235 CDC GetLineCoding Request Callback
236 Called automatically on CDC GET_LINE_CODING Request
237 Parameters: None (global SetupPacket and EP0Buf)
238 Return Value: TRUE - Success, FALSE - Error
239 *---------------------------------------------------------------------------*/
240 uint32_t CDC_GetLineCoding (void) {
242 EP0Buf
[0] = (CDC_LineCoding
.dwDTERate
>> 0) & 0xFF;
243 EP0Buf
[1] = (CDC_LineCoding
.dwDTERate
>> 8) & 0xFF;
244 EP0Buf
[2] = (CDC_LineCoding
.dwDTERate
>> 16) & 0xFF;
245 EP0Buf
[3] = (CDC_LineCoding
.dwDTERate
>> 24) & 0xFF;
246 EP0Buf
[4] = CDC_LineCoding
.bCharFormat
;
247 EP0Buf
[5] = CDC_LineCoding
.bParityType
;
248 EP0Buf
[6] = CDC_LineCoding
.bDataBits
;
254 /*----------------------------------------------------------------------------
255 CDC SetControlLineState Request Callback
256 Called automatically on CDC SET_CONTROL_LINE_STATE Request
257 Parameters: ControlSignalBitmap
258 Return Value: TRUE - Success, FALSE - Error
259 *---------------------------------------------------------------------------*/
260 uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap
) {
262 /* ... add code to handle request */
267 /*----------------------------------------------------------------------------
268 CDC SendBreak Request Callback
269 Called automatically on CDC Set_COMM_FATURE Request
270 Parameters: 0xFFFF start of Break
272 0x#### Duration of Break
273 Return Value: TRUE - Success, FALSE - Error
274 *---------------------------------------------------------------------------*/
275 uint32_t CDC_SendBreak (unsigned short wDurationOfBreak
) {
277 /* ... add code to handle request */
282 /*----------------------------------------------------------------------------
283 CDC_BulkIn call on DataIn Request
286 *---------------------------------------------------------------------------*/
287 void CDC_BulkIn(void) {
288 //int numBytesRead, numBytesAvail;
290 // uint8_t frame[64];
291 // uint32_t bytesRead = 0;
292 // if (cdcBufferDataPending())
294 // // Read up to 64 bytes
295 // bytesRead = cdcBufferReadLen(frame, 64);
296 // if (bytesRead > 0)
298 // USB_WriteEP (CDC_DEP_IN, frame, bytesRead);
303 // ser_AvailChar (&numBytesAvail);
305 // // ... add code to check for overwrite
307 // numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);
310 // if (numBytesRead > 0) {
311 // USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
314 // CDC_DepInEmpty = 1;
319 /*----------------------------------------------------------------------------
320 CDC_BulkOut call on DataOut Request
323 *---------------------------------------------------------------------------*/
324 void CDC_BulkOut(void) {
327 // get data from USB into intermediate buffer
328 numBytesRead
= USB_ReadEP(CDC_DEP_OUT
, &BulkBufOut
[0]);
330 // ... add code to check for overwrite
332 // store data in a buffer to transmit it over serial interface
333 CDC_WrOutBuf ((char *)&BulkBufOut
[0], &numBytesRead
);
338 /*----------------------------------------------------------------------------
339 Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
341 Return Value: SerialState as defined in usbcdc11.pdf
342 *---------------------------------------------------------------------------*/
343 unsigned short CDC_GetSerialState (void) {
344 // unsigned short temp;
347 // ser_LineState (&temp);
349 // if (temp & 0x8000) CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER;
350 // if (temp & 0x2000) CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER;
351 // if (temp & 0x0010) CDC_SerialState |= CDC_SERIAL_STATE_BREAK;
352 // if (temp & 0x4000) CDC_SerialState |= CDC_SERIAL_STATE_RING;
353 // if (temp & 0x0008) CDC_SerialState |= CDC_SERIAL_STATE_FRAMING;
354 // if (temp & 0x0004) CDC_SerialState |= CDC_SERIAL_STATE_PARITY;
355 // if (temp & 0x0002) CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;
357 return (CDC_SerialState
);
361 /*----------------------------------------------------------------------------
362 Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
363 *---------------------------------------------------------------------------*/
364 void CDC_NotificationIn (void) {
366 NotificationBuf
[0] = 0xA1; // bmRequestType
367 NotificationBuf
[1] = CDC_NOTIFICATION_SERIAL_STATE
; // bNotification (SERIAL_STATE)
368 NotificationBuf
[2] = 0x00; // wValue
369 NotificationBuf
[3] = 0x00;
370 NotificationBuf
[4] = 0x00; // wIndex (Interface #, LSB first)
371 NotificationBuf
[5] = 0x00;
372 NotificationBuf
[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
373 NotificationBuf
[7] = 0x00;
374 NotificationBuf
[8] = (CDC_SerialState
>> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
375 NotificationBuf
[9] = (CDC_SerialState
>> 8) & 0xFF;
377 USB_WriteEP (CDC_CEP_IN
, &NotificationBuf
[0], 10); // send notification