Example #1
0
/**************************************************************************************************
 * @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;
  
  HAL_ENTER_ISR();

  rfim = RFIRQM1;

  /*  The CPU level RF interrupt flag must be cleared here (before clearing RFIRQFx).
   *  to allow the interrupts to be nested.
   */
  S1CON = 0x00;

  if ((RFIRQF1 & IRQ_CSP_MANINT) & 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 */
    RFIRQF1 = ~IRQ_CSP_MANINT;
    macCspTxIntIsr();
  }
  else if ((RFIRQF1 & IRQ_CSP_STOP) & rfim)
  {
    /* clear flag */
    RFIRQF1 = ~IRQ_CSP_STOP;
    macCspTxStopIsr();
  }
  else if ((RFIRQF1 & IRQ_TXACKDONE) & rfim)
  {
    /* disable interrupt - set up is for "one shot" operation */
    RFIRQM1 &= ~IM_TXACKDONE;
    macRxAckTxDoneCallback();
  }

  rfim = RFIRQM0;

  /* process RFIRQF0 next */
  if ((RFIRQF0 & IRQ_FIFOP) & rfim)
  {
    /* continue to execute interrup                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        t handler as long as FIFOP is active */
    do
    {
      macRxThresholdIsr();
      RFIRQF0 = ~IRQ_FIFOP;
    } while (FSMSTAT1 & FIFOP);
  }
  
  CLEAR_SLEEP_MODE();
  HAL_EXIT_ISR();  
}
Example #2
0
/**************************************************************************************************
 * @fn          halMacIoPortIsr
 *
 * @brief       Radio interrupt service routine.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
HAL_ISR_FUNCTION( halMacFifopIsr, FIFOP_VECTOR() )
{
  uint8 pxie, excflag0;

  /*
   *  Copy interrupt enable register.  Used to avoid compiler warning regarding
   *  undefined order of volatile acesses.
   */
  pxie = PXIE;

  /* currently FIFO, FIFOP, and TX_ACK_DONE are the only signals that cause an interrupt on this port */
  MAC_ASSERT(pxie & PXIFG & (BV(HAL_MAC_FIFOP_GPIO_BIT) | BV(HAL_MAC_TX_ACK_DONE_GPIO_BIT) | BV(HAL_MAC_FIFO_GPIO_BIT))); /* unrecognized interrupt */

  /*
   *  Test all bits in port that are used as interrupts.  If the enable flag is set and
   *  the interrupt pending flag is set, call the corresponding ISR.
   *
   *  Note: the MSP430 requires that the software clear the interrupt pending flag.
   *  This logic design of the ISR's themselves handles this.
   */

  /* TX_ACK_DONE interrupt - processes TX_ACK_DONE before FIFOP when interrupts are simultaneous */
  if (pxie & PXIFG & BV(HAL_MAC_TX_ACK_DONE_GPIO_BIT))
  {
    excflag0 = macSpiReadReg(EXCFLAG0);

    /* Determine what caused the GPIO to go high */
    if (MAC_RADIO_TX_ACK_AND_TX_FRM_DONE_EXCEPTION(excflag0))
    {
      macDualchipTxAckDoneIsr();
      macDualchipTxFrmDoneIsr();
      MAC_RADIO_CLEAR_TX_ACK_AND_TX_FRM_DONE_PIN();
    }
    else
    {
      if (MAC_RADIO_TX_ACK_DONE_EXCEPTION(excflag0))
      {
        macDualchipTxAckDoneIsr();
        MAC_RADIO_CLEAR_TX_ACK_DONE_PIN();
      }
      else
      if (MAC_RADIO_TX_FRM_DONE_EXCEPTION(excflag0))
      {
        macDualchipTxFrmDoneIsr();
        MAC_RADIO_CLEAR_TX_FRM_DONE_PIN();
      }
    }

    if ( !HAL_MAC_READ_TX_ACK_DONE_PIN() )
    {
      /* Clear the flag only when the pin is phisically low */
      HAL_MAC_CLEAR_TX_ACK_DONE_INT_FLAG();
    }
  }

  /*
   * TX interrupt is very time consuming and it may trigger more transmissions.
   * Don't let RX run until all TXs are completed.
   */
  else if (pxie & PXIFG & BV(HAL_MAC_FIFOP_GPIO_BIT)) /* FIFOP interrupt */
  {
    /* To get here: FIFOP = 1, FIFO = X
     * See CC2520 Errata Note Bug 2, Glitches on the FIFOP Signal.
     */
    if (!HAL_MAC_READ_FIFOP_PIN() && HAL_MAC_READ_FIFO_PIN())
    {
      /* To get here: FIFOP = 0, FIFO = 1
       * It appears that after rxPayloadIsr(), a FIFOP glitch can occur. If
       * this is happening, the FIFOP interrupt flag should not be cleared.
       * Instead, do nothing so that the FIFOP interrupt can be triggered
       * again when the RX FIFO threshold is reached. FIFOP pin should stay
       * high for the real FOFOP interrupt.
       */
      if (!macRxActive)
      {
        /* If the FIFOP glitch occurs before RX is active, go ahead and
         * clear the FIFOP interrupt flag as if the glitch has never happened.
         */
        HAL_MAC_CLEAR_FIFOP_INT_FLAG();
      }
    }
    else if (HAL_MAC_READ_FIFOP_PIN())
    {
      /* To get here: FIFOP = 1, FIFO = X */
      do
      {
        /* Clear the FIFOP int flag. */
        HAL_MAC_CLEAR_FIFOP_INT_FLAG();

        macRxThresholdIsr();

      } while(HAL_MAC_READ_FIFOP_PIN());
    }
    else
    {
      /* To get here: FIFOP = 0, FIFO = 0
       * This is the second half of the FIFOP glitch workaround.
       * Need to clear FIFOP interrupt so that the FIFOP interrupt will be
       * fired on the next rising edge.
       */
      HAL_MAC_CLEAR_FIFOP_INT_FLAG();
    }
  }

  /* The RXFIFO overflow must be checked last to ensure new FIFOP interrupt */
  if (pxie & PXIFG & BV(HAL_MAC_FIFO_GPIO_BIT)) /* FIFO interrupt */
  {
    /* Handle RX FIFO overflow */
    if (MAC_RADIO_RX_FIFO_HAS_OVERFLOWED())
    {
      macRxFifoOverflowIsr();

      /* Clear RX FIFO overflow exception flag */
      macSpiWriteReg(EXCFLAG0, RX_OVERFLOW_FLAG);
    }

    /* clear interrupt */
    HAL_MAC_CLEAR_FIFO_INT_FLAG();
  }
}