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