ST / X_NUCLEO_IDW01M1

Dependents:   SpwfInterface_NSAPI_Tests HelloWorld_IDW01M1

Fork of X_NUCLEO_IDW01M1 by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ring_buffer.c Source File

ring_buffer.c

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    ring_buffer.c
00004  * @author  Central LAB
00005  * @version V2.0.0
00006  * @date    10-February-2016
00007  * @brief   Implements the Circular Buffer management of the Wi-Fi module
00008  ******************************************************************************
00009  * @attention
00010  *
00011  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *   1. Redistributions of source code must retain the above copyright notice,
00016  *      this list of conditions and the following disclaimer.
00017  *   2. Redistributions in binary form must reproduce the above copyright notice,
00018  *      this list of conditions and the following disclaimer in the documentation
00019  *      and/or other materials provided with the distribution.
00020  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021  *      may be used to endorse or promote products derived from this software
00022  *      without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  ******************************************************************************
00036  */
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include "ring_buffer.h"
00041 #include "wifi_module.h"
00042 
00043 /** @addtogroup MIDDLEWARES
00044 * @{
00045 */ 
00046 
00047 
00048 /** @defgroup  NUCLEO_WIFI_UTILS
00049   * @brief Wi-Fi buffer utility
00050   * @{
00051   */ 
00052 
00053 
00054 /** @defgroup NUCLEO_WIFI_UTILS_Private_Defines
00055   * @{
00056   */
00057 
00058 /**
00059   * @}
00060   */
00061 
00062 /** @defgroup NUCLEO_WIFI_UTILS_Private_Variables
00063   * @{
00064   */
00065 
00066 extern uint8_t ring_buffer[RINGBUF_SIZE];
00067 extern uint8_t pop_buffer[MAX_BUFFER_GLOBAL];
00068 extern uint8_t prefetch_buffer[20];
00069 //extern wifi_bool enable_receive_data_chunk;
00070 extern volatile Wifi_Status_Var status_flag;
00071 extern uint32_t pop_buffer_size;
00072 
00073 #define ELEMENT_SIZE 1
00074 
00075                
00076 /**
00077   * @}
00078   */
00079 
00080 /** @defgroup NUCLEO_WIFI_UTILS_Private_Functions
00081   * @{
00082   */
00083 
00084 /**
00085   * @brief  init
00086   *         Initialize a circular buffer of type buffer_td
00087   * @param  None
00088   * @retval None
00089   */
00090 void init(buffer_td *buffer, int size) 
00091 {
00092     buffer->size = size;
00093     buffer->start = 0;
00094     buffer->count = 0;
00095     buffer->end = 0;
00096     buffer->element = ring_buffer;
00097 }
00098 
00099 /**
00100   * @brief  flush_buffer_queue
00101   *         flushes the buffer
00102   * @param  None
00103   * @retval None
00104   */ 
00105 void flush_buffer_queue(buffer_td *buffer) 
00106 {
00107   buffer->start = buffer->end;//the tail goes up to the head and buffer becomes empty
00108   buffer->count = 0;
00109 }
00110 
00111 /**
00112   * @brief  is_half_full
00113   *         checks if the buffer is half full (empty)
00114   * @param  None
00115   * @retval None
00116   */ 
00117 int is_half_full(buffer_td *buffer)
00118 {
00119   int bufsize = buffer->size;
00120   if (buffer->count >= bufsize - 100)
00121   {
00122     //printf("half full!");
00123     return 1;
00124   } 
00125   else 
00126   {
00127     return 0;
00128   }
00129 }
00130 
00131 /**
00132   * @brief  is_half_empty
00133   *         checks if the buffer is less than half
00134   * @param  None
00135   * @retval None
00136   */
00137 int is_half_empty(buffer_td *buffer)
00138 {
00139   //int bufsize = buffer->size;
00140   if (buffer->count <= 100)
00141   {
00142     return 1;
00143   }
00144   else 
00145   {
00146     return 0;
00147   }
00148 }
00149 
00150 /**
00151   * @brief  full
00152   *         indicates if the given buffer is full or not
00153   * @param  None
00154   * @retval None
00155   */
00156 int full(buffer_td *buffer) 
00157 {
00158   int bufsize = buffer->size;
00159   if (buffer->count == bufsize) 
00160   {
00161     return 1;
00162   }
00163   else 
00164   {
00165     return 0;
00166   }
00167 }
00168 
00169 /**
00170   * @brief  empty
00171   *         indicates if the given buffer is empty or not
00172   * @param  None
00173   * @retval None
00174   */
00175 int empty(buffer_td *buffer) {
00176     if (buffer->count == 0) {
00177         return 1;
00178     } else {
00179         return 0;
00180     }
00181 }
00182 
00183 /**
00184   * @brief  prefetch_buffer_queue
00185   *         prefetches the pipeline upto xx bytes
00186   * @param  None
00187   * @retval None
00188   */ 
00189 uint8_t * prefetch_buffer_queue(buffer_td *buffer)
00190 {
00191   //int i = 0;
00192   uint8_t * element;
00193   int bufsize;
00194 
00195   memset(prefetch_buffer,0x00,20);
00196   element = &prefetch_buffer[0];
00197   element[4] = '\0';
00198 
00199   if(!empty(buffer))
00200       {
00201         bufsize = (buffer->count);
00202         if(buffer->count <= 20)
00203             memcpy(element, &buffer->element[buffer->start], bufsize);
00204         else
00205             memcpy(element, &buffer->element[buffer->start], 20);
00206         return element;
00207       }
00208   else return NULL;
00209 }
00210 
00211 /*
00212   * @brief  push_buffer
00213   *         pushes a new item onto the circular buffer (queues it)
00214   * @param  None
00215   * @retval None
00216   */
00217 void push_buffer(buffer_td *buffer, uint8_t *data) 
00218 {
00219   int bufsize;
00220 
00221   if (full(buffer)) 
00222   {     
00223     //Buffer overflow and no more space
00224     //MPD: No Action taken here; in case of buffer overflow, do we need to overwrite last buffer?
00225     //printf("\r\nRing Buffer Full!!\r\n");
00226     //printf(data);
00227     return;
00228   } 
00229   else
00230   {
00231     buffer->count++;    
00232     memcpy(&buffer->element[buffer->end], data, ELEMENT_SIZE);
00233     buffer->end = buffer->end + ELEMENT_SIZE;
00234     
00235     //wrap around if max size is reached
00236     bufsize = (buffer->size);
00237     if (buffer->end >= bufsize) 
00238     {
00239       buffer->end = 0;
00240     }
00241   }
00242 }
00243  
00244 /**
00245   * @brief  pop_buffer_queue
00246   *         dequeues the circular buffer
00247   * @param  None
00248   * @retval None
00249   */ 
00250 uint8_t * pop_buffer_queue(buffer_td *buffer) 
00251 {
00252   uint8_t * element;
00253   int bufsize;
00254 
00255   element = &pop_buffer[0];
00256   if (empty(buffer)) 
00257   {
00258     //printf("\r\nRing Buffer Empty!!\r\n");
00259     return NULL;
00260   } 
00261   else 
00262   {
00263       memset(pop_buffer, 0x00 , MAX_BUFFER_GLOBAL);
00264       if(status_flag.enable_receive_data_chunk)
00265       {
00266         int buf_end = buffer->end;
00267         // int buf_start = buffer->start;
00268         if(buffer->count < 512)
00269         {
00270             pop_buffer_size = buffer->count;
00271             if(buf_end >= buffer->start)
00272             {
00273                   memcpy(element, &buffer->element[buffer->start], pop_buffer_size);
00274             }
00275             else
00276             {
00277                   int buf_start = buffer->start;
00278                   memcpy(element, &buffer->element[buffer->start], RINGBUF_SIZE - buf_start);
00279                   memcpy(element+(RINGBUF_SIZE-buffer->start), &buffer->element[0], buf_end);
00280             }
00281             buffer->start = buffer->end;
00282             buffer->count = 0;
00283         }
00284         else
00285         {
00286             if(buf_end >= buffer->start)
00287             {
00288                   memcpy(element, &buffer->element[buffer->start], 511);
00289                   buffer->start = buffer->start + 511;
00290                   buffer->count = buf_end - buffer->start;
00291             }
00292             else
00293             {
00294                   if(buffer->start + 511 < RINGBUF_SIZE)
00295                   {
00296                       memcpy(element, &buffer->element[buffer->start], 511);
00297                       buffer->start = buffer->start + 511;
00298                       buffer->count = (RINGBUF_SIZE - buffer->start)+ buf_end;
00299                   }
00300                   else
00301                   {
00302                       int buf_start = buffer->start;
00303                       memcpy(element, &buffer->element[buffer->start], RINGBUF_SIZE-buf_start);
00304                       memcpy(element+(RINGBUF_SIZE-buffer->start), &buffer->element[0], buf_start-513);  //(buffer->start + 511) - 1024;
00305                       buffer->start = (buffer->start-513);
00306                       buffer->count = buf_end - buffer->start;
00307                   }
00308             }
00309             pop_buffer_size = 511;
00310         }
00311     }
00312     else
00313     {
00314         /* First in First Out*/
00315         memcpy(element, &buffer->element[buffer->start], ELEMENT_SIZE);
00316         buffer->start = buffer->start + ELEMENT_SIZE;
00317         buffer->count--;
00318         pop_buffer_size = 1;
00319         bufsize = (buffer->size);
00320         if (buffer->start >= bufsize)
00321         {
00322           buffer->start = 0;
00323         } 
00324     }
00325     return element;
00326   }
00327 }
00328 
00329 /**
00330   * @brief  rewinds_buffer_queue
00331   *         rewinds the circular buffer
00332   * @param  None
00333   * @retval None
00334   */ 
00335 void rewind_buffer_queue(buffer_td *buffer , int count)
00336 {
00337     int buf_end = buffer->end;
00338     if(buffer->start - count >= 0)
00339     {
00340         buffer->start = buffer->start - count;
00341         if(buf_end > buffer->start) {
00342           buffer->count = buf_end - buffer->start;
00343         }
00344         else {
00345           buffer->count = (RINGBUF_SIZE-buffer->start)+buf_end;
00346         }
00347     }
00348     else
00349     {
00350         buffer->start = RINGBUF_SIZE - (count - buffer->start);
00351         buffer->count = (RINGBUF_SIZE - buffer->start)+ buf_end;
00352     }
00353 }
00354 
00355 /**
00356   * @}
00357   */ 
00358 
00359 /**
00360   * @}
00361   */ 
00362 
00363 
00364 /**
00365   * @}
00366   */ 
00367 
00368 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/