2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 2015, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #ifndef _IA_CSS_CIRCBUF_H
16 #define _IA_CSS_CIRCBUF_H
19 #include <type_support.h>
20 #include <math_support.h>
21 #include <storage_class.h>
22 #include <assert_support.h>
23 #include <platform_support.h>
24 #include "ia_css_circbuf_comm.h"
25 #include "ia_css_circbuf_desc.h"
27 /****************************************************************
31 ****************************************************************/
33 * @brief Data structure for the circular buffer.
35 typedef struct ia_css_circbuf_s ia_css_circbuf_t;
36 struct ia_css_circbuf_s {
37 ia_css_circbuf_desc_t *desc; /* Pointer to the descriptor of the circbuf */
38 ia_css_circbuf_elem_t *elems; /* an array of elements */
42 * @brief Create the circular buffer.
44 * @param cb The pointer to the circular buffer.
45 * @param elems An array of elements.
46 * @param desc The descriptor set to the size using ia_css_circbuf_desc_init().
48 STORAGE_CLASS_EXTERN void ia_css_circbuf_create(
50 ia_css_circbuf_elem_t *elems,
51 ia_css_circbuf_desc_t *desc);
54 * @brief Destroy the circular buffer.
56 * @param cb The pointer to the circular buffer.
58 STORAGE_CLASS_EXTERN void ia_css_circbuf_destroy(
59 ia_css_circbuf_t *cb);
62 * @brief Pop a value out of the circular buffer.
63 * Get a value at the head of the circular buffer.
64 * The user should call "ia_css_circbuf_is_empty()"
65 * to avoid accessing to an empty buffer.
67 * @param cb The pointer to the circular buffer.
69 * @return the pop-out value.
71 STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_pop(
72 ia_css_circbuf_t *cb);
75 * @brief Extract a value out of the circular buffer.
76 * Get a value at an arbitrary poistion in the circular
77 * buffer. The user should call "ia_css_circbuf_is_empty()"
78 * to avoid accessing to an empty buffer.
80 * @param cb The pointer to the circular buffer.
81 * @param offset The offset from "start" to the target position.
83 * @return the extracted value.
85 STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_extract(
89 /****************************************************************
93 ****************************************************************/
95 * @brief Set the "val" field in the element.
97 * @param elem The pointer to the element.
98 * @param val The value to be set.
100 STORAGE_CLASS_INLINE void ia_css_circbuf_elem_set_val(
101 ia_css_circbuf_elem_t *elem,
104 OP___assert(elem != NULL);
110 * @brief Initialize the element.
112 * @param elem The pointer to the element.
114 STORAGE_CLASS_INLINE void ia_css_circbuf_elem_init(
115 ia_css_circbuf_elem_t *elem)
117 OP___assert(elem != NULL);
118 ia_css_circbuf_elem_set_val(elem, 0);
122 * @brief Copy an element.
124 * @param src The element as the copy source.
125 * @param dest The element as the copy destination.
127 STORAGE_CLASS_INLINE void ia_css_circbuf_elem_cpy(
128 ia_css_circbuf_elem_t *src,
129 ia_css_circbuf_elem_t *dest)
131 OP___assert(src != NULL);
132 OP___assert(dest != NULL);
134 ia_css_circbuf_elem_set_val(dest, src->val);
138 * @brief Get position in the circular buffer.
140 * @param cb The pointer to the circular buffer.
141 * @param base The base position.
142 * @param offset The offset.
144 * @return the position at offset.
146 STORAGE_CLASS_INLINE uint8_t ia_css_circbuf_get_pos_at_offset(
147 ia_css_circbuf_t *cb,
153 OP___assert(cb != NULL);
154 OP___assert(cb->desc != NULL);
155 OP___assert(cb->desc->size > 0);
157 /* step 1: adjudst the offset */
159 offset += cb->desc->size;
162 /* step 2: shift and round by the upper limit */
163 dest = OP_std_modadd(base, offset, cb->desc->size);
169 * @brief Get the offset between two positions in the circular buffer.
170 * Get the offset from the source position to the terminal position,
171 * along the direction in which the new elements come in.
173 * @param cb The pointer to the circular buffer.
174 * @param src_pos The source position.
175 * @param dest_pos The terminal position.
177 * @return the offset.
179 STORAGE_CLASS_INLINE int ia_css_circbuf_get_offset(
180 ia_css_circbuf_t *cb,
186 OP___assert(cb != NULL);
187 OP___assert(cb->desc != NULL);
189 offset = (int)(dest_pos - src_pos);
190 offset += (offset < 0) ? cb->desc->size : 0;
196 * @brief Get the maximum number of elements.
198 * @param cb The pointer to the circular buffer.
200 * @return the maximum number of elements.
202 * TODO: Test this API.
204 STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_size(
205 ia_css_circbuf_t *cb)
207 OP___assert(cb != NULL);
208 OP___assert(cb->desc != NULL);
210 return cb->desc->size;
214 * @brief Get the number of available elements.
216 * @param cb The pointer to the circular buffer.
218 * @return the number of available elements.
220 STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_num_elems(
221 ia_css_circbuf_t *cb)
225 OP___assert(cb != NULL);
226 OP___assert(cb->desc != NULL);
228 num = ia_css_circbuf_get_offset(cb, cb->desc->start, cb->desc->end);
230 return (uint32_t)num;
234 * @brief Test if the circular buffer is empty.
236 * @param cb The pointer to the circular buffer.
239 * - true when it is empty.
240 * - false when it is not empty.
242 STORAGE_CLASS_INLINE bool ia_css_circbuf_is_empty(
243 ia_css_circbuf_t *cb)
245 OP___assert(cb != NULL);
246 OP___assert(cb->desc != NULL);
248 return ia_css_circbuf_desc_is_empty(cb->desc);
252 * @brief Test if the circular buffer is full.
254 * @param cb The pointer to the circular buffer.
257 * - true when it is full.
258 * - false when it is not full.
260 STORAGE_CLASS_INLINE bool ia_css_circbuf_is_full(ia_css_circbuf_t *cb)
262 OP___assert(cb != NULL);
263 OP___assert(cb->desc != NULL);
265 return ia_css_circbuf_desc_is_full(cb->desc);
269 * @brief Write a new element into the circular buffer.
270 * Write a new element WITHOUT checking whether the
271 * circular buffer is full or not. So it also overwrites
272 * the oldest element when the buffer is full.
274 * @param cb The pointer to the circular buffer.
275 * @param elem The new element.
277 STORAGE_CLASS_INLINE void ia_css_circbuf_write(
278 ia_css_circbuf_t *cb,
279 ia_css_circbuf_elem_t elem)
281 OP___assert(cb != NULL);
282 OP___assert(cb->desc != NULL);
284 /* Cannot continue as the queue is full*/
285 assert(!ia_css_circbuf_is_full(cb));
287 ia_css_circbuf_elem_cpy(&elem, &cb->elems[cb->desc->end]);
289 cb->desc->end = ia_css_circbuf_get_pos_at_offset(cb, cb->desc->end, 1);
293 * @brief Push a value in the circular buffer.
294 * Put a new value at the tail of the circular buffer.
295 * The user should call "ia_css_circbuf_is_full()"
296 * to avoid accessing to a full buffer.
298 * @param cb The pointer to the circular buffer.
299 * @param val The value to be pushed in.
301 STORAGE_CLASS_INLINE void ia_css_circbuf_push(
302 ia_css_circbuf_t *cb,
305 ia_css_circbuf_elem_t elem;
307 OP___assert(cb != NULL);
309 /* set up an element */
310 ia_css_circbuf_elem_init(&elem);
311 ia_css_circbuf_elem_set_val(&elem, val);
313 /* write the element into the buffer */
314 ia_css_circbuf_write(cb, elem);
318 * @brief Get the number of free elements.
320 * @param cb The pointer to the circular buffer.
322 * @return: The number of free elements.
324 STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_free_elems(
325 ia_css_circbuf_t *cb)
327 OP___assert(cb != NULL);
328 OP___assert(cb->desc != NULL);
330 return ia_css_circbuf_desc_get_free_elems(cb->desc);
334 * @brief Peek an element in Circular Buffer.
336 * @param cb The pointer to the circular buffer.
337 * @param offset Offset to the element.
339 * @return the elements value.
341 STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek(
342 ia_css_circbuf_t *cb,
346 * @brief Get an element in Circular Buffer.
348 * @param cb The pointer to the circular buffer.
349 * @param offset Offset to the element.
351 * @return the elements value.
353 STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek_from_start(
354 ia_css_circbuf_t *cb,
358 * @brief Increase Size of a Circular Buffer.
359 * Use 'CAUTION' before using this function, This was added to
360 * support / fix issue with increasing size for tagger only
362 * @param cb The pointer to the circular buffer.
363 * @param sz_delta delta increase for new size
364 * @param elems (optional) pointers to new additional elements
365 * cb element array size will not be increased dynamically,
366 * but new elements should be added at the end to existing
367 * cb element array which if of max_size >= new size
369 * @return true on succesfully increasing the size
372 STORAGE_CLASS_EXTERN bool ia_css_circbuf_increase_size(
373 ia_css_circbuf_t *cb,
374 unsigned int sz_delta,
375 ia_css_circbuf_elem_t *elems);
377 #endif /*_IA_CSS_CIRCBUF_H */