Skip to content
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

add to the stm32-adc internal channel handling #34458

Closed
wants to merge 4 commits into from
Closed

add to the stm32-adc internal channel handling #34458

wants to merge 4 commits into from

Conversation

StefJar
Copy link

@StefJar StefJar commented Apr 21, 2021

drivers: adc: enable the stm32 adc driver VRef via internal channel

changes:
- inside the dts the channel 17 can be set up as internal channel
- this is done via adding "ch17-internal;" to the adc1 node
- the "ch17-internal" flag enables the internal channel routing
at the stm32 adc driver
note:
- this is only tested for the stm32f412 MCU

Signed-off-by: Stefan Jaritz stefan@kokoontech.com

Stefan Jaritz and others added 3 commits April 21, 2021 11:37
changes:
	- inside the dts the channel 17 can be set up as internal channel
	- this is done via adding "ch17-internal;" to the adc1 node
	- the "ch17-internal" flag enables the internal channel routing
	at the stm32 adc driver
note:
	- this is only tested for the stm32f412 MCU

Signed-off-by: Stefan Jaritz <stefan@kokoontech.com>
changed wrong sample
@@ -248,6 +248,18 @@ static int check_buffer_size(const struct adc_sequence *sequence,
return 0;
}

static uint32_t adc_stm32_getChannelByIndx(const uint8_t index) {
uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(index);
#if DT_N_S_soc_S_adc_40012000_P_ch17_internal == 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know this part is soc specific, right ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only know the stm32f412 MCU so I don't know how to make my code fitting to others st archs.

In general this code is a demo to show, how to add the internal channels to the stm32f412 by using the dts and some minor code patch of the stm32 adc driver.

I am happy to get some advice and execute the changes to make this commit better ;)

@@ -716,6 +728,13 @@ static int adc_stm32_init(const struct device *dev)
}
#endif

// handle internal channels
#if DT_N_S_soc_S_adc_40012000_P_ch17_internal == 1
Copy link
Contributor

@mbolivar-nordic mbolivar-nordic Apr 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will leave the SoC specific parts of this to @erwango, but I am -1 on using the generated devicetree_unfixed.h macros directly. They are implementation details. Use the documented macro APIs provided in devicetree.h only please.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbolivar-nordic Sure. We'll first review the pure driver implementation first (to make sure the proposed changes make sense), then we'll focus on getting the change compliant (and simply functional) vs DT API.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi
I changed the mentioned lines. Now using dts macros
I also used C comments instead of C++ comments

changes:
            - the internal channels are now switched on, if
            the soc is an stm32f4xx and ch17_internal is
            set.
* for now only the channel 17 (VRef internal)
* is implemented
*/
#if defined(CONFIG_SOC_SERIES_STM32F4X)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If using DT macros to control the enabled code, you don't need this anymore.

* is implemented
*/
#if defined(CONFIG_SOC_SERIES_STM32F4X)
#if (DT_PROP(DT_NODELABEL(adc1), ch17_internal) == 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that only valid for adc1 ?
Also, one problem raised here is that this piece of code will be applied whatever the instance in use, as long as ch17_internal is defined for adc1.

I'd advice to store the information about ch17_internal in a device specific struct (adc_stm32_cfg),
and check for the info in that structure in run time. So you ensure that channel setting is done only on the expected instance (be it adc1, adc2, adcx or any combination)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx for the comment
I just dived into DT and its macros. So I am still beginner - if you have an better idea pls let me know.
Storing the internal/external channel info must be handled at one instance. I used macros that are fixed at compile time. The adc_stm32_cfg is a good idea, because its constant and therefore the compiler can resolve this const expr into static code. So that should not cost any performance (because the channel setup is done for every conversation). An other topic is in general the adc API, what translates the sequence into the device specific adc sequence for EVERY adc_read call. IMHO that is a bad design ;)

@erwango
Copy link
Member

erwango commented Apr 30, 2021

@StefJar can you have a look to #34673 ? This is not exactly the same, but not far way.

@StefJar
Copy link
Author

StefJar commented Apr 30, 2021

@erwango I quickly checked #34673

From a perspective of an stm32f412 this implementation is missing 2 things:

  • the internal and external adc source is mapped to the same channel. Since adc_start is just resolving the channel via __LL_ADC_DECIMAL_NB_TO_CHANNEL macro that gives back the external channel it's not getting the right channel
  • the internal channel needs some extra init. That is done at this commit via LL_ADC_SetCommonPathInternalCh. For the L4 etc. series it seems different and this is done at the driver, but for the F4 series its missing

The commit does not explicit solves the problem that the F4 adc channels are multiplexed (internal/external). The current driver assumes that all channels are external. As long as there is no definition for that via dts/kconfig etc. the driver can't set internal channels up. Maybe we should start there first. My time is limited and I have only a stm32f412 custom board here. So no chance for me for stm32Fx/stm32Lx testing :(

@StefJar
Copy link
Author

StefJar commented May 19, 2021

this feature was addressed and solved via #34673

thx @erwango for reviewing and @Delsian for the works

@StefJar StefJar closed this May 19, 2021
@StefJar StefJar deleted the adc_stm32_withInternalChannels branch May 19, 2021 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ADC Analog-to-Digital Converter (ADC) area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree platform: STM32 ST Micro STM32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants