Parent directory

eeprom_legacy_emulated_flash_tests.cpp

18011 bytes
  1/* Copyright 2021 by Don Kjer
  2 *
  3 * This program is free software: you can redistribute it and/or modify
  4 * it under the terms of the GNU General Public License as published by
  5 * the Free Software Foundation, either version 2 of the License, or
  6 * (at your option) any later version.
  7 *
  8 * This program is distributed in the hope that it will be useful,
  9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 *
 13 * You should have received a copy of the GNU General Public License
 14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 15 */
 16
 17#include "gtest/gtest.h"
 18
 19extern "C" {
 20#include "eeprom.h"
 21}
 22
 23/* Mock Flash Parameters:
 24 *
 25 * === Large Layout ===
 26 * flash size: 65536
 27 * page size: 2048
 28 * density pages: 16
 29 * Simulated EEPROM size: 16384
 30 *
 31 * FlashBuf Layout:
 32 * [Unused | Compact |  Write Log  ]
 33 * [0......|32768......|49152......65535]
 34 *
 35 * === Tiny Layout ===
 36 * flash size: 1024
 37 * page size: 512
 38 * density pages: 1
 39 * Simulated EEPROM size: 256
 40 *
 41 * FlashBuf Layout:
 42 * [Unused | Compact |  Write Log  ]
 43 * [0......|512......|768......1023]
 44 *
 45 */
 46
 47#define LOG_SIZE EEPROM_SIZE
 48#define LOG_BASE (MOCK_FLASH_SIZE - LOG_SIZE)
 49#define EEPROM_BASE (LOG_BASE - EEPROM_SIZE)
 50
 51/* Log encoding helpers */
 52#define BYTE_VALUE(addr, value) (((addr) << 8) | (value))
 53#define WORD_ZERO(addr) (0x8000 | ((addr) >> 1))
 54#define WORD_ONE(addr) (0xA000 | ((addr) >> 1))
 55#define WORD_NEXT(addr) (0xE000 | (((addr)-0x80) >> 1))
 56
 57class EepromStm32Test : public testing::Test {
 58   public:
 59    EepromStm32Test() {}
 60    ~EepromStm32Test() {}
 61
 62   protected:
 63    void SetUp() override {
 64        EEPROM_Erase();
 65    }
 66
 67    void TearDown() override {
 68#ifdef EEPROM_DEBUG
 69        dumpEepromDataBuf();
 70#endif
 71    }
 72};
 73
 74TEST_F(EepromStm32Test, TestErase) {
 75    EEPROM_WriteDataByte(0, 0x42);
 76    EEPROM_Erase();
 77    EXPECT_EQ(EEPROM_ReadDataByte(0), 0);
 78    EXPECT_EQ(EEPROM_ReadDataByte(1), 0);
 79}
 80
 81TEST_F(EepromStm32Test, TestReadGarbage) {
 82    uint8_t garbage = 0x3c;
 83    for (int i = 0; i < MOCK_FLASH_SIZE; ++i) {
 84        garbage ^= 0xa3;
 85        garbage += i;
 86        FlashBuf[i] = garbage;
 87    }
 88    EEPROM_Init(); // Just verify we don't crash
 89}
 90
 91TEST_F(EepromStm32Test, TestWriteBadAddress) {
 92    EXPECT_EQ(EEPROM_WriteDataByte(EEPROM_SIZE, 0x42), FLASH_BAD_ADDRESS);
 93    EXPECT_EQ(EEPROM_WriteDataWord(EEPROM_SIZE - 1, 0xbeef), FLASH_BAD_ADDRESS);
 94    EXPECT_EQ(EEPROM_WriteDataWord(EEPROM_SIZE, 0xbeef), FLASH_BAD_ADDRESS);
 95}
 96
 97TEST_F(EepromStm32Test, TestReadBadAddress) {
 98    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE), 0xFF);
 99    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 1), 0xFFFF);
