ADC Hardware register file updated for G0

First commit of ADC for G0. Have it working basically. Need to make changes regarding adccmn stuff.

Added changes to make stm32_adc.c compatible with both G0 and other families.

Add oversampling support. This is for G0 and L0. Add ADC oversampling to Kconfig. Use adccmn_modifyreg for all, updated hw file to accomodate G0.

Style fixes. Move init of oversampling to a function, and call it if OVERSAMPLE is configured.

Limited changes to stm32_bringup.c

Style fixes to hardware/stm32_adc.h

Changed nucleo-g0b1re to run at 64 MHz. Fixed errors in clock setup. Added defines for setting up ADC clock.

Added code for STM32G0 ADC clock configuration.

Added adc_ckmode_cfg function. ckmode bits were previously neglected, assuming async clock to ADC was used. Added other feedback from pull request #16500.

Added feedback from pull request #16500.

Changed format of STM32F0L0G0_HAVE_ADC_OVERSAMPLE config.

Removed FARs from ioc_set_oversample.

Fixed formatting of helps in Kconfig. Adjusted spacing on help content.

Simplified adc_common_cfg. CCR_PRESC relies on board.h

Fixed formatting

Add ADC pinmaps for stm32g0
This commit is contained in:
Tyler Bennett
2025-06-06 09:35:15 -05:00
committed by Xiang Xiao
parent 99bd3d0f73
commit 54b7bf6e36
13 changed files with 535 additions and 36 deletions

View File

@@ -1512,6 +1512,10 @@ config STM32F0L0G0_HAVE_ADC1_DMA
bool
default n
config STM32F0L0G0_HAVE_ADC_OVERSAMPLE
bool
default STM32F0L0G0_STM32L0 || STM32F0L0G0_STM32G0 || STM32F0L0G0_STM32C0
config STM32F0L0G0_HAVE_CEC
bool
default n
@@ -3419,6 +3423,45 @@ config STM32F0L0G0_ADC1_DMA_CFG
---help---
0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode
config STM32F0L0G0_ADC_OVERSAMPLE
bool "Enable ADC hardware oversampling support"
depends on STM32F0L0G0_ADC1 && STM32F0L0G0_HAVE_ADC_OVERSAMPLE
default n
---help---
Enable the on-chip ADC oversampling/accumulation block (CFGR2.OVSE).
Only STM32G0 and STM32L0 series include this hardware block.
if STM32F0L0G0_ADC_OVERSAMPLE
config STM32F0L0G0_ADC_TOVS
bool "Enable triggered oversampling (CFGR2.TOVS)"
default n
---help---
If set, oversampling will only occur when a trigger event occurs.
If not set, oversampling occurs continuously (TOVS=0).
config STM32F0L0G0_ADC_OVSR
int "Oversampling ratio (CFGR2.OVSR)"
default 0
range 0 7
---help---
Sets the oversampling ratio as 2^(OVSR+1). For example:
0 → 2×
1 → 4×
2 → 8×
...
7 → 256×
config STM32F0L0G0_ADC_OVSS
int "Oversampling right-shift bits (CFGR2.OVSS)"
default 0
range 0 8
---help---
Sets how many bits the accumulated result is right-shifted.
Max of 8-bits.
endif # STM32F0L0G0_ADC_OVERSAMPLE
config STM32F0L0G0_ADC1_DMA_BATCH
int "ADC1 DMA number of conversions"
depends on STM32F0L0G0_ADC1 && STM32F0L0G0_ADC1_DMA

View File

@@ -92,12 +92,17 @@
#define STM32_ADC_CFGR2_OFFSET 0x0010 /* ADC configuration register 2 */
#define STM32_ADC_SMPR_OFFSET 0x0014 /* ADC sample time register */
#define STM32_ADC_TR_OFFSET 0x0020 /* ADC watchdog threshold register */
#define STM32_ADC_AWD2TR_OFFSET 0x0024 /* ADC watchdog 2 threshold register */
#define STM32_ADC_CHSELR_OFFSET 0x0028 /* ADC channel selection register */
#define STM32_ADC_AWD3TR_OFFSET 0x002c /* ADC watchdog 3 threshold register */
#define STM32_ADC_DR_OFFSET 0x0040 /* ADC regular data register */
#define STM32_ADC_AWD2CR_OFFSET 0x00a0 /* ADC watchdog 2 control register */
#define STM32_ADC_AWD3CR_OFFSET 0x00a4 /* ADC watchdog 2 control register */
#define STM32_ADC_CALFACT_OFFSET 0x00b4 /* ADC Calibration factor register */
/* Master and Slave ADC Common Registers */
#define STM32_ADC_CCR_OFFSET 0x0008 /* Common control register */
#define STM32_ADC_CCR_OFFSET 0x0008 /* Common control register */
/* Register Addresses *******************************************************/
@@ -108,9 +113,16 @@
#define STM32_ADC1_CFGR2 (STM32_ADC1_BASE + STM32_ADC_CFGR2_OFFSET)
#define STM32_ADC1_SMPR (STM32_ADC1_BASE + STM32_ADC_SMPR_OFFSET)
#define STM32_ADC1_TR (STM32_ADC1_BASE + STM32_ADC_TR_OFFSET)
#define STM32_ADC1_AWD2TR (STM32_ADC1_BASE + STM32_ADC_AWD2TR_OFFSET)
#define STM32_ADC1_CHSELR (STM32_ADC1_BASE + STM32_ADC_CHSELR_OFFSET)
#define STM32_ADC1_AWD3TR (STM32_ADC1_BASE + STM32_ADC_AWD3TR_OFFSET)
#define STM32_ADC1_DR (STM32_ADC1_BASE + STM32_ADC_DR_OFFSET)
#define STM32_ADC1_CCR (STM32_ADC1_BASE + STM32_ADC_CCR_OFFSET)
#define STM32_ADC1_AWD2CR (STM32_ADC1_BASE + STM32_ADC_AWD2CR_OFFSET)
#define STM32_ADC1_AWD3CR (STM32_ADC1_BASE + STM32_ADC_AWD3CR_OFFSET)
#define STM32_ADC1_CALFACT (STM32_ADC1_BASE + STM32_ADC_CALFACT_OFFSET)
#if defined(CONFIG_ARCH_CHIP_STM32G0)
# define STM32_ADC1_CCR (STM32_ADC1_BASE + STM32_ADC_CCR_OFFSET)
#endif
/* Register Bitfield Definitions ********************************************/
@@ -124,6 +136,8 @@
#define ADC_INT_EOS (1 << 3) /* Bit 3: End of regular sequence flag */
#define ADC_INT_OVR (1 << 4) /* Bit 4: Overrun */
#define ADC_INT_AWD (1 << 7) /* Bit 7: Analog watchdog flag */
#define ADC_INT_EOCAL (1 << 11) /* Bit 11: End of calibration flag */
#define ADC_INT_CCRDY (1 << 13) /* Bit 13: Channel configuration ready flag*/
/* ADC control register */
@@ -169,6 +183,7 @@
#define ADC_CFGR1_WAIT (1 << 14) /* Bit 14: Wait conversion mode */
#define ADC_CFGR1_AUTOFF (1 << 15) /* Bit 15: Auto-off mode */
#define ADC_CFGR1_DISCEN (1 << 16) /* Bit 16: Discontinuous mode on regular channels */
#define ADC_CFGR1_CHSELRMOD (1 << 21) /* Bit 21: Mode selection of ADC_CHSELR register */
#define ADC_CFGR1_AWDSGL (1 << 22) /* Bit 22: Enable watchdog on single/all channels */
#define ADC_CFGR1_AWDEN (1 << 23) /* Bit 23: Analog watchdog enable */
#define ADC_CFGR1_AWDCH_SHIFT (26) /* Bits 26-30: Analog watchdog 1 channel select bits */
@@ -177,6 +192,24 @@
/* ADC configuration register 2 */
#define ADC_CFGR2_OVSE (1 << 0) /* Bit 1: Oversampler enable */
#define ADC_CFGR2_OVSR_SHIFT (2) /* Bits 2-4: Oversampling ratio */
#define ADC_CFGR2_OVSR_MASK (7 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_2X (0 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_4X (1 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_8X (2 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_16X (3 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_32X (4 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_64X (5 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_128X (6 << ADC_CFGR2_OVSR_SHIFT)
# define ADC_CFGR2_OVSR_256X (7 << ADC_CFGR2_OVSR_SHIFT)
#define ADC_CFGR2_OVSS_SHIFT (5) /* Bits 5-8: Oversampling shift */
#define ADC_CFGR2_OVSS_MASK (0xf << ADC_CFGR2_OVSS_SHIFT)
#define ADC_CFGR2_OVSS(sb) ((sb) << ADC_CFGR2_OVSS_SHIFT) /* Shift sb bits */
# define ADC_CFGR2_OVSS_NONE (0 << ADC_CFGR2_OVSS_SHIFT)
#define ADC_CFGR2_TOVS (1 << 9) /* Bit 9: Triggered oversampling */
/* Bits 10-28: Reserved */
#define ADC_CFGR2_LFTRIG (1 << 29) /* Bit 29: Low frequency trigger mode enable */
#define ADC_CFGR2_CKMODE_SHIFT (30) /* Bits 30-31: ADC clock mode */
#define ADC_CFGR2_CKMODE_MASK (3 << ADC_CFGR2_CKMODE_SHIFT)
# define ADC_CFGR2_CKMODE_ADCCLK (0 << ADC_CFGR2_CKMODE_SHIFT) /* 00: ADCCLK (Asynchronous) generated at product level */
@@ -185,7 +218,7 @@
/* ADC sample time register */
#ifdef CONFIG_ARCH_CHIP_STM32C0
#if defined(CONFIG_ARCH_CHIP_STM32C0) || defined(CONFIG_ARCH_CHIP_STM32G0)
# define ADC_SMPR_1p5 (0) /* 000: 1.5 cycles */
# define ADC_SMPR_3p5 (1) /* 001: 3.5 cycles */
# define ADC_SMPR_7p5 (2) /* 010: 7.5 cycles */
@@ -210,7 +243,11 @@
#define ADC_SMPR_SMP2_SHIFT (4) /* Bits 4-6: Sampling time selection 2 */
#define ADC_SMPR_SMP2_MASK (7 << ADC_SMPR_SMP_SHIFT)
#define ADC_SMPR_SMPSEL_SHIFT (8) /* Bits 8-26: channel-x sampling time selection */
#define ADC_SMPR_SMPSEL(ch, smp) (smp << ADC_SMPR_SMPSEL_SHIFT)
#if defined(CONFIG_ARCH_CHIP_STM32G0)
# define ADC_SMPR_SMPSEL(ch, smp) ((smp) << (ADC_SMPR_SMPSEL_SHIFT + ch)) /* ch = [0..18] and smp = 1 or 0 */
#else
# define ADC_SMPR_SMPSEL(ch, smp) (smp << ADC_SMPR_SMPSEL_SHIFT)
#endif
/* ADC watchdog threshold register */
@@ -240,27 +277,49 @@
#define ADC_CHSELR_CHSEL16 (1 << 16) /* Select channel 16 */
#define ADC_CHSELR_CHSEL17 (1 << 17) /* Select channel 17 */
#define ADC_CHSELR_CHSEL18 (1 << 18) /* Select channel 18 */
#define ADC_CHSELR_CHSEL(ch) (1 << ch)
#define ADC_CHSELR_CHSEL(ch) (1 << (ch))
/* ADC channel selection alternate register
* Enabled when CHSELRMOD = 1 in ADC_CFGR1
*/
#if defined(CONFIG_ARCH_CHIP_STM32G0)
# define ADC_CHSELR_ALT_SQN(sqn, ch) ((ch) << (((sqn) - 1) * 4)) /* sqn = [0..8], ch = [0..14] */
#endif
#define ADC_DR_RDATA_SHIFT (0)
#define ADC_DR_RDATA_MASK (0xffff << ADC_DR_RDATA_SHIFT)
/* Analog watchdog 2/3 configuration register */
#define ADC_AWDXCR_AWDXCHN(ch) (1 << (ch)) /* ch = [0..18] */
/* Calibration factor register */
#define ADC_CALFACT_CALFACT_SHIFT (0)
#define ADC_CALFACT_CALFACT_MASK (0x7f << ADC_CALFACT_CALFACT_SHIFT)
/* Common configuration register */
#ifdef HAVE_ADC_VLCD
# define ADC_CCR_PRESC_SHIFT (18) /* ADC Prescaler */
# define ADC_CCR_PRESC_MASK (0xf << ADC_CCR_PRESC_SHIFT)
#endif
#define ADC_CCR_PRESC_SHIFT (18) /* ADC Prescaler */
#define ADC_CCR_PRESC_MASK (0xf << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_NOT_DIV (0)
# define ADC_CCR_PRESC_DIV2 (1 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV4 (2 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV6 (3 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV8 (4 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV10 (5 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV12 (6 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV16 (7 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV32 (8 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV64 (9 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV128 (10 << ADC_CCR_PRESC_SHIFT)
# define ADC_CCR_PRESC_DIV256 (11 << ADC_CCR_PRESC_SHIFT)
#define ADC_CCR_VREFEN (1 << 22) /* Bit 22: VREFINT enable */
#define ADC_CCR_TSEN (1 << 23) /* Bit 23: Temperature sensor enable */
#ifdef HAVE_ADC_VBAT
# define ADC_CCR_VBATEN (1 << 24) /* Bit 24: VBAT enable */
#endif
#ifdef HAVE_ADC_VLCD
# define ADC_CCR_VLCDEN (1 << 24) /* Bit 24: VLCD enable */
#endif
#ifdef HAVE_ADC_LFM
# define ADC_CCR_LFMEN (1 << 25) /* Bit 25: Low Frequency Mode enable */
#endif
#define ADC_CCR_VBATEN (1 << 24) /* Bit 24: VBAT enable */
#define ADC_CCR_VLCDEN (1 << 24) /* Bit 24: VLCD enable */
#define ADC_CCR_LFMEN (1 << 25) /* Bit 25: Low Frequency Mode enable */
#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32_ADC_H */

View File

@@ -70,7 +70,29 @@
* defined for most pins in this file.
*/
/* TODO: ADC */
/* ADC */
#define GPIO_ADC1_IN0_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0)
#define GPIO_ADC1_IN1_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN1)
#define GPIO_ADC1_IN2_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN2)
#define GPIO_ADC1_IN3_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN3)
#define GPIO_ADC1_IN4_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4)
#define GPIO_ADC1_IN5_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5)
#define GPIO_ADC1_IN6_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN6)
#define GPIO_ADC1_IN7_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN7)
#define GPIO_ADC1_IN8_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN0)
#define GPIO_ADC1_IN9_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN1)
#define GPIO_ADC1_IN10_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN2)
#define GPIO_ADC1_IN11_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN10)
#define GPIO_ADC1_IN11_2 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN7)
#define GPIO_ADC1_IN15_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN11)
#define GPIO_ADC1_IN15_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN11)
#define GPIO_ADC1_IN16_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN12)
#define GPIO_ADC1_IN16_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN12)
#define GPIO_ADC1_IN17_1 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN4)
#define GPIO_ADC1_IN17_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN13)
#define GPIO_ADC1_IN18_1 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN5)
#define GPIO_ADC1_IN18_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN14)
/* TODO: DAC */

View File

@@ -70,7 +70,29 @@
* defined for most pins in this file.
*/
/* TODO: ADC */
/* ADC */
#define GPIO_ADC1_IN0_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0)
#define GPIO_ADC1_IN1_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN1)
#define GPIO_ADC1_IN2_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN2)
#define GPIO_ADC1_IN3_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN3)
#define GPIO_ADC1_IN4_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4)
#define GPIO_ADC1_IN5_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5)
#define GPIO_ADC1_IN6_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN6)
#define GPIO_ADC1_IN7_1 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN7)
#define GPIO_ADC1_IN8_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN0)
#define GPIO_ADC1_IN9_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN1)
#define GPIO_ADC1_IN10_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN2)
#define GPIO_ADC1_IN11_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN10)
#define GPIO_ADC1_IN11_2 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN7)
#define GPIO_ADC1_IN15_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN11)
#define GPIO_ADC1_IN15_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN11)
#define GPIO_ADC1_IN16_1 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN12)
#define GPIO_ADC1_IN16_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN12)
#define GPIO_ADC1_IN17_1 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN4)
#define GPIO_ADC1_IN17_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN13)
#define GPIO_ADC1_IN18_1 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN5)
#define GPIO_ADC1_IN18_2 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN14)
/* TODO: DAC */

