📄 pageeepromm.nc
字号:
flashBusy = TRUE; buffer[checking].busy = TRUE; // The 10us wait makes old mica motes (Atmega 103) happy, for // some mysterious reason (w/o this wait, the first compare // always fail, even though the compare after the rewrite // succeeds...) TOSH_uwait(10); requestFlashStatus(); break; case P_FILL: // page load started flashBusy = TRUE; buffer[selected].page = reqPage; buffer[selected].clean = buffer[selected].busy = TRUE; buffer[selected].erased = FALSE; handleRWRequest(); break; case P_ERASE: flashBusy = TRUE; // The buffer contains garbage, but we don't care about the state // of bits on this page anyway (if we do, we'll perform a // subsequent write) buffer[selected].page = reqPage; buffer[selected].clean = TRUE; buffer[selected].erased = TRUE; requestDone(SUCCESS); break; } } event result_t FlashSelect.notifyHigh() { if (deselectRequested) { deselectRequested = FALSE; flashCommandComplete(); } return SUCCESS; } void execCommand(bool wait, uint8_t reqCmd, uint8_t dontCare, eeprompage_t page, eeprompageoffset_t offset) { // page (2 bytes) and highest bit of offset cmd[0] = reqCmd; cmd[1] = page >> 7; cmd[2] = page << 1 | offset >> 8; cmd[3] = offset; // low-order 8 bits cmdCount = 4 + dontCare; if (wait && flashBusy) requestFlashStatus(); else sendFlashCommand(); } void execRWBuffer(uint8_t reqCmd, uint8_t dontCare, eeprompageoffset_t offset) { execCommand(buffer[selected].busy, reqCmd, dontCare, 0, offset); } result_t syncOrFlushAll(uint8_t newReq); void handleRWRequest() { if (reqPage == buffer[selected].page) switch (request) { case R_ERASE: switch (reqOffset) { case TOS_EEPROM_ERASE: cmdPhase = P_ERASE; execCommand(TRUE, C_ERASE_PAGE, 0, reqPage, 0); break; case TOS_EEPROM_PREVIOUSLY_ERASED: // We believe the user... buffer[selected].erased = TRUE; /* Fallthrough */ case TOS_EEPROM_DONT_ERASE: // The buffer contains garbage, but we don't care about the state // of bits on this page anyway (if we do, we'll perform a // subsequent write) buffer[selected].clean = TRUE; requestDone(SUCCESS); break; } break; case R_SYNC: case R_SYNCALL: if (buffer[selected].clean && buffer[selected].unchecked) { checkBuffer(selected); return; } /* fall through */ case R_FLUSH: case R_FLUSHALL: if (!buffer[selected].clean) flushBuffer(); else if (request == R_FLUSH || request == R_SYNC) post taskSuccess(); else { // Check for more dirty pages uint8_t oreq = request; request = IDLE; syncOrFlushAll(oreq); } break; case R_READ: data = reqBuf; dataCount = reqBytes; cmdPhase = P_READ; execRWBuffer(OP(C_READ_BUFFER), 2, reqOffset); break; case R_READCRC: dataCount = reqBytes; cmdPhase = P_READCRC; execRWBuffer(OP(C_READ_BUFFER), 2, 0); break; case R_WRITE: data = reqBuf; dataCount = reqBytes; cmdPhase = P_WRITE; buffer[selected].clean = FALSE; buffer[selected].unchecked = 0; execRWBuffer(OP(C_WRITE_BUFFER), 0, reqOffset); break; } else if (!buffer[selected].clean) flushBuffer(); else if (buffer[selected].unchecked) checkBuffer(selected); else { // just get the new page (except for erase) if (request == R_ERASE) { buffer[selected].page = reqPage; handleRWRequest(); } else { cmdPhase = P_FILL; execCommand(TRUE, OP(C_FILL_BUFFER), 0, reqPage, 0); } } } void requestDone(result_t result) { uint8_t orequest = request; request = IDLE; switch (orequest) { case R_READ: signal PageEEPROM.readDone(result); break; case R_READCRC: signal PageEEPROM.computeCrcDone(result, computedCrc); break; case R_WRITE: signal PageEEPROM.writeDone(result); break; case R_SYNC: case R_SYNCALL: signal PageEEPROM.syncDone(result); break; case R_FLUSH: case R_FLUSHALL: signal PageEEPROM.flushDone(result); break; case R_ERASE: signal PageEEPROM.eraseDone(result); break; } } result_t newRequest(uint8_t req, eeprompage_t page, eeprompageoffset_t offset, void *reqdata, eeprompageoffset_t n) {#ifdef CHECKARGS if (page >= TOS_EEPROM_MAX_PAGES || offset >= TOS_EEPROM_PAGE_SIZE || n > TOS_EEPROM_PAGE_SIZE || offset + n > TOS_EEPROM_PAGE_SIZE) return FAIL;#endif if (request != IDLE) return FAIL; request = req; if (broken) { post taskFail(); return SUCCESS; } reqBuf = reqdata; reqBytes = n; reqPage = page; reqOffset = offset; if (page == buffer[0].page) selected = 0; else if (page == buffer[1].page) selected = 1; else selected = !selected; // LRU with 2 buffers... handleRWRequest(); return SUCCESS; } command result_t PageEEPROM.read(eeprompage_t page, eeprompageoffset_t offset, void *reqdata, eeprompageoffset_t n) { return newRequest(R_READ, page, offset, reqdata, n); } command result_t PageEEPROM.computeCrc(eeprompage_t page, eeprompageoffset_t offset, eeprompageoffset_t n) { if (n == 0) { request = R_READCRC; computedCrc = 0; post taskSuccess(); return SUCCESS; } else return newRequest(R_READCRC, page, offset, NULL, n); } command result_t PageEEPROM.write(eeprompage_t page, eeprompageoffset_t offset, void *reqdata, eeprompageoffset_t n) {#if 0 /* Fast write path */ if (request == IDLE && !broken && page == buffer[selected].page && !buffer[selected].busy) { eeprompageoffset_t i; request = R_WRITE; data = reqdata; dataCount = n; cmdPhase = P_WRITE; buffer[selected].clean = FALSE; buffer[selected].unchecked = 0; selectFlash(); call FlashSPI.txByte(OP(C_WRITE_BUFFER)); call FlashSPI.txByte(page >> 7); call FlashSPI.txByte(page << 1 | offset >> 8); call FlashSPI.txByte(offset); for (i = 0; i < n; i++) call FlashSPI.txByte(((uint8_t *)reqdata)[i]); requestDeselect(); return SUCCESS; }#endif return newRequest(R_WRITE, page, offset, reqdata, n); } command result_t PageEEPROM.erase(eeprompage_t page, uint8_t eraseKind) { return newRequest(R_ERASE, page, eraseKind, NULL, 0); } result_t syncOrFlush(eeprompage_t page, uint8_t newReq) { if (request != IDLE) return FAIL; request = newReq; if (broken) { post taskFail(); return SUCCESS; } else if (buffer[0].page == page) selected = 0; else if (buffer[1].page == page) selected = 1; else { post taskSuccess(); return SUCCESS; } buffer[selected].unchecked = 0; handleRWRequest(); return SUCCESS; } command result_t PageEEPROM.sync(eeprompage_t page) { return syncOrFlush(page, R_SYNC); } command result_t PageEEPROM.flush(eeprompage_t page) { return syncOrFlush(page, R_FLUSH); } result_t syncOrFlushAll(uint8_t newReq) { if (request != IDLE) return FAIL; request = newReq; if (broken) { post taskFail(); return SUCCESS; } else if (!buffer[0].clean) selected = 0; else if (!buffer[1].clean) selected = 1; else { post taskSuccess(); return SUCCESS; } buffer[selected].unchecked = 0; handleRWRequest(); return SUCCESS; } command result_t PageEEPROM.syncAll() { return syncOrFlushAll(R_SYNCALL); } command result_t PageEEPROM.flushAll() { return syncOrFlushAll(R_FLUSHALL); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -