[Tinyos-commits] CVS: tinyos-1.x/tos/lib/Flash/STM25P BlockStorageC.nc, NONE, 1.1 BlockStorageM.nc, NONE, 1.1 FlashWP.nc, NONE, 1.1 FlashWPC.nc, NONE, 1.1 FlashWPM.nc, NONE, 1.1 FormatStorageC.nc, NONE, 1.1 FormatStorageM.nc, NONE, 1.1 HALSTM25P.h, NONE, 1.1 HALSTM25P.nc, NONE, 1.1 HALSTM25PC.nc, NONE, 1.1 HALSTM25PM.nc, NONE, 1.1 HPLSTM25P.nc, NONE, 1.1 SectorStorage.nc, NONE, 1.1 StorageManager.nc, NONE, 1.1 StorageManagerC.nc, NONE, 1.1 StorageManagerM.nc, NONE, 1.1 StorageRemap.nc, NONE, 1.1 Storage_chip.h, NONE, 1.1

David Gay idgay at users.sourceforge.net
Mon Jul 11 16:36:12 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/tos/lib/Flash/STM25P
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28470/STM25P

Added Files:
	BlockStorageC.nc BlockStorageM.nc FlashWP.nc FlashWPC.nc 
	FlashWPM.nc FormatStorageC.nc FormatStorageM.nc HALSTM25P.h 
	HALSTM25P.nc HALSTM25PC.nc HALSTM25PM.nc HPLSTM25P.nc 
	SectorStorage.nc StorageManager.nc StorageManagerC.nc 
	StorageManagerM.nc StorageRemap.nc Storage_chip.h 
Log Message:
new flash abstraction (BlockStorage only for now), + reorganisation of
duplicated files


--- NEW FILE: BlockStorageC.nc ---
// $Id: BlockStorageC.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes BlockStorage;

configuration BlockStorageC {
  provides {
    interface Mount[blockstorage_t blockId];
    interface BlockRead[blockstorage_t blockId];
    interface BlockWrite[blockstorage_t blockId];
    interface StorageRemap[blockstorage_t blockId];
  }
}

implementation {

  components BlockStorageM, Main, StorageManagerC, LedsC as Leds;

  Mount = BlockStorageM.Mount;
  BlockRead = BlockStorageM.BlockRead;
  BlockWrite = BlockStorageM.BlockWrite;
  StorageRemap = StorageManagerC.StorageRemap;

  Main.StdControl -> StorageManagerC;

  BlockStorageM.SectorStorage -> StorageManagerC.SectorStorage;
  BlockStorageM.ActualMount -> StorageManagerC.Mount;
  BlockStorageM.StorageManager -> StorageManagerC.StorageManager;
  BlockStorageM.Leds -> Leds;

}

--- NEW FILE: BlockStorageM.nc ---
// $Id: BlockStorageM.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

module BlockStorageM {
  provides {
    interface Mount[blockstorage_t blockId];
    interface BlockRead[blockstorage_t blockId];
    interface BlockWrite[blockstorage_t blockId];
  }
  uses {
    interface SectorStorage[blockstorage_t blockId];
    interface Leds;
    interface Mount as ActualMount[blockstorage_t blockId];
    interface StorageManager[blockstorage_t blockId];
  }
}

