123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- /**************************************************************************************************
- Filename: mac_autopend.c
- Revised: $Date: 2009-08-28 09:29:33 -0700 (Fri, 28 Aug 2009) $
- Revision: $Revision: 20674 $
- Description: This file implements the TIMAC Autopend feature.
- Copyright 2006-2009 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- **************************************************************************************************/
- /* low-level */
- #include "mac_api.h"
- #include "mac_radio_defs.h"
- /* osal */
- #include "OSAL.h"
- #include "saddr.h"
- #include "ZComDef.h"
- #include "mac_autopend.h"
- /* ------------------------------------------------------------------------------------------------
- * Defines
- * ------------------------------------------------------------------------------------------------
- */
- #define MAC_SRCMATCH_INVALID_INDEX 0xFF
- #define MAC_SRCMATCH_SHORT_ENTRY_SIZE 4
- #define MAC_SRCMATCH_EXT_ENTRY_SIZE Z_EXTADDR_LEN
- #define MAC_SRCMATCH_SHORT_MAX_NUM_ENTRIES 24
- #define MAC_SRCMATCH_EXT_MAX_NUM_ENTRIES 12
- #define MAC_SRCMATCH_ENABLE_BITMAP_LEN 3
-
- /* ------------------------------------------------------------------------------------------------
- * Global Variables
- * ------------------------------------------------------------------------------------------------
- */
- bool macSrcMatchIsEnabled = FALSE;
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- /*
- The following local Varables are only set in MAC_SrcMatchEnable()
- They are read only to the rest of the module.
- */
- uint8 macSrcMatchMaxNumEntries = 0;
- uint8 macSrcMatchAddrMode = SADDR_MODE_SHORT;
- bool macSrcMatchIsAckAllPending = FALSE;
- /* ------------------------------------------------------------------------------------------------
- * Local Functions
- * ------------------------------------------------------------------------------------------------
- */
- static uint8 macSrcMatchFindEmptyEntry( void );
- static uint8 macSrcMatchCheckSrcAddr ( sAddr_t *addr, uint16 panID );
- static void macSrcMatchSetPendEnBit( uint8 index );
- static void macSrcMatchSetEnableBit( uint8 index, bool option );
- static bool macSrcMatchCheckEnableBit( uint8 index );
- static uint24 macSrcMatchGetEnableBit( void );
- static uint24 macSrcMatchGetPendEnBit( void );
- /*********************************************************************
- * @fn MAC_SrcMatchEnable
- *
- * @brief Enabled AUTOPEND and source address matching. If number of source
- * address table entries asked for is more than the hardware
- * supports. It will allocate maximum number of entries and return
- * MAC_INVALID_PARAMETER. This function shall be not be called from
- * ISR. It is not thread safe.
- *
- * @param addressType - address type that the application uses
- * SADDR_MODE_SHORT or SADDR_MODE_EXT
- * @param num - number of source address table entries to be used
- *
- * @return MAC_SUCCESS or MAC_INVALID_PARAMETER
- */
- uint8 MAC_SrcMatchEnable ( uint8 addrType, uint8 num )
- {
- uint8 rtn;
- uint8 maxNum;
-
- /* Verify the address type */
- if( addrType != SADDR_MODE_SHORT && addrType != SADDR_MODE_EXT )
- {
- return MAC_INVALID_PARAMETER;
- }
-
- maxNum = ( addrType == SADDR_MODE_SHORT ) ?
- MAC_SRCMATCH_SHORT_MAX_NUM_ENTRIES : MAC_SRCMATCH_EXT_MAX_NUM_ENTRIES;
-
- if( num > maxNum )
- {
- rtn = MAC_INVALID_PARAMETER;
- num = maxNum;
- }
- else
- {
- rtn = MAC_SUCCESS;
- }
-
- /* Turn on Frame Filter (TIMAC enables frame filter by default), TBD */
- MAC_RADIO_TURN_ON_RX_FRAME_FILTERING();
-
- /* Turn on Auto ACK (TIMAC turn on Auto ACK by default), TBD */
- MAC_RADIO_TURN_ON_AUTO_ACK();
-
- /* Turn on Autopend: set SRCMATCH.AUTOPEND and SRCMATCH.SRC_MATCH_EN */
- MAC_RADIO_TURN_ON_SRC_MATCH();
-
- /* Set SRCMATCH.AUTOPEND */
- MAC_RADIO_TURN_ON_AUTOPEND();
-
- /* Configure all the globals */
- macSrcMatchIsEnabled = TRUE;
- macSrcMatchMaxNumEntries = num;
- macSrcMatchAddrMode = addrType;
- return rtn;
- }
- /*********************************************************************
- * @fn MAC_SrcMatchAddEntry
- *
- * @brief Add a short or extended address to source address table. This
- * function shall be not be called from ISR. It is not thread safe.
- *
- * @param addr - a pointer to sAddr_t which contains addrMode
- * and a union of a short 16-bit MAC address or an extended
- * 64-bit MAC address to be added to the source address table.
- * @param panID - the device PAN ID. It is only used when the addr is
- * using short address
- * @return MAC_SUCCESS or MAC_NO_RESOURCES (source address table full)
- * or MAC_DUPLICATED_ENTRY (the entry added is duplicated),
- * or MAC_INVALID_PARAMETER if the input parameters are invalid.
- */
- uint8 MAC_SrcMatchAddEntry ( sAddr_t *addr, uint16 panID )
- {
- uint8 index;
- uint8 entry[MAC_SRCMATCH_SHORT_ENTRY_SIZE];
-
- /* Check if the input parameters are valid */
- if ( addr == NULL || addr->addrMode != macSrcMatchAddrMode )
- {
- return MAC_INVALID_PARAMETER;
- }
-
- /* Check if the entry already exists. Do not add duplicated entry */
- if ( macSrcMatchCheckSrcAddr( addr, panID ) != MAC_SRCMATCH_INVALID_INDEX )
- {
- return MAC_DUPLICATED_ENTRY;
- }
-
- /* If not duplicated, write to the radio RAM and enable the control bit */
-
- /* Find the first empty entry */
- index = macSrcMatchFindEmptyEntry();
- if ( index == macSrcMatchMaxNumEntries )
- {
- return MAC_NO_RESOURCES; /* Table is full */
- }
-
- if ( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- /* Write the PanID and short address */
- entry[0] = LO_UINT16( panID ); /* Little Endian for the radio RAM */
- entry[1] = HI_UINT16( panID );
- entry[2] = LO_UINT16( addr->addr.shortAddr );
- entry[3] = HI_UINT16( addr->addr.shortAddr );
- MAC_RADIO_SRC_MATCH_TABLE_WRITE( ( index * MAC_SRCMATCH_SHORT_ENTRY_SIZE ),
- entry, MAC_SRCMATCH_SHORT_ENTRY_SIZE );
- }
- else
- {
- /* Write the extended address */
- MAC_RADIO_SRC_MATCH_TABLE_WRITE( ( index * MAC_SRCMATCH_EXT_ENTRY_SIZE ),
- addr->addr.extAddr, MAC_SRCMATCH_EXT_ENTRY_SIZE );
- }
-
- /* Set the Autopend enable bits */
- macSrcMatchSetPendEnBit( index );
-
- /* Set the Src Match enable bits */
- macSrcMatchSetEnableBit( index, TRUE );
-
- return MAC_SUCCESS;
- }
- /*********************************************************************
- * @fn MAC_SrcMatchDeleteEntry
- *
- * @brief Delete a short or extended address from source address table.
- * This function shall be not be called from ISR. It is not thread safe.
- *
- * @param addr - a pointer to sAddr_t which contains addrMode
- * and a union of a short 16-bit MAC address or an extended
- * 64-bit MAC address to be deleted from the source address table.
- * @param panID - the device PAN ID. It is only used when the addr is
- * using short address
- *
- * @return MAC_SUCCESS or MAC_INVALID_PARAMETER (address to be deleted
- * cannot be found in the source address table).
- */
- uint8 MAC_SrcMatchDeleteEntry ( sAddr_t *addr, uint16 panID )
- {
- uint8 index;
-
- if ( addr == NULL || addr->addrMode != macSrcMatchAddrMode )
- {
- return MAC_INVALID_PARAMETER;
- }
-
- /* Look up the source address table and find the entry. */
- index = macSrcMatchCheckSrcAddr( addr, panID );
- if( index == MAC_SRCMATCH_INVALID_INDEX )
- {
- return MAC_INVALID_PARAMETER;
- }
-
- /* Clear Src Match enable bits */
- macSrcMatchSetEnableBit( index, FALSE );
- return MAC_SUCCESS;
- }
-
- /*********************************************************************
- * @fn MAC_SrcMatchAckAllPending
- *
- * @brief Enabled/disable acknowledging all packets with pending bit set
- * The application normally enables it when adding new entries to
- * the source address table fails due to the table is full, or
- * disables it when more entries are deleted and the table has
- * empty slots.
- *
- * @param option - TRUE (acknowledging all packets with pending field set)
- * FALSE (acknowledging all packets with pending field cleared)
- *
- * @return none
- */
- void MAC_SrcMatchAckAllPending ( uint8 option )
- {
- if( option == TRUE )
- {
- macSrcMatchIsAckAllPending = TRUE;
-
- /* Set the PENDING_OR register */
- MAC_RADIO_TURN_ON_PENDING_OR();
- }
- else
- {
- macSrcMatchIsAckAllPending = FALSE;
-
- /* Clear the PENDING_OR register */
- MAC_RADIO_TURN_OFF_PENDING_OR();
- }
- }
- /*********************************************************************
- * @fn MAC_SrcMatchCheckAllPending
- *
- * @brief Check if acknowledging all packets with pending bit set
- * is enabled.
- *
- * @param none
- *
- * @return MAC_AUTOACK_PENDING_ALL_ON or MAC_AUTOACK_PENDING_ALL_OFF
- */
- uint8 MAC_SrcMatchCheckAllPending ( void )
- {
- if( macSrcMatchIsAckAllPending == TRUE )
- {
- return MAC_AUTOACK_PENDING_ALL_ON;
- }
-
- return MAC_AUTOACK_PENDING_ALL_OFF;
- }
- /*********************************************************************
- * @fn MAC_SrcMatchCheckResult
- *
- * @brief Check the result of source matching
- *
- * @param index - index of the entry in the source address table
- *
- * @return TRUE or FALSE
- */
- MAC_INTERNAL_API bool MAC_SrcMatchCheckResult( void )
- {
- uint8 resIndex;
-
- if ( macSrcMatchIsAckAllPending )
- {
- return (TRUE);
- }
-
- MAC_RADIO_SRC_MATCH_RESINDEX( resIndex );
-
- return ( resIndex & AUTOPEND_RES );
- }
- /*********************************************************************
- * @fn macSrcMatchFindEmptyEntry
- *
- * @brief return index of the first empty entry found
- *
- * @param none
- *
- * @return uint8 - return index of the first empty entry found
- */
- static uint8 macSrcMatchFindEmptyEntry( void )
- {
- uint8 index;
- uint24 enable;
-
- enable = MAC_RADIO_SRC_MATCH_GET_EN();
-
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
- {
- if( ( enable & ( (uint24)0x01 << index ) ) == 0 )
- {
- return index;
- }
- }
- }
- else
- {
- for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
- {
- if( ( enable & ( (uint24)0x01 << ( index * 2 ) ) ) == 0 )
- {
- return index;
- }
- }
- }
-
- /*
- The value of index shall be macSrcMatchMaxNumEntries when it executes
- here. The table is full.
- */
- return index;
- }
- /*********************************************************************
- * @fn macSrcMatchCheckSrcAddr
- *
- * @brief Check if a short or extended address is in the source address table.
- * This function shall not be called from ISR. It is not thread safe.
- *
- * @param addr - a pointer to sAddr_t which contains addrMode
- * and a union of a short 16-bit MAC address or an extended
- * 64-bit MAC address to be checked in the source address table.
- * @param panID - the device PAN ID. It is only used when the addr is
- * using short address
- * @return uint8 - index of the entry in the table. Return
- * MAC_SRCMATCH_INVALID_INDEX (0xFF) if address not found.
- */
- static uint8 macSrcMatchCheckSrcAddr ( sAddr_t *addr, uint16 panID )
- {
- uint8 index;
- uint8 *pAddr;
- uint8 entrySize;
- uint8 entry[MAC_SRCMATCH_SHORT_ENTRY_SIZE];
- uint8 ramEntry[MAC_SRCMATCH_EXT_ENTRY_SIZE];
-
- /*
- Currently, shadow memory is not supported to optimize SPI traffic.
- */
-
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- entry[0] = LO_UINT16( panID ); /* Little Endian for the radio RAM */
- entry[1] = HI_UINT16( panID );
- entry[2] = LO_UINT16( addr->addr.shortAddr );
- entry[3] = HI_UINT16( addr->addr.shortAddr );
- pAddr = entry;
- entrySize = MAC_SRCMATCH_SHORT_ENTRY_SIZE;
- }
- else
- {
- pAddr = addr->addr.extAddr;
- entrySize = MAC_SRCMATCH_EXT_ENTRY_SIZE;
- }
-
- for( index = 0; index < macSrcMatchMaxNumEntries; index++ )
- {
- /* Check if the entry is enabled */
- if( macSrcMatchCheckEnableBit( index ) == FALSE )
- {
- continue;
- }
-
- /* Compare the short address and pan ID */
- MAC_RADIO_SRC_MATCH_TABLE_READ( ( index * entrySize ), ramEntry, entrySize );
-
- if( osal_memcmp( pAddr, ramEntry, entrySize ) == TRUE )
- {
- /* Match found */
- return index;
- }
- }
-
- return MAC_SRCMATCH_INVALID_INDEX;
- }
- /*********************************************************************
- * @fn macSrcMatchSetPendEnBit
- *
- * @brief Set the enable bit in the source address table
- *
- * @param index - index of the entry in the source address table
- *
- * @return none
- */
- static void macSrcMatchSetPendEnBit( uint8 index )
- {
- uint24 enable;
- uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
-
- enable = MAC_RADIO_SRC_MATCH_GET_PENDEN();
-
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- enable |= ( (uint24)0x01 << index );
- osal_buffer_uint24( buf, enable );
- MAC_RADIO_SRC_MATCH_SET_SHORTPENDEN( buf );
- }
- else
- {
- enable |= ( (uint24)0x01 << ( index * 2 ) );
- osal_buffer_uint24( buf, enable );
- MAC_RADIO_SRC_MATCH_SET_EXTPENDEN( buf );
- }
- }
- /*********************************************************************
- * @fn macSrcMatchSetEnableBit
- *
- * @brief Set or clear the enable bit in the SRCMATCH EN register
- *
- * @param index - index of the entry in the source address table
- * @param option - true (set the enable bit), or false (clear the enable bit)
- *
- * @return none
- */
- static void macSrcMatchSetEnableBit( uint8 index, bool option )
- {
- uint24 enable;
-
- enable = MAC_RADIO_SRC_MATCH_GET_EN();
-
- if( option == TRUE )
- {
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- enable |= ( (uint24)0x01 << index );
- MAC_RADIO_SRC_MATCH_SET_SHORTEN( enable );
- }
- else
- {
- enable |= ( (uint24)0x01 << ( index * 2 ) );
- MAC_RADIO_SRC_MATCH_SET_EXTEN( enable );
- }
- }
- else
- {
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- enable &= ~( (uint24)0x01 << index );
- MAC_RADIO_SRC_MATCH_SET_SHORTEN( enable );
- }
- else
- {
- enable &= ~( (uint24)0x01 << ( index * 2 ) );
- MAC_RADIO_SRC_MATCH_SET_EXTEN( enable );
- }
- }
- }
- /*********************************************************************
- * @fn macSrcMatchCheckEnableBit
- *
- * @brief Check the enable bit in the source address table
- *
- * @param index - index of the entry in the source address table
- *
- * @return TRUE or FALSE
- */
- static bool macSrcMatchCheckEnableBit( uint8 index )
- {
- uint24 enable;
-
- if( macSrcMatchAddrMode == SADDR_MODE_EXT )
- {
- index *= 2;
- }
-
- enable = MAC_RADIO_SRC_MATCH_GET_EN();
-
- if( enable & ( (uint24)0x01 << index ) )
- {
- return TRUE;
- }
- return FALSE;
- }
-
- /*********************************************************************
- * @fn macSrcMatchGetEnableBit
- *
- * @brief Return the SRCMATCH enable bitmap
- *
- * @param none
- *
- * @return uint24 - 24 bits bitmap
- */
- static uint24 macSrcMatchGetEnableBit( void )
- {
- uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
-
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- MAC_RADIO_GET_SRC_SHORTEN( buf );
- }
- else
- {
- MAC_RADIO_GET_SRC_EXTEN( buf );
- }
-
- return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN );
- }
- /*********************************************************************
- * @fn macSrcMatchGetPendEnBit
- *
- * @brief Return the SRCMATCH Pend enable bitmap
- *
- * @param none
- *
- * @return uint24 - 24 bits bitmap
- */
- static uint24 macSrcMatchGetPendEnBit( void )
- {
- uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN];
- if( macSrcMatchAddrMode == SADDR_MODE_SHORT )
- {
- MAC_RADIO_GET_SRC_SHORTPENDEN( buf );
- }
- else
- {
- MAC_RADIO_GET_SRC_EXTENPEND( buf );
- }
-
- return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN );
- }
|