diff --git a/arch/arm/src/common/stm32/hardware/stm32_adc_v2.h b/arch/arm/src/common/stm32/hardware/stm32_adc_v2.h index e8629afef8024..364035d7e6f3b 100644 --- a/arch/arm/src/common/stm32/hardware/stm32_adc_v2.h +++ b/arch/arm/src/common/stm32/hardware/stm32_adc_v2.h @@ -637,14 +637,13 @@ /* ADC analog watchdog 3 configuration register */ -#define ADC_AWD3CR_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 2 channel selection */ +#define ADC_AWD3CR_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 3 channel selection */ #define ADC_AWD3CR_CH_MASK (0x3ffff << ADC_AWD3CR_CH_SHIFT) # define ADC_AWD3CR_CH(n) (1 << (n)) /* Channel n=1..18 */ -/* ADC differential mode selection register 2 */ -#define ADC_DIFSEL_ +/* ADC differential mode selection register */ -#define ADC_DIFSEL_CH_SHIFT (1) /* Bits 1-18: Analog watchdog 2 channel selection */ +#define ADC_DIFSEL_CH_SHIFT (1) /* Bits 1-18: Differential mode selection */ #define ADC_DIFSEL_CH_MASK (0x3ffff << ADC_DIFSEL_CH_SHIFT) # define ADC_DIFSEL_CH(n) (1 << (n)) /* Channel n=1..18 */ diff --git a/arch/arm/src/common/stm32/hardware/stm32_adc_v2g4.h b/arch/arm/src/common/stm32/hardware/stm32_adc_v2g4.h index 314244086db37..96c8d7f7951af 100644 --- a/arch/arm/src/common/stm32/hardware/stm32_adc_v2g4.h +++ b/arch/arm/src/common/stm32/hardware/stm32_adc_v2g4.h @@ -766,13 +766,13 @@ /* ADC analog watchdog 3 configuration register (AWD3CR) */ -#define ADC_AWD3CR_CH_SHIFT (0) /* Bits 0-18: Analog watchdog 2 channel selection */ +#define ADC_AWD3CR_CH_SHIFT (0) /* Bits 0-18: Analog watchdog 3 channel selection */ #define ADC_AWD3CR_CH_MASK (0x7ffff << ADC_AWD3CR_CH_SHIFT) # define ADC_AWD3CR_CH(n) (1 << (n)) /* Channel n=0..18 */ /* ADC differential mode selection register (DIFSEL) */ -#define ADC_DIFSEL_CH_SHIFT (0) /* Bits 0-18: Analog watchdog 2 channel selection */ +#define ADC_DIFSEL_CH_SHIFT (0) /* Bits 0-18: Differential mode selection */ #define ADC_DIFSEL_CH_MASK (0x7ffff << ADC_DIFSEL_CH_SHIFT) # define ADC_DIFSEL_CH(n) (1 << (n)) /* Channel n=0..18 */ diff --git a/arch/arm/src/common/stm32/stm32_adc_m3m4_v1v2.c b/arch/arm/src/common/stm32/stm32_adc_m3m4_v1v2.c index b53e2b6a07166..f65aa02f9ae0a 100644 --- a/arch/arm/src/common/stm32/stm32_adc_m3m4_v1v2.c +++ b/arch/arm/src/common/stm32/stm32_adc_m3m4_v1v2.c @@ -371,6 +371,14 @@ #define ANIOC_TRIGGER_REGULAR (1 << 0) #define ANIOC_TRIGGER_INJECTED (1 << 1) +/* ADC differential mode selection configuration */ + +#ifdef HAVE_IP_ADC_V2 +# define ADC_DIFSEL_DEFAULT 0 +# define ADC_DIFSEL_ALL_SINGLE 0x0 +# define ADC_DIFSEL_ALL_DIFF 0x7ffff +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -447,6 +455,9 @@ struct stm32_dev_s #ifdef ADC_HAVE_JEXTCFG uint32_t jextcfg; /* External event configuration for injected group */ #endif +#ifdef HAVE_IP_ADC_V2 + uint32_t difsel; /* ADCx_DIFSEL (Differential Mode) value */ +#endif #ifdef ADC_HAVE_TIMER uint32_t tbase; /* Base address of timer used by this ADC block */ uint32_t pclck; /* The PCLK frequency that drives this timer */ @@ -596,7 +607,6 @@ static int adc_extcfg_set(struct stm32_dev_s *priv, uint32_t extcfg); #ifdef ADC_HAVE_JEXTCFG static int adc_jextcfg_set(struct stm32_dev_s *priv, uint32_t jextcfg); #endif - static void adc_dumpregs(struct stm32_dev_s *priv); #ifdef CONFIG_STM32_ADC_LL_OPS @@ -787,6 +797,13 @@ static struct stm32_dev_s g_adcpriv1 = #ifdef ADC1_HAVE_JEXTCFG .jextcfg = ADC1_JEXTCFG_VALUE, #endif +#ifdef HAVE_IP_ADC_V2 +# ifdef BOARD_ADC1_DIFSEL + .difsel = BOARD_ADC1_DIFSEL, +# else + .difsel = ADC_DIFSEL_DEFAULT, +# endif +#endif #ifdef ADC1_HAVE_TIMER .trigger = CONFIG_STM32_ADC1_TIMTRIG, .tbase = ADC1_TIMER_BASE, @@ -855,6 +872,13 @@ static struct stm32_dev_s g_adcpriv2 = #ifdef ADC2_HAVE_JEXTCFG .jextcfg = ADC2_JEXTCFG_VALUE, #endif +#ifdef HAVE_IP_ADC_V2 +# ifdef BOARD_ADC2_DIFSEL + .difsel = BOARD_ADC2_DIFSEL, +# else + .difsel = ADC_DIFSEL_DEFAULT, +# endif +#endif #ifdef ADC2_HAVE_TIMER .trigger = CONFIG_STM32_ADC2_TIMTRIG, .tbase = ADC2_TIMER_BASE, @@ -923,6 +947,13 @@ static struct stm32_dev_s g_adcpriv3 = #ifdef ADC3_HAVE_JEXTCFG .jextcfg = ADC3_JEXTCFG_VALUE, #endif +#ifdef HAVE_IP_ADC_V2 +# ifdef BOARD_ADC3_DIFSEL + .difsel = BOARD_ADC3_DIFSEL, +# else + .difsel = ADC_DIFSEL_DEFAULT, +# endif +#endif #ifdef ADC3_HAVE_TIMER .trigger = CONFIG_STM32_ADC3_TIMTRIG, .tbase = ADC3_TIMER_BASE, @@ -984,6 +1015,13 @@ static struct stm32_dev_s g_adcpriv4 = #ifdef ADC4_HAVE_JEXTCFG .jextcfg = ADC4_JEXTCFG_VALUE, #endif +#ifdef HAVE_IP_ADC_V2 +# ifdef BOARD_ADC4_DIFSEL + .difsel = BOARD_ADC4_DIFSEL, +# else + .difsel = ADC_DIFSEL_DEFAULT, +# endif +#endif #ifdef ADC4_HAVE_TIMER .trigger = CONFIG_STM32_ADC4_TIMTRIG, .tbase = ADC4_TIMER_BASE, @@ -1255,6 +1293,7 @@ static void tim_modifyreg32(struct stm32_dev_s *priv, int offset, uint32_t clrbits, uint32_t setbits) { uint32_t addr = priv->tbase + offset; + putreg32((getreg32(addr) & ~clrbits) | setbits, addr); } #endif @@ -2387,18 +2426,29 @@ static void adc_watchdog_cfg(struct stm32_dev_s *priv) #if defined(HAVE_IP_ADC_V2) static void adc_calibrate(struct stm32_dev_s *priv) { -#if 0 /* Doesn't work */ - /* Calibrate the ADC */ + /* Calibrate single-ended channels if necessary */ - adc_modifyreg(priv, STM32_ADC_CR_OFFSET, ADC_CR_ADCALDIF, AD_CR_ADCAL); + if (priv->difsel != ADC_DIFSEL_ALL_DIFF) + { + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, ADC_CR_ADCALDIF, 0); + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, 0, ADC_CR_ADCAL); - /* Wait for the calibration to complete */ + /* Wait for the single-ended calibration to complete */ - while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADCAL) != 0); + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADCAL) != 0); + } -#else - UNUSED(priv); -#endif + /* Calibrate differential channels if necessary */ + + if (priv->difsel != ADC_DIFSEL_ALL_SINGLE) + { + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, 0, ADC_CR_ADCALDIF); + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, 0, ADC_CR_ADCAL); + + /* Wait for the differential calibration to complete */ + + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_ADCAL) != 0); + } } #elif defined(HAVE_IP_ADC_V1) && defined(HAVE_BASIC_ADC) static void adc_calibrate(struct stm32_dev_s *priv) @@ -2746,7 +2796,7 @@ static void adc_configure(struct adc_dev_s *dev) adc_voltreg_cfg(priv); - /* Calibrate ADC - doesn't work for now */ + /* Calibrate ADC */ adc_calibrate(priv); @@ -2809,6 +2859,12 @@ static void adc_configure(struct adc_dev_s *dev) adc_extcfg_set(priv, priv->extcfg); #endif +#ifdef HAVE_IP_ADC_V2 + /* Configure differential mode */ + + adc_putreg(priv, STM32_ADC_DIFSEL_OFFSET, priv->difsel); +#endif + /* Enable ADC */ adc_enable(priv, true); @@ -2922,8 +2978,8 @@ static void adc_reset(struct adc_dev_s *dev) #ifdef HAVE_HSI_CONTROL static void adc_reset_hsi_disable(struct adc_dev_s *dev) { - adc_reset(dev); - adc_shutdown(dev); + adc_reset(dev); + adc_shutdown(dev); } #endif @@ -4656,8 +4712,8 @@ static void adc_llops_dumpregs(struct stm32_adc_dev_s *dev) * ****************************************************************************/ -static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) #if defined(HAVE_IP_ADC_V2) +static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; int ret = OK; @@ -4710,6 +4766,7 @@ static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) return ret; } #elif defined(HAVE_IP_ADC_V1) && !defined(HAVE_BASIC_ADC) +static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) { struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; int ret = OK; @@ -4784,6 +4841,7 @@ static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) return ret; } #else /* ADV IPv1 BASIC */ +static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) { if (mode != ADC_MULTIMODE_INDEP) {