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

📄 wirelessuart.c

📁 Jennic的Zigbee协议Demo程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    }

    /* only accept SET commands */
    if ((eCommandTypeId != SET) && (eCommandTypeId != SET_ACKNOWLEDGMENT))
    {
        return KVP_INVALID_COMMAND_TYPE;
    }

    /* Check address of source*/
    u16DeviceAddr = afSrcAddr.hAddress.shortAddress;

	if (	(u16DeviceAddr != sWuart.sSystem.u16MatchAddr)
		|| 	(sWuart.sSystem.eBound != E_BIND_MATCHED))
    {
        return KVP_SUCCESS;
    }

	/* Extract data and send to UART */
    if (u16AttributeId == WUP_CID_UART_DATA)
    {
		pu8Afdu++;
        if (u8SequenceNum == sWuart.sSystem.u8RxFrameHandle)
        {
            sWuart.sSystem.u8RxFrameHandle++;

            /* Copy frame data to serial buffer for output on UART */
            for (i = 0; i < (*pu8AfduLength - 1); i++)
            {
                vSerial_TxChar(*pu8Afdu++);
            }
        }
        /* Must have missed a frame */
        else if (u8SequenceNum > sWuart.sSystem.u8RxFrameHandle)
        {
            sWuart.sSystem.u8RxFrameHandle = u8SequenceNum + 1;

            /* Copy frame data to serial buffer for output on UART */
            for (i = 0; i < (*pu8AfduLength - 1); i++)
            {
                vSerial_TxChar(*pu8Afdu++);
            }
        }
        /* Must be the same frame as last time */
        else if (u8SequenceNum < sWuart.sSystem.u8RxFrameHandle)
        {
            /* Don't do anything as we already have the data */
		}

        return KVP_SUCCESS;
	}
	else
	{
		return KVP_UNSUPPORTED_ATTRIBUTE;
	}
}

/****************************************************************************
 *
 * NAME: JZA_vAfKvpResponse
 *
 * DESCRIPTION:
 * Used to send response to incoming KVP frame
 *
 * PARAMETERS:      Name            		RW  Usage
 *                  srcAddressMod  			R   Address of responding node
 *					transactionSequenceNum	R	Sequence number of frame
 *					commandTypeIdentifier   R 	Type of command sent
 *					dstEndPoint				R	Endpoint which response is sent to
 *					clusterID				R	ID of target cluster
 *					attributeIdentifier		R	Attibute ID of target cluster
 *					errorCode				R 	Success or otherwise of request
 *					afduLength				R   Length of data portion
 *					*pAfdu					R	Pointer to data portion of frame
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void JZA_vAfKvpResponse	  (AF_ADDRTYPE         srcAddressMod,
                         		   UINT8               transactionSequenceNum,
                         		   AF_COMMAND_TYPE_ID  commandTypeIdentifier,
                         		   UINT8               dstEndPoint,
                         		   UINT8               clusterID,
                         		   UINT16              attributeIdentifier,
                         		   UINT8               errorCode,
                         		   UINT8               afduLength,
                         		   UINT8              *pAfdu )
{
	if (transactionSequenceNum == sWuart.sSystem.u8TxFrameHandle)
	{
		sWuart.sSystem.bAwaitingResponse = FALSE;
		sWuart.sSystem.u8KvpResponseTimeout = 0;
		sWuart.sSystem.u8TxFrameHandle++;
	}
}

/****************************************************************************
 *
 * NAME: applicationMSGObject
 *
 * DESCRIPTION:
 * Receives incoming MSG data frames.
 *
 * PARAMETERS:      Name            		RW  Usage
 *					afSrcAddr				R	Source address of message frame
 *					dstEndPoint				R	Destination Endpoint of message
 *					*clusterID				R   Pointer to Cluster ID for frame
 *					*afduLength				R   Pointer to length of data portion
 *					*pAfdu					R   Pointer to data portion
 * RETURNS:
 *
 *
 ****************************************************************************/
PUBLIC UINT8 *JZA_pu8AfMsgObject(AF_ADDRTYPE 	afSrcAddr,
                       		      UINT8       	dstEndPoint,
                          		  UINT8      	*clusterID,
                           		  UINT8      	*afduLength,
                            	  UINT8      	*pAfdu)
{
    return NULL;
}

/****************************************************************************
 *
 * NAME: vZdpResponse
 *
 * DESCRIPTION:
 * Receives responses to Binding or MatchDescriptor requests
 *
 * PARAMETERS:      Name            		RW  Usage
 * 					u8Type					R	Type of response
 *					*pu8Payload				R	Pointer to response
 *					u8PayloadLen			R	Length of response
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void JZA_vZdpResponse(uint8 u8Type, uint8 *pu8Payload, uint8 u8PayloadLen)
{
	/* if already matched with another node, ignore any incoming responses */
	if (sWuart.sSystem.eBound == E_BIND_MATCHED)
    {
	    return;
    }

    switch (u8Type)
    {
    case Match_Desc_rsp:
    	/* response to a MatchDescriptor request has been received. If valid
    	extract the short address and endpoint form the response and store it.
    	Turn off LED to indicate successful matching */
        if ((pu8Payload[0] == ZDP_SUCCESS_VALID) && (pu8Payload[3] > 0))
        {
            BOSMemCpy(&sWuart.sSystem.u16MatchAddr, &pu8Payload[1], 2);
            sWuart.sSystem.u8MatchEndpoint = pu8Payload[4];
            sWuart.sSystem.eBound = E_BIND_MATCHED;
            /* turn off LED2 to indicate matching successful */
            vAHI_DioSetOutput(LED2_MASK, 0);
        }
        break;

    case End_Device_Bind_rsp:
    	/* this would be used to receive responses if a Bind Request
    	had been used */
        break;

    default:
        break;

    }
}

/****************************************************************************/
/***        Local Functions                                               ***/
/****************************************************************************/
/****************************************************************************
 *
 * NAME: vInit
 *
 * DESCRIPTION:
 * Initialises the hardware
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vInit(void)
{
    /* Initialise Zigbee stack */
    (void)JZS_u32InitSystem();

    /* Set LED IO's to outputs */
    vAHI_DioSetDirection(0, LED_OUTPUTS_MASK);
    vAHI_DioSetOutput(0, LED1_MASK);
    vAHI_DioSetOutput(0, LED2_MASK);

	vButtonInitRfd();

    /* Initialise the serial port and rx/tx queues */
    vSerial_Init();

    /* Use timer to give 10ms tick period */
    vAHI_TimerEnable(E_AHI_TIMER_1, 10, FALSE, TRUE, FALSE);
    vAHI_TimerClockSelect(E_AHI_TIMER_1, FALSE, TRUE);
    vAHI_TimerStartRepeat(E_AHI_TIMER_1, 80, 160);

    /* Initialise software elements */
    vInitDevice();

    /* Start BOS */
    BOSIntSystem();
    BOSStartSystem();
}

/****************************************************************************
 *
 * NAME: vInitDevice
 *
 * DESCRIPTION:
 * Initialises software structures.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vInitDevice(void)
{
	sWuart.sSystem.eBound = E_BIND_NONE;
	sWuart.sSystem.bAwaitingResponse = FALSE;
	sWuart.sSystem.u16BindResponseTimeout = 0;
	sWuart.sSystem.u8KvpResponseTimeout = 0;
	sWuart.sSystem.u8WuartEndpoint = 0x31;
	sWuart.sSystem.u16MatchAddr = 0x0000;
   	sWuart.sQueue.u8ReadPtr = 0;
    sWuart.sQueue.u8WritePtr = 0;
    sWuart.sSystem.u8TxFrameHandle = 0;
    sWuart.sSystem.u8RxFrameHandle = 0;
}

/****************************************************************************
 *
 * NAME: vPerformMatchRequest
 *
 * DESCRIPTION:
 * Obtains nodes own simple descriptor and initiates a Match Descriptor
 * request
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vPerformMatchRequest(void)
{
    AF_SIMPLE_DESCRIPTOR *pAfSimpleDesc;

    /* obtain simple descriptor */
    pAfSimpleDesc = afmeSearchEndpoint(sWuart.sSystem.u8WuartEndpoint);

    if(pAfSimpleDesc)
    {
        /* Send Match Descriptor request */
        zdpMatchDescReq(0xffff,
                        pAfSimpleDesc->u16ProfileId,
                        pAfSimpleDesc->u8OutputClusterCnt,
                        pAfSimpleDesc->u8OutputClusterLst,
                      	pAfSimpleDesc->u8InputClusterCnt,
                        pAfSimpleDesc->u8InputClusterLst,
                        APS_TXOPTION_NONE);

		sWuart.sSystem.eBound = E_BIND_BINDING;
    }
}