View File

@@ -335,6 +335,12 @@
/* TODO: Clock configuration register */
#define RCC_CCIPR_ADCSEL_SHIFT (30)
#define RCC_CCIPR_ADCSEL_MASK (3 << RCC_CCIPR_ADCSEL_SHIFT)
#define RCC_CCIPR_ADCSEL_SYSCLK (0)
#define RCC_CCIPR_ADCSEL_PLLPCLK (1 << RCC_CCIPR_ADCSEL_SHIFT)
#define RCC_CCIPR_ADCSEL_HSI16 (2 << RCC_CCIPR_ADCSEL_SHIFT)
/* TODO: RTC domain control register */
/* Control/status register */

View File

@@ -60,7 +60,7 @@
#if defined(CONFIG_STM32F0L0G0_ADC1)
#if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32G0)
#if defined(CONFIG_STM32F0L0G0_STM32F0)
# error Not tested
#endif
@@ -134,7 +134,8 @@
#if defined(CONFIG_STM32F0L0G0_STM32F0) || \
defined(CONFIG_STM32F0L0G0_STM32L0) || \
defined(CONFIG_STM32F0L0G0_STM32C0)
defined(CONFIG_STM32F0L0G0_STM32C0) || \
defined(CONFIG_STM32F0L0G0_STM32G0)
# define ADC_CHANNELS_NUMBER 19
#else
# error "Not supported"
@@ -165,6 +166,12 @@
#define ADC_HAVE_DMACFG 1
#if defined(CONFIG_STM32F0L0G0_STM32G0) || defined(CONFIG_STM32F0L0G0_STM32L0)
# ifndef ANIOC_SET_OVERSAMPLE
# define ANIOC_SET_OVERSAMPLE _ANIOC(0x0f)
# endif
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@@ -1458,6 +1465,22 @@ static void adc_sampletime_cfg(struct adc_dev_s *dev)
#endif
}
/****************************************************************************
* Name: adc_ckmode_cfg
****************************************************************************/
static void adc_ckmode_cfg(struct stm32_dev_s *priv)
{
uint32_t setbits = 0;
uint32_t clearbits = ADC_CFGR2_CKMODE_MASK;
#ifdef STM32_ADC_CFGR2_CKMODE
setbits |= STM32_ADC_CFGR2_CKMODE;
#endif
adc_modifyreg(priv, STM32_ADC_CFGR2_OFFSET, clearbits, setbits);
}
/****************************************************************************
* Name: adc_common_cfg
****************************************************************************/
@@ -1467,10 +1490,18 @@ static void adc_common_cfg(struct stm32_dev_s *priv)
uint32_t clrbits = 0;
uint32_t setbits = 0;
#ifdef STM32_ADC_CCR_PRESC
setbits |= STM32_ADC_CCR_PRESC;
#endif
/* REVISIT: for now we reset all CCR bits */
clrbits |= ADC_CCR_VREFEN;
clrbits |= ADC_CCR_TSEN;
clrbits |= ADC_CCR_PRESC_MASK | ADC_CCR_VREFEN |
ADC_CCR_TSEN;
#ifdef HAVE_ADC_VBAT
clrbits |= ADC_CCR_VBATEN;
#endif
#ifdef HAVE_ADC_VLCD
clrbits |= ADC_CCR_PRESC_MASK;
@@ -1484,8 +1515,6 @@ static void adc_common_cfg(struct stm32_dev_s *priv)
clrbits |= ADC_CCR_LFMEN;
#endif
setbits = 0;
adccmn_modifyreg(priv, STM32_ADC_CCR_OFFSET, clrbits, setbits);
}
@@ -1590,6 +1619,10 @@ static void adc_configure(struct adc_dev_s *dev)
adc_set_ch(dev, 0);
}
/* ADC clock mode configuration */
adc_ckmode_cfg(priv);
/* ADC common register configuration */
adc_common_cfg(priv);
@@ -1630,6 +1663,31 @@ static void adc_configure(struct adc_dev_s *dev)
adc_dumpregs(priv);
}
#ifdef CONFIG_STM32F0L0G0_ADC_OVERSAMPLE
/****************************************************************************
* Name: adc_oversample
****************************************************************************/
static void adc_oversample(struct adc_dev_s *dev)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev->ad_priv;
uint32_t clrbits = ADC_CFGR2_OVSE | ADC_CFGR2_TOVS |
ADC_CFGR2_OVSR_MASK | ADC_CFGR2_OVSS_MASK;
uint32_t setbits = ADC_CFGR2_OVSE |
(CONFIG_STM32F0L0G0_ADC_OVSR << ADC_CFGR2_OVSR_SHIFT) |
(CONFIG_STM32F0L0G0_ADC_OVSS << ADC_CFGR2_OVSS_SHIFT);
# ifdef CONFIG_STM32F0L0G0_ADC_TOVS
setbits |= ADC_CFGR2_TOVS;
# endif
adc_modifyreg(priv, STM32_ADC_CFGR2_OFFSET, clrbits, setbits);
}
#endif
/****************************************************************************
* Name: adc_reset
*
@@ -1727,6 +1785,10 @@ static int adc_setup(struct adc_dev_s *dev)
adc_configure(dev);
#ifdef CONFIG_STM32F0L0G0_ADC_OVERSAMPLE
adc_oversample(dev);
#endif
#ifdef ADC_HAVE_TIMER
/* Configure timer */
@@ -2193,6 +2255,55 @@ static int adc_ioc_change_ints(struct adc_dev_s *dev, int cmd, bool arg)
return ret;
}
#ifdef CONFIG_STM32F0L0G0_ADC_OVERSAMPLE
/****************************************************************************
* Name: adc_ioc_set_oversample
*
* Description:
* For STM32G0 and STM32L0: Configure hardware oversampling via CFGR2.
*
* Input:
* dev - pointer to the ADC device
* arg - Packed 32-bit value that matches CFGR2 layout for OVSE, TOVS,
* OVSR[2:0] and OVSS[3:0].
*
* Bit fields (match ADC_CFGR2 register layout):
* [0] = OVSE (enable oversampling)
* [1] = TOVS (triggered oversampling)
* [4:2] = OVSR (ratio: 000=2x, ..., 111=256x)
* [9:5] = OVSS (right shift: 00000=no shift, ..., 11111=31-bit)
*
* Returned Value:
* OK (0) on success
*
****************************************************************************/
static int adc_ioc_set_oversample(struct adc_dev_s *dev, uint32_t arg)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev->ad_priv;
uint32_t clrbits;
uint32_t setbits;
/* Mask out the oversampling-related fields from CFGR2:
* OVSE | TOVS | OVSR[2:0] | OVSS[3:0]
*/
clrbits = ADC_CFGR2_OVSE |
ADC_CFGR2_TOVS |
ADC_CFGR2_OVSR_MASK |
ADC_CFGR2_OVSS_MASK;
setbits = arg & (ADC_CFGR2_OVSE |
ADC_CFGR2_TOVS |
ADC_CFGR2_OVSR_MASK |
ADC_CFGR2_OVSS_MASK);
adc_modifyreg(priv, STM32_ADC_CFGR2_OFFSET, clrbits, setbits);
return OK;
}
#endif /* G0 or L0 */
/****************************************************************************
* Name: adc_set_ch
@@ -2286,6 +2397,7 @@ static int adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
ret = priv->cr_channels;
}
break;
case IO_TRIGGER_REG:
@@ -2363,6 +2475,14 @@ static int adc_ioctl(struct adc_dev_s *dev, int cmd, unsigned long arg)
break;
}
#if defined(CONFIG_STM32F0L0G0_ADC_OVERSAMPLE)
case ANIOC_SET_OVERSAMPLE:
{
ret = adc_ioc_set_oversample(dev, arg);
break;
}
#endif
default:
{
aerr("ERROR: Unknown cmd: %d\n", cmd);

View File

@@ -643,6 +643,13 @@ static void stm32_stdclockconfig(void)
stm32_rcc_enablelse();
#endif
#if defined(STM32_RCC_CCIPR_ADCSEL)
regval = getreg32(STM32_RCC_CCIPR);
regval &= ~RCC_CCIPR_ADCSEL_MASK;
regval |= STM32_RCC_CCIPR_ADCSEL;
putreg32(regval, STM32_RCC_CCIPR);
#endif
}
#endif

View File

@@ -0,0 +1,59 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_LIBC_LONG_LONG is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_STM32F0G0L0_USE_LEGACY_PINMAP is not set
CONFIG_ADC=y
CONFIG_ANALOG=y
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="nucleo-g0b1re"
CONFIG_ARCH_BOARD_NUCLEO_G0B1RE=y
CONFIG_ARCH_CHIP="stm32f0l0g0"
CONFIG_ARCH_CHIP_STM32G0=y
CONFIG_ARCH_CHIP_STM32G0B1RE=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=4164
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DISABLE_ENVIRON=y
CONFIG_DISABLE_MQUEUE=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y
CONFIG_EXAMPLES_ADC=y
CONFIG_EXAMPLES_ADC_GROUPSIZE=1
CONFIG_EXAMPLES_ADC_NSAMPLES=1
CONFIG_EXAMPLES_HELLO=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=1536
CONFIG_INTELHEX_BINARY=y
CONFIG_LINE_MAX=64
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=64
CONFIG_NSH_READLINE=y
CONFIG_NUNGET_CHARS=0
CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=1536
CONFIG_PTHREAD_MUTEX_UNSAFE=y
CONFIG_PTHREAD_STACK_DEFAULT=1536
CONFIG_RAM_SIZE=147456
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=19
CONFIG_START_MONTH=5
CONFIG_START_YEAR=2013
CONFIG_STDIO_DISABLE_BUFFERING=y
CONFIG_STM32F0L0G0_ADC1=y
CONFIG_STM32F0L0G0_PWR=y
CONFIG_STM32F0L0G0_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART2_SERIAL_CONSOLE=y

View File

@@ -76,14 +76,14 @@
* 2 <= PLLR <= 8
*
* PLLR <= 64MHz
* PLLQ <= 128MHz
* PLLP <= 128MHz
* PLLQ <= 64MHz
* PLLP <= 64MHz
*
* PLL_VCO = (16,000,000 / 4) * 50 = 200 MHz
* PLL_VCO = (16,000,000 / 2) * 32 = 256 MHz
*
* PLLP = PLL_VCO/4 = 200 MHz / 4 = 40 MHz
* PLLQ = PLL_VCO/4 = 200 MHz / 4 = 40 MHz
* PLLR = PLL_VCO/4 = 200 MHz / 4 = 40 MHz
* PLLP = PLL_VCO/4 = 256 MHz / 4 = 64 MHz
* PLLQ = PLL_VCO/4 = 256 MHz / 4 = 64 MHz
* PLLR = PLL_VCO/4 = 256 MHz / 4 = 64 MHz
*/
#define STM32_PLLCFG_PLLSRC RCC_PLLCFG_PLLSRC_HSI
@@ -91,13 +91,13 @@
RCC_PLLCFG_PLLQEN | \
RCC_PLLCFG_PLLREN)
#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(4)
#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(50)
#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(2)
#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(64)
#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP(4)
#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(4)
#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(4)
#define STM32_VCO_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 50)
#define STM32_VCO_FREQUENCY ((STM32_HSI_FREQUENCY / 2) * 64)
#define STM32_PLLP_FREQUENCY (STM32_VCO_FREQUENCY / 4)
#define STM32_PLLQ_FREQUENCY (STM32_VCO_FREQUENCY / 4)
#define STM32_PLLR_FREQUENCY (STM32_VCO_FREQUENCY / 4)
@@ -118,6 +118,13 @@
#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2)
/* ADC1 clock prescaled is SYSCLK (64MHz) / 2 = 32MHz */
#define STM32_ADC_CLK_FREQUENCY STM32_SYSCLK_FREQUENCY
#define STM32_RCC_CCIPR_ADCSEL RCC_CCIPR_ADCSEL_SYSCLK
#define STM32_ADC_CFGR2_CKMODE ADC_CFGR2_CKMODE_ADCCLK
#define STM32_ADC_CCR_PRESC ADC_CCR_PRESC_DIV2
/* LED definitions **********************************************************/
/* The Nucleo G0B1RE board has four LEDs. Three of these are controlled by
@@ -201,6 +208,10 @@
#define GPIO_USART2_RX (GPIO_USART2_RX_1|GPIO_SPEED_HIGH) /* PA3 */
#define GPIO_USART2_TX (GPIO_USART2_TX_1|GPIO_SPEED_HIGH) /* PA2 */
/* ADC */
#define GPIO_ADC1_IN0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0)
/* DMA channels *************************************************************/
/* ADC */

