[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/tos/platform/micro4/flash
FlashAccessC.nc, NONE, 1.1 HPLSTM25P40M.nc, NONE,
1.1 HALSTM25P40M.nc, NONE, 1.1 FlashAccess.nc, NONE,
1.1 FlashAccessM.nc, NONE, 1.1 HALSTM25P40.nc, NONE,
1.1 HPLSTM25P40.nc, NONE, 1.1
Marcus Chang
marcus_chang at users.sourceforge.net
Thu Mar 15 07:40:21 PDT 2007
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/tools/make
micro4.target, NONE, 1.1
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/apps/DataCollectorBase
ProtocolServerM.nc, NONE, 1.1 DataCollectorBase.nc, NONE,
1.1 ProtocolServerC.nc, NONE, 1.1 DatasetManagerM.nc, NONE,
1.1 Makefile, NONE, 1.1 DataCollectorBaseM.nc, NONE,
1.1 ProtocolControllerM.nc, NONE, 1.1 DatasetManager.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/contrib/diku/sensinode/tos/platform/micro4/flash
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv30685/sensinode/tos/platform/micro4/flash
Added Files:
FlashAccessC.nc HPLSTM25P40M.nc HALSTM25P40M.nc FlashAccess.nc
FlashAccessM.nc HALSTM25P40.nc HPLSTM25P40.nc
Log Message:
* Sensinode Micro.4 platform support
* Hoghtrob Data Collection Application
--- NEW FILE: FlashAccessC.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
configuration FlashAccessC {
provides {
interface StdControl as FlashControl;
interface FlashAccess;
}
}
implementation {
components FlashAccessM, HALSTM25P40M, HPLSTM25P40M, HPLSpiM, TimerC, BusArbitrationC, StdOutC;
FlashControl = FlashAccessM.FlashControl;
FlashAccess = FlashAccessM.FlashAccess;
FlashAccessM.Flash -> HALSTM25P40M.Flash;
HALSTM25P40M.BusArbitration -> BusArbitrationC.BusArbitration[unique("BusArbitration")];
HALSTM25P40M.Timer -> TimerC.Timer[unique("Timer")];
HALSTM25P40M.Spi -> HPLSpiM.Spi;
HALSTM25P40M.HPLFlash -> HPLSTM25P40M.HPLFlash;
HPLSTM25P40M.Spi -> HPLSpiM.Spi;
HALSTM25P40M.StdOut -> StdOutC;
HPLSTM25P40M.StdOut -> StdOutC;
}
--- NEW FILE: HPLSTM25P40M.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*These macros control flash select signal and assume correct bus state*/
#define FLASH_SELECT(x) P3OUT &= ~0x01
#define FLASH_UNSELECT(x) P3OUT |= 0x01
/*Flash control commands*/
#define M25P_WREN 0x06
#define M25P_WRDI 0x04
#define M25P_RDID 0x9F
#define M25P_RDSR 0x05
#define M25P_WRSR 0x01
#define M25P_READ 0x03
#define M25P_FAST_READ 0x0B
#define M25P_PP 0x02
#define M25P_SE 0xD8
#define M25P_BE 0xC7
#define M25P_DP 0xB9
#define M25P_RES 0xAB
/** Flash status register bits */
#define FLASH_SR_SRWD 0x80 /*!< Status register write protect */
#define FLASH_SR_BP2 0x10 /*!< Block protect bit 2*/
#define FLASH_SR_BP1 0x08 /*!< Block protect bit 1*/
#define FLASH_SR_BP0 0x04 /*!< Block protect bit 0*/
#define FLASH_SR_WEL 0x02 /*!< Write enable latch*/
#define FLASH_SR_WIP 0x01 /*!< Write in progress (busy)*/
module HPLSTM25P40M {
provides {
interface HPLSTM25P40 as HPLFlash;
}
uses {
interface StdOut;
interface Spi;
}
}
implementation {
bool flashBusy();
void flashWait();
/**********************************************************************
* Flash read
*********************************************************************/
/**
* Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
command result_t HPLFlash.read(uint32_t address, uint8_t *buffer, uint16_t length)
{
uint16_t i;
uint8_t * p = buffer;
/***********************************************
** Read flash into buffer
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_READ);
call Spi.write(address >> 16);
call Spi.write(address >> 8);
call Spi.write(address);
for (i = 0; i < length; i++)
{
*p++ = call Spi.write(0);
}
FLASH_UNSELECT();
return SUCCESS;
}
/**
* Fast Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
command result_t HPLFlash.fastRead(uint32_t address, uint8_t *buffer, uint16_t length)
{
uint16_t i;
uint8_t *p = buffer;
/***********************************************
** Fast read flash into buffer
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_FAST_READ);
call Spi.write(address >> 16);
call Spi.write(address >> 8);
call Spi.write(address);
call Spi.write(0);
for (i = 0; i< length ; i++)
{
*p++ = call Spi.write(0);
}
FLASH_UNSELECT();
return SUCCESS;
}
/**********************************************************************
* Flash write
*********************************************************************/
/**
* Write flash page. Page size is 256 bytes.
* Write address must point at start of page.
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or buffer too long
*/
command result_t HPLFlash.write(uint32_t address, uint8_t *buffer, uint16_t length)
{
uint16_t i;
uint8_t *p = buffer;
/***********************************************
** Enable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WREN);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Write buffer to page, starting at address
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_PP);
call Spi.write(address >> 16);
call Spi.write(address >> 8);
call Spi.write(address);
for (i = 0; i< length ; i++)
{
call Spi.write(*p++);
}
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Disable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WRDI);
FLASH_UNSELECT();
return SUCCESS;
}
/**********************************************************************
* Flash erase
*********************************************************************/
/**
* Flash sector erase. Sector size is 64 kilobytes.
* Address must point at start of sector.
*
* \param address block address on flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t HPLFlash.sectorErase(uint32_t address)
{
/***********************************************
** Enable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WREN);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Erase sector holding address
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_SE);
call Spi.write(address >> 16);
call Spi.write(address >> 8);
call Spi.write(address);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Disable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WRDI);
FLASH_UNSELECT();
return SUCCESS;
}
/**
* Flash bulk erase.
* Erases entire flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t HPLFlash.bulkErase()
{
/***********************************************
** Enable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WREN);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Bulk erase
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_BE);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Disable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WRDI);
FLASH_UNSELECT();
return SUCCESS;
}
/**********************************************************************
* Flash power management
*********************************************************************/
/**
* Deep Power-down.
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t HPLFlash.sleep()
{
/***********************************************
** Send command to enter deep power-down
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_DP);
FLASH_UNSELECT();
TOSH_uwait(10);
return SUCCESS;
}
/**
* Flash signature read. Wakes the device up from power down mode.
* Signature value should be 0x12 if the flash is present and working.
*
* \return signature value
* \return -1 bus not free
*/
command int16_t HPLFlash.wakeUp()
{
int16_t retval;
/***********************************************
** Read signature
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_RES);
call Spi.write(0);
call Spi.write(0);
call Spi.write(0);
retval = call Spi.write(0);
FLASH_UNSELECT();
TOSH_uwait(10);
return retval;
}
/**********************************************************************
* Flash services
*********************************************************************/
/**
* Flash identification read.
* Only available in chips with Process Technology code X
*
* \return id value
* \return -1 bus not free
*/
command int32_t HPLFlash.readIdentification()
{
int32_t retval;
/***********************************************
** Read identification
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_RDID);
retval = call Spi.write(0);
retval = (retval << 8) + call Spi.write(0);
retval = (retval << 8) + call Spi.write(0);
FLASH_UNSELECT();
return retval;
}
/**
* Flash status register read.
*
* \return status register value
* \return -1 bus not free
*/
command int16_t HPLFlash.readStatus()
{
int16_t retval;
/***********************************************
** Read status register
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_RDSR);
retval = call Spi.write(M25P_RDSR);
FLASH_UNSELECT();
return retval;
}
/**
* Flash status register write.
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t HPLFlash.writeStatus(uint8_t value)
{
/***********************************************
** Enable write mode
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WREN);
FLASH_UNSELECT();
TOSH_uwait(10);
/***********************************************
** Write status register
***********************************************/
FLASH_SELECT();
call Spi.write(M25P_WRSR);
call Spi.write(value);
FLASH_UNSELECT();
return SUCCESS;
}
/**********************************************************************
* Checks if flash is writing
*********************************************************************/
command result_t HPLFlash.isFree() {
uint8_t status;
FLASH_SELECT();
call Spi.write(M25P_RDSR);
status = call Spi.write(0);
FLASH_UNSELECT();
TOSH_uwait(10);
if (status & FLASH_SR_WIP) {
return FAIL;
} else {
return SUCCESS;
}
}
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: HALSTM25P40M.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "HPLSpi.h"
module HALSTM25P40M {
provides {
interface HALSTM25P40 as Flash;
}
uses {
interface HPLSTM25P40 as HPLFlash;
interface Timer;
interface Spi;
interface BusArbitration;
interface StdOut;
}
}
implementation {
#define QUEUE_SIZE 9
#define FLASH_BUSY_BACKOFF 200
enum
{
TASK_READ = 0x01,
TASK_FAST_READ = 0x02,
TASK_WRITE = 0x03,
TASK_SECTOR_ERASE = 0x04,
TASK_BULK_ERASE = 0x05,
TASK_SLEEP = 0x06,
TASK_WAKEUP = 0x07,
TASK_CHECK_BUSY = 0x08,
};
task void readTask();
task void fastReadTask();
task void writeTask();
task void sectorEraseTask();
task void bulkEraseTask();
task void sleepTask();
task void wakeupTask();
task void checkBusyTask();
bool taskPosted[QUEUE_SIZE];
uint8_t queue[QUEUE_SIZE];
uint8_t first, last, currentTask;
bool timerActive = FALSE, flashTaskPosted = FALSE, postCheckBusyTask = FALSE;
bool flashOn = FALSE;
/**********************************************************************
*********************************************************************/
bool queuePutBack(uint8_t id) {
if ( (queue[id] != 0) || (last == id) || (id > QUEUE_SIZE - 1) )
return FALSE;
if (first == 0) {
first = id;
last = id;
} else {
queue[last] = id;
last = id;
}
return TRUE;
}
bool queuePutFront(uint8_t id) {
if ( (queue[id] != 0) || (last == id) || (id > QUEUE_SIZE - 1) )
return FALSE;
if (first == 0) {
first = id;
last = id;
} else {
queue[id] = first;
first = id;
}
return TRUE;
}
uint8_t queueGet() {
uint8_t retval;
retval = first;
first = queue[retval];
queue[retval] = 0;
if (first == 0) {
last = 0;
}
return retval;
}
bool queueEmpty() {
if ( (first == 0) && (flashTaskPosted == FALSE) ) {
return TRUE;
} else {
return FALSE;
}
}
void postNextTask() {
uint8_t id;
id = queueGet();
switch(id) {
case TASK_READ:
flashTaskPosted = TRUE;
post readTask();
break;
case TASK_FAST_READ:
flashTaskPosted = TRUE;
post fastReadTask();
break;
case TASK_WRITE:
flashTaskPosted = TRUE;
post writeTask();
break;
case TASK_SECTOR_ERASE:
flashTaskPosted = TRUE;
post sectorEraseTask();
break;
case TASK_BULK_ERASE:
flashTaskPosted = TRUE;
post bulkEraseTask();
break;
case TASK_SLEEP:
flashTaskPosted = TRUE;
post sleepTask();
break;
case TASK_WAKEUP:
flashTaskPosted = TRUE;
post wakeupTask();
break;
default:
break;
}
return;
}
/**********************************************************************
*********************************************************************/
event result_t BusArbitration.busFree()
{
if (!timerActive && !queueEmpty() && !flashTaskPosted)
{
postNextTask();
}
else if (!timerActive && queueEmpty() && !flashTaskPosted && flashOn)
{
flashTaskPosted = TRUE;
post sleepTask();
}
else if (postCheckBusyTask == TRUE)
{
postCheckBusyTask = FALSE;
post checkBusyTask();
}
return SUCCESS;
}
/**********************************************************************
*********************************************************************/
event result_t Timer.fired()
{
post checkBusyTask();
return SUCCESS;
}
/**********************************************************************
* Flash read
*********************************************************************/
/**
* Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
uint32_t readQueueAddress;
uint8_t * readQueueBuffer;
uint16_t readQueueLength;
command result_t Flash.read(uint32_t address, uint8_t *buffer, uint16_t length)
{
if (address > 0x07FFFF) return FAIL;
if (!taskPosted[TASK_READ]) {
taskPosted[TASK_READ] = TRUE;
readQueueAddress = address;
readQueueBuffer = buffer;
readQueueLength = length;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty()) {
flashTaskPosted = TRUE;
if (flashOn)
{
post readTask();
} else
{
post wakeupTask();
queuePutBack(TASK_READ);
}
} else
queuePutBack(TASK_READ);
return SUCCESS;
} else {
return FAIL;
}
}
task void readTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_READ);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Read flash into buffer
***********************************************/
call HPLFlash.read(readQueueAddress, readQueueBuffer, readQueueLength);
signal Flash.readReady(readQueueAddress, readQueueBuffer, readQueueLength);
flashTaskPosted = FALSE;
taskPosted[TASK_READ] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**
* Fast Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
uint32_t fastReadQueueAddress;
uint8_t * fastReadQueueBuffer;
uint16_t fastReadQueueLength;
command result_t Flash.fastRead(uint32_t address, uint8_t *buffer, uint16_t length)
{
if (address > 0x07FFFF) return FAIL;
if (!taskPosted[TASK_FAST_READ]) {
taskPosted[TASK_FAST_READ] = TRUE;
fastReadQueueAddress = address;
fastReadQueueBuffer = buffer;
fastReadQueueLength = length;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty()) {
flashTaskPosted = TRUE;
if (flashOn)
{
post fastReadTask();
} else
{
post wakeupTask();
queuePutBack(TASK_FAST_READ);
}
} else
queuePutBack(TASK_FAST_READ);
return SUCCESS;
} else {
return FAIL;
}
}
task void fastReadTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_FAST_READ);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Fast read flash into buffer
***********************************************/
call HPLFlash.fastRead(fastReadQueueAddress, fastReadQueueBuffer, fastReadQueueLength);
signal Flash.fastReadReady(fastReadQueueAddress, fastReadQueueBuffer, fastReadQueueLength);
flashTaskPosted = FALSE;
taskPosted[TASK_FAST_READ] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**********************************************************************
* Flash write
*********************************************************************/
/**
* Write flash page. Page size is 256 bytes.
* Write address must point at start of page.
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or buffer too long
*/
uint32_t writeQueueAddress;
uint8_t * writeQueueBuffer;
uint16_t writeQueueLength;
command result_t Flash.write(uint32_t address, uint8_t *buffer, uint16_t length)
{
if (address > 0x07FFFF) return FAIL;
if ((length > 256) || (length == 0)) return FAIL;
if (!taskPosted[TASK_WRITE]) {
taskPosted[TASK_WRITE] = TRUE;
writeQueueAddress = address;
writeQueueBuffer = buffer;
writeQueueLength = length;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty()) {
flashTaskPosted = TRUE;
if (flashOn)
{
post writeTask();
} else
{
post wakeupTask();
queuePutBack(TASK_WRITE);
}
} else
queuePutBack(TASK_WRITE);
return SUCCESS;
} else {
return FAIL;
}
}
task void writeTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_WRITE);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Write buffer to page, starting at address
***********************************************/
call HPLFlash.write(writeQueueAddress, writeQueueBuffer, writeQueueLength);
/* set timer to post checkBusyTask (signalTask) */
call Timer.start(TIMER_ONE_SHOT, 20);
timerActive = TRUE;
currentTask = TASK_WRITE;
taskPosted[TASK_WRITE] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**********************************************************************
* Flash erase
*********************************************************************/
/**
* Flash sector erase. Sector size is 64 kilobytes.
* Address must point at start of sector.
*
* \param address block address on flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
uint32_t sectorEraseQueueAddress;
command result_t Flash.sectorErase(uint32_t address)
{
if (address > 0x07FFFF) return FAIL;
if (!taskPosted[TASK_SECTOR_ERASE]) {
taskPosted[TASK_SECTOR_ERASE] = TRUE;
sectorEraseQueueAddress = address;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty()) {
flashTaskPosted = TRUE;
if (flashOn)
{
post sectorEraseTask();
} else
{
post wakeupTask();
queuePutBack(TASK_SECTOR_ERASE);
}
} else
queuePutBack(TASK_SECTOR_ERASE);
return SUCCESS;
} else {
return FAIL;
}
}
task void sectorEraseTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_SECTOR_ERASE);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Erase sector holding address
***********************************************/
call HPLFlash.sectorErase(sectorEraseQueueAddress);
/* set timer to post checkBusyTask (signalTask) */
call Timer.start(TIMER_ONE_SHOT, 1000);
timerActive = TRUE;
currentTask = TASK_SECTOR_ERASE;
taskPosted[TASK_SECTOR_ERASE] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**
* Flash bulk erase.
* Erases entire flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t Flash.bulkErase()
{
if (!taskPosted[TASK_BULK_ERASE]) {
taskPosted[TASK_BULK_ERASE] = TRUE;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty()) {
flashTaskPosted = TRUE;
if (flashOn)
{
post bulkEraseTask();
} else
{
post wakeupTask();
queuePutBack(TASK_BULK_ERASE);
}
} else
queuePutBack(TASK_BULK_ERASE);
return SUCCESS;
} else {
return FAIL;
}
}
task void bulkEraseTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_BULK_ERASE);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Bulk erase
***********************************************/
call HPLFlash.bulkErase();
/* set timer to post checkBusyTask (signalTask) */
call Timer.start(TIMER_ONE_SHOT, 4500);
timerActive = TRUE;
currentTask = TASK_BULK_ERASE;
taskPosted[TASK_BULK_ERASE] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**********************************************************************
* Flash power management
*********************************************************************/
/**
* Deep Power-down.
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t Flash.sleep()
{
if (!taskPosted[TASK_SLEEP])
{
taskPosted[TASK_SLEEP] = TRUE;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty())
{
flashTaskPosted = TRUE;
post sleepTask();
} else {
queuePutBack(TASK_SLEEP);
}
return SUCCESS;
} else {
return FAIL;
}
}
task void sleepTask() {
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_SLEEP);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Send command to enter deep power-down
***********************************************/
call HPLFlash.sleep();
call StdOut.print("sleep\r\n");
flashOn = FALSE;
flashTaskPosted = FALSE;
taskPosted[TASK_SLEEP] = FALSE;
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**
* Flash signature read. Wakes the device up from power down mode.
* Signature value should be 0x12 if the flash is present and working.
*
* \return signature value
* \return -1 bus not free
*/
command result_t Flash.wakeUp()
{
if (!taskPosted[TASK_WAKEUP])
{
taskPosted[TASK_WAKEUP] = TRUE;
/* if the queue is empty no task has been posted and the flash is off */
if (queueEmpty())
{
flashTaskPosted = TRUE;
post wakeupTask();
} else {
queuePutBack(TASK_WAKEUP);
}
return SUCCESS;
} else {
return FAIL;
}
}
task void wakeupTask() {
int16_t retval;
if (call BusArbitration.getBus() == FAIL) {
queuePutFront(TASK_WAKEUP);
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Read signature
***********************************************/
retval = call HPLFlash.wakeUp();
call StdOut.print("wakeup: ");
call StdOut.printHex(retval);
call StdOut.print("\r\n");
/* check if wakeup was successfull */
if (retval != 0x12) {
/* flash not ready - repost wakeup task */
post wakeupTask();
} else
{
/* wakeup completed */
flashOn = TRUE;
flashTaskPosted = FALSE;
taskPosted[TASK_WAKEUP] = FALSE;
}
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
/**********************************************************************
* Checks if flash is writing
*********************************************************************/
task void checkBusyTask() {
if (call BusArbitration.getBus() == FAIL) {
postCheckBusyTask = TRUE;
return;
}
/***********************************************
** select SPI bus and module 1 (micro4)
***********************************************/
call Spi.enable(BUS_CLOCK_INVERT + BUS_CLOCK_4MHZ, 1);
/***********************************************
** Checks if flash is writing
***********************************************/
if (call HPLFlash.isFree() == SUCCESS) {
/* signal recent task */
switch(currentTask) {
case TASK_WRITE:
signal Flash.writeDone(writeQueueAddress, writeQueueBuffer, writeQueueLength);
break;
case TASK_SECTOR_ERASE:
signal Flash.sectorEraseDone(sectorEraseQueueAddress);
break;
case TASK_BULK_ERASE:
signal Flash.bulkEraseDone();
break;
default:
break;
}
currentTask = 0;
/* post - if any - next task */
flashTaskPosted = FALSE;
timerActive = FALSE;
postNextTask();
} else {
call Timer.start(TIMER_ONE_SHOT, FLASH_BUSY_BACKOFF);
}
call Spi.disable();
call BusArbitration.releaseBus();
return;
}
async event result_t StdOut.get(uint8_t data) {
return SUCCESS;
}
}
--- NEW FILE: FlashAccess.nc ---
/*
Interface for accessing flash with the page abstraction.
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
interface FlashAccess {
command uint16_t firstUsablePage();
command uint16_t lastUsablePage();
/**
* Read a page from the flash.
*
* @param page_no The page to read from.
* @param page A buffer to hold the page bring read.
* @return SUCCESS, the page could be read
*/
command result_t read(uint16_t page_no, void *page);
event void readReady(uint16_t page_no, void *page, uint16_t length);
/**
* Erase the sector holding the page in the flash.
*
* @param page_no The page inside the sector.
* @return SUCCESS, the sector was erased.
*/
command result_t erase(uint16_t page_no);
event void eraseDone(uint16_t page_no);
/**
* Erase the entire flash.
*
* @return SUCCESS, the flash was erased.
*/
command result_t eraseAll();
event void eraseAllDone();
/**
* Write a page to the flash
*
* <p>Note this function does not clear the page before the
* write. This must be done by calling erase</p>
*
* @param page_no The page to write
* @param page A buffer containing the contents to write
* @result SUCCESS, the self-programming has successfully finished.
*/
command result_t write(uint16_t page_no, void *page);
event void writeDone(uint16_t page_no, void *page);
}
--- NEW FILE: FlashAccessM.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
module FlashAccessM
{
provides {
interface StdControl as FlashControl;
interface FlashAccess;
}
uses interface HALSTM25P40 as Flash;
}
implementation
{
#define FIRST_PAGE 0x0000
#define LAST_PAGE 0x07FF
#define PAGE_SIZE 0x0100
command result_t FlashControl.init()
{
result_t r1, r2;
r1 = call Flash.wakeUp();
r2 = call Flash.sleep();
return rcombine(r1, r2);
}
command result_t FlashControl.start()
{
return call Flash.wakeUp();
}
command result_t FlashControl.stop()
{
return call Flash.sleep();
}
command uint16_t FlashAccess.firstUsablePage() {
return FIRST_PAGE;
}
command uint16_t FlashAccess.lastUsablePage() {
return LAST_PAGE;
}
/**
* Read a page from the flash.
*
* @param page_no The page to read from.
* @param page A buffer to hold the page bring read.
* @return SUCCESS, the page could be read
*/
command result_t FlashAccess.read(uint16_t page_no, void *page) {
uint32_t address;
if ( (FIRST_PAGE <= page_no) && (page_no <= LAST_PAGE) ) {
address = page_no;
address = address << 8;
return call Flash.read(address, (uint8_t *) page, PAGE_SIZE);
} else {
return FAIL;
}
}
event void Flash.readReady(uint32_t address, uint8_t *buffer, uint16_t length) {
signal FlashAccess.readReady(address >> 8, buffer, length);
return;
}
event void Flash.fastReadReady(uint32_t address, uint8_t *buffer, uint16_t length) {
return;
}
/**
* Erase the sector holding the page in the flash.
*
* @param page_no The page inside the sector.
* @return SUCCESS, the sector was erased.
*/
command result_t FlashAccess.erase(uint16_t page_no) {
uint32_t address;
if ( (FIRST_PAGE <= page_no) && (page_no <= LAST_PAGE) ) {
address = page_no;
address = address << 8;
return call Flash.sectorErase(address);
} else {
return FAIL;
}
}
event void Flash.sectorEraseDone(uint32_t address)
{
signal FlashAccess.eraseDone(address >> 8);
}
/**
* Erase the sector holding the page in the flash.
*
* @param page_no The page inside the sector.
* @return SUCCESS, the sector was erased.
*/
command result_t FlashAccess.eraseAll() {
return call Flash.bulkErase();
}
event void Flash.bulkEraseDone()
{
signal FlashAccess.eraseAllDone();
}
/**
* Write a page to the flash
*
* <p>Note this function does not clear the page before the
* write. This must be done by calling erase</p>
*
* @param page_no The page to write
* @param page A buffer containing the contents to write
* @result SUCCESS, the self-programming has successfully finished.
*/
command result_t FlashAccess.write(uint16_t page_no, void *page) {
uint32_t address;
if ( (FIRST_PAGE <= page_no) && (page_no <= LAST_PAGE) ) {
address = page_no;
address = address << 8;
return call Flash.write(address, (uint8_t *) page, PAGE_SIZE);
} else {
return FAIL;
}
}
event void Flash.writeDone(uint32_t address, uint8_t *buffer, uint16_t length)
{
signal FlashAccess.writeDone(address >> 8, buffer);
}
}
--- NEW FILE: HALSTM25P40.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
interface HALSTM25P40 {
/**
* Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
command result_t read(uint32_t address, uint8_t *buffer, uint16_t length);
event void readReady(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Fast Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or init failed
*/
command result_t fastRead(uint32_t address, uint8_t *buffer, uint16_t length);
event void fastReadReady(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Write flash page. Page size is 256 bytes.
* Write address must point at start of page.
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
* \return FAIL bus not free or buffer too long
*/
command result_t write(uint32_t address, uint8_t *buffer, uint16_t length);
event void writeDone(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Flash sector erase. Sector size is 64 kilobytes.
* Address must point at start of or within sector.
*
* \param address block address on flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t sectorErase(uint32_t address);
event void sectorEraseDone(uint32_t address);
/**
* Flash bulk erase.
* Erases entire flash
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t bulkErase();
event void bulkEraseDone();
/**
* Deep Power-down.
*
* \return SUCCESS
* \return FAIL bus not free
*/
command result_t sleep();
/**
* Flash signature read. Wakes the device up from power down mode.
* Signature value should be 0x12 if the flash is present and working.
*
* \return signature value
* \return -1 bus not free
*/
command result_t wakeUp();
}
--- NEW FILE: HPLSTM25P40.nc ---
/*
Copyright (C) 2004 Klaus S. Madsen <klaussm at diku.dk>
Copyright (C) 2006 Marcus Chang <marcus at diku.dk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
interface HPLSTM25P40 {
/**
* Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
*/
command result_t read(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Fast Read flash block.
*
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
*/
command result_t fastRead(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Write flash page. Page size is 256 bytes.
* Write address must point at start of page.
*
* \param address block address on flash
* \param buffer pointer to buffer
* \param length length of read buffer
*
* \return SUCCESS
*/
command result_t write(uint32_t address, uint8_t *buffer, uint16_t length);
/**
* Flash sector erase. Sector size is 64 kilobytes.
* Address must point at start of or within sector.
*
* \param address block address on flash
*
* \return SUCCESS
*/
command result_t sectorErase(uint32_t address);
/**
* Flash bulk erase.
* Erases entire flash
*
* \return SUCCESS
*/
command result_t bulkErase();
/**
* Deep Power-down.
*
* \return SUCCESS
*/
command result_t sleep();
/**
* Flash signature read. Wakes the device up from power down mode.
* Signature value should be 0x12 if the flash is present and working.
*
* \return signature value
*/
command int16_t wakeUp();
/**
* Flash identification read.
* Only available in chips with Process Technology code X
*
* \return id value
*/
command int32_t readIdentification();
/**
* Flash status register read.
*
* \return status register value
*/
command int16_t readStatus();
/**
* Flash status register write.
*
* \return SUCCESS
*/
command result_t writeStatus(uint8_t value);
/**
* Flash write status.
*
* \return SUCCESS
* \return FAIL write in progress
*/
command result_t isFree();
}
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/tools/make
micro4.target, NONE, 1.1
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/sensinode/apps/DataCollectorBase
ProtocolServerM.nc, NONE, 1.1 DataCollectorBase.nc, NONE,
1.1 ProtocolServerC.nc, NONE, 1.1 DatasetManagerM.nc, NONE,
1.1 Makefile, NONE, 1.1 DataCollectorBaseM.nc, NONE,
1.1 ProtocolControllerM.nc, NONE, 1.1 DatasetManager.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-contrib-commits
mailing list