Exemple #1
0
/**
  * @brief Send data in blocking mode 
  * @param hcec: CEC handle
  * @param DestinationAddress: destination logical address      
  * @param pData: pointer to input byte data buffer
  * @param Size: amount of data to be sent in bytes (without counting the header).
  *              0 means only the header is sent (ping operation).
  *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
  * @param  Timeout: Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout)
{
  uint8_t  temp = 0;  
  uint32_t tempisr = 0;   
  uint32_t tickstart = 0;

  if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) 
  {
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
    if((pData == NULL ) && (Size > 0)) 
    {
      hcec->State = HAL_CEC_STATE_ERROR;
      return  HAL_ERROR;                                    
    }

    assert_param(IS_CEC_ADDRESS(DestinationAddress)); 
    assert_param(IS_CEC_MSGSIZE(Size));
    
    /* Process Locked */
    __HAL_LOCK(hcec);
    
    hcec->State = HAL_CEC_STATE_BUSY_TX;

    hcec->TxXferCount = Size;
    
    /* case no data to be sent, sender is only pinging the system */
    if (Size == 0)
    {
      /* Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
      __HAL_CEC_LAST_BYTE_TX_SET(hcec);
    }
    
    /* send header block */
    temp = ((uint32_t)hcec->Init.InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress;
    hcec->Instance->TXDR = temp;
    /* Set TX Start of Message  (TXSOM) bit */
    __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
    
    while (hcec->TxXferCount > 0)
    {
      hcec->TxXferCount--;

      tickstart = HAL_GetTick();
      while(HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_TXBR))
      {
      	if(Timeout != HAL_MAX_DELAY)
        {
          if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
          {
            hcec->State = HAL_CEC_STATE_TIMEOUT;                
            /* Process Unlocked */
            __HAL_UNLOCK(hcec);       
            return HAL_TIMEOUT;
          }
        }        

        /* check whether error occured while waiting for TXBR to be set:
         * has Tx underrun occurred ?
         * has Tx error occurred ?
         * has Tx Missing Acknowledge error occurred ? 
         * has Arbitration Loss error occurred ? */
        tempisr = hcec->Instance->ISR;
        if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0)
        {
          /* copy ISR for error handling purposes */
          hcec->ErrorCode = tempisr;
         /* clear all error flags by default */
         __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST));
         hcec->State = HAL_CEC_STATE_ERROR;
         __HAL_UNLOCK(hcec);
         return  HAL_ERROR;                                    
        }
      } 
      /* TXBR to clear BEFORE writing TXDR register */
      __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR);
      if (hcec->TxXferCount == 0)
      {
        /* if last byte transmission, set TX End of Message (TXEOM) bit */
        __HAL_CEC_LAST_BYTE_TX_SET(hcec);
      }
      hcec->Instance->TXDR = *pData++;
      
      /* error check after TX byte write up */
      tempisr = hcec->Instance->ISR;
      if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0)
      {
        /* copy ISR for error handling purposes */
        hcec->ErrorCode = tempisr;
        /* clear all error flags by default */
        __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST));
        hcec->State = HAL_CEC_STATE_ERROR;
        __HAL_UNLOCK(hcec);
        return  HAL_ERROR;                                    
      }
    } /* end while (while (hcec->TxXferCount > 0)) */
    
   
    /* if no error up to this point, check that transmission is  
     * complete, that is wait until TXEOM is reset */
    tickstart = HAL_GetTick();

    while (HAL_IS_BIT_SET(hcec->Instance->CR, CEC_CR_TXEOM))
    {
    	if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
        {
          hcec->State = HAL_CEC_STATE_ERROR;
          __HAL_UNLOCK(hcec);             
          return HAL_TIMEOUT;
        }
      } 
    }

    /* Final error check once all bytes have been transmitted */
    tempisr = hcec->Instance->ISR;
    if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE)) != 0)
    {
      /* copy ISR for error handling purposes */
      hcec->ErrorCode = tempisr;
      /* clear all error flags by default */
      __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE));
      hcec->State = HAL_CEC_STATE_ERROR;
      __HAL_UNLOCK(hcec);
      return  HAL_ERROR;                                    
    } 

    hcec->State = HAL_CEC_STATE_READY;
    __HAL_UNLOCK(hcec);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;   
  }
}
Exemple #2
0
/**
  * @brief  Enables the selected ADC software start conversion of the injected channels.
  * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains
  *         the configuration information for the specified ADC.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)
{
  __IO uint32_t counter = 0U;
  uint32_t tmp1 = 0U, tmp2 = 0U;
  ADC_Common_TypeDef *tmpADC_Common;

  /* Process locked */
  __HAL_LOCK(hadc);

  /* Enable the ADC peripheral */

  /* Check if ADC peripheral is disabled in order to enable it and wait during
     Tstab time the ADC's stabilization */
  if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
  {
    /* Enable the Peripheral */
    __HAL_ADC_ENABLE(hadc);

    /* Delay for ADC stabilization time */
    /* Compute number of CPU cycles to wait for */
    counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
    while(counter != 0U)
    {
      counter--;
    }
  }

  /* Start conversion if ADC is effectively enabled */
  if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
  {
    /* Set ADC state                                                          */
    /* - Clear state bitfield related to injected group conversion results    */
    /* - Set state bitfield related to injected operation                     */
    ADC_STATE_CLR_SET(hadc->State,
                      HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
                      HAL_ADC_STATE_INJ_BUSY);

    /* Check if a regular conversion is ongoing */
    /* Note: On this device, there is no ADC error code fields related to     */
    /*       conversions on group injected only. In case of conversion on     */
    /*       going on group regular, no error code is reset.                  */
    if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
    {
      /* Reset ADC all error code fields */
      ADC_CLEAR_ERRORCODE(hadc);
    }

    /* Process unlocked */
    /* Unlock before starting ADC conversions: in case of potential           */
    /* interruption, to let the process to ADC IRQ Handler.                   */
    __HAL_UNLOCK(hadc);

    /* Clear injected group conversion flag */
    /* (To ensure of no unknown state from potential previous ADC operations) */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);

    /* Pointer to the common control register to which is belonging hadc    */
    /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */
    /* control register)                                                    */
    tmpADC_Common = ADC_COMMON_REGISTER(hadc);

    /* Check if Multimode enabled */
    if(HAL_IS_BIT_CLR(tmpADC_Common->CCR, ADC_CCR_MULTI))
    {
      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
      if(tmp1 && tmp2)
      {
        /* Enable the selected ADC software conversion for injected group */
        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
      }
    }
    else
    {
      tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
      tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
      if((hadc->Instance == ADC1) && tmp1 && tmp2)
      {
        /* Enable the selected ADC software conversion for injected group */
        hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
      }
    }
  }

  /* Return function status */
  return HAL_OK;
}
/**
  * @brief SMARTCARD interrupt requests handling.
  * @param hsc: SMARTCARD handle
  * @retval None
  */
void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
{
  uint32_t isrflags   = READ_REG(hsc->Instance->ISR);
  uint32_t cr1its     = READ_REG(hsc->Instance->CR1);
  uint32_t cr3its     = READ_REG(hsc->Instance->CR3);
  uint32_t dmarequest = 0x00U;
  uint32_t errorflags = 0x00U;

  /* If no error occurs */
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
  if(errorflags == RESET)
  {
    /* SMARTCARD in mode Receiver -------------------------------------------------*/
    if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
    {
      SMARTCARD_Receive_IT(hsc);
      return;
    }
  }

  /* If some errors occur */
  if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET))
  {
    /* SMARTCARD parity error interrupt occurred ---------------------------*/
    if(((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
    { 
      hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
    }

    /* SMARTCARD frame error interrupt occurred ----------------------------*/
    if(((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
    { 
      hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
    }

    /* SMARTCARD noise error interrupt occurred ----------------------------*/
    if(((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
    { 
      hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
    }

    /* SMARTCARD Over-Run interrupt occurred -------------------------------*/
    if(((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
    { 
      hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
    }
    /* Call the Error call Back in case of Errors */
    if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
    {
      /* SMARTCARD in mode Receiver -----------------------------------------------*/
      if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
      {
        SMARTCARD_Receive_IT(hsc);
      }

      /* If Overrun error occurs, or if any error occurs in DMA mode reception,
         consider error as blocking */
      dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
      if(((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest)
      {
        /* Blocking error : transfer is aborted
          Set the SMARTCARD state ready to be able to start again the process,
          Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
        SMARTCARD_EndRxTransfer(hsc);
        /* Disable the SMARTCARD DMA Rx request if enabled */
        if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
        {
          CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);

          /* Abort the SMARTCARD DMA Rx channel */
          if(hsc->hdmarx != NULL)
          {
            /* Set the SMARTCARD DMA Abort callback : 
              will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */
            hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError;

           if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
            {
              /* Call Directly XferAbortCallback function in case of error */
              hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
            }
          }
          else
          {
            /* Call user error callback */
            HAL_SMARTCARD_ErrorCallback(hsc);
          }
        }
        else
        {
          /* Call user error callback */
          HAL_SMARTCARD_ErrorCallback(hsc);
        }
      }
      else
      {
        /* Call user error callback */
        HAL_SMARTCARD_ErrorCallback(hsc);
        hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
      }
    }
    return;
  } /* End if some error occurs */
  
  /* SMARTCARD in mode Transmitter -------------------------------------------*/
  if(((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
  {
    SMARTCARD_Transmit_IT(hsc);
    return;
  }
  
  /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/
  if(((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
  {
    /* Disable the SMARTCARD Transmit Complete Interrupt */   
    CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TCIE);

    /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
    CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);

    /* Tx process is ended, restore hsmartcard->gState to Ready */
    hsc->gState = HAL_SMARTCARD_STATE_READY;

    HAL_SMARTCARD_TxCpltCallback(hsc);
    
    return;
  }
}
/**
  * @brief  Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral
  * 
  * @note   Caution: This function must be used only with the ADC master.  
  *
  * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains
  *         the configuration information for the specified ADC.
  * @param  pData:   Pointer to buffer in which transferred from ADC peripheral to memory will be stored. 
  * @param  Length:  The length of data to be transferred from ADC peripheral to memory.  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
{
  __IO uint32_t counter = 0;
  
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
  assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
  
  /* Process locked */
  __HAL_LOCK(hadc);
  
  /* Check if ADC peripheral is disabled in order to enable it and wait during 
     Tstab time the ADC's stabilization */
  if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
  {  
    /* Enable the Peripheral */
    __HAL_ADC_ENABLE(hadc);
    
    /* Delay for temperature sensor stabilization time */
    /* Compute number of CPU cycles to wait for */
    counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
    while(counter != 0)
    {
      counter--;
    }
  }
  
  /* Start conversion if ADC is effectively enabled */
  if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
  {
    /* Set ADC state                                                          */
    /* - Clear state bitfield related to regular group conversion results     */
    /* - Set state bitfield related to regular group operation                */
    ADC_STATE_CLR_SET(hadc->State,
                      HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
                      HAL_ADC_STATE_REG_BUSY);
    
    /* If conversions on group regular are also triggering group injected,    */
    /* update ADC state.                                                      */
    if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
    {
      ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);  
    }
    
    /* State machine update: Check if an injected conversion is ongoing */
    if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
    {
      /* Reset ADC error code fields related to conversions on group regular */
      CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));         
    }
    else
    {
      /* Reset ADC all error code fields */
      ADC_CLEAR_ERRORCODE(hadc);
    }
    
    /* Process unlocked */
    /* Unlock before starting ADC conversions: in case of potential           */
    /* interruption, to let the process to ADC IRQ Handler.                   */
    __HAL_UNLOCK(hadc);
    
    /* Set the DMA transfer complete callback */
    hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt;
    
    /* Set the DMA half transfer complete callback */
    hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;
    
    /* Set the DMA error callback */
    hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;
    
    /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC     */
    /* start (in case of SW start):                                           */
    
    /* Clear regular group conversion flag and overrun flag */
    /* (To ensure of no unknown state from potential previous ADC operations) */
    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);

    /* Enable ADC overrun interrupt */
    __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
    
    if (hadc->Init.DMAContinuousRequests != DISABLE)
    {
      /* Enable the selected ADC DMA request after last transfer */
      ADC->CCR |= ADC_CCR_DDS;
    }
    else
    {
      /* Disable the selected ADC EOC rising on each regular channel conversion */
      ADC->CCR &= ~ADC_CCR_DDS;
    }
    
    /* Enable the DMA Stream */
    HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);
    
    /* if no external trigger present enable software conversion of regular channels */
    if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) 
    {
      /* Enable the selected ADC software conversion for regular group */
      hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
    }
  }
  
  /* Return function status */
  return HAL_OK;
}
/**
  * @brief Send data in blocking mode 
  * @param hcec: CEC handle
  * @param DestinationAddress: destination logical address      
  * @param pData: pointer to input byte data buffer
  * @param Size: amount of data to be sent in bytes (without counting the header).
  *              0 means only the header is sent (ping operation).
  *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
  * @param  Timeout: Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout)
{
  uint8_t  temp = 0;
  uint32_t tickstart = 0;

  /* If the IP is ready */
  if((hcec->State == HAL_CEC_STATE_READY) 
     && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) 
  {
    /* Basic check on pData pointer */
    if(((pData == NULL) && (Size > 0)) || (! IS_CEC_MSGSIZE(Size))) 
    {
      return  HAL_ERROR;
    }

    assert_param(IS_CEC_ADDRESS(DestinationAddress));
    
    /* Process Locked */
    __HAL_LOCK(hcec);
    
    /* Enter the transmit mode */
    hcec->State = HAL_CEC_STATE_BUSY_TX;
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;

    /* Initialize the number of bytes to send,
     * 0 means only one header is sent (ping operation) */
    hcec->TxXferCount = Size;

    /* Send header block */
    temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
    hcec->Instance->TXD = temp;

    /* In case no data to be sent, sender is only pinging the system */
    if (Size != 0)
    {    
      /* Set TX Start of Message (TXSOM) bit */
      hcec->Instance->CSR = CEC_FLAG_TSOM;
    }
    else
    {
      /* Send a ping command */
      hcec->Instance->CSR = CEC_FLAG_TEOM|CEC_FLAG_TSOM;
    }

    /* Polling TBTRF bit with timeout handling*/
    while (hcec->TxXferCount > 0)
    {
      /* Decreasing of the number of remaining data to receive */
      hcec->TxXferCount--;
      
      /* Timeout handling */
      tickstart = HAL_GetTick();
      
      /* Waiting for the next data transmission */
      while(HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF))
      {
        /* Timeout handling */
        if(Timeout != HAL_MAX_DELAY)
        {
          if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
          {
            hcec->State = HAL_CEC_STATE_READY; 
            /* Process Unlocked */
            __HAL_UNLOCK(hcec);  
            return HAL_TIMEOUT;
          }
        }        

        /* Check if an error occured */
        if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
        {
          /* Copy ESR for error handling purposes */
          hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
          
          /* Acknowledgement of the error */
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
          
          hcec->State = HAL_CEC_STATE_READY;
          __HAL_UNLOCK(hcec);
          return  HAL_ERROR;                                    
        }
      }
      
      /* Write the next data to TX buffer */
      hcec->Instance->TXD = *pData++;
      
      /* If this is the last byte of the ongoing transmission */
      if (hcec->TxXferCount == 0)
      {
        /* Acknowledge byte request and signal end of message */
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM);
      }
      else
      {
        /* Acknowledge byte request by writing 0x00 */
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
      }
    }
    
    /* Timeout handling */
    tickstart = HAL_GetTick();
    
    /* Wait for message transmission completion (TBTRF is set) */
    while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF))
    {
      /* Timeout handling */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
        {
          hcec->State = HAL_CEC_STATE_READY;
          __HAL_UNLOCK(hcec);             
          return HAL_TIMEOUT;
        }
      } 

      /* Check of error during transmission of the last byte */
      if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
      {
        /* Copy ESR for error handling purposes */
        hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
        
        /* Acknowledgement of the error */
        __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
        __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
        
        hcec->State = HAL_CEC_STATE_READY;
        __HAL_UNLOCK(hcec);
        return  HAL_ERROR;                                    
      }
    }
    
    /* Check of error after the last byte transmission */
    if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
    {
      /* Copy ESR for error handling purposes */
      hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
      
      /* Acknowledgement of the error */
      __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
      __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
      
      hcec->State = HAL_CEC_STATE_READY;
      __HAL_UNLOCK(hcec);
      return  HAL_ERROR;
    }
    
    /* Acknowledge successful completion by writing 0x00 */
    MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
    
    hcec->State = HAL_CEC_STATE_READY;
    __HAL_UNLOCK(hcec);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;   
  }
}
/**
  * @brief Receive data in blocking mode. 
  * @param hcec: CEC handle
  * @param pData: pointer to received data buffer.
  * @param Timeout: Timeout duration.
  * @note  The received data size is not known beforehand, the latter is known
  *        when the reception is complete and is stored in hcec->RxXferSize.  
  *        hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
  *        If only a header is received, hcec->RxXferSize = 0    
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout)
{
  uint32_t temp = 0;
  uint32_t tickstart = 0;   

  if(hcec->State == HAL_CEC_STATE_READY)
  {
    if(pData == NULL) 
    {
      return HAL_ERROR;
    }
    
    /* When a ping is received, RxXferSize is 0*/
    /* When a message is received, RxXferSize contains the number of received bytes */
    hcec->RxXferSize = CEC_RXXFERSIZE_INITIALIZE; 
    
    /* Process Locked */
    __HAL_LOCK(hcec);

    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
    
    /* Continue the reception until the End Of Message is received (CEC_FLAG_REOM) */
    do
    {
      /* Timeout handling */
      tickstart = HAL_GetTick();
      
      /* Wait for next byte to be received */
      while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_RBTF))
      {
        /* Timeout handling */
        if(Timeout != HAL_MAX_DELAY)
        {
          if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
          {
            hcec->State = HAL_CEC_STATE_READY;
            __HAL_UNLOCK(hcec);    
            return HAL_TIMEOUT;
          }
        }
        
        /* Check if an error occured during the reception */
        if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
        {
          /* Copy ESR for error handling purposes */
          hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
          
          /* Acknowledgement of the error */
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
          
          hcec->State = HAL_CEC_STATE_READY;
          __HAL_UNLOCK(hcec);
          return  HAL_ERROR;
        }
      }
      
      /* Keep the value of CSR register as the register is cleared during reception process */
      temp = hcec->Instance->CSR;
      
      /* Read received data */
      *pData++ = hcec->Instance->RXD;
      
      /* Acknowledge received byte by writing 0x00 */
      CLEAR_BIT(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK);
      
      /* Increment the number of received data */
      if(hcec->RxXferSize == CEC_RXXFERSIZE_INITIALIZE)
      {
        hcec->RxXferSize = 0;
      }
      else
      {
        hcec->RxXferSize++;
      }
      
    }while (HAL_IS_BIT_CLR(temp, CEC_FLAG_REOM));
    
    hcec->State = HAL_CEC_STATE_READY;
    __HAL_UNLOCK(hcec);  
    
    if(IS_CEC_MSGSIZE(hcec->RxXferSize))
    {
      return HAL_OK;
    }
    else
    {
      return HAL_ERROR;
    }
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief  Receive an amount of data in blocking mode.
  * @param  hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
  *                the configuration information for SWPMI module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be received
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = HAL_GetTick();
  HAL_StatusTypeDef status = HAL_OK;

  if((pData == NULL ) || (Size == 0))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
    {
      /* Check if a non-blocking transmit process is ongoing or not */
      if(hswpmi->State == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;

        /* Disable any receiver interrupts */
        CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      do
      {
        /* Wait the RXNE to read data */
        if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
        {
          (*pData++) = hswpmi->Instance->RDR;
          Size--;
        }
        else
        {
          /* Check for the Timeout */
          if(Timeout != HAL_MAX_DELAY)
          {
            if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
            {
              status = HAL_TIMEOUT;
              break;
            }
          }
        }
      } while(Size != 0);
      
      if(status == HAL_OK)
      {
        if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
        {
          /* Clear RXBFF at end of reception */
          WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
        }

        /* Check if a non-blocking transmit Process is ongoing or not */
        if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
        {
          hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
        }
        else
        {
          hswpmi->State = HAL_SWPMI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_BUSY;
    }
  }

  if((status != HAL_OK) && (status != HAL_BUSY))
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}
/**
  * @brief  Perform an ADC automatic self-calibration
  *         Calibration prerequisite: ADC must be disabled (execute this
  *         function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
  *         During calibration process, ADC is enabled. ADC is let enabled at
  *         the completion of this function.
  * @param  hadc: ADC handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)
{
  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
  uint32_t tickstart;
  __IO uint32_t wait_loop_index = 0;
  
  /* Check the parameters */
  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));

  /* Process locked */
  __HAL_LOCK(hadc);
    
  /* 1. Calibration prerequisite:                                             */
  /*    - ADC must be disabled for at least two ADC clock cycles in disable   */
  /*      mode before ADC enable                                              */
  /* Stop potential conversion on going, on regular and injected groups       */
  /* Disable ADC peripheral */
  tmp_hal_status = ADC_ConversionStop_Disable(hadc);
  
  /* Check if ADC is effectively disabled */
  if (tmp_hal_status != HAL_ERROR)
  {
    /* Hardware prerequisite: delay before starting the calibration.          */
    /*  - Computation of CPU clock cycles corresponding to ADC clock cycles.  */
    /*  - Wait for the expected ADC clock cycles delay */
    wait_loop_index = ((SystemCoreClock
                        / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC))
                       * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES        );

    while(wait_loop_index != 0)
    {
      wait_loop_index--;
    }
    
    /* 2. Enable the ADC peripheral */
    ADC_Enable(hadc);
    

    /* 3. Resets ADC calibration registers */  
    SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL);
    
    tickstart = HAL_GetTick();  

    /* Wait for calibration reset completion */
    while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL))
    {
      if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
      {
        /* Update ADC state machine to error */
        hadc->State = HAL_ADC_STATE_ERROR;
        
        /* Process unlocked */
        __HAL_UNLOCK(hadc);
        
        return HAL_ERROR;
      }
    }
    
    
    /* 4. Start ADC calibration */
    SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL);
    
    tickstart = HAL_GetTick();  

    /* Wait for calibration completion */
    while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL))
    {
      if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
      {
        /* Update ADC state machine to error */
        hadc->State = HAL_ADC_STATE_ERROR;
        
        /* Process unlocked */
        __HAL_UNLOCK(hadc);
        
        return HAL_ERROR;
      }
    }
    
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hadc);
  
  /* Return function status */
  return tmp_hal_status;
}
/**
  * @brief  Transmit an amount of data in blocking mode.
  * @param  hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
  *                the configuration information for SWPMI module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be sent
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = HAL_GetTick();
  HAL_StatusTypeDef status = HAL_OK;

  if((pData == NULL ) || (Size == 0))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
    {
      /* Check if a non-blocking receive process is ongoing or not */
      if(hswpmi->State == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;

        /* Disable any transmitter interrupts */
        __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);

        /* Disable any transmitter flags */
        __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      do
      {
        /* Wait the TXE to write data */
        if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
        {
          hswpmi->Instance->TDR = (*pData++);
          Size--;
        }
        else
        {
          /* Check for the Timeout */
          if(Timeout != HAL_MAX_DELAY)
          {
            if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
            {
              status = HAL_TIMEOUT;
              break;
            }
          }
        }
      } while(Size != 0);

      /* Wait on TXBEF flag to be able to start a second transfer */
      if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, Timeout) != HAL_OK)
      {
        status = HAL_TIMEOUT;
      }

      if(status == HAL_OK)
      {
        /* Check if a non-blocking receive Process is ongoing or not */
        if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
        {
          hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
        }
        else
        {
          hswpmi->State = HAL_SWPMI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_BUSY;
    }
  }

  if((status != HAL_OK) && (status != HAL_BUSY))
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}
/**
 * @brief  Receives an amount of data in non blocking mode. 
 * @param  hirda: IRDA handle
 * @retval HAL status
 */
static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
{
	uint16_t* tmp;
	uint32_t tmp1 = 0;

	tmp1 = hirda->State;
	if((tmp1 == HAL_IRDA_STATE_BUSY_RX) || (tmp1 == HAL_IRDA_STATE_BUSY_TX_RX))
	{
		/* Process Locked */
		__HAL_LOCK(hirda);

		if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
		{
			tmp = (uint16_t*) hirda->pRxBuffPtr;
			if(hirda->Init.Parity == IRDA_PARITY_NONE)
			{
				*tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
				hirda->pRxBuffPtr += 2;
			}
			else
			{
				*tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
				hirda->pRxBuffPtr += 1;
			}
		}
		else
		{
			if(hirda->Init.Parity == IRDA_PARITY_NONE)
			{
				*hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
			}
			else
			{
				*hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
			}
		}

		if(--hirda->RxXferCount == 0)
		{
			while(HAL_IS_BIT_SET(hirda->Instance->SR, IRDA_FLAG_RXNE))
			{
			}
			__HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE);

			if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)
			{
				hirda->State = HAL_IRDA_STATE_BUSY_TX;
			}
			else
			{
				/* Disable the IRDA Parity Error Interrupt */
				__HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE);

				/* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
				__HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR);

				hirda->State = HAL_IRDA_STATE_READY;
			}
			/* Call the Process Unlocked before calling the Rx call back API to give the possibiity to
			 start again the receiption under the Rx call back API */
			__HAL_UNLOCK(hirda);

			HAL_IRDA_RxCpltCallback(hirda);

			return HAL_OK;
		}

		/* Process Unlocked */
		__HAL_UNLOCK(hirda);

		return HAL_OK;
	}
	else
	{
		return HAL_BUSY;
	}
}
Exemple #11
0
/**
  * @brief  Initiates and transmits a CAN frame message.
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
{
  uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;

  /* Check the parameters */
  assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));

  if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
  {
    /* Process Locked */
    __HAL_LOCK(hcan);

    /* Select one empty transmit mailbox */
    if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
    {
      transmitmailbox = 0;
    }
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
    {
      transmitmailbox = 1;
    }
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
    {
      transmitmailbox = 2;
    }
    else
    {
      transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
    }

    if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
    {
      /* Set up the Id */
      hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
      if (hcan->pTxMsg->IDE == CAN_ID_STD)
      {
        assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
                                                             hcan->pTxMsg->RTR);
      }
      else
      {
        assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
                                                             hcan->pTxMsg->IDE |
                                                             hcan->pTxMsg->RTR);
      }

      /* Set up the DLC */
      hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;

      /* Set up the data field */
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
                                                                  ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );

      if(hcan->State == HAL_CAN_STATE_BUSY_RX)
      {
        /* Change CAN state */
        hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
      }
      else
      {
        /* Change CAN state */
        hcan->State = HAL_CAN_STATE_BUSY_TX;
      }

      /* Set CAN error code to none */
      hcan->ErrorCode = HAL_CAN_ERROR_NONE;

      /* Process Unlocked */
      __HAL_UNLOCK(hcan);

      /* Enable interrupts: */
      /*  - Enable Error warning Interrupt */
      /*  - Enable Error passive Interrupt */
      /*  - Enable Bus-off Interrupt */
      /*  - Enable Last error code Interrupt */
      /*  - Enable Error Interrupt */
      /*  - Enable Transmit mailbox empty Interrupt */
      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
                                CAN_IT_EPV |
                                CAN_IT_BOF |
                                CAN_IT_LEC |
                                CAN_IT_ERR |
                                CAN_IT_TME  );

      /* Request transmission */
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
    }
  }
  else
  {
    return HAL_BUSY;
  }

  return HAL_OK;
}
Exemple #12
0
/**
  * @brief  Initiates and transmits a CAN frame message.
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @param  Timeout: Specify Timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
{
  uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  uint32_t tickstart = 0;

  /* Check the parameters */
  assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));

  /* Process locked */
  __HAL_LOCK(hcan);

  if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  {
    /* Change CAN state */
    hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  }
  else
  {
    /* Change CAN state */
    hcan->State = HAL_CAN_STATE_BUSY_TX;
  }

  /* Select one empty transmit mailbox */
  if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  {
    transmitmailbox = 0;
  }
  else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  {
    transmitmailbox = 1;
  }
  else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  {
    transmitmailbox = 2;
  }
  else
  {
    transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  }

  if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  {
    /* Set up the Id */
    hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
    if (hcan->pTxMsg->IDE == CAN_ID_STD)
    {
      assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
                                                           hcan->pTxMsg->RTR);
    }
    else
    {
      assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
                                                           hcan->pTxMsg->IDE |
                                                           hcan->pTxMsg->RTR);
    }

    /* Set up the DLC */
    hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
    hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
    hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;

    /* Set up the data field */
    WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
    WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
                                                                ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
    /* Request transmission */
    SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);

    /* Get timeout */
    tickstart = HAL_GetTick();

    /* Check End of transmission flag */
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
        {
          hcan->State = HAL_CAN_STATE_TIMEOUT;

          /* Process unlocked */
          __HAL_UNLOCK(hcan);

          return HAL_TIMEOUT;
        }
      }
    }
    if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
    {
      /* Change CAN state */
      hcan->State = HAL_CAN_STATE_BUSY_RX;

      /* Process unlocked */
      __HAL_UNLOCK(hcan);
    }
    else
    {
      /* Change CAN state */
      hcan->State = HAL_CAN_STATE_READY;
    }

    /* Process unlocked */
    __HAL_UNLOCK(hcan);

    /* Return function status */
    return HAL_OK;
  }
  else
  {
    /* Change CAN state */
    hcan->State = HAL_CAN_STATE_ERROR;

    /* Process unlocked */
    __HAL_UNLOCK(hcan);

    /* Return function status */
    return HAL_ERROR;
  }
}
Exemple #13
0
/**
  * @brief  Initializes the CAN peripheral according to the specified
  *         parameters in the CAN_InitStruct.
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
  *         the configuration information for the specified CAN.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
{
  uint32_t status = CAN_INITSTATUS_FAILED;  /* Default init status */
  uint32_t tickstart = 0;
  uint32_t tmp_mcr = 0;

  /* Check CAN handle */
  if(hcan == NULL)
  {
     return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
  assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
  assert_param(IS_CAN_MODE(hcan->Init.Mode));
  assert_param(IS_CAN_SJW(hcan->Init.SJW));
  assert_param(IS_CAN_BS1(hcan->Init.BS1));
  assert_param(IS_CAN_BS2(hcan->Init.BS2));
  assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));

  if(hcan->State == HAL_CAN_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hcan->Lock = HAL_UNLOCKED;
    /* Init the low level hardware */
    HAL_CAN_MspInit(hcan);
  }

  /* Initialize the CAN state*/
  hcan->State = HAL_CAN_STATE_BUSY;

  /* Exit from sleep mode */
  CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);

  /* Request initialisation */
  SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);

  /* Get timeout */
  tickstart = HAL_GetTick();

  /* Wait the acknowledge */
  while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  {
    if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
    {
      hcan->State= HAL_CAN_STATE_TIMEOUT;

      /* Process unlocked */
      __HAL_UNLOCK(hcan);

      return HAL_TIMEOUT;
    }
  }

  /* Check acknowledge */
  if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
  {
    /* Set the time triggered communication mode */
    if (hcan->Init.TTCM == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_TTCM);
    }

    /* Set the automatic bus-off management */
    if (hcan->Init.ABOM == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_ABOM);
    }

    /* Set the automatic wake-up mode */
    if (hcan->Init.AWUM == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_AWUM);
    }

    /* Set the no automatic retransmission */
    if (hcan->Init.NART == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_NART);
    }

    /* Set the receive FIFO locked mode */
    if (hcan->Init.RFLM == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_RFLM);
    }

    /* Set the transmit FIFO priority */
    if (hcan->Init.TXFP == ENABLE)
    {
      SET_BIT(tmp_mcr, CAN_MCR_TXFP);
    }

    /* Update register MCR */
    MODIFY_REG(hcan->Instance->MCR,
               CAN_MCR_TTCM |
               CAN_MCR_ABOM |
               CAN_MCR_AWUM |
               CAN_MCR_NART |
               CAN_MCR_RFLM |
               CAN_MCR_TXFP,
               tmp_mcr);

    /* Set the bit timing register */
    WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode           |
                                              hcan->Init.SJW            |
                                              hcan->Init.BS1            |
                                              hcan->Init.BS2            |
                                              (hcan->Init.Prescaler - 1) ));

    /* Request leave initialisation */
    CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);

    /* Get timeout */
    tickstart = HAL_GetTick();

    /* Wait the acknowledge */
    while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
    {
      if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
      {
        hcan->State= HAL_CAN_STATE_TIMEOUT;

        /* Process unlocked */
        __HAL_UNLOCK(hcan);

        return HAL_TIMEOUT;
      }
    }

    /* Check acknowledged */
    if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
    {
      status = CAN_INITSTATUS_SUCCESS;
    }
  }

  if(status == CAN_INITSTATUS_SUCCESS)
  {
    /* Set CAN error code to none */
    hcan->ErrorCode = HAL_CAN_ERROR_NONE;

    /* Initialize the CAN state */
    hcan->State = HAL_CAN_STATE_READY;

    /* Return function status */
    return HAL_OK;
  }
  else
  {
    /* Initialize the CAN state */
    hcan->State = HAL_CAN_STATE_ERROR;

    /* Return function status */
    return HAL_ERROR;
  }
}