Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

>It seems that the ADCs on the STM32G4 do not like to be turned on in rapid succession, and if they do, bad things can happen like having the prescaler flipped to a different value without it showing in the corresponding register.

This sounds very, VERY much like an incorrectly configured clock where some of the peripherals would end up with a clock frequency slightly above what they were designed for. Will work 99% of the time and will give you hell for the remaining 1%. Much more likely than stumbling upon an undiscovered errata in a fairly popular device family with 10+ years of history.

Could also be flakey power (check your decoupling capacitors) or an outright b0rked chip/board.



For what it is worth, the G0/4 family is relatively new. I'm pretty sure it has unique ADC IP too, since the published errata (which I'm very familiar with) are different from any other ST chip I know of.

The clock should of course have been suspect (as noted in the writeup). The "bad state" in this problem was basically indistinguishable from running the ADC at too high a clock rate. In fact, the default rate when I first encountered this problem does ever so slightly overclock the ADC. It is rated for 60MHz for single ADC operation, but only 26MHz for multiple ADCs. The firmware used to run the ADCs at ~28MHz, purposefully going a tiny bit above that.

I didn't include it in the writeup since it was somewhat of a diversion, but this particular problem occurred even with the ADCs configured to be clocked slower. As mentioned, I think that their clock configuration became mis-set as a result of the underlying problem.

And while poor decoupling is also a likely problem, I'm 95% sure it is about as good as it can get. A high quality cap of appropriate size is immediately next to the chip on every supply pin with vias directly to the ground plane. This is a low pin count QFN part, so the only ground on the chip is the center pad, which is also via'ed directly to the ground plane.


I wonder if it would be possible to create a test jig that turns on the ADCs all at once then samples data through them (perhaps just from a function generator)?


Maybe, anyway it's worth opening a case with ST support. I found a bug in STM32L0 a few years ago, and they did help (they found a software workaround which was not yet documented- had to do with waking up from deep sleep).


Or it was just faulty firmware and he did hit the (almost) correct conclusion:

ADEN bit on g4:

"Note: The software is allowed to set ADEN only when all bits of ADC_CR registers are 0 (ADCAL = 0, JADSTART = 0, ADSTART = 0, ADSTP = 0, ADDIS = 0 and ADEN = 0) except for bit ADVREGEN which must be 1 (and the software must have wait for the startup time of the voltage regulator"

No errata needed, it's clearly stated that you cannot just set ADEN without waiting for certain other conditions.


Actually, if you look at the firmware at the time, the proper procedure was followed as far as I can tell. All of the necessary bits were set and checked with the appropriate delays where required.

https://github.com/mjbots/moteus/blob/dcb900c92ffd5d5c8f5405...

Notably, the datasheet is largely silent on interactions between different ADCs during initialization.


I think it's more likely that the data needs to cross a clock boundary and multi-clock synchronisation takes time (especially if metastability is potentially an issue) - they way you make it safe is by holding the data you're synchronising stable for multiple clocks and synchronise a strobe signal across the clock boundary and then back again

My guess is that the circuit they're using gets confused if you start a second write when the first is not yet done


That is possible, although here the consecutive writes were to different ADC peripherals. The ADC peripherals do share some common configuration and triggering, but I believe are otherwise largely independent.


but they're going over the same peripheral bus (from the CPU, and being synchronised to a subsystem with likely the same ADC clock domain - I'd design that hardware once (metastability stuff is notorious for being hard to get right, especially when you are trying to transfer multiple related bits across clock boundaries at the same time, and you want them all to arrive together)


Yep, there is probably one clock domain for all the ADCs, although there are two different prescalers (one for ADC1/2 and another for 3/4/5).

I could see one of the writes getting lost. In this case though, the ADC enable is what seems to be timing sensitive, however the ADCs always end up enabled properly. It is just that a write that was significantly earlier (the one that sets the prescaler) seems to be lost, despite the register reading back that it was read correctly.

I would expect that if the synchronization failed, reads back would read the wrong value?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: