diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2021-12-19 21:30:33 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2021-12-23 22:15:26 -0500 |
commit | 1c243173809fc068681385c2a3095c04c5645705 (patch) | |
tree | b30856b805e58b416efc2861ba2ea5a2698f50ec /src | |
parent | 88325b6c9334bb87702ab80ac6895f0b6cea8398 (diff) | |
download | kutter-1c243173809fc068681385c2a3095c04c5645705.tar.gz kutter-1c243173809fc068681385c2a3095c04c5645705.tar.xz kutter-1c243173809fc068681385c2a3095c04c5645705.zip |
stm32: Enable ADC support on stm32g0
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/stm32/Kconfig | 2 | ||||
-rw-r--r-- | src/stm32/Makefile | 2 | ||||
-rw-r--r-- | src/stm32/stm32f0_adc.c | 59 |
3 files changed, 51 insertions, 12 deletions
diff --git a/src/stm32/Kconfig b/src/stm32/Kconfig index 90bc63ae..7d9f6cb2 100644 --- a/src/stm32/Kconfig +++ b/src/stm32/Kconfig @@ -6,7 +6,7 @@ config STM32_SELECT bool default y select HAVE_GPIO - select HAVE_GPIO_ADC if !MACH_STM32G0 + select HAVE_GPIO_ADC select HAVE_GPIO_I2C if !(MACH_STM32F031 || MACH_STM32H7) select HAVE_GPIO_SPI if !(MACH_STM32F031 || MACH_STM32G0) select HAVE_GPIO_HARD_PWM if MACH_STM32F1 || MACH_STM32F4 || MACH_STM32H7 diff --git a/src/stm32/Makefile b/src/stm32/Makefile index 35a4cd39..5f2ad8ec 100644 --- a/src/stm32/Makefile +++ b/src/stm32/Makefile @@ -44,7 +44,7 @@ src-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c src-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c stm32/adc.c stm32/i2c.c src-$(CONFIG_MACH_STM32G0) += generic/timer_irq.c stm32/stm32f0_timer.c src-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c -src-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_i2c.c +src-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_adc.c stm32/stm32f0_i2c.c src-$(CONFIG_MACH_STM32H7) += ../lib/stm32h7/system_stm32h7xx.c src-$(CONFIG_MACH_STM32H7) += stm32/stm32h7.c generic/armcm_timer.c src-$(CONFIG_MACH_STM32H7) += stm32/gpioperiph.c stm32/stm32h7_adc.c diff --git a/src/stm32/stm32f0_adc.c b/src/stm32/stm32f0_adc.c index e3ae95e5..951d5bb1 100644 --- a/src/stm32/stm32f0_adc.c +++ b/src/stm32/stm32f0_adc.c @@ -21,11 +21,49 @@ DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN); static const uint8_t adc_pins[] = { GPIO('A', 0), GPIO('A', 1), GPIO('A', 2), GPIO('A', 3), GPIO('A', 4), GPIO('A', 5), GPIO('A', 6), GPIO('A', 7), - GPIO('B', 0), GPIO('B', 1), GPIO('C', 0), GPIO('C', 1), + GPIO('B', 0), GPIO('B', 1), +#if CONFIG_MACH_STM32F0 + GPIO('C', 0), GPIO('C', 1), GPIO('C', 2), GPIO('C', 3), GPIO('C', 4), GPIO('C', 5), ADC_TEMPERATURE_PIN +#elif CONFIG_MACH_STM32G0 + GPIO('B', 2), GPIO('B', 10), + ADC_TEMPERATURE_PIN, 0x00, 0x00, + GPIO('B', 11), GPIO('B', 12), GPIO('C', 4), GPIO('C', 5), +#endif }; +// Setup and calibrate ADC on stm32f0 chips +static void +stm32f0_adc_setup(void) +{ +#if CONFIG_MACH_STM32F0 + #define CR_FLAGS 0 + ADC_TypeDef *adc = ADC1; + // 100: 41.5 ADC clock cycles + adc->SMPR = 4 << ADC_SMPR_SMP_Pos; +#endif +} + +// Setup and calibrate ADC on stm32g0 chips +static void +stm32g0_adc_setup(void) +{ +#if CONFIG_MACH_STM32G0 + #define CR_FLAGS ADC_CR_ADVREGEN + ADC_TypeDef *adc = ADC1; + // 101: 39.5 ADC clock cycles + adc->SMPR = 5 << ADC_SMPR_SMP1_Pos; + adc->CFGR2 = 2 << ADC_CFGR2_CKMODE_Pos; // 16Mhz + + // Enable voltage regulator + adc->CR = CR_FLAGS; + uint32_t end = timer_read_time() + timer_from_us(20); + while (timer_is_before(timer_read_time(), end)) + ; +#endif +} + struct gpio_adc gpio_adc_setup(uint32_t pin) { @@ -41,18 +79,19 @@ gpio_adc_setup(uint32_t pin) // Enable the ADC if (!is_enabled_pclock(ADC1_BASE)) { enable_pclock(ADC1_BASE); + if (CONFIG_MACH_STM32F0) + stm32f0_adc_setup(); + else if (CONFIG_MACH_STM32G0) + stm32g0_adc_setup(); + // Start calibration and wait for completion ADC_TypeDef *adc = ADC1; - // 100: 41.5 ADC clock cycles - adc->SMPR = 4 << ADC_SMPR_SMP_Pos; - - // start calibration and wait for completion - adc->CR = ADC_CR_ADCAL; + adc->CR = CR_FLAGS | ADC_CR_ADCAL; while (adc->CR & ADC_CR_ADCAL) ; - + // Enable ADC adc->ISR = ADC_ISR_ADRDY; - adc->CR = ADC_CR_ADEN; + adc->CR = CR_FLAGS | ADC_CR_ADEN; while (!(adc->ISR & ADC_ISR_ADRDY)) ; } @@ -80,7 +119,7 @@ gpio_adc_sample(struct gpio_adc g) goto need_delay; } adc->CHSELR = g.chan; - adc->CR = ADC_CR_ADSTART; + adc->CR = CR_FLAGS | ADC_CR_ADSTART; need_delay: return timer_from_us(10); @@ -102,7 +141,7 @@ gpio_adc_cancel_sample(struct gpio_adc g) irqstatus_t flag = irq_save(); if (adc->CHSELR == g.chan) { if (adc->CR & ADC_CR_ADSTART) - adc->CR = ADC_CR_ADSTP; + adc->CR = CR_FLAGS | ADC_CR_ADSTP; if (adc->ISR & ADC_ISR_EOC) gpio_adc_read(g); } |