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