View File

@@ -38,6 +38,10 @@ ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
ifeq ($(CONFIG_ADC),y)
CSRCS += stm32_adc.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board

View File

@@ -89,4 +89,15 @@
int stm32_bringup(void);
/****************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
****************************************************************************/
#ifdef CONFIG_ADC
int stm32_adc_setup(void);
#endif
#endif /* __BOARDS_ARM_STM32F0L0G0_NUCLEO_G0B1RE_SRC_NUCLEO_G0B1RE_H */

View File

@@ -0,0 +1,131 @@
/****************************************************************************
* boards/arm/stm32f0l0g0/nucleo-g0b1re/src/stm32_adc.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/analog/adc.h>
#include "stm32.h"
#if defined(CONFIG_ADC) && defined(CONFIG_STM32F0L0G0_ADC1)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* The number of ADC channels in the conversion list */
#define ADC1_NCHANNELS 1
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* Identifying number of each ADC channel (even if NCHANNELS is less ) */
static const uint8_t g_chanlist1[1] =
{
0
};
/* Configurations of pins used by each ADC channel */
static const uint32_t g_pinlist1[1] =
{
GPIO_ADC1_IN0
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_adc_setup
*
* Description:
* Initialize ADC and register the ADC driver.
*
****************************************************************************/
int stm32_adc_setup(void)
{
static bool initialized = false;
struct adc_dev_s *adc;
int ret;
int i;
/* Check if we have already initialized */
if (!initialized)
{
/* Configure the pins as analog inputs for the selected channels */
for (i = 0; i < ADC1_NCHANNELS; i++)
{
stm32_configgpio(g_pinlist1[i]);
}
/* Call stm32_adcinitialize() to get an instance of the ADC interface */
adc = stm32_adcinitialize(1, g_chanlist1, ADC1_NCHANNELS);
if (adc == NULL)
{
aerr("ERROR: Failed to get ADC interface 1\n");
return -ENODEV;
}
/* Register the ADC driver at "/dev/adc0" */
ret = adc_register("/dev/adc0", adc);
if (ret < 0)
{
aerr("ERROR: adc_register /dev/adc0 failed: %d\n", ret);
return ret;
}
initialized = true;
}
return OK;
}
#endif

View File

@@ -26,11 +26,15 @@
#include <nuttx/config.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <syslog.h>
#include <debug.h>
#include <nuttx/board.h>
#include <nuttx/input/buttons.h>
#include <nuttx/leds/userled.h>
#include <arch/board/board.h>
#include "nucleo-g0b1re.h"