📄 cc2420controlp.nc
字号:
/*
* 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>
* @author David Moss
* @author Urs Hunkeler (ReadRssi implementation)
* @version $Revision: 1.1 $ $Date: 2008/02/11 17:41:25 $
*/
#include "Timer.h"
module CC2420ControlP {
provides interface Init;
provides interface Resource;
provides interface CC2420Config;
provides interface CC2420Power;
provides interface Read<uint16_t> as ReadRssi;
// provides interface Read_rssi;
uses interface Alarm<T32khz,uint32_t> as StartupTimer;
uses interface GeneralIO as CSN;
uses interface GeneralIO as RSTN;
uses interface GeneralIO as VREN;
uses interface GpioInterrupt as InterruptCCA;
//uses interface ActiveMessageAddress;
uses interface CC2420Ram as PANID;
uses interface CC2420Register as FSCTRL;
uses interface CC2420Register as IOCFG0;
uses interface CC2420Register as IOCFG1;
uses interface CC2420Register as MDMCTRL0;
uses interface CC2420Register as MDMCTRL1;
uses interface CC2420Register as RXCTRL1;
uses interface CC2420Register as RSSI;
uses interface CC2420Strobe as SRXON;
uses interface CC2420Strobe as SRFOFF;
uses interface CC2420Strobe as SXOSCOFF;
uses interface CC2420Strobe as SXOSCON;
// uses interface AMPacket;
uses interface Resource as SpiResource;
uses interface Resource as RssiResource;
uses interface Resource as SyncResource;
uses interface Leds;
}
implementation {
typedef enum {
S_VREG_STOPPED,
S_VREG_STARTING,
S_VREG_STARTED,
S_XOSC_STARTING,
S_XOSC_STARTED,
} cc2420_control_state_t;
uint8_t m_channel;
uint8_t m_tx_power;
uint16_t m_pan;
uint16_t m_short_addr;
bool m_sync_busy;
bool autoAckEnabled;
bool hwAutoAckDefault;
bool addressRecognition;
norace cc2420_control_state_t m_state = S_VREG_STOPPED;
/***************** Prototypes ****************/
void writeFsctrl();
void writeMdmctrl0();
void writeId();
task void sync();
task void syncDone();
/***************** Init Commands ****************/
command error_t Init.init() {
call CSN.makeOutput();
call RSTN.makeOutput();
call VREN.makeOutput();
//m_short_addr = call ActiveMessageAddress.amAddress();
// m_pan = call ActiveMessageAddress.amGroup();
m_tx_power = CC2420_DEF_RFPOWER;
//m_channel = CC2420_DEF_CHANNEL;
m_channel = LOGICAL_CHANNEL;
//#if defined(CC2420_NO_ACKNOWLEDGEMENTS)
autoAckEnabled = FALSE;
//#else
// autoAckEnabled = TRUE;
//#endif
//#if defined(CC2420_HW_ACKNOWLEDGEMENTS)
// hwAutoAckDefault = TRUE;
//#else
hwAutoAckDefault = FALSE;
//#endif
//#if defined(CC2420_NO_ADDRESS_RECOGNITION)
addressRecognition = FALSE;
//#else
// addressRecognition = TRUE;
//#endif
return SUCCESS;
}
/***************** Resource Commands ****************/
async command error_t Resource.immediateRequest() {
error_t error = call SpiResource.immediateRequest();
if ( error == SUCCESS ) {
call CSN.clr();
}
return error;
}
async command error_t Resource.request() {
return call SpiResource.request();
}
async command uint8_t Resource.isOwner() {
return call SpiResource.isOwner();
}
async command error_t Resource.release() {
atomic {
call CSN.set();
return call SpiResource.release();
}
}
/***************** CC2420Power Commands ****************/
async command error_t CC2420Power.startVReg() {
atomic {
if ( m_state != S_VREG_STOPPED ) {
return FAIL;
}
m_state = S_VREG_STARTING;
}
call VREN.set();
call StartupTimer.start( CC2420_TIME_VREN );
return SUCCESS;
}
async command error_t CC2420Power.stopVReg() {
m_state = S_VREG_STOPPED;
call RSTN.clr();
call VREN.clr();
call RSTN.set();
return SUCCESS;
}
async command error_t CC2420Power.startOscillator() {
atomic {
//if ( m_state != S_VREG_STARTED ) {
// return FAIL;
//}
//m_state = S_XOSC_STARTING;
/*
call IOCFG1.write( CC2420_SFDMUX_XOSC16M_STABLE <<
CC2420_IOCFG1_CCAMUX );
*/
call IOCFG1.write(0x0018);
call InterruptCCA.enableRisingEdge();
call SXOSCON.strobe();
/*
call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |
( 127 << CC2420_IOCFG0_FIFOP_THR ) );
*/
call IOCFG0.write(0x027F);
writeFsctrl();
//call FSCTRL.write(0x4192);
//initial set of frequency channel
//call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) | ( ( (LOGICAL_CHANNEL - 11)*5+357) << CC2420_FSCTRL_FREQ ) );
//call MDMCTRL0.write(0x0AE2);
call MDMCTRL0.write(0x02E2);
//CHANGE
writeMdmctrl0();
//call RXCTRL1.write(0x0A56);
/*
call RXCTRL1.write( ( 1 << CC2420_RXCTRL1_RXBPF_LOCUR ) |
( 1 << CC2420_RXCTRL1_LOW_LOWGAIN ) |
( 1 << CC2420_RXCTRL1_HIGH_HGM ) |
( 1 << CC2420_RXCTRL1_LNA_CAP_ARRAY ) |
( 1 << CC2420_RXCTRL1_RXMIX_TAIL ) |
( 1 << CC2420_RXCTRL1_RXMIX_VCM ) |
( 2 << CC2420_RXCTRL1_RXMIX_CURRENT ) );
*/
}
return SUCCESS;
}
async command error_t CC2420Power.stopOscillator() {
atomic {
if ( m_state != S_XOSC_STARTED ) {
return FAIL;
}
m_state = S_VREG_STARTED;
call SXOSCOFF.strobe();
}
return SUCCESS;
}
async command error_t CC2420Power.rxOn() {
atomic {
if ( m_state != S_XOSC_STARTED ) {
return FAIL;
}
call SRXON.strobe();
}
return SUCCESS;
}
async command error_t CC2420Power.rfOff() {
atomic {
if ( m_state != S_XOSC_STARTED ) {
return FAIL;
}
call SRFOFF.strobe();
}
return SUCCESS;
}
/***************** CC2420Config Commands ****************/
command uint8_t CC2420Config.getChannel() {
atomic return m_channel;
}
command void CC2420Config.setChannel( uint8_t channel ) {
atomic m_channel = channel;
}
async command uint16_t CC2420Config.getShortAddr() {
atomic return m_short_addr;
}
command void CC2420Config.setShortAddr( uint16_t addr ) {
atomic m_short_addr = addr;
}
async command uint16_t CC2420Config.getPanAddr() {
atomic return m_pan;
}
command void CC2420Config.setPanAddr( uint16_t pan ) {
atomic m_pan = pan;
}
/**
* Sync must be called to commit software parameters configured on
* the microcontroller (through the CC2420Config interface) to the
* CC2420 radio chip.
*/
command error_t CC2420Config.sync() {
atomic {
if ( m_sync_busy ) {
return FAIL;
}
m_sync_busy = TRUE;
if ( m_state == S_XOSC_STARTED ) {
call SyncResource.request();
} else {
post syncDone();
}
}
return SUCCESS;
}
/**
* @param on TRUE to turn address recognition on, FALSE to turn it off
*/
command void CC2420Config.setAddressRecognition(bool on) {
atomic addressRecognition = on;
}
/**
* @return TRUE if address recognition is enabled
*/
async command bool CC2420Config.isAddressRecognitionEnabled() {
atomic return addressRecognition;
}
/**
* Sync must be called for acknowledgement changes to take effect
* @param enableAutoAck TRUE to enable auto acknowledgements
* @param hwAutoAck TRUE to default to hardware auto acks, FALSE to
* default to software auto acknowledgements
*/
command void CC2420Config.setAutoAck(bool enableAutoAck, bool hwAutoAck) {
autoAckEnabled = enableAutoAck;
hwAutoAckDefault = hwAutoAck;
}
/**
* @return TRUE if hardware auto acks are the default, FALSE if software
* acks are the default
*/
async command bool CC2420Config.isHwAutoAckDefault() {
atomic return hwAutoAckDefault;
}
/**
* @return TRUE if auto acks are enabled
*/
async command bool CC2420Config.isAutoAckEnabled() {
atomic return autoAckEnabled;
}
/***************** ReadRssi Commands ****************/
command error_t ReadRssi.read() {
return call RssiResource.request();
}
/***************** Spi Resources Events ****************/
event void SyncResource.granted() {
//possibly this is on the sync of the new configuration of the transceiver //CHECK
call CSN.clr();
call SRFOFF.strobe();
writeFsctrl();
//CHANGE
writeMdmctrl0();
writeId();
call CSN.set();
call CSN.clr();
call SRXON.strobe();
call CSN.set();
call SyncResource.release();
post syncDone();
}
event void SpiResource.granted() {
call CSN.clr();
signal Resource.granted();
}
event void RssiResource.granted() {
uint16_t data;
call CSN.clr();
call RSSI.read(&data);
call CSN.set();
call RssiResource.release();
data += 0x7f;
data &= 0x00ff;
//signal ReadRssi.readDone(SUCCESS, data);
//signal Read_rssi.readDone(SUCCESS, data);
}
/***************** StartupTimer Events ****************/
async event void StartupTimer.fired() {
if ( m_state == S_VREG_STARTING ) {
m_state = S_VREG_STARTED;
call RSTN.clr();
call RSTN.set();
signal CC2420Power.startVRegDone();
}
}
/***************** InterruptCCA Events ****************/
async event void InterruptCCA.fired() {
m_state = S_XOSC_STARTED;
call InterruptCCA.disable();
call IOCFG1.write( 0 );
writeId();
call CSN.set();
call CSN.clr();
signal CC2420Power.startOscillatorDone();
}
/***************** ActiveMessageAddress Events ****************/
/*
async event void ActiveMessageAddress.changed() {
atomic {
m_short_addr = call ActiveMessageAddress.amAddress();
m_pan = call ActiveMessageAddress.amGroup();
}
post sync();
}
*/
/***************** Tasks ****************/
/**
* Attempt to synchronize our current settings with the CC2420
*/
task void sync() {
call CC2420Config.sync();
}
task void syncDone() {
atomic m_sync_busy = FALSE;
signal CC2420Config.syncDone( SUCCESS );
}
/***************** Functions ****************/
/**
* Write teh FSCTRL register
*/
void writeFsctrl() {
uint8_t channel;
atomic {
channel = m_channel;
}
call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
( ( (channel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );
/*
call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
( channel << CC2420_FSCTRL_FREQ ) );
*/
}
/**
* Write the MDMCTRL0 register
*/
void writeMdmctrl0() {
atomic {
call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |
( addressRecognition << CC2420_MDMCTRL0_ADR_DECODE ) |
( 2 << CC2420_MDMCTRL0_CCA_HYST ) |
( 3 << CC2420_MDMCTRL0_CCA_MOD ) |
( 1 << CC2420_MDMCTRL0_AUTOCRC ) |
( (autoAckEnabled && hwAutoAckDefault) << CC2420_MDMCTRL0_AUTOACK ) |
( 0 << CC2420_MDMCTRL0_AUTOACK ) |
( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );
}
// Jon Green:
// MDMCTRL1.CORR_THR is defaulted to 20 instead of 0 like the datasheet says
// If we add in changes to MDMCTRL1, be sure to include this fix.
}
/**
* Write the PANID register
*/
void writeId() {
nxle_uint16_t id[ 2 ];
atomic {
id[ 0 ] = m_pan;
id[ 1 ] = m_short_addr;
}
call PANID.write(0, (uint8_t*)&id, sizeof(id));
}
/***************** Defaults ****************/
default event void CC2420Config.syncDone( error_t error ) {
}
default event void ReadRssi.readDone(error_t error, uint16_t data) {
}
/*
command error_t Read_rssi.read() {
return call RssiResource.request();
}
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -