📄 cdax7eep.c
字号:
* DAX1EEP_PGOFF(fh) r/w offset rel DAX1EEP_PAGE(fh) * DAX1EEP_PGSZ(fh) r/- size of EEPROM page * DAX1EEP_LEN(fh) r/w remaining num of bytes to read * DAX1EEP_UBUF(fh) r/w pointer to user buffer, moved with DAX1EEP_LEN(fh) * DAX1EEP_EEBUF(fh) -/w internal EEPROM page buffer for unaligned areas * * PARAMETERS * fh=pst_FH i/- pointer fh to file handle structure for EEPROM * s32_State i/- internal state machine state * returns -/o next state machine state * == DAX1_DONE: normal termination * <= DAX_READY: abort * > DAX_READY: service ongoing * * INTERFACE DECLARATION: */s32 p_dax7_DoEepRd (t_dax1_EeHandle *pst_FH, s32 s32_State){ u32 page, offset, length; u8 * buf; s32 nextState= s32_State; // default: same state => no DAX1_TRANSOPT DAX_TRACE3("p_dax7_DoEepRd(FH%d, st%d)\n", DAX1FH_FH(pst_FH), nextState); switch (nextState) // preset with input state {# if (DAFLAGS & VTD_DAX_VER) default: DAX_VERIFY(0, DAXEV_FATAL_DoEepRd, 0); DAX1_TRANSUNC(nextState, DAX_READY); // abort break;# endif case DAX1EERD_VIAEEBUF: // transfer part of EEBUF to UBUF DAX1EEP_PAGE(pst_FH)++; offset= DAX1EEP_PGOFF(pst_FH); length= p_dax7_CalcRemOnPage(pst_FH); DAX1EEP_LEN(pst_FH) -= length; buf= DAX1EEP_UBUF(pst_FH); DAX1EEP_UBUF(pst_FH)= buf + length; while (length--){ buf[length]= DAX1EEP_EEBUF(pst_FH)[offset+length]; } //no break; check if ready case DAX1EERD_MORE: // continue state DAX1EEP_PGOFF(pst_FH)= 0; case DAX1_START: // start state if ((DAX1G_DEVTYPES & FDR_DEVTYPE_EE)==0){ DAX1_TRANSUNC(nextState, DAXEV_DEVICE_ERR2); // ----------------------------------------------------------------> break; } length= DAX1EEP_LEN(pst_FH); if (length==0){ DAX1_TRANSUNC(nextState, DAX1_DONE); // ----------------------------------------------------------------> break; } page= DAX1EEP_PAGE(pst_FH); offset= DAX1EEP_PGOFF(pst_FH); buf= DAX1EEP_UBUF(pst_FH); if ( (length < DAX1EEP_PGSZ(pst_FH) && (length&1))// length short and odd || ( (offset | (buf - (u8*)0) ) &1) ) { // offset or buffer odd // not aligned read via eeBuf: // read full page (first or last of request) to EEBUF // extract part in question to UBUF in state DAX1EERD_VIAEEBUF offset= 0; length= DAX1EEP_PGSZ(pst_FH); buf= DAX1EEP_EEBUF(pst_FH); DAX1_TRANSUNC(nextState, DAX1EERD_VIAEEBUF); }else{ // immediate read, 16bit aligned // length to be made even, offset and buffer are already even // PR223: offset to be respected if (length&1){ length -= (length+offset)%DAX1EEP_PGSZ(pst_FH); // unaligned read of last page remains } if (page < DAX1EEP_PGPERDIE(pst_FH)) { u32 length2= (DAX1EEP_PGPERDIE(pst_FH) - page) * DAX1EEP_PGSZ(pst_FH) - offset; if (length2 < length){ // straddling dies length= length2; } } DAX1EEP_LEN(pst_FH) -= length; DAX1EEP_PAGE(pst_FH) += (length + offset) / DAX1EEP_PGSZ(pst_FH); DAX1EEP_UBUF(pst_FH)= buf + length; DAX1_TRANSUNC(nextState, DAX1EERD_MORE); } p_dax7_RdEepReq(pst_FH, page | (offset<<16), length, buf); break; } DAX_TRACE2("p_dax7_DoEepRd returns state= %d\n", nextState); return nextState;}/* FUNCTIONAL DESCRIPTION: * * This function is the state machine for p_dax_EepWriteReq * * The EEPROM write service avoids unnecessary erase ops and includes a verify * step. It is performed pagewise in the following VEPV steps: * (V) read current page, Verify if change required or continue with next page * (E) if current page different from all 0xFF: Erase page * (P) if change required: Program current page * (V) Verify content of current page * * * GLOBALS * DAX1G_DEVTYPES r/- check if EEPROM is accessible * DAX1EEP_PAGE(fh) r/w EEPROM page to write * DAX1EEP_PGOFF(fh) r/w offset rel DAX1EEP_PAGE(fh), only first != 0 * DAX1EEP_PGSZ(fh) r/- size of EEPROM page * DAX1EEP_LEN(fh) r/w remaining num of bytes to write * DAX1EEP_UBUF(fh) r/w pointer to user buffer, moved with DAX1EEP_LEN(fh) * DAX1EEP_EEBUF(fh) -/w internal EEPROM page buffer * DAX1EEP_CMP(fh) -/w state of page in first V step, result of final V * DAX1EEP_EVCBK(fh) r/w callback event * r/- DAX1_DONE optimistic preset * -/w DAXEV_EEP_VERIFY_ERR, dep on DAX1EEP_CMP(fh) * * PARAMETERS * fh=pst_FH i/- pointer fh to file handle structure for EEPROM * s32_State i/- internal state machine state * returns -/o next state machine state * == DAX1_DONE: normal termination * <= DAX_READY: abort * > DAX_READY: service ongoing * * INTERFACE DECLARATION: */s32 p_dax7_DoEepWr (t_dax1_EeHandle *pst_FH, s32 s32_State){ u32 offset, i, endOfPage; u8 *buf, *eeBuf; s32 start; s32 nextState; DAX_TRACE3("p_dax7_DoEepWr(FH%d, st%d)\n", DAX1FH_FH(pst_FH), s32_State); switch (nextState= s32_State) // default: same state {# if (DAFLAGS & VTD_DAX_VER) default: DAX_VERIFY(0, DAXEV_FATAL_DoEepWr, 0); DAX1_TRANSUNC(nextState, DAX_READY); // abort break;# endif case DAX1EEWR_VERIFY: if (DAX1EEP_CMP(pst_FH)) { DAX1EEP_EVCBK(pst_FH)= DAXEV_EEP_VERIFY_ERR; } case DAX1_START: // start state (first page) if ((DAX1G_DEVTYPES & FDR_DEVTYPE_EE)==0){ DAX1_TRANSUNC(nextState, DAXEV_DEVICE_ERR2); // ----------------------------------------------------------------> break; } nextState= p_dax7_DoEepWrReadPage(pst_FH, s32_State!=DAX1_START); break; case DAX1EEWR_DOPAGE: // analyse required changes, program UBUF offset= DAX1EEP_PGOFF(pst_FH); // 0..endOfPage, first byte to consider buf= DAX1EEP_UBUF(pst_FH); // UBUF corresponds to PGOFF eeBuf= DAX1EEP_EEBUF(pst_FH); // EEBUF aligned to start of page endOfPage= p_dax7_CalcRemOnPage(pst_FH) + offset; // compare EEPROM page and user data to write start= 0; // start values: // 0 no change // -1 erase page // i+1 next byte to write: i for (i=offset; i<endOfPage; i++) { if (eeBuf[i] != buf[i-offset]) { if (start==0) { start= i+1; // first byte to change: start-1 } if (eeBuf[i] != 0xFF) { start= -1; // need to erase before change break; } } } // dep on result of compare: if (start == 0) // no (further) change for this page { if (DAX1EEP_STAT(pst_FH)) { // do final verify after change of page p_dax7_CmpEepReq(pst_FH); nextState= DAX1EEWR_VERIFY; }else{ nextState= p_dax7_DoEepWrReadPage(pst_FH, 1); // next or ready } } else { DAX1EEP_STAT(pst_FH) |= start; // mark changed if (start > 0) { // program bytes from start-1 on start--; // copy sequence of user bytes to eeBuf for (i=start; i<endOfPage; i++) { if (eeBuf[i] == buf[i-offset]) { break; } eeBuf[i]= buf[i-offset]; } // area processed: [offset .. i-1] DAX1EEP_UBUF(pst_FH) += i - offset; DAX1EEP_LEN(pst_FH) -= i - offset; DAX1EEP_PGOFF(pst_FH) = i; // area to write: [start .. i-1], offset <= start-1 p_dax7_WrEepReq(pst_FH, start, i-start); // prgrm seq from eeBuf } else { // start < 0: need to erase before change p_dax7_ErEepReq(pst_FH); // erase page // mark area for ubuf data, look for to be restored parts for(i=0; i<DAX1EEP_PGSZ(pst_FH); i++) { if (i < offset || i >= endOfPage) { // preserve to be restored parts ? if (nextState!=DAX1EEWR_RESTORE && eeBuf[i] != 0xFF) { nextState= DAX1EEWR_RESTORE; DAX1EEP_STAT(pst_FH)= i; // index for restore } }else{ // ubuf data area: mark erased eeBuf[i]= 0xFF; } } } } break; case DAX1EEWR_RESTORE: // re-program not to be changed but erased part offset= DAX1EEP_PGOFF(pst_FH); // 0..endOfPage, first byte to consider eeBuf= DAX1EEP_EEBUF(pst_FH); // EEBUF aligned to start of page endOfPage= p_dax7_CalcRemOnPage(pst_FH) + offset; // search for sequence of not-FF bytes to restore // start byte is DAX1EEP_STAT(pst_FH) start= DAX1EEP_STAT(pst_FH); for (i= start+1; i<DAX1EEP_PGSZ(pst_FH); i++) { if (eeBuf[i]==0xFF || i==offset) { break; // i= first byte not to restore } } // i= first byte not to restore, start < i <= pgsz p_dax7_WrEepReq(pst_FH, start, i-start); // look if there is more to restore nextState= DAX1EEWR_DOPAGE; // assume not for (i= i; i<DAX1EEP_PGSZ(pst_FH); i++) { if (i < offset || i >= endOfPage) { if (eeBuf[i] != 0xFF) { nextState= DAX1EEWR_RESTORE; // still more to restore DAX1EEP_STAT(pst_FH)= i; break; } } } break; } DAX_TRACE2("p_dax7_DoEepWr returns state= %d\n", nextState); return nextState;}#endif // DAX_EE//eof
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -