Exemple #1
0
/**************************************************************************************************
 * @fn          macBackoffTimerRealign
 *
 * @brief       
 *
 *  Realignment is accomplished by adjusting the internal time base to align with the expected
 *  reception time of an incoming frame.  The difference between the expected reception time and
 *  the actual reception time is computed and this difference is used to adjust the hardware
 *  timer count and backoff count.
 *
 *  The realignment is based on the SFD signal for the incoming frame.  The timer is aligned
 *  by adjusting it with the difference between the expected SFD time and the actual SFD time.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
int32 macBackoffTimerRealign(macRx_t *pMsg)
{
  uint16 timerDelayTicks;
  int32 backoffDelta;
  int32 backoffCount;

  MAC_ASSERT(!MAC_TX_IS_PHYSICALLY_ACTIVE()); /* realignment during actual transmit corrupts timing */

  /*-------------------------------------------------------------------------------
   *  Calculate the delta backoff difference between expected backoff count,
   *  which is zero, and the backoff count of the received frame.
   */

  /* since expected receive time is zero, the delta is simply the receive time */
  backoffDelta = pMsg->mac.timestamp;

  /* if the frame was received more than halfway to the rollover count, use a negative delta value */
  if (((uint32) backoffDelta) > (backoffTimerRollover / 2))
  {
    backoffDelta = backoffDelta - backoffTimerRollover;    /* result will be negative */
  }

  /*-------------------------------------------------------------------------------
   *  Calculate the number of timer ticks to delay that will align the internal
   *  time base with the received frame.
   */

  /* retrieve the timer count when frame was received */
  timerDelayTicks = pMsg->mac.timestamp2;

  /*
   *  Subtract the expected SFD time from the actual SFD time to find the needed
   *  timer adjustment. If subtracting the offset would result in a negative value,
   *  the tick delay must wrap around.
   */
  if (timerDelayTicks >= TIMER_TICKS_EXPECTED_AT_SFD)
  {
    /* since delay count is greater than or equal to offset, subtract it directly */
    timerDelayTicks = timerDelayTicks - TIMER_TICKS_EXPECTED_AT_SFD;
  }
  else
  {
    /*
     *  The expected time is greater that actualy time so it cannot be subtracted directly.
     *  The tick count per backoff is added to wrap around within the backoff.
     *  Since a wrap around did happen, the backoff delta is adjusted by one.
     */
    timerDelayTicks = timerDelayTicks - TIMER_TICKS_EXPECTED_AT_SFD + MAC_RADIO_TIMER_TICKS_PER_BACKOFF();
    backoffDelta--;
  }

  /*-------------------------------------------------------------------------------
   *  Calculate the new backoff count.
   */

  backoffCount = MAC_RADIO_BACKOFF_COUNT() - backoffDelta;

  if (backoffCount >= ((int32) backoffTimerRollover))
  {
    backoffCount -= backoffTimerRollover;
  }
  else if (backoffCount < 0)
  {
    backoffCount += backoffTimerRollover;
  }

  MAC_RADIO_TIMER_FORCE_DELAY(timerDelayTicks);
  MAC_RADIO_BACKOFF_SET_COUNT(backoffCount);

  return(backoffDelta);
}
/**************************************************************************************************
 * @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();
}
/**************************************************************************************************
 * @fn          macMcuInit
 *
 * @brief       Initialize the MCU.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuInit(void)
{
  uint16 i;

///////////////////////////////////////////////////////////////////////////////////
//  FIX_ON_REV_C : replace with line below after transition to Rev C
#ifndef _NEXTREV
  MAC_ASSERT(CHVER >= 0x01); /* chip revision is obsolete */
#else
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//  keep this code, delete the rest (may need to update compare value)
  MAC_ASSERT(CHVER >= 0x02); /* chip revision is obsolete */
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
///////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////
//  FIX_ON_REV_C : workaround for chip bug #51, remove when fixed
#ifndef _NEXTREV
  FSCTRLH = 0x41;
#endif
///////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////
//  FIX_ON_REV_C : workaround for chip bug #267, remove when fixed
#ifndef _NEXTREV
  MDMCTRL0L |= AUTOACK;  /* enable autoack */
#endif
///////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////
//  FIX_ON_REV_C : workaround for chip bug #267, make permanent with Rev C
#ifndef _NEXTREV
  /* do nothing */
#else
// this part can go away once new .h file is shipping
#ifndef IRQSRC
#define IRQSRC    XREG( 0xDF64 )
#endif
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//  keep this code, delete the rest
  /* enable TX_DONE interrupts for ACK transmits */
  IRQSRC = TXACK;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
///////////////////////////////////////////////////////////////////////////////////

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

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

  /* enable CSP INT interrupts */
  RFIM |= IM_CSP_INT;

  /* intialize shadow register */
  shadowPerof2 = 0;

  /* set RF interrupts to be second highest interrupt level (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;

  /* configure clock to use XOSC */
  SLEEP &= ~OSC_PD;                       /* turn on 16MHz RC and 32MHz XOSC */
  while (!(SLEEP & XOSC_STB));            /* wait for 32MHz XOSC stable */
  asm("NOP");                             /* chip bug workaround */
  for (i=0; i<504; i++) asm("NOP");       /* Require 63us delay for Rev B */
  CLKCON = (0x00 | OSC_32KHZ);            /* 32MHz XOSC */
  while (CLKCON != (0x00 | OSC_32KHZ));
  SLEEP |= OSC_PD;                        /* turn off 16MHz RC */
}
Exemple #4
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;
}