示例#1
0
/**************************************************************************************************
 * @fn          macRadioUpdateChannel
 *
 * @brief       Update the radio channel if a new channel has been requested.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRadioUpdateChannel(void)
{
  halIntState_t  s;

  MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */

  /* if the channel has changed, set the radio to the new channel */
  HAL_ENTER_CRITICAL_SECTION(s);
  if (reqChannel != macPhyChannel)
  {
    macPhyChannel = reqChannel;
    HAL_EXIT_CRITICAL_SECTION(s);

    /* changing the channel stops any receive in progress */
    macRxOff();
    MAC_RADIO_SET_CHANNEL(macPhyChannel);

    /* If the channel is updated in the middle of receiving a frame, we must
     * clean up the Rx logic.
     */
    macRxHaltCleanup();

    macRxOnRequest();
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION(s);
  }
}
示例#2
0
/**************************************************************************************************
 * @fn          macRxOffRequest
 *
 * @brief       Turn off receiver if permitted.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxOffRequest(void)
{
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  if (!macRxEnableFlags)
  {
    if (!MAC_RX_IS_PHYSICALLY_ACTIVE() && !MAC_TX_IS_PHYSICALLY_ACTIVE())
    {
      macRxOff();
    }
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}
示例#3
0
/**************************************************************************************************
 * @fn          macRxOffRequest
 *
 * @brief       Turn off receiver if permitted.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRxOffRequest(void)
{
  halIntState_t  s;

  DBG_PRINT0(DBGSYS, "macRxOffRequest()");
  HAL_ENTER_CRITICAL_SECTION(s);
  if (!macRxEnableFlags)
  {
    if (!MAC_RX_IS_PHYSICALLY_ACTIVE() && !MAC_TX_IS_PHYSICALLY_ACTIVE())
    {
      macRxOff();
    }
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}
示例#4
0
/**************************************************************************************************
 * @fn          macSleep
 *
 * @brief       Puts radio into the selected sleep mode.
 *
 * @param       sleepState - selected sleep level, see #defines in .h file
 *
 * @return      TRUE if radio was successfully put into selected sleep mode.
 *              FALSE if it was not safe for radio to go to sleep.
 **************************************************************************************************
 */
uint8 macSleep(uint8 sleepState)
{
  halIntState_t  s;

  /* disable interrupts until macSleepState can be set */
  HAL_ENTER_CRITICAL_SECTION(s);

  /* assert checks */
  MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake to put it to sleep */
  MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* do not sleep when scanning or in promiscuous mode */

  /* if either RX or TX is active or any RX enable flags are set, it's not OK to sleep */
  if (macRxActive || macRxOutgoingAckFlag || macTxActive || macRxEnableFlags)
  {
    HAL_EXIT_CRITICAL_SECTION(s);
    return(FALSE);
  }

  /* turn off the receiver */
  macRxOff();

  /* update sleep state variable */
  macSleepState = sleepState;

  /* macSleepState is now set, re-enable interrupts */
  HAL_EXIT_CRITICAL_SECTION(s);

  /* put MAC timer to sleep */
  MAC_RADIO_TIMER_SLEEP();

  /* put radio in selected sleep mode */
  if (sleepState == MAC_SLEEP_STATE_OSC_OFF)
  {
    MAC_RADIO_TURN_OFF_OSC();
  }
  else
  {
    MAC_ASSERT(sleepState == MAC_SLEEP_STATE_RADIO_OFF); /* unknown sleep state */
    MAC_RADIO_TURN_OFF_POWER();
  }

  /* radio successfully entered sleep mode */
  return(TRUE);
}
示例#5
0
/**************************************************************************************************
 * @fn          macRadioUpdateChannel
 *
 * @brief       Update the radio channel if a new channel has been requested.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRadioUpdateChannel(void)
{
  halIntState_t  s;

  MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */

  /* if the channel has changed, set the radio to the new channel */
  HAL_ENTER_CRITICAL_SECTION(s);
  if (reqChannel != macPhyChannel)
  {
    macPhyChannel = reqChannel;
    HAL_EXIT_CRITICAL_SECTION(s);

    /* changing the channel stops any receive in progress */
    macRxOff();
    MAC_RADIO_SET_CHANNEL(macPhyChannel);
    macRxOnRequest();
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION(s);
  }
}
示例#6
0
/**************************************************************************************************
 * @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();
}
示例#7
0
/**************************************************************************************************
 * @fn          macMcuInit
 *
 * @brief       Initialize the MCU.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuInit(void)
{

  MAC_ASSERT(CHVER >= 0x03); /* chip versions before version D are obsolete */

  /* tuning adjustments for optimal radio performance; details available in datasheet */
  RXCTRL0H = 0x32;
  RXCTRL0L = 0xF5;

  /* enable TX_DONE interrupts for ACK transmits */
  IRQSRC = TXACK;

  /* disable the CSPT register compare function */
  CSPT = 0xFF;

  /* enable general RF interrupts */
  IEN2 |= RFIE;

  /* intialize shadow register */
  shadowPerof2 = 0;

  /* set RF interrupts one notch above lowest priority (four levels available) */
  IP0 |=  IP_RFERR_RF_DMA_BV;
  IP1 &= ~IP_RFERR_RF_DMA_BV;

  /*-------------------------------------------------------------------------------
   *  Initialize MAC timer.
   */

  /* set timer rollover */
  T2CAPLPL = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() & 0xFF;
  T2CAPHPH = MAC_RADIO_TIMER_TICKS_PER_BACKOFF() >> 8;

  /* start timer */
  T2CNF |= RUN;

  /* enable timer interrupts */
  T2IE = 1;

 /*----------------------------------------------------------------------------------------------
  *  Initialize random seed value.
  */

  /* turn on radio power */
  RFPWR &= ~RREG_RADIO_PD;
  while((RFPWR & ADI_RADIO_PD));

  /*
   *  Set radio for infinite reception.  Once radio reaches this state,
   *  it will stay in receive mode regardless RF activity.
   */
  MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_INFINITE_RECEPTION;

  /* turn on the receiver */
  macRxOn();

  /*
   *  Wait for radio to reach infinite reception state.  Once it does,
   *  The least significant bit of ADTSTH should be pretty random.
   */
  while (FSMSTATE != FSM_FFCTRL_STATE_RX_INF)

  /* 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) | (ADCTSTH & 0x01);
    }

    /*
     *  The seed value must not be zero.  If it is, the psuedo random sequence will be always be zero.
     *  There is an extremely small chance this seed could randomly be zero (more likely some type of
     *  hardware problem would cause this).  The following check makes sure this does not happen.
     */
    if (rndSeed == 0x0000)
    {
      rndSeed = 0xBEEF; /* 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;
  }

  /* turn off the receiver */
  macRxOff();

  /* take receiver out of infinite reception mode; set back to normal operation */
  MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_NORMAL_OPERATION;

  /* turn radio back off */
  RFPWR |= RREG_RADIO_PD;
}