Patched version of nrf51822 FOTA compatible driver, with GPTIO disabled, as it clashed with the mbed definitions...

Fork of nRF51822 by Nordic Semiconductor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hci_mem_pool.c Source File

hci_mem_pool.c

00001 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012  
00013 #include "hci_mem_pool.h "
00014 #include "hci_mem_pool_internal.h "
00015 #include <stdbool.h>
00016 #include <stdio.h>
00017 
00018 /**@brief RX buffer element instance structure. 
00019  */
00020 typedef struct 
00021 {
00022     uint8_t  rx_buffer[RX_BUF_SIZE];                                /**< RX buffer memory array. */  
00023     uint32_t length;                                                /**< Length of the RX buffer memory array. */
00024 } rx_buffer_elem_t;
00025 
00026 /**@brief RX buffer queue element instance structure. 
00027  */
00028 typedef struct 
00029 {
00030     rx_buffer_elem_t * p_buffer;                                    /**< Pointer to RX buffer element. */
00031     uint32_t           free_window_count;                           /**< Free space element count. */
00032     uint32_t           free_available_count;                        /**< Free area element count. */
00033     uint32_t           read_available_count;                        /**< Read area element count. */
00034     uint32_t           write_index;                                 /**< Write position index. */                                      
00035     uint32_t           read_index;                                  /**< Read position index. */                                                                            
00036     uint32_t           free_index;                                  /**< Free position index. */                                                                                                                  
00037 } rx_buffer_queue_t;
00038 
00039 static bool              m_is_tx_allocated;                         /**< Boolean value to determine if the TX buffer is allocated. */
00040 static rx_buffer_elem_t  m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
00041 static rx_buffer_queue_t m_rx_buffer_queue;                         /**< RX buffer queue element instance. */
00042 
00043 
00044 uint32_t hci_mem_pool_open(void)
00045 {
00046     m_is_tx_allocated                      = false;    
00047     m_rx_buffer_queue.p_buffer             = m_rx_buffer_elem_queue;
00048     m_rx_buffer_queue.free_window_count    = RX_BUF_QUEUE_SIZE;
00049     m_rx_buffer_queue.free_available_count = 0;
00050     m_rx_buffer_queue.read_available_count = 0;
00051     m_rx_buffer_queue.write_index          = 0;    
00052     m_rx_buffer_queue.read_index           = 0;        
00053     m_rx_buffer_queue.free_index           = 0;            
00054     
00055     return NRF_SUCCESS;
00056 }
00057 
00058 
00059 uint32_t hci_mem_pool_close(void)
00060 {    
00061     return NRF_SUCCESS;
00062 }
00063 
00064 
00065 uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
00066 {
00067     static uint8_t tx_buffer[TX_BUF_SIZE];  
00068 
00069     uint32_t err_code;
00070     
00071     if (pp_buffer == NULL)
00072     {
00073         return NRF_ERROR_NULL;
00074     }
00075     
00076     if (!m_is_tx_allocated)
00077     {        
00078             m_is_tx_allocated = true;
00079             *pp_buffer        = tx_buffer;
00080             err_code          = NRF_SUCCESS;
00081     }
00082     else
00083     {
00084         err_code              = NRF_ERROR_NO_MEM;
00085     }
00086     
00087     return err_code;
00088 }
00089 
00090 
00091 uint32_t hci_mem_pool_tx_free(void)
00092 {
00093     m_is_tx_allocated = false;
00094     
00095     return NRF_SUCCESS;
00096 }
00097 
00098 
00099 uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
00100 {
00101     uint32_t err_code; 
00102 
00103     if (pp_buffer == NULL)
00104     {
00105         return NRF_ERROR_NULL;
00106     }    
00107     *pp_buffer = NULL;
00108     
00109     if (m_rx_buffer_queue.free_window_count != 0)
00110     {    
00111         if (length <= RX_BUF_SIZE)
00112         {    
00113             --(m_rx_buffer_queue.free_window_count);            
00114             ++(m_rx_buffer_queue.read_available_count);            
00115 
00116             *pp_buffer                    = 
00117                     m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
00118 
00119             m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
00120 
00121             // @note: Adjust the write_index making use of the fact that the buffer size is of 
00122             // power of two and two's complement arithmetic. For details refer example to book 
00123             // "Making embedded systems: Elicia White".
00124             m_rx_buffer_queue.write_index = 
00125                     (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
00126             
00127             err_code                      = NRF_SUCCESS;
00128         }
00129         else
00130         {
00131             err_code = NRF_ERROR_DATA_SIZE;    
00132         }        
00133     }
00134     else
00135     {
00136         err_code = NRF_ERROR_NO_MEM;    
00137     }
00138     
00139     return err_code;
00140 }
00141 
00142 
00143 uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
00144 {
00145     uint32_t err_code;
00146     uint32_t consume_index;
00147     uint32_t start_index;
00148     
00149     if (m_rx_buffer_queue.free_available_count != 0)
00150     {
00151         // Find the buffer that has been freed -
00152         // Start at read_index minus free_available_count and then increment until read index.
00153         err_code      = NRF_ERROR_INVALID_ADDR;
00154         consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & 
00155                         (RX_BUF_QUEUE_SIZE - 1u);
00156         start_index   = consume_index;
00157         
00158         do
00159         {
00160             if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
00161             {
00162                 m_rx_buffer_queue.free_index ^= (1u << consume_index);
00163                 err_code = NRF_SUCCESS;
00164                 break;
00165             }
00166             else
00167             {
00168                 consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
00169             }
00170         }
00171         while (consume_index != m_rx_buffer_queue.read_index);
00172 
00173         while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && 
00174                 (m_rx_buffer_queue.free_available_count != 0))
00175         {
00176             --(m_rx_buffer_queue.free_available_count);
00177             ++(m_rx_buffer_queue.free_window_count);            
00178             start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
00179         }
00180     }
00181     else
00182     {
00183         err_code = NRF_ERROR_NO_MEM;
00184     }
00185         
00186     return err_code;    
00187 }
00188 
00189 
00190 uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
00191 {
00192     // @note: Adjust the write_index making use of the fact that the buffer size is of power
00193     // of two and two's complement arithmetic. For details refer example to book 
00194     // "Making embedded systems: Elicia White".
00195     const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u);
00196     m_rx_buffer_queue.p_buffer[index].length = length;    
00197     
00198     return NRF_SUCCESS;
00199 }
00200 
00201 
00202 uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
00203 {
00204     uint32_t err_code;
00205     
00206     if ((pp_buffer == NULL) || (p_length == NULL))
00207     {
00208         return NRF_ERROR_NULL;
00209     }
00210     
00211     if (m_rx_buffer_queue.read_available_count != 0)
00212     {
00213         --(m_rx_buffer_queue.read_available_count);
00214         ++(m_rx_buffer_queue.free_available_count);        
00215         
00216         *pp_buffer                   = 
00217             m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
00218         *p_length                    = 
00219             m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
00220         
00221         // @note: Adjust the write_index making use of the fact that the buffer size is of power
00222         // of two and two's complement arithmetic. For details refer example to book 
00223         // "Making embedded systems: Elicia White".            
00224         m_rx_buffer_queue.read_index = 
00225             (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 
00226         
00227         err_code                     = NRF_SUCCESS;
00228     }
00229     else
00230     {
00231         err_code                     = NRF_ERROR_NO_MEM;        
00232     }
00233     
00234     return err_code;
00235 }