mbed library sources
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c
- Revision:
- 441:d2c15dda23c1
- Parent:
- 392:2b59412bb664
diff -r 8a0b45cd594f -r d2c15dda23c1 targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c --- a/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c Tue Dec 16 08:15:08 2014 +0000 +++ b/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c Tue Jan 06 16:15:36 2015 +0000 @@ -2,8 +2,8 @@ ****************************************************************************** * @file stm32f0xx_hal_adc.c * @author MCD Application Team - * @version V1.1.0 - * @date 03-Oct-2014 + * @version V1.2.0 + * @date 11-December-2014 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: @@ -251,7 +251,7 @@ uint32_t tmpCFGR1 = 0; /* Check ADC handle */ - if(hadc == HAL_NULL) + if(hadc == NULL) { return HAL_ERROR; } @@ -364,7 +364,7 @@ /* Enable external trigger if trigger selection is different of software */ /* start. */ - /* Note: This configuration keeps the hardware feature of parameter */ + /* @Note: This configuration keeps the hardware feature of parameter */ /* ExternalTrigConvEdge "trigger edge none" equivalent to */ /* software start. */ if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) @@ -431,7 +431,7 @@ HAL_StatusTypeDef tmpHALStatus = HAL_OK; /* Check ADC handle */ - if(hadc == HAL_NULL) + if(hadc == NULL) { return HAL_ERROR; } @@ -487,7 +487,7 @@ ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN ); /* Reset register CFGR2 */ - /* Note: Update of ADC clock mode is conditioned to ADC state disabled: */ + /* @Note: Update of ADC clock mode is conditioned to ADC state disabled: */ /* already done above. */ hadc->Instance->CFGR2 &= ~ADC_CFGR2_CKMODE; @@ -601,40 +601,49 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - - /* Process locked */ - __HAL_LOCK(hadc); - - /* Enable the ADC peripheral */ - /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ - /* performed automatically by hardware. */ - if (hadc->Init.LowPowerAutoPowerOff != ENABLE) - { - tmpHALStatus = ADC_Enable(hadc); - } - - /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) + + /* Perform ADC enable and conversion start if no conversion is on going */ + if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; - - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); - - /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ + /* performed automatically by hardware. */ + if (hadc->Init.LowPowerAutoPowerOff != ENABLE) + { + tmpHALStatus = ADC_Enable(hadc); + } - /* Enable conversion of regular group. */ - /* If software start has been selected, conversion starts immediately. */ - /* If external trigger has been selected, conversion will start at next */ - /* trigger event. */ - hadc->Instance->CR |= ADC_CR_ADSTART; + /* Start conversion if ADC is effectively enabled */ + if (tmpHALStatus != HAL_ERROR) + { + /* State machine update: Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + + /* Set ADC error code to none */ + __HAL_ADC_CLEAR_ERRORCODE(hadc); + + /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + hadc->Instance->CR |= ADC_CR_ADSTART; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); } - - /* Process unlocked */ - __HAL_UNLOCK(hadc); + else + { + tmpHALStatus = HAL_BUSY; + } /* Return function status */ return tmpHALStatus; @@ -822,8 +831,11 @@ /** * @brief Enables ADC, starts conversion of regular group with interruption. - * Interruptions enabled in this function: EOC (end of conversion), - * overrun. + * Interruptions enabled in this function: + * - EOC (end of conversion of regular group) or EOS (end of + * sequence of regular group) depending on ADC initialization + * parameter "EOCSelection" + * - overrun (if available) * Each of these interruptions has its dedicated callback function. * @param hadc: ADC handle * @retval HAL status @@ -835,54 +847,63 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - /* Process locked */ - __HAL_LOCK(hadc); - - /* Enable the ADC peripheral */ - /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ - /* performed automatically by hardware. */ - if (hadc->Init.LowPowerAutoPowerOff != ENABLE) - { - tmpHALStatus = ADC_Enable(hadc); - } - - /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) + /* Perform ADC enable and conversion start if no conversion is on going */ + if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; - - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); - - /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); - - /* Enable ADC end of conversion interrupt */ - /* Enable ADC overrun interrupt */ - switch(hadc->Init.EOCSelection) + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ + /* performed automatically by hardware. */ + if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { - case EOC_SEQ_CONV: - __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); - __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOS | ADC_IT_OVR)); - break; - /* case EOC_SINGLE_CONV */ - default: - __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); - break; + tmpHALStatus = ADC_Enable(hadc); } - /* Enable conversion of regular group. */ - /* If software start has been selected, conversion starts immediately. */ - /* If external trigger has been selected, conversion will start at next */ - /* trigger event. */ - hadc->Instance->CR |= ADC_CR_ADSTART; + /* Start conversion if ADC is effectively enabled */ + if (tmpHALStatus != HAL_ERROR) + { + /* State machine update: Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + + /* Set ADC error code to none */ + __HAL_ADC_CLEAR_ERRORCODE(hadc); + + /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); + + /* Enable ADC end of conversion interrupt */ + /* Enable ADC overrun interrupt */ + switch(hadc->Init.EOCSelection) + { + case EOC_SEQ_CONV: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOS | ADC_IT_OVR)); + break; + /* case EOC_SINGLE_CONV */ + default: + __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); + break; + } + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + hadc->Instance->CR |= ADC_CR_ADSTART; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); } - - /* Process unlocked */ - __HAL_UNLOCK(hadc); - + else + { + tmpHALStatus = HAL_BUSY; + } + /* Return function status */ return tmpHALStatus; } @@ -936,7 +957,9 @@ * @brief Enables ADC, starts conversion of regular group and transfers result * through DMA. * Interruptions enabled in this function: - * overrun, DMA half transfer, DMA transfer complete. + * - DMA transfer complete + * - DMA half transfer + * - overrun * Each of these interruptions has its dedicated callback function. * @param hadc: ADC handle * @param pData: The destination Buffer address. @@ -949,66 +972,73 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - - /* Process locked */ - __HAL_LOCK(hadc); - - /* Enable the ADC peripheral */ - /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ - /* performed automatically by hardware. */ - if (hadc->Init.LowPowerAutoPowerOff != ENABLE) + + /* Perform ADC enable and conversion start if no conversion is on going */ + if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { - tmpHALStatus = ADC_Enable(hadc); - } - - /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) - { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + /* If low power mode AutoPowerOff is enabled, power-on/off phases are */ + /* performed automatically by hardware. */ + if (hadc->Init.LowPowerAutoPowerOff != ENABLE) + { + tmpHALStatus = ADC_Enable(hadc); + } - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); - - - /* Set the DMA transfer complete callback */ - hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; - - /* Set the DMA half transfer complete callback */ - hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + /* Start conversion if ADC is effectively enabled */ + if (tmpHALStatus != HAL_ERROR) + { + /* State machine update: Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + + /* Set ADC error code to none */ + __HAL_ADC_CLEAR_ERRORCODE(hadc); - /* Set the DMA error callback */ - hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; - - /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); - - /* Enable ADC overrun interrupt */ - __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* 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 | ADC_FLAG_EOS | ADC_FLAG_OVR)); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Enable ADC DMA mode */ + hadc->Instance->CFGR1 |= ADC_CFGR1_DMAEN; + + /* Start the DMA channel */ + HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + hadc->Instance->CR |= ADC_CR_ADSTART; + } - /* Enable ADC DMA mode */ - hadc->Instance->CFGR1 |= ADC_CFGR1_DMAEN; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + else + { + tmpHALStatus = HAL_BUSY; + } - /* Start the DMA channel */ - HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); - - /* Enable conversion of regular group. */ - /* If software start has been selected, conversion starts immediately. */ - /* If external trigger has been selected, conversion will start at next */ - /* trigger event. */ - hadc->Instance->CR |= ADC_CR_ADSTART; - } - - - /* Process unlocked */ - __HAL_UNLOCK(hadc); - /* Return function status */ return tmpHALStatus; } @@ -1083,6 +1113,10 @@ /** * @brief Get ADC regular group conversion result. + * @note Reading DR register automatically clears EOC (end of conversion of + * regular group) flag. + * Additionally, this functions clears EOS (end of sequence of + * regular group) flag, in case of the end of the sequence is reached. * @param hadc: ADC handle * @retval Converted value */ @@ -1091,11 +1125,11 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - /* Note: EOC flag is automatically cleared by hardware when reading */ - /* register DR. Additionally, clear flag EOS by software. */ + /* @Note: EOC flag is not cleared here by software because automatically */ + /* cleared by hardware when reading register DR. */ - /* Clear regular group conversion flag */ - __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS) ); + /* Clear regular group end of sequence flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOS); /* Return ADC converted value */ return hadc->Instance->DR; @@ -1193,7 +1227,7 @@ if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Disable ADC end of sequence conversion interrupt */ - /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* @Note: Overrun interrupt was enabled with EOC interrupt in */ /* HAL_Start_IT(), but is not disabled here because can be used */ /* by overrun IRQ process below. */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS); @@ -1210,14 +1244,14 @@ } /* Conversion complete callback */ - /* Note: into callback, to determine if conversion has been triggered */ + /* @Note: into callback, to determine if conversion has been triggered */ /* from EOC or EOS, possibility to use: */ /* " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */ HAL_ADC_ConvCpltCallback(hadc); /* Clear regular group conversion flag */ - /* Note: in case of overrun set to OVR_DATA_PRESERVED, end of conversion */ + /* @Note: in case of overrun set to OVR_DATA_PRESERVED, end of conversion */ /* flags clear induces the release of the preserved data. */ /* Therefore, if the preserved data value is needed, it must be */ /* read preliminarily into HAL_ADC_ConvCpltCallback(). */ @@ -1230,11 +1264,12 @@ /* Change ADC state */ hadc->State = HAL_ADC_STATE_AWD; + /* Level out of window callback */ + HAL_ADC_LevelOutOfWindowCallback(hadc); + /* Clear ADC Analog watchdog flag */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); - - /* Level out of window callback */ - HAL_ADC_LevelOutOfWindowCallback(hadc); + } @@ -1406,7 +1441,7 @@ /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */ /* internal measurement paths enable: If internal channel selected, */ /* enable dedicated internal buffers and path. */ - /* Note: these internal measurement paths can be disabled using */ + /* @Note: these internal measurement paths can be disabled using */ /* HAL_ADC_DeInit() or removing the channel from sequencer with */ /* channel configuration parameter "Rank". */ @@ -1505,13 +1540,17 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); /* Verify if threshold is within the selected ADC resolution */ assert_param(IS_ADC_RANGE(__HAL_ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold)); assert_param(IS_ADC_RANGE(__HAL_ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold)); + if(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) + { + assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); + } + /* Process locked */ __HAL_LOCK(hadc); @@ -1544,7 +1583,7 @@ hadc->Instance->TR |= ( __HAL_ADC_TRX_HIGHTHRESHOLD (tmpAWDHighThresholdShifted) | tmpAWDLowThresholdShifted ); - /* Clear the ADC Analog watchdog flag (in case of let enabled by */ + /* Clear the ADC Analog watchdog flag (in case of left enabled by */ /* previous ADC operations) to be ready to use for HAL_ADC_IRQHandler() */ /* or HAL_ADC_PollForEvent(). */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_IT_AWD); @@ -1715,7 +1754,7 @@ uint32_t tickstart = 0; /* Verification if ADC is not already disabled: */ - /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ + /* @Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ /* disabled. */ if (__HAL_ADC_IS_ENABLED(hadc) != RESET ) {