1 /* --COPYRIGHT--,BSD\r
2 * Copyright (c) 2014, Texas Instruments Incorporated\r
3 * All rights reserved.\r
4 *\r
5 * Redistribution and use in source and binary forms, with or without\r
6 * modification, are permitted provided that the following conditions\r
7 * are met:\r
8 *\r
9 * * Redistributions of source code must retain the above copyright\r
10 * notice, this list of conditions and the following disclaimer.\r
11 *\r
12 * * Redistributions in binary form must reproduce the above copyright\r
13 * notice, this list of conditions and the following disclaimer in the\r
14 * documentation and/or other materials provided with the distribution.\r
15 *\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of\r
17 * its contributors may be used to endorse or promote products derived\r
18 * from this software without specific prior written permission.\r
19 *\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31 * --/COPYRIGHT--*/\r
32 /** @file usbConstructs.c\r
33 * @brief Contains example constructs for send/receive operations\r
34 */\r
35 /* \r
36 * ======== usbConstructs.c ========\r
37 */\r
38 //\r
39 //! \cond\r
40 //\r
41 \r
42 #include "USB_API/USB_Common/device.h"\r
43 \r
44 #include "USB_config/descriptors.h"\r
45 #include "USB_API/USB_Common/usb.h" // USB-specific functions\r
46 \r
47 #ifdef _CDC_\r
48 #include "USB_API/USB_CDC_API/UsbCdc.h"\r
49 #endif\r
50 #ifdef _HID_\r
51 #include "USB_API/USB_HID_API/UsbHid.h"\r
52 #endif\r
53 #ifdef _PHDC_\r
54 #include "USB_API/USB_PHDC_API/UsbPHDC.h"\r
55 #endif\r
56 \r
57 #include "usbConstructs.h"\r
58 \r
59 \r
60 \r
61 /**************************************************************************************************\r
62 These are example, user-editable construct functions for calling the API. \r
63 \r
64 In cases where fast development is the priority, it's usually best to use these sending \r
65 construct functions, rather than calling USBCDC_sendData() or USBHID_sendData() \r
66 directly. This is because they put boundaries on the "background execution" of sends,\r
67 simplfying the application. \r
68 \r
69 xxxsendDataWaitTilDone() essentially eliminates background processing altogether, always \r
70 polling after the call to send and not allowing execution to resume until it's done. This\r
71 allows simpler coding at the expense of wasted MCU cycles, and MCU execution being "locked" \r
72 to the host (also called "synchronous" operation). \r
73 \r
74 xxxsendDataInBackground() takes advantage of background processing ("asynchronous" operation) \r
75 by allowing sending to happen during application execution; while at the same time ensuring \r
76 that the sending always definitely occurs. It provides most of the simplicity of \r
77 xxxsendDataWaitTilDone() while minimizing wasted cycles. It's probably the best choice \r
78 for most applications. \r
79 \r
80 A true, asynchronous implementation would be the most cycle-efficient, but is the most \r
81 difficult to code; and can't be "contained" in an example function as these other approaches \r
82 are. Such an implementation might be advantageous in RTOS-based implementations or those \r
83 requiring the highest levels of efficiency. \r
84 \r
85 These functions take into account all the pertinent return codes, toward ensuring fully \r
86 robust operation. The send functions implement a timeout feature, using a loose "number of \r
87 retries" approach. This was done in order to avoid using additional hardware resources. A \r
88 more sophisticated approach, which the developer might want to implement, would be to use a \r
89 hardware timer. \r
90 \r
91 Please see the MSP430 CDC/HID/MSC USB API Programmer's Guide for a full description of these \r
92 functions, how they work, and how to use them. \r
93 **************************************************************************************************/\r
94 //\r
95 //! \endcond\r
96 //\r
97 \r
98 //\r
99 //! \cond\r
100 //\r
101 #ifdef _HID_\r
102 //\r
103 //! \endcond\r
104 //\r
105 //*****************************************************************************\r
106 //\r
107 //! Completely Sends the Data in dataBuf\r
108 //! \r
109 //! \param *dataBuf is the address of the data buffer.\r
110 //! \param size is the size of the data.\r
111 //! \param intfnum intfNum is which HID interface is being used.\r
112 //! \param ulTimeout is the (32-bit) number of polls to USBHID_intfStatus().\r
113 //!\r
114 //! Sends the data in \b dataBuf, of size \b size, using the post-call polling method.\r
115 //! It does so over interface \b intfNum. The function doesn’t return until the\r
116 //! send has completed. Because of this, the user buffer can be edited\r
117 //! immediately after the function returns, without consequence. The\r
118 //! function assumes that size is non-zero. It assumes no previous send\r
119 //! operation is underway. \r
120 //! \r
121 //! The 32-bit number \b ulTimeout selects how many times USBHID_intfStatus() will\r
122 //! be polled while waiting for the operation to complete. If the value is zero,\r
123 //! then no timeout is employed; it will wait indefinitely. When choosing a\r
124 //! number, it is advised to consider MCLK speed, as a faster CPU will cycle\r
125 //! through the calls more quickly. The function provides the simplest coding,\r
126 //! at the expense of wasted cycles and potentially allowing MCU execution to\r
127 //! become "locked" to the host, a disadvantage if the host (or bus) is slow.\r
128 //! \r
129 //! The function also checks all valid return codes, and returns non-zero if an\r
130 //! error occurred. In many applications, the return value can simply be\r
131 //! evaluated as zero or non-zero, where nonzero means the call failed for\r
132 //! reasons of host or bus non-availability. Therefore, it may desirable for the\r
133 //! application to break from execution. Other applications may wish to handle\r
134 //! return values 1 and 2 in different ways.\r
135 //! \r
136 //! It’s recommended not to call this function from within an event handler.\r
137 //! This is because if an interface currently has an open send operation, the\r
138 //! operation will never complete during the event handler; rather, only after\r
139 //! the ISR that spawned the event returns. Thus the USBHID_intfStatus() polling\r
140 //! would loop indefinitely (or timeout). It’s better to set a flag from within\r
141 //! the event handler, and use this flag to trigger the calling of this function\r
142 //! from within main().\r
143 //! \r
144 //! \return \b 0 if the call succeeded; all data has been sent.\r
145 //! \return \b 1 if the call timed out, either because the host is unavailable\r
146 //! or a COM port with an active application on the host wasn't opened.\r
147 //! \return \b 2 if the bus is unavailable.\r
148 //\r
149 //*****************************************************************************\r
150 uint8_t hidSendDataWaitTilDone (uint8_t* dataBuf,\r
151 uint16_t size,\r
152 uint8_t intfNum,\r
153 uint32_t ulTimeout)\r
154 {\r
155 uint32_t sendCounter = 0;\r
156 uint16_t bytesSent, bytesReceived;\r
157 \r
158 switch (USBHID_sendData(dataBuf,size,intfNum)){\r
159 case kUSBHID_sendStarted:\r
160 break;\r
161 case kUSBHID_busNotAvailable:\r
162 return ( 2) ;\r
163 case kUSBHID_intfBusyError:\r
164 return ( 3) ;\r
165 case kUSBHID_generalError:\r
166 return ( 4) ;\r
167 default:;\r
168 }\r
169 \r
170 /* If execution reaches this point, then the operation successfully started. Now wait til it's finished. */\r
171 while (1){\r
172 uint8_t ret = USBHID_intfStatus(intfNum,&bytesSent,&bytesReceived);\r
173 if (ret & kUSBHID_busNotAvailable){ /* This may happen at any time */\r
174 return ( 2) ;\r
175 }\r
176 if (ret & kUSBHID_waitingForSend){\r
177 if (ulTimeout && (sendCounter++ >= ulTimeout)){ /* Incr counter & try again */\r
178 return ( 1) ; /* Timed out */\r
179 }\r
180 } else {\r
181 return ( 0) ; /* If neither busNotAvailable nor waitingForSend, it succeeded */\r
182 }\r
183 }\r
184 }\r
185 \r
186 \r
187 \r
188 //*****************************************************************************\r
189 //\r
190 //! Completely Sends the Data in dataBuf\r
191 //! \r
192 //! \param *dataBuf is the address of the data buffer.\r
193 //! \param size is the size of the data.\r
194 //! \param intfnum intfNum is which HID interface is being used.\r
195 //! \param ulTimeout is the (32-bit) number of polls to USBHID_intfStatus().\r
196 //!\r
197 //! Sends the data in \b dataBuf, of size \b size, using the pre-call polling\r
198 //! method. It does so over interface \b intfNum. The send operation may still\r
199 //! be active after the function returns, and \b dataBuf should not be edited\r
200 //! until it can be verified that the operation has completed. The function\r
201 //! assumes that size is non-zero. This call assumes a previous send operation\r
202 //! might be underway.\r
203 //! \r
204 //! The 32-bit number \b ulTimeout selects how many times USBHID_intfStatus()\r
205 //! will be polled while waiting for the previous operation to complete. If the\r
206 //! value is zero, then no timeout is employed; it will wait indefinitely. When\r
207 //! choosing a number, it is advised to consider MCLK speed, as a faster CPU\r
208 //! will cycle through the calls more quickly. The function provides simple\r
209 //! coding while also taking advantage of the efficiencies of background\r
210 //! processing. If a previous send operation is underway, this function does\r
211 //! waste cycles polling, like xxxsendDataWaitTilDone(); however it's less\r
212 //! likely to do so since much of the sending presumably took place in the \r
213 //! background since the last call to xxxsendDataInBackground().\r
214 //! \r
215 //! The function also checks all valid return codes, and returns non-zero if an\r
216 //! error occurred. In many applications, the return value can simply be\r
217 //! evaluated as zero or non-zero, where nonzero means the call failed for\r
218 //! reasons of host or bus non-availability. Therefore, it may desirable for the\r
219 //! application to break from execution. Other applications may wish to handle\r
220 //! return values 1 and 2 in different ways.\r
221 //! \r
222 //! It’s recommended not to call this function from within an event handler.\r
223 //! This is because if an interface currently has an open send operation, the\r
224 //! operation will never complete during the event handler; rather, only after\r
225 //! the ISR that spawned the event returns. Thus the USBHID_intfStatus() polling\r
226 //! would loop indefinitely (or timeout). It’s better to set a flag from within\r
227 //! the event handler, and use this flag to trigger the calling of this function\r
228 //! from within main().\r
229 //! \r
230 //! \return \b 0 if the call succeeded; all data has been sent.\r
231 //! \return \b 1 if the call timed out, either because the host is unavailable\r
232 //! or a COM port with an active application on the host wasn't opened.\r
233 //! \return \b 2 if the bus is unavailable.\r
234 //\r
235 //*****************************************************************************\r
236 uint8_t hidSendDataInBackground (uint8_t* dataBuf,\r
237 uint16_t size,\r
238 uint8_t intfNum,\r
239 uint32_t ulTimeout)\r
240 {\r
241 uint32_t sendCounter = 0;\r
242 uint16_t bytesSent, bytesReceived;\r
243 \r
244 while (USBHID_intfStatus(intfNum,&bytesSent,\r
245 &bytesReceived) & kUSBHID_waitingForSend){\r
246 if (ulTimeout && ((sendCounter++) > ulTimeout)){ /* A send operation is underway; incr counter & try again */\r
247 return ( 1) ; /* Timed out */\r
248 }\r
249 }\r
250 \r
251 /* The interface is now clear. Call sendData(). */\r
252 switch (USBHID_sendData(dataBuf,size,intfNum)){\r
253 case kUSBHID_sendStarted:\r
254 return ( 0) ;\r
255 case kUSBHID_busNotAvailable:\r
256 return ( 2) ;\r
257 default:\r
258 return ( 4) ;\r
259 }\r
260 }\r
261 \r
262 \r
263 \r
264 \r
265 //*****************************************************************************\r
266 //\r
267 //! Opens a Receive Operation\r
268 //! \r
269 //! \param *dataBuf is the address of the data buffer.\r
270 //! \param size is the size of the data.\r
271 //! \param intfnum intfNum is which HID interface is being used.\r
272 //!\r
273 //! Opens a brief receive operation for any data that has already been received\r
274 //! into the USB buffer over interface \b intfNum. This call only retrieves data\r
275 //! that is already waiting in the USB buffer -- that is, data that has already\r
276 //! been received by the MCU. It assumes a previous, open receive operation\r
277 //! (began by a direct call to USBxxx_receiveData()) is NOT underway on this\r
278 //! interface; and no receive operation remains open after this call returns.\r
279 //! It doesn't check for kUSBxxx_busNotAvailable, because it doesn't matter if\r
280 //! it's not. The data in the USB buffer is copied into \b dataBuf, and the\r
281 //! function returns the number of bytes received.\r
282 //! \r
283 //! \b size is the maximum that is allowed to be received before exiting; i.e.,\r
284 //! it is the size allotted to \b dataBuf. If \b size bytes are received, the\r
285 //! function ends, returning \b size. In this case, it’s possible that more\r
286 //! bytes are still in the USB buffer; it might be a good idea to open another\r
287 //! receive operation to retrieve them. For this reason, operation is simplified\r
288 //! by using large \b size values, since it helps ensure all the data is\r
289 //! retrieved at one time.\r
290 //! \r
291 //! This function is usually called when a USBHID_handleDataReceived() event\r
292 //! flags the application that data has been received into the USB buffer.\r
293 //! \r
294 //! \return The number of bytes received into \b dataBuf.\r
295 //\r
296 //*****************************************************************************\r
297 uint16_t hidReceiveDataInBuffer (uint8_t* dataBuf, uint16_t size, uint8_t intfNum)\r
298 {\r
299 uint16_t bytesInBuf;\r
300 uint16_t rxCount = 0;\r
301 uint8_t* currentPos = dataBuf;\r
302 \r
303 while (bytesInBuf = USBHID_bytesInUSBBuffer(intfNum)){\r
304 if ((uint16_t)(currentPos - dataBuf + bytesInBuf) <= size){\r
305 rxCount = bytesInBuf;\r
306 USBHID_receiveData(currentPos,rxCount,intfNum);\r
307 currentPos += rxCount;\r
308 } else {\r
309 rxCount = size - (currentPos - dataBuf);\r
310 USBHID_receiveData(currentPos,rxCount,intfNum);\r
311 currentPos += rxCount;\r
312 return (currentPos - dataBuf);\r
313 }\r
314 }\r
315 \r
316 return (currentPos - dataBuf);\r
317 }\r
318 \r
319 //\r
320 //! \cond\r
321 //\r
322 #endif\r
323 \r
324 /*********************************************************************************************\r
325 Please see the MSP430 USB CDC API Programmer's Guide Sec. 9 for a full description of these \r
326 functions, how they work, and how to use them. \r
327 **********************************************************************************************/\r
328 \r
329 #ifdef _CDC_\r
330 //\r
331 //! \endcond\r
332 //\r
333 //*****************************************************************************\r
334 //\r
335 //! Completely Sends the Data in dataBuf\r
336 //! \r
337 //! \param *dataBuf is the address of the data buffer.\r
338 //! \param size is the size of the data.\r
339 //! \param intfnum intfNum is which interface is being used.\r
340 //! \param ulTimeout is the (32-bit) number of polls to USBCDC_intfStatus().\r
341 //!\r
342 //! Sends the data in \b dataBuf, of size \b size, using the post-call polling method.\r
343 //! It does so over interface \b intfNum. The function doesn’t return until the\r
344 //! send has completed. Because of this, the user buffer can be edited\r
345 //! immediately after the function returns, without consequence. The\r
346 //! function assumes that size is non-zero. It assumes no previous send\r
347 //! operation is underway. \r
348 //! \r
349 //! The 32-bit number \b ulTimeout selects how many times USBCDC_intfStatus() will\r
350 //! be polled while waiting for the operation to complete. If the value is zero,\r
351 //! then no timeout is employed; it will wait indefinitely. When choosing a\r
352 //! number, it is advised to consider MCLK speed, as a faster CPU will cycle\r
353 //! through the calls more quickly. The function provides the simplest coding,\r
354 //! at the expense of wasted cycles and potentially allowing MCU execution to\r
355 //! become "locked" to the host, a disadvantage if the host (or bus) is slow.\r
356 //! \r
357 //! The function also checks all valid return codes, and returns non-zero if an\r
358 //! error occurred. In many applications, the return value can simply be\r
359 //! evaluated as zero or non-zero, where nonzero means the call failed for\r
360 //! reasons of host or bus non-availability. Therefore, it may desirable for the\r
361 //! application to break from execution. Other applications may wish to handle\r
362 //! return values 1 and 2 in different ways.\r
363 //! \r
364 //! It’s recommended not to call this function from within an event handler.\r
365 //! This is because if an interface currently has an open send operation, the\r
366 //! operation will never complete during the event handler; rather, only after\r
367 //! the ISR that spawned the event returns. Thus the USBCDC_intfStatus() polling\r
368 //! would loop indefinitely (or timeout). It’s better to set a flag from within\r
369 //! the event handler, and use this flag to trigger the calling of this function\r
370 //! from within main().\r
371 //! \r
372 //! \return \b 0 if the call succeeded; all data has been sent.\r
373 //! \return \b 1 if the call timed out, either because the host is unavailable\r
374 //! or a COM port with an active application on the host wasn't opened.\r
375 //! \return \b 2 if the bus is unavailable.\r
376 //\r
377 //*****************************************************************************\r
378 uint8_t cdcSendDataWaitTilDone (uint8_t* dataBuf,\r
379 uint16_t size,\r
380 uint8_t intfNum,\r
381 uint32_t ulTimeout)\r
382 {\r
383 uint32_t sendCounter = 0;\r
384 uint16_t bytesSent, bytesReceived;\r
385 \r
386 switch (USBCDC_sendData(dataBuf,size,intfNum))\r
387 {\r
388 case kUSBCDC_sendStarted:\r
389 break;\r
390 case kUSBCDC_busNotAvailable:\r
391 return ( 2) ;\r
392 case kUSBCDC_intfBusyError:\r
393 return ( 3) ;\r
394 case kUSBCDC_generalError:\r
395 return ( 4) ;\r
396 default:;\r
397 }\r
398 \r
399 /* If execution reaches this point, then the operation successfully started. Now wait til it's finished. */\r
400 while (1){\r
401 uint8_t ret = USBCDC_intfStatus(intfNum,&bytesSent,&bytesReceived);\r
402 if (ret & kUSBCDC_busNotAvailable){ /* This may happen at any time */\r
403 return ( 2) ;\r
404 }\r
405 if (ret & kUSBCDC_waitingForSend){\r
406 if (ulTimeout && (sendCounter++ >= ulTimeout)){ /* Incr counter & try again */\r
407 return ( 1) ; /* Timed out */\r
408 }\r
409 } else {\r
410 return ( 0) ; /* If neither busNotAvailable nor waitingForSend, it succeeded */\r
411 }\r
412 }\r
413 }\r
414 \r
415 \r
416 \r
417 \r
418 //*****************************************************************************\r
419 //\r
420 //! Completely Sends the Data in dataBuf\r
421 //! \r
422 //! \param *dataBuf is the address of the data buffer.\r
423 //! \param size is the size of the data.\r
424 //! \param intfnum intfNum is which interface is being used.\r
425 //! \param ulTimeout is the (32-bit) number of polls to USBCDC_intfStatus().\r
426 //!\r
427 //! Sends the data in \b dataBuf, of size \b size, using the pre-call polling\r
428 //! method. It does so over interface \b intfNum. The send operation may still\r
429 //! be active after the function returns, and \b dataBuf should not be edited\r
430 //! until it can be verified that the operation has completed. The function\r
431 //! assumes that size is non-zero. This call assumes a previous send operation\r
432 //! might be underway.\r
433 //! \r
434 //! The 32-bit number \b ulTimeout selects how many times USBCDC_intfStatus()\r
435 //! will be polled while waiting for the previous operation to complete. If the\r
436 //! value is zero, then no timeout is employed; it will wait indefinitely. When\r
437 //! choosing a number, it is advised to consider MCLK speed, as a faster CPU\r
438 //! will cycle through the calls more quickly. The function provides simple\r
439 //! coding while also taking advantage of the efficiencies of background\r
440 //! processing. If a previous send operation is underway, this function does\r
441 //! waste cycles polling, like xxxsendDataWaitTilDone(); however it's less\r
442 //! likely to do so since much of the sending presumably took place in the \r
443 //! background since the last call to xxxsendDataInBackground().\r
444 //! \r
445 //! The function also checks all valid return codes, and returns non-zero if an\r
446 //! error occurred. In many applications, the return value can simply be\r
447 //! evaluated as zero or non-zero, where nonzero means the call failed for\r
448 //! reasons of host or bus non-availability. Therefore, it may desirable for the\r
449 //! application to break from execution. Other applications may wish to handle\r
450 //! return values 1 and 2 in different ways.\r
451 //! \r
452 //! It’s recommended not to call this function from within an event handler.\r
453 //! This is because if an interface currently has an open send operation, the\r
454 //! operation will never complete during the event handler; rather, only after\r
455 //! the ISR that spawned the event returns. Thus the USBCDC_intfStatus() polling\r
456 //! would loop indefinitely (or timeout). It’s better to set a flag from within\r
457 //! the event handler, and use this flag to trigger the calling of this function\r
458 //! from within main().\r
459 //! \r
460 //! \return \b 0 if the call succeeded; all data has been sent.\r
461 //! \return \b 1 if the call timed out, either because the host is unavailable\r
462 //! or a COM port with an active application on the host wasn't opened.\r
463 //! \return \b 2 if the bus is unavailable.\r
464 //\r
465 //*****************************************************************************\r
466 uint8_t cdcSendDataInBackground (uint8_t* dataBuf,\r
467 uint16_t size,\r
468 uint8_t intfNum,\r
469 uint32_t ulTimeout)\r
470 {\r
471 uint32_t sendCounter = 0;\r
472 uint16_t bytesSent, bytesReceived;\r
473 \r
474 while (USBCDC_intfStatus(intfNum,&bytesSent,\r
475 &bytesReceived) & kUSBCDC_waitingForSend){\r
476 if (ulTimeout && ((sendCounter++) > ulTimeout)){ /* A send operation is underway; incr counter & try again */\r
477 return ( 1) ; /* Timed out */\r
478 }\r
479 }\r
480 \r
481 /* The interface is now clear. Call sendData(). */\r
482 switch (USBCDC_sendData(dataBuf,size,intfNum)){\r
483 case kUSBCDC_sendStarted:\r
484 return ( 0) ;\r
485 case kUSBCDC_busNotAvailable:\r
486 return ( 2) ;\r
487 default:\r
488 return ( 4) ;\r
489 }\r
490 }\r
491 \r
492 \r
493 \r
494 \r
495 //*****************************************************************************\r
496 //\r
497 //! Opens a Receive Operation\r
498 //! \r
499 //! \param *dataBuf is the address of the data buffer.\r
500 //! \param size is the size of the data.\r
501 //! \param intfnum intfNum is which CDC interface is being used.\r
502 //!\r
503 //! Opens a brief receive operation for any data that has already been received\r
504 //! into the USB buffer over interface \b intfNum. This call only retrieves data\r
505 //! that is already waiting in the USB buffer -- that is, data that has already\r
506 //! been received by the MCU. It assumes a previous, open receive operation\r
507 //! (began by a direct call to USBxxx_receiveData()) is NOT underway on this\r
508 //! interface; and no receive operation remains open after this call returns.\r
509 //! It doesn't check for kUSBxxx_busNotAvailable, because it doesn't matter if\r
510 //! it's not. The data in the USB buffer is copied into \b dataBuf, and the\r
511 //! function returns the number of bytes received.\r
512 //! \r
513 //! \b size is the maximum that is allowed to be received before exiting; i.e.,\r
514 //! it is the size allotted to \b dataBuf. If \b size bytes are received, the\r
515 //! function ends, returning \b size. In this case, it’s possible that more\r
516 //! bytes are still in the USB buffer; it might be a good idea to open another\r
517 //! receive operation to retrieve them. For this reason, operation is simplified\r
518 //! by using large \b size values, since it helps ensure all the data is\r
519 //! retrieved at one time.\r
520 //! \r
521 //! This function is usually called when a USBCDC_handleDataReceived() event\r
522 //! flags the application that data has been received into the USB buffer.\r
523 //! \r
524 //! \return The number of bytes received into \b dataBuf.\r
525 //\r
526 //*****************************************************************************\r
527 uint16_t cdcReceiveDataInBuffer (uint8_t* dataBuf, uint16_t size, uint8_t intfNum)\r
528 {\r
529 uint16_t bytesInBuf;\r
530 uint16_t rxCount = 0;\r
531 uint8_t* currentPos = dataBuf;\r
532 \r
533 while (bytesInBuf = USBCDC_bytesInUSBBuffer(intfNum)){\r
534 if ((uint16_t)(currentPos - dataBuf + bytesInBuf) <= size){\r
535 rxCount = bytesInBuf;\r
536 USBCDC_receiveData(currentPos,rxCount,intfNum);\r
537 currentPos += rxCount;\r
538 } else {\r
539 rxCount = size - (currentPos - dataBuf);\r
540 USBCDC_receiveData(currentPos,rxCount,intfNum);\r
541 currentPos += rxCount;\r
542 return (currentPos - dataBuf);\r
543 }\r
544 }\r
545 \r
546 return (currentPos - dataBuf);\r
547 }\r
548 //\r
549 //! \cond\r
550 //\r
551 \r
552 #endif\r
553 //\r
554 //! \endcond\r
555 //\r
556 \r
557 #ifdef _PHDC_\r
558 /* This construct implements post-call polling to ensure the sending completes before the function\r
559 * returns. It provides the simplest coding, at the expense of wasted cycles and potentially\r
560 * allowing MCU execution to become "locked" to the host, a disadvantage if the host (or bus) is\r
561 * slow. The function also checks all valid return codes, and returns non-zero if an error occurred.\r
562 * It assumes no previous send operation is underway; also assumes size is non-zero. */\r
563 uint8_t phdcSendDataWaitTilDone (uint8_t* dataBuf,\r
564 uint16_t size,\r
565 uint8_t intfNum,\r
566 uint32_t ulTimeout)\r
567 {\r
568 uint32_t sendCounter = 0;\r
569 uint16_t bytesSent, bytesReceived;\r
570 \r
571 switch (USBPHDC_sendData(dataBuf,size,intfNum))\r
572 {\r
573 case kUSBPHDC_sendStarted:\r
574 break;\r
575 case kUSBPHDC_busNotAvailable:\r
576 return ( 2) ;\r
577 case kUSBPHDC_intfBusyError:\r
578 return ( 3) ;\r
579 case kUSBPHDC_generalError:\r
580 return ( 4) ;\r
581 default:;\r
582 }\r
583 \r
584 /* If execution reaches this point, then the operation successfully started. Now wait til it's finished. */\r
585 while (1){\r
586 uint8_t ret = USBPHDC_intfStatus(intfNum,&bytesSent,&bytesReceived);\r
587 if (ret & kUSBPHDC_busNotAvailable){ /* This may happen at any time */\r
588 return ( 2) ;\r
589 }\r
590 if (ret & kUSBPHDC_waitingForSend){\r
591 if (ulTimeout && (sendCounter++ >= ulTimeout)){ /* Incr counter & try again */\r
592 return ( 1) ; /* Timed out */\r
593 }\r
594 } else {\r
595 return ( 0) ; /* If neither busNotAvailable nor waitingForSend, it succeeded */\r
596 }\r
597 }\r
598 }\r
599 \r
600 /* This construct implements pre-call polling to ensure the sending completes before the function\r
601 * returns. It provides simple coding while also taking advantage of the efficiencies of background\r
602 * processing. If a previous send operation is underway, this function does waste cycles polling,\r
603 * like xxxsendDataWaitTilDone(); however it's less likely to do so since much of the sending\r
604 * presumably took place in the background since the last call to xxxsendDataInBackground().\r
605 * The function also checks all valid return codes, and returns non-zero if an error occurred.\r
606 * It assumes no previous send operation is underway; also assumes size is non-zero.\r
607 * This call assumes a previous send operation might be underway; also assumes size is non-zero.\r
608 * Returns zero if send completed; non-zero if it failed, with 1 = timeout and 2 = bus is gone. */\r
609 uint8_t phdcSendDataInBackground (uint8_t* dataBuf,\r
610 uint16_t size,\r
611 uint8_t intfNum,\r
612 uint32_t ulTimeout)\r
613 {\r
614 uint32_t sendCounter = 0;\r
615 uint16_t bytesSent, bytesReceived;\r
616 \r
617 while (USBPHDC_intfStatus(intfNum,&bytesSent,\r
618 &bytesReceived) & kUSBPHDC_waitingForSend){\r
619 if (ulTimeout && ((sendCounter++) > ulTimeout)){ /* A send operation is underway; incr counter & try again */\r
620 return ( 1) ; /* Timed out */\r
621 }\r
622 }\r
623 \r
624 /* The interface is now clear. Call sendData(). */\r
625 switch (USBPHDC_sendData(dataBuf,size,intfNum)){\r
626 case kUSBPHDC_sendStarted:\r
627 return ( 0) ;\r
628 case kUSBPHDC_busNotAvailable:\r
629 return ( 2) ;\r
630 default:\r
631 return ( 4) ;\r
632 }\r
633 }\r
634 \r
635 /* This call only retrieves data that is already waiting in the USB buffer -- that is, data that has\r
636 * already been received by the MCU. It assumes a previous, open receive operation (began by a direct\r
637 * call to USBxxx_receiveData()) is NOT underway on this interface; and no receive operation remains\r
638 * open after this call returns. It doesn't check for kUSBxxx_busNotAvailable, because it doesn't\r
639 * matter if it's not. size is the maximum that is allowed to be received before exiting; i.e., it\r
640 * is the size allotted to dataBuf. Returns the number of bytes received. */\r
641 uint16_t phdcReceiveDataInBuffer (uint8_t* dataBuf, uint16_t size, uint8_t intfNum)\r
642 {\r
643 uint16_t bytesInBuf;\r
644 uint16_t rxCount = 0;\r
645 uint8_t* currentPos = dataBuf;\r
646 \r
647 while (bytesInBuf = USBPHDC_bytesInUSBBuffer(intfNum)){\r
648 if ((uint16_t)(currentPos - dataBuf + bytesInBuf) <= size){\r
649 rxCount = bytesInBuf;\r
650 USBPHDC_receiveData(currentPos,rxCount,intfNum);\r
651 currentPos += rxCount;\r
652 } else {\r
653 rxCount = size - (currentPos - dataBuf);\r
654 USBPHDC_receiveData(currentPos,rxCount,intfNum);\r
655 currentPos += rxCount;\r
656 return (currentPos - dataBuf);\r
657 }\r
658 }\r
659 \r
660 return (currentPos - dataBuf);\r
661 }\r
662 \r
663 #endif\r
664 //Released_Version_4_10_02\r