Back to Peer-to-peer sample application.
00001 00017 /****************************************************************************** 00018 Includes section 00019 ******************************************************************************/ 00020 #include <types.h> 00021 #include <configServer.h> 00022 #include <appTimer.h> 00023 #include <zdo.h> 00024 #include <peer2peer.h> 00025 #include <serialInterface.h> 00026 00027 /****************************************************************************** 00028 Define(s) section 00029 ******************************************************************************/ 00030 00031 /****************************************************************************** 00032 Variables section 00033 ******************************************************************************/ 00034 // Network related variables 00035 static uint16_t nwkAddr; // Own NWK address 00036 static AppMessageBuffer_t appMessageBuffer; // Application message buffer 00037 static uint8_t messageIdTx = 0; // Application transmitted message ID 00038 static uint8_t messageIdRx = 0; // Application received message ID 00039 static bool messageIdRxValid = false; // Application received message ID valid flag 00040 static uint8_t actualDataLength = 0; // Actual data length to be transmitted via network 00041 00042 // Temporary data received via network buffer 00043 static uint8_t tmpDataBuffer[APP_TMP_DATA_BUFFER_SIZE]; 00044 static uint8_t tmpDataBufferActualLength = 0; 00045 00046 // UART related variables 00047 static HAL_UartDescriptor_t appUartDescriptor; // UART descriptor (required by stack) 00048 static bool uartTxBusyFlag = false; // UART transmission transaction status 00049 static uint8_t uartTxBuffer[APP_UART_TX_BUFFER_SIZE]; // UART Tx buffer 00050 static uint8_t uartRxBuffer[APP_UART_RX_BUFFER_SIZE]; // UART Rx buffer 00051 static uint8_t uartRxPending = 0; 00052 00053 static AppState_t appState = APP_INITIAL_STATE; // application state 00054 static AppDataTransmission_t appDataTransmissionState = APP_DATA_TRANSMISSION_IDLE_STATE; //application data transmission feature state 00055 static ZDO_StartNetworkReq_t networkParams; // request params for ZDO_StartNetworkReq 00056 static APS_DataReq_t apsDataReq; 00057 00058 // endpoint parameters 00059 static SimpleDescriptor_t simpleDescriptor = { APP_ENDPOINT, APP_PROFILE_ID, 1, 1, 0, 0 , NULL, 0, NULL }; 00060 static APS_RegisterEndpointReq_t endpointParams; 00061 00062 // Timer indicating starting network during network joining. 00063 // Also used as delay timer between APS_DataConf and APS_DataReq. 00064 static HAL_AppTimer_t delayTimer; 00065 00066 /*********************************************************************************** 00067 Static functions declarations section 00068 ***********************************************************************************/ 00069 static void APS_DataIndication(APS_DataInd_t* dataInd); 00070 static void APS_DataConf(APS_DataConf_t* confInfo); 00071 static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t* confirmInfo); 00072 static void initNetwork(void); 00073 static void startNetwork(void); 00074 static void networkSendData(bool newTransmission); 00075 static void startBlinkTimer(void); 00076 static void initSerialInterface(void); 00077 static void sendDataToUart(uint8_t*, uint8_t); 00078 static void startingNetworkTimerFired(void); 00079 static void delayTimerFired(void); 00080 static void uartBytesReceived(uint8_t readBytesLen); 00081 static void uartWriteConf(void); 00082 static void buttonReleased(uint8_t buttons); 00083 00084 /*********************************************************************************** 00085 Implementation section 00086 ***********************************************************************************/ 00087 /**************************************************************************/ 00093 void APL_TaskHandler(void) 00094 { 00095 switch (appState) 00096 { 00097 case APP_INITIAL_STATE: // Node has initial state 00098 initSerialInterface(); // Open UART 00099 appOpenButtons(NULL, buttonReleased); // Open buttons 00100 appOpenLeds(); // Enable LEDs 00101 initNetwork(); 00102 SYS_PostTask(APL_TASK_ID); // Execute next step 00103 break; 00104 00105 case APP_NETWORK_JOINING_STATE: 00106 startBlinkTimer(); 00107 startNetwork(); 00108 break; 00109 00110 case APP_NETWORK_JOINED_STATE: 00111 default: 00112 break; 00113 } 00114 } 00115 00116 /**************************************************************************/ 00122 static void initNetwork(void) 00123 { 00124 DeviceType_t deviceType = DEVICE_TYPE_ROUTER; 00125 ExtAddr_t extAddr = APP_COORD_UID; 00126 00127 #ifndef _SLIDERS_ 00128 // NWK preconfigured address reading for Config Server 00129 CS_ReadParameter(CS_NWK_ADDR_ID, &nwkAddr); 00130 #else //#ifndef _SLIDERS_ 00131 // NWK address reading from sliders 00132 nwkAddr = BSP_ReadSliders(); 00133 // Set the NWK address value to Config Server 00134 CS_WriteParameter(CS_NWK_ADDR_ID, &nwkAddr); 00135 #endif //#ifndef _SLIDERS_ 00136 00137 //NWK address value check 00138 if (APP_MAX_NWK_ADDR < nwkAddr) 00139 { 00140 appState = APP_ERROR_STATE; 00141 } 00142 else 00143 { 00144 // Node role detection. If nwkAddr == 0 then node is coordinator. 00145 // In othe case the node role is router. 00146 if (0 == nwkAddr) 00147 { 00148 deviceType = DEVICE_TYPE_COORDINATOR; 00149 // Set the extended address value to Config Server for coordinator only 00150 CS_WriteParameter(CS_UID_ID, &extAddr); 00151 } 00152 // Set the deviceType value to Config Server 00153 CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType); 00154 00155 // Application state changing 00156 appState = APP_NETWORK_JOINING_STATE; 00157 } 00158 } 00159 00160 /**************************************************************************/ 00166 void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t* confirmInfo) 00167 { 00168 if (confirmInfo->status == ZDO_SUCCESS_STATUS) 00169 { 00170 appState = APP_NETWORK_JOINED_STATE; 00171 actualDataLength = 0; 00172 messageIdRxValid = false; 00173 uartRxPending = 0; 00174 00175 // Stop the blink timer 00176 HAL_StopAppTimer(&delayTimer); 00177 appOnLed(APP_NETWORK_STATUS_LED); 00178 00179 #if APP_DATA_TRANSMISSION_DELAY 00180 // Setup timer to be used as delay timer between APS_DataConf and APS_DataReq. 00181 delayTimer.interval = APP_DATA_TRANSMISSION_DELAY; 00182 delayTimer.mode = TIMER_ONE_SHOT_MODE; 00183 delayTimer.callback = delayTimerFired; 00184 #endif 00185 00186 // Set application endpoint properties 00187 endpointParams.simpleDescriptor = &simpleDescriptor; 00188 endpointParams.APS_DataInd = APS_DataIndication; 00189 // Register endpoint 00190 APS_RegisterEndpointReq(&endpointParams); 00191 } 00192 else 00193 { 00194 SYS_PostTask(APL_TASK_ID); 00195 } 00196 } 00197 00198 /**************************************************************************/ 00204 static void startNetwork(void) 00205 { 00206 networkParams.ZDO_StartNetworkConf = ZDO_StartNetworkConf; 00207 // start network 00208 ZDO_StartNetworkReq(&networkParams); 00209 } 00210 00211 /**************************************************************************/ 00217 static void startBlinkTimer(void) 00218 { 00219 delayTimer.interval = APP_JOINING_INDICATION_PERIOD; 00220 delayTimer.mode = TIMER_REPEAT_MODE; 00221 delayTimer.callback = startingNetworkTimerFired; 00222 HAL_StartAppTimer(&delayTimer); 00223 } 00224 00225 /**************************************************************************/ 00231 static void startingNetworkTimerFired(void) 00232 { 00233 appToggleLed(APP_NETWORK_STATUS_LED); 00234 } 00235 00236 /**************************************************************************/ 00242 void ZDO_MgmtNwkUpdateNotf(ZDO_MgmtNwkUpdateNotf_t *nwkParams) 00243 { 00244 switch (nwkParams->status) 00245 { 00246 case ZDO_NETWORK_STARTED_STATUS: 00247 break; 00248 00249 case ZDO_NETWORK_LOST_STATUS: 00250 // case ZDO_REJOIN_STARTED_STATUS: 00251 { 00252 APS_UnregisterEndpointReq_t unregEndpoint; 00253 if (APP_NETWORK_JOINED_STATE == appState) 00254 { 00255 unregEndpoint.endpoint = endpointParams.simpleDescriptor->endpoint; 00256 APS_UnregisterEndpointReq(&unregEndpoint); 00257 } 00258 appOffLed(APP_NETWORK_STATUS_LED); 00259 00260 // try to rejoin the network 00261 appState = APP_NETWORK_JOINING_STATE; 00262 SYS_PostTask(APL_TASK_ID); 00263 break; 00264 } 00265 00266 case ZDO_NWK_UPDATE_STATUS: 00267 break; 00268 00269 default: 00270 break; 00271 } 00272 } 00273 00274 /**************************************************************************/ 00280 void ZDO_WakeUpInd(void) 00281 { 00282 } 00283 00284 /**************************************************************************/ 00290 void ZDO_SleepInd(void) 00291 { 00292 } 00293 00294 /**************************************************************************/ 00301 static void networkSendData(bool newTransmission) 00302 { 00303 if (APP_DATA_TRANSMISSION_IDLE_STATE == appDataTransmissionState) 00304 { 00305 appDataTransmissionState = APP_DATA_TRANSMISSION_BUSY_STATE; 00306 // indicate we're sending 00307 appOnLed(APP_SENDING_STATUS_LED); 00308 00309 if (newTransmission) 00310 { 00311 // The new applicatiom message will be sent 00312 // messageId value 00313 appMessageBuffer.message.messageId = messageIdTx++; 00314 // APS Data Request preparing 00315 apsDataReq.dstAddrMode = APS_SHORT_ADDRESS; // Short addressing mode 00316 // Destination address 00317 apsDataReq.dstAddress.shortAddress = (nwkAddr & 0xfffe) | ((~nwkAddr) & 0x01); 00318 apsDataReq.profileId = simpleDescriptor.AppProfileId; // Profile ID 00319 apsDataReq.dstEndpoint = simpleDescriptor.endpoint; // Desctination endpoint 00320 apsDataReq.clusterId = APP_CLUSTER_ID; // Desctination cluster ID 00321 apsDataReq.srcEndpoint = simpleDescriptor.endpoint; // Source endpoint 00322 apsDataReq.asdu = (uint8_t*) &appMessageBuffer.message; // application message pointer 00323 // actual application message length 00324 apsDataReq.asduLength = actualDataLength + sizeof(appMessageBuffer.message.messageId); 00325 apsDataReq.txOptions.acknowledgedTransmission = 1; // Acknowledged transmission enabled 00326 apsDataReq.radius = 0; // Default radius 00327 apsDataReq.APS_DataConf = APS_DataConf; // Confirm handler 00328 } 00329 00330 // send data request 00331 APS_DataReq(&apsDataReq); 00332 } 00333 } 00334 00335 /**************************************************************************/ 00341 void APS_DataConf(APS_DataConf_t* confInfo) 00342 { 00343 appOffLed(APP_SENDING_STATUS_LED); 00344 00345 if (APS_SUCCESS_STATUS == confInfo->status) // data delivered 00346 { 00347 #if APP_DATA_TRANSMISSION_DELAY 00348 // Start delay timer. This timer is used to prevent collisions in duplex mode. 00349 HAL_StartAppTimer(&delayTimer); 00350 #else 00351 // No delay needed. 00352 delayTimerFired(); 00353 #endif 00354 } 00355 else // data not delivered, resend 00356 { 00357 appDataTransmissionState = APP_DATA_TRANSMISSION_IDLE_STATE; 00358 networkSendData(false); // Current application message retransmission 00359 } 00360 } 00361 00362 /**************************************************************************/ 00368 static void delayTimerFired(void) 00369 { 00370 appDataTransmissionState = APP_DATA_TRANSMISSION_IDLE_STATE; 00371 00372 appOffLed(APP_SENDING_STATUS_LED); 00373 00374 if (uartRxPending > 0) 00375 uartBytesReceived(uartRxPending); 00376 } 00377 00378 /**************************************************************************/ 00384 void APS_DataIndication(APS_DataInd_t* indData) 00385 { 00386 AppMessage_t *appMessage = (AppMessage_t *) indData->asdu; 00387 00388 // Data received indication 00389 appOnLed(APP_RECEIVING_STATUS_LED); 00390 00391 if ((false == messageIdRxValid) || 00392 (messageIdRx != appMessage->messageId)) 00393 { 00394 messageIdRxValid = true; 00395 messageIdRx = appMessage->messageId; 00396 // write received data to UART 00397 sendDataToUart(appMessage->data, indData->asduLength - 1); 00398 } 00399 appOffLed(APP_RECEIVING_STATUS_LED); 00400 } 00401 00402 /**************************************************************************/ 00408 static void initSerialInterface(void) 00409 { 00410 uartTxBusyFlag = false; 00411 00412 appUartDescriptor.tty = UART_CHANNEL; 00413 appUartDescriptor.mode = ASYNC; 00414 appUartDescriptor.baudrate = UART_BAUDRATE_38400; 00415 appUartDescriptor.dataLength = UART_DATA8; 00416 appUartDescriptor.parity = UART_PARITY_NONE; 00417 appUartDescriptor.stopbits = UART_STOPBIT_1; 00418 appUartDescriptor.rxBuffer = uartRxBuffer; 00419 appUartDescriptor.rxBufferLength = sizeof(uartRxBuffer); 00420 appUartDescriptor.txBuffer = NULL; // use callback mode 00421 appUartDescriptor.txBufferLength = 0; 00422 appUartDescriptor.rxCallback = uartBytesReceived; 00423 appUartDescriptor.txCallback = uartWriteConf; 00424 appUartDescriptor.flowControl = UART_FLOW_CONTROL_HARDWARE; 00425 OPEN_UART(&appUartDescriptor); 00426 } 00427 00428 /**************************************************************************/ 00435 static void sendDataToUart(uint8_t* data, uint8_t length) 00436 { 00437 if (APP_TMP_DATA_BUFFER_SIZE > tmpDataBufferActualLength + length) 00438 { 00439 memcpy(&tmpDataBuffer[tmpDataBufferActualLength], data, length); 00440 tmpDataBufferActualLength += length; 00441 // If there are no space in tmp Buffer for future messages receive 00442 } 00443 00444 if (false == uartTxBusyFlag) 00445 { 00446 uartWriteConf(); 00447 } 00448 00449 // If there are no space in tmp Buffer for future messages receive 00450 if (APP_TMP_DATA_BUFFER_SIZE < tmpDataBufferActualLength + APP_MAX_DATA_SIZE) 00451 { 00452 APS_StopEndpointIndication(APP_ENDPOINT); // Disable APS Data Indications 00453 } 00454 } 00455 00456 /**************************************************************************/ 00462 static void uartWriteConf(void) 00463 { 00464 int bytesWritten; 00465 00466 if (0 < tmpDataBufferActualLength) // data waiting to be written to UART 00467 { 00468 memcpy(uartTxBuffer, tmpDataBuffer, tmpDataBufferActualLength); 00469 bytesWritten = WRITE_UART(&appUartDescriptor, uartTxBuffer, tmpDataBufferActualLength); 00470 if (0 < bytesWritten) 00471 { 00472 tmpDataBufferActualLength -= bytesWritten; 00473 uartTxBusyFlag = true; 00474 } 00475 } 00476 else 00477 { 00478 uartTxBusyFlag = false; 00479 APS_ResumeEndpointIndication(APP_ENDPOINT); // Enable APS Data Indications 00480 } 00481 } 00482 00483 /**************************************************************************/ 00489 static void uartBytesReceived(uint8_t bytesToRead) 00490 { 00491 if (APP_NETWORK_JOINED_STATE == appState) 00492 { 00493 uartRxPending = bytesToRead; 00494 00495 if (APP_DATA_TRANSMISSION_IDLE_STATE == appDataTransmissionState) 00496 { 00497 if (APP_MAX_DATA_SIZE < bytesToRead) 00498 bytesToRead = APP_MAX_DATA_SIZE; 00499 00500 // Read data from UART 00501 actualDataLength = (uint8_t) READ_UART(&appUartDescriptor, appMessageBuffer.message.data, bytesToRead); 00502 00503 networkSendData(true); 00504 00505 uartRxPending -= bytesToRead; 00506 } 00507 } 00508 } 00509 00510 /**************************************************************************/ 00516 static void buttonReleased(uint8_t aButton) 00517 { 00518 switch (aButton) 00519 { 00520 case BSP_KEY0: // SW1 pressed 00521 if ((APP_NETWORK_JOINED_STATE == appState) && 00522 (APP_DATA_TRANSMISSION_IDLE_STATE == appDataTransmissionState)) 00523 { 00524 // Fill the buffer with some data and send it 00525 memset(&appMessageBuffer.message.data, 0xdd, APP_MAX_DATA_SIZE); 00526 actualDataLength = APP_MAX_DATA_SIZE; 00527 networkSendData(true); 00528 break; 00529 } 00530 00531 default: 00532 break; 00533 } 00534 } 00535 00536 // eof peer2Peer.c