stm25pspip.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 273 行
NC
273 行
/*
* 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.4 $ $Date: 2006/12/12 18:23:13 $
*/
#include "crc.h"
module Stm25pSpiP {
provides interface Init;
provides interface Resource as ClientResource;
provides interface Stm25pSpi as Spi;
uses interface Resource as SpiResource;
uses interface GeneralIO as CSN;
uses interface GeneralIO as Hold;
uses interface SpiByte;
uses interface SpiPacket;
uses interface Leds;
}
implementation {
enum {
CRC_BUF_SIZE = 16,
};
typedef enum {
S_READ = 0x3,
S_PAGE_PROGRAM = 0x2,
S_SECTOR_ERASE = 0xd8,
S_BULK_ERASE = 0xc7,
S_WRITE_ENABLE = 0x6,
S_POWER_ON = 0xab,
S_DEEP_SLEEP = 0xb9,
} stm25p_cmd_t;
norace uint8_t m_cmd[ 4 ];
norace bool m_is_writing = FALSE;
norace bool m_computing_crc = FALSE;
norace stm25p_addr_t m_addr;
norace uint8_t* m_buf;
norace stm25p_len_t m_len;
norace stm25p_addr_t m_cur_addr;
norace stm25p_len_t m_cur_len;
norace uint8_t m_crc_buf[ CRC_BUF_SIZE ];
norace uint16_t m_crc;
error_t newRequest( bool write, stm25p_len_t cmd_len );
void signalDone( error_t error );
uint8_t sendCmd( uint8_t cmd, uint8_t len ) {
uint8_t tmp = 0;
int i;
call CSN.clr();
for ( i = 0; i < len; i++ )
tmp = call SpiByte.write( cmd );
call CSN.set();
return tmp;
}
command error_t Init.init() {
call CSN.makeOutput();
call Hold.makeOutput();
call CSN.set();
call Hold.set();
return SUCCESS;
}
async command error_t ClientResource.request() {
return call SpiResource.request();
}
async command error_t ClientResource.immediateRequest() {
return call SpiResource.immediateRequest();
}
async command error_t ClientResource.release() {
return call SpiResource.release();
}
async command uint8_t ClientResource.isOwner() {
return call SpiResource.isOwner();
}
stm25p_len_t calcReadLen() {
return ( m_cur_len < CRC_BUF_SIZE ) ? m_cur_len : CRC_BUF_SIZE;
}
async command error_t Spi.powerDown() {
sendCmd( S_DEEP_SLEEP, 1 );
return SUCCESS;
}
async command error_t Spi.powerUp() {
sendCmd( S_POWER_ON, 5 );
return SUCCESS;
}
async command error_t Spi.read( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len ) {
m_cmd[ 0 ] = S_READ;
m_addr = addr;
m_buf = buf;
m_len = len;
return newRequest( FALSE, 4 );
}
async command error_t Spi.computeCrc( uint16_t crc, stm25p_addr_t addr,
stm25p_len_t len ) {
m_computing_crc = TRUE;
m_crc = crc;
m_addr = m_cur_addr = addr;
m_len = m_cur_len = len;
return call Spi.read( addr, m_crc_buf, calcReadLen() );
}
async command error_t Spi.pageProgram( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len ) {
m_cmd[ 0 ] = S_PAGE_PROGRAM;
m_addr = addr;
m_buf = buf;
m_len = len;
return newRequest( TRUE, 4 );
}
async command error_t Spi.sectorErase( uint8_t sector ) {
m_cmd[ 0 ] = S_SECTOR_ERASE;
m_addr = (stm25p_addr_t)sector << STM25P_SECTOR_SIZE_LOG2;
return newRequest( TRUE, 4 );
}
async command error_t Spi.bulkErase() {
m_cmd[ 0 ] = S_BULK_ERASE;
return newRequest( TRUE, 1 );
}
error_t newRequest( bool write, stm25p_len_t cmd_len ) {
m_cmd[ 1 ] = m_addr >> 16;
m_cmd[ 2 ] = m_addr >> 8;
m_cmd[ 3 ] = m_addr;
if ( write )
sendCmd( S_WRITE_ENABLE, 1 );
call CSN.clr();
call SpiPacket.send( m_cmd, NULL, cmd_len );
return SUCCESS;
}
void releaseAndRequest() {
call SpiResource.release();
call SpiResource.request();
}
async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf,
uint16_t len, error_t error ) {
int i;
switch( m_cmd[ 0 ] ) {
case S_READ:
if ( tx_buf == m_cmd ) {
call SpiPacket.send( NULL, m_buf, m_len );
break;
}
else if ( m_computing_crc ) {
for ( i = 0; i < len; i++ )
m_crc = crcByte( m_crc, m_crc_buf[ i ] );
m_cur_addr += len;
m_cur_len -= len;
if ( m_cur_len ) {
call SpiPacket.send( NULL, m_crc_buf, calcReadLen() );
break;
}
}
call CSN.set();
signalDone( SUCCESS );
break;
case S_PAGE_PROGRAM:
if ( tx_buf == m_cmd ) {
call SpiPacket.send( m_buf, NULL, m_len );
break;
}
// fall through
case S_SECTOR_ERASE: case S_BULK_ERASE:
call CSN.set();
m_is_writing = TRUE;
releaseAndRequest();
break;
default:
break;
}
}
event void SpiResource.granted() {
if ( !m_is_writing )
signal ClientResource.granted();
else if ( sendCmd( 0x5, 2 ) & 0x1 )
releaseAndRequest();
else
signalDone( SUCCESS );
}
void signalDone( error_t error ) {
m_is_writing = FALSE;
switch( m_cmd[ 0 ] ) {
case S_READ:
if ( m_computing_crc ) {
m_computing_crc = FALSE;
signal Spi.computeCrcDone( m_crc, m_addr, m_len, error );
}
else {
signal Spi.readDone( m_addr, m_buf, m_len, error );
}
break;
case S_PAGE_PROGRAM:
signal Spi.pageProgramDone( m_addr, m_buf, m_len, error );
break;
case S_SECTOR_ERASE:
signal Spi.sectorEraseDone( m_addr >> STM25P_SECTOR_SIZE_LOG2, error );
break;
case S_BULK_ERASE:
signal Spi.bulkEraseDone( error );
break;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?