1 /* --COPYRIGHT--,BSD
2 * Copyright (c) 2012, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 /*
33 * ======== UsbCdc.c ========
34 */
35 #include <descriptors.h>
36
37 #ifdef _CDC_
38
39
40 #include "../USB_Common/device.h"
41 #include "../USB_Common/types.h" //Basic Type declarations
42 #include "../USB_Common/defMSP430USB.h"
43 #include "../USB_Common/usb.h" //USB-specific Data Structures
44 #include "../USB_CDC_API/UsbCdc.h"
45 #include "hw_compiler_specific.h"
46
47 #include <string.h>
48
49 //Local Macros
50 #define INTFNUM_OFFSET(X) (X - CDC0_INTFNUM) //Get the CDC offset
51
52 static struct _CdcControl {
53 ULONG lBaudrate;
54 BYTE bDataBits;
55 BYTE bStopBits;
56 BYTE bParity;
57 } CdcControl[CDC_NUM_INTERFACES];
58
59 struct _CdcWrite CdcWriteCtrl[CDC_NUM_INTERFACES];
60
61 struct _CdcRead CdcReadCtrl[CDC_NUM_INTERFACES];
62
63 #ifdef BRIDGE_CDC_PRESENT
64
65 static struct _CdcBridgeCtrl {
66 BYTE *uartRx;
67 BYTE *uartTx;
68 BYTE *uartIFG;
69 WORD *usbToUartDmaChSz;
70 WORD *usbToUartDmaChCtl;
71 BYTE ctsState;
72 } CdcBridgeCtrl;
73
74 #endif
75
76 extern WORD wUsbEventMask;
77
78 //function pointers
79 extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
80 extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
81
82
83 /*----------------------------------------------------------------------------+
84 | Global Variables |
85 +----------------------------------------------------------------------------*/
86
87 extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
88 extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
89
90
CdcResetData()91 VOID CdcResetData ()
92 {
93 int i;
94
95 //indicates which buffer is used by host to transmit data via OUT endpoint3 - X buffer is first
96 //CdcReadCtrl[intfIndex].bCurrentBufferXY = X_BUFFER;
97
98 memset(&CdcWriteCtrl, 0, sizeof(CdcWriteCtrl));
99 memset(&CdcReadCtrl, 0, sizeof(CdcReadCtrl));
100 memset(&CdcControl, 0, sizeof(CdcControl));
101
102 for (i = 0; i < CDC_NUM_INTERFACES; i++){
103 CdcControl[i].bDataBits = 8;
104 }
105 }
106
107 /*
108 * Sends data over interface intfNum, of size size and starting at address data.
109 * Returns: kUSBCDC_sendStarted
110 * kUSBCDC_sendComplete
111 * kUSBCDC_intfBusyError
112 */
USBCDC_sendData(const BYTE * data,WORD size,BYTE intfNum)113 BYTE USBCDC_sendData (const BYTE* data, WORD size, BYTE intfNum)
114 {
115 BYTE edbIndex;
116 WORD state;
117
118 edbIndex = stUsbHandle[intfNum].edb_Index;
119
120 if (size == 0)
121 {
122 return (kUSBCDC_generalError);
123 }
124
125 state = usbDisableInEndpointInterrupt(edbIndex);
126
127 //do not access USB memory if suspended (PLL uce BUS_ERROR
128 if ((bFunctionSuspended) ||
129 (bEnumerationStatus != ENUMERATION_COMPLETE))
130 {
131 //data can not be read because of USB suspended
132 usbRestoreInEndpointInterrupt(state); //restore interrupt status
133 return (kUSBCDC_busNotAvailable);
134 }
135
136 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0)
137 {
138 //the USB still sends previous data, we have to wait
139 usbRestoreInEndpointInterrupt(state); //restore interrupt status
140 return (kUSBCDC_intfBusyError);
141 }
142
143 //This function generate the USB interrupt. The data will be sent out from interrupt
144
145 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = size;
146 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = size;
147 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend = data;
148
149 //trigger Endpoint Interrupt - to start send operation
150 USBIEPIFG |= 1 << (edbIndex + 1); //IEPIFGx;
151
152 usbRestoreInEndpointInterrupt(state);
153
154 return (kUSBCDC_sendStarted);
155 }
156
157 #define EP_MAX_PACKET_SIZE_CDC 0x40
158
159 //this function is used only by USB interrupt
CdcToHostFromBuffer(BYTE intfNum)160 BOOL CdcToHostFromBuffer (BYTE intfNum)
161 {
162 BYTE byte_count, nTmp2;
163 BYTE * pEP1;
164 BYTE * pEP2;
165 BYTE * pCT1;
166 BYTE * pCT2;
167 BYTE bWakeUp = FALSE; //TRUE for wake up after interrupt
168 BYTE edbIndex;
169
170 edbIndex = stUsbHandle[intfNum].edb_Index;
171
172 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft == 0){ //do we have somtething to send?
173 if (!CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent){ //zero packet was not yet sent
174 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = TRUE;
175
176 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend ==
177 EP_MAX_PACKET_SIZE_CDC){
178 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY ==
179 X_BUFFER){
180 if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTX &
181 EPBCNT_NAK){
182 tInputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;
183 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY
184 = Y_BUFFER; //switch buffer
185 }
186 } else {
187 if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTY &
188 EPBCNT_NAK){
189 tInputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;
190 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY
191 = X_BUFFER; //switch buffer
192 }
193 }
194 }
195
196 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0; //nothing to send
197
198 //call event callback function
199 if (wUsbEventMask & kUSB_sendCompletedEvent){
200 bWakeUp = USBCDC_handleSendCompleted(intfNum);
201 }
202 } //if (!bSentZeroPacket)
203
204 return (bWakeUp);
205 }
206
207 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = FALSE; //zero packet will be not sent: we have data
208
209 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){
210 //this is the active EP buffer
211 pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
212 pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
213
214 //second EP buffer
215 pEP2 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
216 pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
217 } else {
218 //this is the active EP buffer
219 pEP1 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
220 pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
221
222 //second EP buffer
223 pEP2 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
224 pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
225 }
226
227 //how many byte we can send over one endpoint buffer
228 byte_count =
229 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft >
230 EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl[
231 INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
232 nTmp2 = *pCT1;
233
234 if (nTmp2 & EPBCNT_NAK){
235 USB_TX_memcpy(pEP1, CdcWriteCtrl[INTFNUM_OFFSET(
236 intfNum)].pUsbBufferToSend,
237 byte_count); //copy data into IEP3 X or Y buffer
238 *pCT1 = byte_count; //Set counter for usb In-Transaction
239 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
240 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01; //switch buffer
241 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -= byte_count;
242 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count; //move buffer pointer
243 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;
244
245 //try to send data over second buffer
246 nTmp2 = *pCT2;
247 if ((CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft > 0) && //do we have more data to send?
248 (nTmp2 & EPBCNT_NAK)){ //if the second buffer is free?
249 //how many byte we can send over one endpoint buffer
250 byte_count =
251 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft >
252 EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC :
253 CdcWriteCtrl[
254 INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
255
256 USB_TX_memcpy(pEP2, CdcWriteCtrl[INTFNUM_OFFSET(
257 intfNum)].pUsbBufferToSend,
258 byte_count); //copy data into IEP3 X or Y buffer
259 *pCT2 = byte_count; //Set counter for usb In-Transaction
260 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
261 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
262 1) & 0x01; //switch buffer
263 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -=
264 byte_count;
265 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend +=
266 byte_count; //move buffer pointer
267 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;
268 }
269 }
270 return (bWakeUp);
271 }
272
273 /*
274 * Aborts an active send operation on interface intfNum.
275 * Returns the number of bytes that were sent prior to the abort, in size.
276 */
USBCDC_abortSend(WORD * size,BYTE intfNum)277 BYTE USBCDC_abortSend (WORD* size, BYTE intfNum)
278 {
279 BYTE edbIndex;
280 WORD state;
281
282 edbIndex = stUsbHandle[intfNum].edb_Index;
283
284 state = usbDisableInEndpointInterrupt(edbIndex); //disable interrupts - atomic operation
285
286 *size =
287 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend -
288 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft);
289 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0;
290 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = 0;
291
292 usbRestoreInEndpointInterrupt(state);
293 return (kUSB_succeed);
294 }
295
296 //This function copies data from OUT endpoint into user's buffer
297 //Arguments:
298 //pEP - pointer to EP to copy from
299 //pCT - pointer to pCT control reg
300 //
CopyUsbToBuff(BYTE * pEP,BYTE * pCT,BYTE intfNum)301 VOID CopyUsbToBuff (BYTE* pEP, BYTE* pCT, BYTE intfNum)
302 {
303 BYTE nCount;
304
305 //how many byte we can get from one endpoint buffer
306 nCount =
307 (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft >
308 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) ? CdcReadCtrl[
309 INTFNUM_OFFSET(intfNum)].nBytesInEp : CdcReadCtrl[INTFNUM_OFFSET(
310 intfNum)].
311 nBytesToReceiveLeft;
312
313 USB_RX_memcpy(CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer, pEP, nCount); //copy data from OEP3 X or Y buffer
314 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft -= nCount;
315 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer += nCount; //move buffer pointer
316 //to read rest of data next time from this place
317
318 if (nCount == CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //all bytes are copied from receive buffer?
319 //switch current buffer
320 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
321 (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01;
322
323 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
324
325 //clear NAK, EP ready to receive data
326 *pCT = 0x00;
327 } else {
328 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp -= nCount;
329 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = pEP + nCount;
330 }
331 }
332
333 /*
334 * Receives data over interface intfNum, of size size, into memory starting at address data.
335 * Returns:
336 * kUSBCDC_receiveStarted if the receiving process started.
337 * kUSBCDC_receiveCompleted all requested date are received.
338 * kUSBCDC_receiveInProgress previous receive opereation is in progress. The requested receive operation can be not started.
339 * kUSBCDC_generalError error occurred.
340 */
USBCDC_receiveData(BYTE * data,WORD size,BYTE intfNum)341 BYTE USBCDC_receiveData (BYTE* data, WORD size, BYTE intfNum)
342 {
343 BYTE nTmp1;
344 BYTE edbIndex;
345 WORD state;
346
347 edbIndex = stUsbHandle[intfNum].edb_Index;
348
349 if ((size == 0) || //read size is 0
350 (data == NULL)){
351 return (kUSBCDC_generalError);
352 }
353
354 state = usbDisableOutEndpointInterrupt(edbIndex);
355 //atomic operation - disable interrupts
356
357 //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
358 if ((bFunctionSuspended) ||
359 (bEnumerationStatus != ENUMERATION_COMPLETE)){
360 //data can not be read because of USB suspended
361 usbRestoreOutEndpointInterrupt(state);
362 return (kUSBCDC_busNotAvailable);
363 }
364
365 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){ //receive process already started
366 usbRestoreOutEndpointInterrupt(state);
367 return (kUSBCDC_intfBusyError);
368 }
369
370 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size; //bytes to receive
371 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size; //left bytes to receive
372 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data; //set user receive buffer
373
374 //read rest of data from buffer, if any
375 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){
376 //copy data from pEP-endpoint into User's buffer
377 CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(
378 intfNum)].pCurrentEpPos,
379 CdcReadCtrl[INTFNUM_OFFSET(
380 intfNum)
381 ].pCT1, intfNum);
382
383 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
384 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending
385 if (wUsbEventMask & kUSB_receiveCompletedEvent){
386 USBCDC_handleReceiveCompleted(intfNum); //call event handler in interrupt context
387 }
388 usbRestoreOutEndpointInterrupt(state);
389 return (kUSBCDC_receiveCompleted); //receive completed
390 }
391
392 //check other EP buffer for data - exchange pCT1 with pCT2
393 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 ==
394 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX){
395 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
396 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
397 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
398 (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
399 } else {
400 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
401 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
402 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
403 (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
404 }
405
406 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
407 //try read data from second buffer
408 if (nTmp1 & EPBCNT_NAK){ //if the second buffer has received data?
409 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
410 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
411 CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(
412 intfNum)].pCurrentEpPos,
413 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
414 }
415
416 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
417 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending
418 if (wUsbEventMask & kUSB_receiveCompletedEvent){
419 USBCDC_handleReceiveCompleted(intfNum); //call event handler in interrupt context
420 }
421 usbRestoreOutEndpointInterrupt(state);
422 return (kUSBCDC_receiveCompleted); //receive completed
423 }
424 } //read rest of data from buffer, if any
425
426 //read 'fresh' data, if available
427 nTmp1 = 0;
428 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //this is current buffer
429 if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){ //this buffer has a valid data packet
430 //this is the active EP buffer
431 //pEP1
432 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
433 (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
434 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
435 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
436
437 //second EP buffer
438 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
439 (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
440 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
441 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
442 nTmp1 = 1; //indicate that data is available
443 }
444 } else { //Y_BUFFER
445 if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){
446 //this is the active EP buffer
447 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
448 (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
449 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
450 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
451
452 //second EP buffer
453 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
454 (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
455 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
456 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
457 nTmp1 = 1; //indicate that data is available
458 }
459 }
460
461 if (nTmp1){
462 //how many byte we can get from one endpoint buffer
463 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
464 while (nTmp1 == 0)
465 {
466 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
467 }
468
469 if (nTmp1 & EPBCNT_NAK){
470 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
471 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
472
473 CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(
474 intfNum)].pCurrentEpPos,
475 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
476
477 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
478 //try read data from second buffer
479 if ((CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft >
480 0) && //do we have more data to send?
481 (nTmp1 & EPBCNT_NAK)){ //if the second buffer has received data?
482 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
483 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
484 CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(
485 intfNum)].pEP2,
486 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum);
487 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
488 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
489 }
490 }
491 }
492
493 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
494 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending
495 if (wUsbEventMask & kUSB_receiveCompletedEvent){
496 USBCDC_handleReceiveCompleted(intfNum); //call event handler in interrupt context
497 }
498 usbRestoreOutEndpointInterrupt(state);
499 return (kUSBCDC_receiveCompleted);
500 }
501
502 //interrupts enable
503 usbRestoreOutEndpointInterrupt(state);
504 return (kUSBCDC_receiveStarted);
505 }
506
507 //this function is used only by USB interrupt.
508 //It fills user receiving buffer with received data
CdcToBufferFromHost(BYTE intfNum)509 BOOL CdcToBufferFromHost (BYTE intfNum)
510 {
511 BYTE * pEP1;
512 BYTE nTmp1;
513 BYTE bWakeUp = FALSE; //per default we do not wake up after interrupt
514
515 BYTE edbIndex;
516
517 edbIndex = stUsbHandle[intfNum].edb_Index;
518
519 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //do we have somtething to receive?
520 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending
521 return (bWakeUp);
522 }
523
524 //No data to receive...
525 if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX |
526 tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY)
527 & 0x80)){
528 return (bWakeUp);
529 }
530
531 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //X is current buffer
532 //this is the active EP buffer
533 pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
534 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
535 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
536
537 //second EP buffer
538 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
539 (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
540 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
541 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
542 } else {
543 //this is the active EP buffer
544 pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
545 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
546 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
547
548 //second EP buffer
549 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
550 (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
551 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
552 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
553 }
554
555 //how many byte we can get from one endpoint buffer
556 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
557
558 if (nTmp1 & EPBCNT_NAK){
559 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
560 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
561
562 CopyUsbToBuff(pEP1, CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
563
564 nTmp1 = *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
565 //try read data from second buffer
566 if ((CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && //do we have more data to send?
567 (nTmp1 & EPBCNT_NAK)){ //if the second buffer has received data?
568 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
569 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
570 CopyUsbToBuff(CdcReadCtrl[INTFNUM_OFFSET(
571 intfNum)].pEP2,
572 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum);
573 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
574 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
575 }
576 }
577
578 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
579 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending
580 if (wUsbEventMask & kUSB_receiveCompletedEvent){
581 bWakeUp |= USBCDC_handleReceiveCompleted(intfNum);
582 }
583
584 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //Is not read data still available in the EP?
585 if (wUsbEventMask & kUSB_dataReceivedEvent){
586 bWakeUp |= USBCDC_handleDataReceived(intfNum);
587 }
588 }
589 }
590 return (bWakeUp);
591 }
592
593 //helper for USB interrupt handler
CdcIsReceiveInProgress(BYTE intfNum)594 BOOL CdcIsReceiveInProgress (BYTE intfNum)
595 {
596 return (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL);
597 }
598
599 /*
600 * Aborts an active receive operation on interface intfNum.
601 * Returns the number of bytes that were received and transferred
602 * to the data location established for this receive operation.
603 */
USBCDC_abortReceive(WORD * size,BYTE intfNum)604 BYTE USBCDC_abortReceive (WORD* size, BYTE intfNum)
605 {
606 //interrupts disable
607 BYTE edbIndex;
608 WORD state;
609
610 edbIndex = stUsbHandle[intfNum].edb_Index;
611 state = usbDisableOutEndpointInterrupt(edbIndex);
612
613 *size = 0; //set received bytes count to 0
614
615 //is receive operation underway?
616 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
617 //how many bytes are already received?
618 *size = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
619 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
620
621 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
622 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
623 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
624 }
625
626 //restore interrupt status
627 usbRestoreOutEndpointInterrupt(state);
628 return (kUSB_succeed);
629 }
630
631 /*
632 * This function rejects payload data that has been received from the host.
633 */
USBCDC_rejectData(BYTE intfNum)634 BYTE USBCDC_rejectData (BYTE intfNum)
635 {
636 BYTE edbIndex;
637 WORD state;
638
639 edbIndex = stUsbHandle[intfNum].edb_Index;
640 state = usbDisableOutEndpointInterrupt(edbIndex);
641
642 //atomic operation - disable interrupts
643
644 //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
645 if (bFunctionSuspended){
646 usbRestoreOutEndpointInterrupt(state);
647 return (kUSBCDC_busNotAvailable);
648 }
649
650 //Is receive operation underway?
651 //- do not flush buffers if any operation still active.
652 if (!CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
653 BYTE tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
654 EPBCNT_NAK;
655 BYTE tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
656 EPBCNT_NAK;
657
658 if (tmp1 ^ tmp2){ //switch current buffer if any and only ONE of buffers
659 //is full
660 //switch current buffer
661 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
662 (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
663 1) & 0x01;
664 }
665
666 tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0; //flush buffer X
667 tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0; //flush buffer Y
668 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0; //indicates that no more data available in the EP
669 }
670
671 usbRestoreOutEndpointInterrupt(state);
672 return (kUSB_succeed);
673 }
674
675 /*
676 * This function indicates the status of the itnerface intfNum.
677 * If a send operation is active for this interface,
678 * the function also returns the number of bytes that have been transmitted to the host.
679 * If a receiver operation is active for this interface, the function also returns
680 * the number of bytes that have been received from the host and are waiting at the assigned address.
681 *
682 * returns kUSBCDC_waitingForSend (indicates that a call to USBCDC_SendData()
683 * has been made, for which data transfer has not been completed)
684 *
685 * returns kUSBCDC_waitingForReceive (indicates that a receive operation
686 * has been initiated, but not all data has yet been received)
687 *
688 * returns kUSBCDC_dataWaiting (indicates that data has been received
689 * from the host, waiting in the USB receive buffers)
690 */
USBCDC_intfStatus(BYTE intfNum,WORD * bytesSent,WORD * bytesReceived)691 BYTE USBCDC_intfStatus (BYTE intfNum, WORD* bytesSent, WORD* bytesReceived)
692 {
693 BYTE ret = 0;
694 WORD stateIn, stateOut;
695 BYTE edbIndex;
696
697 *bytesSent = 0;
698 *bytesReceived = 0;
699
700 edbIndex = stUsbHandle[intfNum].edb_Index;
701
702 stateIn = usbDisableInEndpointInterrupt(edbIndex);
703 stateOut = usbDisableOutEndpointInterrupt(edbIndex);
704
705 //Is send operation underway?
706 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0){
707 ret |= kUSBCDC_waitingForSend;
708 *bytesSent = CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend -
709 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
710 }
711
712 //Is receive operation underway?
713 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){
714 ret |= kUSBCDC_waitingForReceive;
715 *bytesReceived = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
716 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].
717 nBytesToReceiveLeft;
718 }
719 else
720 { //receive operation not started
721 //do not access USB memory if suspended (PLL off).
722 //It may produce BUS_ERROR
723 if (!bFunctionSuspended)
724 {
725 if ((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
726 EPBCNT_NAK) | //any of buffers has a valid data packet
727 (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
728 EPBCNT_NAK)){
729 ret |= kUSBCDC_dataWaiting;
730 }
731 }
732 }
733
734 if ((bFunctionSuspended) ||
735 (bEnumerationStatus != ENUMERATION_COMPLETE)){
736 //if suspended or not enumerated - report no other tasks pending
737 ret = kUSBCDC_busNotAvailable;
738 }
739
740 //restore interrupt status
741 usbRestoreInEndpointInterrupt(stateIn);
742 usbRestoreOutEndpointInterrupt(stateOut);
743
744 __no_operation();
745 return (ret);
746 }
747
748 /*
749 * Returns how many bytes are in the buffer are received and ready to be read.
750 */
USBCDC_bytesInUSBBuffer(BYTE intfNum)751 BYTE USBCDC_bytesInUSBBuffer (BYTE intfNum)
752 {
753 BYTE bTmp1 = 0;
754 WORD state;
755 BYTE edbIndex;
756
757 edbIndex = stUsbHandle[intfNum].edb_Index;
758
759 state = usbDisableOutEndpointInterrupt(edbIndex);
760 //atomic operation - disable interrupts
761
762 if ((bFunctionSuspended) ||
763 (bEnumerationStatus != ENUMERATION_COMPLETE)){
764 usbRestoreOutEndpointInterrupt(state);
765 //if suspended or not enumerated - report 0 bytes available
766 return (0);
767 }
768
769 if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){ //If a RX operation is underway, part of data may
770 //was read of the OEP buffer
771 bTmp1 = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
772 if (*CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK){ //the next buffer has a valid data packet
773 bTmp1 += *CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F;
774 }
775 } else {
776 if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){ //this buffer has a valid data packet
777 bTmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
778 }
779 if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){ //this buffer has a valid data packet
780 bTmp1 += tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
781 }
782 }
783
784 usbRestoreOutEndpointInterrupt(state);
785 return (bTmp1);
786 }
787
788 //----------------------------------------------------------------------------
789 //Line Coding Structure
790 //dwDTERate | 4 | Data terminal rate, in bits per second
791 //bCharFormat | 1 | Stop bits, 0 = 1 Stop bit, 1 = 1,5 Stop bits, 2 = 2 Stop bits
792 //bParityType | 1 | Parity, 0 = None, 1 = Odd, 2 = Even, 3= Mark, 4 = Space
793 //bDataBits | 1 | Data bits (5,6,7,8,16)
794 //----------------------------------------------------------------------------
usbGetLineCoding(VOID)795 BYTE usbGetLineCoding (VOID)
796 {
797 BYTE infIndex;
798
799 if(tSetupPacket.wIndex % 2)
800 {
801 infIndex = (tSetupPacket.wIndex-1) / 2;
802 }
803 else
804 {
805 infIndex = (tSetupPacket.wIndex) / 2;
806 }
807
808 abUsbRequestReturnData[6] =
809 CdcControl[infIndex].bDataBits; //Data bits = 8
810 abUsbRequestReturnData[5] =
811 CdcControl[infIndex].bParity; //No Parity
812 abUsbRequestReturnData[4] =
813 CdcControl[infIndex].bStopBits; //Stop bits = 1
814
815 abUsbRequestReturnData[3] =
816 CdcControl[infIndex].lBaudrate >> 24;
817 abUsbRequestReturnData[2] =
818 CdcControl[infIndex].lBaudrate >> 16;
819 abUsbRequestReturnData[1] =
820 CdcControl[infIndex].lBaudrate >> 8;
821 abUsbRequestReturnData[0] =
822 CdcControl[infIndex].lBaudrate;
823
824 wBytesRemainingOnIEP0 = 0x07; //amount of data to be send over EP0 to host
825 usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]); //send data to host
826
827 return (FALSE);
828 }
829
830 //----------------------------------------------------------------------------
831
usbSetLineCoding(VOID)832 BYTE usbSetLineCoding (VOID)
833 {
834 usbReceiveDataPacketOnEP0((PBYTE)&abUsbRequestIncomingData); //receive data over EP0 from Host
835
836 return (FALSE);
837 }
838
839 //----------------------------------------------------------------------------
840
usbSetControlLineState(VOID)841 BYTE usbSetControlLineState (VOID)
842 {
843 USBCDC_handleSetControlLineState((BYTE)tSetupPacket.wIndex,
844 (BYTE)tSetupPacket.wValue);
845 usbSendZeroLengthPacketOnIEP0(); //Send ZLP for status stage
846
847 return (FALSE);
848 }
849
850 //----------------------------------------------------------------------------
851
Handler_SetLineCoding(VOID)852 BYTE Handler_SetLineCoding (VOID)
853 {
854 BYTE bWakeUp;
855 volatile BYTE infIndex;
856
857 if(tSetupPacket.wIndex % 2)
858 {
859 infIndex = (tSetupPacket.wIndex-1) / 2;
860 }
861 else
862 {
863 infIndex = (tSetupPacket.wIndex) / 2;
864 }
865
866 //Baudrate Settings
867
868 CdcControl[infIndex].lBaudrate =
869 (ULONG)abUsbRequestIncomingData[3] << 24 |
870 (ULONG)abUsbRequestIncomingData[2] << 16 |
871 (ULONG)
872 abUsbRequestIncomingData[1] << 8 | abUsbRequestIncomingData[0];
873 bWakeUp =
874 USBCDC_handleSetLineCoding(tSetupPacket.wIndex,
875 CdcControl[infIndex].lBaudrate);
876
877 return (bWakeUp);
878 }
879
880 #ifdef BRIDGE_CDC_PRESENT
881
USBCDC_setupDMA_Bridge()882 BYTE USBCDC_setupDMA_Bridge()
883 {
884 CdcBridgeCtrl.ctsState = 0;
885 switch (BRIDGE_UART_USCI_NUM) {
886 case 0:
887 CdcBridgeCtrl.uartRx = (BYTE *)&UCA0RXBUF;
888 CdcBridgeCtrl.uartTx = (BYTE *)&UCA0TXBUF;
889 CdcBridgeCtrl.uartIFG = (BYTE *)&UCA0IFG;
890 break;
891 case 1:
892 CdcBridgeCtrl.uartRx = (BYTE *)&UCA1RXBUF;
893 CdcBridgeCtrl.uartTx = (BYTE *)&UCA1TXBUF;
894 CdcBridgeCtrl.uartIFG = (BYTE *)&UCA1IFG;
895 break;
896 case 2:
897 CdcBridgeCtrl.uartRx = (BYTE *)&UCB0RXBUF;
898 CdcBridgeCtrl.uartTx = (BYTE *)&UCB0TXBUF;
899 CdcBridgeCtrl.uartIFG = (BYTE *)&UCB0IFG;
900 break;
901 case 3:
902 CdcBridgeCtrl.uartRx = (BYTE *)&UCB1RXBUF;
903 CdcBridgeCtrl.uartTx = (BYTE *)&UCB1TXBUF;
904 CdcBridgeCtrl.uartIFG = (BYTE *)&UCB1IFG;
905 break;
906 }
907 switch (BRIDGE_UART_TO_USB_DMA_CHAN)
908 {
909 case 0:
910 DMACTL0 = DMA0TSEL_16;
911 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long)CdcBridgeCtrl.uartRx);
912 __data16_write_addr((unsigned short) &DMA0DA,(unsigned long)USBCDC_Bridge_getInEndpointBufferXAddr(CDC0_INTFNUM));
913 DMA0SZ = 16;
914 DMA0CTL = DMADT_0 + DMADSTINCR_3 + DMASBDB + DMAEN + DMAIE;
915 break;
916 case 1:
917 DMACTL0 = DMA1TSEL_16;
918 __data16_write_addr((unsigned short) &DMA1SA,(unsigned long)CdcBridgeCtrl.uartRx);
919 __data16_write_addr((unsigned short) &DMA1DA,(unsigned long)USBCDC_Bridge_getInEndpointBufferXAddr(CDC0_INTFNUM));
920 DMA1SZ = 16;
921 DMA1CTL = DMADT_0 + DMADSTINCR_3 + DMASBDB + DMAEN + DMAIE;
922 break;
923 case 2:
924 DMACTL1 = DMA2TSEL_16;
925 __data16_write_addr((unsigned short) &DMA2SA,(unsigned long)CdcBridgeCtrl.uartRx);
926 __data16_write_addr((unsigned short) &DMA2DA,(unsigned long)USBCDC_Bridge_getInEndpointBufferXAddr(CDC0_INTFNUM));
927 DMA2SZ = 16;
928 DMA2CTL = DMADT_0 + DMADSTINCR_3 + DMASBDB + DMAEN + DMAIE;
929 break;
930 }
931
932 switch (BRIDGE_USB_TO_UART_DMA_CHAN)
933 {
934 case 0:
935 CdcBridgeCtrl.usbToUartDmaChSz = (WORD *)&DMA0SZ;
936 CdcBridgeCtrl.usbToUartDmaChCtl = (WORD *)&DMA0CTL;
937 DMACTL0 = DMA0TSEL_17;
938 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long)(USBCDC_Bridge_getOutEndpointBufferXAddr(CDC0_INTFNUM) + 1));
939 __data16_write_addr((unsigned short) &DMA0DA,(unsigned long)CdcBridgeCtrl.uartTx);
940 break;
941 case 1:
942 CdcBridgeCtrl.usbToUartDmaChSz = (WORD *)&DMA1SZ;
943 CdcBridgeCtrl.usbToUartDmaChCtl = (WORD *)&DMA1CTL;
944 DMACTL0 = DMA1TSEL_17;
945 __data16_write_addr((unsigned short) &DMA1SA,(unsigned long)(USBCDC_Bridge_getOutEndpointBufferXAddr(CDC0_INTFNUM) + 1));
946 __data16_write_addr((unsigned short) &DMA1DA,(unsigned long)CdcBridgeCtrl.uartTx);
947 break;
948 case 2:
949 CdcBridgeCtrl.usbToUartDmaChSz = (WORD *)&DMA2SZ;
950 CdcBridgeCtrl.usbToUartDmaChCtl = (WORD *)&DMA2CTL;
951 DMACTL1 = DMA2TSEL_17;
952 __data16_write_addr((unsigned short) &DMA2SA,(unsigned long)(USBCDC_Bridge_getOutEndpointBufferXAddr(CDC0_INTFNUM) + 1));
953 __data16_write_addr((unsigned short) &DMA2DA,(unsigned long)CdcBridgeCtrl.uartTx);
954 break;
955 }
956
957 return (TRUE);
958 }
959
USBCDC_Bridge_sendData(WORD size,BYTE intfNum)960 BYTE USBCDC_Bridge_sendData (WORD size, BYTE intfNum)
961 {
962 BYTE edbIndex;
963 WORD state;
964
965 edbIndex = stUsbHandle[intfNum].edb_Index;
966
967 state = usbDisableInEndpointInterrupt(edbIndex);
968 //atomic operation - disable interrupts
969
970 //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
971 if ((bFunctionSuspended) ||
972 (bEnumerationStatus != ENUMERATION_COMPLETE)){
973 //data can not be read because of USB suspended
974 usbRestoreInEndpointInterrupt(state);
975 return (kUSBCDC_busNotAvailable);
976 }
977
978 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0){
979 //the USB still sends previous data, we have to wait
980 usbRestoreInEndpointInterrupt(state);
981 return (kUSBCDC_intfBusyError);
982 }
983
984 //This function generate the USB interrupt. The data will be sent out from interrupt
985
986 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = size;
987 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = size;
988
989 //trigger Endpoint Interrupt - to start send operation
990 USBIEPIFG |= 1 << (edbIndex + 1); //IEPIFGx;
991
992 usbRestoreInEndpointInterrupt(state);
993
994 return (kUSBCDC_sendStarted);
995 }
996
997 //this function is used only by USB interrupt
CdcToHostFromBuffer_Bridge(BYTE intfNum)998 BOOL CdcToHostFromBuffer_Bridge (BYTE intfNum)
999 {
1000 BYTE byte_count, nTmp2;
1001 BYTE * pCT1;
1002 BYTE bWakeUp = FALSE; //TRUE for wake up after interrupt
1003 BYTE edbIndex;
1004
1005 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft == 0){
1006 return (bWakeUp);
1007 }
1008
1009 edbIndex = stUsbHandle[intfNum].edb_Index;
1010
1011 //this is the active EP buffer
1012 pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1013
1014 if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){
1015 pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1016 } else {
1017 pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1018 }
1019
1020 //how many byte we can send over one endpoint buffer
1021 byte_count =
1022 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft >
1023 EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl[
1024 INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
1025 nTmp2 = *pCT1;
1026
1027 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
1028 (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01;
1029
1030 if (nTmp2 & EPBCNT_NAK){ //copy data into IEP3 X or Y buffer
1031 *pCT1 = byte_count; //Set counter for usb In-Transaction
1032 CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -= byte_count;
1033 }
1034
1035 return (bWakeUp);
1036 }
1037
USBCDC_Bridge_getInEndpointBufferXAddr(BYTE intfNum)1038 BYTE *USBCDC_Bridge_getInEndpointBufferXAddr(BYTE intfNum) {
1039 return ((BYTE *)stUsbHandle[CDC0_INTFNUM].iep_X_Buffer);
1040 }
1041
USBCDC_Bridge_getInEndpointBufferYAddr(BYTE intfNum)1042 BYTE *USBCDC_Bridge_getInEndpointBufferYAddr(BYTE intfNum) {
1043 return ((BYTE *)stUsbHandle[CDC0_INTFNUM].iep_Y_Buffer);
1044 }
1045
USBCDC_Bridge_getOutEndpointBufferXAddr(BYTE intfNum)1046 BYTE *USBCDC_Bridge_getOutEndpointBufferXAddr(BYTE intfNum) {
1047 return ((BYTE *)stUsbHandle[CDC0_INTFNUM].oep_X_Buffer);
1048 }
1049
USBCDC_Bridge_getOutEndpointBufferYAddr(BYTE intfNum)1050 BYTE *USBCDC_Bridge_getOutEndpointBufferYAddr(BYTE intfNum) {
1051 return ((BYTE *)stUsbHandle[CDC0_INTFNUM].oep_Y_Buffer);
1052 }
1053
1054 //this function is used only by USB interrupt.
1055 //It fills user receiving buffer with received data
CdcToBufferFromHost_Bridge(BYTE intfNum)1056 BOOL CdcToBufferFromHost_Bridge (BYTE intfNum)
1057 {
1058 BYTE *pEP1, *pCT1;
1059 BYTE nTmp1;
1060 BYTE bWakeUp = FALSE; //per default we do not wake up after interrupt
1061 BYTE i;
1062 BYTE edbIndex;
1063
1064 edbIndex = stUsbHandle[intfNum].edb_Index;
1065
1066 //No data to receive...
1067 if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x80))){
1068 return (bWakeUp);
1069 }
1070
1071 if (CdcBridgeCtrl.ctsState == 0) {
1072 return (bWakeUp);
1073 }
1074
1075 //this is the active EP buffer
1076 pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
1077 pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1078
1079 __no_operation();
1080 __no_operation();
1081
1082 //how many byte we can get from endpoint buffer
1083 nTmp1 = *pCT1;
1084
1085 if (nTmp1 & EPBCNT_NAK){
1086 nTmp1 = nTmp1 & 0x7f; //clear NAK bit
1087 CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1; //holds how many valid bytes in the EP buffer
1088
1089 if (nTmp1 > 0) {
1090 //Start DMA
1091 if (nTmp1 > 5 ) {
1092 //Start DMA
1093 while (!(*CdcBridgeCtrl.uartIFG & UCTXIFG));
1094 *CdcBridgeCtrl.uartTx = *pEP1;
1095 *CdcBridgeCtrl.usbToUartDmaChSz = nTmp1 - 1; // Block size
1096 *CdcBridgeCtrl.usbToUartDmaChCtl = DMADT_0 + DMASRCINCR_3 + DMASBDB + DMAEN + DMAIE;// Rpt, inc src, enable
1097 }
1098 else {
1099 for (i = 0; i < nTmp1; i++) {
1100 while (!(*CdcBridgeCtrl.uartIFG & UCTXIFG)); // USCI_A0 TX buffer ready?
1101 *CdcBridgeCtrl.uartTx = *pEP1++; // TX -> RXed character
1102 }
1103 *pCT1 = 0x00;
1104 }
1105 }
1106 else {
1107 *pCT1 = 0x00;
1108 }
1109 }
1110
1111 return (bWakeUp);
1112 }
1113
USBCDC_Bridge_completeReceiveData(BYTE intfNum)1114 BYTE USBCDC_Bridge_completeReceiveData (BYTE intfNum)
1115 {
1116 BYTE *pCT1;
1117 BYTE edbIndex;
1118
1119 DMA2CTL = 0;
1120 edbIndex = stUsbHandle[intfNum].edb_Index;
1121 pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1122 *pCT1 = 0x00;
1123
1124 return (FALSE);
1125 }
1126
USBCDC_setCTS(BYTE state)1127 void USBCDC_setCTS(BYTE state)
1128 {
1129 CdcBridgeCtrl.ctsState = state;
1130 CdcToBufferFromHost_Bridge(CDC0_INTFNUM);
1131 }
1132 #endif //BRIDGE_CDC_PRESENT
1133
1134 #endif //ifdef _CDC_
1135
1136 /*----------------------------------------------------------------------------+
1137 | End of source file |
1138 +----------------------------------------------------------------------------*/
1139 /*------------------------ Nothing Below This Line --------------------------*/
1140