implementation {

  enum {
    S_IDLE,
    S_WRITE,
    S_ERASE,
    S_COMMIT,
    S_READ,
    S_VERIFY,
    S_CRC,
  };

  uint8_t state;
  uint8_t client;

  block_addr_t rwAddr, rwLen;
  void* rwBuf;
  uint16_t crc;

  command result_t Mount.mount[blockstorage_t blockId](volume_id_t id) {
    return call ActualMount.mount[blockId](id);
  }

  event void ActualMount.mountDone[blockstorage_t blockId](storage_result_t result, volume_id_t id) {
    signal Mount.mountDone[blockId](result, id);
  }

  void signalDone(storage_result_t result) {
    uint8_t tmpState = state;
    state = S_IDLE;
    switch(tmpState) {
    case S_WRITE: signal BlockWrite.writeDone[client](result, rwAddr, rwBuf, rwLen); break;
    case S_ERASE: signal BlockWrite.eraseDone[client](result); break;
    case S_COMMIT: signal BlockWrite.commitDone[client](result); break;
    case S_READ: signal BlockRead.readDone[client](result, rwAddr, rwBuf, rwLen); break;
    case S_VERIFY: signal BlockRead.verifyDone[client](result); break;
    case S_CRC: signal BlockRead.computeCrcDone[client](result, crc, rwAddr, rwLen); break;
    }
  }

  task void signalDoneTask() {
    signalDone(STORAGE_OK);
  }

  result_t newRequest(uint8_t newState, blockstorage_t blockId, 
		      block_addr_t addr, void* buf, block_addr_t len) {

    result_t result = FAIL;

    if (state != S_IDLE)
      return FAIL;

    client = blockId;

    rwAddr = addr;
    rwBuf = buf;
    rwLen = len;

    switch(newState) {
    case S_READ:
      result = call SectorStorage.read[blockId](rwAddr, rwBuf, rwLen);
      break;
    case S_CRC:
      result = call SectorStorage.computeCrc[blockId](&crc, 0, rwAddr, rwLen);
      break;
    case S_VERIFY:
      break;
    case S_WRITE:
      result = call SectorStorage.write[blockId](rwAddr, rwBuf, rwLen);
      break;
    case S_ERASE:
      result = call SectorStorage.erase[blockId](0, call StorageManager.getVolumeSize[blockId]());
      break;
    case S_COMMIT:
      break;
    }
    
    if (newState == S_READ || newState == S_CRC || newState == S_VERIFY) {
      if (result == SUCCESS) 
	result = post signalDoneTask();
    }
    
    if (result == SUCCESS)
      state = newState;

    return result;

  }
  
  command uint32_t BlockRead.getSize[blockstorage_t blockId]() {
    return call StorageManager.getVolumeSize[blockId]();
  }

  command result_t BlockRead.read[blockstorage_t blockId](block_addr_t addr, void* buf, block_addr_t len) {
    return newRequest(S_READ, blockId, addr, buf, len);
  }

  command result_t BlockRead.verify[blockstorage_t blockId]() {
    return newRequest(S_VERIFY, blockId, 0, NULL, 0);
  }

  command result_t BlockRead.computeCrc[blockstorage_t blockId](block_addr_t addr, block_addr_t len) {
    return newRequest(S_CRC, blockId, addr, NULL, len);
  }

  command result_t BlockWrite.erase[blockstorage_t blockId]() {
    return newRequest(S_ERASE, blockId, 0, NULL, 0);
  }

  command result_t BlockWrite.write[blockstorage_t blockId](block_addr_t addr, void* buf, block_addr_t len) {
    return newRequest(S_WRITE, blockId, addr, buf, len);
  }
  
  command result_t BlockWrite.commit[blockstorage_t blockId]() {
    return newRequest(S_COMMIT, blockId, 0, NULL, 0);
  }
  
  event void SectorStorage.writeDone[blockstorage_t blockId](storage_result_t result) {
    signalDone(result);
  }
  
  event void SectorStorage.eraseDone[blockstorage_t blockId](storage_result_t result) {
    signalDone(result);
  }

  default event void BlockWrite.writeDone[blockstorage_t blockId](storage_result_t result, block_addr_t addr, void* buf, block_addr_t len) { ; }
  default event void BlockWrite.eraseDone[blockstorage_t blockId](storage_result_t result) { ; }
  default event void BlockWrite.commitDone[blockstorage_t blockId](storage_result_t result) { ; }
  default event void BlockRead.readDone[blockstorage_t blockId](storage_result_t result, block_addr_t addr, void* buf, block_addr_t len) { ; }
  default event void BlockRead.verifyDone[blockstorage_t blockId](storage_result_t result) { ; }
  default event void BlockRead.computeCrcDone[blockstorage_t blockId](storage_result_t result, uint16_t crcResult, block_addr_t addr, block_addr_t len) { ; }

  default event void Mount.mountDone[blockstorage_t blockId](storage_result_t result, volume_id_t id) { ; }

}

--- NEW FILE: FlashWP.nc ---
// $Id: FlashWP.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

interface FlashWP {
  command result_t setWP();
  event void setWPDone();
  command result_t clrWP();
  event void clrWPDone();
}

--- NEW FILE: FlashWPC.nc ---
// $Id: FlashWPC.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

configuration FlashWPC {
  provides {
    interface FlashWP;
    interface StdControl;
  }
}

implementation {

  components FlashWPM, HALSTM25PC;

  StdControl = FlashWPM;
  FlashWP = FlashWPM;

  FlashWPM.HALSTM25P -> HALSTM25PC.HALSTM25P[unique("HALSTM25P")];

}

--- NEW FILE: FlashWPM.nc ---
// $Id: FlashWPM.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

module FlashWPM {
  provides {
    interface FlashWP;
    interface StdControl;
  }
  uses {
    interface HALSTM25P;
  }
}

implementation {

  uint8_t state;

  enum {
    S_IDLE = 0xff,
    S_CLR = 0x00,
    S_SET = 0x84,
  };

  command result_t StdControl.init() {
    state = S_IDLE;
    return SUCCESS;
  }

  command result_t StdControl.start() { return SUCCESS; }
  command result_t StdControl.stop() { return SUCCESS; }

  result_t newRequest(uint8_t newState) {

    result_t result;

    if (state != S_IDLE)
      return FAIL;
    
    result = call HALSTM25P.writeSR(newState);

    if (result == SUCCESS)
      state = newState;
      
    return result;

  }

  command result_t FlashWP.clrWP() {
    return newRequest(S_CLR);
  }

  command result_t FlashWP.setWP() {
    return newRequest(S_SET);
  }
  
  event void HALSTM25P.writeSRDone() {
    uint8_t tmpState = state;
    state = S_IDLE;
    switch(tmpState) {
    case S_CLR: signal FlashWP.clrWPDone(); break;
    case S_SET: signal FlashWP.setWPDone(); break;
    }
  }

  event void HALSTM25P.pageProgramDone() {}
  event void HALSTM25P.sectorEraseDone() {}
  event void HALSTM25P.bulkEraseDone() {}

}