100    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE), 0xFFFF);
101    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0);
102    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 3)), 0xFF000000);
103    EXPECT_EQ(eeprom_read_dword((uint32_t*)EEPROM_SIZE), 0xFFFFFFFF);
104}
105
106TEST_F(EepromStm32Test, TestReadByte) {
107    /* Direct compacted-area baseline: Address < 0x80 */
108    FlashBuf[EEPROM_BASE + 2] = ~0xef;
109    FlashBuf[EEPROM_BASE + 3] = ~0xbe;
110    /* Direct compacted-area baseline: Address >= 0x80 */
111    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 2] = ~0x78;
112    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 1] = ~0x56;
113    /* Check values */
114    EEPROM_Init();
115    EXPECT_EQ(EEPROM_ReadDataByte(2), 0xef);
116    EXPECT_EQ(EEPROM_ReadDataByte(3), 0xbe);
117    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 2), 0x78);
118    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 1), 0x56);
119    /* Write Log byte value */
120    FlashBuf[LOG_BASE]     = 0x65;
121    FlashBuf[LOG_BASE + 1] = 3;
122    /* Write Log word value */
123    *(uint16_t*)&FlashBuf[LOG_BASE + 2] = WORD_NEXT(EEPROM_SIZE - 2);
124    *(uint16_t*)&FlashBuf[LOG_BASE + 4] = ~0x9abc;
125    /* Check values */
126    EEPROM_Init();
127    EXPECT_EQ(EEPROM_ReadDataByte(2), 0xef);
128    EXPECT_EQ(EEPROM_ReadDataByte(3), 0x65);
129    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 2), 0xbc);
130    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 1), 0x9a);
131}
132
133TEST_F(EepromStm32Test, TestWriteByte) {
134    /* Direct compacted-area baseline: Address < 0x80 */
135    EEPROM_WriteDataByte(2, 0xef);
136    EEPROM_WriteDataByte(3, 0xbe);
137    /* Direct compacted-area baseline: Address >= 0x80 */
138    EEPROM_WriteDataByte(EEPROM_SIZE - 2, 0x78);
139    EEPROM_WriteDataByte(EEPROM_SIZE - 1, 0x56);
140    /* Check values */
141    /* First write in each aligned word should have been direct */
142    EXPECT_EQ(FlashBuf[EEPROM_BASE + 2], (uint8_t)~0xef);
143    EXPECT_EQ(FlashBuf[EEPROM_BASE + EEPROM_SIZE - 2], (uint8_t)~0x78);
144
145    /* Second write per aligned word requires a log entry */
146    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE], BYTE_VALUE(3, 0xbe));
147    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 2], WORD_NEXT(EEPROM_SIZE - 1));
148    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 4], (uint16_t)~0x5678);
149}
150
151TEST_F(EepromStm32Test, TestByteRoundTrip) {
152    /* Direct compacted-area: Address < 0x80 */
153    EEPROM_WriteDataWord(0, 0xdead);
154    EEPROM_WriteDataByte(2, 0xef);
155    EEPROM_WriteDataByte(3, 0xbe);
156    /* Direct compacted-area: Address >= 0x80 */
157    EEPROM_WriteDataByte(EEPROM_SIZE - 2, 0x78);
158    EEPROM_WriteDataByte(EEPROM_SIZE - 1, 0x56);
159    /* Check values */
160    EEPROM_Init();
161    EXPECT_EQ(EEPROM_ReadDataByte(0), 0xad);
162    EXPECT_EQ(EEPROM_ReadDataByte(1), 0xde);
163    EXPECT_EQ(EEPROM_ReadDataByte(2), 0xef);
164    EXPECT_EQ(EEPROM_ReadDataByte(3), 0xbe);
165    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 2), 0x78);
166    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 1), 0x56);
167    /* Write log entries */
168    EEPROM_WriteDataByte(2, 0x80);
169    EEPROM_WriteDataByte(EEPROM_SIZE - 2, 0x3c);
170    /* Check values */
171    EEPROM_Init();
172    EXPECT_EQ(EEPROM_ReadDataByte(2), 0x80);
173    EXPECT_EQ(EEPROM_ReadDataByte(3), 0xbe);
174    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 2), 0x3c);
175    EXPECT_EQ(EEPROM_ReadDataByte(EEPROM_SIZE - 1), 0x56);
176}
177
178TEST_F(EepromStm32Test, TestReadWord) {
179    /* Direct compacted-area baseline: Address < 0x80 */
180    FlashBuf[EEPROM_BASE + 0] = ~0xad;
181    FlashBuf[EEPROM_BASE + 1] = ~0xde;
182    /* Direct compacted-area baseline: Address >= 0x80 */
183    FlashBuf[EEPROM_BASE + 200]             = ~0xcd;
184    FlashBuf[EEPROM_BASE + 201]             = ~0xab;
185    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 4] = ~0x34;
186    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 3] = ~0x12;
187    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 2] = ~0x78;
188    FlashBuf[EEPROM_BASE + EEPROM_SIZE - 1] = ~0x56;
189    /* Check values */
190    EEPROM_Init();
191    EXPECT_EQ(EEPROM_ReadDataWord(0), 0xdead);
192    EXPECT_EQ(EEPROM_ReadDataWord(200), 0xabcd);
193    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 4), 0x1234);
194    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 2), 0x5678);
195    /* Write Log word zero-encoded */
196    *(uint16_t*)&FlashBuf[LOG_BASE] = WORD_ZERO(200);
197    /* Write Log word one-encoded */
198    *(uint16_t*)&FlashBuf[LOG_BASE + 2] = WORD_ONE(EEPROM_SIZE - 4);
199    /* Write Log word value */
200    *(uint16_t*)&FlashBuf[LOG_BASE + 4] = WORD_NEXT(EEPROM_SIZE - 2);
201    *(uint16_t*)&FlashBuf[LOG_BASE + 6] = ~0x9abc;
202    /* Check values */
203    EEPROM_Init();
204    EXPECT_EQ(EEPROM_ReadDataWord(200), 0);
205    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 4), 1);
206    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 2), 0x9abc);
207}
208
209TEST_F(EepromStm32Test, TestWriteWord) {
210    /* Direct compacted-area: Address < 0x80 */
211    EEPROM_WriteDataWord(0, 0xdead); // Aligned
212    EEPROM_WriteDataWord(3, 0xbeef); // Unaligned
213    /* Direct compacted-area: Address >= 0x80 */
214    EEPROM_WriteDataWord(200, 0xabcd); // Aligned
215    EEPROM_WriteDataWord(203, 0x9876); // Unaligned
216    EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0x1234);
217    EEPROM_WriteDataWord(EEPROM_SIZE - 2, 0x5678);
218    /* Write Log word zero-encoded */
219    EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0);
220    /* Write Log word one-encoded */
221    EEPROM_WriteDataWord(EEPROM_SIZE - 2, 1);
222    /* Write Log word value aligned */
223    EEPROM_WriteDataWord(200, 0x4321); // Aligned
224    /* Write Log word value unaligned */
225    EEPROM_WriteDataByte(202, 0x3c);   // Set neighboring byte
226    EEPROM_WriteDataWord(203, 0xcdef); // Unaligned
227    /* Check values */
228    /* Direct compacted-area */
229    EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE], (uint16_t)~0xdead);
230    EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE + 3], (uint16_t)~0xbeef);
231    EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE + 200], (uint16_t)~0xabcd);
232    EXPECT_EQ(FlashBuf[EEPROM_BASE + 203], (uint8_t)~0x76);
233    EXPECT_EQ(FlashBuf[EEPROM_BASE + 204], (uint8_t)~0x98);
234    EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE + EEPROM_SIZE - 4], (uint16_t)~0x1234);
235    EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE + EEPROM_SIZE - 2], (uint16_t)~0x5678);
236    /* Write Log word zero-encoded */
237    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE], WORD_ZERO(EEPROM_SIZE - 4));
238    /* Write Log word one-encoded */
239    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 2], WORD_ONE(EEPROM_SIZE - 2));
240    /* Write Log word value aligned */
241    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 4], WORD_NEXT(200));
242    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 6], (uint16_t)~0x4321);
243    /* Write Log word value unaligned */
244    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 8], WORD_NEXT(202));
245    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 10], (uint16_t)~0x763c);
246    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 12], WORD_NEXT(202));
247    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 14], (uint16_t)~0xef3c);
248    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 16], WORD_NEXT(204));
249    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 18], (uint16_t)~0x00cd);
250}
251
252TEST_F(EepromStm32Test, TestWordRoundTrip) {
253    /* Direct compacted-area: Address < 0x80 */
254    EEPROM_WriteDataWord(0, 0xdead); // Aligned
255    EEPROM_WriteDataWord(3, 0xbeef); // Unaligned
256    /* Direct compacted-area: Address >= 0x80 */
257    EEPROM_WriteDataWord(200, 0xabcd); // Aligned
258    EEPROM_WriteDataWord(203, 0x9876); // Unaligned
259    EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0x1234);
260    EEPROM_WriteDataWord(EEPROM_SIZE - 2, 0x5678);
261    /* Check values */
262    EEPROM_Init();
263    EXPECT_EQ(EEPROM_ReadDataWord(0), 0xdead);
264    EXPECT_EQ(EEPROM_ReadDataWord(3), 0xbeef);
265    EXPECT_EQ(EEPROM_ReadDataWord(200), 0xabcd);
266    EXPECT_EQ(EEPROM_ReadDataWord(203), 0x9876);
267    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 4), 0x1234);
268    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 2), 0x5678);
269
270    /* Write Log word zero-encoded */
271    EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0);
272    /* Write Log word one-encoded */
273    EEPROM_WriteDataWord(EEPROM_SIZE - 2, 1);
274    /* Write Log word value aligned */
275    EEPROM_WriteDataWord(200, 0x4321); // Aligned
276    /* Write Log word value unaligned */
277    EEPROM_WriteDataByte(202, 0x3c);   // Set neighboring byte
278    EEPROM_WriteDataWord(203, 0xcdef); // Unaligned
279    /* Check values */
280    EEPROM_Init();
281    EXPECT_EQ(EEPROM_ReadDataWord(200), 0x4321);
282    EXPECT_EQ(EEPROM_ReadDataByte(202), 0x3c);
283    EXPECT_EQ(EEPROM_ReadDataWord(203), 0xcdef);
284    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 4), 0);
285    EXPECT_EQ(EEPROM_ReadDataWord(EEPROM_SIZE - 2), 1);
286}
287
288TEST_F(EepromStm32Test, TestByteWordBoundary) {
289    /* Direct compacted-area write */
290    EEPROM_WriteDataWord(0x7e, 0xdead);
291    EEPROM_WriteDataWord(0x80, 0xbeef);
292    /* Byte log entry */
293    EEPROM_WriteDataByte(0x7f, 0x3c);
294    /* Word log entry */
295    EEPROM_WriteDataByte(0x80, 0x18);
296    /* Check values */
297    EEPROM_Init();
298    EXPECT_EQ(EEPROM_ReadDataWord(0x7e), 0x3cad);
299    EXPECT_EQ(EEPROM_ReadDataWord(0x80), 0xbe18);
300    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE], BYTE_VALUE(0x7f, 0x3c));
301    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 2], WORD_NEXT(0x80));
302    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 4], (uint16_t)~0xbe18);
303    /* Byte log entries */
304    EEPROM_WriteDataWord(0x7e, 0xcafe);
305    /* Check values */
306    EEPROM_Init();
307    EXPECT_EQ(EEPROM_ReadDataWord(0x7e), 0xcafe);
308    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 6], BYTE_VALUE(0x7e, 0xfe));
309    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 8], BYTE_VALUE(0x7f, 0xca));
310    /* Byte and Word log entries */
311    EEPROM_WriteDataWord(0x7f, 0xba5e);
312    /* Check values */
313    EEPROM_Init();
314    EXPECT_EQ(EEPROM_ReadDataWord(0x7f), 0xba5e);
315    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 10], BYTE_VALUE(0x7f, 0x5e));
316    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 12], WORD_NEXT(0x80));
317    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 14], (uint16_t)~0xbeba);
318    /* Word log entry */
319    EEPROM_WriteDataWord(0x80, 0xf00d);
320    /* Check values */
321    EEPROM_Init();
322    EXPECT_EQ(EEPROM_ReadDataWord(0x80), 0xf00d);
323    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 16], WORD_NEXT(0x80));
324    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + 18], (uint16_t)~0xf00d);
325}
326
327TEST_F(EepromStm32Test, TestDWordRoundTrip) {
328    /* Direct compacted-area: Address < 0x80 */
329    eeprom_write_dword((uint32_t*)0, 0xdeadbeef); // Aligned
330    eeprom_write_dword((uint32_t*)9, 0x12345678); // Unaligned
331    /* Direct compacted-area: Address >= 0x80 */
332    eeprom_write_dword((uint32_t*)200, 0xfacef00d);
333    eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xba5eba11); // Aligned
334    eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0xcafed00d); // Unaligned
335    /* Check direct values */
336    EEPROM_Init();
337    EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdeadbeef);
338    EXPECT_EQ(eeprom_read_dword((uint32_t*)9), 0x12345678);
339    EXPECT_EQ(eeprom_read_dword((uint32_t*)200), 0xfacef00d);
340    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xba5eba11); // Aligned
341    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0xcafed00d); // Unaligned
342    /* Write Log byte encoded */
343    eeprom_write_dword((uint32_t*)0, 0xdecafbad);
344    eeprom_write_dword((uint32_t*)9, 0x87654321);
345    /* Write Log word encoded */
346    eeprom_write_dword((uint32_t*)200, 1);
347    /* Write Log word value aligned */
348    eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xdeadc0de); // Aligned
349    eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0x6789abcd); // Unaligned
350    /* Check log values */
351    EEPROM_Init();
352    EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdecafbad);
353    EXPECT_EQ(eeprom_read_dword((uint32_t*)9), 0x87654321);
354    EXPECT_EQ(eeprom_read_dword((uint32_t*)200), 1);
355    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xdeadc0de); // Aligned
356    EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0x6789abcd); // Unaligned
357}
358
359TEST_F(EepromStm32Test, TestBlockRoundTrip) {
360    char  src0[] = "0123456789abcdef";
361    void* src1   = (void*)&src0[1];
362    /* Various alignments of src & dst, Address < 0x80 */
363    eeprom_write_block(src0, (void*)0, sizeof(src0));
364    eeprom_write_block(src0, (void*)21, sizeof(src0));
365    eeprom_write_block(src1, (void*)40, sizeof(src0) - 1);
366    eeprom_write_block(src1, (void*)61, sizeof(src0) - 1);
367    /* Various alignments of src & dst, Address >= 0x80 */
368    eeprom_write_block(src0, (void*)140, sizeof(src0));
369    eeprom_write_block(src0, (void*)161, sizeof(src0));
370    eeprom_write_block(src1, (void*)180, sizeof(src0) - 1);
371    eeprom_write_block(src1, (void*)201, sizeof(src0) - 1);
372
373    /* Check values */
374    EEPROM_Init();
375
376    char  dstBuf[256] = {0};
377    char* dst0a       = (char*)dstBuf;
378    char* dst0b       = (char*)&dstBuf[20];
379    char* dst1a       = (char*)&dstBuf[41];
380    char* dst1b       = (char*)&dstBuf[61];
381    char* dst0c       = (char*)&dstBuf[80];
382    char* dst0d       = (char*)&dstBuf[100];
383    char* dst1c       = (char*)&dstBuf[121];
384    char* dst1d       = (char*)&dstBuf[141];
385    eeprom_read_block((void*)dst0a, (void*)0, sizeof(src0));
386    eeprom_read_block((void*)dst0b, (void*)21, sizeof(src0));
387    eeprom_read_block((void*)dst1a, (void*)40, sizeof(src0) - 1);
388    eeprom_read_block((void*)dst1b, (void*)61, sizeof(src0) - 1);
389    eeprom_read_block((void*)dst0c, (void*)140, sizeof(src0));
390    eeprom_read_block((void*)dst0d, (void*)161, sizeof(src0));
391    eeprom_read_block((void*)dst1c, (void*)180, sizeof(src0) - 1);
392    eeprom_read_block((void*)dst1d, (void*)201, sizeof(src0) - 1);
393    EXPECT_EQ(strcmp((char*)src0, dst0a), 0);
394    EXPECT_EQ(strcmp((char*)src0, dst0b), 0);
395    EXPECT_EQ(strcmp((char*)src0, dst0c), 0);
396    EXPECT_EQ(strcmp((char*)src0, dst0d), 0);
397    EXPECT_EQ(strcmp((char*)src1, dst1a), 0);
398    EXPECT_EQ(strcmp((char*)src1, dst1b), 0);
399    EXPECT_EQ(strcmp((char*)src1, dst1c), 0);
400    EXPECT_EQ(strcmp((char*)src1, dst1d), 0);
401}
402
403TEST_F(EepromStm32Test, TestCompaction) {
404    /* Direct writes */
405    eeprom_write_dword((uint32_t*)0, 0xdeadbeef);
406    eeprom_write_byte((uint8_t*)4, 0x3c);
407    eeprom_write_word((uint16_t*)6, 0xd00d);
408    eeprom_write_dword((uint32_t*)150, 0xcafef00d);
409    eeprom_write_dword((uint32_t*)200, 0x12345678);
410    /* Fill write log entries */
411    uint32_t i;
412    uint32_t val = 0xd8453c6b;
413    for (i = 0; i < (LOG_SIZE / (sizeof(uint32_t) * 2)); i++) {
414        val ^= 0x593ca5b3;
415        val += i;
416        eeprom_write_dword((uint32_t*)200, val);
417    }
418    /* Check values pre-compaction */
419    EEPROM_Init();
420    EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdeadbeef);
421    EXPECT_EQ(eeprom_read_byte((uint8_t*)4), 0x3c);
422    EXPECT_EQ(eeprom_read_word((uint16_t*)6), 0xd00d);
423    EXPECT_EQ(eeprom_read_dword((uint32_t*)150), 0xcafef00d);
424    EXPECT_EQ(eeprom_read_dword((uint32_t*)200), val);
425    EXPECT_NE(*(uint16_t*)&FlashBuf[LOG_BASE], 0xFFFF);
426    EXPECT_NE(*(uint16_t*)&FlashBuf[LOG_BASE + LOG_SIZE - 2], 0xFFFF);
427    /* Run compaction */
428    eeprom_write_byte((uint8_t*)4, 0x1f);
429    EEPROM_Init();
430    EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdeadbeef);
431    EXPECT_EQ(eeprom_read_byte((uint8_t*)4), 0x1f);
432    EXPECT_EQ(eeprom_read_word((uint16_t*)6), 0xd00d);
433    EXPECT_EQ(eeprom_read_dword((uint32_t*)150), 0xcafef00d);
434    EXPECT_EQ(eeprom_read_dword((uint32_t*)200), val);
435    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE], 0xFFFF);
436    EXPECT_EQ(*(uint16_t*)&FlashBuf[LOG_BASE + LOG_SIZE - 2], 0xFFFF);
437}