Fix race condition causing ADCs to read stale values #203
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #201
This was a fun bug to track down.
Some decided that it would be a good idea to make one way of starting the ADC conversion to write a
1
to theadon
bit if theadon
bit is already one. But that might trigger a read when you want to modify other parts of the register, so this behaviour only happens if no other bits are modified. Thus,modify
on thecr2
register will start a conversion unless at least one bit is actually modified.This was accidentally done as the first part of the
convert
function, which started a conversion which would be ready roughly by the time the CPU starts checking foreoc
bits.The race condition occurs if the CPU gets to the
EOC
check, before the ADC has time to reset the bit as a result of theswstart
trigger. This relies on the CPU being faster than the ADC clock which explains the behaviour at high prescalers.Finally, it seems like the line
should have prevented this as the ADC should have taken care of the
swstart
and reset theEOC
before that line. For whatever reason, that did not happenThnaks @adamgreig for helping debug this :), and for a more detailed log of the steps we used to track it down, see the commit message.