⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_mcu.c

📁 Zigbee2006入门源代码,包括了Zigbee的入门介绍,和源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * @return      none
 **************************************************************************************************
 */
void macMcuOverflowSetCompare(uint32 count)
{
  halIntState_t  s;
  uint8 imBits;

  MAC_ASSERT(!((count >> 16) & ~PEROF2_BITS));   /* illegal count value */

  HAL_ENTER_CRITICAL_SECTION(s);

  /* remember value of interrupt mask bits, allows OFCMPIM bit to be restored later */
  imBits = T2PEROF2 & ~PEROF2_BITS;

  /*
   *  Disable overflow compare interrupts.  (It is OK to write zero to compare part of
   *  this register.  Interrupts are disabled and the new value will be written and the
   *  interrupt flag cleared before interrupts are re-enabled.)
   */
  T2PEROF2 = imBits & ~OFCMPIM;
  T2PEROF2 = imBits & ~OFCMPIM;  /* writing twice is chip bug workaround */
  
  /* for efficiency, the 32-bit value is decoded using endian abstracted indexing */
  T2PEROF0 = ((uint8 *)&count)[UINT32_NDX0];
  T2PEROF1 = ((uint8 *)&count)[UINT32_NDX1];

  /* see declaration of this shadow variable for more information */
  shadowPerof2 = ((uint8 *)&count)[UINT32_NDX2];

  /* write the compare value part of T2PEROF2 without re-enabling overflow compare interrupts */
  T2PEROF2 = (imBits & ~OFCMPIM) | shadowPerof2;
  T2PEROF2 = (imBits & ~OFCMPIM) | shadowPerof2;  /* writing twice is chip bug workaround */
  
  /*
   *  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.
   */
  T2CNF = T2CNF_BASE_VALUE | (~OFCMPIF & T2CNF_IF_BITS);

  /* re-enable overflow compare interrupts if they were previously enabled */
  T2PEROF2 = imBits | shadowPerof2;
  T2PEROF2 = imBits | shadowPerof2;  /* writing twice is chip bug workaround */
  
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @fn          macMcuTimer2Isr
 *
 * @brief       Interrupt service routine for timer2, the MAC timer.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
HAL_ISR_FUNCTION( macMcuTimer2Isr, T2_VECTOR )
{
  uint8 t2perof2;

  /* temporary variable used to suppress volatile access order warning */
  t2perof2 = T2PEROF2;

  /*------------------------------------------------------------------------------------------------
   *  Overflow compare interrupt - triggers when then overflow counter is
   *  equal to the overflow compare register.
   */
  if ((T2CNF & OFCMPIF) & t2perof2)
  {
    /* call function for dealing with the timer compare interrupt */
    macBackoffTimerCompareIsr();
    
    /*
     *  NOTE : The interrupt flag for overflow compare is not cleared here.  This is done
     *         in the code that sets a new overflow compare value.
     */
  }

  /*------------------------------------------------------------------------------------------------
   *  Overflow interrupt - triggers when the hardware timer rolls over.
   */
  else if ((T2CNF & PERIF) & t2perof2)
  {
    /* call energy detect interrupt function, this interrupt not used for any other functionality */
    mcuRecordMaxRssiIsr();

    /* clear the interrupt flag by writing a zero to only that flag, write one to other flags */
    T2CNF = T2CNF_BASE_VALUE | (~PERIF & T2CNF_IF_BITS);
  }
}


/**************************************************************************************************
 * @fn          macMcuOrT2PEROF2
 *
 * @brief       This function is used to OR the interrupt mask bits in register T2PERFOF2.
 *              Because of the hardware design a shadow register is required to preserve the
 *              other bits in this register.  See the declaration of variable shadowPerof2 above
 *              for a full description.
 *
 * @param       orValue - value to OR register with
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuOrT2PEROF2(uint8 orValue)
{
  halIntState_t  s;

  MAC_ASSERT(!(orValue & PEROF2_BITS)); /* only interrupt mask bits should be affected */

  /*
   *  Perform OR operation only on interrupt mask bits.  The shadow register preserves
   *  the value previously written to the other bits in the register.
   */
  HAL_ENTER_CRITICAL_SECTION(s);
  T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) | orValue) | shadowPerof2;
  T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) | orValue) | shadowPerof2;  /* writing twice is chip bug workaround */
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @fn          macMcuAndT2PEROF2
 *
 * @brief       This function is used to AND the interrupt mask bits in register T2PERFOF2.
 *              Because of the hardware design a shadow register is required to preserve the
 *              other bits in this register.  See the declaration of variable shadowPerof2 above
 *              for a full description.
 *
 * @param       andValue - value to AND register with
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuAndT2PEROF2(uint8 andValue)
{
  halIntState_t  s;
  
  MAC_ASSERT((andValue & PEROF2_BITS) == PEROF2_BITS); /* only interrupt mask bits should be affected */
  
  /*
   *  Perform AND operation only on interrupt mask bits.  The shadow register preserves
   *  the value previously written to the other bits in the register.
   */
  HAL_ENTER_CRITICAL_SECTION(s);
  T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) & andValue) | shadowPerof2;
  T2PEROF2 = ((T2PEROF2 & ~PEROF2_BITS) & andValue) | shadowPerof2;  /* writing twice is chip bug workaround */
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @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;

  rfim = RFIM;

  if ((RFIF & IRQ_CSP_INT) & 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 */
    RFIF = ~IRQ_CSP_INT;
    macCspTxIntIsr();
  }
  else if ((RFIF & IRQ_CSP_STOP) & rfim)
  {
    /* clear flag */
    RFIF = ~IRQ_CSP_STOP;
    macCspTxStopIsr();
  }
  else if ((RFIF & IRQ_TXDONE) & rfim)
  {
    /* disable interrupt - set up is for "one shot" operation */
    HAL_DISABLE_INTERRUPTS();
    RFIM &= ~IM_TXDONE;
    HAL_ENABLE_INTERRUPTS();
//////////////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : On Rev B parts the TXDONE signal does not fire for transmitted ACKs.
//  As a workaround, the SFD signal is used instead (the TXDONE #defines used here have
//  been redefined elsewhere to be SFD values).  There is a problem with the SFD signal
//  though... it fires at the *start* of an ACK.  To get around this, the code pends until
//  the TX_ACTIVE signal goes inactive.  Ugly.  Delete posthaste once Rev B is obsolete.
#ifndef _REMOVE_REV_B_WORKAROUNDS
    while (RFSTATUS & TX_ACTIVE);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
    macRxAckTxDoneCallback();
  }
  else if ((RFIF & IRQ_FIFOP) & rfim)
  {
    /* continue to execute interrupt handler as long as FIFOP is active */
    do
    {
      macRxThresholdIsr();
      RFIF = ~IRQ_FIFOP;
    } while (RFSTATUS & FIFOP);
  }

