Example #1
0
/*********************************************************************
 * @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;
}
Example #3
0
/*********************************************************************
 * @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();
}