TransmitApp.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. /**************************************************************************************************
  2. Filename: TransmitApp.c
  3. Revised: $Date: 2012-03-05 09:54:49 -0800 (Mon, 05 Mar 2012) $
  4. Revision: $Revision: 29619 $
  5. Description: Transmit Application (no Profile).
  6. Copyright 2004-2012 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. This application will send a data packet to another
  35. tranmitApp device as fast as it can. The receiving
  36. transmitApp device will calculate the following transmit
  37. rate statistics:
  38. - Number bytes in the last second
  39. - Number of seconds running
  40. - Average number of bytes per second
  41. - Number of packets received.
  42. The application will send one message and as soon as it
  43. receives the confirmation for that message it will send
  44. the next message.
  45. If you would like a delay between messages
  46. define TRANSMITAPP_DELAY_SEND and set the delay amount
  47. in TRANSMITAPP_SEND_DELAY.
  48. TransmitApp_MaxDataLength defines the message size
  49. Set TRANSMITAPP_TX_OPTIONS to AF_MSG_ACK_REQUEST to send
  50. the message expecting an APS ACK, this will decrease your
  51. throughput. Set TRANSMITAPP_TX_OPTIONS to 0 for no
  52. APS ACK.
  53. This applications doesn't have a profile, so it handles
  54. everything directly - itself.
  55. Key control:
  56. SW1: Starts and stops the transmitting
  57. SW2: initiates end device binding
  58. SW3: Resets the display totals
  59. SW4: initiates a match description request
  60. Notes:
  61. This application was intended to be used to test the maximum
  62. throughput between 2 devices in a network - between routers
  63. coordinators.
  64. Although not recommended, it can be used between
  65. an end device and a router (or coordinator), but you must
  66. enable the delay feature (TRANSMITAPP_DELAY_SEND and
  67. TRANSMITAPP_SEND_DELAY). If you don't include the delay, the
  68. end device can't receive messages because it will stop polling.
  69. Also, the delay must be greater than RESPONSE_POLL_RATE (default 100 MSec).
  70. *********************************************************************/
  71. /*********************************************************************
  72. * INCLUDES
  73. */
  74. #include "OSAL.h"
  75. #include "AF.h"
  76. #include "ZDObject.h"
  77. #include "ZDProfile.h"
  78. #include "TransmitApp.h"
  79. #include "OnBoard.h"
  80. #include "DebugTrace.h"
  81. /* HAL */
  82. #include "hal_lcd.h"
  83. #include "hal_led.h"
  84. #include "hal_key.h"
  85. #include "hal_uart.h"
  86. /*********************************************************************
  87. * MACROS
  88. */
  89. /*********************************************************************
  90. * CONSTANTS
  91. */
  92. //#define TRANSMITAPP_RANDOM_LEN
  93. #define TRANSMITAPP_STATE_WAITING 0
  94. #define TRANSMITAPP_STATE_SENDING 1
  95. #if !defined ( RTR_NWK )
  96. // Use these 2 lines to add a delay between each packet sent
  97. // - default for end devices
  98. #define TRANSMITAPP_DELAY_SEND
  99. #define TRANSMITAPP_SEND_DELAY (RESPONSE_POLL_RATE * 2) // in MSecs
  100. #endif
  101. // Send with or without APS ACKs
  102. //#define TRANSMITAPP_TX_OPTIONS (AF_DISCV_ROUTE | AF_ACK_REQUEST)
  103. #define TRANSMITAPP_TX_OPTIONS AF_DISCV_ROUTE
  104. #define TRANSMITAPP_INITIAL_MSG_COUNT 2
  105. #define TRANSMITAPP_TRANSMIT_TIME 4 // 4 MS
  106. #define TRANSMITAPP_DISPLAY_TIMER (2 * 1000)
  107. #if defined ( TRANSMITAPP_FRAGMENTED )
  108. #define TRANSMITAPP_MAX_DATA_LEN 225
  109. #else
  110. #define TRANSMITAPP_MAX_DATA_LEN 102
  111. #endif
  112. /*********************************************************************
  113. * TYPEDEFS
  114. */
  115. /*********************************************************************
  116. * GLOBAL VARIABLES
  117. */
  118. // This is the buffer that is sent out as data.
  119. byte TransmitApp_Msg[ TRANSMITAPP_MAX_DATA_LEN ];
  120. // This is the Cluster ID List and should be filled with Application
  121. // specific cluster IDs.
  122. const cId_t TransmitApp_ClusterList[TRANSMITAPP_MAX_CLUSTERS] =
  123. {
  124. TRANSMITAPP_CLUSTERID_TESTMSG // MSG Cluster ID
  125. };
  126. const SimpleDescriptionFormat_t TransmitApp_SimpleDesc =
  127. {
  128. TRANSMITAPP_ENDPOINT, // int Endpoint;
  129. TRANSMITAPP_PROFID, // uint16 AppProfId[2];
  130. TRANSMITAPP_DEVICEID, // uint16 AppDeviceId[2];
  131. TRANSMITAPP_DEVICE_VERSION, // int AppDevVer:4;
  132. TRANSMITAPP_FLAGS, // int AppFlags:4;
  133. TRANSMITAPP_MAX_CLUSTERS, // byte AppNumInClusters;
  134. (cId_t *)TransmitApp_ClusterList, // byte *pAppInClusterList;
  135. TRANSMITAPP_MAX_CLUSTERS, // byte AppNumInClusters;
  136. (cId_t *)TransmitApp_ClusterList // byte *pAppInClusterList;
  137. };
  138. // This is the Endpoint/Interface description. It is defined here, but
  139. // filled-in in TransmitApp_Init(). Another way to go would be to fill
  140. // in the structure here and make it a "const" (in code space). The
  141. // way it's defined in this sample app it is define in RAM.
  142. endPointDesc_t TransmitApp_epDesc;
  143. /*********************************************************************
  144. * EXTERNAL VARIABLES
  145. */
  146. /*********************************************************************
  147. * EXTERNAL FUNCTIONS
  148. */
  149. /*********************************************************************
  150. * LOCAL VARIABLES
  151. */
  152. // Task ID for event processing - received when TransmitApp_Init() is called.
  153. byte TransmitApp_TaskID;
  154. devStates_t TransmitApp_NwkState;
  155. static byte TransmitApp_TransID; // This is the unique message ID (counter)
  156. afAddrType_t TransmitApp_DstAddr;
  157. byte TransmitApp_State;
  158. // Shadow of the OSAL system clock used for calculating actual time expired.
  159. static uint32 clkShdw;
  160. // Running total count of test messages recv/sent since beginning current run.
  161. static uint32 rxTotal, txTotal;
  162. // Running count of test messages recv/sent since last display / update - 1 Hz.
  163. static uint32 rxAccum, txAccum;
  164. static byte timerOn;
  165. static byte timesToSend;
  166. uint16 pktCounter;
  167. // Max Data Request Length
  168. uint16 TransmitApp_MaxDataLength;
  169. /*********************************************************************
  170. * LOCAL FUNCTIONS
  171. */
  172. void TransmitApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
  173. void TransmitApp_HandleKeys( byte shift, byte keys );
  174. void TransmitApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
  175. void TransmitApp_SendTheMessage( void );
  176. void TransmitApp_ChangeState( void );
  177. /*********************************************************************
  178. * NETWORK LAYER CALLBACKS
  179. */
  180. /*********************************************************************
  181. * PUBLIC FUNCTIONS
  182. */
  183. void TransmitApp_DisplayResults( void );
  184. /*********************************************************************
  185. * @fn TransmitApp_Init
  186. *
  187. * @brief Initialization function for the Generic App Task.
  188. * This is called during initialization and should contain
  189. * any application specific initialization (ie. hardware
  190. * initialization/setup, table initialization, power up
  191. * notificaiton ... ).
  192. *
  193. * @param task_id - the ID assigned by OSAL. This ID should be
  194. * used to send messages and set timers.
  195. *
  196. * @return none
  197. */
  198. void TransmitApp_Init( byte task_id )
  199. {
  200. #if !defined ( TRANSMITAPP_FRAGMENTED )
  201. afDataReqMTU_t mtu;
  202. #endif
  203. uint16 i;
  204. TransmitApp_TaskID = task_id;
  205. TransmitApp_NwkState = DEV_INIT;
  206. TransmitApp_TransID = 0;
  207. pktCounter = 0;
  208. TransmitApp_State = TRANSMITAPP_STATE_WAITING;
  209. // Device hardware initialization can be added here or in main() (Zmain.c).
  210. // If the hardware is application specific - add it here.
  211. // If the hardware is other parts of the device add it in main().
  212. TransmitApp_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
  213. TransmitApp_DstAddr.endPoint = 0;
  214. TransmitApp_DstAddr.addr.shortAddr = 0;
  215. // Fill out the endpoint description.
  216. TransmitApp_epDesc.endPoint = TRANSMITAPP_ENDPOINT;
  217. TransmitApp_epDesc.task_id = &TransmitApp_TaskID;
  218. TransmitApp_epDesc.simpleDesc
  219. = (SimpleDescriptionFormat_t *)&TransmitApp_SimpleDesc;
  220. TransmitApp_epDesc.latencyReq = noLatencyReqs;
  221. // Register the endpoint/interface description with the AF
  222. afRegister( &TransmitApp_epDesc );
  223. // Register for all key events - This app will handle all key events
  224. RegisterForKeys( TransmitApp_TaskID );
  225. // Update the display
  226. #if defined ( LCD_SUPPORTED )
  227. HalLcdWriteString( "TransmitApp", HAL_LCD_LINE_2 );
  228. #endif
  229. // Set the data length
  230. #if defined ( TRANSMITAPP_FRAGMENTED )
  231. TransmitApp_MaxDataLength = TRANSMITAPP_MAX_DATA_LEN;
  232. #else
  233. mtu.kvp = FALSE;
  234. mtu.aps.secure = FALSE;
  235. TransmitApp_MaxDataLength = afDataReqMTU( &mtu );
  236. #endif
  237. // Generate the data
  238. for (i=0; i<TransmitApp_MaxDataLength; i++)
  239. {
  240. TransmitApp_Msg[i] = (uint8) i;
  241. }
  242. ZDO_RegisterForZDOMsg( TransmitApp_TaskID, End_Device_Bind_rsp );
  243. ZDO_RegisterForZDOMsg( TransmitApp_TaskID, Match_Desc_rsp );
  244. }
  245. /*********************************************************************
  246. * @fn TransmitApp_ProcessEvent
  247. *
  248. * @brief Generic Application Task event processor. This function
  249. * is called to process all events for the task. Events
  250. * include timers, messages and any other user defined events.
  251. *
  252. * @param task_id - The OSAL assigned task ID.
  253. * @param events - events to process. This is a bit map and can
  254. * contain more than one event.
  255. *
  256. * @return none
  257. */
  258. UINT16 TransmitApp_ProcessEvent( byte task_id, UINT16 events )
  259. {
  260. afIncomingMSGPacket_t *MSGpkt;
  261. afDataConfirm_t *afDataConfirm;
  262. (void)task_id; // Intentionally unreferenced parameter
  263. // Data Confirmation message fields
  264. ZStatus_t sentStatus;
  265. byte sentEP;
  266. if ( events & SYS_EVENT_MSG )
  267. {
  268. MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TransmitApp_TaskID );
  269. while ( MSGpkt )
  270. {
  271. switch ( MSGpkt->hdr.event )
  272. {
  273. case ZDO_CB_MSG:
  274. TransmitApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
  275. break;
  276. case KEY_CHANGE:
  277. TransmitApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
  278. break;
  279. case AF_DATA_CONFIRM_CMD:
  280. // This message is received as a confirmation of a data packet sent.
  281. // The status is of ZStatus_t type [defined in ZComDef.h]
  282. // The message fields are defined in AF.h
  283. afDataConfirm = (afDataConfirm_t *)MSGpkt;
  284. sentEP = afDataConfirm->endpoint;
  285. sentStatus = afDataConfirm->hdr.status;
  286. if ( (ZSuccess == sentStatus) &&
  287. (TransmitApp_epDesc.endPoint == sentEP) )
  288. {
  289. #if !defined ( TRANSMITAPP_RANDOM_LEN )
  290. txAccum += TransmitApp_MaxDataLength;
  291. #endif
  292. if ( !timerOn )
  293. {
  294. osal_start_timerEx( TransmitApp_TaskID,TRANSMITAPP_RCVTIMER_EVT,
  295. TRANSMITAPP_DISPLAY_TIMER);
  296. clkShdw = osal_GetSystemClock();
  297. timerOn = TRUE;
  298. }
  299. }
  300. // Action taken when confirmation is received: Send the next message.
  301. TransmitApp_SetSendEvt();
  302. break;
  303. case AF_INCOMING_MSG_CMD:
  304. TransmitApp_MessageMSGCB( MSGpkt );
  305. break;
  306. case ZDO_STATE_CHANGE:
  307. TransmitApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
  308. break;
  309. default:
  310. break;
  311. }
  312. // Release the memory
  313. osal_msg_deallocate( (uint8 *)MSGpkt );
  314. // Next
  315. MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TransmitApp_TaskID );
  316. }
  317. // Squash compiler warnings until values are used.
  318. (void)sentStatus;
  319. (void)sentEP;
  320. // Return unprocessed events
  321. return (events ^ SYS_EVENT_MSG);
  322. }
  323. // Send a message out
  324. if ( events & TRANSMITAPP_SEND_MSG_EVT )
  325. {
  326. if ( TransmitApp_State == TRANSMITAPP_STATE_SENDING )
  327. {
  328. TransmitApp_SendTheMessage();
  329. }
  330. // Return unprocessed events
  331. return (events ^ TRANSMITAPP_SEND_MSG_EVT);
  332. }
  333. // Timed wait from error
  334. if ( events & TRANSMITAPP_SEND_ERR_EVT )
  335. {
  336. TransmitApp_SetSendEvt();
  337. // Return unprocessed events
  338. return (events ^ TRANSMITAPP_SEND_ERR_EVT);
  339. }
  340. // Receive timer
  341. if ( events & TRANSMITAPP_RCVTIMER_EVT )
  342. {
  343. // Setup to display the next result
  344. osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT,
  345. TRANSMITAPP_DISPLAY_TIMER );
  346. TransmitApp_DisplayResults();
  347. return (events ^ TRANSMITAPP_RCVTIMER_EVT);
  348. }
  349. // Discard unknown events
  350. return 0;
  351. }
  352. /*********************************************************************
  353. * Event Generation Functions
  354. */
  355. /*********************************************************************
  356. * @fn TransmitApp_ProcessZDOMsgs()
  357. *
  358. * @brief Process response messages
  359. *
  360. * @param none
  361. *
  362. * @return none
  363. */
  364. void TransmitApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
  365. {
  366. switch ( inMsg->clusterID )
  367. {
  368. case End_Device_Bind_rsp:
  369. if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
  370. {
  371. // Light LED
  372. HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
  373. }
  374. #if defined(BLINK_LEDS)
  375. else
  376. {
  377. // Flash LED to show failure
  378. HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );
  379. }
  380. #endif
  381. break;
  382. case Match_Desc_rsp:
  383. {
  384. ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
  385. if ( pRsp )
  386. {
  387. if ( pRsp->status == ZSuccess && pRsp->cnt )
  388. {
  389. TransmitApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
  390. TransmitApp_DstAddr.addr.shortAddr = pRsp->nwkAddr;
  391. // Take the first endpoint, Can be changed to search through endpoints
  392. TransmitApp_DstAddr.endPoint = pRsp->epList[0];
  393. // Light LED
  394. HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
  395. }
  396. osal_mem_free( pRsp );
  397. }
  398. }
  399. break;
  400. }
  401. }
  402. /*********************************************************************
  403. * @fn TransmitApp_HandleKeys
  404. *
  405. * @brief Handles all key events for this device.
  406. *
  407. * @param shift - true if in shift/alt.
  408. * @param keys - bit field for key events. Valid entries:
  409. * EVAL_SW4
  410. * EVAL_SW3
  411. * EVAL_SW2
  412. * EVAL_SW1
  413. *
  414. * @return none
  415. */
  416. void TransmitApp_HandleKeys( byte shift, byte keys )
  417. {
  418. zAddrType_t dstAddr;
  419. // Shift is used to make each button/switch dual purpose.
  420. if ( shift )
  421. {
  422. if ( keys & HAL_KEY_SW_1 )
  423. {
  424. }
  425. if ( keys & HAL_KEY_SW_2 )
  426. {
  427. }
  428. if ( keys & HAL_KEY_SW_3 )
  429. {
  430. }
  431. if ( keys & HAL_KEY_SW_4 )
  432. {
  433. }
  434. }
  435. else
  436. {
  437. if ( keys & HAL_KEY_SW_1 )
  438. {
  439. TransmitApp_ChangeState();
  440. }
  441. if ( keys & HAL_KEY_SW_2 )
  442. {
  443. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  444. // Initiate an End Device Bind Request for the mandatory endpoint
  445. dstAddr.addrMode = Addr16Bit;
  446. dstAddr.addr.shortAddr = 0x0000; // Coordinator
  447. ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
  448. TransmitApp_epDesc.endPoint,
  449. TRANSMITAPP_PROFID,
  450. TRANSMITAPP_MAX_CLUSTERS, (cId_t *)TransmitApp_ClusterList,
  451. TRANSMITAPP_MAX_CLUSTERS, (cId_t *)TransmitApp_ClusterList,
  452. FALSE );
  453. }
  454. if ( keys & HAL_KEY_SW_3 )
  455. {
  456. rxTotal = txTotal = 0;
  457. rxAccum = txAccum = 0;
  458. TransmitApp_DisplayResults();
  459. }
  460. if ( keys & HAL_KEY_SW_4 )
  461. {
  462. HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
  463. // Initiate a Match Description Request (Service Discovery)
  464. dstAddr.addrMode = AddrBroadcast;
  465. dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
  466. ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
  467. TRANSMITAPP_PROFID,
  468. TRANSMITAPP_MAX_CLUSTERS, (cId_t *)TransmitApp_ClusterList,
  469. TRANSMITAPP_MAX_CLUSTERS, (cId_t *)TransmitApp_ClusterList,
  470. FALSE );
  471. }
  472. }
  473. }
  474. /*********************************************************************
  475. * LOCAL FUNCTIONS
  476. */
  477. /*********************************************************************
  478. * @fn TransmitApp_MessageMSGCB
  479. *
  480. * @brief Data message processor callback. This function processes
  481. * any incoming data - probably from other devices. So, based
  482. * on cluster ID, perform the intended action.
  483. *
  484. * @param none
  485. *
  486. * @return none
  487. */
  488. void TransmitApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
  489. {
  490. uint16 i;
  491. uint8 error = FALSE;
  492. switch ( pkt->clusterId )
  493. {
  494. case TRANSMITAPP_CLUSTERID_TESTMSG:
  495. #if !defined ( TRANSMITAPP_RANDOM_LEN )
  496. if (pkt->cmd.DataLength != TransmitApp_MaxDataLength)
  497. {
  498. error = TRUE;
  499. }
  500. #endif
  501. for (i=4; i<pkt->cmd.DataLength; i++)
  502. {
  503. if (pkt->cmd.Data[i] != i%256)
  504. error = TRUE;
  505. }
  506. if (error)
  507. {
  508. // Display error LED
  509. HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);
  510. }
  511. else
  512. {
  513. if ( !timerOn )
  514. {
  515. osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT,
  516. TRANSMITAPP_DISPLAY_TIMER );
  517. clkShdw = osal_GetSystemClock();
  518. timerOn = TRUE;
  519. }
  520. rxAccum += pkt->cmd.DataLength;
  521. }
  522. break;
  523. // Could receive control messages in the future.
  524. default:
  525. break;
  526. }
  527. }
  528. /*********************************************************************
  529. * @fn TransmitApp_SendTheMessage
  530. *
  531. * @brief Send "the" message.
  532. *
  533. * @param none
  534. *
  535. * @return none
  536. */
  537. void TransmitApp_SendTheMessage( void )
  538. {
  539. uint16 len;
  540. uint8 tmp;
  541. do {
  542. // put the sequence number in the message
  543. tmp = HI_UINT8( TransmitApp_TransID );
  544. tmp += (tmp <= 9) ? ('0') : ('A' - 0x0A);
  545. TransmitApp_Msg[2] = tmp;
  546. tmp = LO_UINT8( TransmitApp_TransID );
  547. tmp += (tmp <= 9) ? ('0') : ('A' - 0x0A);
  548. TransmitApp_Msg[3] = tmp;
  549. len = TransmitApp_MaxDataLength;
  550. #if defined ( TRANSMITAPP_RANDOM_LEN )
  551. len = (uint8)(osal_rand() & 0x7F);
  552. if( len > TransmitApp_MaxDataLength || len == 0 )
  553. len = TransmitApp_MaxDataLength;
  554. else if ( len < 4 )
  555. len = 4;
  556. #endif
  557. tmp = AF_DataRequest( &TransmitApp_DstAddr, &TransmitApp_epDesc,
  558. TRANSMITAPP_CLUSTERID_TESTMSG,
  559. len, TransmitApp_Msg,
  560. &TransmitApp_TransID,
  561. TRANSMITAPP_TX_OPTIONS,
  562. AF_DEFAULT_RADIUS );
  563. #if defined ( TRANSMITAPP_RANDOM_LEN )
  564. if ( tmp == afStatus_SUCCESS )
  565. {
  566. txAccum += len;
  567. }
  568. #endif
  569. if ( timesToSend )
  570. {
  571. timesToSend--;
  572. }
  573. } while ( (timesToSend != 0) && (afStatus_SUCCESS == tmp) );
  574. if ( afStatus_SUCCESS == tmp )
  575. {
  576. pktCounter++;
  577. }
  578. else
  579. {
  580. // Error, so wait (10 mSec) and try again.
  581. osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_SEND_ERR_EVT, 10 );
  582. }
  583. }
  584. /*********************************************************************
  585. * @fn TransmitApp_ChangeState
  586. *
  587. * @brief Toggle the Sending/Waiting state flag
  588. *
  589. * @param none
  590. *
  591. * @return none
  592. */
  593. void TransmitApp_ChangeState( void )
  594. {
  595. if ( TransmitApp_State == TRANSMITAPP_STATE_WAITING )
  596. {
  597. TransmitApp_State = TRANSMITAPP_STATE_SENDING;
  598. TransmitApp_SetSendEvt();
  599. timesToSend = TRANSMITAPP_INITIAL_MSG_COUNT;
  600. }
  601. else
  602. {
  603. TransmitApp_State = TRANSMITAPP_STATE_WAITING;
  604. }
  605. }
  606. /*********************************************************************
  607. * @fn TransmitApp_SetSendEvt
  608. *
  609. * @brief Set the event flag
  610. *
  611. * @param none
  612. *
  613. * @return none
  614. */
  615. void TransmitApp_SetSendEvt( void )
  616. {
  617. #if defined( TRANSMITAPP_DELAY_SEND )
  618. // Adds a delay to sending the data
  619. osal_start_timerEx( TransmitApp_TaskID,
  620. TRANSMITAPP_SEND_MSG_EVT, TRANSMITAPP_SEND_DELAY );
  621. #else
  622. // No Delay - just send the data
  623. osal_set_event( TransmitApp_TaskID, TRANSMITAPP_SEND_MSG_EVT );
  624. #endif
  625. }
  626. /*********************************************************************
  627. * @fn TransmitApp_DisplayResults
  628. *
  629. * @brief Display the results and clear the accumulators
  630. *
  631. * @param none
  632. *
  633. * @return none
  634. */
  635. void TransmitApp_DisplayResults( void )
  636. {
  637. #ifdef LCD_SUPPORTED
  638. #define LCD_W 16
  639. uint32 rxShdw, txShdw, tmp;
  640. byte lcd_buf[LCD_W+1];
  641. byte idx;
  642. #endif
  643. // The OSAL timers are not real-time, so calculate the actual time expired.
  644. uint32 msecs = osal_GetSystemClock() - clkShdw;
  645. clkShdw = osal_GetSystemClock();
  646. rxTotal += rxAccum;
  647. txTotal += txAccum;
  648. #if defined ( LCD_SUPPORTED )
  649. rxShdw = (rxAccum * 1000 + msecs/2) / msecs;
  650. txShdw = (txAccum * 1000 + msecs/2) / msecs;
  651. osal_memset( lcd_buf, ' ', LCD_W );
  652. lcd_buf[LCD_W] = NULL;
  653. idx = 4;
  654. tmp = (rxShdw >= 100000) ? 99999 : rxShdw;
  655. do
  656. {
  657. lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
  658. tmp /= 10;
  659. } while ( tmp );
  660. idx = LCD_W-1;
  661. tmp = rxTotal;
  662. do
  663. {
  664. lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
  665. tmp /= 10;
  666. } while ( tmp );
  667. HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_1 );
  668. osal_memset( lcd_buf, ' ', LCD_W );
  669. idx = 4;
  670. tmp = (txShdw >= 100000) ? 99999 : txShdw;
  671. do
  672. {
  673. lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
  674. tmp /= 10;
  675. } while ( tmp );
  676. idx = LCD_W-1;
  677. tmp = txTotal;
  678. do
  679. {
  680. lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
  681. tmp /= 10;
  682. } while ( tmp );
  683. HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_2 );
  684. #elif defined( MT_TASK )
  685. DEBUG_INFO( COMPID_APP, SEVERITY_INFORMATION, 3,
  686. rxAccum, (uint16)msecs, (uint16)rxTotal );
  687. #else
  688. (void)msecs; // Not used when no output
  689. #endif
  690. if ( (rxAccum == 0) && (txAccum == 0) )
  691. {
  692. osal_stop_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT );
  693. timerOn = FALSE;
  694. }
  695. rxAccum = txAccum = 0;
  696. }
  697. /*********************************************************************
  698. *********************************************************************/