znp_app.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /**************************************************************************************************
  2. Filename: znp_app.c
  3. Revised: $Date: 2011-06-01 14:52:32 -0700 (Wed, 01 Jun 2011) $
  4. Revision: $Revision: 26173 $
  5. Description: This file is the Application implementation for the ZNP.
  6. Copyright 2009-2011 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. * Includes
  35. * ------------------------------------------------------------------------------------------------
  36. */
  37. #include "hal_board_cfg.h"
  38. #include "mac_radio_defs.h"
  39. #include "MT.h"
  40. #include "MT_AF.h"
  41. #include "MT_SYS.h"
  42. #include "MT_ZDO.h"
  43. #include "MT_UART.h"
  44. #include "MT_UTIL.h"
  45. #include "OSAL.h"
  46. #include "OSAL_Nv.h"
  47. #if defined POWER_SAVING || defined CC2531ZNP
  48. #include "OSAL_PwrMgr.h"
  49. #endif
  50. #include "ZComDef.h"
  51. #include "ZMAC.h"
  52. #include "znp_app.h"
  53. #include "znp_spi.h"
  54. /* ------------------------------------------------------------------------------------------------
  55. * Local Functions
  56. * ------------------------------------------------------------------------------------------------
  57. */
  58. static void npInit(void);
  59. static void npInitNV(void);
  60. static void npUartCback(uint8 port, uint8 event);
  61. static void npUartTxReady(void);
  62. static uint8* npMtUartAlloc(uint8 cmd0, uint8 len);
  63. static void npMtUartSend(uint8 *pBuf);
  64. #if !defined CC2531ZNP
  65. static uint8* npMtSpiAlloc(uint8 cmd0, uint8 len);
  66. static void npMtSpiSend(uint8 *pBuf);
  67. uint8* npSpiPollCallback(void);
  68. bool npSpiReadyCallback(void);
  69. #endif
  70. /* ------------------------------------------------------------------------------------------------
  71. * Local Variables
  72. * ------------------------------------------------------------------------------------------------
  73. */
  74. static osal_msg_q_t npTxQueue;
  75. /* ------------------------------------------------------------------------------------------------
  76. * Global Variables
  77. * ------------------------------------------------------------------------------------------------
  78. */
  79. uint8 znpCfg1;
  80. uint8 znpCfg0;
  81. #if defined TC_LINKKEY_JOIN
  82. extern uint8 zcl_TaskID;
  83. extern void zclProcessMessageMSG(afIncomingMSGPacket_t *pkt);
  84. #endif
  85. /**************************************************************************************************
  86. * @fn znpInit
  87. *
  88. * @brief This function is the OSAL task initialization callback.
  89. *
  90. * input parameters
  91. *
  92. * @param taskId - The task ID assigned to this task by the OSAL.
  93. *
  94. * output parameters
  95. *
  96. * None.
  97. *
  98. * @return None.
  99. **************************************************************************************************
  100. */
  101. void znpInit(uint8 taskId)
  102. {
  103. znpTaskId = taskId;
  104. osal_set_event(taskId, ZNP_SECONDARY_INIT_EVENT);
  105. }
  106. /**************************************************************************************************
  107. * @fn znpEventLoop
  108. *
  109. * @brief This function processes the OSAL events and messages for the application.
  110. *
  111. * input parameters
  112. *
  113. * @param taskId - The task ID assigned to this application by OSAL at system initialization.
  114. * @param events - A bit mask of the pending event(s).
  115. *
  116. * output parameters
  117. *
  118. * None.
  119. *
  120. * @return The events bit map received via parameter with the bits cleared which correspond to
  121. * the event(s) that were processed on this invocation.
  122. **************************************************************************************************
  123. */
  124. uint16 znpEventLoop(uint8 taskId, uint16 events)
  125. {
  126. osal_event_hdr_t *pMsg;
  127. #if !defined CC2531ZNP
  128. uint8 *pBuf;
  129. #endif
  130. if (events & SYS_EVENT_MSG)
  131. {
  132. if ((pMsg = (osal_event_hdr_t *) osal_msg_receive(znpTaskId)) != NULL)
  133. {
  134. switch (pMsg->event)
  135. {
  136. /* incoming message from UART transport */
  137. case CMD_SERIAL_MSG:
  138. MT_ProcessIncoming(((mtOSALSerialData_t *)pMsg)->msg);
  139. break;
  140. #if defined TC_LINKKEY_JOIN
  141. #if defined (MT_UTIL_FUNC)
  142. case ZCL_KEY_ESTABLISH_IND:
  143. MT_UtilKeyEstablishInd((keyEstablishmentInd_t *)pMsg);
  144. break;
  145. #endif
  146. #endif
  147. case AF_INCOMING_MSG_CMD:
  148. #if defined TC_LINKKEY_JOIN
  149. if (ZCL_KEY_ESTABLISHMENT_ENDPOINT == (((afIncomingMSGPacket_t *)pMsg)->endPoint))
  150. {
  151. zclProcessMessageMSG((afIncomingMSGPacket_t *)pMsg);
  152. }
  153. else
  154. #endif
  155. {
  156. MT_AfIncomingMsg((afIncomingMSGPacket_t *)pMsg);
  157. }
  158. break;
  159. #ifdef MT_ZDO_FUNC
  160. case ZDO_STATE_CHANGE:
  161. MT_ZdoStateChangeCB(pMsg);
  162. break;
  163. case ZDO_CB_MSG:
  164. MT_ZdoSendMsgCB((zdoIncomingMsg_t *)pMsg);
  165. break;
  166. #endif
  167. case AF_DATA_CONFIRM_CMD:
  168. MT_AfDataConfirm((afDataConfirm_t *)pMsg);
  169. break;
  170. default:
  171. break;
  172. }
  173. osal_msg_deallocate((byte *)pMsg);
  174. }
  175. events ^= SYS_EVENT_MSG;
  176. }
  177. #if !defined CC2531ZNP
  178. else if (events & ZNP_SPI_RX_AREQ_EVENT)
  179. {
  180. if ((pBuf = npSpiGetReqBuf()) != NULL )
  181. {
  182. MT_ProcessIncoming(pBuf);
  183. npSpiAReqComplete();
  184. }
  185. events ^= ZNP_SPI_RX_AREQ_EVENT;
  186. }
  187. else if (events & ZNP_SPI_RX_SREQ_EVENT)
  188. {
  189. if ((pBuf = npSpiGetReqBuf()) != NULL)
  190. {
  191. MT_ProcessIncoming(pBuf);
  192. }
  193. events ^= ZNP_SPI_RX_SREQ_EVENT;
  194. }
  195. #endif
  196. else if (events & ZNP_UART_TX_READY_EVENT)
  197. {
  198. npUartTxReady();
  199. events ^= ZNP_UART_TX_READY_EVENT;
  200. }
  201. #if defined MT_SYS_FUNC
  202. else if (events & MT_SYS_OSAL_EVENT_0)
  203. {
  204. MT_SysOsalTimerExpired(0x00);
  205. events ^= MT_SYS_OSAL_EVENT_0;
  206. }
  207. else if (events & MT_SYS_OSAL_EVENT_1)
  208. {
  209. MT_SysOsalTimerExpired(0x01);
  210. events ^= MT_SYS_OSAL_EVENT_1;
  211. }
  212. else if (events & MT_SYS_OSAL_EVENT_2)
  213. {
  214. MT_SysOsalTimerExpired(0x02);
  215. events ^= MT_SYS_OSAL_EVENT_2;
  216. }
  217. else if (events & MT_SYS_OSAL_EVENT_3)
  218. {
  219. MT_SysOsalTimerExpired(0x03);
  220. events ^= MT_SYS_OSAL_EVENT_3;
  221. }
  222. #endif
  223. #if defined POWER_SAVING
  224. else if (events & ZNP_PWRMGR_CONSERVE_EVENT)
  225. {
  226. (void)osal_pwrmgr_task_state(znpTaskId, PWRMGR_CONSERVE);
  227. events ^= ZNP_PWRMGR_CONSERVE_EVENT;
  228. }
  229. #endif
  230. else if (events & ZNP_SECONDARY_INIT_EVENT)
  231. {
  232. npInit();
  233. events ^= ZNP_SECONDARY_INIT_EVENT;
  234. }
  235. else if (events & MT_AF_EXEC_EVT)
  236. {
  237. MT_AfExec();
  238. events ^= MT_AF_EXEC_EVT;
  239. }
  240. else
  241. {
  242. events = 0; /* Discard unknown events. */
  243. }
  244. return ( events );
  245. }
  246. /**************************************************************************************************
  247. * @fn MT_TransportAlloc
  248. *
  249. * @brief This function is the definition of the physical transport API for allocation a msg.
  250. *
  251. * input parameters
  252. *
  253. * @param cmd0 - The RPC command byte 0.
  254. * @param len - The RPC data length.
  255. *
  256. * output parameters
  257. *
  258. * @param uint8 * - Pointer to the buffer to use build and send the RPC message.
  259. *
  260. * @return None.
  261. **************************************************************************************************
  262. */
  263. uint8 *MT_TransportAlloc(uint8 cmd0, uint8 len)
  264. {
  265. #if !defined CC2531ZNP
  266. if (ZNP_CFG1_UART == znpCfg1)
  267. #endif
  268. {
  269. return npMtUartAlloc(cmd0, len);
  270. }
  271. #if !defined CC2531ZNP
  272. else
  273. {
  274. return npMtSpiAlloc(cmd0, len);
  275. }
  276. #endif
  277. }
  278. /**************************************************************************************************
  279. * @fn MT_TransportSend
  280. *
  281. * @brief This function is the definition of the physical transport API for sending a message.
  282. *
  283. * input parameters
  284. *
  285. * @param pBuf - Pointer to the buffer created with MT_TransportAlloc.
  286. *
  287. * output parameters
  288. *
  289. * None.
  290. *
  291. * @return None.
  292. **************************************************************************************************
  293. */
  294. void MT_TransportSend(uint8 *pBuf)
  295. {
  296. #if !defined CC2531ZNP
  297. if (ZNP_CFG1_UART == znpCfg1)
  298. #endif
  299. {
  300. npMtUartSend(pBuf);
  301. }
  302. #if !defined CC2531ZNP
  303. else
  304. {
  305. npMtSpiSend(pBuf);
  306. }
  307. #endif
  308. }
  309. /**************************************************************************************************
  310. * @fn npInit
  311. *
  312. * @brief This function is the secondary initialization that resolves conflicts during
  313. * osalInitTasks(). For example, since ZNP is the highest priority task, and
  314. * specifically because the ZNP task is initialized before the ZDApp task, if znpInit()
  315. * registers anything with ZDO_RegisterForZdoCB(), it is wiped out when ZDApp task
  316. * initialization invokes ZDApp_InitZdoCBFunc().
  317. * There may be other existing or future such races, so try to do all possible
  318. * NP initialization here vice in znpInit().
  319. *
  320. * input parameters
  321. *
  322. * None.
  323. *
  324. * output parameters
  325. *
  326. * None.
  327. *
  328. * @return None.
  329. **************************************************************************************************
  330. */
  331. static void npInit(void)
  332. {
  333. if (ZNP_CFG1_UART == znpCfg1)
  334. {
  335. halUARTCfg_t uartConfig;
  336. uartConfig.configured = TRUE;
  337. uartConfig.baudRate = ZNP_UART_BAUD;
  338. uartConfig.flowControl = TRUE;
  339. uartConfig.flowControlThreshold = HAL_UART_FLOW_THRESHOLD;
  340. uartConfig.rx.maxBufSize = HAL_UART_RX_BUF_SIZE;
  341. uartConfig.tx.maxBufSize = HAL_UART_TX_BUF_SIZE;
  342. uartConfig.idleTimeout = HAL_UART_IDLE_TIMEOUT;
  343. uartConfig.intEnable = TRUE;
  344. uartConfig.callBackFunc = npUartCback;
  345. HalUARTOpen(HAL_UART_PORT, &uartConfig);
  346. MT_UartRegisterTaskID(znpTaskId);
  347. }
  348. else
  349. {
  350. //npSpiInit() is called by hal_spi.c: HalSpiInit().
  351. }
  352. npInitNV();
  353. MT_Init();
  354. #if defined TC_LINKKEY_JOIN
  355. zcl_TaskID = znpTaskId;
  356. #endif
  357. #if LQI_ADJUST
  358. ZMacLqiAdjustMode(LQI_ADJ_MODE1);
  359. #endif
  360. #if defined CC2531ZNP
  361. (void)osal_pwrmgr_task_state(znpTaskId, PWRMGR_HOLD);
  362. #endif
  363. }
  364. /**************************************************************************************************
  365. * @fn npInitNV
  366. *
  367. * @brief
  368. *
  369. * input parameters
  370. *
  371. * None.
  372. *
  373. * output parameters
  374. *
  375. * None.
  376. *
  377. * @return None.
  378. **************************************************************************************************
  379. */
  380. static void npInitNV(void)
  381. {
  382. /* 4 x 2 bytes ZNP_NV_APP_ITEM_X */
  383. osal_nv_item_init(ZNP_NV_APP_ITEM_1, 2, NULL);
  384. osal_nv_item_init(ZNP_NV_APP_ITEM_2, 2, NULL);
  385. osal_nv_item_init(ZNP_NV_APP_ITEM_3, 2, NULL);
  386. osal_nv_item_init(ZNP_NV_APP_ITEM_4, 2, NULL);
  387. /* 2 x 16 bytes ZNP_NV_APP_ITEM_X */
  388. osal_nv_item_init(ZNP_NV_APP_ITEM_5, 16, NULL);
  389. osal_nv_item_init(ZNP_NV_APP_ITEM_6, 16, NULL);
  390. }
  391. /**************************************************************************************************
  392. * @fn npUartCback
  393. *
  394. * @brief This function is the UART callback processor.
  395. *
  396. * input parameters
  397. *
  398. * @param port - The port being used for UART.
  399. * @param event - The reason for the callback.
  400. *
  401. * output parameters
  402. *
  403. * None.
  404. *
  405. * @return None.
  406. **************************************************************************************************
  407. */
  408. static void npUartCback(uint8 port, uint8 event)
  409. {
  410. switch (event) {
  411. case HAL_UART_RX_FULL:
  412. case HAL_UART_RX_ABOUT_FULL:
  413. case HAL_UART_RX_TIMEOUT:
  414. MT_UartProcessZToolData(port, znpTaskId);
  415. break;
  416. case HAL_UART_TX_EMPTY:
  417. osal_set_event(znpTaskId, ZNP_UART_TX_READY_EVENT);
  418. break;
  419. default:
  420. break;
  421. }
  422. }
  423. /**************************************************************************************************
  424. * @fn npUartTxReady
  425. *
  426. * @brief This function gets and writes the next chunk of data to the UART.
  427. *
  428. * input parameters
  429. *
  430. * None.
  431. *
  432. * output parameters
  433. *
  434. * None.
  435. *
  436. * @return None.
  437. **************************************************************************************************
  438. */
  439. static void npUartTxReady(void)
  440. {
  441. static uint16 npUartTxCnt = 0;
  442. static uint8 *npUartTxMsg = NULL;
  443. static uint8 *pMsg = NULL;
  444. if (!npUartTxMsg)
  445. {
  446. if ((pMsg = npUartTxMsg = osal_msg_dequeue(&npTxQueue)))
  447. {
  448. /* | SOP | Data Length | CMD | DATA | FSC |
  449. * | 1 | 1 | 2 | as dLen | 1 |
  450. */
  451. npUartTxCnt = pMsg[1] + MT_UART_FRAME_OVHD + MT_RPC_FRAME_HDR_SZ;
  452. }
  453. }
  454. if (npUartTxMsg)
  455. {
  456. uint16 len = HalUARTWrite(HAL_UART_PORT, pMsg, npUartTxCnt);
  457. npUartTxCnt -= len;
  458. if (npUartTxCnt == 0)
  459. {
  460. osal_msg_deallocate(npUartTxMsg);
  461. npUartTxMsg = NULL;
  462. }
  463. else
  464. {
  465. pMsg += len;
  466. }
  467. }
  468. }
  469. /**************************************************************************************************
  470. * @fn npMtUartAlloc
  471. *
  472. * @brief This function allocates a buffer for Txing on UART.
  473. *
  474. * input parameters
  475. *
  476. * @param cmd0 - The first byte of the MT command id containing the command type and subsystem.
  477. * @param len - Data length required.
  478. *
  479. * output parameters
  480. *
  481. * None.
  482. *
  483. * @return Pointer to the buffer obtained; possibly NULL if an allocation failed.
  484. **************************************************************************************************
  485. */
  486. static uint8* npMtUartAlloc(uint8 cmd0, uint8 len)
  487. {
  488. uint8 *p;
  489. if ((p = osal_msg_allocate(len + MT_RPC_FRAME_HDR_SZ + MT_UART_FRAME_OVHD)) != NULL)
  490. {
  491. return p + 1;
  492. }
  493. return NULL;
  494. }
  495. /**************************************************************************************************
  496. * @fn npMtUartSend
  497. *
  498. * @brief This function transmits or enqueues the buffer for transmitting on UART.
  499. *
  500. * input parameters
  501. *
  502. * @param pBuf - Pointer to the buffer to transmit on the UART.
  503. *
  504. * output parameters
  505. *
  506. * None.
  507. *
  508. * @return None.
  509. **************************************************************************************************
  510. */
  511. static void npMtUartSend(uint8 *pBuf)
  512. {
  513. uint8 len = pBuf[0] + MT_RPC_FRAME_HDR_SZ;
  514. pBuf[len] = MT_UartCalcFCS(pBuf, len);
  515. pBuf--;
  516. pBuf[0] = MT_UART_SOF;
  517. osal_msg_enqueue(&npTxQueue, pBuf);
  518. osal_set_event(znpTaskId, ZNP_UART_TX_READY_EVENT);
  519. }
  520. #if !defined CC2531ZNP
  521. /**************************************************************************************************
  522. * @fn npMtSpiAlloc
  523. *
  524. * @brief This function gets or allocates a buffer for Txing on SPI.
  525. *
  526. * input parameters
  527. *
  528. * @param cmd0 - The first byte of the MT command id containing the command type and subsystem.
  529. * @param len - Data length required.
  530. *
  531. * output parameters
  532. *
  533. * None.
  534. *
  535. * @return Pointer to the buffer obtained; possibly NULL if an allocation failed.
  536. **************************************************************************************************
  537. */
  538. static uint8* npMtSpiAlloc(uint8 cmd0, uint8 len)
  539. {
  540. if ((cmd0 & MT_RPC_CMD_TYPE_MASK) == MT_RPC_CMD_SRSP)
  541. {
  542. return npSpiSRspAlloc(len);
  543. }
  544. else
  545. {
  546. return npSpiAReqAlloc(len);
  547. }
  548. }
  549. /**************************************************************************************************
  550. * @fn npMtSpiSend
  551. *
  552. * @brief This function transmits or enqueues the buffer for transmitting on SPI.
  553. *
  554. * input parameters
  555. *
  556. * @param pBuf - Pointer to the buffer to transmit on the SPI.
  557. *
  558. * output parameters
  559. *
  560. * None.
  561. *
  562. * @return None.
  563. **************************************************************************************************
  564. */
  565. static void npMtSpiSend(uint8 *pBuf)
  566. {
  567. if ((pBuf[1] & MT_RPC_CMD_TYPE_MASK) == MT_RPC_CMD_SRSP)
  568. {
  569. npSpiSRspReady(pBuf);
  570. }
  571. else
  572. {
  573. osal_msg_enqueue(&npTxQueue, pBuf);
  574. npSpiAReqReady();
  575. }
  576. }
  577. /**************************************************************************************************
  578. * @fn npSpiPollCallback
  579. *
  580. * @brief This function is called by the SPI driver when a POLL frame is received.
  581. *
  582. * input parameters
  583. *
  584. * None.
  585. *
  586. * output parameters
  587. *
  588. * None.
  589. *
  590. * @return A pointer to an OSAL message buffer containing the next AREQ frame to transmit,
  591. * if any; NULL otherwise.
  592. **************************************************************************************************
  593. */
  594. uint8* npSpiPollCallback(void)
  595. {
  596. return osal_msg_dequeue(&npTxQueue);
  597. }
  598. /**************************************************************************************************
  599. * @fn npSpiReadyCallback
  600. *
  601. * @brief This function is called by the SPI driver to check if any data is ready to send.
  602. *
  603. * input parameters
  604. *
  605. * None.
  606. *
  607. * output parameters
  608. *
  609. * None.
  610. *
  611. * @return TRUE if data is ready to send; FALSE otherwise.
  612. **************************************************************************************************
  613. */
  614. bool npSpiReadyCallback(void)
  615. {
  616. return !OSAL_MSG_Q_EMPTY(&npTxQueue);
  617. }
  618. #endif
  619. /**************************************************************************************************
  620. */