2024-10-01 01:49 AM
Hi all.
I'm working on a project with STM32H7 and I've got a question:
I'm doing some experiments with ADC multichannel and wacthdog enabled to launch an interrupt of One of the Channel measured level passes the alert level (High threshold).
Everything works fine but here the question:
If more than 1 Channel Is linked to a wacthdog, how can I distinguish what channel caused the interrupt to be launched?
2024-10-01 02:30 AM
ADC watchdogs have outputs connected to some timers' ETR (e.g. in 'H743 see ETRSEL in TIM1_AF1/TIM8_AF1) so you can for example select ETR as TRC signal in TIMx_SMCR.TS=0b111 and subsequently use it as capture input by setting TIMx_CCMRx.CC1S to 0b11, and use the captured value as a timestamp, from which you can infer the ADC mux setting (i.e. channel causing the watchdog output to go active) according to how did you set up the ADC trigger.
JW
2024-10-10 01:54 AM
Sorry for he late answer.
Is not clear to me how can I understand which channel caused the alert to be launched.
What I understood from your answer is to connect a timer to the watchdog, in this way when the alert occurs, the timer will launch an interrupt and the data contained into data register is moved maybe inside another variable? If yes, can I read the value contained into the Data register if I'm using DMA to continuously move read data to a circular buffer?
2024-10-10 03:55 AM
> What I understood from your answer is to connect a timer to the watchdog, in this way when the alert occurs, the timer will launch an interrupt
Depending on the rate the ADC conversions and all the factors influencing interrupt latency, you may want to both have some method to store a suitable register (see below), either being directly a capture in the timer or through triggering a "strategic" DMA transfer, and then also an interrupt where the "strategically" stored value would be evaluated.
> and the data contained into data register is moved maybe inside another variable?
No, although maybe that would be enough, if you also DMA all the data, so that you can then compare that in software (I believe you can read the ADC data register *after* the DMA which was triggered from ADC reads it (and of course before the next conversion finishes and overwrites that value), I did this on 'F4 but it may be different in 'H7 as the ADCs vary significantly in details between STM32 families).
What I had in mind was, that you freely run the timer, into which the signal is fed and you capture the current value of the timer's counter using that signal, and in processing, based on that value, you calculate . It assumes that you run ADC and timer synchronously from the same primary clock source (which in most normal setups is fulfilled) and you know the timing ratios and also have started both simultaneously enough to know their mutual relationship.
But, if you DMA the ADC results, you can also just read the given DMA Stream's NDTR register to find out, which channel was the latest stored, this is probably more straightforward than the timestamp method above.
Note that nowhere did I promise this is easy or even possible at all in your setup. This is just what I'd be after.
JW
2024-10-10 07:21 AM
Suppose there is a buffer for adc multichannel data readings, than just run search in for loop to find an index of the value that cross watch level. Index directly points to number of the channel that fired up an interrupt, as a remainder of integer division Ind % N, where N is the number of active channels.
2024-10-10 07:53 AM
> just run search in for loop to find an index of the value that cross watch level
Well, yes, I may have just overcomplicated the issue in expectation of rapid ADC readout bursts.
Also, if the ADC measurements are started/triggered slowly enough that an interrupt is viable (i.e. it's latency is lower than the ADC measurement interval), simply reading out the DMA's NDTR in the watchdog interrupt indicates directly which reading is going on.
The ADC internally must have a counter for currently converted channel ("pointer" to ADC_SQRx fields' array) - pity it is not brought out for reading, e.g. in the status register.
JW
2024-10-10 08:16 AM
Thank you all people for the answers, now it's clear to me and yes, working with the for loop seems a good idea.
The sampling time for each ADC channel is 382 cycles so I think is slow enough.
On past experiences I worked with ADC channels directly linked with the watchdog and the manage is easier.
I'll test more and more this solution e I will check if everything is ok.
2024-10-10 10:13 AM
> The sampling time for each ADC channel is 382 cycles so I think is slow enough.
Processor cycles or some other clock cycles?
In 'H7?
That's probably viable but may be quite tight for an interrupt. You'd need it to run from a guaranteed fast memory (ITCM?), high(est) priority, use compiler optimization and try to avoid Cube/HAL or any other "library". At any case you'd need to properly qualify the ISR latency/duration.
JW