ring_buffer.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * @brief Common ring buffer support functions
  3. *
  4. * @note
  5. * Copyright(C) NXP Semiconductors, 2012
  6. * All rights reserved.
  7. *
  8. * @par
  9. * Software that is described herein is for illustrative purposes only
  10. * which provides customers with programming information regarding the
  11. * LPC products. This software is supplied "AS IS" without any warranties of
  12. * any kind, and NXP Semiconductors and its licensor disclaim any and
  13. * all warranties, express or implied, including all implied warranties of
  14. * merchantability, fitness for a particular purpose and non-infringement of
  15. * intellectual property rights. NXP Semiconductors assumes no responsibility
  16. * or liability for the use of the software, conveys no license or rights under any
  17. * patent, copyright, mask work right, or any other intellectual property rights in
  18. * or to any products. NXP Semiconductors reserves the right to make changes
  19. * in the software without notification. NXP Semiconductors also makes no
  20. * representation or warranty that such application will be suitable for the
  21. * specified use without further testing or modification.
  22. *
  23. * @par
  24. * Permission to use, copy, modify, and distribute this software and its
  25. * documentation is hereby granted, under NXP Semiconductors' and its
  26. * licensor's relevant copyrights in the software, without fee, provided that it
  27. * is used in conjunction with NXP Semiconductors microcontrollers. This
  28. * copyright, permission, and disclaimer notice must appear in all copies of
  29. * this code.
  30. */
  31. #include "ring_buffer.h"
  32. int32_t RingBuf_Init(ring_buffer_t* pRB, uint8_t* buffer, uint32_t size )
  33. {
  34. pRB->pBuf = (uint8_t*)buffer;
  35. pRB->size = size;
  36. pRB->rNdx = 0;
  37. pRB->wNdx = 0;
  38. pRB->cnt = 0;
  39. return 0;
  40. }
  41. int32_t RingBuf_Deinit(ring_buffer_t* pRB )
  42. {
  43. pRB = pRB;;
  44. return 0;
  45. }
  46. int32_t RingBuf_GetFreeBytes(ring_buffer_t* pRB )
  47. {
  48. return pRB->size - pRB->cnt;
  49. }
  50. int32_t RingBuf_GetUsedBytes(ring_buffer_t* pRB)
  51. {
  52. return pRB->cnt;
  53. }
  54. int32_t RingBuf_Write(ring_buffer_t* pRB, const uint8_t* data, uint32_t dataBytes)
  55. {
  56. uint32_t writeToEnd, bytesToCopy;
  57. INIT_CRITICAL();
  58. ENTER_CRITICAL();
  59. /* Calculate the maximum amount we can copy */
  60. writeToEnd = pRB->size - pRB->wNdx;
  61. bytesToCopy = MIN(dataBytes, pRB->size - pRB->cnt);
  62. if (bytesToCopy != 0)
  63. {
  64. /* Copy as much as we can until we fall off the end of the buffer */
  65. memcpy(&pRB->pBuf[pRB->wNdx], data, MIN(bytesToCopy, writeToEnd));
  66. /* Check if we have more to copy to the front of the buffer */
  67. if (writeToEnd < bytesToCopy)
  68. {
  69. memcpy(pRB->pBuf, data + writeToEnd, bytesToCopy - writeToEnd);
  70. }
  71. /* Update the wNdx */
  72. pRB->wNdx = (pRB->wNdx + bytesToCopy) % pRB->size;
  73. pRB->cnt += dataBytes;
  74. }
  75. LEAVE_CRITICAL();
  76. return bytesToCopy;
  77. }
  78. int32_t RingBuf_Write1Byte(ring_buffer_t* pRB, const uint8_t *pcData)
  79. {
  80. uint32_t ret = 0;
  81. INIT_CRITICAL();
  82. ENTER_CRITICAL();
  83. if (pRB->cnt < pRB->size)
  84. {
  85. pRB->pBuf[pRB->wNdx] = pcData[0];
  86. pRB->wNdx = (pRB->wNdx + 1) % pRB->size;
  87. pRB->cnt++;
  88. ret = 1;
  89. }
  90. LEAVE_CRITICAL();
  91. return ret;
  92. }
  93. int32_t _prvRingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes, uint32_t isToFree)
  94. {
  95. uint32_t readToEnd, bytesToCopy;
  96. INIT_CRITICAL();
  97. ENTER_CRITICAL();
  98. readToEnd = pRB->size - pRB->rNdx;
  99. bytesToCopy = MIN(dataBytes, pRB->cnt);
  100. if (bytesToCopy != 0)
  101. {
  102. memcpy(data, &pRB->pBuf[pRB->rNdx], MIN(bytesToCopy, readToEnd));
  103. if (readToEnd < bytesToCopy)
  104. memcpy(data + readToEnd, &pRB->pBuf[0], bytesToCopy - readToEnd);
  105. if (isToFree)
  106. {
  107. pRB->rNdx = (pRB->rNdx + bytesToCopy) % pRB->size;
  108. pRB->cnt -= bytesToCopy;
  109. }
  110. }
  111. LEAVE_CRITICAL();
  112. return bytesToCopy;
  113. }
  114. int32_t RingBuf_Read(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
  115. {
  116. return _prvRingBuf_Read(pRB, data, dataBytes, 1);
  117. }
  118. int32_t RingBuf_Copy(ring_buffer_t* pRB, uint8_t* data, uint32_t dataBytes)
  119. {
  120. return _prvRingBuf_Read(pRB, data, dataBytes, 0);
  121. }
  122. int32_t RingBuf_Read1Byte(ring_buffer_t* pRB, uint8_t *pData)
  123. {
  124. uint32_t ret = 0;
  125. INIT_CRITICAL();
  126. ENTER_CRITICAL();
  127. if (pRB->cnt != 0)
  128. {
  129. pData[0] = pRB->pBuf[pRB->rNdx];
  130. pRB->rNdx = (pRB->rNdx + 1) % pRB->size;
  131. pRB->cnt--;
  132. ret = 1;
  133. }
  134. LEAVE_CRITICAL();
  135. return ret;
  136. }
  137. int32_t RingBuf_Peek(ring_buffer_t* pRB, uint8_t **ppData)
  138. {
  139. uint32_t readToEnd = pRB->size - pRB->rNdx;
  140. uint32_t contiguousBytes;
  141. *ppData = &(pRB->pBuf[pRB->rNdx]);
  142. contiguousBytes = MIN(readToEnd, (readToEnd + pRB->wNdx) % pRB->size);
  143. return contiguousBytes;
  144. }
  145. int32_t RingBuf_Free(ring_buffer_t* pRB, uint32_t bytesToFree)
  146. {
  147. INIT_CRITICAL();
  148. ENTER_CRITICAL();
  149. pRB->rNdx = (pRB->rNdx + bytesToFree) % pRB->size;
  150. pRB->cnt -= bytesToFree;
  151. LEAVE_CRITICAL();
  152. return bytesToFree;
  153. }