Skip to content

Commit 7abfbdd

Browse files
kywwilson11xiaoxiang781216
authored andcommitted
Add additional support for STM32H5 ADC
Put define guard around call to adc_oversample. Fixed formatting.
1 parent d3da5e6 commit 7abfbdd

File tree

3 files changed

+241
-1
lines changed

3 files changed

+241
-1
lines changed

arch/arm/src/stm32h5/Kconfig

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,14 @@ config STM32H5_ADC_MAX_SAMPLES
895895
for all supported devices, the user can change the default
896896
values in the board initialization logic and avoid ADC overrun.
897897

898+
config STM32H5_ADC1_RESOLUTION
899+
int "ADC1 resolution"
900+
depends on STM32H5_ADC1
901+
default 0
902+
range 0 3
903+
---help---
904+
ADC1 resolution. 0 - 12 bit, 1 - 10 bit, 2 - 8 bit, 3 - 6 bit
905+
898906
config STM32H5_ADC1_DMA
899907
bool "ADC1 DMA Enable"
900908
depends on STM32H5_ADC1 && STM32H5_DMA
@@ -921,6 +929,53 @@ config STM32H5_ADC1_DMA_CFG
921929
---help---
922930
0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode
923931

932+
config STM32H5_ADC1_OVERSAMPLE
933+
bool "Enable ADC1 hardware oversampling support"
934+
depends on STM32H5_ADC1
935+
default n
936+
---help---
937+
Enable the on-chip ADC oversampling/accumulation block (CFGR2.OVSE).
938+
Only STM32G0 and STM32L0 series include this hardware block.
939+
940+
if STM32H5_ADC1_OVERSAMPLE
941+
942+
config STM32H5_ADC1_TROVS
943+
bool "Enable triggered oversampling (CFGR2.TROVS)"
944+
default n
945+
---help---
946+
If set, oversampling will only occur when a trigger event occurs.
947+
If not set, oversampling occurs continuously (TOVS=0).
948+
949+
config STM32H5_ADC1_OVSR
950+
int "Oversampling ratio (CFGR2.OVSR)"
951+
default 0
952+
range 0 7
953+
---help---
954+
Sets the oversampling ratio as 2^(OVSR+1). For example:
955+
0 -> 2×
956+
1 -> 4×
957+
2 -> 8×
958+
...
959+
7 -> 256×
960+
961+
config STM32H5_ADC1_OVSS
962+
int "Oversampling right-shift bits (CFGR2.OVSS)"
963+
default 0
964+
range 0 8
965+
---help---
966+
Sets how many bits the accumulated result is right-shifted.
967+
Max of 8-bits.
968+
969+
endif # STM32H5_ADC1_OVERSAMPLE
970+
971+
config STM32H5_ADC2_RESOLUTION
972+
int "ADC2 resolution"
973+
depends on STM32H5_ADC2
974+
default 0
975+
range 0 3
976+
---help---
977+
ADC1 resolution. 0 - 12 bit, 1 - 10 bit, 2 - 8 bit, 3 - 6 bit
978+
924979
config STM32H5_ADC2_DMA
925980
bool "ADC2 DMA Enable"
926981
depends on STM32H5_ADC2 && STM32H5_DMA
@@ -948,6 +1003,45 @@ config STM32H5_ADC2_DMA_CFG
9481003
---help---
9491004
0 - ADC2 DMA in One Shot Mode, 1 - ADC2 DMA in Circular Mode
9501005

