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);
 | 
						|
}
 |