Example #1
0
/**
  * @brief  Initialize the COMP according to the specified
  *         parameters in the COMP_InitTypeDef and initialize the associated handle.
  * @note   If the selected comparator is locked, initialization can't be performed.
  *         To unlock the configuration, perform a system reset.
  * @note   When the LPTIM connection is enabled, the following pins LPTIM_IN1(PB5, PC0)
            and LPTIM_IN2(PB7, PC2) should not be configured in alternate function.
  * @param  hcomp  COMP handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
{
  uint32_t tmp_csr = 0U;
  uint32_t exti_line = 0U;
  uint32_t comp_voltage_scaler_not_initialized = 0U;
  __IO uint32_t wait_loop_index = 0U;
  HAL_StatusTypeDef status = HAL_OK;
  
  /* Check the COMP handle allocation and lock status */
  if((hcomp == NULL) || (__HAL_COMP_IS_LOCKED(hcomp)))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Check the parameters */
    assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
    assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.NonInvertingInput));
    assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InvertingInput));
    assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
    assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
    assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
    assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
    
    if(hcomp->State == HAL_COMP_STATE_RESET)
    {
      /* Allocate lock resource and initialize it */
      hcomp->Lock = HAL_UNLOCKED;
      
      /* Init SYSCFG and the low level hardware to access comparators */
      /* Note: HAL_COMP_Init() calls __HAL_RCC_SYSCFG_CLK_ENABLE()            */
      /*       to enable internal control clock of the comparators.           */
      /*       However, this is a legacy strategy. In future STM32 families,  */
      /*       COMP clock enable must be implemented by user                  */
      /*       in "HAL_COMP_MspInit()".                                       */
      /*       Therefore, for compatibility anticipation, it is recommended   */
      /*       to implement __HAL_RCC_SYSCFG_CLK_ENABLE()                     */
      /*       in "HAL_COMP_MspInit()".                                       */
      __HAL_RCC_SYSCFG_CLK_ENABLE();
      
      /* Init the low level hardware */
      HAL_COMP_MspInit(hcomp);
    }
    
    /* Set COMP parameters */
    tmp_csr = (hcomp->Init.InvertingInput   |
               hcomp->Init.OutputPol         );
    
    /* Configuration specific to comparator instance: COMP2 */
    if ((hcomp->Instance) == COMP2)
    {
      /* Comparator input plus configuration is available on COMP2 only */
      /* Comparator power mode configuration is available on COMP2 only */
      tmp_csr |= (hcomp->Init.NonInvertingInput |
                  hcomp->Init.Mode               );
      
      /* COMP2 specificity: when using VrefInt or subdivision of VrefInt,     */
      /* specific path must be enabled.                                       */
      if((hcomp->Init.InvertingInput == COMP_INPUT_MINUS_VREFINT)    ||
         (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_1_4VREFINT) ||
         (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_1_2VREFINT) ||
         (hcomp->Init.InvertingInput == COMP_INPUT_MINUS_3_4VREFINT)   )
      {
        /* Memorize voltage scaler state before initialization */
        comp_voltage_scaler_not_initialized = (READ_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP) == 0U);
        
        SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUFLP_VREFINT_COMP  );
        
        /* Delay for COMP scaler bridge voltage stabilization */
        /* Apply the delay if voltage scaler bridge is enabled for the first time */
        if (comp_voltage_scaler_not_initialized != 0U)
        {
          /* Wait loop initialization and execution */
          /* Note: Variable divided by 2 to compensate partially              */
          /*       CPU processing cycles.                                     */
          wait_loop_index = (COMP_DELAY_VOLTAGE_SCALER_STAB_US * (SystemCoreClock / (1000000U * 2U)));
          while(wait_loop_index != 0U)
          {
            wait_loop_index--;
          }
        }
      }
    }
    
    /* Set comparator output connection to LPTIM */
    if (hcomp->Init.LPTIMConnection != COMP_LPTIMCONNECTION_DISABLED)
    {
      /* LPTIM connexion requested on COMP1 */
      if ((hcomp->Instance) == COMP1)
      {
        /* Note : COMP1 can be connected to the input 1 of LPTIM if requested */
        assert_param(IS_COMP1_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
        if (hcomp->Init.LPTIMConnection == COMP_LPTIMCONNECTION_IN1_ENABLED)
        {
          tmp_csr |= (COMP_CSR_COMP1LPTIM1IN1);
        }
      }
      else
      {
        /* Check the MCU_ID in order to allow or not the COMP2 connection to LPTIM-input2 */
        if (((HAL_GetDEVID() == C_DEV_ID_L073) && (HAL_GetREVID() == C_REV_ID_A))
                          ||
            ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_A))
                          ||
            ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_Z)))
        {
          /* Note : COMP2 can be connected only to input 1 of LPTIM if requested */
          assert_param(IS_COMP2_LPTIMCONNECTION_RESTRICTED(hcomp->Init.LPTIMConnection));
          
          tmp_csr |= (COMP_CSR_COMP2LPTIM1IN1);
        }
        /* LPTIM connexion requested on COMP2 */
        else
        {
           /* Note : COMP2 can be connected to input 1 or input2  of LPTIM if requested */
          assert_param(IS_COMP2_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
          switch (hcomp->Init.LPTIMConnection)
          {
          case  COMP_LPTIMCONNECTION_IN1_ENABLED :
              tmp_csr |= (COMP_CSR_COMP2LPTIM1IN1);
              break;
          case  COMP_LPTIMCONNECTION_IN2_ENABLED :
              tmp_csr |= (COMP_CSR_COMP2LPTIM1IN2);
              break;
          default :
              break;
          }
        }
      }
    }
      
    /* Update comparator register */
    if ((hcomp->Instance) == COMP1)
    {
      MODIFY_REG(hcomp->Instance->CSR,
                 COMP_CSR_COMP1INNSEL     | COMP_CSR_COMP1WM       |
                 COMP_CSR_COMP1LPTIM1IN1  | COMP_CSR_COMP1POLARITY  ,
                 tmp_csr
                );
    }
    else /* Instance == COMP2 */
    {
      MODIFY_REG(hcomp->Instance->CSR,
                 COMP_CSR_COMP2SPEED     | COMP_CSR_COMP2INNSEL    |
                 COMP_CSR_COMP2INPSEL    | COMP_CSR_COMP2POLARITY  |
                 COMP_CSR_COMP2LPTIM1IN2 | COMP_CSR_COMP2LPTIM1IN1  ,
                 tmp_csr
                );
    }
    
    /* Set window mode */
    /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP     */
    /*       instances. Therefore, this function can update another COMP      */
    /*       instance that the one currently selected.                        */
    if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
    {
      SET_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
    }
    else
    {
      CLEAR_BIT(COMP12_COMMON->CSR, COMP_CSR_WINMODE);
    }
    
    /* Get the EXTI line corresponding to the selected COMP instance */
    exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
    
    /* Manage EXTI settings */
    if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != RESET)
    {
      /* Configure EXTI rising edge */
      if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != RESET)
      {
        SET_BIT(EXTI->RTSR, exti_line);
      }
      else
      {
        CLEAR_BIT(EXTI->RTSR, exti_line);
      }
      
      /* Configure EXTI falling edge */
      if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != RESET)
      {
        SET_BIT(EXTI->FTSR, exti_line);
      }
      else
      {
        CLEAR_BIT(EXTI->FTSR, exti_line);
      }
      
      /* Clear COMP EXTI pending bit (if any) */
      WRITE_REG(EXTI->PR, exti_line);
      
      /* Configure EXTI event mode */
      if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != RESET)
      {
        SET_BIT(EXTI->EMR, exti_line);
      }
      else
      {
        CLEAR_BIT(EXTI->EMR, exti_line);
      }
      
      /* Configure EXTI interrupt mode */
      if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != RESET)
      {
        SET_BIT(EXTI->IMR, exti_line);
      }
      else
      {
        CLEAR_BIT(EXTI->IMR, exti_line);
      }
    }
    else
    {
      /* Disable EXTI event generation */
      CLEAR_BIT(EXTI->EMR, exti_line);
    }
    
    /* Set HAL COMP handle state */
    /* Note: Transition from state reset to state ready,                      */
    /*       otherwise (coming from state ready or busy) no state update.     */
    if (hcomp->State == HAL_COMP_STATE_RESET)
    {
      hcomp->State = HAL_COMP_STATE_READY;
    }
  }
  
  return status;
}
/**
  * @brief  Initializes the COMP according to the specified
  *         parameters in the COMP_InitTypeDef and create the associated handle.
  * @note   If the selected comparator is locked, initialization can't be performed.
  *         To unlock the configuration, perform a system reset.
  * @note   When the LPTIM connection is enabled, the following pins LPTIM_IN1(PB5, PC0)
            and LPTIM_IN2(PB7, PC2) should not be configured in AF. 
  * @param  hcomp: COMP handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
{
 HAL_StatusTypeDef status = HAL_OK;
  
  /* Check the COMP handle allocation and lock status */
  if((hcomp == NULL) || ((hcomp->State & COMP_STATE_BIT_LOCK) != 0x00))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Check the parameter */
    assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
    assert_param(IS_COMP_INVERTINGINPUT(hcomp->Init.InvertingInput));
    assert_param(IS_COMP_NONINVERTINGINPUT(hcomp->Init.NonInvertingInput));
    assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
    assert_param(IS_COMP_MODE(hcomp->Init.Mode));
    
    if(hcomp->Init.WindowMode != COMP_WINDOWMODE_DISABLE)
    {
      assert_param(IS_COMP_WINDOWMODE_INSTANCE(hcomp->Instance));
      assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
    }
    
    if(hcomp->State == HAL_COMP_STATE_RESET)
    {
      /* Allocate lock resource and initialize it */
      hcomp->Lock = HAL_UNLOCKED;
      /* Init SYSCFG and the low level hardware to access comparators */
     __HAL_RCC_SYSCFG_CLK_ENABLE();
      /* Init the low level hardware : SYSCFG to access comparators */
      HAL_COMP_MspInit(hcomp);
    }
    
    /* Change COMP peripheral state */
    hcomp->State = HAL_COMP_STATE_BUSY;
  
    /* Set COMP parameters                                                              */
    /*     Set COMPxINSEL bits according to hcomp->Init.InvertingInput value            */
    /*     Set COMPxNONINSEL bits according to hcomp->Init.NonInvertingInput value      */
    /*     Set COMPxLPTIMCONNECTION bits according to hcomp->Init.LPTIMConnection value */
    /*     Set COMPxPOL bit according to hcomp->Init.OutputPol value                    */
    /*     Set COMPxMODE bits according to hcomp->Init.Mode value                       */
    /*     Set COMP1WM bit according to hcomp->Init.WindowMode value                    */

    /* No LPTIM connexion requested */
    if (hcomp->Init.LPTIMConnection == COMP_LPTIMCONNECTION_DISABLED)
    {
         MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                       hcomp->Init.InvertingInput    |  \
                                       hcomp->Init.NonInvertingInput |  \
                                       hcomp->Init.OutputPol         |  \
                                       hcomp->Init.Mode              |  \
                                       hcomp->Init.WindowMode);
    }
    else
    {
      /* LPTIM connexion requested on COMP2*/
      if ((hcomp->Instance) == COMP2)
      {
        /* Check the MCU_ID in order to allow or not the COMP2 connection to LPTIM-input2 */
        if (((HAL_GetDEVID() == C_DEV_ID_L073) && (HAL_GetREVID() == C_REV_ID_A))
                          ||
            ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_A))
                          ||
            ((HAL_GetDEVID() == C_DEV_ID_L053) && (HAL_GetREVID() == C_REV_ID_Z)))
        {
          /* Note : COMP2 can be connected only to input 1 of LPTIM if requested */
          assert_param(IS_COMP2_LPTIMCONNECTION_RESTRICTED(hcomp->Init.LPTIMConnection));
          MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                       hcomp->Init.InvertingInput    |  \
                                       hcomp->Init.NonInvertingInput |  \
                                       COMP_CSR_COMP2LPTIM1IN1       |  \
                                       hcomp->Init.OutputPol         |  \
                                       hcomp->Init.Mode              |  \
                                       hcomp->Init.WindowMode);
        }
        else
        {
           /* Note : COMP2 can be connected to input 1 or input2  of LPTIM if requested */
          assert_param(IS_COMP2_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
          switch (hcomp->Init.LPTIMConnection)
          {
          case  COMP_LPTIMCONNECTION_IN1_ENABLED :
              MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                         hcomp->Init.InvertingInput    |  \
                                         hcomp->Init.NonInvertingInput |  \
                                         COMP_CSR_COMP2LPTIM1IN1       |  \
                                         hcomp->Init.OutputPol         |  \
                                         hcomp->Init.Mode              |  \
                                         hcomp->Init.WindowMode);
              break;
          case  COMP_LPTIMCONNECTION_IN2_ENABLED :
              MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                         hcomp->Init.InvertingInput    |  \
                                         hcomp->Init.NonInvertingInput |  \
                                         COMP_CSR_COMP2LPTIM1IN2       |  \
                                         hcomp->Init.OutputPol         |  \
                                         hcomp->Init.Mode              |  \
                                         hcomp->Init.WindowMode);
              break;
          default :
              MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                         hcomp->Init.InvertingInput    |  \
                                         hcomp->Init.NonInvertingInput |  \
                                         hcomp->Init.OutputPol         |  \
                                         hcomp->Init.Mode              |  \
                                         hcomp->Init.WindowMode);
              break;
          }
        }
      }
      else
      /* LPTIM connexion requested on COMP1 */
      {
        /* Note : COMP1 can be connected to the input 1 of LPTIM if requested */
        assert_param(IS_COMP1_LPTIMCONNECTION(hcomp->Init.LPTIMConnection));
        if (hcomp->Init.LPTIMConnection == COMP_LPTIMCONNECTION_IN1_ENABLED)
            MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                         hcomp->Init.InvertingInput    |      \
                                         hcomp->Init.NonInvertingInput |      \
                                         COMP_CSR_COMP1LPTIM1IN1       |      \
                                         hcomp->Init.OutputPol         |      \
                                         hcomp->Init.Mode              |      \
                                         hcomp->Init.WindowMode);
        else
            MODIFY_REG(hcomp->Instance->CSR, COMP_CSR_UPDATE_PARAMETERS_MASK, \
                                         hcomp->Init.InvertingInput    |      \
                                         hcomp->Init.NonInvertingInput |      \
                                         hcomp->Init.OutputPol         |      \
                                         hcomp->Init.Mode              |      \
                                         hcomp->Init.WindowMode);
      }
    }
    /* Initialize the COMP state*/
    hcomp->State = HAL_COMP_STATE_READY;

  }
  
  return status;
}