/********************************************************************* * @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 None * * @return None */ void MAC_SrcMatchEnable (void) { /* 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; }
/********************************************************************* * @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_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 None * * @return None */ void MAC_SrcMatchEnable (void) { /* 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(); /* AUTOPEND function requires that the received * frame is a DATA REQUEST MAC command frame */ MAC_RADIO_TURN_ON_AUTOPEND_DATAREQ_ONLY(); /* Configure all the globals */ macSrcMatchIsEnabled = TRUE; }
static #endif /* USE_ICALL */ void macBackoffTimerEventHandler(void) { halIntState_t is; uint8 events; HAL_ENTER_CRITICAL_SECTION(is); events = macBackoffTimerEvents; macBackoffTimerEvents = 0; HAL_EXIT_CRITICAL_SECTION(is); if (events & MAC_BACKOFF_TIMER_EVENT_POWER_WAKEUP) { // Wakeup radio // Turning on radio domain before clock set up seems to cause // unexpected interrupt. // Hence interrupt shall be disabled here. MB_DisableInts(); // Enable clocks for all radio internal modules. // Use Non-Buff access for safety and check for sanity HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = 0x7FF; /* Setup mailbox */ macSetupMailbox(); #ifdef DEBUG_SW_TRACE /* re-enable RF trace output for FPGA */ MB_SendCommand( BUILD_DIRECT_PARAM_EXT_CMD( CMD_ENABLE_DEBUG, 0x1D40 ) ); /* or 0x1940 for less trace */ DBG_PRINT0(DBGSYS, "RF Trace Resumes..."); #endif /* DEBUG_SW_TRACE */ /* Start off CM0. Patch it. */ macSetupRfHal(); /* Restore states */ MAC_RADIO_SET_CHANNEL(macPhyChannel); MAC_RADIO_SET_PAN_COORDINATOR(macPanCoordinator); MAC_RADIO_SET_PAN_ID(pMacPib->panId); MAC_RADIO_SET_SHORT_ADDR(pMacPib->shortAddress); MAC_RADIO_SET_IEEE_ADDR(pMacPib->extendedAddress.addr.extAddr); #if !defined( USE_FPGA ) #ifdef USE_ICALL // Switch back to HFOSC. while (!ICall_pwrIsStableXOSCHF()); ICall_pwrSwitchXOSCHF(); #endif /* USE_ICALL */ #ifdef OSAL_PORT2TIRTOS // Switches back to HFOSC. while (!Power_isStableXOSC_HF()); Power_switchXOSC_HF(); #endif /* OSAL_PORT2TIRTOS */ #endif /* !defined( USE_FPGA ) */ /* Synchronize RAT timer */ macSyncStartRAT(macRATValue); /* 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(); /* Start 15.4 Radio */ macSetupRadio(); /* Restore timer comparators */ MAC_RADIO_BACKOFF_SET_PERIOD(macBackoffTimerRollover); MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerTrigger); #if 0 /* Following code should be disabled normally */ /* Code for wakeup lead time calibration */ { static uint32 macBackoffTimerMinMargin = 0xffffffffu; uint32 delta = macPrevPeriodRatCount + backoffTimerTrigger * MAC_BACKOFF_TO_RAT_RATIO - MAC_RAT_COUNT; if (delta < macBackoffTimerMinMargin) { macBackoffTimerMinMargin = delta; } } #endif } /* Note that MAC_BACKOFF_TIMER_EVENT_POWER_TIMER_EXP handling must always * occur after handling of MAC_BACKOFF_TIMER_EVENT_POWER_WAKEUP event * because the device might be waking up upon the timer event itself * in which case, radio has to be turned on before updating the RAT timer. */ if (events & MAC_BACKOFF_TIMER_EVENT_POWER_TIMER_EXP) { /* Update wakeup schedule, which most likely would vote not to enter * sleep state. */ HAL_ENTER_CRITICAL_SECTION(is); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(is); } }
/************************************************************************************************** * @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 /* Makes sync word detection less likely by requiring two zero symbols before the sync word. * details available in datasheet. */ MDMCTRL0 = 0x85; #if defined (HAL_MCU_CC2533) 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; } #endif /* Adjust current in VCO; details available in datasheet. */ FSCAL1 = 0x01; /* 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; /*Controls bias currents */ IVCTRL = 0x0B; /* disable the CSPT register compare function */ CSPT = 0xFFUL; IntPrioritySet(INT_RFCORERTX, HAL_INT_PRIOR_MAC); IntPrioritySet(INT_RFCOREERR, HAL_INT_PRIOR_MAC); /* enable general RF interrupts */ HAL_ENABLE_RF_INTERRUPT(); /* enable general REERR interrupts */ HAL_ENABLE_RF_ERROR_INTERRUPT(); /* set T2 interrupts one notch above lowest priority (four levels available) * This effectively turned off nested interrupt between T2 and RF. */ IntPrioritySet(INT_MACTIMR, HAL_INT_PRIOR_MAC); /* read chip version */ macChipVersion = CHIPID >> 16; /*------------------------------------------------------------------------------- * Initialize MAC timer. */ /* set timer rollover */ HAL_ENTER_CRITICAL_SECTION(s); MAC_MCU_T2_ACCESS_PERIOD_VALUE(); T2M0 = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() & 0xFFUL; T2M1 = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() >> 8UL; 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 */ IntEnable(INT_MACTIMR); /*---------------------------------------------------------------------------------------------- * 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 < MAC_RANDOM_SEED_LEN; 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(); }