--- NEW FILE: FormatStorageC.nc ---
// $Id: FormatStorageC.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes crc;

configuration FormatStorageC {
  provides {
    interface FormatStorage;
  }
}

implementation {

  components CrcC, FormatStorageM, HALSTM25PC, Main;

  FormatStorage = FormatStorageM;

  Main.StdControl -> FormatStorageM;
  Main.StdControl -> HALSTM25PC;

  FormatStorageM.Crc -> CrcC;
  FormatStorageM.HALSTM25P -> HALSTM25PC.HALSTM25P[unique("HALSTM25P")];

}

--- NEW FILE: FormatStorageM.nc ---
// $Id: FormatStorageM.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

module FormatStorageM {
  provides {
    interface FormatStorage;
    interface StdControl;
  }
  uses {
    interface Crc;
    interface HALSTM25P;
  }
}

implementation {

  SectorTable sectorTable;
  stm25p_addr_t curAddr;

  uint8_t state;

  enum {
    S_INIT,
    S_COMMIT,
    S_COMMIT_DONE,
  };
  
  void signalDone(storage_result_t result) {
    state = S_COMMIT_DONE;
    signal FormatStorage.commitDone(result);
  }

  command result_t StdControl.init() {
    state = S_COMMIT_DONE;
    return SUCCESS;
  }

  command result_t StdControl.start() {
    return SUCCESS;
  }

  command result_t StdControl.stop() {
    return SUCCESS;
  }

  command result_t FormatStorage.init() {

    volume_id_t i;

    if (state == S_COMMIT)
      return FAIL;

    state = S_INIT;

    for ( i = 0; i < STM25P_NUM_SECTORS; i++ )
      sectorTable.sector[i].volumeId = STM25P_INVALID_VOLUME_ID;

    return SUCCESS;

  }

  result_t allocate(volume_id_t id, storage_addr_t addr, storage_addr_t size) {

    volume_id_t freeSectors;
    uint8_t base;
    volume_id_t i;

    if (state != S_INIT)
      return FAIL;

    if (addr % STM25P_SECTOR_SIZE)
      return FAIL;

    // size must be a multiple of sector size
    if (size % STM25P_SECTOR_SIZE)
      return FAIL;

    addr /= STM25P_SECTOR_SIZE;
    size /= STM25P_SECTOR_SIZE;

    // check if id is already taken
    for ( i = 0; i < STM25P_NUM_SECTORS; i++ ) {
      if (sectorTable.sector[i].volumeId == id)
	return FAIL;
    }
    
    // count number of free sectors
    for ( i = addr, freeSectors = 0, base = addr; i < STM25P_NUM_SECTORS && freeSectors < size; i++ ) {
      if (sectorTable.sector[i].volumeId == STM25P_INVALID_VOLUME_ID) {
	freeSectors++;
      }
      else {
	// if trying to allocate fixed, return fail
	if (addr != 0)
	  return FAIL;
	freeSectors = 0;
	base = i + 1;
      }
    }

    // check if there are enough free sectors
    if (freeSectors < size)
      return FAIL;

    // allocate space
    for ( i = base; i < STM25P_NUM_SECTORS && size > 0; i++, size-- )
      sectorTable.sector[i].volumeId = id;

    return SUCCESS;

  }

  command result_t FormatStorage.allocate(volume_id_t id, storage_addr_t size) {
    return allocate(id, 0, size);
  }

  command result_t FormatStorage.allocateFixed(volume_id_t id, storage_addr_t addr, storage_addr_t size) {
    return allocate(id, addr, size);
  }
   
  uint16_t computeSectorTableCrc() {
    return call Crc.crc16(&sectorTable, sizeof(SectorTable)-2);
  }

  command result_t FormatStorage.commit() {

    if (state != S_INIT)
      return FAIL;

    state = S_COMMIT;

    sectorTable.crc = computeSectorTableCrc();

    curAddr = STM25P_SECTOR_SIZE - sizeof(SectorTable);

    if (call HALSTM25P.sectorErase(curAddr) == FAIL) {
      state = S_INIT;
      return FAIL;
    }

    return SUCCESS;

  }

  void pageProgramDone() {

    curAddr += STM25P_SECTOR_SIZE;

    if ( curAddr < STM25P_SECTOR_SIZE * STM25P_NUM_SECTORS ) {
      if (call HALSTM25P.sectorErase(curAddr) == FAIL) {
	state = S_INIT;
	signalDone(STORAGE_FAIL);
      }
      return;
    }
    
    signalDone(STORAGE_OK);

  }

  event void HALSTM25P.sectorEraseDone() { 

    uint8_t sector = curAddr / STM25P_SECTOR_SIZE;

    if ( sector == STM25P_NUM_SECTORS - 1 ||
	 sectorTable.sector[sector].volumeId != sectorTable.sector[sector+1].volumeId ) {
      stm25p_addr_t addr = STM25P_SECTOR_SIZE*(sector+1) - sizeof(SectorTable);
      if (call HALSTM25P.pageProgram(addr, &sectorTable, sizeof(SectorTable)) == FAIL)
	signalDone(STORAGE_FAIL);
    }
    else {
      pageProgramDone();
    }

  }

  event void HALSTM25P.pageProgramDone() {
    pageProgramDone();
  }

  event void HALSTM25P.bulkEraseDone() {}
  event void HALSTM25P.writeSRDone() {}

}

