BLE FOTA APP

Dependencies:   BLE_API mbed

It doesn't work with the default FOTA bootloader. It use NVIC_SystemReset() to enter a bootloader.

Committer:
yihui
Date:
Fri Oct 10 03:36:28 2014 +0000
Revision:
1:a607cd9655d7
use NVIC_SystemReset() to run bootloader

Who changed what in which revision?

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