📄 wirelessuart.c
字号:
{
vSerial_TxChar(*pu8Afdu++);
}
}
/* Must have missed a frame */
else if (puTransactionInd->u8SequenceNum > sWuart.sSystem.u8RxFrameHandle)
{
sWuart.sSystem.u8RxFrameHandle = puTransactionInd->u8SequenceNum + 1;
/* Copy frame data to serial buffer for output on UART */
for (i = 0; i < u8Length; i++)
{
vSerial_TxChar(*pu8Afdu++);
}
}
/* Must be the same frame as last time */
else if (puTransactionInd->u8SequenceNum < sWuart.sSystem.u8RxFrameHandle)
{
/* Don't do anything as we already have the data */
}
puTransactionRsp->uFrame.sKvp.eErrorCode = KVP_SUCCESS;
}
else
{
puTransactionRsp->uFrame.sKvp.eErrorCode = KVP_UNSUPPORTED_ATTRIBUTE;
}
return bReturnVal;
}
/****************************************************************************
*
* NAME: JZA_vAfKvpResponse
*
* DESCRIPTION:
* Used to send response to incoming KVP frame
*
* PARAMETERS: Name RW Usage
* eAddrMode R Address mode of incoming frame
* u16AddrSrc R Network address of source node
* u8SrcEP R Endpoint address of source node
* u8LQI R Link Quality Indication
* u8DstEP R Destination endpoint address
* u8ClusterId R Cluster ID of incoming frame
* *puTransactionInd R Pointer to incoming frame
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vAfKvpResponse(APS_Addrmode_e eAddrMode,
uint16 u16AddrSrc,
uint8 u8SrcEP,
uint8 u8LQI,
uint8 u8DstEP,
uint8 u8ClusterID,
AF_Transaction_s *puTransactionInd)
{
if (puTransactionInd->u8SequenceNum == sWuart.sSystem.u8TxFrameHandle)
{
sWuart.sSystem.bAwaitingResponse = FALSE;
sWuart.sSystem.u8KvpResponseTimeout = 0;
sWuart.sSystem.u8TxFrameHandle++;
}
}
/****************************************************************************
*
* NAME: JZA_pu8AfMsgObject
*
* DESCRIPTION:
* Receives incoming MSG data frames.
*
* PARAMETERS: Name RW Usage
* eAddrMode R Address mode of incoming frame
* u16AddrSrc R Network address of source node
* u8SrcEP R Endpoint address of source node
* u8LQI R Link Quality Indication
* u8DstEP R Destination endpoint address
* u8ClusterId R Cluster ID of incoming frame
* *pu8ClusterIDRsp R Pointer to cluster ID of response frame
* *puTransactionInd R Pointer to incoming frame
* *puTransactionRsp R Pointer to response frame
* RETURNS:
* FALSE
*
****************************************************************************/
PUBLIC bool_t JZA_bAfMsgObject(APS_Addrmode_e eAddrMode,
uint16 u16AddrSrc,
uint8 u8SrcEP,
uint8 u8LQI,
uint8 u8DstEP,
uint8 u8ClusterID,
uint8 *pu8ClusterIDRsp,
AF_Transaction_s *puTransactionInd,
AF_Transaction_s *puTransactionRsp)
{
return FALSE;
}
/****************************************************************************
*
* NAME: JZA_vZdpResponse
*
* DESCRIPTION:
* Receives responses to Binding or MatchDescriptor requests
*
* PARAMETERS: Name RW Usage
* u8Type R Type of response
* u8LQI R Link Quality Indication
* *pu8Payload R Pointer to response
* u8PayloadLen R Length of response
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vZdpResponse(uint8 u8Type, uint8 u8Lqi, 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 ZDP_MatchDescRsp:
/* 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))
{
sWuart.sSystem.u16MatchAddr = (uint16) (pu8Payload[2] << 8);
sWuart.sSystem.u16MatchAddr |= pu8Payload[1];
sWuart.sSystem.u8MatchEndpoint = pu8Payload[4];
sWuart.sSystem.eBound = E_BIND_MATCHED;
/* turn off LED2 to indicate matching successful */
vLedControl(1, FALSE);
}
break;
case ZDP_EndDeviceBindRsp:
/* this would be used to receive responses if a Bind Request
had been used */
break;
default:
break;
}
}
/****************************************************************************
*
* NAME: JZA_vStackEvent
*
* DESCRIPTION:
* Used to receive additional stack events such as Data Request confirm
*
* PARAMETERS: Name RW Usage
* eEventId R ID number of stack event
* *puStackEvent R Pointer to union containing
* stack event data
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vStackEvent(teJZS_EventIdentifier eEventId,
tuJZS_StackEvent *puStackEvent)
{
if (eEventId == JZS_EVENT_NWK_JOINED_AS_ROUTER)
{
sWuart.sSystem.bStackReady = TRUE;
vAddDesc();
}
}
/****************************************************************************/
/*** Local Functions ***/
/****************************************************************************/
/****************************************************************************
*
* NAME: vInit
*
* DESCRIPTION:
* Initialises the hardware
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vInit(void)
{
/* Initialise Zigbee stack */
(void)JZS_u32InitSystem(TRUE);
/* Set LED IO's to outputs */
vLedInitRfd();
vLedControl(0, TRUE);
vLedControl(1, TRUE);
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 */
(void)bBosRun(TRUE);
}
/****************************************************************************
*
* 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;
sWuart.sSystem.bStackReady = FALSE;
}
/****************************************************************************
*
* 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->u8OutClusterCount,
pAfSimpleDesc->au8OutClusterList,
pAfSimpleDesc->u8InClusterCount,
pAfSimpleDesc->au8InClusterList,
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;
APS_Addrmode_e eAddrMode;
uint16 u16DestAddr;
uint8 u8DestEndpoint;
uint8 transCount = 1;
int16 i16RxChar;
int i = 0;
bool_t bNewData = FALSE;
PRIVATE AF_Transaction_s Transaction;
PRIVATE uint8 au8Afdu[MAX_DATA_PER_FRAME];
/* specify destination node short address and endpoint */
eAddrMode = APS_ADDRMODE_SHORT;
u16DestAddr = sWuart.sSystem.u16MatchAddr;
u8DestEndpoint = 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 */
Transaction.u8SequenceNum = sWuart.sSystem.u8TxFrameHandle;
/* We want to send data to an input, so use the SET command type */
Transaction.uFrame.sKvp.eCommandTypeID = SET_ACKNOWLEDGMENT;
Transaction.uFrame.sKvp.eAttributeDataType = KVP_CHARACTER_STRING;
/* use the DATA attribute for a UART cluster, as specified in the
wireless UART private profile defined for this demo application */
Transaction.uFrame.sKvp.u16AttributeID = WUP_CID_UART_DATA;
Transaction.uFrame.sKvp.eErrorCode = 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;
}
}
/* Specify length of data portion */
memcpy(&Transaction.uFrame.sKvp.uAttributeData.CharacterString.au8CharacterData,
au8Afdu, i);
Transaction.uFrame.sKvp.uAttributeData.CharacterString.u8CharacterCount = i;
bNewData = TRUE;
}
}
/* either sending a new frame or re-sending the last one */
if (bNewData || sWuart.sSystem.bAwaitingResponse)
{
/* send KVP data request */
afdeDataRequest(eAddrMode,
u16DestAddr,
u8DestEndpoint,
u8SrcEP,
WUP_PROFILE_ID,
WUP_CID_UART,
AF_KVP,
transCount,
&Transaction,
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();
}
}
/****************************************************************************
*
* NAME: vAddDesc
*
* DESCRIPTION:
* Adds Simple descriptor
* re-sent.
*
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vAddDesc(void)
{
/* Controller has 1 endpoints, with 1 input and 1 output clusters */
uint8 u8DeviceVer = 0x00;
uint8 u8Flags = 0x00;
uint8 u8EndPoint = sWuart.sSystem.u8WuartEndpoint;
uint16 u16DeviceId = 0x0000;
/* use the same cluster ID for the input and output clusters. This means
that the output cluster from one node will match the input cluster of the
other node */
uint8 u8InputClusterCnt = 1;
uint8 au8InputClusterList[] = {WUP_CID_UART};
uint8 u8OutputClusterCnt = 1;
uint8 au8OutputClusterList[] = {WUP_CID_UART};
(void)afmeAddSimpleDesc(u8EndPoint, WUP_PROFILE_ID, u16DeviceId,
u8DeviceVer, u8Flags, u8InputClusterCnt,
au8InputClusterList, u8OutputClusterCnt,
au8OutputClusterList);
}
/****************************************************************************/
/*** END OF FILE ***/
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -