| /** | |
| ****************************************************************************** | |
| * File Name : ADC.c | |
| * Description : This file provides code for the configuration | |
| * of the ADC instances. | |
| ****************************************************************************** | |
| * @attention | |
| * | |
| * <h2><center>© Copyright (c) 2020 STMicroelectronics. | |
| * All rights reserved.</center></h2> | |
| * | |
| * This software component is licensed by ST under Ultimate Liberty license | |
| * SLA0044, the "License"; You may not use this file except in compliance with | |
| * the License. You may obtain a copy of the License at: | |
| * www.st.com/SLA0044 | |
| * | |
| ****************************************************************************** | |
| */ | |
| /* Includes ------------------------------------------------------------------*/ | |
| #include "adc.h" | |
| #include "gpio_defs.h" | |
| /* USER CODE BEGIN 0 */ | |
| /* USER CODE END 0 */ | |
| ADC_HandleTypeDef hadc1; | |
| ADC_HandleTypeDef hadc3; | |
| DMA_HandleTypeDef hdma_adc1; | |
| DMA_HandleTypeDef hdma_adc3; | |
| /* ADC1 init function */ | |
| void MX_ADC1_Init(void) | |
| { | |
| ADC_MultiModeTypeDef multimode = {0}; | |
| ADC_ChannelConfTypeDef sConfig = {0}; | |
| /** Common config | |
| */ | |
| hadc1.Instance = ADC1; | |
| hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; | |
| hadc1.Init.Resolution = ADC_RESOLUTION_16B; | |
| hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; | |
| hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; | |
| hadc1.Init.LowPowerAutoWait = DISABLE; | |
| hadc1.Init.ContinuousConvMode = ENABLE; | |
| hadc1.Init.NbrOfConversion = 2; | |
| hadc1.Init.DiscontinuousConvMode = DISABLE; | |
| hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; | |
| hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; | |
| hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; | |
| hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; | |
| hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; | |
| hadc1.Init.OversamplingMode = ENABLE; | |
| hadc1.Init.Oversampling.Ratio = 256; // Number of ADC samples to be summed together | |
| hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_8; // Right bit shift (division effectively) for resulting ADC sum | |
| hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER; | |
| hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE; | |
| if (HAL_ADC_Init(&hadc1) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure the ADC multi-mode | |
| */ | |
| multimode.Mode = ADC_MODE_INDEPENDENT; | |
| if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_4; | |
| sConfig.Rank = ADC_REGULAR_RANK_1; | |
| sConfig.SamplingTime = ADC_SAMPLETIME_32CYCLES_5; | |
| sConfig.SingleDiff = ADC_SINGLE_ENDED; | |
| sConfig.OffsetNumber = ADC_OFFSET_NONE; | |
| sConfig.Offset = 0; | |
| if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_10; | |
| sConfig.Rank = ADC_REGULAR_RANK_2; | |
| if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| } | |
| /* ADC3 init function */ | |
| void MX_ADC3_Init(void) | |
| { | |
| ADC_ChannelConfTypeDef sConfig = {0}; | |
| /** Common config | |
| */ | |
| hadc3.Instance = ADC3; | |
| hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; | |
| hadc3.Init.Resolution = ADC_RESOLUTION_16B; | |
| hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE; | |
| hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; | |
| hadc3.Init.LowPowerAutoWait = DISABLE; | |
| hadc3.Init.ContinuousConvMode = ENABLE; | |
| hadc3.Init.NbrOfConversion = 4; | |
| hadc3.Init.DiscontinuousConvMode = DISABLE; | |
| hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; | |
| hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; | |
| hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; | |
| hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; | |
| hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; | |
| hadc3.Init.OversamplingMode = ENABLE; | |
| hadc3.Init.Oversampling.Ratio = 256; // Number of ADC samples to be summed together | |
| hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_8; // Right bit shift (division effectively) for resulting ADC sum | |
| hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER; | |
| hadc3.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE; | |
| if (HAL_ADC_Init(&hadc3) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_11; | |
| sConfig.Rank = ADC_REGULAR_RANK_1; | |
| sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; | |
| sConfig.SingleDiff = ADC_SINGLE_ENDED; | |
| sConfig.OffsetNumber = ADC_OFFSET_NONE; | |
| sConfig.Offset = 0; | |
| if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_0; | |
| sConfig.Rank = ADC_REGULAR_RANK_2; | |
| if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_1; | |
| sConfig.Rank = ADC_REGULAR_RANK_3; | |
| if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| /** Configure Regular Channel | |
| * Reading ADC channel twice, just to make sure | |
| * I kid. This is actually here because the DMA transfer is circular, | |
| * and 3 readings into a 32-sample buffer means we have a phase problem. | |
| * Adding this reading will ensure our 3 ADC readings are always left-aligned. | |
| * TODO: There must be a sensible way to fix this. | |
| */ | |
| sConfig.Channel = ADC_CHANNEL_1; | |
| sConfig.Rank = ADC_REGULAR_RANK_4; | |
| if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| } | |
| void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) | |
| { | |
| if(adcHandle->Instance==ADC1) | |
| { | |
| /* USER CODE BEGIN ADC1_MspInit 0 */ | |
| /* USER CODE END ADC1_MspInit 0 */ | |
| /* ADC1 clock enable */ | |
| __HAL_RCC_ADC12_CLK_ENABLE(); | |
| __HAL_RCC_GPIOC_CLK_ENABLE(); | |
| /* ADC1 DMA Init */ | |
| /* ADC1 Init */ | |
| hdma_adc1.Instance = DMA1_Stream0; | |
| hdma_adc1.Init.Request = DMA_REQUEST_ADC1; | |
| hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; | |
| hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; | |
| hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; | |
| hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; | |
| hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; | |
| hdma_adc1.Init.Mode = DMA_CIRCULAR; | |
| hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; | |
| hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_ENABLE; | |
| if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1); | |
| /* ADC1 interrupt Init */ | |
| HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); | |
| HAL_NVIC_EnableIRQ(ADC_IRQn); | |
| /* USER CODE BEGIN ADC1_MspInit 1 */ | |
| /* USER CODE END ADC1_MspInit 1 */ | |
| } | |
| else if(adcHandle->Instance==ADC3) | |
| { | |
| /* USER CODE BEGIN ADC3_MspInit 0 */ | |
| /* USER CODE END ADC3_MspInit 0 */ | |
| /* ADC3 clock enable */ | |
| __HAL_RCC_ADC3_CLK_ENABLE(); | |
| __HAL_RCC_GPIOC_CLK_ENABLE(); | |
| /**ADC3 GPIO Configuration | |
| PC1 ------> ADC3_INP11 | |
| PC2_C ------> ADC3_INP0 | |
| PC3_C ------> ADC3_INP1 | |
| */ | |
| HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC2, SYSCFG_SWITCH_PC2_OPEN); | |
| HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_OPEN); | |
| /* ADC3 DMA Init */ | |
| /* ADC3 Init */ | |
| hdma_adc3.Instance = DMA1_Stream1; | |
| hdma_adc3.Init.Request = DMA_REQUEST_ADC3; | |
| hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY; | |
| hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE; | |
| hdma_adc3.Init.MemInc = DMA_MINC_ENABLE; | |
| hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; | |
| hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; | |
| hdma_adc3.Init.Mode = DMA_CIRCULAR; | |
| hdma_adc3.Init.Priority = DMA_PRIORITY_MEDIUM; | |
| hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_ENABLE; | |
| if (HAL_DMA_Init(&hdma_adc3) != HAL_OK) | |
| { | |
| Error_Handler(); | |
| } | |
| __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3); | |
| /* ADC3 interrupt Init */ | |
| HAL_NVIC_SetPriority(ADC3_IRQn, 0, 0); | |
| HAL_NVIC_EnableIRQ(ADC3_IRQn); | |
| /* USER CODE BEGIN ADC3_MspInit 1 */ | |
| /* USER CODE END ADC3_MspInit 1 */ | |
| } | |
| } | |
| void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) | |
| { | |
| if(adcHandle->Instance==ADC1) | |
| { | |
| /* USER CODE BEGIN ADC1_MspDeInit 0 */ | |
| /* USER CODE END ADC1_MspDeInit 0 */ | |
| /* Peripheral clock disable */ | |
| __HAL_RCC_ADC12_CLK_DISABLE(); | |
| /**ADC1 GPIO Configuration | |
| PC0 ------> ADC1_INP10 | |
| PC4 ------> ADC1_INP4 | |
| */ | |
| HAL_GPIO_DeInit(GPIOC, JOYSTICK_Y_Pin|JOYSTICK_X_Pin); | |
| /* ADC1 DMA DeInit */ | |
| HAL_DMA_DeInit(adcHandle->DMA_Handle); | |
| /* ADC1 interrupt Deinit */ | |
| HAL_NVIC_DisableIRQ(ADC_IRQn); | |
| /* USER CODE BEGIN ADC1_MspDeInit 1 */ | |
| /* USER CODE END ADC1_MspDeInit 1 */ | |
| } | |
| else if(adcHandle->Instance==ADC3) | |
| { | |
| /* USER CODE BEGIN ADC3_MspDeInit 0 */ | |
| /* USER CODE END ADC3_MspDeInit 0 */ | |
| /* Peripheral clock disable */ | |
| __HAL_RCC_ADC3_CLK_DISABLE(); | |
| /**ADC3 GPIO Configuration | |
| PC1 ------> ADC3_INP11 | |
| PC2_C ------> ADC3_INP0 | |
| PC3_C ------> ADC3_INP1 | |
| */ | |
| HAL_GPIO_DeInit(USER_LEFT1_GPIO_Port, USER_LEFT1_Pin); | |
| /* ADC3 DMA DeInit */ | |
| HAL_DMA_DeInit(adcHandle->DMA_Handle); | |
| /* ADC3 interrupt Deinit */ | |
| HAL_NVIC_DisableIRQ(ADC3_IRQn); | |
| /* USER CODE BEGIN ADC3_MspDeInit 1 */ | |
| /* USER CODE END ADC3_MspDeInit 1 */ | |
| } | |
| } | |
| /* USER CODE BEGIN 1 */ | |
| /* USER CODE END 1 */ | |
| /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |