Nordic stack and drivers for the mbed BLE API

Dependents:   idd_hw5_bleFanProto

Fork of nRF51822 by Nordic Semiconductor

Committer:
pgao
Date:
Thu Nov 06 05:29:15 2014 +0000
Revision:
70:c36c550b7208
Parent:
46:2bfbbe290083
asdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rohit Grover 46:2bfbbe290083 1 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
Rohit Grover 46:2bfbbe290083 2 *
Rohit Grover 46:2bfbbe290083 3 * The information contained herein is property of Nordic Semiconductor ASA.
Rohit Grover 46:2bfbbe290083 4 * Terms and conditions of usage are described in detail in NORDIC
Rohit Grover 46:2bfbbe290083 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Rohit Grover 46:2bfbbe290083 6 *
Rohit Grover 46:2bfbbe290083 7 * Licensees are granted free, non-transferable use of the information. NO
Rohit Grover 46:2bfbbe290083 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
Rohit Grover 46:2bfbbe290083 9 * the file.
Rohit Grover 46:2bfbbe290083 10 *
Rohit Grover 46:2bfbbe290083 11 */
Rohit Grover 46:2bfbbe290083 12
Rohit Grover 46:2bfbbe290083 13 #include "hci_mem_pool.h"
Rohit Grover 46:2bfbbe290083 14 #include "hci_mem_pool_internal.h"
Rohit Grover 46:2bfbbe290083 15 #include <stdbool.h>
Rohit Grover 46:2bfbbe290083 16 #include <stdio.h>
Rohit Grover 46:2bfbbe290083 17
Rohit Grover 46:2bfbbe290083 18 /**@brief RX buffer element instance structure.
Rohit Grover 46:2bfbbe290083 19 */
Rohit Grover 46:2bfbbe290083 20 typedef struct
Rohit Grover 46:2bfbbe290083 21 {
Rohit Grover 46:2bfbbe290083 22 uint8_t rx_buffer[RX_BUF_SIZE]; /**< RX buffer memory array. */
Rohit Grover 46:2bfbbe290083 23 uint32_t length; /**< Length of the RX buffer memory array. */
Rohit Grover 46:2bfbbe290083 24 } rx_buffer_elem_t;
Rohit Grover 46:2bfbbe290083 25
Rohit Grover 46:2bfbbe290083 26 /**@brief RX buffer queue element instance structure.
Rohit Grover 46:2bfbbe290083 27 */
Rohit Grover 46:2bfbbe290083 28 typedef struct
Rohit Grover 46:2bfbbe290083 29 {
Rohit Grover 46:2bfbbe290083 30 rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */
Rohit Grover 46:2bfbbe290083 31 uint32_t free_window_count; /**< Free space element count. */
Rohit Grover 46:2bfbbe290083 32 uint32_t free_available_count; /**< Free area element count. */
Rohit Grover 46:2bfbbe290083 33 uint32_t read_available_count; /**< Read area element count. */
Rohit Grover 46:2bfbbe290083 34 uint32_t write_index; /**< Write position index. */
Rohit Grover 46:2bfbbe290083 35 uint32_t read_index; /**< Read position index. */
Rohit Grover 46:2bfbbe290083 36 uint32_t free_index; /**< Free position index. */
Rohit Grover 46:2bfbbe290083 37 } rx_buffer_queue_t;
Rohit Grover 46:2bfbbe290083 38
Rohit Grover 46:2bfbbe290083 39 static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */
Rohit Grover 46:2bfbbe290083 40 static rx_buffer_elem_t m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
Rohit Grover 46:2bfbbe290083 41 static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */
Rohit Grover 46:2bfbbe290083 42
Rohit Grover 46:2bfbbe290083 43
Rohit Grover 46:2bfbbe290083 44 uint32_t hci_mem_pool_open(void)
Rohit Grover 46:2bfbbe290083 45 {
Rohit Grover 46:2bfbbe290083 46 m_is_tx_allocated = false;
Rohit Grover 46:2bfbbe290083 47 m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue;
Rohit Grover 46:2bfbbe290083 48 m_rx_buffer_queue.free_window_count = RX_BUF_QUEUE_SIZE;
Rohit Grover 46:2bfbbe290083 49 m_rx_buffer_queue.free_available_count = 0;
Rohit Grover 46:2bfbbe290083 50 m_rx_buffer_queue.read_available_count = 0;
Rohit Grover 46:2bfbbe290083 51 m_rx_buffer_queue.write_index = 0;
Rohit Grover 46:2bfbbe290083 52 m_rx_buffer_queue.read_index = 0;
Rohit Grover 46:2bfbbe290083 53 m_rx_buffer_queue.free_index = 0;
Rohit Grover 46:2bfbbe290083 54
Rohit Grover 46:2bfbbe290083 55 return NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 56 }
Rohit Grover 46:2bfbbe290083 57
Rohit Grover 46:2bfbbe290083 58
Rohit Grover 46:2bfbbe290083 59 uint32_t hci_mem_pool_close(void)
Rohit Grover 46:2bfbbe290083 60 {
Rohit Grover 46:2bfbbe290083 61 return NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 62 }
Rohit Grover 46:2bfbbe290083 63
Rohit Grover 46:2bfbbe290083 64
Rohit Grover 46:2bfbbe290083 65 uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
Rohit Grover 46:2bfbbe290083 66 {
Rohit Grover 46:2bfbbe290083 67 static uint8_t tx_buffer[TX_BUF_SIZE];
Rohit Grover 46:2bfbbe290083 68
Rohit Grover 46:2bfbbe290083 69 uint32_t err_code;
Rohit Grover 46:2bfbbe290083 70
Rohit Grover 46:2bfbbe290083 71 if (pp_buffer == NULL)
Rohit Grover 46:2bfbbe290083 72 {
Rohit Grover 46:2bfbbe290083 73 return NRF_ERROR_NULL;
Rohit Grover 46:2bfbbe290083 74 }
Rohit Grover 46:2bfbbe290083 75
Rohit Grover 46:2bfbbe290083 76 if (!m_is_tx_allocated)
Rohit Grover 46:2bfbbe290083 77 {
Rohit Grover 46:2bfbbe290083 78 m_is_tx_allocated = true;
Rohit Grover 46:2bfbbe290083 79 *pp_buffer = tx_buffer;
Rohit Grover 46:2bfbbe290083 80 err_code = NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 81 }
Rohit Grover 46:2bfbbe290083 82 else
Rohit Grover 46:2bfbbe290083 83 {
Rohit Grover 46:2bfbbe290083 84 err_code = NRF_ERROR_NO_MEM;
Rohit Grover 46:2bfbbe290083 85 }
Rohit Grover 46:2bfbbe290083 86
Rohit Grover 46:2bfbbe290083 87 return err_code;
Rohit Grover 46:2bfbbe290083 88 }
Rohit Grover 46:2bfbbe290083 89
Rohit Grover 46:2bfbbe290083 90
Rohit Grover 46:2bfbbe290083 91 uint32_t hci_mem_pool_tx_free(void)
Rohit Grover 46:2bfbbe290083 92 {
Rohit Grover 46:2bfbbe290083 93 m_is_tx_allocated = false;
Rohit Grover 46:2bfbbe290083 94
Rohit Grover 46:2bfbbe290083 95 return NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 96 }
Rohit Grover 46:2bfbbe290083 97
Rohit Grover 46:2bfbbe290083 98
Rohit Grover 46:2bfbbe290083 99 uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
Rohit Grover 46:2bfbbe290083 100 {
Rohit Grover 46:2bfbbe290083 101 uint32_t err_code;
Rohit Grover 46:2bfbbe290083 102
Rohit Grover 46:2bfbbe290083 103 if (pp_buffer == NULL)
Rohit Grover 46:2bfbbe290083 104 {
Rohit Grover 46:2bfbbe290083 105 return NRF_ERROR_NULL;
Rohit Grover 46:2bfbbe290083 106 }
Rohit Grover 46:2bfbbe290083 107 *pp_buffer = NULL;
Rohit Grover 46:2bfbbe290083 108
Rohit Grover 46:2bfbbe290083 109 if (m_rx_buffer_queue.free_window_count != 0)
Rohit Grover 46:2bfbbe290083 110 {
Rohit Grover 46:2bfbbe290083 111 if (length <= RX_BUF_SIZE)
Rohit Grover 46:2bfbbe290083 112 {
Rohit Grover 46:2bfbbe290083 113 --(m_rx_buffer_queue.free_window_count);
Rohit Grover 46:2bfbbe290083 114 ++(m_rx_buffer_queue.read_available_count);
Rohit Grover 46:2bfbbe290083 115
Rohit Grover 46:2bfbbe290083 116 *pp_buffer =
Rohit Grover 46:2bfbbe290083 117 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
Rohit Grover 46:2bfbbe290083 118
Rohit Grover 46:2bfbbe290083 119 m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
Rohit Grover 46:2bfbbe290083 120
Rohit Grover 46:2bfbbe290083 121 // @note: Adjust the write_index making use of the fact that the buffer size is of
Rohit Grover 46:2bfbbe290083 122 // power of two and two's complement arithmetic. For details refer example to book
Rohit Grover 46:2bfbbe290083 123 // "Making embedded systems: Elicia White".
Rohit Grover 46:2bfbbe290083 124 m_rx_buffer_queue.write_index =
Rohit Grover 46:2bfbbe290083 125 (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 126
Rohit Grover 46:2bfbbe290083 127 err_code = NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 128 }
Rohit Grover 46:2bfbbe290083 129 else
Rohit Grover 46:2bfbbe290083 130 {
Rohit Grover 46:2bfbbe290083 131 err_code = NRF_ERROR_DATA_SIZE;
Rohit Grover 46:2bfbbe290083 132 }
Rohit Grover 46:2bfbbe290083 133 }
Rohit Grover 46:2bfbbe290083 134 else
Rohit Grover 46:2bfbbe290083 135 {
Rohit Grover 46:2bfbbe290083 136 err_code = NRF_ERROR_NO_MEM;
Rohit Grover 46:2bfbbe290083 137 }
Rohit Grover 46:2bfbbe290083 138
Rohit Grover 46:2bfbbe290083 139 return err_code;
Rohit Grover 46:2bfbbe290083 140 }
Rohit Grover 46:2bfbbe290083 141
Rohit Grover 46:2bfbbe290083 142
Rohit Grover 46:2bfbbe290083 143 uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
Rohit Grover 46:2bfbbe290083 144 {
Rohit Grover 46:2bfbbe290083 145 uint32_t err_code;
Rohit Grover 46:2bfbbe290083 146 uint32_t consume_index;
Rohit Grover 46:2bfbbe290083 147 uint32_t start_index;
Rohit Grover 46:2bfbbe290083 148
Rohit Grover 46:2bfbbe290083 149 if (m_rx_buffer_queue.free_available_count != 0)
Rohit Grover 46:2bfbbe290083 150 {
Rohit Grover 46:2bfbbe290083 151 // Find the buffer that has been freed -
Rohit Grover 46:2bfbbe290083 152 // Start at read_index minus free_available_count and then increment until read index.
Rohit Grover 46:2bfbbe290083 153 err_code = NRF_ERROR_INVALID_ADDR;
Rohit Grover 46:2bfbbe290083 154 consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) &
Rohit Grover 46:2bfbbe290083 155 (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 156 start_index = consume_index;
Rohit Grover 46:2bfbbe290083 157
Rohit Grover 46:2bfbbe290083 158 do
Rohit Grover 46:2bfbbe290083 159 {
Rohit Grover 46:2bfbbe290083 160 if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
Rohit Grover 46:2bfbbe290083 161 {
Rohit Grover 46:2bfbbe290083 162 m_rx_buffer_queue.free_index ^= (1u << consume_index);
Rohit Grover 46:2bfbbe290083 163 err_code = NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 164 break;
Rohit Grover 46:2bfbbe290083 165 }
Rohit Grover 46:2bfbbe290083 166 else
Rohit Grover 46:2bfbbe290083 167 {
Rohit Grover 46:2bfbbe290083 168 consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 169 }
Rohit Grover 46:2bfbbe290083 170 }
Rohit Grover 46:2bfbbe290083 171 while (consume_index != m_rx_buffer_queue.read_index);
Rohit Grover 46:2bfbbe290083 172
Rohit Grover 46:2bfbbe290083 173 while (!(m_rx_buffer_queue.free_index & (1 << start_index)) &&
Rohit Grover 46:2bfbbe290083 174 (m_rx_buffer_queue.free_available_count != 0))
Rohit Grover 46:2bfbbe290083 175 {
Rohit Grover 46:2bfbbe290083 176 --(m_rx_buffer_queue.free_available_count);
Rohit Grover 46:2bfbbe290083 177 ++(m_rx_buffer_queue.free_window_count);
Rohit Grover 46:2bfbbe290083 178 start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 179 }
Rohit Grover 46:2bfbbe290083 180 }
Rohit Grover 46:2bfbbe290083 181 else
Rohit Grover 46:2bfbbe290083 182 {
Rohit Grover 46:2bfbbe290083 183 err_code = NRF_ERROR_NO_MEM;
Rohit Grover 46:2bfbbe290083 184 }
Rohit Grover 46:2bfbbe290083 185
Rohit Grover 46:2bfbbe290083 186 return err_code;
Rohit Grover 46:2bfbbe290083 187 }
Rohit Grover 46:2bfbbe290083 188
Rohit Grover 46:2bfbbe290083 189
Rohit Grover 46:2bfbbe290083 190 uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
Rohit Grover 46:2bfbbe290083 191 {
Rohit Grover 46:2bfbbe290083 192 // @note: Adjust the write_index making use of the fact that the buffer size is of power
Rohit Grover 46:2bfbbe290083 193 // of two and two's complement arithmetic. For details refer example to book
Rohit Grover 46:2bfbbe290083 194 // "Making embedded systems: Elicia White".
Rohit Grover 46:2bfbbe290083 195 const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 196 m_rx_buffer_queue.p_buffer[index].length = length;
Rohit Grover 46:2bfbbe290083 197
Rohit Grover 46:2bfbbe290083 198 return NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 199 }
Rohit Grover 46:2bfbbe290083 200
Rohit Grover 46:2bfbbe290083 201
Rohit Grover 46:2bfbbe290083 202 uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
Rohit Grover 46:2bfbbe290083 203 {
Rohit Grover 46:2bfbbe290083 204 uint32_t err_code;
Rohit Grover 46:2bfbbe290083 205
Rohit Grover 46:2bfbbe290083 206 if ((pp_buffer == NULL) || (p_length == NULL))
Rohit Grover 46:2bfbbe290083 207 {
Rohit Grover 46:2bfbbe290083 208 return NRF_ERROR_NULL;
Rohit Grover 46:2bfbbe290083 209 }
Rohit Grover 46:2bfbbe290083 210
Rohit Grover 46:2bfbbe290083 211 if (m_rx_buffer_queue.read_available_count != 0)
Rohit Grover 46:2bfbbe290083 212 {
Rohit Grover 46:2bfbbe290083 213 --(m_rx_buffer_queue.read_available_count);
Rohit Grover 46:2bfbbe290083 214 ++(m_rx_buffer_queue.free_available_count);
Rohit Grover 46:2bfbbe290083 215
Rohit Grover 46:2bfbbe290083 216 *pp_buffer =
Rohit Grover 46:2bfbbe290083 217 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
Rohit Grover 46:2bfbbe290083 218 *p_length =
Rohit Grover 46:2bfbbe290083 219 m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
Rohit Grover 46:2bfbbe290083 220
Rohit Grover 46:2bfbbe290083 221 // @note: Adjust the write_index making use of the fact that the buffer size is of power
Rohit Grover 46:2bfbbe290083 222 // of two and two's complement arithmetic. For details refer example to book
Rohit Grover 46:2bfbbe290083 223 // "Making embedded systems: Elicia White".
Rohit Grover 46:2bfbbe290083 224 m_rx_buffer_queue.read_index =
Rohit Grover 46:2bfbbe290083 225 (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
Rohit Grover 46:2bfbbe290083 226
Rohit Grover 46:2bfbbe290083 227 err_code = NRF_SUCCESS;
Rohit Grover 46:2bfbbe290083 228 }
Rohit Grover 46:2bfbbe290083 229 else
Rohit Grover 46:2bfbbe290083 230 {
Rohit Grover 46:2bfbbe290083 231 err_code = NRF_ERROR_NO_MEM;
Rohit Grover 46:2bfbbe290083 232 }
Rohit Grover 46:2bfbbe290083 233
Rohit Grover 46:2bfbbe290083 234 return err_code;
Rohit Grover 46:2bfbbe290083 235 }