Exemple #1
0
HAL_ISR_FUNCTION(port1Isr, P1INT_VECTOR)
#endif
{
	HAL_ENTER_ISR();
	
	PxIFG = 0;
	PxIF = 0;
	
	dmaRdyIsr = 1;

#ifdef POWER_SAVING
	CLEAR_SLEEP_MODE();
	osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_HOLD);

#if HAL_UART_TX_BY_ISR 
	if (dmaCfg.txHead == dmaCfg.txTail) {
		HAL_UART_DMA_CLR_RDY_OUT();
	}
#endif
#endif
	HAL_EXIT_ISR();
}
Exemple #2
0
HAL_ISR_FUNCTION(port0Isr, P0INT_VECTOR)
{
  unsigned char status;
  unsigned char i;

  HAL_ENTER_ISR();

  status = P0IFG;
  status &= P0IEN;
  if (status)
  {
    P0IFG = ~status;
    P0IF = 0;
    
#if HAL_UART_DMA == 1
    extern uint8 Hal_TaskID;
    extern volatile uint8 dmaRdyIsr;
    dmaRdyIsr = 1;
    CLEAR_SLEEP_MODE();
    osal_pwrmgr_task_state(Hal_TaskID, PWRMGR_HOLD);
#if HAL_UART_TX_BY_ISR
    if (dmaCfg.txHead == dmaCfg.txTail)
    {
      HAL_UART_DMA_CLR_RDY_OUT();
    }
#endif
#endif // HAL_UART_DMA

    for (i = 0; i < OS_MAX_INTERRUPT; i++)
    {
      if (PIN_MAJOR(blueBasic_interrupts[i].pin) == 0 && (status & (1 << PIN_MINOR(blueBasic_interrupts[i].pin))))
      {
        osal_set_event(blueBasic_TaskID, BLUEBASIC_EVENT_INTERRUPT << i);
      }
    }
  }

  HAL_EXIT_ISR();
}
Exemple #3
0
static uint16 HalUARTRxAvailDMA(void)
{
  uint16 cnt = 0;
#ifndef POWER_SAVING  
  bool detectOverflow = FALSE;
#endif
  // First, synchronize the Rx tail marker with where the DMA Rx engine is working.
  rxIdx_t tail = dmaCfg.rxTail;

#ifndef POWER_SAVING
  if (!DMA_PM && (UxUCR & UCR_FLOW))
  {
    HAL_UART_DMA_CLR_RDY_OUT();  // Stop the inflow for counting the bytes
  }
#endif

  do
  {
    if (!HAL_UART_DMA_NEW_RX_BYTE(tail))
    {
      break;
    }
    else
    {
      cnt++;
    }

    HAL_UART_RX_IDX_T_INCR(tail);
  } while (cnt  < HAL_UART_DMA_RX_MAX);

  if(!cnt)
  {
    while(sweepIdx < HAL_UART_DMA_RX_MAX)
    {
      if (HAL_UART_DMA_NEW_RX_BYTE(sweepIdx))
      {
        dmaCfg.rxTail = sweepIdx;
        dmaCfg.rxHead = sweepIdx;
        cnt = 0;
#ifndef POWER_SAVING
        detectOverflow = TRUE;
#endif
        break;
      }

      sweepIdx++;
    }

    if ( sweepIdx == HAL_UART_DMA_RX_MAX )
    {
      sweepIdx = 0;
    }
  }

#ifndef POWER_SAVING
  if ( (!DMA_PM && (UxUCR & UCR_FLOW)) && (!detectOverflow ) )
  {
    HAL_UART_DMA_SET_RDY_OUT();  // Re-enable the flow asap
  }
#endif
  return cnt;
}
Exemple #4
0
/******************************************************************************
 * @fn      HalUARTPollDMA
 *
 * @brief   Poll a USART module implemented by DMA, including the hybrid solution in which the Rx
 *          is driven by DMA but the Tx is driven by ISR.
 *
 * @param   none
 *
 * @return  none
 *****************************************************************************/
