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

📄 mac_csp_tx.c

📁 Zigbee2006入门源代码,包括了Zigbee的入门介绍,和源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}


/**************************************************************************************************
 * @fn          macCspForceTxDoneIfPending
 *
 * @brief       The function clears out any pending TX done logic.  Used by receive logic
 *              to make sure its ISR does not prevent transmit from completing in a reasonable
 *              amount of time.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspForceTxDoneIfPending(void)
{
///////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : work workaround for chip bug #273.  The instruction DECZ might
//  be incorrectly executed twice, resulting an illegal value for CSPZ.
//  Delete when Rev B is obsolete.
///////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
  if (CSPZ >= 0xF8) { CSPZ = 0; }
#endif
///////////////////////////////////////////////////////////////////////////////////////
  
  if ((CSPZ == CSPZ_CODE_TX_DONE) &&  MAC_MCU_CSP_STOP_INTERRUPT_IS_ENABLED())
  {
    MAC_MCU_CSP_STOP_DISABLE_INTERRUPT();
    if (MAC_MCU_CSP_INT_INTERRUPT_IS_ENABLED())
    {
      macCspTxIntIsr();
    }
    macTxDoneCallback();
  }
}


/**************************************************************************************************
 * @fn          macCspTxRequestAckTimeoutCallback
 *
 * @brief       Requests a callback after the ACK timeout period has expired.  At that point,
 *              the function macTxAckTimeoutCallback() is called via an interrupt.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxRequestAckTimeoutCallback(void)
{
  uint8 startSymbol;
  uint8 symbols;
  uint8 rollovers;

  MAC_ASSERT(!(RFIM & IM_CSP_STOP)); /* already an active CSP program */

  /* record current symbol count */
  startSymbol = CSP_WEVENT_READ_COUNT_SYMBOLS();

  /* set symbol timeout from PIB */
  symbols = macPib.ackWaitDuration;

  /* make sure delay value is not too small for logic to handle */
  MAC_ASSERT(symbols > MAC_A_UNIT_BACKOFF_PERIOD);  /* symbols timeout period must be great than a backoff */

  /* subtract out symbols left in current backoff period */
  symbols = symbols - (MAC_A_UNIT_BACKOFF_PERIOD - startSymbol);

  /* calculate rollovers needed for remaining symbols */
  rollovers = symbols / MAC_A_UNIT_BACKOFF_PERIOD;

  /* calculate symbols that still need counted after last rollover */
  symbols = symbols - (rollovers * MAC_A_UNIT_BACKOFF_PERIOD);

  /* add one to rollovers to account for symbols remaining in the current backoff period */
  rollovers++;

  /* set up parameters for CSP program */
  CSPZ = CSPZ_CODE_TX_ACK_TIME_OUT;
  CSPX = rollovers;
  CSP_WEVENT_SET_TRIGGER_SYMBOLS(symbols);

  /* clear the currently loaded CSP, this generates a stop interrupt which must be cleared */
  CSP_STOP_AND_CLEAR_PROGRAM();
  MAC_MCU_CSP_STOP_CLEAR_INTERRUPT();
  
  /*--------------------------
   * load CSP program
   */
  RFST = WAITX;
  RFST = WEVENT;
  /*--------------------------
   */
  
  /* run CSP program */
  MAC_MCU_CSP_STOP_ENABLE_INTERRUPT();
  CSP_START_PROGRAM();

  /*
   *  For bullet proof operation, must account for the boundary condition
   *  where a rollover occurs after count was read but before CSP program
   *  was started.
   *
   *  If current symbol count is less that the symbol count recorded at the
   *  start of this function, a rollover has occurred.
   */
  if (CSP_WEVENT_READ_COUNT_SYMBOLS() < startSymbol)
  {
    /* a rollover has occurred, make sure it was accounted for */
    if (CSPX == rollovers)
    {
      /*
       *  Rollover event missed, manually decrement CSPX to adjust.
       *
       *  Note : there is a very small chance that CSPX does not
       *  get decremented.  This would occur if CSPX were written
       *  at exactly the same time a timer overflow is occurring (which
       *  causes the CSP instruction WAITX to decrement CSPX).  This
       *  would be extremely rare, but if it does happen, the only
       *  consequence is that the ACK timeout period is extended
       *  by one backoff.
       */
      CSPX--;
    }
  }
}


