📄 defaultlplp.nc
字号:
/* * Copyright (c) 2005-2006 Rincon Research 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 Rincon Research 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 * RINCON RESEARCH 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 *//** * Low Power Listening for the CC2420. This component is responsible for * delivery of an LPL packet, and for turning off the radio when the radio * has run out of tasks. * * The PowerCycle component is responsible for duty cycling the radio * and performing receive detections. * * @author David Moss */#include "DefaultLpl.h"#include "AM.h"module DefaultLplP { provides { interface Init; interface LowPowerListening; interface Send; interface Receive; } uses { interface Send as SubSend; interface CC2420Transmit as Resend; interface RadioBackoff; interface Receive as SubReceive; interface AMPacket; interface SplitControl as SubControl; interface PowerCycle; interface CC2420PacketBody; interface PacketAcknowledgements; interface State as SendState; interface State as RadioPowerState; interface State as SplitControlState; interface Timer<TMilli> as OffTimer; interface Timer<TMilli> as SendDoneTimer; interface Random; interface Leds; }}implementation { /** The message currently being sent */ norace message_t *currentSendMsg; /** The length of the current send message */ uint8_t currentSendLen; /** TRUE if the radio is duty cycling and not always on */ bool dutyCycling; /** * Radio Power State */ enum { S_OFF, // off by default S_TURNING_ON, S_ON, S_TURNING_OFF, }; /** * Send States */ enum { S_IDLE, S_SENDING, }; enum { ONE_MESSAGE = 0, }; /***************** Prototypes ***************/ task void send(); task void resend(); task void startRadio(); task void stopRadio(); void initializeSend(); void startOffTimer(); uint16_t getActualDutyCycle(uint16_t dutyCycle); /***************** Init Commands ***************/ command error_t Init.init() { dutyCycling = FALSE; return SUCCESS; } /***************** LowPowerListening Commands ***************/ /** * Set this this node's radio sleep interval, in milliseconds. * Once every interval, the node will sleep and perform an Rx check * on the radio. Setting the sleep interval to 0 will keep the radio * always on. * * This is the equivalent of setting the local duty cycle rate. * * @param sleepIntervalMs the length of this node's Rx check interval, in [ms] */ command void LowPowerListening.setLocalSleepInterval( uint16_t sleepIntervalMs) { call PowerCycle.setSleepInterval(sleepIntervalMs); } /** * @return the local node's sleep interval, in [ms] */ command uint16_t LowPowerListening.getLocalSleepInterval() { return call PowerCycle.getSleepInterval(); } /** * Set this node's radio duty cycle rate, in units of [percentage*100]. * For example, to get a 0.05% duty cycle, * <code> * call LowPowerListening.setDutyCycle(5); * </code> * * For a 100% duty cycle (always on), * <code> * call LowPowerListening.setDutyCycle(10000); * </code> * * This is the equivalent of setting the local sleep interval explicitly. * * @param dutyCycle The duty cycle percentage, in units of [percentage*100] */ command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { call PowerCycle.setSleepInterval( call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); } /** * @return this node's radio duty cycle rate, in units of [percentage*100] */ command uint16_t LowPowerListening.getLocalDutyCycle() { return call LowPowerListening.sleepIntervalToDutyCycle( call PowerCycle.getSleepInterval()); } /** * Configure this outgoing message so it can be transmitted to a neighbor mote * with the specified Rx sleep interval. * @param msg Pointer to the message that will be sent * @param sleepInterval The receiving node's sleep interval, in [ms] */ command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { (call CC2420PacketBody.getMetadata(msg))->rxInterval = sleepIntervalMs; } /** * @return the destination node's sleep interval configured in this message */ command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return (call CC2420PacketBody.getMetadata(msg))->rxInterval; } /** * Configure this outgoing message so it can be transmitted to a neighbor mote * with the specified Rx duty cycle rate. * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25. * * @param msg Pointer to the message that will be sent * @param dutyCycle The duty cycle of the receiving mote, in units of * [percentage*100] */ command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { (call CC2420PacketBody.getMetadata(msg))->rxInterval = call LowPowerListening.dutyCycleToSleepInterval(dutyCycle); } /** * @return the destination node's duty cycle configured in this message * in units of [percentage*100] */ command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return call LowPowerListening.sleepIntervalToDutyCycle( (call CC2420PacketBody.getMetadata(msg))->rxInterval); } /** * Convert a duty cycle, in units of [percentage*100], to * the sleep interval of the mote in milliseconds * @param dutyCycle The duty cycle in units of [percentage*100] * @return The equivalent sleep interval, in units of [ms] */ command uint16_t LowPowerListening.dutyCycleToSleepInterval( uint16_t dutyCycle) { dutyCycle = getActualDutyCycle(dutyCycle); if(dutyCycle == 10000) { return 0; } return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle; } /** * Convert a sleep interval, in units of [ms], to a duty cycle * in units of [percentage*100] * @param sleepInterval The sleep interval in units of [ms] * @return The duty cycle in units of [percentage*100] */ command uint16_t LowPowerListening.sleepIntervalToDutyCycle( uint16_t sleepInterval) { if(sleepInterval == 0) { return 10000; } return getActualDutyCycle((DUTY_ON_TIME * 10000) / (sleepInterval + DUTY_ON_TIME)); } /***************** Send Commands ***************/ /** * Each call to this send command gives the message a single * DSN that does not change for every copy of the message * sent out. For messages that are not acknowledged, such as * a broadcast address message, the receiving end does not * signal receive() more than once for that message. */ command error_t Send.send(message_t *msg, uint8_t len) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -