1434: rp pio IV (the voyage home) r=Dirbaio a=pennae
this should hopefully be the last entry in this series. after this we'll have a reasonably safe interface to pio, both for configuration and at runtime. pio now looks very much like the other peripherals (though not exactly, seeing how state machines can't be constructed from a config but only have it applied to them later). the generated code for `StateMachine::set_config` is still larger than we'd like (almost 300 bytes at Oz), but it's a great step up in safety from the previous interface at approximately the same code space cost.
Co-authored-by: pennae <github@quasiparticle.net>
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 flag for example permits the following clock tree
configuration on stm32f103r8
let mut config = Config::default();
config.rcc.hse = Some(Hertz(16_000_000));
config.rcc.sys_ck = Some(Hertz(72_000_000));
config.rcc.pclk1 = Some(Hertz(36_000_000));
config.rcc.pclk2 = Some(Hertz(72_000_000));
config.rcc.pllxtpre = true;
Init fails if pllxtpre is false.
1429: rp pio, √9 r=Dirbaio a=pennae
another mix of refactoring and soundness issues. most notably pio pins are now checked for being actually accessible to the pio blocks, are constructible from not just the owned peripherals but refs as well, and have their registrations to the pio block reverted once all state machines and the common block has been dropped.
state machines are now also stopped when dropped, and concurrent rx+tx using dma can finally be done in a sound manner. previously it was possible to do, but allowed users to start two concurrent transfers to the same fifo using different dma channels, which obviously would not have the expected results on average.
Co-authored-by: pennae <github@quasiparticle.net>
1430: Handle SUBGHZSPI as async r=lulf a=ceekdee
For STM32WL, simplify configuration for the use of SUBGHZSPI to perform LoRa operations. Use Rx/Tx DMA on SPI to enable async functionality.
Co-authored-by: ceekdee <taigatensor@gmail.com>
Co-authored-by: Chuck Davis <taigatensor@gmail.com>
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.