1 /**
2 * @file stream.c
3 *
4 * @brief
5 * The file implements the STREAM module.
6 *
7 * \par
8 * NOTE:
9 * (C) Copyright 2008, Texas Instruments, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * \par
40 */
43 /**********************************************************************
44 ************************** Local Structures **************************
45 **********************************************************************/
46 #include "types.h"
47 #include "iblcfg.h"
48 #include "stream_osal.h"
49 #include <string.h>
51 /**
52 * @defgroup stream_op
53 *
54 * @ingroup stream_op
55 * @{
56 *
57 * @brief
58 * Internal defintion to distinguish between read and peek
59 */
60 /**
61 * @def STREAM_READ
62 */
63 #define STREAM_READ 200 /**< Read from a stream */
65 /**
66 * @def STREAM_PEEK
67 */
68 #define STREAM_PEEK 210 /**< Peek from a stream */
70 /* @} */
74 /**
75 * @brief
76 * The structure describes the Stream Master Control block.
77 *
78 * @details
79 * The structure stores information about the stream module
80 * internal buffers and state information.
81 */
82 typedef struct STREAM_MCB
83 {
84 /**
85 * @brief Flag which indicates if the stream buffer is open or not?
86 */
87 Bool is_open;
89 /**
90 * @brief This is the *internal* stream buffer.
91 */
92 Uint8 buffer[MAX_SIZE_STREAM_BUFFER];
94 /**
95 * @brief This is the read index from where data is read.
96 */
97 Int32 read_idx;
99 /**
100 * @brief This is the write index to which data is written.
101 */
102 Int32 write_idx;
104 /**
105 * @brief This is the free size available in the internal buffer.
106 */
107 Int32 free_size;
108 }STREAM_MCB;
110 /**********************************************************************
111 ************************** Global Variables **************************
112 **********************************************************************/
114 /**
115 * @brief This is the STREAM Master control block which keeps track
116 * of all the stream module information.
117 */
118 STREAM_MCB stream_mcb;
120 /**********************************************************************
121 ************************** Stream Functions **************************
122 **********************************************************************/
124 /**
125 * @b Description
126 * @n
127 * The function is called to open the stream module
128 *
129 * @param[in] chunk_size
130 * Maximum amount of data that can be received at any
131 * instant by the boot module.
132 *
133 * @retval
134 * Success - 0
135 * @retval
136 * Error - <0
137 */
138 Int32 stream_open (Uint32 chunk_size)
139 {
140 /* Basic Validations: Ensure that the chunk size is not greater
141 * than the internal buffer size. */
142 if (chunk_size > MAX_SIZE_STREAM_BUFFER)
143 return -1;
145 /* Initialize the Master control block. */
146 stream_mcb.is_open = TRUE;
147 stream_mcb.read_idx = 0;
148 stream_mcb.write_idx = 0;
149 stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
151 /* Module has been initialized. */
152 return 0;
153 }
155 /**
156 * @b Description
157 * @n
158 * The function is called to read/peek data from the stream module.
159 *
160 * @param[in] ptr_data
161 * Pointer to the data buffer where the data will be copied to.
162 * @param[in] num_bytes
163 * Number of bytes to be read.
164 * @param[in] op
165 * Distinguishes a read from a peek @ref stream_op
166 *
167 * @retval
168 * Success - Number of bytes actually read
169 * @retval
170 * Error - <0
171 */
172 Int32 stream_read_peek (Uint8* ptr_data, Int32 num_bytes, Int32 op)
173 {
174 Int32 index, read_index;
175 Int32 num_bytes_to_read;
177 /* Determine the number of bytes which can be read. */
178 if (num_bytes > (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size))
179 {
180 /* User has requested more data than what is available. In this case we
181 * can return only what we have. */
182 num_bytes_to_read = (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size);
183 }
184 else
185 {
186 /* User has requested less data than what is available. In this case we
187 * return only what the user wants. */
188 num_bytes_to_read = num_bytes;
189 }
191 /* There is data available copy it from the internal to the user supplied buffer. */
192 for (index = 0; index < num_bytes_to_read; index++)
193 {
194 /* Copy the data to the "write" index. */
195 if (ptr_data != NULL)
196 {
197 read_index = stream_mcb.read_idx + index;
198 read_index = read_index % MAX_SIZE_STREAM_BUFFER;
199 *(ptr_data + index) = *(stream_mcb.buffer + read_index);
200 }
201 }
203 /* Increment the read index.
204 * Once data has been copied; increment the free size accordingly */
205 if (op == STREAM_READ) {
206 stream_mcb.read_idx = (stream_mcb.read_idx + num_bytes_to_read) % MAX_SIZE_STREAM_BUFFER;
207 stream_mcb.free_size = stream_mcb.free_size + num_bytes_to_read;
208 }
211 /* Return the number of bytes read. */
212 return num_bytes_to_read;
213 }
216 /**
217 * @b Description
218 * @n
219 * The function is called to read data from the stream module.
220 *
221 * @param[in] ptr_data
222 * Pointer to the data buffer where the data will be copied to.
223 * @param[in] num_bytes
224 * Number of bytes to be read.
225 *
226 * @retval
227 * Success - Number of bytes actually read
228 * @retval
229 * Error - <0
230 */
231 Int32 stream_read (Uint8* ptr_data, Int32 num_bytes)
232 {
233 return (stream_read_peek (ptr_data, num_bytes, STREAM_READ));
234 }
236 /**
237 * @b Description
238 * @n
239 * The function is called to peek data from the stream module.
240 *
241 * @param[in] ptr_data
242 * Pointer to the data buffer where the data will be copied to.
243 * @param[in] num_bytes
244 * Number of bytes to be read.
245 *
246 * @retval
247 * Success - Number of bytes actually read
248 * @retval
249 * Error - <0
250 */
251 Int32 stream_peek (Uint8* ptr_data, Int32 num_bytes)
252 {
253 return (stream_read_peek (ptr_data, num_bytes, STREAM_PEEK));
254 }
257 /**
258 * @b Description
259 * @n
260 * The function is called to write data to the stream
261 * module.
262 *
263 * @param[in] ptr_data
264 * Pointer to the data buffer which contains the data to be copied.
265 * @param[in] num_bytes
266 * Number of bytes being written
267 *
268 * @retval
269 * Success - 0
270 * @retval
271 * Error - <0
272 */
273 Int32 stream_write (Uint8* ptr_data, Int32 num_bytes)
274 {
275 Int32 index;
277 /* Basic Validations: Ensure there is sufficient space to copy the data. */
278 if (num_bytes > stream_mcb.free_size)
279 return -1;
281 /* Basic Validations: Make sure the pointers are valid. */
282 if (ptr_data == NULL)
283 return -1;
285 /* There was sufficient space to copy the data lets do so but we copy byte by byte
286 * since the internal buffer is circular and we can wrap around... */
287 for (index = 0; index < num_bytes; index++)
288 {
289 /* Copy the data to the "write" index. */
290 *(stream_mcb.buffer + stream_mcb.write_idx) = *(ptr_data + index);
292 /* Increment the write index. */
293 stream_mcb.write_idx = (stream_mcb.write_idx + 1) % MAX_SIZE_STREAM_BUFFER;
294 }
296 /* Once data has been copied; decrement the free size accordingly */
297 stream_mcb.free_size = stream_mcb.free_size - num_bytes;
298 return 0;
299 }
301 /**
302 * @b Description
303 * @n
304 * The function is used to check if the stream buffers are empty or
305 * not?
306 *
307 * @retval
308 * Empty - TRUE
309 * @retval
310 * Not Empty - FALSE
311 */
312 Bool stream_isempty (void)
313 {
314 /* Check the number of free bytes available? */
315 if (stream_mcb.free_size == MAX_SIZE_STREAM_BUFFER)
316 return TRUE;
318 /* There is data in the stream buffer; so its not empty. */
319 return FALSE;
320 }
322 /**
323 * @b Description
324 * @n
325 * The function closes the stream module.
326 *
327 * @retval
328 * Not Applicable.
329 */
330 void stream_close (void)
331 {
332 /* The stream module is no longer open... */
333 stream_mcb.is_open = FALSE;
334 return;
335 }
337 /**
338 * @b Description
339 * @n
340 * The function initializes the stream module.
341 *
342 * @retval
343 * Not Applicable.
344 */
345 void stream_init (void)
346 {
347 /* Reset the memory contents. */
348 streamMemset ((void *)&stream_mcb, 0, sizeof(STREAM_MCB));
350 /* Make sure we initialize the free size correctly. */
351 stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
352 return;
353 }
356 /**
357 * @b Description
358 * @n
359 * Returns the number of bytes currently available in the stream
360 *
361 * @retval
362 * The number of bytes in the stream buffer
363 * -1 if the stream is closed AND empty
364 */
365 Int32 stream_level (void)
366 {
367 Int32 remain;
369 remain = MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size;
371 if ((stream_mcb.is_open != TRUE) && (remain == 0))
372 return (-1);
374 return (remain);
376 }