⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf230layerp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2007, Vanderbilt University * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. *  * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Author: Miklos Maroti */#include <RF230.h>#include <HplRF230.h>#include <Tasklet.h>#include <RadioAssert.h>#include <TimeSyncMessage.h>module RF230LayerP{	provides	{		interface Init as PlatformInit @exactlyonce();		interface Init as SoftwareInit @exactlyonce();		interface RadioState;		interface RadioSend;		interface RadioReceive;		interface RadioCCA;	}	uses	{		interface GeneralIO as SELN;		interface Resource as SpiResource;		interface SpiByte;		interface HplRF230;		interface GeneralIO as SLP_TR;		interface GeneralIO as RSTN;		interface GpioCapture as IRQ;		interface BusyWait<TMicro, uint16_t>;		interface PacketField<uint8_t> as PacketLinkQuality;		interface PacketField<uint8_t> as PacketTransmitPower;		interface PacketField<uint8_t> as PacketRSSI;		interface PacketField<uint8_t> as PacketTimeSyncOffset;		interface PacketTimeStamp<TRF230, uint32_t>;		interface LocalTime<TRF230>;		interface RF230Config;		interface Tasklet;		interface RadioAlarm;#ifdef RF230_DEBUG		interface DiagMsg;#endif	}}implementation{/*----------------- STATE -----------------*/	tasklet_norace uint8_t state;	enum	{		STATE_P_ON = 0,		STATE_SLEEP = 1,		STATE_SLEEP_2_TRX_OFF = 2,		STATE_TRX_OFF = 3,		STATE_TRX_OFF_2_RX_ON = 4,		STATE_RX_ON = 5,		STATE_BUSY_TX_2_RX_ON = 6,		STATE_PLL_ON_2_RX_ON = 7,	};	tasklet_norace uint8_t cmd;	enum	{		CMD_NONE = 0,			// the state machine has stopped		CMD_TURNOFF = 1,		// goto SLEEP state		CMD_STANDBY = 2,		// goto TRX_OFF state		CMD_TURNON = 3,			// goto RX_ON state		CMD_TRANSMIT = 4,		// currently transmitting a message		CMD_RECEIVE = 5,		// currently receiving a message		CMD_CCA = 6,			// performing clear chanel assesment		CMD_CHANNEL = 7,		// changing the channel		CMD_SIGNAL_DONE = 8,	// signal the end of the state transition		CMD_DOWNLOAD = 9,		// download the received message	};	norace bool radioIrq;	tasklet_norace uint8_t txPower;	tasklet_norace uint8_t channel;	tasklet_norace message_t* rxMsg;	message_t rxMsgBuffer;	uint16_t capturedTime;	// the current time when the last interrupt has occured	tasklet_norace uint8_t rssiClear;	tasklet_norace uint8_t rssiBusy;/*----------------- REGISTER -----------------*/	inline void writeRegister(uint8_t reg, uint8_t value)	{		ASSERT( call SpiResource.isOwner() );		ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );		call SELN.clr();		call HplRF230.spiSplitWrite(RF230_CMD_REGISTER_WRITE | reg);		call HplRF230.spiSplitReadWrite(value);		call HplRF230.spiSplitRead();		call SELN.set();	}	inline uint8_t readRegister(uint8_t reg)	{		ASSERT( call SpiResource.isOwner() );		ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );		call SELN.clr();		call HplRF230.spiSplitWrite(RF230_CMD_REGISTER_READ | reg);		call HplRF230.spiSplitReadWrite(0);		reg = call HplRF230.spiSplitRead();		call SELN.set();		return reg;	}/*----------------- ALARM -----------------*/	enum	{		SLEEP_WAKEUP_TIME = (uint16_t)(880 * RF230_ALARM_MICROSEC),		CCA_REQUEST_TIME = (uint16_t)(140 * RF230_ALARM_MICROSEC),		TX_SFD_DELAY = (uint16_t)(176 * RF230_ALARM_MICROSEC),		RX_SFD_DELAY = (uint16_t)(8 * RF230_ALARM_MICROSEC),	};	tasklet_async event void RadioAlarm.fired()	{		if( state == STATE_SLEEP_2_TRX_OFF )			state = STATE_TRX_OFF;		else if( cmd == CMD_CCA )		{			uint8_t cca;			ASSERT( state == STATE_RX_ON );			cmd = CMD_NONE;			cca = readRegister(RF230_TRX_STATUS);			ASSERT( (cca & RF230_TRX_STATUS_MASK) == RF230_RX_ON );			signal RadioCCA.done( (cca & RF230_CCA_DONE) ? ((cca & RF230_CCA_STATUS) ? SUCCESS : EBUSY) : FAIL );		}		else			ASSERT(FALSE);		// make sure the rest of the command processing is called		call Tasklet.schedule();	}/*----------------- INIT -----------------*/	command error_t PlatformInit.init()	{		call SELN.makeOutput();		call SELN.set();		call SLP_TR.makeOutput();		call SLP_TR.clr();		call RSTN.makeOutput();		call RSTN.set();		rxMsg = &rxMsgBuffer;		// these are just good approximates		rssiClear = 0;		rssiBusy = 90;		return SUCCESS;	}	command error_t SoftwareInit.init()	{		// for powering up the radio		return call SpiResource.request();	}	void initRadio()	{		call BusyWait.wait(510);		call RSTN.clr();		call SLP_TR.clr();		call BusyWait.wait(6);		call RSTN.set();		writeRegister(RF230_TRX_CTRL_0, RF230_TRX_CTRL_0_VALUE);		writeRegister(RF230_TRX_STATE, RF230_TRX_OFF);		call BusyWait.wait(510);		writeRegister(RF230_IRQ_MASK, RF230_IRQ_TRX_UR | RF230_IRQ_PLL_LOCK | RF230_IRQ_TRX_END | RF230_IRQ_RX_START);		writeRegister(RF230_CCA_THRES, RF230_CCA_THRES_VALUE);		writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | RF230_TX_PWR_DEFAULT);		txPower = RF230_TX_PWR_DEFAULT;		channel = call RF230Config.getDefaultChannel() & RF230_CHANNEL_MASK;		writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);		call SLP_TR.set();		state = STATE_SLEEP;	}/*----------------- SPI -----------------*/	event void SpiResource.granted()	{		call SELN.makeOutput();		call SELN.set();		if( state == STATE_P_ON )		{			initRadio();			call SpiResource.release();		}		else			call Tasklet.schedule();	}	bool isSpiAcquired()	{		if( call SpiResource.isOwner() )			return TRUE;		if( call SpiResource.immediateRequest() == SUCCESS )		{			call SELN.makeOutput();			call SELN.set();			return TRUE;		}		call SpiResource.request();		return FALSE;	}/*----------------- CHANNEL -----------------*/	tasklet_async command error_t RadioState.setChannel(uint8_t c)	{		c &= RF230_CHANNEL_MASK;		if( cmd != CMD_NONE )			return EBUSY;		else if( channel == c )			return EALREADY;		channel = c;		cmd = CMD_CHANNEL;		call Tasklet.schedule();		return SUCCESS;	}	inline void changeChannel()	{		ASSERT( cmd == CMD_CHANNEL );		ASSERT( state == STATE_SLEEP || state == STATE_TRX_OFF || state == STATE_RX_ON );		if( isSpiAcquired() )		{			writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);			if( state == STATE_RX_ON )				state = STATE_TRX_OFF_2_RX_ON;			else				cmd = CMD_SIGNAL_DONE;		}	}/*----------------- TURN ON/OFF -----------------*/	inline void changeState()	{		if( (cmd == CMD_STANDBY || cmd == CMD_TURNON)			&& state == STATE_SLEEP && call RadioAlarm.isFree() )		{			call SLP_TR.clr();			call RadioAlarm.wait(SLEEP_WAKEUP_TIME);			state = STATE_SLEEP_2_TRX_OFF;		}		else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() )		{			ASSERT( ! radioIrq );			readRegister(RF230_IRQ_STATUS); // clear the interrupt register			call IRQ.captureRisingEdge();			writeRegister(RF230_TRX_STATE, RF230_RX_ON);			state = STATE_TRX_OFF_2_RX_ON;		}		else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY) 			&& state == STATE_RX_ON && isSpiAcquired() )		{			writeRegister(RF230_TRX_STATE, RF230_FORCE_TRX_OFF);			call IRQ.disable();			radioIrq = FALSE;			state = STATE_TRX_OFF;		}		if( cmd == CMD_TURNOFF && state == STATE_TRX_OFF )		{			call SLP_TR.set();			state = STATE_SLEEP;			cmd = CMD_SIGNAL_DONE;		}		else if( cmd == CMD_STANDBY && state == STATE_TRX_OFF )			cmd = CMD_SIGNAL_DONE;	}	tasklet_async command error_t RadioState.turnOff()	{		if( cmd != CMD_NONE )			return EBUSY;		else if( state == STATE_SLEEP )			return EALREADY;		cmd = CMD_TURNOFF;		call Tasklet.schedule();		return SUCCESS;	}		tasklet_async command error_t RadioState.standby()	{		if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )			return EBUSY;		else if( state == STATE_TRX_OFF )			return EALREADY;		cmd = CMD_STANDBY;		call Tasklet.schedule();		return SUCCESS;	}	tasklet_async command error_t RadioState.turnOn()	{		if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )			return EBUSY;		else if( state == STATE_RX_ON )			return EALREADY;		cmd = CMD_TURNON;		call Tasklet.schedule();		return SUCCESS;	}	default tasklet_async event void RadioState.done() { }/*----------------- TRANSMIT -----------------*/	tasklet_async command error_t RadioSend.send(message_t* msg)	{		uint16_t time;		uint8_t length;		uint8_t* data;		uint8_t header;		uint32_t time32;		void* timesync;		if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )			return EBUSY;		length = (call PacketTransmitPower.isSet(msg) ?			call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK;		if( length != txPower )		{			txPower = length;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -