From 1c243173809fc068681385c2a3095c04c5645705 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 19 Dec 2021 21:30:33 -0500 Subject: [PATCH] stm32: Enable ADC support on stm32g0 Signed-off-by: Kevin O'Connor --- klippy/extras/temperature_mcu.py | 6 ++++ src/stm32/Kconfig | 2 +- src/stm32/Makefile | 2 +- src/stm32/stm32f0_adc.c | 59 ++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/klippy/extras/temperature_mcu.py b/klippy/extras/temperature_mcu.py index 188ad316..9e1005a7 100644 --- a/klippy/extras/temperature_mcu.py +++ b/klippy/extras/temperature_mcu.py @@ -70,6 +70,7 @@ class PrinterTemperatureMCU: ('stm32f042', self.config_stm32f0x2), ('stm32f070', self.config_stm32f070), ('stm32f072', self.config_stm32f0x2), + ('stm32g0', self.config_stm32g0), ('', self.config_unknown)] for name, func in cfg_funcs: if self.mcu_type.startswith(name): @@ -133,6 +134,11 @@ class PrinterTemperatureMCU: self.slope = 3.3 / -.004300 cal_adc_30 = self.read16(0x1FFFF7B8) / 4095. self.base_temperature = self.calc_base(30., cal_adc_30) + def config_stm32g0(self): + cal_adc_30 = self.read16(0x1FFF75A8) * 3.0 / (3.3 * 4095.) + cal_adc_130 = self.read16(0x1FFF75CA) * 3.0 / (3.3 * 4095.) + self.slope = (130. - 30.) / (cal_adc_130 - cal_adc_30) + self.base_temperature = self.calc_base(30., cal_adc_30) def read16(self, addr): params = self.debug_read_cmd.send([1, addr]) return params['val'] 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); }