Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers circ_buf.c Source File

circ_buf.c

00001 /**
00002  * @file    circular_buffer.c
00003  * @brief   Implementation of a circular buffer
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2016-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "circ_buf.h"
00023 
00024 #include "cortex_m.h"
00025 #include "util.h"
00026 
00027 void circ_buf_init(circ_buf_t *circ_buf, uint8_t *buffer, uint32_t size)
00028 {
00029     cortex_int_state_t state;
00030     state = cortex_int_get_and_disable();
00031 
00032     circ_buf->buf = buffer;
00033     circ_buf->size = size;
00034     circ_buf->head = 0;
00035     circ_buf->tail = 0;
00036 
00037     cortex_int_restore(state);
00038 }
00039 
00040 void circ_buf_push(circ_buf_t *circ_buf, uint8_t data)
00041 {
00042     cortex_int_state_t state;
00043     state = cortex_int_get_and_disable();
00044 
00045     circ_buf->buf[circ_buf->tail] = data;
00046     circ_buf->tail += 1;
00047     if (circ_buf->tail >= circ_buf->size) {
00048         util_assert(circ_buf->tail == circ_buf->size);
00049         circ_buf->tail = 0;
00050     }
00051 
00052     // Assert no overflow
00053     util_assert(circ_buf->head != circ_buf->tail);
00054 
00055     cortex_int_restore(state);
00056 }
00057 
00058 uint8_t circ_buf_pop(circ_buf_t *circ_buf)
00059 {
00060     uint8_t data;
00061     cortex_int_state_t state;
00062 
00063     state = cortex_int_get_and_disable();
00064 
00065     // Assert buffer isn't empty
00066     util_assert(circ_buf->head != circ_buf->tail);
00067 
00068     data = circ_buf->buf[circ_buf->head];
00069     circ_buf->head += 1;
00070     if (circ_buf->head >= circ_buf->size) {
00071         util_assert(circ_buf->head == circ_buf->size);
00072         circ_buf->head = 0;
00073     }
00074 
00075     cortex_int_restore(state);
00076 
00077     return data;
00078 }
00079 
00080 uint32_t circ_buf_count_used(circ_buf_t *circ_buf)
00081 {
00082     uint32_t cnt;
00083     cortex_int_state_t state;
00084 
00085     state = cortex_int_get_and_disable();
00086 
00087     if (circ_buf->tail >= circ_buf->head) {
00088         cnt = circ_buf->tail - circ_buf->head;
00089     } else {
00090         cnt = circ_buf->tail + circ_buf->size - circ_buf->head;
00091     }
00092 
00093     cortex_int_restore(state);
00094     return cnt;
00095 }
00096 
00097 uint32_t circ_buf_count_free(circ_buf_t *circ_buf)
00098 {
00099     uint32_t cnt;
00100     cortex_int_state_t state;
00101 
00102     state = cortex_int_get_and_disable();
00103 
00104     cnt = circ_buf->size - circ_buf_count_used(circ_buf) - 1;
00105 
00106     cortex_int_restore(state);
00107     return cnt;
00108 }
00109 
00110 uint32_t circ_buf_read(circ_buf_t *circ_buf, uint8_t *data, uint32_t size)
00111 {
00112     uint32_t cnt;
00113     uint32_t i;
00114 
00115     cnt = circ_buf_count_used(circ_buf);
00116     cnt = MIN(size, cnt);
00117     for (i = 0; i < cnt; i++) {
00118         data[i] = circ_buf_pop(circ_buf);
00119     }
00120 
00121     return cnt;
00122 }
00123 
00124 uint32_t circ_buf_write(circ_buf_t *circ_buf, const uint8_t *data, uint32_t size)
00125 {
00126     uint32_t cnt;
00127     uint32_t i;
00128 
00129     cnt = circ_buf_count_free(circ_buf);
00130     cnt = MIN(size, cnt);
00131     for (i = 0; i < cnt; i++) {
00132         circ_buf_push(circ_buf, data[i]);
00133     }
00134 
00135     return cnt;
00136 }