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

📄 hplat45dbbytec.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/*
 * Copyright (c) 2005-2006 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.
 */

/**
 * Generic byte-at-a-time implementation of the AT45DB HPL.
 * 
 * Each platform must provide its own HPL implementation for its AT45DB
 * flash chip. To simplify this task, this component can easily be used to
 * build an AT45DB HPL by connecting it to a byte-at-a-time SPI interface,
 * and an HplAt45dbByte interface.
 *
 * @param The number of bits needed to represent a sector size, e.g., 9
 *   for the AT45DB041B.
 *
 * @author David Gay
 */

generic module HplAt45dbByteC(int sectorSizeLog2) @safe() {
  provides interface HplAt45db;
  uses {
    interface Resource;
    interface SpiByte as FlashSpi;
    interface HplAt45dbByte;
  }
}
implementation 
{
  enum {
    P_IDLE,
    P_SEND_CMD, 
    P_READ,
    P_READ_CRC,
    P_WRITE,
    P_WAIT_IDLE,
    P_WAIT_COMPARE,
    P_WAIT_COMPARE_OK,
    P_FILL,
    P_FLUSH,
    P_COMPARE,
    P_ERASE
  };
  uint8_t status = P_IDLE;
  uint8_t flashCmd[9];
  at45pageoffset_t dataCount;
  uint8_t * COUNT_NOK(dataCount) data;
  uint8_t dontCare;

  void complete(uint16_t crc) {
    uint8_t s = status;

    status = P_IDLE;
    switch (s)
      {
      default: break;
      case P_READ_CRC:
	signal HplAt45db.crcDone(crc);
	break;
      case P_FILL:
	signal HplAt45db.fillDone();
	break;
      case P_FLUSH:
	signal HplAt45db.flushDone();
	break;
      case P_COMPARE:
	signal HplAt45db.compareDone();
	break;
      case P_ERASE:
	signal HplAt45db.eraseDone();
	break;
      case P_READ:
	signal HplAt45db.readDone();
	break;
      case P_WRITE:
	signal HplAt45db.writeDone();
	break;
      }
  }

  void requestFlashStatus() {
    call HplAt45dbByte.select();
    call FlashSpi.write(AT45_C_REQ_STATUS);
    call HplAt45dbByte.waitIdle();
  }

  void doCommand() {
    uint8_t in = 0, out = 0;
    uint8_t *ptr;
    at45pageoffset_t count;
    uint8_t lphase;
    uint16_t crc = (uint16_t)data;

    if (dataCount) // skip 0-byte ops
      {
	/* 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
	*/

	ptr = flashCmd;
	lphase = P_SEND_CMD;
	count = 4 + dontCare;

	call HplAt45dbByte.select();
	for (;;)
	  {
	    if (lphase == P_READ_CRC)
	      {
		crc = crcByte(crc, in);

		--count;
		if (!count)
		  break;
	      }
	    else if (lphase == P_SEND_CMD)
	      {
		// Note: the dontCare bytes are read after the end of cmd...
		out = *ptr++;
		count--;
		if (!count)
		  {
		    lphase = status;
		    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_COMMAND */
	      break;
	
	    in = call FlashSpi.write(out);
	  }
	call HplAt45dbByte.deselect();
      }

    call Resource.release();
    complete(crc);
  }

  event void Resource.granted() {
    switch (status)
      {
      case P_WAIT_COMPARE: case P_WAIT_IDLE:
	requestFlashStatus();
	break;
      default:
	doCommand();
	break;
      }
  }

  void execCommand(uint8_t op, uint8_t reqCmd, uint8_t reqDontCare,
		   at45page_t reqPage, at45pageoffset_t reqOffset,
		   uint8_t * COUNT_NOK(reqCount) reqData, at45pageoffset_t reqCount) {
    status = op;

    // page (2 bytes) and highest bit of offset
    flashCmd[0] = reqCmd;
    flashCmd[1] = reqPage >> (16 - sectorSizeLog2);
    flashCmd[2] = reqPage << (sectorSizeLog2 - 8) | reqOffset >> 8;
    flashCmd[3] = reqOffset; // low-order 8 bits
    data = NULL;
    dataCount = reqCount;
    data = reqData;
    dontCare = reqDontCare;

    call Resource.request();
  }

  command void HplAt45db.waitIdle() {
    status = P_WAIT_IDLE;
    call Resource.request();
  }

  command void HplAt45db.waitCompare() {
    status = P_WAIT_COMPARE;
    call Resource.request();
  }

  event void HplAt45dbByte.idle() {
    if (status == P_WAIT_COMPARE)
      {
	bool cstatus = call HplAt45dbByte.getCompareStatus();
	call HplAt45dbByte.deselect();
	call Resource.release();
	signal HplAt45db.waitCompareDone(cstatus);
      }
    else
      {
	call HplAt45dbByte.deselect();
	call Resource.release();
	signal HplAt45db.waitIdleDone();
      }
  }

  command void HplAt45db.fill(uint8_t cmd, at45page_t page) {
    execCommand(P_FILL, cmd, 0, page, 0, NULL, 1);
  }

  command void HplAt45db.flush(uint8_t cmd, at45page_t page) {
    execCommand(P_FLUSH, cmd, 0, page, 0, NULL, 1);
  }

  command void HplAt45db.compare(uint8_t cmd, at45page_t page) {
    execCommand(P_COMPARE, cmd, 0, page, 0, NULL, 1);
  }

  command void HplAt45db.erase(uint8_t cmd, at45page_t page) {
    execCommand(P_ERASE, cmd, 0, page, 0, NULL, 1);
  }

  command void HplAt45db.read(uint8_t cmd,
			      at45page_t page, at45pageoffset_t offset,
			      uint8_t *pdata, at45pageoffset_t count) {
    execCommand(P_READ, cmd, 5, page, offset, pdata, count);
  }

  command void HplAt45db.readBuffer(uint8_t cmd, at45pageoffset_t offset,
				    uint8_t *pdata, at45pageoffset_t count) {
    execCommand(P_READ, cmd, 2, 0, offset, pdata, count);
  }

  command void HplAt45db.crc(uint8_t cmd,
			     at45page_t page, at45pageoffset_t offset,
			     at45pageoffset_t count,
			     uint16_t baseCrc) {
    execCommand(P_READ_CRC, cmd, 2, page, offset, TCAST(uint8_t * COUNT(count), baseCrc), count);
  }

  command void HplAt45db.write(uint8_t cmd,
			       at45page_t page, at45pageoffset_t offset,
			       uint8_t *pdata, at45pageoffset_t count) {
    execCommand(P_WRITE, cmd, 0, page, offset, pdata, count);
  }
}

⌨️ 快捷键说明

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