-
Notifications
You must be signed in to change notification settings - Fork 8.1k
STM32 ADC: support prescaler from RCC #97725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a53adf3
68d093f
e185ade
7d42991
8221080
914425f
79dbd37
d3801a9
ef0e8f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,7 +71,6 @@ | |
| ahb-prescaler = <1>; | ||
| apb1-prescaler = <2>; | ||
| apb2-prescaler = <1>; | ||
| adc-prescaler = <2>; | ||
| }; | ||
|
|
||
| &usart1 { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -216,15 +216,18 @@ struct adc_stm32_data { | |
| struct adc_stm32_cfg { | ||
| ADC_TypeDef *base; | ||
| void (*irq_cfg_func)(void); | ||
| const struct stm32_pclken *pclken; | ||
| size_t pclk_len; | ||
| const struct stm32_pclken pclken; | ||
| const struct stm32_pclken pclken_ker; | ||
| const struct stm32_pclken pclken_pre; | ||
| uint32_t clk_prescaler; | ||
| const struct pinctrl_dev_config *pcfg; | ||
| const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME]; | ||
| int8_t num_sampling_time_common_channels; | ||
| int8_t sequencer_type; | ||
| int8_t oversampler_type; | ||
| int8_t internal_regulator; | ||
| bool has_pclken_ker :1; | ||
| bool has_pclken_pre :1; | ||
| bool has_deep_powerdown :1; | ||
| bool has_channel_preselection :1; | ||
| bool has_differential_support :1; | ||
|
|
@@ -471,8 +474,7 @@ static void adc_stm32_calibration_delay(const struct device *dev) | |
| const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); | ||
| uint32_t adc_rate, wait_cycles; | ||
|
|
||
| if (clock_control_get_rate(clk, | ||
| (clock_control_subsys_t) &config->pclken[0], &adc_rate) < 0) { | ||
| if (clock_control_get_rate(clk, (clock_control_subsys_t)&config->pclken, &adc_rate) < 0) { | ||
| LOG_ERR("ADC clock rate get error."); | ||
| } | ||
|
|
||
|
|
@@ -1496,8 +1498,8 @@ static int adc_stm32h7_setup_boost(const struct adc_stm32_cfg *config, ADC_TypeD | |
| int presc; | ||
|
|
||
| /* Get the input frequency */ | ||
| clk_src = (clock_control_subsys_t)(adc_stm32_is_clk_sync(config) ? &config->pclken[0] | ||
| : &config->pclken[1]); | ||
| clk_src = (clock_control_subsys_t)(adc_stm32_is_clk_sync(config) ? &config->pclken | ||
| : &config->pclken_ker); | ||
|
|
||
| if (clock_control_get_rate(clk, clk_src, &input_freq) != 0) { | ||
| LOG_ERR("Failed to get ADC clock frequency"); | ||
|
|
@@ -1534,33 +1536,27 @@ static int adc_stm32h7_setup_boost(const struct adc_stm32_cfg *config, ADC_TypeD | |
| } | ||
| #endif | ||
|
|
||
| /* This symbol takes the value 1 if one of the device instances */ | ||
| /* is configured in dts with a domain clock */ | ||
| #if STM32_DT_INST_DEV_DOMAIN_CLOCK_SUPPORT | ||
| #define STM32_ADC_DOMAIN_CLOCK_SUPPORT 1 | ||
| #else | ||
| #define STM32_ADC_DOMAIN_CLOCK_SUPPORT 0 | ||
| #endif | ||
|
|
||
| static int adc_stm32_set_clock(const struct device *dev) | ||
| { | ||
| const struct adc_stm32_cfg *config = dev->config; | ||
| const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); | ||
| __maybe_unused ADC_TypeDef *adc = config->base; | ||
| int ret = 0; | ||
|
|
||
| if (clock_control_on(clk, | ||
| (clock_control_subsys_t) &config->pclken[0]) != 0) { | ||
| if (clock_control_on(clk, (clock_control_subsys_t)&config->pclken) != 0) { | ||
| return -EIO; | ||
| } | ||
|
|
||
| if (IS_ENABLED(STM32_ADC_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) { | ||
| /* Enable ADC clock source */ | ||
| if (clock_control_configure(clk, | ||
| (clock_control_subsys_t) &config->pclken[1], | ||
| NULL) != 0) { | ||
| return -EIO; | ||
| } | ||
| /* Enable ADC clock source if applicable */ | ||
| if (config->has_pclken_ker && | ||
| clock_control_configure(clk, (clock_control_subsys_t)&config->pclken_ker, NULL) != 0) { | ||
| return -EIO; | ||
| } | ||
|
|
||
| /* Configure ADC prescaler (at RCC level) if applicable */ | ||
| if (config->has_pclken_pre && | ||
| clock_control_configure(clk, (clock_control_subsys_t)&config->pclken_pre, NULL) != 0) { | ||
| return -EIO; | ||
| } | ||
|
|
||
| #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) | ||
|
|
@@ -1735,7 +1731,7 @@ static int adc_stm32_suspend_setup(const struct device *dev) | |
| adc_stm32_disable_analog_supply(); | ||
|
|
||
| /* Stop device clock. Note: fixed clocks are not handled yet. */ | ||
| err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken[0]); | ||
| err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken); | ||
| if (err != 0) { | ||
| LOG_ERR("Could not disable ADC clock"); | ||
| return err; | ||
|
|
@@ -1806,7 +1802,7 @@ static DEVICE_API(adc, api_stm32_driver_api) = { | |
|
|
||
| /* Macro to check if the ADC instance clock setup is correct */ | ||
| #define ADC_STM32_CHECK_DT_CLOCK(x) \ | ||
| BUILD_ASSERT(IS_EQ(ADC_STM32_CLOCK(x), SYNC) || (DT_INST_NUM_CLOCKS(x) > 1), \ | ||
| BUILD_ASSERT(IS_EQ(ADC_STM32_CLOCK(x), SYNC) || DT_INST_CLOCKS_HAS_NAME(x, adc_ker), \ | ||
| "ASYNC clock mode defined without ASYNC clock defined in device tree") | ||
|
|
||
| #else /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) */ | ||
|
|
@@ -1963,14 +1959,21 @@ ADC_STM32_CHECK_DT_CLOCK(index); \ | |
| \ | ||
| PINCTRL_DT_INST_DEFINE(index); \ | ||
| \ | ||
| static const struct stm32_pclken pclken_##index[] = \ | ||
| STM32_DT_INST_CLOCKS(index); \ | ||
| \ | ||
| static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \ | ||
| .base = (ADC_TypeDef *)DT_INST_REG_ADDR(index), \ | ||
| ADC_STM32_IRQ_FUNC(index) \ | ||
| .pclken = pclken_##index, \ | ||
| .pclk_len = DT_INST_NUM_CLOCKS(index), \ | ||
| .pclken = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adcx, bus), \ | ||
| .enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adcx, bits)}, \ | ||
|
Comment on lines
+1965
to
+1966
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I would make a STM32-level macro for this. Basically all drivers are "wrong" today ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a change for another PR. As you say, all drivers are impacted, so I'm not going to introduce such a change in this one. There are enough as it is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My 2 cents. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
By |
||
| COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(index, adc_ker), \ | ||
| (.pclken_ker = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_ker, bus), \ | ||
| .enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_ker, bits)}, \ | ||
| .has_pclken_ker = true,), \ | ||
| (.has_pclken_ker = false,)) \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: could be But I don't mind the extra verbosity. |
||
| COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(index, adc_pre), \ | ||
| (.pclken_pre = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_pre, bus), \ | ||
| .enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_pre, bits)}, \ | ||
| .has_pclken_pre = true,), \ | ||
| (.has_pclken_pre = false,)) \ | ||
| .clk_prescaler = ADC_STM32_DT_PRESC(index), \ | ||
| .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ | ||
| .differential_channels_used = (ANY_CHILD_NODE_IS_DIFFERENTIAL(index) > 0), \ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.