Helmut Tschemernjak / NVProperty

Dependents:   Turtle_RadioShuttle

Committer:
Helmut Tschemernjak
Date:
Thu Jan 24 14:28:11 2019 +0100
Revision:
1:3a8297ad8cd9
Added new files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut Tschemernjak 1:3a8297ad8cd9 1 /*
Helmut Tschemernjak 1:3a8297ad8cd9 2 * This is an unpublished work copyright
Helmut Tschemernjak 1:3a8297ad8cd9 3 * (c) 2019 Helmut Tschemernjak
Helmut Tschemernjak 1:3a8297ad8cd9 4 * 30826 Garbsen (Hannover) Germany
Helmut Tschemernjak 1:3a8297ad8cd9 5 *
Helmut Tschemernjak 1:3a8297ad8cd9 6 *
Helmut Tschemernjak 1:3a8297ad8cd9 7 * Use is granted to registered RadioShuttle licensees only.
Helmut Tschemernjak 1:3a8297ad8cd9 8 * Licensees must own a valid serial number and product code.
Helmut Tschemernjak 1:3a8297ad8cd9 9 * Details see: www.radioshuttle.de
Helmut Tschemernjak 1:3a8297ad8cd9 10 */
Helmut Tschemernjak 1:3a8297ad8cd9 11
Helmut Tschemernjak 1:3a8297ad8cd9 12 #ifdef TARGET_STM32L4
Helmut Tschemernjak 1:3a8297ad8cd9 13
Helmut Tschemernjak 1:3a8297ad8cd9 14 #include <mbed.h>
Helmut Tschemernjak 1:3a8297ad8cd9 15 #include "main.h"
Helmut Tschemernjak 1:3a8297ad8cd9 16 #include <NVPropertyProviderInterface.h>
Helmut Tschemernjak 1:3a8297ad8cd9 17 #include <NVProperty_L4Flash.h>
Helmut Tschemernjak 1:3a8297ad8cd9 18 #include <NVProperty.h>
Helmut Tschemernjak 1:3a8297ad8cd9 19
Helmut Tschemernjak 1:3a8297ad8cd9 20 #if 0
Helmut Tschemernjak 1:3a8297ad8cd9 21 #define OTP_TEST_IN_RAM // test OTP in RAM
Helmut Tschemernjak 1:3a8297ad8cd9 22
Helmut Tschemernjak 1:3a8297ad8cd9 23
Helmut Tschemernjak 1:3a8297ad8cd9 24 NVProperty_L4OTP::NVProperty_L4OTP()
Helmut Tschemernjak 1:3a8297ad8cd9 25 {
Helmut Tschemernjak 1:3a8297ad8cd9 26 _debug = false;
Helmut Tschemernjak 1:3a8297ad8cd9 27 _propSize = 1 * 1024; // no define in HAL laye
Helmut Tschemernjak 1:3a8297ad8cd9 28 _startAddress = (uint8_t *) 0x1FFF7000; // no define in HAL layer
Helmut Tschemernjak 1:3a8297ad8cd9 29
Helmut Tschemernjak 1:3a8297ad8cd9 30 #ifdef OTP_TEST_IN_RAM
Helmut Tschemernjak 1:3a8297ad8cd9 31 static uint8_t *savedStart;
Helmut Tschemernjak 1:3a8297ad8cd9 32 if (!savedStart) {
Helmut Tschemernjak 1:3a8297ad8cd9 33 _startAddress = (uint8_t *) malloc(512);
Helmut Tschemernjak 1:3a8297ad8cd9 34 memset(_startAddress, 0xff, 512);
Helmut Tschemernjak 1:3a8297ad8cd9 35 savedStart = _startAddress;
Helmut Tschemernjak 1:3a8297ad8cd9 36 } else {
Helmut Tschemernjak 1:3a8297ad8cd9 37 _startAddress = savedStart;
Helmut Tschemernjak 1:3a8297ad8cd9 38 }
Helmut Tschemernjak 1:3a8297ad8cd9 39 #endif
Helmut Tschemernjak 1:3a8297ad8cd9 40
Helmut Tschemernjak 1:3a8297ad8cd9 41 _endAddress = _startAddress + (_propSize);
Helmut Tschemernjak 1:3a8297ad8cd9 42 _lastEntry = NULL;
Helmut Tschemernjak 1:3a8297ad8cd9 43
Helmut Tschemernjak 1:3a8297ad8cd9 44 _FlashInititalize();
Helmut Tschemernjak 1:3a8297ad8cd9 45 }
Helmut Tschemernjak 1:3a8297ad8cd9 46
Helmut Tschemernjak 1:3a8297ad8cd9 47
Helmut Tschemernjak 1:3a8297ad8cd9 48 NVProperty_L4OTP::~NVProperty_L4OTP()
Helmut Tschemernjak 1:3a8297ad8cd9 49 {
Helmut Tschemernjak 1:3a8297ad8cd9 50 _debug = true;
Helmut Tschemernjak 1:3a8297ad8cd9 51 _DumpAllEntires();
Helmut Tschemernjak 1:3a8297ad8cd9 52 }
Helmut Tschemernjak 1:3a8297ad8cd9 53
Helmut Tschemernjak 1:3a8297ad8cd9 54
Helmut Tschemernjak 1:3a8297ad8cd9 55 void
Helmut Tschemernjak 1:3a8297ad8cd9 56 NVProperty_L4OTP::_FlashInititalize(void)
Helmut Tschemernjak 1:3a8297ad8cd9 57 {
Helmut Tschemernjak 1:3a8297ad8cd9 58 _flash_header *fh = (_flash_header *)_startAddress;
Helmut Tschemernjak 1:3a8297ad8cd9 59 if (fh->magic == FLASH_PROP_MAGIC && fh->version == FLASH_PROP_VERSION && fh->size == _propSize) {
Helmut Tschemernjak 1:3a8297ad8cd9 60 return;
Helmut Tschemernjak 1:3a8297ad8cd9 61 }
Helmut Tschemernjak 1:3a8297ad8cd9 62
Helmut Tschemernjak 1:3a8297ad8cd9 63 uint8_t *p = _startAddress;
Helmut Tschemernjak 1:3a8297ad8cd9 64 for (int i = 0; i < (int)sizeof(_flash_header); i++) {
Helmut Tschemernjak 1:3a8297ad8cd9 65 if (*p++ != 0xff)
Helmut Tschemernjak 1:3a8297ad8cd9 66 return; // invalid data
Helmut Tschemernjak 1:3a8297ad8cd9 67 }
Helmut Tschemernjak 1:3a8297ad8cd9 68
Helmut Tschemernjak 1:3a8297ad8cd9 69 _flash_header f;
Helmut Tschemernjak 1:3a8297ad8cd9 70 memset(&f, 0, sizeof(f));
Helmut Tschemernjak 1:3a8297ad8cd9 71 f.magic = FLASH_PROP_MAGIC;
Helmut Tschemernjak 1:3a8297ad8cd9 72 f.version = FLASH_PROP_VERSION;
Helmut Tschemernjak 1:3a8297ad8cd9 73 f.size = _propSize;
Helmut Tschemernjak 1:3a8297ad8cd9 74
Helmut Tschemernjak 1:3a8297ad8cd9 75 _OTPWrite(_startAddress, &f, sizeof(f));
Helmut Tschemernjak 1:3a8297ad8cd9 76 }
Helmut Tschemernjak 1:3a8297ad8cd9 77
Helmut Tschemernjak 1:3a8297ad8cd9 78
Helmut Tschemernjak 1:3a8297ad8cd9 79 int
Helmut Tschemernjak 1:3a8297ad8cd9 80 NVProperty_L4OTP::GetProperty(int key)
Helmut Tschemernjak 1:3a8297ad8cd9 81 {
Helmut Tschemernjak 1:3a8297ad8cd9 82 return GetProperty64(key);
Helmut Tschemernjak 1:3a8297ad8cd9 83 }
Helmut Tschemernjak 1:3a8297ad8cd9 84
Helmut Tschemernjak 1:3a8297ad8cd9 85
Helmut Tschemernjak 1:3a8297ad8cd9 86 int64_t
Helmut Tschemernjak 1:3a8297ad8cd9 87 NVProperty_L4OTP::GetProperty64(int key)
Helmut Tschemernjak 1:3a8297ad8cd9 88 {
Helmut Tschemernjak 1:3a8297ad8cd9 89 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 90 if (!p)
Helmut Tschemernjak 1:3a8297ad8cd9 91 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 1:3a8297ad8cd9 92
Helmut Tschemernjak 1:3a8297ad8cd9 93 int64_t value = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 94
Helmut Tschemernjak 1:3a8297ad8cd9 95 switch(p->t.type) {
Helmut Tschemernjak 1:3a8297ad8cd9 96 case NVProperty::T_BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 97 if (p->t.t_bit)
Helmut Tschemernjak 1:3a8297ad8cd9 98 value = 1;
Helmut Tschemernjak 1:3a8297ad8cd9 99 else
Helmut Tschemernjak 1:3a8297ad8cd9 100 value = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 101 break;
Helmut Tschemernjak 1:3a8297ad8cd9 102 case NVProperty::T_8BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 103 value = p->u.v_8bit;
Helmut Tschemernjak 1:3a8297ad8cd9 104 break;
Helmut Tschemernjak 1:3a8297ad8cd9 105 case NVProperty::T_16BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 106 {
Helmut Tschemernjak 1:3a8297ad8cd9 107 int16_t v;
Helmut Tschemernjak 1:3a8297ad8cd9 108 memcpy(&v, &p->u.v_16bit, sizeof(p->u.v_16bit));
Helmut Tschemernjak 1:3a8297ad8cd9 109 value = v;
Helmut Tschemernjak 1:3a8297ad8cd9 110 }
Helmut Tschemernjak 1:3a8297ad8cd9 111 break;
Helmut Tschemernjak 1:3a8297ad8cd9 112 case NVProperty::T_32BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 113 {
Helmut Tschemernjak 1:3a8297ad8cd9 114 int32_t v;
Helmut Tschemernjak 1:3a8297ad8cd9 115 memcpy(&v, &p->data.v_32bit, sizeof(p->data.v_32bit));
Helmut Tschemernjak 1:3a8297ad8cd9 116 value =v;
Helmut Tschemernjak 1:3a8297ad8cd9 117 }
Helmut Tschemernjak 1:3a8297ad8cd9 118 break;
Helmut Tschemernjak 1:3a8297ad8cd9 119 case NVProperty::T_64BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 120 memcpy(&value, p->data.v_64bit, sizeof(p->data.v_64bit));
Helmut Tschemernjak 1:3a8297ad8cd9 121 break;
Helmut Tschemernjak 1:3a8297ad8cd9 122 case NVProperty::T_STR:
Helmut Tschemernjak 1:3a8297ad8cd9 123 case NVProperty::T_BLOB:
Helmut Tschemernjak 1:3a8297ad8cd9 124 value = p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 125 break;
Helmut Tschemernjak 1:3a8297ad8cd9 126 }
Helmut Tschemernjak 1:3a8297ad8cd9 127 return value;
Helmut Tschemernjak 1:3a8297ad8cd9 128 }
Helmut Tschemernjak 1:3a8297ad8cd9 129
Helmut Tschemernjak 1:3a8297ad8cd9 130 const char *
Helmut Tschemernjak 1:3a8297ad8cd9 131 NVProperty_L4OTP::GetPropertyStr(int key)
Helmut Tschemernjak 1:3a8297ad8cd9 132 {
Helmut Tschemernjak 1:3a8297ad8cd9 133 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 134 if (!p || p->t.type != NVProperty::T_STR)
Helmut Tschemernjak 1:3a8297ad8cd9 135 return NULL;
Helmut Tschemernjak 1:3a8297ad8cd9 136 return strdup(p->data.v_str);
Helmut Tschemernjak 1:3a8297ad8cd9 137 }
Helmut Tschemernjak 1:3a8297ad8cd9 138
Helmut Tschemernjak 1:3a8297ad8cd9 139 int
Helmut Tschemernjak 1:3a8297ad8cd9 140 NVProperty_L4OTP::GetPropertyBlob(int key, const void *blob, int *size)
Helmut Tschemernjak 1:3a8297ad8cd9 141 {
Helmut Tschemernjak 1:3a8297ad8cd9 142 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 143 if (!p || p->t.type != NVProperty::T_BLOB)
Helmut Tschemernjak 1:3a8297ad8cd9 144 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 1:3a8297ad8cd9 145
Helmut Tschemernjak 1:3a8297ad8cd9 146 int cplen = std::min(*size, (int)p->u.option.d_len);
Helmut Tschemernjak 1:3a8297ad8cd9 147 if (blob)
Helmut Tschemernjak 1:3a8297ad8cd9 148 memcpy((void *)blob, p->data.v_blob, cplen);
Helmut Tschemernjak 1:3a8297ad8cd9 149 *size = cplen;
Helmut Tschemernjak 1:3a8297ad8cd9 150
Helmut Tschemernjak 1:3a8297ad8cd9 151 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 152 }
Helmut Tschemernjak 1:3a8297ad8cd9 153
Helmut Tschemernjak 1:3a8297ad8cd9 154
Helmut Tschemernjak 1:3a8297ad8cd9 155 int
Helmut Tschemernjak 1:3a8297ad8cd9 156 NVProperty_L4OTP::SetProperty(int key, int64_t value, int type)
Helmut Tschemernjak 1:3a8297ad8cd9 157 {
Helmut Tschemernjak 1:3a8297ad8cd9 158 UNUSED(type);
Helmut Tschemernjak 1:3a8297ad8cd9 159 uint8_t valbuf[FLASH_ENTRY_MIN_SIZE + sizeof(int64_t)];
Helmut Tschemernjak 1:3a8297ad8cd9 160 _flashEntry *p = (_flashEntry *) valbuf;
Helmut Tschemernjak 1:3a8297ad8cd9 161 int storeType;
Helmut Tschemernjak 1:3a8297ad8cd9 162
Helmut Tschemernjak 1:3a8297ad8cd9 163 if (GetProperty64(key) == value) // no need to save it again.
Helmut Tschemernjak 1:3a8297ad8cd9 164 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 165
Helmut Tschemernjak 1:3a8297ad8cd9 166
Helmut Tschemernjak 1:3a8297ad8cd9 167 memset(valbuf, 0, sizeof(valbuf));
Helmut Tschemernjak 1:3a8297ad8cd9 168
Helmut Tschemernjak 1:3a8297ad8cd9 169 if (value == 0 || value == 1)
Helmut Tschemernjak 1:3a8297ad8cd9 170 storeType = NVProperty::T_BIT;
Helmut Tschemernjak 1:3a8297ad8cd9 171 else if (value >= -128 && value < 128)
Helmut Tschemernjak 1:3a8297ad8cd9 172 storeType = NVProperty::T_8BIT;
Helmut Tschemernjak 1:3a8297ad8cd9 173 else if (value >= -32768 && value < 32768)
Helmut Tschemernjak 1:3a8297ad8cd9 174 storeType = NVProperty::T_16BIT;
Helmut Tschemernjak 1:3a8297ad8cd9 175 else if (value > -2147483647 && value < 2147483648)
Helmut Tschemernjak 1:3a8297ad8cd9 176 storeType = NVProperty::T_32BIT;
Helmut Tschemernjak 1:3a8297ad8cd9 177 else
Helmut Tschemernjak 1:3a8297ad8cd9 178 storeType = NVProperty::T_64BIT;
Helmut Tschemernjak 1:3a8297ad8cd9 179
Helmut Tschemernjak 1:3a8297ad8cd9 180 p->key = key;
Helmut Tschemernjak 1:3a8297ad8cd9 181 p->t.type = storeType;
Helmut Tschemernjak 1:3a8297ad8cd9 182
Helmut Tschemernjak 1:3a8297ad8cd9 183
Helmut Tschemernjak 1:3a8297ad8cd9 184 switch(storeType) {
Helmut Tschemernjak 1:3a8297ad8cd9 185 case NVProperty::T_BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 186 p->t.t_bit = value;
Helmut Tschemernjak 1:3a8297ad8cd9 187 break;
Helmut Tschemernjak 1:3a8297ad8cd9 188 case NVProperty::T_8BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 189 p->u.v_8bit = value;
Helmut Tschemernjak 1:3a8297ad8cd9 190 break;
Helmut Tschemernjak 1:3a8297ad8cd9 191 case NVProperty::T_16BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 192 p->u.v_16bit = value;
Helmut Tschemernjak 1:3a8297ad8cd9 193 break;
Helmut Tschemernjak 1:3a8297ad8cd9 194 case NVProperty::T_32BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 195 p->u.option.d_len = sizeof(p->data.v_32bit);
Helmut Tschemernjak 1:3a8297ad8cd9 196 {
Helmut Tschemernjak 1:3a8297ad8cd9 197 int32_t v = value;
Helmut Tschemernjak 1:3a8297ad8cd9 198 memcpy(&p->data.v_32bit, &v, sizeof(p->data.v_32bit));
Helmut Tschemernjak 1:3a8297ad8cd9 199 }
Helmut Tschemernjak 1:3a8297ad8cd9 200 break;
Helmut Tschemernjak 1:3a8297ad8cd9 201 case NVProperty::T_64BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 202 p->u.option.d_len = sizeof(p->data.v_64bit);
Helmut Tschemernjak 1:3a8297ad8cd9 203 memcpy(p->data.v_64bit, &value, sizeof(p->data.v_64bit));
Helmut Tschemernjak 1:3a8297ad8cd9 204 break;
Helmut Tschemernjak 1:3a8297ad8cd9 205 }
Helmut Tschemernjak 1:3a8297ad8cd9 206 int len;
Helmut Tschemernjak 1:3a8297ad8cd9 207 if (storeType == NVProperty::T_BIT || storeType == NVProperty::T_8BIT || storeType == NVProperty::T_16BIT || storeType == NVProperty::T_32BIT) {
Helmut Tschemernjak 1:3a8297ad8cd9 208 len = FLASH_ENTRY_MIN_SIZE;
Helmut Tschemernjak 1:3a8297ad8cd9 209 } else { // 64/STR/BLOB
Helmut Tschemernjak 1:3a8297ad8cd9 210 len = (FLASH_ENTRY_MIN_SIZE - 4) + p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 211 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 1:3a8297ad8cd9 212 }
Helmut Tschemernjak 1:3a8297ad8cd9 213 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 1:3a8297ad8cd9 214 if (!_FlashReorgEntries(len))
Helmut Tschemernjak 1:3a8297ad8cd9 215 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 216 }
Helmut Tschemernjak 1:3a8297ad8cd9 217
Helmut Tschemernjak 1:3a8297ad8cd9 218 _OTPWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 1:3a8297ad8cd9 219 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 1:3a8297ad8cd9 220
Helmut Tschemernjak 1:3a8297ad8cd9 221 // _DumpAllEntires();
Helmut Tschemernjak 1:3a8297ad8cd9 222 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 223 }
Helmut Tschemernjak 1:3a8297ad8cd9 224
Helmut Tschemernjak 1:3a8297ad8cd9 225
Helmut Tschemernjak 1:3a8297ad8cd9 226 int
Helmut Tschemernjak 1:3a8297ad8cd9 227 NVProperty_L4OTP::SetPropertyStr(int key, const char *value, int type)
Helmut Tschemernjak 1:3a8297ad8cd9 228 {
Helmut Tschemernjak 1:3a8297ad8cd9 229 if (type != NVProperty::T_STR)
Helmut Tschemernjak 1:3a8297ad8cd9 230 return NVProperty::NVP_INVALD_PARM;
Helmut Tschemernjak 1:3a8297ad8cd9 231
Helmut Tschemernjak 1:3a8297ad8cd9 232 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 233 if (p && p->t.type == NVProperty::T_STR && strcmp(p->data.v_str, value) == 0) {
Helmut Tschemernjak 1:3a8297ad8cd9 234 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 235 }
Helmut Tschemernjak 1:3a8297ad8cd9 236
Helmut Tschemernjak 1:3a8297ad8cd9 237 int err = NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 238
Helmut Tschemernjak 1:3a8297ad8cd9 239 p = new _flashEntry();
Helmut Tschemernjak 1:3a8297ad8cd9 240 if (!p)
Helmut Tschemernjak 1:3a8297ad8cd9 241 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 242
Helmut Tschemernjak 1:3a8297ad8cd9 243 p->key = key;
Helmut Tschemernjak 1:3a8297ad8cd9 244 p->t.type = NVProperty::T_STR;
Helmut Tschemernjak 1:3a8297ad8cd9 245 int cplen = std::min(strlen(value), sizeof(p->data.v_str)-1);
Helmut Tschemernjak 1:3a8297ad8cd9 246 memcpy(p->data.v_str, value, cplen);
Helmut Tschemernjak 1:3a8297ad8cd9 247 p->u.option.d_len = cplen + 1; // zero term
Helmut Tschemernjak 1:3a8297ad8cd9 248
Helmut Tschemernjak 1:3a8297ad8cd9 249 int len = (FLASH_ENTRY_MIN_SIZE - 4) + p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 250 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 1:3a8297ad8cd9 251
Helmut Tschemernjak 1:3a8297ad8cd9 252 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 1:3a8297ad8cd9 253 if (!_FlashReorgEntries(len)) {
Helmut Tschemernjak 1:3a8297ad8cd9 254 err = NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 255 goto done;
Helmut Tschemernjak 1:3a8297ad8cd9 256 }
Helmut Tschemernjak 1:3a8297ad8cd9 257 }
Helmut Tschemernjak 1:3a8297ad8cd9 258
Helmut Tschemernjak 1:3a8297ad8cd9 259 _OTPWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 1:3a8297ad8cd9 260 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 1:3a8297ad8cd9 261
Helmut Tschemernjak 1:3a8297ad8cd9 262 done:
Helmut Tschemernjak 1:3a8297ad8cd9 263 delete[] p;
Helmut Tschemernjak 1:3a8297ad8cd9 264 // _DumpAllEntires();
Helmut Tschemernjak 1:3a8297ad8cd9 265 return err;
Helmut Tschemernjak 1:3a8297ad8cd9 266 }
Helmut Tschemernjak 1:3a8297ad8cd9 267
Helmut Tschemernjak 1:3a8297ad8cd9 268 int
Helmut Tschemernjak 1:3a8297ad8cd9 269 NVProperty_L4OTP::SetPropertyBlob(int key, const void *blob, int size, int type)
Helmut Tschemernjak 1:3a8297ad8cd9 270 {
Helmut Tschemernjak 1:3a8297ad8cd9 271 if (type != NVProperty::T_BLOB)
Helmut Tschemernjak 1:3a8297ad8cd9 272 return NVProperty::NVP_INVALD_PARM;
Helmut Tschemernjak 1:3a8297ad8cd9 273
Helmut Tschemernjak 1:3a8297ad8cd9 274 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 275 if (p && p->t.type == NVProperty::T_BLOB && size == p->u.option.d_len) { // check for duplicate
Helmut Tschemernjak 1:3a8297ad8cd9 276 if (memcmp(blob, p->data.v_blob, size) == 0)
Helmut Tschemernjak 1:3a8297ad8cd9 277 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 278 }
Helmut Tschemernjak 1:3a8297ad8cd9 279 int err = NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 280
Helmut Tschemernjak 1:3a8297ad8cd9 281 p = new _flashEntry();
Helmut Tschemernjak 1:3a8297ad8cd9 282 if (!p)
Helmut Tschemernjak 1:3a8297ad8cd9 283 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 284
Helmut Tschemernjak 1:3a8297ad8cd9 285 p->key = key;
Helmut Tschemernjak 1:3a8297ad8cd9 286 p->t.type = NVProperty::T_BLOB;
Helmut Tschemernjak 1:3a8297ad8cd9 287 int cplen = std::min(size, (int)sizeof(p->data.v_blob));
Helmut Tschemernjak 1:3a8297ad8cd9 288 p->u.option.d_len = cplen;
Helmut Tschemernjak 1:3a8297ad8cd9 289 memcpy(p->data.v_blob, blob, cplen);
Helmut Tschemernjak 1:3a8297ad8cd9 290
Helmut Tschemernjak 1:3a8297ad8cd9 291 int len = (FLASH_ENTRY_MIN_SIZE - 4) + p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 292 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 1:3a8297ad8cd9 293
Helmut Tschemernjak 1:3a8297ad8cd9 294 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 1:3a8297ad8cd9 295 if (!_FlashReorgEntries(len)) {
Helmut Tschemernjak 1:3a8297ad8cd9 296 err = NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 297 goto done;
Helmut Tschemernjak 1:3a8297ad8cd9 298 }
Helmut Tschemernjak 1:3a8297ad8cd9 299 }
Helmut Tschemernjak 1:3a8297ad8cd9 300
Helmut Tschemernjak 1:3a8297ad8cd9 301 _OTPWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 1:3a8297ad8cd9 302 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 1:3a8297ad8cd9 303
Helmut Tschemernjak 1:3a8297ad8cd9 304 done:
Helmut Tschemernjak 1:3a8297ad8cd9 305 delete[] p;
Helmut Tschemernjak 1:3a8297ad8cd9 306 // _DumpAllEntires();
Helmut Tschemernjak 1:3a8297ad8cd9 307 return err;
Helmut Tschemernjak 1:3a8297ad8cd9 308 }
Helmut Tschemernjak 1:3a8297ad8cd9 309
Helmut Tschemernjak 1:3a8297ad8cd9 310 int
Helmut Tschemernjak 1:3a8297ad8cd9 311 NVProperty_L4OTP::EraseProperty(int key)
Helmut Tschemernjak 1:3a8297ad8cd9 312 {
Helmut Tschemernjak 1:3a8297ad8cd9 313 uint8_t valbuf[FLASH_ENTRY_MIN_SIZE];
Helmut Tschemernjak 1:3a8297ad8cd9 314 _flashEntry *p = (_flashEntry *) valbuf;
Helmut Tschemernjak 1:3a8297ad8cd9 315
Helmut Tschemernjak 1:3a8297ad8cd9 316 _flashEntry *op = _GetFlashEntry(key);
Helmut Tschemernjak 1:3a8297ad8cd9 317 if (!op)
Helmut Tschemernjak 1:3a8297ad8cd9 318 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 1:3a8297ad8cd9 319 if (op->t.deleted)
Helmut Tschemernjak 1:3a8297ad8cd9 320 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 321
Helmut Tschemernjak 1:3a8297ad8cd9 322 memset(valbuf, 0, sizeof(valbuf));
Helmut Tschemernjak 1:3a8297ad8cd9 323 p->key = key;
Helmut Tschemernjak 1:3a8297ad8cd9 324 p->t.type = op->t.type;
Helmut Tschemernjak 1:3a8297ad8cd9 325 p->t.deleted = true;
Helmut Tschemernjak 1:3a8297ad8cd9 326
Helmut Tschemernjak 1:3a8297ad8cd9 327 if ((uint8_t *)_lastEntry + FLASH_ENTRY_MIN_SIZE > _endAddress) {
Helmut Tschemernjak 1:3a8297ad8cd9 328 if (!_FlashReorgEntries(FLASH_ENTRY_MIN_SIZE))
Helmut Tschemernjak 1:3a8297ad8cd9 329 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 1:3a8297ad8cd9 330 }
Helmut Tschemernjak 1:3a8297ad8cd9 331
Helmut Tschemernjak 1:3a8297ad8cd9 332 _OTPWrite((uint8_t *)_lastEntry, p, FLASH_ENTRY_MIN_SIZE);
Helmut Tschemernjak 1:3a8297ad8cd9 333 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + FLASH_ENTRY_MIN_SIZE);
Helmut Tschemernjak 1:3a8297ad8cd9 334
Helmut Tschemernjak 1:3a8297ad8cd9 335 // _DumpAllEntires();
Helmut Tschemernjak 1:3a8297ad8cd9 336 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 337 }
Helmut Tschemernjak 1:3a8297ad8cd9 338
Helmut Tschemernjak 1:3a8297ad8cd9 339 int
Helmut Tschemernjak 1:3a8297ad8cd9 340 NVProperty_L4OTP::ReorgProperties(void)
Helmut Tschemernjak 1:3a8297ad8cd9 341 {
Helmut Tschemernjak 1:3a8297ad8cd9 342 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 343 }
Helmut Tschemernjak 1:3a8297ad8cd9 344
Helmut Tschemernjak 1:3a8297ad8cd9 345
Helmut Tschemernjak 1:3a8297ad8cd9 346 int
Helmut Tschemernjak 1:3a8297ad8cd9 347 NVProperty_L4OTP::OpenPropertyStore(bool forWrite)
Helmut Tschemernjak 1:3a8297ad8cd9 348 {
Helmut Tschemernjak 1:3a8297ad8cd9 349 UNUSED(forWrite);
Helmut Tschemernjak 1:3a8297ad8cd9 350 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 351 }
Helmut Tschemernjak 1:3a8297ad8cd9 352
Helmut Tschemernjak 1:3a8297ad8cd9 353 int
Helmut Tschemernjak 1:3a8297ad8cd9 354 NVProperty_L4OTP::ClosePropertyStore(bool flush)
Helmut Tschemernjak 1:3a8297ad8cd9 355 {
Helmut Tschemernjak 1:3a8297ad8cd9 356 return NVProperty::NVP_OK;
Helmut Tschemernjak 1:3a8297ad8cd9 357 }
Helmut Tschemernjak 1:3a8297ad8cd9 358
Helmut Tschemernjak 1:3a8297ad8cd9 359 #if 1
Helmut Tschemernjak 1:3a8297ad8cd9 360 void
Helmut Tschemernjak 1:3a8297ad8cd9 361 NVProperty_L4OTP::_DumpAllEntires(void)
Helmut Tschemernjak 1:3a8297ad8cd9 362 {
Helmut Tschemernjak 1:3a8297ad8cd9 363 if (!_debug)
Helmut Tschemernjak 1:3a8297ad8cd9 364 return;
Helmut Tschemernjak 1:3a8297ad8cd9 365
Helmut Tschemernjak 1:3a8297ad8cd9 366 dprintf("------------- DumpAllEntires -------- ");
Helmut Tschemernjak 1:3a8297ad8cd9 367
Helmut Tschemernjak 1:3a8297ad8cd9 368 int index = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 369 _flashEntry *p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 1:3a8297ad8cd9 370 while((uint8_t *)p < _endAddress && p->key != NVProperty::PROPERTIES_EOF) {
Helmut Tschemernjak 1:3a8297ad8cd9 371
Helmut Tschemernjak 1:3a8297ad8cd9 372 int64_t value = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 373 switch(p->t.type) {
Helmut Tschemernjak 1:3a8297ad8cd9 374 case NVProperty::T_BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 375 if (p->t.t_bit)
Helmut Tschemernjak 1:3a8297ad8cd9 376 value = 1;
Helmut Tschemernjak 1:3a8297ad8cd9 377 else
Helmut Tschemernjak 1:3a8297ad8cd9 378 value = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 379 break;
Helmut Tschemernjak 1:3a8297ad8cd9 380 case NVProperty::T_8BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 381 value = p->u.v_8bit;
Helmut Tschemernjak 1:3a8297ad8cd9 382 break;
Helmut Tschemernjak 1:3a8297ad8cd9 383 case NVProperty::T_16BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 384 {
Helmut Tschemernjak 1:3a8297ad8cd9 385 int16_t v;
Helmut Tschemernjak 1:3a8297ad8cd9 386 memcpy(&v, &p->u.v_16bit, sizeof(p->u.v_16bit));
Helmut Tschemernjak 1:3a8297ad8cd9 387 value = v;
Helmut Tschemernjak 1:3a8297ad8cd9 388 }
Helmut Tschemernjak 1:3a8297ad8cd9 389 break;
Helmut Tschemernjak 1:3a8297ad8cd9 390 case NVProperty::T_32BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 391 {
Helmut Tschemernjak 1:3a8297ad8cd9 392 int32_t v;
Helmut Tschemernjak 1:3a8297ad8cd9 393 memcpy(&v, &p->data.v_32bit, sizeof(p->data.v_32bit));
Helmut Tschemernjak 1:3a8297ad8cd9 394 value = v;
Helmut Tschemernjak 1:3a8297ad8cd9 395 }
Helmut Tschemernjak 1:3a8297ad8cd9 396 break;
Helmut Tschemernjak 1:3a8297ad8cd9 397 case NVProperty::T_64BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 398 memcpy(&value, p->data.v_64bit, sizeof(p->data.v_64bit));
Helmut Tschemernjak 1:3a8297ad8cd9 399 break;
Helmut Tschemernjak 1:3a8297ad8cd9 400 case NVProperty::T_STR:
Helmut Tschemernjak 1:3a8297ad8cd9 401 case NVProperty::T_BLOB:
Helmut Tschemernjak 1:3a8297ad8cd9 402 value = p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 403 break;
Helmut Tschemernjak 1:3a8297ad8cd9 404 }
Helmut Tschemernjak 1:3a8297ad8cd9 405 index++;
Helmut Tschemernjak 1:3a8297ad8cd9 406 if (p->t.deleted) {
Helmut Tschemernjak 1:3a8297ad8cd9 407 dprintf("Dump[%.2d] Key: %d Type: %d deleted(%d)", index, p->key, p->t.type, p->t.deleted);
Helmut Tschemernjak 1:3a8297ad8cd9 408
Helmut Tschemernjak 1:3a8297ad8cd9 409 } else if (p->t.type == NVProperty::T_STR) {
Helmut Tschemernjak 1:3a8297ad8cd9 410 dprintf("Dump[%.2d] Key: %d Type: %d value: %s", index, p->key, p->t.type, p->data.v_str);
Helmut Tschemernjak 1:3a8297ad8cd9 411 } else if (p->t.type == NVProperty::T_BLOB) {
Helmut Tschemernjak 1:3a8297ad8cd9 412 dprintf("Dump[%.2d] Key: %d Type: %d len: %d", index, p->key, p->t.type, p->u.option.d_len);
Helmut Tschemernjak 1:3a8297ad8cd9 413 dump("Blob", p->data.v_str, p->u.option.d_len);
Helmut Tschemernjak 1:3a8297ad8cd9 414 } else {
Helmut Tschemernjak 1:3a8297ad8cd9 415 if (p->t.type == NVProperty::T_64BIT) {
Helmut Tschemernjak 1:3a8297ad8cd9 416 dprintf("Dump[%.2d] Key: %d Type: %d value: %lld (0x%llx)", index, p->key, p->t.type, value, value);
Helmut Tschemernjak 1:3a8297ad8cd9 417 } else {
Helmut Tschemernjak 1:3a8297ad8cd9 418 dprintf("Dump[%.2d] Key: %d Type: %d value: %ld (0x%x)", index, p->key, p->t.type, (int32_t)value, (unsigned int)value);
Helmut Tschemernjak 1:3a8297ad8cd9 419 }
Helmut Tschemernjak 1:3a8297ad8cd9 420 }
Helmut Tschemernjak 1:3a8297ad8cd9 421
Helmut Tschemernjak 1:3a8297ad8cd9 422 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 1:3a8297ad8cd9 423 }
Helmut Tschemernjak 1:3a8297ad8cd9 424 int freebytes = _endAddress -(uint8_t *)_lastEntry;
Helmut Tschemernjak 1:3a8297ad8cd9 425 if (_lastEntry)
Helmut Tschemernjak 1:3a8297ad8cd9 426 dprintf("------ %d bytes free -------", freebytes);
Helmut Tschemernjak 1:3a8297ad8cd9 427 }
Helmut Tschemernjak 1:3a8297ad8cd9 428 #endif
Helmut Tschemernjak 1:3a8297ad8cd9 429
Helmut Tschemernjak 1:3a8297ad8cd9 430 NVProperty_L4OTP::_flashEntry *
Helmut Tschemernjak 1:3a8297ad8cd9 431 NVProperty_L4OTP::_GetFlashEntry(int key, uint8_t *start)
Helmut Tschemernjak 1:3a8297ad8cd9 432 {
Helmut Tschemernjak 1:3a8297ad8cd9 433 _flashEntry *p;
Helmut Tschemernjak 1:3a8297ad8cd9 434
Helmut Tschemernjak 1:3a8297ad8cd9 435 if (start)
Helmut Tschemernjak 1:3a8297ad8cd9 436 p = (_flashEntry *)start;
Helmut Tschemernjak 1:3a8297ad8cd9 437 else
Helmut Tschemernjak 1:3a8297ad8cd9 438 p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 1:3a8297ad8cd9 439 _flashEntry *lastP = NULL;
Helmut Tschemernjak 1:3a8297ad8cd9 440 while(true) {
Helmut Tschemernjak 1:3a8297ad8cd9 441 if ((uint8_t*)p >= _endAddress || p->key == NVProperty::PROPERTIES_EOF) {
Helmut Tschemernjak 1:3a8297ad8cd9 442 if ((uint8_t*)p <= _endAddress)
Helmut Tschemernjak 1:3a8297ad8cd9 443 _lastEntry = p;
Helmut Tschemernjak 1:3a8297ad8cd9 444 if (!lastP || lastP->t.deleted)
Helmut Tschemernjak 1:3a8297ad8cd9 445 return NULL;
Helmut Tschemernjak 1:3a8297ad8cd9 446 break;
Helmut Tschemernjak 1:3a8297ad8cd9 447 }
Helmut Tschemernjak 1:3a8297ad8cd9 448 if (p->key == key)
Helmut Tschemernjak 1:3a8297ad8cd9 449 lastP = p;
Helmut Tschemernjak 1:3a8297ad8cd9 450
Helmut Tschemernjak 1:3a8297ad8cd9 451 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 1:3a8297ad8cd9 452 }
Helmut Tschemernjak 1:3a8297ad8cd9 453 return lastP;
Helmut Tschemernjak 1:3a8297ad8cd9 454 }
Helmut Tschemernjak 1:3a8297ad8cd9 455
Helmut Tschemernjak 1:3a8297ad8cd9 456
Helmut Tschemernjak 1:3a8297ad8cd9 457 int
Helmut Tschemernjak 1:3a8297ad8cd9 458 NVProperty_L4OTP::_GetFlashEntryLen(_flashEntry *p)
Helmut Tschemernjak 1:3a8297ad8cd9 459 {
Helmut Tschemernjak 1:3a8297ad8cd9 460 int len = 0;
Helmut Tschemernjak 1:3a8297ad8cd9 461
Helmut Tschemernjak 1:3a8297ad8cd9 462 switch(p->t.type) {
Helmut Tschemernjak 1:3a8297ad8cd9 463 case NVProperty::T_64BIT:
Helmut Tschemernjak 1:3a8297ad8cd9 464 case NVProperty::T_STR:
Helmut Tschemernjak 1:3a8297ad8cd9 465 case NVProperty::T_BLOB:
Helmut Tschemernjak 1:3a8297ad8cd9 466 len = (FLASH_ENTRY_MIN_SIZE - 4) + p->u.option.d_len;
Helmut Tschemernjak 1:3a8297ad8cd9 467 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 1:3a8297ad8cd9 468 break;
Helmut Tschemernjak 1:3a8297ad8cd9 469 default:
Helmut Tschemernjak 1:3a8297ad8cd9 470 len = FLASH_ENTRY_MIN_SIZE;
Helmut Tschemernjak 1:3a8297ad8cd9 471 }
Helmut Tschemernjak 1:3a8297ad8cd9 472 return len;
Helmut Tschemernjak 1:3a8297ad8cd9 473 }
Helmut Tschemernjak 1:3a8297ad8cd9 474
Helmut Tschemernjak 1:3a8297ad8cd9 475 int
Helmut Tschemernjak 1:3a8297ad8cd9 476 NVProperty_L4OTP::_GetFlashPaddingSize(int len)
Helmut Tschemernjak 1:3a8297ad8cd9 477 {
Helmut Tschemernjak 1:3a8297ad8cd9 478 int remain = len % FLASH_PADDING_SIZE;
Helmut Tschemernjak 1:3a8297ad8cd9 479
Helmut Tschemernjak 1:3a8297ad8cd9 480 if (remain == 0)
Helmut Tschemernjak 1:3a8297ad8cd9 481 return 0;
Helmut Tschemernjak 1:3a8297ad8cd9 482
Helmut Tschemernjak 1:3a8297ad8cd9 483 return (len + FLASH_PADDING_SIZE - remain) - len;
Helmut Tschemernjak 1:3a8297ad8cd9 484 }
Helmut Tschemernjak 1:3a8297ad8cd9 485
Helmut Tschemernjak 1:3a8297ad8cd9 486
Helmut Tschemernjak 1:3a8297ad8cd9 487 int
Helmut Tschemernjak 1:3a8297ad8cd9 488 NVProperty_L4OTP::_FlashReorgEntries(int minRequiredSpace)
Helmut Tschemernjak 1:3a8297ad8cd9 489 {
Helmut Tschemernjak 1:3a8297ad8cd9 490 return 0; // no reorg on OTP
Helmut Tschemernjak 1:3a8297ad8cd9 491 }
Helmut Tschemernjak 1:3a8297ad8cd9 492
Helmut Tschemernjak 1:3a8297ad8cd9 493
Helmut Tschemernjak 1:3a8297ad8cd9 494 void
Helmut Tschemernjak 1:3a8297ad8cd9 495 NVProperty_L4OTP::_OTPWrite(uint8_t *address, const void *d, size_t length)
Helmut Tschemernjak 1:3a8297ad8cd9 496 {
Helmut Tschemernjak 1:3a8297ad8cd9 497 //FlashIAP f;
Helmut Tschemernjak 1:3a8297ad8cd9 498 //f.init();
Helmut Tschemernjak 1:3a8297ad8cd9 499 #ifdef OTP_TEST_IN_RAM
Helmut Tschemernjak 1:3a8297ad8cd9 500 memcpy(address, d, length);
Helmut Tschemernjak 1:3a8297ad8cd9 501 #else
Helmut Tschemernjak 1:3a8297ad8cd9 502 uint8_t *data = (uint8_t *)d;
Helmut Tschemernjak 1:3a8297ad8cd9 503 uint32_t addr = (uint32_t)address;
Helmut Tschemernjak 1:3a8297ad8cd9 504 volatile uint64_t data64;
Helmut Tschemernjak 1:3a8297ad8cd9 505
Helmut Tschemernjak 1:3a8297ad8cd9 506 HAL_FLASH_Unlock();
Helmut Tschemernjak 1:3a8297ad8cd9 507 while (length > 0) {
Helmut Tschemernjak 1:3a8297ad8cd9 508 for (uint8_t i = 0; i < 8; i++) {
Helmut Tschemernjak 1:3a8297ad8cd9 509 *(((uint8_t *) &data64) + i) = *(data + i);
Helmut Tschemernjak 1:3a8297ad8cd9 510 }
Helmut Tschemernjak 1:3a8297ad8cd9 511 int err = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, data64);
Helmut Tschemernjak 1:3a8297ad8cd9 512 addr += 8;
Helmut Tschemernjak 1:3a8297ad8cd9 513 data += 8;
Helmut Tschemernjak 1:3a8297ad8cd9 514 length -= 8;
Helmut Tschemernjak 1:3a8297ad8cd9 515 }
Helmut Tschemernjak 1:3a8297ad8cd9 516 HAL_FLASH_Lock();
Helmut Tschemernjak 1:3a8297ad8cd9 517 #endif
Helmut Tschemernjak 1:3a8297ad8cd9 518 }
Helmut Tschemernjak 1:3a8297ad8cd9 519
Helmut Tschemernjak 1:3a8297ad8cd9 520 #endif
Helmut Tschemernjak 1:3a8297ad8cd9 521
Helmut Tschemernjak 1:3a8297ad8cd9 522
Helmut Tschemernjak 1:3a8297ad8cd9 523 #endif // TARGET_STM32L4