]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/driver/stream/stream.c
Merge branch 'tmp-mike2'
[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 "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;
88         
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)
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;
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)
174     Int32 index;
175     Int32 num_bytes_to_read;
176     
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             *(ptr_data + index) = *(stream_mcb.buffer + stream_mcb.read_idx + index);
198     }
200     /* Increment the read index. 
201     * Once data has been copied; increment the free size accordingly */
202     if (op == STREAM_READ)  {
203         stream_mcb.read_idx  = (stream_mcb.read_idx + num_bytes_to_read) % MAX_SIZE_STREAM_BUFFER;
204         stream_mcb.free_size = stream_mcb.free_size + num_bytes_to_read;
205     }
208     /* Return the number of bytes read. */
209     return num_bytes_to_read;
213 /**
214  *  @b Description
215  *  @n
216  *      The function is called to read data from the stream module.
217  *
218  *  @param[in]  ptr_data
219  *      Pointer to the data buffer where the data will be copied to.
220  *  @param[in]  num_bytes
221  *      Number of bytes to be read.
222  *
223  *  @retval
224  *      Success -   Number of bytes actually read
225  *  @retval
226  *      Error   -   <0
227  */
228 Int32 stream_read (Uint8* ptr_data, Int32 num_bytes)
230     return (stream_read_peek (ptr_data, num_bytes, STREAM_READ));
233 /**
234  *  @b Description
235  *  @n
236  *      The function is called to peek data from the stream module.
237  *
238  *  @param[in]  ptr_data
239  *      Pointer to the data buffer where the data will be copied to.
240  *  @param[in]  num_bytes
241  *      Number of bytes to be read.
242  *
243  *  @retval
244  *      Success -   Number of bytes actually read
245  *  @retval
246  *      Error   -   <0
247  */
248 Int32 stream_peek (Uint8* ptr_data, Int32 num_bytes)
250     return (stream_read_peek (ptr_data, num_bytes, STREAM_PEEK));
254 /**
255  *  @b Description
256  *  @n
257  *      The function is called to write data to the stream
258  *      module.
259  *
260  *  @param[in]  ptr_data
261  *      Pointer to the data buffer which contains the data to be copied.
262  *  @param[in]  num_bytes
263  *      Number of bytes being written
264  *
265  *  @retval
266  *      Success -   0
267  *  @retval
268  *      Error   -   <0
269  */
270 Int32 stream_write (Uint8* ptr_data, Int32 num_bytes)
272     Int32 index;
274     /* Basic Validations: Ensure there is sufficient space to copy the data. */
275     if (num_bytes > stream_mcb.free_size)
276         return -1;
278     /* Basic Validations: Make sure the pointers are valid. */
279     if (ptr_data == NULL)
280         return -1;
282     /* There was sufficient space to copy the data lets do so but we copy byte by byte
283      * since the internal buffer is circular and we can wrap around... */
284     for (index = 0; index < num_bytes; index++)
285     {
286         /* Copy the data to the "write" index. */
287         *(stream_mcb.buffer + stream_mcb.write_idx) = *(ptr_data + index);
289         /* Increment the write index. */
290         stream_mcb.write_idx = (stream_mcb.write_idx + 1) % MAX_SIZE_STREAM_BUFFER;
291     }
293     /* Once data has been copied; decrement the free size accordingly */
294     stream_mcb.free_size = stream_mcb.free_size - num_bytes;
295     return 0;
298 /**
299  *  @b Description
300  *  @n
301  *      The function is used to check if the stream buffers are empty or
302  *      not?
303  *
304  *  @retval
305  *      Empty       -   TRUE
306  *  @retval
307  *      Not Empty   -   FALSE
308  */
309 Bool stream_isempty (void)
311     /* Check the number of free bytes available? */
312     if (stream_mcb.free_size == MAX_SIZE_STREAM_BUFFER)
313         return TRUE;
315     /* There is data in the stream buffer; so its not empty. */
316     return FALSE;
319 /**
320  *  @b Description
321  *  @n
322  *      The function closes the stream module.
323  *
324  *  @retval
325  *      Not Applicable.
326  */
327 void stream_close (void)
329     /* The stream module is no longer open... */
330     stream_mcb.is_open   = FALSE;
331     return;
334 /**
335  *  @b Description
336  *  @n
337  *      The function initializes the stream module.
338  *
339  *  @retval
340  *      Not Applicable.
341  */
342 void stream_init (void)
344     /* Reset the memory contents. */
345     streamMemset ((void *)&stream_mcb, 0, sizeof(STREAM_MCB));
347     /* Make sure we initialize the free size correctly. */
348     stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
349     return;
353 /**
354  *  @b Description
355  *  @n
356  *      Returns the number of bytes currently available in the stream
357  *
358  *  @retval
359  *      The number of bytes in the stream buffer
360  *      -1 if the stream is closed AND empty
361  */
362 Int32 stream_level (void)
364     Int32 remain;
366     remain = MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size;
368     if ((stream_mcb.is_open != TRUE) && (remain == 0))
369         return (-1);
371     return (remain);