ring_buf.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /**
  2. *******************************************************************************
  3. * @file usart/usart_uart_int/source/ring_buf.c
  4. * @brief This file provides firmware functions to manage the ring buffer.
  5. @verbatim
  6. Change Logs:
  7. Date Author Notes
  8. 2022-12-31 CDT First version
  9. @endverbatim
  10. *******************************************************************************
  11. * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
  12. *
  13. * This software component is licensed by XHSC under BSD 3-Clause license
  14. * (the "License"); You may not use this file except in compliance with the
  15. * License. You may obtain a copy of the License at:
  16. * opensource.org/licenses/BSD-3-Clause
  17. *
  18. *******************************************************************************
  19. */
  20. /*******************************************************************************
  21. * Include files
  22. ******************************************************************************/
  23. #include <string.h>
  24. #include "ring_buf.h"
  25. #include "hc32_ll_utility.h"
  26. /**
  27. * @addtogroup USART_UART_Interrupt
  28. * @{
  29. */
  30. /**
  31. * @defgroup Ring_Buffer Ring Buffer
  32. * @{
  33. */
  34. /*******************************************************************************
  35. * Local type definitions ('typedef')
  36. ******************************************************************************/
  37. /*******************************************************************************
  38. * Local pre-processor symbols/macros ('#define')
  39. ******************************************************************************/
  40. /*******************************************************************************
  41. * Global variable definitions (declared in header file with 'extern')
  42. ******************************************************************************/
  43. /*******************************************************************************
  44. * Local function prototypes ('static')
  45. ******************************************************************************/
  46. /*******************************************************************************
  47. * Local variable definitions ('static')
  48. ******************************************************************************/
  49. /*******************************************************************************
  50. * Function implementation - global ('extern') and local ('static')
  51. ******************************************************************************/
  52. /**
  53. * @defgroup Ring_Buffer_Global_Functions Ring Buffer Global Functions
  54. * @{
  55. */
  56. /**
  57. * @brief Initialize ring buffer.
  58. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  59. * @param [in] pu8Data Data buffer
  60. * @param [in] u32Size Data buffer size
  61. * @retval int32_t:
  62. * - LL_OK: Initialize successfully.
  63. * - LL_ERR_INVD_PARAM: If one of following cases matches:
  64. * - The pointer pstcBuf value is NULL.
  65. * - The pointer pu8Data value is NULL.
  66. * - The u32Size value is 0.
  67. */
  68. int32_t BUF_Init(stc_ring_buf_t *pstcBuf, uint8_t *pu8Data, uint32_t u32Size)
  69. {
  70. int32_t i32Ret = LL_ERR_INVD_PARAM;
  71. if ((pstcBuf != NULL) && (pu8Data != NULL) && (u32Size != 0UL)) {
  72. pstcBuf->pu8Data = pu8Data;
  73. pstcBuf->u32In = 0;
  74. pstcBuf->u32Out = 0;
  75. pstcBuf->u32Size = u32Size;
  76. pstcBuf->u32FreeSize = u32Size;
  77. i32Ret = LL_OK;
  78. }
  79. return i32Ret;
  80. }
  81. /**
  82. * @brief Ring buffer free size.
  83. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  84. * @retval Ring buffer free size
  85. */
  86. uint32_t BUF_FreeSize(const stc_ring_buf_t *pstcBuf)
  87. {
  88. return pstcBuf->u32FreeSize;
  89. }
  90. /**
  91. * @brief Ring buffer used size.
  92. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  93. * @retval Ring buffer used size
  94. */
  95. uint32_t BUF_UsedSize(const stc_ring_buf_t *pstcBuf)
  96. {
  97. return (pstcBuf->u32Size - pstcBuf->u32FreeSize);
  98. }
  99. /**
  100. * @brief Ring buffer full.
  101. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  102. * @retval Ring buffer status
  103. */
  104. bool BUF_Full(const stc_ring_buf_t *pstcBuf)
  105. {
  106. return (0UL == pstcBuf->u32FreeSize);
  107. }
  108. /**
  109. * @brief Check ring buffer empty.
  110. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  111. * @retval Ring buffer status
  112. */
  113. bool BUF_Empty(const stc_ring_buf_t *pstcBuf)
  114. {
  115. return (pstcBuf->u32Size == pstcBuf->u32FreeSize);
  116. }
  117. /**
  118. * @brief Read ring buffer.
  119. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  120. * @param [in] au8Data Pointer to data buffer to read
  121. * @param [in] u32Len Data length
  122. * @retval Read length
  123. */
  124. uint32_t BUF_Read(stc_ring_buf_t *pstcBuf, uint8_t au8Data[], uint32_t u32Len)
  125. {
  126. uint32_t u32CopyLen;
  127. uint32_t u32ReadLen = 0UL;
  128. if ((pstcBuf != NULL) && (au8Data != NULL) && (u32Len != 0UL)) {
  129. u32ReadLen = BUF_UsedSize(pstcBuf);
  130. if (u32ReadLen >= u32Len) {
  131. u32ReadLen = u32Len;
  132. }
  133. if (pstcBuf->u32Out + u32ReadLen <= pstcBuf->u32Size) {
  134. (void)memcpy(au8Data, &pstcBuf->pu8Data[pstcBuf->u32Out], u32ReadLen);
  135. } else {
  136. u32CopyLen = pstcBuf->u32Size - pstcBuf->u32Out;
  137. (void)memcpy(&au8Data[0], &pstcBuf->pu8Data[pstcBuf->u32Out], u32CopyLen);
  138. (void)memcpy(&au8Data[u32CopyLen], &pstcBuf->pu8Data[0], u32ReadLen - u32CopyLen);
  139. }
  140. __disable_irq();
  141. pstcBuf->u32FreeSize += u32ReadLen;
  142. pstcBuf->u32Out += u32ReadLen;
  143. if (pstcBuf->u32Out >= pstcBuf->u32Size) {
  144. pstcBuf->u32Out %= pstcBuf->u32Size;
  145. }
  146. __enable_irq();
  147. }
  148. return u32ReadLen;
  149. }
  150. /**
  151. * @brief Write ring buffer.
  152. * @param [in] pstcBuf Pointer to a @ref stc_ring_buf_t structure
  153. * @param [in] au8Data Pointer to data buffer to write
  154. * @param [in] u32Len Data length
  155. * @retval Write length
  156. */
  157. uint32_t BUF_Write(stc_ring_buf_t *pstcBuf, uint8_t au8Data[], uint32_t u32Len)
  158. {
  159. uint32_t u32CopyLen;
  160. uint32_t u32WriteLen = 0UL;
  161. if ((pstcBuf != NULL) && (au8Data != NULL) && (u32Len != 0UL)) {
  162. u32WriteLen = BUF_FreeSize(pstcBuf);
  163. if (u32Len <= u32WriteLen) {
  164. u32WriteLen = u32Len;
  165. }
  166. if (pstcBuf->u32In + u32WriteLen <= pstcBuf->u32Size) {
  167. (void)memcpy(&pstcBuf->pu8Data[pstcBuf->u32In], au8Data, u32WriteLen);
  168. } else {
  169. u32CopyLen = pstcBuf->u32Size - pstcBuf->u32In;
  170. (void)memcpy(&pstcBuf->pu8Data[pstcBuf->u32In], &au8Data[0], u32CopyLen);
  171. (void)memcpy(&pstcBuf->pu8Data[0], &au8Data[u32CopyLen], u32WriteLen - u32CopyLen);
  172. }
  173. __disable_irq();
  174. pstcBuf->u32FreeSize -= u32WriteLen;
  175. pstcBuf->u32In += u32WriteLen;
  176. if (pstcBuf->u32In >= pstcBuf->u32Size) {
  177. pstcBuf->u32In %= pstcBuf->u32Size;
  178. }
  179. __enable_irq();
  180. }
  181. return u32WriteLen;
  182. }
  183. /**
  184. * @}
  185. */
  186. /**
  187. * @}
  188. */
  189. /**
  190. * @}
  191. */
  192. /*******************************************************************************
  193. * EOF (not truncated)
  194. ******************************************************************************/