don't recalculate clock frequencies every time they are asked for. while
this is not very often in practice it does consume a bunch of flash
space that cannot be optimized away, and was pulled in unconditionally
previously. while we technically only need the configured rosc, xosc and
gpin frequencies it is easier to store all frequencies (and much cheaper
at runtime too).
if rosc really does run at 140MHz in high at div=1 then these values
were not correct and would've exceeded the chip spec. the HIL test
device seems to run fast (150MHz) so they're still not quite correct,
but rosc has high variance anyway so it's probably fine.
exposing pac items kind of undermines the unstable-pac feature. directly
exposing register structure is also pretty inconvenient since the clock
switching code takes care of the src/aux difference in behavior, so a
user needn't really be forced to write down decomposed register values.
the datasheet says that the xosc may be run by feeding a square wave
into the XIN pin of the chip, but requires that the oscillator be set to
pass through XIN in that case. it does not mention how, the xosc
peripheral does not seem to have any config bits that could be set to
this effect, and pico-sdk seems to have no (or at least no special)
handling for this configuration at all. it can thus be assumed to either
be not supported even by the reference sdk or to not need different
handling.
solvers usually output fbdiv directly, using vco_freq to get back to
fbdiv is not all that necessary or useful. both vco_freq and fbdiv have
hidden constraints, but vco_freq is a lot less accurate because the
fbdiv value resulting from the division may be off by almost a full
ref_freq's worth of frequency.
also fixes the usb pll config, which ran the pll vco way out of (below)
spec.
we might not configure both, so we should put the others into reset
state. leaving them fully as is might leave them running, which might
not be the goal for runtime reconfig (when it comes around). this now
mirrors how we reset all clock-using peripherals and only unreset those
that are properly clocked.
this is only really useful for runtime *re*configuration, which we don't
currently support. even runtime reconfig probably won't need it, unless
we keep taking the sledgehammer approach of reconfiguring everything all
the time.
It is UB to pass `entry` to core1 as `&mut`, because core0 keeps
an aliasing pointer to that memory region, and actually writes to
it (when `spawn_core1` returns, the stack frame gets deallocated and the memory
gets reused). This violates noalias requirements.
Added the fence just in case, een though it works without.
It was intended to allow changing baudrate on shared spi/i2c. There's no
advantage in using it for PWM or PIO, and makes it less usable because you have to
have `embassy-embedded-hal` as a dep to use it.
1439: rp: use rp2040-boot2 to provide the boot2 blob r=Dirbaio a=pennae
we're currently shipping an old boot2 that runs the flash at half speed. use the more recent version instead, and allow user to choose between the different supported boot2 versions for different flash chips if they need that.
Co-authored-by: pennae <github@quasiparticle.net>
we're currently shipping an old boot2 that runs the flash at half speed.
use the more recent version instead, and allow user to choose between
the different supported boot2 versions for different flash chips if they
need that.
execution wraps around after the end of instruction memory and wrapping
works with this, so we may as well allow program loading across this
boundary. could be useful for reusing chunks of instruction memory.
sometimes state machines need to be started, restarted, or synchronized
at exactly the same time. the current interface does not allow this but
the hardware does, so let's expose that.
the many individual sets aren't very efficient, and almost no checks
were done to ensure that the configuration written to the hardware was
actually valid. this adresses both of these.
none of these are safe. the x/y functions mangle the fifos, the set
functions require the state machine to be stopped to be in any way safe,
the out functions do both of those things at once. only the jump
instruction is marginally safe, but running this on an active program is
bound to cause problems.
programs contain information we could pull from them directly and use to
validate other configuration of the state machine instead of asking the
user to pull them out and hand them to us bit by bit. unfortunately
programs do not specify how many in or out bits they use, so we can only
handle side-set and wrapping jumps like this. it's still something though.
there's nothing this critical section protects against. both read and
write-to-clear are atomic and don't interfere with other irq futures,
only potentially with setting/clearing an irq flag from an arm core.
neither have ever been synchronized, and both have the same observable
effects under atomic writes and critical sections. (for both setting and
clearing an irq flag observable differences could only happen if the
set/clear happened after the poll read, but before the write. if it's a
clear we observe the same effects as sequencing the clear entirely after
the poll, and if it's a set we observe the same effects as sequencing
the set entirely before the poll)
it's only any good for PioPin because there it follows a pattern of gpio
pin alternate functions being named like that, everything else can just
as well be referred to as `pio::Thing`
this *finally* allows sound implementions of bidirectional transfers
without blocking. the futures previously allowed only a single direction
to be active at any given time, and the dma transfers didn't take a
mutable reference and were thus unsound.
this way we can share irq handling between state machines and common
without having to duplicate the methods. it also lets us give irq flag
access to places without having to dedicate a state machine or the
common instance to those places, which can be very useful to eg trigger
an event and wait for a confirmation using an irq wait object.
we can only have one active waiter for any given irq at any given time.
allowing waits for irqs on state machines bypasses this limitation and
causes lost events for all but the latest waiter for a given irq.
splitting this out also allows us to signal from state machines to other
parts of the application without monopolizing state machine access for
the irq wait, as would be necessary to make irq waiting sound.
move all methods into PioStateMachine instead. the huge trait wasn't
object-safe and thus didn't have any benefits whatsoever except for
making it *slightly* easier to write bounds for passing around state
machines. that would be much better solved with generics-less instances.