aconno flash API for nrf52832. (Modified mbed flash API)
aconno_flash.cpp@1:954ac9003e99, 2018-05-22 (annotated)
- Committer:
- jurica238814
- Date:
- Tue May 22 17:41:01 2018 +0200
- Revision:
- 1:954ac9003e99
- Parent:
- 0:eb5ed8411c6f
- Child:
- 2:e5390f8eab8c
functions renamed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jurica238814 | 0:eb5ed8411c6f | 1 | /** |
jurica238814 | 0:eb5ed8411c6f | 2 | * Made by Jurica Resetar @ aconno |
jurica238814 | 0:eb5ed8411c6f | 3 | * ResetarJurica@gmail.com |
jurica238814 | 0:eb5ed8411c6f | 4 | * More info @ aconno.de |
jurica238814 | 0:eb5ed8411c6f | 5 | * |
jurica238814 | 0:eb5ed8411c6f | 6 | */ |
jurica238814 | 0:eb5ed8411c6f | 7 | |
jurica238814 | 0:eb5ed8411c6f | 8 | /* |
jurica238814 | 0:eb5ed8411c6f | 9 | * Copyright (c) 2017 Nordic Semiconductor ASA |
jurica238814 | 0:eb5ed8411c6f | 10 | * All rights reserved. |
jurica238814 | 0:eb5ed8411c6f | 11 | * |
jurica238814 | 0:eb5ed8411c6f | 12 | * Redistribution and use in source and binary forms, with or without modification, |
jurica238814 | 0:eb5ed8411c6f | 13 | * are permitted provided that the following conditions are met: |
jurica238814 | 0:eb5ed8411c6f | 14 | * |
jurica238814 | 0:eb5ed8411c6f | 15 | * 1. Redistributions of source code must retain the above copyright notice, this list |
jurica238814 | 0:eb5ed8411c6f | 16 | * of conditions and the following disclaimer. |
jurica238814 | 0:eb5ed8411c6f | 17 | * |
jurica238814 | 0:eb5ed8411c6f | 18 | * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA |
jurica238814 | 0:eb5ed8411c6f | 19 | * integrated circuit in a product or a software update for such product, must reproduce |
jurica238814 | 0:eb5ed8411c6f | 20 | * the above copyright notice, this list of conditions and the following disclaimer in |
jurica238814 | 0:eb5ed8411c6f | 21 | * the documentation and/or other materials provided with the distribution. |
jurica238814 | 0:eb5ed8411c6f | 22 | * |
jurica238814 | 0:eb5ed8411c6f | 23 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be |
jurica238814 | 0:eb5ed8411c6f | 24 | * used to endorse or promote products derived from this software without specific prior |
jurica238814 | 0:eb5ed8411c6f | 25 | * written permission. |
jurica238814 | 0:eb5ed8411c6f | 26 | * |
jurica238814 | 0:eb5ed8411c6f | 27 | * 4. This software, with or without modification, must only be used with a |
jurica238814 | 0:eb5ed8411c6f | 28 | * Nordic Semiconductor ASA integrated circuit. |
jurica238814 | 0:eb5ed8411c6f | 29 | * |
jurica238814 | 0:eb5ed8411c6f | 30 | * 5. Any software provided in binary or object form under this license must not be reverse |
jurica238814 | 0:eb5ed8411c6f | 31 | * engineered, decompiled, modified and/or disassembled. |
jurica238814 | 0:eb5ed8411c6f | 32 | * |
jurica238814 | 0:eb5ed8411c6f | 33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
jurica238814 | 0:eb5ed8411c6f | 34 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
jurica238814 | 0:eb5ed8411c6f | 35 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
jurica238814 | 0:eb5ed8411c6f | 36 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
jurica238814 | 0:eb5ed8411c6f | 37 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
jurica238814 | 0:eb5ed8411c6f | 38 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
jurica238814 | 0:eb5ed8411c6f | 39 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
jurica238814 | 0:eb5ed8411c6f | 40 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
jurica238814 | 0:eb5ed8411c6f | 41 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
jurica238814 | 0:eb5ed8411c6f | 42 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
jurica238814 | 0:eb5ed8411c6f | 43 | * |
jurica238814 | 0:eb5ed8411c6f | 44 | */ |
jurica238814 | 0:eb5ed8411c6f | 45 | |
jurica238814 | 0:eb5ed8411c6f | 46 | #if DEVICE_FLASH |
jurica238814 | 0:eb5ed8411c6f | 47 | |
jurica238814 | 0:eb5ed8411c6f | 48 | #include "hal/flash_api.h" |
jurica238814 | 0:eb5ed8411c6f | 49 | #include "hal/lp_ticker_api.h" |
jurica238814 | 0:eb5ed8411c6f | 50 | |
jurica238814 | 0:eb5ed8411c6f | 51 | #include "nrf_drv_common.h" |
jurica238814 | 0:eb5ed8411c6f | 52 | #include "nrf_nvmc.h" |
jurica238814 | 0:eb5ed8411c6f | 53 | #include "nrf_soc.h" |
jurica238814 | 0:eb5ed8411c6f | 54 | |
jurica238814 | 0:eb5ed8411c6f | 55 | // Max. value from datasheet: 338 us |
jurica238814 | 0:eb5ed8411c6f | 56 | // // Constant increased by the author experimentaly |
jurica238814 | 0:eb5ed8411c6f | 57 | #define WORD_WRITE_TIMEOUT_US (1 * 100000) |
jurica238814 | 0:eb5ed8411c6f | 58 | // Max. value from datasheet: 89.7 ms |
jurica238814 | 0:eb5ed8411c6f | 59 | // Constant increased by the author experimentaly |
jurica238814 | 0:eb5ed8411c6f | 60 | #define PAGE_ERASE_TIMEOUT_US (200 * 10000) |
jurica238814 | 0:eb5ed8411c6f | 61 | |
jurica238814 | 0:eb5ed8411c6f | 62 | /* Macro for testing if the SoftDevice is active, regardless of whether the |
jurica238814 | 0:eb5ed8411c6f | 63 | * application is build with the SoftDevice or not. |
jurica238814 | 0:eb5ed8411c6f | 64 | */ |
jurica238814 | 0:eb5ed8411c6f | 65 | #if defined(SOFTDEVICE_PRESENT) |
jurica238814 | 0:eb5ed8411c6f | 66 | #include "nrf_sdm.h" |
jurica238814 | 0:eb5ed8411c6f | 67 | |
jurica238814 | 0:eb5ed8411c6f | 68 | static uint8_t wrapper(void) { |
jurica238814 | 0:eb5ed8411c6f | 69 | uint8_t softdevice_is_enabled; |
jurica238814 | 0:eb5ed8411c6f | 70 | ret_code_t result = sd_softdevice_is_enabled(&softdevice_is_enabled); |
jurica238814 | 0:eb5ed8411c6f | 71 | return ((result == NRF_SUCCESS) && (softdevice_is_enabled == 1)); |
jurica238814 | 0:eb5ed8411c6f | 72 | } |
jurica238814 | 0:eb5ed8411c6f | 73 | |
jurica238814 | 0:eb5ed8411c6f | 74 | #define NRF_HAL_SD_IS_ENABLED() wrapper() |
jurica238814 | 0:eb5ed8411c6f | 75 | #else |
jurica238814 | 0:eb5ed8411c6f | 76 | #define NRF_HAL_SD_IS_ENABLED() 0 |
jurica238814 | 0:eb5ed8411c6f | 77 | #endif |
jurica238814 | 0:eb5ed8411c6f | 78 | |
jurica238814 | 0:eb5ed8411c6f | 79 | |
jurica238814 | 1:954ac9003e99 | 80 | int32_t aconno_flash_init(flash_t *obj) |
jurica238814 | 0:eb5ed8411c6f | 81 | { |
jurica238814 | 0:eb5ed8411c6f | 82 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 83 | |
jurica238814 | 0:eb5ed8411c6f | 84 | /* Initialize low power ticker. Used for timeouts. */ |
jurica238814 | 0:eb5ed8411c6f | 85 | static bool first_init = true; |
jurica238814 | 0:eb5ed8411c6f | 86 | |
jurica238814 | 0:eb5ed8411c6f | 87 | if(first_init) |
jurica238814 | 0:eb5ed8411c6f | 88 | { |
jurica238814 | 0:eb5ed8411c6f | 89 | first_init = false; |
jurica238814 | 0:eb5ed8411c6f | 90 | lp_ticker_init(); |
jurica238814 | 0:eb5ed8411c6f | 91 | } |
jurica238814 | 0:eb5ed8411c6f | 92 | return 0; |
jurica238814 | 0:eb5ed8411c6f | 93 | } |
jurica238814 | 0:eb5ed8411c6f | 94 | |
jurica238814 | 1:954ac9003e99 | 95 | int32_t aconno_flash_free(flash_t *obj) |
jurica238814 | 0:eb5ed8411c6f | 96 | { |
jurica238814 | 0:eb5ed8411c6f | 97 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 98 | |
jurica238814 | 0:eb5ed8411c6f | 99 | return 0; |
jurica238814 | 0:eb5ed8411c6f | 100 | } |
jurica238814 | 0:eb5ed8411c6f | 101 | |
jurica238814 | 1:954ac9003e99 | 102 | int32_t aconno_flash_erase_sector(flash_t *obj, uint32_t address) |
jurica238814 | 0:eb5ed8411c6f | 103 | { |
jurica238814 | 0:eb5ed8411c6f | 104 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 105 | |
jurica238814 | 0:eb5ed8411c6f | 106 | /* Return value defaults to error. */ |
jurica238814 | 0:eb5ed8411c6f | 107 | uint32_t result = NRF_ERROR_BUSY; |
jurica238814 | 0:eb5ed8411c6f | 108 | |
jurica238814 | 0:eb5ed8411c6f | 109 | if(NRF_HAL_SD_IS_ENABLED()) |
jurica238814 | 0:eb5ed8411c6f | 110 | { |
jurica238814 | 0:eb5ed8411c6f | 111 | /* Convert address to page number. */ |
jurica238814 | 0:eb5ed8411c6f | 112 | uint32_t page_number = address / NRF_FICR->CODEPAGESIZE; |
jurica238814 | 0:eb5ed8411c6f | 113 | |
jurica238814 | 0:eb5ed8411c6f | 114 | /* Setup stop watch for timeout. */ |
jurica238814 | 0:eb5ed8411c6f | 115 | uint32_t start_us = lp_ticker_read(); |
jurica238814 | 0:eb5ed8411c6f | 116 | uint32_t now_us = start_us; |
jurica238814 | 0:eb5ed8411c6f | 117 | |
jurica238814 | 0:eb5ed8411c6f | 118 | /* Retry if flash is busy until timeout is reached. */ |
jurica238814 | 0:eb5ed8411c6f | 119 | while(((now_us - start_us) < PAGE_ERASE_TIMEOUT_US) && |
jurica238814 | 0:eb5ed8411c6f | 120 | (result == NRF_ERROR_BUSY)){ |
jurica238814 | 0:eb5ed8411c6f | 121 | |
jurica238814 | 0:eb5ed8411c6f | 122 | result = sd_flash_page_erase(page_number); |
jurica238814 | 0:eb5ed8411c6f | 123 | /* Read timeout timer. */ |
jurica238814 | 0:eb5ed8411c6f | 124 | now_us = lp_ticker_read(); |
jurica238814 | 0:eb5ed8411c6f | 125 | } |
jurica238814 | 0:eb5ed8411c6f | 126 | } |
jurica238814 | 0:eb5ed8411c6f | 127 | else |
jurica238814 | 0:eb5ed8411c6f | 128 | { |
jurica238814 | 0:eb5ed8411c6f | 129 | /* Raw API doesn't return error code, assume success. */ |
jurica238814 | 0:eb5ed8411c6f | 130 | nrf_nvmc_page_erase(address); |
jurica238814 | 0:eb5ed8411c6f | 131 | result = NRF_SUCCESS; |
jurica238814 | 0:eb5ed8411c6f | 132 | } |
jurica238814 | 0:eb5ed8411c6f | 133 | |
jurica238814 | 0:eb5ed8411c6f | 134 | /* Convert Nordic error code to mbed HAL error code. */ |
jurica238814 | 0:eb5ed8411c6f | 135 | return (result == NRF_SUCCESS) ? 0 : -1; |
jurica238814 | 0:eb5ed8411c6f | 136 | } |
jurica238814 | 0:eb5ed8411c6f | 137 | |
jurica238814 | 1:954ac9003e99 | 138 | int32_t aconno_flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) |
jurica238814 | 0:eb5ed8411c6f | 139 | { |
jurica238814 | 0:eb5ed8411c6f | 140 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 141 | |
jurica238814 | 0:eb5ed8411c6f | 142 | /* Return value defaults to error. */ |
jurica238814 | 0:eb5ed8411c6f | 143 | uint32_t result = NRF_ERROR_BUSY; |
jurica238814 | 0:eb5ed8411c6f | 144 | |
jurica238814 | 0:eb5ed8411c6f | 145 | /* Convert size to words. */ |
jurica238814 | 0:eb5ed8411c6f | 146 | uint32_t words = size / sizeof(uint32_t); |
jurica238814 | 0:eb5ed8411c6f | 147 | |
jurica238814 | 0:eb5ed8411c6f | 148 | if(NRF_HAL_SD_IS_ENABLED()){ |
jurica238814 | 0:eb5ed8411c6f | 149 | /* Setup stop watch for timeout. */ |
jurica238814 | 0:eb5ed8411c6f | 150 | uint32_t start_us = lp_ticker_read(); |
jurica238814 | 0:eb5ed8411c6f | 151 | uint32_t now_us = start_us; |
jurica238814 | 0:eb5ed8411c6f | 152 | |
jurica238814 | 0:eb5ed8411c6f | 153 | /* Retry if flash is busy until timeout is reached. */ |
jurica238814 | 0:eb5ed8411c6f | 154 | while(((now_us - start_us) < (words * WORD_WRITE_TIMEOUT_US)) && |
jurica238814 | 0:eb5ed8411c6f | 155 | (result == NRF_ERROR_BUSY)){ |
jurica238814 | 0:eb5ed8411c6f | 156 | result = sd_flash_write((uint32_t *) address, (const uint32_t *) data, words); |
jurica238814 | 0:eb5ed8411c6f | 157 | /* Read timeout timer. */ |
jurica238814 | 0:eb5ed8411c6f | 158 | now_us = lp_ticker_read(); |
jurica238814 | 0:eb5ed8411c6f | 159 | } |
jurica238814 | 0:eb5ed8411c6f | 160 | } |
jurica238814 | 0:eb5ed8411c6f | 161 | else |
jurica238814 | 0:eb5ed8411c6f | 162 | { |
jurica238814 | 0:eb5ed8411c6f | 163 | /* We will use *_words function to speed up flashing code. |
jurica238814 | 0:eb5ed8411c6f | 164 | * Word means 32bit -> 4B or sizeof(uint32_t). */ |
jurica238814 | 0:eb5ed8411c6f | 165 | nrf_nvmc_write_words(address, (const uint32_t *) data, words); |
jurica238814 | 0:eb5ed8411c6f | 166 | result = NRF_SUCCESS; |
jurica238814 | 0:eb5ed8411c6f | 167 | } |
jurica238814 | 0:eb5ed8411c6f | 168 | |
jurica238814 | 0:eb5ed8411c6f | 169 | /* Convert Nordic error code to mbed HAL error code. */ |
jurica238814 | 0:eb5ed8411c6f | 170 | return (result == NRF_SUCCESS) ? 0 : -1; |
jurica238814 | 0:eb5ed8411c6f | 171 | } |
jurica238814 | 0:eb5ed8411c6f | 172 | |
jurica238814 | 1:954ac9003e99 | 173 | uint32_t aconno_flash_get_size(const flash_t *obj) |
jurica238814 | 0:eb5ed8411c6f | 174 | { |
jurica238814 | 0:eb5ed8411c6f | 175 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 176 | |
jurica238814 | 0:eb5ed8411c6f | 177 | /* Just count flash size. */ |
jurica238814 | 0:eb5ed8411c6f | 178 | return NRF_FICR->CODESIZE * NRF_FICR->CODEPAGESIZE; |
jurica238814 | 0:eb5ed8411c6f | 179 | } |
jurica238814 | 0:eb5ed8411c6f | 180 | |
jurica238814 | 1:954ac9003e99 | 181 | uint32_t aconno_flash_get_sector_size(const flash_t *obj, uint32_t address) |
jurica238814 | 0:eb5ed8411c6f | 182 | { |
jurica238814 | 0:eb5ed8411c6f | 183 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 184 | |
jurica238814 | 0:eb5ed8411c6f | 185 | /* Test if passed address is in flash space. */ |
jurica238814 | 0:eb5ed8411c6f | 186 | if (address < flash_get_size(obj)) { |
jurica238814 | 0:eb5ed8411c6f | 187 | return NRF_FICR->CODEPAGESIZE; |
jurica238814 | 0:eb5ed8411c6f | 188 | } |
jurica238814 | 0:eb5ed8411c6f | 189 | |
jurica238814 | 0:eb5ed8411c6f | 190 | /* Something goes wrong, return invalid size error code. */ |
jurica238814 | 0:eb5ed8411c6f | 191 | return MBED_FLASH_INVALID_SIZE; |
jurica238814 | 0:eb5ed8411c6f | 192 | } |
jurica238814 | 0:eb5ed8411c6f | 193 | |
jurica238814 | 1:954ac9003e99 | 194 | uint32_t aconno_flash_get_page_size(const flash_t *obj) |
jurica238814 | 0:eb5ed8411c6f | 195 | { |
jurica238814 | 0:eb5ed8411c6f | 196 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 197 | /* Return minimum writeable size. Note that this is |
jurica238814 | 0:eb5ed8411c6f | 198 | different from the erase page size. */ |
jurica238814 | 0:eb5ed8411c6f | 199 | return 4; |
jurica238814 | 0:eb5ed8411c6f | 200 | } |
jurica238814 | 0:eb5ed8411c6f | 201 | |
jurica238814 | 1:954ac9003e99 | 202 | uint32_t aconno_flash_get_start_address(const flash_t *obj) |
jurica238814 | 0:eb5ed8411c6f | 203 | { |
jurica238814 | 0:eb5ed8411c6f | 204 | (void)(obj); |
jurica238814 | 0:eb5ed8411c6f | 205 | |
jurica238814 | 0:eb5ed8411c6f | 206 | return 0; |
jurica238814 | 0:eb5ed8411c6f | 207 | } |
jurica238814 | 0:eb5ed8411c6f | 208 | |
jurica238814 | 0:eb5ed8411c6f | 209 | #endif |
jurica238814 | 0:eb5ed8411c6f | 210 | /** @}*/ |