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

📄 mac_csp_tx.c

📁 Zigbee2006入门源代码,包括了Zigbee的入门介绍,和源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   */
  RFST = SKIP(2+__SNOP_SKIP__, C_SFD_IS_INACTIVE);
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECY;
  RFST = __SNOP__;

  /*
   *  Watch the SFD pin to determine when the transmit has finished going out.
   *  The INT instruction causes an interrupt to fire.  The ISR for this interrupt
   *  handles the record the timestamp (which was just captured when SFD went high).
   *  Decrement CSPZ at the last step to indicate transmit was successful.
   */
  RFST = WHILE(C_SFD_IS_INACTIVE);
  RFST = INT;
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECZ;
}


/**************************************************************************************************
 * @fn          macCspTxPrepCsmaSlotted
 *
 * @brief       Prepare CSP for "Slotted CSMA" transmit.  Load CSP program and set CSP parameters.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxPrepCsmaSlotted(void)
{
  cspPrepForTxProgram();

  /*----------------------------------------------------------------------
   *  Load CSP program :  Slotted CSMA transmit 
   */
  
  /* wait for X number of backoffs */
  RFST = WAITX;

  /* wait for one backoff to guarantee receiver has been on at least that long */
  RFST = WAITW(1);

  /* sample CCA, if it fails exit from here, CSPZ indicates result */
  RFST = SKIP(1+__SNOP_SKIP__, C_CCA_IS_VALID);
  RFST = SSTOP;
  RFST = __SNOP__;
  
  /* per CSMA in specification, wait one backoff */
  RFST = WAITW(1);
  
  /* sample CCA again, if it fails exit from here, CSPZ indicates result */
  RFST = SKIP(1+__SNOP_SKIP__, C_CCA_IS_VALID);
  RFST = SSTOP;
  RFST = __SNOP__;
  
  /* CSMA has passed so transmit */
  RFST = STXON;

  /*
   *  If the SFD pin is high at this point, there was an RX-TX collision.
   *  In other words, TXON was strobed while receiving.  The CSP variable
   *  CSPY is decremented to indicate this happened.  The rest of the transmit
   *  continues normally.
   */
  RFST = SKIP(2+__SNOP_SKIP__, C_SFD_IS_INACTIVE);
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECY;
  RFST = __SNOP__;

  /*
   *  Watch the SFD pin to determine when the transmit has finished going out.
   *  The INT instruction causes an interrupt to fire.  The ISR for this interrupt
   *  handles the record the timestamp (which was just captured when SFD went high).
   *  Decrement CSPZ at the last step to indicate transmit was successful.
   */
  RFST = WHILE(C_SFD_IS_INACTIVE);
  RFST = INT;
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECZ;
}


/**************************************************************************************************
 * @fn          macCspTxGoCsma
 *
 * @brief       Run previously loaded CSP program for CSMA transmit.  Handles either
 *              slotted or unslotted CSMA transmits.  When CSP program has finished,
 *              an interrupt occurs and macCspTxStopIsr() is called.  This ISR will in
 *              turn call macTxDoneCallback().
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxGoCsma(void)
{
  /*
   *  Set CSPX with the countdown time of the CSMA delay.  Subtract one because there is
   *  a built-in one backoff delay in the CSP program to make sure receiver has been 'on'
   *  for at least one backoff.  Don't subtract though if CSPX is already zero!
   */
  CSPX = macTxCsmaBackoffDelay;
  if (CSPX != 0)
  {
    CSPX--;
  }

  /*
   *  Set WEVENT to trigger at the current value of the timer.  This allows
   *  unslotted CSMA to transmit just a little bit sooner.
   */
  CSP_WEVENT_SET_TRIGGER_NOW();

  /*
   *  Enable interrupt that fires when CSP program stops.
   *  Also enable interrupt that fires when INT instruction
   *  is executed.
   */
  MAC_MCU_CSP_STOP_ENABLE_INTERRUPT();
  MAC_MCU_CSP_INT_ENABLE_INTERRUPT();
  
  /*
   *  Turn on the receiver if it is not already on.  Receiver must be 'on' for at
   *  least one backoff before performing clear channel assessment (CCA).
   */
  macRxOn();

  /* start the CSP program */
  CSP_START_PROGRAM();
}


/**************************************************************************************************
 * @fn          macCspTxPrepSlotted
 *
 * @brief       Prepare CSP for "Slotted" (non-CSMA) transmit.
 *              Load CSP program and set CSP parameters.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxPrepSlotted(void)
{
  cspPrepForTxProgram();

  /*----------------------------------------------------------------------
   *  Load CSP program :  Slotted transmit (no CSMA)
   */
  
  /* wait for X number of backoffs */
  RFST = WAITX;

  /* just transmit, no CSMA required */
  RFST = STXON;

  /*
   *  If the SFD pin is high at this point, there was an RX-TX collision.
   *  In other words, TXON was strobed while receiving.  The CSP variable
   *  CSPY is decremented to indicate this happened.  The rest of the transmit
   *  continues normally.
   */
  RFST = SKIP(2+__SNOP_SKIP__, C_SFD_IS_INACTIVE);
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECY;
  RFST = __SNOP__;
  
  /*
   *  Watch the SFD pin to determine when the transmit has finished going out.
   *  The INT instruction causes an interrupt to fire.  The ISR for this interrupt
   *  handles the record the timestamp (which was just captured when SFD went high).
   *  Decrement CSPZ at the last step to indicate transmit was successful.
   */
  RFST = WHILE(C_SFD_IS_INACTIVE);
  RFST = INT;
  RFST = WHILE(C_SFD_IS_ACTIVE);
  RFST = DECZ;
}


/**************************************************************************************************
 * @fn          macCspTxGoSlotted
 *
 * @brief       Run previously loaded CSP program for non-CSMA slotted transmit.   When CSP
 *              program has finished, an interrupt occurs and macCspTxStopIsr() is called.
 *              This ISR will in turn call macTxDoneCallback().
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macCspTxGoSlotted(void)
{
  halIntState_t  s;
  uint8 lowByteOfBackoffCount;
  uint8 backoffCountdown;
  
  /*
   *  Enable interrupt that fires when CSP program stops.
   *  Also enable interrupt that fires when INT instruction
   *  is executed.
   */
  MAC_MCU_CSP_STOP_ENABLE_INTERRUPT();
  MAC_MCU_CSP_INT_ENABLE_INTERRUPT();

  /* critical section needed for timer accesses */
  HAL_ENTER_CRITICAL_SECTION(s);

  /* store lowest byte of backoff count (same as lowest byte of overflow count) */
  lowByteOfBackoffCount = T2OF0;

  /*
   *  Compute the number of backoffs until time to strobe transmit.  The strobe should
   *  occur one backoff before the SFD pin is expected to go high.  So, the forumla for the
   *  countdown value is to determine when the lower bits would rollover and become zero,
   *  and then subtract one.
   */
  backoffCountdown = SLOTTED_TX_MAX_BACKOFF_COUNTDOWN - (lowByteOfBackoffCount & SLOTTED_TX_BACKOFF_COUNT_ALIGN_BIT_MASK) - 1;
  
  /*
   *  Store backoff countdown value into CSPX.
   *
   *  Note: it is OK if this value is zero.  The WAITX instruction at the top of the
   *  CSP program will immediately continue if CSPX is zero when executed.  However,
   *  if the countdown is zero, it means the transmit function was not called early
   *  enough for a properly timed slotted transmit.  The transmit will be late.
   */
  CSPX = backoffCountdown;

  /*
   *  The receiver will be turned on during CSP execution, guaranteed.
   *  Since it is not possible to update C variables within the CSP,
   *  the new "on" state of the receiver must be set a little early
   *  here before the CSP is started.
   */
  MAC_RX_WAS_FORCED_ON();

  /* start the CSP program */
  CSP_START_PROGRAM();
  
  /*
   *  If the previous stored low byte of the backoff count is no longer equal to
   *  the current value, a rollover has occurred.  This means the backoff countdown
   *  stored in CSPX may not be correct.
   *
   *  In this case, the value of CSPX is reloaded to reflect the correct backoff
   *  countdown value (this is one less than what was just used as a rollover has
   *  occurred).  Since it is certain a rollover *just* occurred, there is no danger
   *  of another rollover occurring.  This means the value written to CSPX is guaranteed
   *  to be accurate.
   *
   *  Also, the logic below ensures that the value written to CSPX is at least one.
   *  This is needed for correct operation of the WAITX instruction.  As with an
   *  initial backoff countdown value of zero, if this case does occur, it means the
   *  transmit function was not called early enough for a properly timed slotted transmit.
   *  The transmit will be late.
   *
   *  Finally, worth noting, writes to CSPX may not work if the CSP is executing the WAITX
   *  instruction and a timer rollover occurs.  In this case, however, there is no possibility
   *  of that happening.  If CSPX is updated here, a rollover has just occurred so a
   *  collision is not possible (still within a critical section here too).
   */
  if ((lowByteOfBackoffCount != T2OF0) && (backoffCountdown > 1))
  {
    CSPX = backoffCountdown - 1;
  }
  
  HAL_EXIT_CRITICAL_SECTION(s);

⌨️ 快捷键说明

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