--- NEW FILE: HALSTM25P.h ---
// $Id: HALSTM25P.h,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

#ifndef __STM25P_H__
#define __STM25P_H__

#include "Storage.h"

enum {
  STM25P_PAGE_SIZE = 256,
  STM25P_SECTOR_SIZE_LOG2 = 16,
  STM25P_SECTOR_SIZE = 1L << STM25P_SECTOR_SIZE_LOG2,
  STM25P_NUM_SECTORS = 16,
  STM25P_POWEROFF_DELAY = 1024,
};

enum {
  STM25P_INVALID_SIG = 0xff,
  STM25P_INVALID_VOLUME_ID = 0xff,
  STM25P_INVALID_SECTOR = 0xff,
};

enum {
  STM25P_CMD_SIZE        = 1,
  STM25P_ADDR_SIZE       = 3,
  STM25P_FR_DUMMY_BYTES  = 1,
  STM25P_RES_DUMMY_BYTES = 3,
};

typedef struct stm25p_cmd_t {
  uint8_t cmd;
  uint8_t address : 2;
  uint8_t dummy : 2;
  bool transmit : 1;
  bool receive : 1;
  bool write : 1;
  bool reserved : 1;
} stm25p_cmd_t;

enum {                   // I, A, D, T, R
  STM25P_WREN      = 0,  // 1, 0, 0, 0, 0
  STM25P_WRDI      = 1,  // 1, 0, 0, 0, 0
  STM25P_RDSR      = 2,  // 1, 0, 0, 0, 1
  STM25P_WRSR      = 3,  // 1, 0, 0, 1, 0
  STM25P_READ      = 4,  // 1, 3, 0, 0, N
  STM25P_FAST_READ = 5,  // 1, 3, 1, 0, N
  STM25P_PP        = 6,  // 1, 3, 0, N, 0
  STM25P_SE        = 7,  // 1, 3, 0, 0, 0
  STM25P_BE        = 8,  // 1, 0, 0, 0, 0
  STM25P_DP        = 9,  // 1, 0, 0, 0, 0
  STM25P_RES       = 10, // 1, 0, 3, 0, 1
  STM25P_CRC       = 11, // 1, 3, 0, 0, 1
};

static const stm25p_cmd_t STM25P_CMDS[12] = {
  { cmd : 0x06, // STM25P_WREN
    address : 0,
    dummy : 0,
    transmit : FALSE,
    receive : FALSE,
    write : FALSE },
  { cmd : 0x04, // STM25P_WRDI
    address : 0,
    dummy : 0,
    transmit : FALSE,
    receive : FALSE,
    write : FALSE },
  { cmd : 0x05, // STM25P_RDSR
    address : 0,
    dummy : 0,
    transmit : FALSE,
    receive : TRUE,
    write : FALSE },
  { cmd : 0x01, // STM25P_WRSR
    address : 0,
    dummy : 0,
    transmit : TRUE,
    receive : FALSE,
    write : TRUE },
  { cmd : 0x03, // STM25P_READ
    address : STM25P_ADDR_SIZE,
    dummy : 0,
    transmit : FALSE,
    receive : TRUE,
    write : FALSE },
  { cmd : 0x0b, // STM25P_FAST_READ
    address : STM25P_ADDR_SIZE,
    dummy : STM25P_FR_DUMMY_BYTES,
    transmit : FALSE,
    receive : TRUE,
    write : FALSE },
  { cmd : 0x02, // STM25P_PP
    address : STM25P_ADDR_SIZE,
    dummy : 0,
    transmit : TRUE,
    receive : FALSE,
    write : TRUE },
  { cmd : 0xd8, // STM25P_SE
    address : STM25P_ADDR_SIZE,
    dummy : 0,
    transmit : FALSE,
    receive : FALSE,
    write : TRUE },
  { cmd : 0xc7, // STM25P_BE
    address : 0,
    dummy : 0,
    transmit : FALSE,
    receive : FALSE,
    write : TRUE },
  { cmd : 0xb9, // STM25P_DP
    address : 0,
    dummy : 0,
    transmit : FALSE,
    receive : FALSE,
    write : FALSE },
  { cmd : 0xab, // STM25P_RES
    address : 0,
    dummy : 3,
    transmit : FALSE,
    receive : TRUE,
    write : FALSE },
  { cmd : 0x03, // STM25P_CRC
    address : STM25P_ADDR_SIZE,
    dummy : 0,
    transmit : FALSE,
    receive : TRUE,
    write : FALSE },
};

typedef uint8_t  stm25p_status_t;
typedef uint32_t stm25p_addr_t;
typedef uint8_t  stm25p_sig_t;

typedef struct {
  volume_id_t volumeId;
} SectorMetadata;

typedef struct {
  SectorMetadata sector[STM25P_NUM_SECTORS];
  uint16_t crc;
} SectorTable;

enum {
  STM25P_INVALID_VERSION = 0xffff,
};

enum {
  STM25P_INVALID_ADDR = 0xffffffff,
};

enum {
  STORAGE_BLOCK_SIZE = STM25P_SECTOR_SIZE,
};

