Added a really tiny USB device reset tool
[cerebrum.git] / msp / fifo.c
bloba9fa9d3dde8b5db92947d8583c88e63d3b83dbc0
1 /*
2 * Copyright (c) 2012, Alexander I. Mykyta
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 /*==================================================================================================
27 * File History:
28 * NAME DATE COMMENTS
29 * Alex M. 04/07/2011 born
31 *=================================================================================================*/
33 /**
34 * \addtogroup MOD_FIFO
35 * \{
36 **/
38 /**
39 * \file
40 * \brief Code for \ref MOD_FIFO "FIFO Datapipe"
41 * \author Alex Mykyta (amykyta3@gmail.com)
42 **/
44 #include <msp430.h>
45 #include <stdint.h>
46 #include <stddef.h>
47 #include <string.h>
48 #include "result.h"
50 #include "fifo.h"
52 //--------------------------------------------------------------------------------------------------
53 ///\addtogroup FIFO_FUNCTIONS
54 ///\{
56 /**
57 * \brief Initializes a new FIFO Datapipe
58 * \param [in] bufptr Pointer to the buffer to be used as storage for the FIFO
59 * \param [in] bufsize Size of the buffer in bytes
60 * \param [in] fifo Pointer to an empty #FIFO_t object
61 * \param [out] fifo Initialized FIFO object
62 * \return Nothing
63 **/
64 void fifo_init(FIFO_t *fifo, register void *bufptr, register size_t bufsize){
65 fifo->bufptr = bufptr;
66 fifo->bufsize = bufsize;
67 fifo->rdidx = 0;
68 fifo->wridx = 0;
69 #if(FIFO_LOG_MAX_USAGE == 1)
70 fifo->max = 0;
71 #endif
74 //--------------------------------------------------------------------------------------------------
75 /**
76 * \brief Write data into the FIFO buffer
77 * \param [in] fifo Pointer to the #FIFO_t object
78 * \param [in] src Pointer to the data to be stored
79 * \param [in] size Number of bytes to be written to the FIFO
80 * \retval RES_OK
81 * \retval RES_FULL Not enough space in FIFO for requested write operation
82 **/
83 RES_t fifo_write(FIFO_t *fifo, register void *src, register size_t size){
84 register size_t wrcount;
86 if(size > fifo_wrcount(fifo)){
87 return(RES_FULL);
92 if((wrcount = fifo->bufsize - fifo->wridx) <= size){
93 // write operation will wrap around in fifo
94 // write first half of fifo
95 memcpy(fifo->bufptr+fifo->wridx,src,wrcount);
97 //wrap around and continue
98 fifo->wridx = 0;
99 size -= wrcount;
100 src = (uint8_t*)src + wrcount;
103 if(size > 0){
104 memcpy(fifo->bufptr+fifo->wridx,src,size);
105 fifo->wridx += size;
108 #if(FIFO_LOG_MAX_USAGE == 1)
109 wrcount = fifo_rdcount(fifo);
110 if(wrcount > fifo->max){
111 fifo->max = wrcount;
113 #endif
116 return(RES_OK);
119 //--------------------------------------------------------------------------------------------------
121 * \brief Read data from the FIFO buffer
122 * \param [in] fifo Pointer to the #FIFO_t object
123 * \param [out] dst Destination of the data to be read. A \c NULL pointer discards the data.
124 * \param [in] size Number of bytes to be read from the FIFO
125 * \retval RES_OK
126 * \retval RES_PARAMERR Not enough bytes written in FIFO for requested read operation
128 RES_t fifo_read(FIFO_t *fifo, register void *dst, register size_t size){
129 register size_t rdcount;
131 if(size > fifo_rdcount(fifo)){
132 return(RES_PARAMERR);
135 if((rdcount = fifo->bufsize - fifo->rdidx) <= size){
136 // read operation will wrap around in fifo
137 // read first half of fifo
138 if(dst != NULL){
139 memcpy(dst,fifo->bufptr+fifo->rdidx,rdcount);
141 //wrap around and continue
142 fifo->rdidx = 0;
143 size -= rdcount;
144 dst = (uint8_t*)dst + rdcount;
147 if(size > 0){
148 if(dst != NULL){
149 memcpy(dst,fifo->bufptr+fifo->rdidx,size);
151 fifo->rdidx += size;
154 return(RES_OK);
156 //--------------------------------------------------------------------------------------------------
158 * \brief Read data from the FIFO buffer without advancing the read pointer
159 * \param [in] fifo Pointer to the #FIFO_t object
160 * \param [out] dst Destination of the data to be read.
161 * \param [in] size Number of bytes to be read from the FIFO
162 * \retval RES_OK
163 * \retval RES_PARAMERR Not enough bytes written in FIFO for requested read operation
165 RES_t fifo_peek(FIFO_t *fifo, register void *dst, register size_t size){
166 register size_t rdcount;
167 register size_t rdidx;
169 if(size > fifo_rdcount(fifo)){
170 return(RES_PARAMERR);
173 rdidx = fifo->rdidx;
175 if((rdcount = fifo->bufsize - rdidx) <= size){
176 // read operation will wrap around in fifo
177 // read first half of fifo
178 memcpy(dst,fifo->bufptr+rdidx,rdcount);
179 //wrap around and continue
180 rdidx = 0;
181 size -= rdcount;
182 dst = (uint8_t*)dst + rdcount;
185 if(size > 0){
186 memcpy(dst,fifo->bufptr+rdidx,size);
187 rdidx += size;
190 return(RES_OK);
193 //--------------------------------------------------------------------------------------------------
195 * \brief Empties the FIFO
196 * \param [in] fifo Pointer to the #FIFO_t object
197 * \return Nothing
199 void fifo_clear(FIFO_t *fifo){
200 fifo->rdidx = 0;
201 fifo->wridx = 0;
204 //--------------------------------------------------------------------------------------------------
206 * \brief Get the number of bytes available for read in the FIFO
207 * \param [in] fifo Pointer to the #FIFO_t object
208 * \return Number of bytes
210 size_t fifo_rdcount(FIFO_t *fifo){
211 register size_t wridx,rdidx;
212 wridx = fifo->wridx;
213 rdidx = fifo->rdidx;
215 if(wridx >= rdidx){
216 return(wridx-rdidx);
217 }else{
218 return((fifo->bufsize-rdidx)+wridx);
222 //--------------------------------------------------------------------------------------------------
224 * \brief Get the number of bytes that can be written to the FIFO
225 * \param [in] fifo Pointer to the #FIFO_t object
226 * \return Number of bytes
228 size_t fifo_wrcount(FIFO_t *fifo){
229 register size_t wridx,rdidx;
230 wridx = fifo->wridx;
231 rdidx = fifo->rdidx;
233 if(fifo->rdidx >= fifo->wridx+1){
234 return(rdidx-wridx-1);
235 }else{
236 return((fifo->bufsize-wridx)+rdidx-1);
240 ///\}
241 ///\}