[Tinyos-2-commits] CVS: tinyos-2.x/tos/platforms/eyesIFX/byte_radio
code4b6b.h, NONE, 1.1.2.1 Uart4b6bPhyC.nc, NONE,
1.1.2.1 Uart4b6bPhyP.nc, NONE, 1.1.2.1
Philipp Huppertz
phihup at users.sourceforge.net
Wed Oct 11 04:52:31 PDT 2006
Update of /cvsroot/tinyos/tinyos-2.x/tos/platforms/eyesIFX/byte_radio
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv24080/tos/platforms/eyesIFX/byte_radio
Added Files:
Tag: tinyos-2_0_devel-BRANCH
code4b6b.h Uart4b6bPhyC.nc Uart4b6bPhyP.nc
Log Message:
- additional UartPhy with 4b6b code (now default on eyes)
--- NEW FILE: code4b6b.h ---
/* -*- mode:c++; indent-tabs-mode: nil -*-
* Copyright (c) 2006, Technische Universitaet Berlin
* 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 Technische Universitaet Berlin 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 COPYRIGHT
* OWNER OR 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.
*/
/**
* provide functions to encode/decode a 4b 6b stream
* @author Andreas Koepke <koepke at tkn.tu-berlin.de>
* Book: RF Monolithics, Inc: ASH Transceiver Designer's Guide, Okt 2002.
* http://www.rfm.com/products/tr_des24.pdf
*/
#ifndef CODE_4B_6B_H
#define CODE_4B_6B_H
enum {
ILLEGAL_CODE = 0xff
};
const uint8_t nibbleToSixBit[] = {
13, // 001101
14, // 001110
19, // 010011
21, // 010101
22, // 010110
25, // 011001
26, // 011010
28, // 011100
35, // 100011
37, // 100101
38, // 100110
41, // 101001
42, // 101010
44, // 101100
50, // 110010
52 // 110100
};
const uint8_t sixBitToNibble[] = {
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x00,
0x01,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x02,
ILLEGAL_CODE,
0x03,
0x04,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x05,
0x06,
ILLEGAL_CODE,
0x07,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x08,
ILLEGAL_CODE,
0x09,
0x0a,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x0b,
0x0c,
ILLEGAL_CODE,
0x0d,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
0x0e,
ILLEGAL_CODE,
0x0f,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE,
ILLEGAL_CODE
};
#endif
--- NEW FILE: Uart4b6bPhyC.nc ---
/* -*- mode:c++; indent-tabs-mode: nil -*-
* Copyright (c) 2006, Technische Universitaet Berlin
* 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 Technische Universitaet Berlin 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 COPYRIGHT
* OWNER OR 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.
*/
/**
* Configuration for the byte radio physical layer. Together with the
* PacketSerializerP the UartPhyP module turns byte streams into packets.
* This one 4b6b encodes/decodes a byte stream
*
* @see PacketSerializerP
*
* @author Philipp Huppertz <huppertz at tkn.tu-berlin.de>
*/
configuration Uart4b6bPhyC
{
provides{
interface PhyPacketTx;
interface RadioByteComm as SerializerRadioByteComm;
interface PhyPacketRx;
interface UartPhyControl;
}
uses {
interface RadioByteComm;
}
}
implementation
{
components
new Alarm32khzC() as RxByteTimer,
Uart4b6bPhyP,
// PlatformLedsC,
MainC;
MainC.SoftwareInit -> Uart4b6bPhyP;
PhyPacketRx = Uart4b6bPhyP;
SerializerRadioByteComm = Uart4b6bPhyP;
RadioByteComm = Uart4b6bPhyP;
PhyPacketTx = Uart4b6bPhyP;
UartPhyControl = Uart4b6bPhyP;
Uart4b6bPhyP.RxByteTimer -> RxByteTimer;
// PlatformLedsC.Led3 <- Uart4b6bPhyP.Led3;
// PlatformLedsC.Led1 <- Uart4b6bPhyP.Led1;
}
--- NEW FILE: Uart4b6bPhyP.nc ---
/* -*- mode:c++; indent-tabs-mode: nil -*-
* Copyright (c) 2006, Technische Universitaet Berlin
* 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 Technische Universitaet Berlin 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 COPYRIGHT
* OWNER OR 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.
*/
#include "code4b6b.h"
/**
* Implementation of the physical layer for the eyesIFX byte radio.
* Together with the PacketSerializerP this module turns byte streams
* into packets.
*
* @author Andreas Koepke <koepke at tkn.tu-berlin.de>
*/
module Uart4b6bPhyP {
provides {
interface Init;
interface PhyPacketTx;
interface RadioByteComm as SerializerRadioByteComm;
interface PhyPacketRx;
interface UartPhyControl;
}
uses {
interface RadioByteComm;
interface Alarm<T32khz, uint16_t> as RxByteTimer;
}
}
implementation
{
/* Module Definitions */
typedef enum {
STATE_PREAMBLE,
STATE_PREAMBLE_CODE,
STATE_SYNC,
STATE_SFD1,
STATE_SFD2,
STATE_HEADER_DONE,
STATE_DATA_HIGH_OR_SFD,
STATE_DATA_HIGH,
STATE_DATA_MIDDLE,
STATE_DATA_LOW,
STATE_DATA_LOW_FOOTER,
STATE_FOOTER_START,
STATE_FOOTER_DONE
} phyState_t;
/* constants */
enum {
PREAMBLE_LENGTH=2,
BYTE_TIME=11,
PREAMBLE_BYTE=0x55,
SYNC_BYTE=0xFF,
SFD_BYTE=0x83
};
/** Module Global Variables */
phyState_t phyState; // Current Phy state State
uint16_t preambleCount;
uint16_t numPreambles; // Number of preambles to send before the packet
uint8_t byteTime; // max. time between two bytes
uint8_t bufByte;
/* Local Function Declarations */
void TransmitNextByte();
void ReceiveNextByte(uint8_t data);
/* Radio Init */
command error_t Init.init(){
atomic {
phyState = STATE_PREAMBLE;
numPreambles = PREAMBLE_LENGTH;
byteTime = BYTE_TIME;
}
return SUCCESS;
}
async command error_t UartPhyControl.setNumPreambles(uint16_t numPreambleBytes) {
atomic {
numPreambles = numPreambleBytes;
}
return SUCCESS;
}
command error_t UartPhyControl.setByteTimeout(uint8_t byteTimeout) {
if (call RxByteTimer.isRunning() == TRUE) {
return FAIL;
} else {
byteTime = byteTimeout * 33;
return SUCCESS;
}
}
async command bool UartPhyControl.isBusy() {
return phyState != STATE_PREAMBLE;
}
void resetState() {
call RxByteTimer.stop();
switch(phyState) {
case STATE_PREAMBLE:
case STATE_PREAMBLE_CODE:
break;
default:
signal PhyPacketRx.recvFooterDone(FAIL);
break;
}
phyState = STATE_PREAMBLE;
}
inline void signalHeader() {
signal PhyPacketRx.recvHeaderDone(SUCCESS);
phyState = STATE_DATA_HIGH_OR_SFD;
}
async event void RxByteTimer.fired() {
// no bytes have arrived, so...
resetState();
}
async command void PhyPacketTx.sendHeader() {
phyState = STATE_PREAMBLE;
preambleCount = numPreambles;
TransmitNextByte();
}
async command void SerializerRadioByteComm.txByte(uint8_t data) {
uint8_t high = nibbleToSixBit[(data & 0xf0) >> 4];
uint8_t low = nibbleToSixBit[data & 0x0f];
if(phyState == STATE_DATA_HIGH) {
high <<= 2;
if(low & 0x20) high |= 2;
if(low & 0x10) high |= 1;
bufByte = low << 4;
call RadioByteComm.txByte(high);
phyState = STATE_DATA_MIDDLE;
}
else {
call RadioByteComm.txByte(bufByte | (high >> 2));
if(high & 0x02) low |= 0x80;
if(high & 0x01) low |= 0x40;
bufByte = low;
phyState = STATE_DATA_LOW;
}
}
async command bool SerializerRadioByteComm.isTxDone() {
return call RadioByteComm.isTxDone();
}
async command void PhyPacketTx.sendFooter() {
if(phyState == STATE_DATA_MIDDLE) {
bufByte |= (nibbleToSixBit[0] >> 2);
phyState = STATE_DATA_LOW_FOOTER;
call RadioByteComm.txByte(bufByte);
} else {
phyState = STATE_FOOTER_START;
TransmitNextByte();
}
}
/* Radio Recv */
async command void PhyPacketRx.recvFooter() {
// currently there is no footer
// atomic phyState = STATE_FOOTER_START;
phyState = STATE_PREAMBLE;
call RxByteTimer.stop();
signal PhyPacketRx.recvFooterDone(SUCCESS);
}
/* Tx Done */
async event void RadioByteComm.txByteReady(error_t error) {
if(error == SUCCESS) {
TransmitNextByte();
} else {
signal SerializerRadioByteComm.txByteReady(error);
phyState = STATE_PREAMBLE;
}
}
void TransmitNextByte() {
switch(phyState) {
case STATE_PREAMBLE:
if(preambleCount > 0) {
preambleCount--;
} else {
phyState = STATE_SYNC;
}
call RadioByteComm.txByte(PREAMBLE_BYTE);
break;
case STATE_SYNC:
phyState = STATE_SFD1;
call RadioByteComm.txByte(SYNC_BYTE);
break;
case STATE_SFD1:
phyState = STATE_SFD2;
call RadioByteComm.txByte(SFD_BYTE);
break;
case STATE_SFD2:
phyState = STATE_HEADER_DONE;
call RadioByteComm.txByte(SFD_BYTE);
break;
case STATE_HEADER_DONE:
phyState = STATE_DATA_HIGH;
signal PhyPacketTx.sendHeaderDone();
break;
case STATE_DATA_HIGH:
signal SerializerRadioByteComm.txByteReady(SUCCESS);
break;
case STATE_DATA_MIDDLE:
signal SerializerRadioByteComm.txByteReady(SUCCESS);
break;
case STATE_DATA_LOW:
call RadioByteComm.txByte(bufByte);
phyState = STATE_DATA_HIGH;
break;
case STATE_DATA_LOW_FOOTER:
phyState = STATE_FOOTER_START;
call RadioByteComm.txByte(bufByte);
break;
case STATE_FOOTER_START:
/* Pseudo-Footer: the MSP430 has two buffers: one for
* transmit, one to store the next byte to be transmitted,
* this footer fills the next-to-transmit buffer, to make
* sure that the last real byte is actually
* transmitted. The byte stored by this call may not be
* transmitted fully or not at all.
*/
phyState = STATE_FOOTER_DONE;
call RadioByteComm.txByte(bufByte);
break;
case STATE_FOOTER_DONE:
phyState = STATE_PREAMBLE;
signal PhyPacketTx.sendFooterDone();
break;
default:
break;
}
}
/* Rx Done */
async event void RadioByteComm.rxByteReady(uint8_t data) {
call RxByteTimer.start(byteTime);
ReceiveNextByte(data);
}
/* Receive the next Byte from the USART */
void ReceiveNextByte(uint8_t data) {
uint8_t decodedByte;
uint8_t low;
uint8_t high;
if((data == SFD_BYTE) && (phyState != STATE_DATA_HIGH_OR_SFD)) {
resetState();
signalHeader();
call RxByteTimer.start(byteTime<<1);
}
switch(phyState) {
case STATE_PREAMBLE:
low = data & 0xf;
high = data >> 4;
if((low > 0) && (low < 0xf) && (high > 0) && (high < 0xf))
phyState = STATE_PREAMBLE_CODE;
break;
case STATE_PREAMBLE_CODE:
low = data & 0xf;
high = data >> 4;
if((low == 0) || (low == 0xf) || (high == 0) || (high == 0xf))
phyState = STATE_PREAMBLE;
break;
case STATE_DATA_HIGH_OR_SFD:
if(data != SFD_BYTE) {
decodedByte = sixBitToNibble[data >> 2];
if(decodedByte != ILLEGAL_CODE) {
bufByte = decodedByte << 2;
bufByte |= data & 0x03;
bufByte <<= 2;
phyState = STATE_DATA_MIDDLE;
}
else {
resetState();
}
}
else {
phyState = STATE_DATA_HIGH;
}
break;
case STATE_DATA_HIGH:
decodedByte = sixBitToNibble[data >> 2];
if(decodedByte != ILLEGAL_CODE) {
bufByte = decodedByte << 2;
bufByte |= data & 0x03;
bufByte <<= 2;
phyState = STATE_DATA_MIDDLE;
}
else {
resetState();
}
break;
case STATE_DATA_MIDDLE:
decodedByte = sixBitToNibble[((bufByte & 0x0f)<<2) | (data >> 4)];
if(decodedByte != ILLEGAL_CODE) {
phyState = STATE_DATA_LOW;
signal SerializerRadioByteComm.rxByteReady((bufByte & 0xf0) | decodedByte);
bufByte = (data & 0x0f) << 2;
}
else {
resetState();
}
break;
case STATE_DATA_LOW:
decodedByte = sixBitToNibble[bufByte | (data >> 6)];
if(decodedByte != ILLEGAL_CODE) {
bufByte = (decodedByte << 4);
decodedByte = sixBitToNibble[data & 0x3f];
if(decodedByte != ILLEGAL_CODE) {
phyState = STATE_DATA_HIGH;
signal SerializerRadioByteComm.rxByteReady(bufByte | decodedByte);
}
else {
resetState();
}
}
else {
resetState();
}
break;
// maybe there will be a time.... we will need this. but for now there is no footer
//case STATE_FOOTER_START:
//phyState = STATE_FOOTER_DONE;
//break;
//case STATE_FOOTER_DONE:
//phyState = STATE_NULL;
//signal PhyPacketRx.recvFooterDone(TRUE);
//break;
default:
break;
}
}
}
More information about the Tinyos-2-commits
mailing list