12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016 |
- /**************************************************************************************************
- Filename: mac_mcu.c
- Revised: $Date: 2012-03-07 16:55:44 -0800 (Wed, 07 Mar 2012) $
- Revision: $Revision: 29672 $
- 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_mcu.h"
- /* low-level specific */
- #include "mac_rx.h"
- #include "mac_tx.h"
- #include "mac_backoff_timer.h"
- #include "mac_csp_tx.h"
- #include "mac_rx_onoff.h"
- #include "mac_low_level.h"
- /* target specific */
- #include "mac_mcu.h"
- #include "mac_radio_defs.h"
- /* debug */
- #include "mac_assert.h"
- /* ------------------------------------------------------------------------------------------------
- * Defines
- * ------------------------------------------------------------------------------------------------
- */
- /* for optimized indexing of uint32's */
- #if HAL_MCU_LITTLE_ENDIAN()
- #define UINT32_NDX0 0
- #define UINT32_NDX1 1
- #define UINT32_NDX2 2
- #define UINT32_NDX3 3
- #else
- #define UINT32_NDX0 3
- #define UINT32_NDX1 2
- #define UINT32_NDX2 1
- #define UINT32_NDX3 0
- #endif
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- uint8 macChipVersion = 0;
- static int8 maxRssi;
- static uint32 prevAccumulatedOverflowCount = 0;
- static bool updateRolloverflag = FALSE;
- static uint32 prevoverflowCount = 0;
- /*
- * This number is used to calculate the precision count for OSAL timer update. In Beacon mode,
- * the overflow count may be initialized to zero or to a constant. The "skip" in overflow count
- * needs to be accounted for in this variable.
- */
- static uint32 accumulatedOverflowCount = 0;
- /* Function pointer for the random seed callback */
- static macRNGFcn_t pRandomSeedCB = NULL;
- /* ------------------------------------------------------------------------------------------------
- * Local Prototypes
- * ------------------------------------------------------------------------------------------------
- */
- static void mcuRecordMaxRssiIsr(void);
- static uint32 macMcuOverflowGetCompare(void);
- void MAC_SetRandomSeedCB(macRNGFcn_t pCBFcn);
- /**************************************************************************************************
- * @fn MAC_SetRandomSeedCB
- *
- * @brief Set the function pointer for the random seed callback.
- *
- * @param pCBFcn - function pointer of the random seed callback
- *
- * @return none
- **************************************************************************************************
- */
- void MAC_SetRandomSeedCB(macRNGFcn_t pCBFcn)
- {
- pRandomSeedCB = pCBFcn;
- }
- /**************************************************************************************************
- * @fn macMcuInit
- *
- * @brief Initialize the MCU.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuInit(void)
- {
- halIntState_t s;
- /* This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that
- * too many false frames are received if the reset value is used. Make it more likely to detect
- * sync by removing the requirement that both symbols in the SFD must have a correlation value
- * above the correlation threshold, and make sync word detection less likely by raising the
- * correlation threshold.
- */
- MDMCTRL1 = CORR_THR;
- #ifdef FEATURE_CC253X_LOW_POWER_RX
- /* Reduce RX power consumption current to 20mA at the cost of some sensitivity
- * Note: This feature can be applied to CC2530 and CC2533 only.
- */
- RXCTRL = 0x00;
- FSCTRL = 0x50;
- #else
- /* tuning adjustments for optimal radio performance; details available in datasheet */
- RXCTRL = 0x3F;
-
- /* Adjust current in synthesizer; details available in datasheet. */
- FSCTRL = 0x55;
- #endif /* #ifdef FEATURE_CC253X_LOW_POWER_RX */
- #if !(defined HAL_PA_LNA || defined HAL_PA_LNA_CC2590)
- /* Raises the CCA threshold from about -108 dBm to about -80 dBm input level.
- */
- CCACTRL0 = CCA_THR;
- #endif
- #ifdef CC2591_COMPRESSION_WORKAROUND
- /* For Coordinators/Routers with CC2591, increase preamble from 4 to 12 bytes */
- MDMCTRL0 = 0x95;
- /* For End devices without CC2591, increase preamble from 4 to 8 bytes */
- /* MDMCTRL0 = 0x8D; */
- #else
- /* Makes sync word detection less likely by requiring two zero symbols before the sync word.
- * details available in datasheet.
- */
- MDMCTRL0 = 0x85;
- #endif /* CC2591_COMPRESSION_WORKAROUND */
- if (*(uint8 *)(P_INFOPAGE+0x03) == 0x95) // Device is a CC2533
- {
- /* In case the device is a 2533, just update the IVCTRL regoster which is 2533 specific */
- #define IVCTRL XREG( 0x6265 )
- IVCTRL = 0xF;
- }
- /* Adjust current in VCO; details available in datasheet. */
- FSCAL1 = 0x00;
- /* Adjust target value for AGC control loop; details available in datasheet. */
- AGCCTRL1 = 0x15;
- /* Disable source address matching an autopend for now */
- SRCMATCH = 0;
- /* Tune ADC performance, details available in datasheet. */
- ADCTEST0 = 0x10;
- ADCTEST1 = 0x0E;
- ADCTEST2 = 0x03;
- /* Sets TX anti-aliasing filter to appropriate bandwidth.
- * Reduces spurious emissions close to signal.
- */
- TXFILTCFG = TXFILTCFG_RESET_VALUE;
- /* disable the CSPT register compare function */
- CSPT = 0xFF;
- /* enable general RF interrupts */
- IEN2 |= RFIE;
- /* enable general REERR interrupts */
- IEN0 |= RFERRIE;
- /* set RF interrupts one notch above lowest priority (four levels available) */
- IP0 |= IP_RFERR_RF_DMA_BV;
- IP1 &= ~IP_RFERR_RF_DMA_BV;
- /* set T2 interrupts one notch above lowest priority (four levels available)
- * This effectively turned off nested interrupt between T2 and RF.
- */
- IP0 |= IP_RXTX0_T2_BV;
- IP1 &= ~IP_RXTX0_T2_BV;
- /* read chip version */
- macChipVersion = CHVER;
- /*-------------------------------------------------------------------------------
- * Initialize MAC timer.
- */
- /* set timer rollover */
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_PERIOD_VALUE();
- T2M0 = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() & 0xFF;
- T2M1 = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() >> 8;
- HAL_EXIT_CRITICAL_SECTION(s);
- /* start timer */
- MAC_RADIO_TIMER_WAKE_UP();
- /* Enable latch mode and T2 SYNC start. OSAL timer is based on MAC timer.
- * The SYNC start msut be on when POWER_SAVING is on for this design to work.
- */
- T2CTRL |= (LATCH_MODE | TIMER2_SYNC);
-
- /* enable timer interrupts */
- T2IE = 1;
- /*----------------------------------------------------------------------------------------------
- * Initialize random seed value.
- */
- /*
- * Set radio for infinite reception. Once radio reaches this state,
- * it will stay in receive mode regardless RF activity.
- */
- FRMCTRL0 = FRMCTRL0_RESET_VALUE | RX_MODE_INFINITE_RECEPTION;
- /* turn on the receiver */
- macRxOn();
- /*
- * Wait for radio to reach infinite reception state by checking RSSI valid flag.
- * Once it does, the least significant bit of ADTSTH should be pretty random.
- */
- while (!(RSSISTAT & 0x01));
- /* put 16 random bits into the seed value */
- {
- uint16 rndSeed;
- uint8 i;
- rndSeed = 0;
- for(i=0; i<16; i++)
- {
- /* use most random bit of analog to digital receive conversion to populate the random seed */
- rndSeed = (rndSeed << 1) | (RFRND & 0x01);
- }
- /*
- * The seed value must not be zero or 0x0380 (0x8003 in the polynomial). If it is, the psuedo
- * random sequence won’t be random. There is an extremely small chance this seed could randomly
- * be zero or 0x0380. The following check makes sure this does not happen.
- */
- if (rndSeed == 0x0000 || rndSeed == 0x0380)
- {
- rndSeed = 0xBABE; /* completely arbitrary "random" value */
- }
- /*
- * Two writes to RNDL will set the random seed. A write to RNDL copies current contents
- * of RNDL to RNDH before writing new the value to RNDL.
- */
- RNDL = rndSeed & 0xFF;
- RNDL = rndSeed >> 8;
- }
- /* Read 16*8 random bits and store them in flash for future use in random
- key generation for CBKE key establishment */
- if( pRandomSeedCB )
- {
- uint8 randomSeed[MAC_RANDOM_SEED_LEN];
- uint8 i,j;
- for(i = 0; i < 16; i++)
- {
- uint8 rndByte = 0;
- for(j = 0; j < 8; j++)
- {
- /* use most random bit of analog to digital receive conversion to
- populate the random seed */
- rndByte = (rndByte << 1) | (RFRND & 0x01);
- }
- randomSeed[i] = rndByte;
- }
- pRandomSeedCB( randomSeed );
- }
- /* turn off the receiver */
- macRxOff();
- /* take receiver out of infinite reception mode; set back to normal operation */
- FRMCTRL0 = FRMCTRL0_RESET_VALUE | RX_MODE_NORMAL_OPERATION;
- /* Turn on autoack */
- MAC_RADIO_TURN_ON_AUTO_ACK();
- /* Initialize SRCEXTPENDEN and SRCSHORTPENDEN to zeros */
- MAC_RADIO_SRC_MATCH_INIT_EXTPENDEN();
- MAC_RADIO_SRC_MATCH_INIT_SHORTPENDEN();
- }
- /**************************************************************************************************
- * @fn macMcuRandomByte
- *
- * @brief Returns a random byte using a special hardware feature that generates new
- * random values based on the truly random seed set earlier.
- *
- * @param none
- *
- * @return a random byte
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint8 macMcuRandomByte(void)
- {
- /* clock the random generator to get a new random value */
- ADCCON1 = (ADCCON1 & ~RCTRL_BITS) | RCTRL_CLOCK_LFSR;
- /* return new randomized value from hardware */
- return(RNDH);
- }
- /**************************************************************************************************
- * @fn macMcuRandomWord
- *
- * @brief Returns a random word using a special hardware feature that generates new
- * random values based on the truly random seed set earlier.
- *
- * @param none
- *
- * @return a random word
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint16 macMcuRandomWord(void)
- {
- uint16 random_word;
- /* clock the random generator to get a new random value */
- ADCCON1 = (ADCCON1 & ~RCTRL_BITS) | RCTRL_CLOCK_LFSR;
- /* read random word */
- random_word = (RNDH << 8);
- random_word += RNDL;
- /* return new randomized value from hardware */
- return(random_word);
- }
- /**************************************************************************************************
- * @fn macMcuTimerForceDelay
- *
- * @brief Delay the timer by the requested number of ticks.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuTimerForceDelay(uint16 x)
- {
- halIntState_t s;
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_COUNT_VALUE();
- T2M0 = (x) & 0xFF;
- T2M1 = (x) >> 8;
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /**************************************************************************************************
- * @fn macMcuTimerCapture
- *
- * @brief Returns the last timer capture. This capture should have occurred at the
- * receive time of the last frame (the last time SFD transitioned to active).
- *
- * @param none
- *
- * @return last capture of hardware timer (full 16-bit value)
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint16 macMcuTimerCapture(void)
- {
- uint16 timerCapture;
- halIntState_t s;
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_CAPTURE_VALUE();
- timerCapture = T2M1 << 8;
- timerCapture |= T2M0;
- HAL_EXIT_CRITICAL_SECTION(s);
- return (timerCapture);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowCount
- *
- * @brief Returns the value of the overflow counter which is a special hardware feature.
- * The overflow count actually is 24 bits of information.
- *
- * @param none
- *
- * @return value of overflow counter
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint32 macMcuOverflowCount(void)
- {
- uint32 overflowCount;
- halIntState_t s;
- /* for efficiency, the 32-bit value is encoded using endian abstracted indexing */
- HAL_ENTER_CRITICAL_SECTION(s);
- /* This T2 access macro allows accessing both T2MOVFx and T2Mx */
- MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE();
- /* Latch the entire T2MOVFx first by reading T2M0. */
- T2M0;
- ((uint8 *)&overflowCount)[UINT32_NDX0] = T2MOVF0;
- ((uint8 *)&overflowCount)[UINT32_NDX1] = T2MOVF1;
- ((uint8 *)&overflowCount)[UINT32_NDX2] = T2MOVF2;
- ((uint8 *)&overflowCount)[UINT32_NDX3] = 0;
- HAL_EXIT_CRITICAL_SECTION(s);
- return (overflowCount);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowCapture
- *
- * @brief Returns the last capture of the overflow counter. A special hardware feature
- * captures the overflow counter when the regular hardware timer is captured.
- *
- * @param none
- *
- * @return last capture of overflow count
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint32 macMcuOverflowCapture(void)
- {
- uint32 overflowCapture;
- halIntState_t s;
- /* for efficiency, the 32-bit value is encoded using endian abstracted indexing */
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_OVF_CAPTURE_VALUE();
- ((uint8 *)&overflowCapture)[UINT32_NDX0] = T2MOVF0;
- ((uint8 *)&overflowCapture)[UINT32_NDX1] = T2MOVF1;
- ((uint8 *)&overflowCapture)[UINT32_NDX2] = T2MOVF2;
- ((uint8 *)&overflowCapture)[UINT32_NDX3] = 0;
- HAL_EXIT_CRITICAL_SECTION(s);
- return (overflowCapture);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowSetCount
- *
- * @brief Sets the value of the hardware overflow counter.
- *
- * @param count - new overflow count value
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuOverflowSetCount(uint32 count)
- {
- halIntState_t s;
- MAC_ASSERT(! (count >> 24) ); /* illegal count value */
- /* save the current overflow count */
- accumulatedOverflowCount += macMcuOverflowCount();
-
- /* deduct the initial count */
- accumulatedOverflowCount -= count;
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE();
- /* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
- /* T2OF2 must be written last */
- T2MOVF0 = ((uint8 *)&count)[UINT32_NDX0];
- T2MOVF1 = ((uint8 *)&count)[UINT32_NDX1];
- T2MOVF2 = ((uint8 *)&count)[UINT32_NDX2];
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowSetCompare
- *
- * @brief Set overflow count compare value. An interrupt is triggered when the overflow
- * count equals this compare value.
- *
- * @param count - overflow count compare value
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuOverflowSetCompare(uint32 count)
- {
- halIntState_t s;
- uint8 enableCompareInt = 0;
- MAC_ASSERT( !(count >> 24) ); /* illegal count value */
- HAL_ENTER_CRITICAL_SECTION(s);
- /* Disable overflow compare interrupts. */
- if (T2IRQM & TIMER2_OVF_COMPARE1M)
- {
- enableCompareInt = 1;
- T2IRQM &= ~TIMER2_OVF_COMPARE1M;
- }
- MAC_MCU_T2_ACCESS_OVF_CMP1_VALUE();
- /* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
- T2MOVF0 = ((uint8 *)&count)[UINT32_NDX0];
- T2MOVF1 = ((uint8 *)&count)[UINT32_NDX1];
- T2MOVF2 = ((uint8 *)&count)[UINT32_NDX2];
- /*
- * Now that new compare value is stored, clear the interrupt flag. This is important just
- * in case a false match was generated as the multi-byte compare value was written.
- */
- T2IRQF = ~TIMER2_OVF_COMPARE1F;
- /* re-enable overflow compare interrupts if they were previously enabled */
- if (enableCompareInt)
- {
- T2IRQM |= TIMER2_OVF_COMPARE1M;
- }
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowSetPeriod
- *
- * @brief Set overflow count period value. An interrupt is triggered when the overflow
- * count equals this period value.
- *
- * @param count - overflow count compare value
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuOverflowSetPeriod(uint32 count)
- {
- halIntState_t s;
- uint8 enableCompareInt = 0;
- MAC_ASSERT( !(count >> 24) ); /* illegal count value */
- HAL_ENTER_CRITICAL_SECTION(s);
- /* Disable overflow compare interrupts. */
- if (T2IRQM & TIMER2_OVF_PERM)
- {
- enableCompareInt = 1;
- T2IRQM &= ~TIMER2_OVF_PERM;
- }
- MAC_MCU_T2_ACCESS_OVF_PERIOD_VALUE();
- /* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
- T2MOVF0 = ((uint8 *)&count)[UINT32_NDX0];
- T2MOVF1 = ((uint8 *)&count)[UINT32_NDX1];
- T2MOVF2 = ((uint8 *)&count)[UINT32_NDX2];
- /*
- * Now that new compare value is stored, clear the interrupt flag. This is important just
- * in case a false match was generated as the multi-byte compare value was written.
- */
- T2IRQF &= ~TIMER2_OVF_PERF;
- /* re-enable overflow compare interrupts if they were previously enabled */
- if (enableCompareInt)
- {
- T2IRQM |= TIMER2_OVF_PERM;
- }
- halSetMaxSleepLoopTime(count);
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /**************************************************************************************************
- * @fn macMcuOverflowGetCompare
- *
- * @brief Get overflow count compare value.
- *
- * @param none
- *
- * @return overflow count compare value
- **************************************************************************************************
- */
- MAC_INTERNAL_API uint32 macMcuOverflowGetCompare(void)
- {
- halIntState_t s;
- uint32 compare;
- HAL_ENTER_CRITICAL_SECTION(s);
- MAC_MCU_T2_ACCESS_OVF_CMP1_VALUE();
- /* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
- ((uint8 *)&compare)[UINT32_NDX0] = T2MOVF0;
- ((uint8 *)&compare)[UINT32_NDX1] = T2MOVF1;
- ((uint8 *)&compare)[UINT32_NDX2] = T2MOVF2;
- ((uint8 *)&compare)[UINT32_NDX3] = 0;
- HAL_EXIT_CRITICAL_SECTION(s);
- return(compare);
- }
- /**************************************************************************************************
- * @fn macMcuTimer2Isr
- *
- * @brief Interrupt service routine for timer2, the MAC timer.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- HAL_ISR_FUNCTION( macMcuTimer2Isr, T2_VECTOR )
- {
- uint8 t2irqm;
- uint8 t2irqf;
-
- HAL_ENTER_ISR();
- t2irqm = T2IRQM;
- t2irqf = T2IRQF;
- /*------------------------------------------------------------------------------------------------
- * Overflow compare interrupt - triggers when then overflow counter is
- * equal to the overflow compare register.
- */
- if ((t2irqf & TIMER2_OVF_COMPARE1F) & t2irqm)
- {
- /* call function for dealing with the timer compare interrupt */
- macBackoffTimerCompareIsr();
- /* clear overflow compare interrupt flag */
- T2IRQF = ~TIMER2_OVF_COMPARE1F;
- }
- /*------------------------------------------------------------------------------------------------
- * Overflow compare interrupt - triggers when then overflow counter is
- * equal to the overflow compare register.
- */
- if ((t2irqf & TIMER2_OVF_PERF) & t2irqm)
- {
- /* call function for dealing with the timer compare interrupt */
- macBackoffTimerPeriodIsr();
- /* clear overflow compare interrupt flag */
- T2IRQF = ~TIMER2_OVF_PERF;
- }
- /*------------------------------------------------------------------------------------------------
- * Overflow interrupt - triggers when the hardware timer rolls over.
- */
- else if ((t2irqf & TIMER2_PERF) & t2irqm)
- {
- /* call energy detect interrupt function, this interrupt not used for any other functionality */
- mcuRecordMaxRssiIsr();
- /* clear the interrupt flag */
- T2IRQF = ~TIMER2_PERF;
- }
-
- CLEAR_SLEEP_MODE();
- HAL_EXIT_ISR();
- }
- /**************************************************************************************************
- * @fn macMcuTimer2OverflowWorkaround
- *
- * @brief For CC2530, T2 interrupt won’t be generated when the current count is greater than
- * the comparator. The interrupt is only generated when the current count is equal to
- * the comparator. When the CC2530 is waking up from sleep, there is a small window
- * that the count may be grater than the comparator, therefore, missing the interrupt.
- * This workaround will call the T2 ISR when the current T2 count is greater than the
- * comparator.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- void macMcuTimer2OverflowWorkaround(void)
- {
- if (T2IRQM & TIMER2_OVF_COMPARE1F)
- {
- /* T2 comapre 1 interrupt is enabled but T2 compare 1 intererrupt is not generated */
- if (!(T2IRQF & TIMER2_OVF_COMPARE1F))
- {
- if (MAC_RADIO_BACKOFF_COUNT() > macMcuOverflowGetCompare())
- {
- /* Set the flag to trigger the timer compare interrupt */
- macBackoffTimerCompareIsr();
- T2IRQF = ~TIMER2_OVF_COMPARE1F;
- }
- }
- }
- }
- /**************************************************************************************************
- * @fn macMcuPrecisionCount
- *
- * @brief This function is used by higher layer to read a free running counter driven by
- * MAC timer.
- *
- * @param none
- *
- * @return overflowCount
- **************************************************************************************************
- */
- uint32 macMcuPrecisionCount(void)
- {
- uint32 overflowCount = 0;
- halIntState_t s;
- HAL_ENTER_CRITICAL_SECTION(s);
- /* This T2 access macro allows accessing both T2MOVFx and T2Mx */
- MAC_MCU_T2_ACCESS_OVF_COUNT_VALUE();
- /* Latch the entire T2MOVFx first by reading T2M0.
- * T2M0 is discarded.
- */
- T2M0;
- ((uint8 *)&overflowCount)[UINT32_NDX0] = T2MOVF0;
- ((uint8 *)&overflowCount)[UINT32_NDX1] = T2MOVF1;
- ((uint8 *)&overflowCount)[UINT32_NDX2] = T2MOVF2;
- /* the overflowCount needs to account for the accumulated overflow count in Beacon mode.
- */
- overflowCount += accumulatedOverflowCount;
-
- /*
- * Workaround to take care of the case where a rollover just occured and the call to
- * macBackoffTimerPeriodIsr() hasn't yet occured or if one rollover occured during
- * sleep then update the accumulatedoverflowCount with the rollover
- */
- if((prevoverflowCount > overflowCount) && (prevAccumulatedOverflowCount == accumulatedOverflowCount))
- {
- accumulatedOverflowCount += macGetBackOffTimerRollover();
- overflowCount += macGetBackOffTimerRollover();
- /*don't update the rollover since it has been updated already */
- updateRolloverflag = TRUE;
- }
- /* store the current value of overflowcount and accumulatedOverflowCount */
- prevoverflowCount = overflowCount;
- prevAccumulatedOverflowCount = accumulatedOverflowCount;
- HAL_EXIT_CRITICAL_SECTION(s);
- return(overflowCount);
- }
- /**************************************************************************************************
- * @fn macMcuRfIsr
- *
- * @brief Interrupt service routine that handles all RF interrupts. There are a number
- * of conditions "ganged" onto this one ISR so each condition must be tested for.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- HAL_ISR_FUNCTION( macMcuRfIsr, RF_VECTOR )
- {
- uint8 rfim;
-
- HAL_ENTER_ISR();
- rfim = RFIRQM1;
- /* The CPU level RF interrupt flag must be cleared here (before clearing RFIRQFx).
- * to allow the interrupts to be nested.
- */
- S1CON = 0x00;
- if ((RFIRQF1 & IRQ_CSP_MANINT) & rfim)
- {
- /*
- * Important! Because of how the CSP programs are written, CSP_INT interrupts should
- * be processed before CSP_STOP interrupts. This becomes an issue when there are
- * long critical sections.
- */
- /* clear flag */
- RFIRQF1 = ~IRQ_CSP_MANINT;
- macCspTxIntIsr();
- }
- else if ((RFIRQF1 & IRQ_CSP_STOP) & rfim)
- {
- /* clear flag */
- RFIRQF1 = ~IRQ_CSP_STOP;
- macCspTxStopIsr();
- }
- else if ((RFIRQF1 & IRQ_TXACKDONE) & rfim)
- {
- /* disable interrupt - set up is for "one shot" operation */
- RFIRQM1 &= ~IM_TXACKDONE;
- macRxAckTxDoneCallback();
- }
- rfim = RFIRQM0;
- /* process RFIRQF0 next */
- if ((RFIRQF0 & IRQ_FIFOP) & rfim)
- {
- /* continue to execute interrup t handler as long as FIFOP is active */
- do
- {
- macRxThresholdIsr();
- RFIRQF0 = ~IRQ_FIFOP;
- } while (FSMSTAT1 & FIFOP);
- }
-
- CLEAR_SLEEP_MODE();
- HAL_EXIT_ISR();
- }
- /**************************************************************************************************
- * @fn macMcuRfErrIsr
- *
- * @brief Interrupt service routine that handles all RF Error interrupts. Only the RX FIFO
- * overflow condition is handled.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- HAL_ISR_FUNCTION( macMcuRfErrIsr, RFERR_VECTOR )
- {
- uint8 rferrm;
-
- HAL_ENTER_ISR();
-
- rferrm = RFERRM;
- if ((RFERRF & RFERR_RXOVERF) & rferrm)
- {
- RFERRF = ~RFERR_RXOVERF;
- macRxFifoOverflowIsr();
- }
- CLEAR_SLEEP_MODE();
- HAL_EXIT_ISR();
- }
- /**************************************************************************************************
- * @fn macMcuRecordMaxRssiStart
- *
- * @brief Starts recording of the maximum received RSSI value.
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuRecordMaxRssiStart(void)
- {
- /* start maximum recorded value at the lowest possible value */
- maxRssi = -128;
- /* enable timer overflow interrupt */
- T2IRQM |= TIMER2_PERM;
- }
- /**************************************************************************************************
- * @fn macMcuRecordMaxRssiStop
- *
- * @brief Stops recording of the maximum received RSSI. It returns the maximum value
- * received since starting the recording.
- *
- * @param none
- *
- * @return maximum received RSSI value
- **************************************************************************************************
- */
- MAC_INTERNAL_API int8 macMcuRecordMaxRssiStop(void)
- {
- /* disable timer overflow interrupt */
- T2IRQM &= ~TIMER2_PERM;
- return(maxRssi);
- }
- /*=================================================================================================
- * @fn macMcuRecordMaxRssiIsr
- *
- * @brief Interrupt service routine called during recording of max RSSI value.
- *
- * @param none
- *
- * @return none
- *=================================================================================================
- */
- static void mcuRecordMaxRssiIsr(void)
- {
- int8 rssi;
- /* read latest RSSI value */
- rssi = RSSI;
- /* if new RSSI value is greater than the maximum already received, it is the new maximum */
- if (rssi > maxRssi)
- {
- maxRssi = rssi;
- }
- }
- /**************************************************************************************************
- * @fn macMcuAccumulatedOverFlow
- *
- * @brief This function is used to accumulate timer 2 overflow if applicable
- * on the relevant platform
- *
- * @param none
- *
- * @return none
- **************************************************************************************************
- */
- MAC_INTERNAL_API void macMcuAccumulatedOverFlow(void)
- {
- halIntState_t s;
- HAL_ENTER_CRITICAL_SECTION(s);
- if(updateRolloverflag == FALSE)
- {
- accumulatedOverflowCount += macGetBackOffTimerRollover();
- }
- else
- {
- updateRolloverflag = FALSE;
- }
- HAL_EXIT_CRITICAL_SECTION(s);
- }
- /**************************************************************************************************
- * Compile Time Integrity Checks
- **************************************************************************************************
- */
- #if ((IRQ_SFD != IM_SFD) || (IRQ_FIFOP != IM_FIFOP) || (IRQ_TXACKDONE != IM_TXACKDONE))
- #error "ERROR: Compile time error with RFIRQFx vs RFIRQMx register defines."
- #endif
- #if defined (FEATURE_CC253X_LOW_POWER_RX) && !(defined (HAL_MCU_CC2530) || defined (HAL_MCU_CC2533))
- #error "ERROR: FEATURE_CC253X_LOW_POWER_RX can only be used with CC2530 or CC2533."
- #endif
- /**************************************************************************************************
- */
|