/** * @brief Initializes the ADCx peripheral according to the specified parameters * in the ADC_InitStruct. * @note This function is used to configure the global features of the ADC ( * Resolution, Data Alignment, continuous mode activation, External * trigger source and edge, Sequence Scan Direction). * @param ADCx: where x can be 1 to select the ADC peripheral. * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains * the configuration information for the specified ADC peripheral. * @retval None */ void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); assert_param(IS_ADC_EXTERNAL_TRIG_CONV(ADC_InitStruct->ADC_ExternalTrigConv)); assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); assert_param(IS_ADC_SCAN_DIRECTION(ADC_InitStruct->ADC_ScanDirection)); /* Get the ADCx CFGR value */ tmpreg = ADCx->CFGR1; /* Clear SCANDIR, RES[1:0], ALIGN, EXTSEL[2:0], EXTEN[1:0] and CONT bits */ tmpreg &= CFGR1_CLEAR_MASK; /*---------------------------- ADCx CFGR Configuration ---------------------*/ /* Set RES[1:0] bits according to ADC_Resolution value */ /* Set CONT bit according to ADC_ContinuousConvMode value */ /* Set EXTEN[1:0] bits according to ADC_ExternalTrigConvEdge value */ /* Set EXTSEL[2:0] bits according to ADC_ExternalTrigConv value */ /* Set ALIGN bit according to ADC_DataAlign value */ /* Set SCANDIR bit according to ADC_ScanDirection value */ tmpreg |= (uint32_t)(ADC_InitStruct->ADC_Resolution | ((uint32_t)(ADC_InitStruct->ADC_ContinuousConvMode) << 13) | ADC_InitStruct->ADC_ExternalTrigConvEdge | ADC_InitStruct->ADC_ExternalTrigConv | ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ScanDirection); /* Write to ADCx CFGR */ ADCx->CFGR1 = tmpreg; }
/** * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param pData: The destination Buffer address. * @param Length: The length of data to be transferred from ADC peripheral to memory. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) { uint16_t i = 0; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); /* Process locked */ __HAL_LOCK(hadc); /* Enable ADC overrun interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); /* Enable ADC DMA mode */ hadc->Instance->CR2 |= ADC_CR2_DMA; /* 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 ; /* Enable the DMA Stream */ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_REG; /* 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 inserted to wait during Tstab time the ADC's stabilazation */ for(; i <= 540; i++) { __NOP(); } } /* if no external trigger present enable software conversion of regular channels */ if (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE) { /* Enable the selected ADC software conversion for regular group */ hadc->Instance->CR2 |= ADC_CR2_SWSTART; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param pData: The destination Buffer address. * @param Length: The length of data to be transferred from ADC peripheral to memory. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Start_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)); /* Process locked */ __HAL_LOCK(hadc); /* Enable ADC overrun interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); /* Enable ADC DMA mode */ hadc->Instance->CR2 |= ADC_CR2_DMA; /* 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 ; /* Enable the DMA Stream */ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_REG; /* Process unlocked */ __HAL_UNLOCK(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 ADC stabilization time */ /* Compute number of CPU cycles to wait for */ counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); while (counter != 0) { counter--; } } /* 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 |= ADC_CR2_SWSTART; } /* Return function status */ return HAL_OK; }
/** * @brief Enables ADC and starts conversion of the regular 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_Start(ADC_HandleTypeDef* hadc) { __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)); /* Process locked */ __HAL_LOCK(hadc); /* Check if an injected conversion is ongoing */ if (hadc->State == HAL_ADC_STATE_BUSY_INJ) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_REG; } /* 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 / 1000000)); while (counter != 0) { counter--; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Check if Multimode enabled */ if (HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { /* 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; } } else { /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ if ((hadc->Instance == ADC1) && ((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 Initializes the ADCx peripheral according to the specified parameters * in the ADC_InitStruct and initializes the ADC MSP. * * @note This function is used to configure the global features of the ADC ( * ClockPrescaler, Resolution, Data Alignment and number of conversion), however, * the rest of the configuration parameters are specific to the regular * channels group (scan mode activation, continuous mode activation, * External trigger source and edge, DMA continuous request after the * last transfer and End of conversion selection). * * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) { /* Check ADC handle */ if(hadc == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler)); assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ScanConvMode)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG(hadc->Init.ExternalTrigConv)); assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); if(hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) { assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); } if(hadc->State == HAL_ADC_STATE_RESET) { /* Allocate lock resource and initialize it */ hadc->Lock = HAL_UNLOCKED; /* Init the low level hardware */ HAL_ADC_MspInit(hadc); } /* Initialize the ADC state */ hadc->State = HAL_ADC_STATE_BUSY; /* Set ADC parameters */ ADC_Init(hadc); /* Set ADC error code to none */ hadc->ErrorCode = HAL_ADC_ERROR_NONE; /* Initialize the ADC state */ hadc->State = HAL_ADC_STATE_READY; /* Release Lock */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Initializes the ADCx peripheral according to the specified parameters * in the ADC_InitStruct. * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains * the configuration information for the specified ADC peripheral. * @retval None */ void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) { uint32_t tmpreg1 = 0; uint8_t tmpreg2 = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion)); /*---------------------------- ADCx CR1 Configuration -----------------*/ /* Get the ADCx CR1 value */ tmpreg1 = ADCx->CR1; /* Clear RES and SCAN bits */ tmpreg1 &= CR1_CLEAR_MASK; /* Configure ADCx: scan conversion mode and resolution */ /* Set SCAN bit according to ADC_ScanConvMode value */ /* Set RES bit according to ADC_Resolution value */ tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | ADC_InitStruct->ADC_Resolution); /* Write to ADCx CR1 */ ADCx->CR1 = tmpreg1; /*---------------------------- ADCx CR2 Configuration -----------------*/ /* Get the ADCx CR2 value */ tmpreg1 = ADCx->CR2; /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */ tmpreg1 &= CR2_CLEAR_MASK; /* Configure ADCx: external trigger event and edge, data alignment and continuous conversion mode */ /* Set ALIGN bit according to ADC_DataAlign value */ /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */ /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ /* Set CONT bit according to ADC_ContinuousConvMode value */ tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv | ADC_InitStruct->ADC_ExternalTrigConvEdge | ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); /* Write to ADCx CR2 */ ADCx->CR2 = tmpreg1; /*---------------------------- ADCx SQR1 Configuration -----------------*/ /* Get the ADCx SQR1 value */ tmpreg1 = ADCx->SQR1; /* Clear L bits */ tmpreg1 &= SQR1_L_RSEET; /* Configure ADCx: regular channel sequence length */ /* Set L bits according to ADC_NbrOfConversion value */ tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1); tmpreg1 |= ((uint32_t)tmpreg2 << 20); /* Write to ADCx SQR1 */ ADCx->SQR1 = tmpreg1; }
/** * @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 = 0U; /* 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 / 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 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 Enables the interrupt and starts ADC conversion of regular 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_Start_IT(ADC_HandleTypeDef* hadc) { uint16_t i = 0; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); /* Process locked */ __HAL_LOCK(hadc); /* Check if an injected conversion is ongoing */ if(hadc->State == HAL_ADC_STATE_BUSY_INJ) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_REG; } /* Set ADC error code to none */ hadc->ErrorCode = HAL_ADC_ERROR_NONE; /* 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 inserted to wait during Tstab time the ADC's stabilazation */ for(; i <= 540; i++) { __NOP(); } } /* Enable the ADC overrun interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); /* Enable the ADC end of conversion interrupt for regular group */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC); /* Check if Multimode enabled */ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { /* if no externel trigger present enable software conversion of regular channels */ if (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE) { /* Enable the selected ADC software conversion for regular group */ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; } } else { /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ if ((hadc->Instance == (ADC_TypeDef*)0x40012000) && (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE)) { /* Enable the selected ADC software conversion for regular group */ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }