Nordic stack and drivers for the mbed BLE API

Fork of nRF51822 by Nordic Semiconductor

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
640:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vincent Coubard 640:c90ae1400bf2 1 /*
Vincent Coubard 640:c90ae1400bf2 2 * Copyright (c) Nordic Semiconductor ASA
Vincent Coubard 640:c90ae1400bf2 3 * All rights reserved.
Vincent Coubard 640:c90ae1400bf2 4 *
Vincent Coubard 640:c90ae1400bf2 5 * Redistribution and use in source and binary forms, with or without modification,
Vincent Coubard 640:c90ae1400bf2 6 * are permitted provided that the following conditions are met:
Vincent Coubard 640:c90ae1400bf2 7 *
Vincent Coubard 640:c90ae1400bf2 8 * 1. Redistributions of source code must retain the above copyright notice, this
Vincent Coubard 640:c90ae1400bf2 9 * list of conditions and the following disclaimer.
Vincent Coubard 640:c90ae1400bf2 10 *
Vincent Coubard 640:c90ae1400bf2 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
Vincent Coubard 640:c90ae1400bf2 12 * list of conditions and the following disclaimer in the documentation and/or
Vincent Coubard 640:c90ae1400bf2 13 * other materials provided with the distribution.
Vincent Coubard 640:c90ae1400bf2 14 *
Vincent Coubard 640:c90ae1400bf2 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
Vincent Coubard 640:c90ae1400bf2 16 * contributors to this software may be used to endorse or promote products
Vincent Coubard 640:c90ae1400bf2 17 * derived from this software without specific prior written permission.
Vincent Coubard 640:c90ae1400bf2 18 *
Vincent Coubard 640:c90ae1400bf2 19 *
Vincent Coubard 640:c90ae1400bf2 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Vincent Coubard 640:c90ae1400bf2 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Vincent Coubard 640:c90ae1400bf2 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Vincent Coubard 640:c90ae1400bf2 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
Vincent Coubard 640:c90ae1400bf2 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Vincent Coubard 640:c90ae1400bf2 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Vincent Coubard 640:c90ae1400bf2 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Vincent Coubard 640:c90ae1400bf2 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Vincent Coubard 640:c90ae1400bf2 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Vincent Coubard 640:c90ae1400bf2 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Vincent Coubard 640:c90ae1400bf2 30 *
Vincent Coubard 640:c90ae1400bf2 31 */
Vincent Coubard 640:c90ae1400bf2 32
Vincent Coubard 640:c90ae1400bf2 33 #include "ble_flash.h"
Vincent Coubard 640:c90ae1400bf2 34 #include <stdlib.h>
Vincent Coubard 640:c90ae1400bf2 35 #include <stdint.h>
Vincent Coubard 640:c90ae1400bf2 36 #include <string.h>
Vincent Coubard 640:c90ae1400bf2 37 #include "nrf_soc.h"
Vincent Coubard 640:c90ae1400bf2 38 #include "nordic_common.h"
Vincent Coubard 640:c90ae1400bf2 39 #include "nrf_error.h"
Vincent Coubard 640:c90ae1400bf2 40 #include "nrf.h"
Vincent Coubard 640:c90ae1400bf2 41 #include "app_util.h"
Vincent Coubard 640:c90ae1400bf2 42
Vincent Coubard 640:c90ae1400bf2 43
Vincent Coubard 640:c90ae1400bf2 44 static volatile bool m_radio_active = false; /**< TRUE if radio is active (or about to become active), FALSE otherwise. */
Vincent Coubard 640:c90ae1400bf2 45
Vincent Coubard 640:c90ae1400bf2 46
Vincent Coubard 640:c90ae1400bf2 47 uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc)
Vincent Coubard 640:c90ae1400bf2 48 {
Vincent Coubard 640:c90ae1400bf2 49 uint16_t i;
Vincent Coubard 640:c90ae1400bf2 50 uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc;
Vincent Coubard 640:c90ae1400bf2 51
Vincent Coubard 640:c90ae1400bf2 52 for (i = 0; i < size; i++)
Vincent Coubard 640:c90ae1400bf2 53 {
Vincent Coubard 640:c90ae1400bf2 54 crc = (unsigned char)(crc >> 8) | (crc << 8);
Vincent Coubard 640:c90ae1400bf2 55 crc ^= p_data[i];
Vincent Coubard 640:c90ae1400bf2 56 crc ^= (unsigned char)(crc & 0xff) >> 4;
Vincent Coubard 640:c90ae1400bf2 57 crc ^= (crc << 8) << 4;
Vincent Coubard 640:c90ae1400bf2 58 crc ^= ((crc & 0xff) << 4) << 1;
Vincent Coubard 640:c90ae1400bf2 59 }
Vincent Coubard 640:c90ae1400bf2 60 return crc;
Vincent Coubard 640:c90ae1400bf2 61 }
Vincent Coubard 640:c90ae1400bf2 62
Vincent Coubard 640:c90ae1400bf2 63
Vincent Coubard 640:c90ae1400bf2 64 /**@brief Function for erasing a page in flash.
Vincent Coubard 640:c90ae1400bf2 65 *
Vincent Coubard 640:c90ae1400bf2 66 * @param[in] p_page Pointer to first word in page to be erased.
Vincent Coubard 640:c90ae1400bf2 67 */
Vincent Coubard 640:c90ae1400bf2 68 static void flash_page_erase(uint32_t * p_page)
Vincent Coubard 640:c90ae1400bf2 69 {
Vincent Coubard 640:c90ae1400bf2 70 // Turn on flash erase enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 71 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 72 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 73 {
Vincent Coubard 640:c90ae1400bf2 74 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 75 }
Vincent Coubard 640:c90ae1400bf2 76
Vincent Coubard 640:c90ae1400bf2 77 // Erase page.
Vincent Coubard 640:c90ae1400bf2 78 NRF_NVMC->ERASEPAGE = (uint32_t)p_page;
Vincent Coubard 640:c90ae1400bf2 79 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 80 {
Vincent Coubard 640:c90ae1400bf2 81 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 82 }
Vincent Coubard 640:c90ae1400bf2 83
Vincent Coubard 640:c90ae1400bf2 84 // Turn off flash erase enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 85 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 86 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 87 {
Vincent Coubard 640:c90ae1400bf2 88 // Do nothing
Vincent Coubard 640:c90ae1400bf2 89 }
Vincent Coubard 640:c90ae1400bf2 90 }
Vincent Coubard 640:c90ae1400bf2 91
Vincent Coubard 640:c90ae1400bf2 92
Vincent Coubard 640:c90ae1400bf2 93 /**@brief Function for writing one word to flash. Unprotected write, which can interfere with radio communication.
Vincent Coubard 640:c90ae1400bf2 94 *
Vincent Coubard 640:c90ae1400bf2 95 * @details This function DOES NOT use the m_radio_active variable, but will force the write even
Vincent Coubard 640:c90ae1400bf2 96 * when the radio is active. To be used only from @ref ble_flash_page_write.
Vincent Coubard 640:c90ae1400bf2 97 *
Vincent Coubard 640:c90ae1400bf2 98 * @note Flash location to be written must have been erased previously.
Vincent Coubard 640:c90ae1400bf2 99 *
Vincent Coubard 640:c90ae1400bf2 100 * @param[in] p_address Pointer to flash location to be written.
Vincent Coubard 640:c90ae1400bf2 101 * @param[in] value Value to write to flash.
Vincent Coubard 640:c90ae1400bf2 102 */
Vincent Coubard 640:c90ae1400bf2 103 static void flash_word_unprotected_write(uint32_t * p_address, uint32_t value)
Vincent Coubard 640:c90ae1400bf2 104 {
Vincent Coubard 640:c90ae1400bf2 105 // Turn on flash write enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 106 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 107 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 108 {
Vincent Coubard 640:c90ae1400bf2 109 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 110 }
Vincent Coubard 640:c90ae1400bf2 111 *p_address = value;
Vincent Coubard 640:c90ae1400bf2 112
Vincent Coubard 640:c90ae1400bf2 113 // Wait flash write to finish
Vincent Coubard 640:c90ae1400bf2 114 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 115 {
Vincent Coubard 640:c90ae1400bf2 116 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 117 }
Vincent Coubard 640:c90ae1400bf2 118
Vincent Coubard 640:c90ae1400bf2 119 // Turn off flash write enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 120 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 121 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 122 {
Vincent Coubard 640:c90ae1400bf2 123 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 124 }
Vincent Coubard 640:c90ae1400bf2 125 }
Vincent Coubard 640:c90ae1400bf2 126
Vincent Coubard 640:c90ae1400bf2 127
Vincent Coubard 640:c90ae1400bf2 128 /**@brief Function for writing one word to flash.
Vincent Coubard 640:c90ae1400bf2 129 *
Vincent Coubard 640:c90ae1400bf2 130 * @note Flash location to be written must have been erased previously.
Vincent Coubard 640:c90ae1400bf2 131 *
Vincent Coubard 640:c90ae1400bf2 132 * @param[in] p_address Pointer to flash location to be written.
Vincent Coubard 640:c90ae1400bf2 133 * @param[in] value Value to write to flash.
Vincent Coubard 640:c90ae1400bf2 134 */
Vincent Coubard 640:c90ae1400bf2 135 static void flash_word_write(uint32_t * p_address, uint32_t value)
Vincent Coubard 640:c90ae1400bf2 136 {
Vincent Coubard 640:c90ae1400bf2 137 // If radio is active, wait for it to become inactive.
Vincent Coubard 640:c90ae1400bf2 138 while (m_radio_active)
Vincent Coubard 640:c90ae1400bf2 139 {
Vincent Coubard 640:c90ae1400bf2 140 // Do nothing (just wait for radio to become inactive).
Vincent Coubard 640:c90ae1400bf2 141 (void) sd_app_evt_wait();
Vincent Coubard 640:c90ae1400bf2 142 }
Vincent Coubard 640:c90ae1400bf2 143
Vincent Coubard 640:c90ae1400bf2 144 // Turn on flash write enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 145 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 146 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 147 {
Vincent Coubard 640:c90ae1400bf2 148 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 149 }
Vincent Coubard 640:c90ae1400bf2 150
Vincent Coubard 640:c90ae1400bf2 151 *p_address = value;
Vincent Coubard 640:c90ae1400bf2 152 // Wait flash write to finish
Vincent Coubard 640:c90ae1400bf2 153 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 154 {
Vincent Coubard 640:c90ae1400bf2 155 // Do nothing.
Vincent Coubard 640:c90ae1400bf2 156 }
Vincent Coubard 640:c90ae1400bf2 157 // Turn off flash write enable and wait until the NVMC is ready.
Vincent Coubard 640:c90ae1400bf2 158 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
Vincent Coubard 640:c90ae1400bf2 159 while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
Vincent Coubard 640:c90ae1400bf2 160 {
Vincent Coubard 640:c90ae1400bf2 161 // Do nothing
Vincent Coubard 640:c90ae1400bf2 162 }
Vincent Coubard 640:c90ae1400bf2 163 }
Vincent Coubard 640:c90ae1400bf2 164
Vincent Coubard 640:c90ae1400bf2 165
Vincent Coubard 640:c90ae1400bf2 166 uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value)
Vincent Coubard 640:c90ae1400bf2 167 {
Vincent Coubard 640:c90ae1400bf2 168 flash_word_write(p_address, value);
Vincent Coubard 640:c90ae1400bf2 169 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 170 }
Vincent Coubard 640:c90ae1400bf2 171
Vincent Coubard 640:c90ae1400bf2 172
Vincent Coubard 640:c90ae1400bf2 173 uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count)
Vincent Coubard 640:c90ae1400bf2 174 {
Vincent Coubard 640:c90ae1400bf2 175 uint16_t i;
Vincent Coubard 640:c90ae1400bf2 176
Vincent Coubard 640:c90ae1400bf2 177 for (i = 0; i < word_count; i++)
Vincent Coubard 640:c90ae1400bf2 178 {
Vincent Coubard 640:c90ae1400bf2 179 flash_word_write(p_address, p_in_array[i]);
Vincent Coubard 640:c90ae1400bf2 180 p_address++;
Vincent Coubard 640:c90ae1400bf2 181 }
Vincent Coubard 640:c90ae1400bf2 182
Vincent Coubard 640:c90ae1400bf2 183 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 184 }
Vincent Coubard 640:c90ae1400bf2 185
Vincent Coubard 640:c90ae1400bf2 186
Vincent Coubard 640:c90ae1400bf2 187 uint32_t ble_flash_page_erase(uint8_t page_num)
Vincent Coubard 640:c90ae1400bf2 188 {
Vincent Coubard 640:c90ae1400bf2 189 uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
Vincent Coubard 640:c90ae1400bf2 190 flash_page_erase(p_page);
Vincent Coubard 640:c90ae1400bf2 191
Vincent Coubard 640:c90ae1400bf2 192 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 193 }
Vincent Coubard 640:c90ae1400bf2 194
Vincent Coubard 640:c90ae1400bf2 195
Vincent Coubard 640:c90ae1400bf2 196 uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count)
Vincent Coubard 640:c90ae1400bf2 197 {
Vincent Coubard 640:c90ae1400bf2 198 int i;
Vincent Coubard 640:c90ae1400bf2 199 uint32_t * p_page;
Vincent Coubard 640:c90ae1400bf2 200 uint32_t * p_curr_addr;
Vincent Coubard 640:c90ae1400bf2 201 uint16_t in_data_crc;
Vincent Coubard 640:c90ae1400bf2 202 uint16_t flash_crc;
Vincent Coubard 640:c90ae1400bf2 203 uint32_t flash_header;
Vincent Coubard 640:c90ae1400bf2 204
Vincent Coubard 640:c90ae1400bf2 205 p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
Vincent Coubard 640:c90ae1400bf2 206 p_curr_addr = p_page;
Vincent Coubard 640:c90ae1400bf2 207
Vincent Coubard 640:c90ae1400bf2 208 // Calculate CRC of the data to write.
Vincent Coubard 640:c90ae1400bf2 209 in_data_crc = ble_flash_crc16_compute((uint8_t *)p_in_array,
Vincent Coubard 640:c90ae1400bf2 210 word_count * sizeof(uint32_t),
Vincent Coubard 640:c90ae1400bf2 211 NULL);
Vincent Coubard 640:c90ae1400bf2 212
Vincent Coubard 640:c90ae1400bf2 213 // Compare the calculated to the one in flash.
Vincent Coubard 640:c90ae1400bf2 214 flash_header = *p_curr_addr;
Vincent Coubard 640:c90ae1400bf2 215 flash_crc = (uint16_t)flash_header;
Vincent Coubard 640:c90ae1400bf2 216
Vincent Coubard 640:c90ae1400bf2 217 if (flash_crc == in_data_crc)
Vincent Coubard 640:c90ae1400bf2 218 {
Vincent Coubard 640:c90ae1400bf2 219 // Data is the same as the data already stored in flash, return without modifying flash.
Vincent Coubard 640:c90ae1400bf2 220 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 221 }
Vincent Coubard 640:c90ae1400bf2 222
Vincent Coubard 640:c90ae1400bf2 223 // Erase flash page
Vincent Coubard 640:c90ae1400bf2 224 flash_page_erase(p_page);
Vincent Coubard 640:c90ae1400bf2 225
Vincent Coubard 640:c90ae1400bf2 226 // Reserve space for magic number (for detecting if flash content is valid).
Vincent Coubard 640:c90ae1400bf2 227 p_curr_addr++;
Vincent Coubard 640:c90ae1400bf2 228
Vincent Coubard 640:c90ae1400bf2 229 // Reserve space for saving word_count.
Vincent Coubard 640:c90ae1400bf2 230 p_curr_addr++;
Vincent Coubard 640:c90ae1400bf2 231
Vincent Coubard 640:c90ae1400bf2 232 // Write data
Vincent Coubard 640:c90ae1400bf2 233 for (i = 0; i < word_count; i++)
Vincent Coubard 640:c90ae1400bf2 234 {
Vincent Coubard 640:c90ae1400bf2 235 flash_word_unprotected_write(p_curr_addr, p_in_array[i]);
Vincent Coubard 640:c90ae1400bf2 236 p_curr_addr++;
Vincent Coubard 640:c90ae1400bf2 237 }
Vincent Coubard 640:c90ae1400bf2 238
Vincent Coubard 640:c90ae1400bf2 239 // Write number of elements.
Vincent Coubard 640:c90ae1400bf2 240 flash_word_write(p_page + 1, (uint32_t)(word_count));
Vincent Coubard 640:c90ae1400bf2 241
Vincent Coubard 640:c90ae1400bf2 242 // Write magic number and CRC to indicate that flash content is valid.
Vincent Coubard 640:c90ae1400bf2 243 flash_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)in_data_crc;
Vincent Coubard 640:c90ae1400bf2 244 flash_word_write(p_page, flash_header);
Vincent Coubard 640:c90ae1400bf2 245
Vincent Coubard 640:c90ae1400bf2 246 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 247 }
Vincent Coubard 640:c90ae1400bf2 248
Vincent Coubard 640:c90ae1400bf2 249
Vincent Coubard 640:c90ae1400bf2 250 uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count)
Vincent Coubard 640:c90ae1400bf2 251 {
Vincent Coubard 640:c90ae1400bf2 252 int byte_count;
Vincent Coubard 640:c90ae1400bf2 253 uint32_t * p_page;
Vincent Coubard 640:c90ae1400bf2 254 uint32_t * p_curr_addr;
Vincent Coubard 640:c90ae1400bf2 255 uint32_t flash_header;
Vincent Coubard 640:c90ae1400bf2 256 uint32_t calc_header;
Vincent Coubard 640:c90ae1400bf2 257 uint16_t calc_crc;
Vincent Coubard 640:c90ae1400bf2 258 uint32_t tmp;
Vincent Coubard 640:c90ae1400bf2 259
Vincent Coubard 640:c90ae1400bf2 260 p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
Vincent Coubard 640:c90ae1400bf2 261 p_curr_addr = p_page;
Vincent Coubard 640:c90ae1400bf2 262
Vincent Coubard 640:c90ae1400bf2 263 // Check if block is valid
Vincent Coubard 640:c90ae1400bf2 264 flash_header = *p_curr_addr;
Vincent Coubard 640:c90ae1400bf2 265 tmp = flash_header & 0xFFFF0000;
Vincent Coubard 640:c90ae1400bf2 266 if (tmp != BLE_FLASH_MAGIC_NUMBER)
Vincent Coubard 640:c90ae1400bf2 267 {
Vincent Coubard 640:c90ae1400bf2 268 *p_word_count = 0;
Vincent Coubard 640:c90ae1400bf2 269 return NRF_ERROR_NOT_FOUND;
Vincent Coubard 640:c90ae1400bf2 270 }
Vincent Coubard 640:c90ae1400bf2 271 p_curr_addr++;
Vincent Coubard 640:c90ae1400bf2 272
Vincent Coubard 640:c90ae1400bf2 273 // Read number of elements
Vincent Coubard 640:c90ae1400bf2 274 *p_word_count = (uint8_t)(*(p_curr_addr));
Vincent Coubard 640:c90ae1400bf2 275 p_curr_addr++;
Vincent Coubard 640:c90ae1400bf2 276
Vincent Coubard 640:c90ae1400bf2 277 // Read data
Vincent Coubard 640:c90ae1400bf2 278 byte_count = (*p_word_count) * sizeof(uint32_t);
Vincent Coubard 640:c90ae1400bf2 279 memcpy(p_out_array, p_curr_addr, byte_count);
Vincent Coubard 640:c90ae1400bf2 280
Vincent Coubard 640:c90ae1400bf2 281 // Check CRC
Vincent Coubard 640:c90ae1400bf2 282 calc_crc = ble_flash_crc16_compute((uint8_t *)p_out_array,
Vincent Coubard 640:c90ae1400bf2 283 (*p_word_count) * sizeof(uint32_t),
Vincent Coubard 640:c90ae1400bf2 284 NULL);
Vincent Coubard 640:c90ae1400bf2 285 calc_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)calc_crc;
Vincent Coubard 640:c90ae1400bf2 286
Vincent Coubard 640:c90ae1400bf2 287 if (calc_header != flash_header)
Vincent Coubard 640:c90ae1400bf2 288 {
Vincent Coubard 640:c90ae1400bf2 289 return NRF_ERROR_NOT_FOUND;
Vincent Coubard 640:c90ae1400bf2 290 }
Vincent Coubard 640:c90ae1400bf2 291
Vincent Coubard 640:c90ae1400bf2 292 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 293 }
Vincent Coubard 640:c90ae1400bf2 294
Vincent Coubard 640:c90ae1400bf2 295
Vincent Coubard 640:c90ae1400bf2 296 uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr)
Vincent Coubard 640:c90ae1400bf2 297 {
Vincent Coubard 640:c90ae1400bf2 298 *pp_page_addr = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
Vincent Coubard 640:c90ae1400bf2 299 return NRF_SUCCESS;
Vincent Coubard 640:c90ae1400bf2 300 }
Vincent Coubard 640:c90ae1400bf2 301
Vincent Coubard 640:c90ae1400bf2 302
Vincent Coubard 640:c90ae1400bf2 303 void ble_flash_on_radio_active_evt(bool radio_active)
Vincent Coubard 640:c90ae1400bf2 304 {
Vincent Coubard 640:c90ae1400bf2 305 m_radio_active = radio_active;
Vincent Coubard 640:c90ae1400bf2 306 }