diff --git a/arch/arm/src/stm32/hardware/stm32_adc_v2.h b/arch/arm/src/stm32/hardware/stm32_adc_v2.h index a6398f5c0e..21cee472bf 100644 --- a/arch/arm/src/stm32/hardware/stm32_adc_v2.h +++ b/arch/arm/src/stm32/hardware/stm32_adc_v2.h @@ -686,6 +686,7 @@ # define ADC_CCR_DUAL_DUAL (1 << ADC_CCR_DUAL_SHIFT) /* Dual mode, master/slave ADCs together */ # define ADC_CCR_DUAL_SIMINJ (1 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + injected sim. */ # define ADC_CCR_DUAL_SIMALT (2 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + alternate trigger */ +# define ADC_CCR_DUAL_INTINJ (3 << ADC_CCR_DUAL_SHIFT) /* Combined interl. mode + injected sim. */ # define ADC_CCR_DUAL_INJECTED (5 << ADC_CCR_DUAL_SHIFT) /* Injected simultaneous mode only */ # define ADC_CCR_DUAL_SIM (6 << ADC_CCR_DUAL_SHIFT) /* Regular simultaneous mode only */ # define ADC_CCR_DUAL_INTERLEAVE (7 << ADC_CCR_DUAL_SHIFT) /* Interleaved mode only */ diff --git a/arch/arm/src/stm32/hardware/stm32_adc_v2g4.h b/arch/arm/src/stm32/hardware/stm32_adc_v2g4.h index e7622532a5..1036b63c0e 100644 --- a/arch/arm/src/stm32/hardware/stm32_adc_v2g4.h +++ b/arch/arm/src/stm32/hardware/stm32_adc_v2g4.h @@ -819,6 +819,7 @@ # define ADC_CCR_DUAL_DUAL (0x1 << ADC_CCR_DUAL_SHIFT) /* 00001: Dual mode, master/slave ADCs together */ # define ADC_CCR_DUAL_SIMINJ (0x1 << ADC_CCR_DUAL_SHIFT) /* 00001: Combined regular sim. + injected sim. */ # define ADC_CCR_DUAL_SIMALT (0x2 << ADC_CCR_DUAL_SHIFT) /* 00010: Combined regular sim. + alternate trigger */ +# define ADC_CCR_DUAL_INTINJ (0x3 << ADC_CCR_DUAL_SHIFT) /* 00011: Combined interl. mode + injected sim. */ # define ADC_CCR_DUAL_INJECTED (0x5 << ADC_CCR_DUAL_SHIFT) /* 00101: Injected simultaneous mode only */ # define ADC_CCR_DUAL_SIM (0x6 << ADC_CCR_DUAL_SHIFT) /* 00110: Regular simultaneous mode only */ # define ADC_CCR_DUAL_INTERLEAVE (0x7 << ADC_CCR_DUAL_SHIFT) /* 00111: Interleaved mode only */ diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index a663db6936..2f7398eef2 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -626,6 +626,8 @@ static void adc_sampletime_set(struct stm32_adc_dev_s *dev, static void adc_sampletime_write(struct stm32_adc_dev_s *dev); # endif 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); +static void adc_llops_enable(struct stm32_adc_dev_s *dev, bool enable); #endif /**************************************************************************** @@ -679,7 +681,9 @@ static const struct stm32_adc_ops_s g_adc_llops = .stime_set = adc_sampletime_set, .stime_write = adc_sampletime_write, # endif - .dump_regs = adc_llops_dumpregs + .dump_regs = adc_llops_dumpregs, + .multi_cfg = adc_llops_multicfg, + .enable = adc_llops_enable }; #endif @@ -4581,6 +4585,162 @@ static void adc_llops_dumpregs(struct stm32_adc_dev_s *dev) adc_dumpregs(priv); } +/**************************************************************************** + * Name: adc_llops_multicfg + * + * IMPORTANT: this interface is allowed only when the ADCs are disabled! + * + ****************************************************************************/ + +static int adc_llops_multicfg(struct stm32_adc_dev_s *dev, uint8_t mode) +#if defined(HAVE_IP_ADC_V2) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + int ret = OK; + uint32_t setbits = 0; + uint32_t clrbits = 0; + + switch (mode) + { + case ADC_MULTIMODE_INDEP: + setbits = ADC_CCR_DUAL_IND; + break; + + case ADC_MULTIMODE_RSISM2: + setbits = ADC_CCR_DUAL_SIMALT; + break; + + case ADC_MULTIMODE_RSATM2: + setbits = ADC_CCR_DUAL_SIMALT; + break; + + case ADC_MULTIMODE_IMIS2: + setbits = ADC_CCR_DUAL_INTINJ; + break; + + case ADC_MULTIMODE_ISM2: + setbits = ADC_CCR_DUAL_INJECTED; + break; + + case ADC_MULTIMODE_RSM2: + setbits = ADC_CCR_DUAL_SIM; + break; + + case ADC_MULTIMODE_IM2: + setbits = ADC_CCR_DUAL_INTERLEAVE; + break; + + case ADC_MULTIMODE_ATM2: + setbits = ADC_CCR_DUAL_ALT; + break; + + default: + ret = -EINVAL; + goto errout; + } + + clrbits = ADC_CCR_DUAL_MASK; + adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, clrbits, setbits); + +errout: + return ret; +} +#elif defined(HAVE_IP_ADC_V1) && !defined(HAVE_BASIC_ADC) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + int ret = OK; + uint32_t setbits = 0; + uint32_t clrbits = 0; + + switch (mode) + { + case ADC_MULTIMODE_INDEP: + setbits = ADC_CCR_MULTI_NONE; + break; + + case ADC_MULTIMODE_RSISM2: + setbits = ADC_CCR_MULTI_RSISM2; + break; + + case ADC_MULTIMODE_RSATM2: + setbits = ADC_CCR_MULTI_RSATM2; + break; + + case ADC_MULTIMODE_ISM2: + setbits = ADC_CCR_MULTI_ISM2; + break; + + case ADC_MULTIMODE_RSM2: + setbits = ADC_CCR_MULTI_ISM2; + break; + + case ADC_MULTIMODE_IM2: + setbits = ADC_CCR_MULTI_IM2; + break; + + case ADC_MULTIMODE_ATM2: + setbits = ADC_CCR_MULTI_ATM2; + break; + + case ADC_MULTIMODE_RSISM3: + setbits = ADC_CCR_MULTI_RSISM3; + break; + + case ADC_MULTIMODE_RSATM3: + setbits = ADC_CCR_MULTI_RSATM3; + break; + + case ADC_MULTIMODE_ISM3: + setbits = ADC_CCR_MULTI_ISM3; + break; + + case ADC_MULTIMODE_RSM3: + setbits = ADC_CCR_MULTI_ISM3; + break; + + case ADC_MULTIMODE_IM3: + setbits = ADC_CCR_MULTI_IM3; + break; + + case ADC_MULTIMODE_ATM3: + setbits = ADC_CCR_MULTI_ATM3; + break; + + case ADC_MULTIMODE_IMIS2: + case ADC_MULTIMODE_IMIS3: + default: + ret = -EINVAL; + goto errout; + } + + clrbits = ADC_CCR_MULTI_MASK; + adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, clrbits, setbits); + +errout: + return ret; +} +#else /* ADV IPv1 BASIC */ +{ + if (mode != ADC_MULTIMODE_INDEP) + { + return -EINVAL; + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc_llops_enable + ****************************************************************************/ + +static void adc_llops_enable(struct stm32_adc_dev_s *dev, bool enable) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + adc_enable(priv, enable); +} + #endif /* CONFIG_STM32_ADC_LL_OPS */ /**************************************************************************** diff --git a/arch/arm/src/stm32/stm32_adc.h b/arch/arm/src/stm32/stm32_adc.h index 8334ec1e29..2eb84851ed 100644 --- a/arch/arm/src/stm32/stm32_adc.h +++ b/arch/arm/src/stm32/stm32_adc.h @@ -2056,6 +2056,10 @@ (adc)->llops->setup(adc) #define STM32_ADC_SHUTDOWN(adc) \ (adc)->llops->shutdown(adc) +#define STM32_ADC_MULTICFG(adc, mode) \ + (adc)->llops->multi_cfg(adc, mode) +#define STM32_ADC_ENABLE(adc, en) \ + (adc)->llops->enable(adc, en) /**************************************************************************** * Public Types @@ -2105,6 +2109,35 @@ enum stm32_adc_resoluton_e ADC_RESOLUTION_6BIT = 3 /* 6 bit */ }; +/* ADC multi mode selection */ + +enum stm32_adc_multimode_e +{ + /* Independent mode */ + + ADC_MULTIMODE_INDEP = 0, /* Independent mode */ + + /* Dual mode */ + + ADC_MULTIMODE_RSISM2 = 1, /* Dual combined regular sim. + injected sim. */ + ADC_MULTIMODE_RSATM2 = 2, /* Dual combined regular sim. + alternate trigger */ + ADC_MULTIMODE_IMIS2 = 3, /* Dual combined interl. mode + injected sim. */ + ADC_MULTIMODE_ISM2 = 4, /* Dual injected simultaneous mode only */ + ADC_MULTIMODE_RSM2 = 5, /* Dual degular simultaneous mode only */ + ADC_MULTIMODE_IM2 = 6, /* Dual interleaved mode only */ + ADC_MULTIMODE_ATM2 = 7, /* Dual alternate trigger mode only */ + + /* Triple mode */ + + ADC_MULTIMODE_RSISM3 = 8, /* Triple combined regular sim. + injected sim. */ + ADC_MULTIMODE_RSATM3 = 9, /* Triple combined regular sim. + alternate trigger */ + ADC_MULTIMODE_IMIS3 = 10, /* Triple combined interl. mode + injected sim. */ + ADC_MULTIMODE_ISM3 = 11, /* Triple injected simultaneous mode only */ + ADC_MULTIMODE_RSM3 = 12, /* Triple degular simultaneous mode only */ + ADC_MULTIMODE_IM3 = 13, /* Triple interleaved mode only */ + ADC_MULTIMODE_ATM3 = 14, /* Triple alternate trigger mode only */ +}; + #ifdef CONFIG_STM32_ADC_LL_OPS #ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME @@ -2229,6 +2262,14 @@ struct stm32_adc_ops_s #endif void (*dump_regs)(struct stm32_adc_dev_s *dev); + + /* Configure ADC multi mode */ + + int (*multi_cfg)(struct stm32_adc_dev_s *dev, uint8_t mode); + + /* Enable/disable ADC */ + + void (*enable)(struct stm32_adc_dev_s *dev, bool enable); }; #endif /* CONFIG_STM32_ADC_LL_OPS */ diff --git a/arch/arm/src/stm32f7/stm32_adc.c b/arch/arm/src/stm32f7/stm32_adc.c index 1b55b9a0dc..0bfbef3582 100644 --- a/arch/arm/src/stm32f7/stm32_adc.c +++ b/arch/arm/src/stm32f7/stm32_adc.c @@ -376,6 +376,8 @@ static void adc_sampletime_set(struct stm32_adc_dev_s *dev, static void adc_sampletime_write(struct stm32_adc_dev_s *dev); # endif 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); +static void adc_llops_enable(struct stm32_adc_dev_s *dev, bool enable); #endif /**************************************************************************** @@ -425,7 +427,9 @@ static const struct stm32_adc_ops_s g_adc_llops = .stime_set = adc_sampletime_set, .stime_write = adc_sampletime_write, # endif - .dump_regs = adc_llops_dumpregs + .dump_regs = adc_llops_dumpregs, + .multi_cfg = adc_llops_multicfg, + .enable = adc_llops_enable }; #endif @@ -2870,6 +2874,99 @@ static void adc_llops_dumpregs(struct stm32_adc_dev_s *dev) adc_dumpregs(priv); } +/**************************************************************************** + * Name: adc_llops_multicfg + * + * IMPORTANT: this interface is allowed only when the ADCs are disabled! + * + ****************************************************************************/ + +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; + uint32_t setbits = 0; + uint32_t clrbits = 0; + + switch (mode) + { + case ADC_MULTIMODE_INDEP: + setbits = ADC_CCR_MULTI_NONE; + break; + + case ADC_MULTIMODE_RSISM2: + setbits = ADC_CCR_MULTI_RSISM2; + break; + + case ADC_MULTIMODE_RSATM2: + setbits = ADC_CCR_MULTI_RSATM2; + break; + + case ADC_MULTIMODE_ISM2: + setbits = ADC_CCR_MULTI_ISM2; + break; + + case ADC_MULTIMODE_RSM2: + setbits = ADC_CCR_MULTI_ISM2; + break; + + case ADC_MULTIMODE_IM2: + setbits = ADC_CCR_MULTI_IM2; + break; + + case ADC_MULTIMODE_ATM2: + setbits = ADC_CCR_MULTI_ATM2; + break; + + case ADC_MULTIMODE_RSISM3: + setbits = ADC_CCR_MULTI_RSISM3; + break; + + case ADC_MULTIMODE_RSATM3: + setbits = ADC_CCR_MULTI_RSATM3; + break; + + case ADC_MULTIMODE_ISM3: + setbits = ADC_CCR_MULTI_ISM3; + break; + + case ADC_MULTIMODE_RSM3: + setbits = ADC_CCR_MULTI_ISM3; + break; + + case ADC_MULTIMODE_IM3: + setbits = ADC_CCR_MULTI_IM3; + break; + + case ADC_MULTIMODE_ATM3: + setbits = ADC_CCR_MULTI_ATM3; + break; + + case ADC_MULTIMODE_IMIS2: + case ADC_MULTIMODE_IMIS3: + default: + ret = -EINVAL; + goto errout; + } + + clrbits = ADC_CCR_MULTI_MASK; + adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, clrbits, setbits); + +errout: + return ret; +} + +/**************************************************************************** + * Name: adc_llops_enable + ****************************************************************************/ + +static void adc_llops_enable(struct stm32_adc_dev_s *dev, bool enable) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + adc_enable(priv, enable); +} + #endif /* CONFIG_STM32F7_ADC_LL_OPS */ /**************************************************************************** diff --git a/arch/arm/src/stm32f7/stm32_adc.h b/arch/arm/src/stm32f7/stm32_adc.h index 6ebde261ca..c33ab8172e 100644 --- a/arch/arm/src/stm32f7/stm32_adc.h +++ b/arch/arm/src/stm32f7/stm32_adc.h @@ -853,6 +853,10 @@ (adc)->llops->setup(adc) #define STM32_ADC_SHUTDOWN(adc) \ (adc)->llops->shutdown(adc) +#define STM32_ADC_MULTICFG(adc, mode) \ + (adc)->llops->multi_cfg(adc, mode) +#define STM32_ADC_ENABLE(adc, en) \ + (adc)->llops->enable(adc, en) /**************************************************************************** * Public Types @@ -879,6 +883,35 @@ enum stm32_adc_resoluton_e ADC_RESOLUTION_6BIT = 3 /* 6 bit */ }; +/* ADC multi mode selection */ + +enum stm32_adc_multimode_e +{ + /* Independent mode */ + + ADC_MULTIMODE_INDEP = 0, /* Independent mode */ + + /* Dual mode */ + + ADC_MULTIMODE_RSISM2 = 1, /* Dual combined regular sim. + injected sim. */ + ADC_MULTIMODE_RSATM2 = 2, /* Dual combined regular sim. + alternate trigger */ + ADC_MULTIMODE_IMIS2 = 3, /* Dual combined interl. mode + injected sim. */ + ADC_MULTIMODE_ISM2 = 4, /* Dual injected simultaneous mode only */ + ADC_MULTIMODE_RSM2 = 5, /* Dual degular simultaneous mode only */ + ADC_MULTIMODE_IM2 = 6, /* Dual interleaved mode only */ + ADC_MULTIMODE_ATM2 = 7, /* Dual alternate trigger mode only */ + + /* Triple mode */ + + ADC_MULTIMODE_RSISM3 = 8, /* Triple combined regular sim. + injected sim. */ + ADC_MULTIMODE_RSATM3 = 9, /* Triple combined regular sim. + alternate trigger */ + ADC_MULTIMODE_IMIS3 = 10, /* Triple combined interl. mode + injected sim. */ + ADC_MULTIMODE_ISM3 = 11, /* Triple injected simultaneous mode only */ + ADC_MULTIMODE_RSM3 = 12, /* Triple degular simultaneous mode only */ + ADC_MULTIMODE_IM3 = 13, /* Triple interleaved mode only */ + ADC_MULTIMODE_ATM3 = 14, /* Triple alternate trigger mode only */ +}; + #ifdef CONFIG_STM32F7_ADC_LL_OPS #ifdef CONFIG_STM32F7_ADC_CHANGE_SAMPLETIME @@ -1001,6 +1034,14 @@ struct stm32_adc_ops_s #endif void (*dump_regs)(struct stm32_adc_dev_s *dev); + + /* Configure ADC multi mode */ + + int (*multi_cfg)(struct stm32_adc_dev_s *dev, uint8_t mode); + + /* Enable/disable ADC */ + + void (*enable)(struct stm32_adc_dev_s *dev, bool enable); }; #endif /* CONFIG_STM32F7_ADC_LL_OPS */