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

📄 rf230layerp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
			writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower);		}		if( call RF230Config.requiresRssiCca(msg) 				&& (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) )			return EBUSY;		writeRegister(RF230_TRX_STATE, RF230_PLL_ON);		// do something useful, just to wait a little		time32 = call LocalTime.get();		timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0;		// we have missed an incoming message in this short amount of time		if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON )		{			ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_BUSY_RX );			state = STATE_PLL_ON_2_RX_ON;			return EBUSY;		}		atomic		{			call SLP_TR.set();			time = call RadioAlarm.getNow() + TX_SFD_DELAY;		}		call SLP_TR.clr();		ASSERT( ! radioIrq );		call SELN.clr();		call HplRF230.spiSplitWrite(RF230_CMD_FRAME_WRITE);		length = call RF230Config.getLength(msg);		data = call RF230Config.getPayload(msg);		// length | data[0] ... data[length-3] | automatically generated FCS		call HplRF230.spiSplitReadWrite(length);		// the FCS is atomatically generated (2 bytes)		length -= 2;		header = call RF230Config.getHeaderLength();		if( header > length )			header = length;		length -= header;		// first upload the header to gain some time		do {			call HplRF230.spiSplitReadWrite(*(data++));		}		while( --header != 0 );		time32 += (int16_t)(time) - (int16_t)(time32);		if( timesync != 0 )			*(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32;		do {			call HplRF230.spiSplitReadWrite(*(data++));		}		while( --length != 0 );		// wait for the SPI transfer to finish		call HplRF230.spiSplitRead();		call SELN.set();		/*		 * There is a very small window (~1 microsecond) when the RF230 went 		 * into PLL_ON state but was somehow not properly initialized because 		 * of an incoming message and could not go into BUSY_TX. I think the		 * radio can even receive a message, and generate a TRX_UR interrupt		 * because of concurrent access, but that message probably cannot be		 * recovered.		 *		 * TODO: this needs to be verified, and make sure that the chip is 		 * not locked up in this case.		 */		// go back to RX_ON state when finished		writeRegister(RF230_TRX_STATE, RF230_RX_ON);#ifdef RF230_DEBUG_MESSAGES		if( call DiagMsg.record() )		{			length = call RF230Config.getLength(msg);			call DiagMsg.str("tx");			call DiagMsg.uint16(time);			call DiagMsg.uint8(length);			call DiagMsg.hex8s(data, length - 2);			call DiagMsg.send();		}#endif		if( timesync != 0 )			*(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32;		call PacketTimeStamp.set(msg, time32);		// wait for the TRX_END interrupt		state = STATE_BUSY_TX_2_RX_ON;		cmd = CMD_TRANSMIT;		return SUCCESS;	}	default tasklet_async event void RadioSend.sendDone(error_t error) { }	default tasklet_async event void RadioSend.ready() { }/*----------------- CCA -----------------*/	tasklet_async command error_t RadioCCA.request()	{		if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || ! call RadioAlarm.isFree() )			return EBUSY;		// see Errata B7 of the datasheet		// writeRegister(RF230_TRX_STATE, RF230_PLL_ON);		// writeRegister(RF230_TRX_STATE, RF230_RX_ON);		writeRegister(RF230_PHY_CC_CCA, RF230_CCA_REQUEST | RF230_CCA_MODE_VALUE | channel);		call RadioAlarm.wait(CCA_REQUEST_TIME);		cmd = CMD_CCA;				return SUCCESS;	}	default tasklet_async event void RadioCCA.done(error_t error) { }/*----------------- RECEIVE -----------------*/	inline void downloadMessage()	{		uint8_t length;		uint16_t crc;		call SELN.clr();		call HplRF230.spiWrite(RF230_CMD_FRAME_READ);		// read the length byte		length = call HplRF230.spiWrite(0);		// if correct length		if( length >= 3 && length <= call RF230Config.getMaxLength() )		{			uint8_t read;			uint8_t* data;			// initiate the reading			call HplRF230.spiSplitWrite(0);			call RF230Config.setLength(rxMsg, length);			data = call RF230Config.getPayload(rxMsg);			crc = 0;			// we do not store the CRC field			length -= 2;			read = call RF230Config.getHeaderLength();			if( length < read )				read = length;			length -= read;			do {				crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0));			}			while( --read != 0  );			if( signal RadioReceive.header(rxMsg) )			{				while( length-- != 0 )					crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0));				crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));				crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));				call PacketLinkQuality.set(rxMsg, call HplRF230.spiSplitRead());			}			else				crc = 1;		}		else			crc = 1;		call SELN.set();		state = STATE_RX_ON;#ifdef RF230_DEBUG_MESSAGES		if( call DiagMsg.record() )		{			length = call RF230Config.getLength(rxMsg);			call DiagMsg.str("rx");			call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0);			call DiagMsg.uint16(call RadioAlarm.getNow());			call DiagMsg.uint8(crc != 0);			call DiagMsg.uint8(length);			call DiagMsg.hex8s(call RF230Config.getPayload(rxMsg), length - 2);			call DiagMsg.send();		}#endif				cmd = CMD_NONE;		// signal only if it has passed the CRC check		if( crc == 0 )			rxMsg = signal RadioReceive.receive(rxMsg);	}/*----------------- IRQ -----------------*/	async event void IRQ.captured(uint16_t time)	{		ASSERT( ! radioIrq );		atomic		{			capturedTime = time;			radioIrq = TRUE;		}		call Tasklet.schedule();	}	void serviceRadio()	{		if( isSpiAcquired() )		{			uint16_t time;			uint32_t time32;			uint8_t irq;			uint8_t temp;						atomic time = capturedTime;			radioIrq = FALSE;			irq = readRegister(RF230_IRQ_STATUS);#ifdef RF230_DEBUG			// TODO: handle this interrupt			if( irq & RF230_IRQ_TRX_UR )			{				if( call DiagMsg.record() )				{					call DiagMsg.str("assert ur");					call DiagMsg.uint16(call RadioAlarm.getNow());					call DiagMsg.hex8(readRegister(RF230_TRX_STATUS));					call DiagMsg.hex8(readRegister(RF230_TRX_STATE));					call DiagMsg.hex8(irq);					call DiagMsg.uint8(state);					call DiagMsg.uint8(cmd);					call DiagMsg.send();				}			}#endif			if( irq & RF230_IRQ_PLL_LOCK )			{				if( cmd == CMD_TURNON || cmd == CMD_CHANNEL )				{					ASSERT( state == STATE_TRX_OFF_2_RX_ON );					state = STATE_RX_ON;					cmd = CMD_SIGNAL_DONE;				}				else if( cmd == CMD_TRANSMIT )				{					ASSERT( state == STATE_BUSY_TX_2_RX_ON );				}				else					ASSERT(FALSE);			}			if( irq & RF230_IRQ_RX_START )			{				if( cmd == CMD_CCA )				{					signal RadioCCA.done(FAIL);					cmd = CMD_NONE;				}				if( cmd == CMD_NONE )				{					ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );					// the most likely place for busy channel, with no TRX_END interrupt					if( irq == RF230_IRQ_RX_START )					{						temp = readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK;						rssiBusy += temp - (rssiBusy >> 2);#ifdef RF230_RSSI_ENERGY						temp = readRegister(RF230_PHY_ED_LEVEL);#endif						call PacketRSSI.set(rxMsg, temp);					}					else						call PacketRSSI.clear(rxMsg);					/*					 * The timestamp corresponds to the first event which could not					 * have been a PLL_LOCK because then cmd != CMD_NONE, so we must					 * have received a message (and could also have received the 					 * TRX_END interrupt in the mean time, but that is fine. Also,					 * we could not be after a transmission, because then cmd = 					 * CMD_TRANSMIT.					 */					if( irq == RF230_IRQ_RX_START ) // just to be cautious					{						time32 = call LocalTime.get();						time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32);						call PacketTimeStamp.set(rxMsg, time32);					}					else						call PacketTimeStamp.clear(rxMsg);					cmd = CMD_RECEIVE;				}				else					ASSERT( cmd == CMD_TURNOFF );			}			if( irq & RF230_IRQ_TRX_END )			{				if( cmd == CMD_TRANSMIT )				{					ASSERT( state == STATE_BUSY_TX_2_RX_ON );					state = STATE_RX_ON;					cmd = CMD_NONE;					signal RadioSend.sendDone(SUCCESS);					// TODO: we could have missed a received message					ASSERT( ! (irq & RF230_IRQ_RX_START) );				}				else if( cmd == CMD_RECEIVE )				{					ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );					if( state == STATE_PLL_ON_2_RX_ON )					{						ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_PLL_ON );						writeRegister(RF230_TRX_STATE, RF230_RX_ON);						state = STATE_RX_ON;					}					else					{						// the most likely place for clear channel (hope to avoid acks)						rssiClear += (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) - (rssiClear >> 2);					}					cmd = CMD_DOWNLOAD;				}				else					ASSERT(FALSE);			}		}	}	default tasklet_async event bool RadioReceive.header(message_t* msg)	{		return TRUE;	}	default tasklet_async event message_t* RadioReceive.receive(message_t* msg)	{		return msg;	}/*----------------- TASKLET -----------------*/	tasklet_async event void Tasklet.run()	{		if( radioIrq )			serviceRadio();		if( cmd != CMD_NONE )		{			if( cmd == CMD_DOWNLOAD )				downloadMessage();			else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON )				changeState();			else if( cmd == CMD_CHANNEL )				changeChannel();						if( cmd == CMD_SIGNAL_DONE )			{				cmd = CMD_NONE;				signal RadioState.done();			}		}		if( cmd == CMD_NONE && state == STATE_RX_ON && ! radioIrq )			signal RadioSend.ready();		if( cmd == CMD_NONE )			call SpiResource.release();	}}

⌨️ 快捷键说明

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