1 /* 2 * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /** 32 *@file 33 *@brief NMVC driver implementation 34 */ 35 36 #include <nrfx.h> 37 #include "nrf_nvmc.h" 38 39 static inline void wait_for_flash_ready(void) 40 { 41 while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;} 42 } 43 44 void nrf_nvmc_page_erase(uint32_t address) 45 { 46 // Enable erase. 47 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; 48 __ISB(); 49 __DSB(); 50 51 // Erase the page 52 NRF_NVMC->ERASEPAGE = address; 53 wait_for_flash_ready(); 54 55 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; 56 __ISB(); 57 __DSB(); 58 } 59 60 61 void nrf_nvmc_write_byte(uint32_t address, uint8_t value) 62 { 63 uint32_t byte_shift = address & (uint32_t)0x03; 64 uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. 65 uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); 66 value32 = value32 + ((uint32_t)value << (byte_shift << 3)); 67 68 // Enable write. 69 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); 70 __ISB(); 71 __DSB(); 72 73 *(uint32_t*)address32 = value32; 74 wait_for_flash_ready(); 75 76 NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); 77 __ISB(); 78 __DSB(); 79 } 80 81 void nrf_nvmc_write_word(uint32_t address, uint32_t value) 82 { 83 // Enable write. 84 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; 85 __ISB(); 86 __DSB(); 87 88 *(uint32_t*)address = value; 89 wait_for_flash_ready(); 90 91 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; 92 __ISB(); 93 __DSB(); 94 } 95 96 void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes) 97 { 98 uint32_t i; 99 for (i = 0; i < num_bytes; i++) 100 { 101 nrf_nvmc_write_byte(address + i,src[i]); 102 } 103 } 104 105 void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words) 106 { 107 uint32_t i; 108 109 // Enable write. 110 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; 111 __ISB(); 112 __DSB(); 113 114 for (i = 0; i < num_words; i++) 115 { 116 ((uint32_t*)address)[i] = src[i]; 117 wait_for_flash_ready(); 118 } 119 120 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; 121 __ISB(); 122 __DSB(); 123 } 124 125