/** * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) { /* Process locked */ __HAL_LOCK(hadc); /* Enable the Peripheral */ __HAL_ADC_DISABLE(hadc); /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); /* Disable the selected ADC DMA request after last transfer */ ADC->CCR &= ~ADC_CCR_DDS; /* Disable the ADC DMA Stream */ HAL_DMA_Abort(hadc->DMA_Handle); /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Disables the interrupt and stop ADC conversion of regular channels. * * @note Caution: This function will stop also 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_ADC_Stop_IT(ADC_HandleTypeDef* hadc) { /* Disable the ADC end of conversion interrupt for regular group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* Disable the ADC end of conversion interrupt for injected group */ __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE); /* Enable the Peripheral */ __HAL_ADC_DISABLE(hadc); /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; /* Return function status */ return HAL_OK; }
/** * @brief Configures the analog watchdog. * @note Analog watchdog thresholds can be modified while ADC conversion is on going. * In this case, some constraints must be taken into account: the programmed threshold * values are effective from the next ADC EOC (end of unitary conversion). * Considering that registers write delay may happen due to bus activity, this might cause * an uncertainty on the effective timing of the new programmed threshold values. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param AnalogWDGConfig : pointer to an ADC_AnalogWDGConfTypeDef structure * that contains the configuration information of ADC analog watchdog. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig) { #ifdef USE_FULL_ASSERT uint32_t tmp = 0; #endif /* USE_FULL_ASSERT */ /* Check the parameters */ assert_param(IS_ADC_ANALOG_WATCHDOG(AnalogWDGConfig->WatchdogMode)); assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); #ifdef USE_FULL_ASSERT tmp = ADC_GET_RESOLUTION(hadc); assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->HighThreshold)); assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->LowThreshold)); #endif /* USE_FULL_ASSERT */ /* Process locked */ __HAL_LOCK(hadc); if(AnalogWDGConfig->ITMode == ENABLE) { /* Enable the ADC Analog watchdog interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD); } else { /* Disable the ADC Analog watchdog interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD); } /* Clear AWDEN, JAWDEN and AWDSGL bits */ hadc->Instance->CR1 &= ~(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN); /* Set the analog watchdog enable mode */ hadc->Instance->CR1 |= AnalogWDGConfig->WatchdogMode; /* Set the high threshold */ hadc->Instance->HTR = AnalogWDGConfig->HighThreshold; /* Set the low threshold */ hadc->Instance->LTR = AnalogWDGConfig->LowThreshold; /* Clear the Analog watchdog channel select bits */ hadc->Instance->CR1 &= ~ADC_CR1_AWDCH; /* Set the Analog watchdog channel */ hadc->Instance->CR1 |= (uint32_t)((uint16_t)(AnalogWDGConfig->Channel)); /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Stop conversion of injected channels, disable interruption of * end-of-conversion. Disable ADC peripheral if no regular conversion * is on going. * @note If ADC must be disabled and if conversion is on going on * regular group, function HAL_ADC_Stop must be used to stop both * injected and regular groups, and disable the ADC. * @note If injected group mode auto-injection is enabled, * function HAL_ADC_Stop must be used. * @param hadc: ADC handle * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion and disable ADC peripheral */ /* Conditioned to: */ /* - No conversion on the other group (regular group) is intended to */ /* continue (injected and regular groups stop conversion and ADC disable */ /* are common) */ /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) { /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ __HAL_ADC_DISABLE(hadc); /* Check if ADC is effectively disabled */ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) { /* Disable ADC end of conversion interrupt for injected channels */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY); } } else { /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); tmp_hal_status = HAL_ERROR; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief DMA transfer complete callback. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma) { /* Retrieve ADC handle corresponding to current DMA handle */ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* Update state machine on conversion status if not in error state */ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) { /* Update ADC state machine */ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); /* Determine whether any further conversion upcoming on group regular */ /* by external trigger, continuous mode or scan sequence on going. */ /* Note: On STM32F4, there is no independent flag of end of sequence. */ /* The test of scan sequence on going is done either with scan */ /* sequence disabled or with end of conversion flag set to */ /* of end of sequence. */ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && (hadc->Init.ContinuousConvMode == DISABLE) && (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) ) { /* Disable ADC end of single conversion interrupt on group regular */ /* Note: Overrun interrupt was enabled with EOC interrupt in */ /* HAL_ADC_Start_IT(), but is not disabled here because can be used */ /* by overrun IRQ process below. */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* Set ADC state */ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) { SET_BIT(hadc->State, HAL_ADC_STATE_READY); } } /* Conversion complete callback */ HAL_ADC_ConvCpltCallback(hadc); } else { /* Call DMA error callback */ hadc->DMA_Handle->XferErrorCallback(hdma); } }
/** * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; ADC_Common_TypeDef *tmpADC_Common; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ __HAL_ADC_DISABLE(hadc); /* 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 ADC is effectively disabled */ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) { /* Disable the selected ADC DMA mode for multimode */ tmpADC_Common->CCR &= ~ADC_CCR_DDS; /* Disable the DMA channel (in case of DMA in circular mode or stop while */ /* DMA transfer is on going) */ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY); } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Disables ADC DMA (Single-ADC mode) and disables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) { /* Disable the Peripheral */ __HAL_ADC_DISABLE(hadc); /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); /* Disable the selected ADC DMA mode */ hadc->Instance->CR2 &= ~ADC_CR2_DMA; /* Disable the ADC DMA Stream */ HAL_DMA_Abort(hadc->DMA_Handle); /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; /* Return function status */ return HAL_OK; }
/** * @brief Handles ADC interrupt request * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval None */ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) { uint32_t tmp1 = 0, tmp2 = 0; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC); /* Check End of conversion flag for regular channels */ if(tmp1 && tmp2) { /* Check if an injected conversion is ready */ if(hadc->State == HAL_ADC_STATE_EOC_INJ) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_REG; } if((hadc->Init.ContinuousConvMode == DISABLE) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) { if(hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) { /* DISABLE the ADC end of conversion interrupt for regular group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* DISABLE the ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); } else { if (hadc->NbrOfCurrentConversionRank == 0) { hadc->NbrOfCurrentConversionRank = hadc->Init.NbrOfConversion; } /* Decrement the number of conversion when an interrupt occurs */ hadc->NbrOfCurrentConversionRank--; /* Check if all conversions are finished */ if(hadc->NbrOfCurrentConversionRank == 0) { /* DISABLE the ADC end of conversion interrupt for regular group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* DISABLE the ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); } } } /* Conversion complete callback */ HAL_ADC_ConvCpltCallback(hadc); /* Clear the ADCx flag for regular end of conversion */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_EOC); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC); /* Check End of conversion flag for injected channels */ if(tmp1 && tmp2) { /* Check if a regular conversion is ready */ if(hadc->State == HAL_ADC_STATE_EOC_REG) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ; } tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); if(((hadc->Init.ContinuousConvMode == DISABLE) || tmp1) && tmp2) { /* DISABLE the ADC end of conversion interrupt for injected group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); } /* Conversion complete callback */ HAL_ADCEx_InjectedConvCpltCallback(hadc); /* Clear the ADCx flag for injected end of conversion */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD); /* Check Analog watchdog flag */ if(tmp1 && tmp2) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_AWD; /* Clear the ADCx's Analog watchdog flag */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_AWD); /* Level out of window callback */ HAL_ADC_LevelOutOfWindowCallback(hadc); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_OVR); /* Check Overrun flag */ if(tmp1 && tmp2) { /* Change ADC state to overrun state */ hadc->State = HAL_ADC_STATE_ERROR; /* Set ADC error code to overrun */ hadc->ErrorCode |= HAL_ADC_ERROR_OVR; /* Clear the Overrun flag */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_OVR); /* Error callback */ HAL_ADC_ErrorCallback(hadc); } }