STM32GENERIC/STM32/cores/arduino/stm32/stm32_ADC.c

105 lines
3.2 KiB
C
Raw Normal View History

2017-04-15 01:25:28 -07:00
/**
* Implementation of Arduino methods:
* analogRead(): https://www.arduino.cc/en/Reference/AnalogRead
*
* TODO actually create stm32_analog_in_XX.c files for the different variants. This is getting too compicated
*
* TODO improve performance by saving if the pin was configured for analog, and do not configure again.
* also deconfigure from pinMode in this case
* TODO implement analogReadResolution
* TODO F1 has no resolution, map to arduino default 10 bits
* TODO check if ClockPrescaler can always be set to ADC_CLOCK_SYNC_PCLK_DIV2
*/
#include "stm32_gpio_af.h"
2017-04-16 05:44:56 -07:00
void stm32_adc_init(ADC_HandleTypeDef *handle);
#ifdef ADC_CLOCK_SYNC_PCLK_DIV2
#define ADC_CLOCK_DIV ADC_CLOCK_SYNC_PCLK_DIV2
#elif defined(ADC_CLOCK_ASYNC_DIV1)
#define ADC_CLOCK_DIV ADC_CLOCK_ASYNC_DIV1
#elif defined(ADC_CLOCKPRESCALER_PCLK_DIV2)
#define ADC_CLOCK_DIV ADC_CLOCKPRESCALER_PCLK_DIV2
#else
#error "Unknown clock"
2017-04-15 01:25:28 -07:00
#endif
int analogRead(uint8_t pin) {
static ADC_HandleTypeDef handle = {};
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = port_pin_list[pin].pin_mask;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(port_pin_list[pin].port, &GPIO_InitStruct);
if (handle.Instance == NULL) {
2017-04-16 05:44:56 -07:00
#ifdef __HAL_RCC_ADC1_CLK_ENABLE
2017-04-15 01:25:28 -07:00
__HAL_RCC_ADC1_CLK_ENABLE();
2017-04-16 05:44:56 -07:00
#endif
#ifdef __HAL_RCC_ADC_CLK_ENABLE
__HAL_RCC_ADC_CLK_ENABLE();
#endif
2017-04-15 01:25:28 -07:00
handle.Instance = ADC1;
handle.Init.ScanConvMode = DISABLE;
handle.Init.ContinuousConvMode = ENABLE;
handle.Init.DiscontinuousConvMode = DISABLE;
handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
2017-04-16 05:44:56 -07:00
#ifdef STM32L0
handle.Init.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
#endif
#if !defined(STM32L0) && !defined(STM32F0)
handle.Init.NbrOfConversion = 1;
2017-04-15 01:25:28 -07:00
#endif
#ifdef ADC_EOC_SINGLE_CONV
2017-04-16 05:44:56 -07:00
handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
2017-04-15 01:25:28 -07:00
#endif
#ifdef STM32F1
handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
#else
2017-04-16 05:44:56 -07:00
handle.Init.ClockPrescaler = ADC_CLOCK_DIV;
handle.Init.Resolution = ADC_RESOLUTION_12B;
2017-04-15 01:25:28 -07:00
#endif
HAL_ADC_Init(&handle);
2017-04-16 05:44:56 -07:00
2017-04-15 01:25:28 -07:00
}
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = stm32_adc1_get_channel(port_pin_list[pin].port, port_pin_list[pin].pin_mask);
sConfig.Rank = 1;
2017-04-16 05:44:56 -07:00
#if STM32L0
2017-04-15 01:25:28 -07:00
//in handle
#elif defined(ADC_SAMPLETIME_15CYCLES)
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
#elif defined(ADC_SAMPLETIME_13CYCLES_5)
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
2017-04-16 05:44:56 -07:00
#elif defined(ADC_SAMPLETIME_19CYCLES_5)
sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
#elif defined(ADC_SAMPLETIME_16CYCLES)
sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES;
#elif defined(ADC_SAMPLETIME_12CYCLES_5)
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
2017-04-15 01:25:28 -07:00
#else
2017-04-16 05:44:56 -07:00
#error "unknown sampleing time"
2017-04-15 01:25:28 -07:00
#endif
HAL_ADC_ConfigChannel(&handle, &sConfig);
HAL_ADC_Start(&handle);
if (HAL_ADC_PollForConversion(&handle, 1000) != HAL_OK) {
return 0;
}
2017-04-16 05:44:56 -07:00
return HAL_ADC_GetValue(&handle) >> 2;
2017-04-15 01:25:28 -07:00
}