ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
413477 Топик полностью
koyodza (29.05.2013 13:25, просмотров: 140) ответил Лeoнид Ивaнoвич на Как жить без EEPROM?
AN2594 http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
у меня реализовано немного не так, без таблицы в ОЗУ использованных ячеек: __private void* EE_FindTopOfPage(DWORD pageAddr) { DWORD addr = (pageAddr & dwPageMask) | dwAddrMask; DWORD* p = (DWORD*)addr; while (dwAddrMask & (DWORD)p) { if (*p == MAX_DWORD) return p; p--; } return NULL; } /////////////////////////////////////////////////////////////////////////////// __private void* EE_Find(DWORD startAddr, WORD vAddr) { UN32* p = (UN32*)startAddr; do { p++; if (!(dwAddrMask & (DWORD)p)) return NULL; } while (p->wh != vAddr); return p; } /////////////////////////////////////////////////////////////////////////////// __private void EE_CopyPage(void) { static BYTE nEnter = 0; nEnter++; if (nEnter > 1) return; DWORD pageDst = (DWORD)pFreePage & dwPageMask; DWORD pageSrc = (DWORD)pTop & dwPageMask; UN32* pSrcBegin = (UN32*)pageSrc; UN32* pSrc = pTop; UN32 sign32 = *pSrcBegin; pTop = (UN32*)((pageDst & dwPageMask) | dwAddrMask); if (!FlashIsFree((void*)pageDst, 1024)) FlashErasePage((void*)pageDst); if (!FlashIsFree((void*)(pageDst + 1024), 1024)) FlashErasePage((void*)(pageDst + 1024)); while (TRUE) { pSrc++; if (!(dwAddrMask & (DWORD)pSrc)) break; UN32 tmp = *pSrc; if (!EE_Find((DWORD)pTop, tmp.wh)) EE_Write(tmp.wh, tmp.wl); } sign32.dw = LOBYTE(sign32.dw + 1); FlashWrite32((void*)pageDst, sign32); pPage = (UN32*)(pageDst & dwPageMask); pFreePage = pSrcBegin; nEnter--; } /////////////////////////////////////////////////////////////////////////////// __public int EE_Write(WORD vAddr, WORD vData) { if (!((DWORD)pTop & dwAddrMask)) EE_CopyPage(); FlashWrite32(pTop, (UN32){.wh = vAddr, .wl = vData}); pTop--; return TRUE; } /////////////////////////////////////////////////////////////////////////////// __public int EE_Read(WORD vAddr, WORD* pData) { DWORD startAddr = (DWORD)pTop; UN32* p = EE_Find(startAddr, vAddr); if (p) { *pData = p->wl; return TRUE; } return FALSE; } /////////////////////////////////////////////////////////////////////////////// __public void EEPROMInit(void) { DWORD pageSize = 0x800; dwAddrMask = pageSize - 4; dwPageMask = ~(pageSize - 1); DWORD flashSize = DEVSIGN->flashSize * 1024; UN32* pX[2] = { (UN32*)(FLASH_BASE + flashSize - pageSize), (UN32*)(FLASH_BASE + flashSize - (2 * pageSize)), }; __int8 d = pX[0]->b[0] - pX[1]->b[0]; pPage = pX[0], pFreePage = pX[1]; if (d < 0) pPage = pX[1], pFreePage = pX[0]; else if (d == 0) { FlashErasePage(pPage); FlashErasePage(pFreePage); FlashWrite32(pPage, (UN32){.wh = MAX_WORD, .wl = 0}); } DWORD addr = (DWORD)pPage + dwAddrMask; UN32* p = EE_FindTopOfPage(addr); if (!p) p = pPage; pTop = p; }