63
63
#pragma message "Power Management not implemented in H5 ADC driver. "
64
64
#endif
65
65
66
+ #ifndef ANIOC_SET_OVERSAMPLE
67
+ # define ANIOC_SET_OVERSAMPLE _ANIOC(0x0f)
68
+ #endif
69
+
66
70
/* ADC Channels/DMA *********************************************************/
67
71
68
72
#define ADC_SMPR_DEFAULT ADC_SMPR_640p5
@@ -101,6 +105,7 @@ struct stm32_dev_s
101
105
uint8_t cchannels ; /* Number of configured channels */
102
106
uint8_t intf ; /* ADC interface number */
103
107
uint8_t current ; /* Current ADC channel being converted */
108
+ uint8_t resolution ; /* ADC resolution (0-3) */
104
109
bool hasdma ; /* True: This ADC supports DMA */
105
110
#ifdef ADC_HAVE_DMA
106
111
uint16_t dmabatch ; /* Number of conversions for DMA batch */
@@ -138,6 +143,13 @@ struct stm32_dev_s
138
143
uint16_t * r_dmabuffer ;
139
144
#endif
140
145
146
+ bool oversample ;
147
+ #ifdef ADC_HAVE_OVERSAMPLE
148
+ bool trovs ;
149
+ uint8_t ovsr ;
150
+ uint8_t ovss ;
151
+ #endif
152
+
141
153
/* List of selected ADC channels to sample */
142
154
143
155
uint8_t chanlist [CONFIG_STM32H5_ADC_MAX_SAMPLES ];
@@ -190,6 +202,10 @@ static void adc_dmacfg(struct stm32_dev_s *priv,
190
202
struct stm32_gpdma_cfg_s * cfg );
191
203
#endif
192
204
205
+ #ifdef ADC_HAVE_OVERSAMPLE
206
+ static void adc_oversample (struct adc_dev_s * dev );
207
+ #endif
208
+
193
209
/* ADC Interrupt Handler */
194
210
195
211
static int adc_interrupt (struct adc_dev_s * dev , uint32_t regval );
@@ -235,6 +251,7 @@ static struct stm32_dev_s g_adcpriv1 =
235
251
.irq = STM32_IRQ_ADC1 ,
236
252
.isr = adc12_interrupt ,
237
253
.intf = 1 ,
254
+ .resolution = CONFIG_STM32H5_ADC1_RESOLUTION ,
238
255
.base = STM32_ADC1_BASE ,
239
256
.mbase = STM32_ADC1_BASE ,
240
257
.initialized = false,
@@ -259,6 +276,19 @@ static struct stm32_dev_s g_adcpriv1 =
259
276
#else
260
277
.hasdma = false,
261
278
#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
262
292
};
263
293
264
294
static struct adc_dev_s g_adcdev1 =
@@ -282,6 +312,7 @@ static struct stm32_dev_s g_adcpriv2 =
282
312
.irq = STM32_IRQ_ADC2 ,
283
313
.isr = adc12_interrupt ,
284
314
.intf = 2 ,
315
+ .resolution = CONFIG_STM32H5_ADC2_RESOLUTION ,
285
316
.base = STM32_ADC2_BASE ,
286
317
.mbase = STM32_ADC2_BASE ,
287
318
.initialized = false,
@@ -306,6 +337,19 @@ static struct stm32_dev_s g_adcpriv2 =
306
337
#else
307
338
.hasdma = false,
308
339
#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
309
353
};
310
354
311
355
static struct adc_dev_s g_adcdev2 =
@@ -776,6 +820,28 @@ static void adc_setupclock(struct stm32_dev_s *priv)
776
820
adc_modifyreg (priv , STM32_ADC_CCR_OFFSET , ADC_CCR_PRESC_MASK , setbits );
777
821
}
778
822
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
+
779
845
/****************************************************************************
780
846
* Name: adc_reset
781
847
*
@@ -965,7 +1031,7 @@ static int adc_setup(struct adc_dev_s *dev)
965
1031
/* Set the resolution of the conversion. */
966
1032
967
1033
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 ;
969
1035
970
1036
#ifdef ADC_HAVE_DMA
971
1037
if (priv -> hasdma )
@@ -1031,6 +1097,13 @@ static int adc_setup(struct adc_dev_s *dev)
1031
1097
1032
1098
adc_setupclock (priv );
1033
1099
1100
+ #ifdef ADC_HAVE_OVERSAMPLE
1101
+ if (priv -> oversample )
1102
+ {
1103
+ adc_oversample (dev );
1104
+ }
1105
+ #endif
1106
+
1034
1107
#ifdef ADC_HAVE_DMA
1035
1108
1036
1109
/* Enable DMA */
@@ -1235,6 +1308,55 @@ static int adc_set_ch(struct adc_dev_s *dev, uint8_t ch)
1235
1308
return OK ;
1236
1309
}
1237
1310
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
+
1238
1360
/****************************************************************************
1239
1361
* Name: adc_ioctl
1240
1362
*
@@ -1321,6 +1443,14 @@ static int adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
1321
1443
}
1322
1444
break ;
1323
1445
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
+
1324
1454
default :
1325
1455
aerr ("ERROR: Unknown cmd: %d\n" , cmd );
1326
1456
ret = - ENOTTY ;
0 commit comments