typedef stm25p_addr_t storage_addr_t;

#endif

--- NEW FILE: HALSTM25P.nc ---
// $Id: HALSTM25P.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes HALSTM25P;

interface HALSTM25P {

  command result_t read(stm25p_addr_t addr, void* data, stm25p_addr_t len);

  command result_t pageProgram(stm25p_addr_t addr, void* data, stm25p_addr_t len);
  event void pageProgramDone();

  command result_t sectorErase(stm25p_addr_t addr);
  event void sectorEraseDone();

  command result_t bulkErase();
  event void bulkEraseDone();

  command result_t readSR(void* value);

  command result_t writeSR(uint8_t value);
  event void writeSRDone();

  command result_t computeCrc(uint16_t* crcResult, uint16_t crc, stm25p_addr_t addr, stm25p_addr_t len);

  command stm25p_sig_t getSignature();

}

--- NEW FILE: HALSTM25PC.nc ---
// $Id: HALSTM25PC.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes crc;
includes HALSTM25P;

configuration HALSTM25PC {
  provides {
    interface StdControl;
    interface HALSTM25P[volume_t volume];
  }
}

implementation {
  components HALSTM25PM, HPLSTM25PC, LedsC as Leds, TimerC;

  StdControl = HALSTM25PM;
  StdControl = HPLSTM25PC;
  HALSTM25P = HALSTM25PM;

  HALSTM25PM.HPLSTM25P -> HPLSTM25PC;
  HALSTM25PM.Leds -> Leds;
  HALSTM25PM.Timer -> TimerC.Timer[unique("Timer")];
}

--- NEW FILE: HALSTM25PM.nc ---
// $Id: HALSTM25PM.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

module HALSTM25PM {
  provides {
    interface StdControl;
    interface HALSTM25P[volume_t volume];
  }
  uses {
    interface HPLSTM25P;
    interface Leds;
    interface Timer;
  }
}

implementation {

  enum {
    S_POWEROFF = 0xfe,  // deep power-down state
    S_POWERON  = 0xff,  // awake state, no command in progress
  };

  volume_t curVolume;
  stm25p_sig_t signature;
  uint16_t crcScratch;
  uint8_t curCmd;

  void sendCmd(uint8_t cmd, stm25p_addr_t addr, void* data, stm25p_addr_t len);

  command result_t StdControl.init() {
    curCmd = S_POWEROFF;
    signature = STM25P_INVALID_SIG;
    return SUCCESS;
  }

  command result_t StdControl.start() { return SUCCESS; }
  command result_t StdControl.stop() { return SUCCESS; }

  void signalDone() {

    uint8_t tmpCmd = curCmd;
    curCmd = S_POWERON;

    call Timer.start(TIMER_ONE_SHOT, STM25P_POWEROFF_DELAY);

    switch(tmpCmd) {
    case STM25P_PP: signal HALSTM25P.pageProgramDone[curVolume](); break;
    case STM25P_SE: signal HALSTM25P.sectorEraseDone[curVolume](); break;
    case STM25P_BE: signal HALSTM25P.bulkEraseDone[curVolume](); break;
    case STM25P_WRSR: signal HALSTM25P.writeSRDone[curVolume](); break;
    }

  }

  bool isWriting() {
    uint8_t status;
    if (call HPLSTM25P.getBus() == FAIL)
      return TRUE;
    sendCmd(STM25P_RDSR, 0, &status, sizeof(status));
    call HPLSTM25P.releaseBus();
    return !!(status & 0x1);
  }

  void powerOff() {
    sendCmd(STM25P_DP, 0, NULL, 0);
    curCmd = S_POWEROFF;
  }

  void powerOn() {
    sendCmd(STM25P_RES, 0, &signature, sizeof(signature));
    TOSH_uwait(2); // wait at least 1.8us to power on
    curCmd = S_POWERON;
  }

  event result_t Timer.fired() {

    if (curCmd == S_POWERON)
      powerOff();
    else if (isWriting())
      call Timer.start(TIMER_ONE_SHOT, 1);
    else
      signalDone();

    return SUCCESS;

  }

  void sendCmd(uint8_t cmd, stm25p_addr_t addr, void* data, stm25p_addr_t len) {

    uint8_t cmdBytes[2*STM25P_ADDR_SIZE + 1];
    uint8_t i;

    // begin command
    call HPLSTM25P.beginCmd();
    
    cmdBytes[0] = STM25P_CMDS[cmd].cmd;

    // command, address and dummy bytes
    for ( i = 0; i < STM25P_ADDR_SIZE; i++ )
      cmdBytes[i+1] = (addr >> ((STM25P_ADDR_SIZE-1-i)*8)) & 0xff;
    call HPLSTM25P.txBuf(cmdBytes, (STM25P_CMD_SIZE +
				    STM25P_CMDS[cmd].address +
				    STM25P_CMDS[cmd].dummy) );

    // data
    if (STM25P_CMDS[cmd].receive)
      call HPLSTM25P.rxBuf(data, len, &crcScratch);
    else if (STM25P_CMDS[cmd].transmit)
      call HPLSTM25P.txBuf(data, len);

    // end command
    call HPLSTM25P.endCmd();

  }

  result_t newRequest(uint8_t cmd, volume_t volume, stm25p_addr_t addr, uint8_t* data, stm25p_addr_t len) {

    if (curCmd != S_POWERON && curCmd != S_POWEROFF)
      return FAIL;
    
    if (call HPLSTM25P.getBus() == FAIL)
      return FAIL;

    call Timer.stop();
    
    if (curCmd == S_POWEROFF)
      powerOn();

    curVolume = volume;
    curCmd = cmd;

    // enable writes
    if (STM25P_CMDS[curCmd].write)
      sendCmd(STM25P_WREN, 0, NULL, 0);

    // send command
    sendCmd(curCmd, addr, data, len);

    // post check for write done
    if (STM25P_CMDS[curCmd].write)
      call Timer.start(TIMER_ONE_SHOT, 1);
    else {
      curCmd = S_POWERON;
      call Timer.start(TIMER_ONE_SHOT, STM25P_POWEROFF_DELAY);
    }

    call HPLSTM25P.releaseBus();

    return SUCCESS;

  }

  command result_t HALSTM25P.read[volume_t volume](stm25p_addr_t addr, void* data, stm25p_addr_t len) {
    return newRequest(STM25P_READ, volume, addr, data, len);
  }

  command result_t HALSTM25P.pageProgram[volume_t volume](stm25p_addr_t addr, void* data, stm25p_addr_t len) {
    return newRequest(STM25P_PP, volume, addr, data, len);
  }

  command result_t HALSTM25P.sectorErase[volume_t volume](stm25p_addr_t addr) {
    return newRequest(STM25P_SE, volume, addr, NULL, 0);
  }

  command result_t HALSTM25P.bulkErase[volume_t volume]() {
    return newRequest(STM25P_BE, volume, 0, NULL, 0);
  }

  command result_t HALSTM25P.readSR[volume_t volume](void* value) {
    return newRequest(STM25P_RDSR, volume, 0, value, 1);
  }

  command result_t HALSTM25P.writeSR[volume_t volume](uint8_t value) {
    return newRequest(STM25P_WRSR, volume, 0, &value, 1);
  }

  command result_t HALSTM25P.computeCrc[volume_t volume](uint16_t* crcResult, uint16_t crc, stm25p_addr_t addr, stm25p_addr_t len) {
    result_t result;
    crcScratch = crc;
    result = newRequest(STM25P_CRC, volume, addr, NULL, len);
    *crcResult = crcScratch;
    return result;
  }

  command stm25p_sig_t HALSTM25P.getSignature[volume_t volume]() { 
    return signature; 
  }
  
  default event void HALSTM25P.pageProgramDone[volume_t volume]() {}
  default event void HALSTM25P.sectorEraseDone[volume_t volume]() {}
  default event void HALSTM25P.bulkEraseDone[volume_t volume]() {}
  default event void HALSTM25P.writeSRDone[volume_t volume]() {}

}

