310 #define EEPROM_ABSOLUTE_FIRST_BYTE_OFFSET (STORAGE_EEPROM_FIRST_ROW * EEPROM_ROW_SIZE) 314 #define EEPROM_ABSOLUTE_LAST_BYTE_OFFSET (((STORAGE_EEPROM_LAST_ROW + 1) * EEPROM_ROW_SIZE) - 1) 317 #define FLASH_CURSOR_TO_BYTE_ADDRESS(flashByteCursor) \ 318 ((uint8_t *)(FLASH_START + (STORAGE_FLASH_FIRST_PAGE * FLASH_PAGE_SIZE) + (flashByteCursor))) 321 #define FLASH_CURSOR_TO_PAGE(flashByteCursor) (STORAGE_FLASH_FIRST_PAGE + ((flashByteCursor) / FLASH_PAGE_SIZE)) 324 #define FLASH_PAGE_TO_ADDRESS(type, flashPage) ((type)(FLASH_START + ((flashPage) * FLASH_PAGE_SIZE))) 327 #define FLASH_FIRST_BYTE_ADDRESS FLASH_PAGE_TO_ADDRESS(uint8_t *, STORAGE_FLASH_FIRST_PAGE) 330 #define FLASH_LAST_BYTE_ADDRESS (FLASH_PAGE_TO_ADDRESS(uint8_t *, STORAGE_FLASH_LAST_PAGE + 1) - 1) 333 #define FLASH_FIRST_WORD_ADDRESS FLASH_PAGE_TO_ADDRESS(uint32_t *, STORAGE_FLASH_FIRST_PAGE) 336 #define FLASH_LAST_WORD_ADDRESS (FLASH_PAGE_TO_ADDRESS(uint32_t *, STORAGE_FLASH_LAST_PAGE + 1) - 1) 349 #define FLASH_DATA_HEADER_SIZE STORAGE_BLOCK_HEADER_SIZE 373 #define FLASH_BLOCK_SIZE(bitCount) (4 * STORAGE_IDIVUP((bitCount) + FLASH_DATA_HEADER_SIZE * 8, 32)) 381 #define MARKER_HEADER ((int)0x0000FFFF) 382 #define MARKER_FOOTER ((int)0x7FFFFFFF) 385 #define MARKER_CURSOR_ZERO_MASK 0xFFFF8003 389 #if !STORAGE_FLASH_FIRST_PAGE 391 extern const int _data;
393 __attribute__ ((section(
".noinit")))
395 #undef STORAGE_FLASH_FIRST_PAGE 396 #define STORAGE_FLASH_FIRST_PAGE sStorageFlashFirstPage 402 typedef enum LOCATION {
404 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 412 #define FIRST_BITS_OF_CACHE_SIZE 13 422 typedef struct RecoverInfo_s {
437 #define SIZE_OF_HINT 4 440 #define INVERSE_HINT_ABSOLUTE_BYTE_OFFSET ((EEPROM_ABSOLUTE_LAST_BYTE_OFFSET + 1 - SIZE_OF_HINT)) 443 #define HINT_ABSOLUTE_BYTE_OFFSET (INVERSE_HINT_ABSOLUTE_BYTE_OFFSET - SIZE_OF_HINT) 446 #if STORAGE_REDUCE_RECOVERY_WRITES 447 #define SIZE_OF_DUPLICATE_DATA (EEPROM_ROW_SIZE - (2 * SIZE_OF_HINT)) 448 #if SIZE_OF_DUPLICATE_DATA != 56 449 #error Unexpected value for SIZE_OF_DUPLICATE_DATA. Check the comments for magic values 56 and 8 that are related to this. 452 #define SIZE_OF_DUPLICATE_DATA 64 456 #if STORAGE_REDUCE_RECOVERY_WRITES 457 #define DUPLICATE_DATA_ABSOLUTE_BYTE_OFFSET (EEPROM_ABSOLUTE_LAST_BYTE_OFFSET + 1 - EEPROM_ROW_SIZE) 459 #define DUPLICATE_DATA_ABSOLUTE_BYTE_OFFSET (EEPROM_ABSOLUTE_LAST_BYTE_OFFSET + 1 - (2 * EEPROM_ROW_SIZE)) 473 typedef struct Hint_s {
487 typedef struct Marker_s {
510 #define SIZE_OF_MARKER 12 517 typedef struct Storage_Instance_s {
597 #if STORAGE_REDUCE_RECOVERY_WRITES 598 #define EEPROM_OVERHEAD_IN_BITS ((SIZE_OF_MARKER + EEPROM_ROW_SIZE) * 8) 600 #define EEPROM_OVERHEAD_IN_BITS ((SIZE_OF_MARKER + 2 * EEPROM_ROW_SIZE) * 8) 603 #if STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES != (((STORAGE_EEPROM_ROW_COUNT * EEPROM_ROW_SIZE * 8) - EEPROM_OVERHEAD_IN_BITS) / STORAGE_BITSIZE) 604 #error Internal memory storage model has changed - likely Marker_t or Hint_t - and no longer matches the define STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES 607 #pragma GCC diagnostic push 608 #pragma GCC diagnostic ignored "-Wunused-parameter" 622 #if STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT != (((5 - STORAGE_FIRST_ALON_REGISTER) * 32 - (32 - FIRST_BITS_OF_CACHE_SIZE)) / STORAGE_BITSIZE) 625 #error Internal memory storage model has changed - likely RecoverInfo_t - and no longer matches the define STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT 628 #pragma GCC diagnostic pop 636 __attribute__ ((section(
".noinit")))
643 __attribute__ ((section(".noinit"))) __attribute__((aligned (4)))
649 __attribute__ ((section(".noinit")))
660 #if STORAGE_WORKAREA_SELF_DEFINED == 1 661 __attribute__ ((section(
".noinit"))) __attribute__((aligned (4)))
669 #pragma GCC diagnostic push 670 #pragma GCC diagnostic ignored "-Wunused-parameter" 700 #pragma GCC diagnostic pop 705 static void ShiftAlignedData(uint8_t * pTo,
const uint8_t * pFrom,
const int bitAlignment,
const int bitCount);
706 static void ShiftUnalignedData(uint8_t * pTo,
const uint8_t * pFrom,
const int bitAlignment,
const int bitCount);
707 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 711 static void WriteToEeprom(
const int bitCursor,
const void * pData,
const int bitCount);
712 static void ReadFromEeprom(
const unsigned int bitCursor,
void * pData,
const int bitCount);
716 #if STORAGE_FLASH_FIRST_PAGE <= STORAGE_FLASH_LAST_PAGE 717 static bool WriteToFlash(
const int pageCursor,
const uint8_t * pData,
const int pageCount);
762 static void ShiftAlignedData(uint8_t * pTo,
const uint8_t * pFrom,
const int bitAlignment,
const int bitCount)
764 const uint8_t mask = (uint8_t)(0xFF & ((1 << bitAlignment) - 1));
766 ASSERT((bitAlignment >= 0) && (bitAlignment < 8));
767 ASSERT(bitCount > 0);
781 *pTo = (uint8_t)((pFrom[n] << bitAlignment) | ((*pTo) & mask));
783 if ((n * 8) + 8 - bitAlignment < bitCount) {
788 *pTo = (uint8_t)(pFrom[n] >> (8 - bitAlignment));
792 }
while (n * 8 < bitCount);
795 uint8_t finalMask = (uint8_t)~(0xFF << ((bitCount + bitAlignment) % 8));
796 if (finalMask != 0) {
797 *pTo = *pTo & finalMask;
817 static void ShiftUnalignedData(uint8_t * pTo,
const uint8_t * pFrom,
const int bitAlignment,
const int bitCount)
819 const uint8_t mask = 0xFF & (uint8_t)((1 << (8 - bitAlignment)) - 1);
821 ASSERT((bitAlignment >= 0) && (bitAlignment < 8));
822 ASSERT(bitCount > 0);
837 *pTo = (uint8_t)((pFrom[n]) >> bitAlignment);
842 if (((n - 1) * 8) + 8 - bitAlignment < bitCount) {
845 *pTo = (uint8_t)((pFrom[n] << (8 - bitAlignment)) | ((*pTo) & mask));
847 if (n * 8 < bitCount) {
851 }
while (n * 8 < bitCount);
854 uint8_t finalMask = (uint8_t)~(0xFF << (bitCount % 8));
855 if (finalMask != 0) {
856 *pTo = *pTo & finalMask;
862 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 870 bool success =
false;
874 int byteOffset = bitCursor / 8;
875 int bitAlignment = bitCursor % 8;
892 if (n < spRecoverInfo->sampleCacheCount) {
894 int byteOffset = bitCursor / 8;
895 int bitAlignment = bitCursor % 8;
912 static void WriteToEeprom(
const int bitCursor,
const void * pData,
const int bitCount)
914 const int bitAlignment = bitCursor % 8;
917 ASSERT(bitCursor >= 0);
918 ASSERT(pData != NULL);
919 ASSERT(bitCount > 0);
922 uint8_t bytes[byteCount];
927 Chip_EEPROM_Read(NSS_EEPROM, byteOffset, &bytes, 1);
929 Chip_EEPROM_Write(NSS_EEPROM, byteOffset, bytes, byteCount);
942 static void ReadFromEeprom(
const unsigned int bitCursor,
void * pData,
const int bitCount)
944 const int bitAlignment = bitCursor % 8;
947 ASSERT(pData != NULL);
948 ASSERT(bitCount > 0);
951 uint8_t bytes[byteCount];
953 Chip_EEPROM_Read(NSS_EEPROM, (
int)byteOffset, bytes, byteCount);
968 unsigned int eepromBitCursor;
1000 Chip_EEPROM_Read(NSS_EEPROM, (
int)byteOffset, &word, 2);
1001 if (word == 0xFFFF) {
1002 Chip_EEPROM_Read(NSS_EEPROM, (
int)byteOffset - 8, &word, 2);
1003 if (((word + 1) & word) == 0) {
1005 for (bits = 0; word; bits++) {
1006 word &= (uint16_t)(word - 1);
1020 eepromBitCursor = 0;
1021 memset(pMarker, 0,
sizeof(
Marker_t));
1023 return eepromBitCursor;
1036 int sequenceCount = 0;
1041 int bitCount = (int)(header[0] | (header[1] << 8));
1045 return sequenceCount;
1050 #if STORAGE_FLASH_FIRST_PAGE <= STORAGE_FLASH_LAST_PAGE 1063 static bool WriteToFlash(
const int pageCursor,
const uint8_t * pData,
const int pageCount)
1067 IAP_STATUS_T status;
1068 uint32_t sectorStart = (uint32_t)(pageCursor / FLASH_PAGES_PER_SECTOR);
1069 uint32_t sectorEnd = (uint32_t)((pageCursor + pageCount - 1) / FLASH_PAGES_PER_SECTOR);
1071 ASSERT(pageCursor > 0);
1072 ASSERT(pData != NULL);
1073 ASSERT(pageCount > 0);
1074 ASSERT(sectorEnd < FLASH_NR_OF_RW_SECTORS);
1076 pDest = (uint8_t *)FLASH_START + (pageCursor * FLASH_PAGE_SIZE);
1077 size = (uint32_t)pageCount * FLASH_PAGE_SIZE;
1079 status = Chip_IAP_Flash_PrepareSector(sectorStart, sectorEnd);
1080 if (status == IAP_STATUS_CMD_SUCCESS) {
1082 status = Chip_IAP_Flash_Program(pData, pDest, size, 0);
1085 if (status == IAP_STATUS_CMD_SUCCESS) {
1089 uint32_t fillWord = *(uint32_t *)pData;
1090 while ((fillWord == 0xFFFFFFFF) && (size > 0)) {
1094 fillWord = *(uint32_t *)pData;
1097 status = Chip_IAP_Compare(pData, pDest, size, NULL);
1100 return status == IAP_STATUS_CMD_SUCCESS;
1162 #if STORAGE_FLASH_FIRST_PAGE > STORAGE_FLASH_LAST_PAGE 1197 memset(pOut, 0xFF, (
size_t)flashByteOffsetInPage);
1198 pOut += flashByteOffsetInPage;
1216 pOut[0] = (uint8_t)(bitCount & 0xFF);
1217 pOut[1] = (uint8_t)((bitCount >> 8) & 0xFF);
1221 pOut += compressedDataSizeInBytes;
1230 ASSERT((newFlashByteCursor & 0x3) == 0);
1237 int pageCountToFlash = (pOut -
STORAGE_WORKAREA + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;
1238 ASSERT(pageCountToFlash > 0);
1239 success = WriteToFlash(firstFlashPage,
STORAGE_WORKAREA, pageCountToFlash);
1274 uint8_t zeroMarker[
sizeof(
Marker_t)] = {0};
1303 int bitCount = (int)(pHeader[0] | (pHeader[1] << 8));
1309 if (bitCount == 0x0000FFFF) {
1358 if (ok && (expectedFlashByteCursor >= 0)) {
1427 #if !STORAGE_FLASH_FIRST_PAGE 1443 bool markerIsValid =
false;
1445 if (recoverInfoIsValid) {
1450 if (!markerIsValid) {
1458 if (!markerIsValid) {
1464 if (markerIsValid) {
1468 else if (hintIsValid) {
1492 if (!markerIsValid) {
1498 Chip_EEPROM_Flush(NSS_EEPROM,
true);
1519 if ((!hintIsValid) || (difference < 0)
1524 Chip_EEPROM_Flush(NSS_EEPROM,
true);
1543 uint8_t zeroMarker[
sizeof(
Marker_t)] = {0};
1549 #if STORAGE_FLASH_FIRST_PAGE > STORAGE_FLASH_LAST_PAGE 1570 while ((cursor <= last) && (*cursor == 0xFFFFFFFF)) {
1573 if (cursor <= last) {
1574 IAP_STATUS_T status;
1577 status = Chip_IAP_Flash_PrepareSector(sectorStart, sectorEnd);
1578 if (status == IAP_STATUS_CMD_SUCCESS) {
1586 uint32_t b = s * FLASH_PAGES_PER_SECTOR;
1587 uint32_t t = sectorEnd;
1595 ASSERT(status == IAP_STATUS_CMD_SUCCESS);
1599 status = Chip_IAP_Flash_EraseSector(s, t, 0);
1601 ASSERT(status == IAP_STATUS_CMD_SUCCESS);
1603 if (t < sectorEnd) {
1607 ASSERT(status == IAP_STATUS_CMD_SUCCESS);
1610 ASSERT(status == IAP_STATUS_CMD_SUCCESS);
1618 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 1621 ASSERT(samples != NULL);
1630 int cachedCount = 0;
1635 cachedSamples[cachedCount] = samples[count];
1643 for (
int i = stored; i < cachedCount; i++) {
1676 ASSERT(samples != NULL);
1687 if (n < 0) {
return false; }
1689 int currentSequence = -1;
1690 int currentCursor = -1;
1691 int nextSequence = 0;
1700 currentSequence = nextSequence;
1701 currentCursor = nextCursor;
1704 int bitCount = (int)(header[0] | (header[1] << 8));
1707 ASSERT((nextCursor & 0x3) == 0);
1708 if ((currentSequence <= n) && (n < nextSequence)) {
1712 if ((currentSequence <= n) && (n < nextSequence)) {
1729 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 1735 nextCursor = n - nextSequence;
1736 if (nextCursor < spRecoverInfo->sampleCacheCount) {
1753 ASSERT(samples != NULL);
1765 int byteOffset = bitOffset / 8;
1766 int bitAlignment = bitOffset % 8;
1799 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 1808 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > 0 1823 for (
int i = 0; i < count; i++) {
static Storage_Instance_t sInstance
int Storage_DummyDecompressCb(const uint8_t *pData, int bitCount, void *pOut)
#define STORAGE_FLASH_LAST_PAGE
#define STORAGE_SAMPLE_ALON_CACHE_COUNT
static void ShiftUnalignedData(uint8_t *pTo, const uint8_t *pFrom, const int bitAlignment, const int bitCount)
#define STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES
int STORAGE_DECOMPRESS_CB(const uint8_t *pData, int bitCount, void *pOut)
#define EEPROM_ABSOLUTE_FIRST_BYTE_OFFSET
#define STORAGE_WORKAREA_SIZE
#define STORAGE_FIRST_ALON_REGISTER
int Storage_Read(STORAGE_TYPE *samples, int n)
int checkSizeOfHint[(SIZE_OF_HINT==sizeof(Hint_t)) ? 1 :-1]
#define STORAGE_BLOCK_SIZE_IN_SAMPLES
static bool ValidateHint(const Hint_t *pHint)
#define FLASH_DATA_HEADER_SIZE
uint8_t STORAGE_WORKAREA[STORAGE_WORKAREA_SIZE]
static bool ValidateRecoverInfo(void)
#define STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS
#define FLASH_CURSOR_TO_BYTE_ADDRESS(flashByteCursor)
#define HINT_ABSOLUTE_BYTE_OFFSET
static int GetFlashCount(void)
#define EEPROM_ABSOLUTE_LAST_BYTE_OFFSET
static int ReadAndCacheSamplesFromFlash(int readCursor)
#define FLASH_LAST_BYTE_ADDRESS
#define MARKER_CURSOR_ZERO_MASK
#define FLASH_FIRST_WORD_ADDRESS
#define FLASH_CURSOR_TO_PAGE(flashByteCursor)
static bool sEepromBitCursorChanged
static bool ValidateMarker(const Marker_t *pMarker, int expectedFlashByteCursor)
static uint8_t sCache[4 *(5 - STORAGE_FIRST_ALON_REGISTER)]
static void WriteToEeprom(const int bitCursor, const void *pData, const int bitCount)
int checkSizeOfMarker[(SIZE_OF_MARKER==sizeof(Marker_t)) ? 1 :-1]
#define STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES
static int StoreSamplesInEeprom(const STORAGE_TYPE *pSamples, int n)
void Storage_DeInit(void)
#define FIRST_BITS_OF_CACHE_SIZE
#define STORAGE_MAX_UNCOMPRESSED_BLOCK_SIZE_IN_BITS
#define STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES
#define EEPROM_OVERHEAD_IN_BITS
unsigned int eepromBitCursor
#define DUPLICATE_DATA_ABSOLUTE_BYTE_OFFSET
static bool GetCachedSample(const int n, void *pData)
int Storage_DummyCompressCb(int eepromByteOffset, int bitCount, void *pOut)
unsigned int sampleCacheCount
static unsigned int FindMarker(Marker_t *pMarker)
static bool MoveSamplesFromEepromToFlash(void)
static int GetEepromCount(void)
static int sStorageFlashFirstPage
int Storage_GetCount(void)
void Storage_Reset(bool checkFlash)
#define FLASH_LAST_WORD_ADDRESS
static RecoverInfo_t * spRecoverInfo
#define STORAGE_IDIVUP(n, d)
static void WriteHint(void)
int STORAGE_COMPRESS_CB(int eepromByteOffset, int bitCount, void *pOut)
int Storage_Write(STORAGE_TYPE *samples, int n)
static void WriteMarker(void)
uint8_t sStorage_Workarea[STORAGE_WORKAREA_SIZE]
#define INVERSE_HINT_ABSOLUTE_BYTE_OFFSET
#define FLASH_BLOCK_SIZE(bitCount)
#define SIZE_OF_DUPLICATE_DATA
static void ReadFromEeprom(const unsigned int bitCursor, void *pData, const int bitCount)
static bool CacheSample(const STORAGE_TYPE *pSample)
#define STORAGE_FLASH_FIRST_PAGE
int checkSizeOfSampleType[(sizeof(STORAGE_TYPE) *8< STORAGE_BITSIZE) ? -1 :1]
unsigned int firstBitsOfCache
static void ResetInstance(void)
static void ShiftAlignedData(uint8_t *pTo, const uint8_t *pFrom, const int bitAlignment, const int bitCount)
int checkSizeOfRecoverInfo[sizeof(RecoverInfo_t)==4 ? 1 :-1]