Version 0.4 from Mike Line
[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  *  \par
12  */
15 /**********************************************************************
16  ************************** Local Structures **************************
17  **********************************************************************/
18 #include "types.h"
19 #include "iblcfg.h"
20 #include <string.h>
22 /** 
23  * @defgroup stream_op
24  *
25  * @ingroup stream_op
26  * @{
27  *
28  * @brief
29  *  Internal defintion to distinguish between read and peek
30  */
31 /**
32  *  @def STREAM_READ
33  */
34 #define STREAM_READ     200   /**< Read from a stream */
36 /**
37  *  @def STREAM_PEEK
38  */
39 #define STREAM_PEEK     210   /**< Peek from a stream */
41 /* @} */
45 /**
46  * @brief 
47  *  The structure describes the Stream Master Control block.
48  *
49  * @details
50  *  The structure stores information about the stream module
51  *  internal buffers and state information.
52  */
53 typedef struct STREAM_MCB
54 {
55     /**
56      * @brief   Flag which indicates if the stream buffer is open or not?
57      */
58     Bool       is_open;
59         
60     /**
61      * @brief   This is the *internal* stream buffer.
62      */
63     Uint8      buffer[MAX_SIZE_STREAM_BUFFER];
65     /**
66      * @brief   This is the read index from where data is read.
67      */
68     Int32      read_idx;
70     /**
71      * @brief   This is the write index to which data is written.
72      */
73     Int32      write_idx;
75     /**
76      * @brief   This is the free size available in the internal buffer.
77      */
78     Int32      free_size;
79 }STREAM_MCB;
81 /**********************************************************************
82  ************************** Global Variables **************************
83  **********************************************************************/
85 /**
86  * @brief   This is the STREAM Master control block which keeps track
87  * of all the stream module information.
88  */
89 STREAM_MCB  stream_mcb;
91 /**********************************************************************
92  ************************** Stream Functions **************************
93  **********************************************************************/
95 /**
96  *  @b Description
97  *  @n
98  *      The function is called to open the stream module
99  *
100  *  @param[in]  chunk_size
101  *      Maximum amount of data that can be received at any
102  *      instant by the boot module.
103  *
104  *  @retval
105  *      Success -   0
106  *  @retval
107  *      Error   -   <0
108  */
109 Int32 stream_open (Uint32 chunk_size)
111     /* Basic Validations: Ensure that the chunk size is not greater
112      * than the internal buffer size. */
113     if (chunk_size > MAX_SIZE_STREAM_BUFFER)
114         return -1;
116     /* Initialize the Master control block. */
117     stream_mcb.is_open   = TRUE;
118     stream_mcb.read_idx  = 0;
119     stream_mcb.write_idx = 0;
120     stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
122     /* Module has been initialized. */
123     return 0;
126 /**
127  *  @b Description
128  *  @n
129  *      The function is called to read/peek data from the stream module.
130  *
131  *  @param[in]  ptr_data
132  *      Pointer to the data buffer where the data will be copied to.
133  *  @param[in]  num_bytes
134  *      Number of bytes to be read.
135  *  @param[in]  op
136  *      Distinguishes a read from a peek @ref stream_op
137  *
138  *  @retval
139  *      Success -   Number of bytes actually read
140  *  @retval
141  *      Error   -   <0
142  */
143 Int32 stream_read_peek (Uint8* ptr_data, Int32 num_bytes, Int32 op)
145     Int32 index;
146     Int32 num_bytes_to_read;
147     
148     /* Determine the number of bytes which can be read. */
149     if (num_bytes > (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size))
150     {
151         /* User has requested more data than what is available. In this case we 
152          * can return only what we have. */
153         num_bytes_to_read = (MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size);
154     }
155     else
156     {
157         /* User has requested less data than what is available. In this case we 
158          * return only what the user wants. */            
159         num_bytes_to_read = num_bytes;
160     }
162     /* There is data available copy it from the internal to the user supplied buffer.  */
163     for (index = 0; index < num_bytes_to_read; index++)
164     {
165         /* Copy the data to the "write" index. */
166         if (ptr_data != NULL)
167             *(ptr_data + index) = *(stream_mcb.buffer + stream_mcb.read_idx + index);
169     }
171     /* Increment the read index. 
172     * Once data has been copied; increment the free size accordingly */
173     if (op == STREAM_READ)  {
174         stream_mcb.read_idx  = (stream_mcb.read_idx + num_bytes_to_read) % MAX_SIZE_STREAM_BUFFER;
175         stream_mcb.free_size = stream_mcb.free_size + num_bytes_to_read;
176     }
179     /* Return the number of bytes read. */
180     return num_bytes_to_read;
184 /**
185  *  @b Description
186  *  @n
187  *      The function is called to read data from the stream module.
188  *
189  *  @param[in]  ptr_data
190  *      Pointer to the data buffer where the data will be copied to.
191  *  @param[in]  num_bytes
192  *      Number of bytes to be read.
193  *
194  *  @retval
195  *      Success -   Number of bytes actually read
196  *  @retval
197  *      Error   -   <0
198  */
199 Int32 stream_read (Uint8* ptr_data, Int32 num_bytes)
201     return (stream_read_peek (ptr_data, num_bytes, STREAM_READ));
204 /**
205  *  @b Description
206  *  @n
207  *      The function is called to peek data from the stream module.
208  *
209  *  @param[in]  ptr_data
210  *      Pointer to the data buffer where the data will be copied to.
211  *  @param[in]  num_bytes
212  *      Number of bytes to be read.
213  *
214  *  @retval
215  *      Success -   Number of bytes actually read
216  *  @retval
217  *      Error   -   <0
218  */
219 Int32 stream_peek (Uint8* ptr_data, Int32 num_bytes)
221     return (stream_read_peek (ptr_data, num_bytes, STREAM_PEEK));
225 /**
226  *  @b Description
227  *  @n
228  *      The function is called to write data to the stream
229  *      module.
230  *
231  *  @param[in]  ptr_data
232  *      Pointer to the data buffer which contains the data to be copied.
233  *  @param[in]  num_bytes
234  *      Number of bytes being written
235  *
236  *  @retval
237  *      Success -   0
238  *  @retval
239  *      Error   -   <0
240  */
241 Int32 stream_write (Uint8* ptr_data, Int32 num_bytes)
243     Int32 index;
245     /* Basic Validations: Ensure there is sufficient space to copy the data. */
246     if (num_bytes > stream_mcb.free_size)
247         return -1;
249     /* Basic Validations: Make sure the pointers are valid. */
250     if (ptr_data == NULL)
251         return -1;
253     /* There was sufficient space to copy the data lets do so but we copy byte by byte
254      * since the internal buffer is circular and we can wrap around... */
255     for (index = 0; index < num_bytes; index++)
256     {
257         /* Copy the data to the "write" index. */
258         *(stream_mcb.buffer + stream_mcb.write_idx) = *(ptr_data + index);
260         /* Increment the write index. */
261         stream_mcb.write_idx = (stream_mcb.write_idx + 1) % MAX_SIZE_STREAM_BUFFER;
262     }
264     /* Once data has been copied; decrement the free size accordingly */
265     stream_mcb.free_size = stream_mcb.free_size - num_bytes;
266     return 0;
269 /**
270  *  @b Description
271  *  @n
272  *      The function is used to check if the stream buffers are empty or
273  *      not?
274  *
275  *  @retval
276  *      Empty       -   TRUE
277  *  @retval
278  *      Not Empty   -   FALSE
279  */
280 Bool stream_isempty (void)
282     /* Check the number of free bytes available? */
283     if (stream_mcb.free_size == MAX_SIZE_STREAM_BUFFER)
284         return TRUE;
286     /* There is data in the stream buffer; so its not empty. */
287     return FALSE;
290 /**
291  *  @b Description
292  *  @n
293  *      The function closes the stream module.
294  *
295  *  @retval
296  *      Not Applicable.
297  */
298 void stream_close (void)
300     /* The stream module is no longer open... */
301     stream_mcb.is_open   = FALSE;
302     return;
305 /**
306  *  @b Description
307  *  @n
308  *      The function initializes the stream module.
309  *
310  *  @retval
311  *      Not Applicable.
312  */
313 void stream_init (void)
315     /* Reset the memory contents. */
316     memset ((void *)&stream_mcb, 0, sizeof(STREAM_MCB));
318     /* Make sure we initialize the free size correctly. */
319     stream_mcb.free_size = MAX_SIZE_STREAM_BUFFER;
320     return;
324 /**
325  *  @b Description
326  *  @n
327  *      Returns the number of bytes currently available in the stream
328  *
329  *  @retval
330  *      The number of bytes in the stream buffer
331  *      -1 if the stream is closed AND empty
332  */
333 Int32 stream_level (void)
335     Int32 remain;
337     remain = MAX_SIZE_STREAM_BUFFER - stream_mcb.free_size;
339     if ((stream_mcb.is_open != TRUE) && (remain == 0))
340         return (-1);
342     return (remain);