usbringbuf.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. //*****************************************************************************
  2. //
  3. // usbringbuf.c - USB library ring buffer management utilities.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of AM1808 Sitaraware USB Library and reused from revision 6288
  22. // of the Stellaris USB Library.
  23. //
  24. //*****************************************************************************
  25. #include "hw_types.h"
  26. #include "debug.h"
  27. #include "interrupt.h"
  28. #include "usblib.h"
  29. //*****************************************************************************
  30. //
  31. //! \addtogroup usblib_buffer_api
  32. //! @{
  33. //
  34. //*****************************************************************************
  35. //*****************************************************************************
  36. //
  37. // Define NULL, if not already defined.
  38. //
  39. //*****************************************************************************
  40. #ifndef NULL
  41. #define NULL ((void *)0)
  42. #endif
  43. //*****************************************************************************
  44. //
  45. // Change the value of a variable atomically.
  46. //
  47. // \param pulVal points to the index whose value is to be modified.
  48. // \param ulDelta is the number of bytes to increment the index by.
  49. // \param ulSize is the size of the buffer the index refers to.
  50. //
  51. // This function is used to increment a read or write buffer index that may be
  52. // written in various different contexts. It ensures that the
  53. // read/modify/write sequence is not interrupted and, hence, guards against
  54. // corruption of the variable. The new value is adjusted for buffer wrap.
  55. //
  56. // \return None.
  57. //
  58. //*****************************************************************************
  59. #ifdef _TMS320C6X
  60. static void
  61. UpdateIndexAtomic(volatile unsigned int *pulVal, unsigned int ulDelta,
  62. unsigned int ulSize)
  63. {
  64. unsigned int IntStatus;
  65. //
  66. // Turn interrupts off temporarily.
  67. //
  68. IntStatus = IntGlobalDisable();
  69. //
  70. // Update the variable value.
  71. //
  72. *pulVal += ulDelta;
  73. //
  74. // Correct for wrap. We use a loop here since we don't want to use a
  75. // modulus operation with interrupts off but we don't want to fail in
  76. // case ulDelta is greater than ulSize (which is extremely unlikely but...)
  77. //
  78. while(*pulVal >= ulSize)
  79. {
  80. *pulVal -= ulSize;
  81. }
  82. //
  83. // Restore the interrupt state
  84. //
  85. IntGlobalRestore(IntStatus);
  86. }
  87. #else
  88. static void
  89. UpdateIndexAtomic(volatile unsigned int *pulVal, unsigned int ulDelta,
  90. unsigned int ulSize)
  91. {
  92. unsigned char IntStatus;
  93. //
  94. // Turn interrupts off temporarily.
  95. //
  96. IntStatus = IntDisable();
  97. //
  98. // Update the variable value.
  99. //
  100. *pulVal += ulDelta;
  101. //
  102. // Correct for wrap. We use a loop here since we don't want to use a
  103. // modulus operation with interrupts off but we don't want to fail in
  104. // case ulDelta is greater than ulSize (which is extremely unlikely but...)
  105. //
  106. while(*pulVal >= ulSize)
  107. {
  108. *pulVal -= ulSize;
  109. }
  110. //
  111. // Restore the interrupt state
  112. //
  113. IntEnable(IntStatus);
  114. }
  115. #endif
  116. //*****************************************************************************
  117. //
  118. //! Determines whether a ring buffer is full or not.
  119. //!
  120. //! \param ptUSBRingBuf is the ring buffer object to empty.
  121. //!
  122. //! This function is used to determine whether or not a given ring buffer is
  123. //! full. The structure is specifically to ensure that we do not see
  124. //! warnings from the compiler related to the order of volatile accesses
  125. //! being undefined.
  126. //!
  127. //! \return Returns \b true if the buffer is full or \b false otherwise.
  128. //
  129. //*****************************************************************************
  130. tBoolean
  131. USBRingBufFull(tUSBRingBufObject *ptUSBRingBuf)
  132. {
  133. unsigned int ulWrite;
  134. unsigned int ulRead;
  135. //
  136. // Check the arguments.
  137. //
  138. ASSERT(ptUSBRingBuf != NULL);
  139. //
  140. // Copy the Read/Write indices for calculation.
  141. //
  142. ulWrite = ptUSBRingBuf->ulWriteIndex;
  143. ulRead = ptUSBRingBuf->ulReadIndex;
  144. //
  145. // Return the full status of the buffer.
  146. //
  147. return((((ulWrite + 1) % ptUSBRingBuf->ulSize) == ulRead) ? true : false);
  148. }
  149. //*****************************************************************************
  150. //
  151. //! Determines whether a ring buffer is empty or not.
  152. //!
  153. //! \param ptUSBRingBuf is the ring buffer object to empty.
  154. //!
  155. //! This function is used to determine whether or not a given ring buffer is
  156. //! empty. The structure is specifically to ensure that we do not see
  157. //! warnings from the compiler related to the order of volatile accesses
  158. //! being undefined.
  159. //!
  160. //! \return Returns \b true if the buffer is empty or \b false otherwise.
  161. //
  162. //*****************************************************************************
  163. tBoolean
  164. USBRingBufEmpty(tUSBRingBufObject *ptUSBRingBuf)
  165. {
  166. unsigned int ulWrite;
  167. unsigned int ulRead;
  168. //
  169. // Check the arguments.
  170. //
  171. ASSERT(ptUSBRingBuf != NULL);
  172. //
  173. // Copy the Read/Write indices for calculation.
  174. //
  175. ulWrite = ptUSBRingBuf->ulWriteIndex;
  176. ulRead = ptUSBRingBuf->ulReadIndex;
  177. //
  178. // Return the empty status of the buffer.
  179. //
  180. return((ulWrite == ulRead) ? true : false);
  181. }
  182. //*****************************************************************************
  183. //
  184. //! Empties the ring buffer.
  185. //!
  186. //! \param ptUSBRingBuf is the ring buffer object to empty.
  187. //!
  188. //! Discards all data from the ring buffer.
  189. //!
  190. //! \return None.
  191. //
  192. //*****************************************************************************
  193. #ifdef _TMS320C6X
  194. void
  195. USBRingBufFlush(tUSBRingBufObject *ptUSBRingBuf)
  196. {
  197. unsigned int bIntsOff;
  198. //
  199. // Check the arguments.
  200. //
  201. ASSERT(ptUSBRingBuf != NULL);
  202. //
  203. // Set the Read/Write pointers to be the same. Do this with interrupts
  204. // disabled to prevent the possibility of corruption of the read index.
  205. //
  206. bIntsOff = IntGlobalDisable();
  207. ptUSBRingBuf->ulReadIndex = ptUSBRingBuf->ulWriteIndex;
  208. IntGlobalRestore(bIntsOff);
  209. }
  210. #else
  211. void
  212. USBRingBufFlush(tUSBRingBufObject *ptUSBRingBuf)
  213. {
  214. unsigned char bIntsOff;
  215. //
  216. // Check the arguments.
  217. //
  218. ASSERT(ptUSBRingBuf != NULL);
  219. //
  220. // Set the Read/Write pointers to be the same. Do this with interrupts
  221. // disabled to prevent the possibility of corruption of the read index.
  222. //
  223. bIntsOff =IntDisable();
  224. ptUSBRingBuf->ulReadIndex = ptUSBRingBuf->ulWriteIndex;
  225. IntEnable(bIntsOff);
  226. }
  227. #endif
  228. //*****************************************************************************
  229. //
  230. //! Returns number of bytes stored in ring buffer.
  231. //!
  232. //! \param ptUSBRingBuf is the ring buffer object to check.
  233. //!
  234. //! This function returns the number of bytes stored in the ring buffer.
  235. //!
  236. //! \return Returns the number of bytes stored in the ring buffer.
  237. //
  238. //*****************************************************************************
  239. unsigned int
  240. USBRingBufUsed(tUSBRingBufObject *ptUSBRingBuf)
  241. {
  242. unsigned int ulWrite;
  243. unsigned int ulRead;
  244. //
  245. // Check the arguments.
  246. //
  247. ASSERT(ptUSBRingBuf != NULL);
  248. //
  249. // Copy the Read/Write indices for calculation.
  250. //
  251. ulWrite = ptUSBRingBuf->ulWriteIndex;
  252. ulRead = ptUSBRingBuf->ulReadIndex;
  253. //
  254. // Return the number of bytes contained in the ring buffer.
  255. //
  256. return((ulWrite >= ulRead) ? (ulWrite - ulRead) :
  257. (ptUSBRingBuf->ulSize - (ulRead - ulWrite)));
  258. }
  259. //*****************************************************************************
  260. //
  261. //! Returns number of bytes available in a ring buffer.
  262. //!
  263. //! \param ptUSBRingBuf is the ring buffer object to check.
  264. //!
  265. //! This function returns the number of bytes available in the ring buffer.
  266. //!
  267. //! \return Returns the number of bytes available in the ring buffer.
  268. //
  269. //*****************************************************************************
  270. unsigned int
  271. USBRingBufFree(tUSBRingBufObject *ptUSBRingBuf)
  272. {
  273. //
  274. // Check the arguments.
  275. //
  276. ASSERT(ptUSBRingBuf != NULL);
  277. //
  278. // Return the number of bytes available in the ring buffer.
  279. //
  280. return((ptUSBRingBuf->ulSize - 1) - USBRingBufUsed(ptUSBRingBuf));
  281. }
  282. //*****************************************************************************
  283. //
  284. //! Returns number of contiguous bytes of data stored in ring buffer ahead of
  285. //! the current read pointer.
  286. //!
  287. //! \param ptUSBRingBuf is the ring buffer object to check.
  288. //!
  289. //! This function returns the number of contiguous bytes of data available in
  290. //! the ring buffer ahead of the current read pointer. This represents the
  291. //! largest block of data which does not straddle the buffer wrap.
  292. //!
  293. //! \return Returns the number of contiguous bytes available.
  294. //
  295. //*****************************************************************************
  296. unsigned int
  297. USBRingBufContigUsed(tUSBRingBufObject *ptUSBRingBuf)
  298. {
  299. unsigned int ulWrite;
  300. unsigned int ulRead;
  301. //
  302. // Check the arguments.
  303. //
  304. ASSERT(ptUSBRingBuf != NULL);
  305. //
  306. // Copy the Read/Write indices for calculation.
  307. //
  308. ulWrite = ptUSBRingBuf->ulWriteIndex;
  309. ulRead = ptUSBRingBuf->ulReadIndex;
  310. //
  311. // Return the number of contiguous bytes available.
  312. //
  313. return((ulWrite >= ulRead) ? (ulWrite - ulRead) :
  314. (ptUSBRingBuf->ulSize - ulRead));
  315. }
  316. //*****************************************************************************
  317. //
  318. //! Returns number of contiguous free bytes available in a ring buffer.
  319. //!
  320. //! \param ptUSBRingBuf is the ring buffer object to check.
  321. //!
  322. //! This function returns the number of contiguous free bytes ahead of the
  323. //! current write pointer in the ring buffer.
  324. //!
  325. //! \return Returns the number of contiguous bytes available in the ring
  326. //! buffer.
  327. //
  328. //*****************************************************************************
  329. unsigned int
  330. USBRingBufContigFree(tUSBRingBufObject *ptUSBRingBuf)
  331. {
  332. unsigned int ulWrite;
  333. unsigned int ulRead;
  334. //
  335. // Check the arguments.
  336. //
  337. ASSERT(ptUSBRingBuf != NULL);
  338. //
  339. // Copy the Read/Write indices for calculation.
  340. //
  341. ulWrite = ptUSBRingBuf->ulWriteIndex;
  342. ulRead = ptUSBRingBuf->ulReadIndex;
  343. //
  344. // Return the number of contiguous bytes available.
  345. //
  346. if(ulRead > ulWrite)
  347. {
  348. //
  349. // The read pointer is above the write pointer so the amount of free
  350. // space is the difference between the two indices minus 1 to account
  351. // for the buffer full condition (write index one behind read index).
  352. //
  353. return((ulRead - ulWrite) - 1);
  354. }
  355. else
  356. {
  357. //
  358. // If the write pointer is above the read pointer, the amount of free
  359. // space is the size of the buffer minus the write index. We need to
  360. // add a special-case adjustment if the read index is 0 since we need
  361. // to leave 1 byte empty to ensure we can tell the difference between
  362. // the buffer being full and empty.
  363. //
  364. return(ptUSBRingBuf->ulSize - ulWrite - ((ulRead == 0) ? 1 : 0));
  365. }
  366. }
  367. //*****************************************************************************
  368. //
  369. //! Returns the size in bytes of a ring buffer.
  370. //!
  371. //! \param ptUSBRingBuf is the ring buffer object to check.
  372. //!
  373. //! This function returns the size of the ring buffer.
  374. //!
  375. //! \return Returns the size in bytes of the ring buffer.
  376. //
  377. //*****************************************************************************
  378. unsigned int
  379. USBRingBufSize(tUSBRingBufObject *ptUSBRingBuf)
  380. {
  381. //
  382. // Check the arguments.
  383. //
  384. ASSERT(ptUSBRingBuf != NULL);
  385. //
  386. // Return the number of bytes available in the ring buffer.
  387. //
  388. return(ptUSBRingBuf->ulSize);
  389. }
  390. //*****************************************************************************
  391. //
  392. //! Reads a single byte of data from a ring buffer.
  393. //!
  394. //! \param ptUSBRingBuf points to the ring buffer to be written to.
  395. //!
  396. //! This function reads a single byte of data from a ring buffer.
  397. //!
  398. //! \return The byte read from the ring buffer.
  399. //
  400. //*****************************************************************************
  401. unsigned char
  402. USBRingBufReadOne(tUSBRingBufObject *ptUSBRingBuf)
  403. {
  404. unsigned char ucTemp;
  405. //
  406. // Check the arguments.
  407. //
  408. ASSERT(ptUSBRingBuf != NULL);
  409. //
  410. // Verify that space is available in the buffer.
  411. //
  412. ASSERT(USBRingBufUsed(ptUSBRingBuf) != 0);
  413. //
  414. // Write the data byte.
  415. //
  416. ucTemp = ptUSBRingBuf->pucBuf[ptUSBRingBuf->ulReadIndex];
  417. //
  418. // Increment the read index.
  419. //
  420. UpdateIndexAtomic(&ptUSBRingBuf->ulReadIndex, 1, ptUSBRingBuf->ulSize);
  421. //
  422. // Return the character read.
  423. //
  424. return(ucTemp);
  425. }
  426. //*****************************************************************************
  427. //
  428. //! Reads data from a ring buffer.
  429. //!
  430. //! \param ptUSBRingBuf points to the ring buffer to be read from.
  431. //! \param pucData points to where the data should be stored.
  432. //! \param ulLength is the number of bytes to be read.
  433. //!
  434. //! This function reads a sequence of bytes from a ring buffer.
  435. //!
  436. //! \return None.
  437. //
  438. //*****************************************************************************
  439. void
  440. USBRingBufRead(tUSBRingBufObject *ptUSBRingBuf, unsigned char *pucData,
  441. unsigned int ulLength)
  442. {
  443. unsigned int ulTemp;
  444. //
  445. // Check the arguments.
  446. //
  447. ASSERT(ptUSBRingBuf != NULL);
  448. ASSERT(pucData != NULL);
  449. ASSERT(ulLength != 0);
  450. //
  451. // Verify that data is available in the buffer.
  452. //
  453. ASSERT(ulLength <= USBRingBufUsed(ptUSBRingBuf));
  454. //
  455. // Read the data from the ring buffer.
  456. //
  457. for(ulTemp = 0; ulTemp < ulLength; ulTemp++)
  458. {
  459. pucData[ulTemp] = USBRingBufReadOne(ptUSBRingBuf);
  460. }
  461. }
  462. //*****************************************************************************
  463. //
  464. //! Removes bytes from the ring buffer by advancing the read index.
  465. //!
  466. //! \param ptUSBRingBuf points to the ring buffer from which bytes are to be
  467. //! removed.
  468. //! \param ulNumBytes is the number of bytes to be removed from the buffer.
  469. //!
  470. //! This function advances the ring buffer read index by a given number of
  471. //! bytes, removing that number of bytes of data from the buffer. If \e
  472. //! ulNumBytes is larger than the number of bytes currently in the buffer, the
  473. //! buffer is emptied.
  474. //!
  475. //! \return None.
  476. //
  477. //*****************************************************************************
  478. void
  479. USBRingBufAdvanceRead(tUSBRingBufObject *ptUSBRingBuf,
  480. unsigned int ulNumBytes)
  481. {
  482. unsigned int ulCount;
  483. //
  484. // Check the arguments.
  485. //
  486. ASSERT(ptUSBRingBuf != NULL);
  487. //
  488. // Make sure that we are not being asked to remove more data than is
  489. // there to be removed.
  490. //
  491. ulCount = USBRingBufUsed(ptUSBRingBuf);
  492. ulCount = (ulCount < ulNumBytes) ? ulCount : ulNumBytes;
  493. //
  494. // Advance the buffer read index by the required number of bytes.
  495. //
  496. UpdateIndexAtomic(&ptUSBRingBuf->ulReadIndex, ulCount,
  497. ptUSBRingBuf->ulSize);
  498. }
  499. //*****************************************************************************
  500. //
  501. //! Adds bytes to the ring buffer by advancing the write index.
  502. //!
  503. //! \param ptUSBRingBuf points to the ring buffer to which bytes have been
  504. //! added.
  505. //! \param ulNumBytes is the number of bytes added to the buffer.
  506. //!
  507. //! This function should be used by clients who wish to add data to the buffer
  508. //! directly rather than via calls to USBRingBufWrite() or
  509. //! USBRingBufWriteOne(). It advances the write index by a given number of
  510. //! bytes.
  511. //!
  512. //! \note It is considered an error if the \e ulNumBytes parameter is larger
  513. //! than the amount of free space in the buffer and a debug build of this
  514. //! function will fail (ASSERT) if this condition is detected. In a release
  515. //! build, the buffer read pointer will be advanced if too much data is written
  516. //! but this will, of course, result in some of the oldest data in the buffer
  517. //! being discarded and also, depending upon how data is being read from
  518. //! the buffer, may result in a race condition which could corrupt the read
  519. //! pointer.
  520. //!
  521. //! \return None.
  522. //
  523. //*****************************************************************************
  524. void
  525. USBRingBufAdvanceWrite(tUSBRingBufObject *ptUSBRingBuf,
  526. unsigned int ulNumBytes)
  527. {
  528. unsigned int ulCount;
  529. //
  530. // Check the arguments.
  531. //
  532. ASSERT(ptUSBRingBuf != NULL);
  533. //
  534. // Make sure we were not asked to add a silly number of bytes.
  535. //
  536. ASSERT(ulNumBytes <= ptUSBRingBuf->ulSize);
  537. //
  538. // Determine how much free space we currently think the buffer has.
  539. //
  540. ulCount = USBRingBufFree(ptUSBRingBuf);
  541. //
  542. // Check that the client has not added more data to the buffer than there
  543. // is space for. In this case, corruption may have occurred since the
  544. // buffer may have been read under interrupt context while the writer was
  545. // busy trashing the area around the read pointer.
  546. //
  547. ASSERT(ulCount >= ulNumBytes);
  548. //
  549. // Update the write pointer.
  550. //
  551. ptUSBRingBuf->ulWriteIndex += ulNumBytes;
  552. //
  553. // Check and correct for wrap.
  554. //
  555. if(ptUSBRingBuf->ulWriteIndex >= ptUSBRingBuf->ulSize)
  556. {
  557. ptUSBRingBuf->ulWriteIndex -= ptUSBRingBuf->ulSize;
  558. }
  559. //
  560. // Did the client add more bytes than the buffer had free space for? This
  561. // should be considered a bug since, unless this function is called in
  562. // the same context as the code which is reading from the buffer, writing
  563. // over the earliest data can cause corrupted data to be read. The
  564. // ASSERT above catches this in debug builds but, in release builds, we
  565. // go ahead and try to fix up the read pointer appropriately.
  566. //
  567. if(ulCount < ulNumBytes)
  568. {
  569. //
  570. // Yes - we need to advance the read pointer to ahead of the write
  571. // pointer to discard some of the oldest data.
  572. //
  573. ptUSBRingBuf->ulReadIndex = ptUSBRingBuf->ulWriteIndex + 1;
  574. //
  575. // Correct for buffer wrap if necessary.
  576. //
  577. if(ptUSBRingBuf->ulReadIndex >= ptUSBRingBuf->ulSize)
  578. {
  579. ptUSBRingBuf->ulReadIndex -= ptUSBRingBuf->ulSize;
  580. }
  581. }
  582. }
  583. //*****************************************************************************
  584. //
  585. //! Writes a single byte of data to a ring buffer.
  586. //!
  587. //! \param ptUSBRingBuf points to the ring buffer to be written to.
  588. //! \param ucData is the byte to be written.
  589. //!
  590. //! This function writes a single byte of data into a ring buffer.
  591. //!
  592. //! \return None.
  593. //
  594. //*****************************************************************************
  595. void
  596. USBRingBufWriteOne(tUSBRingBufObject *ptUSBRingBuf, unsigned char ucData)
  597. {
  598. //
  599. // Check the arguments.
  600. //
  601. ASSERT(ptUSBRingBuf != NULL);
  602. //
  603. // Verify that space is available in the buffer.
  604. //
  605. ASSERT(USBRingBufFree(ptUSBRingBuf) != 0);
  606. //
  607. // Write the data byte.
  608. //
  609. ptUSBRingBuf->pucBuf[ptUSBRingBuf->ulWriteIndex] = ucData;
  610. //
  611. // Increment the write index.
  612. //
  613. UpdateIndexAtomic(&ptUSBRingBuf->ulWriteIndex, 1, ptUSBRingBuf->ulSize);
  614. }
  615. //*****************************************************************************
  616. //
  617. //! Writes data to a ring buffer.
  618. //!
  619. //! \param ptUSBRingBuf points to the ring buffer to be written to.
  620. //! \param pucData points to the data to be written.
  621. //! \param ulLength is the number of bytes to be written.
  622. //!
  623. //! This function write a sequence of bytes into a ring buffer.
  624. //!
  625. //! \return None.
  626. //
  627. //*****************************************************************************
  628. void
  629. USBRingBufWrite(tUSBRingBufObject *ptUSBRingBuf, const unsigned char *pucData,
  630. unsigned int ulLength)
  631. {
  632. unsigned int ulTemp;
  633. //
  634. // Check the arguments.
  635. //
  636. ASSERT(ptUSBRingBuf != NULL);
  637. ASSERT(pucData != NULL);
  638. ASSERT(ulLength != 0);
  639. //
  640. // Verify that space is available in the buffer.
  641. //
  642. ASSERT(ulLength <= USBRingBufFree(ptUSBRingBuf));
  643. //
  644. // Write the data into the ring buffer.
  645. //
  646. for(ulTemp = 0; ulTemp < ulLength; ulTemp++)
  647. {
  648. USBRingBufWriteOne(ptUSBRingBuf, pucData[ulTemp]);
  649. }
  650. }
  651. //*****************************************************************************
  652. //
  653. //! Initializes a ring buffer object.
  654. //!
  655. //! \param ptUSBRingBuf points to the ring buffer to be initialized.
  656. //! \param pucBuf points to the data buffer to be used for the ring buffer.
  657. //! \param ulSize is the size of the buffer in bytes.
  658. //!
  659. //! This function initializes a ring buffer object, preparing it to store data.
  660. //!
  661. //! \return None.
  662. //
  663. //*****************************************************************************
  664. void
  665. USBRingBufInit(tUSBRingBufObject *ptUSBRingBuf, unsigned char *pucBuf,
  666. unsigned int ulSize)
  667. {
  668. //
  669. // Check the arguments.
  670. //
  671. ASSERT(ptUSBRingBuf != NULL);
  672. ASSERT(pucBuf != NULL);
  673. ASSERT(ulSize != 0);
  674. //
  675. // Initialize the ring buffer object.
  676. //
  677. ptUSBRingBuf->ulSize = ulSize;
  678. ptUSBRingBuf->pucBuf = pucBuf;
  679. ptUSBRingBuf->ulWriteIndex = ptUSBRingBuf->ulReadIndex = 0;
  680. }
  681. //*****************************************************************************
  682. //
  683. // Close the Doxygen group.
  684. //! @}
  685. //
  686. //*****************************************************************************