DDR controller Pre-code review updates/comments, cleaned up c66xinit.c
[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, read_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         {
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;
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)
233     return (stream_read_peek (ptr_data, num_bytes, STREAM_READ));
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)
253     return (stream_read_peek (ptr_data, num_bytes, STREAM_PEEK));
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)
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;
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)
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;
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)
332     /* The stream module is no longer open... */
333     stream_mcb.is_open   = FALSE;
334     return;
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)
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;
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)
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);