/**************************************************************************************************
 * @fn          macCspTxCancelAckTimeoutCallback
 *
 * @brief       Cancels previous request for ACK timeout callback.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxCancelAckTimeoutCallback(void)
{
  MAC_MCU_CSP_STOP_DISABLE_INTERRUPT();
  CSP_STOP_AND_CLEAR_PROGRAM();
}


/**************************************************************************************************
 * @fn          macCspTxIntIsr
 *
 * @brief       Interrupt service routine for handling INT type interrupts from CSP.
 *              This interrupt happens when the CSP instruction INT is executed.  It occurs
 *              once the SFD signal goes high indicating that transmit has successfully
 *              started.  The timer value has been captured at this point and timestamp
 *              can be stored.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxIntIsr(void)
{
///////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : work workaround for chip bug #273.  The instruction DECY might
//  be incorrectly executed twice, resulting an illegal value for CSPZ.
//  Delete when Rev B is obsolete.
///////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
  if (CSPY >= 0xF8) { CSPY = 0; }
#endif
///////////////////////////////////////////////////////////////////////////////////////

  MAC_MCU_CSP_INT_DISABLE_INTERRUPT();

  if (CSPY == CSPY_RXTX_COLLISION)
  {
    macRxHaltCleanup();
  }

  /* execute callback function that records transmit timestamp */
  macTxTimestampCallback();
}


/**************************************************************************************************
 * @fn          macCspTxStopIsr
 *
 * @brief       Interrupt service routine for handling STOP type interrupts from CSP.
 *              This interrupt occurs when the CSP program stops by 1) reaching the end of the
 *              program, 2) executing SSTOP within the program, 3) executing immediate
 *              instruction ISSTOP.
 *
 *              The value of CSPZ indicates if interrupt is being used for ACK timeout or
 *              is the end of a transmit.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxStopIsr(void)
{
  MAC_MCU_CSP_STOP_DISABLE_INTERRUPT();

///////////////////////////////////////////////////////////////////////////////////////
//  REV_B_WORKAROUND : work workaround for chip bug #273.  The instruction DECZ might
//  be incorrectly executed twice, resulting an illegal value for CSPZ.
//  Delete when Rev B is obsolete.
///////////////////////////////////////////////////////////////////////////////////////
#ifndef _REMOVE_REV_B_WORKAROUNDS
  if (CSPZ >= 0xF8) { CSPZ = 0; }
#endif
///////////////////////////////////////////////////////////////////////////////////////

  if (CSPZ == CSPZ_CODE_TX_DONE)
  {
    macTxDoneCallback();
  }
  else if (CSPZ == CSPZ_CODE_CHANNEL_BUSY)
  {
    macTxChannelBusyCallback();
  }
  else
  {
    MAC_ASSERT(CSPZ == CSPZ_CODE_TX_ACK_TIME_OUT); /* unexpected CSPZ value */
    macTxAckNotReceivedCallback();
  }
}



/**************************************************************************************************
 *                                  Compile Time Integrity Checks
 **************************************************************************************************
 */
#if ((CSPY_RXTX_COLLISION != 0) || (CSPY_NO_RXTX_COLLISION != 1))
#error "ERROR!  The CSPY return values are very specific and tied into the actual CSP program."
#endif

#if ((CSPZ_CODE_TX_DONE != 0) || (CSPZ_CODE_CHANNEL_BUSY != 1))
#error "ERROR!  The CSPZ return values are very specific and tied into the actual CSP program."
#endif

#if (MAC_TX_TYPE_SLOTTED_CSMA != 0)
#error "WARNING!  This define value changed.  It was selected for optimum performance."
#endif

#if (T2THD_TICKS_PER_SYMBOL == 0)
#error "ERROR!  Timer compare will not work on high byte.  Clock speed is probably too slow."
#endif

#define BACKOFFS_PER_BASE_SUPERFRAME  (MAC_A_BASE_SLOT_DURATION * MAC_A_NUM_SUPERFRAME_SLOTS)
#if (((BACKOFFS_PER_BASE_SUPERFRAME - 1) & SLOTTED_TX_BACKOFF_COUNT_ALIGN_BIT_MASK) != SLOTTED_TX_BACKOFF_COUNT_ALIGN_BIT_MASK)
#error "ERROR!  The specified bit mask for backoff alignment of slotted transmit does not rollover 'cleanly'."
/*
 *  In other words, the backoff count for the number of superframe rolls over before the
 *  specified number of bits rollover.  For example, if backoff count for a superframe
 *  rolls over at 48, the binary number immediately before a rollover is 00101111.
 *  In this case four bits would work as an alignment mask.  Five would not work though as
 *  the lower five bits would go from 01111 to 00000 (instead of the value 10000 which
 *  would be expected) because it a new superframe is starting.
 */
#endif
#if (SLOTTED_TX_MAX_BACKOFF_COUNTDOWN_NUM_BITS < 2)
#error "ERROR!  Not enough backoff countdown bits to be practical."
#endif


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

⌨️ 快捷键说明

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