cbuf.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file cbuf interface
  8. */
  9. #include <kernel.h>
  10. #include "cbuf.h"
  11. #include <string.h>
  12. int cbuf_read(cbuf_t *cbuf, void *buffer, int32_t len)
  13. {
  14. int32_t read_len = len;
  15. int32_t copy_len;
  16. uint32_t flags;
  17. if(!cbuf){
  18. return 0;
  19. }
  20. if(cbuf->length < len){
  21. return 0;
  22. }
  23. if(cbuf->read_ptr >= cbuf->capacity){
  24. cbuf->read_ptr = 0;
  25. }
  26. //buffer is null only change read ptr and length
  27. if(!buffer){
  28. flags = irq_lock();
  29. cbuf->read_ptr += len;
  30. if (cbuf->capacity != 0){
  31. cbuf->read_ptr %= cbuf->capacity;
  32. }
  33. cbuf->length -= len;
  34. irq_unlock(flags);
  35. return len;
  36. }
  37. copy_len = cbuf->capacity - cbuf->read_ptr;
  38. if(copy_len > len){
  39. copy_len = len;
  40. }
  41. len -= copy_len;
  42. memcpy(buffer, cbuf->raw_data + cbuf->read_ptr, copy_len);
  43. if(len == 0){
  44. cbuf->read_ptr += copy_len;
  45. }else{
  46. memcpy((uint8_t *)buffer + copy_len, cbuf->raw_data, len);
  47. cbuf->read_ptr = len;
  48. }
  49. flags = irq_lock();
  50. cbuf->length -= read_len;
  51. irq_unlock(flags);
  52. return read_len;
  53. }
  54. int cbuf_dma_read(cbuf_t *cbuf, cbuf_dma_t *dma, int32_t read_len)
  55. {
  56. uint32_t copy_len;
  57. if(!cbuf){
  58. goto ret;
  59. }
  60. if(cbuf->length < read_len){
  61. read_len = cbuf->length;
  62. goto ret;
  63. }
  64. if(cbuf->read_ptr >= cbuf->capacity){
  65. cbuf->read_ptr = 0;
  66. }
  67. copy_len = cbuf->capacity - cbuf->read_ptr;
  68. if(copy_len > read_len){
  69. copy_len = read_len;
  70. }
  71. dma->read_len = copy_len;
  72. dma->start_addr = cbuf->raw_data + cbuf->read_ptr;
  73. return read_len;
  74. ret:
  75. dma->read_len = 0;
  76. return 0;
  77. }
  78. int cbuf_dma_update_read_ptr(cbuf_t *cbuf, int32_t read_len)
  79. {
  80. uint32_t flags;
  81. flags = irq_lock();
  82. cbuf->read_ptr += read_len;
  83. cbuf->length -= read_len;
  84. irq_unlock(flags);
  85. return 0;
  86. }
  87. int cbuf_prepare_read(cbuf_t *cbuf, void *buffer, int32_t len)
  88. {
  89. int32_t read_len = len;
  90. int32_t copy_len;
  91. if(!cbuf){
  92. return 0;
  93. }
  94. if(cbuf->length < len){
  95. return 0;
  96. }
  97. if(!buffer){
  98. return 0;
  99. }
  100. if(cbuf->read_ptr >= cbuf->capacity){
  101. cbuf->read_ptr = 0;
  102. }
  103. copy_len = cbuf->capacity - cbuf->read_ptr;
  104. if(copy_len > len){
  105. copy_len = len;
  106. }
  107. len -= copy_len;
  108. memcpy(buffer, cbuf->raw_data + cbuf->read_ptr, copy_len);
  109. if(len){
  110. memcpy((uint8_t *)buffer + copy_len, cbuf->raw_data, len);
  111. }
  112. return read_len;
  113. }
  114. int cbuf_write(cbuf_t *cbuf, void *buffer, int32_t len)
  115. {
  116. uint32_t write_len;
  117. uint32_t rem_len;
  118. uint32_t flags;
  119. if((!cbuf) || (len == 0) || (len > cbuf->capacity)){
  120. return 0;
  121. }
  122. if((cbuf->capacity - cbuf->length) < len){
  123. return 0;
  124. }
  125. if(cbuf->write_ptr >= cbuf->capacity){
  126. cbuf->write_ptr = 0;
  127. }
  128. write_len = cbuf->capacity - cbuf->write_ptr;
  129. if(write_len >= len){
  130. memcpy(cbuf->raw_data + cbuf->write_ptr, buffer, len);
  131. cbuf->write_ptr += len;
  132. }else{
  133. rem_len = len - write_len;
  134. memcpy(cbuf->raw_data + cbuf->write_ptr, buffer, write_len);
  135. memcpy(cbuf->raw_data, (uint8_t *)buffer + write_len, rem_len);
  136. cbuf->write_ptr = rem_len;
  137. }
  138. flags = irq_lock();
  139. cbuf->length += len;
  140. irq_unlock(flags);
  141. return len;
  142. }
  143. void cbuf_init(cbuf_t *cbuf, void *buffer, int32_t size)
  144. {
  145. uint32_t flags;
  146. flags = irq_lock();
  147. cbuf->raw_data = buffer;
  148. cbuf->capacity = size;
  149. cbuf->write_ptr = 0;
  150. cbuf->read_ptr = 0;
  151. cbuf->length = 0;
  152. irq_unlock(flags);
  153. }
  154. void cbuf_reset(cbuf_t *cbuf)
  155. {
  156. uint32_t flags;
  157. flags = irq_lock();
  158. cbuf->write_ptr = 0;
  159. cbuf->read_ptr = 0;
  160. cbuf->length = 0;
  161. irq_unlock(flags);
  162. }
  163. void cbuf_copy_write_ptr(cbuf_t *src, cbuf_t *dest, uint32_t len)
  164. {
  165. uint32_t flags;
  166. flags = irq_lock();
  167. dest->write_ptr = src->write_ptr;
  168. dest->length += len;
  169. irq_unlock(flags);
  170. }
  171. void cbuf_deinit(cbuf_t *cbuf)
  172. {
  173. memset(cbuf, 0, sizeof(cbuf_t));
  174. }