⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdax7eep.c

📁 EEPROM驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 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 + -