stm25psectorp.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 293 行
NC
293 行
/*
* Copyright (c) 2005-2006 Arch Rock 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 Arch Rock 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
* ARCHED ROCK 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
*/
/**
* @author Jonathan Hui <jhui@archrock.com>
* @version $Revision: 1.5 $ $Date: 2007/12/22 08:11:51 $
*/
#include <Stm25p.h>
#include <StorageVolumes.h>
module Stm25pSectorP {
provides interface SplitControl;
provides interface Resource as ClientResource[ uint8_t id ];
provides interface Stm25pSector as Sector[ uint8_t id ];
provides interface Stm25pVolume as Volume[ uint8_t id ];
uses interface Resource as Stm25pResource[ uint8_t id ];
uses interface Resource as SpiResource;
uses interface Stm25pSpi as Spi;
uses interface Leds;
}
implementation {
enum {
NO_CLIENT = 0xff,
};
typedef enum {
S_IDLE,
S_READ,
S_WRITE,
S_ERASE,
S_CRC,
} stm25p_sector_state_t;
norace stm25p_sector_state_t m_state;
typedef enum {
S_NONE,
S_START,
S_STOP,
} stm25p_power_state_t;
norace stm25p_power_state_t m_power_state;
norace uint8_t m_client;
norace stm25p_addr_t m_addr;
norace stm25p_len_t m_len;
norace stm25p_len_t m_cur_len;
norace uint8_t* m_buf;
norace error_t m_error;
norace uint16_t m_crc;
void bindVolume();
void signalDone( error_t error );
task void signalDone_task();
command error_t SplitControl.start() {
error_t error = call SpiResource.request();
if ( error == SUCCESS )
m_power_state = S_START;
return error;
}
command error_t SplitControl.stop() {
error_t error = call SpiResource.request();
if ( error == SUCCESS )
m_power_state = S_STOP;
return error;
}
async command error_t ClientResource.request[ uint8_t id ]() {
return call Stm25pResource.request[ id ]();
}
async command error_t ClientResource.immediateRequest[ uint8_t id ]() {
return FAIL;
}
async command error_t ClientResource.release[ uint8_t id ]() {
if ( m_client == id ) {
m_state = S_IDLE;
m_client = NO_CLIENT;
call SpiResource.release();
call Stm25pResource.release[ id ]();
return SUCCESS;
}
return FAIL;
}
event void Stm25pResource.granted[ uint8_t id ]() {
m_client = id;
call SpiResource.request();
}
uint8_t getVolumeId( uint8_t client ) {
return signal Volume.getVolumeId[ client ]();
}
event void SpiResource.granted() {
error_t error;
stm25p_power_state_t power_state = m_power_state;
m_power_state = S_NONE;
if ( power_state == S_START ) {
error = call Spi.powerUp();
call SpiResource.release();
signal SplitControl.startDone( error );
return;
}
else if ( power_state == S_STOP ) {
error = call Spi.powerDown();
call SpiResource.release();
signal SplitControl.stopDone( error );
return;
}
signal ClientResource.granted[ m_client ]();
}
async command uint8_t ClientResource.isOwner[ uint8_t id ]() {
return call Stm25pResource.isOwner[id]();
}
stm25p_addr_t physicalAddr( uint8_t id, stm25p_addr_t addr ) {
return addr + ( (stm25p_addr_t)STM25P_VMAP[ getVolumeId( id ) ].base
<< STM25P_SECTOR_SIZE_LOG2 );
}
stm25p_len_t calcWriteLen( stm25p_addr_t addr ) {
stm25p_len_t len = STM25P_PAGE_SIZE - ( addr & STM25P_PAGE_MASK );
return ( m_cur_len < len ) ? m_cur_len : len;
}
command stm25p_addr_t Sector.getPhysicalAddress[ uint8_t id ]( stm25p_addr_t addr ) {
return physicalAddr( id, addr );
}
command uint8_t Sector.getNumSectors[ uint8_t id ]() {
return STM25P_VMAP[ getVolumeId( id ) ].size;
}
command error_t Sector.read[ uint8_t id ]( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len ) {
m_state = S_READ;
m_addr = addr;
m_buf = buf;
m_len = len;
return call Spi.read( physicalAddr( id, addr ), buf, len );
}
async event void Spi.readDone( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len, error_t error ) {
signalDone( error );
}
command error_t Sector.write[ uint8_t id ]( stm25p_addr_t addr,
uint8_t* buf,
stm25p_len_t len ) {
m_state = S_WRITE;
m_addr = addr;
m_buf = buf;
m_len = m_cur_len = len;
return call Spi.pageProgram( physicalAddr( id, addr ), buf,
calcWriteLen( addr ) );
}
async event void Spi.pageProgramDone( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len, error_t error ) {
addr += len;
buf += len;
m_cur_len -= len;
if ( !m_cur_len )
signalDone( SUCCESS );
else
call Spi.pageProgram( addr, buf, calcWriteLen( addr ) );
}
command error_t Sector.erase[ uint8_t id ]( uint8_t sector,
uint8_t num_sectors ) {
m_state = S_ERASE;
m_addr = sector;
m_len = num_sectors;
m_cur_len = 0;
return call Spi.sectorErase( STM25P_VMAP[ getVolumeId(id) ].base + m_addr +
m_cur_len );
}
async event void Spi.sectorEraseDone( uint8_t sector, error_t error ) {
if ( ++m_cur_len < m_len )
call Spi.sectorErase( STM25P_VMAP[getVolumeId(m_client)].base + m_addr +
m_cur_len );
else
signalDone( error );
}
command error_t Sector.computeCrc[ uint8_t id ]( uint16_t crc,
stm25p_addr_t addr,
stm25p_len_t len ) {
m_state = S_CRC;
m_addr = addr;
m_len = len;
return call Spi.computeCrc( crc, physicalAddr( id, addr ), m_len );
}
async event void Spi.computeCrcDone( uint16_t crc, stm25p_addr_t addr,
stm25p_len_t len, error_t error ) {
m_crc = crc;
signalDone( SUCCESS );
}
async event void Spi.bulkEraseDone( error_t error ) {
}
void signalDone( error_t error ) {
m_error = error;
post signalDone_task();
}
task void signalDone_task() {
switch( m_state ) {
case S_IDLE:
signal ClientResource.granted[ m_client ]();
break;
case S_READ:
signal Sector.readDone[ m_client ]( m_addr, m_buf, m_len, m_error );
break;
case S_CRC:
signal Sector.computeCrcDone[ m_client ]( m_addr, m_len,
m_crc, m_error );
break;
case S_WRITE:
signal Sector.writeDone[ m_client ]( m_addr, m_buf, m_len, m_error );
break;
case S_ERASE:
signal Sector.eraseDone[ m_client ]( m_addr, m_len, m_error );
break;
default:
break;
}
}
default event void ClientResource.granted[ uint8_t id ]() {}
default event void Sector.readDone[ uint8_t id ]( stm25p_addr_t addr, uint8_t* buf, stm25p_len_t len, error_t error ) {}
default event void Sector.writeDone[ uint8_t id ]( stm25p_addr_t addr, uint8_t* buf, stm25p_len_t len, error_t error ) {}
default event void Sector.eraseDone[ uint8_t id ]( uint8_t sector, uint8_t num_sectors, error_t error ) {}
default event void Sector.computeCrcDone[ uint8_t id ]( stm25p_addr_t addr, stm25p_len_t len, uint16_t crc, error_t error ) {}
default async event volume_id_t Volume.getVolumeId[ uint8_t id ]() { return 0xff; }
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?