50 #define ALIGNED_REC_SIZE(n) \
51 (flash_offset_t)MFS_ALIGN_NEXT(sizeof (mfs_data_header_t) + (size_t)(n))
56 #define ALIGNED_DHDR_SIZE \
62 #define ALIGNED_SIZEOF(t) \
63 (((sizeof (t) - 1U) | MFS_ALIGN_MASK) + 1U)
68 #define PAIR(a, b) (((unsigned)(a) << 2U) | (unsigned)(b))
73 #define RET_ON_ERROR(err) do { \
74 mfs_error_t e = (err); \
75 if (e != MFS_NO_ERROR) { \
88 static const uint16_t crc16_table[256] = {
89 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
90 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
91 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
92 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
93 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
94 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
95 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
96 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
97 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
98 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
99 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
100 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
101 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
102 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
103 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
104 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
105 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
106 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
107 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
108 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
109 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
110 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
111 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
112 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
113 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
114 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
115 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
116 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
117 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
118 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
119 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
120 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
127 uint16_t crc16(uint16_t crc,
const uint8_t *data,
size_t n) {
130 crc = (crc << 8U) ^ crc16_table[(crc >> 8U) ^ (uint16_t)*data];
138 static void mfs_state_reset(
MFSDriver *mfsp) {
158 mfsp->config->bank1_start);
173 size_t n, uint8_t *rp) {
177 if (ferr != FLASH_NO_ERROR) {
178 mfsp->
state = MFS_ERROR;
179 return MFS_ERR_FLASH_FAILURE;
205 if (ferr != FLASH_NO_ERROR) {
206 mfsp->
state = MFS_ERROR;
207 return MFS_ERR_FLASH_FAILURE;
210 #if MFS_CFG_WRITE_VERIFY == TRUE
217 if (memcmp((
void *)mfsp->
buffer.data8, (
void *)wp, chunk)) {
218 mfsp->
state = MFS_ERROR;
219 return MFS_ERR_FLASH_FAILURE;
282 if (bank == MFS_BANK_0) {
291 while (sector < end) {
295 if (ferr != FLASH_NO_ERROR) {
296 mfsp->
state = MFS_ERROR;
297 return MFS_ERR_FLASH_FAILURE;
300 if (ferr != FLASH_NO_ERROR) {
301 mfsp->
state = MFS_ERROR;
302 return MFS_ERR_FLASH_FAILURE;
305 if (ferr != FLASH_NO_ERROR) {
306 mfsp->
state = MFS_ERROR;
307 return MFS_ERR_FLASH_FAILURE;
328 if (bank == MFS_BANK_0) {
337 while (sector < end) {
341 if (ferr == FLASH_ERROR_VERIFY) {
342 return MFS_ERR_NOT_ERASED;
344 if (ferr != FLASH_NO_ERROR) {
345 mfsp->
state = MFS_ERROR;
346 return MFS_ERR_FLASH_FAILURE;
371 if (bank == MFS_BANK_0) {
378 bhdr.fields.
magic1 = MFS_BANK_MAGIC_1;
379 bhdr.fields.
magic2 = MFS_BANK_MAGIC_2;
382 bhdr.fields.
crc = crc16(0xFFFFU, bhdr.hdr8,
406 return MFS_BANK_ERASED;
410 if ((mfsp->
buffer.bhdr.fields.
magic1 != MFS_BANK_MAGIC_1) ||
411 (mfsp->
buffer.bhdr.fields.
magic2 != MFS_BANK_MAGIC_2) ||
414 return MFS_BANK_GARBAGE;
418 crc = crc16(0xFFFFU, mfsp->
buffer.bhdr.hdr8,
420 if (crc != mfsp->
buffer.bhdr.fields.
crc) {
421 return MFS_BANK_GARBAGE;
448 start_offset = mfs_flash_get_bank_offset(mfsp, bank);
474 if ((u.dhdr.fields.magic1 != MFS_HEADER_MAGIC_1) ||
475 (u.dhdr.fields.magic2 != MFS_HEADER_MAGIC_2) ||
476 (u.dhdr.fields.id < 1U) ||
478 (u.dhdr.fields.size > end_offset - hdr_offset)) {
486 if (u.dhdr.fields.size > 0U) {
488 uint32_t total = u.dhdr.fields.size;
498 crc = crc16(crc, &mfsp->
buffer.data8[0], chunk);
505 if (crc != u.dhdr.fields.crc) {
512 if (u.dhdr.fields.size == 0U) {
513 mfsp->
descriptors[u.dhdr.fields.id - 1U].offset = 0U;
514 mfsp->
descriptors[u.dhdr.fields.id - 1U].size = 0U;
517 mfsp->
descriptors[u.dhdr.fields.id - 1U].offset = hdr_offset;
518 mfsp->
descriptors[u.dhdr.fields.id - 1U].size = u.dhdr.fields.size;
565 if (*statep == MFS_BANK_ERASED) {
570 if (err == MFS_ERR_NOT_ERASED) {
571 *statep = MFS_BANK_GARBAGE;
593 if (sbank == MFS_BANK_0) {
601 dest_offset = mfs_flash_get_bank_offset(mfsp, dbank) +
612 dest_offset += totsize;
641 uint32_t cnt0 = 0, cnt1 = 0;
642 bool w1 =
false, w2 =
false;
645 mfs_state_reset(mfsp);
653 switch (
PAIR(sts0, sts1)) {
655 case PAIR(MFS_BANK_ERASED, MFS_BANK_ERASED):
661 case PAIR(MFS_BANK_OK, MFS_BANK_OK):
677 case PAIR(MFS_BANK_GARBAGE, MFS_BANK_GARBAGE):
686 case PAIR(MFS_BANK_ERASED, MFS_BANK_OK):
691 case PAIR(MFS_BANK_OK, MFS_BANK_ERASED):
696 case PAIR(MFS_BANK_ERASED, MFS_BANK_GARBAGE):
704 case PAIR(MFS_BANK_GARBAGE, MFS_BANK_ERASED):
712 case PAIR(MFS_BANK_OK, MFS_BANK_GARBAGE):
719 case PAIR(MFS_BANK_GARBAGE, MFS_BANK_OK):
727 return MFS_ERR_INTERNAL;
741 return MFS_ERR_INTERNAL;
766 return (w1 || w2) ? MFS_WARN_REPAIR : MFS_NO_ERROR;
789 mfs_state_reset(mfsp);
796 if (err == MFS_ERR_INTERNAL) {
799 mfsp->
state = MFS_ERROR;
802 if (!MFS_IS_ERROR(err)) {
803 mfsp->
state = MFS_READY;
809 mfsp->
state = MFS_ERROR;
810 return MFS_ERR_FLASH_FAILURE;
828 mfsp->
state = MFS_STOP;
853 (mfsp->
state == MFS_ERROR),
"invalid state");
872 (mfsp->
state == MFS_ERROR),
"invalid state");
875 mfsp->
state = MFS_STOP;
898 if (mfsp->
state != MFS_READY) {
899 return MFS_ERR_INV_STATE;
933 size_t *np, uint8_t *buffer) {
938 (np != NULL) && (*np > 0U) && (buffer != NULL));
940 if ((mfsp->
state != MFS_READY) && (mfsp->
state != MFS_TRANSACTION)) {
941 return MFS_ERR_INV_STATE;
946 return MFS_ERR_NOT_FOUND;
950 if (*np < mfsp->descriptors[
id - 1U].size) {
951 return MFS_ERR_INV_SIZE;
968 crc = crc16(0xFFFFU, buffer, *np);
969 if (crc != mfsp->
buffer.dhdr.fields.
crc) {
970 mfsp->
state = MFS_ERROR;
971 return MFS_ERR_FLASH_FAILURE;
1006 size_t n,
const uint8_t *buffer) {
1011 (n > 0U) && (buffer != NULL));
1017 if (mfsp->
state == MFS_READY) {
1018 bool warning =
false;
1026 return MFS_ERR_OUT_OF_MEM;
1030 free = (mfs_flash_get_bank_offset(mfsp, mfsp->
current_bank) +
1032 if (rspace > free) {
1040 mfsp->
buffer.dhdr.fields.
id = (uint16_t)
id;
1042 mfsp->
buffer.dhdr.fields.
crc = crc16(0xFFFFU, buffer, n);
1046 mfsp->
buffer.data8 + (sizeof (uint32_t) * 2U)));
1055 mfsp->
buffer.dhdr.fields.
magic1 = (uint32_t)MFS_HEADER_MAGIC_1;
1056 mfsp->
buffer.dhdr.fields.
magic2 = (uint32_t)MFS_HEADER_MAGIC_2;
1059 sizeof (uint32_t) * 2U,
1074 return warning ? MFS_WARN_GC : MFS_NO_ERROR;
1077 #if MFS_CFG_TRANSACTION_MAX > 0
1079 if (mfsp->
state == MFS_TRANSACTION) {
1085 return MFS_ERR_TRANSACTION_NUM;
1092 return MFS_ERR_TRANSACTION_SIZE;
1096 mfsp->
buffer.dhdr.fields.
id = (uint16_t)
id;
1098 mfsp->
buffer.dhdr.fields.
crc = crc16(0xFFFFU, buffer, n);
1102 mfsp->
buffer.data8 + (sizeof (uint32_t) * 2U)));
1120 return MFS_NO_ERROR;
1125 return MFS_ERR_INV_STATE;
1164 if (mfsp->
state == MFS_READY) {
1165 bool warning =
false;
1169 return MFS_ERR_NOT_FOUND;
1176 return MFS_ERR_INTERNAL;
1180 free = (mfs_flash_get_bank_offset(mfsp, mfsp->
current_bank) +
1182 if (rspace > free) {
1191 mfsp->
buffer.dhdr.fields.
magic1 = (uint32_t)MFS_HEADER_MAGIC_1;
1192 mfsp->
buffer.dhdr.fields.
magic2 = (uint32_t)MFS_HEADER_MAGIC_2;
1193 mfsp->
buffer.dhdr.fields.
id = (uint16_t)
id;
1195 mfsp->
buffer.dhdr.fields.
crc = (uint16_t)0xFFFF;
1207 return warning ? MFS_WARN_GC : MFS_NO_ERROR;
1210 #if MFS_CFG_TRANSACTION_MAX > 0
1212 if (mfsp->
state == MFS_TRANSACTION) {
1217 return MFS_ERR_NOT_FOUND;
1223 return MFS_ERR_TRANSACTION_NUM;
1230 return MFS_ERR_TRANSACTION_SIZE;
1235 mfsp->
buffer.dhdr.fields.
id = (uint16_t)
id;
1237 mfsp->
buffer.dhdr.fields.
crc = (uint16_t)0xFFFF;
1241 mfsp->
buffer.data8 + (sizeof (uint32_t) * 2U)));
1253 return MFS_NO_ERROR;
1257 return MFS_ERR_INV_STATE;
1282 if (mfsp->
state != MFS_READY) {
1283 return MFS_ERR_INV_STATE;
1289 #if (MFS_CFG_TRANSACTION_MAX > 0) || defined(__DOXYGEN__)
1326 if (mfsp->
state != MFS_READY) {
1327 return MFS_ERR_INV_STATE;
1337 return MFS_ERR_OUT_OF_MEM;
1341 free = (mfs_flash_get_bank_offset(mfsp, mfsp->
current_bank) +
1343 if (rspace > free) {
1350 mfsp->
state = MFS_TRANSACTION;
1357 return MFS_NO_ERROR;
1382 if (mfsp->
state != MFS_TRANSACTION) {
1383 return MFS_ERR_INV_STATE;
1387 mfsp->
buffer.dhdr.fields.
magic1 = (uint32_t)MFS_HEADER_MAGIC_1;
1388 mfsp->
buffer.dhdr.fields.
magic2 = (uint32_t)MFS_HEADER_MAGIC_2;
1390 while (top > &mfsp->
tr_ops[0]) {
1397 sizeof (uint32_t) * 2U,
1404 while (top < &mfsp->tr_ops[mfsp->
tr_nops]) {
1405 unsigned i = (unsigned)top->
id - 1U;
1409 if (top->
size > 0U) {
1434 mfsp->
state = MFS_READY;
1436 return MFS_NO_ERROR;
1462 if (mfsp->
state != MFS_TRANSACTION) {
1463 return MFS_ERR_INV_STATE;
1467 mfsp->
state = MFS_READY;