1006+
config STM32H5_ADC2_OVERSAMPLE
1007+
bool "Enable ADC2 hardware oversampling support"
1008+
depends on STM32H5_ADC2
1009+
default n
1010+
---help---
1011+
Enable the on-chip ADC oversampling/accumulation block (CFGR2.OVSE).
1012+
Only STM32G0 and STM32L0 series include this hardware block.
1013+
1014+
if STM32H5_ADC2_OVERSAMPLE
1015+
1016+
config STM32H5_ADC2_TROVS
1017+
bool "Enable triggered oversampling (CFGR2.TROVS)"
1018+
default n
1019+
---help---
1020+
If set, oversampling will only occur when a trigger event occurs.
1021+
If not set, oversampling occurs continuously (TOVS=0).
1022+
1023+
config STM32H5_ADC2_OVSR
1024+
int "Oversampling ratio (CFGR2.OVSR)"
1025+
default 0
1026+
range 0 7
1027+
---help---
1028+
Sets the oversampling ratio as 2^(OVSR+1). For example:
1029+
0 -> 2×
1030+
1 -> 4×
1031+
2 -> 8×
1032+
...
1033+
7 -> 256×
1034+
1035+
config STM32H5_ADC2_OVSS
1036+
int "Oversampling right-shift bits (CFGR2.OVSS)"
1037+
default 0
1038+
range 0 8
1039+
---help---
1040+
Sets how many bits the accumulated result is right-shifted.
1041+
Max of 8-bits.
1042+
1043+
endif # STM32H5_ADC2_OVERSAMPLE
1044+
9511045
endmenu # ADC Configuration
9521046

9531047
menu "SPI Configuration"

arch/arm/src/stm32h5/stm32_adc.c

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
#pragma message "Power Management not implemented in H5 ADC driver. "
6464
#endif
6565

66+
#ifndef ANIOC_SET_OVERSAMPLE
67+
# define ANIOC_SET_OVERSAMPLE _ANIOC(0x0f)
68+
#endif
69+
6670
/* ADC Channels/DMA *********************************************************/
6771

6872
#define ADC_SMPR_DEFAULT ADC_SMPR_640p5
@@ -101,6 +105,7 @@ struct stm32_dev_s
101105
uint8_t cchannels; /* Number of configured channels */
102106
uint8_t intf; /* ADC interface number */
103107
uint8_t current; /* Current ADC channel being converted */
108+
uint8_t resolution; /* ADC resolution (0-3) */
104109
bool hasdma; /* True: This ADC supports DMA */
105110
#ifdef ADC_HAVE_DMA
106111
uint16_t dmabatch; /* Number of conversions for DMA batch */
@@ -138,6 +143,13 @@ struct stm32_dev_s
138143
uint16_t *r_dmabuffer;
139144
#endif
140145

146+
bool oversample;
147+
#ifdef ADC_HAVE_OVERSAMPLE
148+
bool trovs;
149+
uint8_t ovsr;
150+
uint8_t ovss;
151+
#endif
152+
141153
/* List of selected ADC channels to sample */
142154

143155
uint8_t chanlist[CONFIG_STM32H5_ADC_MAX_SAMPLES];
@@ -190,6 +202,10 @@ static void adc_dmacfg(struct stm32_dev_s *priv,
190202
struct stm32_gpdma_cfg_s *cfg);
191203
#endif
192204

205+
#ifdef ADC_HAVE_OVERSAMPLE
206+
static void adc_oversample(struct adc_dev_s *dev);
207+
#endif
208+
193209
/* ADC Interrupt Handler */
194210

195211
static int adc_interrupt(struct adc_dev_s *dev, uint32_t regval);
@@ -235,6 +251,7 @@ static struct stm32_dev_s g_adcpriv1 =
235251
.irq = STM32_IRQ_ADC1,
236252
.isr = adc12_interrupt,
237253
.intf = 1,
254+
.resolution = CONFIG_STM32H5_ADC1_RESOLUTION,
238255
.base = STM32_ADC1_BASE,
239256
.mbase = STM32_ADC1_BASE,
240257
.initialized = false,
@@ -259,6 +276,19 @@ static struct stm32_dev_s g_adcpriv1 =
259276
#else
260277
.hasdma = false,
261278
#endif
279+
280+
#ifdef ADC1_HAVE_OVERSAMPLE
281+
.oversample = true,
282+
# ifdef CONFIG_STM32H5_ADC1_TROVS
283+
.trovs = true,
284+
# else
285+
.trovs = false,
286+
# endif
287+
.ovsr = CONFIG_STM32H5_ADC1_OVSR,
288+
.ovss = CONFIG_STM32H5_ADC1_OVSS,
289+
#else
290+
.oversample = false,
291+
#endif
262292
};
263293