static void HalUARTPollDMA(void)
{
  uint8 evt = 0;
  uint16 cnt;

#if DMA_PM
  PxIEN &= ~DMA_RDYIn_BIT;  // Clear to not race with DMA_RDY_IN ISR.
  {
    if (dmaRdyIsr || HAL_UART_DMA_RDY_IN() || HalUARTBusyDMA())
    {
      // Master may have timed-out the SRDY asserted state & may need a new edge.
#if HAL_UART_TX_BY_ISR
      if (!HAL_UART_DMA_RDY_IN() && (dmaCfg.txHead != dmaCfg.txTail))
#else
      if (!HAL_UART_DMA_RDY_IN() && ((dmaCfg.txIdx[0] != 0) || (dmaCfg.txIdx[1] != 0)))
#endif
      {
        HAL_UART_DMA_CLR_RDY_OUT();
      }
      dmaRdyIsr = 0;

      if (dmaRdyDly == 0)
      {
        (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_HOLD_EVENT);
      }

      if ((dmaRdyDly = ST0) == 0)  // Reserve zero to signify that the delay expired.
      {
        dmaRdyDly = 0xFF;
      }
      HAL_UART_DMA_SET_RDY_OUT();
    }
    else if ((dmaRdyDly != 0) && (!DMA_PM_DLY || ((uint8)(ST0 - dmaRdyDly) > DMA_PM_DLY)))
    {
      dmaRdyDly = 0;
      (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT);
    }
  }
  PxIEN |= DMA_RDYIn_BIT;
#endif

#if !HAL_UART_TX_BY_ISR
  HalUARTPollTxTrigDMA();
#endif


  cnt = HalUARTRxAvailDMA();  // Wait to call until after the above DMA Rx bug work-around.

#if HAL_UART_DMA_IDLE
  if (dmaCfg.rxTick)
  {
    // Use the LSB of the sleep timer (ST0 must be read first anyway) to measure the Rx timeout.
    if ((ST0 - dmaCfg.rxTick) > HAL_UART_DMA_IDLE)
    {
      dmaCfg.rxTick = 0;
      evt = HAL_UART_RX_TIMEOUT;
    }
  }
  else if (cnt != 0)
  {
    if ((dmaCfg.rxTick = ST0) == 0)  // Zero signifies that the Rx timeout is not running.
    {
      dmaCfg.rxTick = 0xFF;
    }
  }
#else
  if (cnt != 0)
  {
    evt = HAL_UART_RX_TIMEOUT;
  }
#endif

  if (cnt >= HAL_UART_DMA_FULL)
  {
    evt |= HAL_UART_RX_FULL;
  }
  else if (cnt >= HAL_UART_DMA_HIGH)
  {
    evt |= HAL_UART_RX_ABOUT_FULL;

    if (!DMA_PM && (UxUCR & UCR_FLOW))
    {
      HAL_UART_DMA_CLR_RDY_OUT();  // Disable Rx flow.
    }
  }

  if (dmaCfg.txMT)
  {
    dmaCfg.txMT = FALSE;
    evt |= HAL_UART_TX_EMPTY;
  }

  if ((evt != 0) && (dmaCfg.uartCB != NULL))
  {
    dmaCfg.uartCB(HAL_UART_DMA-1, evt);
  }

  if (DMA_PM && (dmaRdyDly == 0) && !HalUARTBusyDMA())
  {
    HAL_UART_DMA_CLR_RDY_OUT();
  }
}
Exemple #5
0
/******************************************************************************
 * @fn      HalUARTInitDMA
 *
 * @brief   Initialize the UART
 *
 * @param   none
 *
 * @return  none
 *****************************************************************************/
static void HalUARTInitDMA(void)
{
  halDMADesc_t *ch;
#if (HAL_UART_DMA == 1)
  PERCFG &= ~HAL_UART_PERCFG_BIT;    // Set UART0 I/O to Alt. 1 location on P0.
#else
  PERCFG |= HAL_UART_PERCFG_BIT;     // Set UART1 I/O to Alt. 2 location on P1.
#endif
  PxSEL  |= HAL_UART_Px_SEL;         // Enable Peripheral control of Rx/Tx on Px.     p0.2 P0.3 set peripheral   //i0 setting
  UxCSR = CSR_MODE;                  // Mode is UART Mode.
  UxUCR = UCR_FLUSH;                 // Flush it.

  P2DIR &= ~P2DIR_PRIPO;                                                                                        //ÓÅÏȼ¶
  P2DIR |= HAL_UART_PRIPO;

  if (DMA_PM)
  {
    // Setup GPIO for interrupts by falling edge on DMA_RDY_IN.
    PxIEN |= DMA_RDYIn_BIT;
    PICTL |= PICTL_BIT;

    HAL_UART_DMA_CLR_RDY_OUT();
    PxDIR |= DMA_RDYOut_BIT;
  }

#if !HAL_UART_TX_BY_ISR
  // Setup Tx by DMA.
  ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX );

  // Abort any pending DMA operations (in case of a soft reset).
  HAL_DMA_ABORT_CH( HAL_DMA_CH_TX );

  // The start address of the destination.
  HAL_DMA_SET_DEST( ch, DMA_UxDBUF );

  // Using the length field to determine how many bytes to transfer.
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  // One byte is transferred each time.
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE );

  // The bytes are transferred 1-by-1 on Tx Complete trigger.
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX );

  // The source address is incremented by 1 byte after each transfer.
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 );

  // The destination address is constant - the Tx Data Buffer.
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 );

  // The DMA Tx done is serviced by ISR in order to maintain full thruput.
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE );

  // Xfer all 8 bits of a byte xfer.
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  // DMA has highest priority for memory access.
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH);
#endif

  // Setup Rx by DMA.
  ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX );

  // Abort any pending DMA operations (in case of a soft reset).
  HAL_DMA_ABORT_CH( HAL_DMA_CH_RX );

  // The start address of the source.
  HAL_DMA_SET_SOURCE( ch, DMA_UxDBUF );

  // Using the length field to determine how many bytes to transfer.
  HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );

  /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx.
   * The byte after the Rx Data Buffer is the Baud Cfg Register,
   * which always has a known value. So init Rx buffer to inverse of that
   * known value. DMA word xfer will flip the bytes, so every valid Rx byte
   * in the Rx buffer will be preceded by a DMA_PAD char equal to the
   * Baud Cfg Register value.
   */
  HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD );

  // The bytes are transferred 1-by-1 on Rx Complete trigger.
  HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED );
  HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX );

  // The source address is constant - the Rx Data Buffer.
  HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 );

  // The destination address is incremented by 1 word after each transfer.
  HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 );
  HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf );
  HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX );

  // The DMA is to be polled and shall not issue an IRQ upon completion.
  HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE );

  // Xfer all 8 bits of a byte xfer.
  HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );

  // DMA has highest priority for memory access.
  HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH);

  volatile uint8 dummy = *(volatile uint8 *)DMA_UxDBUF;  // Clear the DMA Rx trigger.
  HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX);
  HAL_DMA_ARM_CH(HAL_DMA_CH_RX);
  (void)memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX * sizeof(uint16));
}