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