/**
  * @brief  Sends an amount of data in non-blocking mode. 
  * @param  hirda: Pointer to a IRDA_HandleTypeDef structure that contains
  *                the configuration information for the specified IRDA module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
{
  uint32_t *tmp = 0;
  uint32_t  tmp_state = 0;

  tmp_state = hirda->State;
  if((tmp_state == HAL_IRDA_STATE_READY) || (tmp_state == HAL_IRDA_STATE_BUSY_RX))
  {
    if((pData == NULL) || (Size == 0)) 
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hirda);

    hirda->pTxBuffPtr = pData;
    hirda->TxXferSize = Size;
    hirda->TxXferCount = Size;
    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;

    if(hirda->State == HAL_IRDA_STATE_BUSY_RX)
    {
      hirda->State = HAL_IRDA_STATE_BUSY_TX_RX;
    }
    else
    {
      hirda->State = HAL_IRDA_STATE_BUSY_TX;
    }

    /* Set the IRDA DMA transfer complete callback */
    hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;

    /* Set the IRDA DMA half transfert complete callback */
    hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;

    /* Set the DMA error callback */
    hirda->hdmatx->XferErrorCallback = IRDA_DMAError;

    /* Enable the IRDA transmit DMA channel */
    tmp = (uint32_t*)&pData;
    HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size);

    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the USART CR3 register */
    SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);

    /* Process Unlocked */
    __HAL_UNLOCK(hirda);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
Beispiel #2
0
/**
  * @brief Send an amount of data in DMA mode.
  * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains
  *               the configuration information for the specified IRDA module.
  * @param pData: pointer to data buffer.
  * @param Size: amount of data to be sent.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
{
  uint32_t *tmp;

  /* Check that a Tx process is not already ongoing */
  if(hirda->gState == HAL_IRDA_STATE_READY)
  {
    if((pData == NULL) || (Size == 0))
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hirda);

    hirda->pTxBuffPtr = pData;
    hirda->TxXferSize = Size;
    hirda->TxXferCount = Size;

    hirda->ErrorCode = HAL_IRDA_ERROR_NONE;

    hirda->gState = HAL_IRDA_STATE_BUSY_TX;

    /* Set the IRDA DMA transfer complete callback */
    hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;

    /* Set the IRDA DMA half transfer complete callback */
    hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;

    /* Set the DMA error callback */
    hirda->hdmatx->XferErrorCallback = IRDA_DMAError;

    /* Enable the IRDA transmit DMA channel */
    tmp = (uint32_t*)&pData;
    HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size);

    /* Clear the TC flag in the ICR register */
    __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF);

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the USART CR3 register */
    hirda->Instance->CR3 |= USART_CR3_DMAT;

    /* Process Unlocked */
    __HAL_UNLOCK(hirda);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
 * @brief  This function handles IRDA interrupt request.
 * @param  hirda: IRDA handle
 * @retval None
 */
void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
{
	uint32_t tmp1 = 0, tmp2 =0;

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_PE);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE);
	/* IRDA parity error interrupt occured -------------------------------------*/
	if((tmp1 != RESET) && (tmp2 != RESET))
	{
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_PE);
		hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
	}

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_FE);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR);
	/* IRDA frame error interrupt occured --------------------------------------*/
	if((tmp1 != RESET) && (tmp2 != RESET))
	{
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_FE);
		hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
	}

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_NE);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR);
	/* IRDA noise error interrupt occured --------------------------------------*/
	if((tmp1 != RESET) && (tmp2 != RESET))
	{
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_NE);
		hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
	}

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_ORE);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR);
	/* IRDA Over-Run interrupt occured -----------------------------------------*/
	if((tmp1 != RESET) && (tmp2 != RESET))
	{
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_ORE);
		hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
	}

	/* Call the Error call Back in case of Errors */
	if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
	{
		/* Set the IRDA state ready to be able to start again the process */
		hirda->State = HAL_IRDA_STATE_READY;
		HAL_IRDA_ErrorCallback(hirda);
	}

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_RXNE);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE);
	/* IRDA in mode Receiver ---------------------------------------------------*/
	if((tmp1 != RESET) && (tmp2 != RESET))
	{
		IRDA_Receive_IT(hirda);
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_IT_RXNE);
	}

	tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_TC);
	tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC);
	/* IRDA in mode Transmitter ------------------------------------------------*/
	if((tmp1 != RESET) &&(tmp2 != RESET))
	{
		IRDA_Transmit_IT(hirda);
		__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_IT_TC);
	}
}