Docs say "PSEL.RXD, PSEL.RTS, PSEL.RTS, and PSEL.TXD must only be configured when the UARTE is disabled."
For some reason nrf52 doesn't care but nrf91 does.
- Move typelevel interrupts to a special-purpose mod: `embassy_xx::interrupt::typelevel`.
- Reexport the PAC interrupt enum in `embassy_xx::interrupt`.
This has a few advantages:
- The `embassy_xx::interrupt` module is now more "standard".
- It works with `cortex-m` functions for manipulating interrupts, for example.
- It works with RTIC.
- the interrupt enum allows holding value that can be "any interrupt at runtime", this can't be done with typelevel irqs.
- When "const-generics on enums" is stable, we can remove the typelevel interrupts without disruptive changes to `embassy_xx::interrupt`.
> dirbaio: so I was checking how zephyr does UARTE RX on nRF
> dirbaio: because currently we have the ugly "restart DMA on line idle to flush it" hack
> dirbaio: because according to the docs "For each byte received over the RXD line, an RXDRDY event will be generated. This event is likely to occur before the corresponding data has been transferred to Data RAM."
> dirbaio: so as I understood it, the only way to guarantee the data is actually transferred to RAM is to stop+restart DMA
> dirbaio: well, guess what?
> dirbaio: they just count RXDRDY's, and process that amount of data without restarting DMA
> dirbaio: with a timer configured as counter https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/serial/uart_nrfx_uarte.c#L650-L692
> dirbaio: 🤔🤷⁉️
> dirbaio: someone saying you can do the "hook up rxdrdy to a counter" trick, someone else saying it's wrong 🤪https://devzone.nordicsemi.com/f/nordic-q-a/28420/uarte-in-circular-mode
So we're going to do just that!
- BufferedUarte is lock-free now. No PeripheralMutex.
- The "restart DMA on line idle to flush it" hack is GONE. This means
- It'll work correctly without RTS/CTS now.
- It'll have better throughput when using RTS/CTS.
It's a perfectly fine thing to do, should be just a noop. Erroring is
really annoying when you're writing a payload to uart that might
be zero-length or not.
This commit removes some of the code duplication for UarteWithIdle at the expense of requiring a split. As the example illustrates though, this expense seems worth the benefit in terms of maintenance, and the avoidance of copying over methods. My main motivation for this commit was actually due to the `event_endtx` method not having been copied across.
Old code used `cfg_if!` because rustc still parses code inside disabled cfg's, and Rust stable at that time couldn't parse the new GAT where-clause location. This is not the case anymore.
Allow creating UarteRx/UarteTx directly. This allows using uart unidirectionally
(rx-only or tx-only), without having to 'waste' a pin for the unused direction.
- Move Interrupt and InterruptExecutor from `embassy` to `embassy-cortex-m`.
- Move Unborrow from `embassy` to `embassy-hal-common` (nothing in `embassy` requires it anymore)
- Move PeripheralMutex from `embassy-hal-common` to `embassy-cortex-m`.
613: Rust stable support r=Dirbaio a=Dirbaio
This PR adds (limited) stable Rust support!
The drawbacks are:
- No `#[embassy::task]`, `#[embassy::main]`. (requires `type_alias_impl_trait`). You have to manually allocate the tasks somewhere they'll live forever. See [example](https://github.com/embassy-rs/embassy/blob/master/examples/nrf/src/bin/raw_spawn.rs)
- No async trait impls (requires GATs). Note that the full API surface of HALs is still available through inherent methods: #552#581
- Some stuff is not constructible in const (requires `const_fn_trait_bound`), although there's an (ugly) workaround for the generic `Mutex`.
So it's not that bad in the end, it's fully usable for shipping production-ready firmwares. We'll still recommend nightly as the default, until GATs and `type_alias_impl_trait` are stable.
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>