123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428 |
- /**************************************************************************************************
- Filename: mac_rx.c
- Revised: $Date: 2007-10-08 14:05:36 -0700 (Mon, 08 Oct 2007) $
- Revision: $Revision: 15624 $
- Description: Describe the purpose and contents of the file.
- Copyright 2006-2012 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.
- **************************************************************************************************/
- /* ------------------------------------------------------------------------------------------------
- * Includes
- * ------------------------------------------------------------------------------------------------
- */
- /* hal */
- #include "hal_defs.h"
- #include "hal_types.h"
- /* OSAL */
- #include "OSAL.h"
- /* high-level */
- #include "mac_high_level.h"
- #include "mac_spec.h"
- /* MAC security */
- #include "mac_security.h"
- /* exported low-level */
- #include "mac_low_level.h"
- /* low-level specific */
- #include "mac_rx.h"
- #include "mac_tx.h"
- #include "mac_rx_onoff.h"
- #include "mac_radio.h"
- /* target specific */
- #include "mac_radio_defs.h"
- #include "mac_autopend.h"
- /* debug */
- #include "mac_assert.h"
- /* ------------------------------------------------------------------------------------------------
- * Defines
- * ------------------------------------------------------------------------------------------------
- */
- #define MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT 16 /* adjustable to tune performance */
- /* receive FIFO bytes needed to start a valid receive (see function rxStartIsr for details) */
- #define RX_THRESHOLD_START_LEN (MAC_PHY_PHR_LEN + \
- MAC_FCF_FIELD_LEN + \
- MAC_SEQ_NUM_FIELD_LEN + \
- MAC_FCS_FIELD_LEN)
- /* maximum size of addressing fields (note: command frame identifier processed as part of address) */
- #define MAX_ADDR_FIELDS_LEN ((MAC_EXT_ADDR_FIELD_LEN + MAC_PAN_ID_FIELD_LEN) * 2)
- /* addressing mode reserved value */
- #define ADDR_MODE_RESERVERED 1
- /* length of command frame identifier */
- #define CMD_FRAME_ID_LEN 1
- /* packet size mask is equal to the maximum value */
- #define PHY_PACKET_SIZE_MASK 0x7F
- /* value for promiscuous off, must not conflict with other mode variants from separate include files */
- #define PROMISCUOUS_MODE_OFF 0x00
- /* bit of proprietary FCS format that indicates if the CRC is OK */
- #define PROPRIETARY_FCS_CRC_OK_BIT 0x80
- /* dummy length value for unused entry in lookup table */
- #define DUMMY_LEN 0xBE
- /* value for rxThresholdIntState */
- #define RX_THRESHOLD_INT_STATE_INACTIVE 0
- #define RX_THRESHOLD_INT_STATE_ACTIVE 1
- #define RX_THRESHOLD_INT_STATE_RESET 2
- /* ------------------------------------------------------------------------------------------------
- * Macros
- * ------------------------------------------------------------------------------------------------
- */
- #define MEM_ALLOC(x) macDataRxMemAlloc(x)
- #define MEM_FREE(x) macDataRxMemFree((uint8 **)x)
- /*
- * Macro for encoding frame control information into internal flags format.
- * Parameter is pointer to the frame. NOTE! If either the internal frame
- * format *or* the specification changes, this macro will need to be modified.
- */
- #define INTERNAL_FCF_FLAGS(p) ((((p)[1] >> 4) & 0x03) | ((p)[0] & 0x78))
- /*
- * The radio replaces the actual FCS with different information. This proprietary FCS is
- * the same length as the original and includes:
- * 1) the RSSI value
- * 2) the average correlation value (used for LQI)
- * 3) a CRC passed bit
- *
- * These macros decode the proprietary FCS. The macro parameter is a pointer to the two byte FCS.
- */
- #define PROPRIETARY_FCS_RSSI(p) ((int8)((p)[0]))
- #define PROPRIETARY_FCS_CRC_OK(p) ((p)[1] & PROPRIETARY_FCS_CRC_OK_BIT)
- #define PROPRIETARY_FCS_CORRELATION_VALUE(p) ((p)[1] & ~PROPRIETARY_FCS_CRC_OK_BIT)
- /*
- * Macros for security control field.
- */
- #define SECURITY_LEVEL(s) (s & 0x07)
- #define KEY_IDENTIFIER_MODE(s) ((s & 0x18) >> 3)
- #define SECURITY_CONTROL_RESERVED(s) ((s & 0xE0) >> 5)
- /* ------------------------------------------------------------------------------------------------
- * Global Variables
- * ------------------------------------------------------------------------------------------------
- */
- uint8 macRxActive;
- uint8 macRxFilter;
- uint8 macRxOutgoingAckFlag;
- /* ------------------------------------------------------------------------------------------------
- * Local Constants
- * ------------------------------------------------------------------------------------------------
- */
- static const uint8 CODE macRxAddrLen[] =
- {
- 0, /* no address */
- DUMMY_LEN, /* reserved */
- MAC_PAN_ID_FIELD_LEN + MAC_SHORT_ADDR_FIELD_LEN, /* short address + pan id */
- MAC_PAN_ID_FIELD_LEN + MAC_EXT_ADDR_FIELD_LEN /* extended address + pan id */
- };
- /* ------------------------------------------------------------------------------------------------
- * Local Prototypes
- * ------------------------------------------------------------------------------------------------
- */
- static void rxHaltCleanupFinalStep(void);
- static void rxStartIsr(void);
- static void rxAddrIsr(void);
- #ifdef MAC_SECURITY
- static void rxSecurityHdrIsr(void);
- #endif
-
- static void rxPayloadIsr(void);
- static void rxDiscardIsr(void);
- static void rxFcsIsr(void);
- static void rxPrepPayload(void);
- static void rxDiscardFrame(void);
- static void rxDone(void);
- static void rxPostRxUpdates(void);
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- static void (* pFuncRxState)(void);
- static macRx_t * pRxBuf;
- static uint8 rxBuf[MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN];
- static uint8 rxUnreadLen;
- static uint8 rxNextLen;
- static uint8 rxPayloadLen;
- static uint8 rxFilter;
- static uint8 rxPromiscuousMode;
- static uint8 rxIsrActiveFlag;
- static uint8 rxResetFlag;
- static uint8 rxFifoOverflowCount;
- #ifdef PACKET_FILTER_STATS
- uint32 rxCrcFailure = 0;
- uint32 rxCrcSuccess = 0;
- #endif /* PACKET_FILTER_STATS */
- #ifdef CC2591_COMPRESSION_WORKAROUND
- void macRxResetRssi(void);
- #endif
- /**************************************************************************************************
- * @fn macRxInit
- *
- * @brief Initialize receive variable states.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxInit(void)
- {
- macRxFilter = RX_FILTER_OFF;
- rxPromiscuousMode = PROMISCUOUS_MODE_OFF;
- pRxBuf = NULL; /* required for macRxReset() to function correctly */
- macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
- pFuncRxState = &rxStartIsr;
- macRxOutgoingAckFlag = 0;
- rxIsrActiveFlag = 0;
- rxResetFlag = 0;
- rxFifoOverflowCount = 0;
- }
- /**************************************************************************************************
- * @fn macRxRadioPowerUpInit
- *
- * @brief Initialization for after radio first powers up.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxRadioPowerUpInit(void)
- {
- /* set threshold at initial value */
- MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
- /* clear any accidental threshold interrupt that happened as part of power up sequence */
- MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();
- /* enable threshold interrupts */
- MAC_RADIO_ENABLE_RX_THRESHOLD_INTERRUPT();
- }
- /**************************************************************************************************
- * @fn macRxTxReset
- *
- * @brief Reset the receive state.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxTxReset(void)
- {
- /* forces receiver off, cleans up by calling macRxHaltCleanup() and macTxHaltCleanup() */
- macRxHardDisable();
- /*
- * Note : transmit does not require any reset logic
- * beyond what macRxHardDisable() provides.
- */
- /* restore deault filter mode to off */
- macRxFilter = RX_FILTER_OFF;
- /* return promiscuous mode to default off state */
- macRxPromiscuousMode(MAC_PROMISCUOUS_MODE_OFF);
- }
- /**************************************************************************************************
- * @fn macRxHaltCleanup
- *
- * @brief Cleanup up the receive logic after receiver is forced off.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxHaltCleanup(void)
- {
- rxResetFlag = 1;
- if (!rxIsrActiveFlag)
- {
- rxHaltCleanupFinalStep();
- rxResetFlag = 0;
- }
- }
- /*=================================================================================================
- * @fn rxHaltCleanupFinalStep
- *
- * @brief Required cleanup if receiver is halted in the middle of a receive.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxHaltCleanupFinalStep(void)
- {
- /* cancel any upcoming ACK transmit complete callback */
- MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
- /* set start of frame threshold */
- MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
- /* flush the receive FIFO */
- MAC_RADIO_FLUSH_RX_FIFO();
- /* clear any receive interrupt that happened to squeak through */
- MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();
- /* if data buffer has been allocated, free it */
- if (pRxBuf != NULL)
- {
- MEM_FREE((uint8 **)&pRxBuf);
- }
- /* MEM_FREE() sets parameter to NULL. */
- pFuncRxState = &rxStartIsr;
- /* if receive was active, perform the post receive updates */
- if (macRxActive || macRxOutgoingAckFlag)
- {
- macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
- macRxOutgoingAckFlag = 0;
- rxPostRxUpdates();
- }
- }
- /**************************************************************************************************
- * @fn macRxThresholdIsr
- *
- * @brief Interrupt service routine called when bytes in FIFO reach threshold value.
- * It implements a state machine for receiving a packet.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxThresholdIsr(void)
- {
- /* if currently reseting, do not execute receive ISR logic */
- if (rxResetFlag)
- {
- return;
- }
- /*
- * Call the function that handles the current receive state.
- * A flag is set for the duration of the call to indicate
- * the ISR is executing. This is necessary for the reset
- * logic so it does not perform a reset in the middle of
- * executing the ISR.
- */
- rxIsrActiveFlag = 1;
- (*pFuncRxState)();
- rxIsrActiveFlag = 0;
- /* if a reset occurred during the ISR, peform cleanup here */
- if (rxResetFlag)
- {
- rxHaltCleanupFinalStep();
- rxResetFlag = 0;
- }
- }
- /*=================================================================================================
- * @fn rxStartIsr
- *
- * @brief First ISR state for receiving a packet - compute packet length, allocate
- * buffer, initialize buffer. Acknowledgements are handled immediately without
- * allocating a buffer.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxStartIsr(void)
- {
- uint8 addrLen;
- uint8 ackWithPending;
- uint8 dstAddrMode;
- uint8 srcAddrMode;
- uint8 mhrLen = 0;
- MAC_ASSERT(!macRxActive); /* receive on top of receive */
- /* indicate rx is active */
- macRxActive = MAC_RX_ACTIVE_STARTED;
- /*
- * For bullet proof functionality, need to see if the receiver was just turned off.
- * The logic to request turning off the receiver, disables interrupts and then checks
- * the value of macRxActive. If it is TRUE, the receiver will not be turned off.
- *
- * There is a small hole though. It's possible to attempt turning off the receiver
- * in the window from when the receive interrupt fires and the point where macRxActive
- * is set to TRUE. To plug this hole, the on/off status must be tested *after*
- * macRxActive has been set. If the receiver is off at this point, there is nothing
- * in the RX fifo and the receive is simply aborted.
- *
- * Also, there are some considerations in case a hard disable just happened. Usually,
- * the receiver will just be off at this point after a hard disable. The check described
- * above will account for this case too. However, if a hard disable were immediately
- * followed by an enable, the receiver would be on. To catch this case, the receive
- * FIFO is also tested to see if it is empty. Recovery is identical to the other cases.
- */
- if (!macRxOnFlag || MAC_RADIO_RX_FIFO_IS_EMPTY())
- {
- /* reset active flag */
- macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
- /*
- * To be absolutely bulletproof, must make sure no transmit queue'ed up during
- * the tiny, tiny window when macRxActive was not zero.
- */
- rxPostRxUpdates();
- /* return immediately from here */
- return;
- }
- /*
- * If interrupts are held off for too long it's possible the previous "transmit done"
- * callback is pending. If this is the case, it needs to be completed before
- * continuing with the receive logic.
- */
- MAC_RADIO_FORCE_TX_DONE_IF_PENDING();
- /*
- * It's possible receive logic is still waiting for confirmation of an ACK that went out
- * for the previous receive. This is OK but the callback needs to be canceled at this point.
- * That callback execute receive cleanup logic that will run at the completion
- * of *this* receive. Also, it is important the flag for the outgoing ACK to be cleared.
- */
- MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
- macRxOutgoingAckFlag = 0;
- /*
- * Make a module-local copy of macRxFilter. This prevents the selected
- * filter from changing in the middle of a receive.
- */
- rxFilter = macRxFilter;
- /*-------------------------------------------------------------------------------
- * Read initial frame information from FIFO.
- *
- * This code is not triggered until the following are in the RX FIFO:
- * frame length - one byte containing length of MAC frame (excludes this field)
- * frame control field - two bytes defining frame type, addressing fields, control flags
- * sequence number - one byte unique sequence identifier
- * additional two bytes - these bytes are available in case the received frame is an ACK,
- * if so, the frame can be verified and responded to immediately,
- * if not an ACK, these bytes will be processed normally
- */
- /* read frame length, frame control field, and sequence number from FIFO */
- MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN);
- /* bytes to read from FIFO equals frame length minus length of MHR fields just read from FIFO */
- rxUnreadLen = (rxBuf[0] & PHY_PACKET_SIZE_MASK) - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN;
- /*
- * Workaround for chip bug #1547. The receive buffer can sometimes be corrupted by hardware.
- * This usually occurs under heavy traffic. If a corrupted receive buffer is detected
- * the entire receive buffer is flushed.
- *
- * In the case that this workaround is not needed, an assert is used to make sure the
- * receive length field is not corrupted. This is important because a corrupted receive
- * length field is utterly fatal and, if not caught here, extremely hard to track down.
- */
- if (macChipVersion == REV_A)
- {
- if ((rxUnreadLen > (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN)) ||
- (MAC_FRAME_TYPE(&rxBuf[1]) > MAC_FRAME_TYPE_MAX_VALID))
- {
- MAC_RADIO_FLUSH_RX_FIFO();
- rxDone();
- return;
- }
- }
- else
- {
- /* radio supplied a corrupted receive buffer length */
- MAC_ASSERT(rxUnreadLen <= (MAC_A_MAX_PHY_PACKET_SIZE - MAC_FCF_FIELD_LEN - MAC_SEQ_NUM_FIELD_LEN));
- }
- /*-------------------------------------------------------------------------------
- * Process ACKs.
- *
- * If this frame is an ACK, process it immediately and exit from here.
- * If this frame is not an ACK and transmit is listening for an ACK, let
- * the transmit logic know an non-ACK was received so transmit can complete.
- *
- * In promiscuous mode ACKs are treated like any other frame.
- */
- if ((MAC_FRAME_TYPE(&rxBuf[1]) == MAC_FRAME_TYPE_ACK) && (rxPromiscuousMode == PROMISCUOUS_MODE_OFF))
- {
- halIntState_t s;
- uint8 fcsBuf[MAC_FCF_FIELD_LEN];
- /*
- * There are guaranteed to be two unread bytes in the FIFO. By defintion, for ACK frames
- * these two bytes will be the FCS.
- */
- /* read FCS from FIFO (threshold set so bytes are guaranteed to be there) */
- MAC_RADIO_READ_RX_FIFO(fcsBuf, MAC_FCS_FIELD_LEN);
- /*
- * This critical section ensures that the ACK timeout won't be triggered in the
- * middle of receiving the ACK frame.
- */
- HAL_ENTER_CRITICAL_SECTION(s);
- /* see if transmit is listening for an ACK */
- if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
- {
- MAC_ASSERT(pMacDataTx != NULL); /* transmit buffer must be present */
- /* record link quality metrics for the receive ACK */
- {
- int8 rssiDbm;
- uint8 corr;
- rssiDbm = PROPRIETARY_FCS_RSSI(fcsBuf) + MAC_RADIO_RSSI_OFFSET;
- MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm);
- corr = PROPRIETARY_FCS_CORRELATION_VALUE(fcsBuf);
- pMacDataTx->internal.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr);
- pMacDataTx->internal.correlation = corr;
- pMacDataTx->internal.rssi= rssiDbm;
- }
- /*
- * It's okay if the ACK timeout is triggered here. The callbacks for ACK received
- * or ACK not received will check "macTxActive" flag before taking any actions.
- */
- HAL_EXIT_CRITICAL_SECTION(s);
- /*
- * An ACK was received so transmit logic needs to know. If the FCS failed,
- * the transmit logic still needs to know. In that case, treat the frame
- * as a non-ACK to complete the active transmit.
- */
- if (PROPRIETARY_FCS_CRC_OK(fcsBuf))
- {
- /* call transmit logic to indicate ACK was received */
- macTxAckReceivedCallback(MAC_SEQ_NUMBER(&rxBuf[1]), MAC_FRAME_PENDING(&rxBuf[1]));
- }
- else
- {
- macTxAckNotReceivedCallback();
- }
- }
- else
- {
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /* receive is done, exit from here */
- rxDone();
- return;
- }
- else if (macTxActive == MAC_TX_ACTIVE_LISTEN_FOR_ACK)
- {
- macTxAckNotReceivedCallback();
- }
- /*-------------------------------------------------------------------------------
- * Apply filtering.
- *
- * For efficiency, see if filtering is even 'on' before processing. Also test
- * to make sure promiscuous mode is disabled. If promiscuous mode is enabled,
- * do not apply filtering.
- */
- if ((rxFilter != RX_FILTER_OFF) && !rxPromiscuousMode)
- {
- if (/* filter all frames */
- (rxFilter == RX_FILTER_ALL) ||
- /* filter non-beacon frames */
- ((rxFilter == RX_FILTER_NON_BEACON_FRAMES) &&
- (MAC_FRAME_TYPE(&rxBuf[1]) != MAC_FRAME_TYPE_BEACON)) ||
- /* filter non-command frames */
- ((rxFilter == RX_FILTER_NON_COMMAND_FRAMES) &&
- ((MAC_FRAME_TYPE(&rxBuf[1]) != MAC_FRAME_TYPE_COMMAND))))
- {
- /* discard rest of frame */
- rxDiscardFrame();
- return;
- }
- }
- /*-------------------------------------------------------------------------------
- * Compute length of addressing fields. Compute payload length.
- */
- /* decode addressing modes */
- dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]);
- srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]);
- /*
- * Workaround for chip bug #1547. The receive buffer can sometimes be corrupted by hardware.
- * This usually occurs under heavy traffic. If a corrupted receive buffer is detected
- * the entire receive buffer is flushed.
- */
- if (macChipVersion == REV_A)
- {
- if ((srcAddrMode == ADDR_MODE_RESERVERED) || (dstAddrMode == ADDR_MODE_RESERVERED))
- {
- MAC_RADIO_FLUSH_RX_FIFO();
- rxDone();
- return;
- }
- }
- /*
- * Compute the addressing field length. A lookup table based on addressing
- * mode is used for efficiency. If the source address is present and the
- * frame is intra-PAN, the PAN Id is not repeated. In this case, the address
- * length is adjusted to match the smaller length.
- */
- addrLen = macRxAddrLen[dstAddrMode] + macRxAddrLen[srcAddrMode];
- if ((srcAddrMode != SADDR_MODE_NONE) && MAC_INTRA_PAN(&rxBuf[1]))
- {
- addrLen -= MAC_PAN_ID_FIELD_LEN;
- }
- /*
- * If there are not enough unread bytes to include the computed address
- * plus FCS field, the frame is corrupted and must be discarded.
- */
- if ((addrLen + MAC_FCS_FIELD_LEN) > rxUnreadLen)
- {
- /* discard frame and exit */
- rxDiscardFrame();
- return;
- }
- /* aux security header plus payload length is equal to unread bytes minus
- * address length, minus the FCS
- */
- rxPayloadLen = rxUnreadLen - addrLen - MAC_FCS_FIELD_LEN;
- /*-------------------------------------------------------------------------------
- * Allocate memory for the incoming frame.
- */
- if (MAC_SEC_ENABLED(&rxBuf[1]))
- {
- /* increase the allocation size of MAC header for security */
- mhrLen = MAC_MHR_LEN;
- }
- pRxBuf = (macRx_t *) MEM_ALLOC(sizeof(macRx_t) + mhrLen + rxPayloadLen);
- if (pRxBuf == NULL)
- {
- /* Cancel the outgoing TX ACK */
- MAC_RADIO_CANCEL_TX_ACK();
- /* buffer allocation failed, discard the frame and exit*/
- rxDiscardFrame();
- return;
- }
- /*-------------------------------------------------------------------------------
- * Set up to process ACK request. Do not ACK if in promiscuous mode.
- */
- ackWithPending = 0;
- if (!rxPromiscuousMode)
- {
- macRxOutgoingAckFlag = MAC_ACK_REQUEST(&rxBuf[1]);
- }
- /*-------------------------------------------------------------------------------
- * Process any ACK request.
- */
- if (macRxOutgoingAckFlag)
- {
- halIntState_t s;
- /*
- * This critical section ensures that the callback ISR is initiated within time
- * to guarantee correlation with the strobe.
- */
- HAL_ENTER_CRITICAL_SECTION(s);
- /* Do not ack data packet with pending more data */
- if( MAC_FRAME_TYPE(&rxBuf[1]) == MAC_FRAME_TYPE_COMMAND )
- {
- if( macRxCheckMACPendingCallback())
- {
- /* Check is any mac data pending for end devices */
- ackWithPending = MAC_RX_FLAG_ACK_PENDING;
- }
- else
- {
- if( macSrcMatchIsEnabled )
- {
- /* When autopend is enabled, check if allpending is set to true */
- if( MAC_SrcMatchCheckAllPending() == MAC_AUTOACK_PENDING_ALL_ON )
- {
- ackWithPending = MAC_RX_FLAG_ACK_PENDING;
- }
- }
- else
- {
- /* When autopend is disabled, check the application pending callback */
- if( macRxCheckPendingCallback() )
- {
- ackWithPending = MAC_RX_FLAG_ACK_PENDING;
- }
- }
- }
- }
- if( ackWithPending == MAC_RX_FLAG_ACK_PENDING )
- {
- MAC_RADIO_TX_ACK_PEND();
- }
- else
- {
- MAC_RADIO_TX_ACK();
- }
- /* request a callback to macRxAckTxDoneCallback() when the ACK transmit has finished */
- MAC_RADIO_REQUEST_ACK_TX_DONE_CALLBACK();
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /*-------------------------------------------------------------------------------
- * Populate the receive buffer going up to high-level.
- */
- /* configure the payload buffer
- * save MAC header pointer regardless of security status.
- */
- pRxBuf->mhr.p = pRxBuf->msdu.p = (uint8 *) (pRxBuf + 1);
- pRxBuf->mhr.len = pRxBuf->msdu.len = rxPayloadLen;
- if (MAC_SEC_ENABLED(&rxBuf[1]))
- {
- /* Copy FCF and sequence number to RX buffer */
- pRxBuf->mhr.len = MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN;
- osal_memcpy(pRxBuf->mhr.p, &rxBuf[1], pRxBuf->mhr.len);
- pRxBuf->mhr.p += pRxBuf->mhr.len;
- }
- /* set internal values */
- pRxBuf->mac.srcAddr.addrMode = srcAddrMode;
- pRxBuf->mac.dstAddr.addrMode = dstAddrMode;
- pRxBuf->mac.timestamp = MAC_RADIO_BACKOFF_CAPTURE();
- pRxBuf->mac.timestamp2 = MAC_RADIO_TIMER_CAPTURE();
- pRxBuf->internal.frameType = MAC_FRAME_TYPE(&rxBuf[1]);
- pRxBuf->mac.dsn = MAC_SEQ_NUMBER(&rxBuf[1]);
- pRxBuf->internal.flags = INTERNAL_FCF_FLAGS(&rxBuf[1]) | ackWithPending;
- /*-------------------------------------------------------------------------------
- * If the processing the addressing fields does not require more bytes from
- * the FIFO go directly address processing function. Otherwise, configure
- * interrupt to jump there once bytes are received.
- */
- if (addrLen == 0)
- {
- /* no addressing fields to read, prepare for payload interrupts */
- pFuncRxState = &rxPayloadIsr;
- rxPrepPayload();
- }
- else
- {
- /* need to read and process addressing fields, prepare for address interrupt */
- rxNextLen = addrLen;
- if (MAC_SEC_ENABLED(&rxBuf[1]))
- {
- /* When security is enabled, read off security control field as well */
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen + MAC_SEC_CONTROL_FIELD_LEN);
- }
- else
- {
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
- }
- pFuncRxState = &rxAddrIsr;
- }
- }
- /*=================================================================================================
- * @fn rxAddrIsr
- *
- * @brief Receive ISR state for decoding address. Reads and stores the address information
- * from the incoming packet.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxAddrIsr(void)
- {
- uint8 buf[MAX_ADDR_FIELDS_LEN];
- uint8 dstAddrMode;
- uint8 srcAddrMode;
- #ifdef MAC_SECURITY
- uint8 securityControl;
- #endif /* MAC_SECURITY */
- uint8 * p;
- MAC_ASSERT(rxNextLen != 0); /* logic assumes at least one address byte in buffer */
- /* read out address fields into local buffer in one shot */
- MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
- /* set pointer to buffer with addressing fields */
- p = buf;
- /* destination address */
- dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]);
- if (dstAddrMode != SADDR_MODE_NONE)
- {
- pRxBuf->mac.srcPanId = pRxBuf->mac.dstPanId = BUILD_UINT16(p[0], p[1]);
- p += MAC_PAN_ID_FIELD_LEN;
- if (dstAddrMode == SADDR_MODE_EXT)
- {
- sAddrExtCpy(pRxBuf->mac.dstAddr.addr.extAddr, p);
- p += MAC_EXT_ADDR_FIELD_LEN;
- }
- else
- {
- pRxBuf->mac.dstAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
- p += MAC_SHORT_ADDR_FIELD_LEN;
- }
- }
- /* sources address */
- srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]);
- if (srcAddrMode != SADDR_MODE_NONE)
- {
- if (!(pRxBuf->internal.flags & MAC_RX_FLAG_INTRA_PAN))
- {
- pRxBuf->mac.srcPanId = BUILD_UINT16(p[0], p[1]);
- p += MAC_PAN_ID_FIELD_LEN;
- }
- if (srcAddrMode == SADDR_MODE_EXT)
- {
- sAddrExtCpy(pRxBuf->mac.srcAddr.addr.extAddr, p);
- }
- else
- {
- pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
- }
- }
- #ifdef MAC_SECURITY
- if (MAC_SEC_ENABLED(&rxBuf[1]))
- {
- uint8 keyIdMode;
- if (MAC_FRAME_VERSION(&rxBuf[1]) == 0)
- {
- /* MAC_UNSUPPORTED_LEGACY - Cancel the outgoing TX ACK.
- * It may be too late but we have to try.
- */
- MAC_RADIO_CANCEL_TX_ACK();
- /* clean up after unsupported security legacy */
- macRxHaltCleanup();
- return;
- }
- /* Copy addressing fields to RX buffer */
- osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen);
- pRxBuf->mhr.p += rxNextLen;
- pRxBuf->mhr.len += rxNextLen;
- /*-------------------------------------------------------------------------------
- * Prepare for auxiliary security header interrupts.
- */
- /* read out security control field from FIFO (threshold set so bytes are guaranteed to be there) */
- MAC_RADIO_READ_RX_FIFO(&securityControl, MAC_SEC_CONTROL_FIELD_LEN);
- /* Copy security fields to MHR buffer */
- *pRxBuf->mhr.p = securityControl;
- pRxBuf->mhr.p += MAC_SEC_CONTROL_FIELD_LEN;
- pRxBuf->mhr.len += MAC_SEC_CONTROL_FIELD_LEN;
- /* store security level and key ID mode */
- pRxBuf->sec.securityLevel = SECURITY_LEVEL(securityControl);
- pRxBuf->sec.keyIdMode = keyIdMode = KEY_IDENTIFIER_MODE(securityControl);
- /* Corrupted RX frame, should never occur. */
- if ((keyIdMode > MAC_KEY_ID_MODE_8)
- /* Get the next RX length according to AuxLen table minus security control field.
- * The security control length is counted already.
- */
- || ((macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN) >= rxPayloadLen)
- /* Security Enabled subfield is one, but the Security Level in the header is zero:
- * MAC_UNSUPPORTED_SECURITY - Cancel the outgoing TX ACK.
- */
- || (pRxBuf->sec.securityLevel == MAC_SEC_LEVEL_NONE))
- {
- /* It may be too late but we have to try. */
- MAC_RADIO_CANCEL_TX_ACK();
- /* clean up after unsupported security or corrupted RX frame. */
- macRxHaltCleanup();
- return;
- }
- /* get the next RX length according to AuxLen table minus security control field.
- * The sceurity control length is counted already.
- */
- rxNextLen = macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN;
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
- pFuncRxState = &rxSecurityHdrIsr;
- }
- else
- #endif /* MAC_SECURITY */
- {
- /* clear security level */
- pRxBuf->sec.securityLevel = MAC_SEC_LEVEL_NONE;
- /*-------------------------------------------------------------------------------
- * Prepare for payload interrupts.
- */
- pFuncRxState = &rxPayloadIsr;
- rxPrepPayload();
- }
- }
- #ifdef MAC_SECURITY
- /*=================================================================================================
- * @fn rxSecurityHdrIsr
- *
- * @brief Receive ISR state for reading out and storing the auxiliary security header.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxSecurityHdrIsr(void)
- {
- uint8 buf[MAC_FRAME_COUNTER_LEN + MAC_KEY_ID_8_LEN];
- /* read out frame counter and key ID */
- MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
- /* Incoming frame counter */
- macFrameCounter = BUILD_UINT32(buf[0], buf[1], buf[2], buf[3]);
- if (rxNextLen - MAC_FRAME_COUNTER_LEN > 0)
- {
- /* Explicit mode */
- osal_memcpy(pRxBuf->sec.keySource, &buf[MAC_FRAME_COUNTER_LEN], rxNextLen - MAC_FRAME_COUNTER_LEN - 1);
- pRxBuf->sec.keyIndex = buf[rxNextLen - MAC_KEY_INDEX_LEN];
- }
- /* Copy security fields to RX buffer */
- osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen);
- pRxBuf->mhr.p += rxNextLen;
- pRxBuf->mhr.len += rxNextLen;
- /* Update payload pointer and payload length. The rxPayloadLen includes security header length
- * and SCF byte. The security header and SCF length must be deducted from the rxPayloadLen.
- */
- rxPayloadLen -= (rxNextLen + MAC_SEC_CONTROL_FIELD_LEN);
- pRxBuf->msdu.len = rxPayloadLen;
- pRxBuf->mhr.len += rxPayloadLen;
- /*-------------------------------------------------------------------------------
- * Prepare for payload interrupts.
- */
- pFuncRxState = &rxPayloadIsr;
- rxPrepPayload();
- }
- #endif /* MAC_SECURITY */
- /*=================================================================================================
- * @fn rxPrepPayload
- *
- * @brief Common code to prepare for the payload ISR.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxPrepPayload(void)
- {
- if (rxPayloadLen == 0)
- {
- MAC_RADIO_SET_RX_THRESHOLD(MAC_FCS_FIELD_LEN);
- pFuncRxState = &rxFcsIsr;
- }
- else
- {
- rxNextLen = MIN(rxPayloadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
- }
- }
- /*=================================================================================================
- * @fn rxPayloadIsr
- *
- * @brief Receive ISR state for reading out and storing the packet payload.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxPayloadIsr(void)
- {
- MAC_RADIO_READ_RX_FIFO(pRxBuf->mhr.p, rxNextLen);
- pRxBuf->mhr.p += rxNextLen;
- rxPayloadLen -= rxNextLen;
- rxPrepPayload();
- }
- /*=================================================================================================
- * @fn rxFcsIsr
- *
- * @brief Receive ISR state for handling the FCS.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxFcsIsr(void)
- {
- uint8 crcOK;
- uint8 ackWithPending = 0;
- /* read FCS, rxBuf is now available storage */
- MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_FCS_FIELD_LEN);
- /*
- * The FCS has actually been replaced within the radio by a proprietary version of the FCS.
- * This proprietary FCS is two bytes (same length as the real FCS) and contains:
- * 1) the RSSI value
- * 2) the average correlation value (used for LQI)
- * 3) a CRC passed bit
- */
- /* save the "CRC-is-OK" status */
- crcOK = PROPRIETARY_FCS_CRC_OK(rxBuf);
- /*
- * See if the frame should be passed up to high-level MAC. If the CRC is OK, the
- * the frame is always passed up. Frames with a bad CRC are also passed up *if*
- * a special variant of promiscuous mode is active.
- */
- if (crcOK || (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC))
- {
- int8 rssiDbm;
- uint8 corr;
- #ifdef PACKET_FILTER_STATS
- rxCrcSuccess++;
- #endif /* PACKET_FILTER_STATS */
- /*
- * As power saving optimization, set state variable to indicate physical receive
- * has completed and then request turning of the receiver. This means the receiver
- * can be off (if other conditions permit) during execution of the callback function.
- *
- * The receiver will be requested to turn off once again at the end of the receive
- * logic. There is no harm in doing this.
- */
- macRxActive = MAC_RX_ACTIVE_DONE;
- macRxOffRequest();
- /* decode RSSI and correlation values */
- rssiDbm = PROPRIETARY_FCS_RSSI(rxBuf) + MAC_RADIO_RSSI_OFFSET;
- MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm);
- corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf);
- /* Read the source matching result back */
- if( macSrcMatchIsEnabled && MAC_RADIO_SRC_MATCH_RESULT() )
- {
- /* This result will not overwrite the previously determined pRxBuf->internal.flags */
- ackWithPending = MAC_RX_FLAG_ACK_PENDING;
- }
- /* record parameters that get passed up to high-level */
- pRxBuf->internal.flags |= ( crcOK | ackWithPending );
- pRxBuf->mac.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr);
- pRxBuf->mac.rssi = rssiDbm;
- pRxBuf->mac.correlation = corr;
- /* set the MSDU pointer to point at start of data */
- pRxBuf->mhr.p = (uint8 *) (pRxBuf + 1);
- pRxBuf->msdu.p += (pRxBuf->mhr.len - pRxBuf->msdu.len);
- /* finally... execute callback function */
- macRxCompleteCallback(pRxBuf);
- pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
- }
- else
- {
- #ifdef PACKET_FILTER_STATS
- rxCrcFailure++;
- #endif /* PACKET_FILTER_STATS */
- /*
- * The CRC is bad so no ACK was sent. Cancel any callback and clear the flag.
- * (It's OK to cancel the outgoing ACK even if an ACK was not requested. It's
- * slightly more efficient to do so.)
- */
- MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
- macRxOutgoingAckFlag = 0;
- /* the CRC failed so the packet must be discarded */
- MEM_FREE((uint8 **)&pRxBuf);
- pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
- }
- /* reset threshold level, reset receive state, and complete receive logic */
- MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
- pFuncRxState = &rxStartIsr;
- rxDone();
- }
- /*=================================================================================================
- * @fn rxDone
- *
- * @brief Common exit point for receive.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxDone(void)
- {
- /* Make sure the peak RSSI is reset */
- COMPRESSION_WORKAROUND_RESET_RSSI();
-
- /* if the receive FIFO has overflowed, flush it here */
- if (MAC_RADIO_RX_FIFO_HAS_OVERFLOWED())
- {
- MAC_RADIO_FLUSH_RX_FIFO();
- }
- /* mark receive as inactive */
- macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
- /* if there is no outgoing ACK, run the post receive updates */
- if (!macRxOutgoingAckFlag)
- {
- rxPostRxUpdates();
- }
- }
- /**************************************************************************************************
- * @fn macRxAckTxDoneCallback
- *
- * @brief Function called when the outoing ACK has completed transmitting.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- void macRxAckTxDoneCallback(void)
- {
- macRxOutgoingAckFlag = 0;
- /*
- * With certain interrupt priorities and timing conditions, it is possible this callback
- * could be executed before the primary receive logic completes. To prevent this, the
- * post updates are only executed if receive logic is no longer active. In the case the
- * post updates are not executed here, they will execute when the main receive logic
- * completes.
- */
- if (!macRxActive)
- {
- rxPostRxUpdates();
- }
- }
- /*=================================================================================================
- * @fn rxPostRxUpdates
- *
- * @brief Updates that need to be performed once receive is complete.
- *
- * It is not fatal to execute this function if somehow receive is active. Under
- * certain timing/interrupt conditions a new receive may have started before this
- * function executes. This should happen very rarely (if it happens at all) and
- * would cause no problems.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxPostRxUpdates(void)
- {
- /* turn off receiver if permitted */
- macRxOffRequest();
- /* update the transmit power, update may have been blocked by transmit of outgoing ACK */
- macRadioUpdateTxPower();
- /* initiate and transmit that was queued during receive */
- macTxStartQueuedFrame();
- }
- /*=================================================================================================
- * @fn rxDiscardFrame
- *
- * @brief Initializes for discarding a packet. Must be called before ACK is strobed.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxDiscardFrame(void)
- {
- MAC_ASSERT(pFuncRxState == &rxStartIsr); /* illegal state for calling discard frame function */
- if (rxUnreadLen == 0)
- {
- rxDone();
- }
- else
- {
- rxNextLen = MIN(rxUnreadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
- pFuncRxState = &rxDiscardIsr;
- }
- }
- /*=================================================================================================
- * @fn rxDiscardIsr
- *
- * @brief Receive ISR state for discarding a packet.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void rxDiscardIsr(void)
- {
- uint8 buf[MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT];
- MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
- rxUnreadLen -= rxNextLen;
- /* read out and discard bytes until all bytes of packet are disposed of */
- if (rxUnreadLen != 0)
- {
- if (rxUnreadLen < MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT)
- {
- rxNextLen = rxUnreadLen;
- MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
- }
- }
- else
- {
- /* reset threshold level, reset receive state, and complete receive logic */
- MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
- pFuncRxState = &rxStartIsr;
- rxDone();
- }
- }
- /**************************************************************************************************
- * @fn macRxFifoOverflowIsr
- *
- * @brief This interrupt service routine is called when RX FIFO overflow. Note that this
- * exception does not retrieve the good frames that are trapped in the RX FIFO.
- * It simply halts and cleanup the RX.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxFifoOverflowIsr(void)
- {
- rxFifoOverflowCount++; /* This flag is used for debug purpose only */
- macRxHaltCleanup();
- }
- /**************************************************************************************************
- * @fn macRxPromiscuousMode
- *
- * @brief Sets promiscuous mode - enabling or disabling it.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macRxPromiscuousMode(uint8 mode)
- {
- rxPromiscuousMode = mode;
- if (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_OFF)
- {
- MAC_RADIO_TURN_ON_RX_FRAME_FILTERING();
- }
- else
- {
- MAC_ASSERT((mode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC) ||
- (mode == MAC_PROMISCUOUS_MODE_COMPLIANT)); /* invalid mode */
- MAC_RADIO_TURN_OFF_RX_FRAME_FILTERING();
- }
- }
- #ifdef CC2591_COMPRESSION_WORKAROUND
- /**************************************************************************************************
- * @fn macRxResetRssi
- *
- * @brief This function reset RSSI peak if the device is not actively in TX or RX.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- void macRxResetRssi(void)
- {
- if ( !(macRxActive || macRxOutgoingAckFlag || macTxActive) )
- {
- COMPRESSION_WORKAROUND_RESET_RSSI();
- }
- }
- #endif /* CC2591_COMPRESSION_WORKAROUND */
- /**************************************************************************************************
- * Compile Time Integrity Checks
- **************************************************************************************************
- */
- /* check for changes to the spec that would affect the source code */
- #if ((MAC_A_MAX_PHY_PACKET_SIZE != 0x7F ) || \
- (MAC_FCF_FIELD_LEN != 2 ) || \
- (MAC_FCF_FRAME_TYPE_POS != 0 ) || \
- (MAC_FCF_FRAME_PENDING_POS != 4 ) || \
- (MAC_FCF_ACK_REQUEST_POS != 5 ) || \
- (MAC_FCF_INTRA_PAN_POS != 6 ) || \
- (MAC_FCF_DST_ADDR_MODE_POS != 10 ) || \
- (MAC_FCF_FRAME_VERSION_POS != 12 ) || \
- (MAC_FCF_SRC_ADDR_MODE_POS != 14 ))
- #error "ERROR! Change to the spec that requires modification of source code."
- #endif
- /* check for changes to the internal flags format */
- #if ((MAC_RX_FLAG_VERSION != 0x03) || \
- (MAC_RX_FLAG_ACK_PENDING != 0x04) || \
- (MAC_RX_FLAG_SECURITY != 0x08) || \
- (MAC_RX_FLAG_PENDING != 0x10) || \
- (MAC_RX_FLAG_ACK_REQUEST != 0x20) || \
- (MAC_RX_FLAG_INTRA_PAN != 0x40))
- #error "ERROR! Change to the internal RX flags format. Requires modification of source code."
- #endif
- /* validate CRC OK bit optimization */
- #if (MAC_RX_FLAG_CRC_OK != PROPRIETARY_FCS_CRC_OK_BIT)
- #error "ERROR! Optimization relies on these bits having the same position."
- #endif
- #if (MAC_RX_ACTIVE_NO_ACTIVITY != 0x00)
- #error "ERROR! Zero is reserved value of macRxActive. Allows boolean operations, e.g !macRxActive."
- #endif
- #if (MAC_PROMISCUOUS_MODE_OFF != 0x00)
- #error "ERROR! Zero is reserved value of rxPromiscuousMode. Allows boolean operations, e.g !rxPromiscuousMode."
- #endif
- /**************************************************************************************************
- */
|