[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/umass/tos/platform/mica2
FalC.nc, NONE, 1.1 FlashM.nc, NONE, 1.1 I2CMasterC.nc, NONE,
1.1 I2CPacketMasterC.nc, NONE, 1.1 I2CPacketMasterM.nc, NONE,
1.1 NANDFlashM.nc, NONE, 1.1 PageNANDC.nc, NONE,
1.1 PageNANDM.nc, NONE, 1.1 nand.h, NONE, 1.1 platform.h, NONE, 1.1
Gaurav
gmathur at users.sourceforge.net
Sat Dec 9 13:05:52 PST 2006
- Previous message: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/umass/tos/lib/Util
ConsoleC.nc, NONE, 1.1 ConsoleM.nc, NONE, 1.1
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/umass/tos/platform/telosb
FalC.nc, NONE, 1.1 FlashM.nc, NONE, 1.1 platform.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/contrib/umass/tos/platform/mica2
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv17795/tos/platform/mica2
Added Files:
FalC.nc FlashM.nc I2CMasterC.nc I2CPacketMasterC.nc
I2CPacketMasterM.nc NANDFlashM.nc PageNANDC.nc PageNANDM.nc
nand.h platform.h
Log Message:
Added contrib/umass containing Capsule -- a storage system for sensors
--- NEW FILE: FalC.nc ---
/*
* file: FalC.nc
* description: This abstracts away the flash device
*/
includes platform;
configuration FalC {
provides {
interface GenericFlash[uint8_t id];
interface StdControl;
}
#ifdef FLASH_DEBUG
uses interface Console;
#endif
}
/* Using the separate configuration file lets us #ifdef the wiring for
*the serial debug console.
*/
implementation {
#ifndef PLATFORM_MICA2_NOR
/* UMass NAND */
components PageNANDM,
NANDFlashM;
GenericFlash = NANDFlashM.GenericFlash;
NANDFlashM.PageNAND -> PageNANDM.PageNAND;
StdControl = PageNANDM.StdControl;
#else
/* Mica2 NOR */
components PageEEPROMC,
FlashM, LedsC;
GenericFlash = FlashM.GenericFlash;
FlashM.PageEEPROM -> PageEEPROMC.PageEEPROM[unique("PageEEPROM")];
StdControl = PageEEPROMC.StdControl;
FlashM.Leds -> LedsC;
#ifdef FLASH_DEBUG
Console = FlashM.Console;
#endif
#endif
}
--- NEW FILE: FlashM.nc ---
includes common_header;
//#define FLASH_DEBUG
module FlashM {
provides interface GenericFlash[uint8_t id];
uses {
interface PageEEPROM;
interface Leds;
#ifdef FLASH_DEBUG
interface Console;
#endif
}
}
implementation
{
pageptr_t Tpage;
result_t r;
uint8_t Tid;
bool busy;
/*********************************************
************** Lock / Unlock ****************
*********************************************/
result_t lock()
{
bool localBusy;
atomic
{
localBusy = busy;
busy = TRUE;
}
if (!localBusy)
{
return (SUCCESS);
}
else
{
return (FAIL);
}
}
void unlock()
{
busy = FALSE;
}
task void initDone()
{
signal GenericFlash.initDone[Tid](SUCCESS);
}
command result_t GenericFlash.init[uint8_t id]()
{
post initDone();
Tid = id;
return(SUCCESS);
}
command pageptr_t GenericFlash.numPages[uint8_t id]()
{
return(2048);
}
command result_t GenericFlash.write[uint8_t id](pageptr_t page, offsetptr_t offset,
void *data, datalen_t len)
{
if (lock() != SUCCESS)
{
#ifdef FLASH_DEBUG
call Console.string("ERROR ! Unable to acquire Flash-write lock if:");
call Console.decimal(id);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
return (FAIL);
}
#ifdef FLASH_DEBUG
call Console.string("Acquired Flash-write lock if:");
call Console.decimal(id);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
Tpage = page;
Tid = id;
if (SUCCESS != call PageEEPROM.write(page, offset, data, len))
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM write call failed\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
return (FAIL);
}
else
return (SUCCESS);
}
event result_t PageEEPROM.writeDone(result_t res)
{
if (res == SUCCESS)
{
if (SUCCESS != call PageEEPROM.flush(Tpage))
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM flush call failed\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
signal GenericFlash.writeDone[Tid](FAIL);
}
}
else
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM write call returned failure\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
signal GenericFlash.writeDone[Tid](FAIL);
}
return (SUCCESS);
}
event result_t PageEEPROM.flushDone(result_t res)
{
unlock();
signal GenericFlash.writeDone[Tid](res);
return (SUCCESS);
}
enum{FAL_ONE, FAL_TWO, READ};
uint8_t headerBuf[MAX_HEADERS_LEN];
bool state;
datalen_t Tdata_len, Tapp_len;
offsetptr_t Toffset;
void *Theader, *Tapp_buff, *Tdata_buff;
command result_t GenericFlash.falRead[uint8_t id](pageptr_t page, offsetptr_t offset,
void *header,
void *app_buff, datalen_t app_len,
void *data_buff)
{
if (lock() != SUCCESS)
{
#ifdef FLASH_DEBUG
call Console.string("ERROR ! Unable to acquire Flash-falread lock if:");
call Console.decimal(id);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
return (FAIL);
}
#ifdef FLASH_DEBUG
call Console.string("Acquired Flash-falread lock if:");
call Console.decimal(id);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
if (sizeof(headerBuf) < (sizeof(chunk_header) + app_len))
{
#ifdef FLASH_DEBUG
call Console.string("ERROR - Size of header larger than MAX_HEADERS_LEN -- redefine it\n");
TOSH_uwait(40000L);
#endif
return (FAIL);
}
state = FAL_ONE;
Theader = header; Tapp_buff = app_buff; Tdata_buff = data_buff;
Tapp_len = app_len; Tpage = page; Toffset = offset;
Tid = id;
#ifdef FLASH_DEBUG
call Console.string("Read pg:");
call Console.decimal(page);
call Console.string(" off:");
call Console.decimal(offset);
TOSH_uwait(40000L);
call Console.string(" len:");
call Console.decimal(sizeof(chunk_header) + app_len);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
if (SUCCESS != call PageEEPROM.read(page, offset, headerBuf,
sizeof(chunk_header) + app_len))
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM read call failed\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
return (FAIL);
}
else
return (SUCCESS);
}
task void readData()
{
#ifdef FLASH_DEBUG
call Console.string("Read pg:");
call Console.decimal(Tpage);
call Console.string(" off:");
call Console.decimal(Toffset + sizeof(chunk_header) + Tapp_len);
TOSH_uwait(40000L);
call Console.string(" len:");
call Console.decimal(Tdata_len);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
/* Check if data is larger than page size */
if (PAGE_SIZE < Tdata_len)
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("ERROR - Data larger than page size - ");
call Console.decimal(Tdata_len);
call Console.string(" > ");
call Console.decimal(PAGE_SIZE);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
signal GenericFlash.falReadDone[Tid](FAIL);
return;
}
if (SUCCESS != call PageEEPROM.read(Tpage, Toffset + sizeof(chunk_header) + Tapp_len,
Tdata_buff, Tdata_len))
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM read call 2 failed\n");
TOSH_uwait(40000L);
#endif
call Leds.redOn();
signal GenericFlash.falReadDone[Tid](FAIL);
}
else
state = FAL_TWO;
}
event result_t PageEEPROM.readDone(result_t res)
{
if (state == FAL_ONE)
{
if (res == SUCCESS)
{
chunk_header *h = (chunk_header *) Theader;
memcpy(Theader, headerBuf, sizeof(chunk_header));
if(Tapp_len > 0)
{
#ifdef FLASH_DEBUG
call Console.string("Obj hdr len:");
call Console.decimal(Tapp_len);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
memcpy(Tapp_buff, &headerBuf[sizeof(chunk_header)], Tapp_len);
}
#ifdef FLASH_DEBUG
call Console.string("Chunk len:");
call Console.decimal(h->data_len);
call Console.string(" if:");
call Console.decimal(Tid);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
/* Now retrieve the chunk data */
Tdata_len = h->data_len - Tapp_len;
#ifdef FLASH_DEBUG
call Console.string("Data len to read:");
call Console.decimal(Tdata_len);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
if (Tdata_len > 0)
post readData();
else if (Tdata_len == 0)
signal GenericFlash.falReadDone[Tid](SUCCESS);
else if (Tdata_len < 0)
signal GenericFlash.falReadDone[Tid](FAIL);
}
else
{
unlock();
#ifdef FLASH_DEBUG
call Console.string("PageEEPROM read call returned failure\n");
TOSH_uwait(40000L);
#endif
signal GenericFlash.falReadDone[Tid](FAIL);
}
}
else if (state == FAL_TWO)
{
/* Just finished reading the data also */
unlock();
signal GenericFlash.falReadDone[Tid](res);
}
else if (state == READ)
{
/* Just finished reading the data also */
unlock();
signal GenericFlash.readDone[Tid](res);
}
return (SUCCESS);
}
command result_t GenericFlash.read[uint8_t id](pageptr_t page, offsetptr_t offset,
void *app_buff, datalen_t app_len)
{
if (lock() != SUCCESS)
{
#ifdef FLASH_DEBUG
call Console.string("ERROR ! Unable to acquire Flash-read lock\n");
TOSH_uwait(40000L);
#endif
return (FAIL);
}
#ifdef FLASH_DEBUG
call Console.string("Acquired Flash-read lock\n");
TOSH_uwait(40000L);
#endif
state = READ;
Tid = id;
#ifdef FLASH_DEBUG
call Console.string("Read pg:");
call Console.decimal(page);
call Console.string(" off:");
call Console.decimal(offset);
TOSH_uwait(40000L);
call Console.string(" hdr len:");
call Console.decimal(app_len);
call Console.string("\n");
TOSH_uwait(40000L);
#endif
return(call PageEEPROM.read(page, offset, app_buff, app_len));
}
command result_t GenericFlash.erase[uint8_t id](pageptr_t page)
{
if (lock() != SUCCESS)
{
#ifdef FLASH_DEBUG
call Console.string("ERROR ! Unable to acquire Flash-erase lock\n");
TOSH_uwait(20000);
#endif
return (FAIL);
}
#ifdef FLASH_DEBUG
//call Console.string("Acquired Flash-erase lock\n");
//TOSH_uwait(20000L);
#endif
#ifdef FLASH_DEBUG
call Console.string("Erase pg:");
call Console.decimal(page);
call Console.string("\n");
TOSH_uwait(20000L);
#endif
Tid = id;
return(call PageEEPROM.erase(page, TOS_EEPROM_ERASE));
}
event result_t PageEEPROM.eraseDone(result_t res)
{
unlock();
signal GenericFlash.eraseDone[Tid](res);
return (SUCCESS);
}
event result_t PageEEPROM.syncDone(result_t result)
{
return (SUCCESS);
}
event result_t PageEEPROM.computeCrcDone(result_t result, uint16_t crc)
{
return (SUCCESS);
}
default event result_t GenericFlash.initDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.writeDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.readDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.eraseDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.falReadDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
#ifdef FLASH_DEBUG
event void Console.input(char *s)
{}
#endif
}
--- NEW FILE: I2CMasterC.nc ---
/*
*
* "Copyright (c) 2000-2002 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."
*
*/
/*
*
* Authors: Phil Buonadonna, Joe Polastre, Rob Szewczyk
* Date last modified: 12/19/02
* Modified on 05/12/05 by Ning Xu, for cyclops I2C master
*/
/* Uncomment line below to enable Hardware based I2C on the mica128 */
#define HARDWARE_I2C
configuration I2CMasterC
{
provides {
interface StdControl;
interface I2CMaster;
}
}
implementation {
#ifdef HARDWARE_I2C
components HPLI2CMasterM,LedsC, HPLPowerManagementM;
StdControl = HPLI2CMasterM;
I2CMaster = HPLI2CMasterM;
HPLI2CMasterM.Leds -> LedsC.Leds;
HPLI2CMasterM.PowerManagement -> HPLPowerManagementM;
#else
components I2CMasterSoft as I2CM;
StdControl = I2CM;
I2CMaster = I2CM;
#endif
}
--- NEW FILE: I2CPacketMasterC.nc ---
/* tab:4
*
*
* "Copyright (c) 2000-2002 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."
*
*/
/* tab:4
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
* downloading, copying, installing or using the software you agree to
* this license. If you do not agree to this license, do not download,
* install, copy or use the software.
*
* Intel Open Source License
*
* Copyright (c) 2002 Intel Corporation
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
/*
*
* Authors: Joe Polastre
* Date last modified: 7/18/02
*
*/
/**
* Provides the ability to write or read a series of bytes to/from the
* I2C bus. For more information, look at the I2CPacket.ti interface
**/
configuration I2CPacketMasterC
{
provides {
interface StdControl;
interface I2CPacketMaster[uint8_t id];
}
}
implementation {
components I2CMasterC,I2CPacketMasterM,LedsC;
StdControl = I2CPacketMasterM;
I2CPacketMaster = I2CPacketMasterM;
I2CPacketMasterM.I2CMaster -> I2CMasterC;
I2CPacketMasterM.I2CStdControl -> I2CMasterC.StdControl;
I2CPacketMasterM.Leds -> LedsC;
}
--- NEW FILE: I2CPacketMasterM.nc ---
//Authors: Mohammad Rahimi mhr at cens.ucla.edu
module I2CPacketMasterM
{
provides {
interface StdControl;
interface I2CPacketMaster[uint8_t id];
}
uses {
interface I2CMaster;
interface StdControl as I2CStdControl;
interface Leds;
}
}
implementation
{
/* state of the i2c request */
enum {IDLE=45,
I2C_START_COMMAND=35,
I2C_WRITE_ADDRESS=33,
I2C_WRITE_DATA=22,
I2C_WRITE_DONE=31,
I2C_READ_ADDRESS=56,
I2C_READ_DATA=41,
I2C_READ_DONE=44,
I2C_STOP_COMMAND=27};
//Note: The only variable to be protected is state most notably at two places that the component
//can be entered at write and read
norace char* data; //bytes to write to the i2c bus
norace char length; //length in bytes of the request
norace char index; //current index of read/write byte
norace char state; //current state of the i2c request
norace char address; //destination address
//**************************************************************
//*****************Initialization and Termination***************
//**************************************************************
command result_t StdControl.init()
{
call I2CStdControl.init();
atomic {state = IDLE;}
index = 0;
return SUCCESS;
}
command result_t StdControl.start()
{
call I2CStdControl.start();
return SUCCESS;
}
command result_t StdControl.stop() {
return SUCCESS;
}
//**************************************************************
//***************Starting the Read/Write transaction************
//**************************************************************
command result_t I2CPacketMaster.writePacket[uint8_t id](char in_length,char* in_data)
{
uint8_t status;
atomic
{
status = FALSE;
if (state == IDLE) status = TRUE;
}
if(status == FALSE ) return FAIL;
address = id;
data = in_data;
index = 0;
length = in_length;
state = I2C_WRITE_ADDRESS;
call I2CMaster.sendStart();
return SUCCESS;
}
command result_t I2CPacketMaster.readPacket[uint8_t id](char in_length, char* in_data) {
uint8_t status;
atomic {
status = FALSE;
if (state == IDLE) status = TRUE;
}
if(status == FALSE ) return FAIL;
address = id;
data = in_data;
index = 0;
length = in_length;
state = I2C_READ_ADDRESS;
call I2CMaster.sendStart();
return SUCCESS;
}
// the start symbol was sent
async event result_t I2CMaster.sendStartDone()
{
if(state == I2C_WRITE_ADDRESS)
{
state = I2C_WRITE_DATA;
call I2CMaster.write((address << 1) + 0);
}
else if (state == I2C_READ_ADDRESS)
{
state = I2C_READ_DATA;
call I2CMaster.write((address << 1) + 1);
}
return SUCCESS;
}
// the stop symbol was sent, note that it is return in a task so we can very well return to upper layer
async event result_t I2CMaster.sendEndDone() {
if (state == I2C_WRITE_DONE) { //successfull write
state = IDLE;
signal I2CPacketMaster.writePacketDone[address](SUCCESS);
}
else if (state == I2C_READ_DONE) { //successfull read
state = IDLE;
signal I2CPacketMaster.readPacketDone[address](length,data);
}
return SUCCESS;
}
//write fail task.
task void write_fail()
{
signal I2CPacketMaster.writePacketDone[address](FAIL);
atomic {state = IDLE;}
}
//notification of a byte successfully written to the bus following by write or read continuation or ending
async event result_t I2CMaster.writeDone(bool result) {
if(result == FAIL) {
post write_fail(); //we can not return in the context of interrupt
return FAIL;
}
switch(state)
{
case I2C_WRITE_DATA:
index++;
if (index == length) state = I2C_STOP_COMMAND;
return call I2CMaster.write(data[index-1]);
break;
case I2C_STOP_COMMAND:
state = I2C_WRITE_DONE;
return call I2CMaster.sendEnd();
break;
case I2C_READ_DATA:
index++;
if (index == length) return call I2CMaster.read(0);
else if (index < length) return call I2CMaster.read(1);
break;
default:
return FAIL;
}
return SUCCESS;
}
//notification of a byte successfully read from the bus following by more read continuation or ending
async event result_t I2CMaster.readDone(char in_data) {
data[index-1] = in_data;
index++;
if (index == length)
call I2CMaster.read(0);
else if (index < length)
call I2CMaster.read(1);
else if (index > length)
{
state = I2C_READ_DONE;
call I2CMaster.sendEnd();
}
return SUCCESS;
}
default event result_t I2CPacketMaster.readPacketDone[uint8_t id](char in_length, char* in_data)
{
return SUCCESS;
}
default event result_t I2CPacketMaster.writePacketDone[uint8_t id](bool result)
{
return SUCCESS;
}
}
--- NEW FILE: NANDFlashM.nc ---
/*
* file: FalC.nc
* description: This abstracts away the flash device
*/
includes common_header;
module NANDFlashM {
provides interface GenericFlash[uint8_t id];
uses {
interface PageNAND;
}
}
implementation
{
pageptr_t Tpage;
uint8_t Tid;
uint8_t init = 0;
task void initPageNAND()
{
call PageNAND.init();
}
task void initDone()
{
signal GenericFlash.initDone[Tid](SUCCESS);
}
command result_t GenericFlash.init[uint8_t id]()
{
Tid = id;
atomic{
if( init == 0 )
{
init++;
post initPageNAND();
}
else
post initDone();
}
return SUCCESS;
}
event result_t PageNAND.initDone(result_t r)
{
signal GenericFlash.initDone[Tid](r);
return(SUCCESS);
}
command pageptr_t GenericFlash.numPages[uint8_t id]()
{
return(call PageNAND.numPages());
}
command result_t GenericFlash.write[uint8_t id](pageptr_t page,
offsetptr_t offset,
void *data,
datalen_t len)
{
Tpage = page;
Tid = id;
return(call PageNAND.write(page, offset, data, len));
}
event result_t PageNAND.writeDone(result_t r)
{
signal GenericFlash.writeDone[Tid](r);
return(SUCCESS);
}
command result_t GenericFlash.falRead[uint8_t id](pageptr_t page,
offsetptr_t offset,
void *header,
void *app_buff,
datalen_t app_len,
void *data_buff)
{
Tid = id;
Tpage = page;
return(call PageNAND.falRead(page,
offset,
header,
app_buff,
app_len,
data_buff));
}
event result_t PageNAND.falReadDone(result_t r)
{
signal GenericFlash.falReadDone[Tid](r);
return(SUCCESS);
}
command result_t GenericFlash.read[uint8_t id](pageptr_t page,
offsetptr_t offset,
void *app_buff,
datalen_t app_len)
{
Tid = id;
Tpage = page;
return(call PageNAND.read(page, offset, app_buff, app_len));
}
event result_t PageNAND.readDone(result_t r)
{
signal GenericFlash.readDone[Tid](r);
return(SUCCESS);
}
command result_t GenericFlash.erase[uint8_t id](pageptr_t page)
{
Tid = id;
Tpage = page;
return(call PageNAND.erase(page));
}
event result_t PageNAND.eraseDone(result_t result)
{
signal GenericFlash.eraseDone[Tid](result);
return(SUCCESS);
}
default event result_t GenericFlash.initDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.writeDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.readDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.eraseDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
default event result_t GenericFlash.falReadDone[uint8_t id](result_t result)
{
return (SUCCESS);
}
}
--- NEW FILE: PageNANDC.nc ---
/*
* file: PageNANDC.nc
* description: Component for NAND Flash driver
*/
configuration PageNANDC {
provides {
interface StdControl;
interface PageNAND;
}
}
/* Using the separate configuration file lets us #ifdef the wiring for
*the serial debug console.
*/
implementation {
components PageNANDM;
#ifdef DEBUG_NAND
components ConsoleC;
#endif
StdControl = PageNANDM;
PageNAND = PageNANDM;
#ifdef DEBUG_NAND
PageNANDM.Console -> ConsoleC;
#endif
}
--- NEW FILE: PageNANDM.nc ---
/*
* file: PageNANDM.nc
* description:
*/
includes nand;
includes PageNAND;
//#define FAL_DEBUG
module PageNANDM {
provides {
interface StdControl;
interface PageNAND;
}
//#ifdef DEBUG_NAND
uses {
interface Console;
}
//#endif
}
implementation
{
result_t res;
#define NO_ADDR 0, NULL
#define NO_DATA 0, NULL
#define NAND_WE_PORT PORTD
#define NAND_WE_BIT 0
#define NAND_RE_PORT PORTD
#define NAND_RE_BIT 1
#define MAX_ADDR 5
int addr_len = 5;
int small_page = 1;
uint16_t num_pages = 32766;
/* translate page/offset into address for read/write command
*/
int data_addr(nandpage_t page, nandoffset_t offset, uint8_t *buf) {
*buf++ = offset; offset = offset >> 8;
if (!small_page)
*buf++ = offset;
*buf++ = page; page = page >> 8;
*buf++ = page; page = page >> 8;
*buf++ = page;
return addr_len;
}
/* translate page/offset into address for erase command
*/
int erase_addr(nandpage_t page, uint8_t *buf) {
*buf++ = page; page = page >> 8;
*buf++ = page; page = page >> 8;
*buf++ = page; page = page >> 8;
return small_page ? addr_len-1 : addr_len-2;
}
/* the all-purpose function to send a command to the flash and get
* any results.
*/
result_t SendRcv(uint8_t cmd, int naddr, uint8_t *addr,
int nout, uint8_t *out, int nin, uint8_t *in) {
atomic {
int i;
register uint8_t we_hi, we_lo, re_hi, re_lo;
TOSH_SET_NAND_WE_PIN();
TOSH_SET_NAND_RE_PIN();
TOSH_CLR_NAND_CE_PIN(); /* start the transaction */
TOSH_SET_NAND_CLE_PIN(); /* send the command */
MAKE_PWBUS_OUTPUT();
WRITE_PWBUS(cmd);
TOSH_CLR_NAND_WE_PIN();
TOSH_SET_NAND_WE_PIN();
#ifdef DEBUG_NAND
call Console.printf1("cmd: %x2\n", cmd);
#endif
TOSH_CLR_NAND_CLE_PIN();
if (naddr > 0)
TOSH_SET_NAND_ALE_PIN();
for (i = 0; i < naddr; i++) { /* send the address */
WRITE_PWBUS(addr[i]);
TOSH_CLR_NAND_WE_PIN();
TOSH_SET_NAND_WE_PIN();
}
TOSH_CLR_NAND_ALE_PIN(); /* redundant clear OK if n=0 */
#ifdef DEBUG_NAND
if (naddr) {
call Console.printf1("addr: ", 0);
for (i = 0; i < naddr; i++)
call Console.printf1("%x2", addr[i]);
call Console.newline();
}
#endif
we_hi = inp(NAND_WE_PORT) | (1 << NAND_WE_BIT);
we_lo = we_hi & ~(1 << NAND_WE_BIT);
for (i = 0; i < nout; i++) { /* send any data */
WRITE_PWBUS(out[i]);
//outp(we_lo, NAND_WE_PORT);
TOSH_CLR_NAND_WE_PIN();
//outp(we_hi, NAND_WE_PORT);
TOSH_SET_NAND_WE_PIN();
}
#ifdef DEBUG_NAND
if (nout) {
call Console.printf1("%d bytes data:", nout);
for (i = 0; i < nout && i < 16; i++)
call Console.printf1(" %x2", out[i]);
call Console.newline();
}
#endif
TOSH_SET_NAND_RY_PIN(); /* set pullup */
asm __volatile__ ("nop");
asm __volatile__ ("nop");
while (!TOSH_READ_NAND_RY_PIN()) /* wait for READY */
;
TOSH_CLR_NAND_RY_PIN();
re_hi = inp(NAND_RE_PORT) | (1 << NAND_RE_BIT);
re_lo = re_hi & ~(1 << NAND_RE_BIT);
MAKE_PWBUS_INPUT();
WRITE_PWBUS(0); /* no pullups */
TOSH_CLR_NAND_RE_PIN();
asm __volatile__ ("nop");
for (i = 0; i < nin; i++) {
TOSH_SET_NAND_RE_PIN();
asm __volatile__ ("nop");
asm __volatile__ ("nop");
outp(re_hi, NAND_RE_PORT);
in[i] = READ_PWBUS();
TOSH_CLR_NAND_RE_PIN();
outp(re_lo, NAND_RE_PORT);
asm __volatile__ ("nop");
}
TOSH_SET_NAND_RE_PIN();
#ifdef DEBUG_NAND
if (nin) {
call Console.printf1("%d bytes in:", nin);
for (i = 0; i < nin && i < 16; i++)
call Console.printf1(" %x2", in[i]);
call Console.newline();
}
#endif
TOSH_SET_NAND_CE_PIN(); /* finish the transaction */
}
return SUCCESS;
}
/********** Hacked for FAL **************/
/* the all-purpose function to send a command to the flash and get
* any results.
*/
result_t FalReadSendRcv(uint8_t cmd, int naddr, uint8_t *addr,
uint8_t *in1, int nin2, uint8_t *in2, uint8_t *in3) {
bool read_abort = FALSE;
atomic {
int i;
register uint8_t we_hi, we_lo, re_hi, re_lo;
int count = 0;
uint8_t byte;
uint16_t *dlen = NULL, tempval;
#ifdef FAL_DEBUG
uint8_t temp[20];
#endif
TOSH_SET_NAND_WE_PIN();
TOSH_SET_NAND_RE_PIN();
TOSH_CLR_NAND_CE_PIN(); /* start the transaction */
TOSH_SET_NAND_CLE_PIN(); /* send the command */
MAKE_PWBUS_OUTPUT();
WRITE_PWBUS(cmd);
TOSH_CLR_NAND_WE_PIN();
TOSH_SET_NAND_WE_PIN();
#ifdef DEBUG_NAND
call Console.printf1("cmd: %x2\n", cmd);
#endif
TOSH_CLR_NAND_CLE_PIN();
if (naddr > 0)
TOSH_SET_NAND_ALE_PIN();
for (i = 0; i < naddr; i++) { /* send the address */
WRITE_PWBUS(addr[i]);
TOSH_CLR_NAND_WE_PIN();
TOSH_SET_NAND_WE_PIN();
}
TOSH_CLR_NAND_ALE_PIN(); /* redundant clear OK if n=0 */
#ifdef DEBUG_NAND
if (naddr) {
call Console.printf1("addr: ", 0);
for (i = 0; i < naddr; i++)
call Console.printf1("%x2", addr[i]);
call Console.newline();
}
#endif
we_hi = inp(NAND_WE_PORT) | (1 << NAND_WE_BIT);
we_lo = we_hi & ~(1 << NAND_WE_BIT);
#ifdef DEBUG_NAND
if (nout) {
call Console.printf1("%d bytes data:", nout);
for (i = 0; i < nout && i < 16; i++)
call Console.printf1(" %x2", out[i]);
call Console.newline();
}
#endif
TOSH_SET_NAND_RY_PIN(); /* set pullup */
asm __volatile__ ("nop");
asm __volatile__ ("nop");
while (!TOSH_READ_NAND_RY_PIN()) /* wait for READY */
;
TOSH_CLR_NAND_RY_PIN();
re_hi = inp(NAND_RE_PORT) | (1 << NAND_RE_BIT);
re_lo = re_hi & ~(1 << NAND_RE_BIT);
MAKE_PWBUS_INPUT();
WRITE_PWBUS(0); /* no pullups */
TOSH_CLR_NAND_RE_PIN();
asm __volatile__ ("nop");
/** FAL hack start **/
asm __volatile__ ("nop");
asm __volatile__ ("nop");
while (1) {
outp(re_hi, NAND_RE_PORT);
byte = READ_PWBUS();
#ifdef FAL_DEBUG
temp[count] = byte;
#endif
tempval = nin2 + 3;
outp(re_lo, NAND_RE_PORT);
//asm __volatile__ ("nop");
/* Shove into the right buffer */
if(count < 3)
{
/* Part of FAL header */
in1[count]=byte;
/* Have read the FAL header completely ->
Perform header sanity check */
if(count == 2)
{
dlen = (uint16_t *) in1;
if (*dlen > (TOS_NAND_PAGE_SIZE-3))
{
/* Dunno what im reading */
read_abort = TRUE;
break;
}
}
}
else if ( (count >= 3) && (count < tempval) )
{
/* Part of App header */
in2[count-3]=byte;
/* Check for end */
if (count == (tempval - 1))
{
if( (count == (3 + *dlen -1)) || (in3 == NULL) )
/* This is the last byte || We dont want data */
break;
}
}
else if ( (count >= tempval) && (count < (3 + *dlen)) )
{
/* Part of Data */
in3[count-tempval]=byte;
/* Check for end */
if(count == (3 + *dlen -1))
/* This is the last byte */
break;
}
count++;
}
TOSH_SET_NAND_RE_PIN();
/** FAL hack end **/
#ifdef FAL_DEBUG
{
call Console.string("Data read:");
for (i = 0; i <= count; i++)
{
call Console.decimal(temp[i]);
call Console.string(" ");
TOSH_uwait(1000);
}
call Console.newline();
}
#endif
TOSH_SET_NAND_CE_PIN(); /* finish the transaction */
}
if (read_abort == TRUE)
return (FAIL);
else
return SUCCESS;
}
result_t InitPort() {
TOSH_MAKE_NAND_WP_OUTPUT(); /* assert !WP */
TOSH_SET_NAND_WP_PIN();
TOSH_MAKE_NAND_CE_OUTPUT(); /* set up other pins */
TOSH_SET_NAND_CE_PIN();
TOSH_MAKE_NAND_CLE_OUTPUT();
TOSH_CLR_NAND_CLE_PIN();
TOSH_MAKE_NAND_ALE_OUTPUT();
TOSH_CLR_NAND_ALE_PIN();
TOSH_MAKE_NAND_WE_OUTPUT();
TOSH_SET_NAND_WE_PIN();
TOSH_MAKE_NAND_RE_OUTPUT();
TOSH_SET_NAND_RE_PIN();
TOSH_MAKE_NAND_RY_INPUT();
TOSH_CLR_NAND_RY_PIN(); /* no active pullup */
MAKE_PWBUS_INPUT();
cbi(EIMSK, 4); /* disable RY/BY input */
EICRB |= 0x03; /* make it rising-edge */
return SUCCESS;
}
result_t ResetNAND() {
return SendRcv(NAND_RESET, NO_ADDR, NO_DATA, NO_DATA);
}
command result_t StdControl.init() {
return InitPort();
}
command result_t StdControl.start() {
return SUCCESS;
}
command result_t StdControl.stop() {
return SUCCESS;
}
command nandpage_t PageNAND.numPages() {
return num_pages;
}
task void initRespond() {
signal PageNAND.initDone(SUCCESS);
}
command result_t PageNAND.init() {
ResetNAND();
post initRespond();
return SUCCESS;
}
default event result_t PageNAND.initDone(result_t r) {
return FAIL;
}
/* For small-page flash, the address only gives us 8 bits to
* indicate a beginning offset ranging from 0 to 527, so for both
* reads and writes we have to use an additional command to set
* the internal pointer if the start offset * is >= 256.
*/
uint8_t write_status;
task void WriteRespond() {
signal PageNAND.writeDone(res);
}
command result_t PageNAND.write(nandpage_t page, nandoffset_t offset,
void *data, nandoffset_t len) {
uint8_t xaddr[MAX_ADDR], alen = data_addr(page, offset, xaddr);
uint8_t cmd;
result_t result = FAIL;
/*if (offset + len > 0x210)
return FAIL;*/
post WriteRespond();
if (small_page) {
if (offset > 0x1ff)
cmd = NAND_READ_3;
else if (offset > 0xff)
cmd = NAND_READ_2;
else
cmd = NAND_READ_1;
SendRcv(cmd, NO_ADDR, NO_DATA, NO_DATA);
}
write_status = 0;
/* now send the data and program it.
*/
if (SendRcv(NAND_DATA_IN, alen, xaddr, len, data, NO_DATA) &&
SendRcv(NAND_PROGRAM, NO_ADDR, NO_DATA, NO_DATA) &&
SendRcv(NAND_STATUS, NO_ADDR, NO_DATA, 1, &write_status))
result = ((write_status & 0xC1) == 0xC0) ? SUCCESS : FAIL;
#ifdef DEBUG_NAND
call Console.printf1("status=%x2\n", write_status);
#endif
res = result;
return result;
}
task void ReadRespond() {
signal PageNAND.readDone(res);
}
task void FalReadRespond() {
signal PageNAND.falReadDone(res);
}
command result_t PageNAND.read(nandpage_t page, nandoffset_t offset,
void *data, nandoffset_t len) {
uint8_t xaddr[MAX_ADDR], alen = data_addr(page, offset, xaddr);
uint8_t cmd;
post ReadRespond();
if (small_page) {
if (offset > 0x1ff)
cmd = NAND_READ_3;
else if (offset > 0xff)
cmd = NAND_READ_2;
else
cmd = NAND_READ_1;
res = SendRcv(cmd, alen, xaddr, NO_DATA, len, data);
return (res);
}
else {
SendRcv(NAND_READ_1, alen, xaddr, NO_DATA, NO_DATA);
res = SendRcv(0x30, NO_ADDR, NO_DATA, len, data);
return (res);
}
}
command result_t PageNAND.falRead(nandpage_t page, nandoffset_t offset,
void *data1, // this buffer is a constant 3 bytes (FAL header)
void *data2, nandoffset_t len2,
void *data3)
{
uint8_t xaddr[MAX_ADDR], alen = data_addr(page, offset, xaddr);
uint8_t cmd;
if ((len2 > 0) && (data2 == NULL))
return(FAIL);
if (small_page) {
if (offset > 0x1ff)
cmd = NAND_READ_3;
else if (offset > 0xff)
cmd = NAND_READ_2;
else
cmd = NAND_READ_1;
res = FalReadSendRcv(cmd, alen, xaddr, data1, len2, data2, data3);
}
else {
SendRcv(NAND_READ_1, alen, xaddr, NO_DATA, NO_DATA);
res = FalReadSendRcv(0x30, 0, NULL, data1, len2, data2, data3);
}
post FalReadRespond();
return (res);
}
command result_t PageNAND.id(uint8_t *id) {
uint8_t addr = 0, len = small_page ? 2 : 4;
return SendRcv(NAND_ID_READ, 1, &addr, NO_DATA, len, id);
}
task void EraseRespond() {
signal PageNAND.eraseDone(SUCCESS);
}
command result_t PageNAND.erase(nandpage_t page) {
uint8_t xaddr[MAX_ADDR], len = erase_addr(page, xaddr);
SendRcv(NAND_ERASE, len, xaddr, NO_DATA, NO_DATA);
SendRcv(NAND_ERASE_CONFIRM, NO_ADDR, NO_DATA, NO_DATA);
post EraseRespond();
return SUCCESS;
}
default event result_t PageNAND.eraseDone(result_t r) {
return FAIL;
}
/* TODO: do something here
*/
command result_t PageNAND.generateECC(void *data, nandoffset_t len,
uint8_t *ecc) {
return SUCCESS;
}
command result_t PageNAND.checkECC(void *data, nandoffset_t len,
uint8_t *ecc) {
return SUCCESS;
}
//#ifdef DEBUG_NAND
event void Console.input(char *s) {}
//#endif
}
--- NEW FILE: nand.h ---
/*
* file: nand.h
* description: pin assignments for NAND flash board.
* wired: /CE -- ADC6 CLE -- ADC0
* ALE -- ADC1 /WE -- ADC2 /WP -- ADC3
* /RE -- ADC5 RY/BY -- INT1
*/
#define OLD_NAND
TOSH_ASSIGN_PIN(NAND_CE, F, 6);
TOSH_ASSIGN_PIN(NAND_CLE, F, 0);
TOSH_ASSIGN_PIN(NAND_ALE, F, 1);
#ifdef OLD_NAND
//old board pin assignments
TOSH_ASSIGN_PIN(NAND_WE, D, 0);
TOSH_ASSIGN_PIN(NAND_RE, D, 1);
TOSH_ASSIGN_PIN(NAND_RY, E, 5);
#endif
#ifdef NEW_NAND_WIRE
//new board with modified assignments
TOSH_ASSIGN_PIN(NAND_WE, F, 2);
TOSH_ASSIGN_PIN(NAND_RE, F, 5);
TOSH_ASSIGN_PIN(NAND_RY, B, 6);
#endif
#ifdef NEW_NAND
//new board without modifications
TOSH_ASSIGN_PIN(NAND_WE, F, 2);
TOSH_ASSIGN_PIN(NAND_RE, F, 5);
TOSH_ASSIGN_PIN(NAND_RY, D, 1);
#endif
TOSH_ASSIGN_PIN(NAND_WP, F, 3);
static inline void MAKE_PWBUS_OUTPUT() { outp(0xff, DDRC); }
static inline void MAKE_PWBUS_INPUT() { outp(0, DDRC); }
static inline uint8_t READ_PWBUS() { return inp(PINC); }
static inline void WRITE_PWBUS(uint8_t val) { outp(val, PORTC); }
enum {
NAND_DATA_IN = 0x80,
NAND_PROGRAM = 0x10,
NAND_READ_1 = 0x00,
NAND_READ_2 = 0x01,
NAND_READ_3 = 0x50,
NAND_RESET = 0xFF,
NAND_ERASE = 0x60,
NAND_ERASE_CONFIRM = 0xD0,
NAND_STATUS = 0x70,
NAND_ID_READ = 0x90
};
--- NEW FILE: platform.h ---
/*
* file: platform.h
* description: A platform-specific file
*/
/*
* Common declarations
*/
#ifndef PLATFORM_H
#define PLATFORM_H
#define PLATFORM_MICA2_NOR
#ifndef PLATFORM_MICA2_NOR
/************ NAND board ***************/
#define PLATFORM_MICA2_NAND
/*
* NOTE : These need to be set according to flash and user configuration
*/
typedef uint16_t pageptr_t;
typedef unsigned int offsetptr_t;
typedef uint16_t datalen_t;
/* The size of each page on the NAND flash */
#define PAGE_SIZE 512
/* The size of each page on the NAND flash */
#define ERASE_BLOCK_SIZE 32
/* XXX --------------- SET THE FOLLOWING BEFORE OPERATION ----------------- XXX
* The following both should be calculated based on the size of a page
* NAND_BUFFER_SIZE = NAND_PAGE_SIZE (set in common_header.h) / number of
* times write is possible to a page
*/
#define BUFFER_SIZE 512
#else
/************ Mica2 NOR ***************/
/*
* * NOTE : These need to be set according to flash and user configuration
* */
typedef uint16_t pageptr_t;
typedef uint16_t offsetptr_t;
typedef uint16_t datalen_t;
/* The size of each page on the flash */
#define PAGE_SIZE 256
#define ERASE_BLOCK_SIZE 1
/* XXX --------------- SET THE FOLLOWING BEFORE OPERATION ----------------- XXX
* * The following both should be calculated based on the size of a page
* * NAND_BUFFER_SIZE = NAND_PAGE_SIZE (set in common_header.h) / number of
* * times write is possible to a page
* */
#define BUFFER_SIZE 256
#endif
/*
* The allocated root directory area in units of erase blocks
* 1 erase block = NAND_ERASE_BLOCK_SIZE pages
*/
#define ROOT_DIRECTORY_AREA 2
#define DELUGE_AREA 2
#endif
- Previous message: [Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/umass/tos/lib/Util
ConsoleC.nc, NONE, 1.1 ConsoleM.nc, NONE, 1.1
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/umass/tos/platform/telosb
FalC.nc, NONE, 1.1 FlashM.nc, NONE, 1.1 platform.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-contrib-commits
mailing list