Update copyright information
[keystone-rtos/ibl.git] / src / driver / stream / stream.c
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 <string.h>
50 /** 
51  * @defgroup stream_op
52  *
53  * @ingroup stream_op
54  * @{
55  *
56  * @brief
57  *  Internal defintion to distinguish between read and peek
58  */
59 /**
60  *  @def STREAM_READ
61  */
62 #define STREAM_READ     200   /**< Read from a stream */
64 /**
65  *  @def STREAM_PEEK
66  */
67 #define STREAM_PEEK     210   /**< Peek from a stream */
69 /* @} */
73 /**
74  * @brief 
75  *  The structure describes the Stream Master Control block.
76  *
77  * @details
78  *  The structure stores information about the stream module
79  *  internal buffers and state information.
80  */
81 typedef struct STREAM_MCB
82 {
83     /**
84      * @brief   Flag which indicates if the stream buffer is open or not?
85      */
86     Bool       is_open;
87         
88     /**
89      * @brief   This is the *internal* stream buffer.
90      */
91     Uint8      buffer[MAX_SIZE_STREAM_BUFFER];
93     /**
94      * @brief   This is the read index from where data is read.
95      */
96     Int32      read_idx;
98     /**
99      * @brief   This is the write index to which data is written.
100      */
101     Int32      write_idx;
103     /**
104      * @brief   This is the free size available in the internal buffer.
105      */
106     Int32      free_size;
107 }STREAM_MCB;
109 /**********************************************************************
110  ************************** Global Variables **************************
111  **********************************************************************/
113 /**
114  * @brief   This is the STREAM Master control block which keeps track
115  * of all the stream module information.
116  */
117 STREAM_MCB  stream_mcb;
119 /**********************************************************************
120  ************************** Stream Functions **************************
121  **********************************************************************/
123 /**
124  *  @b Description
125  *  @n
126  *      The function is called to open the stream module
127  *
128  *  @param[in]  chunk_size
129  *      Maximum amount of data that can be received at any
130  *      instant by the boot module.
131  *
132  *  @retval
133  *      Success -   0
134  *  @retval
135  *      Error   -   <0
136  */
137 Int32 stream_open (Uint32 chunk_size)
139     /* Basic Validations: Ensure that the chunk size is not greater
140      * than the internal buffer size. */
141     if (chunk_size > MAX_SIZE_STREAM_BUFFER)
142         return -1;
144     /* Initialize the Master control block. */
145     stream_mcb.is_open   = TRUE;
146     stream_mcb.read_idx  = 0;
147     stream_mcb.write_idx = 0;
148     stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
150     /* Module has been initialized. */
151     return 0;
154 /**
155  *  @b Description
156  *  @n
157  *      The function is called to read/peek data from the stream module.
158  *
159  *  @param[in]  ptr_data
160  *      Pointer to the data buffer where the data will be copied to.
161  *  @param[in]  num_bytes
162  *      Number of bytes to be read.
163  *  @param[in]  op
164  *      Distinguishes a read from a peek @ref stream_op
165  *
166  *  @retval
167  *      Success -   Number of bytes actually read
168  *  @retval
169  *      Error   -   <0
170  */
171 Int32 stream_read_peek (Uint8* ptr_data, Int32 num_bytes, Int32 op)
173     Int32 index;
174     Int32 num_bytes_to_read;
175     
176     /* Determine the number of bytes which can be read. */
177     if (num_bytes > (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size))
178     {
179         /* User has requested more data than what is available. In this case we 
180          * can return only what we have. */
181         num_bytes_to_read = (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size);
182     }
183     else
184     {
185         /* User has requested less data than what is available. In this case we 
186          * return only what the user wants. */            
187         num_bytes_to_read = num_bytes;
188     }
190     /* There is data available copy it from the internal to the user supplied buffer.  */
191     for (index = 0; index < num_bytes_to_read; index++)
192     {
193         /* Copy the data to the "write" index. */
194         if (ptr_data != NULL)
195             *(ptr_data + index) = *(stream_mcb.buffer + stream_mcb.read_idx + index);
197     }
199     /* Increment the read index. 
200     * Once data has been copied; increment the free size accordingly */
201     if (op == STREAM_READ)  {
202         stream_mcb.read_idx  = (stream_mcb.read_idx + num_bytes_to_read) % MAX_SIZE_STREAM_BUFFER;
203         stream_mcb.free_size = stream_mcb.free_size + num_bytes_to_read;
204     }
207     /* Return the number of bytes read. */
208     return num_bytes_to_read;
212 /**
213  *  @b Description
214  *  @n
215  *      The function is called to read data from the stream module.
216  *
217  *  @param[in]  ptr_data
218  *      Pointer to the data buffer where the data will be copied to.
219  *  @param[in]  num_bytes
220  *      Number of bytes to be read.
221  *
222  *  @retval
223  *      Success -   Number of bytes actually read
224  *  @retval
225  *      Error   -   <0
226  */
227 Int32 stream_read (Uint8* ptr_data, Int32 num_bytes)
229     return (stream_read_peek (ptr_data, num_bytes, STREAM_READ));
232 /**
233  *  @b Description
234  *  @n
235  *      The function is called to peek data from the stream module.
236  *
237  *  @param[in]  ptr_data
238  *      Pointer to the data buffer where the data will be copied to.
239  *  @param[in]  num_bytes
240  *      Number of bytes to be read.
241  *
242  *  @retval
243  *      Success -   Number of bytes actually read
244  *  @retval
245  *      Error   -   <0
246  */
247 Int32 stream_peek (Uint8* ptr_data, Int32 num_bytes)
249     return (stream_read_peek (ptr_data, num_bytes, STREAM_PEEK));
253 /**
254  *  @b Description
255  *  @n
256  *      The function is called to write data to the stream
257  *      module.
258  *
259  *  @param[in]  ptr_data
260  *      Pointer to the data buffer which contains the data to be copied.
261  *  @param[in]  num_bytes
262  *      Number of bytes being written
263  *
264  *  @retval
265  *      Success -   0
266  *  @retval
267  *      Error   -   <0
268  */
269 Int32 stream_write (Uint8* ptr_data, Int32 num_bytes)
271     Int32 index;
273     /* Basic Validations: Ensure there is sufficient space to copy the data. */
274     if (num_bytes > stream_mcb.free_size)
275         return -1;
277     /* Basic Validations: Make sure the pointers are valid. */
278     if (ptr_data == NULL)
279         return -1;
281     /* There was sufficient space to copy the data lets do so but we copy byte by byte
282      * since the internal buffer is circular and we can wrap around... */
283     for (index = 0; index < num_bytes; index++)
284     {
285         /* Copy the data to the "write" index. */
286         *(stream_mcb.buffer + stream_mcb.write_idx) = *(ptr_data + index);
288         /* Increment the write index. */
289         stream_mcb.write_idx = (stream_mcb.write_idx + 1) % MAX_SIZE_STREAM_BUFFER;
290     }
292     /* Once data has been copied; decrement the free size accordingly */
293     stream_mcb.free_size = stream_mcb.free_size - num_bytes;
294     return 0;
297 /**
298  *  @b Description
299  *  @n
300  *      The function is used to check if the stream buffers are empty or
301  *      not?
302  *
303  *  @retval
304  *      Empty       -   TRUE
305  *  @retval
306  *      Not Empty   -   FALSE
307  */
308 Bool stream_isempty (void)
310     /* Check the number of free bytes available? */
311     if (stream_mcb.free_size == MAX_SIZE_STREAM_BUFFER)
312         return TRUE;
314     /* There is data in the stream buffer; so its not empty. */
315     return FALSE;
318 /**
319  *  @b Description
320  *  @n
321  *      The function closes the stream module.
322  *
323  *  @retval
324  *      Not Applicable.
325  */
326 void stream_close (void)
328     /* The stream module is no longer open... */
329     stream_mcb.is_open   = FALSE;
330     return;
333 /**
334  *  @b Description
335  *  @n
336  *      The function initializes the stream module.
337  *
338  *  @retval
339  *      Not Applicable.
340  */
341 void stream_init (void)
343     /* Reset the memory contents. */
344     memset ((void *)&stream_mcb, 0, sizeof(STREAM_MCB));
346     /* Make sure we initialize the free size correctly. */
347     stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
348     return;
352 /**
353  *  @b Description
354  *  @n
355  *      Returns the number of bytes currently available in the stream
356  *
357  *  @retval
358  *      The number of bytes in the stream buffer
359  *      -1 if the stream is closed AND empty
360  */
361 Int32 stream_level (void)
363     Int32 remain;
365     remain = MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size;
367     if ((stream_mcb.is_open != TRUE) && (remain == 0))
368         return (-1);
370     return (remain);