mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
187:0387e8f68319
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 181:57724642e740 1 /* mbed Microcontroller Library
AnnaBridge 181:57724642e740 2 *******************************************************************************
AnnaBridge 181:57724642e740 3 * Copyright (c) 2016, MultiTech Systems
AnnaBridge 181:57724642e740 4 * All rights reserved.
AnnaBridge 181:57724642e740 5 *
AnnaBridge 181:57724642e740 6 * Redistribution and use in source and binary forms, with or without
AnnaBridge 181:57724642e740 7 * modification, are permitted provided that the following conditions are met:
AnnaBridge 181:57724642e740 8 *
AnnaBridge 181:57724642e740 9 * 1. Redistributions of source code must retain the above copyright notice,
AnnaBridge 181:57724642e740 10 * this list of conditions and the following disclaimer.
AnnaBridge 181:57724642e740 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
AnnaBridge 181:57724642e740 12 * this list of conditions and the following disclaimer in the documentation
AnnaBridge 181:57724642e740 13 * and/or other materials provided with the distribution.
AnnaBridge 181:57724642e740 14 * 3. Neither the name of MultiTech nor the names of its contributors
AnnaBridge 181:57724642e740 15 * may be used to endorse or promote products derived from this software
AnnaBridge 181:57724642e740 16 * without specific prior written permission.
AnnaBridge 181:57724642e740 17 *
AnnaBridge 181:57724642e740 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AnnaBridge 181:57724642e740 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
AnnaBridge 181:57724642e740 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
AnnaBridge 181:57724642e740 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
AnnaBridge 181:57724642e740 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
AnnaBridge 181:57724642e740 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
AnnaBridge 181:57724642e740 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
AnnaBridge 181:57724642e740 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
AnnaBridge 181:57724642e740 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
AnnaBridge 181:57724642e740 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AnnaBridge 181:57724642e740 28 *******************************************************************************
AnnaBridge 181:57724642e740 29 */
AnnaBridge 181:57724642e740 30
AnnaBridge 181:57724642e740 31 #include "xdot_eeprom.h"
AnnaBridge 181:57724642e740 32
AnnaBridge 181:57724642e740 33 #define XDOT_EEPROM_START 0x08080000
AnnaBridge 181:57724642e740 34 #define XDOT_EEPROM_SIZE 0x00002000
AnnaBridge 181:57724642e740 35
AnnaBridge 181:57724642e740 36 typedef union {
AnnaBridge 187:0387e8f68319 37 uint32_t *w;
AnnaBridge 187:0387e8f68319 38 uint8_t *b;
AnnaBridge 181:57724642e740 39 } b2w;
AnnaBridge 181:57724642e740 40
AnnaBridge 181:57724642e740 41 typedef union {
AnnaBridge 187:0387e8f68319 42 uint16_t *hw;
AnnaBridge 187:0387e8f68319 43 uint8_t *b;
AnnaBridge 181:57724642e740 44 } b2hw;
AnnaBridge 181:57724642e740 45
AnnaBridge 181:57724642e740 46 enum {
AnnaBridge 181:57724642e740 47 byte_write = 0,
AnnaBridge 181:57724642e740 48 hword_write,
AnnaBridge 181:57724642e740 49 word_write
AnnaBridge 181:57724642e740 50 };
AnnaBridge 181:57724642e740 51
AnnaBridge 187:0387e8f68319 52 static int xdot_eeprom_write_byte(uint32_t addr, uint8_t data)
AnnaBridge 187:0387e8f68319 53 {
AnnaBridge 181:57724642e740 54 if (addr > XDOT_EEPROM_SIZE - 1) {
AnnaBridge 181:57724642e740 55 return -1;
AnnaBridge 181:57724642e740 56 }
AnnaBridge 181:57724642e740 57
AnnaBridge 181:57724642e740 58 if (HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, XDOT_EEPROM_START + addr, (uint32_t)data) != HAL_OK) {
AnnaBridge 181:57724642e740 59 return -1;
AnnaBridge 181:57724642e740 60 } else {
AnnaBridge 181:57724642e740 61 return 0;
AnnaBridge 181:57724642e740 62 }
AnnaBridge 181:57724642e740 63 }
AnnaBridge 181:57724642e740 64
AnnaBridge 187:0387e8f68319 65 static int xdot_eeprom_write_hword(uint32_t addr, uint16_t data)
AnnaBridge 187:0387e8f68319 66 {
AnnaBridge 181:57724642e740 67 if (addr > XDOT_EEPROM_SIZE - 2) {
AnnaBridge 181:57724642e740 68 return -1;
AnnaBridge 181:57724642e740 69 }
AnnaBridge 181:57724642e740 70
AnnaBridge 181:57724642e740 71 if (HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_HALFWORD, XDOT_EEPROM_START + addr, (uint32_t)data) != HAL_OK) {
AnnaBridge 181:57724642e740 72 return -1;
AnnaBridge 181:57724642e740 73 } else {
AnnaBridge 181:57724642e740 74 return 0;
AnnaBridge 181:57724642e740 75 }
AnnaBridge 181:57724642e740 76 }
AnnaBridge 181:57724642e740 77
AnnaBridge 187:0387e8f68319 78 static int xdot_eeprom_write_word(uint32_t addr, uint32_t data)
AnnaBridge 187:0387e8f68319 79 {
AnnaBridge 181:57724642e740 80 if (addr > XDOT_EEPROM_SIZE - 4) {
AnnaBridge 181:57724642e740 81 return -1;
AnnaBridge 181:57724642e740 82 }
AnnaBridge 181:57724642e740 83
AnnaBridge 181:57724642e740 84 if (HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_WORD, XDOT_EEPROM_START + addr, (uint32_t)data) != HAL_OK) {
AnnaBridge 181:57724642e740 85 return -1;
AnnaBridge 181:57724642e740 86 } else {
AnnaBridge 181:57724642e740 87 return 0;
AnnaBridge 181:57724642e740 88 }
AnnaBridge 181:57724642e740 89 }
AnnaBridge 181:57724642e740 90
AnnaBridge 187:0387e8f68319 91 static int xdot_eeprom_read_byte(uint32_t addr, uint8_t *data)
AnnaBridge 187:0387e8f68319 92 {
AnnaBridge 181:57724642e740 93 if (addr > XDOT_EEPROM_SIZE - 1) {
AnnaBridge 181:57724642e740 94 return -1;
AnnaBridge 181:57724642e740 95 }
AnnaBridge 181:57724642e740 96
AnnaBridge 187:0387e8f68319 97 *data = (*((uint8_t *)(XDOT_EEPROM_START + addr)));
AnnaBridge 181:57724642e740 98
AnnaBridge 181:57724642e740 99 return 0;
AnnaBridge 181:57724642e740 100 }
AnnaBridge 181:57724642e740 101
AnnaBridge 181:57724642e740 102
AnnaBridge 187:0387e8f68319 103 int xdot_eeprom_write_buf(uint32_t addr, uint8_t *buf, uint32_t size)
AnnaBridge 187:0387e8f68319 104 {
AnnaBridge 181:57724642e740 105 uint32_t bytes_written = 0;
AnnaBridge 181:57724642e740 106
AnnaBridge 181:57724642e740 107 if (addr + size > XDOT_EEPROM_SIZE) {
AnnaBridge 181:57724642e740 108 return -1;
AnnaBridge 181:57724642e740 109 }
AnnaBridge 181:57724642e740 110
AnnaBridge 181:57724642e740 111 HAL_FLASHEx_DATAEEPROM_Unlock();
AnnaBridge 181:57724642e740 112
AnnaBridge 181:57724642e740 113 while (bytes_written < size) {
AnnaBridge 181:57724642e740 114 uint32_t bytes_remaining = size - bytes_written;
AnnaBridge 181:57724642e740 115 uint32_t current_addr = addr + bytes_written;
AnnaBridge 181:57724642e740 116 uint8_t write_type = 0xFF;
AnnaBridge 181:57724642e740 117 uint8_t mismatch[4];
AnnaBridge 181:57724642e740 118 uint8_t match_byte = 0xFF;
AnnaBridge 181:57724642e740 119 b2w byte2word;
AnnaBridge 181:57724642e740 120 b2hw byte2hword;
AnnaBridge 181:57724642e740 121 //printf("0x%04X (%lu) bytes remaining\r\n", bytes_remaining, bytes_remaining);
AnnaBridge 181:57724642e740 122 //printf("addr 0x%04X\t%d\r\n", current_addr, current_addr % 4);
AnnaBridge 181:57724642e740 123
AnnaBridge 181:57724642e740 124 mismatch[0] = mismatch[1] = mismatch[2] = mismatch[3] = 0;
AnnaBridge 181:57724642e740 125
AnnaBridge 181:57724642e740 126 if ((current_addr % 4 == 0) && bytes_remaining >= 4) {
AnnaBridge 181:57724642e740 127 // aligned for word write
AnnaBridge 181:57724642e740 128 //printf("aligned for word write\r\n");
AnnaBridge 181:57724642e740 129 //printf("addr\tcurrent\t\tnew\r\n");
AnnaBridge 181:57724642e740 130 for (int i = 0; i < 4; i++) {
AnnaBridge 181:57724642e740 131 if (xdot_eeprom_read_byte(current_addr + i, &match_byte)) {
AnnaBridge 181:57724642e740 132 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 133 return -1;
AnnaBridge 181:57724642e740 134 }
AnnaBridge 181:57724642e740 135 //printf("0x%04X\t0x%08X\t0x%08X\t", current_addr + i, match_byte, buf[bytes_written + i]);
AnnaBridge 181:57724642e740 136 if (match_byte != buf[bytes_written + i]) {
AnnaBridge 181:57724642e740 137 mismatch[i] = 1;
AnnaBridge 181:57724642e740 138 }
AnnaBridge 181:57724642e740 139 //printf("%smatch\r\n", mismatch[i] ? "mis" : "");
AnnaBridge 181:57724642e740 140 }
AnnaBridge 187:0387e8f68319 141 if (!(mismatch[0] || mismatch[1] || mismatch[2] || mismatch[3])) {
AnnaBridge 181:57724642e740 142 //printf("all match - no write necessary\r\n");
AnnaBridge 181:57724642e740 143 bytes_written += 4;
AnnaBridge 181:57724642e740 144 continue;
AnnaBridge 181:57724642e740 145 }
AnnaBridge 181:57724642e740 146 if ((mismatch[0] || mismatch[1]) && (mismatch[2] || mismatch[3])) {
AnnaBridge 181:57724642e740 147 // if at least one of byte 1 or byte 2 and one of byte 3 or byte 4 needs to be written, write a word
AnnaBridge 181:57724642e740 148 // this should also account for all 3 or 4 byte combinations as well
AnnaBridge 181:57724642e740 149 write_type = word_write;
AnnaBridge 181:57724642e740 150 } else if ((mismatch[0] && mismatch[1]) || (mismatch[2] && mismatch[3])) {
AnnaBridge 181:57724642e740 151 // if only bytes 1 and 2 or only bytes 3 and 4 need to be written, write a half-word
AnnaBridge 181:57724642e740 152 write_type = hword_write;
AnnaBridge 181:57724642e740 153 // increment bytes_written if we're skipping bytes that match
AnnaBridge 181:57724642e740 154 if (mismatch[2] && mismatch[3]) {
AnnaBridge 181:57724642e740 155 bytes_written += 2;
AnnaBridge 181:57724642e740 156 current_addr += 2;
AnnaBridge 181:57724642e740 157 }
AnnaBridge 181:57724642e740 158 } else if (mismatch[0] || mismatch[1] || mismatch[2] || mismatch[3]) {
AnnaBridge 181:57724642e740 159 // anything else is just a byte write
AnnaBridge 181:57724642e740 160 write_type = byte_write;
AnnaBridge 181:57724642e740 161 // increment bytes_written if we're skipping bytes that match
AnnaBridge 181:57724642e740 162 if (mismatch[1]) {
AnnaBridge 181:57724642e740 163 bytes_written += 1;
AnnaBridge 181:57724642e740 164 current_addr += 1;
AnnaBridge 181:57724642e740 165 } else if (mismatch[2]) {
AnnaBridge 181:57724642e740 166 bytes_written += 2;
AnnaBridge 181:57724642e740 167 current_addr += 2;
AnnaBridge 181:57724642e740 168 } else if (mismatch[3]) {
AnnaBridge 181:57724642e740 169 bytes_written += 3;
AnnaBridge 181:57724642e740 170 current_addr += 3;
AnnaBridge 181:57724642e740 171 }
AnnaBridge 181:57724642e740 172 }
AnnaBridge 181:57724642e740 173 } else if ((current_addr % 2 == 0) && bytes_remaining >= 2) {
AnnaBridge 181:57724642e740 174 // aligned for half word write
AnnaBridge 181:57724642e740 175 //printf("aligned for half word write\r\n");
AnnaBridge 181:57724642e740 176 //printf("addr\tcurrent\t\tnew\r\n");
AnnaBridge 181:57724642e740 177 for (int i = 0; i < 2; i++) {
AnnaBridge 181:57724642e740 178 if (xdot_eeprom_read_byte(current_addr + i, &match_byte)) {
AnnaBridge 181:57724642e740 179 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 180 return -1;
AnnaBridge 181:57724642e740 181 }
AnnaBridge 181:57724642e740 182 //printf("0x%04X\t0x%08X\t0x%08X\t", current_addr + i, match_byte, buf[bytes_written + i]);
AnnaBridge 181:57724642e740 183 if (match_byte != buf[bytes_written + i]) {
AnnaBridge 181:57724642e740 184 mismatch[i] = 1;
AnnaBridge 181:57724642e740 185 }
AnnaBridge 181:57724642e740 186 //printf("%smatch\r\n", mismatch[i] ? "mis" : "");
AnnaBridge 181:57724642e740 187 }
AnnaBridge 187:0387e8f68319 188 if (!(mismatch[0] || mismatch[1])) {
AnnaBridge 181:57724642e740 189 //printf("all match - no write necessary\r\n");
AnnaBridge 181:57724642e740 190 bytes_written += 2;
AnnaBridge 181:57724642e740 191 continue;
AnnaBridge 181:57724642e740 192 }
AnnaBridge 181:57724642e740 193 if (mismatch[0] && mismatch[1]) {
AnnaBridge 181:57724642e740 194 // if bytes 1 and 2 need to be written, we truly want to write a half word
AnnaBridge 181:57724642e740 195 write_type = hword_write;
AnnaBridge 181:57724642e740 196 } else {
AnnaBridge 181:57724642e740 197 // anything else is just a byte write
AnnaBridge 181:57724642e740 198 write_type = byte_write;
AnnaBridge 181:57724642e740 199 // increment bytes_written if we're skipping bytes that match
AnnaBridge 181:57724642e740 200 if (mismatch[1]) {
AnnaBridge 181:57724642e740 201 bytes_written += 1;
AnnaBridge 181:57724642e740 202 current_addr += 1;
AnnaBridge 181:57724642e740 203 }
AnnaBridge 181:57724642e740 204 }
AnnaBridge 181:57724642e740 205 } else {
AnnaBridge 181:57724642e740 206 // aligned for byte write
AnnaBridge 181:57724642e740 207 //printf("aligned for byte write\r\n");
AnnaBridge 181:57724642e740 208 //printf("addr\tcurrent\t\tnew\r\n");
AnnaBridge 181:57724642e740 209 for (int i = 0; i < 1; i++) {
AnnaBridge 181:57724642e740 210 if (xdot_eeprom_read_byte(current_addr + i, &match_byte)) {
AnnaBridge 181:57724642e740 211 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 212 return -1;
AnnaBridge 181:57724642e740 213 }
AnnaBridge 181:57724642e740 214 //printf("0x%04X\t0x%08X\t0x%08X\t", current_addr + i, match_byte, buf[bytes_written + i]);
AnnaBridge 181:57724642e740 215 if (match_byte != buf[bytes_written + i]) {
AnnaBridge 181:57724642e740 216 mismatch[i] = 1;
AnnaBridge 181:57724642e740 217 }
AnnaBridge 181:57724642e740 218 //printf("%smatch\r\n", mismatch[i] ? "mis" : "");
AnnaBridge 181:57724642e740 219 }
AnnaBridge 181:57724642e740 220 if (! mismatch[0]) {
AnnaBridge 181:57724642e740 221 //printf("all match - no write necessary\r\n");
AnnaBridge 181:57724642e740 222 bytes_written += 1;
AnnaBridge 181:57724642e740 223 continue;
AnnaBridge 181:57724642e740 224 }
AnnaBridge 181:57724642e740 225 write_type = byte_write;
AnnaBridge 181:57724642e740 226 }
AnnaBridge 181:57724642e740 227
AnnaBridge 181:57724642e740 228 switch (write_type) {
AnnaBridge 181:57724642e740 229 case word_write:
AnnaBridge 181:57724642e740 230 // we can write a word (32 bits)
AnnaBridge 181:57724642e740 231 //printf("word write\r\n");
AnnaBridge 181:57724642e740 232 byte2word.b = buf + bytes_written;
AnnaBridge 181:57724642e740 233 if (xdot_eeprom_write_word(current_addr, *byte2word.w)) {
AnnaBridge 181:57724642e740 234 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 235 return -1;
AnnaBridge 181:57724642e740 236 }
AnnaBridge 181:57724642e740 237 bytes_written += 4;
AnnaBridge 181:57724642e740 238 break;
AnnaBridge 181:57724642e740 239 case hword_write:
AnnaBridge 181:57724642e740 240 // we can write a half-word (16 bits)
AnnaBridge 181:57724642e740 241 //printf("half-word write\r\n");
AnnaBridge 181:57724642e740 242 byte2hword.b = buf + bytes_written;
AnnaBridge 181:57724642e740 243 if (xdot_eeprom_write_hword(current_addr, *byte2hword.hw)) {
AnnaBridge 181:57724642e740 244 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 245 return -1;
AnnaBridge 181:57724642e740 246 }
AnnaBridge 181:57724642e740 247 bytes_written += 2;
AnnaBridge 181:57724642e740 248 break;
AnnaBridge 181:57724642e740 249 case byte_write:
AnnaBridge 181:57724642e740 250 // we can write a byte (8 bits)
AnnaBridge 181:57724642e740 251 //printf("byte write\r\n");
AnnaBridge 181:57724642e740 252 if (xdot_eeprom_write_byte(current_addr, buf[bytes_written])) {
AnnaBridge 181:57724642e740 253 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 254 return -1;
AnnaBridge 181:57724642e740 255 }
AnnaBridge 181:57724642e740 256 bytes_written += 1;
AnnaBridge 181:57724642e740 257 break;
AnnaBridge 181:57724642e740 258 default:
AnnaBridge 181:57724642e740 259 //printf("no write needed\r\n");
AnnaBridge 181:57724642e740 260 break;
AnnaBridge 181:57724642e740 261 }
AnnaBridge 181:57724642e740 262 }
AnnaBridge 181:57724642e740 263
AnnaBridge 181:57724642e740 264 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 265
AnnaBridge 181:57724642e740 266 return 0;
AnnaBridge 181:57724642e740 267 }
AnnaBridge 181:57724642e740 268
AnnaBridge 187:0387e8f68319 269 int xdot_eeprom_read_buf(uint32_t addr, uint8_t *buf, uint32_t size)
AnnaBridge 187:0387e8f68319 270 {
AnnaBridge 181:57724642e740 271 if (addr + size > XDOT_EEPROM_SIZE) {
AnnaBridge 181:57724642e740 272 return -1;
AnnaBridge 181:57724642e740 273 }
AnnaBridge 181:57724642e740 274
AnnaBridge 181:57724642e740 275 HAL_FLASHEx_DATAEEPROM_Unlock();
AnnaBridge 181:57724642e740 276
AnnaBridge 181:57724642e740 277 for (uint32_t i = 0; i < size; i++) {
AnnaBridge 181:57724642e740 278 if (xdot_eeprom_read_byte(addr + i, buf + i)) {
AnnaBridge 181:57724642e740 279 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 280 return -1;
AnnaBridge 181:57724642e740 281 }
AnnaBridge 181:57724642e740 282 }
AnnaBridge 181:57724642e740 283
AnnaBridge 181:57724642e740 284 HAL_FLASHEx_DATAEEPROM_Lock();
AnnaBridge 181:57724642e740 285
AnnaBridge 181:57724642e740 286 return 0;
AnnaBridge 181:57724642e740 287 }