mac_autopend.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /**************************************************************************************************
  2. Filename: mac_autopend.c
  3. Revised: $Date: 2009-08-28 09:29:33 -0700 (Fri, 28 Aug 2009) $
  4. Revision: $Revision: 20674 $
  5. Description: This file implements the TIMAC Autopend feature.
  6. Copyright 2006-2009 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. /* low-level */
  34. #include "mac_api.h"
  35. #include "mac_radio_defs.h"
  36. /* osal */
  37. #include "OSAL.h"
  38. #include "saddr.h"
  39. #include "ZComDef.h"
  40. #include "mac_autopend.h"
  41. /* ------------------------------------------------------------------------------------------------
  42. * Defines
  43. * ------------------------------------------------------------------------------------------------
  44. */
  45. #define MAC_SRCMATCH_INVALID_INDEX 0xFF
  46. #define MAC_SRCMATCH_SHORT_ENTRY_SIZE 4
  47. #define MAC_SRCMATCH_EXT_ENTRY_SIZE Z_EXTADDR_LEN
  48. #define MAC_SRCMATCH_SHORT_MAX_NUM_ENTRIES 24
  49. #define MAC_SRCMATCH_EXT_MAX_NUM_ENTRIES 12
  50. #define MAC_SRCMATCH_ENABLE_BITMAP_LEN 3
  51. /* ------------------------------------------------------------------------------------------------
  52. * Global Variables
  53. * ------------------------------------------------------------------------------------------------
  54. */
  55. bool macSrcMatchIsEnabled = FALSE;
  56. /* ------------------------------------------------------------------------------------------------
  57. * Local Variables
  58. * ------------------------------------------------------------------------------------------------
  59. */
  60. /*
  61. The following local Varables are only set in MAC_SrcMatchEnable()
  62. They are read only to the rest of the module.
  63. */
  64. uint8 macSrcMatchMaxNumEntries = 0;
  65. uint8 macSrcMatchAddrMode = SADDR_MODE_SHORT;
  66. bool macSrcMatchIsAckAllPending = FALSE;
  67. /* ------------------------------------------------------------------------------------------------
  68. * Local Functions
  69. * ------------------------------------------------------------------------------------------------
  70. */
  71. static uint8 macSrcMatchFindEmptyEntry( void );
  72. static uint8 macSrcMatchCheckSrcAddr ( sAddr_t *addr, uint16 panID );
  73. static void macSrcMatchSetPendEnBit( uint8 index );
  74. static void macSrcMatchSetEnableBit( uint8 index, bool option );
  75. static bool macSrcMatchCheckEnableBit( uint8 index );
  76. static uint24 macSrcMatchGetEnableBit( void );
  77. static uint24 macSrcMatchGetPendEnBit( void );
  78. /*********************************************************************
  79. * @fn MAC_SrcMatchEnable
  80. *
  81. * @brief Enabled AUTOPEND and source address matching. If number of source
  82. * address table entries asked for is more than the hardware
  83. * supports. It will allocate maximum number of entries and return
  84. * MAC_INVALID_PARAMETER. This function shall be not be called from
  85. * ISR. It is not thread safe.
  86. *
  87. * @param addressType - address type that the application uses
  88. * SADDR_MODE_SHORT or SADDR_MODE_EXT
  89. * @param num - number of source address table entries to be used
  90. *
  91. * @return MAC_SUCCESS or MAC_INVALID_PARAMETER
  92. */
  93. uint8 MAC_SrcMatchEnable ( uint8 addrType, uint8 num )
  94. {
  95. uint8 rtn;
  96. uint8 maxNum;
  97. /* Verify the address type */
  98. if( addrType != SADDR_MODE_SHORT && addrType != SADDR_MODE_EXT )
  99. {
  100. return MAC_INVALID_PARAMETER;
  101. }
  102. maxNum = ( addrType == SADDR_MODE_SHORT ) ?
  103. MAC_SRCMATCH_SHORT_MAX_NUM_ENTRIES : MAC_SRCMATCH_EXT_MAX_NUM_ENTRIES;
  104. if( num > maxNum )
  105. {
  106. rtn = MAC_INVALID_PARAMETER;
  107. num = maxNum;
  108. }
  109. else
  110. {
  111. rtn = MAC_SUCCESS;
  112. }
  113. /* Turn on Frame Filter (TIMAC enables frame filter by default), TBD */
  114. MAC_RADIO_TURN_ON_RX_FRAME_FILTERING();
  115. /* Turn on Auto ACK (TIMAC turn on Auto ACK by default), TBD */
  116. MAC_RADIO_TURN_ON_AUTO_ACK();
  117. /* Turn on Autopend: set SRCMATCH.AUTOPEND and SRCMATCH.SRC_MATCH_EN */
  118. MAC_RADIO_TURN_ON_SRC_MATCH();
  119. /* Set SRCMATCH.AUTOPEND */
  120. MAC_RADIO_TURN_ON_AUTOPEND();
  121. /* Configure all the globals */
  122. macSrcMatchIsEnabled = TRUE;
  123. macSrcMatchMaxNumEntries = num;
  124. macSrcMatchAddrMode = addrType;
  125. return rtn;
  126. }
  127. /*********************************************************************
  128. * @fn MAC_SrcMatchAddEntry
  129. *
  130. * @brief Add a short or extended address to source address table. This
  131. * function shall be not be called from ISR. It is not thread safe.
  132. *
  133. * @param addr - a pointer to sAddr_t which contains addrMode
  134. * and a union of a short 16-bit MAC address or an extended
  135. * 64-bit MAC address to be added to the source address table.
  136. * @param panID - the device PAN ID. It is only used when the addr is
  137. * using short address
  138. * @return MAC_SUCCESS or MAC_NO_RESOURCES (source address table full)
  139. * or MAC_DUPLICATED_ENTRY (the entry added is duplicated),
  140. * or MAC_INVALID_PARAMETER if the input parameters are invalid.
  141. */
  142. uint8 MAC_SrcMatchAddEntry ( sAddr_t *addr, uint16 panID )
  143. {
  144. uint8 index;
  145. uint8 entry[MAC_SRCMATCH_SHORT_ENTRY_SIZE];
  146. /* Check if the input parameters are valid */
  147. if ( addr == NULL || addr->addrMode != macSrcMatchAddrMode )
  148. {
  149. return MAC_INVALID_PARAMETER;
  150. }
  151. /* Check if the entry already exists. Do not add duplicated entry */
  152. if ( macSrcMatchCheckSrcAddr( addr, panID ) != MAC_SRCMATCH_INVALID_INDEX )
  153. {
  154. return MAC_DUPLICATED_ENTRY;
  155. }
  156. /* If not duplicated, write to the radio RAM and enable the control bit */
  157. /* Find the first empty entry */
  158. index = macSrcMatchFindEmptyEntry();
  159. if ( index == macSrcMatchMaxNumEntries )
  160. {
  161. return MAC_NO_RESOURCES; /* Table is full */
  162. }
  163. if ( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  164. {
  165. /* Write the PanID and short address */
  166. entry[0] = LO_UINT16( panID ); /* Little Endian for the radio RAM */
  167. entry[1] = HI_UINT16( panID );
  168. entry[2] = LO_UINT16( addr->addr.shortAddr );
  169. entry[3] = HI_UINT16( addr->addr.shortAddr );
  170. MAC_RADIO_SRC_MATCH_TABLE_WRITE( ( index * MAC_SRCMATCH_SHORT_ENTRY_SIZE ),
  171. entry, MAC_SRCMATCH_SHORT_ENTRY_SIZE );
  172. }
  173. else
  174. {
  175. /* Write the extended address */
  176. MAC_RADIO_SRC_MATCH_TABLE_WRITE( ( index * MAC_SRCMATCH_EXT_ENTRY_SIZE ),
  177. addr->addr.extAddr, MAC_SRCMATCH_EXT_ENTRY_SIZE );
  178. }
  179. /* Set the Autopend enable bits */
  180. macSrcMatchSetPendEnBit( index );
  181. /* Set the Src Match enable bits */
  182. macSrcMatchSetEnableBit( index, TRUE );
  183. return MAC_SUCCESS;
  184. }
  185. /*********************************************************************
  186. * @fn MAC_SrcMatchDeleteEntry
  187. *
  188. * @brief Delete a short or extended address from source address table.
  189. * This function shall be not be called from ISR. It is not thread safe.
  190. *
  191. * @param addr - a pointer to sAddr_t which contains addrMode
  192. * and a union of a short 16-bit MAC address or an extended
  193. * 64-bit MAC address to be deleted from the source address table.
  194. * @param panID - the device PAN ID. It is only used when the addr is
  195. * using short address
  196. *
  197. * @return MAC_SUCCESS or MAC_INVALID_PARAMETER (address to be deleted
  198. * cannot be found in the source address table).
  199. */
  200. uint8 MAC_SrcMatchDeleteEntry ( sAddr_t *addr, uint16 panID )
  201. {
  202. uint8 index;
  203. if ( addr == NULL || addr->addrMode != macSrcMatchAddrMode )
  204. {
  205. return MAC_INVALID_PARAMETER;
  206. }
  207. /* Look up the source address table and find the entry. */
  208. index = macSrcMatchCheckSrcAddr( addr, panID );
  209. if( index == MAC_SRCMATCH_INVALID_INDEX )
  210. {
  211. return MAC_INVALID_PARAMETER;
  212. }
  213. /* Clear Src Match enable bits */
  214. macSrcMatchSetEnableBit( index, FALSE );
  215. return MAC_SUCCESS;
  216. }
  217. /*********************************************************************
  218. * @fn MAC_SrcMatchAckAllPending
  219. *
  220. * @brief Enabled/disable acknowledging all packets with pending bit set
  221. * The application normally enables it when adding new entries to
  222. * the source address table fails due to the table is full, or
  223. * disables it when more entries are deleted and the table has
  224. * empty slots.
  225. *
  226. * @param option - TRUE (acknowledging all packets with pending field set)
  227. * FALSE (acknowledging all packets with pending field cleared)
  228. *
  229. * @return none
  230. */
  231. void MAC_SrcMatchAckAllPending ( uint8 option )
  232. {
  233. if( option == TRUE )
  234. {
  235. macSrcMatchIsAckAllPending = TRUE;
  236. /* Set the PENDING_OR register */
  237. MAC_RADIO_TURN_ON_PENDING_OR();
  238. }
  239. else
  240. {
  241. macSrcMatchIsAckAllPending = FALSE;
  242. /* Clear the PENDING_OR register */
  243. MAC_RADIO_TURN_OFF_PENDING_OR();
  244. }
  245. }
  246. /*********************************************************************
  247. * @fn MAC_SrcMatchCheckAllPending
  248. *
  249. * @brief Check if acknowledging all packets with pending bit set
  250. * is enabled.
  251. *
  252. * @param none
  253. *
  254. * @return MAC_AUTOACK_PENDING_ALL_ON or MAC_AUTOACK_PENDING_ALL_OFF
  255. */
  256. uint8 MAC_SrcMatchCheckAllPending ( void )
  257. {
  258. if( macSrcMatchIsAckAllPending == TRUE )
  259. {
  260. return MAC_AUTOACK_PENDING_ALL_ON;
  261. }
  262. return MAC_AUTOACK_PENDING_ALL_OFF;
  263. }
  264. /*********************************************************************
  265. * @fn MAC_SrcMatchCheckResult
  266. *
  267. * @brief Check the result of source matching
  268. *
  269. * @param index - index of the entry in the source address table
  270. *
  271. * @return TRUE or FALSE
  272. */
  273. MAC_INTERNAL_API bool MAC_SrcMatchCheckResult( void )
  274. {
  275. uint8 resIndex;
  276. if ( macSrcMatchIsAckAllPending )
  277. {
  278. return (TRUE);
  279. }
  280. MAC_RADIO_SRC_MATCH_RESINDEX( resIndex );
  281. return ( resIndex & AUTOPEND_RES );
  282. }
  283. /*********************************************************************
  284. * @fn macSrcMatchFindEmptyEntry
  285. *
  286. * @brief return index of the first empty entry found
  287. *
  288. * @param none
  289. *
  290. * @return uint8 - return index of the first empty entry found
  291. */
  292. static uint8 macSrcMatchFindEmptyEntry( void )
  293. {
  294. uint8 index;
  295. uint24 enable;
  296. enable = MAC_RADIO_SRC_MATCH_GET_EN();
  297. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  298. {
  299. for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
  300. {
  301. if( ( enable & ( (uint24)0x01 << index ) ) == 0 )
  302. {
  303. return index;
  304. }
  305. }
  306. }
  307. else
  308. {
  309. for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
  310. {
  311. if( ( enable & ( (uint24)0x01 << ( index * 2 ) ) ) == 0 )
  312. {
  313. return index;
  314. }
  315. }
  316. }
  317. /*
  318. The value of index shall be macSrcMatchMaxNumEntries when it executes
  319. here. The table is full.
  320. */
  321. return index;
  322. }
  323. /*********************************************************************
  324. * @fn macSrcMatchCheckSrcAddr
  325. *
  326. * @brief Check if a short or extended address is in the source address table.
  327. * This function shall not be called from ISR. It is not thread safe.
  328. *
  329. * @param addr - a pointer to sAddr_t which contains addrMode
  330. * and a union of a short 16-bit MAC address or an extended
  331. * 64-bit MAC address to be checked in the source address table.
  332. * @param panID - the device PAN ID. It is only used when the addr is
  333. * using short address
  334. * @return uint8 - index of the entry in the table. Return
  335. * MAC_SRCMATCH_INVALID_INDEX (0xFF) if address not found.
  336. */
  337. static uint8 macSrcMatchCheckSrcAddr ( sAddr_t *addr, uint16 panID )
  338. {
  339. uint8 index;
  340. uint8 *pAddr;
  341. uint8 entrySize;
  342. uint8 entry[MAC_SRCMATCH_SHORT_ENTRY_SIZE];
  343. uint8 ramEntry[MAC_SRCMATCH_EXT_ENTRY_SIZE];
  344. /*
  345. Currently, shadow memory is not supported to optimize SPI traffic.
  346. */
  347. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  348. {
  349. entry[0] = LO_UINT16( panID ); /* Little Endian for the radio RAM */
  350. entry[1] = HI_UINT16( panID );
  351. entry[2] = LO_UINT16( addr->addr.shortAddr );
  352. entry[3] = HI_UINT16( addr->addr.shortAddr );
  353. pAddr = entry;
  354. entrySize = MAC_SRCMATCH_SHORT_ENTRY_SIZE;
  355. }
  356. else
  357. {
  358. pAddr = addr->addr.extAddr;
  359. entrySize = MAC_SRCMATCH_EXT_ENTRY_SIZE;
  360. }
  361. for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
  362. {
  363. /* Check if the entry is enabled */
  364. if( macSrcMatchCheckEnableBit( index ) == FALSE )
  365. {
  366. continue;
  367. }
  368. /* Compare the short address and pan ID */
  369. MAC_RADIO_SRC_MATCH_TABLE_READ( ( index * entrySize ), ramEntry, entrySize );
  370. if( osal_memcmp( pAddr, ramEntry, entrySize ) == TRUE )
  371. {
  372. /* Match found */
  373. return index;
  374. }
  375. }
  376. return MAC_SRCMATCH_INVALID_INDEX;
  377. }
  378. /*********************************************************************
  379. * @fn macSrcMatchSetPendEnBit
  380. *
  381. * @brief Set the enable bit in the source address table
  382. *
  383. * @param index - index of the entry in the source address table
  384. *
  385. * @return none
  386. */
  387. static void macSrcMatchSetPendEnBit( uint8 index )
  388. {
  389. uint24 enable;
  390. uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
  391. enable = MAC_RADIO_SRC_MATCH_GET_PENDEN();
  392. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  393. {
  394. enable |= ( (uint24)0x01 << index );
  395. osal_buffer_uint24( buf, enable );
  396. MAC_RADIO_SRC_MATCH_SET_SHORTPENDEN( buf );
  397. }
  398. else
  399. {
  400. enable |= ( (uint24)0x01 << ( index * 2 ) );
  401. osal_buffer_uint24( buf, enable );
  402. MAC_RADIO_SRC_MATCH_SET_EXTPENDEN( buf );
  403. }
  404. }
  405. /*********************************************************************
  406. * @fn macSrcMatchSetEnableBit
  407. *
  408. * @brief Set or clear the enable bit in the SRCMATCH EN register
  409. *
  410. * @param index - index of the entry in the source address table
  411. * @param option - true (set the enable bit), or false (clear the enable bit)
  412. *
  413. * @return none
  414. */
  415. static void macSrcMatchSetEnableBit( uint8 index, bool option )
  416. {
  417. uint24 enable;
  418. enable = MAC_RADIO_SRC_MATCH_GET_EN();
  419. if( option == TRUE )
  420. {
  421. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  422. {
  423. enable |= ( (uint24)0x01 << index );
  424. MAC_RADIO_SRC_MATCH_SET_SHORTEN( enable );
  425. }
  426. else
  427. {
  428. enable |= ( (uint24)0x01 << ( index * 2 ) );
  429. MAC_RADIO_SRC_MATCH_SET_EXTEN( enable );
  430. }
  431. }
  432. else
  433. {
  434. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  435. {
  436. enable &= ~( (uint24)0x01 << index );
  437. MAC_RADIO_SRC_MATCH_SET_SHORTEN( enable );
  438. }
  439. else
  440. {
  441. enable &= ~( (uint24)0x01 << ( index * 2 ) );
  442. MAC_RADIO_SRC_MATCH_SET_EXTEN( enable );
  443. }
  444. }
  445. }
  446. /*********************************************************************
  447. * @fn macSrcMatchCheckEnableBit
  448. *
  449. * @brief Check the enable bit in the source address table
  450. *
  451. * @param index - index of the entry in the source address table
  452. *
  453. * @return TRUE or FALSE
  454. */
  455. static bool macSrcMatchCheckEnableBit( uint8 index )
  456. {
  457. uint24 enable;
  458. if( macSrcMatchAddrMode == SADDR_MODE_EXT )
  459. {
  460. index *= 2;
  461. }
  462. enable = MAC_RADIO_SRC_MATCH_GET_EN();
  463. if( enable & ( (uint24)0x01 << index ) )
  464. {
  465. return TRUE;
  466. }
  467. return FALSE;
  468. }
  469. /*********************************************************************
  470. * @fn macSrcMatchGetEnableBit
  471. *
  472. * @brief Return the SRCMATCH enable bitmap
  473. *
  474. * @param none
  475. *
  476. * @return uint24 - 24 bits bitmap
  477. */
  478. static uint24 macSrcMatchGetEnableBit( void )
  479. {
  480. uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
  481. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  482. {
  483. MAC_RADIO_GET_SRC_SHORTEN( buf );
  484. }
  485. else
  486. {
  487. MAC_RADIO_GET_SRC_EXTEN( buf );
  488. }
  489. return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN );
  490. }
  491. /*********************************************************************
  492. * @fn macSrcMatchGetPendEnBit
  493. *
  494. * @brief Return the SRCMATCH Pend enable bitmap
  495. *
  496. * @param none
  497. *
  498. * @return uint24 - 24 bits bitmap
  499. */
  500. static uint24 macSrcMatchGetPendEnBit( void )
  501. {
  502. uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
  503. if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
  504. {
  505. MAC_RADIO_GET_SRC_SHORTPENDEN( buf );
  506. }
  507. else
  508. {
  509. MAC_RADIO_GET_SRC_EXTENPEND( buf );
  510. }
  511. return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN );
  512. }