Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nrf51-sdk by
hci_mem_pool.c
00001 /* 00002 * Copyright (c) Nordic Semiconductor ASA 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 00016 * contributors to this software may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00024 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 #include "hci_mem_pool.h " 00034 #include "hci_mem_pool_internal.h " 00035 #include <stdbool.h> 00036 #include <stdio.h> 00037 00038 /**@brief RX buffer element instance structure. 00039 */ 00040 typedef struct 00041 { 00042 uint8_t rx_buffer[RX_BUF_SIZE]; /**< RX buffer memory array. */ 00043 uint32_t length; /**< Length of the RX buffer memory array. */ 00044 } rx_buffer_elem_t; 00045 00046 /**@brief RX buffer queue element instance structure. 00047 */ 00048 typedef struct 00049 { 00050 rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */ 00051 uint32_t free_window_count; /**< Free space element count. */ 00052 uint32_t free_available_count; /**< Free area element count. */ 00053 uint32_t read_available_count; /**< Read area element count. */ 00054 uint32_t write_index; /**< Write position index. */ 00055 uint32_t read_index; /**< Read position index. */ 00056 uint32_t free_index; /**< Free position index. */ 00057 } rx_buffer_queue_t; 00058 00059 static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */ 00060 static rx_buffer_elem_t m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */ 00061 static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */ 00062 00063 00064 uint32_t hci_mem_pool_open(void) 00065 { 00066 m_is_tx_allocated = false; 00067 m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue; 00068 m_rx_buffer_queue.free_window_count = RX_BUF_QUEUE_SIZE; 00069 m_rx_buffer_queue.free_available_count = 0; 00070 m_rx_buffer_queue.read_available_count = 0; 00071 m_rx_buffer_queue.write_index = 0; 00072 m_rx_buffer_queue.read_index = 0; 00073 m_rx_buffer_queue.free_index = 0; 00074 00075 return NRF_SUCCESS; 00076 } 00077 00078 00079 uint32_t hci_mem_pool_close(void) 00080 { 00081 return NRF_SUCCESS; 00082 } 00083 00084 00085 uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer) 00086 { 00087 static uint8_t tx_buffer[TX_BUF_SIZE]; 00088 00089 uint32_t err_code; 00090 00091 if (pp_buffer == NULL) 00092 { 00093 return NRF_ERROR_NULL; 00094 } 00095 00096 if (!m_is_tx_allocated) 00097 { 00098 m_is_tx_allocated = true; 00099 *pp_buffer = tx_buffer; 00100 err_code = NRF_SUCCESS; 00101 } 00102 else 00103 { 00104 err_code = NRF_ERROR_NO_MEM; 00105 } 00106 00107 return err_code; 00108 } 00109 00110 00111 uint32_t hci_mem_pool_tx_free(void) 00112 { 00113 m_is_tx_allocated = false; 00114 00115 return NRF_SUCCESS; 00116 } 00117 00118 00119 uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer) 00120 { 00121 uint32_t err_code; 00122 00123 if (pp_buffer == NULL) 00124 { 00125 return NRF_ERROR_NULL; 00126 } 00127 *pp_buffer = NULL; 00128 00129 if (m_rx_buffer_queue.free_window_count != 0) 00130 { 00131 if (length <= RX_BUF_SIZE) 00132 { 00133 --(m_rx_buffer_queue.free_window_count); 00134 ++(m_rx_buffer_queue.read_available_count); 00135 00136 *pp_buffer = 00137 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer; 00138 00139 m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index); 00140 00141 // @note: Adjust the write_index making use of the fact that the buffer size is of 00142 // power of two and two's complement arithmetic. For details refer example to book 00143 // "Making embedded systems: Elicia White". 00144 m_rx_buffer_queue.write_index = 00145 (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 00146 00147 err_code = NRF_SUCCESS; 00148 } 00149 else 00150 { 00151 err_code = NRF_ERROR_DATA_SIZE; 00152 } 00153 } 00154 else 00155 { 00156 err_code = NRF_ERROR_NO_MEM; 00157 } 00158 00159 return err_code; 00160 } 00161 00162 00163 uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer) 00164 { 00165 uint32_t err_code; 00166 uint32_t consume_index; 00167 uint32_t start_index; 00168 00169 if (m_rx_buffer_queue.free_available_count != 0) 00170 { 00171 // Find the buffer that has been freed - 00172 // Start at read_index minus free_available_count and then increment until read index. 00173 err_code = NRF_ERROR_INVALID_ADDR; 00174 consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & 00175 (RX_BUF_QUEUE_SIZE - 1u); 00176 start_index = consume_index; 00177 00178 do 00179 { 00180 if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer) 00181 { 00182 m_rx_buffer_queue.free_index ^= (1u << consume_index); 00183 err_code = NRF_SUCCESS; 00184 break; 00185 } 00186 else 00187 { 00188 consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 00189 } 00190 } 00191 while (consume_index != m_rx_buffer_queue.read_index); 00192 00193 while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && 00194 (m_rx_buffer_queue.free_available_count != 0)) 00195 { 00196 --(m_rx_buffer_queue.free_available_count); 00197 ++(m_rx_buffer_queue.free_window_count); 00198 start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 00199 } 00200 } 00201 else 00202 { 00203 err_code = NRF_ERROR_NO_MEM; 00204 } 00205 00206 return err_code; 00207 } 00208 00209 00210 uint32_t hci_mem_pool_rx_data_size_set(uint32_t length) 00211 { 00212 // @note: Adjust the write_index making use of the fact that the buffer size is of power 00213 // of two and two's complement arithmetic. For details refer example to book 00214 // "Making embedded systems: Elicia White". 00215 const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u); 00216 m_rx_buffer_queue.p_buffer[index].length = length; 00217 00218 return NRF_SUCCESS; 00219 } 00220 00221 00222 uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length) 00223 { 00224 uint32_t err_code; 00225 00226 if ((pp_buffer == NULL) || (p_length == NULL)) 00227 { 00228 return NRF_ERROR_NULL; 00229 } 00230 00231 if (m_rx_buffer_queue.read_available_count != 0) 00232 { 00233 --(m_rx_buffer_queue.read_available_count); 00234 ++(m_rx_buffer_queue.free_available_count); 00235 00236 *pp_buffer = 00237 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer; 00238 *p_length = 00239 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length; 00240 00241 // @note: Adjust the write_index making use of the fact that the buffer size is of power 00242 // of two and two's complement arithmetic. For details refer example to book 00243 // "Making embedded systems: Elicia White". 00244 m_rx_buffer_queue.read_index = 00245 (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 00246 00247 err_code = NRF_SUCCESS; 00248 } 00249 else 00250 { 00251 err_code = NRF_ERROR_NO_MEM; 00252 } 00253 00254 return err_code; 00255 }
Generated on Tue Jul 12 2022 14:11:19 by