/****************************************************************************
 *
 * NAME: vTxData
 *
 * DESCRIPTION:
 * Creates a KVP data frame and sends it to the matched node
 *
 * PARAMETERS:      Name            		RW  Usage
 *					bLastFrameFailed		R	Response not received from last
 *												frame sent
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vTxData(void)
{
    UINT8               u8SrcEP = sWuart.sSystem.u8WuartEndpoint;
    AF_ADDRTYPE         hDstAddr;
    UINT8               transCount = 1;
    int16 				i16RxChar;
    int					i = 1;
    bool_t				bNewData = FALSE;

    PRIVATE AFDE_DATA_REQ_INFO  asAfdeDataReq;
    PRIVATE UINT8               au8Afdu[MAX_DATA_PER_FRAME];

    /* specify destination node short address and endpoint */
    hDstAddr.hAddrMode = DEV_16BIT_ADDR;
    hDstAddr.hAddress.shortAddress = sWuart.sSystem.u16MatchAddr;
    hDstAddr.u8EndPoint = sWuart.sSystem.u8MatchEndpoint;

    /* if last frame was sent and acknowledged successfully, check to see if
    new data is waiting, and if so create a new data request. */
    if (!sWuart.sSystem.bAwaitingResponse)
    {
	    /* if there is any data in the UART receive buffer, extract it and send it
	    to the matched node */
		i16RxChar = i16Serial_RxChar();
    	if (i16RxChar >= 0)
        {
            /* specify the transaction sequence number */
            asAfdeDataReq.u8SequenceNum = sWuart.sSystem.u8TxFrameHandle;
            /* We want to send data to an input, so use the SET command type */
            asAfdeDataReq.hCommandTypeID = SET_ACKNOWLEDGMENT;
            asAfdeDataReq.hAttributeDataType = CHARACTER_STRING;
            /* use the DATA attribute for a UART cluster, as specified in the
            wireless UART private profile defined for this demo application */
            asAfdeDataReq.u16AttributeID = WUP_CID_UART_DATA;
            asAfdeDataReq.hErrorCode = KVP_SUCCESS;

            /* insert the UART rx data */
            au8Afdu[i++] = i16RxChar;

            while ((i16RxChar >= 0) && (i < MAX_DATA_PER_FRAME))
            {
                i16RxChar = i16Serial_RxChar();
                if (i16RxChar >= 0)
                {
                	/* Set payload data */
                	au8Afdu[i++] = (uint8)i16RxChar;
				}
            }

            /* First byte of data portion is actual number of chars */
            au8Afdu[0] = i - 1;
			/* Specify length of data portion */
            asAfdeDataReq.u8DividedAfduLen = i;

            bNewData = TRUE;
		}
	}

  	/* either sending a new frame or re-sending the last one */
  	if (bNewData || sWuart.sSystem.bAwaitingResponse)
  	{
  	  	/* send KVP data request */
  	  	afdeDataRequest(hDstAddr,
                    u8SrcEP,
                    WUP_PROFILE_ID,
                    WUP_CID_UART,
                    KVP,
                    transCount,
                    &asAfdeDataReq,
                   	au8Afdu,
                    APS_TXOPTION_NONE,
                    ENABLE_ROUTE_DISCOVERY,
                    0);

		sWuart.sSystem.bAwaitingResponse	 = TRUE;
	}
 }

/****************************************************************************
 *
 * NAME: vCheckForBindResponseTimeout
 *
 * DESCRIPTION:
 * Keeps track of how long ago Match Descriptor request was sent.
 * If time exceeds a limit without a response being received, makes a new
 * Match Descriptor request
 *
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vCheckForBindResponseTimeout(void)
{
	/* increment counter */
	sWuart.sSystem.u16BindResponseTimeout++;
	if (sWuart.sSystem.u16BindResponseTimeout == MAX_BIND_RESPONSE_WAIT)
	{
		/* too long since request sent, so re-send it */
		sWuart.sSystem.u16BindResponseTimeout = 0;
		vPerformMatchRequest();
	}
}

/****************************************************************************
 *
 * NAME: vCheckForKvpResponseTimeout
 *
 * DESCRIPTION:
 * Keeps track of how long ago KVP data packet was sent.
 * If time exceeds a limit without a response being received, the packet is
 * re-sent.
 *
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vCheckForKvpResponseTimeout(void)
{
	/* increment counter */
	sWuart.sSystem.u8KvpResponseTimeout++;
	if (sWuart.sSystem.u8KvpResponseTimeout == MAX_KVP_RESPONSE_WAIT)
	{
		/* too long since packet sent, so re-send it */
		sWuart.sSystem.u8KvpResponseTimeout = 0;
		vTxData();
	}
}

/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/

⌨️ 快捷键说明

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