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

📄 pageeepromm.nc

📁 传感器网络中的嵌入式操作系统源代码
💻 NC
📖 第 1 页 / 共 2 页
字号:
// $Id: PageEEPROMM.nc,v 1.4.2.3 2003/08/18 22:09:49 cssharp Exp $/*									tab:4 * "Copyright (c) 2000-2003 The Regents of the University  of California.   * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Copyright (c) 2002-2003 Intel Corporation * All rights reserved. * * This file is distributed under the terms in the attached INTEL-LICENSE      * file. If you do not find these files, copies can be found by writing to * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,  * 94704.  Attention:  Intel License Inquiry. */includes crc;includes PageEEPROM;module PageEEPROMM {  provides {    interface StdControl;    interface PageEEPROM;  }  uses {    interface StdControl as FlashControl;    interface SlavePin as FlashSelect;    interface FastSPI as FlashSPI;    interface Resource as FlashIdle;    command bool getCompareStatus();    interface Leds;  }}implementation{#define CHECKARGS#if 0  uint8_t work[20];  uint8_t woffset;  void wdbg(uint8_t x) {    work[woffset++] = x;    if (woffset == sizeof work)      woffset = 0;  }#else#define wdbg(n)#endif  enum { // requests    IDLE,    R_READ,    R_READCRC,    R_WRITE,    R_ERASE,    R_SYNC,    R_SYNCALL,    R_FLUSH,    R_FLUSHALL  };  uint8_t request;  uint8_t *reqBuf;  eeprompageoffset_t reqOffset, reqBytes;  eeprompage_t reqPage;  bool deselectRequested; /* deselect of EEPROM requested (needed between			     two commands) */  bool broken; // Write failed. Fail all subsequent requests.  bool compareOk;  enum {    P_SEND_CMD,     P_READ,    P_READCRC,    P_WRITE,    P_FLUSH,    P_FILL,    P_ERASE,    P_COMPARE,    P_COMPARE_CHECK  };  uint8_t cmdPhase, waiting;  uint8_t *data, cmd[4];  uint8_t cmdCount;  eeprompageoffset_t dataCount;  uint16_t computedCrc;  struct {    eeprompage_t page;    bool busy : 1;    bool clean : 1;    bool erased : 1;    uint8_t unchecked : 2;  } buffer[2];  uint8_t selected; // buffer used by the current op  uint8_t checking;  bool flashBusy;  enum { // commands we're executing (all SPI Mode 0 or 3)    C_READ_BUFFER1 = 0xd4,    C_READ_BUFFER2 = 0xd6,    C_WRITE_BUFFER1 = 0x84,    C_WRITE_BUFFER2 = 0x87,    C_FILL_BUFFER1 = 0x53,     C_FILL_BUFFER2 = 0x55,     C_FLUSH_BUFFER1 = 0x83,    C_FLUSH_BUFFER2 = 0x86,    C_QFLUSH_BUFFER1 = 0x88,    C_QFLUSH_BUFFER2 = 0x89,    C_COMPARE_BUFFER1 = 0x60,    C_COMPARE_BUFFER2 = 0x61,    C_REQ_STATUS = 0xd7,    C_ERASE_PAGE = 0x81  };  // Select a command for the current buffer#define OPN(n, name) ((n) ? name ## 1 : name ## 2)#define OP(name) OPN(selected, name)  command result_t StdControl.init() {    request = IDLE;    waiting = deselectRequested = FALSE;    flashBusy = TRUE;          // pretend we're on an invalid non-existent page    buffer[0].page = buffer[1].page = TOS_EEPROM_MAX_PAGES;    buffer[0].busy = buffer[1].busy = FALSE;    buffer[0].clean = buffer[1].clean = TRUE;    buffer[0].unchecked = buffer[1].unchecked = 0;    buffer[0].erased = buffer[1].erased = FALSE;    return call FlashControl.init();  }    command result_t StdControl.start() {    return call FlashControl.start();  }  command result_t StdControl.stop() {    return call FlashControl.stop();  }  /* Select EEPROM, start a SPI transaction */  void selectFlash() {    call FlashSelect.low();  }  /* Deselect EEPROM via SlavePin */  void requestDeselect() {    deselectRequested = TRUE;    call FlashSelect.high(TRUE);  }  event result_t FlashIdle.available() {    if (cmdPhase == P_COMPARE_CHECK)      compareOk = call getCompareStatus();    requestDeselect();    return SUCCESS;  }  void requestFlashStatus() {    waiting = TRUE;    selectFlash();    wdbg(C_REQ_STATUS);    call FlashSPI.txByte(C_REQ_STATUS);    if (call FlashIdle.wait() == FAIL) // already done      signal FlashIdle.available();  }  void sendFlashCommand() {    uint8_t in = 0, out = 0;    uint8_t *ptr = cmd;    eeprompageoffset_t count = cmdCount;    uint16_t crc = 0;    uint8_t lphase = P_SEND_CMD;    /* For a 3% speedup, we could use labels and goto *.       But: very gcc-specific. Also, need to do              asm ("ijmp" : : "z" (state))	    instead of goto *state    */    wdbg(cmd[0]);    selectFlash();    for (;;)      {	if (lphase == P_READCRC)	  {	    crc = crcByte(crc, in);	    --count;	    if (!count)	      {		computedCrc = crc;		break;	      }	  }	else if (lphase == P_SEND_CMD)	  { 	    out = *ptr++;	    count--;	    if (!count)	      {		lphase = cmdPhase;		ptr = data;		count = dataCount;	      }	  }	else if (lphase == P_READ)	  {	    *ptr++ = in;	    --count;	    if (!count)	      break;	  }	else if (lphase == P_WRITE)	  {	    if (!count)	      break;	    out = *ptr++;	    --count;	  }	else /* P_FILL, P_FLUSH, P_ERASE, P_COMPARE */	  break;		in = call FlashSPI.txByte(out);      }    requestDeselect();  }  void requestDone(result_t result);  task void taskSuccess() {    requestDone(SUCCESS);  }  task void taskFail() {    requestDone(FAIL);  }  void handleRWRequest();  void execCommand(bool wait, uint8_t reqCmd, uint8_t dontCare,		   eeprompage_t page, eeprompageoffset_t offset);  void checkBuffer(uint8_t buf) {    cmdPhase = P_COMPARE;    checking = buf;    execCommand(TRUE, OPN(buf, C_COMPARE_BUFFER), 0,		buffer[buf].page, 0);  }  void flushBuffer() {    cmdPhase = P_FLUSH;    execCommand(TRUE, buffer[selected].erased ?		OP(C_QFLUSH_BUFFER) :		OP(C_FLUSH_BUFFER), 0,		buffer[selected].page, 0);  }  void flashCommandComplete() {    if (waiting)      {	waiting = flashBusy = buffer[0].busy = buffer[1].busy = FALSE;	if (cmdPhase == P_COMPARE_CHECK)	  {	    if (compareOk)	      buffer[checking].unchecked = 0;	    else if (buffer[checking].unchecked < 2)	      buffer[checking].clean = FALSE;	    else	      {		broken = TRUE; // write failed. refuse all further reqs		requestDone(FAIL);		return;	      }	    handleRWRequest();	  }	else	  {	    // Eager compare - this steals the current command#if 1	    if ((buffer[0].unchecked || buffer[1].unchecked) &&		!(cmdPhase == P_COMPARE || cmdPhase == P_COMPARE_CHECK))	      checkBuffer(buffer[0].unchecked ? 0 : 1);	    else#endif	      sendFlashCommand();	  }	return;      }    switch (cmdPhase)      {      default: // shouldn't happen	requestDone(FAIL);	break;      case P_READ: case P_READCRC: case P_WRITE:	requestDone(SUCCESS);	break;      case P_FLUSH:	flashBusy = TRUE;	buffer[selected].clean = buffer[selected].busy = TRUE;	buffer[selected].unchecked++;	buffer[selected].erased = FALSE;	handleRWRequest();	break;      case P_COMPARE:	cmdPhase = P_COMPARE_CHECK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -