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