913: (embassy-rp): Add DMA implementation r=Dirbaio a=MathiasKoch
This PR adds everything necessary to do peripheral to memory DMA & memory to memory DMA operations.
It also adds async UART read & write, powered by DMA
Co-authored-by: Mathias <mk@blackbird.online>
This fixes the WASM support which was failing due to missing
critical-section implementation. This also upgrades the bindgen
dependency and ensures that tooling works.
It was only useful for doing #[embassy_executor::main(config = "config()")]`. Now that
it's gone, it makes more sense to build the config in main directly.
896: Implement I2C pullup configuration r=lulf a=chemicstry
I wasn't sure if I should put frequency into config struct, so left it separate as in SPI periph.
Also added Copy derives to gpio types, not sure why they weren't?
Co-authored-by: chemicstry <chemicstry@gmail.com>
853: Add embedded_hal_async support for embassy-rp r=Dirbaio a=danbev
This commit adds support for embedded-hal-async to the Embassy
Raspberry PI crate.
Co-authored-by: Daniel Bevenius <daniel.bevenius@gmail.com>
858: embassy-stm32: Simplify time r=Dirbaio a=GrantM11235
- Remove unused `MilliSeconds`, `MicroSeconds`, and `NanoSeconds` types
- Remove `Bps`, `KiloHertz`, and `MegaHertz` types that were only used
for converting to `Hertz`
- Replace all instances of `impl Into<Hertz>` with `Hertz`
- Add `hz`, `khz`, and `mhz` methods to `Hertz`, as well as
free function shortcuts
- Remove `U32Ext` extension trait
Co-authored-by: Grant Miller <GrantM11235@gmail.com>
- Remove unused `MilliSeconds`, `MicroSeconds`, and `NanoSeconds` types
- Remove `Bps`, `KiloHertz`, and `MegaHertz` types that were only used
for converting to `Hertz`
- Replace all instances of `impl Into<Hertz>` with `Hertz`
- Add `hz`, `khz`, and `mhz` methods to `Hertz`, as well as
free function shortcuts
- Remove `U32Ext` extension trait
810: Takes care of power for nRF USB devices r=Dirbaio a=huntc
Modifies the usb-serial example to illustrate how to setup USB for situations where the USB power can be detected and removed.
Gaps:
~~* No support for the nrf-softdevices as yet, although this should be possible via another constructor.~~
* No support for the nrf5340, although this should be possible via USBREG.
The change is tested and appears to work. Some notes:
* There's an existing field named self_powered as a UsbDevice field. It doesn't ever appear to get set. I'm wondering if this field is intended to signal that a device has the nRF VBUS power situation or not. I'm not presently using it.
* The new PowerDetected event is generated on the bus initially in situations where just new is used i.e. without power management, including on STM. We can therefore rely on this event always being generated.
Old description:
~~EnabledUsbDevice is a wrapper around the `UsbDevice` where its enablement is also subject to external events, such as `POWER` events for nRF. It is introduced generically to support other platforms should they also require external signaling for enablement.~~
Co-authored-by: huntc <huntchr@gmail.com>
Eliminated a signal by using a simpler trait method that returns whether VBus power is available. Also includes a UsbSupply that can be signalled for use with the nRF softdevice. Includes the requirement for waiting for power to become available.
EnabledUsbDevice is a wrapper around the UsbDevice where their enablement is also subject to external events, such as POWER events for nRF. It is introduced generically to support other platforms should they also require external signalling for enablement.
817: Added a pubsub channel implementation r=lulf a=diondokter
This is similar to Tokio's Broadcast channel, except that it doesn't allocate.
The publishers and subscribers are dynamic. They use an &dyn channel reference because it's really annoying to have to specify the mutex and const generics every time.
Do we need fully generic types as well?
Co-authored-by: Dion Dokter <diondokter@gmail.com>
Co-authored-by: Dion Dokter <dion@tweedegolf.com>
It currently contains whoever was first to write some code for the crate,
even if many more people have contributed to it later.
The field is "sort of" deprecated, it was made optional recently:
https://rust-lang.github.io/rfcs/3052-optional-authors-field.html
Due the the reasons listed there I believe removing it is better than
setting it to generic fluff like "The Embassy contributors".
806: Add embassy-cortex-m crate. r=Dirbaio a=Dirbaio
- 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`.
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
- 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`.
I've renamed the channel module for the MPMC as mpmc. There was a previous debate about this, but I feel that the strategy here avoids importing `channel::channel`. The change leaves `signal::Signal`, but I think that's ok. It is all a bit subjective of course. The bottom line for me is that I really like the term mpmc - it means something to me and aligns with broader naming e.g. in Tokio.
Following the project's decision that "leak unsafe" APIs are not marked as "unsafe",
update PeripheralMutex to accept non-'static state without unsafe.
Fixes#801
781: embassy-net v2 r=Dirbaio a=Dirbaio
- No more `dyn`
- It's no longer a global singleton, you can create muliple net stacks at once.
- You can't tear them down though, the Device it still has to be `'static` due to restrictions with smoltcp's "fake GAT" in the Device trait. :(
- Removed `_embassy_rand` hack, random seed is passed on creation.
785: stm32: g0: add PLL clock source r=Dirbaio a=willglynn
STM32G0 SYSCLK can be sourced from PLLRCLK. Given that the HSI runs at 16 MHz and the HSE range is 4-48 MHz, the PLL is the only way to reach 64 MHz. This commit adds `ClockSrc::PLL`.
The PLL sources from either HSI16 or HSE, divides it by `m`, and locks its VCO to multiple `n`. It then divides the VCO by `r`, `p`, and `q` to produce up to three associated clock signals:
* PLLRCLK is one of the inputs on the SYSCLK mux. This is the main reason the user will configure the PLL, so `r` is mandatory and the output is enabled unconditionally.
* PLLPCLK is available as a clock source for the ADC and I2S peripherals, so `p` is optional and the output is conditional.
* PLLQCLK exists only on STM32G0B0xx, and exists only to feed the MCO and MCO2 peripherals, so `q` is optional and the output is conditional.
When the user specifies `ClockSrc::PLL(PllConfig)`, `rcc::init()` calls `PllConfig::init()` which initializes the PLL per [RM0454]. It disables the PLL, waits for it to stop, enables the source oscillator, configures the PLL, waits for it to lock, and then enables the appropriate outputs. `rcc::init()` then switches the clock source to PLLRCLK.
`rcc::init()` is now also resonsible for calculating and setting flash wait states. SYSCLCK < 24 MHz is fine in the reset state, but 24-48 MHz requires waiting 1 cycle and 48-64 MHz requires waiting 2 cycles. (This was likely a blocker for anyone using HSE >= 24 MHz, with or without the PLL.) Flash accesses are now automatically slowed down as needed before changing the clock source, and sped up as permitted after changing the clock source. The number of flash wait states also determines if flash prefetching will be profitable, so that is now handled automatically too.
[RM0454]: https://www.st.com/resource/en/reference_manual/rm0454-stm32g0x0-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Co-authored-by: Will Glynn <will@willglynn.com>
783: Reimplement BufRead for BufferedUart r=Dirbaio a=chemicstry
The `AsyncBufRead` implementation for `BufferedUart` was removed in https://github.com/embassy-rs/embassy/pull/752, this PR reimplements it from `embedded-io`. This allows reading `BufferedUart` without copying slices.
Co-authored-by: chemicstry <chemicstry@gmail.com>
776: Automatically set ADC clock prescaler on v2 ADC to respect max frequency r=Dirbaio a=matoushybl
Co-authored-by: Matous Hybl <hyblmatous@gmail.com>
763: Misc USB improvements r=Dirbaio a=Dirbaio
The "simplify control in/out handlng" commit gives a -2kb code size improvement.
766: Make usb_serial examples work on windows r=Dirbaio a=timokroeger
Windows shows `error 10` when using CDC ACM on non composite devices.
Workaround is to use IADS:
https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Co-authored-by: Timo Kröger <timo.kroeger@hitachienergy.com>
The replacement is `embassy-usb`. There's a WIP driver for stm32 USBD in #709,
there's no WIP driver for stm32 USB_OTG. This means we're left without
USB_OTG support for now.
Reason for removing is I'm going to soon remove `embassy::io`, and
USB uses it. I don't want to spend time maintaining "dead" code
that is going to be removed. Volunteers welcome, either to update
old USB to the new IO, or write a USB_OTG driver fo the new USB.
743: Add PLL config support for F2 r=Dirbaio a=Gekkio
- minor changes to make the F2 RCC API a bit more flexible
- low-level PLL config with assertions based on datasheet specs. It shouldn't be very difficult to later add a "reverse API" where you pass the clocks you want to a function and it generates a `PLLConfig` struct for you
- PLL API tested on my custom board with 12 MHz HSE as source for PLL to generate max clocks for SYSCLK/AHB/APB/APB1/PLL48
- the example *should* work but is untested since I don't have the Nucleo board 😞
Co-authored-by: Joonas Javanainen <joonas.javanainen@gmail.com>
SMI Ethernet PHYs all share a common base set of registers that can do
90% of all tasks. The LAN8742 driver used some vendor-specific
registers to check link negotiation status, but the need for that was
debatable, so I migrated it to a generic driver instead, anybody who
wants extra functionality can copy it and impl their own on top of it.
* Less generics on bootloader. Keep PAGE_SIZE as a common multiple of
DFU and ACTIVE page sizes.
* Document restriction
* Add unit tests for different page sizes
* Add flash drivers for L0, L1, L4, WB and WL. Not tested for WB, but
should be similar to WL.
* Add embassy-boot-stm32 for bootloading on STM32.
* Add flash examples and bootloader examples
* Update stm32-data
734: executor: Add `Spawner::for_current_executor`. r=Dirbaio a=Dirbaio
This is needed to spawn non-Send tasks in an InterruptExecutor, after the fixes in #730 .
`@matoushybl` could you check if this works for your use case?
735: stm32: add stm32u5 GPDMA, SPIv4 support, add HIL tests. r=Dirbaio a=Dirbaio
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
The initial closure is not actually called in the interrupt, so this is
illegally sending non-Send futures to the interrupt.
Remove the closure, and return a SendSpawner instead.
* Add FlashProvider and FlashConfig traits to define flash
characteristics
* Use traits in bootloader to retrieve flash handles and for
copying data between flash instances
* Add convenience implementations for using a single flash instance.
* Adds implementations of embedded-storage and embedded-storage-async
for QSPI
* Add blocking implementations of QSPI
* Use blocking implementation in new() and embedded-storage impls
* Use async implementation in embedded-storage-async impls
* Add FLASH_SIZE const generic parameter
* Own IRQ in Qspi to disable it on drop
- Renamed structs to HidReaderWriter, HidReader, HidWriter.
- Removed unused const generics on `State`.
- Simplified generics on `HidReaderWriter`.
The class type previously was `HidClass<D, Driver<'d, USBD>, ReportReader<'d, Driver<'d, USBD>, OUT_N>, IN_N>`
It's now `HidClass<D, Driver<'d, USBD>, IN_N, OUT_N>`. Note that the driver type `Driver<'d, USBD>` is no longer repeated.
- Constructors are now: `HidWriter::new()` for IN-only, `HidReaderWriter::new()` for IN+OUT. No complicated bounds.
- HidReaderWriter has all the methods from HidReader, HidWriter.
711: Add DeviceStateHandler, DeviceCommand channel, and remote wakeup support r=Dirbaio a=alexmoon
Apologies for the size of this PR. Once I started getting into the Vbus power management side of my device I found a couple of areas of functionality missing from embassy-usb. Specifically, I need the application to be able to respond to changes in the USB device state in order to properly control the amount of power I'm drawing from Vbus. I also wanted to enable remote wakeup support for my device.
In order to enable device state monitoring, I've created a `DeviceStateHandler` trait and made it possible to pass in an optional reference a handler implementing that trait when creating the `UsbDeviceBuilder`.
Remote wakeup required a way to send commands to the bus which is exclusively owned by the `UsbDevice::run` method. This is the same problem we were discussing for enabling/disabling the device on Vbus power events. My solution is to allow an optional `Channel` to be provided to the `UsbDeviceBuilder` (via `UsbDeviceBuilder::new_with_channel`), allowing the application to send commands into the `run` method. Right now it supports enable, disable and remote wakeup commands.
Since there's now a way to dynamically enable and disable the device, I also added `Config::start_enabled` to control whether or not the `UsbDevice` should start in the enabled state. That also allowed me to make `UsbDeviceBuilder::build` sync again and move enabling the bus into `UsbDevice::run`.
This led to a few driver changes:
1. `Driver::enable` became `Driver::into_bus`
2. `Bus::enable`, `Bus::disable`, and `Bus::remote_wakeup` were added
3. I removed `Bus::reset`, `Bus::suspend`, and `Bus::resume` because they were only ever called based on the result of `Bus::poll`. It made more sense to me to have `Bus::poll` handle the driver-specific state management itself.
I've updated the `usb_hid_keyboard` example to take advantage of all these additional features.
Let me know what you think.
Thanks!
Co-authored-by: alexmoon <alex.r.moon@gmail.com>
714: add more clock options for l4 and l5 r=Dirbaio a=ant32
- added an assert so it panics if pll48div is not 48Mhz
- added MSI as a clock source for PLL
- removed hsi48 option for MCUs mentioned in l4 rcc presentation
- copied some code from l4 to l5, but don't have a way of testing it.
Co-authored-by: Philip A Reimer <antreimer@gmail.com>
657: Async usb stack r=Dirbaio a=Dirbaio
TODO
- [x] Make it work on nRF
- [x] Add a way for classes to handle their own EP0 control requests - thanks `@alexmoon!`
- [x] Handle CONTROL OUT requests with data.
- [ ] Impl AsyncRead/AsyncWrite for CDC ACM -- will do later, it's not trivial
- [x] Cleanup unwraps/asserts/panics
- [x] Cleanup logs (make everything trace/debug, not info)
- [ ] Port synopsys-usb-otg
- [ ] Port stm32-usbd
- [ ] Add more classes? HID, MSD?
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Co-authored-by: alexmoon <alex.r.moon@gmail.com>
696: Add async Mutex. r=Dirbaio a=Dirbaio
What it says on the tin :)
It allows sharing data between tasks when you want to `.await` stuff while holding it locked.
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
- Allow initializing in a static, without Forever.
- Remove ability to close, since in embedded enviromnents channels usually live forever and don't get closed.
- Remove MPSC restriction, it's MPMC now. Rename "mpsc" to "channel".
- `Sender` and `Receiver` are still available if you want to enforce a piece of code only has send/receive access, but are optional: you can send/receive directly into the Channel if you want.
* Keeps existing API for usart, but wraps it in Tx and Rx sub-types
* Adds split() method similar to nRF for getting indepdendent TX and RX
parts
* Implements e-h traits for TX and RX types
* Add stm32h7 example
648: Fix nRF Saadc continuous sampling r=Dirbaio a=huntc
Starting the sampling task prior to starting the SAADC peripheral can lead to unexpected buffer behaviour with multiple channels. We now provide an init callback at the point where the SAADC has started for the first time. This callback can be used to kick off sampling via PPI.
We also need to trigger the SAADC to start sampling the next buffer when the previous one is ended so that we do not drop samples - the major benefit of double buffering.
Given these additional tasks, we now simplify the API by passing in the TIMER and two PPI channels.
As a bonus, we provide an async `calibrate` method as it is recommended to use before starting up the sampling.
The example has been updated to illustrate these new features along with the simplified API.
The changes here have been tested on my nRF52840-DK.
656: stm32: Refactor DMA interrupts r=Dirbaio a=GrantM11235
Previously, every dma interrupt handler called the same `on_irq`
function which had to check the state of every dma channel.
Now, each dma interrupt handler only calls an `on_irq` method for its
corresponding channel or channels.
Co-authored-by: huntc <huntchr@gmail.com>
Co-authored-by: Grant Miller <GrantM11235@gmail.com>
Starting the sampling task prior to starting the SAADC peripheral can lead to unexpected buffer behaviour with multiple channels. We now provide an init callback at the point where the SAADC has started for the first time. This callback can be used to kick off sampling via PPI.
We also need to trigger the SAADC to start sampling the next buffer when the previous one is ended so that we do not drop samples - the major benefit of double buffering.
As a bonus we provide a calibrate method as it is recommended to use before starting up the sampling.
The example has been updated to illustrate these new features.
608: stm32f4: add adc + example r=Dirbaio a=ain101
Example tested on stm32f407vg Discovery Board.
minimal adc: no vref, dma, complex sequence
Co-authored-by: Frederik <frederik@frederik.at>
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>
607: stm32: Add standard crate-wide macros for pin/dma traits r=Dirbaio a=Dirbaio
All drivers will declare the traits using these macros.
This has a few implications:
- ALL drivers will have an Instance trait, even for drivers that usually have only one instance (for example crc, eth)
- It's no longer possible to have a fn configure() in pin traits, drivers will have to do that some other way
In the future, build.rs will generate all the impls instead of macrotables.
Pin/Dma traits are no longer explicitly sealed, since gpio::Pin and dma::Channel are already sealed, which has the same effect. This means the `af_num()` and `request()` funcs are now public, but IMO that's okay, they're unlikely to change.
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Embassy-boot is a simple bootloader that works together with an
application to provide firmware update capabilities with a minimal risk.
The bootloader consists of a platform-independent part, which implements
the swap algorithm, and a platform-dependent part (currently only for
nRF) that provides addition functionality such as watchdog timers
softdevice support.
602: Add stm32 USB OTG peripherals r=Dirbaio a=chemicstry
Fixes#557. This is similar to #580, but for synopsys IP.
I could add examples to other chips, but I have no way of testing them. The F4 example is tested and working.
Co-authored-by: chemicstry <chemicstry@gmail.com>
591: PWM WS2812B example and flexible sequence config r=Dirbaio a=huntc
I've permitted the PWM sequences to be mutated on stopping the PWM by associating them with a new `SingleSequencer` structure. This is so that we can perform effects on the LEDs (and other use-cases, I'm sure!). The example has been updated to illustrate the use of this by flashing a WS2812B LED.
There's also a `Sequencer` structure for more sophisticated PWM interactions, along with a `pwm_double_sequence` example to illustrate.
These changes should make it possible to attain all of the nRF PWM functionality available.
Co-authored-by: huntc <huntchr@gmail.com>
This approach owns the sequence buffers which, while introducing an extra move, it eliminates the need to guard the lifetime of the sequence buffer. Given ownership, the buffer will be retained until the PWM sequence task is stopped.
Demonstrates how to set the colour of a WS2812B to blue using PWM, and the use of multiple sequences along with their own config. This required an API change.
I had introduced a small bug in my last PR where I assigned the sequence before stopping the PWM. I now stop the PWM before doing that now.
Also, corrected a math comment.
585: Permit many sequences to be passed r=huntc a=huntc
Sequences are now passed in via the start method to avoid having to stop the PWM and restart it. Sequences continue to be constrained with the same lifetime of the Pwm struct itself. The pwm_sequence example has been extended to illustrate multiple sequences being passed around.
Co-authored-by: huntc <huntchr@gmail.com>
Sequences are now passed in via the start method to avoid having to stop the PWM and restart it. Sequences continue to be constrained with the same lifetime of the Pwm object itself. The pwm_sequence example has been extended to illustrate multiple sequences being passed around.