264294
static struct adc_dev_s g_adcdev1 =
@@ -282,6 +312,7 @@ static struct stm32_dev_s g_adcpriv2 =
282312
.irq = STM32_IRQ_ADC2,
283313
.isr = adc12_interrupt,
284314
.intf = 2,
315+
.resolution = CONFIG_STM32H5_ADC2_RESOLUTION,
285316
.base = STM32_ADC2_BASE,
286317
.mbase = STM32_ADC2_BASE,
287318
.initialized = false,
@@ -306,6 +337,19 @@ static struct stm32_dev_s g_adcpriv2 =
306337
#else
307338
.hasdma = false,
308339
#endif
340+
341+
#ifdef ADC2_HAVE_OVERSAMPLE
342+
.oversample = true,
343+
# ifdef CONFIG_STM32H5_ADC2_TROVS
344+
.trovs = true,
345+
# else
346+
.trovs = false,
347+
# endif
348+
.ovsr = CONFIG_STM32H5_ADC2_OVSR,
349+
.ovss = CONFIG_STM32H5_ADC2_OVSS,
350+
#else
351+
.oversample = false,
352+
#endif
309353
};
310354

311355
static struct adc_dev_s g_adcdev2 =
@@ -776,6 +820,28 @@ static void adc_setupclock(struct stm32_dev_s *priv)
776820
adc_modifyreg(priv, STM32_ADC_CCR_OFFSET, ADC_CCR_PRESC_MASK, setbits);
777821
}
778822

823+
#ifdef ADC_HAVE_OVERSAMPLE
824+
/****************************************************************************
825+
* Name: adc_oversample
826+
****************************************************************************/
827+
828+
static void adc_oversample(struct adc_dev_s *dev)
829+
{
830+
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev->ad_priv;
831+
832+
uint32_t clrbits = ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS |
833+
ADC_CFGR2_OVSR_MASK | ADC_CFGR2_OVSS_MASK;
834+
835+
uint32_t setbits = ADC_CFGR2_ROVSE |
836+
(priv->ovsr << ADC_CFGR2_OVSR_SHIFT) |
837+
(priv->ovss << ADC_CFGR2_OVSS_SHIFT);
838+
839+
setbits |= priv->trovs;
840+
841+
adc_modifyreg(priv, STM32_ADC_CFGR2_OFFSET, clrbits, setbits);
842+
}
843+
#endif
844+
779845
/****************************************************************************
780846
* Name: adc_reset
781847
*
@@ -965,7 +1031,7 @@ static int adc_setup(struct adc_dev_s *dev)
9651031
/* Set the resolution of the conversion. */
9661032

9671033
clrbits = ADC_CFGR_RES_MASK | ADC_CFGR_DMACFG | ADC_CFGR_DMAEN;
968-
setbits = ADC_CFGR_RES_12BIT;
1034+
setbits = (priv->resolution << ADC_CFGR_RES_SHIFT) & ADC_CFGR_RES_MASK;
9691035

9701036
#ifdef ADC_HAVE_DMA
9711037
if (priv->hasdma)
@@ -1031,6 +1097,13 @@ static int adc_setup(struct adc_dev_s *dev)
10311097

10321098
adc_setupclock(priv);
10331099

1100+
#ifdef ADC_HAVE_OVERSAMPLE
1101+
if (priv->oversample)
1102+
{
1103+
adc_oversample(dev);
1104+
}
1105+
#endif
1106+
10341107
#ifdef ADC_HAVE_DMA
10351108

