/** * Fills eeprom area with pattern, than read it back and compare */ static void __block_api_write(uint8_t pattern, uint32_t len, uint8_t misaligment){ uint32_t i = 0; uint32_t status = 0; uint32_t pos = 0; /* fill buffer with pattern */ for (i = 0; i < len; i++) referencebuf[i] = pattern; /* move to begin of test area */ chFileStreamSeek(&EfsTest, TestAreaStart + misaligment); pos = chFileStreamGetPosition(&EfsTest); if (pos != TestAreaStart + misaligment) chDbgPanic("file seek error"); /* write */ status = chFileStreamWrite(&EfsTest, referencebuf, len); if (status < len) chDbgPanic("write failed"); /* check */ pos = chFileStreamGetPosition(&EfsTest); if (pos != len + TestAreaStart + misaligment) chDbgPanic("file seek error"); chFileStreamSeek(&EfsTest, pos - len); status = chFileStreamRead(&EfsTest, checkbuf, len); if (status < len) chDbgPanic("veryfication failed"); if (memcmp(referencebuf, checkbuf, len) != 0) chDbgPanic("veryfication failed"); }
/** * Fills eeprom area with pattern, than read it back and compare */ static void pattern_fill(EepromFileStream *EfsTest, uint8_t pattern){ uint32_t i = 0; uint32_t status = 0; uint32_t pos = 0; uint32_t len = chFileStreamGetSize(EfsTest); /* fill buffer with pattern */ for (i = 0; i < len; i++) referencebuf[i] = pattern; /* move to begin of test area */ pos = 0; chFileStreamSeek(EfsTest, pos); if (pos != chFileStreamGetPosition(EfsTest)) chDbgPanic("file seek error"); /* write */ status = chFileStreamWrite(EfsTest, referencebuf, len); if (status != len) chDbgPanic("write failed"); /* check */ pos = chFileStreamGetPosition(EfsTest); if (pos != len) chDbgPanic("writing error"); pos = 0; chFileStreamSeek(EfsTest, pos); status = chFileStreamRead(EfsTest, checkbuf, len); if (status != len) chDbgPanic("reading back failed"); if (memcmp(referencebuf, checkbuf, len) != 0) chDbgPanic("veryfication failed"); }
void eeprom_testsuit(void){ int8_t i = 0; int8_t j = 0; int32_t n = 0; /* backup data from test area */ chFileStreamSeek(&EfsTest, TestAreaStart); if (chFileStreamRead(&EfsTest, backupbuf, TEST_AREA_SIZE) < TEST_AREA_SIZE) chDbgPanic("backuping failed"); /* first check the whole test area */ test_api_all(TEST_AREA_SIZE, 0); for (i = -2; i < 3; i++){ for (j = 0; j < 3; j++){ /* large block tests */ n = EEPROM_PAGE_SIZE; while (n < (TEST_AREA_SIZE - 3 * EEPROM_PAGE_SIZE)){ test_api_all(n + i, j); test_api_all(n + i, EEPROM_PAGE_SIZE - 1 - j); n *= EEPROM_PAGE_SIZE; } /* small block tests */ for (n = 2; n < 7; n++){ test_api_all(n + i, j); test_api_all(n + i, EEPROM_PAGE_SIZE - 1 - j); test_api_all(n*10 + i, j); test_api_all(n*10 + i, EEPROM_PAGE_SIZE - 1 - j); } } } /* wrapper fucntions test */ test_wrapper_write_all_patterns(TestAreaStart); test_wrapper_write_all_patterns(TestAreaStart + 1); for (i = -4; i < 5; i++) test_wrapper_write_all_patterns(TestAreaStart + EEPROM_PAGE_SIZE + i); test_wrapper_write_all_patterns(TestAreaFinish - 5); /* personally check end of test area */ test_wtapper_write_byte (0x55, TestAreaFinish - 1); test_wtapper_write_halfword(0xAA, TestAreaFinish - 2); test_wtapper_write_word (0xA5, TestAreaFinish - 4); /* roll back data from backup */ chFileStreamSeek(&EfsTest, TestAreaStart); if (chFileStreamWrite(&EfsTest, backupbuf, TEST_AREA_SIZE) < TEST_AREA_SIZE) chDbgPanic("rolling back failed"); }
void __burn(BaseSequentialStream *chp, uint8_t pattern){ volatile uint32_t status = 0; uint32_t eeprom_cycle; eeprom_cycle = BKP->DR1; eeprom_cycle = eeprom_cycle << 16; eeprom_cycle += BKP->DR2; if (BKP->DR3 == 1){ //chprintf(chp, "EEPROM exhausted at %u try\n", eeprom_cycle); return; } /* fill memory buffer and write it to eeprom */ memset(databuf, pattern, sizeof(databuf)); chFileStreamSeek(&EepromFile, 0); status = chFileStreamWrite(&EepromFile, databuf, EEPROM_SIZE); if (status != sizeof(databuf)) chDbgPanic(""); /* read eeprom to test buffer */ chFileStreamSeek(&EepromFile, 0); chFileStreamRead(&EepromFile, testbuf, EEPROM_SIZE); if (status != sizeof(databuf)) chDbgPanic(""); /* compare 2 buffers. Non zero value denotes bad sector in eeprom */ status = memcmp(databuf, testbuf, EEPROM_SIZE); if (status != 0){ BKP->DR3 = 1; /* bad sector(s) appeared */ return; } /* Print note to console and increment cycle counter */ //chprintf(chp, "EEPROM burn %u \n", eeprom_cycle); eeprom_cycle++; BKP->DR2 = eeprom_cycle & 0xFFFF; BKP->DR1 = (eeprom_cycle >> 16) & 0xFFFF; palTogglePad(IOPORT3, GPIOC_LED); }
/** * Create overlapped files like this: * * |<--------- outer file ------------>| * | | * ======b1==b2========================b3===b4====== * | | | | * | |<------ inner file ------>| | * |<----------------- EEPROM -------------------->| */ static void overflow_check(uint32_t b1, uint32_t b2, uint32_t b3, uint32_t b4, uint32_t istart, uint32_t ilen, uint8_t pattern, bool_t pat_autoinc, BaseSequentialStream *sdp){ uint32_t status, i, n; chDbgCheck(ilen < (b4-b1),"sequences more than length of outer file can not be verified"); chprintf(sdp, "b1=%u, b2=%u, b3=%u, b4=%u, istart=%u, ilen=%u, ", b1, b2, b3, b4, istart, ilen); cli_print("autoinc="); if (pat_autoinc) cli_print("TRUE"); else cli_print("FALSE"); chThdSleepMilliseconds(50); /* open outer file and clear it */ ocfg.barrier_low = b1; ocfg.barrier_hi = b4; EepromFileOpen(&ofile, &ocfg); pattern_fill(&ofile, 0x00); /* open inner file */ icfg.barrier_low = b2; icfg.barrier_hi = b3; EepromFileOpen(&ifile, &icfg); /* reference buffer */ memset(referencebuf, 0x00, b4-b1); n = b2 - b1 + istart; if ((ilen + istart) > (b3-b2)) i = b3 - b2 - istart; else i = ilen; while (i > 0){ referencebuf[n] = pattern; n++; i--; if (pat_autoinc) pattern++; } /* check buffer */ n = 0; while (n < ilen){ checkbuf[n] = pattern; n++; if (pat_autoinc) pattern++; } /* now write check buffer content into inner file */ chThdSleepMilliseconds(20); chFileStreamSeek(&ifile, istart); status = chFileStreamWrite(&ifile, checkbuf, ilen); if ((istart + ilen) > (b3 - b2)){ /* data must be clamped */ if (status != (b3 - b2 - istart)) chDbgPanic("not all data written or overflow ocrred"); } else{/* data fitted in file */ if (status != ilen) chDbgPanic("not all data written or overflow ocrred"); } /* read outer file and compare content with reference buffer */ memset(checkbuf, 0x00, b4-b1); chFileStreamSeek(&ofile, 0); status = chFileStreamRead(&ofile, checkbuf, b4-b1); if (status != (b4-b1)) chDbgPanic("reading back failed"); if (memcmp(referencebuf, checkbuf, b4-b1) != 0) chDbgPanic("veryfication failed"); chFileStreamClose(&ofile); chFileStreamClose(&ifile); OK(); }
uint32_t EepromReadWord(EepromFileStream *EepromFile_p) { uint8_t buf[4]; chFileStreamRead(EepromFile_p, buf, sizeof(buf)); return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; }
uint16_t EepromReadHalfword(EepromFileStream *EepromFile_p) { uint8_t buf[2]; chFileStreamRead(EepromFile_p, buf, sizeof(buf)); return (buf[0] << 8) | buf[1]; }
uint8_t EepromReadByte(EepromFileStream *EepromFile_p) { uint8_t buf[1]; chFileStreamRead(EepromFile_p, buf, sizeof(buf)); return buf[0]; }
uint32_t EepromReadWord(EepromFileStream *EepromFile_p) { uint8_t buf[4]; size_t status = chFileStreamRead(EepromFile_p, buf, sizeof(buf)); chDbgAssert(status == sizeof(buf), "EepromReadByte(), #1", "read failed"); return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; }
uint16_t EepromReadHalfword(EepromFileStream *EepromFile_p) { uint8_t buf[2]; size_t status = chFileStreamRead(EepromFile_p, buf, sizeof(buf)); chDbgAssert(status == sizeof(buf), "EepromReadByte(), #1", "read failed"); return (buf[0] << 8) | buf[1]; }