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

📄 protocol.c

📁 关于zigbee厂家jennic的zigbee通信模块JN5139的一些示例程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*! *\MODULE              Wireless UART with Flow Control * *\COMPONENT           $RCSfile: Protocol.c,v $ * *\VERSION             $Name:  $ * *\REVISION            $Revision: 1.1 $ * *\DATED               $Date: 2008/01/21 10:15:04 $ * *\STATUS              $State: Exp $ * *\AUTHOR              Martin Looker * *\DESCRIPTION         Handles the over the air protocol. * * Manages the protocol to transmit and receive data over the radio. * * The protocol maintains a single packet containing the next packet of data * for transmission: * * - If the packet is empty it is filled with the next packet of * data from the receive queue. * * - If a packet is ready for transmission the protocol is initiated. * * The basic protocol for A transmitting a data packet to B is as follows: * * - A sends an equiry packet to B * * - If B has space in the UART transmit queue B responds with an ack packet. * * - A sends the data packet to B * * - If B has space in the UART transmit queue it adds the data to the queue and * responds with an ack packet. * * - If B does not have space to receive a packet it responds with a nack packet, A then * pauses for a short while before retrying. * * It is possible that both A and B send an enquiry packet at the same time, the following * rules apply in such a situation: * * - The device that last sent a data packet yields to the other device. If B were the last * device to send data to A then B would yield to A by sending an ack packet, A would then get * to send data. * * - If A gets to send data in the previous scenario, A will pause before sending another * enquiry packet in the expectation that B is ready to send data. * * - The enquiry packets indicate if the device is going to yield, in the event that both * devices are going to take the same action the Router will yield to the Coordinator. *//* *\dot * digraph G { * label="Protocol State Machine" * rankdir="LR" * fontname="FreeSans.ttf" * fontsize=10 * labelfontname="FreeSans.ttf" * labelfontsize=10 * edge	     [fontname="FreeSans.ttf", fontsize=8,  labelfontname="FreeSans.ttf", labelfontsize=8]; * node 	     [fontname="FreeSans.ttf", fontsize=10, labelfontname="FreeSans.ttf", labelfontsize=10,shape="box",height=0.2,width=0.4]; * edge	     [color="Black"]; * IDLE -> ENQ  [label="Data?\nTx Enq"]; * RX   -> IDLE [label="Rx Data?\nTx N/Ack, Yield=F"]; * edge	     [color="#0000AA", fontcolor="#0000AA", labelfontcolor="#0000AA"]; * IDLE -> RX   [label="Rx Enq & Spc?\nTx Ack"]; * RX   -> RX   [label="Rx Enq & Spc?\nTx Ack"]; * WAIT -> RX   [label="Rx Enq & Spc?\nTx Ack"]; * ENQ  -> RX   [label="Rx Enq & Spc & Yield?\nTx Ack"]; * IDLE -> IDLE [label="Rx Enq & !Spc?\nTx Nak"]; * RX   -> RX   [label="Rx Enq & !Spc?\nTx Nak"]; * WAIT -> WAIT [label="Rx Enq & !Spc?\nTx Nak"]; * ENQ  -> ENQ  [label="Rx Enq & !Spc & Yield?\nTx Nak"]; * ENQ  -> ENQ  [label="Rx Enq & !Yield?\nWait=T"]; * edge	     [color="#00AA00", fontcolor="#00AA00", labelfontcolor="#00AA00"]; * ENQ  -> TX   [label="Rx Ack?\nTx Data"]; * TX   -> IDLE [label="Rx Ack?\nYield=T"]; * TX   -> WAIT [label="Rx Ack & Wait?\nYield=T"]; * edge	     [color="#AA0000", fontcolor="#AA0000", labelfontcolor="#AA0000"]; * ENQ  -> WAIT [label="Rx Nak?"]; * TX   -> WAIT [label="Rx Nak?\nYield=T"]; *} *\enddot *\CHANGE HISTORY * * $Log: Protocol.c,v $ * Revision 1.1  2008/01/21 10:15:04  mlook * Initial checkin * * Revision 1.1  2007/11/02 12:32:52  mlook * Adding new application notes * * * *\LAST MODIFIED BY    $Author: mlook $ *                     $Modtime: $ * **************************************************************************** * * This software is owned by Jennic and/or its supplier and is protected * under applicable copyright laws. All rights are reserved. We grant You, * and any third parties, a license to use this software solely and * exclusively on Jennic products. You, and any third parties must reproduce * the copyright and warranty notice and any other legend of ownership on each * copy or partial copy of the software. * * THIS SOFTWARE IS PROVIDED "AS IS". JENNIC MAKES NO WARRANTIES, WHETHER * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, * ACCURACY OR LACK OF NEGLIGENCE. JENNIC SHALL NOT, IN ANY CIRCUMSTANCES, * BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, SPECIAL, * INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON WHATSOEVER. * * Copyright Jennic Ltd 2005, 2006, 2007. All rights reserved * ****************************************************************************//****************************************************************************//***        Include files                                                 ***//****************************************************************************/#include <jendefs.h>#include <string.h>#include <Printf.h>#include "gdb.h"#include "Network.h"#include "Protocol.h"#include "SerialQ.h"#include "Uart.h"/****************************************************************************//***        Macro Definitions                                             ***//****************************************************************************/#define MAX_DATA_PER_FRAME 64   /**< Maximum amount of data per radio frame */#define PR_DEBUG 		    0   /**< Provides protocol debugging *//* Protocol character codes */#if PR_DEBUG#define CHAR_STX  0x00			/**< Data packet */#define CHAR_ENQ  0x01			/**< Transmit enquiry packet */#define CHAR_ACK  0x02			/**< Acknowledge packet */#define CHAR_NACK 0x03			/**< Negative acknowledge packet */#else#define CHAR_STX  0x02			/**< Data packet */#define CHAR_ENQ  0x05			/**< Transmit enquiry packet */#define CHAR_ACK  0x06			/**< Acknowledge packet */#define CHAR_NACK 0x15			/**< Negative acknowledge packet */#endif/****************************************************************************//***        Type Definitions                                              ***//****************************************************************************//** States for protocol's state machine. */typedef enum{	PR_STATE_IDLE=0,				/**< Protocol is idle */	PR_STATE_RX, 					/**< Waiting to receive data */	PR_STATE_ENQ, 					/**< Equiry sent to transmit data */	PR_STATE_TX, 					/**< Data transmitted, waiting for ACK */	PR_STATE_WAIT 					/**< Waiting before trying to transmit */} 	tePrState;/** Data packet structure. */typedef struct{	uint16 u16Length;					 /**< Data length */	uint8  au8Data[MAX_DATA_PER_FRAME+1];/**< Data packet */} 	tsPrPacket;/****************************************************************************//***        Local Function Prototypes                                     ***//****************************************************************************//****************************************************************************//***        Exported Variables                                            ***//****************************************************************************//****************************************************************************//***        Local Variables                                               ***//****************************************************************************/PRIVATE  tePrState  eState;			/**< Protocol state */PRIVATE 	 uint8 u8Timer;			/**< State timer */PRIVATE 	 uint8 u8RxSequence;	/**< Receive sequence */PRIVATE 	 uint8 u8TxSequence;	/**< Transmit sequence */PRIVATE 	bool_t  bCoord;			/**< Coordinator device */PRIVATE 	bool_t  bYield;			/**< Yield next time there is a conflict */PRIVATE 	bool_t  bWait;			/**< Wait before transmission enquiry */PRIVATE tsPrPacket sPacketData;		/**< Data packet */PRIVATE tsPrPacket sPacketCtrl;		/**< Protocol control packet */PRIVATE 	uint16 u16RxCount    = 0;PRIVATE  	uint16 u16TxCount    = 0;PRIVATE 	uint16 u16RxAckCount = 0;PRIVATE 	uint16 u16TxAckCount = 0;PRIVATE 	uint16 u16RxStxCount = 0;PRIVATE 	uint16 u16TxStxCount = 0;PRIVATE 	uint16 u16RxEnqCount = 0;PRIVATE 	uint16 u16TxEnqCount = 0;PRIVATE 	uint16 u16ClEnqCount = 0;#if PR_DEBUGPRIVATE     char   aszAddr[2][4] = {"Rtr", "Crd"};PRIVATE     char   aszCtrl[4][4] = {"STX", "ENQ", "ACK", "NAK"};#endif/****************************************************************************//***        Exported Functions                                            ***//****************************************************************************//****************************************************************************//***        Local Functions                                               ***//****************************************************************************/PRIVATE void   vProtocol_State(tePrState);PRIVATE void   vProtocol_Packet_Reset(tsPrPacket *);PRIVATE void   vProtocol_Packet_Tx(tsPrPacket *);PRIVATE void   vProtocol_Packet_Data(void);PRIVATE void   vProtocol_Packet_Ctrl(char);PRIVATE bool_t bProtocol_RxSequence(uint8);/**************************************************************************** * * NAME  vProtocol_Init *//*! *\DESCRIPTION  Initialises protocol data. *//* PARAMETERS       Name            RW  Usage * None. * * RETURNS * None. * * NOTES * None. ****************************************************************************/PUBLIC void vProtocol_Init(bool_t bInitCoord) /**< (R) Initialise as coordinator */{	/* Initialise protocol data */	eState       = PR_STATE_IDLE;	u8Timer      = 0;	u8TxSequence = 0;	u8RxSequence = 0;	bCoord       = bInitCoord;	bYield       = ! bCoord;	bWait        = FALSE;	/* Reset packets */	vProtocol_Packet_Reset(&sPacketData);	vProtocol_Packet_Reset(&sPacketCtrl);    #if PR_DEBUG    /* Debug */    vSerialQ_AddString(TX_QUEUE, aszAddr[bCoord]);    vSerialQ_AddItem(TX_QUEUE, ' ');    vSerialQ_AddString(TX_QUEUE, "Start\n");    #endif}/**************************************************************************** * * NAME: vProtocol_Tx *//*! *\DESCRIPTION	Builds and initiates transmission of data packets, handles state timeouts. * * If in idle state and the data packet is empty and there is data in the UART's * receive queue the data packet is populated with the next set of data from the * UART's receive queue. * * If in idle state and the data packet is populated initiate transmission by * sending the enquiry control packet. * * If not in idle state and the timer has expired return to the idle state. *//* PARAMETERS:      Name            RW  Usage * None. * * RETURNS: * None. * * NOTES: * None. ****************************************************************************/PUBLIC void vProtocol_Tx(void){	/* Are we idle ? */	if (eState == PR_STATE_IDLE)	{		/* Populate the next data packet if required */		vProtocol_Packet_Data();		/* Got a data packet to send ? */		if (sPacketData.u16Length > 0)		{			/* Go to enquiry state */			vProtocol_State(PR_STATE_ENQ);			/* Send enquiry control packet */			vProtocol_Packet_Ctrl(CHAR_ENQ);		}	}	/* Not idle ? */	else	{		/* Increment timer */		u8Timer++;		/* Timer expired ? */		if (u8Timer > 25)		{			/* Go to idle state */			vProtocol_State(PR_STATE_IDLE);		}	}}/**************************************************************************** * * NAME: vProtocol_Rx *//*! *\DESCRIPTION Receives and processes incoming packets. * * Handles incoming data and control packets updating the state machine as * required. * * Received data packets are added to the UART's transmit queue for output by * the UART. *//* PARAMETERS:      Name            RW  Usage * None. * * RETURNS: * None. * * NOTES: * None. ****************************************************************************/PUBLIC void vProtocol_Rx(uint16   u16Length,	/**< Data length */						 uint8  * pu8Data)		/**< Data packet */{    uint16 i;    bool_t bYieldOther;    #if PR_DEBUG    /* Debug */    vSerialQ_AddString(TX_QUEUE, aszAddr[!bCoord]);    vSerialQ_AddItem(TX_QUEUE, ' ');    vSerialQ_AddString(TX_QUEUE, aszCtrl[pu8Data[0]]);    #endif	/* Enqiry ? */	if (pu8Data[0] == CHAR_ENQ)	{		#if PR_DEBUG	    vSerialQ_AddItem(TX_QUEUE, ' ');	    vSerialQ_AddHex(TX_QUEUE, pu8Data[1], 2);		vSerialQ_AddItem(TX_QUEUE, '\r');		vUart_StartTx();	    #endif		/* Update Rx counts */		u16RxEnqCount++;		/* Update clashing ENQ count if required */		if (eState == PR_STATE_ENQ) u16ClEnqCount++;		/* Get other device's yield state */		bYieldOther = (bool_t) pu8Data[1];		/* Are yield states the same (devices are out of sync) ? */		if (bYieldOther == bYield)		{			/* If endpoint yield, if coord don't */			bYield = ! bCoord;		}		/* Are we in a state where we might receive data ? */		if (eState == PR_STATE_IDLE ||			eState == PR_STATE_RX   ||			eState == PR_STATE_WAIT ||		   (eState == PR_STATE_ENQ  && bYield == TRUE))		{			/* Have we got space in the UART transmit buffer for a full packet ? */			if (u16SerialQ_Free(TX_QUEUE) >= MAX_DATA_PER_FRAME)			{				/* Go to receive state */				vProtocol_State(PR_STATE_RX);				/* Transmit acknowledgement */				vProtocol_Packet_Ctrl(CHAR_ACK);			}			/* No room ? */			else			{				/* Transmit nack */				vProtocol_Packet_Ctrl(CHAR_NACK);			}		}		/* Are we expecting the other end to yield ? */		else if (eState == PR_STATE_ENQ && bYield == FALSE)		{			/* Wait after sending our data to let the other end take its turn */			bWait = TRUE;		}	}	/* Ack ? */	else if (pu8Data[0] == CHAR_ACK)	{		#if PR_DEBUG		vSerialQ_AddItem(TX_QUEUE, '\r');

⌨️ 快捷键说明

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