10361109
/* Enable DMA */
@@ -1235,6 +1308,55 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch)
12351308
return OK;
12361309
}
12371310

1311+
#ifdef ADC_HAVE_OVERSAMPLE
1312+
/****************************************************************************
1313+
* Name: adc_ioc_set_oversample
1314+
*
1315+
* Description:
1316+
* For STM32G0 and STM32L0: Configure hardware oversampling via CFGR2.
1317+
*
1318+
* Input:
1319+
* dev - pointer to the ADC device
1320+
* arg - Packed 32-bit value that matches CFGR2 layout for OVSE, TOVS,
1321+
* OVSR[2:0] and OVSS[3:0].
1322+
*
1323+
* Bit fields (match ADC_CFGR2 register layout):
1324+
* [0] = OVSE (enable oversampling)
1325+
* [1] = TOVS (triggered oversampling)
1326+
* [4:2] = OVSR (ratio: 000=2x, ..., 111=256x)
1327+
* [9:5] = OVSS (right shift: 00000=no shift, ..., 11111=31-bit)
1328+
*
1329+
* Returned Value:
1330+
* OK (0) on success
1331+
*
1332+
****************************************************************************/
1333+
1334+
static int adc_ioc_set_oversample(struct adc_dev_s *dev, uint32_t arg)
1335+
{
1336+
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev->ad_priv;
1337+
uint32_t clrbits;
1338+
uint32_t setbits;
1339+
1340+
/* Mask out the oversampling-related fields from CFGR2:
1341+
* OVSE | TOVS | OVSR[2:0] | OVSS[3:0]
1342+
*/
1343+
1344+
clrbits = ADC_CFGR2_ROVSE |
1345+
ADC_CFGR2_TROVS |
1346+
ADC_CFGR2_OVSR_MASK |
1347+
ADC_CFGR2_OVSS_MASK;
1348+
1349+
setbits = arg & (ADC_CFGR2_ROVSE |
1350+
ADC_CFGR2_TROVS |
1351+
ADC_CFGR2_OVSR_MASK |
1352+
ADC_CFGR2_OVSS_MASK);
1353+
1354+
adc_modifyreg(priv, STM32_ADC_CFGR2_OFFSET, clrbits, setbits);
1355+
return OK;
1356+
}
1357+
1358+
#endif
1359+
12381360
/****************************************************************************
12391361
* Name: adc_ioctl
12401362
*
@@ -1321,6 +1443,14 @@ static int adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
13211443
}
13221444
break;
13231445

1446+
#ifdef ADC_HAVE_OVERSAMPLE
1447+
case ANIOC_SET_OVERSAMPLE:
1448+
{
1449+
ret = adc_ioc_set_oversample(dev, arg);
1450+
break;
1451+
}
1452+
#endif
1453+
13241454
default:
13251455
aerr("ERROR: Unknown cmd: %d\n", cmd);
13261456
ret = -ENOTTY;

arch/arm/src/stm32h5/stm32_adc.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@
9797
# define ADC2_HAVE_DMA 1
9898
#endif
9999

100+
/* Oversampling support */
101+
102+
#undef ADC_HAVE_OVERSAMPLE
103+
#if defined(CONFIG_STM32H5_ADC1_OVERSAMPLE) || \
104+
defined(CONFIG_STM32H5_ADC2_OVERSAMPLE)
105+
# define ADC_HAVE_OVERSAMPLE 1
106+
#endif
107+
108+
#if defined(CONFIG_STM32H5_ADC1_OVERSAMPLE)
109+
# define ADC1_HAVE_OVERSAMPLE 1
110+
#endif
111+
112+
#if defined(CONFIG_STM32H5_ADC2_OVERSAMPLE)
113+
# define ADC2_HAVE_OVERSAMPLE 1
114+
#endif
115+
100116
/* Timer configuration: If a timer trigger is specified, then get
101117
* information about the timer.
102118
*/

0 commit comments

Comments
 (0)