qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

eeprom_legacy_emulated_flash_tests.cpp (18013B)


      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 
     19 extern "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 
     57 class 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 
     74 TEST_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 
     81 TEST_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 
     91 TEST_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 
     97 TEST_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 
    106 TEST_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 
    133 TEST_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 
    151 TEST_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 
    178 TEST_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 
    209 TEST_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 
    252 TEST_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 
    288 TEST_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 
    327 TEST_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 
    359 TEST_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 
    403 TEST_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 }