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

📄 serialp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
/*									 *  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. *  * Revision: $Revision: 1.5 $ *  *//* *  * This modules provides framing for TOS_Msgs using PPP-HDLC-like * framing (see RFC 1662).  When sending, a TOS_Msg is encapsulated in * an HDLC 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. * * @author Phil Buonadonna * @author Lewis Girod * @author Ben Greenstein * @date   August 7 2005 */#include "AM.h"#include "crc.h"module SerialP {  provides {    interface Init;    interface SplitControl;    interface SendBytePacket;    interface ReceiveBytePacket;  }  uses {    interface SerialFrameComm;    interface Leds;    interface StdControl as SerialControl;    interface SerialFlush;  }}implementation {#define NO_TX_SEQNO  enum {    RX_DATA_BUFFER_SIZE = 2,    TX_DATA_BUFFER_SIZE = 4,    SERIAL_MTU = 255,    SERIAL_VERSION = 1,    ACK_QUEUE_SIZE = 5,  };  enum {    RXSTATE_NOSYNC,    RXSTATE_PROTO,    RXSTATE_TOKEN,    RXSTATE_INFO,    RXSTATE_INACTIVE  };  enum {    TXSTATE_IDLE,    TXSTATE_PROTO,    TXSTATE_SEQNO,    TXSTATE_INFO,    TXSTATE_FCS1,    TXSTATE_FCS2,    TXSTATE_ENDFLAG,    TXSTATE_ENDWAIT,    TXSTATE_FINISH,    TXSTATE_ERROR,    TXSTATE_INACTIVE  };  typedef enum {    BUFFER_AVAILABLE,    BUFFER_FILLING,    BUFFER_COMPLETE,  } tx_data_buffer_states_t;  enum {    TX_ACK_INDEX = 0,    TX_DATA_INDEX = 1,    TX_BUFFER_COUNT = 2,  };  typedef struct {    uint8_t writePtr;    uint8_t readPtr;    uint8_t buf[RX_DATA_BUFFER_SIZE+1]; // one wasted byte: writePtr == readPtr means empty  } rx_buf_t;  typedef struct {    uint8_t state;    uint8_t buf;      } tx_buf_t;    typedef struct {    uint8_t writePtr;    uint8_t readPtr;    uint8_t buf[ACK_QUEUE_SIZE+1]; // one wasted byte: writePtr == readPtr means empty      } ack_queue_t;  /* Buffers */  rx_buf_t rxBuf;  tx_buf_t txBuf[TX_BUFFER_COUNT];  /* Receive State */  uint8_t  rxState;  uint8_t  rxByteCnt;  uint8_t  rxProto;  uint8_t  rxSeqno;  uint16_t rxCRC;  /* Transmit State */  norace uint8_t  txState;  norace uint8_t  txByteCnt;  norace uint8_t  txProto;  norace uint8_t  txSeqno;  norace uint16_t txCRC;  uint8_t  txPending;  norace uint8_t txIndex;    /* Ack Queue */  ack_queue_t ackQ;  bool offPending = FALSE;  // Prototypes  inline void txInit();  inline void rxInit();  inline void ackInit();  inline bool ack_queue_is_full();   inline bool ack_queue_is_empty();   inline void ack_queue_push(uint8_t token);  inline uint8_t ack_queue_top();  uint8_t ack_queue_pop();  inline void rx_buffer_init();  inline bool rx_buffer_is_full();  inline bool rx_buffer_is_empty();  inline void rx_buffer_push(uint8_t data);  inline uint8_t rx_buffer_top();  inline uint8_t rx_buffer_pop();  inline uint16_t rx_current_crc();  void rx_state_machine(bool isDelimeter, uint8_t data);  void MaybeScheduleTx();  task void RunTx();    inline void txInit(){    uint8_t i;    atomic for (i = 0; i < TX_BUFFER_COUNT; i++) txBuf[i].state = BUFFER_AVAILABLE;    txState = TXSTATE_IDLE;    txByteCnt = 0;    txProto = 0;    txSeqno = 0;    txCRC = 0;     txPending = FALSE;    txIndex = 0;  }  inline void rxInit(){    rxBuf.writePtr = rxBuf.readPtr = 0;    rxState = RXSTATE_NOSYNC;    rxByteCnt = 0;    rxProto = 0;    rxSeqno = 0;    rxCRC = 0;  }  inline void ackInit(){    ackQ.writePtr = ackQ.readPtr = 0;  }  command error_t Init.init() {    txInit();    rxInit();    ackInit();    return SUCCESS;  }  /*   *  buffer and queue manipulation   */  inline bool ack_queue_is_full(){     uint8_t tmp, tmp2;    atomic {      tmp = ackQ.writePtr;      tmp2 = ackQ.readPtr;    }    if (++tmp > ACK_QUEUE_SIZE) tmp = 0;    return (tmp == tmp2);  }  inline bool ack_queue_is_empty(){    bool ret;    atomic ret = (ackQ.writePtr == ackQ.readPtr);     return ret;  }  inline void ack_queue_push(uint8_t token) {    if (!ack_queue_is_full()){      atomic {        ackQ.buf[ackQ.writePtr] = token;        if (++ackQ.writePtr > ACK_QUEUE_SIZE) ackQ.writePtr = 0;      }      MaybeScheduleTx();    }  }  inline uint8_t ack_queue_top() {    uint8_t tmp = 0;    atomic {      if (!ack_queue_is_empty()){        tmp =  ackQ.buf[ackQ.readPtr];      }    }    return tmp;  }  uint8_t ack_queue_pop() {    uint8_t retval = 0;    atomic {      if (ackQ.writePtr != ackQ.readPtr){        retval =  ackQ.buf[ackQ.readPtr];        if (++(ackQ.readPtr) > ACK_QUEUE_SIZE) ackQ.readPtr = 0;      }    }    return retval;  }  /*    * Buffer Manipulation   */  inline void rx_buffer_init(){    rxBuf.writePtr = rxBuf.readPtr = 0;  }  inline bool rx_buffer_is_full() {    uint8_t tmp = rxBuf.writePtr;    if (++tmp > RX_DATA_BUFFER_SIZE) tmp = 0;    return (tmp == rxBuf.readPtr);  }  inline bool rx_buffer_is_empty(){    return (rxBuf.readPtr == rxBuf.writePtr);  }  inline void rx_buffer_push(uint8_t data){    rxBuf.buf[rxBuf.writePtr] = data;    if (++(rxBuf.writePtr) > RX_DATA_BUFFER_SIZE) rxBuf.writePtr = 0;  }  inline uint8_t rx_buffer_top(){    uint8_t tmp = rxBuf.buf[rxBuf.readPtr];    return tmp;  }  inline uint8_t rx_buffer_pop(){    uint8_t tmp = rxBuf.buf[rxBuf.readPtr];    if (++(rxBuf.readPtr) > RX_DATA_BUFFER_SIZE) rxBuf.readPtr = 0;    return tmp;  }    inline uint16_t rx_current_crc(){    uint16_t crc;    uint8_t tmp = rxBuf.writePtr;    tmp = (tmp == 0 ? RX_DATA_BUFFER_SIZE : tmp - 1);    crc = rxBuf.buf[tmp] & 0x00ff;    crc = (crc << 8) & 0xFF00;    tmp = (tmp == 0 ? RX_DATA_BUFFER_SIZE : tmp - 1);    crc |= (rxBuf.buf[tmp] & 0x00FF);    return crc;  }  task void startDoneTask() {    call SerialControl.start();    signal SplitControl.startDone(SUCCESS);  }  task void stopDoneTask() {    call SerialFlush.flush();  }  event void SerialFlush.flushDone(){    call SerialControl.stop();    signal SplitControl.stopDone(SUCCESS);  }  task void defaultSerialFlushTask(){    signal SerialFlush.flushDone();  }  default command void SerialFlush.flush(){    post defaultSerialFlushTask();  }  command error_t SplitControl.start() {    post startDoneTask();    return SUCCESS;  }  void testOff() {    bool turnOff = FALSE;    atomic {      if (txState == TXSTATE_INACTIVE &&	  rxState == RXSTATE_INACTIVE) {	turnOff = TRUE;      }    }    if (turnOff) {      post stopDoneTask();      atomic offPending = FALSE;    }    else {      atomic offPending = TRUE;    }  }

⌨️ 快捷键说明

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