--- NEW FILE: HPLSTM25P.nc ---
// $Id: HPLSTM25P.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

interface HPLSTM25P {
  async command result_t getBus();
  async command result_t releaseBus();
  async command result_t beginCmd();
  async command result_t endCmd();
  async command result_t hold();
  async command result_t unhold();
  async command result_t txBuf(void* buf, stm25p_addr_t len);
  async command result_t rxBuf(void* buf, stm25p_addr_t len, uint16_t* crc);
}

--- NEW FILE: SectorStorage.nc ---
// $Id: SectorStorage.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes HALSTM25P;

interface SectorStorage {

  command result_t read(stm25p_addr_t addr, void* data, stm25p_addr_t len);

  command result_t write(stm25p_addr_t addr, void* data, stm25p_addr_t len);
  event void writeDone(storage_result_t result);

  command result_t erase(stm25p_addr_t addr, stm25p_addr_t len);
  event void eraseDone(storage_result_t result);
  
  command result_t computeCrc(uint16_t* crcResult, uint16_t crc, stm25p_addr_t addr, stm25p_addr_t len);

}

--- NEW FILE: StorageManager.nc ---
// $Id: StorageManager.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes HALSTM25P;

interface StorageManager {
  command uint8_t getNumSectors();
  command stm25p_addr_t getVolumeSize();
}

--- NEW FILE: StorageManagerC.nc ---
// $Id: StorageManagerC.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes HALSTM25P;

configuration StorageManagerC {
  provides {
    interface SectorStorage[volume_t volume];
    interface Mount[volume_t volume];
    interface StdControl;
    interface StorageRemap[volume_t volume];
    interface StorageManager[volume_t volume];
  }
}

implementation {

  components CrcC, HALSTM25PC, StorageManagerM, LedsC;
  
  StdControl = StorageManagerM;
  StdControl = HALSTM25PC;
  
  SectorStorage = StorageManagerM.SectorStorage;
  Mount = StorageManagerM;
  StorageRemap = StorageManagerM;
  StorageManager = StorageManagerM;
  
  StorageManagerM.Crc -> CrcC;
  StorageManagerM.HALSTM25P -> HALSTM25PC.HALSTM25P[unique("HALSTM25P")];
  StorageManagerM.Leds -> LedsC;

}

--- NEW FILE: StorageManagerM.nc ---
// $Id: StorageManagerM.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

module StorageManagerM {
  provides {
    interface SectorStorage[volume_t volume];
    interface Mount[volume_t volume];
    interface StdControl;
    interface StorageRemap[volume_t volume];
    interface StorageManager[volume_t volume];
  }
  uses {
    interface Crc;
    interface HALSTM25P;
    interface Leds;
  }
}

implementation {

  enum {
    NUM_VOLUMES = uniqueCount("StorageManager"),
  };

  enum {
    S_NEVER_USED,
    S_READY,
    S_MOUNT,
    S_READ,
    S_COMPUTE_CRC,
    S_WRITE,
    S_ERASE,
  };

  uint8_t state;

  SectorTable sectorTable;
  uint8_t baseSector[NUM_VOLUMES];
  volume_t clientVolume;
  volume_id_t curVolumeId;
  uint16_t crcScratch;
  
  stm25p_addr_t rwAddr;
  stm25p_addr_t rwLen;
  void* rwData;

  command result_t StdControl.init() {

    uint8_t i;
    
    state = S_NEVER_USED;

    for ( i = 0; i < STM25P_NUM_SECTORS; i++ )
      sectorTable.sector[i].volumeId = STM25P_INVALID_VOLUME_ID;

    for ( i = 0; i < NUM_VOLUMES; i++ )
      baseSector[i] = STM25P_INVALID_SECTOR;

    return SUCCESS; 

  }

  command result_t StdControl.start() { 
    return SUCCESS; 
  }

  command result_t StdControl.stop() { 
    return SUCCESS; 
 }

  void signalDone(storage_result_t result) {

    uint8_t tmpState = state;
    state = S_READY;

    switch(tmpState) {
    case S_MOUNT: signal Mount.mountDone[clientVolume](result, curVolumeId); break;
    case S_WRITE: signal SectorStorage.writeDone[clientVolume](result); break;
    case S_ERASE: signal SectorStorage.eraseDone[clientVolume](result); break;
    }
    
  }

  uint16_t computeSectorTableCrc() {
    return call Crc.crc16(&sectorTable, sizeof(SectorTable)-2);
  }

  void actualMount() {

    volume_id_t i;

    // find base sector
    for ( i = 0; i < STM25P_NUM_SECTORS; i++ ) {
      if (sectorTable.sector[i].volumeId == curVolumeId) {
	baseSector[clientVolume] = i;
	signalDone(STORAGE_OK);
	return;
      }
    }

    signalDone(STORAGE_FAIL);

  }

  task void mount() {
    actualMount();
  }

  stm25p_addr_t physicalAddr(stm25p_addr_t volumeAddr) {
    return STM25P_SECTOR_SIZE*baseSector[clientVolume] + volumeAddr;
  }

  stm25p_addr_t calcNumBytes() {

    uint32_t numBytes;

    if ( state == S_MOUNT )
      return STM25P_SECTOR_SIZE;
    else if ( state == S_WRITE )
      numBytes = STM25P_PAGE_SIZE - (rwAddr % STM25P_PAGE_SIZE);
    else 
      numBytes = STM25P_SECTOR_SIZE - (rwAddr % STM25P_SECTOR_SIZE);

    if ( rwLen < numBytes )
      numBytes = rwLen;
    
    return numBytes;
    
  }

  result_t continueOp() {
    stm25p_addr_t pAddr = physicalAddr(rwAddr);

    switch(state) {
    case S_READ: return call HALSTM25P.read(pAddr, rwData, rwLen);
    case S_COMPUTE_CRC: return call HALSTM25P.computeCrc(&crcScratch, crcScratch, pAddr, rwLen);
    case S_MOUNT: pAddr = rwAddr;
    case S_ERASE: return call HALSTM25P.sectorErase(pAddr);
    case S_WRITE: return call HALSTM25P.pageProgram(pAddr, rwData, calcNumBytes());
    }
    return FAIL;
  }

  result_t formatFlash() {

    uint8_t i;

    for ( i = 0; i < STM25P_NUM_SECTORS; i++ )
      sectorTable.sector[i].volumeId = 0xd0 + i;
    sectorTable.crc = computeSectorTableCrc();
    
    rwAddr = 0;
    rwLen = STM25P_SECTOR_SIZE*STM25P_NUM_SECTORS;

    return continueOp();

  }

  command result_t Mount.mount[volume_t volume](volume_id_t volumeID) {

    stm25p_addr_t addr = 0;
    result_t result;
    
    if (state != S_READY && state != S_NEVER_USED)
      return FAIL;
    
    curVolumeId = volumeID;
    clientVolume = volume;

    // if never used, look for partition table
    if (state == S_NEVER_USED) {

      // if never used, find valid sector table
      for ( addr = STM25P_SECTOR_SIZE - sizeof(SectorTable); 
	    addr < STM25P_SECTOR_SIZE*STM25P_NUM_SECTORS;
	    addr += STM25P_SECTOR_SIZE ) {
	if (call HALSTM25P.read(addr, &sectorTable, sizeof(SectorTable)) == FAIL)
	  return FAIL;
	if (sectorTable.crc == computeSectorTableCrc()
	    && sectorTable.crc != 0)
	  break;
      }
      
    }

    state = S_MOUNT;
    
    // continue with mount operation
    if ( addr < STM25P_SECTOR_SIZE*STM25P_NUM_SECTORS ) {
      result = post mount();
      if (!result)
	state = S_READY;
    }
    // if flash has no valid sector tables, format it
    else {
      result = formatFlash();
      if (result == FAIL)
	state = S_NEVER_USED;
    }

    return result;

  }

  command uint32_t StorageRemap.physicalAddr[volume_t volume](uint32_t volumeAddr) {
    if (baseSector[volume] == STM25P_INVALID_SECTOR)
      return STM25P_INVALID_ADDR;
    clientVolume = volume;
    return physicalAddr(volumeAddr);
  }

  command uint8_t StorageManager.getNumSectors[volume_t volume]() {
    uint8_t i = baseSector[volume];
    uint8_t tmpVolumeId = sectorTable.sector[i].volumeId;
    
    if (baseSector[volume] == STM25P_INVALID_SECTOR)
      return STM25P_INVALID_SECTOR;
    
    for ( ; i < STM25P_NUM_SECTORS && sectorTable.sector[i].volumeId == tmpVolumeId; i++ );

    return (i - baseSector[volume]);
  }

  command stm25p_addr_t StorageManager.getVolumeSize[volume_t volume]() {
    if (baseSector[volume] == STM25P_INVALID_SECTOR)
      return STM25P_INVALID_ADDR;
    return STM25P_SECTOR_SIZE * call StorageManager.getNumSectors[volume]();
  }

  result_t newRequest(uint8_t newState, volume_t volume, 
		      stm25p_addr_t addr, void* data, stm25p_addr_t len) {

    result_t result;

    if (state != S_READY)
      return FALSE;

    state = newState;
    clientVolume = volume;

    rwAddr = addr;
    rwData = data;
    rwLen = len;

    result = continueOp();

    if (result == FAIL || state == S_READ || state == S_COMPUTE_CRC)
      state = S_READY;

    return result;

  }

  command result_t SectorStorage.read[volume_t volume](stm25p_addr_t addr, void* data, stm25p_addr_t len) {
    return newRequest(S_READ, volume, addr, data, len);
  }

  command result_t SectorStorage.write[volume_t volume](stm25p_addr_t addr, void* data, stm25p_addr_t len) {
    return newRequest(S_WRITE, volume, addr, data, len);
  }

  command result_t SectorStorage.erase[volume_t volume](stm25p_addr_t addr, stm25p_addr_t len) {
    return newRequest(S_ERASE, volume, addr, NULL, 0);
  }

  command result_t SectorStorage.computeCrc[volume_t volume](uint16_t* crcResult, uint16_t crc, 
							     stm25p_addr_t addr, stm25p_addr_t len) {
    result_t result;
    crcScratch = crc;
    result = newRequest(S_COMPUTE_CRC, volume, addr, NULL, len);
    *crcResult = crcScratch;
    return result;
  }

  void pageProgramDone() {

    stm25p_addr_t lastBytes;
    
    lastBytes = calcNumBytes();
    rwAddr += lastBytes;
    rwData += lastBytes;
    rwLen -= lastBytes;
    if ( rwLen == 0 ) {
      if (state == S_MOUNT)
	actualMount();
      else
	signalDone(STORAGE_OK);
      return;
    }

    if (continueOp() == FAIL)
      signalDone(STORAGE_FAIL);

  }

  event void HALSTM25P.pageProgramDone() {
    pageProgramDone();
  }

  event void HALSTM25P.sectorEraseDone() {

    uint8_t sector = rwAddr / STM25P_SECTOR_SIZE;

    if (state != S_MOUNT)
      sector += baseSector[clientVolume];

    if ( sector == STM25P_NUM_SECTORS - 1 ||
	 sectorTable.sector[sector].volumeId != sectorTable.sector[sector+1].volumeId ) {
      stm25p_addr_t addr = STM25P_SECTOR_SIZE*(sector+1) - sizeof(SectorTable);
      if (call HALSTM25P.pageProgram(addr, &sectorTable, sizeof(SectorTable)) == FAIL)
	signalDone(STORAGE_FAIL);
    }
    else {
      pageProgramDone();
    }

  }

  event void HALSTM25P.bulkEraseDone() {}
  event void HALSTM25P.writeSRDone() {}

  default event void Mount.mountDone[volume_t volume](storage_result_t result, volume_id_t id) {}
  default event void SectorStorage.eraseDone[volume_t volume](result_t result) {}
  default event void SectorStorage.writeDone[volume_t volume](result_t result) {}

}

--- NEW FILE: StorageRemap.nc ---
// $Id: StorageRemap.nc,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:4
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes HALSTM25P;

interface StorageRemap {
  command uint32_t physicalAddr(uint32_t volumeAddr);
}

--- NEW FILE: Storage_chip.h ---
// $Id: Storage_chip.h,v 1.1 2005/07/11 23:36:09 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 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."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

#ifndef __STORAGE_CHIP_H__
#define __STORAGE_CHIP_H__

#include "HALSTM25P.h"

#endif



More information about the Tinyos-commits mailing list