/////////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : workaround for chip bug #297, replace with following code when fixed
/////////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
  S1CON = 0x00;
  HAL_DISABLE_INTERRUPTS();
  rfim = RFIM;
  if (RFIF & rfim)
  {
    S1CON = 0x03;
  }
  HAL_ENABLE_INTERRUPTS();
#else
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//  keep this code, delete the rest
  S1CON = 0x00;
  RFIF = 0xFF;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif
/////////////////////////////////////////////////////////////////////////////////////////
}



/////////////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : part of workaround for chip bug #297, delete it when possible
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
/**************************************************************************************************
 * @fn          macMcuOrRFIM
 *
 * @brief       Workaround code that should disappear when Rev B is obsolete.
 *
 * @param       value - value to "or" into RFIM
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuOrRFIM(uint8 value)
{
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  S1CON = 0x00;
  RFIM |= value;
  {
    uint8 rfim;
    rfim = RFIM;
    if (RFIF & rfim)
    {
      S1CON = 0x03;
    }
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}

/**************************************************************************************************
 * @fn          macMcuAndRFIM
 *
 * @brief       Workaround code that should disappear when Rev B is obsolete.
 *
 * @param       value - value to "and" into RFIM
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuAndRFIM(uint8 value)
{
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  S1CON = 0x00;
  RFIM &= value;
  {
    uint8 rfim;
    rfim = RFIM;
    if (RFIF & rfim)
    {
      S1CON = 0x03;
    }
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @fn          macMcuWriteRFIF
 *
 * @brief       Workaround code that should disappear when Rev B is obsolete.
 *
 * @param       value - value write to RFIF
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuWriteRFIF(uint8 value)
{
  halIntState_t  s;
  uint8 rfim;

  HAL_ENTER_CRITICAL_SECTION(s);
  RFIF = value;
  S1CON = 0x00;
  rfim = RFIM;
  if (RFIF & rfim)
  {
    S1CON = 0x03;
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////


/**************************************************************************************************
 * @fn          macMcuRecordMaxRssiStart
 *
 * @brief       Starts recording of the maximum received RSSI value.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macMcuRecordMaxRssiStart(void)
{
  /* start maximum recorded value at the lowest possible value */
  maxRssi = -128;

  /* enable timer overflow interrupt */
  macMcuOrT2PEROF2(PERIM);
}


/**************************************************************************************************
 * @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
 **************************************************************************************************
 */
int8 macMcuRecordMaxRssiStop(void)
{
  /* disable timer overflow interrupt */
  macMcuAndT2PEROF2(~PERIM);

  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 = RSSIL;

  /* if new RSSI value is greater than the maximum already received, it is the new maximum */
  if (rssi > maxRssi)
  {
    maxRssi = rssi;
  }
}



/**************************************************************************************************
 *                                  Compile Time Integrity Checks
 **************************************************************************************************
 */
#if ((IRQ_SFD != IM_SFD) || (IRQ_FIFOP != IM_FIFOP) || (IRQ_TXDONE != IM_TXDONE))
#error "ERROR: Compile time error with RFIF vs RFIM register defines."
#endif

#if ((OFCMPIF != OFCMPIM) || (PERIF != PERIM) || (CMPIF != CMPIM))
#error "ERROR: Compile time error with T2CNF vs T2PEROF2 register defines."
#endif


/**************************************************************************************************
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -