169 lines
4.2 KiB
C
169 lines
4.2 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
|
||
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
|
be copied by any method or incorporated into another program without
|
||
|
the express written consent of Aerospace C.Power. This Information or any portion
|
||
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
|
liability for its use in any way and conveys no license or title under
|
||
|
any patent or copyright and makes no representation or warranty that this
|
||
|
Information is free from patent or copyright infringement.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
/* os shim includes */
|
||
|
#include "os_types.h"
|
||
|
|
||
|
#include "iot_ringbuf.h"
|
||
|
|
||
|
void iot_ringbuf_init(struct ringbuf *r, uint8_t *dataptr, uint32_t size)
|
||
|
{
|
||
|
r->data = dataptr;
|
||
|
r->mask = size - 1;
|
||
|
r->put_ptr = 0;
|
||
|
r->get_ptr = 0;
|
||
|
}
|
||
|
|
||
|
uint32_t IRAM_ATTR iot_get_ring_pos(int32_t pos, struct ringbuf *r)
|
||
|
{
|
||
|
uint32_t value = 0;
|
||
|
if (pos < 0)
|
||
|
value = iot_ringbuf_size(r) + pos;
|
||
|
else if ((uint32_t)pos > r->mask)
|
||
|
value = pos - iot_ringbuf_size(r);
|
||
|
else
|
||
|
value = pos;
|
||
|
if (value > (uint32_t)iot_ringbuf_size(r)){
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
int IRAM_ATTR iot_ringbuf_put(struct ringbuf *r, uint8_t c)
|
||
|
{
|
||
|
/* Check if buffer is full. If it is full, return 0 to indicate that
|
||
|
the element was not inserted into the buffer.
|
||
|
*/
|
||
|
if (iot_ringbuf_elements(r) == r->mask) {
|
||
|
return 0;
|
||
|
}
|
||
|
r->data[r->put_ptr] = c;
|
||
|
r->put_ptr = iot_get_ring_pos(r->put_ptr + 1, r);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int IRAM_ATTR iot_ringbuf_get(struct ringbuf *r)
|
||
|
{
|
||
|
uint8_t c;
|
||
|
|
||
|
/* Check if there are bytes in the buffer. If so, we return the
|
||
|
first one and increase the pointer. If there are no bytes left, we
|
||
|
return -1.
|
||
|
*/
|
||
|
if (iot_ringbuf_elements(r) > 0) {
|
||
|
c = r->data[r->get_ptr];
|
||
|
r->get_ptr = iot_get_ring_pos(r->get_ptr + 1, r);
|
||
|
return c;
|
||
|
} else {
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t iot_ringbuf_gets(struct ringbuf *r, uint8_t *seq, uint32_t len)
|
||
|
{
|
||
|
int c;
|
||
|
uint32_t i = 0;
|
||
|
IOT_ASSERT(seq);
|
||
|
|
||
|
if (!seq)
|
||
|
return 0;
|
||
|
|
||
|
while(i < len){
|
||
|
c = iot_ringbuf_get(r);
|
||
|
if(c < 0 ){
|
||
|
break;
|
||
|
}
|
||
|
*(seq+i) = (uint8_t)c;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
uint32_t iot_ringbuf_drop(struct ringbuf *r, uint32_t len)
|
||
|
{
|
||
|
uint32_t move_len;
|
||
|
|
||
|
if (len > 0){
|
||
|
move_len = len > iot_ringbuf_elements(r) ?
|
||
|
iot_ringbuf_elements(r) : len;
|
||
|
|
||
|
r->get_ptr = iot_get_ring_pos(r->get_ptr + move_len, r);
|
||
|
return move_len;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint32_t iot_ringbuf_puts(struct ringbuf *r, uint8_t *seq, uint32_t len)
|
||
|
{
|
||
|
uint8_t c;
|
||
|
uint32_t i = 0;
|
||
|
|
||
|
while(i < len){
|
||
|
c = *(seq+i);
|
||
|
if(iot_ringbuf_put(r, c) == 0){
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
uint32_t iot_ringbuf_offset_add(ringbuf_t *r, uint32_t origin_pos,
|
||
|
uint32_t add)
|
||
|
{
|
||
|
IOT_ASSERT(origin_pos <= r->mask);
|
||
|
return iot_get_ring_pos(origin_pos + add, r);
|
||
|
}
|
||
|
|
||
|
uint32_t iot_ringbuf_dummy_gets(ringbuf_t *r, uint8_t *buf,
|
||
|
uint32_t len, uint32_t pos)
|
||
|
{
|
||
|
int c;
|
||
|
uint32_t i = 0, get_dummy;
|
||
|
IOT_ASSERT(buf);
|
||
|
if (!buf || pos > r->mask)
|
||
|
return 0;
|
||
|
if (iot_get_ring_pos(pos - r->get_ptr, r) >
|
||
|
iot_get_ring_pos(r->put_ptr - r->get_ptr, r))
|
||
|
get_dummy = r->get_ptr;
|
||
|
else
|
||
|
get_dummy = pos;
|
||
|
/* check if there are bytes in the buffer. If so, we return the
|
||
|
* first one and increase the pointer.
|
||
|
*/
|
||
|
while (i < len && get_dummy != r->put_ptr) {
|
||
|
c = r->data[get_dummy];
|
||
|
get_dummy = iot_get_ring_pos((get_dummy + 1), r);
|
||
|
buf[i] = (uint8_t)c;
|
||
|
i++;
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
int IRAM_ATTR iot_ringbuf_size(struct ringbuf *r)
|
||
|
{
|
||
|
return r->mask + 1;
|
||
|
}
|
||
|
|
||
|
uint32_t IRAM_ATTR iot_ringbuf_elements(struct ringbuf *r)
|
||
|
{
|
||
|
if (r->put_ptr >= r->get_ptr)
|
||
|
return r->put_ptr - r->get_ptr;
|
||
|
else
|
||
|
return iot_ringbuf_size(r) - (r->get_ptr - r->put_ptr);
|
||
|
}
|