📄 framerm.nc
字号:
// $Id: FramerM.nc,v 1.6 2005/07/22 06:19:37 jwhui Exp $/* -*- Mode: C; c-basic-indent: 2; indent-tabs-mode: nil -*- */ /* * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By * downloading, copying, installing or using the software you agree to * this license. If you do not agree to this license, do not download, * install, copy or use the software. * * Intel Open Source License * * Copyright (c) 2002 Intel 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 Intel 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 INTEL 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: Phil Buonadonna * Revision: $Revision: 1.6 $ * *//* * FramerM * * This modules provides framing for TOS_Msg's using PPP-HDLC-like framing * (see RFC 1662). When sending, a TOS_Msg is encapsulated in an HLDC frame. * Receiving is similar EXCEPT that the component expects a special token byte * be received before the data payload. The purpose of the token is to feed back * an acknowledgement to the sender which serves as a crude form of flow-control. * This module is intended for use with the Packetizer class found in * tools/java/net/packet/Packetizer.java. * *//** * @author Phil Buonadonna */includes AM;includes crc;module FramerM { provides { interface StdControl; interface TokenReceiveMsg; interface ReceiveMsg; interface BareSendMsg; } uses { interface ByteComm; interface StdControl as ByteControl; }}implementation {#define MICA2MSGTYPE 1 enum { HDLC_QUEUESIZE = 2,#ifdef MICA2MSGTYPE HDLC_MTU = (sizeof(TOS_Msg) - 5), //Standard MICA TOS Msgsize is shorter#else HDLC_MTU = (sizeof(TOS_Msg)), //CC2420 TOS Msg length#endif HDLC_FLAG_BYTE = 0x7e, //Start of FrameSync HDLC_CTLESC_BYTE = 0x7d, PROTO_ACK = 64, PROTO_PACKET_ACK = 65, //FrameSync - acknowledge the packet PROTO_PACKET_NOACK = 66, //FrameSync - donot acknowledge the packet PROTO_UNKNOWN = 255 }; enum { RXSTATE_NOSYNC, RXSTATE_PROTO, RXSTATE_TOKEN, RXSTATE_INFO, RXSTATE_ESC }; enum { TXSTATE_IDLE, TXSTATE_PROTO, TXSTATE_INFO, TXSTATE_ESC, TXSTATE_FCS1, TXSTATE_FCS2, TXSTATE_ENDFLAG, TXSTATE_FINISH, TXSTATE_ERROR }; enum { FLAGS_TOKENPEND = 0x2, FLAGS_DATAPEND = 0x4, FLAGS_UNKNOWN = 0x8 }; TOS_Msg gMsgRcvBuf[HDLC_QUEUESIZE]; typedef struct _MsgRcvEntry { uint8_t Proto; uint8_t Token; // Used for sending acknowledgements uint16_t Length; // Does not include 'Proto' or 'Token' fields TOS_MsgPtr pMsg; } MsgRcvEntry_t ; MsgRcvEntry_t gMsgRcvTbl[HDLC_QUEUESIZE]; uint8_t * gpRxBuf; uint8_t * gpTxBuf; uint8_t gFlags; // Flags variable protects atomicity norace uint8_t gTxState; norace uint8_t gPrevTxState; norace uint8_t gTxProto; norace uint16_t gTxByteCnt; norace uint16_t gTxLength; norace uint16_t gTxRunningCRC; uint8_t gRxState; uint8_t gRxHeadIndex; uint8_t gRxTailIndex; uint16_t gRxByteCnt; uint16_t gRxRunningCRC; TOS_MsgPtr gpTxMsg; uint8_t gTxTokenBuf; uint8_t gTxUnknownBuf; norace uint8_t gTxEscByte; task void PacketSent();uint8_t fRemapRxPos( uint8_t InPos ); //remap standard TOSMessage fields to CC2420TOSMsg//*************************************************************************/*fRemapRxPosMap incomming byte positions into CC2420 TOSmessage structure*/uint8_t fRemapRxPos( uint8_t InPos ) {#ifdef MICA2MSGTYPE if( InPos<4 ) return( InPos+offsetof(struct TOS_Msg, addr) ); //addr,AM,groupid else if( InPos==4 ) return( offsetof(struct TOS_Msg, length) ); //length else return( InPos+offsetof(struct TOS_Msg, addr)-1 ); //payload etc#else return(InPos); //do nothing#endif}//fRemapRxByte result_t StartTx() { result_t Result = SUCCESS; bool fInitiate = FALSE; atomic { if (gTxState == TXSTATE_IDLE) { if (gFlags & FLAGS_TOKENPEND) {#ifdef MICA2MSGTYPE gpTxBuf = (uint8_t *)&gTxTokenBuf;// gpTxBuf[offsetof(TOS_Msg,addr)] = gTxTokenBuf;#else gpTxBuf = (uint8_t *)&gTxTokenBuf;#endif gTxProto = PROTO_ACK; gTxLength = sizeof(gTxTokenBuf); fInitiate = TRUE; gTxState = TXSTATE_PROTO; } else if (gFlags & FLAGS_DATAPEND) { gpTxBuf = (uint8_t *)gpTxMsg; gTxProto = PROTO_PACKET_NOACK; //number of bytes to xfer = TOSHeader + data + 2CRC bytes#ifdef MICA2MSGTYPE gTxLength = gpTxMsg->length + TOS_HEADER_SIZE + 2+3; //5 extra bytes in CC2420Header#else gTxLength = gpTxMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2);#endif fInitiate = TRUE; gTxState = TXSTATE_PROTO; } else if (gFlags & FLAGS_UNKNOWN) { gpTxBuf = (uint8_t *)&gTxUnknownBuf; gTxProto = PROTO_UNKNOWN; gTxLength = sizeof(gTxUnknownBuf); fInitiate = TRUE; gTxState = TXSTATE_PROTO; } } } if (fInitiate) { atomic {#ifdef MICA2MSGTYPE gTxRunningCRC = 0; //initialize CRC calculation gTxByteCnt = offsetof(struct TOS_Msg, addr); //start at TOSaddr field#else gTxRunningCRC = 0; //initialize CRC calculation gTxByteCnt = 6; //start at addr in tosmsg (= 0 in rev 1.5?)#endif } Result = call ByteComm.txByte(HDLC_FLAG_BYTE); if (Result != SUCCESS) { atomic gTxState = TXSTATE_ERROR; post PacketSent(); } } return Result; } task void PacketUnknown() { atomic { gFlags |= FLAGS_UNKNOWN; } StartTx(); } task void PacketRcvd() { MsgRcvEntry_t *pRcv = &gMsgRcvTbl[gRxTailIndex]; TOS_MsgPtr pBuf = pRcv->pMsg; // Does the rcvd frame actually have a meaningful message??#ifdef MICA2MSGTYPE if (pRcv->Length >= 5) { //handle Standard MICA2 message format #else if (pRcv->Length >= offsetof(struct TOS_Msg,data)) {#endif switch (pRcv->Proto) { case PROTO_ACK: break; case PROTO_PACKET_ACK: pBuf->crc = 1; // Easier to set here... pBuf = signal TokenReceiveMsg.receive(pBuf,pRcv->Token); break; case PROTO_PACKET_NOACK: pBuf->crc = 1; pBuf = signal ReceiveMsg.receive(pBuf); break; default: gTxUnknownBuf = pRcv->Proto; post PacketUnknown(); break; } //switch } //if atomic { if (pBuf) { pRcv->pMsg = pBuf; } pRcv->Length = 0; pRcv->Token = 0; gRxTailIndex++; gRxTailIndex %= HDLC_QUEUESIZE; } } task void PacketSent() { result_t TxResult = SUCCESS; atomic { if (gTxState == TXSTATE_ERROR) { TxResult = FAIL; gTxState = TXSTATE_IDLE; } } if (gTxProto == PROTO_ACK) { atomic gFlags ^= FLAGS_TOKENPEND; } else{ atomic gFlags ^= FLAGS_DATAPEND; signal BareSendMsg.sendDone((TOS_MsgPtr)gpTxMsg,TxResult); atomic gpTxMsg = NULL; } // Trigger transmission in case something else is pending StartTx(); } void HDLCInitialize() { int i; atomic {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -