aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.github/ci/doc.sh1
-rw-r--r--.vscode/settings.json5
-rw-r--r--README.md7
-rwxr-xr-xci.sh14
-rw-r--r--cyw43-pio/src/lib.rs22
-rw-r--r--docs/pages/overview.adoc1
-rw-r--r--embassy-boot-nrf/src/lib.rs4
-rw-r--r--embassy-boot-rp/src/lib.rs3
-rw-r--r--embassy-executor-macros/src/macros/task.rs15
-rw-r--r--embassy-executor/Cargo.toml95
-rw-r--r--embassy-executor/README.md27
-rw-r--r--embassy-executor/build.rs92
-rw-r--r--embassy-executor/src/lib.rs196
-rw-r--r--embassy-executor/tests/ui.rs1
-rw-r--r--embassy-executor/tests/ui/type_error.rs8
-rw-r--r--embassy-executor/tests/ui/type_error.stderr7
-rw-r--r--embassy-hal-internal/src/lib.rs2
-rw-r--r--embassy-hal-internal/src/macros.rs38
-rw-r--r--embassy-hal-internal/src/peripheral.rs151
-rw-r--r--embassy-mspm0/Cargo.toml132
-rw-r--r--embassy-mspm0/build.rs802
-rw-r--r--embassy-mspm0/build_common.rs94
-rw-r--r--embassy-mspm0/src/fmt.rs270
-rw-r--r--embassy-mspm0/src/gpio.rs1071
-rw-r--r--embassy-mspm0/src/int_group/c110x.rs25
-rw-r--r--embassy-mspm0/src/int_group/g350x.rs51
-rw-r--r--embassy-mspm0/src/int_group/g351x.rs52
-rw-r--r--embassy-mspm0/src/int_group/l130x.rs46
-rw-r--r--embassy-mspm0/src/int_group/l222x.rs49
-rw-r--r--embassy-mspm0/src/lib.rs119
-rw-r--r--embassy-mspm0/src/time_driver.rs426
-rw-r--r--embassy-mspm0/src/timer.rs48
-rw-r--r--embassy-nrf/src/buffered_uarte.rs186
-rw-r--r--embassy-nrf/src/egu.rs11
-rw-r--r--embassy-nrf/src/gpio.rs39
-rw-r--r--embassy-nrf/src/gpiote.rs49
-rw-r--r--embassy-nrf/src/i2s.rs68
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--embassy-nrf/src/nfct.rs9
-rw-r--r--embassy-nrf/src/nvmc.rs8
-rw-r--r--embassy-nrf/src/pdm.rs26
-rw-r--r--embassy-nrf/src/ppi/dppi.rs16
-rw-r--r--embassy-nrf/src/ppi/mod.rs76
-rw-r--r--embassy-nrf/src/ppi/ppi.rs16
-rw-r--r--embassy-nrf/src/pwm.rs159
-rw-r--r--embassy-nrf/src/qdec.rs36
-rwxr-xr-xembassy-nrf/src/qspi.rs24
-rw-r--r--embassy-nrf/src/radio/ble.rs8
-rw-r--r--embassy-nrf/src/radio/ieee802154.rs9
-rw-r--r--embassy-nrf/src/radio/mod.rs5
-rw-r--r--embassy-nrf/src/rng.rs12
-rw-r--r--embassy-nrf/src/saadc.rs77
-rw-r--r--embassy-nrf/src/spim.rs60
-rw-r--r--embassy-nrf/src/spis.rs84
-rw-r--r--embassy-nrf/src/temp.rs9
-rw-r--r--embassy-nrf/src/timer.rs18
-rw-r--r--embassy-nrf/src/twim.rs16
-rw-r--r--embassy-nrf/src/twis.rs16
-rw-r--r--embassy-nrf/src/uarte.rs124
-rw-r--r--embassy-nrf/src/usb/mod.rs16
-rw-r--r--embassy-nrf/src/wdt.rs30
-rw-r--r--embassy-nxp/src/gpio.rs35
-rw-r--r--embassy-nxp/src/lib.rs2
-rw-r--r--embassy-nxp/src/pint.rs18
-rw-r--r--embassy-rp/src/adc.rs36
-rw-r--r--embassy-rp/src/bootsel.rs21
-rw-r--r--embassy-rp/src/clocks.rs25
-rw-r--r--embassy-rp/src/dma.rs33
-rw-r--r--embassy-rp/src/flash.rs23
-rw-r--r--embassy-rp/src/gpio.rs41
-rw-r--r--embassy-rp/src/i2c.rs34
-rw-r--r--embassy-rp/src/i2c_slave.rs11
-rw-r--r--embassy-rp/src/lib.rs2
-rw-r--r--embassy-rp/src/multicore.rs4
-rw-r--r--embassy-rp/src/pio/mod.rs18
-rw-r--r--embassy-rp/src/pio_programs/hd44780.rs24
-rw-r--r--embassy-rp/src/pio_programs/i2s.rs39
-rw-r--r--embassy-rp/src/pio_programs/onewire.rs3
-rw-r--r--embassy-rp/src/pio_programs/pwm.rs4
-rw-r--r--embassy-rp/src/pio_programs/rotary_encoder.rs5
-rw-r--r--embassy-rp/src/pio_programs/stepper.rs9
-rw-r--r--embassy-rp/src/pio_programs/uart.rs45
-rw-r--r--embassy-rp/src/pio_programs/ws2812.rs15
-rw-r--r--embassy-rp/src/pwm.rs80
-rw-r--r--embassy-rp/src/rtc/mod.rs10
-rw-r--r--embassy-rp/src/spi.rs136
-rw-r--r--embassy-rp/src/trng.rs10
-rw-r--r--embassy-rp/src/uart/buffered.rs66
-rw-r--r--embassy-rp/src/uart/mod.rs168
-rw-r--r--embassy-rp/src/usb.rs7
-rw-r--r--embassy-rp/src/watchdog.rs18
-rw-r--r--embassy-stm32-wpan/src/lib.rs8
-rw-r--r--embassy-stm32/build.rs21
-rw-r--r--embassy-stm32/src/adc/c0.rs11
-rw-r--r--embassy-stm32/src/adc/f1.rs7
-rw-r--r--embassy-stm32/src/adc/f3.rs8
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs7
-rw-r--r--embassy-stm32/src/adc/g4.rs17
-rw-r--r--embassy-stm32/src/adc/mod.rs15
-rw-r--r--embassy-stm32/src/adc/ringbuffered_v2.rs10
-rw-r--r--embassy-stm32/src/adc/u5_adc4.rs19
-rw-r--r--embassy-stm32/src/adc/v1.rs6
-rw-r--r--embassy-stm32/src/adc/v2.rs7
-rw-r--r--embassy-stm32/src/adc/v3.rs11
-rw-r--r--embassy-stm32/src/adc/v4.rs11
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs13
-rw-r--r--embassy-stm32/src/can/fdcan.rs16
-rw-r--r--embassy-stm32/src/cordic/mod.rs30
-rw-r--r--embassy-stm32/src/crc/v1.rs11
-rw-r--r--embassy-stm32/src/crc/v2v3.rs9
-rw-r--r--embassy-stm32/src/cryp/mod.rs885
-rw-r--r--embassy-stm32/src/dac/mod.rs405
-rw-r--r--embassy-stm32/src/dcmi.rs267
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs44
-rw-r--r--embassy-stm32/src/dma/gpdma.rs28
-rw-r--r--embassy-stm32/src/dma/mod.rs31
-rw-r--r--embassy-stm32/src/dma/util.rs28
-rw-r--r--embassy-stm32/src/dsihost.rs14
-rw-r--r--embassy-stm32/src/dts/mod.rs9
-rw-r--r--embassy-stm32/src/eth/mod.rs3
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs48
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs112
-rw-r--r--embassy-stm32/src/exti.rs35
-rw-r--r--embassy-stm32/src/flash/asynch.rs7
-rw-r--r--embassy-stm32/src/flash/common.rs9
-rw-r--r--embassy-stm32/src/flash/f4.rs11
-rw-r--r--embassy-stm32/src/fmc.rs23
-rw-r--r--embassy-stm32/src/gpio.rs43
-rw-r--r--embassy-stm32/src/hash/mod.rs294
-rw-r--r--embassy-stm32/src/hrtim/mod.rs26
-rw-r--r--embassy-stm32/src/hrtim/traits.rs4
-rw-r--r--embassy-stm32/src/hsem/mod.rs16
-rw-r--r--embassy-stm32/src/hspi/mod.rs164
-rw-r--r--embassy-stm32/src/i2c/mod.rs28
-rw-r--r--embassy-stm32/src/i2c/v2.rs9
-rw-r--r--embassy-stm32/src/i2s.rs87
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/lptim/mod.rs3
-rw-r--r--embassy-stm32/src/lptim/pwm.rs24
-rw-r--r--embassy-stm32/src/lptim/timer/mod.rs8
-rw-r--r--embassy-stm32/src/ltdc.rs68
-rw-r--r--embassy-stm32/src/macros.rs22
-rw-r--r--embassy-stm32/src/opamp.rs27
-rw-r--r--embassy-stm32/src/ospi/mod.rs224
-rw-r--r--embassy-stm32/src/qspi/mod.rs96
-rw-r--r--embassy-stm32/src/rcc/c0.rs10
-rw-r--r--embassy-stm32/src/rcc/g0.rs10
-rw-r--r--embassy-stm32/src/rcc/mco.rs15
-rw-r--r--embassy-stm32/src/rng.rs11
-rw-r--r--embassy-stm32/src/rtc/mod.rs4
-rw-r--r--embassy-stm32/src/sai/mod.rs71
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs231
-rw-r--r--embassy-stm32/src/spdifrx/mod.rs19
-rw-r--r--embassy-stm32/src/spi/mod.rs87
-rw-r--r--embassy-stm32/src/timer/complementary_pwm.rs14
-rw-r--r--embassy-stm32/src/timer/input_capture.rs15
-rw-r--r--embassy-stm32/src/timer/low_level.rs8
-rw-r--r--embassy-stm32/src/timer/mod.rs4
-rw-r--r--embassy-stm32/src/timer/pwm_input.rs24
-rw-r--r--embassy-stm32/src/timer/qei.rs14
-rw-r--r--embassy-stm32/src/timer/simple_pwm.rs42
-rw-r--r--embassy-stm32/src/tsc/mod.rs5
-rw-r--r--embassy-stm32/src/tsc/pin_groups.rs14
-rw-r--r--embassy-stm32/src/tsc/tsc.rs22
-rw-r--r--embassy-stm32/src/ucpd.rs22
-rw-r--r--embassy-stm32/src/usart/buffered.rs82
-rw-r--r--embassy-stm32/src/usart/mod.rs172
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs6
-rw-r--r--embassy-stm32/src/usb/otg.rs76
-rw-r--r--embassy-stm32/src/usb/usb.rs33
-rw-r--r--embassy-stm32/src/wdg/mod.rs9
-rw-r--r--embassy-sync/src/blocking_mutex/mod.rs17
-rw-r--r--embassy-sync/src/zerocopy_channel.rs2
-rw-r--r--embassy-usb/src/class/cdc_acm.rs12
-rw-r--r--embassy-usb/src/class/uac1/speaker.rs2
-rw-r--r--examples/boot/application/nrf/Cargo.toml2
-rw-r--r--examples/boot/application/rp/Cargo.toml2
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml2
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml2
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml2
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml2
-rw-r--r--examples/boot/application/stm32wb-dfu/Cargo.toml2
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml2
-rw-r--r--examples/lpc55s69/Cargo.toml2
-rw-r--r--examples/mspm0c1104/.cargo/config.toml11
-rw-r--r--examples/mspm0c1104/Cargo.toml32
-rw-r--r--examples/mspm0c1104/README.md27
-rw-r--r--examples/mspm0c1104/build.rs35
-rw-r--r--examples/mspm0c1104/memory.x5
-rw-r--r--examples/mspm0c1104/src/bin/blinky.rs25
-rw-r--r--examples/mspm0c1104/src/bin/button.rs33
-rw-r--r--examples/mspm0g3507/.cargo/config.toml9
-rw-r--r--examples/mspm0g3507/Cargo.toml21
-rw-r--r--examples/mspm0g3507/README.md27
-rw-r--r--examples/mspm0g3507/build.rs35
-rw-r--r--examples/mspm0g3507/memory.x6
-rw-r--r--examples/mspm0g3507/src/bin/blinky.rs25
-rw-r--r--examples/mspm0g3507/src/bin/button.rs33
-rw-r--r--examples/mspm0g3519/.cargo/config.toml9
-rw-r--r--examples/mspm0g3519/Cargo.toml21
-rw-r--r--examples/mspm0g3519/README.md27
-rw-r--r--examples/mspm0g3519/build.rs35
-rw-r--r--examples/mspm0g3519/memory.x6
-rw-r--r--examples/mspm0g3519/src/bin/blinky.rs25
-rw-r--r--examples/mspm0g3519/src/bin/button.rs33
-rw-r--r--examples/mspm0l1306/.cargo/config.toml9
-rw-r--r--examples/mspm0l1306/Cargo.toml21
-rw-r--r--examples/mspm0l1306/README.md27
-rw-r--r--examples/mspm0l1306/build.rs35
-rw-r--r--examples/mspm0l1306/memory.x5
-rw-r--r--examples/mspm0l1306/src/bin/blinky.rs25
-rw-r--r--examples/mspm0l1306/src/bin/button.rs33
-rw-r--r--examples/mspm0l2228/.cargo/config.toml9
-rw-r--r--examples/mspm0l2228/Cargo.toml21
-rw-r--r--examples/mspm0l2228/README.md27
-rw-r--r--examples/mspm0l2228/build.rs35
-rw-r--r--examples/mspm0l2228/memory.x6
-rw-r--r--examples/mspm0l2228/src/bin/blinky.rs25
-rw-r--r--examples/mspm0l2228/src/bin/button.rs33
-rw-r--r--examples/nrf51/Cargo.toml2
-rw-r--r--examples/nrf52810/Cargo.toml2
-rw-r--r--examples/nrf52840-rtic/src/bin/blinky.rs4
-rw-r--r--examples/nrf52840/Cargo.toml2
-rw-r--r--examples/nrf52840/src/bin/channel_sender_receiver.rs7
-rw-r--r--examples/nrf52840/src/bin/pdm_continuous.rs4
-rw-r--r--examples/nrf52840/src/bin/qspi_lowpower.rs14
-rw-r--r--examples/nrf52840/src/bin/saadc.rs2
-rw-r--r--examples/nrf52840/src/bin/saadc_continuous.rs12
-rw-r--r--examples/nrf52840/src/bin/twim_lowpower.rs8
-rw-r--r--examples/nrf5340/Cargo.toml2
-rw-r--r--examples/nrf54l15/Cargo.toml2
-rw-r--r--examples/nrf9151/ns/Cargo.toml2
-rw-r--r--examples/nrf9151/s/Cargo.toml2
-rw-r--r--examples/nrf9160/Cargo.toml2
-rw-r--r--examples/nrf9160/src/bin/modem_tcp_client.rs8
-rw-r--r--examples/rp/Cargo.toml4
-rw-r--r--examples/rp/src/bin/adc_dma.rs4
-rw-r--r--examples/rp/src/bin/assign_resources.rs7
-rw-r--r--examples/rp/src/bin/blinky_two_channels.rs4
-rw-r--r--examples/rp/src/bin/blinky_two_tasks.rs4
-rw-r--r--examples/rp/src/bin/orchestrate_tasks.rs2
-rw-r--r--examples/rp/src/bin/pio_async.rs8
-rw-r--r--examples/rp/src/bin/pio_dma.rs6
-rw-r--r--examples/rp/src/bin/pio_i2s.rs7
-rw-r--r--examples/rp/src/bin/pwm.rs5
-rw-r--r--examples/rp/src/bin/shared_bus.rs6
-rw-r--r--examples/rp/src/bin/zerocopy.rs9
-rw-r--r--examples/rp235x/Cargo.toml4
-rw-r--r--examples/rp235x/src/bin/adc_dma.rs4
-rw-r--r--examples/rp235x/src/bin/assign_resources.rs7
-rw-r--r--examples/rp235x/src/bin/blinky_two_channels.rs4
-rw-r--r--examples/rp235x/src/bin/blinky_two_tasks.rs4
-rw-r--r--examples/rp235x/src/bin/pio_async.rs4
-rw-r--r--examples/rp235x/src/bin/pio_dma.rs6
-rw-r--r--examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs6
-rw-r--r--examples/rp235x/src/bin/pwm.rs5
-rw-r--r--examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs2
-rw-r--r--examples/rp235x/src/bin/shared_bus.rs6
-rw-r--r--examples/rp235x/src/bin/zerocopy.rs9
-rw-r--r--examples/std/Cargo.toml2
-rw-r--r--examples/stm32c0/src/bin/adc.rs5
-rw-r--r--examples/stm32f0/src/bin/button_controlled_blink.rs7
-rw-r--r--examples/stm32f1/src/bin/input_capture.rs4
-rw-r--r--examples/stm32f1/src/bin/pwm_input.rs4
-rw-r--r--examples/stm32f1/src/bin/usb_serial.rs2
-rw-r--r--examples/stm32f334/src/bin/opamp.rs2
-rw-r--r--examples/stm32f4/Cargo.toml2
-rw-r--r--examples/stm32f4/src/bin/can.rs2
-rw-r--r--examples/stm32f4/src/bin/dac.rs3
-rw-r--r--examples/stm32f4/src/bin/flash_async.rs8
-rw-r--r--examples/stm32f4/src/bin/input_capture.rs4
-rw-r--r--examples/stm32f4/src/bin/pwm_input.rs4
-rw-r--r--examples/stm32f4/src/bin/ws2812_pwm.rs2
-rw-r--r--examples/stm32f469/Cargo.toml2
-rw-r--r--examples/stm32f7/Cargo.toml2
-rw-r--r--examples/stm32f7/src/bin/can.rs2
-rw-r--r--examples/stm32g0/src/bin/adc_dma.rs2
-rw-r--r--examples/stm32g0/src/bin/input_capture.rs4
-rw-r--r--examples/stm32g0/src/bin/pwm_input.rs4
-rw-r--r--examples/stm32g4/src/bin/adc_dma.rs2
-rw-r--r--examples/stm32h5/Cargo.toml2
-rw-r--r--examples/stm32h5/src/bin/cordic.rs6
-rw-r--r--examples/stm32h5/src/bin/stop.rs4
-rw-r--r--examples/stm32h7/Cargo.toml2
-rw-r--r--examples/stm32h7/src/bin/adc_dma.rs2
-rw-r--r--examples/stm32h7/src/bin/dac.rs3
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs8
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs14
-rw-r--r--examples/stm32h723/Cargo.toml2
-rw-r--r--examples/stm32h723/src/bin/spdifrx.rs34
-rw-r--r--examples/stm32h735/Cargo.toml2
-rw-r--r--examples/stm32h755cm4/Cargo.toml2
-rw-r--r--examples/stm32h755cm7/Cargo.toml2
-rw-r--r--examples/stm32h7b0/Cargo.toml2
-rw-r--r--examples/stm32h7rs/Cargo.toml2
-rw-r--r--examples/stm32l4/Cargo.toml2
-rw-r--r--examples/stm32l4/src/bin/dac.rs3
-rw-r--r--examples/stm32l4/src/bin/dac_dma.rs8
-rw-r--r--examples/stm32l432/Cargo.toml2
-rw-r--r--examples/stm32l5/Cargo.toml2
-rw-r--r--examples/stm32l5/src/bin/stop.rs4
-rw-r--r--examples/stm32u0/src/bin/dac.rs3
-rw-r--r--examples/stm32u5/Cargo.toml2
-rw-r--r--examples/stm32u5/src/bin/adc.rs4
-rw-r--r--examples/stm32wb/Cargo.toml2
-rw-r--r--examples/stm32wba/Cargo.toml2
-rw-r--r--examples/stm32wl/Cargo.toml2
-rw-r--r--tests/nrf/Cargo.toml2
-rw-r--r--tests/nrf/src/bin/buffered_uart.rs14
-rw-r--r--tests/nrf/src/bin/buffered_uart_halves.rs16
-rw-r--r--tests/nrf/src/bin/buffered_uart_spam.rs6
-rw-r--r--tests/nrf/src/bin/spim.rs8
-rw-r--r--tests/nrf/src/bin/uart_halves.rs14
-rw-r--r--tests/nrf/src/bin/uart_split.rs6
-rw-r--r--tests/rp/Cargo.toml2
-rw-r--r--tests/rp/src/bin/adc.rs61
-rw-r--r--tests/rp/src/bin/bootsel.rs5
-rw-r--r--tests/rp/src/bin/gpio.rs40
-rw-r--r--tests/rp/src/bin/gpio_async.rs24
-rw-r--r--tests/rp/src/bin/gpio_multicore.rs5
-rw-r--r--tests/rp/src/bin/pwm.rs50
-rw-r--r--tests/rp/src/bin/uart.rs14
-rw-r--r--tests/rp/src/bin/uart_buffered.rs38
-rw-r--r--tests/rp/src/bin/uart_dma.rs38
-rw-r--r--tests/stm32/Cargo.toml2
-rw-r--r--tests/stm32/src/bin/can.rs2
-rw-r--r--tests/stm32/src/bin/cordic.rs4
-rw-r--r--tests/stm32/src/bin/dac.rs3
-rw-r--r--tests/stm32/src/bin/dac_l1.rs3
-rw-r--r--tests/stm32/src/bin/gpio.rs44
-rw-r--r--tests/stm32/src/bin/hash.rs3
-rw-r--r--tests/stm32/src/bin/sdmmc.rs26
-rw-r--r--tests/stm32/src/bin/spi.rs16
-rw-r--r--tests/stm32/src/bin/spi_dma.rs34
-rw-r--r--tests/stm32/src/bin/ucpd.rs10
-rw-r--r--tests/stm32/src/bin/usart.rs6
338 files changed, 7782 insertions, 4340 deletions
diff --git a/.github/ci/doc.sh b/.github/ci/doc.sh
index c92892406..58ffe5f2e 100755
--- a/.github/ci/doc.sh
+++ b/.github/ci/doc.sh
@@ -25,6 +25,7 @@ docserver-builder -i ./embassy-executor -o webroot/crates/embassy-executor/git.z
25docserver-builder -i ./embassy-futures -o webroot/crates/embassy-futures/git.zup 25docserver-builder -i ./embassy-futures -o webroot/crates/embassy-futures/git.zup
26docserver-builder -i ./embassy-nrf -o webroot/crates/embassy-nrf/git.zup 26docserver-builder -i ./embassy-nrf -o webroot/crates/embassy-nrf/git.zup
27docserver-builder -i ./embassy-rp -o webroot/crates/embassy-rp/git.zup 27docserver-builder -i ./embassy-rp -o webroot/crates/embassy-rp/git.zup
28docserver-builder -i ./embassy-mspm0 -o webroot/crates/embassy-mspm0/git.zup
28docserver-builder -i ./embassy-sync -o webroot/crates/embassy-sync/git.zup 29docserver-builder -i ./embassy-sync -o webroot/crates/embassy-sync/git.zup
29docserver-builder -i ./cyw43 -o webroot/crates/cyw43/git.zup 30docserver-builder -i ./cyw43 -o webroot/crates/cyw43/git.zup
30docserver-builder -i ./cyw43-pio -o webroot/crates/cyw43-pio/git.zup 31docserver-builder -i ./cyw43-pio -o webroot/crates/cyw43-pio/git.zup
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 48d0957e6..e4814ff27 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -28,6 +28,11 @@
28 // To work on the examples, comment the line above and all of the cargo.features lines, 28 // To work on the examples, comment the line above and all of the cargo.features lines,
29 // then uncomment ONE line below to select the chip you want to work on. 29 // then uncomment ONE line below to select the chip you want to work on.
30 // This makes rust-analyzer work on the example crate and all its dependencies. 30 // This makes rust-analyzer work on the example crate and all its dependencies.
31 // "examples/mspm0c1104/Cargo.toml",
32 // "examples/mspm0g3507/Cargo.toml",
33 // "examples/mspm0g3519/Cargo.toml",
34 // "examples/mspm0l1306/Cargo.toml",
35 // "examples/mspm0l2228/Cargo.toml",
31 // "examples/nrf52840-rtic/Cargo.toml", 36 // "examples/nrf52840-rtic/Cargo.toml",
32 // "examples/nrf5340/Cargo.toml", 37 // "examples/nrf5340/Cargo.toml",
33 // "examples/nrf-rtos-trace/Cargo.toml", 38 // "examples/nrf-rtos-trace/Cargo.toml",
diff --git a/README.md b/README.md
index e9f0d3b24..383fb6671 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ Rust's <a href="https://rust-lang.github.io/async-book/">async/await</a> allows
15 - <a href="https://docs.embassy.dev/embassy-stm32/">embassy-stm32</a>, for all STM32 microcontroller families. 15 - <a href="https://docs.embassy.dev/embassy-stm32/">embassy-stm32</a>, for all STM32 microcontroller families.
16 - <a href="https://docs.embassy.dev/embassy-nrf/">embassy-nrf</a>, for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series. 16 - <a href="https://docs.embassy.dev/embassy-nrf/">embassy-nrf</a>, for the Nordic Semiconductor nRF52, nRF53, nRF54 and nRF91 series.
17 - <a href="https://docs.embassy.dev/embassy-rp/">embassy-rp</a>, for the Raspberry Pi RP2040 and RP23xx microcontrollers. 17 - <a href="https://docs.embassy.dev/embassy-rp/">embassy-rp</a>, for the Raspberry Pi RP2040 and RP23xx microcontrollers.
18 - <a href="https://docs.embassy.dev/embassy-mspm0/">embassy-mspm0</a>, for the Texas Instruments MSPM0 microcontrollers.
18 - <a href="https://github.com/esp-rs">esp-rs</a>, for the Espressif Systems ESP32 series of chips. 19 - <a href="https://github.com/esp-rs">esp-rs</a>, for the Espressif Systems ESP32 series of chips.
19 - Embassy HAL support for Espressif chips, as well as Async WiFi, Bluetooth and ESP-NOW, is being developed in the [esp-rs/esp-hal](https://github.com/esp-rs/esp-hal) repository. 20 - Embassy HAL support for Espressif chips, as well as Async WiFi, Bluetooth and ESP-NOW, is being developed in the [esp-rs/esp-hal](https://github.com/esp-rs/esp-hal) repository.
20 - <a href="https://github.com/ch32-rs/ch32-hal">ch32-hal</a>, for the WCH 32-bit RISC-V(CH32V) series of chips. 21 - <a href="https://github.com/ch32-rs/ch32-hal">ch32-hal</a>, for the WCH 32-bit RISC-V(CH32V) series of chips.
@@ -54,11 +55,11 @@ use defmt::info;
54use embassy_executor::Spawner; 55use embassy_executor::Spawner;
55use embassy_time::{Duration, Timer}; 56use embassy_time::{Duration, Timer};
56use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; 57use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
57use embassy_nrf::Peripherals; 58use embassy_nrf::{Peri, Peripherals};
58 59
59// Declare async tasks 60// Declare async tasks
60#[embassy_executor::task] 61#[embassy_executor::task]
61async fn blink(pin: AnyPin) { 62async fn blink(pin: Peri<'static, AnyPin>) {
62 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); 63 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
63 64
64 loop { 65 loop {
@@ -76,7 +77,7 @@ async fn main(spawner: Spawner) {
76 let p = embassy_nrf::init(Default::default()); 77 let p = embassy_nrf::init(Default::default());
77 78
78 // Spawned tasks run in the background, concurrently. 79 // Spawned tasks run in the background, concurrently.
79 spawner.spawn(blink(p.P0_13.degrade())).unwrap(); 80 spawner.spawn(blink(p.P0_13.into())).unwrap();
80 81
81 let mut button = Input::new(p.P0_11, Pull::Up); 82 let mut button = Input::new(p.P0_11, Pull::Up);
82 loop { 83 loop {
diff --git a/ci.sh b/ci.sh
index e32105b16..5b63c507b 100755
--- a/ci.sh
+++ b/ci.sh
@@ -170,6 +170,11 @@ cargo batch \
170 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \ 170 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u073mb,defmt,exti,time-driver-any,time \
171 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \ 171 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32u083rc,defmt,exti,time-driver-any,time \
172 --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \ 172 --- build --release --manifest-path embassy-nxp/Cargo.toml --target thumbv8m.main-none-eabihf \
173 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0c110x,defmt,time-driver-any \
174 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g350x,defmt,time-driver-any \
175 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0g351x,defmt,time-driver-any \
176 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l130x,defmt,time-driver-any \
177 --- build --release --manifest-path embassy-mspm0/Cargo.toml --target thumbv6m-none-eabi --features mspm0l222x,defmt,time-driver-any \
173 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\ 178 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\
174 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \ 179 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
175 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \ 180 --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
@@ -239,6 +244,10 @@ cargo batch \
239 --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \ 244 --- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/stm32wba \
240 --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \ 245 --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabi --artifact-dir out/examples/stm32wl \
241 --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \ 246 --- build --release --manifest-path examples/lpc55s69/Cargo.toml --target thumbv8m.main-none-eabihf --artifact-dir out/examples/lpc55s69 \
247 --- build --release --manifest-path examples/mspm0g3507/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3507 \
248 --- build --release --manifest-path examples/mspm0g3519/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0g3519 \
249 --- build --release --manifest-path examples/mspm0l1306/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l1306 \
250 --- build --release --manifest-path examples/mspm0l2228/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0l2228 \
242 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --artifact-dir out/examples/boot/nrf52840 \ 251 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --artifact-dir out/examples/boot/nrf52840 \
243 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --artifact-dir out/examples/boot/nrf9160 \ 252 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --artifact-dir out/examples/boot/nrf9160 \
244 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns,skip-include --artifact-dir out/examples/boot/nrf9120 \ 253 --- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns,skip-include --artifact-dir out/examples/boot/nrf9120 \
@@ -303,6 +312,11 @@ cargo batch \
303 $BUILD_EXTRA 312 $BUILD_EXTRA
304 313
305 314
315# MSPM0C1104 must be built seperately since cargo batch does not consider env vars set in `.cargo/config.toml`.
316# Since the target has 1KB of ram, we need to limit defmt's buffer size.
317DEFMT_RTT_BUFFER_SIZE="72" cargo batch \
318 --- build --release --manifest-path examples/mspm0c1104/Cargo.toml --target thumbv6m-none-eabi --artifact-dir out/examples/mspm0c1104 \
319
306# temporarily disabled, these boards are dead. 320# temporarily disabled, these boards are dead.
307rm -rf out/tests/stm32f103c8 321rm -rf out/tests/stm32f103c8
308rm -rf out/tests/nrf52840-dk 322rm -rf out/tests/nrf52840-dk
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs
index c1b301547..b0be19358 100644
--- a/cyw43-pio/src/lib.rs
+++ b/cyw43-pio/src/lib.rs
@@ -10,16 +10,16 @@ use embassy_rp::dma::Channel;
10use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; 10use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate};
11use embassy_rp::pio::program::pio_asm; 11use embassy_rp::pio::program::pio_asm;
12use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; 12use embassy_rp::pio::{Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine};
13use embassy_rp::{Peripheral, PeripheralRef}; 13use embassy_rp::Peri;
14use fixed::types::extra::U8; 14use fixed::types::extra::U8;
15use fixed::FixedU32; 15use fixed::FixedU32;
16 16
17/// SPI comms driven by PIO. 17/// SPI comms driven by PIO.
18pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA> { 18pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA: Channel> {
19 cs: Output<'d>, 19 cs: Output<'d>,
20 sm: StateMachine<'d, PIO, SM>, 20 sm: StateMachine<'d, PIO, SM>,
21 irq: Irq<'d, PIO, 0>, 21 irq: Irq<'d, PIO, 0>,
22 dma: PeripheralRef<'d, DMA>, 22 dma: Peri<'d, DMA>,
23 wrap_target: u8, 23 wrap_target: u8,
24} 24}
25 25
@@ -48,20 +48,16 @@ where
48 PIO: Instance, 48 PIO: Instance,
49{ 49{
50 /// Create a new instance of PioSpi. 50 /// Create a new instance of PioSpi.
51 pub fn new<DIO, CLK>( 51 pub fn new(
52 common: &mut Common<'d, PIO>, 52 common: &mut Common<'d, PIO>,
53 mut sm: StateMachine<'d, PIO, SM>, 53 mut sm: StateMachine<'d, PIO, SM>,
54 clock_divider: FixedU32<U8>, 54 clock_divider: FixedU32<U8>,
55 irq: Irq<'d, PIO, 0>, 55 irq: Irq<'d, PIO, 0>,
56 cs: Output<'d>, 56 cs: Output<'d>,
57 dio: DIO, 57 dio: Peri<'d, impl PioPin>,
58 clk: CLK, 58 clk: Peri<'d, impl PioPin>,
59 dma: impl Peripheral<P = DMA> + 'd, 59 dma: Peri<'d, DMA>,
60 ) -> Self 60 ) -> Self {
61 where
62 DIO: PioPin,
63 CLK: PioPin,
64 {
65 let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER { 61 let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER {
66 let overclock_program = pio_asm!( 62 let overclock_program = pio_asm!(
67 ".side_set 1" 63 ".side_set 1"
@@ -146,7 +142,7 @@ where
146 cs, 142 cs,
147 sm, 143 sm,
148 irq, 144 irq,
149 dma: dma.into_ref(), 145 dma: dma,
150 wrap_target: loaded_program.wrap.target, 146 wrap_target: loaded_program.wrap.target,
151 } 147 }
152 } 148 }
diff --git a/docs/pages/overview.adoc b/docs/pages/overview.adoc
index abc7d25de..b169c686e 100644
--- a/docs/pages/overview.adoc
+++ b/docs/pages/overview.adoc
@@ -29,6 +29,7 @@ The Embassy project maintains HALs for select hardware, but you can still use HA
29* link:https://docs.embassy.dev/embassy-stm32/[embassy-stm32], for all STM32 microcontroller families. 29* link:https://docs.embassy.dev/embassy-stm32/[embassy-stm32], for all STM32 microcontroller families.
30* link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series. 30* link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series.
31* link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller. 31* link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller.
32* link:https://docs.embassy.dev/embassy-mspm0/[embassy-mspm0], for the Texas Instruments MSPM0 microcontrollers.
32* link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips. 33* link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips.
33* link:https://github.com/ch32-rs/ch32-hal[ch32-hal], for the WCH 32-bit RISC-V(CH32V) series of chips. 34* link:https://github.com/ch32-rs/ch32-hal[ch32-hal], for the WCH 32-bit RISC-V(CH32V) series of chips.
34* link:https://github.com/AlexCharlton/mpfs-hal[mpfs-hal], for the Microchip PolarFire SoC. 35* link:https://github.com/AlexCharlton/mpfs-hal[mpfs-hal], for the Microchip PolarFire SoC.
diff --git a/embassy-boot-nrf/src/lib.rs b/embassy-boot-nrf/src/lib.rs
index e5bc870b5..46c1994e2 100644
--- a/embassy-boot-nrf/src/lib.rs
+++ b/embassy-boot-nrf/src/lib.rs
@@ -9,7 +9,7 @@ pub use embassy_boot::{
9}; 9};
10use embassy_nrf::nvmc::PAGE_SIZE; 10use embassy_nrf::nvmc::PAGE_SIZE;
11use embassy_nrf::peripherals::WDT; 11use embassy_nrf::peripherals::WDT;
12use embassy_nrf::wdt; 12use embassy_nrf::{wdt, Peri};
13use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; 13use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
14 14
15/// A bootloader for nRF devices. 15/// A bootloader for nRF devices.
@@ -113,7 +113,7 @@ pub struct WatchdogFlash<FLASH> {
113 113
114impl<FLASH> WatchdogFlash<FLASH> { 114impl<FLASH> WatchdogFlash<FLASH> {
115 /// Start a new watchdog with a given flash and WDT peripheral and a timeout 115 /// Start a new watchdog with a given flash and WDT peripheral and a timeout
116 pub fn start(flash: FLASH, wdt: WDT, config: wdt::Config) -> Self { 116 pub fn start(flash: FLASH, wdt: Peri<'static, WDT>, config: wdt::Config) -> Self {
117 let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) { 117 let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) {
118 Ok(x) => x, 118 Ok(x) => x,
119 Err(_) => { 119 Err(_) => {
diff --git a/embassy-boot-rp/src/lib.rs b/embassy-boot-rp/src/lib.rs
index 6ec33a580..f704380ef 100644
--- a/embassy-boot-rp/src/lib.rs
+++ b/embassy-boot-rp/src/lib.rs
@@ -10,6 +10,7 @@ pub use embassy_boot::{
10use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE}; 10use embassy_rp::flash::{Blocking, Flash, ERASE_SIZE};
11use embassy_rp::peripherals::{FLASH, WATCHDOG}; 11use embassy_rp::peripherals::{FLASH, WATCHDOG};
12use embassy_rp::watchdog::Watchdog; 12use embassy_rp::watchdog::Watchdog;
13use embassy_rp::Peri;
13use embassy_time::Duration; 14use embassy_time::Duration;
14use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; 15use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
15 16
@@ -68,7 +69,7 @@ pub struct WatchdogFlash<'d, const SIZE: usize> {
68 69
69impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> { 70impl<'d, const SIZE: usize> WatchdogFlash<'d, SIZE> {
70 /// Start a new watchdog with a given flash and watchdog peripheral and a timeout 71 /// Start a new watchdog with a given flash and watchdog peripheral and a timeout
71 pub fn start(flash: FLASH, watchdog: WATCHDOG, timeout: Duration) -> Self { 72 pub fn start(flash: Peri<'static, FLASH>, watchdog: Peri<'static, WATCHDOG>, timeout: Duration) -> Self {
72 let flash = Flash::<_, Blocking, SIZE>::new_blocking(flash); 73 let flash = Flash::<_, Blocking, SIZE>::new_blocking(flash);
73 let mut watchdog = Watchdog::new(watchdog); 74 let mut watchdog = Watchdog::new(watchdog);
74 watchdog.start(timeout); 75 watchdog.start(timeout);
diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs
index e8134c6a9..91d6beee8 100644
--- a/embassy-executor-macros/src/macros/task.rs
+++ b/embassy-executor-macros/src/macros/task.rs
@@ -145,9 +145,20 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
145 }; 145 };
146 #[cfg(not(feature = "nightly"))] 146 #[cfg(not(feature = "nightly"))]
147 let mut task_outer_body = quote! { 147 let mut task_outer_body = quote! {
148 const fn __task_pool_get<F, Args, Fut>(_: F) -> &'static #embassy_executor::raw::TaskPool<Fut, POOL_SIZE>
149 where
150 F: #embassy_executor::_export::TaskFn<Args, Fut = Fut>,
151 Fut: ::core::future::Future + 'static,
152 {
153 unsafe { &*POOL.get().cast() }
154 }
155
148 const POOL_SIZE: usize = #pool_size; 156 const POOL_SIZE: usize = #pool_size;
149 static POOL: #embassy_executor::_export::TaskPoolRef = #embassy_executor::_export::TaskPoolRef::new(); 157 static POOL: #embassy_executor::_export::TaskPoolHolder<
150 unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } 158 {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)},
159 {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)},
160 > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) };
161 unsafe { __task_pool_get(#task_inner_ident)._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) }
151 }; 162 };
152 163
153 let task_outer_attrs = task_inner.attrs.clone(); 164 let task_outer_attrs = task_inner.attrs.clone();
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index d6f24ce84..79d899c61 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -108,98 +108,3 @@ timer-item-payload-size-2 = ["_timer-item-payload"]
108timer-item-payload-size-4 = ["_timer-item-payload"] 108timer-item-payload-size-4 = ["_timer-item-payload"]
109## 8 bytes 109## 8 bytes
110timer-item-payload-size-8 = ["_timer-item-payload"] 110timer-item-payload-size-8 = ["_timer-item-payload"]
111
112#! ### Task Arena Size
113#! Sets the [task arena](#task-arena) size. Necessary if you’re not using `nightly`.
114#!
115#! <details>
116#! <summary>Preconfigured Task Arena Sizes:</summary>
117#! <!-- rustdoc requires the following blank line for the feature list to render correctly! -->
118#!
119
120# BEGIN AUTOGENERATED CONFIG FEATURES
121# Generated by gen_config.py. DO NOT EDIT.
122## 64
123task-arena-size-64 = []
124## 128
125task-arena-size-128 = []
126## 192
127task-arena-size-192 = []
128## 256
129task-arena-size-256 = []
130## 320
131task-arena-size-320 = []
132## 384
133task-arena-size-384 = []
134## 512
135task-arena-size-512 = []
136## 640
137task-arena-size-640 = []
138## 768
139task-arena-size-768 = []
140## 1024
141task-arena-size-1024 = []
142## 1280
143task-arena-size-1280 = []
144## 1536
145task-arena-size-1536 = []
146## 2048
147task-arena-size-2048 = []
148## 2560
149task-arena-size-2560 = []
150## 3072
151task-arena-size-3072 = []
152## 4096 (default)
153task-arena-size-4096 = [] # Default
154## 5120
155task-arena-size-5120 = []
156## 6144
157task-arena-size-6144 = []
158## 8192
159task-arena-size-8192 = []
160## 10240
161task-arena-size-10240 = []
162## 12288
163task-arena-size-12288 = []
164## 16384
165task-arena-size-16384 = []
166## 20480
167task-arena-size-20480 = []
168## 24576
169task-arena-size-24576 = []
170## 32768
171task-arena-size-32768 = []
172## 40960
173task-arena-size-40960 = []
174## 49152
175task-arena-size-49152 = []
176## 65536
177task-arena-size-65536 = []
178## 81920
179task-arena-size-81920 = []
180## 98304
181task-arena-size-98304 = []
182## 131072
183task-arena-size-131072 = []
184## 163840
185task-arena-size-163840 = []
186## 196608
187task-arena-size-196608 = []
188## 262144
189task-arena-size-262144 = []
190## 327680
191task-arena-size-327680 = []
192## 393216
193task-arena-size-393216 = []
194## 524288
195task-arena-size-524288 = []
196## 655360
197task-arena-size-655360 = []
198## 786432
199task-arena-size-786432 = []
200## 1048576
201task-arena-size-1048576 = []
202
203# END AUTOGENERATED CONFIG FEATURES
204
205#! </details>
diff --git a/embassy-executor/README.md b/embassy-executor/README.md
index 074c73555..85f15edbb 100644
--- a/embassy-executor/README.md
+++ b/embassy-executor/README.md
@@ -3,35 +3,10 @@
3An async/await executor designed for embedded usage. 3An async/await executor designed for embedded usage.
4 4
5- No `alloc`, no heap needed. 5- No `alloc`, no heap needed.
6- With nightly Rust, task futures can be fully statically allocated. 6- Tasks are statically allocated. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible.
7- No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning. 7- No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
8- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`. 8- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`.
9- No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`. 9- No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
10- Efficient polling: a wake will only poll the woken task, not all of them. 10- Efficient polling: a wake will only poll the woken task, not all of them.
11- Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time. 11- Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.
12- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks. 12- Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
13
14## Task arena
15
16When the `nightly` Cargo feature is not enabled, `embassy-executor` allocates tasks out of an arena (a very simple bump allocator).
17
18If the task arena gets full, the program will panic at runtime. To guarantee this doesn't happen, you must set the size to the sum of sizes of all tasks.
19
20Tasks are allocated from the arena when spawned for the first time. If the task exits, the allocation is not released to the arena, but can be reused to spawn the task again. For multiple-instance tasks (like `#[embassy_executor::task(pool_size = 4)]`), the first spawn will allocate memory for all instances. This is done for performance and to increase predictability (for example, spawning at least 1 instance of every task at boot guarantees an immediate panic if the arena is too small, while allocating instances on-demand could delay the panic to only when the program is under load).
21
22The arena size can be configured in two ways:
23
24- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values
25 is available, see [Task Area Sizes](#task-arena-size) for reference.
26- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example
27 `EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`.
28 Any value can be set, unlike with Cargo features.
29
30Environment variables take precedence over Cargo features. If two Cargo features are enabled for the same setting
31with different values, compilation fails.
32
33## Statically allocating tasks
34
35When using nightly Rust, enable the `nightly` Cargo feature. This will make `embassy-executor` use the `type_alias_impl_trait` feature to allocate all tasks in `static`s. Each task gets its own `static`, with the exact size to hold the task (or multiple instances of it, if using `pool_size`) calculated automatically at compile time. If tasks don't fit in RAM, this is detected at compile time by the linker. Runtime panics due to running out of memory are not possible.
36
37The configured arena size is ignored, no arena is used at all.
diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs
index 8a41d7503..37becde3e 100644
--- a/embassy-executor/build.rs
+++ b/embassy-executor/build.rs
@@ -1,99 +1,7 @@
1use std::collections::HashMap;
2use std::fmt::Write;
3use std::path::PathBuf;
4use std::{env, fs};
5
6#[path = "./build_common.rs"] 1#[path = "./build_common.rs"]
7mod common; 2mod common;
8 3
9static CONFIGS: &[(&str, usize)] = &[
10 // BEGIN AUTOGENERATED CONFIG FEATURES
11 // Generated by gen_config.py. DO NOT EDIT.
12 ("TASK_ARENA_SIZE", 4096),
13 // END AUTOGENERATED CONFIG FEATURES
14];
15
16struct ConfigState {
17 value: usize,
18 seen_feature: bool,
19 seen_env: bool,
20}
21
22fn main() { 4fn main() {
23 let crate_name = env::var("CARGO_PKG_NAME")
24 .unwrap()
25 .to_ascii_uppercase()
26 .replace('-', "_");
27
28 // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any
29 // other file changed.
30 println!("cargo:rerun-if-changed=build.rs");
31
32 // Rebuild if config envvar changed.
33 for (name, _) in CONFIGS {
34 println!("cargo:rerun-if-env-changed={crate_name}_{name}");
35 }
36
37 let mut configs = HashMap::new();
38 for (name, default) in CONFIGS {
39 configs.insert(
40 *name,
41 ConfigState {
42 value: *default,
43 seen_env: false,
44 seen_feature: false,
45 },
46 );
47 }
48
49 let prefix = format!("{crate_name}_");
50 for (var, value) in env::vars() {
51 if let Some(name) = var.strip_prefix(&prefix) {
52 let Some(cfg) = configs.get_mut(name) else {
53 panic!("Unknown env var {name}")
54 };
55
56 let Ok(value) = value.parse::<usize>() else {
57 panic!("Invalid value for env var {name}: {value}")
58 };
59
60 cfg.value = value;
61 cfg.seen_env = true;
62 }
63
64 if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") {
65 if let Some(i) = feature.rfind('_') {
66 let name = &feature[..i];
67 let value = &feature[i + 1..];
68 if let Some(cfg) = configs.get_mut(name) {
69 let Ok(value) = value.parse::<usize>() else {
70 panic!("Invalid value for feature {name}: {value}")
71 };
72
73 // envvars take priority.
74 if !cfg.seen_env {
75 if cfg.seen_feature {
76 panic!("multiple values set for feature {}: {} and {}", name, cfg.value, value);
77 }
78
79 cfg.value = value;
80 cfg.seen_feature = true;
81 }
82 }
83 }
84 }
85 }
86
87 let mut data = String::new();
88
89 for (name, cfg) in &configs {
90 writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap();
91 }
92
93 let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
94 let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
95 fs::write(out_file, data).unwrap();
96
97 let mut rustc_cfgs = common::CfgSet::new(); 5 let mut rustc_cfgs = common::CfgSet::new();
98 common::set_target_cfgs(&mut rustc_cfgs); 6 common::set_target_cfgs(&mut rustc_cfgs);
99} 7}
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index d816539ac..d6bd63665 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -50,101 +50,155 @@ pub mod raw;
50mod spawner; 50mod spawner;
51pub use spawner::*; 51pub use spawner::*;
52 52
53mod config {
54 #![allow(unused)]
55 include!(concat!(env!("OUT_DIR"), "/config.rs"));
56}
57
58/// Implementation details for embassy macros. 53/// Implementation details for embassy macros.
59/// Do not use. Used for macros and HALs only. Not covered by semver guarantees. 54/// Do not use. Used for macros and HALs only. Not covered by semver guarantees.
60#[doc(hidden)] 55#[doc(hidden)]
61#[cfg(not(feature = "nightly"))] 56#[cfg(not(feature = "nightly"))]
62pub mod _export { 57pub mod _export {
63 use core::alloc::Layout; 58 use core::cell::UnsafeCell;
64 use core::cell::{Cell, UnsafeCell};
65 use core::future::Future; 59 use core::future::Future;
66 use core::mem::MaybeUninit; 60 use core::mem::MaybeUninit;
67 use core::ptr::null_mut;
68
69 use critical_section::{CriticalSection, Mutex};
70 61
71 use crate::raw::TaskPool; 62 use crate::raw::TaskPool;
72 63
73 struct Arena<const N: usize> { 64 pub trait TaskFn<Args>: Copy {
74 buf: UnsafeCell<MaybeUninit<[u8; N]>>, 65 type Fut: Future + 'static;
75 ptr: Mutex<Cell<*mut u8>>,
76 } 66 }
77 67
78 unsafe impl<const N: usize> Sync for Arena<N> {} 68 macro_rules! task_fn_impl {
79 unsafe impl<const N: usize> Send for Arena<N> {} 69 ($($Tn:ident),*) => {
80 70 impl<F, Fut, $($Tn,)*> TaskFn<($($Tn,)*)> for F
81 impl<const N: usize> Arena<N> { 71 where
82 const fn new() -> Self { 72 F: Copy + FnOnce($($Tn,)*) -> Fut,
83 Self { 73 Fut: Future + 'static,
84 buf: UnsafeCell::new(MaybeUninit::uninit()), 74 {
85 ptr: Mutex::new(Cell::new(null_mut())), 75 type Fut = Fut;
86 } 76 }
87 } 77 };
88 78 }
89 fn alloc<T>(&'static self, cs: CriticalSection) -> &'static mut MaybeUninit<T> {
90 let layout = Layout::new::<T>();
91
92 let start = self.buf.get().cast::<u8>();
93 let end = unsafe { start.add(N) };
94 79
95 let mut ptr = self.ptr.borrow(cs).get(); 80 task_fn_impl!();
96 if ptr.is_null() { 81 task_fn_impl!(T0);
97 ptr = self.buf.get().cast::<u8>(); 82 task_fn_impl!(T0, T1);
98 } 83 task_fn_impl!(T0, T1, T2);
84 task_fn_impl!(T0, T1, T2, T3);
85 task_fn_impl!(T0, T1, T2, T3, T4);
86 task_fn_impl!(T0, T1, T2, T3, T4, T5);
87 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6);
88 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7);
89 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
90 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
91 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
92 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
93 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
94 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
95 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
96 task_fn_impl!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
97
98 #[allow(private_bounds)]
99 #[repr(C)]
100 pub struct TaskPoolHolder<const SIZE: usize, const ALIGN: usize>
101 where
102 Align<ALIGN>: Alignment,
103 {
104 data: UnsafeCell<[MaybeUninit<u8>; SIZE]>,
105 align: Align<ALIGN>,
106 }
99 107
100 let bytes_left = (end as usize) - (ptr as usize); 108 unsafe impl<const SIZE: usize, const ALIGN: usize> Send for TaskPoolHolder<SIZE, ALIGN> where Align<ALIGN>: Alignment {}
101 let align_offset = (ptr as usize).next_multiple_of(layout.align()) - (ptr as usize); 109 unsafe impl<const SIZE: usize, const ALIGN: usize> Sync for TaskPoolHolder<SIZE, ALIGN> where Align<ALIGN>: Alignment {}
102 110
103 if align_offset + layout.size() > bytes_left { 111 #[allow(private_bounds)]
104 panic!("embassy-executor: task arena is full. You must increase the arena size, see the documentation for details: https://docs.embassy.dev/embassy-executor/"); 112 impl<const SIZE: usize, const ALIGN: usize> TaskPoolHolder<SIZE, ALIGN>
105 } 113 where
114 Align<ALIGN>: Alignment,
115 {
116 pub const fn get(&self) -> *const u8 {
117 self.data.get().cast()
118 }
119 }
106 120
107 let res = unsafe { ptr.add(align_offset) }; 121 pub const fn task_pool_size<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
108 let ptr = unsafe { ptr.add(align_offset + layout.size()) }; 122 where
123 F: TaskFn<Args, Fut = Fut>,
124 Fut: Future + 'static,
125 {
126 size_of::<TaskPool<Fut, POOL_SIZE>>()
127 }
109 128
110 self.ptr.borrow(cs).set(ptr); 129 pub const fn task_pool_align<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
130 where
131 F: TaskFn<Args, Fut = Fut>,
132 Fut: Future + 'static,
133 {
134 align_of::<TaskPool<Fut, POOL_SIZE>>()
135 }
111 136
112 unsafe { &mut *(res as *mut MaybeUninit<T>) } 137 pub const fn task_pool_new<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> TaskPool<Fut, POOL_SIZE>
113 } 138 where
139 F: TaskFn<Args, Fut = Fut>,
140 Fut: Future + 'static,
141 {
142 TaskPool::new()
114 } 143 }
115 144
116 static ARENA: Arena<{ crate::config::TASK_ARENA_SIZE }> = Arena::new(); 145 #[allow(private_bounds)]
146 #[repr(transparent)]
147 pub struct Align<const N: usize>([<Self as Alignment>::Archetype; 0])
148 where
149 Self: Alignment;
117 150
118 pub struct TaskPoolRef { 151 trait Alignment {
119 // type-erased `&'static mut TaskPool<F, N>` 152 /// A zero-sized type of particular alignment.
120 // Needed because statics can't have generics. 153 type Archetype: Copy + Eq + PartialEq + Send + Sync + Unpin;
121 ptr: Mutex<Cell<*mut ()>>,
122 } 154 }
123 unsafe impl Sync for TaskPoolRef {}
124 unsafe impl Send for TaskPoolRef {}
125 155
126 impl TaskPoolRef { 156 macro_rules! aligns {
127 pub const fn new() -> Self { 157 ($($AlignX:ident: $n:literal,)*) => {
128 Self { 158 $(
129 ptr: Mutex::new(Cell::new(null_mut())), 159 #[derive(Copy, Clone, Eq, PartialEq)]
130 } 160 #[repr(align($n))]
131 } 161 struct $AlignX {}
132 162 impl Alignment for Align<$n> {
133 /// Get the pool for this ref, allocating it from the arena the first time. 163 type Archetype = $AlignX;
134 ///
135 /// safety: for a given TaskPoolRef instance, must always call with the exact
136 /// same generic params.
137 pub unsafe fn get<F: Future, const N: usize>(&'static self) -> &'static TaskPool<F, N> {
138 critical_section::with(|cs| {
139 let ptr = self.ptr.borrow(cs);
140 if ptr.get().is_null() {
141 let pool = ARENA.alloc::<TaskPool<F, N>>(cs);
142 pool.write(TaskPool::new());
143 ptr.set(pool as *mut _ as _);
144 } 164 }
145 165 )*
146 unsafe { &*(ptr.get() as *const _) } 166 };
147 })
148 }
149 } 167 }
168
169 aligns!(
170 Align1: 1,
171 Align2: 2,
172 Align4: 4,
173 Align8: 8,
174 Align16: 16,
175 Align32: 32,
176 Align64: 64,
177 Align128: 128,
178 Align256: 256,
179 Align512: 512,
180 Align1024: 1024,
181 Align2048: 2048,
182 Align4096: 4096,
183 Align8192: 8192,
184 Align16384: 16384,
185 );
186 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
187 aligns!(
188 Align32768: 32768,
189 Align65536: 65536,
190 Align131072: 131072,
191 Align262144: 262144,
192 Align524288: 524288,
193 Align1048576: 1048576,
194 Align2097152: 2097152,
195 Align4194304: 4194304,
196 Align8388608: 8388608,
197 Align16777216: 16777216,
198 Align33554432: 33554432,
199 Align67108864: 67108864,
200 Align134217728: 134217728,
201 Align268435456: 268435456,
202 Align536870912: 536870912,
203 );
150} 204}
diff --git a/embassy-executor/tests/ui.rs b/embassy-executor/tests/ui.rs
index be4679485..278a4b903 100644
--- a/embassy-executor/tests/ui.rs
+++ b/embassy-executor/tests/ui.rs
@@ -19,5 +19,6 @@ fn ui() {
19 t.compile_fail("tests/ui/not_async.rs"); 19 t.compile_fail("tests/ui/not_async.rs");
20 t.compile_fail("tests/ui/self_ref.rs"); 20 t.compile_fail("tests/ui/self_ref.rs");
21 t.compile_fail("tests/ui/self.rs"); 21 t.compile_fail("tests/ui/self.rs");
22 t.compile_fail("tests/ui/type_error.rs");
22 t.compile_fail("tests/ui/where_clause.rs"); 23 t.compile_fail("tests/ui/where_clause.rs");
23} 24}
diff --git a/embassy-executor/tests/ui/type_error.rs b/embassy-executor/tests/ui/type_error.rs
new file mode 100644
index 000000000..1734bc6c4
--- /dev/null
+++ b/embassy-executor/tests/ui/type_error.rs
@@ -0,0 +1,8 @@
1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2
3#[embassy_executor::task]
4async fn task() {
5 5
6}
7
8fn main() {}
diff --git a/embassy-executor/tests/ui/type_error.stderr b/embassy-executor/tests/ui/type_error.stderr
new file mode 100644
index 000000000..bce315811
--- /dev/null
+++ b/embassy-executor/tests/ui/type_error.stderr
@@ -0,0 +1,7 @@
1error[E0308]: mismatched types
2 --> tests/ui/type_error.rs:5:5
3 |
44 | async fn task() {
5 | - help: try adding a return type: `-> i32`
65 | 5
7 | ^ expected `()`, found integer
diff --git a/embassy-hal-internal/src/lib.rs b/embassy-hal-internal/src/lib.rs
index 89f20e993..7addb71e2 100644
--- a/embassy-hal-internal/src/lib.rs
+++ b/embassy-hal-internal/src/lib.rs
@@ -11,7 +11,7 @@ pub mod drop;
11mod macros; 11mod macros;
12mod peripheral; 12mod peripheral;
13pub mod ratio; 13pub mod ratio;
14pub use peripheral::{Peripheral, PeripheralRef}; 14pub use peripheral::{Peri, PeripheralType};
15 15
16#[cfg(feature = "cortex-m")] 16#[cfg(feature = "cortex-m")]
17pub mod interrupt; 17pub mod interrupt;
diff --git a/embassy-hal-internal/src/macros.rs b/embassy-hal-internal/src/macros.rs
index 07cd89487..cd2bc3cab 100644
--- a/embassy-hal-internal/src/macros.rs
+++ b/embassy-hal-internal/src/macros.rs
@@ -18,8 +18,8 @@ macro_rules! peripherals_definition {
18 /// 18 ///
19 /// You must ensure that you're only using one instance of this type at a time. 19 /// You must ensure that you're only using one instance of this type at a time.
20 #[inline] 20 #[inline]
21 pub unsafe fn steal() -> Self { 21 pub unsafe fn steal() -> $crate::Peri<'static, Self> {
22 Self{ _private: ()} 22 $crate::Peri::new_unchecked(Self{ _private: ()})
23 } 23 }
24 } 24 }
25 25
@@ -42,7 +42,7 @@ macro_rules! peripherals_struct {
42 $( 42 $(
43 #[doc = concat!(stringify!($name), " peripheral")] 43 #[doc = concat!(stringify!($name), " peripheral")]
44 $(#[$cfg])? 44 $(#[$cfg])?
45 pub $name: peripherals::$name, 45 pub $name: $crate::Peri<'static, peripherals::$name>,
46 )* 46 )*
47 } 47 }
48 48
@@ -108,28 +108,26 @@ macro_rules! peripherals {
108 }; 108 };
109} 109}
110 110
111/// Convenience converting into reference.
112#[macro_export]
113macro_rules! into_ref {
114 ($($name:ident),*) => {
115 $(
116 let mut $name = $name.into_ref();
117 )*
118 }
119}
120
121/// Implement the peripheral trait. 111/// Implement the peripheral trait.
122#[macro_export] 112#[macro_export]
123macro_rules! impl_peripheral { 113macro_rules! impl_peripheral {
124 ($type:ident) => { 114 ($type:ident<$($T:ident $(: $bound:tt $(+ $others:tt )*)?),*>) => {
125 impl $crate::Peripheral for $type { 115 impl<$($T: $($bound $(+$others)*)?),*> Copy for $type <$($T),*> {}
126 type P = $type; 116 impl<$($T: $($bound $(+$others)*)?),*> Clone for $type <$($T),*> {
117 fn clone(&self) -> Self {
118 *self
119 }
120 }
121 impl<$($T: $($bound $(+$others)*)?),*> PeripheralType for $type <$($T),*> {}
122 };
127 123
128 #[inline] 124 ($type:ident) => {
129 unsafe fn clone_unchecked(&self) -> Self::P { 125 impl Copy for $type {}
130 #[allow(clippy::needless_update)] 126 impl Clone for $type {
131 $type { ..*self } 127 fn clone(&self) -> Self {
128 *self
132 } 129 }
133 } 130 }
131 impl $crate::PeripheralType for $type {}
134 }; 132 };
135} 133}
diff --git a/embassy-hal-internal/src/peripheral.rs b/embassy-hal-internal/src/peripheral.rs
index 0b0f13338..803259bb8 100644
--- a/embassy-hal-internal/src/peripheral.rs
+++ b/embassy-hal-internal/src/peripheral.rs
@@ -1,5 +1,5 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::ops::{Deref, DerefMut}; 2use core::ops::Deref;
3 3
4/// An exclusive reference to a peripheral. 4/// An exclusive reference to a peripheral.
5/// 5///
@@ -9,20 +9,26 @@ use core::ops::{Deref, DerefMut};
9/// - Memory efficiency: Peripheral singletons are typically either zero-sized (for concrete 9/// - Memory efficiency: Peripheral singletons are typically either zero-sized (for concrete
10/// peripherals like `PA9` or `SPI4`) or very small (for example `AnyPin`, which is 1 byte). 10/// peripherals like `PA9` or `SPI4`) or very small (for example `AnyPin`, which is 1 byte).
11/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized. 11/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized.
12/// PeripheralRef stores a copy of `T` instead, so it's the same size. 12/// Peripheral stores a copy of `T` instead, so it's the same size.
13/// - Code size efficiency. If the user uses the same driver with both `SPI4` and `&mut SPI4`, 13/// - Code size efficiency. If the user uses the same driver with both `SPI4` and `&mut SPI4`,
14/// the driver code would be monomorphized two times. With PeripheralRef, the driver is generic 14/// the driver code would be monomorphized two times. With Peri, the driver is generic
15/// over a lifetime only. `SPI4` becomes `PeripheralRef<'static, SPI4>`, and `&mut SPI4` becomes 15/// over a lifetime only. `SPI4` becomes `Peri<'static, SPI4>`, and `&mut SPI4` becomes
16/// `PeripheralRef<'a, SPI4>`. Lifetimes don't cause monomorphization. 16/// `Peri<'a, SPI4>`. Lifetimes don't cause monomorphization.
17pub struct PeripheralRef<'a, T> { 17pub struct Peri<'a, T: PeripheralType> {
18 inner: T, 18 inner: T,
19 _lifetime: PhantomData<&'a mut T>, 19 _lifetime: PhantomData<&'a mut T>,
20} 20}
21 21
22impl<'a, T> PeripheralRef<'a, T> { 22impl<'a, T: PeripheralType> Peri<'a, T> {
23 /// Create a new reference to a peripheral. 23 /// Create a new owned a peripheral.
24 ///
25 /// For use by HALs only.
26 ///
27 /// If you're an end user you shouldn't use this, you should use `steal()`
28 /// on the actual peripheral types instead.
24 #[inline] 29 #[inline]
25 pub fn new(inner: T) -> Self { 30 #[doc(hidden)]
31 pub unsafe fn new_unchecked(inner: T) -> Self {
26 Self { 32 Self {
27 inner, 33 inner,
28 _lifetime: PhantomData, 34 _lifetime: PhantomData,
@@ -38,46 +44,38 @@ impl<'a, T> PeripheralRef<'a, T> {
38 /// create two SPI drivers on `SPI1`, because they will "fight" each other. 44 /// create two SPI drivers on `SPI1`, because they will "fight" each other.
39 /// 45 ///
40 /// You should strongly prefer using `reborrow()` instead. It returns a 46 /// You should strongly prefer using `reborrow()` instead. It returns a
41 /// `PeripheralRef` that borrows `self`, which allows the borrow checker 47 /// `Peri` that borrows `self`, which allows the borrow checker
42 /// to enforce this at compile time. 48 /// to enforce this at compile time.
43 pub unsafe fn clone_unchecked(&self) -> PeripheralRef<'a, T> 49 pub unsafe fn clone_unchecked(&self) -> Peri<'a, T> {
44 where 50 Peri::new_unchecked(self.inner)
45 T: Peripheral<P = T>,
46 {
47 PeripheralRef::new(self.inner.clone_unchecked())
48 } 51 }
49 52
50 /// Reborrow into a "child" PeripheralRef. 53 /// Reborrow into a "child" Peri.
51 /// 54 ///
52 /// `self` will stay borrowed until the child PeripheralRef is dropped. 55 /// `self` will stay borrowed until the child Peripheral is dropped.
53 pub fn reborrow(&mut self) -> PeripheralRef<'_, T> 56 pub fn reborrow(&mut self) -> Peri<'_, T> {
54 where 57 // safety: we're returning the clone inside a new Peripheral that borrows
55 T: Peripheral<P = T>,
56 {
57 // safety: we're returning the clone inside a new PeripheralRef that borrows
58 // self, so user code can't use both at the same time. 58 // self, so user code can't use both at the same time.
59 PeripheralRef::new(unsafe { self.inner.clone_unchecked() }) 59 unsafe { self.clone_unchecked() }
60 } 60 }
61 61
62 /// Map the inner peripheral using `Into`. 62 /// Map the inner peripheral using `Into`.
63 /// 63 ///
64 /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an 64 /// This converts from `Peri<'a, T>` to `Peri<'a, U>`, using an
65 /// `Into` impl to convert from `T` to `U`. 65 /// `Into` impl to convert from `T` to `U`.
66 /// 66 ///
67 /// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`. 67 /// For example, this can be useful to.into() GPIO pins: converting from Peri<'a, PB11>` to `Peri<'a, AnyPin>`.
68 #[inline] 68 #[inline]
69 pub fn map_into<U>(self) -> PeripheralRef<'a, U> 69 pub fn into<U>(self) -> Peri<'a, U>
70 where 70 where
71 T: Into<U>, 71 T: Into<U>,
72 U: PeripheralType,
72 { 73 {
73 PeripheralRef { 74 unsafe { Peri::new_unchecked(self.inner.into()) }
74 inner: self.inner.into(),
75 _lifetime: PhantomData,
76 }
77 } 75 }
78} 76}
79 77
80impl<'a, T> Deref for PeripheralRef<'a, T> { 78impl<'a, T: PeripheralType> Deref for Peri<'a, T> {
81 type Target = T; 79 type Target = T;
82 80
83 #[inline] 81 #[inline]
@@ -86,92 +84,5 @@ impl<'a, T> Deref for PeripheralRef<'a, T> {
86 } 84 }
87} 85}
88 86
89/// Trait for any type that can be used as a peripheral of type `P`. 87/// Marker trait for peripheral types.
90/// 88pub trait PeripheralType: Copy + Sized {}
91/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`),
92/// or borrowed peripherals (e.g. `&mut TWISPI0`).
93///
94/// For example, if you have a driver with a constructor like this:
95///
96/// ```ignore
97/// impl<'d, T: Instance> Twim<'d, T> {
98/// pub fn new(
99/// twim: impl Peripheral<P = T> + 'd,
100/// irq: impl Peripheral<P = T::Interrupt> + 'd,
101/// sda: impl Peripheral<P = impl GpioPin> + 'd,
102/// scl: impl Peripheral<P = impl GpioPin> + 'd,
103/// config: Config,
104/// ) -> Self { .. }
105/// }
106/// ```
107///
108/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`):
109///
110/// ```ignore
111/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
112/// ```
113///
114/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long
115/// as the borrows last:
116///
117/// ```ignore
118/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
119/// ```
120///
121/// # Implementation details, for HAL authors
122///
123/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral<P = ..>` in
124/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`,
125/// and storing that in the driver struct.
126///
127/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
128/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
129pub trait Peripheral: Sized {
130 /// Peripheral singleton type
131 type P;
132
133 /// Unsafely clone (duplicate) a peripheral singleton.
134 ///
135 /// # Safety
136 ///
137 /// This returns an owned clone of the peripheral. You must manually ensure
138 /// only one copy of the peripheral is in use at a time. For example, don't
139 /// create two SPI drivers on `SPI1`, because they will "fight" each other.
140 ///
141 /// You should strongly prefer using `into_ref()` instead. It returns a
142 /// `PeripheralRef`, which allows the borrow checker to enforce this at compile time.
143 unsafe fn clone_unchecked(&self) -> Self::P;
144
145 /// Convert a value into a `PeripheralRef`.
146 ///
147 /// When called on an owned `T`, yields a `PeripheralRef<'static, T>`.
148 /// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`.
149 #[inline]
150 fn into_ref<'a>(self) -> PeripheralRef<'a, Self::P>
151 where
152 Self: 'a,
153 {
154 PeripheralRef::new(unsafe { self.clone_unchecked() })
155 }
156}
157
158impl<'b, T: DerefMut> Peripheral for T
159where
160 T::Target: Peripheral,
161{
162 type P = <T::Target as Peripheral>::P;
163
164 #[inline]
165 unsafe fn clone_unchecked(&self) -> Self::P {
166 T::Target::clone_unchecked(self)
167 }
168}
169
170impl<'b, T: Peripheral> Peripheral for PeripheralRef<'_, T> {
171 type P = T::P;
172
173 #[inline]
174 unsafe fn clone_unchecked(&self) -> Self::P {
175 T::clone_unchecked(self)
176 }
177}
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml
new file mode 100644
index 000000000..28a8e7724
--- /dev/null
+++ b/embassy-mspm0/Cargo.toml
@@ -0,0 +1,132 @@
1[package]
2name = "embassy-mspm0"
3version = "0.1.0"
4edition = "2021"
5license = "MIT OR Apache-2.0"
6description = "Embassy Hardware Abstraction Layer (HAL) for Texas Instruments MSPM0 series microcontrollers"
7keywords = ["embedded", "async", "mspm0", "hal", "embedded-hal"]
8categories = ["embedded", "hardware-support", "no-std", "asynchronous"]
9repository = "https://github.com/embassy-rs/embassy"
10documentation = "https://docs.embassy.dev/embassy-mspm0"
11
12[package.metadata.embassy_docs]
13src_base = "https://github.com/embassy-rs/embassy/blob/embassy-mspm0-v$VERSION/embassy-mspm0/src/"
14src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-mspm0/src/"
15
16features = ["defmt", "unstable-pac", "time-driver-any"]
17flavors = [
18 { regex_feature = "mspm0c.*", target = "thumbv6m-none-eabi" },
19 { regex_feature = "mspm0l.*", target = "thumbv6m-none-eabi" },
20 { regex_feature = "mspm0g.*", target = "thumbv6m-none-eabi" },
21]
22
23[package.metadata.docs.rs]
24features = ["defmt", "unstable-pac", "time-driver-any", "time", "mspm0g3507"]
25rustdoc-args = ["--cfg", "docsrs"]
26
27[dependencies]
28embassy-sync = { version = "0.6.2", path = "../embassy-sync" }
29embassy-time = { version = "0.4.0", path = "../embassy-time", optional = true }
30# TODO: Support other tick rates
31embassy-time-driver = { version = "0.2", path = "../embassy-time-driver", optional = true, features = ["tick-hz-32_768"] }
32embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true }
33embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
34embassy-hal-internal = { version = "0.2.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
35embassy-embedded-hal = { version = "0.3.0", path = "../embassy-embedded-hal", default-features = false }
36embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional = true }
37
38embedded-hal = { version = "1.0" }
39embedded-hal-async = { version = "1.0" }
40
41defmt = { version = "0.3", optional = true }
42log = { version = "0.4.14", optional = true }
43cortex-m-rt = ">=0.6.15,<0.8"
44cortex-m = "0.7.6"
45critical-section = "1.2.0"
46
47# mspm0-metapac = { version = "" }
48mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a" }
49
50[build-dependencies]
51proc-macro2 = "1.0.94"
52quote = "1.0.40"
53
54# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
55mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-119240dd23ef5748d2a7bef219ca298d37ba604a", default-features = false, features = ["metadata"] }
56
57[features]
58default = ["rt"]
59
60## Enable `mspm0-metapac`'s `rt` feature
61rt = ["mspm0-metapac/rt"]
62
63## Use [`defmt`](https://docs.rs/defmt/latest/defmt/) for logging
64defmt = [
65 "dep:defmt",
66 "embassy-sync/defmt",
67 "embassy-embedded-hal/defmt",
68 "embassy-hal-internal/defmt",
69 "embassy-time?/defmt",
70]
71
72## Re-export mspm0-metapac at `mspm0::pac`.
73## This is unstable because semver-minor (non-breaking) releases of embassy-mspm0 may major-bump (breaking) the mspm0-metapac version.
74## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
75## There are no plans to make this stable.
76unstable-pac = []
77
78#! ## Time
79
80# Features starting with `_` are for internal use only. They're not intended
81# to be enabled by other crates, and are not covered by semver guarantees.
82_time-driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils"]
83
84# Use any time driver
85time-driver-any = ["_time-driver"]
86## Use TIMG0 as time driver
87time-driver-timg0 = ["_time-driver"]
88## Use TIMG1 as time driver
89time-driver-timg1 = ["_time-driver"]
90## Use TIMG2 as time driver
91time-driver-timg2 = ["_time-driver"]
92## Use TIMG3 as time driver
93time-driver-timg3 = ["_time-driver"]
94## Use TIMG4 as time driver
95time-driver-timg4 = ["_time-driver"]
96## Use TIMG5 as time driver
97time-driver-timg5 = ["_time-driver"]
98## Use TIMG6 as time driver
99time-driver-timg6 = ["_time-driver"]
100## Use TIMG7 as time driver
101time-driver-timg7 = ["_time-driver"]
102## Use TIMG8 as time driver
103time-driver-timg8 = ["_time-driver"]
104## Use TIMG9 as time driver
105time-driver-timg9 = ["_time-driver"]
106## Use TIMG10 as time driver
107time-driver-timg10 = ["_time-driver"]
108## Use TIMG11 as time driver
109time-driver-timg11 = ["_time-driver"]
110## Use TIMG12 as time driver
111time-driver-timg12 = ["_time-driver"]
112## Use TIMG13 as time driver
113time-driver-timg13 = ["_time-driver"]
114## Use TIMG14 as time driver
115time-driver-timg14 = ["_time-driver"]
116## Use TIMA0 as time driver
117time-driver-tima0 = ["_time-driver"]
118## Use TIMA1 as time driver
119time-driver-tima1 = ["_time-driver"]
120
121#! ## Chip-selection features
122#! Select your chip by specifying the model as a feature, e.g. `mspm0g350x`.
123#! Check the `Cargo.toml` for the latest list of supported chips.
124#!
125#! **Important:** Do not forget to adapt the target chip in your toolchain,
126#! e.g. in `.cargo/config.toml`.
127
128mspm0c110x = [ "mspm0-metapac/mspm0c110x" ]
129mspm0g350x = [ "mspm0-metapac/mspm0g350x" ]
130mspm0g351x = [ "mspm0-metapac/mspm0g351x" ]
131mspm0l130x = [ "mspm0-metapac/mspm0l130x" ]
132mspm0l222x = [ "mspm0-metapac/mspm0l222x" ]
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs
new file mode 100644
index 000000000..39d8b2f8a
--- /dev/null
+++ b/embassy-mspm0/build.rs
@@ -0,0 +1,802 @@
1use std::cmp::Ordering;
2use std::collections::{BTreeSet, HashMap};
3use std::io::Write;
4use std::path::{Path, PathBuf};
5use std::process::Command;
6use std::sync::LazyLock;
7use std::{env, fs};
8
9use common::CfgSet;
10use mspm0_metapac::metadata::METADATA;
11use proc_macro2::{Ident, Literal, Span, TokenStream};
12use quote::{format_ident, quote};
13
14#[path = "./build_common.rs"]
15mod common;
16
17fn main() {
18 generate_code();
19}
20
21fn generate_code() {
22 let mut cfgs = common::CfgSet::new();
23 common::set_target_cfgs(&mut cfgs);
24
25 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]);
26
27 let mut singletons = get_singletons(&mut cfgs);
28
29 time_driver(&mut singletons, &mut cfgs);
30
31 let mut g = TokenStream::new();
32
33 g.extend(generate_singletons(&singletons));
34 g.extend(generate_pincm_mapping());
35 g.extend(generate_pin());
36 g.extend(generate_timers());
37 g.extend(generate_interrupts());
38 g.extend(generate_peripheral_instances());
39 g.extend(generate_pin_trait_impls());
40
41 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
42 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
43 fs::write(&out_file, g.to_string()).unwrap();
44 rustfmt(&out_file);
45}
46
47#[derive(Debug, Clone)]
48struct Singleton {
49 name: String,
50
51 cfg: Option<TokenStream>,
52}
53
54impl PartialEq for Singleton {
55 fn eq(&self, other: &Self) -> bool {
56 self.name == other.name
57 }
58}
59
60impl Eq for Singleton {}
61
62impl PartialOrd for Singleton {
63 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
64 Some(self.cmp(other))
65 }
66}
67
68impl Ord for Singleton {
69 fn cmp(&self, other: &Self) -> Ordering {
70 self.name.cmp(&other.name)
71 }
72}
73
74fn get_singletons(cfgs: &mut common::CfgSet) -> Vec<Singleton> {
75 let mut singletons = Vec::<Singleton>::new();
76
77 for peripheral in METADATA.peripherals {
78 // Some peripherals do not generate a singleton, but generate a singleton for each pin.
79 let skip_peripheral_singleton = match peripheral.kind {
80 "gpio" => {
81 // Also enable ports that are present.
82 match peripheral.name {
83 "GPIOB" => cfgs.enable("gpio_pb"),
84 "GPIOC" => cfgs.enable("gpio_pc"),
85 _ => (),
86 }
87
88 true
89 }
90
91 // Each channel gets a singleton, handled separately.
92 "dma" => true,
93
94 // These peripherals do not exist as singletons, and have no signals but are managed
95 // by the HAL.
96 "iomux" | "cpuss" => true,
97
98 _ => false,
99 };
100
101 if !skip_peripheral_singleton {
102 singletons.push(Singleton {
103 name: peripheral.name.to_string(),
104 cfg: None,
105 });
106 }
107
108 let mut signals = BTreeSet::new();
109
110 // Pick out each unique signal. There may be multiple instances of each signal due to
111 // iomux mappings.
112 for pin in peripheral.pins {
113 let signal = if peripheral.name.starts_with("GPIO")
114 || peripheral.name.starts_with("VREF")
115 || peripheral.name.starts_with("RTC")
116 {
117 pin.signal.to_string()
118 } else {
119 format!("{}_{}", peripheral.name, pin.signal)
120 };
121
122 // We need to rename some signals to become valid Rust identifiers.
123 let signal = make_valid_identifier(&signal);
124 signals.insert(signal);
125 }
126
127 singletons.extend(signals);
128 }
129
130 // DMA channels get their own singletons
131 for dma_channel in METADATA.dma_channels.iter() {
132 singletons.push(Singleton {
133 name: format!("DMA_CH{}", dma_channel.number),
134 cfg: None,
135 });
136 }
137
138 singletons.sort_by(|a, b| a.name.cmp(&b.name));
139 singletons
140}
141
142fn make_valid_identifier(s: &str) -> Singleton {
143 let name = s.replace('+', "_P").replace("-", "_N");
144
145 Singleton { name, cfg: None }
146}
147
148fn generate_pincm_mapping() -> TokenStream {
149 let pincms = METADATA.pincm_mappings.iter().map(|mapping| {
150 let port_letter = mapping.pin.strip_prefix("P").unwrap();
151 let port_base = (port_letter.chars().next().unwrap() as u8 - b'A') * 32;
152 // This assumes all ports are single letter length.
153 // This is fine unless TI releases a part with 833+ GPIO pins.
154 let pin_number = mapping.pin[2..].parse::<u8>().unwrap();
155
156 let num = port_base + pin_number;
157
158 // But subtract 1 since pincm indices start from 0, not 1.
159 let pincm = Literal::u8_unsuffixed(mapping.pincm - 1);
160 quote! {
161 #num => #pincm
162 }
163 });
164
165 quote! {
166 #[doc = "Get the mapping from GPIO pin port to IOMUX PINCM index. This is required since the mapping from IO to PINCM index is not consistent across parts."]
167 pub(crate) fn gpio_pincm(pin_port: u8) -> u8 {
168 match pin_port {
169 #(#pincms),*,
170 _ => unreachable!(),
171 }
172 }
173 }
174}
175
176fn generate_pin() -> TokenStream {
177 let pin_impls = METADATA.pincm_mappings.iter().map(|pincm_mapping| {
178 let name = Ident::new(&pincm_mapping.pin, Span::call_site());
179 let port_letter = pincm_mapping.pin.strip_prefix("P").unwrap();
180 let port_letter = port_letter.chars().next().unwrap();
181 let pin_number = Literal::u8_unsuffixed(pincm_mapping.pin[2..].parse::<u8>().unwrap());
182
183 let port = Ident::new(&format!("Port{}", port_letter), Span::call_site());
184
185 // TODO: Feature gate pins that can be used as NRST
186
187 quote! {
188 impl_pin!(#name, crate::gpio::Port::#port, #pin_number);
189 }
190 });
191
192 quote! {
193 #(#pin_impls)*
194 }
195}
196
197fn time_driver(singletons: &mut Vec<Singleton>, cfgs: &mut CfgSet) {
198 // Timer features
199 for (timer, _) in TIMERS.iter() {
200 let name = timer.to_lowercase();
201 cfgs.declare(&format!("time_driver_{}", name));
202 }
203
204 let time_driver = match env::vars()
205 .map(|(a, _)| a)
206 .filter(|x| x.starts_with("CARGO_FEATURE_TIME_DRIVER_"))
207 .get_one()
208 {
209 Ok(x) => Some(
210 x.strip_prefix("CARGO_FEATURE_TIME_DRIVER_")
211 .unwrap()
212 .to_ascii_lowercase(),
213 ),
214 Err(GetOneError::None) => None,
215 Err(GetOneError::Multiple) => panic!("Multiple time-driver-xxx Cargo features enabled"),
216 };
217
218 // Verify the selected timer is available
219 let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) {
220 None => "",
221 Some("timg0") => "TIMG0",
222 Some("timg1") => "TIMG1",
223 Some("timg2") => "TIMG2",
224 Some("timg3") => "TIMG3",
225 Some("timg4") => "TIMG4",
226 Some("timg5") => "TIMG5",
227 Some("timg6") => "TIMG6",
228 Some("timg7") => "TIMG7",
229 Some("timg8") => "TIMG8",
230 Some("timg9") => "TIMG9",
231 Some("timg10") => "TIMG10",
232 Some("timg11") => "TIMG11",
233 Some("timg14") => "TIMG14",
234 Some("tima0") => "TIMA0",
235 Some("tima1") => "TIMA1",
236 Some("any") => {
237 // Order of timer candidates:
238 // 1. 16-bit, 2 channel
239 // 2. 16-bit, 2 channel with shadow registers
240 // 3. 16-bit, 4 channel
241 // 4. 16-bit with QEI
242 // 5. Advanced timers
243 //
244 // TODO: Select RTC first if available
245 // TODO: 32-bit timers are not considered yet
246 [
247 // 16-bit, 2 channel
248 "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers
249 "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel
250 "TIMG14", // 16-bit with QEI
251 "TIMG8", "TIMG9", "TIMG10", "TIMG11", // Advanced timers
252 "TIMA0", "TIMA1",
253 ]
254 .iter()
255 .find(|tim| singletons.iter().any(|s| s.name == **tim))
256 .expect("Could not find any timer")
257 }
258 _ => panic!("unknown time_driver {:?}", time_driver),
259 };
260
261 if !selected_timer.is_empty() {
262 cfgs.enable(format!("time_driver_{}", selected_timer.to_lowercase()));
263 }
264
265 // Apply cfgs to each timer and it's pins
266 for singleton in singletons.iter_mut() {
267 if singleton.name.starts_with("TIM") {
268 // Remove suffixes for pin singletons.
269 let name = if singleton.name.contains("_CCP") {
270 singleton.name.split_once("_CCP").unwrap().0
271 } else if singleton.name.contains("_FAULT") {
272 singleton.name.split_once("_FAULT").unwrap().0
273 } else if singleton.name.contains("_IDX") {
274 singleton.name.split_once("_IDX").unwrap().0
275 } else {
276 &singleton.name
277 };
278
279 let feature = format!("time-driver-{}", name.to_lowercase());
280
281 if singleton.name.contains(selected_timer) {
282 singleton.cfg = Some(quote! { #[cfg(not(all(feature = "time-driver-any", feature = #feature)))] });
283 } else {
284 singleton.cfg = Some(quote! { #[cfg(not(feature = #feature))] });
285 }
286 }
287 }
288}
289
290fn generate_singletons(singletons: &[Singleton]) -> TokenStream {
291 let singletons = singletons
292 .iter()
293 .map(|s| {
294 let cfg = s.cfg.clone().unwrap_or_default();
295
296 let ident = format_ident!("{}", s.name);
297
298 quote! {
299 #cfg
300 #ident
301 }
302 })
303 .collect::<Vec<_>>();
304
305 quote! {
306 embassy_hal_internal::peripherals_definition!(#(#singletons),*);
307 embassy_hal_internal::peripherals_struct!(#(#singletons),*);
308 }
309}
310
311fn generate_timers() -> TokenStream {
312 // Generate timers
313 let timer_impls = METADATA
314 .peripherals
315 .iter()
316 .filter(|p| p.name.starts_with("TIM"))
317 .map(|peripheral| {
318 let name = Ident::new(&peripheral.name, Span::call_site());
319 let timers = &*TIMERS;
320
321 let timer = timers.get(peripheral.name).expect("Timer does not exist");
322 assert!(timer.bits == 16 || timer.bits == 32);
323 let bits = if timer.bits == 16 {
324 quote! { Bits16 }
325 } else {
326 quote! { Bits32 }
327 };
328
329 quote! {
330 impl_timer!(#name, #bits);
331 }
332 });
333
334 quote! {
335 #(#timer_impls)*
336 }
337}
338
339fn generate_interrupts() -> TokenStream {
340 // Generate interrupt module
341 let interrupts: Vec<Ident> = METADATA
342 .interrupts
343 .iter()
344 .map(|interrupt| Ident::new(interrupt.name, Span::call_site()))
345 .collect();
346
347 let group_interrupt_enables = METADATA
348 .interrupts
349 .iter()
350 .filter(|interrupt| interrupt.name.contains("GROUP"))
351 .map(|interrupt| {
352 let name = Ident::new(interrupt.name, Span::call_site());
353
354 quote! {
355 crate::interrupt::typelevel::#name::enable();
356 }
357 });
358
359 // Generate interrupt enables for groups
360 quote! {
361 embassy_hal_internal::interrupt_mod! {
362 #(#interrupts),*
363 }
364
365 pub fn enable_group_interrupts(_cs: critical_section::CriticalSection) {
366 use crate::interrupt::typelevel::Interrupt;
367
368 unsafe {
369 #(#group_interrupt_enables)*
370 }
371 }
372 }
373}
374
375fn generate_peripheral_instances() -> TokenStream {
376 let mut impls = Vec::<TokenStream>::new();
377
378 for peripheral in METADATA.peripherals {
379 let peri = format_ident!("{}", peripheral.name);
380
381 // Will be filled in when uart implementation is finished
382 let _ = peri;
383 let tokens = match peripheral.kind {
384 // "uart" => Some(quote! { impl_uart_instance!(#peri); }),
385 _ => None,
386 };
387
388 if let Some(tokens) = tokens {
389 impls.push(tokens);
390 }
391 }
392
393 quote! {
394 #(#impls)*
395 }
396}
397
398fn generate_pin_trait_impls() -> TokenStream {
399 let mut impls = Vec::<TokenStream>::new();
400
401 for peripheral in METADATA.peripherals {
402 for pin in peripheral.pins {
403 let key = (peripheral.kind, pin.signal);
404
405 let pin_name = format_ident!("{}", pin.pin);
406 let peri = format_ident!("{}", peripheral.name);
407 let pf = pin.pf;
408
409 // Will be filled in when uart implementation is finished
410 let _ = pin_name;
411 let _ = peri;
412 let _ = pf;
413
414 let tokens = match key {
415 // ("uart", "TX") => Some(quote! { impl_uart_tx_pin!(#peri, #pin_name, #pf); }),
416 // ("uart", "RX") => Some(quote! { impl_uart_rx_pin!(#peri, #pin_name, #pf); }),
417 // ("uart", "CTS") => Some(quote! { impl_uart_cts_pin!(#peri, #pin_name, #pf); }),
418 // ("uart", "RTS") => Some(quote! { impl_uart_rts_pin!(#peri, #pin_name, #pf); }),
419 _ => None,
420 };
421
422 if let Some(tokens) = tokens {
423 impls.push(tokens);
424 }
425 }
426 }
427
428 quote! {
429 #(#impls)*
430 }
431}
432
433/// rustfmt a given path.
434/// Failures are logged to stderr and ignored.
435fn rustfmt(path: impl AsRef<Path>) {
436 let path = path.as_ref();
437 match Command::new("rustfmt").args([path]).output() {
438 Err(e) => {
439 eprintln!("failed to exec rustfmt {:?}: {:?}", path, e);
440 }
441 Ok(out) => {
442 if !out.status.success() {
443 eprintln!("rustfmt {:?} failed:", path);
444 eprintln!("=== STDOUT:");
445 std::io::stderr().write_all(&out.stdout).unwrap();
446 eprintln!("=== STDERR:");
447 std::io::stderr().write_all(&out.stderr).unwrap();
448 }
449 }
450 }
451}
452
453#[allow(dead_code)]
454struct TimerDesc {
455 bits: u8,
456 /// Is there an 8-bit prescaler
457 prescaler: bool,
458 /// Is there a repeat counter
459 repeat_counter: bool,
460 ccp_channels_internal: u8,
461 ccp_channels_external: u8,
462 external_pwm_channels: u8,
463 phase_load: bool,
464 shadow_load: bool,
465 shadow_ccs: bool,
466 deadband: bool,
467 fault_handler: bool,
468 qei_hall: bool,
469}
470
471/// Description of all timer instances.
472const TIMERS: LazyLock<HashMap<String, TimerDesc>> = LazyLock::new(|| {
473 let mut map = HashMap::new();
474 map.insert(
475 "TIMG0".into(),
476 TimerDesc {
477 bits: 16,
478 prescaler: true,
479 repeat_counter: false,
480 ccp_channels_internal: 2,
481 ccp_channels_external: 2,
482 external_pwm_channels: 2,
483 phase_load: false,
484 shadow_load: false,
485 shadow_ccs: false,
486 deadband: false,
487 fault_handler: false,
488 qei_hall: false,
489 },
490 );
491
492 map.insert(
493 "TIMG1".into(),
494 TimerDesc {
495 bits: 16,
496 prescaler: true,
497 repeat_counter: false,
498 ccp_channels_internal: 2,
499 ccp_channels_external: 2,
500 external_pwm_channels: 2,
501 phase_load: false,
502 shadow_load: false,
503 shadow_ccs: false,
504 deadband: false,
505 fault_handler: false,
506 qei_hall: false,
507 },
508 );
509
510 map.insert(
511 "TIMG2".into(),
512 TimerDesc {
513 bits: 16,
514 prescaler: true,
515 repeat_counter: false,
516 ccp_channels_internal: 2,
517 ccp_channels_external: 2,
518 external_pwm_channels: 2,
519 phase_load: false,
520 shadow_load: false,
521 shadow_ccs: false,
522 deadband: false,
523 fault_handler: false,
524 qei_hall: false,
525 },
526 );
527
528 map.insert(
529 "TIMG3".into(),
530 TimerDesc {
531 bits: 16,
532 prescaler: true,
533 repeat_counter: false,
534 ccp_channels_internal: 2,
535 ccp_channels_external: 2,
536 external_pwm_channels: 2,
537 phase_load: false,
538 shadow_load: false,
539 shadow_ccs: false,
540 deadband: false,
541 fault_handler: false,
542 qei_hall: false,
543 },
544 );
545
546 map.insert(
547 "TIMG4".into(),
548 TimerDesc {
549 bits: 16,
550 prescaler: true,
551 repeat_counter: false,
552 ccp_channels_internal: 2,
553 ccp_channels_external: 2,
554 external_pwm_channels: 2,
555 phase_load: false,
556 shadow_load: true,
557 shadow_ccs: true,
558 deadband: false,
559 fault_handler: false,
560 qei_hall: false,
561 },
562 );
563
564 map.insert(
565 "TIMG5".into(),
566 TimerDesc {
567 bits: 16,
568 prescaler: true,
569 repeat_counter: false,
570 ccp_channels_internal: 2,
571 ccp_channels_external: 2,
572 external_pwm_channels: 2,
573 phase_load: false,
574 shadow_load: true,
575 shadow_ccs: true,
576 deadband: false,
577 fault_handler: false,
578 qei_hall: false,
579 },
580 );
581
582 map.insert(
583 "TIMG6".into(),
584 TimerDesc {
585 bits: 16,
586 prescaler: true,
587 repeat_counter: false,
588 ccp_channels_internal: 2,
589 ccp_channels_external: 2,
590 external_pwm_channels: 2,
591 phase_load: false,
592 shadow_load: true,
593 shadow_ccs: true,
594 deadband: false,
595 fault_handler: false,
596 qei_hall: false,
597 },
598 );
599
600 map.insert(
601 "TIMG7".into(),
602 TimerDesc {
603 bits: 16,
604 prescaler: true,
605 repeat_counter: false,
606 ccp_channels_internal: 2,
607 ccp_channels_external: 2,
608 external_pwm_channels: 2,
609 phase_load: false,
610 shadow_load: true,
611 shadow_ccs: true,
612 deadband: false,
613 fault_handler: false,
614 qei_hall: false,
615 },
616 );
617
618 map.insert(
619 "TIMG8".into(),
620 TimerDesc {
621 bits: 16,
622 prescaler: true,
623 repeat_counter: false,
624 ccp_channels_internal: 2,
625 ccp_channels_external: 2,
626 external_pwm_channels: 2,
627 phase_load: false,
628 shadow_load: false,
629 shadow_ccs: false,
630 deadband: false,
631 fault_handler: false,
632 qei_hall: true,
633 },
634 );
635
636 map.insert(
637 "TIMG9".into(),
638 TimerDesc {
639 bits: 16,
640 prescaler: true,
641 repeat_counter: false,
642 ccp_channels_internal: 2,
643 ccp_channels_external: 2,
644 external_pwm_channels: 2,
645 phase_load: false,
646 shadow_load: false,
647 shadow_ccs: false,
648 deadband: false,
649 fault_handler: false,
650 qei_hall: true,
651 },
652 );
653
654 map.insert(
655 "TIMG10".into(),
656 TimerDesc {
657 bits: 16,
658 prescaler: true,
659 repeat_counter: false,
660 ccp_channels_internal: 2,
661 ccp_channels_external: 2,
662 external_pwm_channels: 2,
663 phase_load: false,
664 shadow_load: false,
665 shadow_ccs: false,
666 deadband: false,
667 fault_handler: false,
668 qei_hall: true,
669 },
670 );
671
672 map.insert(
673 "TIMG11".into(),
674 TimerDesc {
675 bits: 16,
676 prescaler: true,
677 repeat_counter: false,
678 ccp_channels_internal: 2,
679 ccp_channels_external: 2,
680 external_pwm_channels: 2,
681 phase_load: false,
682 shadow_load: false,
683 shadow_ccs: false,
684 deadband: false,
685 fault_handler: false,
686 qei_hall: true,
687 },
688 );
689
690 map.insert(
691 "TIMG12".into(),
692 TimerDesc {
693 bits: 32,
694 prescaler: false,
695 repeat_counter: false,
696 ccp_channels_internal: 2,
697 ccp_channels_external: 2,
698 external_pwm_channels: 2,
699 phase_load: false,
700 shadow_load: false,
701 shadow_ccs: true,
702 deadband: false,
703 fault_handler: false,
704 qei_hall: false,
705 },
706 );
707
708 map.insert(
709 "TIMG13".into(),
710 TimerDesc {
711 bits: 32,
712 prescaler: false,
713 repeat_counter: false,
714 ccp_channels_internal: 2,
715 ccp_channels_external: 2,
716 external_pwm_channels: 2,
717 phase_load: false,
718 shadow_load: false,
719 shadow_ccs: true,
720 deadband: false,
721 fault_handler: false,
722 qei_hall: false,
723 },
724 );
725
726 map.insert(
727 "TIMG14".into(),
728 TimerDesc {
729 bits: 16,
730 prescaler: true,
731 repeat_counter: false,
732 ccp_channels_internal: 4,
733 ccp_channels_external: 4,
734 external_pwm_channels: 4,
735 phase_load: false,
736 shadow_load: false,
737 shadow_ccs: false,
738 deadband: false,
739 fault_handler: false,
740 qei_hall: false,
741 },
742 );
743
744 map.insert(
745 "TIMA0".into(),
746 TimerDesc {
747 bits: 16,
748 prescaler: true,
749 repeat_counter: true,
750 ccp_channels_internal: 4,
751 ccp_channels_external: 2,
752 external_pwm_channels: 8,
753 phase_load: true,
754 shadow_load: true,
755 shadow_ccs: true,
756 deadband: true,
757 fault_handler: true,
758 qei_hall: false,
759 },
760 );
761
762 map.insert(
763 "TIMA1".into(),
764 TimerDesc {
765 bits: 16,
766 prescaler: true,
767 repeat_counter: true,
768 ccp_channels_internal: 2,
769 ccp_channels_external: 2,
770 external_pwm_channels: 4,
771 phase_load: true,
772 shadow_load: true,
773 shadow_ccs: true,
774 deadband: true,
775 fault_handler: true,
776 qei_hall: false,
777 },
778 );
779
780 map
781});
782
783enum GetOneError {
784 None,
785 Multiple,
786}
787
788trait IteratorExt: Iterator {
789 fn get_one(self) -> Result<Self::Item, GetOneError>;
790}
791
792impl<T: Iterator> IteratorExt for T {
793 fn get_one(mut self) -> Result<Self::Item, GetOneError> {
794 match self.next() {
795 None => Err(GetOneError::None),
796 Some(res) => match self.next() {
797 Some(_) => Err(GetOneError::Multiple),
798 None => Ok(res),
799 },
800 }
801 }
802}
diff --git a/embassy-mspm0/build_common.rs b/embassy-mspm0/build_common.rs
new file mode 100644
index 000000000..4f24e6d37
--- /dev/null
+++ b/embassy-mspm0/build_common.rs
@@ -0,0 +1,94 @@
1// NOTE: this file is copy-pasted between several Embassy crates, because there is no
2// straightforward way to share this code:
3// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
4// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
5// reside in the crate's directory,
6// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
7// symlinks don't work on Windows.
8
9use std::collections::HashSet;
10use std::env;
11
12/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
13/// them (`cargo:rust-check-cfg=cfg(X)`).
14#[derive(Debug)]
15pub struct CfgSet {
16 enabled: HashSet<String>,
17 declared: HashSet<String>,
18}
19
20impl CfgSet {
21 pub fn new() -> Self {
22 Self {
23 enabled: HashSet::new(),
24 declared: HashSet::new(),
25 }
26 }
27
28 /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
29 ///
30 /// All configs that can potentially be enabled should be unconditionally declared using
31 /// [`Self::declare()`].
32 pub fn enable(&mut self, cfg: impl AsRef<str>) {
33 if self.enabled.insert(cfg.as_ref().to_owned()) {
34 println!("cargo:rustc-cfg={}", cfg.as_ref());
35 }
36 }
37
38 pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
39 for cfg in cfgs.iter() {
40 self.enable(cfg.as_ref());
41 }
42 }
43
44 /// Declare a valid config for conditional compilation, without enabling it.
45 ///
46 /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
47 pub fn declare(&mut self, cfg: impl AsRef<str>) {
48 if self.declared.insert(cfg.as_ref().to_owned()) {
49 println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
50 }
51 }
52
53 pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
54 for cfg in cfgs.iter() {
55 self.declare(cfg.as_ref());
56 }
57 }
58
59 pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
60 let cfg = cfg.into();
61 if enable {
62 self.enable(cfg.clone());
63 }
64 self.declare(cfg);
65 }
66}
67
68/// Sets configs that describe the target platform.
69pub fn set_target_cfgs(cfgs: &mut CfgSet) {
70 let target = env::var("TARGET").unwrap();
71
72 if target.starts_with("thumbv6m-") {
73 cfgs.enable_all(&["cortex_m", "armv6m"]);
74 } else if target.starts_with("thumbv7m-") {
75 cfgs.enable_all(&["cortex_m", "armv7m"]);
76 } else if target.starts_with("thumbv7em-") {
77 cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
78 } else if target.starts_with("thumbv8m.base") {
79 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
80 } else if target.starts_with("thumbv8m.main") {
81 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
82 }
83 cfgs.declare_all(&[
84 "cortex_m",
85 "armv6m",
86 "armv7m",
87 "armv7em",
88 "armv8m",
89 "armv8m_base",
90 "armv8m_main",
91 ]);
92
93 cfgs.set("has_fpu", target.ends_with("-eabihf"));
94}
diff --git a/embassy-mspm0/src/fmt.rs b/embassy-mspm0/src/fmt.rs
new file mode 100644
index 000000000..8ca61bc39
--- /dev/null
+++ b/embassy-mspm0/src/fmt.rs
@@ -0,0 +1,270 @@
1#![macro_use]
2#![allow(unused)]
3
4use core::fmt::{Debug, Display, LowerHex};
5
6#[cfg(all(feature = "defmt", feature = "log"))]
7compile_error!("You may not enable both `defmt` and `log` features.");
8
9#[collapse_debuginfo(yes)]
10macro_rules! assert {
11 ($($x:tt)*) => {
12 {
13 #[cfg(not(feature = "defmt"))]
14 ::core::assert!($($x)*);
15 #[cfg(feature = "defmt")]
16 ::defmt::assert!($($x)*);
17 }
18 };
19}
20
21#[collapse_debuginfo(yes)]
22macro_rules! assert_eq {
23 ($($x:tt)*) => {
24 {
25 #[cfg(not(feature = "defmt"))]
26 ::core::assert_eq!($($x)*);
27 #[cfg(feature = "defmt")]
28 ::defmt::assert_eq!($($x)*);
29 }
30 };
31}
32
33#[collapse_debuginfo(yes)]
34macro_rules! assert_ne {
35 ($($x:tt)*) => {
36 {
37 #[cfg(not(feature = "defmt"))]
38 ::core::assert_ne!($($x)*);
39 #[cfg(feature = "defmt")]
40 ::defmt::assert_ne!($($x)*);
41 }
42 };
43}
44
45#[collapse_debuginfo(yes)]
46macro_rules! debug_assert {
47 ($($x:tt)*) => {
48 {
49 #[cfg(not(feature = "defmt"))]
50 ::core::debug_assert!($($x)*);
51 #[cfg(feature = "defmt")]
52 ::defmt::debug_assert!($($x)*);
53 }
54 };
55}
56
57#[collapse_debuginfo(yes)]
58macro_rules! debug_assert_eq {
59 ($($x:tt)*) => {
60 {
61 #[cfg(not(feature = "defmt"))]
62 ::core::debug_assert_eq!($($x)*);
63 #[cfg(feature = "defmt")]
64 ::defmt::debug_assert_eq!($($x)*);
65 }
66 };
67}
68
69#[collapse_debuginfo(yes)]
70macro_rules! debug_assert_ne {
71 ($($x:tt)*) => {
72 {
73 #[cfg(not(feature = "defmt"))]
74 ::core::debug_assert_ne!($($x)*);
75 #[cfg(feature = "defmt")]
76 ::defmt::debug_assert_ne!($($x)*);
77 }
78 };
79}
80
81#[collapse_debuginfo(yes)]
82macro_rules! todo {
83 ($($x:tt)*) => {
84 {
85 #[cfg(not(feature = "defmt"))]
86 ::core::todo!($($x)*);
87 #[cfg(feature = "defmt")]
88 ::defmt::todo!($($x)*);
89 }
90 };
91}
92
93#[collapse_debuginfo(yes)]
94macro_rules! unreachable {
95 ($($x:tt)*) => {
96 {
97 #[cfg(not(feature = "defmt"))]
98 ::core::unreachable!($($x)*);
99 #[cfg(feature = "defmt")]
100 ::defmt::unreachable!($($x)*);
101 }
102 };
103}
104
105#[collapse_debuginfo(yes)]
106macro_rules! panic {
107 ($($x:tt)*) => {
108 {
109 #[cfg(not(feature = "defmt"))]
110 ::core::panic!($($x)*);
111 #[cfg(feature = "defmt")]
112 ::defmt::panic!($($x)*);
113 }
114 };
115}
116
117#[collapse_debuginfo(yes)]
118macro_rules! trace {
119 ($s:literal $(, $x:expr)* $(,)?) => {
120 {
121 #[cfg(feature = "log")]
122 ::log::trace!($s $(, $x)*);
123 #[cfg(feature = "defmt")]
124 ::defmt::trace!($s $(, $x)*);
125 #[cfg(not(any(feature = "log", feature="defmt")))]
126 let _ = ($( & $x ),*);
127 }
128 };
129}
130
131#[collapse_debuginfo(yes)]
132macro_rules! debug {
133 ($s:literal $(, $x:expr)* $(,)?) => {
134 {
135 #[cfg(feature = "log")]
136 ::log::debug!($s $(, $x)*);
137 #[cfg(feature = "defmt")]
138 ::defmt::debug!($s $(, $x)*);
139 #[cfg(not(any(feature = "log", feature="defmt")))]
140 let _ = ($( & $x ),*);
141 }
142 };
143}
144
145#[collapse_debuginfo(yes)]
146macro_rules! info {
147 ($s:literal $(, $x:expr)* $(,)?) => {
148 {
149 #[cfg(feature = "log")]
150 ::log::info!($s $(, $x)*);
151 #[cfg(feature = "defmt")]
152 ::defmt::info!($s $(, $x)*);
153 #[cfg(not(any(feature = "log", feature="defmt")))]
154 let _ = ($( & $x ),*);
155 }
156 };
157}
158
159#[collapse_debuginfo(yes)]
160macro_rules! warn {
161 ($s:literal $(, $x:expr)* $(,)?) => {
162 {
163 #[cfg(feature = "log")]
164 ::log::warn!($s $(, $x)*);
165 #[cfg(feature = "defmt")]
166 ::defmt::warn!($s $(, $x)*);
167 #[cfg(not(any(feature = "log", feature="defmt")))]
168 let _ = ($( & $x ),*);
169 }
170 };
171}
172
173#[collapse_debuginfo(yes)]
174macro_rules! error {
175 ($s:literal $(, $x:expr)* $(,)?) => {
176 {
177 #[cfg(feature = "log")]
178 ::log::error!($s $(, $x)*);
179 #[cfg(feature = "defmt")]
180 ::defmt::error!($s $(, $x)*);
181 #[cfg(not(any(feature = "log", feature="defmt")))]
182 let _ = ($( & $x ),*);
183 }
184 };
185}
186
187#[cfg(feature = "defmt")]
188#[collapse_debuginfo(yes)]
189macro_rules! unwrap {
190 ($($x:tt)*) => {
191 ::defmt::unwrap!($($x)*)
192 };
193}
194
195#[cfg(not(feature = "defmt"))]
196#[collapse_debuginfo(yes)]
197macro_rules! unwrap {
198 ($arg:expr) => {
199 match $crate::fmt::Try::into_result($arg) {
200 ::core::result::Result::Ok(t) => t,
201 ::core::result::Result::Err(e) => {
202 ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
203 }
204 }
205 };
206 ($arg:expr, $($msg:expr),+ $(,)? ) => {
207 match $crate::fmt::Try::into_result($arg) {
208 ::core::result::Result::Ok(t) => t,
209 ::core::result::Result::Err(e) => {
210 ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
211 }
212 }
213 }
214}
215
216#[derive(Debug, Copy, Clone, Eq, PartialEq)]
217pub struct NoneError;
218
219pub trait Try {
220 type Ok;
221 type Error;
222 fn into_result(self) -> Result<Self::Ok, Self::Error>;
223}
224
225impl<T> Try for Option<T> {
226 type Ok = T;
227 type Error = NoneError;
228
229 #[inline]
230 fn into_result(self) -> Result<T, NoneError> {
231 self.ok_or(NoneError)
232 }
233}
234
235impl<T, E> Try for Result<T, E> {
236 type Ok = T;
237 type Error = E;
238
239 #[inline]
240 fn into_result(self) -> Self {
241 self
242 }
243}
244
245pub(crate) struct Bytes<'a>(pub &'a [u8]);
246
247impl<'a> Debug for Bytes<'a> {
248 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
249 write!(f, "{:#02x?}", self.0)
250 }
251}
252
253impl<'a> Display for Bytes<'a> {
254 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
255 write!(f, "{:#02x?}", self.0)
256 }
257}
258
259impl<'a> LowerHex for Bytes<'a> {
260 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
261 write!(f, "{:#02x?}", self.0)
262 }
263}
264
265#[cfg(feature = "defmt")]
266impl<'a> defmt::Format for Bytes<'a> {
267 fn format(&self, fmt: defmt::Formatter) {
268 defmt::write!(fmt, "{:02x}", self.0)
269 }
270}
diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs
new file mode 100644
index 000000000..2edadbc5a
--- /dev/null
+++ b/embassy-mspm0/src/gpio.rs
@@ -0,0 +1,1071 @@
1#![macro_use]
2
3use core::convert::Infallible;
4use core::future::Future;
5use core::pin::Pin as FuturePin;
6use core::task::{Context, Poll};
7
8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker;
10
11use crate::pac::gpio::vals::*;
12use crate::pac::gpio::{self};
13#[cfg(all(feature = "rt", feature = "mspm0c110x"))]
14use crate::pac::interrupt;
15use crate::pac::{self};
16
17/// Represents a digital input or output level.
18#[derive(Debug, Eq, PartialEq, Clone, Copy)]
19#[cfg_attr(feature = "defmt", derive(defmt::Format))]
20pub enum Level {
21 /// Logical low.
22 Low,
23 /// Logical high.
24 High,
25}
26
27impl From<bool> for Level {
28 fn from(val: bool) -> Self {
29 match val {
30 true => Self::High,
31 false => Self::Low,
32 }
33 }
34}
35
36impl From<Level> for bool {
37 fn from(level: Level) -> bool {
38 match level {
39 Level::Low => false,
40 Level::High => true,
41 }
42 }
43}
44
45/// Represents a pull setting for an input.
46#[derive(Debug, Clone, Copy, Eq, PartialEq)]
47pub enum Pull {
48 /// No pull.
49 None,
50 /// Internal pull-up resistor.
51 Up,
52 /// Internal pull-down resistor.
53 Down,
54}
55
56/// A GPIO bank with up to 32 pins.
57#[derive(Debug, Clone, Copy, Eq, PartialEq)]
58pub enum Port {
59 /// Port A.
60 PortA = 0,
61
62 /// Port B.
63 #[cfg(gpio_pb)]
64 PortB = 1,
65
66 /// Port C.
67 #[cfg(gpio_pc)]
68 PortC = 2,
69}
70
71/// GPIO flexible pin.
72///
73/// This pin can either be a disconnected, input, or output pin, or both. The level register bit will remain
74/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
75/// mode.
76pub struct Flex<'d> {
77 pin: Peri<'d, AnyPin>,
78}
79
80impl<'d> Flex<'d> {
81 /// Wrap the pin in a `Flex`.
82 ///
83 /// The pin remains disconnected. The initial output level is unspecified, but can be changed
84 /// before the pin is put into output mode.
85 #[inline]
86 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
87 // Pin will be in disconnected state.
88 Self { pin: pin.into() }
89 }
90
91 /// Set the pin's pull.
92 #[inline]
93 pub fn set_pull(&mut self, pull: Pull) {
94 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
95
96 pincm.modify(|w| {
97 w.set_pipd(matches!(pull, Pull::Down));
98 w.set_pipu(matches!(pull, Pull::Up));
99 });
100 }
101
102 /// Put the pin into input mode.
103 ///
104 /// The pull setting is left unchanged.
105 #[inline]
106 pub fn set_as_input(&mut self) {
107 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
108
109 pincm.modify(|w| {
110 w.set_pf(GPIO_PF);
111 w.set_hiz1(false);
112 w.set_pc(true);
113 w.set_inena(true);
114 });
115
116 self.pin.block().doeclr31_0().write(|w| {
117 w.set_dio(self.pin.bit_index(), true);
118 });
119 }
120
121 /// Put the pin into output mode.
122 ///
123 /// The pin level will be whatever was set before (or low by default). If you want it to begin
124 /// at a specific level, call `set_high`/`set_low` on the pin first.
125 #[inline]
126 pub fn set_as_output(&mut self) {
127 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
128
129 pincm.modify(|w| {
130 w.set_pf(GPIO_PF);
131 w.set_hiz1(false);
132 w.set_pc(true);
133 w.set_inena(false);
134 });
135
136 self.pin.block().doeset31_0().write(|w| {
137 w.set_dio(self.pin.bit_index(), true);
138 });
139 }
140
141 /// Put the pin into input + open-drain output mode.
142 ///
143 /// The hardware will drive the line low if you set it to low, and will leave it floating if you set
144 /// it to high, in which case you can read the input to figure out whether another device
145 /// is driving the line low.
146 ///
147 /// The pin level will be whatever was set before (or low by default). If you want it to begin
148 /// at a specific level, call `set_high`/`set_low` on the pin first.
149 ///
150 /// The internal weak pull-up and pull-down resistors will be disabled.
151 #[inline]
152 pub fn set_as_input_output(&mut self) {
153 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
154
155 pincm.modify(|w| {
156 w.set_pf(GPIO_PF);
157 w.set_hiz1(true);
158 w.set_pc(true);
159 w.set_inena(false);
160 });
161
162 self.set_pull(Pull::None);
163 }
164
165 /// Set the pin as "disconnected", ie doing nothing and consuming the lowest
166 /// amount of power possible.
167 ///
168 /// This is currently the same as [`Self::set_as_analog()`] but is semantically different
169 /// really. Drivers should `set_as_disconnected()` pins when dropped.
170 ///
171 /// Note that this also disables the internal weak pull-up and pull-down resistors.
172 #[inline]
173 pub fn set_as_disconnected(&mut self) {
174 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
175
176 pincm.modify(|w| {
177 w.set_pf(DISCONNECT_PF);
178 w.set_hiz1(false);
179 w.set_pc(false);
180 w.set_inena(false);
181 });
182
183 self.set_pull(Pull::None);
184 self.set_inversion(false);
185 }
186
187 /// Configure the logic inversion of this pin.
188 ///
189 /// Logic inversion applies to both the input and output path of this pin.
190 #[inline]
191 pub fn set_inversion(&mut self, invert: bool) {
192 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
193
194 pincm.modify(|w| {
195 w.set_inv(invert);
196 });
197 }
198
199 // TODO: drive strength, hysteresis, wakeup enable, wakeup compare
200
201 /// Put the pin into the PF mode, unchecked.
202 ///
203 /// This puts the pin into the PF mode, with the request number. This is completely unchecked,
204 /// it can attach the pin to literally any peripheral, so use with care. In addition the pin
205 /// peripheral is connected in the iomux.
206 ///
207 /// The peripheral attached to the pin depends on the part in use. Consult the datasheet
208 /// or technical reference manual for additional details.
209 #[inline]
210 pub fn set_pf_unchecked(&mut self, pf: u8) {
211 // Per SLAU893, PF is only 5 bits
212 assert!((pf & 0x3F) != 0, "PF is out of range");
213
214 let pincm = pac::IOMUX.pincm(self.pin.pin_cm() as usize);
215
216 pincm.modify(|w| {
217 w.set_pf(pf);
218 // If the PF is manually set, connect the pin
219 w.set_pc(true);
220 });
221 }
222
223 /// Get whether the pin input level is high.
224 #[inline]
225 pub fn is_high(&self) -> bool {
226 !self.is_low()
227 }
228
229 /// Get whether the pin input level is low.
230 #[inline]
231 pub fn is_low(&self) -> bool {
232 self.pin.block().din31_0().read().dio(self.pin.bit_index())
233 }
234
235 /// Returns current pin level
236 #[inline]
237 pub fn get_level(&self) -> Level {
238 self.is_high().into()
239 }
240
241 /// Set the output as high.
242 #[inline]
243 pub fn set_high(&mut self) {
244 self.pin.block().doutset31_0().write(|w| {
245 w.set_dio(self.pin.bit_index() as usize, true);
246 });
247 }
248
249 /// Set the output as low.
250 #[inline]
251 pub fn set_low(&mut self) {
252 self.pin.block().doutclr31_0().write(|w| {
253 w.set_dio(self.pin.bit_index(), true);
254 });
255 }
256
257 /// Toggle pin output
258 #[inline]
259 pub fn toggle(&mut self) {
260 self.pin.block().douttgl31_0().write(|w| {
261 w.set_dio(self.pin.bit_index(), true);
262 })
263 }
264
265 /// Set the output level.
266 #[inline]
267 pub fn set_level(&mut self, level: Level) {
268 match level {
269 Level::Low => self.set_low(),
270 Level::High => self.set_high(),
271 }
272 }
273
274 /// Get the current pin input level.
275 #[inline]
276 pub fn get_output_level(&self) -> Level {
277 self.is_high().into()
278 }
279
280 /// Is the output level high?
281 #[inline]
282 pub fn is_set_high(&self) -> bool {
283 !self.is_set_low()
284 }
285
286 /// Is the output level low?
287 #[inline]
288 pub fn is_set_low(&self) -> bool {
289 (self.pin.block().dout31_0().read().0 & self.pin.bit_index() as u32) == 0
290 }
291
292 /// Wait until the pin is high. If it is already high, return immediately.
293 #[inline]
294 pub async fn wait_for_high(&mut self) {
295 if self.is_high() {
296 return;
297 }
298
299 self.wait_for_rising_edge().await
300 }
301
302 /// Wait until the pin is low. If it is already low, return immediately.
303 #[inline]
304 pub async fn wait_for_low(&mut self) {
305 if self.is_low() {
306 return;
307 }
308
309 self.wait_for_falling_edge().await
310 }
311
312 /// Wait for the pin to undergo a transition from low to high.
313 #[inline]
314 pub async fn wait_for_rising_edge(&mut self) {
315 InputFuture::new(self.pin.reborrow(), Polarity::RISE).await
316 }
317
318 /// Wait for the pin to undergo a transition from high to low.
319 #[inline]
320 pub async fn wait_for_falling_edge(&mut self) {
321 InputFuture::new(self.pin.reborrow(), Polarity::FALL).await
322 }
323
324 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
325 #[inline]
326 pub async fn wait_for_any_edge(&mut self) {
327 InputFuture::new(self.pin.reborrow(), Polarity::RISE_FALL).await
328 }
329}
330
331impl<'d> Drop for Flex<'d> {
332 #[inline]
333 fn drop(&mut self) {
334 self.set_as_disconnected();
335 }
336}
337
338/// GPIO input driver.
339pub struct Input<'d> {
340 pin: Flex<'d>,
341}
342
343impl<'d> Input<'d> {
344 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
345 #[inline]
346 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
347 let mut pin = Flex::new(pin);
348 pin.set_as_input();
349 pin.set_pull(pull);
350 Self { pin }
351 }
352
353 /// Get whether the pin input level is high.
354 #[inline]
355 pub fn is_high(&self) -> bool {
356 self.pin.is_high()
357 }
358
359 /// Get whether the pin input level is low.
360 #[inline]
361 pub fn is_low(&self) -> bool {
362 self.pin.is_low()
363 }
364
365 /// Get the current pin input level.
366 #[inline]
367 pub fn get_level(&self) -> Level {
368 self.pin.get_level()
369 }
370
371 /// Configure the logic inversion of this pin.
372 ///
373 /// Logic inversion applies to the input path of this pin.
374 #[inline]
375 pub fn set_inversion(&mut self, invert: bool) {
376 self.pin.set_inversion(invert)
377 }
378
379 /// Wait until the pin is high. If it is already high, return immediately.
380 #[inline]
381 pub async fn wait_for_high(&mut self) {
382 self.pin.wait_for_high().await
383 }
384
385 /// Wait until the pin is low. If it is already low, return immediately.
386 #[inline]
387 pub async fn wait_for_low(&mut self) {
388 self.pin.wait_for_low().await
389 }
390
391 /// Wait for the pin to undergo a transition from low to high.
392 #[inline]
393 pub async fn wait_for_rising_edge(&mut self) {
394 self.pin.wait_for_rising_edge().await
395 }
396
397 /// Wait for the pin to undergo a transition from high to low.
398 #[inline]
399 pub async fn wait_for_falling_edge(&mut self) {
400 self.pin.wait_for_falling_edge().await
401 }
402
403 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
404 #[inline]
405 pub async fn wait_for_any_edge(&mut self) {
406 self.pin.wait_for_any_edge().await
407 }
408}
409
410/// GPIO output driver.
411///
412/// Note that pins will **return to their floating state** when `Output` is dropped.
413/// If pins should retain their state indefinitely, either keep ownership of the
414/// `Output`, or pass it to [`core::mem::forget`].
415pub struct Output<'d> {
416 pin: Flex<'d>,
417}
418
419impl<'d> Output<'d> {
420 /// Create GPIO output driver for a [Pin] with the provided [Level] configuration.
421 #[inline]
422 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
423 let mut pin = Flex::new(pin);
424 pin.set_as_output();
425 pin.set_level(initial_output);
426 Self { pin }
427 }
428
429 /// Set the output as high.
430 #[inline]
431 pub fn set_high(&mut self) {
432 self.pin.set_high();
433 }
434
435 /// Set the output as low.
436 #[inline]
437 pub fn set_low(&mut self) {
438 self.pin.set_low();
439 }
440
441 /// Set the output level.
442 #[inline]
443 pub fn set_level(&mut self, level: Level) {
444 self.pin.set_level(level)
445 }
446
447 /// Is the output pin set as high?
448 #[inline]
449 pub fn is_set_high(&self) -> bool {
450 self.pin.is_set_high()
451 }
452
453 /// Is the output pin set as low?
454 #[inline]
455 pub fn is_set_low(&self) -> bool {
456 self.pin.is_set_low()
457 }
458
459 /// What level output is set to
460 #[inline]
461 pub fn get_output_level(&self) -> Level {
462 self.pin.get_output_level()
463 }
464
465 /// Toggle pin output
466 #[inline]
467 pub fn toggle(&mut self) {
468 self.pin.toggle();
469 }
470
471 /// Configure the logic inversion of this pin.
472 ///
473 /// Logic inversion applies to the input path of this pin.
474 #[inline]
475 pub fn set_inversion(&mut self, invert: bool) {
476 self.pin.set_inversion(invert)
477 }
478}
479
480/// GPIO output open-drain driver.
481///
482/// Note that pins will **return to their floating state** when `OutputOpenDrain` is dropped.
483/// If pins should retain their state indefinitely, either keep ownership of the
484/// `OutputOpenDrain`, or pass it to [`core::mem::forget`].
485pub struct OutputOpenDrain<'d> {
486 pin: Flex<'d>,
487}
488
489impl<'d> OutputOpenDrain<'d> {
490 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level].
491 #[inline]
492 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
493 let mut pin = Flex::new(pin);
494 pin.set_level(initial_output);
495 pin.set_as_input_output();
496 Self { pin }
497 }
498
499 /// Get whether the pin input level is high.
500 #[inline]
501 pub fn is_high(&self) -> bool {
502 !self.pin.is_low()
503 }
504
505 /// Get whether the pin input level is low.
506 #[inline]
507 pub fn is_low(&self) -> bool {
508 self.pin.is_low()
509 }
510
511 /// Get the current pin input level.
512 #[inline]
513 pub fn get_level(&self) -> Level {
514 self.pin.get_level()
515 }
516
517 /// Set the output as high.
518 #[inline]
519 pub fn set_high(&mut self) {
520 self.pin.set_high();
521 }
522
523 /// Set the output as low.
524 #[inline]
525 pub fn set_low(&mut self) {
526 self.pin.set_low();
527 }
528
529 /// Set the output level.
530 #[inline]
531 pub fn set_level(&mut self, level: Level) {
532 self.pin.set_level(level);
533 }
534
535 /// Get whether the output level is set to high.
536 #[inline]
537 pub fn is_set_high(&self) -> bool {
538 self.pin.is_set_high()
539 }
540
541 /// Get whether the output level is set to low.
542 #[inline]
543 pub fn is_set_low(&self) -> bool {
544 self.pin.is_set_low()
545 }
546
547 /// Get the current output level.
548 #[inline]
549 pub fn get_output_level(&self) -> Level {
550 self.pin.get_output_level()
551 }
552
553 /// Toggle pin output
554 #[inline]
555 pub fn toggle(&mut self) {
556 self.pin.toggle()
557 }
558
559 /// Configure the logic inversion of this pin.
560 ///
561 /// Logic inversion applies to the input path of this pin.
562 #[inline]
563 pub fn set_inversion(&mut self, invert: bool) {
564 self.pin.set_inversion(invert)
565 }
566
567 /// Wait until the pin is high. If it is already high, return immediately.
568 #[inline]
569 pub async fn wait_for_high(&mut self) {
570 self.pin.wait_for_high().await
571 }
572
573 /// Wait until the pin is low. If it is already low, return immediately.
574 #[inline]
575 pub async fn wait_for_low(&mut self) {
576 self.pin.wait_for_low().await
577 }
578
579 /// Wait for the pin to undergo a transition from low to high.
580 #[inline]
581 pub async fn wait_for_rising_edge(&mut self) {
582 self.pin.wait_for_rising_edge().await
583 }
584
585 /// Wait for the pin to undergo a transition from high to low.
586 #[inline]
587 pub async fn wait_for_falling_edge(&mut self) {
588 self.pin.wait_for_falling_edge().await
589 }
590
591 /// Wait for the pin to undergo any transition, i.e low to high OR high to low.
592 #[inline]
593 pub async fn wait_for_any_edge(&mut self) {
594 self.pin.wait_for_any_edge().await
595 }
596}
597
598/// Type-erased GPIO pin
599pub struct AnyPin {
600 pub(crate) pin_port: u8,
601}
602
603impl AnyPin {
604 /// Create an [AnyPin] for a specific pin.
605 ///
606 /// # Safety
607 /// - `pin_port` should not in use by another driver.
608 #[inline]
609 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
610 Peri::new_unchecked(Self { pin_port })
611 }
612}
613
614impl_peripheral!(AnyPin);
615
616impl Pin for AnyPin {}
617impl SealedPin for AnyPin {
618 #[inline]
619 fn pin_port(&self) -> u8 {
620 self.pin_port
621 }
622}
623
624/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
625#[allow(private_bounds)]
626pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
627 /// The index of this pin in PINCM (pin control management) registers.
628 #[inline]
629 fn pin_cm(&self) -> u8 {
630 self._pin_cm()
631 }
632}
633
634impl<'d> embedded_hal::digital::ErrorType for Flex<'d> {
635 type Error = Infallible;
636}
637
638impl<'d> embedded_hal::digital::InputPin for Flex<'d> {
639 #[inline]
640 fn is_high(&mut self) -> Result<bool, Self::Error> {
641 Ok((*self).is_high())
642 }
643
644 #[inline]
645 fn is_low(&mut self) -> Result<bool, Self::Error> {
646 Ok((*self).is_low())
647 }
648}
649
650impl<'d> embedded_hal::digital::OutputPin for Flex<'d> {
651 #[inline]
652 fn set_low(&mut self) -> Result<(), Self::Error> {
653 Ok(self.set_low())
654 }
655
656 #[inline]
657 fn set_high(&mut self) -> Result<(), Self::Error> {
658 Ok(self.set_high())
659 }
660}
661
662impl<'d> embedded_hal::digital::StatefulOutputPin for Flex<'d> {
663 #[inline]
664 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
665 Ok((*self).is_set_high())
666 }
667
668 #[inline]
669 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
670 Ok((*self).is_set_low())
671 }
672}
673
674impl<'d> embedded_hal_async::digital::Wait for Flex<'d> {
675 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
676 self.wait_for_high().await;
677 Ok(())
678 }
679
680 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
681 self.wait_for_low().await;
682 Ok(())
683 }
684
685 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
686 self.wait_for_rising_edge().await;
687 Ok(())
688 }
689
690 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
691 self.wait_for_falling_edge().await;
692 Ok(())
693 }
694
695 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
696 self.wait_for_any_edge().await;
697 Ok(())
698 }
699}
700
701impl<'d> embedded_hal::digital::ErrorType for Input<'d> {
702 type Error = Infallible;
703}
704
705impl<'d> embedded_hal::digital::InputPin for Input<'d> {
706 #[inline]
707 fn is_high(&mut self) -> Result<bool, Self::Error> {
708 Ok((*self).is_high())
709 }
710
711 #[inline]
712 fn is_low(&mut self) -> Result<bool, Self::Error> {
713 Ok((*self).is_low())
714 }
715}
716
717impl<'d> embedded_hal_async::digital::Wait for Input<'d> {
718 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
719 self.wait_for_high().await;
720 Ok(())
721 }
722
723 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
724 self.wait_for_low().await;
725 Ok(())
726 }
727
728 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
729 self.wait_for_rising_edge().await;
730 Ok(())
731 }
732
733 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
734 self.wait_for_falling_edge().await;
735 Ok(())
736 }
737
738 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
739 self.wait_for_any_edge().await;
740 Ok(())
741 }
742}
743
744impl<'d> embedded_hal::digital::ErrorType for Output<'d> {
745 type Error = Infallible;
746}
747
748impl<'d> embedded_hal::digital::OutputPin for Output<'d> {
749 #[inline]
750 fn set_low(&mut self) -> Result<(), Self::Error> {
751 Ok(self.set_low())
752 }
753
754 #[inline]
755 fn set_high(&mut self) -> Result<(), Self::Error> {
756 Ok(self.set_high())
757 }
758}
759
760impl<'d> embedded_hal::digital::StatefulOutputPin for Output<'d> {
761 #[inline]
762 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
763 Ok((*self).is_set_high())
764 }
765
766 #[inline]
767 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
768 Ok((*self).is_set_low())
769 }
770}
771
772impl<'d> embedded_hal::digital::ErrorType for OutputOpenDrain<'d> {
773 type Error = Infallible;
774}
775
776impl<'d> embedded_hal::digital::InputPin for OutputOpenDrain<'d> {
777 #[inline]
778 fn is_high(&mut self) -> Result<bool, Self::Error> {
779 Ok((*self).is_high())
780 }
781
782 #[inline]
783 fn is_low(&mut self) -> Result<bool, Self::Error> {
784 Ok((*self).is_low())
785 }
786}
787
788impl<'d> embedded_hal::digital::OutputPin for OutputOpenDrain<'d> {
789 #[inline]
790 fn set_low(&mut self) -> Result<(), Self::Error> {
791 Ok(self.set_low())
792 }
793
794 #[inline]
795 fn set_high(&mut self) -> Result<(), Self::Error> {
796 Ok(self.set_high())
797 }
798}
799
800impl<'d> embedded_hal::digital::StatefulOutputPin for OutputOpenDrain<'d> {
801 #[inline]
802 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
803 Ok((*self).is_set_high())
804 }
805
806 #[inline]
807 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
808 Ok((*self).is_set_low())
809 }
810}
811
812impl<'d> embedded_hal_async::digital::Wait for OutputOpenDrain<'d> {
813 async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
814 self.wait_for_high().await;
815 Ok(())
816 }
817
818 async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
819 self.wait_for_low().await;
820 Ok(())
821 }
822
823 async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
824 self.wait_for_rising_edge().await;
825 Ok(())
826 }
827
828 async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
829 self.wait_for_falling_edge().await;
830 Ok(())
831 }
832
833 async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
834 self.wait_for_any_edge().await;
835 Ok(())
836 }
837}
838
839/// The pin function to disconnect peripherals from the pin.
840///
841/// This is also the pin function used to connect to analog peripherals, such as an ADC.
842const DISCONNECT_PF: u8 = 0;
843
844/// The pin function for the GPIO peripheral.
845///
846/// This is fixed to `1` for every part.
847const GPIO_PF: u8 = 1;
848
849macro_rules! impl_pin {
850 ($name: ident, $port: expr, $pin_num: expr) => {
851 impl crate::gpio::Pin for crate::peripherals::$name {}
852 impl crate::gpio::SealedPin for crate::peripherals::$name {
853 #[inline]
854 fn pin_port(&self) -> u8 {
855 ($port as u8) * 32 + $pin_num
856 }
857 }
858
859 impl From<crate::peripherals::$name> for crate::gpio::AnyPin {
860 fn from(val: crate::peripherals::$name) -> Self {
861 Self {
862 pin_port: crate::gpio::SealedPin::pin_port(&val),
863 }
864 }
865 }
866 };
867}
868
869// TODO: Possible micro-op for C110X, not every pin is instantiated even on the 20 pin parts.
870// This would mean cfg guarding to just cfg guarding every pin instance.
871static PORTA_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
872#[cfg(gpio_pb)]
873static PORTB_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
874#[cfg(gpio_pc)]
875static PORTC_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
876
877pub(crate) trait SealedPin {
878 fn pin_port(&self) -> u8;
879
880 fn port(&self) -> Port {
881 match self.pin_port() / 32 {
882 0 => Port::PortA,
883 #[cfg(gpio_pb)]
884 1 => Port::PortB,
885 #[cfg(gpio_pc)]
886 2 => Port::PortC,
887 _ => unreachable!(),
888 }
889 }
890
891 fn waker(&self) -> &AtomicWaker {
892 match self.port() {
893 Port::PortA => &PORTA_WAKERS[self.bit_index()],
894 #[cfg(gpio_pb)]
895 Port::PortB => &PORTB_WAKERS[self.bit_index()],
896 #[cfg(gpio_pc)]
897 Port::PortC => &PORTC_WAKERS[self.bit_index()],
898 }
899 }
900
901 fn _pin_cm(&self) -> u8 {
902 // Some parts like the MSPM0L222x have pincm mappings all over the place.
903 crate::gpio_pincm(self.pin_port())
904 }
905
906 fn bit_index(&self) -> usize {
907 (self.pin_port() % 32) as usize
908 }
909
910 #[inline]
911 fn block(&self) -> gpio::Gpio {
912 match self.pin_port() / 32 {
913 0 => pac::GPIOA,
914 #[cfg(gpio_pb)]
915 1 => pac::GPIOB,
916 #[cfg(gpio_pc)]
917 2 => pac::GPIOC,
918 _ => unreachable!(),
919 }
920 }
921}
922
923#[must_use = "futures do nothing unless you `.await` or poll them"]
924struct InputFuture<'d> {
925 pin: Peri<'d, AnyPin>,
926}
927
928impl<'d> InputFuture<'d> {
929 fn new(pin: Peri<'d, AnyPin>, polarity: Polarity) -> Self {
930 let block = pin.block();
931
932 // Before clearing any previous edge events, we must disable events.
933 //
934 // If we don't do this, it is possible that after we clear the interrupt, the current event
935 // the hardware is listening for may not be the same event we will configure. This may result
936 // in RIS being set. Then when interrupts are unmasked and RIS is set, we may get the wrong event
937 // causing an interrupt.
938 //
939 // Selecting which polarity events happen is a RMW operation.
940 critical_section::with(|_cs| {
941 if pin.bit_index() >= 16 {
942 block.polarity31_16().modify(|w| {
943 w.set_dio(pin.bit_index() - 16, Polarity::DISABLE);
944 });
945 } else {
946 block.polarity15_0().modify(|w| {
947 w.set_dio(pin.bit_index(), Polarity::DISABLE);
948 });
949 };
950 });
951
952 // First clear the bit for this event. Otherwise previous edge events may be recorded.
953 block.cpu_int().iclr().write(|w| {
954 w.set_dio(pin.bit_index(), true);
955 });
956
957 // Selecting which polarity events happen is a RMW operation.
958 critical_section::with(|_cs| {
959 // Tell the hardware which pin event we want to receive.
960 if pin.bit_index() >= 16 {
961 block.polarity31_16().modify(|w| {
962 w.set_dio(pin.bit_index() - 16, polarity);
963 });
964 } else {
965 block.polarity15_0().modify(|w| {
966 w.set_dio(pin.bit_index(), polarity);
967 });
968 };
969 });
970
971 Self { pin }
972 }
973}
974
975impl<'d> Future for InputFuture<'d> {
976 type Output = ();
977
978 fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
979 // We need to register/re-register the waker for each poll because any
980 // calls to wake will deregister the waker.
981 let waker = self.pin.waker();
982 waker.register(cx.waker());
983
984 // The interrupt handler will mask the interrupt if the event has occurred.
985 if self.pin.block().cpu_int().ris().read().dio(self.pin.bit_index()) {
986 return Poll::Ready(());
987 }
988
989 // Unmasking the interrupt is a RMW operation.
990 //
991 // Guard with a critical section in case two different threads try to unmask at the same time.
992 critical_section::with(|_cs| {
993 self.pin.block().cpu_int().imask().modify(|w| {
994 w.set_dio(self.pin.bit_index(), true);
995 });
996 });
997
998 Poll::Pending
999 }
1000}
1001
1002pub(crate) fn init(gpio: gpio::Gpio) {
1003 gpio.gprcm().rstctl().write(|w| {
1004 w.set_resetstkyclr(true);
1005 w.set_resetassert(true);
1006 w.set_key(ResetKey::KEY);
1007 });
1008
1009 gpio.gprcm().pwren().write(|w| {
1010 w.set_enable(true);
1011 w.set_key(PwrenKey::KEY);
1012 });
1013
1014 gpio.evt_mode().modify(|w| {
1015 // The CPU will clear it's own interrupts
1016 w.set_cpu_cfg(EvtCfg::SOFTWARE);
1017 });
1018}
1019
1020#[cfg(feature = "rt")]
1021fn irq_handler(gpio: gpio::Gpio, wakers: &[AtomicWaker; 32]) {
1022 // Only consider pins which have interrupts unmasked.
1023 let bits = gpio.cpu_int().mis().read().0;
1024
1025 for i in BitIter(bits) {
1026 wakers[i as usize].wake();
1027
1028 // Notify the future that an edge event has occurred by masking the interrupt for this pin.
1029 gpio.cpu_int().imask().modify(|w| {
1030 w.set_dio(i as usize, false);
1031 });
1032 }
1033}
1034
1035struct BitIter(u32);
1036
1037impl Iterator for BitIter {
1038 type Item = u32;
1039
1040 fn next(&mut self) -> Option<Self::Item> {
1041 match self.0.trailing_zeros() {
1042 32 => None,
1043 b => {
1044 self.0 &= !(1 << b);
1045 Some(b)
1046 }
1047 }
1048 }
1049}
1050
1051// C110x has a dedicated interrupt just for GPIOA, as it does not have a GROUP1 interrupt.
1052#[cfg(all(feature = "rt", feature = "mspm0c110x"))]
1053#[interrupt]
1054fn GPIOA() {
1055 gpioa_interrupt();
1056}
1057
1058#[cfg(feature = "rt")]
1059pub(crate) fn gpioa_interrupt() {
1060 irq_handler(pac::GPIOA, &PORTA_WAKERS);
1061}
1062
1063#[cfg(all(feature = "rt", gpio_pb))]
1064pub(crate) fn gpiob_interrupt() {
1065 irq_handler(pac::GPIOB, &PORTB_WAKERS);
1066}
1067
1068#[cfg(all(feature = "rt", gpio_pc))]
1069pub(crate) fn gpioc_interrupt() {
1070 irq_handler(pac::GPIOC, &PORTC_WAKERS);
1071}
diff --git a/embassy-mspm0/src/int_group/c110x.rs b/embassy-mspm0/src/int_group/c110x.rs
new file mode 100644
index 000000000..e6a9ddb99
--- /dev/null
+++ b/embassy-mspm0/src/int_group/c110x.rs
@@ -0,0 +1,25 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // TODO: Decompose to direct u8
12 let iidx = group.iidx().read().stat().to_bits();
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
diff --git a/embassy-mspm0/src/int_group/g350x.rs b/embassy-mspm0/src/int_group/g350x.rs
new file mode 100644
index 000000000..706ba2078
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g350x.rs
@@ -0,0 +1,51 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 }
51}
diff --git a/embassy-mspm0/src/int_group/g351x.rs b/embassy-mspm0/src/int_group/g351x.rs
new file mode 100644
index 000000000..e785018a7
--- /dev/null
+++ b/embassy-mspm0/src/int_group/g351x.rs
@@ -0,0 +1,52 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::WWDT1 => todo!("implement WWDT1"),
22 Group0::DEBUGSS => todo!("implement DEBUGSS"),
23 Group0::FLASHCTL => todo!("implement FLASHCTL"),
24 Group0::SYSCTL => todo!("implement SYSCTL"),
25 }
26}
27
28#[cfg(feature = "rt")]
29#[interrupt]
30fn GROUP1() {
31 use mspm0_metapac::Group1;
32
33 let group = pac::CPUSS.int_group(1);
34
35 // Must subtract by 1 since NO_INTR is value 0
36 let iidx = group.iidx().read().stat().to_bits() - 1;
37
38 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
39 debug!("Invalid IIDX for group 1: {}", iidx);
40 return;
41 };
42
43 match group {
44 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
45 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
46 Group1::COMP0 => todo!("implement COMP0"),
47 Group1::COMP1 => todo!("implement COMP1"),
48 Group1::COMP2 => todo!("implement COMP2"),
49 Group1::TRNG => todo!("implement TRNG"),
50 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
51 }
52}
diff --git a/embassy-mspm0/src/int_group/l130x.rs b/embassy-mspm0/src/int_group/l130x.rs
new file mode 100644
index 000000000..8be5adcad
--- /dev/null
+++ b/embassy-mspm0/src/int_group/l130x.rs
@@ -0,0 +1,46 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::COMP0 => todo!("implement COMP0"),
45 }
46}
diff --git a/embassy-mspm0/src/int_group/l222x.rs b/embassy-mspm0/src/int_group/l222x.rs
new file mode 100644
index 000000000..eeb2ce70d
--- /dev/null
+++ b/embassy-mspm0/src/int_group/l222x.rs
@@ -0,0 +1,49 @@
1use crate::pac;
2use crate::pac::interrupt;
3
4#[cfg(feature = "rt")]
5#[interrupt]
6fn GROUP0() {
7 use mspm0_metapac::Group0;
8
9 let group = pac::CPUSS.int_group(0);
10
11 // Must subtract by 1 since NO_INTR is value 0
12 let iidx = group.iidx().read().stat().to_bits() - 1;
13
14 let Ok(group) = pac::Group0::try_from(iidx as u8) else {
15 debug!("Invalid IIDX for group 0: {}", iidx);
16 return;
17 };
18
19 match group {
20 Group0::WWDT0 => todo!("implement WWDT0"),
21 Group0::DEBUGSS => todo!("implement DEBUGSS"),
22 Group0::FLASHCTL => todo!("implement FLASHCTL"),
23 Group0::SYSCTL => todo!("implement SYSCTL"),
24 }
25}
26
27#[cfg(feature = "rt")]
28#[interrupt]
29fn GROUP1() {
30 use mspm0_metapac::Group1;
31
32 let group = pac::CPUSS.int_group(1);
33
34 // Must subtract by 1 since NO_INTR is value 0
35 let iidx = group.iidx().read().stat().to_bits() - 1;
36
37 let Ok(group) = pac::Group1::try_from(iidx as u8) else {
38 debug!("Invalid IIDX for group 1: {}", iidx);
39 return;
40 };
41
42 match group {
43 Group1::GPIOA => crate::gpio::gpioa_interrupt(),
44 Group1::GPIOB => crate::gpio::gpiob_interrupt(),
45 Group1::COMP0 => todo!("implement COMP0"),
46 Group1::TRNG => todo!("implement TRNG"),
47 Group1::GPIOC => crate::gpio::gpioc_interrupt(),
48 }
49}
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs
new file mode 100644
index 000000000..99b7ed4a1
--- /dev/null
+++ b/embassy-mspm0/src/lib.rs
@@ -0,0 +1,119 @@
1#![no_std]
2// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc
3#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))]
4
5// This mod MUST go first, so that the others see its macros.
6pub(crate) mod fmt;
7
8pub mod gpio;
9pub mod timer;
10
11/// Operating modes for peripherals.
12pub mod mode {
13 trait SealedMode {}
14
15 /// Operating mode for a peripheral.
16 #[allow(private_bounds)]
17 pub trait Mode: SealedMode {}
18
19 /// Blocking mode.
20 pub struct Blocking;
21 impl SealedMode for Blocking {}
22 impl Mode for Blocking {}
23
24 /// Async mode.
25 pub struct Async;
26 impl SealedMode for Async {}
27 impl Mode for Async {}
28}
29
30#[cfg(feature = "_time-driver")]
31mod time_driver;
32
33// Interrupt group handlers.
34#[cfg_attr(feature = "mspm0c110x", path = "int_group/c110x.rs")]
35#[cfg_attr(feature = "mspm0g350x", path = "int_group/g350x.rs")]
36#[cfg_attr(feature = "mspm0g351x", path = "int_group/g351x.rs")]
37#[cfg_attr(feature = "mspm0l130x", path = "int_group/l130x.rs")]
38#[cfg_attr(feature = "mspm0l222x", path = "int_group/l222x.rs")]
39mod int_group;
40
41pub(crate) mod _generated {
42 #![allow(dead_code)]
43 #![allow(unused_imports)]
44 #![allow(non_snake_case)]
45 #![allow(missing_docs)]
46
47 include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
48}
49
50// Reexports
51pub(crate) use _generated::gpio_pincm;
52pub use _generated::{peripherals, Peripherals};
53pub use embassy_hal_internal::Peri;
54#[cfg(feature = "unstable-pac")]
55pub use mspm0_metapac as pac;
56#[cfg(not(feature = "unstable-pac"))]
57pub(crate) use mspm0_metapac as pac;
58
59pub use crate::_generated::interrupt;
60
61/// `embassy-mspm0` global configuration.
62#[non_exhaustive]
63#[derive(Clone, Copy)]
64pub struct Config {
65 // TODO
66}
67
68impl Default for Config {
69 fn default() -> Self {
70 Self {
71 // TODO
72 }
73 }
74}
75
76pub fn init(_config: Config) -> Peripherals {
77 critical_section::with(|cs| {
78 let peripherals = Peripherals::take_with_cs(cs);
79
80 // TODO: Further clock configuration
81
82 pac::SYSCTL.mclkcfg().modify(|w| {
83 // Enable MFCLK
84 w.set_usemftick(true);
85 // MDIV must be disabled if MFCLK is enabled.
86 w.set_mdiv(0);
87 });
88
89 // Enable MFCLK for peripheral use
90 //
91 // TODO: Optional?
92 pac::SYSCTL.genclken().modify(|w| {
93 w.set_mfpclken(true);
94 });
95
96 pac::SYSCTL.borthreshold().modify(|w| {
97 w.set_level(0);
98 });
99
100 gpio::init(pac::GPIOA);
101 #[cfg(gpio_pb)]
102 gpio::init(pac::GPIOB);
103 #[cfg(gpio_pc)]
104 gpio::init(pac::GPIOC);
105
106 _generated::enable_group_interrupts(cs);
107
108 #[cfg(feature = "mspm0c110x")]
109 unsafe {
110 use crate::_generated::interrupt::typelevel::Interrupt;
111 crate::interrupt::typelevel::GPIOA::enable();
112 }
113
114 #[cfg(feature = "_time-driver")]
115 time_driver::init(cs);
116
117 peripherals
118 })
119}
diff --git a/embassy-mspm0/src/time_driver.rs b/embassy-mspm0/src/time_driver.rs
new file mode 100644
index 000000000..e80e89e55
--- /dev/null
+++ b/embassy-mspm0/src/time_driver.rs
@@ -0,0 +1,426 @@
1use core::cell::{Cell, RefCell};
2use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
3use core::task::Waker;
4
5use critical_section::{CriticalSection, Mutex};
6use embassy_time_driver::Driver;
7use embassy_time_queue_utils::Queue;
8use mspm0_metapac::interrupt;
9use mspm0_metapac::tim::vals::{Cm, Cvae, CxC, EvtCfg, PwrenKey, Ratio, Repeat, ResetKey};
10use mspm0_metapac::tim::{Counterregs16, Tim};
11
12use crate::peripherals;
13use crate::timer::SealedTimer;
14
15#[cfg(any(time_driver_timg12, time_driver_timg13))]
16compile_error!("TIMG12 and TIMG13 are not supported by the time driver yet");
17
18// Currently TIMG12 and TIMG13 are excluded because those are 32-bit timers.
19#[cfg(time_driver_timg0)]
20type T = peripherals::TIMG0;
21#[cfg(time_driver_timg1)]
22type T = peripherals::TIMG1;
23#[cfg(time_driver_timg2)]
24type T = peripherals::TIMG2;
25#[cfg(time_driver_timg3)]
26type T = peripherals::TIMG3;
27#[cfg(time_driver_timg4)]
28type T = peripherals::TIMG4;
29#[cfg(time_driver_timg5)]
30type T = peripherals::TIMG5;
31#[cfg(time_driver_timg6)]
32type T = peripherals::TIMG6;
33#[cfg(time_driver_timg7)]
34type T = peripherals::TIMG7;
35#[cfg(time_driver_timg8)]
36type T = peripherals::TIMG8;
37#[cfg(time_driver_timg9)]
38type T = peripherals::TIMG9;
39#[cfg(time_driver_timg10)]
40type T = peripherals::TIMG10;
41#[cfg(time_driver_timg11)]
42type T = peripherals::TIMG11;
43#[cfg(time_driver_timg14)]
44type T = peripherals::TIMG14;
45#[cfg(time_driver_tima0)]
46type T = peripherals::TIMA0;
47#[cfg(time_driver_tima1)]
48type T = peripherals::TIMA1;
49
50// TODO: RTC
51
52fn regs() -> Tim {
53 unsafe { Tim::from_ptr(T::regs()) }
54}
55
56fn regs_counter(tim: Tim) -> Counterregs16 {
57 unsafe { Counterregs16::from_ptr(tim.counterregs(0).as_ptr()) }
58}
59
60/// Clock timekeeping works with something we call "periods", which are time intervals
61/// of 2^15 ticks. The Clock counter value is 16 bits, so one "overflow cycle" is 2 periods.
62fn calc_now(period: u32, counter: u16) -> u64 {
63 ((period as u64) << 15) + ((counter as u32 ^ ((period & 1) << 15)) as u64)
64}
65
66/// The TIMx driver uses one of the `TIMG` or `TIMA` timer instances to implement a timer with a 32.768 kHz
67/// tick rate. (TODO: Allow setting the tick rate)
68///
69/// This driver defines a period to be 2^15 ticks. 16-bit timers of course count to 2^16 ticks.
70///
71/// To generate a period every 2^15 ticks, the CC0 value is set to 2^15 and the load value set to 2^16.
72/// Incrementing the period on a CCU0 and load results in the a period of 2^15 ticks.
73///
74/// For a specific timestamp, load the lower 16 bits into the CC1 value. When the period where the timestamp
75/// should be enabled is reached, then the CCU1 (CC1 up) interrupt runs to actually wake the timer.
76///
77/// TODO: Compensate for per part variance. This can supposedly be done with the FCC system.
78/// TODO: Allow using 32-bit timers (TIMG12 and TIMG13).
79struct TimxDriver {
80 /// Number of 2^15 periods elapsed since boot.
81 period: AtomicU32,
82 /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled.
83 alarm: Mutex<Cell<u64>>,
84 queue: Mutex<RefCell<Queue>>,
85}
86
87impl TimxDriver {
88 #[inline(never)]
89 fn init(&'static self, _cs: CriticalSection) {
90 // Clock config
91 // TODO: Configurable tick rate up to 4 MHz (32 kHz for now)
92 let regs = regs();
93
94 // Reset timer
95 regs.gprcm(0).rstctl().write(|w| {
96 w.set_resetassert(true);
97 w.set_key(ResetKey::KEY);
98 w.set_resetstkyclr(true);
99 });
100
101 // Power up timer
102 regs.gprcm(0).pwren().write(|w| {
103 w.set_enable(true);
104 w.set_key(PwrenKey::KEY);
105 });
106
107 // Following the instructions according to SLAU847D 23.2.1: TIMCLK Configuration
108
109 // 1. Select TIMCLK source
110 regs.clksel().modify(|w| {
111 // Use LFCLK for a 32.768kHz tick rate
112 w.set_lfclk_sel(true);
113 // TODO: Allow MFCLK for configurable tick rate up to 4 MHz
114 // w.set_mfclk_sel(ClkSel::ENABLE);
115 });
116
117 // 2. Divide by TIMCLK, we don't need to divide further for the 32kHz tick rate
118 regs.clkdiv().modify(|w| {
119 w.set_ratio(Ratio::DIV_BY_1);
120 });
121
122 // 3. To be generic across timer instances, we do not use the prescaler.
123 // TODO: mspm0-sdk always sets this, regardless of timer width?
124 regs.commonregs(0).cps().modify(|w| {
125 w.set_pcnt(0);
126 });
127
128 regs.pdbgctl().modify(|w| {
129 w.set_free(true);
130 });
131
132 // 4. Enable the TIMCLK.
133 regs.commonregs(0).cclkctl().modify(|w| {
134 w.set_clken(true);
135 });
136
137 regs.counterregs(0).ctrctl().modify(|w| {
138 // allow counting during debug
139 w.set_repeat(Repeat::REPEAT_3);
140 w.set_cvae(Cvae::ZEROVAL);
141 w.set_cm(Cm::UP);
142
143 // Must explicitly set CZC, CAC and CLC to 0 in order for all the timers to count.
144 //
145 // The reset value of these registers is 0x07, which is a reserved value.
146 //
147 // Looking at a bit representation of the reset value, this appears to be an AND
148 // of 2-input QEI mode and CCCTL_3 ACOND. Given that TIMG14 and TIMA0 have no QEI
149 // and 4 capture and compare channels, this works by accident for those timer units.
150 w.set_czc(CxC::CCTL0);
151 w.set_cac(CxC::CCTL0);
152 w.set_clc(CxC::CCTL0);
153 });
154
155 // Setup the period
156 let ctr = regs_counter(regs);
157
158 // Middle
159 ctr.cc(0).modify(|w| {
160 w.set_ccval(0x7FFF);
161 });
162
163 ctr.load().modify(|w| {
164 w.set_ld(u16::MAX);
165 });
166
167 // Enable the period interrupts
168 //
169 // This does not appear to ever be set for CPU_INT in the TI SDK and is not technically needed.
170 regs.evt_mode().modify(|w| {
171 w.set_evt_cfg(0, EvtCfg::SOFTWARE);
172 });
173
174 regs.int_event(0).imask().modify(|w| {
175 w.set_l(true);
176 w.set_ccu0(true);
177 });
178
179 unsafe { T::enable_interrupt() };
180
181 // Allow the counter to start counting.
182 regs.counterregs(0).ctrctl().modify(|w| {
183 w.set_en(true);
184 });
185 }
186
187 #[inline(never)]
188 fn next_period(&self) {
189 let r = regs();
190
191 // We only modify the period from the timer interrupt, so we know this can't race.
192 let period = self.period.load(Ordering::Relaxed) + 1;
193 self.period.store(period, Ordering::Relaxed);
194 let t = (period as u64) << 15;
195
196 critical_section::with(move |cs| {
197 r.int_event(0).imask().modify(move |w| {
198 let alarm = self.alarm.borrow(cs);
199 let at = alarm.get();
200
201 if at < t + 0xC000 {
202 // just enable it. `set_alarm` has already set the correct CC1 val.
203 w.set_ccu1(true);
204 }
205 })
206 });
207 }
208
209 #[inline(never)]
210 fn on_interrupt(&self) {
211 let r = regs();
212
213 critical_section::with(|cs| {
214 let mis = r.int_event(0).mis().read();
215
216 // Advance to next period if overflowed
217 if mis.l() {
218 self.next_period();
219
220 r.int_event(0).iclr().write(|w| {
221 w.set_l(true);
222 });
223 }
224
225 if mis.ccu0() {
226 self.next_period();
227
228 r.int_event(0).iclr().write(|w| {
229 w.set_ccu0(true);
230 });
231 }
232
233 if mis.ccu1() {
234 r.int_event(0).iclr().write(|w| {
235 w.set_ccu1(true);
236 });
237
238 self.trigger_alarm(cs);
239 }
240 });
241 }
242
243 fn trigger_alarm(&self, cs: CriticalSection) {
244 let mut next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now());
245
246 while !self.set_alarm(cs, next) {
247 next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now());
248 }
249 }
250
251 fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool {
252 let r = regs();
253 let ctr = regs_counter(r);
254
255 self.alarm.borrow(cs).set(timestamp);
256
257 let t = self.now();
258
259 if timestamp <= t {
260 // If alarm timestamp has passed the alarm will not fire.
261 // Disarm the alarm and return `false` to indicate that.
262 r.int_event(0).imask().modify(|w| w.set_ccu1(false));
263
264 self.alarm.borrow(cs).set(u64::MAX);
265
266 return false;
267 }
268
269 // Write the CC1 value regardless of whether we're going to enable it now or not.
270 // This way, when we enable it later, the right value is already set.
271 ctr.cc(1).write(|w| {
272 w.set_ccval(timestamp as u16);
273 });
274
275 // Enable it if it'll happen soon. Otherwise, `next_period` will enable it.
276 let diff = timestamp - t;
277 r.int_event(0).imask().modify(|w| w.set_ccu1(diff < 0xC000));
278
279 // Reevaluate if the alarm timestamp is still in the future
280 let t = self.now();
281 if timestamp <= t {
282 // If alarm timestamp has passed since we set it, we have a race condition and
283 // the alarm may or may not have fired.
284 // Disarm the alarm and return `false` to indicate that.
285 // It is the caller's responsibility to handle this ambiguity.
286 r.int_event(0).imask().modify(|w| w.set_ccu1(false));
287
288 self.alarm.borrow(cs).set(u64::MAX);
289
290 return false;
291 }
292
293 // We're confident the alarm will ring in the future.
294 true
295 }
296}
297
298impl Driver for TimxDriver {
299 fn now(&self) -> u64 {
300 let regs = regs();
301
302 let period = self.period.load(Ordering::Relaxed);
303 // Ensure the compiler does not read the counter before the period.
304 compiler_fence(Ordering::Acquire);
305
306 let counter = regs_counter(regs).ctr().read().cctr() as u16;
307
308 calc_now(period, counter)
309 }
310
311 fn schedule_wake(&self, at: u64, waker: &Waker) {
312 critical_section::with(|cs| {
313 let mut queue = self.queue.borrow(cs).borrow_mut();
314
315 if queue.schedule_wake(at, waker) {
316 let mut next = queue.next_expiration(self.now());
317
318 while !self.set_alarm(cs, next) {
319 next = queue.next_expiration(self.now());
320 }
321 }
322 });
323 }
324}
325
326embassy_time_driver::time_driver_impl!(static DRIVER: TimxDriver = TimxDriver {
327 period: AtomicU32::new(0),
328 alarm: Mutex::new(Cell::new(u64::MAX)),
329 queue: Mutex::new(RefCell::new(Queue::new()))
330});
331
332pub(crate) fn init(cs: CriticalSection) {
333 DRIVER.init(cs);
334}
335
336#[cfg(time_driver_timg0)]
337#[interrupt]
338fn TIMG0() {
339 DRIVER.on_interrupt();
340}
341
342#[cfg(time_driver_timg1)]
343#[interrupt]
344fn TIMG1() {
345 DRIVER.on_interrupt();
346}
347
348#[cfg(time_driver_timg2)]
349#[interrupt]
350fn TIMG2() {
351 DRIVER.on_interrupt();
352}
353
354#[cfg(time_driver_timg3)]
355#[interrupt]
356fn TIMG3() {
357 DRIVER.on_interrupt();
358}
359
360#[cfg(time_driver_timg4)]
361#[interrupt]
362fn TIMG4() {
363 DRIVER.on_interrupt();
364}
365
366#[cfg(time_driver_timg5)]
367#[interrupt]
368fn TIMG5() {
369 DRIVER.on_interrupt();
370}
371
372#[cfg(time_driver_timg6)]
373#[interrupt]
374fn TIMG6() {
375 DRIVER.on_interrupt();
376}
377
378#[cfg(time_driver_timg7)]
379#[interrupt]
380fn TIMG7() {
381 DRIVER.on_interrupt();
382}
383
384#[cfg(time_driver_timg8)]
385#[interrupt]
386fn TIMG8() {
387 DRIVER.on_interrupt();
388}
389
390#[cfg(time_driver_timg9)]
391#[interrupt]
392fn TIMG9() {
393 DRIVER.on_interrupt();
394}
395
396#[cfg(time_driver_timg10)]
397#[interrupt]
398fn TIMG10() {
399 DRIVER.on_interrupt();
400}
401
402#[cfg(time_driver_timg11)]
403#[interrupt]
404fn TIMG11() {
405 DRIVER.on_interrupt();
406}
407
408// TODO: TIMG12 and TIMG13
409
410#[cfg(time_driver_timg14)]
411#[interrupt]
412fn TIMG14() {
413 DRIVER.on_interrupt();
414}
415
416#[cfg(time_driver_tima0)]
417#[interrupt]
418fn TIMA0() {
419 DRIVER.on_interrupt();
420}
421
422#[cfg(time_driver_tima1)]
423#[interrupt]
424fn TIMA1() {
425 DRIVER.on_interrupt();
426}
diff --git a/embassy-mspm0/src/timer.rs b/embassy-mspm0/src/timer.rs
new file mode 100644
index 000000000..4441e5640
--- /dev/null
+++ b/embassy-mspm0/src/timer.rs
@@ -0,0 +1,48 @@
1#![macro_use]
2
3/// Amount of bits of a timer.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub enum TimerBits {
7 /// 16 bits.
8 Bits16,
9 /// 32 bits.
10 Bits32,
11}
12
13#[allow(private_bounds)]
14pub trait Timer: SealedTimer + 'static {
15 /// Amount of bits this timer has.
16 const BITS: TimerBits;
17}
18
19pub(crate) trait SealedTimer {
20 /// Registers for this timer.
21 ///
22 /// This is a raw pointer to the register block. The actual register block layout varies depending on the
23 /// timer type.
24 fn regs() -> *mut ();
25
26 /// Enable the interrupt corresponding to this timer.
27 unsafe fn enable_interrupt();
28}
29
30macro_rules! impl_timer {
31 ($name: ident, $bits: ident) => {
32 impl crate::timer::SealedTimer for crate::peripherals::$name {
33 fn regs() -> *mut () {
34 crate::pac::$name.as_ptr()
35 }
36
37 unsafe fn enable_interrupt() {
38 use embassy_hal_internal::interrupt::InterruptExt;
39 crate::interrupt::$name.unpend();
40 crate::interrupt::$name.enable();
41 }
42 }
43
44 impl crate::timer::Timer for crate::peripherals::$name {
45 const BITS: crate::timer::TimerBits = crate::timer::TimerBits::$bits;
46 }
47 };
48}
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index c3fcfd06e..f939be004 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -16,7 +16,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Orde
16use core::task::Poll; 16use core::task::Poll;
17 17
18use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 18use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
19use embassy_hal_internal::{into_ref, PeripheralRef}; 19use embassy_hal_internal::Peri;
20use pac::uarte::vals; 20use pac::uarte::vals;
21// Re-export SVD variants to allow user to directly set values 21// Re-export SVD variants to allow user to directly set values
22pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; 22pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity};
@@ -28,7 +28,7 @@ use crate::ppi::{
28}; 28};
29use crate::timer::{Instance as TimerInstance, Timer}; 29use crate::timer::{Instance as TimerInstance, Timer};
30use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; 30use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance};
31use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; 31use crate::{interrupt, pac, EASY_DMA_SIZE};
32 32
33pub(crate) struct State { 33pub(crate) struct State {
34 tx_buf: RingBuffer, 34 tx_buf: RingBuffer,
@@ -222,27 +222,26 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
222 /// Panics if `rx_buffer.len()` is odd. 222 /// Panics if `rx_buffer.len()` is odd.
223 #[allow(clippy::too_many_arguments)] 223 #[allow(clippy::too_many_arguments)]
224 pub fn new( 224 pub fn new(
225 uarte: impl Peripheral<P = U> + 'd, 225 uarte: Peri<'d, U>,
226 timer: impl Peripheral<P = T> + 'd, 226 timer: Peri<'d, T>,
227 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 227 ppi_ch1: Peri<'d, impl ConfigurableChannel>,
228 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 228 ppi_ch2: Peri<'d, impl ConfigurableChannel>,
229 ppi_group: impl Peripheral<P = impl Group> + 'd, 229 ppi_group: Peri<'d, impl Group>,
230 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 230 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
231 rxd: impl Peripheral<P = impl GpioPin> + 'd, 231 rxd: Peri<'d, impl GpioPin>,
232 txd: impl Peripheral<P = impl GpioPin> + 'd, 232 txd: Peri<'d, impl GpioPin>,
233 config: Config, 233 config: Config,
234 rx_buffer: &'d mut [u8], 234 rx_buffer: &'d mut [u8],
235 tx_buffer: &'d mut [u8], 235 tx_buffer: &'d mut [u8],
236 ) -> Self { 236 ) -> Self {
237 into_ref!(uarte, timer, rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
238 Self::new_inner( 237 Self::new_inner(
239 uarte, 238 uarte,
240 timer, 239 timer,
241 ppi_ch1.map_into(), 240 ppi_ch1.into(),
242 ppi_ch2.map_into(), 241 ppi_ch2.into(),
243 ppi_group.map_into(), 242 ppi_group.into(),
244 rxd.map_into(), 243 rxd.into(),
245 txd.map_into(), 244 txd.into(),
246 None, 245 None,
247 None, 246 None,
248 config, 247 config,
@@ -258,31 +257,30 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
258 /// Panics if `rx_buffer.len()` is odd. 257 /// Panics if `rx_buffer.len()` is odd.
259 #[allow(clippy::too_many_arguments)] 258 #[allow(clippy::too_many_arguments)]
260 pub fn new_with_rtscts( 259 pub fn new_with_rtscts(
261 uarte: impl Peripheral<P = U> + 'd, 260 uarte: Peri<'d, U>,
262 timer: impl Peripheral<P = T> + 'd, 261 timer: Peri<'d, T>,
263 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 262 ppi_ch1: Peri<'d, impl ConfigurableChannel>,
264 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 263 ppi_ch2: Peri<'d, impl ConfigurableChannel>,
265 ppi_group: impl Peripheral<P = impl Group> + 'd, 264 ppi_group: Peri<'d, impl Group>,
266 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 265 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
267 rxd: impl Peripheral<P = impl GpioPin> + 'd, 266 rxd: Peri<'d, impl GpioPin>,
268 txd: impl Peripheral<P = impl GpioPin> + 'd, 267 txd: Peri<'d, impl GpioPin>,
269 cts: impl Peripheral<P = impl GpioPin> + 'd, 268 cts: Peri<'d, impl GpioPin>,
270 rts: impl Peripheral<P = impl GpioPin> + 'd, 269 rts: Peri<'d, impl GpioPin>,
271 config: Config, 270 config: Config,
272 rx_buffer: &'d mut [u8], 271 rx_buffer: &'d mut [u8],
273 tx_buffer: &'d mut [u8], 272 tx_buffer: &'d mut [u8],
274 ) -> Self { 273 ) -> Self {
275 into_ref!(uarte, timer, rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
276 Self::new_inner( 274 Self::new_inner(
277 uarte, 275 uarte,
278 timer, 276 timer,
279 ppi_ch1.map_into(), 277 ppi_ch1.into(),
280 ppi_ch2.map_into(), 278 ppi_ch2.into(),
281 ppi_group.map_into(), 279 ppi_group.into(),
282 rxd.map_into(), 280 rxd.into(),
283 txd.map_into(), 281 txd.into(),
284 Some(cts.map_into()), 282 Some(cts.into()),
285 Some(rts.map_into()), 283 Some(rts.into()),
286 config, 284 config,
287 rx_buffer, 285 rx_buffer,
288 tx_buffer, 286 tx_buffer,
@@ -291,15 +289,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
291 289
292 #[allow(clippy::too_many_arguments)] 290 #[allow(clippy::too_many_arguments)]
293 fn new_inner( 291 fn new_inner(
294 peri: PeripheralRef<'d, U>, 292 peri: Peri<'d, U>,
295 timer: PeripheralRef<'d, T>, 293 timer: Peri<'d, T>,
296 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, 294 ppi_ch1: Peri<'d, AnyConfigurableChannel>,
297 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, 295 ppi_ch2: Peri<'d, AnyConfigurableChannel>,
298 ppi_group: PeripheralRef<'d, AnyGroup>, 296 ppi_group: Peri<'d, AnyGroup>,
299 rxd: PeripheralRef<'d, AnyPin>, 297 rxd: Peri<'d, AnyPin>,
300 txd: PeripheralRef<'d, AnyPin>, 298 txd: Peri<'d, AnyPin>,
301 cts: Option<PeripheralRef<'d, AnyPin>>, 299 cts: Option<Peri<'d, AnyPin>>,
302 rts: Option<PeripheralRef<'d, AnyPin>>, 300 rts: Option<Peri<'d, AnyPin>>,
303 config: Config, 301 config: Config,
304 rx_buffer: &'d mut [u8], 302 rx_buffer: &'d mut [u8],
305 tx_buffer: &'d mut [u8], 303 tx_buffer: &'d mut [u8],
@@ -372,20 +370,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
372 370
373/// Reader part of the buffered UARTE driver. 371/// Reader part of the buffered UARTE driver.
374pub struct BufferedUarteTx<'d, U: UarteInstance> { 372pub struct BufferedUarteTx<'d, U: UarteInstance> {
375 _peri: PeripheralRef<'d, U>, 373 _peri: Peri<'d, U>,
376} 374}
377 375
378impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { 376impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
379 /// Create a new BufferedUarteTx without hardware flow control. 377 /// Create a new BufferedUarteTx without hardware flow control.
380 pub fn new( 378 pub fn new(
381 uarte: impl Peripheral<P = U> + 'd, 379 uarte: Peri<'d, U>,
382 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 380 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
383 txd: impl Peripheral<P = impl GpioPin> + 'd, 381 txd: Peri<'d, impl GpioPin>,
384 config: Config, 382 config: Config,
385 tx_buffer: &'d mut [u8], 383 tx_buffer: &'d mut [u8],
386 ) -> Self { 384 ) -> Self {
387 into_ref!(uarte, txd); 385 Self::new_inner(uarte, txd.into(), None, config, tx_buffer)
388 Self::new_inner(uarte, txd.map_into(), None, config, tx_buffer)
389 } 386 }
390 387
391 /// Create a new BufferedUarte with hardware flow control (RTS/CTS) 388 /// Create a new BufferedUarte with hardware flow control (RTS/CTS)
@@ -394,21 +391,20 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
394 /// 391 ///
395 /// Panics if `rx_buffer.len()` is odd. 392 /// Panics if `rx_buffer.len()` is odd.
396 pub fn new_with_cts( 393 pub fn new_with_cts(
397 uarte: impl Peripheral<P = U> + 'd, 394 uarte: Peri<'d, U>,
398 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 395 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
399 txd: impl Peripheral<P = impl GpioPin> + 'd, 396 txd: Peri<'d, impl GpioPin>,
400 cts: impl Peripheral<P = impl GpioPin> + 'd, 397 cts: Peri<'d, impl GpioPin>,
401 config: Config, 398 config: Config,
402 tx_buffer: &'d mut [u8], 399 tx_buffer: &'d mut [u8],
403 ) -> Self { 400 ) -> Self {
404 into_ref!(uarte, txd, cts); 401 Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer)
405 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config, tx_buffer)
406 } 402 }
407 403
408 fn new_inner( 404 fn new_inner(
409 peri: PeripheralRef<'d, U>, 405 peri: Peri<'d, U>,
410 txd: PeripheralRef<'d, AnyPin>, 406 txd: Peri<'d, AnyPin>,
411 cts: Option<PeripheralRef<'d, AnyPin>>, 407 cts: Option<Peri<'d, AnyPin>>,
412 config: Config, 408 config: Config,
413 tx_buffer: &'d mut [u8], 409 tx_buffer: &'d mut [u8],
414 ) -> Self { 410 ) -> Self {
@@ -426,9 +422,9 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
426 } 422 }
427 423
428 fn new_innerer( 424 fn new_innerer(
429 peri: PeripheralRef<'d, U>, 425 peri: Peri<'d, U>,
430 txd: PeripheralRef<'d, AnyPin>, 426 txd: Peri<'d, AnyPin>,
431 cts: Option<PeripheralRef<'d, AnyPin>>, 427 cts: Option<Peri<'d, AnyPin>>,
432 tx_buffer: &'d mut [u8], 428 tx_buffer: &'d mut [u8],
433 ) -> Self { 429 ) -> Self {
434 let r = U::regs(); 430 let r = U::regs();
@@ -542,7 +538,7 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> {
542 538
543/// Reader part of the buffered UARTE driver. 539/// Reader part of the buffered UARTE driver.
544pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { 540pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> {
545 _peri: PeripheralRef<'d, U>, 541 _peri: Peri<'d, U>,
546 timer: Timer<'d, T>, 542 timer: Timer<'d, T>,
547 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, 543 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
548 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, 544 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
@@ -557,24 +553,23 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
557 /// Panics if `rx_buffer.len()` is odd. 553 /// Panics if `rx_buffer.len()` is odd.
558 #[allow(clippy::too_many_arguments)] 554 #[allow(clippy::too_many_arguments)]
559 pub fn new( 555 pub fn new(
560 uarte: impl Peripheral<P = U> + 'd, 556 uarte: Peri<'d, U>,
561 timer: impl Peripheral<P = T> + 'd, 557 timer: Peri<'d, T>,
562 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 558 ppi_ch1: Peri<'d, impl ConfigurableChannel>,
563 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 559 ppi_ch2: Peri<'d, impl ConfigurableChannel>,
564 ppi_group: impl Peripheral<P = impl Group> + 'd, 560 ppi_group: Peri<'d, impl Group>,
565 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 561 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
566 rxd: impl Peripheral<P = impl GpioPin> + 'd, 562 rxd: Peri<'d, impl GpioPin>,
567 config: Config, 563 config: Config,
568 rx_buffer: &'d mut [u8], 564 rx_buffer: &'d mut [u8],
569 ) -> Self { 565 ) -> Self {
570 into_ref!(uarte, timer, rxd, ppi_ch1, ppi_ch2, ppi_group);
571 Self::new_inner( 566 Self::new_inner(
572 uarte, 567 uarte,
573 timer, 568 timer,
574 ppi_ch1.map_into(), 569 ppi_ch1.into(),
575 ppi_ch2.map_into(), 570 ppi_ch2.into(),
576 ppi_group.map_into(), 571 ppi_group.into(),
577 rxd.map_into(), 572 rxd.into(),
578 None, 573 None,
579 config, 574 config,
580 rx_buffer, 575 rx_buffer,
@@ -588,26 +583,25 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
588 /// Panics if `rx_buffer.len()` is odd. 583 /// Panics if `rx_buffer.len()` is odd.
589 #[allow(clippy::too_many_arguments)] 584 #[allow(clippy::too_many_arguments)]
590 pub fn new_with_rts( 585 pub fn new_with_rts(
591 uarte: impl Peripheral<P = U> + 'd, 586 uarte: Peri<'d, U>,
592 timer: impl Peripheral<P = T> + 'd, 587 timer: Peri<'d, T>,
593 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, 588 ppi_ch1: Peri<'d, impl ConfigurableChannel>,
594 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, 589 ppi_ch2: Peri<'d, impl ConfigurableChannel>,
595 ppi_group: impl Peripheral<P = impl Group> + 'd, 590 ppi_group: Peri<'d, impl Group>,
596 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, 591 _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
597 rxd: impl Peripheral<P = impl GpioPin> + 'd, 592 rxd: Peri<'d, impl GpioPin>,
598 rts: impl Peripheral<P = impl GpioPin> + 'd, 593 rts: Peri<'d, impl GpioPin>,
599 config: Config, 594 config: Config,
600 rx_buffer: &'d mut [u8], 595 rx_buffer: &'d mut [u8],
601 ) -> Self { 596 ) -> Self {
602 into_ref!(uarte, timer, rxd, rts, ppi_ch1, ppi_ch2, ppi_group);
603 Self::new_inner( 597 Self::new_inner(
604 uarte, 598 uarte,
605 timer, 599 timer,
606 ppi_ch1.map_into(), 600 ppi_ch1.into(),
607 ppi_ch2.map_into(), 601 ppi_ch2.into(),
608 ppi_group.map_into(), 602 ppi_group.into(),
609 rxd.map_into(), 603 rxd.into(),
610 Some(rts.map_into()), 604 Some(rts.into()),
611 config, 605 config,
612 rx_buffer, 606 rx_buffer,
613 ) 607 )
@@ -615,13 +609,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
615 609
616 #[allow(clippy::too_many_arguments)] 610 #[allow(clippy::too_many_arguments)]
617 fn new_inner( 611 fn new_inner(
618 peri: PeripheralRef<'d, U>, 612 peri: Peri<'d, U>,
619 timer: PeripheralRef<'d, T>, 613 timer: Peri<'d, T>,
620 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, 614 ppi_ch1: Peri<'d, AnyConfigurableChannel>,
621 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, 615 ppi_ch2: Peri<'d, AnyConfigurableChannel>,
622 ppi_group: PeripheralRef<'d, AnyGroup>, 616 ppi_group: Peri<'d, AnyGroup>,
623 rxd: PeripheralRef<'d, AnyPin>, 617 rxd: Peri<'d, AnyPin>,
624 rts: Option<PeripheralRef<'d, AnyPin>>, 618 rts: Option<Peri<'d, AnyPin>>,
625 config: Config, 619 config: Config,
626 rx_buffer: &'d mut [u8], 620 rx_buffer: &'d mut [u8],
627 ) -> Self { 621 ) -> Self {
@@ -640,13 +634,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
640 634
641 #[allow(clippy::too_many_arguments)] 635 #[allow(clippy::too_many_arguments)]
642 fn new_innerer( 636 fn new_innerer(
643 peri: PeripheralRef<'d, U>, 637 peri: Peri<'d, U>,
644 timer: PeripheralRef<'d, T>, 638 timer: Peri<'d, T>,
645 ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>, 639 ppi_ch1: Peri<'d, AnyConfigurableChannel>,
646 ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>, 640 ppi_ch2: Peri<'d, AnyConfigurableChannel>,
647 ppi_group: PeripheralRef<'d, AnyGroup>, 641 ppi_group: Peri<'d, AnyGroup>,
648 rxd: PeripheralRef<'d, AnyPin>, 642 rxd: Peri<'d, AnyPin>,
649 rts: Option<PeripheralRef<'d, AnyPin>>, 643 rts: Option<Peri<'d, AnyPin>>,
650 rx_buffer: &'d mut [u8], 644 rx_buffer: &'d mut [u8],
651 ) -> Self { 645 ) -> Self {
652 assert!(rx_buffer.len() % 2 == 0); 646 assert!(rx_buffer.len() % 2 == 0);
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs
index 7f9abdac4..028396c7c 100644
--- a/embassy-nrf/src/egu.rs
+++ b/embassy-nrf/src/egu.rs
@@ -7,20 +7,19 @@
7 7
8use core::marker::PhantomData; 8use core::marker::PhantomData;
9 9
10use embassy_hal_internal::into_ref; 10use embassy_hal_internal::PeripheralType;
11 11
12use crate::ppi::{Event, Task}; 12use crate::ppi::{Event, Task};
13use crate::{interrupt, pac, Peripheral, PeripheralRef}; 13use crate::{interrupt, pac, Peri};
14 14
15/// An instance of the EGU. 15/// An instance of the EGU.
16pub struct Egu<'d, T: Instance> { 16pub struct Egu<'d, T: Instance> {
17 _p: PeripheralRef<'d, T>, 17 _p: Peri<'d, T>,
18} 18}
19 19
20impl<'d, T: Instance> Egu<'d, T> { 20impl<'d, T: Instance> Egu<'d, T> {
21 /// Create a new EGU instance. 21 /// Create a new EGU instance.
22 pub fn new(_p: impl Peripheral<P = T> + 'd) -> Self { 22 pub fn new(_p: Peri<'d, T>) -> Self {
23 into_ref!(_p);
24 Self { _p } 23 Self { _p }
25 } 24 }
26 25
@@ -39,7 +38,7 @@ pub(crate) trait SealedInstance {
39 38
40/// Basic Egu instance. 39/// Basic Egu instance.
41#[allow(private_bounds)] 40#[allow(private_bounds)]
42pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 41pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
43 /// Interrupt for this peripheral. 42 /// Interrupt for this peripheral.
44 type Interrupt: interrupt::typelevel::Interrupt; 43 type Interrupt: interrupt::typelevel::Interrupt;
45} 44}
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index c78fa4df5..d02da9ac5 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -5,14 +5,14 @@ use core::convert::Infallible;
5use core::hint::unreachable_unchecked; 5use core::hint::unreachable_unchecked;
6 6
7use cfg_if::cfg_if; 7use cfg_if::cfg_if;
8use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
9 9
10use crate::pac;
10use crate::pac::common::{Reg, RW}; 11use crate::pac::common::{Reg, RW};
11use crate::pac::gpio; 12use crate::pac::gpio;
12use crate::pac::gpio::vals; 13use crate::pac::gpio::vals;
13#[cfg(not(feature = "_nrf51"))] 14#[cfg(not(feature = "_nrf51"))]
14use crate::pac::shared::{regs::Psel, vals::Connect}; 15use crate::pac::shared::{regs::Psel, vals::Connect};
15use crate::{pac, Peripheral};
16 16
17/// A GPIO port with up to 32 pins. 17/// A GPIO port with up to 32 pins.
18#[derive(Debug, Eq, PartialEq)] 18#[derive(Debug, Eq, PartialEq)]
@@ -49,7 +49,7 @@ pub struct Input<'d> {
49impl<'d> Input<'d> { 49impl<'d> Input<'d> {
50 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. 50 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
51 #[inline] 51 #[inline]
52 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { 52 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
53 let mut pin = Flex::new(pin); 53 let mut pin = Flex::new(pin);
54 pin.set_as_input(pull); 54 pin.set_as_input(pull);
55 55
@@ -210,7 +210,7 @@ pub struct Output<'d> {
210impl<'d> Output<'d> { 210impl<'d> Output<'d> {
211 /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration. 211 /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
212 #[inline] 212 #[inline]
213 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, drive: OutputDrive) -> Self { 213 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, drive: OutputDrive) -> Self {
214 let mut pin = Flex::new(pin); 214 let mut pin = Flex::new(pin);
215 match initial_output { 215 match initial_output {
216 Level::High => pin.set_high(), 216 Level::High => pin.set_high(),
@@ -310,7 +310,7 @@ fn convert_pull(pull: Pull) -> vals::Pull {
310/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 310/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
311/// mode. 311/// mode.
312pub struct Flex<'d> { 312pub struct Flex<'d> {
313 pub(crate) pin: PeripheralRef<'d, AnyPin>, 313 pub(crate) pin: Peri<'d, AnyPin>,
314} 314}
315 315
316impl<'d> Flex<'d> { 316impl<'d> Flex<'d> {
@@ -319,10 +319,9 @@ impl<'d> Flex<'d> {
319 /// The pin remains disconnected. The initial output level is unspecified, but can be changed 319 /// The pin remains disconnected. The initial output level is unspecified, but can be changed
320 /// before the pin is put into output mode. 320 /// before the pin is put into output mode.
321 #[inline] 321 #[inline]
322 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { 322 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
323 into_ref!(pin);
324 // Pin will be in disconnected state. 323 // Pin will be in disconnected state.
325 Self { pin: pin.map_into() } 324 Self { pin: pin.into() }
326 } 325 }
327 326
328 /// Put the pin into input mode. 327 /// Put the pin into input mode.
@@ -503,7 +502,7 @@ pub(crate) trait SealedPin {
503 502
504/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. 503/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
505#[allow(private_bounds)] 504#[allow(private_bounds)]
506pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { 505pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
507 /// Number of the pin within the port (0..31) 506 /// Number of the pin within the port (0..31)
508 #[inline] 507 #[inline]
509 fn pin(&self) -> u8 { 508 fn pin(&self) -> u8 {
@@ -529,19 +528,11 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static
529 fn psel_bits(&self) -> pac::shared::regs::Psel { 528 fn psel_bits(&self) -> pac::shared::regs::Psel {
530 pac::shared::regs::Psel(self.pin_port() as u32) 529 pac::shared::regs::Psel(self.pin_port() as u32)
531 } 530 }
532
533 /// Convert from concrete pin type PX_XX to type erased `AnyPin`.
534 #[inline]
535 fn degrade(self) -> AnyPin {
536 AnyPin {
537 pin_port: self.pin_port(),
538 }
539 }
540} 531}
541 532
542/// Type-erased GPIO pin 533/// Type-erased GPIO pin
543pub struct AnyPin { 534pub struct AnyPin {
544 pin_port: u8, 535 pub(crate) pin_port: u8,
545} 536}
546 537
547impl AnyPin { 538impl AnyPin {
@@ -550,8 +541,8 @@ impl AnyPin {
550 /// # Safety 541 /// # Safety
551 /// - `pin_port` should not in use by another driver. 542 /// - `pin_port` should not in use by another driver.
552 #[inline] 543 #[inline]
553 pub unsafe fn steal(pin_port: u8) -> Self { 544 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
554 Self { pin_port } 545 Peri::new_unchecked(Self { pin_port })
555 } 546 }
556} 547}
557 548
@@ -573,7 +564,7 @@ pub(crate) trait PselBits {
573} 564}
574 565
575#[cfg(not(feature = "_nrf51"))] 566#[cfg(not(feature = "_nrf51"))]
576impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { 567impl<'a, P: Pin> PselBits for Option<Peri<'a, P>> {
577 #[inline] 568 #[inline]
578 fn psel_bits(&self) -> pac::shared::regs::Psel { 569 fn psel_bits(&self) -> pac::shared::regs::Psel {
579 match self { 570 match self {
@@ -611,8 +602,10 @@ macro_rules! impl_pin {
611 } 602 }
612 603
613 impl From<peripherals::$type> for crate::gpio::AnyPin { 604 impl From<peripherals::$type> for crate::gpio::AnyPin {
614 fn from(val: peripherals::$type) -> Self { 605 fn from(_val: peripherals::$type) -> Self {
615 crate::gpio::Pin::degrade(val) 606 Self {
607 pin_port: $port_num * 32 + $pin_num,
608 }
616 } 609 }
617 } 610 }
618 }; 611 };
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 8771f9f08..d169b49f9 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -4,7 +4,7 @@ use core::convert::Infallible;
4use core::future::{poll_fn, Future}; 4use core::future::{poll_fn, Future};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; 10use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _};
@@ -189,7 +189,7 @@ impl Iterator for BitIter {
189 189
190/// GPIOTE channel driver in input mode 190/// GPIOTE channel driver in input mode
191pub struct InputChannel<'d> { 191pub struct InputChannel<'d> {
192 ch: PeripheralRef<'d, AnyChannel>, 192 ch: Peri<'d, AnyChannel>,
193 pin: Input<'d>, 193 pin: Input<'d>,
194} 194}
195 195
@@ -204,9 +204,7 @@ impl<'d> Drop for InputChannel<'d> {
204 204
205impl<'d> InputChannel<'d> { 205impl<'d> InputChannel<'d> {
206 /// Create a new GPIOTE input channel driver. 206 /// Create a new GPIOTE input channel driver.
207 pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { 207 pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self {
208 into_ref!(ch);
209
210 let g = regs(); 208 let g = regs();
211 let num = ch.number(); 209 let num = ch.number();
212 210
@@ -228,7 +226,7 @@ impl<'d> InputChannel<'d> {
228 226
229 g.events_in(num).write_value(0); 227 g.events_in(num).write_value(0);
230 228
231 InputChannel { ch: ch.map_into(), pin } 229 InputChannel { ch: ch.into(), pin }
232 } 230 }
233 231
234 /// Asynchronously wait for an event in this channel. 232 /// Asynchronously wait for an event in this channel.
@@ -261,7 +259,7 @@ impl<'d> InputChannel<'d> {
261 259
262/// GPIOTE channel driver in output mode 260/// GPIOTE channel driver in output mode
263pub struct OutputChannel<'d> { 261pub struct OutputChannel<'d> {
264 ch: PeripheralRef<'d, AnyChannel>, 262 ch: Peri<'d, AnyChannel>,
265 _pin: Output<'d>, 263 _pin: Output<'d>,
266} 264}
267 265
@@ -276,8 +274,7 @@ impl<'d> Drop for OutputChannel<'d> {
276 274
277impl<'d> OutputChannel<'d> { 275impl<'d> OutputChannel<'d> {
278 /// Create a new GPIOTE output channel driver. 276 /// Create a new GPIOTE output channel driver.
279 pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { 277 pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self {
280 into_ref!(ch);
281 let g = regs(); 278 let g = regs();
282 let num = ch.number(); 279 let num = ch.number();
283 280
@@ -301,7 +298,7 @@ impl<'d> OutputChannel<'d> {
301 }); 298 });
302 299
303 OutputChannel { 300 OutputChannel {
304 ch: ch.map_into(), 301 ch: ch.into(),
305 _pin: pin, 302 _pin: pin,
306 } 303 }
307 } 304 }
@@ -351,14 +348,12 @@ impl<'d> OutputChannel<'d> {
351 348
352#[must_use = "futures do nothing unless you `.await` or poll them"] 349#[must_use = "futures do nothing unless you `.await` or poll them"]
353pub(crate) struct PortInputFuture<'a> { 350pub(crate) struct PortInputFuture<'a> {
354 pin: PeripheralRef<'a, AnyPin>, 351 pin: Peri<'a, AnyPin>,
355} 352}
356 353
357impl<'a> PortInputFuture<'a> { 354impl<'a> PortInputFuture<'a> {
358 fn new(pin: impl Peripheral<P = impl GpioPin> + 'a) -> Self { 355 fn new(pin: Peri<'a, impl GpioPin>) -> Self {
359 Self { 356 Self { pin: pin.into() }
360 pin: pin.into_ref().map_into(),
361 }
362 } 357 }
363} 358}
364 359
@@ -415,13 +410,13 @@ impl<'d> Flex<'d> {
415 /// Wait until the pin is high. If it is already high, return immediately. 410 /// Wait until the pin is high. If it is already high, return immediately.
416 pub async fn wait_for_high(&mut self) { 411 pub async fn wait_for_high(&mut self) {
417 self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); 412 self.pin.conf().modify(|w| w.set_sense(Sense::HIGH));
418 PortInputFuture::new(&mut self.pin).await 413 PortInputFuture::new(self.pin.reborrow()).await
419 } 414 }
420 415
421 /// Wait until the pin is low. If it is already low, return immediately. 416 /// Wait until the pin is low. If it is already low, return immediately.
422 pub async fn wait_for_low(&mut self) { 417 pub async fn wait_for_low(&mut self) {
423 self.pin.conf().modify(|w| w.set_sense(Sense::LOW)); 418 self.pin.conf().modify(|w| w.set_sense(Sense::LOW));
424 PortInputFuture::new(&mut self.pin).await 419 PortInputFuture::new(self.pin.reborrow()).await
425 } 420 }
426 421
427 /// Wait for the pin to undergo a transition from low to high. 422 /// Wait for the pin to undergo a transition from low to high.
@@ -443,7 +438,7 @@ impl<'d> Flex<'d> {
443 } else { 438 } else {
444 self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); 439 self.pin.conf().modify(|w| w.set_sense(Sense::HIGH));
445 } 440 }
446 PortInputFuture::new(&mut self.pin).await 441 PortInputFuture::new(self.pin.reborrow()).await
447 } 442 }
448} 443}
449 444
@@ -455,24 +450,14 @@ trait SealedChannel {}
455/// 450///
456/// Implemented by all GPIOTE channels. 451/// Implemented by all GPIOTE channels.
457#[allow(private_bounds)] 452#[allow(private_bounds)]
458pub trait Channel: SealedChannel + Into<AnyChannel> + Sized + 'static { 453pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
459 /// Get the channel number. 454 /// Get the channel number.
460 fn number(&self) -> usize; 455 fn number(&self) -> usize;
461
462 /// Convert this channel to a type-erased `AnyChannel`.
463 ///
464 /// This allows using several channels in situations that might require
465 /// them to be the same type, like putting them in an array.
466 fn degrade(self) -> AnyChannel {
467 AnyChannel {
468 number: self.number() as u8,
469 }
470 }
471} 456}
472 457
473/// Type-erased channel. 458/// Type-erased channel.
474/// 459///
475/// Obtained by calling `Channel::degrade`. 460/// Obtained by calling `Channel::into()`.
476/// 461///
477/// This allows using several channels in situations that might require 462/// This allows using several channels in situations that might require
478/// them to be the same type, like putting them in an array. 463/// them to be the same type, like putting them in an array.
@@ -498,7 +483,9 @@ macro_rules! impl_channel {
498 483
499 impl From<peripherals::$type> for AnyChannel { 484 impl From<peripherals::$type> for AnyChannel {
500 fn from(val: peripherals::$type) -> Self { 485 fn from(val: peripherals::$type) -> Self {
501 Channel::degrade(val) 486 Self {
487 number: val.number() as u8,
488 }
502 } 489 }
503 } 490 }
504 }; 491 };
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs
index 384a1637b..a7dde8cd7 100644
--- a/embassy-nrf/src/i2s.rs
+++ b/embassy-nrf/src/i2s.rs
@@ -10,14 +10,14 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
10use core::task::Poll; 10use core::task::Poll;
11 11
12use embassy_hal_internal::drop::OnDrop; 12use embassy_hal_internal::drop::OnDrop;
13use embassy_hal_internal::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
15 15
16use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; 16use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
17use crate::interrupt::typelevel::Interrupt; 17use crate::interrupt::typelevel::Interrupt;
18use crate::pac::i2s::vals; 18use crate::pac::i2s::vals;
19use crate::util::slice_in_ram_or; 19use crate::util::slice_in_ram_or;
20use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; 20use crate::{interrupt, pac, EASY_DMA_SIZE};
21 21
22/// Type alias for `MultiBuffering` with 2 buffers. 22/// Type alias for `MultiBuffering` with 2 buffers.
23pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; 23pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>;
@@ -406,12 +406,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
406 406
407/// I2S driver. 407/// I2S driver.
408pub struct I2S<'d, T: Instance> { 408pub struct I2S<'d, T: Instance> {
409 i2s: PeripheralRef<'d, T>, 409 i2s: Peri<'d, T>,
410 mck: Option<PeripheralRef<'d, AnyPin>>, 410 mck: Option<Peri<'d, AnyPin>>,
411 sck: PeripheralRef<'d, AnyPin>, 411 sck: Peri<'d, AnyPin>,
412 lrck: PeripheralRef<'d, AnyPin>, 412 lrck: Peri<'d, AnyPin>,
413 sdin: Option<PeripheralRef<'d, AnyPin>>, 413 sdin: Option<Peri<'d, AnyPin>>,
414 sdout: Option<PeripheralRef<'d, AnyPin>>, 414 sdout: Option<Peri<'d, AnyPin>>,
415 master_clock: Option<MasterClock>, 415 master_clock: Option<MasterClock>,
416 config: Config, 416 config: Config,
417} 417}
@@ -419,20 +419,19 @@ pub struct I2S<'d, T: Instance> {
419impl<'d, T: Instance> I2S<'d, T> { 419impl<'d, T: Instance> I2S<'d, T> {
420 /// Create a new I2S in master mode 420 /// Create a new I2S in master mode
421 pub fn new_master( 421 pub fn new_master(
422 i2s: impl Peripheral<P = T> + 'd, 422 i2s: Peri<'d, T>,
423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 423 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
424 mck: impl Peripheral<P = impl GpioPin> + 'd, 424 mck: Peri<'d, impl GpioPin>,
425 sck: impl Peripheral<P = impl GpioPin> + 'd, 425 sck: Peri<'d, impl GpioPin>,
426 lrck: impl Peripheral<P = impl GpioPin> + 'd, 426 lrck: Peri<'d, impl GpioPin>,
427 master_clock: MasterClock, 427 master_clock: MasterClock,
428 config: Config, 428 config: Config,
429 ) -> Self { 429 ) -> Self {
430 into_ref!(i2s, mck, sck, lrck);
431 Self { 430 Self {
432 i2s, 431 i2s,
433 mck: Some(mck.map_into()), 432 mck: Some(mck.into()),
434 sck: sck.map_into(), 433 sck: sck.into(),
435 lrck: lrck.map_into(), 434 lrck: lrck.into(),
436 sdin: None, 435 sdin: None,
437 sdout: None, 436 sdout: None,
438 master_clock: Some(master_clock), 437 master_clock: Some(master_clock),
@@ -442,18 +441,17 @@ impl<'d, T: Instance> I2S<'d, T> {
442 441
443 /// Create a new I2S in slave mode 442 /// Create a new I2S in slave mode
444 pub fn new_slave( 443 pub fn new_slave(
445 i2s: impl Peripheral<P = T> + 'd, 444 i2s: Peri<'d, T>,
446 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 445 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
447 sck: impl Peripheral<P = impl GpioPin> + 'd, 446 sck: Peri<'d, impl GpioPin>,
448 lrck: impl Peripheral<P = impl GpioPin> + 'd, 447 lrck: Peri<'d, impl GpioPin>,
449 config: Config, 448 config: Config,
450 ) -> Self { 449 ) -> Self {
451 into_ref!(i2s, sck, lrck);
452 Self { 450 Self {
453 i2s, 451 i2s,
454 mck: None, 452 mck: None,
455 sck: sck.map_into(), 453 sck: sck.into(),
456 lrck: lrck.map_into(), 454 lrck: lrck.into(),
457 sdin: None, 455 sdin: None,
458 sdout: None, 456 sdout: None,
459 master_clock: None, 457 master_clock: None,
@@ -464,10 +462,10 @@ impl<'d, T: Instance> I2S<'d, T> {
464 /// I2S output only 462 /// I2S output only
465 pub fn output<S: Sample, const NB: usize, const NS: usize>( 463 pub fn output<S: Sample, const NB: usize, const NS: usize>(
466 mut self, 464 mut self,
467 sdout: impl Peripheral<P = impl GpioPin> + 'd, 465 sdout: Peri<'d, impl GpioPin>,
468 buffers: MultiBuffering<S, NB, NS>, 466 buffers: MultiBuffering<S, NB, NS>,
469 ) -> OutputStream<'d, T, S, NB, NS> { 467 ) -> OutputStream<'d, T, S, NB, NS> {
470 self.sdout = Some(sdout.into_ref().map_into()); 468 self.sdout = Some(sdout.into());
471 OutputStream { 469 OutputStream {
472 _p: self.build(), 470 _p: self.build(),
473 buffers, 471 buffers,
@@ -477,10 +475,10 @@ impl<'d, T: Instance> I2S<'d, T> {
477 /// I2S input only 475 /// I2S input only
478 pub fn input<S: Sample, const NB: usize, const NS: usize>( 476 pub fn input<S: Sample, const NB: usize, const NS: usize>(
479 mut self, 477 mut self,
480 sdin: impl Peripheral<P = impl GpioPin> + 'd, 478 sdin: Peri<'d, impl GpioPin>,
481 buffers: MultiBuffering<S, NB, NS>, 479 buffers: MultiBuffering<S, NB, NS>,
482 ) -> InputStream<'d, T, S, NB, NS> { 480 ) -> InputStream<'d, T, S, NB, NS> {
483 self.sdin = Some(sdin.into_ref().map_into()); 481 self.sdin = Some(sdin.into());
484 InputStream { 482 InputStream {
485 _p: self.build(), 483 _p: self.build(),
486 buffers, 484 buffers,
@@ -490,13 +488,13 @@ impl<'d, T: Instance> I2S<'d, T> {
490 /// I2S full duplex (input and output) 488 /// I2S full duplex (input and output)
491 pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>( 489 pub fn full_duplex<S: Sample, const NB: usize, const NS: usize>(
492 mut self, 490 mut self,
493 sdin: impl Peripheral<P = impl GpioPin> + 'd, 491 sdin: Peri<'d, impl GpioPin>,
494 sdout: impl Peripheral<P = impl GpioPin> + 'd, 492 sdout: Peri<'d, impl GpioPin>,
495 buffers_out: MultiBuffering<S, NB, NS>, 493 buffers_out: MultiBuffering<S, NB, NS>,
496 buffers_in: MultiBuffering<S, NB, NS>, 494 buffers_in: MultiBuffering<S, NB, NS>,
497 ) -> FullDuplexStream<'d, T, S, NB, NS> { 495 ) -> FullDuplexStream<'d, T, S, NB, NS> {
498 self.sdout = Some(sdout.into_ref().map_into()); 496 self.sdout = Some(sdout.into());
499 self.sdin = Some(sdin.into_ref().map_into()); 497 self.sdin = Some(sdin.into());
500 498
501 FullDuplexStream { 499 FullDuplexStream {
502 _p: self.build(), 500 _p: self.build(),
@@ -505,7 +503,7 @@ impl<'d, T: Instance> I2S<'d, T> {
505 } 503 }
506 } 504 }
507 505
508 fn build(self) -> PeripheralRef<'d, T> { 506 fn build(self) -> Peri<'d, T> {
509 self.apply_config(); 507 self.apply_config();
510 self.select_pins(); 508 self.select_pins();
511 self.setup_interrupt(); 509 self.setup_interrupt();
@@ -702,7 +700,7 @@ impl<'d, T: Instance> I2S<'d, T> {
702 700
703/// I2S output 701/// I2S output
704pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { 702pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
705 _p: PeripheralRef<'d, T>, 703 _p: Peri<'d, T>,
706 buffers: MultiBuffering<S, NB, NS>, 704 buffers: MultiBuffering<S, NB, NS>,
707} 705}
708 706
@@ -756,7 +754,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream<
756 754
757/// I2S input 755/// I2S input
758pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { 756pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
759 _p: PeripheralRef<'d, T>, 757 _p: Peri<'d, T>,
760 buffers: MultiBuffering<S, NB, NS>, 758 buffers: MultiBuffering<S, NB, NS>,
761} 759}
762 760
@@ -811,7 +809,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<'
811 809
812/// I2S full duplex stream (input & output) 810/// I2S full duplex stream (input & output)
813pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { 811pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> {
814 _p: PeripheralRef<'d, T>, 812 _p: Peri<'d, T>,
815 buffers_out: MultiBuffering<S, NB, NS>, 813 buffers_out: MultiBuffering<S, NB, NS>,
816 buffers_in: MultiBuffering<S, NB, NS>, 814 buffers_in: MultiBuffering<S, NB, NS>,
817} 815}
@@ -1148,7 +1146,7 @@ pub(crate) trait SealedInstance {
1148 1146
1149/// I2S peripheral instance. 1147/// I2S peripheral instance.
1150#[allow(private_bounds)] 1148#[allow(private_bounds)]
1151pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 1149pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
1152 /// Interrupt for this peripheral. 1150 /// Interrupt for this peripheral.
1153 type Interrupt: interrupt::typelevel::Interrupt; 1151 type Interrupt: interrupt::typelevel::Interrupt;
1154} 1152}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 5cd0efa58..d2ff054f4 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -263,7 +263,7 @@ pub use chip::pac;
263#[cfg(not(feature = "unstable-pac"))] 263#[cfg(not(feature = "unstable-pac"))]
264pub(crate) use chip::pac; 264pub(crate) use chip::pac;
265pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; 265pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
266pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 266pub use embassy_hal_internal::{Peri, PeripheralType};
267 267
268pub use crate::chip::interrupt; 268pub use crate::chip::interrupt;
269#[cfg(feature = "rt")] 269#[cfg(feature = "rt")]
diff --git a/embassy-nrf/src/nfct.rs b/embassy-nrf/src/nfct.rs
index 8b4b6dfe0..8d70ec954 100644
--- a/embassy-nrf/src/nfct.rs
+++ b/embassy-nrf/src/nfct.rs
@@ -13,7 +13,6 @@ use core::future::poll_fn;
13use core::sync::atomic::{compiler_fence, Ordering}; 13use core::sync::atomic::{compiler_fence, Ordering};
14use core::task::Poll; 14use core::task::Poll;
15 15
16use embassy_hal_internal::{into_ref, PeripheralRef};
17use embassy_sync::waitqueue::AtomicWaker; 16use embassy_sync::waitqueue::AtomicWaker;
18pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode}; 17pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode};
19 18
@@ -22,7 +21,7 @@ use crate::pac::nfct::vals;
22use crate::pac::NFCT; 21use crate::pac::NFCT;
23use crate::peripherals::NFCT; 22use crate::peripherals::NFCT;
24use crate::util::slice_in_ram; 23use crate::util::slice_in_ram;
25use crate::{interrupt, pac, Peripheral}; 24use crate::{interrupt, pac, Peri};
26 25
27/// NFCID1 (aka UID) of different sizes. 26/// NFCID1 (aka UID) of different sizes.
28#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] 27#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
@@ -96,7 +95,7 @@ pub enum Error {
96 95
97/// NFC tag emulator driver. 96/// NFC tag emulator driver.
98pub struct NfcT<'d> { 97pub struct NfcT<'d> {
99 _p: PeripheralRef<'d, NFCT>, 98 _p: Peri<'d, NFCT>,
100 rx_buf: [u8; 256], 99 rx_buf: [u8; 256],
101 tx_buf: [u8; 256], 100 tx_buf: [u8; 256],
102} 101}
@@ -104,12 +103,10 @@ pub struct NfcT<'d> {
104impl<'d> NfcT<'d> { 103impl<'d> NfcT<'d> {
105 /// Create an Nfc Tag driver 104 /// Create an Nfc Tag driver
106 pub fn new( 105 pub fn new(
107 _p: impl Peripheral<P = NFCT> + 'd, 106 _p: Peri<'d, NFCT>,
108 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::NFCT, InterruptHandler> + 'd, 107 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::NFCT, InterruptHandler> + 'd,
109 config: &Config, 108 config: &Config,
110 ) -> Self { 109 ) -> Self {
111 into_ref!(_p);
112
113 let r = pac::NFCT; 110 let r = pac::NFCT;
114 111
115 unsafe { 112 unsafe {
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs
index 6973b4847..c46af0b34 100644
--- a/embassy-nrf/src/nvmc.rs
+++ b/embassy-nrf/src/nvmc.rs
@@ -2,14 +2,13 @@
2 2
3use core::{ptr, slice}; 3use core::{ptr, slice};
4 4
5use embassy_hal_internal::{into_ref, PeripheralRef};
6use embedded_storage::nor_flash::{ 5use embedded_storage::nor_flash::{
7 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, 6 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
8}; 7};
9 8
10use crate::pac::nvmc::vals; 9use crate::pac::nvmc::vals;
11use crate::peripherals::NVMC; 10use crate::peripherals::NVMC;
12use crate::{pac, Peripheral}; 11use crate::{pac, Peri};
13 12
14#[cfg(not(feature = "_nrf5340-net"))] 13#[cfg(not(feature = "_nrf5340-net"))]
15/// Erase size of NVMC flash in bytes. 14/// Erase size of NVMC flash in bytes.
@@ -42,13 +41,12 @@ impl NorFlashError for Error {
42 41
43/// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits. 42/// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits.
44pub struct Nvmc<'d> { 43pub struct Nvmc<'d> {
45 _p: PeripheralRef<'d, NVMC>, 44 _p: Peri<'d, NVMC>,
46} 45}
47 46
48impl<'d> Nvmc<'d> { 47impl<'d> Nvmc<'d> {
49 /// Create Nvmc driver. 48 /// Create Nvmc driver.
50 pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self { 49 pub fn new(_p: Peri<'d, NVMC>) -> Self {
51 into_ref!(_p);
52 Self { _p } 50 Self { _p }
53 } 51 }
54 52
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs
index 483d1a644..c2a4ba65f 100644
--- a/embassy-nrf/src/pdm.rs
+++ b/embassy-nrf/src/pdm.rs
@@ -8,7 +8,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_hal_internal::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13use fixed::types::I7F1; 13use fixed::types::I7F1;
14 14
@@ -25,7 +25,7 @@ pub use crate::pac::pdm::vals::Freq as Frequency;
25 feature = "_nrf91", 25 feature = "_nrf91",
26))] 26))]
27pub use crate::pac::pdm::vals::Ratio; 27pub use crate::pac::pdm::vals::Ratio;
28use crate::{interrupt, pac, Peripheral}; 28use crate::{interrupt, pac};
29 29
30/// Interrupt handler 30/// Interrupt handler
31pub struct InterruptHandler<T: Instance> { 31pub struct InterruptHandler<T: Instance> {
@@ -54,7 +54,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
54 54
55/// PDM microphone interface 55/// PDM microphone interface
56pub struct Pdm<'d, T: Instance> { 56pub struct Pdm<'d, T: Instance> {
57 _peri: PeripheralRef<'d, T>, 57 _peri: Peri<'d, T>,
58} 58}
59 59
60/// PDM error 60/// PDM error
@@ -89,24 +89,16 @@ pub enum SamplerState {
89impl<'d, T: Instance> Pdm<'d, T> { 89impl<'d, T: Instance> Pdm<'d, T> {
90 /// Create PDM driver 90 /// Create PDM driver
91 pub fn new( 91 pub fn new(
92 pdm: impl Peripheral<P = T> + 'd, 92 pdm: Peri<'d, T>,
93 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 93 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
94 clk: impl Peripheral<P = impl GpioPin> + 'd, 94 clk: Peri<'d, impl GpioPin>,
95 din: impl Peripheral<P = impl GpioPin> + 'd, 95 din: Peri<'d, impl GpioPin>,
96 config: Config, 96 config: Config,
97 ) -> Self { 97 ) -> Self {
98 into_ref!(pdm, clk, din); 98 Self::new_inner(pdm, clk.into(), din.into(), config)
99 Self::new_inner(pdm, clk.map_into(), din.map_into(), config)
100 } 99 }
101 100
102 fn new_inner( 101 fn new_inner(pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self {
103 pdm: PeripheralRef<'d, T>,
104 clk: PeripheralRef<'d, AnyPin>,
105 din: PeripheralRef<'d, AnyPin>,
106 config: Config,
107 ) -> Self {
108 into_ref!(pdm);
109
110 let r = T::regs(); 102 let r = T::regs();
111 103
112 // setup gpio pins 104 // setup gpio pins
@@ -452,7 +444,7 @@ pub(crate) trait SealedInstance {
452 444
453/// PDM peripheral instance 445/// PDM peripheral instance
454#[allow(private_bounds)] 446#[allow(private_bounds)]
455pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 447pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
456 /// Interrupt for this peripheral 448 /// Interrupt for this peripheral
457 type Interrupt: interrupt::typelevel::Interrupt; 449 type Interrupt: interrupt::typelevel::Interrupt;
458} 450}
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs
index 3c7b96df7..686f66987 100644
--- a/embassy-nrf/src/ppi/dppi.rs
+++ b/embassy-nrf/src/ppi/dppi.rs
@@ -1,7 +1,5 @@
1use embassy_hal_internal::into_ref;
2
3use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; 1use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
4use crate::{pac, Peripheral}; 2use crate::{pac, Peri};
5 3
6const DPPI_ENABLE_BIT: u32 = 0x8000_0000; 4const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
7const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; 5const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
@@ -12,14 +10,14 @@ pub(crate) fn regs() -> pac::dppic::Dppic {
12 10
13impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { 11impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
14 /// Configure PPI channel to trigger `task` on `event`. 12 /// Configure PPI channel to trigger `task` on `event`.
15 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task: Task<'d>) -> Self { 13 pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self {
16 Ppi::new_many_to_many(ch, [event], [task]) 14 Ppi::new_many_to_many(ch, [event], [task])
17 } 15 }
18} 16}
19 17
20impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { 18impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
21 /// Configure PPI channel to trigger both `task1` and `task2` on `event`. 19 /// Configure PPI channel to trigger both `task1` and `task2` on `event`.
22 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { 20 pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self {
23 Ppi::new_many_to_many(ch, [event], [task1, task2]) 21 Ppi::new_many_to_many(ch, [event], [task1, task2])
24 } 22 }
25} 23}
@@ -28,13 +26,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
28 Ppi<'d, C, EVENT_COUNT, TASK_COUNT> 26 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
29{ 27{
30 /// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires. 28 /// Configure a DPPI channel to trigger all `tasks` when any of the `events` fires.
31 pub fn new_many_to_many( 29 pub fn new_many_to_many(ch: Peri<'d, C>, events: [Event<'d>; EVENT_COUNT], tasks: [Task<'d>; TASK_COUNT]) -> Self {
32 ch: impl Peripheral<P = C> + 'd,
33 events: [Event<'d>; EVENT_COUNT],
34 tasks: [Task<'d>; TASK_COUNT],
35 ) -> Self {
36 into_ref!(ch);
37
38 let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK); 30 let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
39 for task in tasks { 31 for task in tasks {
40 if unsafe { task.subscribe_reg().read_volatile() } != 0 { 32 if unsafe { task.subscribe_reg().read_volatile() } != 0 {
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index 325e4ce00..531777205 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -18,10 +18,10 @@
18use core::marker::PhantomData; 18use core::marker::PhantomData;
19use core::ptr::NonNull; 19use core::ptr::NonNull;
20 20
21use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 21use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
22 22
23use crate::pac::common::{Reg, RW, W}; 23use crate::pac::common::{Reg, RW, W};
24use crate::{peripherals, Peripheral}; 24use crate::peripherals;
25 25
26#[cfg_attr(feature = "_dppi", path = "dppi.rs")] 26#[cfg_attr(feature = "_dppi", path = "dppi.rs")]
27#[cfg_attr(feature = "_ppi", path = "ppi.rs")] 27#[cfg_attr(feature = "_ppi", path = "ppi.rs")]
@@ -30,7 +30,7 @@ pub(crate) use _version::*;
30 30
31/// PPI channel driver. 31/// PPI channel driver.
32pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { 32pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
33 ch: PeripheralRef<'d, C>, 33 ch: Peri<'d, C>,
34 #[cfg(feature = "_dppi")] 34 #[cfg(feature = "_dppi")]
35 events: [Event<'d>; EVENT_COUNT], 35 events: [Event<'d>; EVENT_COUNT],
36 #[cfg(feature = "_dppi")] 36 #[cfg(feature = "_dppi")]
@@ -39,16 +39,14 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize
39 39
40/// PPI channel group driver. 40/// PPI channel group driver.
41pub struct PpiGroup<'d, G: Group> { 41pub struct PpiGroup<'d, G: Group> {
42 g: PeripheralRef<'d, G>, 42 g: Peri<'d, G>,
43} 43}
44 44
45impl<'d, G: Group> PpiGroup<'d, G> { 45impl<'d, G: Group> PpiGroup<'d, G> {
46 /// Create a new PPI group driver. 46 /// Create a new PPI group driver.
47 /// 47 ///
48 /// The group is initialized as containing no channels. 48 /// The group is initialized as containing no channels.
49 pub fn new(g: impl Peripheral<P = G> + 'd) -> Self { 49 pub fn new(g: Peri<'d, G>) -> Self {
50 into_ref!(g);
51
52 let r = regs(); 50 let r = regs();
53 let n = g.number(); 51 let n = g.number();
54 r.chg(n).write(|_| ()); 52 r.chg(n).write(|_| ());
@@ -210,34 +208,22 @@ pub(crate) trait SealedGroup {}
210 208
211/// Interface for PPI channels. 209/// Interface for PPI channels.
212#[allow(private_bounds)] 210#[allow(private_bounds)]
213pub trait Channel: SealedChannel + Peripheral<P = Self> + Sized + 'static { 211pub trait Channel: SealedChannel + PeripheralType + Sized + 'static {
214 /// Returns the number of the channel 212 /// Returns the number of the channel
215 fn number(&self) -> usize; 213 fn number(&self) -> usize;
216} 214}
217 215
218/// Interface for PPI channels that can be configured. 216/// Interface for PPI channels that can be configured.
219pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> { 217pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {}
220 /// Convert into a type erased configurable channel.
221 fn degrade(self) -> AnyConfigurableChannel;
222}
223 218
224/// Interface for PPI channels that cannot be configured. 219/// Interface for PPI channels that cannot be configured.
225pub trait StaticChannel: Channel + Into<AnyStaticChannel> { 220pub trait StaticChannel: Channel + Into<AnyStaticChannel> {}
226 /// Convert into a type erased static channel.
227 fn degrade(self) -> AnyStaticChannel;
228}
229 221
230/// Interface for a group of PPI channels. 222/// Interface for a group of PPI channels.
231#[allow(private_bounds)] 223#[allow(private_bounds)]
232pub trait Group: SealedGroup + Peripheral<P = Self> + Into<AnyGroup> + Sized + 'static { 224pub trait Group: SealedGroup + PeripheralType + Into<AnyGroup> + Sized + 'static {
233 /// Returns the number of the group. 225 /// Returns the number of the group.
234 fn number(&self) -> usize; 226 fn number(&self) -> usize;
235 /// Convert into a type erased group.
236 fn degrade(self) -> AnyGroup {
237 AnyGroup {
238 number: self.number() as u8,
239 }
240 }
241} 227}
242 228
243// ====================== 229// ======================
@@ -255,11 +241,7 @@ impl Channel for AnyStaticChannel {
255 self.number as usize 241 self.number as usize
256 } 242 }
257} 243}
258impl StaticChannel for AnyStaticChannel { 244impl StaticChannel for AnyStaticChannel {}
259 fn degrade(self) -> AnyStaticChannel {
260 self
261 }
262}
263 245
264/// The any configurable channel can represent any configurable channel at runtime. 246/// The any configurable channel can represent any configurable channel at runtime.
265/// This can be used to have fewer generic parameters in some places. 247/// This can be used to have fewer generic parameters in some places.
@@ -273,11 +255,7 @@ impl Channel for AnyConfigurableChannel {
273 self.number as usize 255 self.number as usize
274 } 256 }
275} 257}
276impl ConfigurableChannel for AnyConfigurableChannel { 258impl ConfigurableChannel for AnyConfigurableChannel {}
277 fn degrade(self) -> AnyConfigurableChannel {
278 self
279 }
280}
281 259
282#[cfg(not(feature = "_nrf51"))] 260#[cfg(not(feature = "_nrf51"))]
283macro_rules! impl_ppi_channel { 261macro_rules! impl_ppi_channel {
@@ -291,35 +269,23 @@ macro_rules! impl_ppi_channel {
291 }; 269 };
292 ($type:ident, $number:expr => static) => { 270 ($type:ident, $number:expr => static) => {
293 impl_ppi_channel!($type, $number); 271 impl_ppi_channel!($type, $number);
294 impl crate::ppi::StaticChannel for peripherals::$type { 272 impl crate::ppi::StaticChannel for peripherals::$type {}
295 fn degrade(self) -> crate::ppi::AnyStaticChannel {
296 use crate::ppi::Channel;
297 crate::ppi::AnyStaticChannel {
298 number: self.number() as u8,
299 }
300 }
301 }
302
303 impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { 273 impl From<peripherals::$type> for crate::ppi::AnyStaticChannel {
304 fn from(val: peripherals::$type) -> Self { 274 fn from(val: peripherals::$type) -> Self {
305 crate::ppi::StaticChannel::degrade(val) 275 Self {
276 number: crate::ppi::Channel::number(&val) as u8,
277 }
306 } 278 }
307 } 279 }
308 }; 280 };
309 ($type:ident, $number:expr => configurable) => { 281 ($type:ident, $number:expr => configurable) => {
310 impl_ppi_channel!($type, $number); 282 impl_ppi_channel!($type, $number);
311 impl crate::ppi::ConfigurableChannel for peripherals::$type { 283 impl crate::ppi::ConfigurableChannel for peripherals::$type {}
312 fn degrade(self) -> crate::ppi::AnyConfigurableChannel {
313 use crate::ppi::Channel;
314 crate::ppi::AnyConfigurableChannel {
315 number: self.number() as u8,
316 }
317 }
318 }
319
320 impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { 284 impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel {
321 fn from(val: peripherals::$type) -> Self { 285 fn from(val: peripherals::$type) -> Self {
322 crate::ppi::ConfigurableChannel::degrade(val) 286 Self {
287 number: crate::ppi::Channel::number(&val) as u8,
288 }
323 } 289 }
324 } 290 }
325 }; 291 };
@@ -351,7 +317,9 @@ macro_rules! impl_group {
351 317
352 impl From<peripherals::$type> for crate::ppi::AnyGroup { 318 impl From<peripherals::$type> for crate::ppi::AnyGroup {
353 fn from(val: peripherals::$type) -> Self { 319 fn from(val: peripherals::$type) -> Self {
354 crate::ppi::Group::degrade(val) 320 Self {
321 number: crate::ppi::Group::number(&val) as u8,
322 }
355 } 323 }
356 } 324 }
357 }; 325 };
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
index a1beb9dcd..e04dacbc0 100644
--- a/embassy-nrf/src/ppi/ppi.rs
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -1,7 +1,5 @@
1use embassy_hal_internal::into_ref;
2
3use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; 1use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
4use crate::{pac, Peripheral}; 2use crate::{pac, Peri};
5 3
6impl<'d> Task<'d> { 4impl<'d> Task<'d> {
7 fn reg_val(&self) -> u32 { 5 fn reg_val(&self) -> u32 {
@@ -21,9 +19,7 @@ pub(crate) fn regs() -> pac::ppi::Ppi {
21#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task 19#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task
22impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { 20impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> {
23 /// Configure PPI channel to trigger `task`. 21 /// Configure PPI channel to trigger `task`.
24 pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self { 22 pub fn new_zero_to_one(ch: Peri<'d, C>, task: Task) -> Self {
25 into_ref!(ch);
26
27 let r = regs(); 23 let r = regs();
28 let n = ch.number(); 24 let n = ch.number();
29 r.fork(n).tep().write_value(task.reg_val()); 25 r.fork(n).tep().write_value(task.reg_val());
@@ -34,9 +30,7 @@ impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> {
34 30
35impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { 31impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
36 /// Configure PPI channel to trigger `task` on `event`. 32 /// Configure PPI channel to trigger `task` on `event`.
37 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task: Task<'d>) -> Self { 33 pub fn new_one_to_one(ch: Peri<'d, C>, event: Event<'d>, task: Task<'d>) -> Self {
38 into_ref!(ch);
39
40 let r = regs(); 34 let r = regs();
41 let n = ch.number(); 35 let n = ch.number();
42 r.ch(n).eep().write_value(event.reg_val()); 36 r.ch(n).eep().write_value(event.reg_val());
@@ -49,9 +43,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
49#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task 43#[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task
50impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { 44impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
51 /// Configure PPI channel to trigger both `task1` and `task2` on `event`. 45 /// Configure PPI channel to trigger both `task1` and `task2` on `event`.
52 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { 46 pub fn new_one_to_two(ch: Peri<'d, C>, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self {
53 into_ref!(ch);
54
55 let r = regs(); 47 let r = regs();
56 let n = ch.number(); 48 let n = ch.number();
57 r.ch(n).eep().write_value(event.reg_val()); 49 r.ch(n).eep().write_value(event.reg_val());
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs
index 6247ff6a5..a2e153e26 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -4,34 +4,34 @@
4 4
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{Peri, PeripheralType};
8 8
9use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; 9use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED};
10use crate::pac::gpio::vals as gpiovals; 10use crate::pac::gpio::vals as gpiovals;
11use crate::pac::pwm::vals; 11use crate::pac::pwm::vals;
12use crate::ppi::{Event, Task}; 12use crate::ppi::{Event, Task};
13use crate::util::slice_in_ram_or; 13use crate::util::slice_in_ram_or;
14use crate::{interrupt, pac, Peripheral}; 14use crate::{interrupt, pac};
15 15
16/// SimplePwm is the traditional pwm interface you're probably used to, allowing 16/// SimplePwm is the traditional pwm interface you're probably used to, allowing
17/// to simply set a duty cycle across up to four channels. 17/// to simply set a duty cycle across up to four channels.
18pub struct SimplePwm<'d, T: Instance> { 18pub struct SimplePwm<'d, T: Instance> {
19 _peri: PeripheralRef<'d, T>, 19 _peri: Peri<'d, T>,
20 duty: [u16; 4], 20 duty: [u16; 4],
21 ch0: Option<PeripheralRef<'d, AnyPin>>, 21 ch0: Option<Peri<'d, AnyPin>>,
22 ch1: Option<PeripheralRef<'d, AnyPin>>, 22 ch1: Option<Peri<'d, AnyPin>>,
23 ch2: Option<PeripheralRef<'d, AnyPin>>, 23 ch2: Option<Peri<'d, AnyPin>>,
24 ch3: Option<PeripheralRef<'d, AnyPin>>, 24 ch3: Option<Peri<'d, AnyPin>>,
25} 25}
26 26
27/// SequencePwm allows you to offload the updating of a sequence of duty cycles 27/// SequencePwm allows you to offload the updating of a sequence of duty cycles
28/// to up to four channels, as well as repeat that sequence n times. 28/// to up to four channels, as well as repeat that sequence n times.
29pub struct SequencePwm<'d, T: Instance> { 29pub struct SequencePwm<'d, T: Instance> {
30 _peri: PeripheralRef<'d, T>, 30 _peri: Peri<'d, T>,
31 ch0: Option<PeripheralRef<'d, AnyPin>>, 31 ch0: Option<Peri<'d, AnyPin>>,
32 ch1: Option<PeripheralRef<'d, AnyPin>>, 32 ch1: Option<Peri<'d, AnyPin>>,
33 ch2: Option<PeripheralRef<'d, AnyPin>>, 33 ch2: Option<Peri<'d, AnyPin>>,
34 ch3: Option<PeripheralRef<'d, AnyPin>>, 34 ch3: Option<Peri<'d, AnyPin>>,
35} 35}
36 36
37/// PWM error 37/// PWM error
@@ -54,78 +54,61 @@ pub const PWM_CLK_HZ: u32 = 16_000_000;
54impl<'d, T: Instance> SequencePwm<'d, T> { 54impl<'d, T: Instance> SequencePwm<'d, T> {
55 /// Create a new 1-channel PWM 55 /// Create a new 1-channel PWM
56 #[allow(unused_unsafe)] 56 #[allow(unused_unsafe)]
57 pub fn new_1ch( 57 pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> {
58 pwm: impl Peripheral<P = T> + 'd, 58 Self::new_inner(pwm, Some(ch0.into()), None, None, None, config)
59 ch0: impl Peripheral<P = impl GpioPin> + 'd,
60 config: Config,
61 ) -> Result<Self, Error> {
62 into_ref!(ch0);
63 Self::new_inner(pwm, Some(ch0.map_into()), None, None, None, config)
64 } 59 }
65 60
66 /// Create a new 2-channel PWM 61 /// Create a new 2-channel PWM
67 #[allow(unused_unsafe)] 62 #[allow(unused_unsafe)]
68 pub fn new_2ch( 63 pub fn new_2ch(
69 pwm: impl Peripheral<P = T> + 'd, 64 pwm: Peri<'d, T>,
70 ch0: impl Peripheral<P = impl GpioPin> + 'd, 65 ch0: Peri<'d, impl GpioPin>,
71 ch1: impl Peripheral<P = impl GpioPin> + 'd, 66 ch1: Peri<'d, impl GpioPin>,
72 config: Config, 67 config: Config,
73 ) -> Result<Self, Error> { 68 ) -> Result<Self, Error> {
74 into_ref!(ch0, ch1); 69 Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None, config)
75 Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config)
76 } 70 }
77 71
78 /// Create a new 3-channel PWM 72 /// Create a new 3-channel PWM
79 #[allow(unused_unsafe)] 73 #[allow(unused_unsafe)]
80 pub fn new_3ch( 74 pub fn new_3ch(
81 pwm: impl Peripheral<P = T> + 'd, 75 pwm: Peri<'d, T>,
82 ch0: impl Peripheral<P = impl GpioPin> + 'd, 76 ch0: Peri<'d, impl GpioPin>,
83 ch1: impl Peripheral<P = impl GpioPin> + 'd, 77 ch1: Peri<'d, impl GpioPin>,
84 ch2: impl Peripheral<P = impl GpioPin> + 'd, 78 ch2: Peri<'d, impl GpioPin>,
85 config: Config, 79 config: Config,
86 ) -> Result<Self, Error> { 80 ) -> Result<Self, Error> {
87 into_ref!(ch0, ch1, ch2); 81 Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None, config)
88 Self::new_inner(
89 pwm,
90 Some(ch0.map_into()),
91 Some(ch1.map_into()),
92 Some(ch2.map_into()),
93 None,
94 config,
95 )
96 } 82 }
97 83
98 /// Create a new 4-channel PWM 84 /// Create a new 4-channel PWM
99 #[allow(unused_unsafe)] 85 #[allow(unused_unsafe)]
100 pub fn new_4ch( 86 pub fn new_4ch(
101 pwm: impl Peripheral<P = T> + 'd, 87 pwm: Peri<'d, T>,
102 ch0: impl Peripheral<P = impl GpioPin> + 'd, 88 ch0: Peri<'d, impl GpioPin>,
103 ch1: impl Peripheral<P = impl GpioPin> + 'd, 89 ch1: Peri<'d, impl GpioPin>,
104 ch2: impl Peripheral<P = impl GpioPin> + 'd, 90 ch2: Peri<'d, impl GpioPin>,
105 ch3: impl Peripheral<P = impl GpioPin> + 'd, 91 ch3: Peri<'d, impl GpioPin>,
106 config: Config, 92 config: Config,
107 ) -> Result<Self, Error> { 93 ) -> Result<Self, Error> {
108 into_ref!(ch0, ch1, ch2, ch3);
109 Self::new_inner( 94 Self::new_inner(
110 pwm, 95 pwm,
111 Some(ch0.map_into()), 96 Some(ch0.into()),
112 Some(ch1.map_into()), 97 Some(ch1.into()),
113 Some(ch2.map_into()), 98 Some(ch2.into()),
114 Some(ch3.map_into()), 99 Some(ch3.into()),
115 config, 100 config,
116 ) 101 )
117 } 102 }
118 103
119 fn new_inner( 104 fn new_inner(
120 _pwm: impl Peripheral<P = T> + 'd, 105 _pwm: Peri<'d, T>,
121 ch0: Option<PeripheralRef<'d, AnyPin>>, 106 ch0: Option<Peri<'d, AnyPin>>,
122 ch1: Option<PeripheralRef<'d, AnyPin>>, 107 ch1: Option<Peri<'d, AnyPin>>,
123 ch2: Option<PeripheralRef<'d, AnyPin>>, 108 ch2: Option<Peri<'d, AnyPin>>,
124 ch3: Option<PeripheralRef<'d, AnyPin>>, 109 ch3: Option<Peri<'d, AnyPin>>,
125 config: Config, 110 config: Config,
126 ) -> Result<Self, Error> { 111 ) -> Result<Self, Error> {
127 into_ref!(_pwm);
128
129 let r = T::regs(); 112 let r = T::regs();
130 113
131 if let Some(pin) = &ch0 { 114 if let Some(pin) = &ch0 {
@@ -610,74 +593,54 @@ pub enum CounterMode {
610impl<'d, T: Instance> SimplePwm<'d, T> { 593impl<'d, T: Instance> SimplePwm<'d, T> {
611 /// Create a new 1-channel PWM 594 /// Create a new 1-channel PWM
612 #[allow(unused_unsafe)] 595 #[allow(unused_unsafe)]
613 pub fn new_1ch(pwm: impl Peripheral<P = T> + 'd, ch0: impl Peripheral<P = impl GpioPin> + 'd) -> Self { 596 pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self {
614 unsafe { 597 unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) }
615 into_ref!(ch0);
616 Self::new_inner(pwm, Some(ch0.map_into()), None, None, None)
617 }
618 } 598 }
619 599
620 /// Create a new 2-channel PWM 600 /// Create a new 2-channel PWM
621 #[allow(unused_unsafe)] 601 #[allow(unused_unsafe)]
622 pub fn new_2ch( 602 pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self {
623 pwm: impl Peripheral<P = T> + 'd, 603 Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None)
624 ch0: impl Peripheral<P = impl GpioPin> + 'd,
625 ch1: impl Peripheral<P = impl GpioPin> + 'd,
626 ) -> Self {
627 into_ref!(ch0, ch1);
628 Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None)
629 } 604 }
630 605
631 /// Create a new 3-channel PWM 606 /// Create a new 3-channel PWM
632 #[allow(unused_unsafe)] 607 #[allow(unused_unsafe)]
633 pub fn new_3ch( 608 pub fn new_3ch(
634 pwm: impl Peripheral<P = T> + 'd, 609 pwm: Peri<'d, T>,
635 ch0: impl Peripheral<P = impl GpioPin> + 'd, 610 ch0: Peri<'d, impl GpioPin>,
636 ch1: impl Peripheral<P = impl GpioPin> + 'd, 611 ch1: Peri<'d, impl GpioPin>,
637 ch2: impl Peripheral<P = impl GpioPin> + 'd, 612 ch2: Peri<'d, impl GpioPin>,
638 ) -> Self { 613 ) -> Self {
639 unsafe { 614 unsafe { Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), Some(ch2.into()), None) }
640 into_ref!(ch0, ch1, ch2);
641 Self::new_inner(
642 pwm,
643 Some(ch0.map_into()),
644 Some(ch1.map_into()),
645 Some(ch2.map_into()),
646 None,
647 )
648 }
649 } 615 }
650 616
651 /// Create a new 4-channel PWM 617 /// Create a new 4-channel PWM
652 #[allow(unused_unsafe)] 618 #[allow(unused_unsafe)]
653 pub fn new_4ch( 619 pub fn new_4ch(
654 pwm: impl Peripheral<P = T> + 'd, 620 pwm: Peri<'d, T>,
655 ch0: impl Peripheral<P = impl GpioPin> + 'd, 621 ch0: Peri<'d, impl GpioPin>,
656 ch1: impl Peripheral<P = impl GpioPin> + 'd, 622 ch1: Peri<'d, impl GpioPin>,
657 ch2: impl Peripheral<P = impl GpioPin> + 'd, 623 ch2: Peri<'d, impl GpioPin>,
658 ch3: impl Peripheral<P = impl GpioPin> + 'd, 624 ch3: Peri<'d, impl GpioPin>,
659 ) -> Self { 625 ) -> Self {
660 unsafe { 626 unsafe {
661 into_ref!(ch0, ch1, ch2, ch3);
662 Self::new_inner( 627 Self::new_inner(
663 pwm, 628 pwm,
664 Some(ch0.map_into()), 629 Some(ch0.into()),
665 Some(ch1.map_into()), 630 Some(ch1.into()),
666 Some(ch2.map_into()), 631 Some(ch2.into()),
667 Some(ch3.map_into()), 632 Some(ch3.into()),
668 ) 633 )
669 } 634 }
670 } 635 }
671 636
672 fn new_inner( 637 fn new_inner(
673 _pwm: impl Peripheral<P = T> + 'd, 638 _pwm: Peri<'d, T>,
674 ch0: Option<PeripheralRef<'d, AnyPin>>, 639 ch0: Option<Peri<'d, AnyPin>>,
675 ch1: Option<PeripheralRef<'d, AnyPin>>, 640 ch1: Option<Peri<'d, AnyPin>>,
676 ch2: Option<PeripheralRef<'d, AnyPin>>, 641 ch2: Option<Peri<'d, AnyPin>>,
677 ch3: Option<PeripheralRef<'d, AnyPin>>, 642 ch3: Option<Peri<'d, AnyPin>>,
678 ) -> Self { 643 ) -> Self {
679 into_ref!(_pwm);
680
681 let r = T::regs(); 644 let r = T::regs();
682 645
683 for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() { 646 for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() {
@@ -896,7 +859,7 @@ pub(crate) trait SealedInstance {
896 859
897/// PWM peripheral instance. 860/// PWM peripheral instance.
898#[allow(private_bounds)] 861#[allow(private_bounds)]
899pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { 862pub trait Instance: SealedInstance + PeripheralType + 'static {
900 /// Interrupt for this peripheral. 863 /// Interrupt for this peripheral.
901 type Interrupt: interrupt::typelevel::Interrupt; 864 type Interrupt: interrupt::typelevel::Interrupt;
902} 865}
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index efd2a134c..69bfab0bb 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -6,18 +6,18 @@ use core::future::poll_fn;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{Peri, PeripheralType};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; 12use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
13use crate::interrupt::typelevel::Interrupt; 13use crate::interrupt::typelevel::Interrupt;
14use crate::pac::gpio::vals as gpiovals; 14use crate::pac::gpio::vals as gpiovals;
15use crate::pac::qdec::vals; 15use crate::pac::qdec::vals;
16use crate::{interrupt, pac, Peripheral}; 16use crate::{interrupt, pac};
17 17
18/// Quadrature decoder driver. 18/// Quadrature decoder driver.
19pub struct Qdec<'d, T: Instance> { 19pub struct Qdec<'d, T: Instance> {
20 _p: PeripheralRef<'d, T>, 20 _p: Peri<'d, T>,
21} 21}
22 22
23/// QDEC config 23/// QDEC config
@@ -62,34 +62,32 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
62impl<'d, T: Instance> Qdec<'d, T> { 62impl<'d, T: Instance> Qdec<'d, T> {
63 /// Create a new QDEC. 63 /// Create a new QDEC.
64 pub fn new( 64 pub fn new(
65 qdec: impl Peripheral<P = T> + 'd, 65 qdec: Peri<'d, T>,
66 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 66 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
67 a: impl Peripheral<P = impl GpioPin> + 'd, 67 a: Peri<'d, impl GpioPin>,
68 b: impl Peripheral<P = impl GpioPin> + 'd, 68 b: Peri<'d, impl GpioPin>,
69 config: Config, 69 config: Config,
70 ) -> Self { 70 ) -> Self {
71 into_ref!(qdec, a, b); 71 Self::new_inner(qdec, a.into(), b.into(), None, config)
72 Self::new_inner(qdec, a.map_into(), b.map_into(), None, config)
73 } 72 }
74 73
75 /// Create a new QDEC, with a pin for LED output. 74 /// Create a new QDEC, with a pin for LED output.
76 pub fn new_with_led( 75 pub fn new_with_led(
77 qdec: impl Peripheral<P = T> + 'd, 76 qdec: Peri<'d, T>,
78 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 77 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
79 a: impl Peripheral<P = impl GpioPin> + 'd, 78 a: Peri<'d, impl GpioPin>,
80 b: impl Peripheral<P = impl GpioPin> + 'd, 79 b: Peri<'d, impl GpioPin>,
81 led: impl Peripheral<P = impl GpioPin> + 'd, 80 led: Peri<'d, impl GpioPin>,
82 config: Config, 81 config: Config,
83 ) -> Self { 82 ) -> Self {
84 into_ref!(qdec, a, b, led); 83 Self::new_inner(qdec, a.into(), b.into(), Some(led.into()), config)
85 Self::new_inner(qdec, a.map_into(), b.map_into(), Some(led.map_into()), config)
86 } 84 }
87 85
88 fn new_inner( 86 fn new_inner(
89 p: PeripheralRef<'d, T>, 87 p: Peri<'d, T>,
90 a: PeripheralRef<'d, AnyPin>, 88 a: Peri<'d, AnyPin>,
91 b: PeripheralRef<'d, AnyPin>, 89 b: Peri<'d, AnyPin>,
92 led: Option<PeripheralRef<'d, AnyPin>>, 90 led: Option<Peri<'d, AnyPin>>,
93 config: Config, 91 config: Config,
94 ) -> Self { 92 ) -> Self {
95 let r = T::regs(); 93 let r = T::regs();
@@ -272,7 +270,7 @@ pub(crate) trait SealedInstance {
272 270
273/// qdec peripheral instance. 271/// qdec peripheral instance.
274#[allow(private_bounds)] 272#[allow(private_bounds)]
275pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 273pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
276 /// Interrupt for this peripheral. 274 /// Interrupt for this peripheral.
277 type Interrupt: interrupt::typelevel::Interrupt; 275 type Interrupt: interrupt::typelevel::Interrupt;
278} 276}
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 17e127700..e6e829f6e 100755
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -8,7 +8,7 @@ use core::ptr;
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_hal_internal::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; 13use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
14 14
@@ -19,7 +19,7 @@ use crate::pac::qspi::vals;
19pub use crate::pac::qspi::vals::{ 19pub use crate::pac::qspi::vals::{
20 Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode, 20 Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode,
21}; 21};
22use crate::{interrupt, pac, Peripheral}; 22use crate::{interrupt, pac};
23 23
24/// Deep power-down config. 24/// Deep power-down config.
25pub struct DeepPowerDownConfig { 25pub struct DeepPowerDownConfig {
@@ -139,7 +139,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
139 139
140/// QSPI flash driver. 140/// QSPI flash driver.
141pub struct Qspi<'d, T: Instance> { 141pub struct Qspi<'d, T: Instance> {
142 _peri: PeripheralRef<'d, T>, 142 _peri: Peri<'d, T>,
143 dpm_enabled: bool, 143 dpm_enabled: bool,
144 capacity: u32, 144 capacity: u32,
145} 145}
@@ -147,18 +147,16 @@ pub struct Qspi<'d, T: Instance> {
147impl<'d, T: Instance> Qspi<'d, T> { 147impl<'d, T: Instance> Qspi<'d, T> {
148 /// Create a new QSPI driver. 148 /// Create a new QSPI driver.
149 pub fn new( 149 pub fn new(
150 qspi: impl Peripheral<P = T> + 'd, 150 qspi: Peri<'d, T>,
151 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 151 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
152 sck: impl Peripheral<P = impl GpioPin> + 'd, 152 sck: Peri<'d, impl GpioPin>,
153 csn: impl Peripheral<P = impl GpioPin> + 'd, 153 csn: Peri<'d, impl GpioPin>,
154 io0: impl Peripheral<P = impl GpioPin> + 'd, 154 io0: Peri<'d, impl GpioPin>,
155 io1: impl Peripheral<P = impl GpioPin> + 'd, 155 io1: Peri<'d, impl GpioPin>,
156 io2: impl Peripheral<P = impl GpioPin> + 'd, 156 io2: Peri<'d, impl GpioPin>,
157 io3: impl Peripheral<P = impl GpioPin> + 'd, 157 io3: Peri<'d, impl GpioPin>,
158 config: Config, 158 config: Config,
159 ) -> Self { 159 ) -> Self {
160 into_ref!(qspi, sck, csn, io0, io1, io2, io3);
161
162 let r = T::regs(); 160 let r = T::regs();
163 161
164 macro_rules! config_pin { 162 macro_rules! config_pin {
@@ -664,7 +662,7 @@ pub(crate) trait SealedInstance {
664 662
665/// QSPI peripheral instance. 663/// QSPI peripheral instance.
666#[allow(private_bounds)] 664#[allow(private_bounds)]
667pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 665pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
668 /// Interrupt for this peripheral. 666 /// Interrupt for this peripheral.
669 type Interrupt: interrupt::typelevel::Interrupt; 667 type Interrupt: interrupt::typelevel::Interrupt;
670} 668}
diff --git a/embassy-nrf/src/radio/ble.rs b/embassy-nrf/src/radio/ble.rs
index 682ca1c79..d42bbe5f6 100644
--- a/embassy-nrf/src/radio/ble.rs
+++ b/embassy-nrf/src/radio/ble.rs
@@ -5,7 +5,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy_hal_internal::drop::OnDrop; 7use embassy_hal_internal::drop::OnDrop;
8use embassy_hal_internal::{into_ref, PeripheralRef};
9pub use pac::radio::vals::Mode; 8pub use pac::radio::vals::Mode;
10#[cfg(not(feature = "_nrf51"))] 9#[cfg(not(feature = "_nrf51"))]
11use pac::radio::vals::Plen as PreambleLength; 10use pac::radio::vals::Plen as PreambleLength;
@@ -15,20 +14,19 @@ use crate::pac::radio::vals;
15use crate::radio::*; 14use crate::radio::*;
16pub use crate::radio::{Error, TxPower}; 15pub use crate::radio::{Error, TxPower};
17use crate::util::slice_in_ram_or; 16use crate::util::slice_in_ram_or;
17use crate::Peri;
18 18
19/// Radio driver. 19/// Radio driver.
20pub struct Radio<'d, T: Instance> { 20pub struct Radio<'d, T: Instance> {
21 _p: PeripheralRef<'d, T>, 21 _p: Peri<'d, T>,
22} 22}
23 23
24impl<'d, T: Instance> Radio<'d, T> { 24impl<'d, T: Instance> Radio<'d, T> {
25 /// Create a new radio driver. 25 /// Create a new radio driver.
26 pub fn new( 26 pub fn new(
27 radio: impl Peripheral<P = T> + 'd, 27 radio: Peri<'d, T>,
28 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 28 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
29 ) -> Self { 29 ) -> Self {
30 into_ref!(radio);
31
32 let r = T::regs(); 30 let r = T::regs();
33 31
34 r.pcnf1().write(|w| { 32 r.pcnf1().write(|w| {
diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs
index 083842f4a..2f0bcbe04 100644
--- a/embassy-nrf/src/radio/ieee802154.rs
+++ b/embassy-nrf/src/radio/ieee802154.rs
@@ -4,13 +4,12 @@ use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::drop::OnDrop; 6use embassy_hal_internal::drop::OnDrop;
7use embassy_hal_internal::{into_ref, PeripheralRef};
8 7
9use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower}; 8use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower};
10use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
11use crate::interrupt::{self}; 10use crate::interrupt::{self};
12use crate::pac::radio::vals; 11use crate::pac::radio::vals;
13use crate::Peripheral; 12use crate::Peri;
14 13
15/// Default (IEEE compliant) Start of Frame Delimiter 14/// Default (IEEE compliant) Start of Frame Delimiter
16pub const DEFAULT_SFD: u8 = 0xA7; 15pub const DEFAULT_SFD: u8 = 0xA7;
@@ -33,18 +32,16 @@ pub enum Cca {
33 32
34/// IEEE 802.15.4 radio driver. 33/// IEEE 802.15.4 radio driver.
35pub struct Radio<'d, T: Instance> { 34pub struct Radio<'d, T: Instance> {
36 _p: PeripheralRef<'d, T>, 35 _p: Peri<'d, T>,
37 needs_enable: bool, 36 needs_enable: bool,
38} 37}
39 38
40impl<'d, T: Instance> Radio<'d, T> { 39impl<'d, T: Instance> Radio<'d, T> {
41 /// Create a new IEEE 802.15.4 radio driver. 40 /// Create a new IEEE 802.15.4 radio driver.
42 pub fn new( 41 pub fn new(
43 radio: impl Peripheral<P = T> + 'd, 42 radio: Peri<'d, T>,
44 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 43 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
45 ) -> Self { 44 ) -> Self {
46 into_ref!(radio);
47
48 let r = T::regs(); 45 let r = T::regs();
49 46
50 // Disable and enable to reset peripheral 47 // Disable and enable to reset peripheral
diff --git a/embassy-nrf/src/radio/mod.rs b/embassy-nrf/src/radio/mod.rs
index 251f37d3d..982436266 100644
--- a/embassy-nrf/src/radio/mod.rs
+++ b/embassy-nrf/src/radio/mod.rs
@@ -19,11 +19,12 @@ pub mod ieee802154;
19 19
20use core::marker::PhantomData; 20use core::marker::PhantomData;
21 21
22use embassy_hal_internal::PeripheralType;
22use embassy_sync::waitqueue::AtomicWaker; 23use embassy_sync::waitqueue::AtomicWaker;
23use pac::radio::vals::State as RadioState; 24use pac::radio::vals::State as RadioState;
24pub use pac::radio::vals::Txpower as TxPower; 25pub use pac::radio::vals::Txpower as TxPower;
25 26
26use crate::{interrupt, pac, Peripheral}; 27use crate::{interrupt, pac};
27 28
28/// RADIO error. 29/// RADIO error.
29#[derive(Debug, Clone, Copy, PartialEq, Eq)] 30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -94,7 +95,7 @@ macro_rules! impl_radio {
94 95
95/// Radio peripheral instance. 96/// Radio peripheral instance.
96#[allow(private_bounds)] 97#[allow(private_bounds)]
97pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 98pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
98 /// Interrupt for this peripheral. 99 /// Interrupt for this peripheral.
99 type Interrupt: interrupt::typelevel::Interrupt; 100 type Interrupt: interrupt::typelevel::Interrupt;
100} 101}
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 7a98ab2fb..e75ffda00 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -10,11 +10,11 @@ use core::task::Poll;
10 10
11use critical_section::{CriticalSection, Mutex}; 11use critical_section::{CriticalSection, Mutex};
12use embassy_hal_internal::drop::OnDrop; 12use embassy_hal_internal::drop::OnDrop;
13use embassy_hal_internal::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::WakerRegistration; 14use embassy_sync::waitqueue::WakerRegistration;
15 15
16use crate::interrupt::typelevel::Interrupt; 16use crate::interrupt::typelevel::Interrupt;
17use crate::{interrupt, pac, Peripheral}; 17use crate::{interrupt, pac};
18 18
19/// Interrupt handler. 19/// Interrupt handler.
20pub struct InterruptHandler<T: Instance> { 20pub struct InterruptHandler<T: Instance> {
@@ -56,7 +56,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
56/// 56///
57/// It has a non-blocking API, and a blocking api through `rand`. 57/// It has a non-blocking API, and a blocking api through `rand`.
58pub struct Rng<'d, T: Instance> { 58pub struct Rng<'d, T: Instance> {
59 _peri: PeripheralRef<'d, T>, 59 _peri: Peri<'d, T>,
60} 60}
61 61
62impl<'d, T: Instance> Rng<'d, T> { 62impl<'d, T: Instance> Rng<'d, T> {
@@ -67,11 +67,9 @@ impl<'d, T: Instance> Rng<'d, T> {
67 /// 67 ///
68 /// The synchronous API is safe. 68 /// The synchronous API is safe.
69 pub fn new( 69 pub fn new(
70 rng: impl Peripheral<P = T> + 'd, 70 rng: Peri<'d, T>,
71 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 71 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
72 ) -> Self { 72 ) -> Self {
73 into_ref!(rng);
74
75 let this = Self { _peri: rng }; 73 let this = Self { _peri: rng };
76 74
77 this.stop(); 75 this.stop();
@@ -250,7 +248,7 @@ pub(crate) trait SealedInstance {
250 248
251/// RNG peripheral instance. 249/// RNG peripheral instance.
252#[allow(private_bounds)] 250#[allow(private_bounds)]
253pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 251pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
254 /// Interrupt for this peripheral. 252 /// Interrupt for this peripheral.
255 type Interrupt: interrupt::typelevel::Interrupt; 253 type Interrupt: interrupt::typelevel::Interrupt;
256} 254}
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 70bda9f70..92b6fb01f 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -3,11 +3,12 @@
3#![macro_use] 3#![macro_use]
4 4
5use core::future::poll_fn; 5use core::future::poll_fn;
6use core::marker::PhantomData;
6use core::sync::atomic::{compiler_fence, Ordering}; 7use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 8use core::task::Poll;
8 9
9use embassy_hal_internal::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
10use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 11use embassy_hal_internal::{impl_peripheral, Peri};
11use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
12pub(crate) use vals::Psel as InputChannel; 13pub(crate) use vals::Psel as InputChannel;
13 14
@@ -15,7 +16,7 @@ use crate::interrupt::InterruptExt;
15use crate::pac::saadc::vals; 16use crate::pac::saadc::vals;
16use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; 17use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
17use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 18use crate::timer::{Frequency, Instance as TimerInstance, Timer};
18use crate::{interrupt, pac, peripherals, Peripheral}; 19use crate::{interrupt, pac, peripherals};
19 20
20/// SAADC error 21/// SAADC error
21#[derive(Debug, Clone, Copy, PartialEq, Eq)] 22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -87,37 +88,32 @@ pub struct ChannelConfig<'d> {
87 /// Acquisition time in microseconds. 88 /// Acquisition time in microseconds.
88 pub time: Time, 89 pub time: Time,
89 /// Positive channel to sample 90 /// Positive channel to sample
90 p_channel: PeripheralRef<'d, AnyInput>, 91 p_channel: AnyInput<'d>,
91 /// An optional negative channel to sample 92 /// An optional negative channel to sample
92 n_channel: Option<PeripheralRef<'d, AnyInput>>, 93 n_channel: Option<AnyInput<'d>>,
93} 94}
94 95
95impl<'d> ChannelConfig<'d> { 96impl<'d> ChannelConfig<'d> {
96 /// Default configuration for single ended channel sampling. 97 /// Default configuration for single ended channel sampling.
97 pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self { 98 pub fn single_ended(input: impl Input + 'd) -> Self {
98 into_ref!(input);
99 Self { 99 Self {
100 reference: Reference::INTERNAL, 100 reference: Reference::INTERNAL,
101 gain: Gain::GAIN1_6, 101 gain: Gain::GAIN1_6,
102 resistor: Resistor::BYPASS, 102 resistor: Resistor::BYPASS,
103 time: Time::_10US, 103 time: Time::_10US,
104 p_channel: input.map_into(), 104 p_channel: input.degrade_saadc(),
105 n_channel: None, 105 n_channel: None,
106 } 106 }
107 } 107 }
108 /// Default configuration for differential channel sampling. 108 /// Default configuration for differential channel sampling.
109 pub fn differential( 109 pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self {
110 p_input: impl Peripheral<P = impl Input> + 'd,
111 n_input: impl Peripheral<P = impl Input> + 'd,
112 ) -> Self {
113 into_ref!(p_input, n_input);
114 Self { 110 Self {
115 reference: Reference::INTERNAL, 111 reference: Reference::INTERNAL,
116 gain: Gain::GAIN1_6, 112 gain: Gain::GAIN1_6,
117 resistor: Resistor::BYPASS, 113 resistor: Resistor::BYPASS,
118 time: Time::_10US, 114 time: Time::_10US,
119 p_channel: p_input.map_into(), 115 p_channel: p_input.degrade_saadc(),
120 n_channel: Some(n_input.map_into()), 116 n_channel: Some(n_input.degrade_saadc()),
121 } 117 }
122 } 118 }
123} 119}
@@ -133,19 +129,17 @@ pub enum CallbackResult {
133 129
134/// One-shot and continuous SAADC. 130/// One-shot and continuous SAADC.
135pub struct Saadc<'d, const N: usize> { 131pub struct Saadc<'d, const N: usize> {
136 _p: PeripheralRef<'d, peripherals::SAADC>, 132 _p: Peri<'d, peripherals::SAADC>,
137} 133}
138 134
139impl<'d, const N: usize> Saadc<'d, N> { 135impl<'d, const N: usize> Saadc<'d, N> {
140 /// Create a new SAADC driver. 136 /// Create a new SAADC driver.
141 pub fn new( 137 pub fn new(
142 saadc: impl Peripheral<P = peripherals::SAADC> + 'd, 138 saadc: Peri<'d, peripherals::SAADC>,
143 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SAADC, InterruptHandler> + 'd, 139 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SAADC, InterruptHandler> + 'd,
144 config: Config, 140 config: Config,
145 channel_configs: [ChannelConfig; N], 141 channel_configs: [ChannelConfig; N],
146 ) -> Self { 142 ) -> Self {
147 into_ref!(saadc);
148
149 let r = pac::SAADC; 143 let r = pac::SAADC;
150 144
151 let Config { resolution, oversample } = config; 145 let Config { resolution, oversample } = config;
@@ -284,9 +278,9 @@ impl<'d, const N: usize> Saadc<'d, N> {
284 278
285 pub async fn run_task_sampler<F, T: TimerInstance, const N0: usize>( 279 pub async fn run_task_sampler<F, T: TimerInstance, const N0: usize>(
286 &mut self, 280 &mut self,
287 timer: &mut T, 281 timer: Peri<'_, T>,
288 ppi_ch1: &mut impl ConfigurableChannel, 282 ppi_ch1: Peri<'_, impl ConfigurableChannel>,
289 ppi_ch2: &mut impl ConfigurableChannel, 283 ppi_ch2: Peri<'_, impl ConfigurableChannel>,
290 frequency: Frequency, 284 frequency: Frequency,
291 sample_counter: u32, 285 sample_counter: u32,
292 bufs: &mut [[[i16; N]; N0]; 2], 286 bufs: &mut [[[i16; N]; N0]; 2],
@@ -465,6 +459,10 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> {
465 fn drop(&mut self) { 459 fn drop(&mut self) {
466 let r = Self::regs(); 460 let r = Self::regs();
467 r.enable().write(|w| w.set_enable(false)); 461 r.enable().write(|w| w.set_enable(false));
462 for i in 0..N {
463 r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC));
464 r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC));
465 }
468 } 466 }
469} 467}
470 468
@@ -651,14 +649,18 @@ pub(crate) trait SealedInput {
651 649
652/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. 650/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
653#[allow(private_bounds)] 651#[allow(private_bounds)]
654pub trait Input: SealedInput + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static { 652pub trait Input: SealedInput + Sized {
655 /// Convert this SAADC input to a type-erased `AnyInput`. 653 /// Convert this SAADC input to a type-erased `AnyInput`.
656 /// 654 ///
657 /// This allows using several inputs in situations that might require 655 /// This allows using several inputs in situations that might require
658 /// them to be the same type, like putting them in an array. 656 /// them to be the same type, like putting them in an array.
659 fn degrade_saadc(self) -> AnyInput { 657 fn degrade_saadc<'a>(self) -> AnyInput<'a>
658 where
659 Self: 'a,
660 {
660 AnyInput { 661 AnyInput {
661 channel: self.channel(), 662 channel: self.channel(),
663 _phantom: core::marker::PhantomData,
662 } 664 }
663 } 665 }
664} 666}
@@ -667,23 +669,36 @@ pub trait Input: SealedInput + Into<AnyInput> + Peripheral<P = Self> + Sized + '
667/// 669///
668/// This allows using several inputs in situations that might require 670/// This allows using several inputs in situations that might require
669/// them to be the same type, like putting them in an array. 671/// them to be the same type, like putting them in an array.
670pub struct AnyInput { 672pub struct AnyInput<'a> {
671 channel: InputChannel, 673 channel: InputChannel,
674 _phantom: PhantomData<&'a ()>,
672} 675}
673 676
674impl_peripheral!(AnyInput); 677impl<'a> AnyInput<'a> {
678 /// Reborrow into a "child" AnyInput.
679 ///
680 /// `self` will stay borrowed until the child AnyInput is dropped.
681 pub fn reborrow(&mut self) -> AnyInput<'_> {
682 // safety: we're returning the clone inside a new Peripheral that borrows
683 // self, so user code can't use both at the same time.
684 Self {
685 channel: self.channel,
686 _phantom: PhantomData,
687 }
688 }
689}
675 690
676impl SealedInput for AnyInput { 691impl SealedInput for AnyInput<'_> {
677 fn channel(&self) -> InputChannel { 692 fn channel(&self) -> InputChannel {
678 self.channel 693 self.channel
679 } 694 }
680} 695}
681 696
682impl Input for AnyInput {} 697impl Input for AnyInput<'_> {}
683 698
684macro_rules! impl_saadc_input { 699macro_rules! impl_saadc_input {
685 ($pin:ident, $ch:ident) => { 700 ($pin:ident, $ch:ident) => {
686 impl_saadc_input!(@local, crate::peripherals::$pin, $ch); 701 impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch);
687 }; 702 };
688 (@local, $pin:ty, $ch:ident) => { 703 (@local, $pin:ty, $ch:ident) => {
689 impl crate::saadc::SealedInput for $pin { 704 impl crate::saadc::SealedInput for $pin {
@@ -692,12 +707,6 @@ macro_rules! impl_saadc_input {
692 } 707 }
693 } 708 }
694 impl crate::saadc::Input for $pin {} 709 impl crate::saadc::Input for $pin {}
695
696 impl From<$pin> for crate::saadc::AnyInput {
697 fn from(val: $pin) -> Self {
698 crate::saadc::Input::degrade_saadc(val)
699 }
700 }
701 }; 710 };
702} 711}
703 712
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index bd193cfe8..59f5b6d58 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -10,7 +10,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
10use core::task::Poll; 10use core::task::Poll;
11 11
12use embassy_embedded_hal::SetConfig; 12use embassy_embedded_hal::SetConfig;
13use embassy_hal_internal::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
15pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 15pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
16pub use pac::spim::vals::{Frequency, Order as BitOrder}; 16pub use pac::spim::vals::{Frequency, Order as BitOrder};
@@ -21,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt;
21use crate::pac::gpio::vals as gpiovals; 21use crate::pac::gpio::vals as gpiovals;
22use crate::pac::spim::vals; 22use crate::pac::spim::vals;
23use crate::util::slice_in_ram_or; 23use crate::util::slice_in_ram_or;
24use crate::{interrupt, pac, Peripheral}; 24use crate::{interrupt, pac};
25 25
26/// SPIM error 26/// SPIM error
27#[derive(Debug, Clone, Copy, PartialEq, Eq)] 27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -100,73 +100,61 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
100 100
101/// SPIM driver. 101/// SPIM driver.
102pub struct Spim<'d, T: Instance> { 102pub struct Spim<'d, T: Instance> {
103 _p: PeripheralRef<'d, T>, 103 _p: Peri<'d, T>,
104} 104}
105 105
106impl<'d, T: Instance> Spim<'d, T> { 106impl<'d, T: Instance> Spim<'d, T> {
107 /// Create a new SPIM driver. 107 /// Create a new SPIM driver.
108 pub fn new( 108 pub fn new(
109 spim: impl Peripheral<P = T> + 'd, 109 spim: Peri<'d, T>,
110 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 110 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
111 sck: impl Peripheral<P = impl GpioPin> + 'd, 111 sck: Peri<'d, impl GpioPin>,
112 miso: impl Peripheral<P = impl GpioPin> + 'd, 112 miso: Peri<'d, impl GpioPin>,
113 mosi: impl Peripheral<P = impl GpioPin> + 'd, 113 mosi: Peri<'d, impl GpioPin>,
114 config: Config, 114 config: Config,
115 ) -> Self { 115 ) -> Self {
116 into_ref!(sck, miso, mosi); 116 Self::new_inner(spim, Some(sck.into()), Some(miso.into()), Some(mosi.into()), config)
117 Self::new_inner(
118 spim,
119 Some(sck.map_into()),
120 Some(miso.map_into()),
121 Some(mosi.map_into()),
122 config,
123 )
124 } 117 }
125 118
126 /// Create a new SPIM driver, capable of TX only (MOSI only). 119 /// Create a new SPIM driver, capable of TX only (MOSI only).
127 pub fn new_txonly( 120 pub fn new_txonly(
128 spim: impl Peripheral<P = T> + 'd, 121 spim: Peri<'d, T>,
129 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 122 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
130 sck: impl Peripheral<P = impl GpioPin> + 'd, 123 sck: Peri<'d, impl GpioPin>,
131 mosi: impl Peripheral<P = impl GpioPin> + 'd, 124 mosi: Peri<'d, impl GpioPin>,
132 config: Config, 125 config: Config,
133 ) -> Self { 126 ) -> Self {
134 into_ref!(sck, mosi); 127 Self::new_inner(spim, Some(sck.into()), None, Some(mosi.into()), config)
135 Self::new_inner(spim, Some(sck.map_into()), None, Some(mosi.map_into()), config)
136 } 128 }
137 129
138 /// Create a new SPIM driver, capable of RX only (MISO only). 130 /// Create a new SPIM driver, capable of RX only (MISO only).
139 pub fn new_rxonly( 131 pub fn new_rxonly(
140 spim: impl Peripheral<P = T> + 'd, 132 spim: Peri<'d, T>,
141 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 133 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
142 sck: impl Peripheral<P = impl GpioPin> + 'd, 134 sck: Peri<'d, impl GpioPin>,
143 miso: impl Peripheral<P = impl GpioPin> + 'd, 135 miso: Peri<'d, impl GpioPin>,
144 config: Config, 136 config: Config,
145 ) -> Self { 137 ) -> Self {
146 into_ref!(sck, miso); 138 Self::new_inner(spim, Some(sck.into()), Some(miso.into()), None, config)
147 Self::new_inner(spim, Some(sck.map_into()), Some(miso.map_into()), None, config)
148 } 139 }
149 140
150 /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin. 141 /// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin.
151 pub fn new_txonly_nosck( 142 pub fn new_txonly_nosck(
152 spim: impl Peripheral<P = T> + 'd, 143 spim: Peri<'d, T>,
153 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 144 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
154 mosi: impl Peripheral<P = impl GpioPin> + 'd, 145 mosi: Peri<'d, impl GpioPin>,
155 config: Config, 146 config: Config,
156 ) -> Self { 147 ) -> Self {
157 into_ref!(mosi); 148 Self::new_inner(spim, None, None, Some(mosi.into()), config)
158 Self::new_inner(spim, None, None, Some(mosi.map_into()), config)
159 } 149 }
160 150
161 fn new_inner( 151 fn new_inner(
162 spim: impl Peripheral<P = T> + 'd, 152 spim: Peri<'d, T>,
163 sck: Option<PeripheralRef<'d, AnyPin>>, 153 sck: Option<Peri<'d, AnyPin>>,
164 miso: Option<PeripheralRef<'d, AnyPin>>, 154 miso: Option<Peri<'d, AnyPin>>,
165 mosi: Option<PeripheralRef<'d, AnyPin>>, 155 mosi: Option<Peri<'d, AnyPin>>,
166 config: Config, 156 config: Config,
167 ) -> Self { 157 ) -> Self {
168 into_ref!(spim);
169
170 let r = T::regs(); 158 let r = T::regs();
171 159
172 // Configure pins 160 // Configure pins
@@ -511,7 +499,7 @@ pub(crate) trait SealedInstance {
511 499
512/// SPIM peripheral instance 500/// SPIM peripheral instance
513#[allow(private_bounds)] 501#[allow(private_bounds)]
514pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { 502pub trait Instance: SealedInstance + PeripheralType + 'static {
515 /// Interrupt for this peripheral. 503 /// Interrupt for this peripheral.
516 type Interrupt: interrupt::typelevel::Interrupt; 504 type Interrupt: interrupt::typelevel::Interrupt;
517} 505}
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs
index 88230fa26..2a3928d25 100644
--- a/embassy-nrf/src/spis.rs
+++ b/embassy-nrf/src/spis.rs
@@ -7,7 +7,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_embedded_hal::SetConfig; 9use embassy_embedded_hal::SetConfig;
10use embassy_hal_internal::{into_ref, PeripheralRef}; 10use embassy_hal_internal::{Peri, PeripheralType};
11use embassy_sync::waitqueue::AtomicWaker; 11use embassy_sync::waitqueue::AtomicWaker;
12pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 12pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
13pub use pac::spis::vals::Order as BitOrder; 13pub use pac::spis::vals::Order as BitOrder;
@@ -18,7 +18,7 @@ use crate::interrupt::typelevel::Interrupt;
18use crate::pac::gpio::vals as gpiovals; 18use crate::pac::gpio::vals as gpiovals;
19use crate::pac::spis::vals; 19use crate::pac::spis::vals;
20use crate::util::slice_in_ram_or; 20use crate::util::slice_in_ram_or;
21use crate::{interrupt, pac, Peripheral}; 21use crate::{interrupt, pac};
22 22
23/// SPIS error 23/// SPIS error
24#[derive(Debug, Clone, Copy, PartialEq, Eq)] 24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -98,95 +98,75 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
98 98
99/// SPIS driver. 99/// SPIS driver.
100pub struct Spis<'d, T: Instance> { 100pub struct Spis<'d, T: Instance> {
101 _p: PeripheralRef<'d, T>, 101 _p: Peri<'d, T>,
102} 102}
103 103
104impl<'d, T: Instance> Spis<'d, T> { 104impl<'d, T: Instance> Spis<'d, T> {
105 /// Create a new SPIS driver. 105 /// Create a new SPIS driver.
106 pub fn new( 106 pub fn new(
107 spis: impl Peripheral<P = T> + 'd, 107 spis: Peri<'d, T>,
108 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 108 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
109 cs: impl Peripheral<P = impl GpioPin> + 'd, 109 cs: Peri<'d, impl GpioPin>,
110 sck: impl Peripheral<P = impl GpioPin> + 'd, 110 sck: Peri<'d, impl GpioPin>,
111 miso: impl Peripheral<P = impl GpioPin> + 'd, 111 miso: Peri<'d, impl GpioPin>,
112 mosi: impl Peripheral<P = impl GpioPin> + 'd, 112 mosi: Peri<'d, impl GpioPin>,
113 config: Config, 113 config: Config,
114 ) -> Self { 114 ) -> Self {
115 into_ref!(cs, sck, miso, mosi);
116 Self::new_inner( 115 Self::new_inner(
117 spis, 116 spis,
118 cs.map_into(), 117 cs.into(),
119 Some(sck.map_into()), 118 Some(sck.into()),
120 Some(miso.map_into()), 119 Some(miso.into()),
121 Some(mosi.map_into()), 120 Some(mosi.into()),
122 config, 121 config,
123 ) 122 )
124 } 123 }
125 124
126 /// Create a new SPIS driver, capable of TX only (MISO only). 125 /// Create a new SPIS driver, capable of TX only (MISO only).
127 pub fn new_txonly( 126 pub fn new_txonly(
128 spis: impl Peripheral<P = T> + 'd, 127 spis: Peri<'d, T>,
129 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 128 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
130 cs: impl Peripheral<P = impl GpioPin> + 'd, 129 cs: Peri<'d, impl GpioPin>,
131 sck: impl Peripheral<P = impl GpioPin> + 'd, 130 sck: Peri<'d, impl GpioPin>,
132 miso: impl Peripheral<P = impl GpioPin> + 'd, 131 miso: Peri<'d, impl GpioPin>,
133 config: Config, 132 config: Config,
134 ) -> Self { 133 ) -> Self {
135 into_ref!(cs, sck, miso); 134 Self::new_inner(spis, cs.into(), Some(sck.into()), Some(miso.into()), None, config)
136 Self::new_inner(
137 spis,
138 cs.map_into(),
139 Some(sck.map_into()),
140 Some(miso.map_into()),
141 None,
142 config,
143 )
144 } 135 }
145 136
146 /// Create a new SPIS driver, capable of RX only (MOSI only). 137 /// Create a new SPIS driver, capable of RX only (MOSI only).
147 pub fn new_rxonly( 138 pub fn new_rxonly(
148 spis: impl Peripheral<P = T> + 'd, 139 spis: Peri<'d, T>,
149 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 140 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
150 cs: impl Peripheral<P = impl GpioPin> + 'd, 141 cs: Peri<'d, impl GpioPin>,
151 sck: impl Peripheral<P = impl GpioPin> + 'd, 142 sck: Peri<'d, impl GpioPin>,
152 mosi: impl Peripheral<P = impl GpioPin> + 'd, 143 mosi: Peri<'d, impl GpioPin>,
153 config: Config, 144 config: Config,
154 ) -> Self { 145 ) -> Self {
155 into_ref!(cs, sck, mosi); 146 Self::new_inner(spis, cs.into(), Some(sck.into()), None, Some(mosi.into()), config)
156 Self::new_inner(
157 spis,
158 cs.map_into(),
159 Some(sck.map_into()),
160 None,
161 Some(mosi.map_into()),
162 config,
163 )
164 } 147 }
165 148
166 /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. 149 /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin.
167 pub fn new_txonly_nosck( 150 pub fn new_txonly_nosck(
168 spis: impl Peripheral<P = T> + 'd, 151 spis: Peri<'d, T>,
169 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 152 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
170 cs: impl Peripheral<P = impl GpioPin> + 'd, 153 cs: Peri<'d, impl GpioPin>,
171 miso: impl Peripheral<P = impl GpioPin> + 'd, 154 miso: Peri<'d, impl GpioPin>,
172 config: Config, 155 config: Config,
173 ) -> Self { 156 ) -> Self {
174 into_ref!(cs, miso); 157 Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config)
175 Self::new_inner(spis, cs.map_into(), None, Some(miso.map_into()), None, config)
176 } 158 }
177 159
178 fn new_inner( 160 fn new_inner(
179 spis: impl Peripheral<P = T> + 'd, 161 spis: Peri<'d, T>,
180 cs: PeripheralRef<'d, AnyPin>, 162 cs: Peri<'d, AnyPin>,
181 sck: Option<PeripheralRef<'d, AnyPin>>, 163 sck: Option<Peri<'d, AnyPin>>,
182 miso: Option<PeripheralRef<'d, AnyPin>>, 164 miso: Option<Peri<'d, AnyPin>>,
183 mosi: Option<PeripheralRef<'d, AnyPin>>, 165 mosi: Option<Peri<'d, AnyPin>>,
184 config: Config, 166 config: Config,
185 ) -> Self { 167 ) -> Self {
186 compiler_fence(Ordering::SeqCst); 168 compiler_fence(Ordering::SeqCst);
187 169
188 into_ref!(spis, cs);
189
190 let r = T::regs(); 170 let r = T::regs();
191 171
192 // Configure pins. 172 // Configure pins.
@@ -485,7 +465,7 @@ pub(crate) trait SealedInstance {
485 465
486/// SPIS peripheral instance 466/// SPIS peripheral instance
487#[allow(private_bounds)] 467#[allow(private_bounds)]
488pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { 468pub trait Instance: SealedInstance + PeripheralType + 'static {
489 /// Interrupt for this peripheral. 469 /// Interrupt for this peripheral.
490 type Interrupt: interrupt::typelevel::Interrupt; 470 type Interrupt: interrupt::typelevel::Interrupt;
491} 471}
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
index 1488c5c24..44be0f6d1 100644
--- a/embassy-nrf/src/temp.rs
+++ b/embassy-nrf/src/temp.rs
@@ -4,13 +4,12 @@ use core::future::poll_fn;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::drop::OnDrop; 6use embassy_hal_internal::drop::OnDrop;
7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
9use fixed::types::I30F2; 8use fixed::types::I30F2;
10 9
11use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
12use crate::peripherals::TEMP; 11use crate::peripherals::TEMP;
13use crate::{interrupt, pac, Peripheral}; 12use crate::{interrupt, pac, Peri};
14 13
15/// Interrupt handler. 14/// Interrupt handler.
16pub struct InterruptHandler { 15pub struct InterruptHandler {
@@ -27,7 +26,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHand
27 26
28/// Builtin temperature sensor driver. 27/// Builtin temperature sensor driver.
29pub struct Temp<'d> { 28pub struct Temp<'d> {
30 _peri: PeripheralRef<'d, TEMP>, 29 _peri: Peri<'d, TEMP>,
31} 30}
32 31
33static WAKER: AtomicWaker = AtomicWaker::new(); 32static WAKER: AtomicWaker = AtomicWaker::new();
@@ -35,11 +34,9 @@ static WAKER: AtomicWaker = AtomicWaker::new();
35impl<'d> Temp<'d> { 34impl<'d> Temp<'d> {
36 /// Create a new temperature sensor driver. 35 /// Create a new temperature sensor driver.
37 pub fn new( 36 pub fn new(
38 _peri: impl Peripheral<P = TEMP> + 'd, 37 _peri: Peri<'d, TEMP>,
39 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd, 38 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd,
40 ) -> Self { 39 ) -> Self {
41 into_ref!(_peri);
42
43 // Enable interrupt that signals temperature values 40 // Enable interrupt that signals temperature values
44 interrupt::TEMP.unpend(); 41 interrupt::TEMP.unpend();
45 unsafe { interrupt::TEMP.enable() }; 42 unsafe { interrupt::TEMP.enable() };
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index a9aeb40fa..5b58b0a50 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -6,11 +6,11 @@
6 6
7#![macro_use] 7#![macro_use]
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{Peri, PeripheralType};
10 10
11use crate::pac;
11use crate::pac::timer::vals; 12use crate::pac::timer::vals;
12use crate::ppi::{Event, Task}; 13use crate::ppi::{Event, Task};
13use crate::{pac, Peripheral};
14 14
15pub(crate) trait SealedInstance { 15pub(crate) trait SealedInstance {
16 /// The number of CC registers this instance has. 16 /// The number of CC registers this instance has.
@@ -20,7 +20,7 @@ pub(crate) trait SealedInstance {
20 20
21/// Basic Timer instance. 21/// Basic Timer instance.
22#[allow(private_bounds)] 22#[allow(private_bounds)]
23pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 23pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
24 /// Interrupt for this peripheral. 24 /// Interrupt for this peripheral.
25 type Interrupt: crate::interrupt::typelevel::Interrupt; 25 type Interrupt: crate::interrupt::typelevel::Interrupt;
26} 26}
@@ -84,7 +84,7 @@ pub enum Frequency {
84 84
85/// Timer driver. 85/// Timer driver.
86pub struct Timer<'d, T: Instance> { 86pub struct Timer<'d, T: Instance> {
87 _p: PeripheralRef<'d, T>, 87 _p: Peri<'d, T>,
88} 88}
89 89
90impl<'d, T: Instance> Timer<'d, T> { 90impl<'d, T: Instance> Timer<'d, T> {
@@ -92,7 +92,7 @@ impl<'d, T: Instance> Timer<'d, T> {
92 /// 92 ///
93 /// This can be useful for triggering tasks via PPI 93 /// This can be useful for triggering tasks via PPI
94 /// `Uarte` uses this internally. 94 /// `Uarte` uses this internally.
95 pub fn new(timer: impl Peripheral<P = T> + 'd) -> Self { 95 pub fn new(timer: Peri<'d, T>) -> Self {
96 Self::new_inner(timer, false) 96 Self::new_inner(timer, false)
97 } 97 }
98 98
@@ -100,13 +100,11 @@ impl<'d, T: Instance> Timer<'d, T> {
100 /// 100 ///
101 /// This can be useful for triggering tasks via PPI 101 /// This can be useful for triggering tasks via PPI
102 /// `Uarte` uses this internally. 102 /// `Uarte` uses this internally.
103 pub fn new_counter(timer: impl Peripheral<P = T> + 'd) -> Self { 103 pub fn new_counter(timer: Peri<'d, T>) -> Self {
104 Self::new_inner(timer, true) 104 Self::new_inner(timer, true)
105 } 105 }
106 106
107 fn new_inner(timer: impl Peripheral<P = T> + 'd, _is_counter: bool) -> Self { 107 fn new_inner(timer: Peri<'d, T>, _is_counter: bool) -> Self {
108 into_ref!(timer);
109
110 let regs = T::regs(); 108 let regs = T::regs();
111 109
112 let this = Self { _p: timer }; 110 let this = Self { _p: timer };
@@ -229,7 +227,7 @@ impl<'d, T: Instance> Timer<'d, T> {
229/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register 227/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register
230pub struct Cc<'d, T: Instance> { 228pub struct Cc<'d, T: Instance> {
231 n: usize, 229 n: usize,
232 _p: PeripheralRef<'d, T>, 230 _p: Peri<'d, T>,
233} 231}
234 232
235impl<'d, T: Instance> Cc<'d, T> { 233impl<'d, T: Instance> Cc<'d, T> {
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index bfce00f1b..083b54b99 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -10,7 +10,7 @@ use core::sync::atomic::Ordering::SeqCst;
10use core::task::Poll; 10use core::task::Poll;
11 11
12use embassy_embedded_hal::SetConfig; 12use embassy_embedded_hal::SetConfig;
13use embassy_hal_internal::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{Peri, PeripheralType};
14use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
15#[cfg(feature = "time")] 15#[cfg(feature = "time")]
16use embassy_time::{Duration, Instant}; 16use embassy_time::{Duration, Instant};
@@ -23,7 +23,7 @@ use crate::interrupt::typelevel::Interrupt;
23use crate::pac::gpio::vals as gpiovals; 23use crate::pac::gpio::vals as gpiovals;
24use crate::pac::twim::vals; 24use crate::pac::twim::vals;
25use crate::util::slice_in_ram; 25use crate::util::slice_in_ram;
26use crate::{gpio, interrupt, pac, Peripheral}; 26use crate::{gpio, interrupt, pac};
27 27
28/// TWIM config. 28/// TWIM config.
29#[non_exhaustive] 29#[non_exhaustive]
@@ -114,20 +114,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
114 114
115/// TWI driver. 115/// TWI driver.
116pub struct Twim<'d, T: Instance> { 116pub struct Twim<'d, T: Instance> {
117 _p: PeripheralRef<'d, T>, 117 _p: Peri<'d, T>,
118} 118}
119 119
120impl<'d, T: Instance> Twim<'d, T> { 120impl<'d, T: Instance> Twim<'d, T> {
121 /// Create a new TWI driver. 121 /// Create a new TWI driver.
122 pub fn new( 122 pub fn new(
123 twim: impl Peripheral<P = T> + 'd, 123 twim: Peri<'d, T>,
124 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 124 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
125 sda: impl Peripheral<P = impl GpioPin> + 'd, 125 sda: Peri<'d, impl GpioPin>,
126 scl: impl Peripheral<P = impl GpioPin> + 'd, 126 scl: Peri<'d, impl GpioPin>,
127 config: Config, 127 config: Config,
128 ) -> Self { 128 ) -> Self {
129 into_ref!(twim, sda, scl);
130
131 let r = T::regs(); 129 let r = T::regs();
132 130
133 // Configure pins 131 // Configure pins
@@ -847,7 +845,7 @@ pub(crate) trait SealedInstance {
847 845
848/// TWIM peripheral instance. 846/// TWIM peripheral instance.
849#[allow(private_bounds)] 847#[allow(private_bounds)]
850pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { 848pub trait Instance: SealedInstance + PeripheralType + 'static {
851 /// Interrupt for this peripheral. 849 /// Interrupt for this peripheral.
852 type Interrupt: interrupt::typelevel::Interrupt; 850 type Interrupt: interrupt::typelevel::Interrupt;
853} 851}
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs
index 60de2ed9d..3e4d537ae 100644
--- a/embassy-nrf/src/twis.rs
+++ b/embassy-nrf/src/twis.rs
@@ -8,7 +8,7 @@ use core::sync::atomic::compiler_fence;
8use core::sync::atomic::Ordering::SeqCst; 8use core::sync::atomic::Ordering::SeqCst;
9use core::task::Poll; 9use core::task::Poll;
10 10
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13#[cfg(feature = "time")] 13#[cfg(feature = "time")]
14use embassy_time::{Duration, Instant}; 14use embassy_time::{Duration, Instant};
@@ -19,7 +19,7 @@ use crate::interrupt::typelevel::Interrupt;
19use crate::pac::gpio::vals as gpiovals; 19use crate::pac::gpio::vals as gpiovals;
20use crate::pac::twis::vals; 20use crate::pac::twis::vals;
21use crate::util::slice_in_ram_or; 21use crate::util::slice_in_ram_or;
22use crate::{gpio, interrupt, pac, Peripheral}; 22use crate::{gpio, interrupt, pac};
23 23
24/// TWIS config. 24/// TWIS config.
25#[non_exhaustive] 25#[non_exhaustive]
@@ -141,20 +141,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
141 141
142/// TWIS driver. 142/// TWIS driver.
143pub struct Twis<'d, T: Instance> { 143pub struct Twis<'d, T: Instance> {
144 _p: PeripheralRef<'d, T>, 144 _p: Peri<'d, T>,
145} 145}
146 146
147impl<'d, T: Instance> Twis<'d, T> { 147impl<'d, T: Instance> Twis<'d, T> {
148 /// Create a new TWIS driver. 148 /// Create a new TWIS driver.
149 pub fn new( 149 pub fn new(
150 twis: impl Peripheral<P = T> + 'd, 150 twis: Peri<'d, T>,
151 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 151 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
152 sda: impl Peripheral<P = impl GpioPin> + 'd, 152 sda: Peri<'d, impl GpioPin>,
153 scl: impl Peripheral<P = impl GpioPin> + 'd, 153 scl: Peri<'d, impl GpioPin>,
154 config: Config, 154 config: Config,
155 ) -> Self { 155 ) -> Self {
156 into_ref!(twis, sda, scl);
157
158 let r = T::regs(); 156 let r = T::regs();
159 157
160 // Configure pins 158 // Configure pins
@@ -791,7 +789,7 @@ pub(crate) trait SealedInstance {
791 789
792/// TWIS peripheral instance. 790/// TWIS peripheral instance.
793#[allow(private_bounds)] 791#[allow(private_bounds)]
794pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { 792pub trait Instance: SealedInstance + PeripheralType + 'static {
795 /// Interrupt for this peripheral. 793 /// Interrupt for this peripheral.
796 type Interrupt: interrupt::typelevel::Interrupt; 794 type Interrupt: interrupt::typelevel::Interrupt;
797} 795}
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index ebb4dd941..b44edfe84 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -19,7 +19,7 @@ use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
19use core::task::Poll; 19use core::task::Poll;
20 20
21use embassy_hal_internal::drop::OnDrop; 21use embassy_hal_internal::drop::OnDrop;
22use embassy_hal_internal::{into_ref, PeripheralRef}; 22use embassy_hal_internal::{Peri, PeripheralType};
23use embassy_sync::waitqueue::AtomicWaker; 23use embassy_sync::waitqueue::AtomicWaker;
24// Re-export SVD variants to allow user to directly set values. 24// Re-export SVD variants to allow user to directly set values.
25pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; 25pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity};
@@ -32,7 +32,7 @@ use crate::pac::uarte::vals;
32use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 32use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
33use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 33use crate::timer::{Frequency, Instance as TimerInstance, Timer};
34use crate::util::slice_in_ram_or; 34use crate::util::slice_in_ram_or;
35use crate::{interrupt, pac, Peripheral}; 35use crate::{interrupt, pac};
36 36
37/// UARTE config. 37/// UARTE config.
38#[derive(Clone)] 38#[derive(Clone)]
@@ -141,56 +141,54 @@ pub struct Uarte<'d, T: Instance> {
141/// 141///
142/// This can be obtained via [`Uarte::split`], or created directly. 142/// This can be obtained via [`Uarte::split`], or created directly.
143pub struct UarteTx<'d, T: Instance> { 143pub struct UarteTx<'d, T: Instance> {
144 _p: PeripheralRef<'d, T>, 144 _p: Peri<'d, T>,
145} 145}
146 146
147/// Receiver part of the UARTE driver. 147/// Receiver part of the UARTE driver.
148/// 148///
149/// This can be obtained via [`Uarte::split`], or created directly. 149/// This can be obtained via [`Uarte::split`], or created directly.
150pub struct UarteRx<'d, T: Instance> { 150pub struct UarteRx<'d, T: Instance> {
151 _p: PeripheralRef<'d, T>, 151 _p: Peri<'d, T>,
152} 152}
153 153
154impl<'d, T: Instance> Uarte<'d, T> { 154impl<'d, T: Instance> Uarte<'d, T> {
155 /// Create a new UARTE without hardware flow control 155 /// Create a new UARTE without hardware flow control
156 pub fn new( 156 pub fn new(
157 uarte: impl Peripheral<P = T> + 'd, 157 uarte: Peri<'d, T>,
158 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 158 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
159 rxd: impl Peripheral<P = impl GpioPin> + 'd, 159 rxd: Peri<'d, impl GpioPin>,
160 txd: impl Peripheral<P = impl GpioPin> + 'd, 160 txd: Peri<'d, impl GpioPin>,
161 config: Config, 161 config: Config,
162 ) -> Self { 162 ) -> Self {
163 into_ref!(uarte, rxd, txd); 163 Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config)
164 Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
165 } 164 }
166 165
167 /// Create a new UARTE with hardware flow control (RTS/CTS) 166 /// Create a new UARTE with hardware flow control (RTS/CTS)
168 pub fn new_with_rtscts( 167 pub fn new_with_rtscts(
169 uarte: impl Peripheral<P = T> + 'd, 168 uarte: Peri<'d, T>,
170 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 169 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
171 rxd: impl Peripheral<P = impl GpioPin> + 'd, 170 rxd: Peri<'d, impl GpioPin>,
172 txd: impl Peripheral<P = impl GpioPin> + 'd, 171 txd: Peri<'d, impl GpioPin>,
173 cts: impl Peripheral<P = impl GpioPin> + 'd, 172 cts: Peri<'d, impl GpioPin>,
174 rts: impl Peripheral<P = impl GpioPin> + 'd, 173 rts: Peri<'d, impl GpioPin>,
175 config: Config, 174 config: Config,
176 ) -> Self { 175 ) -> Self {
177 into_ref!(uarte, rxd, txd, cts, rts);
178 Self::new_inner( 176 Self::new_inner(
179 uarte, 177 uarte,
180 rxd.map_into(), 178 rxd.into(),
181 txd.map_into(), 179 txd.into(),
182 Some(cts.map_into()), 180 Some(cts.into()),
183 Some(rts.map_into()), 181 Some(rts.into()),
184 config, 182 config,
185 ) 183 )
186 } 184 }
187 185
188 fn new_inner( 186 fn new_inner(
189 uarte: PeripheralRef<'d, T>, 187 uarte: Peri<'d, T>,
190 rxd: PeripheralRef<'d, AnyPin>, 188 rxd: Peri<'d, AnyPin>,
191 txd: PeripheralRef<'d, AnyPin>, 189 txd: Peri<'d, AnyPin>,
192 cts: Option<PeripheralRef<'d, AnyPin>>, 190 cts: Option<Peri<'d, AnyPin>>,
193 rts: Option<PeripheralRef<'d, AnyPin>>, 191 rts: Option<Peri<'d, AnyPin>>,
194 config: Config, 192 config: Config,
195 ) -> Self { 193 ) -> Self {
196 let r = T::regs(); 194 let r = T::regs();
@@ -239,9 +237,9 @@ impl<'d, T: Instance> Uarte<'d, T> {
239 /// This is useful to concurrently transmit and receive from independent tasks. 237 /// This is useful to concurrently transmit and receive from independent tasks.
240 pub fn split_with_idle<U: TimerInstance>( 238 pub fn split_with_idle<U: TimerInstance>(
241 self, 239 self,
242 timer: impl Peripheral<P = U> + 'd, 240 timer: Peri<'d, U>,
243 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, 241 ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
244 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, 242 ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
245 ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) { 243 ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) {
246 (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2)) 244 (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2))
247 } 245 }
@@ -283,11 +281,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
283 } 281 }
284} 282}
285 283
286pub(crate) fn configure_tx_pins( 284pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts: Option<Peri<'_, AnyPin>>) {
287 r: pac::uarte::Uarte,
288 txd: PeripheralRef<'_, AnyPin>,
289 cts: Option<PeripheralRef<'_, AnyPin>>,
290) {
291 txd.set_high(); 285 txd.set_high();
292 txd.conf().write(|w| { 286 txd.conf().write(|w| {
293 w.set_dir(gpiovals::Dir::OUTPUT); 287 w.set_dir(gpiovals::Dir::OUTPUT);
@@ -306,11 +300,7 @@ pub(crate) fn configure_tx_pins(
306 r.psel().cts().write_value(cts.psel_bits()); 300 r.psel().cts().write_value(cts.psel_bits());
307} 301}
308 302
309pub(crate) fn configure_rx_pins( 303pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts: Option<Peri<'_, AnyPin>>) {
310 r: pac::uarte::Uarte,
311 rxd: PeripheralRef<'_, AnyPin>,
312 rts: Option<PeripheralRef<'_, AnyPin>>,
313) {
314 rxd.conf().write(|w| { 304 rxd.conf().write(|w| {
315 w.set_dir(gpiovals::Dir::INPUT); 305 w.set_dir(gpiovals::Dir::INPUT);
316 w.set_input(gpiovals::Input::CONNECT); 306 w.set_input(gpiovals::Input::CONNECT);
@@ -356,33 +346,26 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont
356impl<'d, T: Instance> UarteTx<'d, T> { 346impl<'d, T: Instance> UarteTx<'d, T> {
357 /// Create a new tx-only UARTE without hardware flow control 347 /// Create a new tx-only UARTE without hardware flow control
358 pub fn new( 348 pub fn new(
359 uarte: impl Peripheral<P = T> + 'd, 349 uarte: Peri<'d, T>,
360 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 350 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
361 txd: impl Peripheral<P = impl GpioPin> + 'd, 351 txd: Peri<'d, impl GpioPin>,
362 config: Config, 352 config: Config,
363 ) -> Self { 353 ) -> Self {
364 into_ref!(uarte, txd); 354 Self::new_inner(uarte, txd.into(), None, config)
365 Self::new_inner(uarte, txd.map_into(), None, config)
366 } 355 }
367 356
368 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) 357 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
369 pub fn new_with_rtscts( 358 pub fn new_with_rtscts(
370 uarte: impl Peripheral<P = T> + 'd, 359 uarte: Peri<'d, T>,
371 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 360 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
372 txd: impl Peripheral<P = impl GpioPin> + 'd, 361 txd: Peri<'d, impl GpioPin>,
373 cts: impl Peripheral<P = impl GpioPin> + 'd, 362 cts: Peri<'d, impl GpioPin>,
374 config: Config, 363 config: Config,
375 ) -> Self { 364 ) -> Self {
376 into_ref!(uarte, txd, cts); 365 Self::new_inner(uarte, txd.into(), Some(cts.into()), config)
377 Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
378 } 366 }
379 367
380 fn new_inner( 368 fn new_inner(uarte: Peri<'d, T>, txd: Peri<'d, AnyPin>, cts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
381 uarte: PeripheralRef<'d, T>,
382 txd: PeripheralRef<'d, AnyPin>,
383 cts: Option<PeripheralRef<'d, AnyPin>>,
384 config: Config,
385 ) -> Self {
386 let r = T::regs(); 369 let r = T::regs();
387 370
388 configure(r, config, cts.is_some()); 371 configure(r, config, cts.is_some());
@@ -539,25 +522,23 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> {
539impl<'d, T: Instance> UarteRx<'d, T> { 522impl<'d, T: Instance> UarteRx<'d, T> {
540 /// Create a new rx-only UARTE without hardware flow control 523 /// Create a new rx-only UARTE without hardware flow control
541 pub fn new( 524 pub fn new(
542 uarte: impl Peripheral<P = T> + 'd, 525 uarte: Peri<'d, T>,
543 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 526 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
544 rxd: impl Peripheral<P = impl GpioPin> + 'd, 527 rxd: Peri<'d, impl GpioPin>,
545 config: Config, 528 config: Config,
546 ) -> Self { 529 ) -> Self {
547 into_ref!(uarte, rxd); 530 Self::new_inner(uarte, rxd.into(), None, config)
548 Self::new_inner(uarte, rxd.map_into(), None, config)
549 } 531 }
550 532
551 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) 533 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
552 pub fn new_with_rtscts( 534 pub fn new_with_rtscts(
553 uarte: impl Peripheral<P = T> + 'd, 535 uarte: Peri<'d, T>,
554 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 536 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
555 rxd: impl Peripheral<P = impl GpioPin> + 'd, 537 rxd: Peri<'d, impl GpioPin>,
556 rts: impl Peripheral<P = impl GpioPin> + 'd, 538 rts: Peri<'d, impl GpioPin>,
557 config: Config, 539 config: Config,
558 ) -> Self { 540 ) -> Self {
559 into_ref!(uarte, rxd, rts); 541 Self::new_inner(uarte, rxd.into(), Some(rts.into()), config)
560 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
561 } 542 }
562 543
563 /// Check for errors and clear the error register if an error occured. 544 /// Check for errors and clear the error register if an error occured.
@@ -568,12 +549,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
568 ErrorSource::from_bits_truncate(err_bits.0).check() 549 ErrorSource::from_bits_truncate(err_bits.0).check()
569 } 550 }
570 551
571 fn new_inner( 552 fn new_inner(uarte: Peri<'d, T>, rxd: Peri<'d, AnyPin>, rts: Option<Peri<'d, AnyPin>>, config: Config) -> Self {
572 uarte: PeripheralRef<'d, T>,
573 rxd: PeripheralRef<'d, AnyPin>,
574 rts: Option<PeripheralRef<'d, AnyPin>>,
575 config: Config,
576 ) -> Self {
577 let r = T::regs(); 553 let r = T::regs();
578 554
579 configure(r, config, rts.is_some()); 555 configure(r, config, rts.is_some());
@@ -592,14 +568,12 @@ impl<'d, T: Instance> UarteRx<'d, T> {
592 /// Upgrade to an instance that supports idle line detection. 568 /// Upgrade to an instance that supports idle line detection.
593 pub fn with_idle<U: TimerInstance>( 569 pub fn with_idle<U: TimerInstance>(
594 self, 570 self,
595 timer: impl Peripheral<P = U> + 'd, 571 timer: Peri<'d, U>,
596 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, 572 ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>,
597 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, 573 ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>,
598 ) -> UarteRxWithIdle<'d, T, U> { 574 ) -> UarteRxWithIdle<'d, T, U> {
599 let timer = Timer::new(timer); 575 let timer = Timer::new(timer);
600 576
601 into_ref!(ppi_ch1, ppi_ch2);
602
603 let r = T::regs(); 577 let r = T::regs();
604 578
605 // BAUDRATE register values are `baudrate * 2^32 / 16000000` 579 // BAUDRATE register values are `baudrate * 2^32 / 16000000`
@@ -617,7 +591,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
617 timer.cc(0).short_compare_stop(); 591 timer.cc(0).short_compare_stop();
618 592
619 let mut ppi_ch1 = Ppi::new_one_to_two( 593 let mut ppi_ch1 = Ppi::new_one_to_two(
620 ppi_ch1.map_into(), 594 ppi_ch1.into(),
621 Event::from_reg(r.events_rxdrdy()), 595 Event::from_reg(r.events_rxdrdy()),
622 timer.task_clear(), 596 timer.task_clear(),
623 timer.task_start(), 597 timer.task_start(),
@@ -625,7 +599,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
625 ppi_ch1.enable(); 599 ppi_ch1.enable();
626 600
627 let mut ppi_ch2 = Ppi::new_one_to_one( 601 let mut ppi_ch2 = Ppi::new_one_to_one(
628 ppi_ch2.map_into(), 602 ppi_ch2.into(),
629 timer.cc(0).event_compare(), 603 timer.cc(0).event_compare(),
630 Task::from_reg(r.tasks_stoprx()), 604 Task::from_reg(r.tasks_stoprx()),
631 ); 605 );
@@ -992,7 +966,7 @@ pub(crate) trait SealedInstance {
992 966
993/// UARTE peripheral instance. 967/// UARTE peripheral instance.
994#[allow(private_bounds)] 968#[allow(private_bounds)]
995pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 969pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
996 /// Interrupt for this peripheral. 970 /// Interrupt for this peripheral.
997 type Interrupt: interrupt::typelevel::Interrupt; 971 type Interrupt: interrupt::typelevel::Interrupt;
998} 972}
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs
index 06dae694b..6cc1b0111 100644
--- a/embassy-nrf/src/usb/mod.rs
+++ b/embassy-nrf/src/usb/mod.rs
@@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
11use core::task::Poll; 11use core::task::Poll;
12 12
13use cortex_m::peripheral::NVIC; 13use cortex_m::peripheral::NVIC;
14use embassy_hal_internal::{into_ref, PeripheralRef}; 14use embassy_hal_internal::{Peri, PeripheralType};
15use embassy_sync::waitqueue::AtomicWaker; 15use embassy_sync::waitqueue::AtomicWaker;
16use embassy_usb_driver as driver; 16use embassy_usb_driver as driver;
17use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; 17use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported};
@@ -20,7 +20,7 @@ use self::vbus_detect::VbusDetect;
20use crate::interrupt::typelevel::Interrupt; 20use crate::interrupt::typelevel::Interrupt;
21use crate::pac::usbd::vals; 21use crate::pac::usbd::vals;
22use crate::util::slice_in_ram; 22use crate::util::slice_in_ram;
23use crate::{interrupt, pac, Peripheral}; 23use crate::{interrupt, pac};
24 24
25static BUS_WAKER: AtomicWaker = AtomicWaker::new(); 25static BUS_WAKER: AtomicWaker = AtomicWaker::new();
26static EP0_WAKER: AtomicWaker = AtomicWaker::new(); 26static EP0_WAKER: AtomicWaker = AtomicWaker::new();
@@ -87,7 +87,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
87 87
88/// USB driver. 88/// USB driver.
89pub struct Driver<'d, T: Instance, V: VbusDetect> { 89pub struct Driver<'d, T: Instance, V: VbusDetect> {
90 _p: PeripheralRef<'d, T>, 90 _p: Peri<'d, T>,
91 alloc_in: Allocator, 91 alloc_in: Allocator,
92 alloc_out: Allocator, 92 alloc_out: Allocator,
93 vbus_detect: V, 93 vbus_detect: V,
@@ -96,12 +96,10 @@ pub struct Driver<'d, T: Instance, V: VbusDetect> {
96impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { 96impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> {
97 /// Create a new USB driver. 97 /// Create a new USB driver.
98 pub fn new( 98 pub fn new(
99 usb: impl Peripheral<P = T> + 'd, 99 usb: Peri<'d, T>,
100 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 100 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
101 vbus_detect: V, 101 vbus_detect: V,
102 ) -> Self { 102 ) -> Self {
103 into_ref!(usb);
104
105 T::Interrupt::unpend(); 103 T::Interrupt::unpend();
106 unsafe { T::Interrupt::enable() }; 104 unsafe { T::Interrupt::enable() };
107 105
@@ -169,7 +167,7 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V
169 167
170/// USB bus. 168/// USB bus.
171pub struct Bus<'d, T: Instance, V: VbusDetect> { 169pub struct Bus<'d, T: Instance, V: VbusDetect> {
172 _p: PeripheralRef<'d, T>, 170 _p: Peri<'d, T>,
173 power_available: bool, 171 power_available: bool,
174 vbus_detect: V, 172 vbus_detect: V,
175} 173}
@@ -592,7 +590,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
592 590
593/// USB control pipe. 591/// USB control pipe.
594pub struct ControlPipe<'d, T: Instance> { 592pub struct ControlPipe<'d, T: Instance> {
595 _p: PeripheralRef<'d, T>, 593 _p: Peri<'d, T>,
596 max_packet_size: u16, 594 max_packet_size: u16,
597} 595}
598 596
@@ -779,7 +777,7 @@ pub(crate) trait SealedInstance {
779 777
780/// USB peripheral instance. 778/// USB peripheral instance.
781#[allow(private_bounds)] 779#[allow(private_bounds)]
782pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 780pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
783 /// Interrupt for this peripheral. 781 /// Interrupt for this peripheral.
784 type Interrupt: interrupt::typelevel::Interrupt; 782 type Interrupt: interrupt::typelevel::Interrupt;
785} 783}
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs
index f7812258c..11cfa398e 100644
--- a/embassy-nrf/src/wdt.rs
+++ b/embassy-nrf/src/wdt.rs
@@ -3,9 +3,11 @@
3//! This HAL implements a basic watchdog timer with 1..=8 handles. 3//! This HAL implements a basic watchdog timer with 1..=8 handles.
4//! Once the watchdog has been started, it cannot be stopped. 4//! Once the watchdog has been started, it cannot be stopped.
5 5
6use core::marker::PhantomData;
7
6use crate::pac::wdt::vals; 8use crate::pac::wdt::vals;
7pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; 9pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
8use crate::peripherals; 10use crate::{peripherals, Peri};
9 11
10const MIN_TICKS: u32 = 15; 12const MIN_TICKS: u32 = 15;
11 13
@@ -61,7 +63,7 @@ impl Default for Config {
61 63
62/// Watchdog driver. 64/// Watchdog driver.
63pub struct Watchdog { 65pub struct Watchdog {
64 _private: (), 66 _wdt: Peri<'static, peripherals::WDT>,
65} 67}
66 68
67impl Watchdog { 69impl Watchdog {
@@ -74,9 +76,9 @@ impl Watchdog {
74 /// `N` must be between 1 and 8, inclusive. 76 /// `N` must be between 1 and 8, inclusive.
75 #[inline] 77 #[inline]
76 pub fn try_new<const N: usize>( 78 pub fn try_new<const N: usize>(
77 wdt: peripherals::WDT, 79 wdt: Peri<'static, peripherals::WDT>,
78 config: Config, 80 config: Config,
79 ) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> { 81 ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> {
80 assert!(N >= 1 && N <= 8); 82 assert!(N >= 1 && N <= 8);
81 83
82 let r = crate::pac::WDT; 84 let r = crate::pac::WDT;
@@ -110,11 +112,19 @@ impl Watchdog {
110 r.tasks_start().write_value(1); 112 r.tasks_start().write_value(1);
111 } 113 }
112 114
113 let this = Self { _private: () }; 115 let this = Self { _wdt: wdt };
114 116
115 let mut handles = [const { WatchdogHandle { index: 0 } }; N]; 117 let mut handles = [const {
118 WatchdogHandle {
119 _wdt: PhantomData,
120 index: 0,
121 }
122 }; N];
116 for i in 0..N { 123 for i in 0..N {
117 handles[i] = WatchdogHandle { index: i as u8 }; 124 handles[i] = WatchdogHandle {
125 _wdt: PhantomData,
126 index: i as u8,
127 };
118 handles[i].pet(); 128 handles[i].pet();
119 } 129 }
120 130
@@ -155,6 +165,7 @@ impl Watchdog {
155 165
156/// Watchdog handle. 166/// Watchdog handle.
157pub struct WatchdogHandle { 167pub struct WatchdogHandle {
168 _wdt: PhantomData<Peri<'static, peripherals::WDT>>,
158 index: u8, 169 index: u8,
159} 170}
160 171
@@ -183,6 +194,9 @@ impl WatchdogHandle {
183 /// Watchdog must be initialized and `index` must be between `0` and `N-1` 194 /// Watchdog must be initialized and `index` must be between `0` and `N-1`
184 /// where `N` is the handle count when initializing. 195 /// where `N` is the handle count when initializing.
185 pub unsafe fn steal(index: u8) -> Self { 196 pub unsafe fn steal(index: u8) -> Self {
186 Self { index } 197 Self {
198 _wdt: PhantomData,
199 index,
200 }
187 } 201 }
188} 202}
diff --git a/embassy-nxp/src/gpio.rs b/embassy-nxp/src/gpio.rs
index d5d04ee69..c7c78ce61 100644
--- a/embassy-nxp/src/gpio.rs
+++ b/embassy-nxp/src/gpio.rs
@@ -1,7 +1,7 @@
1use embassy_hal_internal::impl_peripheral; 1use embassy_hal_internal::{impl_peripheral, PeripheralType};
2 2
3use crate::pac_utils::*; 3use crate::pac_utils::*;
4use crate::{peripherals, Peripheral, PeripheralRef}; 4use crate::{peripherals, Peri};
5 5
6pub(crate) fn init() { 6pub(crate) fn init() {
7 // Enable clocks for GPIO, PINT, and IOCON 7 // Enable clocks for GPIO, PINT, and IOCON
@@ -45,7 +45,7 @@ pub struct Output<'d> {
45impl<'d> Output<'d> { 45impl<'d> Output<'d> {
46 /// Create GPIO output driver for a [Pin] with the provided [initial output](Level). 46 /// Create GPIO output driver for a [Pin] with the provided [initial output](Level).
47 #[inline] 47 #[inline]
48 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { 48 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
49 let mut pin = Flex::new(pin); 49 let mut pin = Flex::new(pin);
50 pin.set_as_output(); 50 pin.set_as_output();
51 let mut result = Self { pin }; 51 let mut result = Self { pin };
@@ -90,7 +90,7 @@ pub struct Input<'d> {
90impl<'d> Input<'d> { 90impl<'d> Input<'d> {
91 /// Create GPIO output driver for a [Pin] with the provided [Pull]. 91 /// Create GPIO output driver for a [Pin] with the provided [Pull].
92 #[inline] 92 #[inline]
93 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { 93 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
94 let mut pin = Flex::new(pin); 94 let mut pin = Flex::new(pin);
95 pin.set_as_input(); 95 pin.set_as_input();
96 let mut result = Self { pin }; 96 let mut result = Self { pin };
@@ -124,7 +124,7 @@ impl<'d> Input<'d> {
124/// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a 124/// A flexible GPIO (digital mode) pin whose mode is not yet determined. Under the hood, this is a
125/// reference to a type-erased pin called ["AnyPin"](AnyPin). 125/// reference to a type-erased pin called ["AnyPin"](AnyPin).
126pub struct Flex<'d> { 126pub struct Flex<'d> {
127 pub(crate) pin: PeripheralRef<'d, AnyPin>, 127 pub(crate) pin: Peri<'d, AnyPin>,
128} 128}
129 129
130impl<'d> Flex<'d> { 130impl<'d> Flex<'d> {
@@ -132,10 +132,8 @@ impl<'d> Flex<'d> {
132 /// 132 ///
133 /// Note: you cannot assume that the pin will be in Digital mode after this call. 133 /// Note: you cannot assume that the pin will be in Digital mode after this call.
134 #[inline] 134 #[inline]
135 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { 135 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
136 Self { 136 Self { pin: pin.into() }
137 pin: pin.into_ref().map_into(),
138 }
139 } 137 }
140 138
141 /// Get the bank of this pin. See also [Bank]. 139 /// Get the bank of this pin. See also [Bank].
@@ -218,15 +216,7 @@ pub(crate) trait SealedPin: Sized {
218/// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the 216/// [AnyPin]. By default, this trait is sealed and cannot be implemented outside of the
219/// `embassy-nxp` crate due to the [SealedPin] trait. 217/// `embassy-nxp` crate due to the [SealedPin] trait.
220#[allow(private_bounds)] 218#[allow(private_bounds)]
221pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { 219pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
222 /// Degrade to a generic pin struct
223 fn degrade(self) -> AnyPin {
224 AnyPin {
225 pin_bank: self.pin_bank(),
226 pin_number: self.pin_number(),
227 }
228 }
229
230 /// Returns the pin number within a bank 220 /// Returns the pin number within a bank
231 #[inline] 221 #[inline]
232 fn pin(&self) -> u8 { 222 fn pin(&self) -> u8 {
@@ -252,8 +242,8 @@ impl AnyPin {
252 /// # Safety 242 /// # Safety
253 /// 243 ///
254 /// You must ensure that you’re only using one instance of this type at a time. 244 /// You must ensure that you’re only using one instance of this type at a time.
255 pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Self { 245 pub unsafe fn steal(pin_bank: Bank, pin_number: u8) -> Peri<'static, Self> {
256 Self { pin_bank, pin_number } 246 Peri::new_unchecked(Self { pin_bank, pin_number })
257 } 247 }
258} 248}
259 249
@@ -289,7 +279,10 @@ macro_rules! impl_pin {
289 279
290 impl From<peripherals::$name> for crate::gpio::AnyPin { 280 impl From<peripherals::$name> for crate::gpio::AnyPin {
291 fn from(val: peripherals::$name) -> Self { 281 fn from(val: peripherals::$name) -> Self {
292 crate::gpio::Pin::degrade(val) 282 Self {
283 pin_bank: val.pin_bank(),
284 pin_number: val.pin_number(),
285 }
293 } 286 }
294 } 287 }
295 }; 288 };
diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs
index 80fdecb2e..ad2056c06 100644
--- a/embassy-nxp/src/lib.rs
+++ b/embassy-nxp/src/lib.rs
@@ -4,7 +4,7 @@ pub mod gpio;
4mod pac_utils; 4mod pac_utils;
5pub mod pint; 5pub mod pint;
6 6
7pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 7pub use embassy_hal_internal::Peri;
8pub use lpc55_pac as pac; 8pub use lpc55_pac as pac;
9 9
10/// Initialize the `embassy-nxp` HAL with the provided configuration. 10/// Initialize the `embassy-nxp` HAL with the provided configuration.
diff --git a/embassy-nxp/src/pint.rs b/embassy-nxp/src/pint.rs
index 809be4bff..8d6dc1277 100644
--- a/embassy-nxp/src/pint.rs
+++ b/embassy-nxp/src/pint.rs
@@ -5,12 +5,12 @@ use core::pin::Pin as FuturePin;
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use critical_section::Mutex; 7use critical_section::Mutex;
8use embassy_hal_internal::{Peripheral, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
10 9
11use crate::gpio::{self, AnyPin, Level, SealedPin}; 10use crate::gpio::{self, AnyPin, Level, SealedPin};
12use crate::pac::interrupt; 11use crate::pac::interrupt;
13use crate::pac_utils::*; 12use crate::pac_utils::*;
13use crate::Peri;
14 14
15struct PinInterrupt { 15struct PinInterrupt {
16 assigned: bool, 16 assigned: bool,
@@ -107,14 +107,14 @@ pub(crate) fn init() {
107#[must_use = "futures do nothing unless you `.await` or poll them"] 107#[must_use = "futures do nothing unless you `.await` or poll them"]
108struct InputFuture<'d> { 108struct InputFuture<'d> {
109 #[allow(dead_code)] 109 #[allow(dead_code)]
110 pin: PeripheralRef<'d, AnyPin>, 110 pin: Peri<'d, AnyPin>,
111 interrupt_number: usize, 111 interrupt_number: usize,
112} 112}
113 113
114impl<'d> InputFuture<'d> { 114impl<'d> InputFuture<'d> {
115 /// Create a new input future. Returns None if all interrupts are in use. 115 /// Create a new input future. Returns None if all interrupts are in use.
116 fn new(pin: impl Peripheral<P = impl gpio::Pin> + 'd, interrupt_on: InterruptOn) -> Option<Self> { 116 fn new(pin: Peri<'d, impl gpio::Pin>, interrupt_on: InterruptOn) -> Option<Self> {
117 let pin = pin.into_ref().map_into(); 117 let pin = pin.into();
118 let interrupt_number = next_available_interrupt()?; 118 let interrupt_number = next_available_interrupt()?;
119 119
120 // Clear interrupt, just in case 120 // Clear interrupt, just in case
@@ -344,35 +344,35 @@ impl gpio::Flex<'_> {
344 /// Wait for a falling or rising edge on the pin. You can have at most 8 pins waiting. If you 344 /// Wait for a falling or rising edge on the pin. You can have at most 8 pins waiting. If you
345 /// try to wait for more than 8 pins, this function will return `None`. 345 /// try to wait for more than 8 pins, this function will return `None`.
346 pub async fn wait_for_any_edge(&mut self) -> Option<()> { 346 pub async fn wait_for_any_edge(&mut self) -> Option<()> {
347 InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Both))?.await; 347 InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Both))?.await;
348 Some(()) 348 Some(())
349 } 349 }
350 350
351 /// Wait for a falling edge on the pin. You can have at most 8 pins waiting. If you try to wait 351 /// Wait for a falling edge on the pin. You can have at most 8 pins waiting. If you try to wait
352 /// for more than 8 pins, this function will return `None`. 352 /// for more than 8 pins, this function will return `None`.
353 pub async fn wait_for_falling_edge(&mut self) -> Option<()> { 353 pub async fn wait_for_falling_edge(&mut self) -> Option<()> {
354 InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Falling))?.await; 354 InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Falling))?.await;
355 Some(()) 355 Some(())
356 } 356 }
357 357
358 /// Wait for a rising edge on the pin. You can have at most 8 pins waiting. If you try to wait 358 /// Wait for a rising edge on the pin. You can have at most 8 pins waiting. If you try to wait
359 /// for more than 8 pins, this function will return `None`. 359 /// for more than 8 pins, this function will return `None`.
360 pub async fn wait_for_rising_edge(&mut self) -> Option<()> { 360 pub async fn wait_for_rising_edge(&mut self) -> Option<()> {
361 InputFuture::new(&mut self.pin, InterruptOn::Edge(Edge::Rising))?.await; 361 InputFuture::new(self.pin.reborrow(), InterruptOn::Edge(Edge::Rising))?.await;
362 Some(()) 362 Some(())
363 } 363 }
364 364
365 /// Wait for a low level on the pin. You can have at most 8 pins waiting. If you try to wait for 365 /// Wait for a low level on the pin. You can have at most 8 pins waiting. If you try to wait for
366 /// more than 8 pins, this function will return `None`. 366 /// more than 8 pins, this function will return `None`.
367 pub async fn wait_for_low(&mut self) -> Option<()> { 367 pub async fn wait_for_low(&mut self) -> Option<()> {
368 InputFuture::new(&mut self.pin, InterruptOn::Level(Level::Low))?.await; 368 InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::Low))?.await;
369 Some(()) 369 Some(())
370 } 370 }
371 371
372 /// Wait for a high level on the pin. You can have at most 8 pins waiting. If you try to wait for 372 /// Wait for a high level on the pin. You can have at most 8 pins waiting. If you try to wait for
373 /// more than 8 pins, this function will return `None`. 373 /// more than 8 pins, this function will return `None`.
374 pub async fn wait_for_high(&mut self) -> Option<()> { 374 pub async fn wait_for_high(&mut self) -> Option<()> {
375 InputFuture::new(&mut self.pin, InterruptOn::Level(Level::High))?.await; 375 InputFuture::new(self.pin.reborrow(), InterruptOn::Level(Level::High))?.await;
376 Some(()) 376 Some(())
377 } 377 }
378} 378}
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs
index 8defb5231..ec0c8c46c 100644
--- a/embassy-rp/src/adc.rs
+++ b/embassy-rp/src/adc.rs
@@ -5,7 +5,6 @@ use core::mem;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
10 9
11use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin}; 10use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin};
@@ -13,7 +12,7 @@ use crate::interrupt::typelevel::Binding;
13use crate::interrupt::InterruptExt; 12use crate::interrupt::InterruptExt;
14use crate::pac::dma::vals::TreqSel; 13use crate::pac::dma::vals::TreqSel;
15use crate::peripherals::{ADC, ADC_TEMP_SENSOR}; 14use crate::peripherals::{ADC, ADC_TEMP_SENSOR};
16use crate::{dma, interrupt, pac, peripherals, Peripheral, RegExt}; 15use crate::{dma, interrupt, pac, peripherals, Peri, RegExt};
17 16
18static WAKER: AtomicWaker = AtomicWaker::new(); 17static WAKER: AtomicWaker = AtomicWaker::new();
19 18
@@ -23,8 +22,8 @@ static WAKER: AtomicWaker = AtomicWaker::new();
23pub struct Config {} 22pub struct Config {}
24 23
25enum Source<'p> { 24enum Source<'p> {
26 Pin(PeripheralRef<'p, AnyPin>), 25 Pin(Peri<'p, AnyPin>),
27 TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>), 26 TempSensor(Peri<'p, ADC_TEMP_SENSOR>),
28} 27}
29 28
30/// ADC channel. 29/// ADC channel.
@@ -32,8 +31,7 @@ pub struct Channel<'p>(Source<'p>);
32 31
33impl<'p> Channel<'p> { 32impl<'p> Channel<'p> {
34 /// Create a new ADC channel from pin with the provided [Pull] configuration. 33 /// Create a new ADC channel from pin with the provided [Pull] configuration.
35 pub fn new_pin(pin: impl Peripheral<P = impl AdcPin + 'p> + 'p, pull: Pull) -> Self { 34 pub fn new_pin(pin: Peri<'p, impl AdcPin + 'p>, pull: Pull) -> Self {
36 into_ref!(pin);
37 pin.pad_ctrl().modify(|w| { 35 pin.pad_ctrl().modify(|w| {
38 #[cfg(feature = "_rp235x")] 36 #[cfg(feature = "_rp235x")]
39 w.set_iso(false); 37 w.set_iso(false);
@@ -47,14 +45,14 @@ impl<'p> Channel<'p> {
47 w.set_pue(pull == Pull::Up); 45 w.set_pue(pull == Pull::Up);
48 w.set_pde(pull == Pull::Down); 46 w.set_pde(pull == Pull::Down);
49 }); 47 });
50 Self(Source::Pin(pin.map_into())) 48 Self(Source::Pin(pin.into()))
51 } 49 }
52 50
53 /// Create a new ADC channel for the internal temperature sensor. 51 /// Create a new ADC channel for the internal temperature sensor.
54 pub fn new_temp_sensor(s: impl Peripheral<P = ADC_TEMP_SENSOR> + 'p) -> Self { 52 pub fn new_temp_sensor(s: Peri<'p, ADC_TEMP_SENSOR>) -> Self {
55 let r = pac::ADC; 53 let r = pac::ADC;
56 r.cs().write_set(|w| w.set_ts_en(true)); 54 r.cs().write_set(|w| w.set_ts_en(true));
57 Self(Source::TempSensor(s.into_ref())) 55 Self(Source::TempSensor(s))
58 } 56 }
59 57
60 fn channel(&self) -> u8 { 58 fn channel(&self) -> u8 {
@@ -190,7 +188,7 @@ impl<'d, M: Mode> Adc<'d, M> {
190impl<'d> Adc<'d, Async> { 188impl<'d> Adc<'d, Async> {
191 /// Create ADC driver in async mode. 189 /// Create ADC driver in async mode.
192 pub fn new( 190 pub fn new(
193 _inner: impl Peripheral<P = ADC> + 'd, 191 _inner: Peri<'d, ADC>,
194 _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>, 192 _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
195 _config: Config, 193 _config: Config,
196 ) -> Self { 194 ) -> Self {
@@ -205,11 +203,13 @@ impl<'d> Adc<'d, Async> {
205 203
206 fn wait_for_ready() -> impl Future<Output = ()> { 204 fn wait_for_ready() -> impl Future<Output = ()> {
207 let r = Self::regs(); 205 let r = Self::regs();
208 r.inte().write(|w| w.set_fifo(true));
209 compiler_fence(Ordering::SeqCst);
210 206
211 poll_fn(move |cx| { 207 poll_fn(move |cx| {
212 WAKER.register(cx.waker()); 208 WAKER.register(cx.waker());
209
210 r.inte().write(|w| w.set_fifo(true));
211 compiler_fence(Ordering::SeqCst);
212
213 if r.cs().read().ready() { 213 if r.cs().read().ready() {
214 return Poll::Ready(()); 214 return Poll::Ready(());
215 } 215 }
@@ -240,7 +240,7 @@ impl<'d> Adc<'d, Async> {
240 buf: &mut [W], 240 buf: &mut [W],
241 fcs_err: bool, 241 fcs_err: bool,
242 div: u16, 242 div: u16,
243 dma: impl Peripheral<P = impl dma::Channel>, 243 dma: Peri<'_, impl dma::Channel>,
244 ) -> Result<(), Error> { 244 ) -> Result<(), Error> {
245 #[cfg(feature = "rp2040")] 245 #[cfg(feature = "rp2040")]
246 let mut rrobin = 0_u8; 246 let mut rrobin = 0_u8;
@@ -321,7 +321,7 @@ impl<'d> Adc<'d, Async> {
321 ch: &mut [Channel<'_>], 321 ch: &mut [Channel<'_>],
322 buf: &mut [S], 322 buf: &mut [S],
323 div: u16, 323 div: u16,
324 dma: impl Peripheral<P = impl dma::Channel>, 324 dma: Peri<'_, impl dma::Channel>,
325 ) -> Result<(), Error> { 325 ) -> Result<(), Error> {
326 self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma) 326 self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma)
327 .await 327 .await
@@ -337,7 +337,7 @@ impl<'d> Adc<'d, Async> {
337 ch: &mut [Channel<'_>], 337 ch: &mut [Channel<'_>],
338 buf: &mut [Sample], 338 buf: &mut [Sample],
339 div: u16, 339 div: u16,
340 dma: impl Peripheral<P = impl dma::Channel>, 340 dma: Peri<'_, impl dma::Channel>,
341 ) { 341 ) {
342 // errors are reported in individual samples 342 // errors are reported in individual samples
343 let _ = self 343 let _ = self
@@ -360,7 +360,7 @@ impl<'d> Adc<'d, Async> {
360 ch: &mut Channel<'_>, 360 ch: &mut Channel<'_>,
361 buf: &mut [S], 361 buf: &mut [S],
362 div: u16, 362 div: u16,
363 dma: impl Peripheral<P = impl dma::Channel>, 363 dma: Peri<'_, impl dma::Channel>,
364 ) -> Result<(), Error> { 364 ) -> Result<(), Error> {
365 self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma) 365 self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma)
366 .await 366 .await
@@ -375,7 +375,7 @@ impl<'d> Adc<'d, Async> {
375 ch: &mut Channel<'_>, 375 ch: &mut Channel<'_>,
376 buf: &mut [Sample], 376 buf: &mut [Sample],
377 div: u16, 377 div: u16,
378 dma: impl Peripheral<P = impl dma::Channel>, 378 dma: Peri<'_, impl dma::Channel>,
379 ) { 379 ) {
380 // errors are reported in individual samples 380 // errors are reported in individual samples
381 let _ = self 381 let _ = self
@@ -392,7 +392,7 @@ impl<'d> Adc<'d, Async> {
392 392
393impl<'d> Adc<'d, Blocking> { 393impl<'d> Adc<'d, Blocking> {
394 /// Create ADC driver in blocking mode. 394 /// Create ADC driver in blocking mode.
395 pub fn new_blocking(_inner: impl Peripheral<P = ADC> + 'd, _config: Config) -> Self { 395 pub fn new_blocking(_inner: Peri<'d, ADC>, _config: Config) -> Self {
396 Self::setup(); 396 Self::setup();
397 397
398 Self { phantom: PhantomData } 398 Self { phantom: PhantomData }
diff --git a/embassy-rp/src/bootsel.rs b/embassy-rp/src/bootsel.rs
index d24ce7bd8..14f9e46aa 100644
--- a/embassy-rp/src/bootsel.rs
+++ b/embassy-rp/src/bootsel.rs
@@ -8,20 +8,19 @@
8//! This module provides functionality to poll BOOTSEL from an embassy application. 8//! This module provides functionality to poll BOOTSEL from an embassy application.
9 9
10use crate::flash::in_ram; 10use crate::flash::in_ram;
11use crate::Peri;
11 12
12impl crate::peripherals::BOOTSEL { 13/// Reads the BOOTSEL button. Returns true if the button is pressed.
13 /// Polls the BOOTSEL button. Returns true if the button is pressed. 14///
14 /// 15/// Reading isn't cheap, as this function waits for core 1 to finish it's current
15 /// Polling isn't cheap, as this function waits for core 1 to finish it's current 16/// task and for any DMAs from flash to complete
16 /// task and for any DMAs from flash to complete 17pub fn is_bootsel_pressed(_p: Peri<'_, crate::peripherals::BOOTSEL>) -> bool {
17 pub fn is_pressed(&mut self) -> bool { 18 let mut cs_status = Default::default();
18 let mut cs_status = Default::default();
19 19
20 unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); 20 unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0");
21 21
22 // bootsel is active low, so invert 22 // bootsel is active low, so invert
23 !cs_status.infrompad() 23 !cs_status.infrompad()
24 }
25} 24}
26 25
27mod ram_helpers { 26mod ram_helpers {
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index 705dde62a..67aa5e540 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -7,13 +7,12 @@ use core::marker::PhantomData;
7use core::sync::atomic::AtomicU16; 7use core::sync::atomic::AtomicU16;
8use core::sync::atomic::{AtomicU32, Ordering}; 8use core::sync::atomic::{AtomicU32, Ordering};
9 9
10use embassy_hal_internal::{into_ref, PeripheralRef};
11use pac::clocks::vals::*; 10use pac::clocks::vals::*;
12 11
13use crate::gpio::{AnyPin, SealedPin}; 12use crate::gpio::{AnyPin, SealedPin};
14#[cfg(feature = "rp2040")] 13#[cfg(feature = "rp2040")]
15use crate::pac::common::{Reg, RW}; 14use crate::pac::common::{Reg, RW};
16use crate::{pac, reset, Peripheral}; 15use crate::{pac, reset, Peri};
17 16
18// NOTE: all gpin handling is commented out for future reference. 17// NOTE: all gpin handling is commented out for future reference.
19// gpin is not usually safe to use during the boot init() call, so it won't 18// gpin is not usually safe to use during the boot init() call, so it won't
@@ -200,8 +199,8 @@ impl ClockConfig {
200 199
201 // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) { 200 // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) {
202 // match P::NR { 201 // match P::NR {
203 // 0 => self.gpin0 = Some((hz, gpin.map_into())), 202 // 0 => self.gpin0 = Some((hz, gpin.into())),
204 // 1 => self.gpin1 = Some((hz, gpin.map_into())), 203 // 1 => self.gpin1 = Some((hz, gpin.into())),
205 // _ => unreachable!(), 204 // _ => unreachable!(),
206 // } 205 // }
207 // // pin is now provisionally bound. if the config is applied it must be forgotten, 206 // // pin is now provisionally bound. if the config is applied it must be forgotten,
@@ -845,15 +844,13 @@ impl_gpinpin!(PIN_22, 22, 1);
845 844
846/// General purpose clock input driver. 845/// General purpose clock input driver.
847pub struct Gpin<'d, T: GpinPin> { 846pub struct Gpin<'d, T: GpinPin> {
848 gpin: PeripheralRef<'d, AnyPin>, 847 gpin: Peri<'d, AnyPin>,
849 _phantom: PhantomData<T>, 848 _phantom: PhantomData<T>,
850} 849}
851 850
852impl<'d, T: GpinPin> Gpin<'d, T> { 851impl<'d, T: GpinPin> Gpin<'d, T> {
853 /// Create new gpin driver. 852 /// Create new gpin driver.
854 pub fn new(gpin: impl Peripheral<P = T> + 'd) -> Self { 853 pub fn new(gpin: Peri<'d, T>) -> Self {
855 into_ref!(gpin);
856
857 #[cfg(feature = "rp2040")] 854 #[cfg(feature = "rp2040")]
858 gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08)); 855 gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08));
859 856
@@ -867,14 +864,10 @@ impl<'d, T: GpinPin> Gpin<'d, T> {
867 }); 864 });
868 865
869 Gpin { 866 Gpin {
870 gpin: gpin.map_into(), 867 gpin: gpin.into(),
871 _phantom: PhantomData, 868 _phantom: PhantomData,
872 } 869 }
873 } 870 }
874
875 // fn map_into(self) -> Gpin<'d, AnyPin> {
876 // unsafe { core::mem::transmute(self) }
877 // }
878} 871}
879 872
880impl<'d, T: GpinPin> Drop for Gpin<'d, T> { 873impl<'d, T: GpinPin> Drop for Gpin<'d, T> {
@@ -936,14 +929,12 @@ pub enum GpoutSrc {
936 929
937/// General purpose clock output driver. 930/// General purpose clock output driver.
938pub struct Gpout<'d, T: GpoutPin> { 931pub struct Gpout<'d, T: GpoutPin> {
939 gpout: PeripheralRef<'d, T>, 932 gpout: Peri<'d, T>,
940} 933}
941 934
942impl<'d, T: GpoutPin> Gpout<'d, T> { 935impl<'d, T: GpoutPin> Gpout<'d, T> {
943 /// Create new general purpose clock output. 936 /// Create new general purpose clock output.
944 pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { 937 pub fn new(gpout: Peri<'d, T>) -> Self {
945 into_ref!(gpout);
946
947 #[cfg(feature = "rp2040")] 938 #[cfg(feature = "rp2040")]
948 gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08)); 939 gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08));
949 940
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 2edcfdf5b..d31d1e159 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use pac::dma::vals::DataSize; 9use pac::dma::vals::DataSize;
10 10
@@ -42,7 +42,7 @@ pub(crate) unsafe fn init() {
42/// 42///
43/// SAFETY: Slice must point to a valid location reachable by DMA. 43/// SAFETY: Slice must point to a valid location reachable by DMA.
44pub unsafe fn read<'a, C: Channel, W: Word>( 44pub unsafe fn read<'a, C: Channel, W: Word>(
45 ch: impl Peripheral<P = C> + 'a, 45 ch: Peri<'a, C>,
46 from: *const W, 46 from: *const W,
47 to: *mut [W], 47 to: *mut [W],
48 dreq: vals::TreqSel, 48 dreq: vals::TreqSel,
@@ -63,7 +63,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
63/// 63///
64/// SAFETY: Slice must point to a valid location reachable by DMA. 64/// SAFETY: Slice must point to a valid location reachable by DMA.
65pub unsafe fn write<'a, C: Channel, W: Word>( 65pub unsafe fn write<'a, C: Channel, W: Word>(
66 ch: impl Peripheral<P = C> + 'a, 66 ch: Peri<'a, C>,
67 from: *const [W], 67 from: *const [W],
68 to: *mut W, 68 to: *mut W,
69 dreq: vals::TreqSel, 69 dreq: vals::TreqSel,
@@ -87,7 +87,7 @@ static mut DUMMY: u32 = 0;
87/// 87///
88/// SAFETY: Slice must point to a valid location reachable by DMA. 88/// SAFETY: Slice must point to a valid location reachable by DMA.
89pub unsafe fn write_repeated<'a, C: Channel, W: Word>( 89pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
90 ch: impl Peripheral<P = C> + 'a, 90 ch: Peri<'a, C>,
91 to: *mut W, 91 to: *mut W,
92 len: usize, 92 len: usize,
93 dreq: vals::TreqSel, 93 dreq: vals::TreqSel,
@@ -107,11 +107,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
107/// DMA copy between slices. 107/// DMA copy between slices.
108/// 108///
109/// SAFETY: Slices must point to locations reachable by DMA. 109/// SAFETY: Slices must point to locations reachable by DMA.
110pub unsafe fn copy<'a, C: Channel, W: Word>( 110pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
111 ch: impl Peripheral<P = C> + 'a,
112 from: &[W],
113 to: &mut [W],
114) -> Transfer<'a, C> {
115 let from_len = from.len(); 111 let from_len = from.len();
116 let to_len = to.len(); 112 let to_len = to.len();
117 assert_eq!(from_len, to_len); 113 assert_eq!(from_len, to_len);
@@ -128,7 +124,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(
128} 124}
129 125
130fn copy_inner<'a, C: Channel>( 126fn copy_inner<'a, C: Channel>(
131 ch: impl Peripheral<P = C> + 'a, 127 ch: Peri<'a, C>,
132 from: *const u32, 128 from: *const u32,
133 to: *mut u32, 129 to: *mut u32,
134 len: usize, 130 len: usize,
@@ -137,8 +133,6 @@ fn copy_inner<'a, C: Channel>(
137 incr_write: bool, 133 incr_write: bool,
138 dreq: vals::TreqSel, 134 dreq: vals::TreqSel,
139) -> Transfer<'a, C> { 135) -> Transfer<'a, C> {
140 into_ref!(ch);
141
142 let p = ch.regs(); 136 let p = ch.regs();
143 137
144 p.read_addr().write_value(from as u32); 138 p.read_addr().write_value(from as u32);
@@ -171,13 +165,11 @@ fn copy_inner<'a, C: Channel>(
171/// DMA transfer driver. 165/// DMA transfer driver.
172#[must_use = "futures do nothing unless you `.await` or poll them"] 166#[must_use = "futures do nothing unless you `.await` or poll them"]
173pub struct Transfer<'a, C: Channel> { 167pub struct Transfer<'a, C: Channel> {
174 channel: PeripheralRef<'a, C>, 168 channel: Peri<'a, C>,
175} 169}
176 170
177impl<'a, C: Channel> Transfer<'a, C> { 171impl<'a, C: Channel> Transfer<'a, C> {
178 pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self { 172 pub(crate) fn new(channel: Peri<'a, C>) -> Self {
179 into_ref!(channel);
180
181 Self { channel } 173 Self { channel }
182 } 174 }
183} 175}
@@ -219,7 +211,7 @@ trait SealedWord {}
219 211
220/// DMA channel interface. 212/// DMA channel interface.
221#[allow(private_bounds)] 213#[allow(private_bounds)]
222pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Sized + 'static { 214pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
223 /// Channel number. 215 /// Channel number.
224 fn number(&self) -> u8; 216 fn number(&self) -> u8;
225 217
@@ -227,11 +219,6 @@ pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Siz
227 fn regs(&self) -> pac::dma::Channel { 219 fn regs(&self) -> pac::dma::Channel {
228 pac::DMA.ch(self.number() as _) 220 pac::DMA.ch(self.number() as _)
229 } 221 }
230
231 /// Convert into type-erased [AnyChannel].
232 fn degrade(self) -> AnyChannel {
233 AnyChannel { number: self.number() }
234 }
235} 222}
236 223
237/// DMA word. 224/// DMA word.
@@ -287,7 +274,7 @@ macro_rules! channel {
287 274
288 impl From<peripherals::$name> for crate::dma::AnyChannel { 275 impl From<peripherals::$name> for crate::dma::AnyChannel {
289 fn from(val: peripherals::$name) -> Self { 276 fn from(val: peripherals::$name) -> Self {
290 crate::dma::Channel::degrade(val) 277 Self { number: val.number() }
291 } 278 }
292 } 279 }
293 }; 280 };
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index fbc8b35ec..ef1cd9212 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use core::pin::Pin; 4use core::pin::Pin;
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{Peri, PeripheralType};
8use embedded_storage::nor_flash::{ 8use embedded_storage::nor_flash::{
9 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, 9 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
10 ReadNorFlash, 10 ReadNorFlash,
@@ -19,7 +19,7 @@ pub const FLASH_BASE: *const u32 = 0x10000000 as _;
19 19
20/// Address for xip setup function set up by the 235x bootrom. 20/// Address for xip setup function set up by the 235x bootrom.
21#[cfg(feature = "_rp235x")] 21#[cfg(feature = "_rp235x")]
22pub const BOOTROM_BASE: *const u32 = 0x400e0000 as _; 22pub const BOOTRAM_BASE: *const u32 = 0x400e0000 as _;
23 23
24/// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead. 24/// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead.
25// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance. 25// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance.
@@ -114,7 +114,7 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, '
114 114
115/// Flash driver. 115/// Flash driver.
116pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> { 116pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
117 dma: Option<PeripheralRef<'d, AnyChannel>>, 117 dma: Option<Peri<'d, AnyChannel>>,
118 phantom: PhantomData<(&'d mut T, M)>, 118 phantom: PhantomData<(&'d mut T, M)>,
119} 119}
120 120
@@ -253,7 +253,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
253 253
254impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> { 254impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
255 /// Create a new flash driver in blocking mode. 255 /// Create a new flash driver in blocking mode.
256 pub fn new_blocking(_flash: impl Peripheral<P = T> + 'd) -> Self { 256 pub fn new_blocking(_flash: Peri<'d, T>) -> Self {
257 Self { 257 Self {
258 dma: None, 258 dma: None,
259 phantom: PhantomData, 259 phantom: PhantomData,
@@ -263,10 +263,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE
263 263
264impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { 264impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
265 /// Create a new flash driver in async mode. 265 /// Create a new flash driver in async mode.
266 pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self { 266 pub fn new(_flash: Peri<'d, T>, dma: Peri<'d, impl Channel>) -> Self {
267 into_ref!(dma);
268 Self { 267 Self {
269 dma: Some(dma.map_into()), 268 dma: Some(dma.into()),
270 phantom: PhantomData, 269 phantom: PhantomData,
271 } 270 }
272 } 271 }
@@ -316,7 +315,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
316 const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _; 315 const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _;
317 let transfer = unsafe { 316 let transfer = unsafe {
318 crate::dma::read( 317 crate::dma::read(
319 self.dma.as_mut().unwrap(), 318 self.dma.as_mut().unwrap().reborrow(),
320 XIP_AUX_BASE, 319 XIP_AUX_BASE,
321 data, 320 data,
322 pac::dma::vals::TreqSel::XIP_STREAM, 321 pac::dma::vals::TreqSel::XIP_STREAM,
@@ -527,7 +526,7 @@ mod ram_helpers {
527 #[cfg(feature = "rp2040")] 526 #[cfg(feature = "rp2040")]
528 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); 527 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
529 #[cfg(feature = "_rp235x")] 528 #[cfg(feature = "_rp235x")]
530 core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); 529 core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256);
531 flash_function_pointers_with_boot2(true, false, &boot2) 530 flash_function_pointers_with_boot2(true, false, &boot2)
532 } else { 531 } else {
533 flash_function_pointers(true, false) 532 flash_function_pointers(true, false)
@@ -560,7 +559,7 @@ mod ram_helpers {
560 #[cfg(feature = "rp2040")] 559 #[cfg(feature = "rp2040")]
561 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); 560 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
562 #[cfg(feature = "_rp235x")] 561 #[cfg(feature = "_rp235x")]
563 core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, (boot2).as_mut_ptr() as *mut u8, 256); 562 core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, (boot2).as_mut_ptr() as *mut u8, 256);
564 flash_function_pointers_with_boot2(true, true, &boot2) 563 flash_function_pointers_with_boot2(true, true, &boot2)
565 } else { 564 } else {
566 flash_function_pointers(true, true) 565 flash_function_pointers(true, true)
@@ -598,7 +597,7 @@ mod ram_helpers {
598 #[cfg(feature = "rp2040")] 597 #[cfg(feature = "rp2040")]
599 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); 598 rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
600 #[cfg(feature = "_rp235x")] 599 #[cfg(feature = "_rp235x")]
601 core::ptr::copy_nonoverlapping(BOOTROM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256); 600 core::ptr::copy_nonoverlapping(BOOTRAM_BASE as *const u8, boot2.as_mut_ptr() as *mut u8, 256);
602 flash_function_pointers_with_boot2(false, true, &boot2) 601 flash_function_pointers_with_boot2(false, true, &boot2)
603 } else { 602 } else {
604 flash_function_pointers(false, true) 603 flash_function_pointers(false, true)
@@ -965,7 +964,7 @@ trait SealedMode {}
965 964
966/// Flash instance. 965/// Flash instance.
967#[allow(private_bounds)] 966#[allow(private_bounds)]
968pub trait Instance: SealedInstance {} 967pub trait Instance: SealedInstance + PeripheralType {}
969/// Flash mode. 968/// Flash mode.
970#[allow(private_bounds)] 969#[allow(private_bounds)]
971pub trait Mode: SealedMode {} 970pub trait Mode: SealedMode {}
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 111e03356..af0837f6a 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -5,13 +5,13 @@ use core::future::Future;
5use core::pin::Pin as FuturePin; 5use core::pin::Pin as FuturePin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::interrupt::InterruptExt; 11use crate::interrupt::InterruptExt;
12use crate::pac::common::{Reg, RW}; 12use crate::pac::common::{Reg, RW};
13use crate::pac::SIO; 13use crate::pac::SIO;
14use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 14use crate::{interrupt, pac, peripherals, RegExt};
15 15
16#[cfg(any(feature = "rp2040", feature = "rp235xa"))] 16#[cfg(any(feature = "rp2040", feature = "rp235xa"))]
17pub(crate) const BANK0_PIN_COUNT: usize = 30; 17pub(crate) const BANK0_PIN_COUNT: usize = 30;
@@ -115,7 +115,7 @@ pub struct Input<'d> {
115impl<'d> Input<'d> { 115impl<'d> Input<'d> {
116 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. 116 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
117 #[inline] 117 #[inline]
118 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { 118 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
119 let mut pin = Flex::new(pin); 119 let mut pin = Flex::new(pin);
120 pin.set_as_input(); 120 pin.set_as_input();
121 pin.set_pull(pull); 121 pin.set_pull(pull);
@@ -266,11 +266,11 @@ fn IO_IRQ_QSPI() {
266 266
267#[must_use = "futures do nothing unless you `.await` or poll them"] 267#[must_use = "futures do nothing unless you `.await` or poll them"]
268struct InputFuture<'d> { 268struct InputFuture<'d> {
269 pin: PeripheralRef<'d, AnyPin>, 269 pin: Peri<'d, AnyPin>,
270} 270}
271 271
272impl<'d> InputFuture<'d> { 272impl<'d> InputFuture<'d> {
273 fn new(pin: PeripheralRef<'d, AnyPin>, level: InterruptTrigger) -> Self { 273 fn new(pin: Peri<'d, AnyPin>, level: InterruptTrigger) -> Self {
274 let pin_group = (pin.pin() % 8) as usize; 274 let pin_group = (pin.pin() % 8) as usize;
275 // first, clear the INTR register bits. without this INTR will still 275 // first, clear the INTR register bits. without this INTR will still
276 // contain reports of previous edges, causing the IRQ to fire early 276 // contain reports of previous edges, causing the IRQ to fire early
@@ -359,7 +359,7 @@ pub struct Output<'d> {
359impl<'d> Output<'d> { 359impl<'d> Output<'d> {
360 /// Create GPIO output driver for a [Pin] with the provided [Level]. 360 /// Create GPIO output driver for a [Pin] with the provided [Level].
361 #[inline] 361 #[inline]
362 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { 362 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
363 let mut pin = Flex::new(pin); 363 let mut pin = Flex::new(pin);
364 match initial_output { 364 match initial_output {
365 Level::High => pin.set_high(), 365 Level::High => pin.set_high(),
@@ -440,7 +440,7 @@ pub struct OutputOpenDrain<'d> {
440impl<'d> OutputOpenDrain<'d> { 440impl<'d> OutputOpenDrain<'d> {
441 /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level]. 441 /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level].
442 #[inline] 442 #[inline]
443 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { 443 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
444 let mut pin = Flex::new(pin); 444 let mut pin = Flex::new(pin);
445 pin.set_low(); 445 pin.set_low();
446 match initial_output { 446 match initial_output {
@@ -581,7 +581,7 @@ impl<'d> OutputOpenDrain<'d> {
581/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 581/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
582/// mode. 582/// mode.
583pub struct Flex<'d> { 583pub struct Flex<'d> {
584 pin: PeripheralRef<'d, AnyPin>, 584 pin: Peri<'d, AnyPin>,
585} 585}
586 586
587impl<'d> Flex<'d> { 587impl<'d> Flex<'d> {
@@ -590,9 +590,7 @@ impl<'d> Flex<'d> {
590 /// The pin remains disconnected. The initial output level is unspecified, but can be changed 590 /// The pin remains disconnected. The initial output level is unspecified, but can be changed
591 /// before the pin is put into output mode. 591 /// before the pin is put into output mode.
592 #[inline] 592 #[inline]
593 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { 593 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
594 into_ref!(pin);
595
596 pin.pad_ctrl().write(|w| { 594 pin.pad_ctrl().write(|w| {
597 #[cfg(feature = "_rp235x")] 595 #[cfg(feature = "_rp235x")]
598 w.set_iso(false); 596 w.set_iso(false);
@@ -606,7 +604,7 @@ impl<'d> Flex<'d> {
606 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _); 604 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _);
607 }); 605 });
608 606
609 Self { pin: pin.map_into() } 607 Self { pin: pin.into() }
610 } 608 }
611 609
612 #[inline] 610 #[inline]
@@ -829,7 +827,7 @@ impl<'d> Drop for Flex<'d> {
829 827
830/// Dormant wake driver. 828/// Dormant wake driver.
831pub struct DormantWake<'w> { 829pub struct DormantWake<'w> {
832 pin: PeripheralRef<'w, AnyPin>, 830 pin: Peri<'w, AnyPin>,
833 cfg: DormantWakeConfig, 831 cfg: DormantWakeConfig,
834} 832}
835 833
@@ -919,14 +917,7 @@ pub(crate) trait SealedPin: Sized {
919 917
920/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. 918/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
921#[allow(private_bounds)] 919#[allow(private_bounds)]
922pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { 920pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
923 /// Degrade to a generic pin struct
924 fn degrade(self) -> AnyPin {
925 AnyPin {
926 pin_bank: self.pin_bank(),
927 }
928 }
929
930 /// Returns the pin number within a bank 921 /// Returns the pin number within a bank
931 #[inline] 922 #[inline]
932 fn pin(&self) -> u8 { 923 fn pin(&self) -> u8 {
@@ -951,8 +942,8 @@ impl AnyPin {
951 /// # Safety 942 /// # Safety
952 /// 943 ///
953 /// You must ensure that you’re only using one instance of this type at a time. 944 /// You must ensure that you’re only using one instance of this type at a time.
954 pub unsafe fn steal(pin_bank: u8) -> Self { 945 pub unsafe fn steal(pin_bank: u8) -> Peri<'static, Self> {
955 Self { pin_bank } 946 Peri::new_unchecked(Self { pin_bank })
956 } 947 }
957} 948}
958 949
@@ -979,7 +970,9 @@ macro_rules! impl_pin {
979 970
980 impl From<peripherals::$name> for crate::gpio::AnyPin { 971 impl From<peripherals::$name> for crate::gpio::AnyPin {
981 fn from(val: peripherals::$name) -> Self { 972 fn from(val: peripherals::$name) -> Self {
982 crate::gpio::Pin::degrade(val) 973 Self {
974 pin_bank: val.pin_bank(),
975 }
983 } 976 }
984 } 977 }
985 }; 978 };
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 3a2ee666c..adc38b73d 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -5,13 +5,13 @@ use core::future;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use pac::i2c; 10use pac::i2c;
11 11
12use crate::gpio::AnyPin; 12use crate::gpio::AnyPin;
13use crate::interrupt::typelevel::{Binding, Interrupt}; 13use crate::interrupt::typelevel::{Binding, Interrupt};
14use crate::{interrupt, pac, peripherals, Peripheral}; 14use crate::{interrupt, pac, peripherals};
15 15
16/// I2C error abort reason 16/// I2C error abort reason
17#[derive(Debug, PartialEq, Eq, Clone, Copy)] 17#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -83,28 +83,25 @@ pub struct I2c<'d, T: Instance, M: Mode> {
83impl<'d, T: Instance> I2c<'d, T, Blocking> { 83impl<'d, T: Instance> I2c<'d, T, Blocking> {
84 /// Create a new driver instance in blocking mode. 84 /// Create a new driver instance in blocking mode.
85 pub fn new_blocking( 85 pub fn new_blocking(
86 peri: impl Peripheral<P = T> + 'd, 86 peri: Peri<'d, T>,
87 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 87 scl: Peri<'d, impl SclPin<T>>,
88 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 88 sda: Peri<'d, impl SdaPin<T>>,
89 config: Config, 89 config: Config,
90 ) -> Self { 90 ) -> Self {
91 into_ref!(scl, sda); 91 Self::new_inner(peri, scl.into(), sda.into(), config)
92 Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
93 } 92 }
94} 93}
95 94
96impl<'d, T: Instance> I2c<'d, T, Async> { 95impl<'d, T: Instance> I2c<'d, T, Async> {
97 /// Create a new driver instance in async mode. 96 /// Create a new driver instance in async mode.
98 pub fn new_async( 97 pub fn new_async(
99 peri: impl Peripheral<P = T> + 'd, 98 peri: Peri<'d, T>,
100 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 99 scl: Peri<'d, impl SclPin<T>>,
101 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 100 sda: Peri<'d, impl SdaPin<T>>,
102 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 101 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
103 config: Config, 102 config: Config,
104 ) -> Self { 103 ) -> Self {
105 into_ref!(scl, sda); 104 let i2c = Self::new_inner(peri, scl.into(), sda.into(), config);
106
107 let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
108 105
109 let r = T::regs(); 106 let r = T::regs();
110 107
@@ -378,14 +375,7 @@ where
378} 375}
379 376
380impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { 377impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
381 fn new_inner( 378 fn new_inner(_peri: Peri<'d, T>, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self {
382 _peri: impl Peripheral<P = T> + 'd,
383 scl: PeripheralRef<'d, AnyPin>,
384 sda: PeripheralRef<'d, AnyPin>,
385 config: Config,
386 ) -> Self {
387 into_ref!(_peri);
388
389 let reset = T::reset(); 379 let reset = T::reset();
390 crate::reset::reset(reset); 380 crate::reset::reset(reset);
391 crate::reset::unreset_wait(reset); 381 crate::reset::unreset_wait(reset);
@@ -804,7 +794,7 @@ impl_mode!(Async);
804 794
805/// I2C instance. 795/// I2C instance.
806#[allow(private_bounds)] 796#[allow(private_bounds)]
807pub trait Instance: SealedInstance { 797pub trait Instance: SealedInstance + PeripheralType {
808 /// Interrupt for this peripheral. 798 /// Interrupt for this peripheral.
809 type Interrupt: interrupt::typelevel::Interrupt; 799 type Interrupt: interrupt::typelevel::Interrupt;
810} 800}
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs
index d17b11d14..d420030d8 100644
--- a/embassy-rp/src/i2c_slave.rs
+++ b/embassy-rp/src/i2c_slave.rs
@@ -3,12 +3,11 @@ use core::future;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::into_ref;
7use pac::i2c; 6use pac::i2c;
8 7
9use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; 8use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE};
10use crate::interrupt::typelevel::{Binding, Interrupt}; 9use crate::interrupt::typelevel::{Binding, Interrupt};
11use crate::{pac, Peripheral}; 10use crate::{pac, Peri};
12 11
13/// I2C error 12/// I2C error
14#[derive(Debug, PartialEq, Eq, Clone, Copy)] 13#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -87,14 +86,12 @@ pub struct I2cSlave<'d, T: Instance> {
87impl<'d, T: Instance> I2cSlave<'d, T> { 86impl<'d, T: Instance> I2cSlave<'d, T> {
88 /// Create a new instance. 87 /// Create a new instance.
89 pub fn new( 88 pub fn new(
90 _peri: impl Peripheral<P = T> + 'd, 89 _peri: Peri<'d, T>,
91 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 90 scl: Peri<'d, impl SclPin<T>>,
92 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 91 sda: Peri<'d, impl SdaPin<T>>,
93 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 92 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
94 config: Config, 93 config: Config,
95 ) -> Self { 94 ) -> Self {
96 into_ref!(_peri, scl, sda);
97
98 assert!(config.addr != 0); 95 assert!(config.addr != 0);
99 96
100 // Configure SCL & SDA pins 97 // Configure SCL & SDA pins
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index de60af890..35099d07b 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -54,7 +54,7 @@ pub mod pio;
54pub(crate) mod relocate; 54pub(crate) mod relocate;
55 55
56// Reexports 56// Reexports
57pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 57pub use embassy_hal_internal::{Peri, PeripheralType};
58#[cfg(feature = "unstable-pac")] 58#[cfg(feature = "unstable-pac")]
59pub use rp_pac as pac; 59pub use rp_pac as pac;
60#[cfg(not(feature = "unstable-pac"))] 60#[cfg(not(feature = "unstable-pac"))]
diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs
index 1450505b9..d10b6837c 100644
--- a/embassy-rp/src/multicore.rs
+++ b/embassy-rp/src/multicore.rs
@@ -51,7 +51,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
51 51
52use crate::interrupt::InterruptExt; 52use crate::interrupt::InterruptExt;
53use crate::peripherals::CORE1; 53use crate::peripherals::CORE1;
54use crate::{gpio, install_stack_guard, interrupt, pac}; 54use crate::{gpio, install_stack_guard, interrupt, pac, Peri};
55 55
56const PAUSE_TOKEN: u32 = 0xDEADBEEF; 56const PAUSE_TOKEN: u32 = 0xDEADBEEF;
57const RESUME_TOKEN: u32 = !0xDEADBEEF; 57const RESUME_TOKEN: u32 = !0xDEADBEEF;
@@ -139,7 +139,7 @@ unsafe fn SIO_IRQ_FIFO() {
139} 139}
140 140
141/// Spawn a function on this core 141/// Spawn a function on this core
142pub fn spawn_core1<F, const SIZE: usize>(_core1: CORE1, stack: &'static mut Stack<SIZE>, entry: F) 142pub fn spawn_core1<F, const SIZE: usize>(_core1: Peri<'static, CORE1>, stack: &'static mut Stack<SIZE>, entry: F)
143where 143where
144 F: FnOnce() -> bad::Never + Send + 'static, 144 F: FnOnce() -> bad::Never + Send + 'static,
145{ 145{
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index fd09d4bba..ec698d99c 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use atomic_polyfill::{AtomicU64, AtomicU8}; 8use atomic_polyfill::{AtomicU64, AtomicU8};
9use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_internal::{Peri, PeripheralType};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use fixed::types::extra::U8; 11use fixed::types::extra::U8;
12use fixed::FixedU32; 12use fixed::FixedU32;
@@ -235,7 +235,7 @@ impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
235 235
236/// Type representing a PIO pin. 236/// Type representing a PIO pin.
237pub struct Pin<'l, PIO: Instance> { 237pub struct Pin<'l, PIO: Instance> {
238 pin: PeripheralRef<'l, AnyPin>, 238 pin: Peri<'l, AnyPin>,
239 pio: PhantomData<PIO>, 239 pio: PhantomData<PIO>,
240} 240}
241 241
@@ -360,7 +360,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
360 /// Prepare DMA transfer from RX FIFO. 360 /// Prepare DMA transfer from RX FIFO.
361 pub fn dma_pull<'a, C: Channel, W: Word>( 361 pub fn dma_pull<'a, C: Channel, W: Word>(
362 &'a mut self, 362 &'a mut self,
363 ch: PeripheralRef<'a, C>, 363 ch: Peri<'a, C>,
364 data: &'a mut [W], 364 data: &'a mut [W],
365 bswap: bool, 365 bswap: bool,
366 ) -> Transfer<'a, C> { 366 ) -> Transfer<'a, C> {
@@ -451,7 +451,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
451 /// Prepare a DMA transfer to TX FIFO. 451 /// Prepare a DMA transfer to TX FIFO.
452 pub fn dma_push<'a, C: Channel, W: Word>( 452 pub fn dma_push<'a, C: Channel, W: Word>(
453 &'a mut self, 453 &'a mut self,
454 ch: PeripheralRef<'a, C>, 454 ch: Peri<'a, C>,
455 data: &'a [W], 455 data: &'a [W],
456 bswap: bool, 456 bswap: bool,
457 ) -> Transfer<'a, C> { 457 ) -> Transfer<'a, C> {
@@ -1147,9 +1147,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
1147 /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and* 1147 /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and*
1148 /// all [`StateMachine`]s for this block have been dropped. **Other members 1148 /// all [`StateMachine`]s for this block have been dropped. **Other members
1149 /// of [`Pio`] do not keep pin registrations alive.** 1149 /// of [`Pio`] do not keep pin registrations alive.**
1150 pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { 1150 pub fn make_pio_pin(&mut self, pin: Peri<'d, impl PioPin + 'd>) -> Pin<'d, PIO> {
1151 into_ref!(pin);
1152
1153 // enable the outputs 1151 // enable the outputs
1154 pin.pad_ctrl().write(|w| w.set_od(false)); 1152 pin.pad_ctrl().write(|w| w.set_od(false));
1155 // especially important on the 235x, where IE defaults to 0 1153 // especially important on the 235x, where IE defaults to 0
@@ -1171,7 +1169,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
1171 // we can be relaxed about this because we're &mut here and nothing is cached 1169 // we can be relaxed about this because we're &mut here and nothing is cached
1172 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); 1170 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
1173 Pin { 1171 Pin {
1174 pin: pin.into_ref().map_into(), 1172 pin: pin.into(),
1175 pio: PhantomData::default(), 1173 pio: PhantomData::default(),
1176 } 1174 }
1177 } 1175 }
@@ -1304,7 +1302,7 @@ pub struct Pio<'d, PIO: Instance> {
1304 1302
1305impl<'d, PIO: Instance> Pio<'d, PIO> { 1303impl<'d, PIO: Instance> Pio<'d, PIO> {
1306 /// Create a new instance of a PIO peripheral. 1304 /// Create a new instance of a PIO peripheral.
1307 pub fn new(_pio: impl Peripheral<P = PIO> + 'd, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self { 1305 pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self {
1308 PIO::state().users.store(5, Ordering::Release); 1306 PIO::state().users.store(5, Ordering::Release);
1309 PIO::state().used_pins.store(0, Ordering::Release); 1307 PIO::state().used_pins.store(0, Ordering::Release);
1310 PIO::Interrupt::unpend(); 1308 PIO::Interrupt::unpend();
@@ -1389,7 +1387,7 @@ trait SealedInstance {
1389 1387
1390/// PIO instance. 1388/// PIO instance.
1391#[allow(private_bounds)] 1389#[allow(private_bounds)]
1392pub trait Instance: SealedInstance + Sized + Unpin { 1390pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin {
1393 /// Interrupt for this peripheral. 1391 /// Interrupt for this peripheral.
1394 type Interrupt: crate::interrupt::typelevel::Interrupt; 1392 type Interrupt: crate::interrupt::typelevel::Interrupt;
1395} 1393}
diff --git a/embassy-rp/src/pio_programs/hd44780.rs b/embassy-rp/src/pio_programs/hd44780.rs
index 6997b91f3..5846a8027 100644
--- a/embassy-rp/src/pio_programs/hd44780.rs
+++ b/embassy-rp/src/pio_programs/hd44780.rs
@@ -5,7 +5,7 @@ use crate::pio::{
5 Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, 5 Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection,
6 StateMachine, 6 StateMachine,
7}; 7};
8use crate::{into_ref, Peripheral, PeripheralRef}; 8use crate::Peri;
9 9
10/// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>) 10/// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>)
11pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> { 11pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> {
@@ -99,7 +99,7 @@ impl<'a, PIO: Instance> PioHD44780CommandSequenceProgram<'a, PIO> {
99 99
100/// Pio backed HD44780 driver 100/// Pio backed HD44780 driver
101pub struct PioHD44780<'l, P: Instance, const S: usize> { 101pub struct PioHD44780<'l, P: Instance, const S: usize> {
102 dma: PeripheralRef<'l, AnyChannel>, 102 dma: Peri<'l, AnyChannel>,
103 sm: StateMachine<'l, P, S>, 103 sm: StateMachine<'l, P, S>,
104 104
105 buf: [u8; 40], 105 buf: [u8; 40],
@@ -111,19 +111,17 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
111 common: &mut Common<'l, P>, 111 common: &mut Common<'l, P>,
112 mut sm: StateMachine<'l, P, S>, 112 mut sm: StateMachine<'l, P, S>,
113 mut irq: Irq<'l, P, S>, 113 mut irq: Irq<'l, P, S>,
114 dma: impl Peripheral<P = impl Channel> + 'l, 114 mut dma: Peri<'l, impl Channel>,
115 rs: impl PioPin, 115 rs: Peri<'l, impl PioPin>,
116 rw: impl PioPin, 116 rw: Peri<'l, impl PioPin>,
117 e: impl PioPin, 117 e: Peri<'l, impl PioPin>,
118 db4: impl PioPin, 118 db4: Peri<'l, impl PioPin>,
119 db5: impl PioPin, 119 db5: Peri<'l, impl PioPin>,
120 db6: impl PioPin, 120 db6: Peri<'l, impl PioPin>,
121 db7: impl PioPin, 121 db7: Peri<'l, impl PioPin>,
122 word_prg: &PioHD44780CommandWordProgram<'l, P>, 122 word_prg: &PioHD44780CommandWordProgram<'l, P>,
123 seq_prg: &PioHD44780CommandSequenceProgram<'l, P>, 123 seq_prg: &PioHD44780CommandSequenceProgram<'l, P>,
124 ) -> PioHD44780<'l, P, S> { 124 ) -> PioHD44780<'l, P, S> {
125 into_ref!(dma);
126
127 let rs = common.make_pio_pin(rs); 125 let rs = common.make_pio_pin(rs);
128 let rw = common.make_pio_pin(rw); 126 let rw = common.make_pio_pin(rw);
129 let e = common.make_pio_pin(e); 127 let e = common.make_pio_pin(e);
@@ -176,7 +174,7 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
176 sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await; 174 sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await;
177 175
178 Self { 176 Self {
179 dma: dma.map_into(), 177 dma: dma.into(),
180 sm, 178 sm,
181 buf: [0x20; 40], 179 buf: [0x20; 40],
182 } 180 }
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs
index 17e321405..b967f0160 100644
--- a/embassy-rp/src/pio_programs/i2s.rs
+++ b/embassy-rp/src/pio_programs/i2s.rs
@@ -6,16 +6,16 @@ use crate::dma::{AnyChannel, Channel, Transfer};
6use crate::pio::{ 6use crate::pio::{
7 Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, 7 Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
8}; 8};
9use crate::{into_ref, Peripheral, PeripheralRef}; 9use crate::Peri;
10 10
11/// This struct represents an i2s output driver program 11/// This struct represents an i2s output driver program
12pub struct PioI2sOutProgram<'a, PIO: Instance> { 12pub struct PioI2sOutProgram<'d, PIO: Instance> {
13 prg: LoadedProgram<'a, PIO>, 13 prg: LoadedProgram<'d, PIO>,
14} 14}
15 15
16impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> { 16impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
17 /// Load the program into the given pio 17 /// Load the program into the given pio
18 pub fn new(common: &mut Common<'a, PIO>) -> Self { 18 pub fn new(common: &mut Common<'d, PIO>) -> Self {
19 let prg = pio::pio_asm!( 19 let prg = pio::pio_asm!(
20 ".side_set 2", 20 ".side_set 2",
21 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock 21 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock
@@ -37,27 +37,25 @@ impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> {
37} 37}
38 38
39/// Pio backed I2s output driver 39/// Pio backed I2s output driver
40pub struct PioI2sOut<'a, P: Instance, const S: usize> { 40pub struct PioI2sOut<'d, P: Instance, const S: usize> {
41 dma: PeripheralRef<'a, AnyChannel>, 41 dma: Peri<'d, AnyChannel>,
42 sm: StateMachine<'a, P, S>, 42 sm: StateMachine<'d, P, S>,
43} 43}
44 44
45impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> { 45impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
46 /// Configure a state machine to output I2s 46 /// Configure a state machine to output I2s
47 pub fn new( 47 pub fn new(
48 common: &mut Common<'a, P>, 48 common: &mut Common<'d, P>,
49 mut sm: StateMachine<'a, P, S>, 49 mut sm: StateMachine<'d, P, S>,
50 dma: impl Peripheral<P = impl Channel> + 'a, 50 dma: Peri<'d, impl Channel>,
51 data_pin: impl PioPin, 51 data_pin: Peri<'d, impl PioPin>,
52 bit_clock_pin: impl PioPin, 52 bit_clock_pin: Peri<'d, impl PioPin>,
53 lr_clock_pin: impl PioPin, 53 lr_clock_pin: Peri<'d, impl PioPin>,
54 sample_rate: u32, 54 sample_rate: u32,
55 bit_depth: u32, 55 bit_depth: u32,
56 channels: u32, 56 channels: u32,
57 program: &PioI2sOutProgram<'a, P>, 57 program: &PioI2sOutProgram<'d, P>,
58 ) -> Self { 58 ) -> Self {
59 into_ref!(dma);
60
61 let data_pin = common.make_pio_pin(data_pin); 59 let data_pin = common.make_pio_pin(data_pin);
62 let bit_clock_pin = common.make_pio_pin(bit_clock_pin); 60 let bit_clock_pin = common.make_pio_pin(bit_clock_pin);
63 let left_right_clock_pin = common.make_pio_pin(lr_clock_pin); 61 let left_right_clock_pin = common.make_pio_pin(lr_clock_pin);
@@ -82,10 +80,7 @@ impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> {
82 80
83 sm.set_enable(true); 81 sm.set_enable(true);
84 82
85 Self { 83 Self { dma: dma.into(), sm }
86 dma: dma.map_into(),
87 sm,
88 }
89 } 84 }
90 85
91 /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. 86 /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer.
diff --git a/embassy-rp/src/pio_programs/onewire.rs b/embassy-rp/src/pio_programs/onewire.rs
index 040333e76..00783aab0 100644
--- a/embassy-rp/src/pio_programs/onewire.rs
+++ b/embassy-rp/src/pio_programs/onewire.rs
@@ -1,6 +1,7 @@
1//! OneWire pio driver 1//! OneWire pio driver
2 2
3use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine}; 3use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine};
4use crate::Peri;
4 5
5/// This struct represents an onewire driver program 6/// This struct represents an onewire driver program
6pub struct PioOneWireProgram<'a, PIO: Instance> { 7pub struct PioOneWireProgram<'a, PIO: Instance> {
@@ -69,7 +70,7 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> {
69 pub fn new( 70 pub fn new(
70 common: &mut Common<'d, PIO>, 71 common: &mut Common<'d, PIO>,
71 mut sm: StateMachine<'d, PIO, SM>, 72 mut sm: StateMachine<'d, PIO, SM>,
72 pin: impl PioPin, 73 pin: Peri<'d, impl PioPin>,
73 program: &PioOneWireProgram<'d, PIO>, 74 program: &PioOneWireProgram<'d, PIO>,
74 ) -> Self { 75 ) -> Self {
75 let pin = common.make_pio_pin(pin); 76 let pin = common.make_pio_pin(pin);
diff --git a/embassy-rp/src/pio_programs/pwm.rs b/embassy-rp/src/pio_programs/pwm.rs
index 01ffe012a..f0f837bc5 100644
--- a/embassy-rp/src/pio_programs/pwm.rs
+++ b/embassy-rp/src/pio_programs/pwm.rs
@@ -4,9 +4,9 @@ use core::time::Duration;
4 4
5use pio::InstructionOperands; 5use pio::InstructionOperands;
6 6
7use crate::clocks;
8use crate::gpio::Level; 7use crate::gpio::Level;
9use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine}; 8use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine};
9use crate::{clocks, Peri};
10 10
11/// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time 11/// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time
12fn to_pio_cycles(duration: Duration) -> u32 { 12fn to_pio_cycles(duration: Duration) -> u32 {
@@ -52,7 +52,7 @@ impl<'d, T: Instance, const SM: usize> PioPwm<'d, T, SM> {
52 pub fn new( 52 pub fn new(
53 pio: &mut Common<'d, T>, 53 pio: &mut Common<'d, T>,
54 mut sm: StateMachine<'d, T, SM>, 54 mut sm: StateMachine<'d, T, SM>,
55 pin: impl PioPin, 55 pin: Peri<'d, impl PioPin>,
56 program: &PioPwmProgram<'d, T>, 56 program: &PioPwmProgram<'d, T>,
57 ) -> Self { 57 ) -> Self {
58 let pin = pio.make_pio_pin(pin); 58 let pin = pio.make_pio_pin(pin);
diff --git a/embassy-rp/src/pio_programs/rotary_encoder.rs b/embassy-rp/src/pio_programs/rotary_encoder.rs
index f2fb02aca..e520da8a3 100644
--- a/embassy-rp/src/pio_programs/rotary_encoder.rs
+++ b/embassy-rp/src/pio_programs/rotary_encoder.rs
@@ -6,6 +6,7 @@ use crate::gpio::Pull;
6use crate::pio::{ 6use crate::pio::{
7 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, 7 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
8}; 8};
9use crate::Peri;
9 10
10/// This struct represents an Encoder program loaded into pio instruction memory. 11/// This struct represents an Encoder program loaded into pio instruction memory.
11pub struct PioEncoderProgram<'a, PIO: Instance> { 12pub struct PioEncoderProgram<'a, PIO: Instance> {
@@ -33,8 +34,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
33 pub fn new( 34 pub fn new(
34 pio: &mut Common<'d, T>, 35 pio: &mut Common<'d, T>,
35 mut sm: StateMachine<'d, T, SM>, 36 mut sm: StateMachine<'d, T, SM>,
36 pin_a: impl PioPin, 37 pin_a: Peri<'d, impl PioPin>,
37 pin_b: impl PioPin, 38 pin_b: Peri<'d, impl PioPin>,
38 program: &PioEncoderProgram<'d, T>, 39 program: &PioEncoderProgram<'d, T>,
39 ) -> Self { 40 ) -> Self {
40 let mut pin_a = pio.make_pio_pin(pin_a); 41 let mut pin_a = pio.make_pio_pin(pin_a);
diff --git a/embassy-rp/src/pio_programs/stepper.rs b/embassy-rp/src/pio_programs/stepper.rs
index c8f74167d..495191659 100644
--- a/embassy-rp/src/pio_programs/stepper.rs
+++ b/embassy-rp/src/pio_programs/stepper.rs
@@ -7,6 +7,7 @@ use fixed::types::extra::U8;
7use fixed::FixedU32; 7use fixed::FixedU32;
8 8
9use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine}; 9use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine};
10use crate::Peri;
10 11
11/// This struct represents a Stepper driver program loaded into pio instruction memory. 12/// This struct represents a Stepper driver program loaded into pio instruction memory.
12pub struct PioStepperProgram<'a, PIO: Instance> { 13pub struct PioStepperProgram<'a, PIO: Instance> {
@@ -50,10 +51,10 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> {
50 pio: &mut Common<'d, T>, 51 pio: &mut Common<'d, T>,
51 mut sm: StateMachine<'d, T, SM>, 52 mut sm: StateMachine<'d, T, SM>,
52 irq: Irq<'d, T, SM>, 53 irq: Irq<'d, T, SM>,
53 pin0: impl PioPin, 54 pin0: Peri<'d, impl PioPin>,
54 pin1: impl PioPin, 55 pin1: Peri<'d, impl PioPin>,
55 pin2: impl PioPin, 56 pin2: Peri<'d, impl PioPin>,
56 pin3: impl PioPin, 57 pin3: Peri<'d, impl PioPin>,
57 program: &PioStepperProgram<'d, T>, 58 program: &PioStepperProgram<'d, T>,
58 ) -> Self { 59 ) -> Self {
59 let pin0 = pio.make_pio_pin(pin0); 60 let pin0 = pio.make_pio_pin(pin0);
diff --git a/embassy-rp/src/pio_programs/uart.rs b/embassy-rp/src/pio_programs/uart.rs
index 641daca61..04e39a571 100644
--- a/embassy-rp/src/pio_programs/uart.rs
+++ b/embassy-rp/src/pio_programs/uart.rs
@@ -10,15 +10,16 @@ use crate::gpio::Level;
10use crate::pio::{ 10use crate::pio::{
11 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, 11 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
12}; 12};
13use crate::Peri;
13 14
14/// This struct represents a uart tx program loaded into pio instruction memory. 15/// This struct represents a uart tx program loaded into pio instruction memory.
15pub struct PioUartTxProgram<'a, PIO: Instance> { 16pub struct PioUartTxProgram<'d, PIO: Instance> {
16 prg: LoadedProgram<'a, PIO>, 17 prg: LoadedProgram<'d, PIO>,
17} 18}
18 19
19impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> { 20impl<'d, PIO: Instance> PioUartTxProgram<'d, PIO> {
20 /// Load the uart tx program into the given pio 21 /// Load the uart tx program into the given pio
21 pub fn new(common: &mut Common<'a, PIO>) -> Self { 22 pub fn new(common: &mut Common<'d, PIO>) -> Self {
22 let prg = pio::pio_asm!( 23 let prg = pio::pio_asm!(
23 r#" 24 r#"
24 .side_set 1 opt 25 .side_set 1 opt
@@ -41,18 +42,18 @@ impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> {
41} 42}
42 43
43/// PIO backed Uart transmitter 44/// PIO backed Uart transmitter
44pub struct PioUartTx<'a, PIO: Instance, const SM: usize> { 45pub struct PioUartTx<'d, PIO: Instance, const SM: usize> {
45 sm_tx: StateMachine<'a, PIO, SM>, 46 sm_tx: StateMachine<'d, PIO, SM>,
46} 47}
47 48
48impl<'a, PIO: Instance, const SM: usize> PioUartTx<'a, PIO, SM> { 49impl<'d, PIO: Instance, const SM: usize> PioUartTx<'d, PIO, SM> {
49 /// Configure a pio state machine to use the loaded tx program. 50 /// Configure a pio state machine to use the loaded tx program.
50 pub fn new( 51 pub fn new(
51 baud: u32, 52 baud: u32,
52 common: &mut Common<'a, PIO>, 53 common: &mut Common<'d, PIO>,
53 mut sm_tx: StateMachine<'a, PIO, SM>, 54 mut sm_tx: StateMachine<'d, PIO, SM>,
54 tx_pin: impl PioPin, 55 tx_pin: Peri<'d, impl PioPin>,
55 program: &PioUartTxProgram<'a, PIO>, 56 program: &PioUartTxProgram<'d, PIO>,
56 ) -> Self { 57 ) -> Self {
57 let tx_pin = common.make_pio_pin(tx_pin); 58 let tx_pin = common.make_pio_pin(tx_pin);
58 sm_tx.set_pins(Level::High, &[&tx_pin]); 59 sm_tx.set_pins(Level::High, &[&tx_pin]);
@@ -92,13 +93,13 @@ impl<PIO: Instance, const SM: usize> Write for PioUartTx<'_, PIO, SM> {
92} 93}
93 94
94/// This struct represents a Uart Rx program loaded into pio instruction memory. 95/// This struct represents a Uart Rx program loaded into pio instruction memory.
95pub struct PioUartRxProgram<'a, PIO: Instance> { 96pub struct PioUartRxProgram<'d, PIO: Instance> {
96 prg: LoadedProgram<'a, PIO>, 97 prg: LoadedProgram<'d, PIO>,
97} 98}
98 99
99impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> { 100impl<'d, PIO: Instance> PioUartRxProgram<'d, PIO> {
100 /// Load the uart rx program into the given pio 101 /// Load the uart rx program into the given pio
101 pub fn new(common: &mut Common<'a, PIO>) -> Self { 102 pub fn new(common: &mut Common<'d, PIO>) -> Self {
102 let prg = pio::pio_asm!( 103 let prg = pio::pio_asm!(
103 r#" 104 r#"
104 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and 105 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
@@ -130,18 +131,18 @@ impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> {
130} 131}
131 132
132/// PIO backed Uart reciever 133/// PIO backed Uart reciever
133pub struct PioUartRx<'a, PIO: Instance, const SM: usize> { 134pub struct PioUartRx<'d, PIO: Instance, const SM: usize> {
134 sm_rx: StateMachine<'a, PIO, SM>, 135 sm_rx: StateMachine<'d, PIO, SM>,
135} 136}
136 137
137impl<'a, PIO: Instance, const SM: usize> PioUartRx<'a, PIO, SM> { 138impl<'d, PIO: Instance, const SM: usize> PioUartRx<'d, PIO, SM> {
138 /// Configure a pio state machine to use the loaded rx program. 139 /// Configure a pio state machine to use the loaded rx program.
139 pub fn new( 140 pub fn new(
140 baud: u32, 141 baud: u32,
141 common: &mut Common<'a, PIO>, 142 common: &mut Common<'d, PIO>,
142 mut sm_rx: StateMachine<'a, PIO, SM>, 143 mut sm_rx: StateMachine<'d, PIO, SM>,
143 rx_pin: impl PioPin, 144 rx_pin: Peri<'d, impl PioPin>,
144 program: &PioUartRxProgram<'a, PIO>, 145 program: &PioUartRxProgram<'d, PIO>,
145 ) -> Self { 146 ) -> Self {
146 let mut cfg = Config::default(); 147 let mut cfg = Config::default();
147 cfg.use_program(&program.prg, &[]); 148 cfg.use_program(&program.prg, &[]);
diff --git a/embassy-rp/src/pio_programs/ws2812.rs b/embassy-rp/src/pio_programs/ws2812.rs
index 2462a64e6..578937e11 100644
--- a/embassy-rp/src/pio_programs/ws2812.rs
+++ b/embassy-rp/src/pio_programs/ws2812.rs
@@ -9,7 +9,7 @@ use crate::dma::{AnyChannel, Channel};
9use crate::pio::{ 9use crate::pio::{
10 Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, 10 Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
11}; 11};
12use crate::{into_ref, Peripheral, PeripheralRef}; 12use crate::Peri;
13 13
14const T1: u8 = 2; // start bit 14const T1: u8 = 2; // start bit
15const T2: u8 = 5; // data bit 15const T2: u8 = 5; // data bit
@@ -53,7 +53,7 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> {
53/// Pio backed ws2812 driver 53/// Pio backed ws2812 driver
54/// Const N is the number of ws2812 leds attached to this pin 54/// Const N is the number of ws2812 leds attached to this pin
55pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> { 55pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> {
56 dma: PeripheralRef<'d, AnyChannel>, 56 dma: Peri<'d, AnyChannel>,
57 sm: StateMachine<'d, P, S>, 57 sm: StateMachine<'d, P, S>,
58} 58}
59 59
@@ -62,12 +62,10 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
62 pub fn new( 62 pub fn new(
63 pio: &mut Common<'d, P>, 63 pio: &mut Common<'d, P>,
64 mut sm: StateMachine<'d, P, S>, 64 mut sm: StateMachine<'d, P, S>,
65 dma: impl Peripheral<P = impl Channel> + 'd, 65 dma: Peri<'d, impl Channel>,
66 pin: impl PioPin, 66 pin: Peri<'d, impl PioPin>,
67 program: &PioWs2812Program<'d, P>, 67 program: &PioWs2812Program<'d, P>,
68 ) -> Self { 68 ) -> Self {
69 into_ref!(dma);
70
71 // Setup sm0 69 // Setup sm0
72 let mut cfg = Config::default(); 70 let mut cfg = Config::default();
73 71
@@ -95,10 +93,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
95 sm.set_config(&cfg); 93 sm.set_config(&cfg);
96 sm.set_enable(true); 94 sm.set_enable(true);
97 95
98 Self { 96 Self { dma: dma.into(), sm }
99 dma: dma.map_into(),
100 sm,
101 }
102 } 97 }
103 98
104 /// Write a buffer of [smart_leds::RGB8] to the ws2812 string 99 /// Write a buffer of [smart_leds::RGB8] to the ws2812 string
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index 4fb8ade12..f631402a2 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -1,6 +1,6 @@
1//! Pulse Width Modulation (PWM) 1//! Pulse Width Modulation (PWM)
2 2
3use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 3use embassy_hal_internal::{Peri, PeripheralType};
4pub use embedded_hal_1::pwm::SetDutyCycle; 4pub use embedded_hal_1::pwm::SetDutyCycle;
5use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType}; 5use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType};
6use fixed::traits::ToFixed; 6use fixed::traits::ToFixed;
@@ -99,8 +99,8 @@ impl Error for PwmError {
99 99
100/// PWM driver. 100/// PWM driver.
101pub struct Pwm<'d> { 101pub struct Pwm<'d> {
102 pin_a: Option<PeripheralRef<'d, AnyPin>>, 102 pin_a: Option<Peri<'d, AnyPin>>,
103 pin_b: Option<PeripheralRef<'d, AnyPin>>, 103 pin_b: Option<Peri<'d, AnyPin>>,
104 slice: usize, 104 slice: usize,
105} 105}
106 106
@@ -131,8 +131,8 @@ impl<'d> SetDutyCycle for Pwm<'d> {
131impl<'d> Pwm<'d> { 131impl<'d> Pwm<'d> {
132 fn new_inner( 132 fn new_inner(
133 slice: usize, 133 slice: usize,
134 a: Option<PeripheralRef<'d, AnyPin>>, 134 a: Option<Peri<'d, AnyPin>>,
135 b: Option<PeripheralRef<'d, AnyPin>>, 135 b: Option<Peri<'d, AnyPin>>,
136 b_pull: Pull, 136 b_pull: Pull,
137 config: Config, 137 config: Config,
138 divmode: Divmode, 138 divmode: Divmode,
@@ -171,60 +171,34 @@ impl<'d> Pwm<'d> {
171 171
172 /// Create PWM driver without any configured pins. 172 /// Create PWM driver without any configured pins.
173 #[inline] 173 #[inline]
174 pub fn new_free<T: Slice>(slice: impl Peripheral<P = T> + 'd, config: Config) -> Self { 174 pub fn new_free<T: Slice>(slice: Peri<'d, T>, config: Config) -> Self {
175 into_ref!(slice);
176 Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) 175 Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV)
177 } 176 }
178 177
179 /// Create PWM driver with a single 'a' pin as output. 178 /// Create PWM driver with a single 'a' pin as output.
180 #[inline] 179 #[inline]
181 pub fn new_output_a<T: Slice>( 180 pub fn new_output_a<T: Slice>(slice: Peri<'d, T>, a: Peri<'d, impl ChannelAPin<T>>, config: Config) -> Self {
182 slice: impl Peripheral<P = T> + 'd, 181 Self::new_inner(slice.number(), Some(a.into()), None, Pull::None, config, Divmode::DIV)
183 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd,
184 config: Config,
185 ) -> Self {
186 into_ref!(slice, a);
187 Self::new_inner(
188 slice.number(),
189 Some(a.map_into()),
190 None,
191 Pull::None,
192 config,
193 Divmode::DIV,
194 )
195 } 182 }
196 183
197 /// Create PWM driver with a single 'b' pin as output. 184 /// Create PWM driver with a single 'b' pin as output.
198 #[inline] 185 #[inline]
199 pub fn new_output_b<T: Slice>( 186 pub fn new_output_b<T: Slice>(slice: Peri<'d, T>, b: Peri<'d, impl ChannelBPin<T>>, config: Config) -> Self {
200 slice: impl Peripheral<P = T> + 'd, 187 Self::new_inner(slice.number(), None, Some(b.into()), Pull::None, config, Divmode::DIV)
201 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd,
202 config: Config,
203 ) -> Self {
204 into_ref!(slice, b);
205 Self::new_inner(
206 slice.number(),
207 None,
208 Some(b.map_into()),
209 Pull::None,
210 config,
211 Divmode::DIV,
212 )
213 } 188 }
214 189
215 /// Create PWM driver with a 'a' and 'b' pins as output. 190 /// Create PWM driver with a 'a' and 'b' pins as output.
216 #[inline] 191 #[inline]
217 pub fn new_output_ab<T: Slice>( 192 pub fn new_output_ab<T: Slice>(
218 slice: impl Peripheral<P = T> + 'd, 193 slice: Peri<'d, T>,
219 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, 194 a: Peri<'d, impl ChannelAPin<T>>,
220 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 195 b: Peri<'d, impl ChannelBPin<T>>,
221 config: Config, 196 config: Config,
222 ) -> Self { 197 ) -> Self {
223 into_ref!(slice, a, b);
224 Self::new_inner( 198 Self::new_inner(
225 slice.number(), 199 slice.number(),
226 Some(a.map_into()), 200 Some(a.into()),
227 Some(b.map_into()), 201 Some(b.into()),
228 Pull::None, 202 Pull::None,
229 config, 203 config,
230 Divmode::DIV, 204 Divmode::DIV,
@@ -234,31 +208,29 @@ impl<'d> Pwm<'d> {
234 /// Create PWM driver with a single 'b' as input pin. 208 /// Create PWM driver with a single 'b' as input pin.
235 #[inline] 209 #[inline]
236 pub fn new_input<T: Slice>( 210 pub fn new_input<T: Slice>(
237 slice: impl Peripheral<P = T> + 'd, 211 slice: Peri<'d, T>,
238 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 212 b: Peri<'d, impl ChannelBPin<T>>,
239 b_pull: Pull, 213 b_pull: Pull,
240 mode: InputMode, 214 mode: InputMode,
241 config: Config, 215 config: Config,
242 ) -> Self { 216 ) -> Self {
243 into_ref!(slice, b); 217 Self::new_inner(slice.number(), None, Some(b.into()), b_pull, config, mode.into())
244 Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into())
245 } 218 }
246 219
247 /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. 220 /// Create PWM driver with a 'a' and 'b' pins in the desired input mode.
248 #[inline] 221 #[inline]
249 pub fn new_output_input<T: Slice>( 222 pub fn new_output_input<T: Slice>(
250 slice: impl Peripheral<P = T> + 'd, 223 slice: Peri<'d, T>,
251 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, 224 a: Peri<'d, impl ChannelAPin<T>>,
252 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 225 b: Peri<'d, impl ChannelBPin<T>>,
253 b_pull: Pull, 226 b_pull: Pull,
254 mode: InputMode, 227 mode: InputMode,
255 config: Config, 228 config: Config,
256 ) -> Self { 229 ) -> Self {
257 into_ref!(slice, a, b);
258 Self::new_inner( 230 Self::new_inner(
259 slice.number(), 231 slice.number(),
260 Some(a.map_into()), 232 Some(a.into()),
261 Some(b.map_into()), 233 Some(b.into()),
262 b_pull, 234 b_pull,
263 config, 235 config,
264 mode.into(), 236 mode.into(),
@@ -373,8 +345,8 @@ impl<'d> Pwm<'d> {
373} 345}
374 346
375enum PwmChannelPin<'d> { 347enum PwmChannelPin<'d> {
376 A(PeripheralRef<'d, AnyPin>), 348 A(Peri<'d, AnyPin>),
377 B(PeripheralRef<'d, AnyPin>), 349 B(Peri<'d, AnyPin>),
378} 350}
379 351
380/// Single channel of Pwm driver. 352/// Single channel of Pwm driver.
@@ -498,7 +470,7 @@ trait SealedSlice {}
498 470
499/// PWM Slice. 471/// PWM Slice.
500#[allow(private_bounds)] 472#[allow(private_bounds)]
501pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { 473pub trait Slice: PeripheralType + SealedSlice + Sized + 'static {
502 /// Slice number. 474 /// Slice number.
503 fn number(&self) -> usize; 475 fn number(&self) -> usize;
504} 476}
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index 2ce7ac645..63cf91d28 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -1,7 +1,7 @@
1//! RTC driver. 1//! RTC driver.
2mod filter; 2mod filter;
3 3
4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 4use embassy_hal_internal::{Peri, PeripheralType};
5 5
6pub use self::filter::DateTimeFilter; 6pub use self::filter::DateTimeFilter;
7 7
@@ -14,7 +14,7 @@ use crate::clocks::clk_rtc_freq;
14 14
15/// A reference to the real time clock of the system 15/// A reference to the real time clock of the system
16pub struct Rtc<'d, T: Instance> { 16pub struct Rtc<'d, T: Instance> {
17 inner: PeripheralRef<'d, T>, 17 inner: Peri<'d, T>,
18} 18}
19 19
20impl<'d, T: Instance> Rtc<'d, T> { 20impl<'d, T: Instance> Rtc<'d, T> {
@@ -23,9 +23,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
23 /// # Errors 23 /// # Errors
24 /// 24 ///
25 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. 25 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
26 pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self { 26 pub fn new(inner: Peri<'d, T>) -> Self {
27 into_ref!(inner);
28
29 // Set the RTC divider 27 // Set the RTC divider
30 inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1)); 28 inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
31 29
@@ -194,7 +192,7 @@ trait SealedInstance {
194 192
195/// RTC peripheral instance. 193/// RTC peripheral instance.
196#[allow(private_bounds)] 194#[allow(private_bounds)]
197pub trait Instance: SealedInstance {} 195pub trait Instance: SealedInstance + PeripheralType {}
198 196
199impl SealedInstance for crate::peripherals::RTC { 197impl SealedInstance for crate::peripherals::RTC {
200 fn regs(&self) -> crate::pac::rtc::Rtc { 198 fn regs(&self) -> crate::pac::rtc::Rtc {
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index c48b5c54f..559b3b909 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -3,12 +3,12 @@ use core::marker::PhantomData;
3 3
4use embassy_embedded_hal::SetConfig; 4use embassy_embedded_hal::SetConfig;
5use embassy_futures::join::join; 5use embassy_futures::join::join;
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{Peri, PeripheralType};
7pub use embedded_hal_02::spi::{Phase, Polarity}; 7pub use embedded_hal_02::spi::{Phase, Polarity};
8 8
9use crate::dma::{AnyChannel, Channel}; 9use crate::dma::{AnyChannel, Channel};
10use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; 10use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
11use crate::{pac, peripherals, Peripheral}; 11use crate::{pac, peripherals};
12 12
13/// SPI errors. 13/// SPI errors.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)] 14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -42,9 +42,9 @@ impl Default for Config {
42 42
43/// SPI driver. 43/// SPI driver.
44pub struct Spi<'d, T: Instance, M: Mode> { 44pub struct Spi<'d, T: Instance, M: Mode> {
45 inner: PeripheralRef<'d, T>, 45 inner: Peri<'d, T>,
46 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 46 tx_dma: Option<Peri<'d, AnyChannel>>,
47 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 47 rx_dma: Option<Peri<'d, AnyChannel>>,
48 phantom: PhantomData<(&'d mut T, M)>, 48 phantom: PhantomData<(&'d mut T, M)>,
49} 49}
50 50
@@ -73,17 +73,15 @@ fn calc_prescs(freq: u32) -> (u8, u8) {
73 73
74impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { 74impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
75 fn new_inner( 75 fn new_inner(
76 inner: impl Peripheral<P = T> + 'd, 76 inner: Peri<'d, T>,
77 clk: Option<PeripheralRef<'d, AnyPin>>, 77 clk: Option<Peri<'d, AnyPin>>,
78 mosi: Option<PeripheralRef<'d, AnyPin>>, 78 mosi: Option<Peri<'d, AnyPin>>,
79 miso: Option<PeripheralRef<'d, AnyPin>>, 79 miso: Option<Peri<'d, AnyPin>>,
80 cs: Option<PeripheralRef<'d, AnyPin>>, 80 cs: Option<Peri<'d, AnyPin>>,
81 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 81 tx_dma: Option<Peri<'d, AnyChannel>>,
82 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 82 rx_dma: Option<Peri<'d, AnyChannel>>,
83 config: Config, 83 config: Config,
84 ) -> Self { 84 ) -> Self {
85 into_ref!(inner);
86
87 Self::apply_config(&inner, &config); 85 Self::apply_config(&inner, &config);
88 86
89 let p = inner.regs(); 87 let p = inner.regs();
@@ -161,7 +159,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
161 /// 159 ///
162 /// Driver should be disabled before making changes and reenabled after the modifications 160 /// Driver should be disabled before making changes and reenabled after the modifications
163 /// are applied. 161 /// are applied.
164 fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) { 162 fn apply_config(inner: &Peri<'d, T>, config: &Config) {
165 let p = inner.regs(); 163 let p = inner.regs();
166 let (presc, postdiv) = calc_prescs(config.frequency); 164 let (presc, postdiv) = calc_prescs(config.frequency);
167 165
@@ -273,18 +271,17 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
273impl<'d, T: Instance> Spi<'d, T, Blocking> { 271impl<'d, T: Instance> Spi<'d, T, Blocking> {
274 /// Create an SPI driver in blocking mode. 272 /// Create an SPI driver in blocking mode.
275 pub fn new_blocking( 273 pub fn new_blocking(
276 inner: impl Peripheral<P = T> + 'd, 274 inner: Peri<'d, T>,
277 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 275 clk: Peri<'d, impl ClkPin<T> + 'd>,
278 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 276 mosi: Peri<'d, impl MosiPin<T> + 'd>,
279 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 277 miso: Peri<'d, impl MisoPin<T> + 'd>,
280 config: Config, 278 config: Config,
281 ) -> Self { 279 ) -> Self {
282 into_ref!(clk, mosi, miso);
283 Self::new_inner( 280 Self::new_inner(
284 inner, 281 inner,
285 Some(clk.map_into()), 282 Some(clk.into()),
286 Some(mosi.map_into()), 283 Some(mosi.into()),
287 Some(miso.map_into()), 284 Some(miso.into()),
288 None, 285 None,
289 None, 286 None,
290 None, 287 None,
@@ -294,16 +291,15 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
294 291
295 /// Create an SPI driver in blocking mode supporting writes only. 292 /// Create an SPI driver in blocking mode supporting writes only.
296 pub fn new_blocking_txonly( 293 pub fn new_blocking_txonly(
297 inner: impl Peripheral<P = T> + 'd, 294 inner: Peri<'d, T>,
298 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 295 clk: Peri<'d, impl ClkPin<T> + 'd>,
299 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 296 mosi: Peri<'d, impl MosiPin<T> + 'd>,
300 config: Config, 297 config: Config,
301 ) -> Self { 298 ) -> Self {
302 into_ref!(clk, mosi);
303 Self::new_inner( 299 Self::new_inner(
304 inner, 300 inner,
305 Some(clk.map_into()), 301 Some(clk.into()),
306 Some(mosi.map_into()), 302 Some(mosi.into()),
307 None, 303 None,
308 None, 304 None,
309 None, 305 None,
@@ -314,17 +310,16 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
314 310
315 /// Create an SPI driver in blocking mode supporting reads only. 311 /// Create an SPI driver in blocking mode supporting reads only.
316 pub fn new_blocking_rxonly( 312 pub fn new_blocking_rxonly(
317 inner: impl Peripheral<P = T> + 'd, 313 inner: Peri<'d, T>,
318 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 314 clk: Peri<'d, impl ClkPin<T> + 'd>,
319 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 315 miso: Peri<'d, impl MisoPin<T> + 'd>,
320 config: Config, 316 config: Config,
321 ) -> Self { 317 ) -> Self {
322 into_ref!(clk, miso);
323 Self::new_inner( 318 Self::new_inner(
324 inner, 319 inner,
325 Some(clk.map_into()), 320 Some(clk.into()),
326 None, 321 None,
327 Some(miso.map_into()), 322 Some(miso.into()),
328 None, 323 None,
329 None, 324 None,
330 None, 325 None,
@@ -336,43 +331,41 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
336impl<'d, T: Instance> Spi<'d, T, Async> { 331impl<'d, T: Instance> Spi<'d, T, Async> {
337 /// Create an SPI driver in async mode supporting DMA operations. 332 /// Create an SPI driver in async mode supporting DMA operations.
338 pub fn new( 333 pub fn new(
339 inner: impl Peripheral<P = T> + 'd, 334 inner: Peri<'d, T>,
340 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 335 clk: Peri<'d, impl ClkPin<T> + 'd>,
341 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 336 mosi: Peri<'d, impl MosiPin<T> + 'd>,
342 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 337 miso: Peri<'d, impl MisoPin<T> + 'd>,
343 tx_dma: impl Peripheral<P = impl Channel> + 'd, 338 tx_dma: Peri<'d, impl Channel>,
344 rx_dma: impl Peripheral<P = impl Channel> + 'd, 339 rx_dma: Peri<'d, impl Channel>,
345 config: Config, 340 config: Config,
346 ) -> Self { 341 ) -> Self {
347 into_ref!(tx_dma, rx_dma, clk, mosi, miso);
348 Self::new_inner( 342 Self::new_inner(
349 inner, 343 inner,
350 Some(clk.map_into()), 344 Some(clk.into()),
351 Some(mosi.map_into()), 345 Some(mosi.into()),
352 Some(miso.map_into()), 346 Some(miso.into()),
353 None, 347 None,
354 Some(tx_dma.map_into()), 348 Some(tx_dma.into()),
355 Some(rx_dma.map_into()), 349 Some(rx_dma.into()),
356 config, 350 config,
357 ) 351 )
358 } 352 }
359 353
360 /// Create an SPI driver in async mode supporting DMA write operations only. 354 /// Create an SPI driver in async mode supporting DMA write operations only.
361 pub fn new_txonly( 355 pub fn new_txonly(
362 inner: impl Peripheral<P = T> + 'd, 356 inner: Peri<'d, T>,
363 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 357 clk: Peri<'d, impl ClkPin<T> + 'd>,
364 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 358 mosi: Peri<'d, impl MosiPin<T> + 'd>,
365 tx_dma: impl Peripheral<P = impl Channel> + 'd, 359 tx_dma: Peri<'d, impl Channel>,
366 config: Config, 360 config: Config,
367 ) -> Self { 361 ) -> Self {
368 into_ref!(tx_dma, clk, mosi);
369 Self::new_inner( 362 Self::new_inner(
370 inner, 363 inner,
371 Some(clk.map_into()), 364 Some(clk.into()),
372 Some(mosi.map_into()), 365 Some(mosi.into()),
373 None, 366 None,
374 None, 367 None,
375 Some(tx_dma.map_into()), 368 Some(tx_dma.into()),
376 None, 369 None,
377 config, 370 config,
378 ) 371 )
@@ -380,29 +373,28 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
380 373
381 /// Create an SPI driver in async mode supporting DMA read operations only. 374 /// Create an SPI driver in async mode supporting DMA read operations only.
382 pub fn new_rxonly( 375 pub fn new_rxonly(
383 inner: impl Peripheral<P = T> + 'd, 376 inner: Peri<'d, T>,
384 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 377 clk: Peri<'d, impl ClkPin<T> + 'd>,
385 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 378 miso: Peri<'d, impl MisoPin<T> + 'd>,
386 tx_dma: impl Peripheral<P = impl Channel> + 'd, 379 tx_dma: Peri<'d, impl Channel>,
387 rx_dma: impl Peripheral<P = impl Channel> + 'd, 380 rx_dma: Peri<'d, impl Channel>,
388 config: Config, 381 config: Config,
389 ) -> Self { 382 ) -> Self {
390 into_ref!(tx_dma, rx_dma, clk, miso);
391 Self::new_inner( 383 Self::new_inner(
392 inner, 384 inner,
393 Some(clk.map_into()), 385 Some(clk.into()),
394 None, 386 None,
395 Some(miso.map_into()), 387 Some(miso.into()),
396 None, 388 None,
397 Some(tx_dma.map_into()), 389 Some(tx_dma.into()),
398 Some(rx_dma.map_into()), 390 Some(rx_dma.into()),
399 config, 391 config,
400 ) 392 )
401 } 393 }
402 394
403 /// Write data to SPI using DMA. 395 /// Write data to SPI using DMA.
404 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 396 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
405 let tx_ch = self.tx_dma.as_mut().unwrap(); 397 let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
406 let tx_transfer = unsafe { 398 let tx_transfer = unsafe {
407 // If we don't assign future to a variable, the data register pointer 399 // If we don't assign future to a variable, the data register pointer
408 // is held across an await and makes the future non-Send. 400 // is held across an await and makes the future non-Send.
@@ -427,14 +419,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
427 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 419 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
428 // Start RX first. Transfer starts when TX starts, if RX 420 // Start RX first. Transfer starts when TX starts, if RX
429 // is not started yet we might lose bytes. 421 // is not started yet we might lose bytes.
430 let rx_ch = self.rx_dma.as_mut().unwrap(); 422 let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
431 let rx_transfer = unsafe { 423 let rx_transfer = unsafe {
432 // If we don't assign future to a variable, the data register pointer 424 // If we don't assign future to a variable, the data register pointer
433 // is held across an await and makes the future non-Send. 425 // is held across an await and makes the future non-Send.
434 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ) 426 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ)
435 }; 427 };
436 428
437 let tx_ch = self.tx_dma.as_mut().unwrap(); 429 let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
438 let tx_transfer = unsafe { 430 let tx_transfer = unsafe {
439 // If we don't assign future to a variable, the data register pointer 431 // If we don't assign future to a variable, the data register pointer
440 // is held across an await and makes the future non-Send. 432 // is held across an await and makes the future non-Send.
@@ -462,20 +454,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
462 async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 454 async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
463 // Start RX first. Transfer starts when TX starts, if RX 455 // Start RX first. Transfer starts when TX starts, if RX
464 // is not started yet we might lose bytes. 456 // is not started yet we might lose bytes.
465 let rx_ch = self.rx_dma.as_mut().unwrap(); 457 let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
466 let rx_transfer = unsafe { 458 let rx_transfer = unsafe {
467 // If we don't assign future to a variable, the data register pointer 459 // If we don't assign future to a variable, the data register pointer
468 // is held across an await and makes the future non-Send. 460 // is held across an await and makes the future non-Send.
469 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ) 461 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ)
470 }; 462 };
471 463
472 let mut tx_ch = self.tx_dma.as_mut().unwrap(); 464 let mut tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
473 // If we don't assign future to a variable, the data register pointer 465 // If we don't assign future to a variable, the data register pointer
474 // is held across an await and makes the future non-Send. 466 // is held across an await and makes the future non-Send.
475 let tx_transfer = async { 467 let tx_transfer = async {
476 let p = self.inner.regs(); 468 let p = self.inner.regs();
477 unsafe { 469 unsafe {
478 crate::dma::write(&mut tx_ch, tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await; 470 crate::dma::write(tx_ch.reborrow(), tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
479 471
480 if rx.len() > tx.len() { 472 if rx.len() > tx.len() {
481 let write_bytes_len = rx.len() - tx.len(); 473 let write_bytes_len = rx.len() - tx.len();
@@ -519,7 +511,7 @@ pub trait Mode: SealedMode {}
519 511
520/// SPI instance trait. 512/// SPI instance trait.
521#[allow(private_bounds)] 513#[allow(private_bounds)]
522pub trait Instance: SealedInstance {} 514pub trait Instance: SealedInstance + PeripheralType {}
523 515
524macro_rules! impl_instance { 516macro_rules! impl_instance {
525 ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { 517 ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => {
diff --git a/embassy-rp/src/trng.rs b/embassy-rp/src/trng.rs
index 9f2f33c4b..44b1bb996 100644
--- a/embassy-rp/src/trng.rs
+++ b/embassy-rp/src/trng.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomData;
5use core::ops::Not; 5use core::ops::Not;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::Peripheral; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::Error; 10use rand_core::Error;
11 11
@@ -20,7 +20,7 @@ trait SealedInstance {
20 20
21/// TRNG peripheral instance. 21/// TRNG peripheral instance.
22#[allow(private_bounds)] 22#[allow(private_bounds)]
23pub trait Instance: SealedInstance { 23pub trait Instance: SealedInstance + PeripheralType {
24 /// Interrupt for this peripheral. 24 /// Interrupt for this peripheral.
25 type Interrupt: Interrupt; 25 type Interrupt: Interrupt;
26} 26}
@@ -158,11 +158,7 @@ const TRNG_BLOCK_SIZE_BYTES: usize = TRNG_BLOCK_SIZE_BITS / 8;
158 158
159impl<'d, T: Instance> Trng<'d, T> { 159impl<'d, T: Instance> Trng<'d, T> {
160 /// Create a new TRNG driver. 160 /// Create a new TRNG driver.
161 pub fn new( 161 pub fn new(_trng: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd, config: Config) -> Self {
162 _trng: impl Peripheral<P = T> + 'd,
163 _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
164 config: Config,
165 ) -> Self {
166 let regs = T::regs(); 162 let regs = T::regs();
167 163
168 regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false)); 164 regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false));
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 152a432c9..5b5159d22 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -90,17 +90,15 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
90impl<'d, T: Instance> BufferedUart<'d, T> { 90impl<'d, T: Instance> BufferedUart<'d, T> {
91 /// Create a buffered UART instance. 91 /// Create a buffered UART instance.
92 pub fn new( 92 pub fn new(
93 _uart: impl Peripheral<P = T> + 'd, 93 _uart: Peri<'d, T>,
94 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 94 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
95 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 95 tx: Peri<'d, impl TxPin<T>>,
96 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 96 rx: Peri<'d, impl RxPin<T>>,
97 tx_buffer: &'d mut [u8], 97 tx_buffer: &'d mut [u8],
98 rx_buffer: &'d mut [u8], 98 rx_buffer: &'d mut [u8],
99 config: Config, 99 config: Config,
100 ) -> Self { 100 ) -> Self {
101 into_ref!(tx, rx); 101 super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config);
102
103 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
104 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); 102 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
105 103
106 Self { 104 Self {
@@ -111,23 +109,21 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
111 109
112 /// Create a buffered UART instance with flow control. 110 /// Create a buffered UART instance with flow control.
113 pub fn new_with_rtscts( 111 pub fn new_with_rtscts(
114 _uart: impl Peripheral<P = T> + 'd, 112 _uart: Peri<'d, T>,
115 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 113 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
116 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 114 tx: Peri<'d, impl TxPin<T>>,
117 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 115 rx: Peri<'d, impl RxPin<T>>,
118 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 116 rts: Peri<'d, impl RtsPin<T>>,
119 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 117 cts: Peri<'d, impl CtsPin<T>>,
120 tx_buffer: &'d mut [u8], 118 tx_buffer: &'d mut [u8],
121 rx_buffer: &'d mut [u8], 119 rx_buffer: &'d mut [u8],
122 config: Config, 120 config: Config,
123 ) -> Self { 121 ) -> Self {
124 into_ref!(tx, rx, cts, rts);
125
126 super::Uart::<'d, T, Async>::init( 122 super::Uart::<'d, T, Async>::init(
127 Some(tx.map_into()), 123 Some(tx.into()),
128 Some(rx.map_into()), 124 Some(rx.into()),
129 Some(rts.map_into()), 125 Some(rts.into()),
130 Some(cts.map_into()), 126 Some(cts.into()),
131 config, 127 config,
132 ); 128 );
133 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); 129 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
@@ -184,15 +180,13 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
184impl<'d, T: Instance> BufferedUartRx<'d, T> { 180impl<'d, T: Instance> BufferedUartRx<'d, T> {
185 /// Create a new buffered UART RX. 181 /// Create a new buffered UART RX.
186 pub fn new( 182 pub fn new(
187 _uart: impl Peripheral<P = T> + 'd, 183 _uart: Peri<'d, T>,
188 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 184 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
189 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 185 rx: Peri<'d, impl RxPin<T>>,
190 rx_buffer: &'d mut [u8], 186 rx_buffer: &'d mut [u8],
191 config: Config, 187 config: Config,
192 ) -> Self { 188 ) -> Self {
193 into_ref!(rx); 189 super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config);
194
195 super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
196 init_buffers::<T>(irq, None, Some(rx_buffer)); 190 init_buffers::<T>(irq, None, Some(rx_buffer));
197 191
198 Self { phantom: PhantomData } 192 Self { phantom: PhantomData }
@@ -200,16 +194,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
200 194
201 /// Create a new buffered UART RX with flow control. 195 /// Create a new buffered UART RX with flow control.
202 pub fn new_with_rts( 196 pub fn new_with_rts(
203 _uart: impl Peripheral<P = T> + 'd, 197 _uart: Peri<'d, T>,
204 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 198 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
205 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 199 rx: Peri<'d, impl RxPin<T>>,
206 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 200 rts: Peri<'d, impl RtsPin<T>>,
207 rx_buffer: &'d mut [u8], 201 rx_buffer: &'d mut [u8],
208 config: Config, 202 config: Config,
209 ) -> Self { 203 ) -> Self {
210 into_ref!(rx, rts); 204 super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config);
211
212 super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
213 init_buffers::<T>(irq, None, Some(rx_buffer)); 205 init_buffers::<T>(irq, None, Some(rx_buffer));
214 206
215 Self { phantom: PhantomData } 207 Self { phantom: PhantomData }
@@ -338,15 +330,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
338impl<'d, T: Instance> BufferedUartTx<'d, T> { 330impl<'d, T: Instance> BufferedUartTx<'d, T> {
339 /// Create a new buffered UART TX. 331 /// Create a new buffered UART TX.
340 pub fn new( 332 pub fn new(
341 _uart: impl Peripheral<P = T> + 'd, 333 _uart: Peri<'d, T>,
342 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 334 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
343 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 335 tx: Peri<'d, impl TxPin<T>>,
344 tx_buffer: &'d mut [u8], 336 tx_buffer: &'d mut [u8],
345 config: Config, 337 config: Config,
346 ) -> Self { 338 ) -> Self {
347 into_ref!(tx); 339 super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config);
348
349 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
350 init_buffers::<T>(irq, Some(tx_buffer), None); 340 init_buffers::<T>(irq, Some(tx_buffer), None);
351 341
352 Self { phantom: PhantomData } 342 Self { phantom: PhantomData }
@@ -354,16 +344,14 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
354 344
355 /// Create a new buffered UART TX with flow control. 345 /// Create a new buffered UART TX with flow control.
356 pub fn new_with_cts( 346 pub fn new_with_cts(
357 _uart: impl Peripheral<P = T> + 'd, 347 _uart: Peri<'d, T>,
358 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 348 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
359 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 349 tx: Peri<'d, impl TxPin<T>>,
360 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 350 cts: Peri<'d, impl CtsPin<T>>,
361 tx_buffer: &'d mut [u8], 351 tx_buffer: &'d mut [u8],
362 config: Config, 352 config: Config,
363 ) -> Self { 353 ) -> Self {
364 into_ref!(tx, cts); 354 super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config);
365
366 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
367 init_buffers::<T>(irq, Some(tx_buffer), None); 355 init_buffers::<T>(irq, Some(tx_buffer), None);
368 356
369 Self { phantom: PhantomData } 357 Self { phantom: PhantomData }
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 8d12aeef6..90c7655be 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5 5
6use atomic_polyfill::{AtomicU16, Ordering}; 6use atomic_polyfill::{AtomicU16, Ordering};
7use embassy_futures::select::{select, Either}; 7use embassy_futures::select::{select, Either};
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use embassy_time::{Delay, Timer}; 10use embassy_time::{Delay, Timer};
11use pac::uart::regs::Uartris; 11use pac::uart::regs::Uartris;
@@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel};
15use crate::gpio::{AnyPin, SealedPin}; 15use crate::gpio::{AnyPin, SealedPin};
16use crate::interrupt::typelevel::{Binding, Interrupt}; 16use crate::interrupt::typelevel::{Binding, Interrupt};
17use crate::pac::io::vals::{Inover, Outover}; 17use crate::pac::io::vals::{Inover, Outover};
18use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 18use crate::{interrupt, pac, peripherals, RegExt};
19 19
20mod buffered; 20mod buffered;
21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; 21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
@@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> {
142 142
143/// UART TX driver. 143/// UART TX driver.
144pub struct UartTx<'d, T: Instance, M: Mode> { 144pub struct UartTx<'d, T: Instance, M: Mode> {
145 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 145 tx_dma: Option<Peri<'d, AnyChannel>>,
146 phantom: PhantomData<(&'d mut T, M)>, 146 phantom: PhantomData<(&'d mut T, M)>,
147} 147}
148 148
149/// UART RX driver. 149/// UART RX driver.
150pub struct UartRx<'d, T: Instance, M: Mode> { 150pub struct UartRx<'d, T: Instance, M: Mode> {
151 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 151 rx_dma: Option<Peri<'d, AnyChannel>>,
152 phantom: PhantomData<(&'d mut T, M)>, 152 phantom: PhantomData<(&'d mut T, M)>,
153} 153}
154 154
155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { 155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
156 /// Create a new DMA-enabled UART which can only send data 156 /// Create a new DMA-enabled UART which can only send data
157 pub fn new( 157 pub fn new(
158 _uart: impl Peripheral<P = T> + 'd, 158 _uart: Peri<'d, T>,
159 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 159 tx: Peri<'d, impl TxPin<T>>,
160 tx_dma: impl Peripheral<P = impl Channel> + 'd, 160 tx_dma: Peri<'d, impl Channel>,
161 config: Config, 161 config: Config,
162 ) -> Self { 162 ) -> Self {
163 into_ref!(tx, tx_dma); 163 Uart::<T, M>::init(Some(tx.into()), None, None, None, config);
164 Uart::<T, M>::init(Some(tx.map_into()), None, None, None, config); 164 Self::new_inner(Some(tx_dma.into()))
165 Self::new_inner(Some(tx_dma.map_into()))
166 } 165 }
167 166
168 fn new_inner(tx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 167 fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
169 Self { 168 Self {
170 tx_dma, 169 tx_dma,
171 phantom: PhantomData, 170 phantom: PhantomData,
@@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
225 224
226impl<'d, T: Instance> UartTx<'d, T, Blocking> { 225impl<'d, T: Instance> UartTx<'d, T, Blocking> {
227 /// Create a new UART TX instance for blocking mode operations. 226 /// Create a new UART TX instance for blocking mode operations.
228 pub fn new_blocking( 227 pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
229 _uart: impl Peripheral<P = T> + 'd, 228 Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config);
230 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
231 config: Config,
232 ) -> Self {
233 into_ref!(tx);
234 Uart::<T, Blocking>::init(Some(tx.map_into()), None, None, None, config);
235 Self::new_inner(None) 229 Self::new_inner(None)
236 } 230 }
237 231
@@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
251impl<'d, T: Instance> UartTx<'d, T, Async> { 245impl<'d, T: Instance> UartTx<'d, T, Async> {
252 /// Write to UART TX from the provided buffer using DMA. 246 /// Write to UART TX from the provided buffer using DMA.
253 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 247 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
254 let ch = self.tx_dma.as_mut().unwrap(); 248 let ch = self.tx_dma.as_mut().unwrap().reborrow();
255 let transfer = unsafe { 249 let transfer = unsafe {
256 T::regs().uartdmacr().write_set(|reg| { 250 T::regs().uartdmacr().write_set(|reg| {
257 reg.set_txdmae(true); 251 reg.set_txdmae(true);
@@ -268,18 +262,17 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
268impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { 262impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
269 /// Create a new DMA-enabled UART which can only receive data 263 /// Create a new DMA-enabled UART which can only receive data
270 pub fn new( 264 pub fn new(
271 _uart: impl Peripheral<P = T> + 'd, 265 _uart: Peri<'d, T>,
272 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 266 rx: Peri<'d, impl RxPin<T>>,
273 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 267 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
274 rx_dma: impl Peripheral<P = impl Channel> + 'd, 268 rx_dma: Peri<'d, impl Channel>,
275 config: Config, 269 config: Config,
276 ) -> Self { 270 ) -> Self {
277 into_ref!(rx, rx_dma); 271 Uart::<T, M>::init(None, Some(rx.into()), None, None, config);
278 Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config); 272 Self::new_inner(true, Some(rx_dma.into()))
279 Self::new_inner(true, Some(rx_dma.map_into()))
280 } 273 }
281 274
282 fn new_inner(has_irq: bool, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 275 fn new_inner(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
283 debug_assert_eq!(has_irq, rx_dma.is_some()); 276 debug_assert_eq!(has_irq, rx_dma.is_some());
284 if has_irq { 277 if has_irq {
285 // disable all error interrupts initially 278 // disable all error interrupts initially
@@ -346,13 +339,8 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
346 339
347impl<'d, T: Instance> UartRx<'d, T, Blocking> { 340impl<'d, T: Instance> UartRx<'d, T, Blocking> {
348 /// Create a new UART RX instance for blocking mode operations. 341 /// Create a new UART RX instance for blocking mode operations.
349 pub fn new_blocking( 342 pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
350 _uart: impl Peripheral<P = T> + 'd, 343 Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config);
351 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
352 config: Config,
353 ) -> Self {
354 into_ref!(rx);
355 Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
356 Self::new_inner(false, None) 344 Self::new_inner(false, None)
357 } 345 }
358 346
@@ -419,7 +407,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
419 // start a dma transfer. if errors have happened in the interim some error 407 // start a dma transfer. if errors have happened in the interim some error
420 // interrupt flags will have been raised, and those will be picked up immediately 408 // interrupt flags will have been raised, and those will be picked up immediately
421 // by the interrupt handler. 409 // by the interrupt handler.
422 let ch = self.rx_dma.as_mut().unwrap(); 410 let ch = self.rx_dma.as_mut().unwrap().reborrow();
423 T::regs().uartimsc().write_set(|w| { 411 T::regs().uartimsc().write_set(|w| {
424 w.set_oeim(true); 412 w.set_oeim(true);
425 w.set_beim(true); 413 w.set_beim(true);
@@ -566,7 +554,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
566 // start a dma transfer. if errors have happened in the interim some error 554 // start a dma transfer. if errors have happened in the interim some error
567 // interrupt flags will have been raised, and those will be picked up immediately 555 // interrupt flags will have been raised, and those will be picked up immediately
568 // by the interrupt handler. 556 // by the interrupt handler.
569 let mut ch = self.rx_dma.as_mut().unwrap(); 557 let ch = self.rx_dma.as_mut().unwrap();
570 T::regs().uartimsc().write_set(|w| { 558 T::regs().uartimsc().write_set(|w| {
571 w.set_oeim(true); 559 w.set_oeim(true);
572 w.set_beim(true); 560 w.set_beim(true);
@@ -583,7 +571,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
583 // If we don't assign future to a variable, the data register pointer 571 // If we don't assign future to a variable, the data register pointer
584 // is held across an await and makes the future non-Send. 572 // is held across an await and makes the future non-Send.
585 crate::dma::read( 573 crate::dma::read(
586 &mut ch, 574 ch.reborrow(),
587 T::regs().uartdr().as_ptr() as *const _, 575 T::regs().uartdr().as_ptr() as *const _,
588 sbuffer, 576 sbuffer,
589 T::RX_DREQ.into(), 577 T::RX_DREQ.into(),
@@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
700impl<'d, T: Instance> Uart<'d, T, Blocking> { 688impl<'d, T: Instance> Uart<'d, T, Blocking> {
701 /// Create a new UART without hardware flow control 689 /// Create a new UART without hardware flow control
702 pub fn new_blocking( 690 pub fn new_blocking(
703 uart: impl Peripheral<P = T> + 'd, 691 uart: Peri<'d, T>,
704 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 692 tx: Peri<'d, impl TxPin<T>>,
705 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 693 rx: Peri<'d, impl RxPin<T>>,
706 config: Config, 694 config: Config,
707 ) -> Self { 695 ) -> Self {
708 into_ref!(tx, rx); 696 Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config)
709 Self::new_inner(
710 uart,
711 tx.map_into(),
712 rx.map_into(),
713 None,
714 None,
715 false,
716 None,
717 None,
718 config,
719 )
720 } 697 }
721 698
722 /// Create a new UART with hardware flow control (RTS/CTS) 699 /// Create a new UART with hardware flow control (RTS/CTS)
723 pub fn new_with_rtscts_blocking( 700 pub fn new_with_rtscts_blocking(
724 uart: impl Peripheral<P = T> + 'd, 701 uart: Peri<'d, T>,
725 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 702 tx: Peri<'d, impl TxPin<T>>,
726 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 703 rx: Peri<'d, impl RxPin<T>>,
727 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 704 rts: Peri<'d, impl RtsPin<T>>,
728 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 705 cts: Peri<'d, impl CtsPin<T>>,
729 config: Config, 706 config: Config,
730 ) -> Self { 707 ) -> Self {
731 into_ref!(tx, rx, cts, rts);
732 Self::new_inner( 708 Self::new_inner(
733 uart, 709 uart,
734 tx.map_into(), 710 tx.into(),
735 rx.map_into(), 711 rx.into(),
736 Some(rts.map_into()), 712 Some(rts.into()),
737 Some(cts.map_into()), 713 Some(cts.into()),
738 false, 714 false,
739 None, 715 None,
740 None, 716 None,
@@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
762impl<'d, T: Instance> Uart<'d, T, Async> { 738impl<'d, T: Instance> Uart<'d, T, Async> {
763 /// Create a new DMA enabled UART without hardware flow control 739 /// Create a new DMA enabled UART without hardware flow control
764 pub fn new( 740 pub fn new(
765 uart: impl Peripheral<P = T> + 'd, 741 uart: Peri<'d, T>,
766 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 742 tx: Peri<'d, impl TxPin<T>>,
767 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 743 rx: Peri<'d, impl RxPin<T>>,
768 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 744 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
769 tx_dma: impl Peripheral<P = impl Channel> + 'd, 745 tx_dma: Peri<'d, impl Channel>,
770 rx_dma: impl Peripheral<P = impl Channel> + 'd, 746 rx_dma: Peri<'d, impl Channel>,
771 config: Config, 747 config: Config,
772 ) -> Self { 748 ) -> Self {
773 into_ref!(tx, rx, tx_dma, rx_dma);
774 Self::new_inner( 749 Self::new_inner(
775 uart, 750 uart,
776 tx.map_into(), 751 tx.into(),
777 rx.map_into(), 752 rx.into(),
778 None, 753 None,
779 None, 754 None,
780 true, 755 true,
781 Some(tx_dma.map_into()), 756 Some(tx_dma.into()),
782 Some(rx_dma.map_into()), 757 Some(rx_dma.into()),
783 config, 758 config,
784 ) 759 )
785 } 760 }
786 761
787 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) 762 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
788 pub fn new_with_rtscts( 763 pub fn new_with_rtscts(
789 uart: impl Peripheral<P = T> + 'd, 764 uart: Peri<'d, T>,
790 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 765 tx: Peri<'d, impl TxPin<T>>,
791 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 766 rx: Peri<'d, impl RxPin<T>>,
792 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 767 rts: Peri<'d, impl RtsPin<T>>,
793 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 768 cts: Peri<'d, impl CtsPin<T>>,
794 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 769 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
795 tx_dma: impl Peripheral<P = impl Channel> + 'd, 770 tx_dma: Peri<'d, impl Channel>,
796 rx_dma: impl Peripheral<P = impl Channel> + 'd, 771 rx_dma: Peri<'d, impl Channel>,
797 config: Config, 772 config: Config,
798 ) -> Self { 773 ) -> Self {
799 into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
800 Self::new_inner( 774 Self::new_inner(
801 uart, 775 uart,
802 tx.map_into(), 776 tx.into(),
803 rx.map_into(), 777 rx.into(),
804 Some(rts.map_into()), 778 Some(rts.into()),
805 Some(cts.map_into()), 779 Some(cts.into()),
806 true, 780 true,
807 Some(tx_dma.map_into()), 781 Some(tx_dma.into()),
808 Some(rx_dma.map_into()), 782 Some(rx_dma.into()),
809 config, 783 config,
810 ) 784 )
811 } 785 }
@@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
813 787
814impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { 788impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
815 fn new_inner( 789 fn new_inner(
816 _uart: impl Peripheral<P = T> + 'd, 790 _uart: Peri<'d, T>,
817 mut tx: PeripheralRef<'d, AnyPin>, 791 mut tx: Peri<'d, AnyPin>,
818 mut rx: PeripheralRef<'d, AnyPin>, 792 mut rx: Peri<'d, AnyPin>,
819 mut rts: Option<PeripheralRef<'d, AnyPin>>, 793 mut rts: Option<Peri<'d, AnyPin>>,
820 mut cts: Option<PeripheralRef<'d, AnyPin>>, 794 mut cts: Option<Peri<'d, AnyPin>>,
821 has_irq: bool, 795 has_irq: bool,
822 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 796 tx_dma: Option<Peri<'d, AnyChannel>>,
823 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 797 rx_dma: Option<Peri<'d, AnyChannel>>,
824 config: Config, 798 config: Config,
825 ) -> Self { 799 ) -> Self {
826 Self::init( 800 Self::init(
@@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
838 } 812 }
839 813
840 fn init( 814 fn init(
841 tx: Option<PeripheralRef<'_, AnyPin>>, 815 tx: Option<Peri<'_, AnyPin>>,
842 rx: Option<PeripheralRef<'_, AnyPin>>, 816 rx: Option<Peri<'_, AnyPin>>,
843 rts: Option<PeripheralRef<'_, AnyPin>>, 817 rts: Option<Peri<'_, AnyPin>>,
844 cts: Option<PeripheralRef<'_, AnyPin>>, 818 cts: Option<Peri<'_, AnyPin>>,
845 config: Config, 819 config: Config,
846 ) { 820 ) {
847 let r = T::regs(); 821 let r = T::regs();
@@ -1326,7 +1300,7 @@ impl_mode!(Async);
1326 1300
1327/// UART instance. 1301/// UART instance.
1328#[allow(private_bounds)] 1302#[allow(private_bounds)]
1329pub trait Instance: SealedInstance { 1303pub trait Instance: SealedInstance + PeripheralType {
1330 /// Interrupt for this instance. 1304 /// Interrupt for this instance.
1331 type Interrupt: interrupt::typelevel::Interrupt; 1305 type Interrupt: interrupt::typelevel::Interrupt;
1332} 1306}
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs
index 26cb90d89..96541ade6 100644
--- a/embassy-rp/src/usb.rs
+++ b/embassy-rp/src/usb.rs
@@ -5,6 +5,7 @@ use core::slice;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::PeripheralType;
8use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
9use embassy_usb_driver as driver; 10use embassy_usb_driver as driver;
10use embassy_usb_driver::{ 11use embassy_usb_driver::{
@@ -12,7 +13,7 @@ use embassy_usb_driver::{
12}; 13};
13 14
14use crate::interrupt::typelevel::{Binding, Interrupt}; 15use crate::interrupt::typelevel::{Binding, Interrupt};
15use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 16use crate::{interrupt, pac, peripherals, Peri, RegExt};
16 17
17trait SealedInstance { 18trait SealedInstance {
18 fn regs() -> crate::pac::usb::Usb; 19 fn regs() -> crate::pac::usb::Usb;
@@ -21,7 +22,7 @@ trait SealedInstance {
21 22
22/// USB peripheral instance. 23/// USB peripheral instance.
23#[allow(private_bounds)] 24#[allow(private_bounds)]
24pub trait Instance: SealedInstance + 'static { 25pub trait Instance: SealedInstance + PeripheralType + 'static {
25 /// Interrupt for this peripheral. 26 /// Interrupt for this peripheral.
26 type Interrupt: interrupt::typelevel::Interrupt; 27 type Interrupt: interrupt::typelevel::Interrupt;
27} 28}
@@ -107,7 +108,7 @@ pub struct Driver<'d, T: Instance> {
107 108
108impl<'d, T: Instance> Driver<'d, T> { 109impl<'d, T: Instance> Driver<'d, T> {
109 /// Create a new USB driver. 110 /// Create a new USB driver.
110 pub fn new(_usb: impl Peripheral<P = T> + 'd, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self { 111 pub fn new(_usb: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self {
111 T::Interrupt::unpend(); 112 T::Interrupt::unpend();
112 unsafe { T::Interrupt::enable() }; 113 unsafe { T::Interrupt::enable() };
113 114
diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs
index 553936602..49cf03850 100644
--- a/embassy-rp/src/watchdog.rs
+++ b/embassy-rp/src/watchdog.rs
@@ -10,8 +10,8 @@ use core::marker::PhantomData;
10 10
11use embassy_time::Duration; 11use embassy_time::Duration;
12 12
13use crate::pac;
14use crate::peripherals::WATCHDOG; 13use crate::peripherals::WATCHDOG;
14use crate::{pac, Peri};
15 15
16/// The reason for a system reset from the watchdog. 16/// The reason for a system reset from the watchdog.
17#[derive(Debug, Copy, Clone, PartialEq, Eq)] 17#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -30,7 +30,7 @@ pub struct Watchdog {
30 30
31impl Watchdog { 31impl Watchdog {
32 /// Create a new `Watchdog` 32 /// Create a new `Watchdog`
33 pub fn new(_watchdog: WATCHDOG) -> Self { 33 pub fn new(_watchdog: Peri<'static, WATCHDOG>) -> Self {
34 Self { 34 Self {
35 phantom: PhantomData, 35 phantom: PhantomData,
36 load_value: 0, 36 load_value: 0,
@@ -89,17 +89,25 @@ impl Watchdog {
89 89
90 /// Start the watchdog timer 90 /// Start the watchdog timer
91 pub fn start(&mut self, period: Duration) { 91 pub fn start(&mut self, period: Duration) {
92 #[cfg(feature = "rp2040")]
93 const MAX_PERIOD: u32 = 0xFFFFFF / 2;
94 #[cfg(feature = "_rp235x")]
92 const MAX_PERIOD: u32 = 0xFFFFFF; 95 const MAX_PERIOD: u32 = 0xFFFFFF;
93 96
94 let delay_us = period.as_micros(); 97 let delay_us = period.as_micros();
95 if delay_us > (MAX_PERIOD / 2) as u64 { 98 if delay_us > (MAX_PERIOD) as u64 {
96 panic!("Period cannot exceed {} microseconds", MAX_PERIOD / 2); 99 panic!("Period cannot exceed {} microseconds", MAX_PERIOD);
97 } 100 }
98 let delay_us = delay_us as u32; 101 let delay_us = delay_us as u32;
99 102
100 // Due to a logic error, the watchdog decrements by 2 and 103 // Due to a logic error, the watchdog decrements by 2 and
101 // the load value must be compensated; see RP2040-E1 104 // the load value must be compensated; see RP2040-E1
102 self.load_value = delay_us * 2; 105 // This errata is fixed in the RP235x
106 if cfg!(feature = "rp2040") {
107 self.load_value = delay_us * 2;
108 } else {
109 self.load_value = delay_us;
110 }
103 111
104 self.enable(false); 112 self.enable(false);
105 self.configure_wdog_reset_triggers(); 113 self.configure_wdog_reset_triggers();
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs
index 25e6d965a..40ff14795 100644
--- a/embassy-stm32-wpan/src/lib.rs
+++ b/embassy-stm32-wpan/src/lib.rs
@@ -23,7 +23,7 @@ mod fmt;
23use core::mem::MaybeUninit; 23use core::mem::MaybeUninit;
24use core::sync::atomic::{compiler_fence, Ordering}; 24use core::sync::atomic::{compiler_fence, Ordering};
25 25
26use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 26use embassy_hal_internal::Peri;
27use embassy_stm32::interrupt; 27use embassy_stm32::interrupt;
28use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; 28use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
29use embassy_stm32::peripherals::IPCC; 29use embassy_stm32::peripherals::IPCC;
@@ -52,7 +52,7 @@ type PacketHeader = LinkedListNode;
52 52
53/// Transport Layer for the Mailbox interface 53/// Transport Layer for the Mailbox interface
54pub struct TlMbox<'d> { 54pub struct TlMbox<'d> {
55 _ipcc: PeripheralRef<'d, IPCC>, 55 _ipcc: Peri<'d, IPCC>,
56 56
57 pub sys_subsystem: Sys, 57 pub sys_subsystem: Sys,
58 pub mm_subsystem: MemoryManager, 58 pub mm_subsystem: MemoryManager,
@@ -92,13 +92,11 @@ impl<'d> TlMbox<'d> {
92 /// Figure 66. 92 /// Figure 66.
93 // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem 93 // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem
94 pub fn init( 94 pub fn init(
95 ipcc: impl Peripheral<P = IPCC> + 'd, 95 ipcc: Peri<'d, IPCC>,
96 _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler> 96 _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
97 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>, 97 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
98 config: Config, 98 config: Config,
99 ) -> Self { 99 ) -> Self {
100 into_ref!(ipcc);
101
102 // this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289. 100 // this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289.
103 // HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this 101 // HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this
104 // implementation 102 // implementation
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index eb0437bc2..798133162 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -324,7 +324,7 @@ fn main() {
324 let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); 324 let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
325 flash_regions.extend(quote! { 325 flash_regions.extend(quote! {
326 #[cfg(flash)] 326 #[cfg(flash)]
327 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>); 327 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
328 }); 328 });
329 } 329 }
330 330
@@ -356,7 +356,7 @@ fn main() {
356 356
357 #[cfg(flash)] 357 #[cfg(flash)]
358 impl<'d, MODE> FlashLayout<'d, MODE> { 358 impl<'d, MODE> FlashLayout<'d, MODE> {
359 pub(crate) fn new(p: embassy_hal_internal::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { 359 pub(crate) fn new(p: embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>) -> Self {
360 Self { 360 Self {
361 #(#inits),*, 361 #(#inits),*,
362 _mode: core::marker::PhantomData, 362 _mode: core::marker::PhantomData,
@@ -1151,6 +1151,8 @@ fn main() {
1151 (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), 1151 (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)),
1152 (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), 1152 (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)),
1153 (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), 1153 (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)),
1154 (("dac", "OUT1"), quote!(crate::dac::DacPin<Ch1>)),
1155 (("dac", "OUT2"), quote!(crate::dac::DacPin<Ch2>)),
1154 ].into(); 1156 ].into();
1155 1157
1156 for p in METADATA.peripherals { 1158 for p in METADATA.peripherals {
@@ -1250,17 +1252,6 @@ fn main() {
1250 } 1252 }
1251 } 1253 }
1252 1254
1253 // DAC is special
1254 if regs.kind == "dac" {
1255 let peri = format_ident!("{}", p.name);
1256 let pin_name = format_ident!("{}", pin.pin);
1257 let ch: u8 = pin.signal.strip_prefix("OUT").unwrap().parse().unwrap();
1258
1259 g.extend(quote! {
1260 impl_dac_pin!( #peri, #pin_name, #ch);
1261 })
1262 }
1263
1264 if regs.kind == "spdifrx" { 1255 if regs.kind == "spdifrx" {
1265 let peri = format_ident!("{}", p.name); 1256 let peri = format_ident!("{}", p.name);
1266 let pin_name = format_ident!("{}", pin.pin); 1257 let pin_name = format_ident!("{}", pin.pin);
@@ -1304,8 +1295,8 @@ fn main() {
1304 (("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)), 1295 (("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)),
1305 (("octospi", "OCTOSPI1"), quote!(crate::ospi::OctoDma)), 1296 (("octospi", "OCTOSPI1"), quote!(crate::ospi::OctoDma)),
1306 (("hspi", "HSPI1"), quote!(crate::hspi::HspiDma)), 1297 (("hspi", "HSPI1"), quote!(crate::hspi::HspiDma)),
1307 (("dac", "CH1"), quote!(crate::dac::DacDma1)), 1298 (("dac", "CH1"), quote!(crate::dac::Dma<Ch1>)),
1308 (("dac", "CH2"), quote!(crate::dac::DacDma2)), 1299 (("dac", "CH2"), quote!(crate::dac::Dma<Ch2>)),
1309 (("timer", "UP"), quote!(crate::timer::UpDma)), 1300 (("timer", "UP"), quote!(crate::timer::UpDma)),
1310 (("hash", "IN"), quote!(crate::hash::Dma)), 1301 (("hash", "IN"), quote!(crate::hash::Dma)),
1311 (("cryp", "IN"), quote!(crate::cryp::DmaIn)), 1302 (("cryp", "IN"), quote!(crate::cryp::DmaIn)),
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index 84763ad4f..a9c1d8faf 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -8,7 +8,7 @@ use super::{
8}; 8};
9use crate::dma::Transfer; 9use crate::dma::Transfer;
10use crate::time::Hertz; 10use crate::time::Hertz;
11use crate::{pac, rcc, Peripheral}; 11use crate::{pac, rcc, Peri};
12 12
13/// Default VREF voltage used for sample conversion to millivolts. 13/// Default VREF voltage used for sample conversion to millivolts.
14pub const VREF_DEFAULT_MV: u32 = 3300; 14pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -154,8 +154,7 @@ pub enum Averaging {
154 154
155impl<'d, T: Instance> Adc<'d, T> { 155impl<'d, T: Instance> Adc<'d, T> {
156 /// Create a new ADC driver. 156 /// Create a new ADC driver.
157 pub fn new(adc: impl Peripheral<P = T> + 'd, sample_time: SampleTime, resolution: Resolution) -> Self { 157 pub fn new(adc: Peri<'d, T>, sample_time: SampleTime, resolution: Resolution) -> Self {
158 embassy_hal_internal::into_ref!(adc);
159 rcc::enable_and_reset::<T>(); 158 rcc::enable_and_reset::<T>();
160 159
161 T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK)); 160 T::regs().cfgr2().modify(|w| w.set_ckmode(Ckmode::SYSCLK));
@@ -319,7 +318,7 @@ impl<'d, T: Instance> Adc<'d, T> {
319 Self::apply_channel_conf() 318 Self::apply_channel_conf()
320 } 319 }
321 320
322 async fn dma_convert(&mut self, rx_dma: &mut impl RxDma<T>, readings: &mut [u16]) { 321 async fn dma_convert(&mut self, rx_dma: Peri<'_, impl RxDma<T>>, readings: &mut [u16]) {
323 // Enable overrun control, so no new DMA requests will be generated until 322 // Enable overrun control, so no new DMA requests will be generated until
324 // previous DR values is read. 323 // previous DR values is read.
325 T::regs().isr().modify(|reg| { 324 T::regs().isr().modify(|reg| {
@@ -374,7 +373,7 @@ impl<'d, T: Instance> Adc<'d, T> {
374 /// TODO(chudsaviet): externalize generic code and merge with read(). 373 /// TODO(chudsaviet): externalize generic code and merge with read().
375 pub async fn read_in_hw_order( 374 pub async fn read_in_hw_order(
376 &mut self, 375 &mut self,
377 rx_dma: &mut impl RxDma<T>, 376 rx_dma: Peri<'_, impl RxDma<T>>,
378 hw_channel_selection: u32, 377 hw_channel_selection: u32,
379 scandir: Scandir, 378 scandir: Scandir,
380 readings: &mut [u16], 379 readings: &mut [u16],
@@ -415,7 +414,7 @@ impl<'d, T: Instance> Adc<'d, T> {
415 // For other channels, use `read_in_hw_order()` or blocking read. 414 // For other channels, use `read_in_hw_order()` or blocking read.
416 pub async fn read( 415 pub async fn read(
417 &mut self, 416 &mut self,
418 rx_dma: &mut impl RxDma<T>, 417 rx_dma: Peri<'_, impl RxDma<T>>,
419 channel_sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>, 418 channel_sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
420 readings: &mut [u16], 419 readings: &mut [u16],
421 ) { 420 ) {
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index b37ec260f..fa6255c23 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -2,12 +2,10 @@ use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_internal::into_ref;
6
7use super::blocking_delay_us; 5use super::blocking_delay_us;
8use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 6use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::time::Hertz; 7use crate::time::Hertz;
10use crate::{interrupt, rcc, Peripheral}; 8use crate::{interrupt, rcc, Peri};
11 9
12pub const VDDA_CALIB_MV: u32 = 3300; 10pub const VDDA_CALIB_MV: u32 = 3300;
13pub const ADC_MAX: u32 = (1 << 12) - 1; 11pub const ADC_MAX: u32 = (1 << 12) - 1;
@@ -48,8 +46,7 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
48} 46}
49 47
50impl<'d, T: Instance> Adc<'d, T> { 48impl<'d, T: Instance> Adc<'d, T> {
51 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 49 pub fn new(adc: Peri<'d, T>) -> Self {
52 into_ref!(adc);
53 rcc::enable_and_reset::<T>(); 50 rcc::enable_and_reset::<T>();
54 T::regs().cr2().modify(|reg| reg.set_adon(true)); 51 T::regs().cr2().modify(|reg| reg.set_adon(true));
55 52
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 0ebeb8a9e..3aeb6f2c7 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -2,13 +2,11 @@ use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_internal::into_ref;
6
7use super::blocking_delay_us; 5use super::blocking_delay_us;
8use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 6use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::interrupt::typelevel::Interrupt; 7use crate::interrupt::typelevel::Interrupt;
10use crate::time::Hertz; 8use crate::time::Hertz;
11use crate::{interrupt, rcc, Peripheral}; 9use crate::{interrupt, rcc, Peri};
12 10
13pub const VDDA_CALIB_MV: u32 = 3300; 11pub const VDDA_CALIB_MV: u32 = 3300;
14pub const ADC_MAX: u32 = (1 << 12) - 1; 12pub const ADC_MAX: u32 = (1 << 12) - 1;
@@ -56,13 +54,11 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
56 54
57impl<'d, T: Instance> Adc<'d, T> { 55impl<'d, T: Instance> Adc<'d, T> {
58 pub fn new( 56 pub fn new(
59 adc: impl Peripheral<P = T> + 'd, 57 adc: Peri<'d, T>,
60 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 58 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
61 ) -> Self { 59 ) -> Self {
62 use crate::pac::adc::vals; 60 use crate::pac::adc::vals;
63 61
64 into_ref!(adc);
65
66 rcc::enable_and_reset::<T>(); 62 rcc::enable_and_reset::<T>();
67 63
68 // Enable the adc regulator 64 // Enable the adc regulator
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index 291a3861e..944e971bb 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -3,14 +3,13 @@ use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_futures::yield_now; 5use embassy_futures::yield_now;
6use embassy_hal_internal::into_ref;
7use embassy_time::Instant; 6use embassy_time::Instant;
8 7
9use super::Resolution; 8use super::Resolution;
10use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 9use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 10use crate::interrupt::typelevel::Interrupt;
12use crate::time::Hertz; 11use crate::time::Hertz;
13use crate::{interrupt, rcc, Peripheral}; 12use crate::{interrupt, rcc, Peri};
14 13
15const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ; 14const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ;
16 15
@@ -138,11 +137,9 @@ impl<T: Instance> Drop for Temperature<T> {
138 137
139impl<'d, T: Instance> Adc<'d, T> { 138impl<'d, T: Instance> Adc<'d, T> {
140 pub fn new( 139 pub fn new(
141 adc: impl Peripheral<P = T> + 'd, 140 adc: Peri<'d, T>,
142 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 141 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
143 ) -> Self { 142 ) -> Self {
144 into_ref!(adc);
145
146 rcc::enable_and_reset::<T>(); 143 rcc::enable_and_reset::<T>();
147 144
148 //let r = T::regs(); 145 //let r = T::regs();
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index 0291ef4de..6b9182ad6 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -11,7 +11,7 @@ use super::{blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolut
11use crate::adc::SealedAdcChannel; 11use crate::adc::SealedAdcChannel;
12use crate::dma::Transfer; 12use crate::dma::Transfer;
13use crate::time::Hertz; 13use crate::time::Hertz;
14use crate::{pac, rcc, Peripheral}; 14use crate::{pac, rcc, Peri};
15 15
16/// Default VREF voltage used for sample conversion to millivolts. 16/// Default VREF voltage used for sample conversion to millivolts.
17pub const VREF_DEFAULT_MV: u32 = 3300; 17pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -135,8 +135,7 @@ impl Prescaler {
135 135
136impl<'d, T: Instance> Adc<'d, T> { 136impl<'d, T: Instance> Adc<'d, T> {
137 /// Create a new ADC driver. 137 /// Create a new ADC driver.
138 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 138 pub fn new(adc: Peri<'d, T>) -> Self {
139 embassy_hal_internal::into_ref!(adc);
140 rcc::enable_and_reset::<T>(); 139 rcc::enable_and_reset::<T>();
141 140
142 let prescaler = Prescaler::from_ker_ck(T::frequency()); 141 let prescaler = Prescaler::from_ker_ck(T::frequency());
@@ -172,7 +171,7 @@ impl<'d, T: Instance> Adc<'d, T> {
172 reg.set_advregen(true); 171 reg.set_advregen(true);
173 }); 172 });
174 173
175 blocking_delay_us(10); 174 blocking_delay_us(20);
176 } 175 }
177 176
178 fn configure_differential_inputs(&mut self) { 177 fn configure_differential_inputs(&mut self) {
@@ -192,6 +191,8 @@ impl<'d, T: Instance> Adc<'d, T> {
192 191
193 while T::regs().cr().read().adcal() {} 192 while T::regs().cr().read().adcal() {}
194 193
194 blocking_delay_us(20);
195
195 T::regs().cr().modify(|w| { 196 T::regs().cr().modify(|w| {
196 w.set_adcaldif(Adcaldif::DIFFERENTIAL); 197 w.set_adcaldif(Adcaldif::DIFFERENTIAL);
197 }); 198 });
@@ -199,6 +200,8 @@ impl<'d, T: Instance> Adc<'d, T> {
199 T::regs().cr().modify(|w| w.set_adcal(true)); 200 T::regs().cr().modify(|w| w.set_adcal(true));
200 201
201 while T::regs().cr().read().adcal() {} 202 while T::regs().cr().read().adcal() {}
203
204 blocking_delay_us(20);
202 } 205 }
203 206
204 fn enable(&mut self) { 207 fn enable(&mut self) {
@@ -364,8 +367,8 @@ impl<'d, T: Instance> Adc<'d, T> {
364 /// use embassy_stm32::adc::{Adc, AdcChannel} 367 /// use embassy_stm32::adc::{Adc, AdcChannel}
365 /// 368 ///
366 /// let mut adc = Adc::new(p.ADC1); 369 /// let mut adc = Adc::new(p.ADC1);
367 /// let mut adc_pin0 = p.PA0.degrade_adc(); 370 /// let mut adc_pin0 = p.PA0.into();
368 /// let mut adc_pin1 = p.PA1.degrade_adc(); 371 /// let mut adc_pin1 = p.PA1.into();
369 /// let mut measurements = [0u16; 2]; 372 /// let mut measurements = [0u16; 2];
370 /// 373 ///
371 /// adc.read_async( 374 /// adc.read_async(
@@ -382,7 +385,7 @@ impl<'d, T: Instance> Adc<'d, T> {
382 /// ``` 385 /// ```
383 pub async fn read( 386 pub async fn read(
384 &mut self, 387 &mut self,
385 rx_dma: &mut impl RxDma<T>, 388 rx_dma: Peri<'_, impl RxDma<T>>,
386 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, 389 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
387 readings: &mut [u16], 390 readings: &mut [u16],
388 ) { 391 ) {
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 31a08b6eb..321db7431 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -22,6 +22,7 @@ use core::marker::PhantomData;
22#[allow(unused)] 22#[allow(unused)]
23#[cfg(not(any(adc_f3_v2)))] 23#[cfg(not(any(adc_f3_v2)))]
24pub use _version::*; 24pub use _version::*;
25use embassy_hal_internal::{impl_peripheral, PeripheralType};
25#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] 26#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
26use embassy_sync::waitqueue::AtomicWaker; 27use embassy_sync::waitqueue::AtomicWaker;
27 28
@@ -42,7 +43,7 @@ dma_trait!(RxDma4, adc4::Instance);
42/// Analog to Digital driver. 43/// Analog to Digital driver.
43pub struct Adc<'d, T: Instance> { 44pub struct Adc<'d, T: Instance> {
44 #[allow(unused)] 45 #[allow(unused)]
45 adc: crate::PeripheralRef<'d, T>, 46 adc: crate::Peri<'d, T>,
46 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))] 47 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))]
47 sample_time: SampleTime, 48 sample_time: SampleTime,
48} 49}
@@ -111,7 +112,7 @@ pub(crate) fn blocking_delay_us(us: u32) {
111 adc_c0 112 adc_c0
112)))] 113)))]
113#[allow(private_bounds)] 114#[allow(private_bounds)]
114pub trait Instance: SealedInstance + crate::Peripheral<P = Self> { 115pub trait Instance: SealedInstance + crate::PeripheralType {
115 type Interrupt: crate::interrupt::typelevel::Interrupt; 116 type Interrupt: crate::interrupt::typelevel::Interrupt;
116} 117}
117/// ADC instance. 118/// ADC instance.
@@ -132,7 +133,7 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
132 adc_c0 133 adc_c0
133))] 134))]
134#[allow(private_bounds)] 135#[allow(private_bounds)]
135pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { 136pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
136 type Interrupt: crate::interrupt::typelevel::Interrupt; 137 type Interrupt: crate::interrupt::typelevel::Interrupt;
137} 138}
138 139
@@ -159,7 +160,7 @@ pub struct AnyAdcChannel<T> {
159 channel: u8, 160 channel: u8,
160 _phantom: PhantomData<T>, 161 _phantom: PhantomData<T>,
161} 162}
162 163impl_peripheral!(AnyAdcChannel<T: Instance>);
163impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {} 164impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
164impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { 165impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
165 fn channel(&self) -> u8 { 166 fn channel(&self) -> u8 {
@@ -233,11 +234,11 @@ foreach_adc!(
233 234
234macro_rules! impl_adc_pin { 235macro_rules! impl_adc_pin {
235 ($inst:ident, $pin:ident, $ch:expr) => { 236 ($inst:ident, $pin:ident, $ch:expr) => {
236 impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {} 237 impl crate::adc::AdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {}
237 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin { 238 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {
238 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] 239 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))]
239 fn setup(&mut self) { 240 fn setup(&mut self) {
240 <Self as crate::gpio::SealedPin>::set_as_analog(self); 241 <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(self);
241 } 242 }
242 243
243 fn channel(&self) -> u8 { 244 fn channel(&self) -> u8 {
diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs
index f3d1ca0ab..fabf0284b 100644
--- a/embassy-stm32/src/adc/ringbuffered_v2.rs
+++ b/embassy-stm32/src/adc/ringbuffered_v2.rs
@@ -2,13 +2,12 @@ use core::marker::PhantomData;
2use core::mem; 2use core::mem;
3use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
4 4
5use embassy_hal_internal::{into_ref, Peripheral};
6use stm32_metapac::adc::vals::SampleTime; 5use stm32_metapac::adc::vals::SampleTime;
7 6
8use crate::adc::{Adc, AdcChannel, Instance, RxDma}; 7use crate::adc::{Adc, AdcChannel, Instance, RxDma};
9use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; 8use crate::dma::{Priority, ReadableRingBuffer, TransferOptions};
10use crate::pac::adc::vals; 9use crate::pac::adc::vals;
11use crate::rcc; 10use crate::{rcc, Peri};
12 11
13#[cfg_attr(feature = "defmt", derive(defmt::Format))] 12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14pub struct OverrunError; 13pub struct OverrunError;
@@ -103,13 +102,8 @@ impl<'d, T: Instance> Adc<'d, T> {
103 /// It is critical to call `read` frequently to prevent DMA buffer overrun. 102 /// It is critical to call `read` frequently to prevent DMA buffer overrun.
104 /// 103 ///
105 /// [`read`]: #method.read 104 /// [`read`]: #method.read
106 pub fn into_ring_buffered( 105 pub fn into_ring_buffered(self, dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> RingBufferedAdc<'d, T> {
107 self,
108 dma: impl Peripheral<P = impl RxDma<T>> + 'd,
109 dma_buf: &'d mut [u16],
110 ) -> RingBufferedAdc<'d, T> {
111 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 106 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
112 into_ref!(dma);
113 107
114 let opts: crate::dma::TransferOptions = TransferOptions { 108 let opts: crate::dma::TransferOptions = TransferOptions {
115 half_transfer_ir: true, 109 half_transfer_ir: true,
diff --git a/embassy-stm32/src/adc/u5_adc4.rs b/embassy-stm32/src/adc/u5_adc4.rs
index cec88d482..a5cfbfdcf 100644
--- a/embassy-stm32/src/adc/u5_adc4.rs
+++ b/embassy-stm32/src/adc/u5_adc4.rs
@@ -6,7 +6,7 @@ use crate::dma::Transfer;
6pub use crate::pac::adc::regs::Adc4Chselrmod0; 6pub use crate::pac::adc::regs::Adc4Chselrmod0;
7pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime}; 7pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime};
8use crate::time::Hertz; 8use crate::time::Hertz;
9use crate::{pac, rcc, Peripheral}; 9use crate::{pac, rcc, Peri};
10 10
11const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); 11const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);
12 12
@@ -169,13 +169,13 @@ pub trait SealedInstance {
169 fn regs() -> crate::pac::adc::Adc4; 169 fn regs() -> crate::pac::adc::Adc4;
170} 170}
171 171
172pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral { 172pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
173 type Interrupt: crate::interrupt::typelevel::Interrupt; 173 type Interrupt: crate::interrupt::typelevel::Interrupt;
174} 174}
175 175
176pub struct Adc4<'d, T: Instance> { 176pub struct Adc4<'d, T: Instance> {
177 #[allow(unused)] 177 #[allow(unused)]
178 adc: crate::PeripheralRef<'d, T>, 178 adc: crate::Peri<'d, T>,
179} 179}
180 180
181#[derive(Debug)] 181#[derive(Debug)]
@@ -186,8 +186,7 @@ pub enum Adc4Error {
186 186
187impl<'d, T: Instance> Adc4<'d, T> { 187impl<'d, T: Instance> Adc4<'d, T> {
188 /// Create a new ADC driver. 188 /// Create a new ADC driver.
189 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 189 pub fn new(adc: Peri<'d, T>) -> Self {
190 embassy_hal_internal::into_ref!(adc);
191 rcc::enable_and_reset::<T>(); 190 rcc::enable_and_reset::<T>();
192 let prescaler = Prescaler::from_ker_ck(T::frequency()); 191 let prescaler = Prescaler::from_ker_ck(T::frequency());
193 192
@@ -379,15 +378,15 @@ impl<'d, T: Instance> Adc4<'d, T> {
379 /// let mut adc4 = adc4::Adc4::new(p.ADC4); 378 /// let mut adc4 = adc4::Adc4::new(p.ADC4);
380 /// let mut adc4_pin1 = p.PC1; 379 /// let mut adc4_pin1 = p.PC1;
381 /// let mut adc4_pin2 = p.PC0; 380 /// let mut adc4_pin2 = p.PC0;
382 /// let mut degraded41 = adc4_pin1.degrade_adc(); 381 /// let mut.into()d41 = adc4_pin1.into();
383 /// let mut degraded42 = adc4_pin2.degrade_adc(); 382 /// let mut.into()d42 = adc4_pin2.into();
384 /// let mut measurements = [0u16; 2]; 383 /// let mut measurements = [0u16; 2];
385 /// // not that the channels must be in ascending order 384 /// // not that the channels must be in ascending order
386 /// adc4.read( 385 /// adc4.read(
387 /// &mut p.GPDMA1_CH1, 386 /// &mut p.GPDMA1_CH1,
388 /// [ 387 /// [
389 /// &mut degraded42, 388 /// &mut.into()d42,
390 /// &mut degraded41, 389 /// &mut.into()d41,
391 /// ] 390 /// ]
392 /// .into_iter(), 391 /// .into_iter(),
393 /// &mut measurements, 392 /// &mut measurements,
@@ -395,7 +394,7 @@ impl<'d, T: Instance> Adc4<'d, T> {
395 /// ``` 394 /// ```
396 pub async fn read( 395 pub async fn read(
397 &mut self, 396 &mut self,
398 rx_dma: &mut impl RxDma4<T>, 397 rx_dma: Peri<'_, impl RxDma4<T>>,
399 sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>, 398 sequence: impl ExactSizeIterator<Item = &mut AnyAdcChannel<T>>,
400 readings: &mut [u16], 399 readings: &mut [u16],
401 ) -> Result<(), Adc4Error> { 400 ) -> Result<(), Adc4Error> {
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index d5cd14661..fb6f5b7d0 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -2,7 +2,6 @@ use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use embassy_hal_internal::into_ref;
6#[cfg(adc_l0)] 5#[cfg(adc_l0)]
7use stm32_metapac::adc::vals::Ckmode; 6use stm32_metapac::adc::vals::Ckmode;
8 7
@@ -10,7 +9,7 @@ use super::blocking_delay_us;
10use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 9use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 10use crate::interrupt::typelevel::Interrupt;
12use crate::peripherals::ADC1; 11use crate::peripherals::ADC1;
13use crate::{interrupt, rcc, Peripheral}; 12use crate::{interrupt, rcc, Peri};
14 13
15pub const VDDA_CALIB_MV: u32 = 3300; 14pub const VDDA_CALIB_MV: u32 = 3300;
16pub const VREF_INT: u32 = 1230; 15pub const VREF_INT: u32 = 1230;
@@ -63,10 +62,9 @@ impl super::SealedAdcChannel<ADC1> for Temperature {
63 62
64impl<'d, T: Instance> Adc<'d, T> { 63impl<'d, T: Instance> Adc<'d, T> {
65 pub fn new( 64 pub fn new(
66 adc: impl Peripheral<P = T> + 'd, 65 adc: Peri<'d, T>,
67 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 66 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
68 ) -> Self { 67 ) -> Self {
69 into_ref!(adc);
70 rcc::enable_and_reset::<T>(); 68 rcc::enable_and_reset::<T>();
71 69
72 // Delay 1μs when using HSI14 as the ADC clock. 70 // Delay 1μs when using HSI14 as the ADC clock.
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 842a5ee6d..e94a25b24 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,10 +1,8 @@
1use embassy_hal_internal::into_ref;
2
3use super::blocking_delay_us; 1use super::blocking_delay_us;
4use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 2use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
5use crate::peripherals::ADC1; 3use crate::peripherals::ADC1;
6use crate::time::Hertz; 4use crate::time::Hertz;
7use crate::{rcc, Peripheral}; 5use crate::{rcc, Peri};
8 6
9mod ringbuffered_v2; 7mod ringbuffered_v2;
10pub use ringbuffered_v2::{RingBufferedAdc, Sequence}; 8pub use ringbuffered_v2::{RingBufferedAdc, Sequence};
@@ -97,8 +95,7 @@ impl<'d, T> Adc<'d, T>
97where 95where
98 T: Instance, 96 T: Instance,
99{ 97{
100 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 98 pub fn new(adc: Peri<'d, T>) -> Self {
101 into_ref!(adc);
102 rcc::enable_and_reset::<T>(); 99 rcc::enable_and_reset::<T>();
103 100
104 let presc = Prescaler::from_pclk2(T::frequency()); 101 let presc = Prescaler::from_pclk2(T::frequency());
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index fc20974dd..2de12d1d6 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,12 +1,11 @@
1use cfg_if::cfg_if; 1use cfg_if::cfg_if;
2use embassy_hal_internal::into_ref;
3use pac::adc::vals::Dmacfg; 2use pac::adc::vals::Dmacfg;
4 3
5use super::{ 4use super::{
6 blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, 5 blocking_delay_us, Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel,
7}; 6};
8use crate::dma::Transfer; 7use crate::dma::Transfer;
9use crate::{pac, rcc, Peripheral}; 8use crate::{pac, rcc, Peri};
10 9
11/// Default VREF voltage used for sample conversion to millivolts. 10/// Default VREF voltage used for sample conversion to millivolts.
12pub const VREF_DEFAULT_MV: u32 = 3300; 11pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -95,8 +94,7 @@ cfg_if! {
95} 94}
96 95
97impl<'d, T: Instance> Adc<'d, T> { 96impl<'d, T: Instance> Adc<'d, T> {
98 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 97 pub fn new(adc: Peri<'d, T>) -> Self {
99 into_ref!(adc);
100 rcc::enable_and_reset::<T>(); 98 rcc::enable_and_reset::<T>();
101 T::regs().cr().modify(|reg| { 99 T::regs().cr().modify(|reg| {
102 #[cfg(not(any(adc_g0, adc_u0)))] 100 #[cfg(not(any(adc_g0, adc_u0)))]
@@ -262,6 +260,9 @@ impl<'d, T: Instance> Adc<'d, T> {
262 /// 260 ///
263 /// `sequence` iterator and `readings` must have the same length. 261 /// `sequence` iterator and `readings` must have the same length.
264 /// 262 ///
263 /// Note: The order of values in `readings` is defined by the pin ADC
264 /// channel number and not the pin order in `sequence`.
265 ///
265 /// Example 266 /// Example
266 /// ```rust,ignore 267 /// ```rust,ignore
267 /// use embassy_stm32::adc::{Adc, AdcChannel} 268 /// use embassy_stm32::adc::{Adc, AdcChannel}
@@ -285,7 +286,7 @@ impl<'d, T: Instance> Adc<'d, T> {
285 /// ``` 286 /// ```
286 pub async fn read( 287 pub async fn read(
287 &mut self, 288 &mut self,
288 rx_dma: &mut impl RxDma<T>, 289 rx_dma: Peri<'_, impl RxDma<T>>,
289 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, 290 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
290 readings: &mut [u16], 291 readings: &mut [u16],
291 ) { 292 ) {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 9860efa8a..5910eef30 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -9,7 +9,7 @@ use super::{
9}; 9};
10use crate::dma::Transfer; 10use crate::dma::Transfer;
11use crate::time::Hertz; 11use crate::time::Hertz;
12use crate::{pac, rcc, Peripheral}; 12use crate::{pac, rcc, Peri};
13 13
14/// Default VREF voltage used for sample conversion to millivolts. 14/// Default VREF voltage used for sample conversion to millivolts.
15pub const VREF_DEFAULT_MV: u32 = 3300; 15pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -158,8 +158,7 @@ pub enum Averaging {
158 158
159impl<'d, T: Instance> Adc<'d, T> { 159impl<'d, T: Instance> Adc<'d, T> {
160 /// Create a new ADC driver. 160 /// Create a new ADC driver.
161 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 161 pub fn new(adc: Peri<'d, T>) -> Self {
162 embassy_hal_internal::into_ref!(adc);
163 rcc::enable_and_reset::<T>(); 162 rcc::enable_and_reset::<T>();
164 163
165 let prescaler = Prescaler::from_ker_ck(T::frequency()); 164 let prescaler = Prescaler::from_ker_ck(T::frequency());
@@ -344,8 +343,8 @@ impl<'d, T: Instance> Adc<'d, T> {
344 /// use embassy_stm32::adc::{Adc, AdcChannel} 343 /// use embassy_stm32::adc::{Adc, AdcChannel}
345 /// 344 ///
346 /// let mut adc = Adc::new(p.ADC1); 345 /// let mut adc = Adc::new(p.ADC1);
347 /// let mut adc_pin0 = p.PA0.degrade_adc(); 346 /// let mut adc_pin0 = p.PA0.into();
348 /// let mut adc_pin2 = p.PA2.degrade_adc(); 347 /// let mut adc_pin2 = p.PA2.into();
349 /// let mut measurements = [0u16; 2]; 348 /// let mut measurements = [0u16; 2];
350 /// 349 ///
351 /// adc.read_async( 350 /// adc.read_async(
@@ -362,7 +361,7 @@ impl<'d, T: Instance> Adc<'d, T> {
362 /// ``` 361 /// ```
363 pub async fn read( 362 pub async fn read(
364 &mut self, 363 &mut self,
365 rx_dma: &mut impl RxDma<T>, 364 rx_dma: Peri<'_, impl RxDma<T>>,
366 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>, 365 sequence: impl ExactSizeIterator<Item = (&mut AnyAdcChannel<T>, SampleTime)>,
367 readings: &mut [u16], 366 readings: &mut [u16],
368 ) { 367 ) {
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index c0b3c730b..305666d5b 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -6,7 +6,7 @@ use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::interrupt::InterruptExt; 8use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_hal_internal::into_ref; 9use embassy_hal_internal::PeripheralType;
10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
11use embassy_sync::channel::Channel; 11use embassy_sync::channel::Channel;
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
@@ -21,7 +21,7 @@ use crate::can::enums::{BusError, InternalOperation, TryReadError};
21use crate::gpio::{AfType, OutputType, Pull, Speed}; 21use crate::gpio::{AfType, OutputType, Pull, Speed};
22use crate::interrupt::typelevel::Interrupt; 22use crate::interrupt::typelevel::Interrupt;
23use crate::rcc::{self, RccPeripheral}; 23use crate::rcc::{self, RccPeripheral};
24use crate::{interrupt, peripherals, Peripheral}; 24use crate::{interrupt, peripherals, Peri};
25 25
26/// Interrupt handler. 26/// Interrupt handler.
27pub struct TxInterruptHandler<T: Instance> { 27pub struct TxInterruptHandler<T: Instance> {
@@ -173,16 +173,15 @@ impl<'d> Can<'d> {
173 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. 173 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
174 /// You must call [Can::enable_non_blocking] to use the peripheral. 174 /// You must call [Can::enable_non_blocking] to use the peripheral.
175 pub fn new<T: Instance>( 175 pub fn new<T: Instance>(
176 _peri: impl Peripheral<P = T> + 'd, 176 _peri: Peri<'d, T>,
177 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 177 rx: Peri<'d, impl RxPin<T>>,
178 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 178 tx: Peri<'d, impl TxPin<T>>,
179 _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>> 179 _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
180 + interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>> 180 + interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
181 + interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>> 181 + interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>
182 + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>> 182 + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>>
183 + 'd, 183 + 'd,
184 ) -> Self { 184 ) -> Self {
185 into_ref!(_peri, rx, tx);
186 let info = T::info(); 185 let info = T::info();
187 let regs = &T::info().regs; 186 let regs = &T::info().regs;
188 187
@@ -1083,7 +1082,7 @@ trait SealedInstance {
1083 1082
1084/// CAN instance trait. 1083/// CAN instance trait.
1085#[allow(private_bounds)] 1084#[allow(private_bounds)]
1086pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + 'static { 1085pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
1087 /// TX interrupt for this instance. 1086 /// TX interrupt for this instance.
1088 type TXInterrupt: crate::interrupt::typelevel::Interrupt; 1087 type TXInterrupt: crate::interrupt::typelevel::Interrupt;
1089 /// RX0 interrupt for this instance. 1088 /// RX0 interrupt for this instance.
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index f950b6f99..5467a40f1 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::interrupt::InterruptExt; 6use embassy_hal_internal::interrupt::InterruptExt;
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::PeripheralType;
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel; 9use embassy_sync::channel::Channel;
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
@@ -13,7 +13,7 @@ use crate::can::fd::peripheral::Registers;
13use crate::gpio::{AfType, OutputType, Pull, Speed}; 13use crate::gpio::{AfType, OutputType, Pull, Speed};
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral}; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peripheral}; 16use crate::{interrupt, peripherals, Peri};
17 17
18pub(crate) mod fd; 18pub(crate) mod fd;
19 19
@@ -175,15 +175,13 @@ impl<'d> CanConfigurator<'d> {
175 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode. 175 /// Creates a new Fdcan instance, keeping the peripheral in sleep mode.
176 /// You must call [Fdcan::enable_non_blocking] to use the peripheral. 176 /// You must call [Fdcan::enable_non_blocking] to use the peripheral.
177 pub fn new<T: Instance>( 177 pub fn new<T: Instance>(
178 _peri: impl Peripheral<P = T> + 'd, 178 _peri: Peri<'d, T>,
179 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 179 rx: Peri<'d, impl RxPin<T>>,
180 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 180 tx: Peri<'d, impl TxPin<T>>,
181 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>> 181 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
182 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>> 182 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
183 + 'd, 183 + 'd,
184 ) -> CanConfigurator<'d> { 184 ) -> CanConfigurator<'d> {
185 into_ref!(_peri, rx, tx);
186
187 rx.set_as_af(rx.af_num(), AfType::input(Pull::None)); 185 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
188 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 186 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
189 187
@@ -957,7 +955,7 @@ trait SealedInstance {
957 955
958/// Instance trait 956/// Instance trait
959#[allow(private_bounds)] 957#[allow(private_bounds)]
960pub trait Instance: SealedInstance + RccPeripheral + 'static { 958pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
961 /// Interrupt 0 959 /// Interrupt 0
962 type IT0Interrupt: crate::interrupt::typelevel::Interrupt; 960 type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
963 /// Interrupt 1 961 /// Interrupt 1
@@ -965,7 +963,7 @@ pub trait Instance: SealedInstance + RccPeripheral + 'static {
965} 963}
966 964
967/// Fdcan Instance struct 965/// Fdcan Instance struct
968pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>); 966pub struct FdcanInstance<'a, T: Instance>(Peri<'a, T>);
969 967
970macro_rules! impl_fdcan { 968macro_rules! impl_fdcan {
971 ($inst:ident, 969 ($inst:ident,
diff --git a/embassy-stm32/src/cordic/mod.rs b/embassy-stm32/src/cordic/mod.rs
index fb342d2e7..320774857 100644
--- a/embassy-stm32/src/cordic/mod.rs
+++ b/embassy-stm32/src/cordic/mod.rs
@@ -1,7 +1,7 @@
1//! coordinate rotation digital computer (CORDIC) 1//! coordinate rotation digital computer (CORDIC)
2 2
3use embassy_hal_internal::drop::OnDrop; 3use embassy_hal_internal::drop::OnDrop;
4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 4use embassy_hal_internal::{Peri, PeripheralType};
5 5
6use crate::pac::cordic::vals; 6use crate::pac::cordic::vals;
7use crate::{dma, peripherals, rcc}; 7use crate::{dma, peripherals, rcc};
@@ -16,7 +16,7 @@ pub mod utils;
16 16
17/// CORDIC driver 17/// CORDIC driver
18pub struct Cordic<'d, T: Instance> { 18pub struct Cordic<'d, T: Instance> {
19 peri: PeripheralRef<'d, T>, 19 peri: Peri<'d, T>,
20 config: Config, 20 config: Config,
21} 21}
22 22
@@ -137,7 +137,7 @@ trait SealedInstance {
137 137
138/// CORDIC instance trait 138/// CORDIC instance trait
139#[allow(private_bounds)] 139#[allow(private_bounds)]
140pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral {} 140pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral {}
141 141
142/// CORDIC configuration 142/// CORDIC configuration
143#[derive(Debug)] 143#[derive(Debug)]
@@ -198,11 +198,9 @@ impl<'d, T: Instance> Cordic<'d, T> {
198 /// Note: 198 /// Note:
199 /// If you need a peripheral -> CORDIC -> peripheral mode, 199 /// If you need a peripheral -> CORDIC -> peripheral mode,
200 /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config] 200 /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config]
201 pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self { 201 pub fn new(peri: Peri<'d, T>, config: Config) -> Self {
202 rcc::enable_and_reset::<T>(); 202 rcc::enable_and_reset::<T>();
203 203
204 into_ref!(peri);
205
206 let mut instance = Self { peri, config }; 204 let mut instance = Self { peri, config };
207 205
208 instance.reconfigure(); 206 instance.reconfigure();
@@ -378,8 +376,8 @@ impl<'d, T: Instance> Cordic<'d, T> {
378 /// If you want to make sure ARG2 is set to +1, consider run [.reconfigure()](Self::reconfigure). 376 /// If you want to make sure ARG2 is set to +1, consider run [.reconfigure()](Self::reconfigure).
379 pub async fn async_calc_32bit( 377 pub async fn async_calc_32bit(
380 &mut self, 378 &mut self,
381 write_dma: impl Peripheral<P = impl WriteDma<T>>, 379 mut write_dma: Peri<'_, impl WriteDma<T>>,
382 read_dma: impl Peripheral<P = impl ReadDma<T>>, 380 mut read_dma: Peri<'_, impl ReadDma<T>>,
383 arg: &[u32], 381 arg: &[u32],
384 res: &mut [u32], 382 res: &mut [u32],
385 arg1_only: bool, 383 arg1_only: bool,
@@ -393,8 +391,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
393 391
394 let active_res_buf = &mut res[..res_cnt]; 392 let active_res_buf = &mut res[..res_cnt];
395 393
396 into_ref!(write_dma, read_dma);
397
398 self.peri 394 self.peri
399 .set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two }); 395 .set_argument_count(if arg1_only { AccessCount::One } else { AccessCount::Two });
400 396
@@ -416,7 +412,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
416 412
417 unsafe { 413 unsafe {
418 let write_transfer = dma::Transfer::new_write( 414 let write_transfer = dma::Transfer::new_write(
419 &mut write_dma, 415 write_dma.reborrow(),
420 write_req, 416 write_req,
421 arg, 417 arg,
422 T::regs().wdata().as_ptr() as *mut _, 418 T::regs().wdata().as_ptr() as *mut _,
@@ -424,7 +420,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
424 ); 420 );
425 421
426 let read_transfer = dma::Transfer::new_read( 422 let read_transfer = dma::Transfer::new_read(
427 &mut read_dma, 423 read_dma.reborrow(),
428 read_req, 424 read_req,
429 T::regs().rdata().as_ptr() as *mut _, 425 T::regs().rdata().as_ptr() as *mut _,
430 active_res_buf, 426 active_res_buf,
@@ -519,8 +515,8 @@ impl<'d, T: Instance> Cordic<'d, T> {
519 /// User will take respond to merge two u16 arguments into one u32 data, and/or split one u32 data into two u16 results. 515 /// User will take respond to merge two u16 arguments into one u32 data, and/or split one u32 data into two u16 results.
520 pub async fn async_calc_16bit( 516 pub async fn async_calc_16bit(
521 &mut self, 517 &mut self,
522 write_dma: impl Peripheral<P = impl WriteDma<T>>, 518 mut write_dma: Peri<'_, impl WriteDma<T>>,
523 read_dma: impl Peripheral<P = impl ReadDma<T>>, 519 mut read_dma: Peri<'_, impl ReadDma<T>>,
524 arg: &[u32], 520 arg: &[u32],
525 res: &mut [u32], 521 res: &mut [u32],
526 ) -> Result<usize, CordicError> { 522 ) -> Result<usize, CordicError> {
@@ -536,8 +532,6 @@ impl<'d, T: Instance> Cordic<'d, T> {
536 532
537 let active_res_buf = &mut res[..res_cnt]; 533 let active_res_buf = &mut res[..res_cnt];
538 534
539 into_ref!(write_dma, read_dma);
540
541 // In q1.15 mode, 1 write/read to access 2 arguments/results 535 // In q1.15 mode, 1 write/read to access 2 arguments/results
542 self.peri.set_argument_count(AccessCount::One); 536 self.peri.set_argument_count(AccessCount::One);
543 self.peri.set_result_count(AccessCount::One); 537 self.peri.set_result_count(AccessCount::One);
@@ -557,7 +551,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
557 551
558 unsafe { 552 unsafe {
559 let write_transfer = dma::Transfer::new_write( 553 let write_transfer = dma::Transfer::new_write(
560 &mut write_dma, 554 write_dma.reborrow(),
561 write_req, 555 write_req,
562 arg, 556 arg,
563 T::regs().wdata().as_ptr() as *mut _, 557 T::regs().wdata().as_ptr() as *mut _,
@@ -565,7 +559,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
565 ); 559 );
566 560
567 let read_transfer = dma::Transfer::new_read( 561 let read_transfer = dma::Transfer::new_read(
568 &mut read_dma, 562 read_dma.reborrow(),
569 read_req, 563 read_req,
570 T::regs().rdata().as_ptr() as *mut _, 564 T::regs().rdata().as_ptr() as *mut _,
571 active_res_buf, 565 active_res_buf,
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index f3d13de7c..a78b3c2b7 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -1,23 +1,18 @@
1use embassy_hal_internal::{into_ref, PeripheralRef};
2
3use crate::pac::CRC as PAC_CRC; 1use crate::pac::CRC as PAC_CRC;
4use crate::peripherals::CRC; 2use crate::peripherals::CRC;
5use crate::{rcc, Peripheral}; 3use crate::{rcc, Peri};
6 4
7/// CRC driver. 5/// CRC driver.
8pub struct Crc<'d> { 6pub struct Crc<'d> {
9 _peri: PeripheralRef<'d, CRC>, 7 _peri: Peri<'d, CRC>,
10} 8}
11 9
12impl<'d> Crc<'d> { 10impl<'d> Crc<'d> {
13 /// Instantiates the CRC32 peripheral and initializes it to default values. 11 /// Instantiates the CRC32 peripheral and initializes it to default values.
14 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd) -> Self { 12 pub fn new(peripheral: Peri<'d, CRC>) -> Self {
15 into_ref!(peripheral);
16
17 // Note: enable and reset come from RccPeripheral. 13 // Note: enable and reset come from RccPeripheral.
18 // enable CRC clock in RCC. 14 // enable CRC clock in RCC.
19 rcc::enable_and_reset::<CRC>(); 15 rcc::enable_and_reset::<CRC>();
20 // Peripheral the peripheral
21 let mut instance = Self { _peri: peripheral }; 16 let mut instance = Self { _peri: peripheral };
22 instance.reset(); 17 instance.reset();
23 instance 18 instance
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index ecb507ff4..c94c9f380 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -1,13 +1,11 @@
1use embassy_hal_internal::{into_ref, PeripheralRef};
2
3use crate::pac::crc::vals; 1use crate::pac::crc::vals;
4use crate::pac::CRC as PAC_CRC; 2use crate::pac::CRC as PAC_CRC;
5use crate::peripherals::CRC; 3use crate::peripherals::CRC;
6use crate::{rcc, Peripheral}; 4use crate::{rcc, Peri};
7 5
8/// CRC driver. 6/// CRC driver.
9pub struct Crc<'d> { 7pub struct Crc<'d> {
10 _peripheral: PeripheralRef<'d, CRC>, 8 _peripheral: Peri<'d, CRC>,
11 _config: Config, 9 _config: Config,
12} 10}
13 11
@@ -80,11 +78,10 @@ pub enum PolySize {
80 78
81impl<'d> Crc<'d> { 79impl<'d> Crc<'d> {
82 /// Instantiates the CRC32 peripheral and initializes it to default values. 80 /// Instantiates the CRC32 peripheral and initializes it to default values.
83 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self { 81 pub fn new(peripheral: Peri<'d, CRC>, config: Config) -> Self {
84 // Note: enable and reset come from RccPeripheral. 82 // Note: enable and reset come from RccPeripheral.
85 // reset to default values and enable CRC clock in RCC. 83 // reset to default values and enable CRC clock in RCC.
86 rcc::enable_and_reset::<CRC>(); 84 rcc::enable_and_reset::<CRC>();
87 into_ref!(peripheral);
88 let mut instance = Self { 85 let mut instance = Self {
89 _peripheral: peripheral, 86 _peripheral: peripheral,
90 _config: config, 87 _config: config,
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index 6afe68a39..fba3c0fd7 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -4,12 +4,13 @@ use core::cmp::min;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::ptr; 5use core::ptr;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{Peri, PeripheralType};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::dma::{NoDma, Transfer, TransferOptions}; 10use crate::dma::{ChannelAndRequest, TransferOptions};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, pac, peripherals, rcc, Peripheral}; 12use crate::mode::{Async, Blocking, Mode};
13use crate::{interrupt, pac, peripherals, rcc};
13 14
14const DES_BLOCK_SIZE: usize = 8; // 64 bits 15const DES_BLOCK_SIZE: usize = 8; // 64 bits
15const AES_BLOCK_SIZE: usize = 16; // 128 bits 16const AES_BLOCK_SIZE: usize = 16; // 128 bits
@@ -57,15 +58,10 @@ pub trait Cipher<'c> {
57 fn prepare_key(&self, _p: pac::cryp::Cryp) {} 58 fn prepare_key(&self, _p: pac::cryp::Cryp) {}
58 59
59 /// Performs any cipher-specific initialization. 60 /// Performs any cipher-specific initialization.
60 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, _p: pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) {} 61 fn init_phase_blocking<T: Instance, M: Mode>(&self, _p: pac::cryp::Cryp, _cryp: &Cryp<T, M>) {}
61 62
62 /// Performs any cipher-specific initialization. 63 /// Performs any cipher-specific initialization.
63 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, _p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) 64 async fn init_phase<T: Instance>(&self, _p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) {}
64 where
65 DmaIn: crate::cryp::DmaIn<T>,
66 DmaOut: crate::cryp::DmaOut<T>,
67 {
68 }
69 65
70 /// Called prior to processing the last data block for cipher-specific operations. 66 /// Called prior to processing the last data block for cipher-specific operations.
71 fn pre_final(&self, _p: pac::cryp::Cryp, _dir: Direction, _padding_len: usize) -> [u32; 4] { 67 fn pre_final(&self, _p: pac::cryp::Cryp, _dir: Direction, _padding_len: usize) -> [u32; 4] {
@@ -73,10 +69,10 @@ pub trait Cipher<'c> {
73 } 69 }
74 70
75 /// Called after processing the last data block for cipher-specific operations. 71 /// Called after processing the last data block for cipher-specific operations.
76 fn post_final_blocking<T: Instance, DmaIn, DmaOut>( 72 fn post_final_blocking<T: Instance, M: Mode>(
77 &self, 73 &self,
78 _p: pac::cryp::Cryp, 74 _p: pac::cryp::Cryp,
79 _cryp: &Cryp<T, DmaIn, DmaOut>, 75 _cryp: &Cryp<T, M>,
80 _dir: Direction, 76 _dir: Direction,
81 _int_data: &mut [u8; AES_BLOCK_SIZE], 77 _int_data: &mut [u8; AES_BLOCK_SIZE],
82 _temp1: [u32; 4], 78 _temp1: [u32; 4],
@@ -85,18 +81,15 @@ pub trait Cipher<'c> {
85 } 81 }
86 82
87 /// Called after processing the last data block for cipher-specific operations. 83 /// Called after processing the last data block for cipher-specific operations.
88 async fn post_final<T: Instance, DmaIn, DmaOut>( 84 async fn post_final<T: Instance>(
89 &self, 85 &self,
90 _p: pac::cryp::Cryp, 86 _p: pac::cryp::Cryp,
91 _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, 87 _cryp: &mut Cryp<'_, T, Async>,
92 _dir: Direction, 88 _dir: Direction,
93 _int_data: &mut [u8; AES_BLOCK_SIZE], 89 _int_data: &mut [u8; AES_BLOCK_SIZE],
94 _temp1: [u32; 4], 90 _temp1: [u32; 4],
95 _padding_mask: [u8; 16], 91 _padding_mask: [u8; 16],
96 ) where 92 ) {
97 DmaIn: crate::cryp::DmaIn<T>,
98 DmaOut: crate::cryp::DmaOut<T>,
99 {
100 } 93 }
101 94
102 /// Returns the AAD header block as required by the cipher. 95 /// Returns the AAD header block as required by the cipher.
@@ -474,13 +467,13 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
474 p.cr().modify(|w| w.set_algomode3(true)); 467 p.cr().modify(|w| w.set_algomode3(true));
475 } 468 }
476 469
477 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) { 470 fn init_phase_blocking<T: Instance, M: Mode>(&self, p: pac::cryp::Cryp, _cryp: &Cryp<T, M>) {
478 p.cr().modify(|w| w.set_gcm_ccmph(0)); 471 p.cr().modify(|w| w.set_gcm_ccmph(0));
479 p.cr().modify(|w| w.set_crypen(true)); 472 p.cr().modify(|w| w.set_crypen(true));
480 while p.cr().read().crypen() {} 473 while p.cr().read().crypen() {}
481 } 474 }
482 475
483 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) { 476 async fn init_phase<T: Instance>(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) {
484 p.cr().modify(|w| w.set_gcm_ccmph(0)); 477 p.cr().modify(|w| w.set_gcm_ccmph(0));
485 p.cr().modify(|w| w.set_crypen(true)); 478 p.cr().modify(|w| w.set_crypen(true));
486 while p.cr().read().crypen() {} 479 while p.cr().read().crypen() {}
@@ -508,10 +501,10 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
508 } 501 }
509 502
510 #[cfg(cryp_v2)] 503 #[cfg(cryp_v2)]
511 fn post_final_blocking<T: Instance, DmaIn, DmaOut>( 504 fn post_final_blocking<T: Instance, M: Mode>(
512 &self, 505 &self,
513 p: pac::cryp::Cryp, 506 p: pac::cryp::Cryp,
514 cryp: &Cryp<T, DmaIn, DmaOut>, 507 cryp: &Cryp<T, M>,
515 dir: Direction, 508 dir: Direction,
516 int_data: &mut [u8; AES_BLOCK_SIZE], 509 int_data: &mut [u8; AES_BLOCK_SIZE],
517 _temp1: [u32; 4], 510 _temp1: [u32; 4],
@@ -534,18 +527,15 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
534 } 527 }
535 528
536 #[cfg(cryp_v2)] 529 #[cfg(cryp_v2)]
537 async fn post_final<T: Instance, DmaIn, DmaOut>( 530 async fn post_final<T: Instance>(
538 &self, 531 &self,
539 p: pac::cryp::Cryp, 532 p: pac::cryp::Cryp,
540 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, 533 cryp: &mut Cryp<'_, T, Async>,
541 dir: Direction, 534 dir: Direction,
542 int_data: &mut [u8; AES_BLOCK_SIZE], 535 int_data: &mut [u8; AES_BLOCK_SIZE],
543 _temp1: [u32; 4], 536 _temp1: [u32; 4],
544 padding_mask: [u8; AES_BLOCK_SIZE], 537 padding_mask: [u8; AES_BLOCK_SIZE],
545 ) where 538 ) {
546 DmaIn: crate::cryp::DmaIn<T>,
547 DmaOut: crate::cryp::DmaOut<T>,
548 {
549 if dir == Direction::Encrypt { 539 if dir == Direction::Encrypt {
550 // Handle special GCM partial block process. 540 // Handle special GCM partial block process.
551 p.cr().modify(|w| w.set_crypen(false)); 541 p.cr().modify(|w| w.set_crypen(false));
@@ -559,8 +549,8 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
559 549
560 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; 550 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
561 551
562 let read = Cryp::<T, DmaIn, DmaOut>::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data); 552 let read = Cryp::<T, Async>::read_bytes(cryp.outdma.as_mut().unwrap(), Self::BLOCK_SIZE, &mut out_data);
563 let write = Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data); 553 let write = Cryp::<T, Async>::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, int_data);
564 554
565 embassy_futures::join::join(read, write).await; 555 embassy_futures::join::join(read, write).await;
566 556
@@ -615,13 +605,13 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
615 p.cr().modify(|w| w.set_algomode3(true)); 605 p.cr().modify(|w| w.set_algomode3(true));
616 } 606 }
617 607
618 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) { 608 fn init_phase_blocking<T: Instance, M: Mode>(&self, p: pac::cryp::Cryp, _cryp: &Cryp<T, M>) {
619 p.cr().modify(|w| w.set_gcm_ccmph(0)); 609 p.cr().modify(|w| w.set_gcm_ccmph(0));
620 p.cr().modify(|w| w.set_crypen(true)); 610 p.cr().modify(|w| w.set_crypen(true));
621 while p.cr().read().crypen() {} 611 while p.cr().read().crypen() {}
622 } 612 }
623 613
624 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) { 614 async fn init_phase<T: Instance>(&self, p: pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, Async>) {
625 p.cr().modify(|w| w.set_gcm_ccmph(0)); 615 p.cr().modify(|w| w.set_gcm_ccmph(0));
626 p.cr().modify(|w| w.set_crypen(true)); 616 p.cr().modify(|w| w.set_crypen(true));
627 while p.cr().read().crypen() {} 617 while p.cr().read().crypen() {}
@@ -649,10 +639,10 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
649 } 639 }
650 640
651 #[cfg(cryp_v2)] 641 #[cfg(cryp_v2)]
652 fn post_final_blocking<T: Instance, DmaIn, DmaOut>( 642 fn post_final_blocking<T: Instance, M: Mode>(
653 &self, 643 &self,
654 p: pac::cryp::Cryp, 644 p: pac::cryp::Cryp,
655 cryp: &Cryp<T, DmaIn, DmaOut>, 645 cryp: &Cryp<T, M>,
656 dir: Direction, 646 dir: Direction,
657 int_data: &mut [u8; AES_BLOCK_SIZE], 647 int_data: &mut [u8; AES_BLOCK_SIZE],
658 _temp1: [u32; 4], 648 _temp1: [u32; 4],
@@ -675,18 +665,15 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
675 } 665 }
676 666
677 #[cfg(cryp_v2)] 667 #[cfg(cryp_v2)]
678 async fn post_final<T: Instance, DmaIn, DmaOut>( 668 async fn post_final<T: Instance>(
679 &self, 669 &self,
680 p: pac::cryp::Cryp, 670 p: pac::cryp::Cryp,
681 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, 671 cryp: &mut Cryp<'_, T, Async>,
682 dir: Direction, 672 dir: Direction,
683 int_data: &mut [u8; AES_BLOCK_SIZE], 673 int_data: &mut [u8; AES_BLOCK_SIZE],
684 _temp1: [u32; 4], 674 _temp1: [u32; 4],
685 padding_mask: [u8; AES_BLOCK_SIZE], 675 padding_mask: [u8; AES_BLOCK_SIZE],
686 ) where 676 ) {
687 DmaIn: crate::cryp::DmaIn<T>,
688 DmaOut: crate::cryp::DmaOut<T>,
689 {
690 if dir == Direction::Encrypt { 677 if dir == Direction::Encrypt {
691 // Handle special GCM partial block process. 678 // Handle special GCM partial block process.
692 p.cr().modify(|w| w.set_crypen(false)); 679 p.cr().modify(|w| w.set_crypen(false));
@@ -700,8 +687,8 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
700 687
701 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; 688 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
702 689
703 let read = Cryp::<T, DmaIn, DmaOut>::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data); 690 let read = Cryp::<T, Async>::read_bytes(cryp.outdma.as_mut().unwrap(), Self::BLOCK_SIZE, &mut out_data);
704 let write = Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data); 691 let write = Cryp::<T, Async>::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, int_data);
705 692
706 embassy_futures::join::join(read, write).await; 693 embassy_futures::join::join(read, write).await;
707 } 694 }
@@ -812,7 +799,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
812 p.cr().modify(|w| w.set_algomode3(true)); 799 p.cr().modify(|w| w.set_algomode3(true));
813 } 800 }
814 801
815 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, cryp: &Cryp<T, DmaIn, DmaOut>) { 802 fn init_phase_blocking<T: Instance, M: Mode>(&self, p: pac::cryp::Cryp, cryp: &Cryp<T, M>) {
816 p.cr().modify(|w| w.set_gcm_ccmph(0)); 803 p.cr().modify(|w| w.set_gcm_ccmph(0));
817 804
818 cryp.write_bytes_blocking(Self::BLOCK_SIZE, &self.block0); 805 cryp.write_bytes_blocking(Self::BLOCK_SIZE, &self.block0);
@@ -821,14 +808,10 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
821 while p.cr().read().crypen() {} 808 while p.cr().read().crypen() {}
822 } 809 }
823 810
824 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, p: pac::cryp::Cryp, cryp: &mut Cryp<'_, T, DmaIn, DmaOut>) 811 async fn init_phase<T: Instance>(&self, p: pac::cryp::Cryp, cryp: &mut Cryp<'_, T, Async>) {
825 where
826 DmaIn: crate::cryp::DmaIn<T>,
827 DmaOut: crate::cryp::DmaOut<T>,
828 {
829 p.cr().modify(|w| w.set_gcm_ccmph(0)); 812 p.cr().modify(|w| w.set_gcm_ccmph(0));
830 813
831 Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, &self.block0).await; 814 Cryp::<T, Async>::write_bytes(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, &self.block0).await;
832 815
833 p.cr().modify(|w| w.set_crypen(true)); 816 p.cr().modify(|w| w.set_crypen(true));
834 while p.cr().read().crypen() {} 817 while p.cr().read().crypen() {}
@@ -865,10 +848,10 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
865 } 848 }
866 849
867 #[cfg(cryp_v2)] 850 #[cfg(cryp_v2)]
868 fn post_final_blocking<T: Instance, DmaIn, DmaOut>( 851 fn post_final_blocking<T: Instance, M: Mode>(
869 &self, 852 &self,
870 p: pac::cryp::Cryp, 853 p: pac::cryp::Cryp,
871 cryp: &Cryp<T, DmaIn, DmaOut>, 854 cryp: &Cryp<T, M>,
872 dir: Direction, 855 dir: Direction,
873 int_data: &mut [u8; AES_BLOCK_SIZE], 856 int_data: &mut [u8; AES_BLOCK_SIZE],
874 temp1: [u32; 4], 857 temp1: [u32; 4],
@@ -902,18 +885,15 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
902 } 885 }
903 886
904 #[cfg(cryp_v2)] 887 #[cfg(cryp_v2)]
905 async fn post_final<T: Instance, DmaIn, DmaOut>( 888 async fn post_final<T: Instance>(
906 &self, 889 &self,
907 p: pac::cryp::Cryp, 890 p: pac::cryp::Cryp,
908 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>, 891 cryp: &mut Cryp<'_, T, Async>,
909 dir: Direction, 892 dir: Direction,
910 int_data: &mut [u8; AES_BLOCK_SIZE], 893 int_data: &mut [u8; AES_BLOCK_SIZE],
911 temp1: [u32; 4], 894 temp1: [u32; 4],
912 padding_mask: [u8; 16], 895 padding_mask: [u8; 16],
913 ) where 896 ) {
914 DmaIn: crate::cryp::DmaIn<T>,
915 DmaOut: crate::cryp::DmaOut<T>,
916 {
917 if dir == Direction::Decrypt { 897 if dir == Direction::Decrypt {
918 //Handle special CCM partial block process. 898 //Handle special CCM partial block process.
919 let mut temp2 = [0; 4]; 899 let mut temp2 = [0; 4];
@@ -937,7 +917,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
937 in_data[i] = int_word; 917 in_data[i] = int_word;
938 in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i]; 918 in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i];
939 } 919 }
940 Cryp::<T, DmaIn, DmaOut>::write_words(&mut cryp.indma, Self::BLOCK_SIZE, &in_data).await; 920 Cryp::<T, Async>::write_words(cryp.indma.as_mut().unwrap(), Self::BLOCK_SIZE, &in_data).await;
941 } 921 }
942 } 922 }
943} 923}
@@ -1007,26 +987,25 @@ pub enum Direction {
1007} 987}
1008 988
1009/// Crypto Accelerator Driver 989/// Crypto Accelerator Driver
1010pub struct Cryp<'d, T: Instance, DmaIn = NoDma, DmaOut = NoDma> { 990pub struct Cryp<'d, T: Instance, M: Mode> {
1011 _peripheral: PeripheralRef<'d, T>, 991 _peripheral: Peri<'d, T>,
1012 indma: PeripheralRef<'d, DmaIn>, 992 _phantom: PhantomData<M>,
1013 outdma: PeripheralRef<'d, DmaOut>, 993 indma: Option<ChannelAndRequest<'d>>,
994 outdma: Option<ChannelAndRequest<'d>>,
1014} 995}
1015 996
1016impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { 997impl<'d, T: Instance> Cryp<'d, T, Blocking> {
1017 /// Create a new CRYP driver. 998 /// Create a new CRYP driver in blocking mode.
1018 pub fn new( 999 pub fn new_blocking(
1019 peri: impl Peripheral<P = T> + 'd, 1000 peri: Peri<'d, T>,
1020 indma: impl Peripheral<P = DmaIn> + 'd,
1021 outdma: impl Peripheral<P = DmaOut> + 'd,
1022 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1001 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1023 ) -> Self { 1002 ) -> Self {
1024 rcc::enable_and_reset::<T>(); 1003 rcc::enable_and_reset::<T>();
1025 into_ref!(peri, indma, outdma);
1026 let instance = Self { 1004 let instance = Self {
1027 _peripheral: peri, 1005 _peripheral: peri,
1028 indma: indma, 1006 _phantom: PhantomData,
1029 outdma: outdma, 1007 indma: None,
1008 outdma: None,
1030 }; 1009 };
1031 1010
1032 T::Interrupt::unpend(); 1011 T::Interrupt::unpend();
@@ -1034,7 +1013,9 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1034 1013
1035 instance 1014 instance
1036 } 1015 }
1016}
1037 1017
1018impl<'d, T: Instance, M: Mode> Cryp<'d, T, M> {
1038 /// Start a new encrypt or decrypt operation for the given cipher. 1019 /// Start a new encrypt or decrypt operation for the given cipher.
1039 pub fn start_blocking<'c, C: Cipher<'c> + CipherSized + IVSized>( 1020 pub fn start_blocking<'c, C: Cipher<'c> + CipherSized + IVSized>(
1040 &self, 1021 &self,
@@ -1114,89 +1095,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1114 ctx 1095 ctx
1115 } 1096 }
1116 1097
1117 /// Start a new encrypt or decrypt operation for the given cipher.
1118 pub async fn start<'c, C: Cipher<'c> + CipherSized + IVSized>(
1119 &mut self,
1120 cipher: &'c C,
1121 dir: Direction,
1122 ) -> Context<'c, C>
1123 where
1124 DmaIn: crate::cryp::DmaIn<T>,
1125 DmaOut: crate::cryp::DmaOut<T>,
1126 {
1127 let mut ctx: Context<'c, C> = Context {
1128 dir,
1129 last_block_processed: false,
1130 cr: 0,
1131 iv: [0; 4],
1132 csgcmccm: [0; 8],
1133 csgcm: [0; 8],
1134 aad_complete: false,
1135 header_len: 0,
1136 payload_len: 0,
1137 cipher: cipher,
1138 phantom_data: PhantomData,
1139 header_processed: false,
1140 aad_buffer: [0; 16],
1141 aad_buffer_len: 0,
1142 };
1143
1144 T::regs().cr().modify(|w| w.set_crypen(false));
1145
1146 let key = ctx.cipher.key();
1147
1148 if key.len() == (128 / 8) {
1149 T::regs().cr().modify(|w| w.set_keysize(0));
1150 } else if key.len() == (192 / 8) {
1151 T::regs().cr().modify(|w| w.set_keysize(1));
1152 } else if key.len() == (256 / 8) {
1153 T::regs().cr().modify(|w| w.set_keysize(2));
1154 }
1155
1156 self.load_key(key);
1157
1158 // Set data type to 8-bit. This will match software implementations.
1159 T::regs().cr().modify(|w| w.set_datatype(2));
1160
1161 ctx.cipher.prepare_key(T::regs());
1162
1163 ctx.cipher.set_algomode(T::regs());
1164
1165 // Set encrypt/decrypt
1166 if dir == Direction::Encrypt {
1167 T::regs().cr().modify(|w| w.set_algodir(false));
1168 } else {
1169 T::regs().cr().modify(|w| w.set_algodir(true));
1170 }
1171
1172 // Load the IV into the registers.
1173 let iv = ctx.cipher.iv();
1174 let mut full_iv: [u8; 16] = [0; 16];
1175 full_iv[0..iv.len()].copy_from_slice(iv);
1176 let mut iv_idx = 0;
1177 let mut iv_word: [u8; 4] = [0; 4];
1178 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1179 iv_idx += 4;
1180 T::regs().init(0).ivlr().write_value(u32::from_be_bytes(iv_word));
1181 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1182 iv_idx += 4;
1183 T::regs().init(0).ivrr().write_value(u32::from_be_bytes(iv_word));
1184 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1185 iv_idx += 4;
1186 T::regs().init(1).ivlr().write_value(u32::from_be_bytes(iv_word));
1187 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1188 T::regs().init(1).ivrr().write_value(u32::from_be_bytes(iv_word));
1189
1190 // Flush in/out FIFOs
1191 T::regs().cr().modify(|w| w.fflush());
1192
1193 ctx.cipher.init_phase(T::regs(), self).await;
1194
1195 self.store_context(&mut ctx);
1196
1197 ctx
1198 }
1199
1200 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] 1098 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1201 /// Controls the header phase of cipher processing. 1099 /// Controls the header phase of cipher processing.
1202 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC. 1100 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
@@ -1294,101 +1192,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1294 self.store_context(ctx); 1192 self.store_context(ctx);
1295 } 1193 }
1296 1194
1297 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1298 /// Controls the header phase of cipher processing.
1299 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
1300 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`.
1301 /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block.
1302 /// When supplying the last block of AAD, `last_aad_block` must be `true`.
1303 pub async fn aad<'c, const TAG_SIZE: usize, C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>>(
1304 &mut self,
1305 ctx: &mut Context<'c, C>,
1306 aad: &[u8],
1307 last_aad_block: bool,
1308 ) where
1309 DmaIn: crate::cryp::DmaIn<T>,
1310 DmaOut: crate::cryp::DmaOut<T>,
1311 {
1312 self.load_context(ctx);
1313
1314 // Perform checks for correctness.
1315 if ctx.aad_complete {
1316 panic!("Cannot update AAD after starting payload!")
1317 }
1318
1319 ctx.header_len += aad.len() as u64;
1320
1321 // Header phase
1322 T::regs().cr().modify(|w| w.set_crypen(false));
1323 T::regs().cr().modify(|w| w.set_gcm_ccmph(1));
1324 T::regs().cr().modify(|w| w.set_crypen(true));
1325
1326 // First write the header B1 block if not yet written.
1327 if !ctx.header_processed {
1328 ctx.header_processed = true;
1329 let header = ctx.cipher.get_header_block();
1330 ctx.aad_buffer[0..header.len()].copy_from_slice(header);
1331 ctx.aad_buffer_len += header.len();
1332 }
1333
1334 // Fill the header block to make a full block.
1335 let len_to_copy = min(aad.len(), C::BLOCK_SIZE - ctx.aad_buffer_len);
1336 ctx.aad_buffer[ctx.aad_buffer_len..ctx.aad_buffer_len + len_to_copy].copy_from_slice(&aad[..len_to_copy]);
1337 ctx.aad_buffer_len += len_to_copy;
1338 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1339 let mut aad_len_remaining = aad.len() - len_to_copy;
1340
1341 if ctx.aad_buffer_len < C::BLOCK_SIZE {
1342 // The buffer isn't full and this is the last buffer, so process it as is (already padded).
1343 if last_aad_block {
1344 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1345 assert_eq!(T::regs().sr().read().ifem(), true);
1346
1347 // Switch to payload phase.
1348 ctx.aad_complete = true;
1349 T::regs().cr().modify(|w| w.set_crypen(false));
1350 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1351 T::regs().cr().modify(|w| w.fflush());
1352 } else {
1353 // Just return because we don't yet have a full block to process.
1354 return;
1355 }
1356 } else {
1357 // Load the full block from the buffer.
1358 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1359 assert_eq!(T::regs().sr().read().ifem(), true);
1360 }
1361
1362 // Handle a partial block that is passed in.
1363 ctx.aad_buffer_len = 0;
1364 let leftovers = aad_len_remaining % C::BLOCK_SIZE;
1365 ctx.aad_buffer[..leftovers].copy_from_slice(&aad[aad.len() - leftovers..aad.len()]);
1366 ctx.aad_buffer_len += leftovers;
1367 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1368 aad_len_remaining -= leftovers;
1369 assert_eq!(aad_len_remaining % C::BLOCK_SIZE, 0);
1370
1371 // Load full data blocks into core.
1372 let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE;
1373 let start_index = len_to_copy;
1374 let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks);
1375 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &aad[start_index..end_index]).await;
1376
1377 if last_aad_block {
1378 if leftovers > 0 {
1379 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1380 assert_eq!(T::regs().sr().read().ifem(), true);
1381 }
1382 // Switch to payload phase.
1383 ctx.aad_complete = true;
1384 T::regs().cr().modify(|w| w.set_crypen(false));
1385 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1386 T::regs().cr().modify(|w| w.fflush());
1387 }
1388
1389 self.store_context(ctx);
1390 }
1391
1392 /// Performs encryption/decryption on the provided context. 1195 /// Performs encryption/decryption on the provided context.
1393 /// The context determines algorithm, mode, and state of the crypto accelerator. 1196 /// The context determines algorithm, mode, and state of the crypto accelerator.
1394 /// When the last piece of data is supplied, `last_block` should be `true`. 1197 /// When the last piece of data is supplied, `last_block` should be `true`.
@@ -1478,105 +1281,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1478 self.store_context(ctx); 1281 self.store_context(ctx);
1479 } 1282 }
1480 1283
1481 /// Performs encryption/decryption on the provided context.
1482 /// The context determines algorithm, mode, and state of the crypto accelerator.
1483 /// When the last piece of data is supplied, `last_block` should be `true`.
1484 /// This function panics under various mismatches of parameters.
1485 /// Output buffer must be at least as long as the input buffer.
1486 /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes.
1487 /// Padding or ciphertext stealing must be managed by the application for these modes.
1488 /// Data must also be a multiple of block size unless `last_block` is `true`.
1489 pub async fn payload<'c, C: Cipher<'c> + CipherSized + IVSized>(
1490 &mut self,
1491 ctx: &mut Context<'c, C>,
1492 input: &[u8],
1493 output: &mut [u8],
1494 last_block: bool,
1495 ) where
1496 DmaIn: crate::cryp::DmaIn<T>,
1497 DmaOut: crate::cryp::DmaOut<T>,
1498 {
1499 self.load_context(ctx);
1500
1501 let last_block_remainder = input.len() % C::BLOCK_SIZE;
1502
1503 // Perform checks for correctness.
1504 if !ctx.aad_complete && ctx.header_len > 0 {
1505 panic!("Additional associated data must be processed first!");
1506 } else if !ctx.aad_complete {
1507 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1508 {
1509 ctx.aad_complete = true;
1510 T::regs().cr().modify(|w| w.set_crypen(false));
1511 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1512 T::regs().cr().modify(|w| w.fflush());
1513 T::regs().cr().modify(|w| w.set_crypen(true));
1514 }
1515 }
1516 if ctx.last_block_processed {
1517 panic!("The last block has already been processed!");
1518 }
1519 if input.len() > output.len() {
1520 panic!("Output buffer length must match input length.");
1521 }
1522 if !last_block {
1523 if last_block_remainder != 0 {
1524 panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE);
1525 }
1526 }
1527 if C::REQUIRES_PADDING {
1528 if last_block_remainder != 0 {
1529 panic!("Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.", C::BLOCK_SIZE);
1530 }
1531 }
1532 if last_block {
1533 ctx.last_block_processed = true;
1534 }
1535
1536 // Load data into core, block by block.
1537 let num_full_blocks = input.len() / C::BLOCK_SIZE;
1538 for block in 0..num_full_blocks {
1539 let index = block * C::BLOCK_SIZE;
1540 // Read block out
1541 let read = Self::read_bytes(
1542 &mut self.outdma,
1543 C::BLOCK_SIZE,
1544 &mut output[index..index + C::BLOCK_SIZE],
1545 );
1546 // Write block in
1547 let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &input[index..index + C::BLOCK_SIZE]);
1548 embassy_futures::join::join(read, write).await;
1549 }
1550
1551 // Handle the final block, which is incomplete.
1552 if last_block_remainder > 0 {
1553 let padding_len = C::BLOCK_SIZE - last_block_remainder;
1554 let temp1 = ctx.cipher.pre_final(T::regs(), ctx.dir, padding_len);
1555
1556 let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1557 let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1558 last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]);
1559 let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut intermediate_data);
1560 let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &last_block);
1561 embassy_futures::join::join(read, write).await;
1562
1563 // Handle the last block depending on mode.
1564 let output_len = output.len();
1565 output[output_len - last_block_remainder..output_len]
1566 .copy_from_slice(&intermediate_data[0..last_block_remainder]);
1567
1568 let mut mask: [u8; 16] = [0; 16];
1569 mask[..last_block_remainder].fill(0xFF);
1570 ctx.cipher
1571 .post_final(T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask)
1572 .await;
1573 }
1574
1575 ctx.payload_len += input.len() as u64;
1576
1577 self.store_context(ctx);
1578 }
1579
1580 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] 1284 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1581 /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC. 1285 /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1582 /// Called after the all data has been encrypted/decrypted by `payload`. 1286 /// Called after the all data has been encrypted/decrypted by `payload`.
@@ -1623,57 +1327,6 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1623 tag 1327 tag
1624 } 1328 }
1625 1329
1626 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1627 // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1628 /// Called after the all data has been encrypted/decrypted by `payload`.
1629 pub async fn finish<
1630 'c,
1631 const TAG_SIZE: usize,
1632 C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>,
1633 >(
1634 &mut self,
1635 mut ctx: Context<'c, C>,
1636 ) -> [u8; TAG_SIZE]
1637 where
1638 DmaIn: crate::cryp::DmaIn<T>,
1639 DmaOut: crate::cryp::DmaOut<T>,
1640 {
1641 self.load_context(&mut ctx);
1642
1643 T::regs().cr().modify(|w| w.set_crypen(false));
1644 T::regs().cr().modify(|w| w.set_gcm_ccmph(3));
1645 T::regs().cr().modify(|w| w.set_crypen(true));
1646
1647 let headerlen1: u32 = ((ctx.header_len * 8) >> 32) as u32;
1648 let headerlen2: u32 = (ctx.header_len * 8) as u32;
1649 let payloadlen1: u32 = ((ctx.payload_len * 8) >> 32) as u32;
1650 let payloadlen2: u32 = (ctx.payload_len * 8) as u32;
1651
1652 #[cfg(cryp_v2)]
1653 let footer: [u32; 4] = [
1654 headerlen1.swap_bytes(),
1655 headerlen2.swap_bytes(),
1656 payloadlen1.swap_bytes(),
1657 payloadlen2.swap_bytes(),
1658 ];
1659 #[cfg(any(cryp_v3, cryp_v4))]
1660 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1661
1662 let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer);
1663
1664 let mut full_tag: [u8; 16] = [0; 16];
1665 let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut full_tag);
1666
1667 embassy_futures::join::join(read, write).await;
1668
1669 let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE];
1670 tag.copy_from_slice(&full_tag[0..TAG_SIZE]);
1671
1672 T::regs().cr().modify(|w| w.set_crypen(false));
1673
1674 tag
1675 }
1676
1677 fn load_key(&self, key: &[u8]) { 1330 fn load_key(&self, key: &[u8]) {
1678 // Load the key into the registers. 1331 // Load the key into the registers.
1679 let mut keyidx = 0; 1332 let mut keyidx = 0;
@@ -1774,17 +1427,392 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1774 } 1427 }
1775 } 1428 }
1776 1429
1777 async fn write_bytes(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u8]) 1430 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1778 where 1431 fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) {
1779 DmaIn: crate::cryp::DmaIn<T>, 1432 assert_eq!((blocks.len() * 4) % block_size, 0);
1780 { 1433 let mut byte_counter: usize = 0;
1434 for word in blocks {
1435 T::regs().din().write_value(*word);
1436 byte_counter += 4;
1437 if byte_counter % block_size == 0 {
1438 // Block until input FIFO is empty.
1439 while !T::regs().sr().read().ifem() {}
1440 }
1441 }
1442 }
1443
1444 fn read_bytes_blocking(&self, block_size: usize, blocks: &mut [u8]) {
1445 // Block until there is output to read.
1446 while !T::regs().sr().read().ofne() {}
1447 // Ensure input is a multiple of block size.
1448 assert_eq!(blocks.len() % block_size, 0);
1449 // Read block out
1450 let mut index = 0;
1451 let end_index = blocks.len();
1452 while index < end_index {
1453 let out_word: u32 = T::regs().dout().read();
1454 blocks[index..index + 4].copy_from_slice(u32::to_ne_bytes(out_word).as_slice());
1455 index += 4;
1456 }
1457 }
1458}
1459
1460impl<'d, T: Instance> Cryp<'d, T, Async> {
1461 /// Create a new CRYP driver.
1462 pub fn new(
1463 peri: Peri<'d, T>,
1464 indma: Peri<'d, impl DmaIn<T>>,
1465 outdma: Peri<'d, impl DmaOut<T>>,
1466 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1467 ) -> Self {
1468 rcc::enable_and_reset::<T>();
1469 let instance = Self {
1470 _peripheral: peri,
1471 _phantom: PhantomData,
1472 indma: new_dma!(indma),
1473 outdma: new_dma!(outdma),
1474 };
1475
1476 T::Interrupt::unpend();
1477 unsafe { T::Interrupt::enable() };
1478
1479 instance
1480 }
1481
1482 /// Start a new encrypt or decrypt operation for the given cipher.
1483 pub async fn start<'c, C: Cipher<'c> + CipherSized + IVSized>(
1484 &mut self,
1485 cipher: &'c C,
1486 dir: Direction,
1487 ) -> Context<'c, C> {
1488 let mut ctx: Context<'c, C> = Context {
1489 dir,
1490 last_block_processed: false,
1491 cr: 0,
1492 iv: [0; 4],
1493 csgcmccm: [0; 8],
1494 csgcm: [0; 8],
1495 aad_complete: false,
1496 header_len: 0,
1497 payload_len: 0,
1498 cipher: cipher,
1499 phantom_data: PhantomData,
1500 header_processed: false,
1501 aad_buffer: [0; 16],
1502 aad_buffer_len: 0,
1503 };
1504
1505 T::regs().cr().modify(|w| w.set_crypen(false));
1506
1507 let key = ctx.cipher.key();
1508
1509 if key.len() == (128 / 8) {
1510 T::regs().cr().modify(|w| w.set_keysize(0));
1511 } else if key.len() == (192 / 8) {
1512 T::regs().cr().modify(|w| w.set_keysize(1));
1513 } else if key.len() == (256 / 8) {
1514 T::regs().cr().modify(|w| w.set_keysize(2));
1515 }
1516
1517 self.load_key(key);
1518
1519 // Set data type to 8-bit. This will match software implementations.
1520 T::regs().cr().modify(|w| w.set_datatype(2));
1521
1522 ctx.cipher.prepare_key(T::regs());
1523
1524 ctx.cipher.set_algomode(T::regs());
1525
1526 // Set encrypt/decrypt
1527 if dir == Direction::Encrypt {
1528 T::regs().cr().modify(|w| w.set_algodir(false));
1529 } else {
1530 T::regs().cr().modify(|w| w.set_algodir(true));
1531 }
1532
1533 // Load the IV into the registers.
1534 let iv = ctx.cipher.iv();
1535 let mut full_iv: [u8; 16] = [0; 16];
1536 full_iv[0..iv.len()].copy_from_slice(iv);
1537 let mut iv_idx = 0;
1538 let mut iv_word: [u8; 4] = [0; 4];
1539 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1540 iv_idx += 4;
1541 T::regs().init(0).ivlr().write_value(u32::from_be_bytes(iv_word));
1542 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1543 iv_idx += 4;
1544 T::regs().init(0).ivrr().write_value(u32::from_be_bytes(iv_word));
1545 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1546 iv_idx += 4;
1547 T::regs().init(1).ivlr().write_value(u32::from_be_bytes(iv_word));
1548 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1549 T::regs().init(1).ivrr().write_value(u32::from_be_bytes(iv_word));
1550
1551 // Flush in/out FIFOs
1552 T::regs().cr().modify(|w| w.fflush());
1553
1554 ctx.cipher.init_phase(T::regs(), self).await;
1555
1556 self.store_context(&mut ctx);
1557
1558 ctx
1559 }
1560
1561 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1562 /// Controls the header phase of cipher processing.
1563 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
1564 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`.
1565 /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block.
1566 /// When supplying the last block of AAD, `last_aad_block` must be `true`.
1567 pub async fn aad<
1568 'c,
1569 const TAG_SIZE: usize,
1570 C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>,
1571 >(
1572 &mut self,
1573 ctx: &mut Context<'c, C>,
1574 aad: &[u8],
1575 last_aad_block: bool,
1576 ) {
1577 self.load_context(ctx);
1578
1579 // Perform checks for correctness.
1580 if ctx.aad_complete {
1581 panic!("Cannot update AAD after starting payload!")
1582 }
1583
1584 ctx.header_len += aad.len() as u64;
1585
1586 // Header phase
1587 T::regs().cr().modify(|w| w.set_crypen(false));
1588 T::regs().cr().modify(|w| w.set_gcm_ccmph(1));
1589 T::regs().cr().modify(|w| w.set_crypen(true));
1590
1591 // First write the header B1 block if not yet written.
1592 if !ctx.header_processed {
1593 ctx.header_processed = true;
1594 let header = ctx.cipher.get_header_block();
1595 ctx.aad_buffer[0..header.len()].copy_from_slice(header);
1596 ctx.aad_buffer_len += header.len();
1597 }
1598
1599 // Fill the header block to make a full block.
1600 let len_to_copy = min(aad.len(), C::BLOCK_SIZE - ctx.aad_buffer_len);
1601 ctx.aad_buffer[ctx.aad_buffer_len..ctx.aad_buffer_len + len_to_copy].copy_from_slice(&aad[..len_to_copy]);
1602 ctx.aad_buffer_len += len_to_copy;
1603 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1604 let mut aad_len_remaining = aad.len() - len_to_copy;
1605
1606 if ctx.aad_buffer_len < C::BLOCK_SIZE {
1607 // The buffer isn't full and this is the last buffer, so process it as is (already padded).
1608 if last_aad_block {
1609 Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await;
1610 assert_eq!(T::regs().sr().read().ifem(), true);
1611
1612 // Switch to payload phase.
1613 ctx.aad_complete = true;
1614 T::regs().cr().modify(|w| w.set_crypen(false));
1615 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1616 T::regs().cr().modify(|w| w.fflush());
1617 } else {
1618 // Just return because we don't yet have a full block to process.
1619 return;
1620 }
1621 } else {
1622 // Load the full block from the buffer.
1623 Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await;
1624 assert_eq!(T::regs().sr().read().ifem(), true);
1625 }
1626
1627 // Handle a partial block that is passed in.
1628 ctx.aad_buffer_len = 0;
1629 let leftovers = aad_len_remaining % C::BLOCK_SIZE;
1630 ctx.aad_buffer[..leftovers].copy_from_slice(&aad[aad.len() - leftovers..aad.len()]);
1631 ctx.aad_buffer_len += leftovers;
1632 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1633 aad_len_remaining -= leftovers;
1634 assert_eq!(aad_len_remaining % C::BLOCK_SIZE, 0);
1635
1636 // Load full data blocks into core.
1637 let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE;
1638 let start_index = len_to_copy;
1639 let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks);
1640 Self::write_bytes(
1641 self.indma.as_mut().unwrap(),
1642 C::BLOCK_SIZE,
1643 &aad[start_index..end_index],
1644 )
1645 .await;
1646
1647 if last_aad_block {
1648 if leftovers > 0 {
1649 Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &ctx.aad_buffer).await;
1650 assert_eq!(T::regs().sr().read().ifem(), true);
1651 }
1652 // Switch to payload phase.
1653 ctx.aad_complete = true;
1654 T::regs().cr().modify(|w| w.set_crypen(false));
1655 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1656 T::regs().cr().modify(|w| w.fflush());
1657 }
1658
1659 self.store_context(ctx);
1660 }
1661
1662 /// Performs encryption/decryption on the provided context.
1663 /// The context determines algorithm, mode, and state of the crypto accelerator.
1664 /// When the last piece of data is supplied, `last_block` should be `true`.
1665 /// This function panics under various mismatches of parameters.
1666 /// Output buffer must be at least as long as the input buffer.
1667 /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes.
1668 /// Padding or ciphertext stealing must be managed by the application for these modes.
1669 /// Data must also be a multiple of block size unless `last_block` is `true`.
1670 pub async fn payload<'c, C: Cipher<'c> + CipherSized + IVSized>(
1671 &mut self,
1672 ctx: &mut Context<'c, C>,
1673 input: &[u8],
1674 output: &mut [u8],
1675 last_block: bool,
1676 ) {
1677 self.load_context(ctx);
1678
1679 let last_block_remainder = input.len() % C::BLOCK_SIZE;
1680
1681 // Perform checks for correctness.
1682 if !ctx.aad_complete && ctx.header_len > 0 {
1683 panic!("Additional associated data must be processed first!");
1684 } else if !ctx.aad_complete {
1685 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1686 {
1687 ctx.aad_complete = true;
1688 T::regs().cr().modify(|w| w.set_crypen(false));
1689 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1690 T::regs().cr().modify(|w| w.fflush());
1691 T::regs().cr().modify(|w| w.set_crypen(true));
1692 }
1693 }
1694 if ctx.last_block_processed {
1695 panic!("The last block has already been processed!");
1696 }
1697 if input.len() > output.len() {
1698 panic!("Output buffer length must match input length.");
1699 }
1700 if !last_block {
1701 if last_block_remainder != 0 {
1702 panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE);
1703 }
1704 }
1705 if C::REQUIRES_PADDING {
1706 if last_block_remainder != 0 {
1707 panic!("Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.", C::BLOCK_SIZE);
1708 }
1709 }
1710 if last_block {
1711 ctx.last_block_processed = true;
1712 }
1713
1714 // Load data into core, block by block.
1715 let num_full_blocks = input.len() / C::BLOCK_SIZE;
1716 for block in 0..num_full_blocks {
1717 let index = block * C::BLOCK_SIZE;
1718 // Read block out
1719 let read = Self::read_bytes(
1720 self.outdma.as_mut().unwrap(),
1721 C::BLOCK_SIZE,
1722 &mut output[index..index + C::BLOCK_SIZE],
1723 );
1724 // Write block in
1725 let write = Self::write_bytes(
1726 self.indma.as_mut().unwrap(),
1727 C::BLOCK_SIZE,
1728 &input[index..index + C::BLOCK_SIZE],
1729 );
1730 embassy_futures::join::join(read, write).await;
1731 }
1732
1733 // Handle the final block, which is incomplete.
1734 if last_block_remainder > 0 {
1735 let padding_len = C::BLOCK_SIZE - last_block_remainder;
1736 let temp1 = ctx.cipher.pre_final(T::regs(), ctx.dir, padding_len);
1737
1738 let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1739 let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1740 last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]);
1741 let read = Self::read_bytes(self.outdma.as_mut().unwrap(), C::BLOCK_SIZE, &mut intermediate_data);
1742 let write = Self::write_bytes(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &last_block);
1743 embassy_futures::join::join(read, write).await;
1744
1745 // Handle the last block depending on mode.
1746 let output_len = output.len();
1747 output[output_len - last_block_remainder..output_len]
1748 .copy_from_slice(&intermediate_data[0..last_block_remainder]);
1749
1750 let mut mask: [u8; 16] = [0; 16];
1751 mask[..last_block_remainder].fill(0xFF);
1752 ctx.cipher
1753 .post_final(T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask)
1754 .await;
1755 }
1756
1757 ctx.payload_len += input.len() as u64;
1758
1759 self.store_context(ctx);
1760 }
1761
1762 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1763 // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1764 /// Called after the all data has been encrypted/decrypted by `payload`.
1765 pub async fn finish<
1766 'c,
1767 const TAG_SIZE: usize,
1768 C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>,
1769 >(
1770 &mut self,
1771 mut ctx: Context<'c, C>,
1772 ) -> [u8; TAG_SIZE] {
1773 self.load_context(&mut ctx);
1774
1775 T::regs().cr().modify(|w| w.set_crypen(false));
1776 T::regs().cr().modify(|w| w.set_gcm_ccmph(3));
1777 T::regs().cr().modify(|w| w.set_crypen(true));
1778
1779 let headerlen1: u32 = ((ctx.header_len * 8) >> 32) as u32;
1780 let headerlen2: u32 = (ctx.header_len * 8) as u32;
1781 let payloadlen1: u32 = ((ctx.payload_len * 8) >> 32) as u32;
1782 let payloadlen2: u32 = (ctx.payload_len * 8) as u32;
1783
1784 #[cfg(cryp_v2)]
1785 let footer: [u32; 4] = [
1786 headerlen1.swap_bytes(),
1787 headerlen2.swap_bytes(),
1788 payloadlen1.swap_bytes(),
1789 payloadlen2.swap_bytes(),
1790 ];
1791 #[cfg(any(cryp_v3, cryp_v4))]
1792 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1793
1794 let write = Self::write_words(self.indma.as_mut().unwrap(), C::BLOCK_SIZE, &footer);
1795
1796 let mut full_tag: [u8; 16] = [0; 16];
1797 let read = Self::read_bytes(self.outdma.as_mut().unwrap(), C::BLOCK_SIZE, &mut full_tag);
1798
1799 embassy_futures::join::join(read, write).await;
1800
1801 let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE];
1802 tag.copy_from_slice(&full_tag[0..TAG_SIZE]);
1803
1804 T::regs().cr().modify(|w| w.set_crypen(false));
1805
1806 tag
1807 }
1808
1809 async fn write_bytes(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &[u8]) {
1781 if blocks.len() == 0 { 1810 if blocks.len() == 0 {
1782 return; 1811 return;
1783 } 1812 }
1784 // Ensure input is a multiple of block size. 1813 // Ensure input is a multiple of block size.
1785 assert_eq!(blocks.len() % block_size, 0); 1814 assert_eq!(blocks.len() % block_size, 0);
1786 // Configure DMA to transfer input to crypto core. 1815 // Configure DMA to transfer input to crypto core.
1787 let dma_request = dma.request();
1788 let dst_ptr: *mut u32 = T::regs().din().as_ptr(); 1816 let dst_ptr: *mut u32 = T::regs().din().as_ptr();
1789 let num_words = blocks.len() / 4; 1817 let num_words = blocks.len() / 4;
1790 let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); 1818 let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
@@ -1793,38 +1821,20 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1793 priority: crate::dma::Priority::High, 1821 priority: crate::dma::Priority::High,
1794 ..Default::default() 1822 ..Default::default()
1795 }; 1823 };
1796 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1824 let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) };
1797 T::regs().dmacr().modify(|w| w.set_dien(true)); 1825 T::regs().dmacr().modify(|w| w.set_dien(true));
1798 // Wait for the transfer to complete. 1826 // Wait for the transfer to complete.
1799 dma_transfer.await; 1827 dma_transfer.await;
1800 } 1828 }
1801 1829
1802 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] 1830 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1803 fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) { 1831 async fn write_words(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &[u32]) {
1804 assert_eq!((blocks.len() * 4) % block_size, 0);
1805 let mut byte_counter: usize = 0;
1806 for word in blocks {
1807 T::regs().din().write_value(*word);
1808 byte_counter += 4;
1809 if byte_counter % block_size == 0 {
1810 // Block until input FIFO is empty.
1811 while !T::regs().sr().read().ifem() {}
1812 }
1813 }
1814 }
1815
1816 #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
1817 async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32])
1818 where
1819 DmaIn: crate::cryp::DmaIn<T>,
1820 {
1821 if blocks.len() == 0 { 1832 if blocks.len() == 0 {
1822 return; 1833 return;
1823 } 1834 }
1824 // Ensure input is a multiple of block size. 1835 // Ensure input is a multiple of block size.
1825 assert_eq!((blocks.len() * 4) % block_size, 0); 1836 assert_eq!((blocks.len() * 4) % block_size, 0);
1826 // Configure DMA to transfer input to crypto core. 1837 // Configure DMA to transfer input to crypto core.
1827 let dma_request = dma.request();
1828 let dst_ptr: *mut u32 = T::regs().din().as_ptr(); 1838 let dst_ptr: *mut u32 = T::regs().din().as_ptr();
1829 let num_words = blocks.len(); 1839 let num_words = blocks.len();
1830 let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); 1840 let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
@@ -1833,38 +1843,19 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1833 priority: crate::dma::Priority::High, 1843 priority: crate::dma::Priority::High,
1834 ..Default::default() 1844 ..Default::default()
1835 }; 1845 };
1836 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1846 let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) };
1837 T::regs().dmacr().modify(|w| w.set_dien(true)); 1847 T::regs().dmacr().modify(|w| w.set_dien(true));
1838 // Wait for the transfer to complete. 1848 // Wait for the transfer to complete.
1839 dma_transfer.await; 1849 dma_transfer.await;
1840 } 1850 }
1841 1851
1842 fn read_bytes_blocking(&self, block_size: usize, blocks: &mut [u8]) { 1852 async fn read_bytes(dma: &mut ChannelAndRequest<'d>, block_size: usize, blocks: &mut [u8]) {
1843 // Block until there is output to read.
1844 while !T::regs().sr().read().ofne() {}
1845 // Ensure input is a multiple of block size.
1846 assert_eq!(blocks.len() % block_size, 0);
1847 // Read block out
1848 let mut index = 0;
1849 let end_index = blocks.len();
1850 while index < end_index {
1851 let out_word: u32 = T::regs().dout().read();
1852 blocks[index..index + 4].copy_from_slice(u32::to_ne_bytes(out_word).as_slice());
1853 index += 4;
1854 }
1855 }
1856
1857 async fn read_bytes(dma: &mut PeripheralRef<'_, DmaOut>, block_size: usize, blocks: &mut [u8])
1858 where
1859 DmaOut: crate::cryp::DmaOut<T>,
1860 {
1861 if blocks.len() == 0 { 1853 if blocks.len() == 0 {
1862 return; 1854 return;
1863 } 1855 }
1864 // Ensure input is a multiple of block size. 1856 // Ensure input is a multiple of block size.
1865 assert_eq!(blocks.len() % block_size, 0); 1857 assert_eq!(blocks.len() % block_size, 0);
1866 // Configure DMA to get output from crypto core. 1858 // Configure DMA to get output from crypto core.
1867 let dma_request = dma.request();
1868 let src_ptr = T::regs().dout().as_ptr(); 1859 let src_ptr = T::regs().dout().as_ptr();
1869 let num_words = blocks.len() / 4; 1860 let num_words = blocks.len() / 4;
1870 let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words); 1861 let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words);
@@ -1873,7 +1864,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1873 priority: crate::dma::Priority::VeryHigh, 1864 priority: crate::dma::Priority::VeryHigh,
1874 ..Default::default() 1865 ..Default::default()
1875 }; 1866 };
1876 let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) }; 1867 let dma_transfer = unsafe { dma.read_raw(src_ptr, dst_ptr, options) };
1877 T::regs().dmacr().modify(|w| w.set_doen(true)); 1868 T::regs().dmacr().modify(|w| w.set_doen(true));
1878 // Wait for the transfer to complete. 1869 // Wait for the transfer to complete.
1879 dma_transfer.await; 1870 dma_transfer.await;
@@ -1886,7 +1877,7 @@ trait SealedInstance {
1886 1877
1887/// CRYP instance trait. 1878/// CRYP instance trait.
1888#[allow(private_bounds)] 1879#[allow(private_bounds)]
1889pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 1880pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
1890 /// Interrupt for this CRYP instance. 1881 /// Interrupt for this CRYP instance.
1891 type Interrupt: interrupt::typelevel::Interrupt; 1882 type Interrupt: interrupt::typelevel::Interrupt;
1892} 1883}
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 8bba5ded0..30046849b 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -3,15 +3,15 @@
3 3
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use crate::dma::ChannelAndRequest;
7 7use crate::mode::{Async, Blocking, Mode as PeriMode};
8use crate::dma::NoDma;
9#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] 8#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
10use crate::pac::dac; 9use crate::pac::dac;
11use crate::rcc::{self, RccPeripheral}; 10use crate::rcc::{self, RccPeripheral};
12use crate::{peripherals, Peripheral}; 11use crate::{peripherals, Peri};
13 12
14mod tsel; 13mod tsel;
14use embassy_hal_internal::PeripheralType;
15pub use tsel::TriggerSel; 15pub use tsel::TriggerSel;
16 16
17/// Operating mode for DAC channel 17/// Operating mode for DAC channel
@@ -100,46 +100,34 @@ pub enum ValueArray<'a> {
100/// 100///
101/// If you want to use both channels, either together or independently, 101/// If you want to use both channels, either together or independently,
102/// create a [`Dac`] first and use it to access each channel. 102/// create a [`Dac`] first and use it to access each channel.
103pub struct DacChannel<'d, T: Instance, const N: u8, DMA = NoDma> { 103pub struct DacChannel<'d, T: Instance, C: Channel, M: PeriMode> {
104 phantom: PhantomData<&'d mut T>, 104 phantom: PhantomData<&'d mut (T, C, M)>,
105 #[allow(unused)] 105 #[allow(unused)]
106 dma: PeripheralRef<'d, DMA>, 106 dma: Option<ChannelAndRequest<'d>>,
107} 107}
108 108
109/// DAC channel 1 type alias. 109/// DAC channel 1 type alias.
110pub type DacCh1<'d, T, DMA = NoDma> = DacChannel<'d, T, 1, DMA>; 110pub type DacCh1<'d, T, M> = DacChannel<'d, T, Ch1, M>;
111/// DAC channel 2 type alias. 111/// DAC channel 2 type alias.
112pub type DacCh2<'d, T, DMA = NoDma> = DacChannel<'d, T, 2, DMA>; 112pub type DacCh2<'d, T, M> = DacChannel<'d, T, Ch2, M>;
113
114impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
115 const IDX: usize = (N - 1) as usize;
116 113
114impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Async> {
117 /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral. 115 /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral.
118 /// 116 ///
119 /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument.
120 ///
121 /// The channel is enabled on creation and begin to drive the output pin. 117 /// The channel is enabled on creation and begin to drive the output pin.
122 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will 118 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will
123 /// disable the channel; you must re-enable it with `enable()`. 119 /// disable the channel; you must re-enable it with `enable()`.
124 /// 120 ///
125 /// By default, triggering is disabled, but it can be enabled using 121 /// By default, triggering is disabled, but it can be enabled using
126 /// [`DacChannel::set_trigger()`]. 122 /// [`DacChannel::set_trigger()`].
127 pub fn new( 123 pub fn new(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
128 _peri: impl Peripheral<P = T> + 'd,
129 dma: impl Peripheral<P = DMA> + 'd,
130 pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::Pin> + 'd,
131 ) -> Self {
132 into_ref!(dma, pin);
133 pin.set_as_analog(); 124 pin.set_as_analog();
134 rcc::enable_and_reset::<T>(); 125 Self::new_inner(
135 let mut dac = Self { 126 peri,
136 phantom: PhantomData, 127 new_dma!(dma),
137 dma, 128 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
138 }; 129 Mode::NormalExternalBuffered,
139 #[cfg(any(dac_v5, dac_v6, dac_v7))] 130 )
140 dac.set_hfsel();
141 dac.enable();
142 dac
143 } 131 }
144 132
145 /// Create a new `DacChannel` instance where the external output pin is not used, 133 /// Create a new `DacChannel` instance where the external output pin is not used,
@@ -150,13 +138,97 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
150 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the 138 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the
151 /// channel; you must re-enable it with `enable()`. 139 /// channel; you must re-enable it with `enable()`.
152 /// 140 ///
153 /// If you're not using DMA, pass [`dma::NoDma`] for the `dma` argument. 141 /// By default, triggering is disabled, but it can be enabled using
142 /// [`DacChannel::set_trigger()`].
143 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
144 pub fn new_internal(peri: Peri<'d, T>, dma: Peri<'d, impl Dma<T, C>>) -> Self {
145 Self::new_inner(peri, new_dma!(dma), Mode::NormalInternalUnbuffered)
146 }
147
148 /// Write `data` to this channel via DMA.
149 ///
150 /// To prevent delays or glitches when outputing a periodic waveform, the `circular`
151 /// flag can be set. This configures a circular DMA transfer that continually outputs
152 /// `data`. Note that for performance reasons in circular mode the transfer-complete
153 /// interrupt is disabled.
154 #[cfg(not(gpdma))]
155 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) {
156 // Enable DAC and DMA
157 T::regs().cr().modify(|w| {
158 w.set_en(C::IDX, true);
159 w.set_dmaen(C::IDX, true);
160 });
161
162 let dma = self.dma.as_mut().unwrap();
163
164 let tx_options = crate::dma::TransferOptions {
165 circular,
166 half_transfer_ir: false,
167 complete_transfer_ir: !circular,
168 ..Default::default()
169 };
170
171 // Initiate the correct type of DMA transfer depending on what data is passed
172 let tx_f = match data {
173 ValueArray::Bit8(buf) => unsafe { dma.write(buf, T::regs().dhr8r(C::IDX).as_ptr() as *mut u8, tx_options) },
174 ValueArray::Bit12Left(buf) => unsafe {
175 dma.write(buf, T::regs().dhr12l(C::IDX).as_ptr() as *mut u16, tx_options)
176 },
177 ValueArray::Bit12Right(buf) => unsafe {
178 dma.write(buf, T::regs().dhr12r(C::IDX).as_ptr() as *mut u16, tx_options)
179 },
180 };
181
182 tx_f.await;
183
184 T::regs().cr().modify(|w| {
185 w.set_en(C::IDX, false);
186 w.set_dmaen(C::IDX, false);
187 });
188 }
189}
190
191impl<'d, T: Instance, C: Channel> DacChannel<'d, T, C, Blocking> {
192 /// Create a new `DacChannel` instance, consuming the underlying DAC peripheral.
193 ///
194 /// The channel is enabled on creation and begin to drive the output pin.
195 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will
196 /// disable the channel; you must re-enable it with `enable()`.
197 ///
198 /// By default, triggering is disabled, but it can be enabled using
199 /// [`DacChannel::set_trigger()`].
200 pub fn new_blocking(peri: Peri<'d, T>, pin: Peri<'d, impl DacPin<T, C>>) -> Self {
201 pin.set_as_analog();
202 Self::new_inner(
203 peri,
204 None,
205 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
206 Mode::NormalExternalBuffered,
207 )
208 }
209
210 /// Create a new `DacChannel` instance where the external output pin is not used,
211 /// so the DAC can only be used to generate internal signals.
212 /// The GPIO pin is therefore available to be used for other functions.
213 ///
214 /// The channel is set to [`Mode::NormalInternalUnbuffered`] and enabled on creation.
215 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the
216 /// channel; you must re-enable it with `enable()`.
154 /// 217 ///
155 /// By default, triggering is disabled, but it can be enabled using 218 /// By default, triggering is disabled, but it can be enabled using
156 /// [`DacChannel::set_trigger()`]. 219 /// [`DacChannel::set_trigger()`].
157 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] 220 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
158 pub fn new_internal(_peri: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = DMA> + 'd) -> Self { 221 pub fn new_internal_blocking(peri: Peri<'d, T>) -> Self {
159 into_ref!(dma); 222 Self::new_inner(peri, None, Mode::NormalInternalUnbuffered)
223 }
224}
225
226impl<'d, T: Instance, C: Channel, M: PeriMode> DacChannel<'d, T, C, M> {
227 fn new_inner(
228 _peri: Peri<'d, T>,
229 dma: Option<ChannelAndRequest<'d>>,
230 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
231 ) -> Self {
160 rcc::enable_and_reset::<T>(); 232 rcc::enable_and_reset::<T>();
161 let mut dac = Self { 233 let mut dac = Self {
162 phantom: PhantomData, 234 phantom: PhantomData,
@@ -164,7 +236,8 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
164 }; 236 };
165 #[cfg(any(dac_v5, dac_v6, dac_v7))] 237 #[cfg(any(dac_v5, dac_v6, dac_v7))]
166 dac.set_hfsel(); 238 dac.set_hfsel();
167 dac.set_mode(Mode::NormalInternalUnbuffered); 239 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
240 dac.set_mode(mode);
168 dac.enable(); 241 dac.enable();
169 dac 242 dac
170 } 243 }
@@ -173,7 +246,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
173 pub fn set_enable(&mut self, on: bool) { 246 pub fn set_enable(&mut self, on: bool) {
174 critical_section::with(|_| { 247 critical_section::with(|_| {
175 T::regs().cr().modify(|reg| { 248 T::regs().cr().modify(|reg| {
176 reg.set_en(Self::IDX, on); 249 reg.set_en(C::IDX, on);
177 }); 250 });
178 }); 251 });
179 } 252 }
@@ -194,8 +267,8 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
194 pub fn set_trigger(&mut self, source: TriggerSel) { 267 pub fn set_trigger(&mut self, source: TriggerSel) {
195 critical_section::with(|_| { 268 critical_section::with(|_| {
196 T::regs().cr().modify(|reg| { 269 T::regs().cr().modify(|reg| {
197 reg.set_en(Self::IDX, false); 270 reg.set_en(C::IDX, false);
198 reg.set_tsel(Self::IDX, source as u8); 271 reg.set_tsel(C::IDX, source as u8);
199 }); 272 });
200 }); 273 });
201 } 274 }
@@ -204,7 +277,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
204 pub fn set_triggering(&mut self, on: bool) { 277 pub fn set_triggering(&mut self, on: bool) {
205 critical_section::with(|_| { 278 critical_section::with(|_| {
206 T::regs().cr().modify(|reg| { 279 T::regs().cr().modify(|reg| {
207 reg.set_ten(Self::IDX, on); 280 reg.set_ten(C::IDX, on);
208 }); 281 });
209 }); 282 });
210 } 283 }
@@ -212,7 +285,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
212 /// Software trigger this channel. 285 /// Software trigger this channel.
213 pub fn trigger(&mut self) { 286 pub fn trigger(&mut self) {
214 T::regs().swtrigr().write(|reg| { 287 T::regs().swtrigr().write(|reg| {
215 reg.set_swtrig(Self::IDX, true); 288 reg.set_swtrig(C::IDX, true);
216 }); 289 });
217 } 290 }
218 291
@@ -223,10 +296,10 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
223 pub fn set_mode(&mut self, mode: Mode) { 296 pub fn set_mode(&mut self, mode: Mode) {
224 critical_section::with(|_| { 297 critical_section::with(|_| {
225 T::regs().cr().modify(|reg| { 298 T::regs().cr().modify(|reg| {
226 reg.set_en(Self::IDX, false); 299 reg.set_en(C::IDX, false);
227 }); 300 });
228 T::regs().mcr().modify(|reg| { 301 T::regs().mcr().modify(|reg| {
229 reg.set_mode(Self::IDX, mode.mode()); 302 reg.set_mode(C::IDX, mode.mode());
230 }); 303 });
231 }); 304 });
232 } 305 }
@@ -237,15 +310,15 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
237 /// it will be output after the next trigger. 310 /// it will be output after the next trigger.
238 pub fn set(&mut self, value: Value) { 311 pub fn set(&mut self, value: Value) {
239 match value { 312 match value {
240 Value::Bit8(v) => T::regs().dhr8r(Self::IDX).write(|reg| reg.set_dhr(v)), 313 Value::Bit8(v) => T::regs().dhr8r(C::IDX).write(|reg| reg.set_dhr(v)),
241 Value::Bit12Left(v) => T::regs().dhr12l(Self::IDX).write(|reg| reg.set_dhr(v)), 314 Value::Bit12Left(v) => T::regs().dhr12l(C::IDX).write(|reg| reg.set_dhr(v)),
242 Value::Bit12Right(v) => T::regs().dhr12r(Self::IDX).write(|reg| reg.set_dhr(v)), 315 Value::Bit12Right(v) => T::regs().dhr12r(C::IDX).write(|reg| reg.set_dhr(v)),
243 } 316 }
244 } 317 }
245 318
246 /// Read the current output value of the DAC. 319 /// Read the current output value of the DAC.
247 pub fn read(&self) -> u16 { 320 pub fn read(&self) -> u16 {
248 T::regs().dor(Self::IDX).read().dor() 321 T::regs().dor(C::IDX).read().dor()
249 } 322 }
250 323
251 /// Set HFSEL as appropriate for the current peripheral clock frequency. 324 /// Set HFSEL as appropriate for the current peripheral clock frequency.
@@ -279,82 +352,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
279 } 352 }
280} 353}
281 354
282macro_rules! impl_dma_methods { 355impl<'d, T: Instance, C: Channel, M: PeriMode> Drop for DacChannel<'d, T, C, M> {
283 ($n:literal, $trait:ident) => {
284 impl<'d, T: Instance, DMA> DacChannel<'d, T, $n, DMA>
285 where
286 DMA: $trait<T>,
287 {
288 /// Write `data` to this channel via DMA.
289 ///
290 /// To prevent delays or glitches when outputing a periodic waveform, the `circular`
291 /// flag can be set. This configures a circular DMA transfer that continually outputs
292 /// `data`. Note that for performance reasons in circular mode the transfer-complete
293 /// interrupt is disabled.
294 #[cfg(not(gpdma))]
295 pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) {
296 // Enable DAC and DMA
297 T::regs().cr().modify(|w| {
298 w.set_en(Self::IDX, true);
299 w.set_dmaen(Self::IDX, true);
300 });
301
302 let tx_request = self.dma.request();
303 let dma_channel = &mut self.dma;
304
305 let tx_options = crate::dma::TransferOptions {
306 circular,
307 half_transfer_ir: false,
308 complete_transfer_ir: !circular,
309 ..Default::default()
310 };
311
312 // Initiate the correct type of DMA transfer depending on what data is passed
313 let tx_f = match data {
314 ValueArray::Bit8(buf) => unsafe {
315 crate::dma::Transfer::new_write(
316 dma_channel,
317 tx_request,
318 buf,
319 T::regs().dhr8r(Self::IDX).as_ptr() as *mut u8,
320 tx_options,
321 )
322 },
323 ValueArray::Bit12Left(buf) => unsafe {
324 crate::dma::Transfer::new_write(
325 dma_channel,
326 tx_request,
327 buf,
328 T::regs().dhr12l(Self::IDX).as_ptr() as *mut u16,
329 tx_options,
330 )
331 },
332 ValueArray::Bit12Right(buf) => unsafe {
333 crate::dma::Transfer::new_write(
334 dma_channel,
335 tx_request,
336 buf,
337 T::regs().dhr12r(Self::IDX).as_ptr() as *mut u16,
338 tx_options,
339 )
340 },
341 };
342
343 tx_f.await;
344
345 T::regs().cr().modify(|w| {
346 w.set_en(Self::IDX, false);
347 w.set_dmaen(Self::IDX, false);
348 });
349 }
350 }
351 };
352}
353
354impl_dma_methods!(1, DacDma1);
355impl_dma_methods!(2, DacDma2);
356
357impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> {
358 fn drop(&mut self) { 356 fn drop(&mut self) {
359 rcc::disable::<T>(); 357 rcc::disable::<T>();
360 } 358 }
@@ -368,14 +366,14 @@ impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> {
368/// 366///
369/// ```ignore 367/// ```ignore
370/// // Pins may need to be changed for your specific device. 368/// // Pins may need to be changed for your specific device.
371/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split(); 369/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new_blocking(p.DAC1, p.PA4, p.PA5).split();
372/// ``` 370/// ```
373pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { 371pub struct Dac<'d, T: Instance, M: PeriMode> {
374 ch1: DacChannel<'d, T, 1, DMACh1>, 372 ch1: DacChannel<'d, T, Ch1, M>,
375 ch2: DacChannel<'d, T, 2, DMACh2>, 373 ch2: DacChannel<'d, T, Ch2, M>,
376} 374}
377 375
378impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { 376impl<'d, T: Instance> Dac<'d, T, Async> {
379 /// Create a new `Dac` instance, consuming the underlying DAC peripheral. 377 /// Create a new `Dac` instance, consuming the underlying DAC peripheral.
380 /// 378 ///
381 /// This struct allows you to access both channels of the DAC, where available. You can either 379 /// This struct allows you to access both channels of the DAC, where available. You can either
@@ -389,37 +387,79 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
389 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` 387 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
390 /// method on the underlying channels. 388 /// method on the underlying channels.
391 pub fn new( 389 pub fn new(
392 _peri: impl Peripheral<P = T> + 'd, 390 peri: Peri<'d, T>,
393 dma_ch1: impl Peripheral<P = DMACh1> + 'd, 391 dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
394 dma_ch2: impl Peripheral<P = DMACh2> + 'd, 392 dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
395 pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::Pin> + 'd, 393 pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
396 pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::Pin> + 'd, 394 pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
397 ) -> Self { 395 ) -> Self {
398 into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
399 pin_ch1.set_as_analog(); 396 pin_ch1.set_as_analog();
400 pin_ch2.set_as_analog(); 397 pin_ch2.set_as_analog();
398 Self::new_inner(
399 peri,
400 new_dma!(dma_ch1),
401 new_dma!(dma_ch2),
402 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
403 Mode::NormalExternalBuffered,
404 )
405 }
401 406
402 // Enable twice to increment the DAC refcount for each channel. 407 /// Create a new `Dac` instance where the external output pins are not used,
403 rcc::enable_and_reset::<T>(); 408 /// so the DAC can only be used to generate internal signals but the GPIO
404 rcc::enable_and_reset::<T>(); 409 /// pins remain available for other functions.
405 410 ///
406 let mut ch1 = DacCh1 { 411 /// This struct allows you to access both channels of the DAC, where available. You can either
407 phantom: PhantomData, 412 /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use the two
408 dma: dma_ch1, 413 /// channels together.
409 }; 414 ///
410 #[cfg(any(dac_v5, dac_v6, dac_v7))] 415 /// The channels are set to [`Mode::NormalInternalUnbuffered`] and enabled on creation.
411 ch1.set_hfsel(); 416 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will disable the
412 ch1.enable(); 417 /// channel; you must re-enable them with `enable()`.
413 418 ///
414 let mut ch2 = DacCh2 { 419 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
415 phantom: PhantomData, 420 /// method on the underlying channels.
416 dma: dma_ch2, 421 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
417 }; 422 pub fn new_internal(
418 #[cfg(any(dac_v5, dac_v6, dac_v7))] 423 peri: Peri<'d, T>,
419 ch2.set_hfsel(); 424 dma_ch1: Peri<'d, impl Dma<T, Ch1>>,
420 ch2.enable(); 425 dma_ch2: Peri<'d, impl Dma<T, Ch2>>,
426 ) -> Self {
427 Self::new_inner(
428 peri,
429 new_dma!(dma_ch1),
430 new_dma!(dma_ch2),
431 Mode::NormalInternalUnbuffered,
432 )
433 }
434}
421 435
422 Self { ch1, ch2 } 436impl<'d, T: Instance> Dac<'d, T, Blocking> {
437 /// Create a new `Dac` instance, consuming the underlying DAC peripheral.
438 ///
439 /// This struct allows you to access both channels of the DAC, where available. You can either
440 /// call `split()` to obtain separate `DacChannel`s, or use methods on `Dac` to use
441 /// the two channels together.
442 ///
443 /// The channels are enabled on creation and begin to drive their output pins.
444 /// Note that some methods, such as `set_trigger()` and `set_mode()`, will
445 /// disable the channel; you must re-enable them with `enable()`.
446 ///
447 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
448 /// method on the underlying channels.
449 pub fn new_blocking(
450 peri: Peri<'d, T>,
451 pin_ch1: Peri<'d, impl DacPin<T, Ch1> + crate::gpio::Pin>,
452 pin_ch2: Peri<'d, impl DacPin<T, Ch2> + crate::gpio::Pin>,
453 ) -> Self {
454 pin_ch1.set_as_analog();
455 pin_ch2.set_as_analog();
456 Self::new_inner(
457 peri,
458 None,
459 None,
460 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
461 Mode::NormalExternalBuffered,
462 )
423 } 463 }
424 464
425 /// Create a new `Dac` instance where the external output pins are not used, 465 /// Create a new `Dac` instance where the external output pins are not used,
@@ -437,12 +477,18 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
437 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()` 477 /// By default, triggering is disabled, but it can be enabled using the `set_trigger()`
438 /// method on the underlying channels. 478 /// method on the underlying channels.
439 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] 479 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
440 pub fn new_internal( 480 pub fn new_internal(peri: Peri<'d, T>) -> Self {
441 _peri: impl Peripheral<P = T> + 'd, 481 Self::new_inner(peri, None, None, Mode::NormalInternalUnbuffered)
442 dma_ch1: impl Peripheral<P = DMACh1> + 'd, 482 }
443 dma_ch2: impl Peripheral<P = DMACh2> + 'd, 483}
484
485impl<'d, T: Instance, M: PeriMode> Dac<'d, T, M> {
486 fn new_inner(
487 _peri: Peri<'d, T>,
488 dma_ch1: Option<ChannelAndRequest<'d>>,
489 dma_ch2: Option<ChannelAndRequest<'d>>,
490 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] mode: Mode,
444 ) -> Self { 491 ) -> Self {
445 into_ref!(dma_ch1, dma_ch2);
446 // Enable twice to increment the DAC refcount for each channel. 492 // Enable twice to increment the DAC refcount for each channel.
447 rcc::enable_and_reset::<T>(); 493 rcc::enable_and_reset::<T>();
448 rcc::enable_and_reset::<T>(); 494 rcc::enable_and_reset::<T>();
@@ -453,7 +499,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
453 }; 499 };
454 #[cfg(any(dac_v5, dac_v6, dac_v7))] 500 #[cfg(any(dac_v5, dac_v6, dac_v7))]
455 ch1.set_hfsel(); 501 ch1.set_hfsel();
456 ch1.set_mode(Mode::NormalInternalUnbuffered); 502 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
503 ch1.set_mode(mode);
457 ch1.enable(); 504 ch1.enable();
458 505
459 let mut ch2 = DacCh2 { 506 let mut ch2 = DacCh2 {
@@ -462,7 +509,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
462 }; 509 };
463 #[cfg(any(dac_v5, dac_v6, dac_v7))] 510 #[cfg(any(dac_v5, dac_v6, dac_v7))]
464 ch2.set_hfsel(); 511 ch2.set_hfsel();
465 ch2.set_mode(Mode::NormalInternalUnbuffered); 512 #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
513 ch2.set_mode(mode);
466 ch2.enable(); 514 ch2.enable();
467 515
468 Self { ch1, ch2 } 516 Self { ch1, ch2 }
@@ -471,17 +519,17 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
471 /// Split this `Dac` into separate channels. 519 /// Split this `Dac` into separate channels.
472 /// 520 ///
473 /// You can access and move the channels around separately after splitting. 521 /// You can access and move the channels around separately after splitting.
474 pub fn split(self) -> (DacCh1<'d, T, DMACh1>, DacCh2<'d, T, DMACh2>) { 522 pub fn split(self) -> (DacCh1<'d, T, M>, DacCh2<'d, T, M>) {
475 (self.ch1, self.ch2) 523 (self.ch1, self.ch2)
476 } 524 }
477 525
478 /// Temporarily access channel 1. 526 /// Temporarily access channel 1.
479 pub fn ch1(&mut self) -> &mut DacCh1<'d, T, DMACh1> { 527 pub fn ch1(&mut self) -> &mut DacCh1<'d, T, M> {
480 &mut self.ch1 528 &mut self.ch1
481 } 529 }
482 530
483 /// Temporarily access channel 2. 531 /// Temporarily access channel 2.
484 pub fn ch2(&mut self) -> &mut DacCh2<'d, T, DMACh2> { 532 pub fn ch2(&mut self) -> &mut DacCh2<'d, T, M> {
485 &mut self.ch2 533 &mut self.ch2
486 } 534 }
487 535
@@ -513,12 +561,31 @@ trait SealedInstance {
513 561
514/// DAC instance. 562/// DAC instance.
515#[allow(private_bounds)] 563#[allow(private_bounds)]
516pub trait Instance: SealedInstance + RccPeripheral + 'static {} 564pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
517dma_trait!(DacDma1, Instance); 565
518dma_trait!(DacDma2, Instance); 566/// Channel 1 marker type.
567pub enum Ch1 {}
568/// Channel 2 marker type.
569pub enum Ch2 {}
570
571trait SealedChannel {
572 const IDX: usize;
573}
574/// DAC channel trait.
575#[allow(private_bounds)]
576pub trait Channel: SealedChannel {}
577
578impl SealedChannel for Ch1 {
579 const IDX: usize = 0;
580}
581impl SealedChannel for Ch2 {
582 const IDX: usize = 1;
583}
584impl Channel for Ch1 {}
585impl Channel for Ch2 {}
519 586
520/// Marks a pin that can be used with the DAC 587dma_trait!(Dma, Instance, Channel);
521pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} 588pin_trait!(DacPin, Instance, Channel);
522 589
523foreach_peripheral!( 590foreach_peripheral!(
524 (dac, $inst:ident) => { 591 (dac, $inst:ident) => {
@@ -531,9 +598,3 @@ foreach_peripheral!(
531 impl crate::dac::Instance for peripherals::$inst {} 598 impl crate::dac::Instance for peripherals::$inst {}
532 }; 599 };
533); 600);
534
535macro_rules! impl_dac_pin {
536 ($inst:ident, $pin:ident, $ch:expr) => {
537 impl crate::dac::DacPin<peripherals::$inst, $ch> for crate::peripherals::$pin {}
538 };
539}
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index 4ba4e824e..d05faee21 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -3,13 +3,13 @@ use core::future::poll_fn;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::PeripheralType;
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::dma::Transfer; 9use crate::dma::Transfer;
10use crate::gpio::{AfType, Pull}; 10use crate::gpio::{AfType, Pull};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, rcc, Peripheral}; 12use crate::{interrupt, rcc, Peri};
13 13
14/// Interrupt handler. 14/// Interrupt handler.
15pub struct InterruptHandler<T: Instance> { 15pub struct InterruptHandler<T: Instance> {
@@ -106,8 +106,7 @@ impl Default for Config {
106 106
107macro_rules! config_pins { 107macro_rules! config_pins {
108 ($($pin:ident),*) => { 108 ($($pin:ident),*) => {
109 into_ref!($($pin),*); 109 critical_section::with(|_| {
110 critical_section::with(|_| {
111 $( 110 $(
112 $pin.set_as_af($pin.af_num(), AfType::input(Pull::None)); 111 $pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
113 )* 112 )*
@@ -117,8 +116,8 @@ macro_rules! config_pins {
117 116
118/// DCMI driver. 117/// DCMI driver.
119pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> { 118pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
120 inner: PeripheralRef<'d, T>, 119 inner: Peri<'d, T>,
121 dma: PeripheralRef<'d, Dma>, 120 dma: Peri<'d, Dma>,
122} 121}
123 122
124impl<'d, T, Dma> Dcmi<'d, T, Dma> 123impl<'d, T, Dma> Dcmi<'d, T, Dma>
@@ -128,23 +127,22 @@ where
128{ 127{
129 /// Create a new DCMI driver with 8 data bits. 128 /// Create a new DCMI driver with 8 data bits.
130 pub fn new_8bit( 129 pub fn new_8bit(
131 peri: impl Peripheral<P = T> + 'd, 130 peri: Peri<'d, T>,
132 dma: impl Peripheral<P = Dma> + 'd, 131 dma: Peri<'d, Dma>,
133 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 132 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
134 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 133 d0: Peri<'d, impl D0Pin<T>>,
135 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 134 d1: Peri<'d, impl D1Pin<T>>,
136 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 135 d2: Peri<'d, impl D2Pin<T>>,
137 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 136 d3: Peri<'d, impl D3Pin<T>>,
138 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 137 d4: Peri<'d, impl D4Pin<T>>,
139 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 138 d5: Peri<'d, impl D5Pin<T>>,
140 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 139 d6: Peri<'d, impl D6Pin<T>>,
141 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 140 d7: Peri<'d, impl D7Pin<T>>,
142 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, 141 v_sync: Peri<'d, impl VSyncPin<T>>,
143 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, 142 h_sync: Peri<'d, impl HSyncPin<T>>,
144 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 143 pixclk: Peri<'d, impl PixClkPin<T>>,
145 config: Config, 144 config: Config,
146 ) -> Self { 145 ) -> Self {
147 into_ref!(peri, dma);
148 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); 146 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
149 config_pins!(v_sync, h_sync, pixclk); 147 config_pins!(v_sync, h_sync, pixclk);
150 148
@@ -153,25 +151,24 @@ where
153 151
154 /// Create a new DCMI driver with 10 data bits. 152 /// Create a new DCMI driver with 10 data bits.
155 pub fn new_10bit( 153 pub fn new_10bit(
156 peri: impl Peripheral<P = T> + 'd, 154 peri: Peri<'d, T>,
157 dma: impl Peripheral<P = Dma> + 'd, 155 dma: Peri<'d, Dma>,
158 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 156 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
159 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 157 d0: Peri<'d, impl D0Pin<T>>,
160 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 158 d1: Peri<'d, impl D1Pin<T>>,
161 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 159 d2: Peri<'d, impl D2Pin<T>>,
162 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 160 d3: Peri<'d, impl D3Pin<T>>,
163 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 161 d4: Peri<'d, impl D4Pin<T>>,
164 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 162 d5: Peri<'d, impl D5Pin<T>>,
165 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 163 d6: Peri<'d, impl D6Pin<T>>,
166 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 164 d7: Peri<'d, impl D7Pin<T>>,
167 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 165 d8: Peri<'d, impl D8Pin<T>>,
168 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 166 d9: Peri<'d, impl D9Pin<T>>,
169 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, 167 v_sync: Peri<'d, impl VSyncPin<T>>,
170 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, 168 h_sync: Peri<'d, impl HSyncPin<T>>,
171 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 169 pixclk: Peri<'d, impl PixClkPin<T>>,
172 config: Config, 170 config: Config,
173 ) -> Self { 171 ) -> Self {
174 into_ref!(peri, dma);
175 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 172 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
176 config_pins!(v_sync, h_sync, pixclk); 173 config_pins!(v_sync, h_sync, pixclk);
177 174
@@ -180,27 +177,26 @@ where
180 177
181 /// Create a new DCMI driver with 12 data bits. 178 /// Create a new DCMI driver with 12 data bits.
182 pub fn new_12bit( 179 pub fn new_12bit(
183 peri: impl Peripheral<P = T> + 'd, 180 peri: Peri<'d, T>,
184 dma: impl Peripheral<P = Dma> + 'd, 181 dma: Peri<'d, Dma>,
185 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 182 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
186 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 183 d0: Peri<'d, impl D0Pin<T>>,
187 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 184 d1: Peri<'d, impl D1Pin<T>>,
188 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 185 d2: Peri<'d, impl D2Pin<T>>,
189 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 186 d3: Peri<'d, impl D3Pin<T>>,
190 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 187 d4: Peri<'d, impl D4Pin<T>>,
191 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 188 d5: Peri<'d, impl D5Pin<T>>,
192 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 189 d6: Peri<'d, impl D6Pin<T>>,
193 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 190 d7: Peri<'d, impl D7Pin<T>>,
194 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 191 d8: Peri<'d, impl D8Pin<T>>,
195 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 192 d9: Peri<'d, impl D9Pin<T>>,
196 d10: impl Peripheral<P = impl D10Pin<T>> + 'd, 193 d10: Peri<'d, impl D10Pin<T>>,
197 d11: impl Peripheral<P = impl D11Pin<T>> + 'd, 194 d11: Peri<'d, impl D11Pin<T>>,
198 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, 195 v_sync: Peri<'d, impl VSyncPin<T>>,
199 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, 196 h_sync: Peri<'d, impl HSyncPin<T>>,
200 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 197 pixclk: Peri<'d, impl PixClkPin<T>>,
201 config: Config, 198 config: Config,
202 ) -> Self { 199 ) -> Self {
203 into_ref!(peri, dma);
204 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 200 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
205 config_pins!(v_sync, h_sync, pixclk); 201 config_pins!(v_sync, h_sync, pixclk);
206 202
@@ -209,29 +205,28 @@ where
209 205
210 /// Create a new DCMI driver with 14 data bits. 206 /// Create a new DCMI driver with 14 data bits.
211 pub fn new_14bit( 207 pub fn new_14bit(
212 peri: impl Peripheral<P = T> + 'd, 208 peri: Peri<'d, T>,
213 dma: impl Peripheral<P = Dma> + 'd, 209 dma: Peri<'d, Dma>,
214 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 210 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
215 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 211 d0: Peri<'d, impl D0Pin<T>>,
216 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 212 d1: Peri<'d, impl D1Pin<T>>,
217 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 213 d2: Peri<'d, impl D2Pin<T>>,
218 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 214 d3: Peri<'d, impl D3Pin<T>>,
219 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 215 d4: Peri<'d, impl D4Pin<T>>,
220 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 216 d5: Peri<'d, impl D5Pin<T>>,
221 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 217 d6: Peri<'d, impl D6Pin<T>>,
222 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 218 d7: Peri<'d, impl D7Pin<T>>,
223 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 219 d8: Peri<'d, impl D8Pin<T>>,
224 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 220 d9: Peri<'d, impl D9Pin<T>>,
225 d10: impl Peripheral<P = impl D10Pin<T>> + 'd, 221 d10: Peri<'d, impl D10Pin<T>>,
226 d11: impl Peripheral<P = impl D11Pin<T>> + 'd, 222 d11: Peri<'d, impl D11Pin<T>>,
227 d12: impl Peripheral<P = impl D12Pin<T>> + 'd, 223 d12: Peri<'d, impl D12Pin<T>>,
228 d13: impl Peripheral<P = impl D13Pin<T>> + 'd, 224 d13: Peri<'d, impl D13Pin<T>>,
229 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd, 225 v_sync: Peri<'d, impl VSyncPin<T>>,
230 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd, 226 h_sync: Peri<'d, impl HSyncPin<T>>,
231 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 227 pixclk: Peri<'d, impl PixClkPin<T>>,
232 config: Config, 228 config: Config,
233 ) -> Self { 229 ) -> Self {
234 into_ref!(peri, dma);
235 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 230 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
236 config_pins!(v_sync, h_sync, pixclk); 231 config_pins!(v_sync, h_sync, pixclk);
237 232
@@ -240,21 +235,20 @@ where
240 235
241 /// Create a new DCMI driver with 8 data bits, with embedded synchronization. 236 /// Create a new DCMI driver with 8 data bits, with embedded synchronization.
242 pub fn new_es_8bit( 237 pub fn new_es_8bit(
243 peri: impl Peripheral<P = T> + 'd, 238 peri: Peri<'d, T>,
244 dma: impl Peripheral<P = Dma> + 'd, 239 dma: Peri<'d, Dma>,
245 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 240 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
246 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 241 d0: Peri<'d, impl D0Pin<T>>,
247 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 242 d1: Peri<'d, impl D1Pin<T>>,
248 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 243 d2: Peri<'d, impl D2Pin<T>>,
249 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 244 d3: Peri<'d, impl D3Pin<T>>,
250 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 245 d4: Peri<'d, impl D4Pin<T>>,
251 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 246 d5: Peri<'d, impl D5Pin<T>>,
252 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 247 d6: Peri<'d, impl D6Pin<T>>,
253 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 248 d7: Peri<'d, impl D7Pin<T>>,
254 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 249 pixclk: Peri<'d, impl PixClkPin<T>>,
255 config: Config, 250 config: Config,
256 ) -> Self { 251 ) -> Self {
257 into_ref!(peri, dma);
258 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); 252 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
259 config_pins!(pixclk); 253 config_pins!(pixclk);
260 254
@@ -263,23 +257,22 @@ where
263 257
264 /// Create a new DCMI driver with 10 data bits, with embedded synchronization. 258 /// Create a new DCMI driver with 10 data bits, with embedded synchronization.
265 pub fn new_es_10bit( 259 pub fn new_es_10bit(
266 peri: impl Peripheral<P = T> + 'd, 260 peri: Peri<'d, T>,
267 dma: impl Peripheral<P = Dma> + 'd, 261 dma: Peri<'d, Dma>,
268 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 262 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
269 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 263 d0: Peri<'d, impl D0Pin<T>>,
270 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 264 d1: Peri<'d, impl D1Pin<T>>,
271 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 265 d2: Peri<'d, impl D2Pin<T>>,
272 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 266 d3: Peri<'d, impl D3Pin<T>>,
273 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 267 d4: Peri<'d, impl D4Pin<T>>,
274 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 268 d5: Peri<'d, impl D5Pin<T>>,
275 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 269 d6: Peri<'d, impl D6Pin<T>>,
276 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 270 d7: Peri<'d, impl D7Pin<T>>,
277 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 271 d8: Peri<'d, impl D8Pin<T>>,
278 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 272 d9: Peri<'d, impl D9Pin<T>>,
279 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 273 pixclk: Peri<'d, impl PixClkPin<T>>,
280 config: Config, 274 config: Config,
281 ) -> Self { 275 ) -> Self {
282 into_ref!(peri, dma);
283 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 276 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
284 config_pins!(pixclk); 277 config_pins!(pixclk);
285 278
@@ -288,25 +281,24 @@ where
288 281
289 /// Create a new DCMI driver with 12 data bits, with embedded synchronization. 282 /// Create a new DCMI driver with 12 data bits, with embedded synchronization.
290 pub fn new_es_12bit( 283 pub fn new_es_12bit(
291 peri: impl Peripheral<P = T> + 'd, 284 peri: Peri<'d, T>,
292 dma: impl Peripheral<P = Dma> + 'd, 285 dma: Peri<'d, Dma>,
293 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 286 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
294 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 287 d0: Peri<'d, impl D0Pin<T>>,
295 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 288 d1: Peri<'d, impl D1Pin<T>>,
296 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 289 d2: Peri<'d, impl D2Pin<T>>,
297 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 290 d3: Peri<'d, impl D3Pin<T>>,
298 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 291 d4: Peri<'d, impl D4Pin<T>>,
299 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 292 d5: Peri<'d, impl D5Pin<T>>,
300 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 293 d6: Peri<'d, impl D6Pin<T>>,
301 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 294 d7: Peri<'d, impl D7Pin<T>>,
302 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 295 d8: Peri<'d, impl D8Pin<T>>,
303 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 296 d9: Peri<'d, impl D9Pin<T>>,
304 d10: impl Peripheral<P = impl D10Pin<T>> + 'd, 297 d10: Peri<'d, impl D10Pin<T>>,
305 d11: impl Peripheral<P = impl D11Pin<T>> + 'd, 298 d11: Peri<'d, impl D11Pin<T>>,
306 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 299 pixclk: Peri<'d, impl PixClkPin<T>>,
307 config: Config, 300 config: Config,
308 ) -> Self { 301 ) -> Self {
309 into_ref!(peri, dma);
310 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 302 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
311 config_pins!(pixclk); 303 config_pins!(pixclk);
312 304
@@ -315,27 +307,26 @@ where
315 307
316 /// Create a new DCMI driver with 14 data bits, with embedded synchronization. 308 /// Create a new DCMI driver with 14 data bits, with embedded synchronization.
317 pub fn new_es_14bit( 309 pub fn new_es_14bit(
318 peri: impl Peripheral<P = T> + 'd, 310 peri: Peri<'d, T>,
319 dma: impl Peripheral<P = Dma> + 'd, 311 dma: Peri<'d, Dma>,
320 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 312 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
321 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 313 d0: Peri<'d, impl D0Pin<T>>,
322 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 314 d1: Peri<'d, impl D1Pin<T>>,
323 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 315 d2: Peri<'d, impl D2Pin<T>>,
324 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 316 d3: Peri<'d, impl D3Pin<T>>,
325 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 317 d4: Peri<'d, impl D4Pin<T>>,
326 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 318 d5: Peri<'d, impl D5Pin<T>>,
327 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 319 d6: Peri<'d, impl D6Pin<T>>,
328 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 320 d7: Peri<'d, impl D7Pin<T>>,
329 d8: impl Peripheral<P = impl D8Pin<T>> + 'd, 321 d8: Peri<'d, impl D8Pin<T>>,
330 d9: impl Peripheral<P = impl D9Pin<T>> + 'd, 322 d9: Peri<'d, impl D9Pin<T>>,
331 d10: impl Peripheral<P = impl D10Pin<T>> + 'd, 323 d10: Peri<'d, impl D10Pin<T>>,
332 d11: impl Peripheral<P = impl D11Pin<T>> + 'd, 324 d11: Peri<'d, impl D11Pin<T>>,
333 d12: impl Peripheral<P = impl D12Pin<T>> + 'd, 325 d12: Peri<'d, impl D12Pin<T>>,
334 d13: impl Peripheral<P = impl D13Pin<T>> + 'd, 326 d13: Peri<'d, impl D13Pin<T>>,
335 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd, 327 pixclk: Peri<'d, impl PixClkPin<T>>,
336 config: Config, 328 config: Config,
337 ) -> Self { 329 ) -> Self {
338 into_ref!(peri, dma);
339 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 330 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
340 config_pins!(pixclk); 331 config_pins!(pixclk);
341 332
@@ -343,8 +334,8 @@ where
343 } 334 }
344 335
345 fn new_inner( 336 fn new_inner(
346 peri: PeripheralRef<'d, T>, 337 peri: Peri<'d, T>,
347 dma: PeripheralRef<'d, Dma>, 338 dma: Peri<'d, Dma>,
348 config: Config, 339 config: Config,
349 use_embedded_synchronization: bool, 340 use_embedded_synchronization: bool,
350 edm: u8, 341 edm: u8,
@@ -396,7 +387,7 @@ where
396 let r = self.inner.regs(); 387 let r = self.inner.regs();
397 let src = r.dr().as_ptr() as *mut u32; 388 let src = r.dr().as_ptr() as *mut u32;
398 let request = self.dma.request(); 389 let request = self.dma.request();
399 let dma_read = unsafe { Transfer::new_read(&mut self.dma, request, src, buffer, Default::default()) }; 390 let dma_read = unsafe { Transfer::new_read(self.dma.reborrow(), request, src, buffer, Default::default()) };
400 391
401 Self::clear_interrupt_flags(); 392 Self::clear_interrupt_flags();
402 Self::enable_irqs(); 393 Self::enable_irqs();
@@ -435,7 +426,7 @@ trait SealedInstance: crate::rcc::RccPeripheral {
435 426
436/// DCMI instance. 427/// DCMI instance.
437#[allow(private_bounds)] 428#[allow(private_bounds)]
438pub trait Instance: SealedInstance + 'static { 429pub trait Instance: SealedInstance + PeripheralType + 'static {
439 /// Interrupt for this instance. 430 /// Interrupt for this instance.
440 type Interrupt: interrupt::typelevel::Interrupt; 431 type Interrupt: interrupt::typelevel::Interrupt;
441} 432}
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs
index d31f4d01a..7dbbe7b72 100644
--- a/embassy-stm32/src/dma/dma_bdma.rs
+++ b/embassy-stm32/src/dma/dma_bdma.rs
@@ -3,7 +3,7 @@ use core::pin::Pin;
3use core::sync::atomic::{fence, AtomicUsize, Ordering}; 3use core::sync::atomic::{fence, AtomicUsize, Ordering};
4use core::task::{Context, Poll, Waker}; 4use core::task::{Context, Poll, Waker};
5 5
6use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 6use embassy_hal_internal::Peri;
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; 9use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer};
@@ -571,13 +571,13 @@ impl AnyChannel {
571/// DMA transfer. 571/// DMA transfer.
572#[must_use = "futures do nothing unless you `.await` or poll them"] 572#[must_use = "futures do nothing unless you `.await` or poll them"]
573pub struct Transfer<'a> { 573pub struct Transfer<'a> {
574 channel: PeripheralRef<'a, AnyChannel>, 574 channel: Peri<'a, AnyChannel>,
575} 575}
576 576
577impl<'a> Transfer<'a> { 577impl<'a> Transfer<'a> {
578 /// Create a new read DMA transfer (peripheral to memory). 578 /// Create a new read DMA transfer (peripheral to memory).
579 pub unsafe fn new_read<W: Word>( 579 pub unsafe fn new_read<W: Word>(
580 channel: impl Peripheral<P = impl Channel> + 'a, 580 channel: Peri<'a, impl Channel>,
581 request: Request, 581 request: Request,
582 peri_addr: *mut W, 582 peri_addr: *mut W,
583 buf: &'a mut [W], 583 buf: &'a mut [W],
@@ -588,16 +588,14 @@ impl<'a> Transfer<'a> {
588 588
589 /// Create a new read DMA transfer (peripheral to memory), using raw pointers. 589 /// Create a new read DMA transfer (peripheral to memory), using raw pointers.
590 pub unsafe fn new_read_raw<W: Word>( 590 pub unsafe fn new_read_raw<W: Word>(
591 channel: impl Peripheral<P = impl Channel> + 'a, 591 channel: Peri<'a, impl Channel>,
592 request: Request, 592 request: Request,
593 peri_addr: *mut W, 593 peri_addr: *mut W,
594 buf: *mut [W], 594 buf: *mut [W],
595 options: TransferOptions, 595 options: TransferOptions,
596 ) -> Self { 596 ) -> Self {
597 into_ref!(channel);
598
599 Self::new_inner( 597 Self::new_inner(
600 channel.map_into(), 598 channel.into(),
601 request, 599 request,
602 Dir::PeripheralToMemory, 600 Dir::PeripheralToMemory,
603 peri_addr as *const u32, 601 peri_addr as *const u32,
@@ -612,7 +610,7 @@ impl<'a> Transfer<'a> {
612 610
613 /// Create a new write DMA transfer (memory to peripheral). 611 /// Create a new write DMA transfer (memory to peripheral).
614 pub unsafe fn new_write<MW: Word, PW: Word>( 612 pub unsafe fn new_write<MW: Word, PW: Word>(
615 channel: impl Peripheral<P = impl Channel> + 'a, 613 channel: Peri<'a, impl Channel>,
616 request: Request, 614 request: Request,
617 buf: &'a [MW], 615 buf: &'a [MW],
618 peri_addr: *mut PW, 616 peri_addr: *mut PW,
@@ -623,16 +621,14 @@ impl<'a> Transfer<'a> {
623 621
624 /// Create a new write DMA transfer (memory to peripheral), using raw pointers. 622 /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
625 pub unsafe fn new_write_raw<MW: Word, PW: Word>( 623 pub unsafe fn new_write_raw<MW: Word, PW: Word>(
626 channel: impl Peripheral<P = impl Channel> + 'a, 624 channel: Peri<'a, impl Channel>,
627 request: Request, 625 request: Request,
628 buf: *const [MW], 626 buf: *const [MW],
629 peri_addr: *mut PW, 627 peri_addr: *mut PW,
630 options: TransferOptions, 628 options: TransferOptions,
631 ) -> Self { 629 ) -> Self {
632 into_ref!(channel);
633
634 Self::new_inner( 630 Self::new_inner(
635 channel.map_into(), 631 channel.into(),
636 request, 632 request,
637 Dir::MemoryToPeripheral, 633 Dir::MemoryToPeripheral,
638 peri_addr as *const u32, 634 peri_addr as *const u32,
@@ -647,17 +643,15 @@ impl<'a> Transfer<'a> {
647 643
648 /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. 644 /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
649 pub unsafe fn new_write_repeated<W: Word>( 645 pub unsafe fn new_write_repeated<W: Word>(
650 channel: impl Peripheral<P = impl Channel> + 'a, 646 channel: Peri<'a, impl Channel>,
651 request: Request, 647 request: Request,
652 repeated: &'a W, 648 repeated: &'a W,
653 count: usize, 649 count: usize,
654 peri_addr: *mut W, 650 peri_addr: *mut W,
655 options: TransferOptions, 651 options: TransferOptions,
656 ) -> Self { 652 ) -> Self {
657 into_ref!(channel);
658
659 Self::new_inner( 653 Self::new_inner(
660 channel.map_into(), 654 channel.into(),
661 request, 655 request,
662 Dir::MemoryToPeripheral, 656 Dir::MemoryToPeripheral,
663 peri_addr as *const u32, 657 peri_addr as *const u32,
@@ -671,7 +665,7 @@ impl<'a> Transfer<'a> {
671 } 665 }
672 666
673 unsafe fn new_inner( 667 unsafe fn new_inner(
674 channel: PeripheralRef<'a, AnyChannel>, 668 channel: Peri<'a, AnyChannel>,
675 _request: Request, 669 _request: Request,
676 dir: Dir, 670 dir: Dir,
677 peri_addr: *const u32, 671 peri_addr: *const u32,
@@ -769,7 +763,7 @@ impl<'a> Future for Transfer<'a> {
769 763
770// ============================== 764// ==============================
771 765
772struct DmaCtrlImpl<'a>(PeripheralRef<'a, AnyChannel>); 766struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>);
773 767
774impl<'a> DmaCtrl for DmaCtrlImpl<'a> { 768impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
775 fn get_remaining_transfers(&self) -> usize { 769 fn get_remaining_transfers(&self) -> usize {
@@ -795,21 +789,20 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
795 789
796/// Ringbuffer for receiving data using DMA circular mode. 790/// Ringbuffer for receiving data using DMA circular mode.
797pub struct ReadableRingBuffer<'a, W: Word> { 791pub struct ReadableRingBuffer<'a, W: Word> {
798 channel: PeripheralRef<'a, AnyChannel>, 792 channel: Peri<'a, AnyChannel>,
799 ringbuf: ReadableDmaRingBuffer<'a, W>, 793 ringbuf: ReadableDmaRingBuffer<'a, W>,
800} 794}
801 795
802impl<'a, W: Word> ReadableRingBuffer<'a, W> { 796impl<'a, W: Word> ReadableRingBuffer<'a, W> {
803 /// Create a new ring buffer. 797 /// Create a new ring buffer.
804 pub unsafe fn new( 798 pub unsafe fn new(
805 channel: impl Peripheral<P = impl Channel> + 'a, 799 channel: Peri<'a, impl Channel>,
806 _request: Request, 800 _request: Request,
807 peri_addr: *mut W, 801 peri_addr: *mut W,
808 buffer: &'a mut [W], 802 buffer: &'a mut [W],
809 mut options: TransferOptions, 803 mut options: TransferOptions,
810 ) -> Self { 804 ) -> Self {
811 into_ref!(channel); 805 let channel: Peri<'a, AnyChannel> = channel.into();
812 let channel: PeripheralRef<'a, AnyChannel> = channel.map_into();
813 806
814 let buffer_ptr = buffer.as_mut_ptr(); 807 let buffer_ptr = buffer.as_mut_ptr();
815 let len = buffer.len(); 808 let len = buffer.len();
@@ -948,21 +941,20 @@ impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
948 941
949/// Ringbuffer for writing data using DMA circular mode. 942/// Ringbuffer for writing data using DMA circular mode.
950pub struct WritableRingBuffer<'a, W: Word> { 943pub struct WritableRingBuffer<'a, W: Word> {
951 channel: PeripheralRef<'a, AnyChannel>, 944 channel: Peri<'a, AnyChannel>,
952 ringbuf: WritableDmaRingBuffer<'a, W>, 945 ringbuf: WritableDmaRingBuffer<'a, W>,
953} 946}
954 947
955impl<'a, W: Word> WritableRingBuffer<'a, W> { 948impl<'a, W: Word> WritableRingBuffer<'a, W> {
956 /// Create a new ring buffer. 949 /// Create a new ring buffer.
957 pub unsafe fn new( 950 pub unsafe fn new(
958 channel: impl Peripheral<P = impl Channel> + 'a, 951 channel: Peri<'a, impl Channel>,
959 _request: Request, 952 _request: Request,
960 peri_addr: *mut W, 953 peri_addr: *mut W,
961 buffer: &'a mut [W], 954 buffer: &'a mut [W],
962 mut options: TransferOptions, 955 mut options: TransferOptions,
963 ) -> Self { 956 ) -> Self {
964 into_ref!(channel); 957 let channel: Peri<'a, AnyChannel> = channel.into();
965 let channel: PeripheralRef<'a, AnyChannel> = channel.map_into();
966 958
967 let len = buffer.len(); 959 let len = buffer.len();
968 let dir = Dir::MemoryToPeripheral; 960 let dir = Dir::MemoryToPeripheral;
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index 799b8b355..ade70fb55 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -5,7 +5,7 @@ use core::pin::Pin;
5use core::sync::atomic::{fence, Ordering}; 5use core::sync::atomic::{fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 8use embassy_hal_internal::Peri;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use super::word::{Word, WordSize}; 11use super::word::{Word, WordSize};
@@ -109,13 +109,13 @@ impl AnyChannel {
109/// DMA transfer. 109/// DMA transfer.
110#[must_use = "futures do nothing unless you `.await` or poll them"] 110#[must_use = "futures do nothing unless you `.await` or poll them"]
111pub struct Transfer<'a> { 111pub struct Transfer<'a> {
112 channel: PeripheralRef<'a, AnyChannel>, 112 channel: Peri<'a, AnyChannel>,
113} 113}
114 114
115impl<'a> Transfer<'a> { 115impl<'a> Transfer<'a> {
116 /// Create a new read DMA transfer (peripheral to memory). 116 /// Create a new read DMA transfer (peripheral to memory).
117 pub unsafe fn new_read<W: Word>( 117 pub unsafe fn new_read<W: Word>(
118 channel: impl Peripheral<P = impl Channel> + 'a, 118 channel: Peri<'a, impl Channel>,
119 request: Request, 119 request: Request,
120 peri_addr: *mut W, 120 peri_addr: *mut W,
121 buf: &'a mut [W], 121 buf: &'a mut [W],
@@ -126,16 +126,14 @@ impl<'a> Transfer<'a> {
126 126
127 /// Create a new read DMA transfer (peripheral to memory), using raw pointers. 127 /// Create a new read DMA transfer (peripheral to memory), using raw pointers.
128 pub unsafe fn new_read_raw<W: Word>( 128 pub unsafe fn new_read_raw<W: Word>(
129 channel: impl Peripheral<P = impl Channel> + 'a, 129 channel: Peri<'a, impl Channel>,
130 request: Request, 130 request: Request,
131 peri_addr: *mut W, 131 peri_addr: *mut W,
132 buf: *mut [W], 132 buf: *mut [W],
133 options: TransferOptions, 133 options: TransferOptions,
134 ) -> Self { 134 ) -> Self {
135 into_ref!(channel);
136
137 Self::new_inner( 135 Self::new_inner(
138 channel.map_into(), 136 channel.into(),
139 request, 137 request,
140 Dir::PeripheralToMemory, 138 Dir::PeripheralToMemory,
141 peri_addr as *const u32, 139 peri_addr as *const u32,
@@ -150,7 +148,7 @@ impl<'a> Transfer<'a> {
150 148
151 /// Create a new write DMA transfer (memory to peripheral). 149 /// Create a new write DMA transfer (memory to peripheral).
152 pub unsafe fn new_write<MW: Word, PW: Word>( 150 pub unsafe fn new_write<MW: Word, PW: Word>(
153 channel: impl Peripheral<P = impl Channel> + 'a, 151 channel: Peri<'a, impl Channel>,
154 request: Request, 152 request: Request,
155 buf: &'a [MW], 153 buf: &'a [MW],
156 peri_addr: *mut PW, 154 peri_addr: *mut PW,
@@ -161,16 +159,14 @@ impl<'a> Transfer<'a> {
161 159
162 /// Create a new write DMA transfer (memory to peripheral), using raw pointers. 160 /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
163 pub unsafe fn new_write_raw<MW: Word, PW: Word>( 161 pub unsafe fn new_write_raw<MW: Word, PW: Word>(
164 channel: impl Peripheral<P = impl Channel> + 'a, 162 channel: Peri<'a, impl Channel>,
165 request: Request, 163 request: Request,
166 buf: *const [MW], 164 buf: *const [MW],
167 peri_addr: *mut PW, 165 peri_addr: *mut PW,
168 options: TransferOptions, 166 options: TransferOptions,
169 ) -> Self { 167 ) -> Self {
170 into_ref!(channel);
171
172 Self::new_inner( 168 Self::new_inner(
173 channel.map_into(), 169 channel.into(),
174 request, 170 request,
175 Dir::MemoryToPeripheral, 171 Dir::MemoryToPeripheral,
176 peri_addr as *const u32, 172 peri_addr as *const u32,
@@ -185,17 +181,15 @@ impl<'a> Transfer<'a> {
185 181
186 /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly. 182 /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
187 pub unsafe fn new_write_repeated<MW: Word, PW: Word>( 183 pub unsafe fn new_write_repeated<MW: Word, PW: Word>(
188 channel: impl Peripheral<P = impl Channel> + 'a, 184 channel: Peri<'a, impl Channel>,
189 request: Request, 185 request: Request,
190 repeated: &'a MW, 186 repeated: &'a MW,
191 count: usize, 187 count: usize,
192 peri_addr: *mut PW, 188 peri_addr: *mut PW,
193 options: TransferOptions, 189 options: TransferOptions,
194 ) -> Self { 190 ) -> Self {
195 into_ref!(channel);
196
197 Self::new_inner( 191 Self::new_inner(
198 channel.map_into(), 192 channel.into(),
199 request, 193 request,
200 Dir::MemoryToPeripheral, 194 Dir::MemoryToPeripheral,
201 peri_addr as *const u32, 195 peri_addr as *const u32,
@@ -209,7 +203,7 @@ impl<'a> Transfer<'a> {
209 } 203 }
210 204
211 unsafe fn new_inner( 205 unsafe fn new_inner(
212 channel: PeripheralRef<'a, AnyChannel>, 206 channel: Peri<'a, AnyChannel>,
213 request: Request, 207 request: Request,
214 dir: Dir, 208 dir: Dir,
215 peri_addr: *const u32, 209 peri_addr: *const u32,
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 66c4aa53c..d3b070a6d 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -22,7 +22,7 @@ pub(crate) use util::*;
22pub(crate) mod ringbuffer; 22pub(crate) mod ringbuffer;
23pub mod word; 23pub mod word;
24 24
25use embassy_hal_internal::{impl_peripheral, Peripheral}; 25use embassy_hal_internal::{impl_peripheral, PeripheralType};
26 26
27use crate::interrupt; 27use crate::interrupt;
28 28
@@ -51,17 +51,7 @@ pub(crate) trait ChannelInterrupt {
51 51
52/// DMA channel. 52/// DMA channel.
53#[allow(private_bounds)] 53#[allow(private_bounds)]
54pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static { 54pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {}
55 /// Type-erase (degrade) this pin into an `AnyChannel`.
56 ///
57 /// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
58 /// are all different types, into the same type. It is useful for
59 /// creating arrays of channels, or avoiding generics.
60 #[inline]
61 fn degrade(self) -> AnyChannel {
62 AnyChannel { id: self.id() }
63 }
64}
65 55
66macro_rules! dma_channel_impl { 56macro_rules! dma_channel_impl {
67 ($channel_peri:ident, $index:expr) => { 57 ($channel_peri:ident, $index:expr) => {
@@ -79,8 +69,10 @@ macro_rules! dma_channel_impl {
79 impl crate::dma::Channel for crate::peripherals::$channel_peri {} 69 impl crate::dma::Channel for crate::peripherals::$channel_peri {}
80 70
81 impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel { 71 impl From<crate::peripherals::$channel_peri> for crate::dma::AnyChannel {
82 fn from(x: crate::peripherals::$channel_peri) -> Self { 72 fn from(val: crate::peripherals::$channel_peri) -> Self {
83 crate::dma::Channel::degrade(x) 73 Self {
74 id: crate::dma::SealedChannel::id(&val),
75 }
84 } 76 }
85 } 77 }
86 }; 78 };
@@ -108,17 +100,6 @@ impl Channel for AnyChannel {}
108const CHANNEL_COUNT: usize = crate::_generated::DMA_CHANNELS.len(); 100const CHANNEL_COUNT: usize = crate::_generated::DMA_CHANNELS.len();
109static STATE: [ChannelState; CHANNEL_COUNT] = [ChannelState::NEW; CHANNEL_COUNT]; 101static STATE: [ChannelState; CHANNEL_COUNT] = [ChannelState::NEW; CHANNEL_COUNT];
110 102
111/// "No DMA" placeholder.
112///
113/// You may pass this in place of a real DMA channel when creating a driver
114/// to indicate it should not use DMA.
115///
116/// This often causes async functionality to not be available on the instance,
117/// leaving only blocking functionality.
118pub struct NoDma;
119
120impl_peripheral!(NoDma);
121
122// safety: must be called only once at startup 103// safety: must be called only once at startup
123pub(crate) unsafe fn init( 104pub(crate) unsafe fn init(
124 cs: critical_section::CriticalSection, 105 cs: critical_section::CriticalSection,
diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs
index 5aaca57c9..8bf89e2fe 100644
--- a/embassy-stm32/src/dma/util.rs
+++ b/embassy-stm32/src/dma/util.rs
@@ -1,13 +1,12 @@
1use embassy_hal_internal::PeripheralRef;
2
3use super::word::Word; 1use super::word::Word;
4use super::{AnyChannel, Request, Transfer, TransferOptions}; 2use super::{AnyChannel, Request, Transfer, TransferOptions};
3use crate::Peri;
5 4
6/// Convenience wrapper, contains a channel and a request number. 5/// Convenience wrapper, contains a channel and a request number.
7/// 6///
8/// Commonly used in peripheral drivers that own DMA channels. 7/// Commonly used in peripheral drivers that own DMA channels.
9pub(crate) struct ChannelAndRequest<'d> { 8pub(crate) struct ChannelAndRequest<'d> {
10 pub channel: PeripheralRef<'d, AnyChannel>, 9 pub channel: Peri<'d, AnyChannel>,
11 pub request: Request, 10 pub request: Request,
12} 11}
13 12
@@ -18,7 +17,7 @@ impl<'d> ChannelAndRequest<'d> {
18 buf: &'a mut [W], 17 buf: &'a mut [W],
19 options: TransferOptions, 18 options: TransferOptions,
20 ) -> Transfer<'a> { 19 ) -> Transfer<'a> {
21 Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options) 20 Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options)
22 } 21 }
23 22
24 pub unsafe fn read_raw<'a, W: Word>( 23 pub unsafe fn read_raw<'a, W: Word>(
@@ -27,7 +26,7 @@ impl<'d> ChannelAndRequest<'d> {
27 buf: *mut [W], 26 buf: *mut [W],
28 options: TransferOptions, 27 options: TransferOptions,
29 ) -> Transfer<'a> { 28 ) -> Transfer<'a> {
30 Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options) 29 Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options)
31 } 30 }
32 31
33 pub unsafe fn write<'a, W: Word>( 32 pub unsafe fn write<'a, W: Word>(
@@ -36,16 +35,16 @@ impl<'d> ChannelAndRequest<'d> {
36 peri_addr: *mut W, 35 peri_addr: *mut W,
37 options: TransferOptions, 36 options: TransferOptions,
38 ) -> Transfer<'a> { 37 ) -> Transfer<'a> {
39 Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options) 38 Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options)
40 } 39 }
41 40
42 pub unsafe fn write_raw<'a, W: Word>( 41 pub unsafe fn write_raw<'a, MW: Word, PW: Word>(
43 &'a mut self, 42 &'a mut self,
44 buf: *const [W], 43 buf: *const [MW],
45 peri_addr: *mut W, 44 peri_addr: *mut PW,
46 options: TransferOptions, 45 options: TransferOptions,
47 ) -> Transfer<'a> { 46 ) -> Transfer<'a> {
48 Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options) 47 Transfer::new_write_raw(self.channel.reborrow(), self.request, buf, peri_addr, options)
49 } 48 }
50 49
51 #[allow(dead_code)] 50 #[allow(dead_code)]
@@ -56,6 +55,13 @@ impl<'d> ChannelAndRequest<'d> {
56 peri_addr: *mut W, 55 peri_addr: *mut W,
57 options: TransferOptions, 56 options: TransferOptions,
58 ) -> Transfer<'a> { 57 ) -> Transfer<'a> {
59 Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options) 58 Transfer::new_write_repeated(
59 self.channel.reborrow(),
60 self.request,
61 repeated,
62 count,
63 peri_addr,
64 options,
65 )
60 } 66 }
61} 67}
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index 77c3d95c3..e97ccd9d0 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -2,12 +2,12 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_internal::{into_ref, PeripheralRef}; 5use embassy_hal_internal::PeripheralType;
6 6
7//use crate::gpio::{AnyPin, SealedPin}; 7//use crate::gpio::{AnyPin, SealedPin};
8use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 8use crate::gpio::{AfType, AnyPin, OutputType, Speed};
9use crate::rcc::{self, RccPeripheral}; 9use crate::rcc::{self, RccPeripheral};
10use crate::{peripherals, Peripheral}; 10use crate::{peripherals, Peri};
11 11
12/// Performs a busy-wait delay for a specified number of microseconds. 12/// Performs a busy-wait delay for a specified number of microseconds.
13pub fn blocking_delay_ms(ms: u32) { 13pub fn blocking_delay_ms(ms: u32) {
@@ -69,14 +69,12 @@ impl From<PacketType> for u8 {
69/// DSIHOST driver. 69/// DSIHOST driver.
70pub struct DsiHost<'d, T: Instance> { 70pub struct DsiHost<'d, T: Instance> {
71 _peri: PhantomData<&'d mut T>, 71 _peri: PhantomData<&'d mut T>,
72 _te: PeripheralRef<'d, AnyPin>, 72 _te: Peri<'d, AnyPin>,
73} 73}
74 74
75impl<'d, T: Instance> DsiHost<'d, T> { 75impl<'d, T: Instance> DsiHost<'d, T> {
76 /// Note: Full-Duplex modes are not supported at this time 76 /// Note: Full-Duplex modes are not supported at this time
77 pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self { 77 pub fn new(_peri: Peri<'d, T>, te: Peri<'d, impl TePin<T>>) -> Self {
78 into_ref!(te);
79
80 rcc::enable_and_reset::<T>(); 78 rcc::enable_and_reset::<T>();
81 79
82 // Set Tearing Enable pin according to CubeMx example 80 // Set Tearing Enable pin according to CubeMx example
@@ -88,7 +86,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
88 */ 86 */
89 Self { 87 Self {
90 _peri: PhantomData, 88 _peri: PhantomData,
91 _te: te.map_into(), 89 _te: te.into(),
92 } 90 }
93 } 91 }
94 92
@@ -412,7 +410,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral {
412 410
413/// DSI instance trait. 411/// DSI instance trait.
414#[allow(private_bounds)] 412#[allow(private_bounds)]
415pub trait Instance: SealedInstance + RccPeripheral + 'static {} 413pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {}
416 414
417pin_trait!(TePin, Instance); 415pin_trait!(TePin, Instance);
418 416
diff --git a/embassy-stm32/src/dts/mod.rs b/embassy-stm32/src/dts/mod.rs
index 58d7cf841..1f39c8db5 100644
--- a/embassy-stm32/src/dts/mod.rs
+++ b/embassy-stm32/src/dts/mod.rs
@@ -4,13 +4,13 @@ use core::future::poll_fn;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::Peri;
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
11use crate::peripherals::DTS; 11use crate::peripherals::DTS;
12use crate::time::Hertz; 12use crate::time::Hertz;
13use crate::{interrupt, pac, rcc, Peripheral}; 13use crate::{interrupt, pac, rcc};
14 14
15mod tsel; 15mod tsel;
16pub use tsel::TriggerSel; 16pub use tsel::TriggerSel;
@@ -72,7 +72,7 @@ const MAX_DTS_CLK_FREQ: Hertz = Hertz::mhz(1);
72 72
73/// Digital temperature sensor driver. 73/// Digital temperature sensor driver.
74pub struct Dts<'d> { 74pub struct Dts<'d> {
75 _peri: PeripheralRef<'d, DTS>, 75 _peri: Peri<'d, DTS>,
76} 76}
77 77
78static WAKER: AtomicWaker = AtomicWaker::new(); 78static WAKER: AtomicWaker = AtomicWaker::new();
@@ -80,11 +80,10 @@ static WAKER: AtomicWaker = AtomicWaker::new();
80impl<'d> Dts<'d> { 80impl<'d> Dts<'d> {
81 /// Create a new temperature sensor driver. 81 /// Create a new temperature sensor driver.
82 pub fn new( 82 pub fn new(
83 _peri: impl Peripheral<P = DTS> + 'd, 83 _peri: Peri<'d, DTS>,
84 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::DTS, InterruptHandler> + 'd, 84 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::DTS, InterruptHandler> + 'd,
85 config: Config, 85 config: Config,
86 ) -> Self { 86 ) -> Self {
87 into_ref!(_peri);
88 rcc::enable_and_reset::<DTS>(); 87 rcc::enable_and_reset::<DTS>();
89 88
90 let prescaler = rcc::frequency::<DTS>() / MAX_DTS_CLK_FREQ; 89 let prescaler = rcc::frequency::<DTS>() / MAX_DTS_CLK_FREQ;
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 109ceeeb3..97d7b4347 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -9,6 +9,7 @@ mod generic_phy;
9use core::mem::MaybeUninit; 9use core::mem::MaybeUninit;
10use core::task::Context; 10use core::task::Context;
11 11
12use embassy_hal_internal::PeripheralType;
12use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; 13use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
13use embassy_sync::waitqueue::AtomicWaker; 14use embassy_sync::waitqueue::AtomicWaker;
14 15
@@ -199,7 +200,7 @@ trait SealedInstance {
199 200
200/// Ethernet instance. 201/// Ethernet instance.
201#[allow(private_bounds)] 202#[allow(private_bounds)]
202pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} 203pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + Send + 'static {}
203 204
204impl SealedInstance for crate::peripherals::ETH { 205impl SealedInstance for crate::peripherals::ETH {
205 fn regs() -> crate::pac::eth::Eth { 206 fn regs() -> crate::pac::eth::Eth {
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index e12ac2fef..640191d69 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -6,7 +6,7 @@ mod tx_desc;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::sync::atomic::{fence, Ordering}; 7use core::sync::atomic::{fence, Ordering};
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::Peri;
10use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; 10use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf};
11 11
12pub(crate) use self::rx_desc::{RDes, RDesRing}; 12pub(crate) use self::rx_desc::{RDes, RDesRing};
@@ -15,6 +15,7 @@ use super::*;
15#[cfg(eth_v1a)] 15#[cfg(eth_v1a)]
16use crate::gpio::Pull; 16use crate::gpio::Pull;
17use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; 17use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
18use crate::interrupt;
18use crate::interrupt::InterruptExt; 19use crate::interrupt::InterruptExt;
19#[cfg(eth_v1a)] 20#[cfg(eth_v1a)]
20use crate::pac::AFIO; 21use crate::pac::AFIO;
@@ -22,7 +23,6 @@ use crate::pac::AFIO;
22use crate::pac::SYSCFG; 23use crate::pac::SYSCFG;
23use crate::pac::{ETH, RCC}; 24use crate::pac::{ETH, RCC};
24use crate::rcc::SealedRccPeripheral; 25use crate::rcc::SealedRccPeripheral;
25use crate::{interrupt, Peripheral};
26 26
27/// Interrupt handler. 27/// Interrupt handler.
28pub struct InterruptHandler {} 28pub struct InterruptHandler {}
@@ -47,11 +47,11 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandl
47 47
48/// Ethernet driver. 48/// Ethernet driver.
49pub struct Ethernet<'d, T: Instance, P: Phy> { 49pub struct Ethernet<'d, T: Instance, P: Phy> {
50 _peri: PeripheralRef<'d, T>, 50 _peri: Peri<'d, T>,
51 pub(crate) tx: TDesRing<'d>, 51 pub(crate) tx: TDesRing<'d>,
52 pub(crate) rx: RDesRing<'d>, 52 pub(crate) rx: RDesRing<'d>,
53 53
54 pins: [PeripheralRef<'d, AnyPin>; 9], 54 pins: [Peri<'d, AnyPin>; 9],
55 pub(crate) phy: P, 55 pub(crate) phy: P,
56 pub(crate) station_management: EthernetStationManagement<T>, 56 pub(crate) station_management: EthernetStationManagement<T>,
57 pub(crate) mac_addr: [u8; 6], 57 pub(crate) mac_addr: [u8; 6],
@@ -95,22 +95,20 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
95 /// safety: the returned instance is not leak-safe 95 /// safety: the returned instance is not leak-safe
96 pub fn new<const TX: usize, const RX: usize>( 96 pub fn new<const TX: usize, const RX: usize>(
97 queue: &'d mut PacketQueue<TX, RX>, 97 queue: &'d mut PacketQueue<TX, RX>,
98 peri: impl Peripheral<P = T> + 'd, 98 peri: Peri<'d, T>,
99 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 99 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
100 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, 100 ref_clk: Peri<'d, impl RefClkPin<T>>,
101 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, 101 mdio: Peri<'d, impl MDIOPin<T>>,
102 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, 102 mdc: Peri<'d, impl MDCPin<T>>,
103 crs: impl Peripheral<P = impl CRSPin<T>> + 'd, 103 crs: Peri<'d, impl CRSPin<T>>,
104 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, 104 rx_d0: Peri<'d, impl RXD0Pin<T>>,
105 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, 105 rx_d1: Peri<'d, impl RXD1Pin<T>>,
106 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, 106 tx_d0: Peri<'d, impl TXD0Pin<T>>,
107 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, 107 tx_d1: Peri<'d, impl TXD1Pin<T>>,
108 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, 108 tx_en: Peri<'d, impl TXEnPin<T>>,
109 phy: P, 109 phy: P,
110 mac_addr: [u8; 6], 110 mac_addr: [u8; 6],
111 ) -> Self { 111 ) -> Self {
112 into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
113
114 // Enable the necessary Clocks 112 // Enable the necessary Clocks
115 #[cfg(eth_v1a)] 113 #[cfg(eth_v1a)]
116 critical_section::with(|_| { 114 critical_section::with(|_| {
@@ -213,15 +211,15 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
213 }; 211 };
214 212
215 let pins = [ 213 let pins = [
216 ref_clk.map_into(), 214 ref_clk.into(),
217 mdio.map_into(), 215 mdio.into(),
218 mdc.map_into(), 216 mdc.into(),
219 crs.map_into(), 217 crs.into(),
220 rx_d0.map_into(), 218 rx_d0.into(),
221 rx_d1.map_into(), 219 rx_d1.into(),
222 tx_d0.map_into(), 220 tx_d0.into(),
223 tx_d1.map_into(), 221 tx_d1.into(),
224 tx_en.map_into(), 222 tx_en.into(),
225 ]; 223 ];
226 224
227 let mut this = Self { 225 let mut this = Self {
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 26e4eeb63..034c5dd88 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -3,16 +3,16 @@ mod descriptors;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::sync::atomic::{fence, Ordering}; 4use core::sync::atomic::{fence, Ordering};
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::Peri;
7use stm32_metapac::syscfg::vals::EthSelPhy; 7use stm32_metapac::syscfg::vals::EthSelPhy;
8 8
9pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 9pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
10use super::*; 10use super::*;
11use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; 11use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
12use crate::interrupt;
12use crate::interrupt::InterruptExt; 13use crate::interrupt::InterruptExt;
13use crate::pac::ETH; 14use crate::pac::ETH;
14use crate::rcc::SealedRccPeripheral; 15use crate::rcc::SealedRccPeripheral;
15use crate::{interrupt, Peripheral};
16 16
17/// Interrupt handler. 17/// Interrupt handler.
18pub struct InterruptHandler {} 18pub struct InterruptHandler {}
@@ -37,7 +37,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandl
37 37
38/// Ethernet driver. 38/// Ethernet driver.
39pub struct Ethernet<'d, T: Instance, P: Phy> { 39pub struct Ethernet<'d, T: Instance, P: Phy> {
40 _peri: PeripheralRef<'d, T>, 40 _peri: Peri<'d, T>,
41 pub(crate) tx: TDesRing<'d>, 41 pub(crate) tx: TDesRing<'d>,
42 pub(crate) rx: RDesRing<'d>, 42 pub(crate) rx: RDesRing<'d>,
43 pins: Pins<'d>, 43 pins: Pins<'d>,
@@ -48,8 +48,8 @@ pub struct Ethernet<'d, T: Instance, P: Phy> {
48 48
49/// Pins of ethernet driver. 49/// Pins of ethernet driver.
50enum Pins<'d> { 50enum Pins<'d> {
51 Rmii([PeripheralRef<'d, AnyPin>; 9]), 51 Rmii([Peri<'d, AnyPin>; 9]),
52 Mii([PeripheralRef<'d, AnyPin>; 14]), 52 Mii([Peri<'d, AnyPin>; 14]),
53} 53}
54 54
55macro_rules! config_pins { 55macro_rules! config_pins {
@@ -67,17 +67,17 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
67 /// Create a new RMII ethernet driver using 9 pins. 67 /// Create a new RMII ethernet driver using 9 pins.
68 pub fn new<const TX: usize, const RX: usize>( 68 pub fn new<const TX: usize, const RX: usize>(
69 queue: &'d mut PacketQueue<TX, RX>, 69 queue: &'d mut PacketQueue<TX, RX>,
70 peri: impl Peripheral<P = T> + 'd, 70 peri: Peri<'d, T>,
71 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 71 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
72 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, 72 ref_clk: Peri<'d, impl RefClkPin<T>>,
73 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, 73 mdio: Peri<'d, impl MDIOPin<T>>,
74 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, 74 mdc: Peri<'d, impl MDCPin<T>>,
75 crs: impl Peripheral<P = impl CRSPin<T>> + 'd, 75 crs: Peri<'d, impl CRSPin<T>>,
76 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, 76 rx_d0: Peri<'d, impl RXD0Pin<T>>,
77 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, 77 rx_d1: Peri<'d, impl RXD1Pin<T>>,
78 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, 78 tx_d0: Peri<'d, impl TXD0Pin<T>>,
79 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, 79 tx_d1: Peri<'d, impl TXD1Pin<T>>,
80 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, 80 tx_en: Peri<'d, impl TXEnPin<T>>,
81 phy: P, 81 phy: P,
82 mac_addr: [u8; 6], 82 mac_addr: [u8; 6],
83 ) -> Self { 83 ) -> Self {
@@ -92,19 +92,18 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
92 crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII)); 92 crate::pac::SYSCFG.pmcr().modify(|w| w.set_eth_sel_phy(EthSelPhy::RMII));
93 }); 93 });
94 94
95 into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
96 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 95 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
97 96
98 let pins = Pins::Rmii([ 97 let pins = Pins::Rmii([
99 ref_clk.map_into(), 98 ref_clk.into(),
100 mdio.map_into(), 99 mdio.into(),
101 mdc.map_into(), 100 mdc.into(),
102 crs.map_into(), 101 crs.into(),
103 rx_d0.map_into(), 102 rx_d0.into(),
104 rx_d1.map_into(), 103 rx_d1.into(),
105 tx_d0.map_into(), 104 tx_d0.into(),
106 tx_d1.map_into(), 105 tx_d1.into(),
107 tx_en.map_into(), 106 tx_en.into(),
108 ]); 107 ]);
109 108
110 Self::new_inner(queue, peri, irq, pins, phy, mac_addr) 109 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
@@ -113,22 +112,22 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
113 /// Create a new MII ethernet driver using 14 pins. 112 /// Create a new MII ethernet driver using 14 pins.
114 pub fn new_mii<const TX: usize, const RX: usize>( 113 pub fn new_mii<const TX: usize, const RX: usize>(
115 queue: &'d mut PacketQueue<TX, RX>, 114 queue: &'d mut PacketQueue<TX, RX>,
116 peri: impl Peripheral<P = T> + 'd, 115 peri: Peri<'d, T>,
117 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 116 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
118 rx_clk: impl Peripheral<P = impl RXClkPin<T>> + 'd, 117 rx_clk: Peri<'d, impl RXClkPin<T>>,
119 tx_clk: impl Peripheral<P = impl TXClkPin<T>> + 'd, 118 tx_clk: Peri<'d, impl TXClkPin<T>>,
120 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, 119 mdio: Peri<'d, impl MDIOPin<T>>,
121 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, 120 mdc: Peri<'d, impl MDCPin<T>>,
122 rxdv: impl Peripheral<P = impl RXDVPin<T>> + 'd, 121 rxdv: Peri<'d, impl RXDVPin<T>>,
123 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd, 122 rx_d0: Peri<'d, impl RXD0Pin<T>>,
124 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd, 123 rx_d1: Peri<'d, impl RXD1Pin<T>>,
125 rx_d2: impl Peripheral<P = impl RXD2Pin<T>> + 'd, 124 rx_d2: Peri<'d, impl RXD2Pin<T>>,
126 rx_d3: impl Peripheral<P = impl RXD3Pin<T>> + 'd, 125 rx_d3: Peri<'d, impl RXD3Pin<T>>,
127 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd, 126 tx_d0: Peri<'d, impl TXD0Pin<T>>,
128 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd, 127 tx_d1: Peri<'d, impl TXD1Pin<T>>,
129 tx_d2: impl Peripheral<P = impl TXD2Pin<T>> + 'd, 128 tx_d2: Peri<'d, impl TXD2Pin<T>>,
130 tx_d3: impl Peripheral<P = impl TXD3Pin<T>> + 'd, 129 tx_d3: Peri<'d, impl TXD3Pin<T>>,
131 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd, 130 tx_en: Peri<'d, impl TXEnPin<T>>,
132 phy: P, 131 phy: P,
133 mac_addr: [u8; 6], 132 mac_addr: [u8; 6],
134 ) -> Self { 133 ) -> Self {
@@ -145,24 +144,23 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
145 .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII)); 144 .modify(|w| w.set_eth_sel_phy(EthSelPhy::MII_GMII));
146 }); 145 });
147 146
148 into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
149 config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en); 147 config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
150 148
151 let pins = Pins::Mii([ 149 let pins = Pins::Mii([
152 rx_clk.map_into(), 150 rx_clk.into(),
153 tx_clk.map_into(), 151 tx_clk.into(),
154 mdio.map_into(), 152 mdio.into(),
155 mdc.map_into(), 153 mdc.into(),
156 rxdv.map_into(), 154 rxdv.into(),
157 rx_d0.map_into(), 155 rx_d0.into(),
158 rx_d1.map_into(), 156 rx_d1.into(),
159 rx_d2.map_into(), 157 rx_d2.into(),
160 rx_d3.map_into(), 158 rx_d3.into(),
161 tx_d0.map_into(), 159 tx_d0.into(),
162 tx_d1.map_into(), 160 tx_d1.into(),
163 tx_d2.map_into(), 161 tx_d2.into(),
164 tx_d3.map_into(), 162 tx_d3.into(),
165 tx_en.map_into(), 163 tx_en.into(),
166 ]); 164 ]);
167 165
168 Self::new_inner(queue, peri, irq, pins, phy, mac_addr) 166 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
@@ -170,7 +168,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
170 168
171 fn new_inner<const TX: usize, const RX: usize>( 169 fn new_inner<const TX: usize, const RX: usize>(
172 queue: &'d mut PacketQueue<TX, RX>, 170 queue: &'d mut PacketQueue<TX, RX>,
173 peri: impl Peripheral<P = T> + 'd, 171 peri: Peri<'d, T>,
174 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 172 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
175 pins: Pins<'d>, 173 pins: Pins<'d>,
176 phy: P, 174 phy: P,
@@ -254,7 +252,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
254 }; 252 };
255 253
256 let mut this = Self { 254 let mut this = Self {
257 _peri: peri.into_ref(), 255 _peri: peri,
258 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), 256 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
259 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), 257 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
260 pins, 258 pins,
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 9604c5149..9fce78f95 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -5,13 +5,13 @@ use core::marker::PhantomData;
5use core::pin::Pin; 5use core::pin::Pin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{impl_peripheral, into_ref}; 8use embassy_hal_internal::{impl_peripheral, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull}; 11use crate::gpio::{AnyPin, Input, Level, Pin as GpioPin, Pull};
12use crate::pac::exti::regs::Lines; 12use crate::pac::exti::regs::Lines;
13use crate::pac::EXTI; 13use crate::pac::EXTI;
14use crate::{interrupt, pac, peripherals, Peripheral}; 14use crate::{interrupt, pac, peripherals, Peri};
15 15
16const EXTI_COUNT: usize = 16; 16const EXTI_COUNT: usize = 16;
17static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT]; 17static EXTI_WAKERS: [AtomicWaker; EXTI_COUNT] = [const { AtomicWaker::new() }; EXTI_COUNT];
@@ -105,13 +105,7 @@ impl<'d> Unpin for ExtiInput<'d> {}
105 105
106impl<'d> ExtiInput<'d> { 106impl<'d> ExtiInput<'d> {
107 /// Create an EXTI input. 107 /// Create an EXTI input.
108 pub fn new<T: GpioPin>( 108 pub fn new<T: GpioPin>(pin: Peri<'d, T>, ch: Peri<'d, T::ExtiChannel>, pull: Pull) -> Self {
109 pin: impl Peripheral<P = T> + 'd,
110 ch: impl Peripheral<P = T::ExtiChannel> + 'd,
111 pull: Pull,
112 ) -> Self {
113 into_ref!(pin, ch);
114
115 // Needed if using AnyPin+AnyChannel. 109 // Needed if using AnyPin+AnyChannel.
116 assert_eq!(pin.pin(), ch.number()); 110 assert_eq!(pin.pin(), ch.number());
117 111
@@ -338,23 +332,12 @@ trait SealedChannel {}
338 332
339/// EXTI channel trait. 333/// EXTI channel trait.
340#[allow(private_bounds)] 334#[allow(private_bounds)]
341pub trait Channel: SealedChannel + Sized { 335pub trait Channel: PeripheralType + SealedChannel + Sized {
342 /// Get the EXTI channel number. 336 /// Get the EXTI channel number.
343 fn number(&self) -> u8; 337 fn number(&self) -> u8;
344
345 /// Type-erase (degrade) this channel into an `AnyChannel`.
346 ///
347 /// This converts EXTI channel singletons (`EXTI0`, `EXTI1`, ...), which
348 /// are all different types, into the same type. It is useful for
349 /// creating arrays of channels, or avoiding generics.
350 fn degrade(self) -> AnyChannel {
351 AnyChannel {
352 number: self.number() as u8,
353 }
354 }
355} 338}
356 339
357/// Type-erased (degraded) EXTI channel. 340/// Type-erased EXTI channel.
358/// 341///
359/// This represents ownership over any EXTI channel, known at runtime. 342/// This represents ownership over any EXTI channel, known at runtime.
360pub struct AnyChannel { 343pub struct AnyChannel {
@@ -377,6 +360,14 @@ macro_rules! impl_exti {
377 $number 360 $number
378 } 361 }
379 } 362 }
363
364 impl From<peripherals::$type> for AnyChannel {
365 fn from(val: peripherals::$type) -> Self {
366 Self {
367 number: val.number() as u8,
368 }
369 }
370 }
380 }; 371 };
381} 372}
382 373
diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs
index 9468ac632..599b7bb4e 100644
--- a/embassy-stm32/src/flash/asynch.rs
+++ b/embassy-stm32/src/flash/asynch.rs
@@ -2,7 +2,6 @@ use core::marker::PhantomData;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3 3
4use embassy_hal_internal::drop::OnDrop; 4use embassy_hal_internal::drop::OnDrop;
5use embassy_hal_internal::into_ref;
6use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 5use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_sync::mutex::Mutex; 6use embassy_sync::mutex::Mutex;
8 7
@@ -12,18 +11,16 @@ use super::{
12}; 11};
13use crate::interrupt::InterruptExt; 12use crate::interrupt::InterruptExt;
14use crate::peripherals::FLASH; 13use crate::peripherals::FLASH;
15use crate::{interrupt, Peripheral}; 14use crate::{interrupt, Peri};
16 15
17pub(super) static REGION_ACCESS: Mutex<CriticalSectionRawMutex, ()> = Mutex::new(()); 16pub(super) static REGION_ACCESS: Mutex<CriticalSectionRawMutex, ()> = Mutex::new(());
18 17
19impl<'d> Flash<'d, Async> { 18impl<'d> Flash<'d, Async> {
20 /// Create a new flash driver with async capabilities. 19 /// Create a new flash driver with async capabilities.
21 pub fn new( 20 pub fn new(
22 p: impl Peripheral<P = FLASH> + 'd, 21 p: Peri<'d, FLASH>,
23 _irq: impl interrupt::typelevel::Binding<crate::interrupt::typelevel::FLASH, InterruptHandler> + 'd, 22 _irq: impl interrupt::typelevel::Binding<crate::interrupt::typelevel::FLASH, InterruptHandler> + 'd,
24 ) -> Self { 23 ) -> Self {
25 into_ref!(p);
26
27 crate::interrupt::FLASH.unpend(); 24 crate::interrupt::FLASH.unpend();
28 unsafe { crate::interrupt::FLASH.enable() }; 25 unsafe { crate::interrupt::FLASH.enable() };
29 26
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index 0004a7488..1376ca4b4 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -2,27 +2,24 @@ use core::marker::PhantomData;
2use core::sync::atomic::{fence, Ordering}; 2use core::sync::atomic::{fence, Ordering};
3 3
4use embassy_hal_internal::drop::OnDrop; 4use embassy_hal_internal::drop::OnDrop;
5use embassy_hal_internal::{into_ref, PeripheralRef};
6 5
7use super::{ 6use super::{
8 family, Async, Blocking, Error, FlashBank, FlashLayout, FlashRegion, FlashSector, FLASH_SIZE, MAX_ERASE_SIZE, 7 family, Async, Blocking, Error, FlashBank, FlashLayout, FlashRegion, FlashSector, FLASH_SIZE, MAX_ERASE_SIZE,
9 READ_SIZE, WRITE_SIZE, 8 READ_SIZE, WRITE_SIZE,
10}; 9};
10use crate::Peri;
11use crate::_generated::FLASH_BASE; 11use crate::_generated::FLASH_BASE;
12use crate::peripherals::FLASH; 12use crate::peripherals::FLASH;
13use crate::Peripheral;
14 13
15/// Internal flash memory driver. 14/// Internal flash memory driver.
16pub struct Flash<'d, MODE = Async> { 15pub struct Flash<'d, MODE = Async> {
17 pub(crate) inner: PeripheralRef<'d, FLASH>, 16 pub(crate) inner: Peri<'d, FLASH>,
18 pub(crate) _mode: PhantomData<MODE>, 17 pub(crate) _mode: PhantomData<MODE>,
19} 18}
20 19
21impl<'d> Flash<'d, Blocking> { 20impl<'d> Flash<'d, Blocking> {
22 /// Create a new flash driver, usable in blocking mode. 21 /// Create a new flash driver, usable in blocking mode.
23 pub fn new_blocking(p: impl Peripheral<P = FLASH> + 'd) -> Self { 22 pub fn new_blocking(p: Peri<'d, FLASH>) -> Self {
24 into_ref!(p);
25
26 Self { 23 Self {
27 inner: p, 24 inner: p,
28 _mode: PhantomData, 25 _mode: PhantomData,
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 86afdce8a..687eabaeb 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -13,8 +13,7 @@ use crate::pac;
13mod alt_regions { 13mod alt_regions {
14 use core::marker::PhantomData; 14 use core::marker::PhantomData;
15 15
16 use embassy_hal_internal::PeripheralRef; 16 use crate::Peri;
17
18 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION}; 17 use crate::_generated::flash_regions::{OTPRegion, BANK1_REGION1, BANK1_REGION2, BANK1_REGION3, OTP_REGION};
19 use crate::_generated::FLASH_SIZE; 18 use crate::_generated::FLASH_SIZE;
20 use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion}; 19 use crate::flash::{asynch, Async, Bank1Region1, Bank1Region2, Blocking, Error, Flash, FlashBank, FlashRegion};
@@ -50,10 +49,10 @@ mod alt_regions {
50 &ALT_BANK2_REGION3, 49 &ALT_BANK2_REGION3,
51 ]; 50 ];
52 51
53 pub struct AltBank1Region3<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>); 52 pub struct AltBank1Region3<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData<MODE>);
54 pub struct AltBank2Region1<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>); 53 pub struct AltBank2Region1<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData<MODE>);
55 pub struct AltBank2Region2<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>); 54 pub struct AltBank2Region2<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData<MODE>);
56 pub struct AltBank2Region3<'d, MODE = Async>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>, PhantomData<MODE>); 55 pub struct AltBank2Region3<'d, MODE = Async>(pub &'static FlashRegion, Peri<'d, FLASH>, PhantomData<MODE>);
57 56
58 pub struct AltFlashLayout<'d, MODE = Async> { 57 pub struct AltFlashLayout<'d, MODE = Async> {
59 pub bank1_region1: Bank1Region1<'d, MODE>, 58 pub bank1_region1: Bank1Region1<'d, MODE>,
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index 83b49a3dd..71ca775cb 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -1,10 +1,10 @@
1//! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC) 1//! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC)
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3 3
4use embassy_hal_internal::into_ref; 4use embassy_hal_internal::PeripheralType;
5 5
6use crate::gpio::{AfType, OutputType, Pull, Speed}; 6use crate::gpio::{AfType, OutputType, Pull, Speed};
7use crate::{rcc, Peripheral}; 7use crate::{rcc, Peri};
8 8
9/// FMC driver 9/// FMC driver
10pub struct Fmc<'d, T: Instance> { 10pub struct Fmc<'d, T: Instance> {
@@ -21,7 +21,7 @@ where
21 /// 21 ///
22 /// **Note:** This is currently used to provide access to some basic FMC functions 22 /// **Note:** This is currently used to provide access to some basic FMC functions
23 /// for manual configuration for memory types that stm32-fmc does not support. 23 /// for manual configuration for memory types that stm32-fmc does not support.
24 pub fn new_raw(_instance: impl Peripheral<P = T> + 'd) -> Self { 24 pub fn new_raw(_instance: Peri<'d, T>) -> Self {
25 Self { peri: PhantomData } 25 Self { peri: PhantomData }
26 } 26 }
27 27
@@ -74,8 +74,7 @@ where
74 74
75macro_rules! config_pins { 75macro_rules! config_pins {
76 ($($pin:ident),*) => { 76 ($($pin:ident),*) => {
77 into_ref!($($pin),*); 77 $(
78 $(
79 $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up)); 78 $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up));
80 )* 79 )*
81 }; 80 };
@@ -92,12 +91,12 @@ macro_rules! fmc_sdram_constructor {
92 )) => { 91 )) => {
93 /// Create a new FMC instance. 92 /// Create a new FMC instance.
94 pub fn $name<CHIP: stm32_fmc::SdramChip>( 93 pub fn $name<CHIP: stm32_fmc::SdramChip>(
95 _instance: impl Peripheral<P = T> + 'd, 94 _instance: Peri<'d, T>,
96 $($addr_pin_name: impl Peripheral<P = impl $addr_signal<T>> + 'd),*, 95 $($addr_pin_name: Peri<'d, impl $addr_signal<T>>),*,
97 $($ba_pin_name: impl Peripheral<P = impl $ba_signal<T>> + 'd),*, 96 $($ba_pin_name: Peri<'d, impl $ba_signal<T>>),*,
98 $($d_pin_name: impl Peripheral<P = impl $d_signal<T>> + 'd),*, 97 $($d_pin_name: Peri<'d, impl $d_signal<T>>),*,
99 $($nbl_pin_name: impl Peripheral<P = impl $nbl_signal<T>> + 'd),*, 98 $($nbl_pin_name: Peri<'d, impl $nbl_signal<T>>),*,
100 $($ctrl_pin_name: impl Peripheral<P = impl $ctrl_signal<T>> + 'd),*, 99 $($ctrl_pin_name: Peri<'d, impl $ctrl_signal<T>>),*,
101 chip: CHIP 100 chip: CHIP
102 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> { 101 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
103 102
@@ -245,7 +244,7 @@ trait SealedInstance: crate::rcc::RccPeripheral {
245 244
246/// FMC instance trait. 245/// FMC instance trait.
247#[allow(private_bounds)] 246#[allow(private_bounds)]
248pub trait Instance: SealedInstance + 'static {} 247pub trait Instance: SealedInstance + PeripheralType + 'static {}
249 248
250foreach_peripheral!( 249foreach_peripheral!(
251 (fmc, $inst:ident) => { 250 (fmc, $inst:ident) => {
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 65e1bfb8c..bb37c4194 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -4,10 +4,10 @@
4use core::convert::Infallible; 4use core::convert::Infallible;
5 5
6use critical_section::CriticalSection; 6use critical_section::CriticalSection;
7use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
8 8
9use crate::pac::gpio::{self, vals}; 9use crate::pac::gpio::{self, vals};
10use crate::{peripherals, Peripheral}; 10use crate::peripherals;
11 11
12/// GPIO flexible pin. 12/// GPIO flexible pin.
13/// 13///
@@ -15,7 +15,7 @@ use crate::{peripherals, Peripheral};
15/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 15/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
16/// mode. 16/// mode.
17pub struct Flex<'d> { 17pub struct Flex<'d> {
18 pub(crate) pin: PeripheralRef<'d, AnyPin>, 18 pub(crate) pin: Peri<'d, AnyPin>,
19} 19}
20 20
21impl<'d> Flex<'d> { 21impl<'d> Flex<'d> {
@@ -25,10 +25,9 @@ impl<'d> Flex<'d> {
25 /// before the pin is put into output mode. 25 /// before the pin is put into output mode.
26 /// 26 ///
27 #[inline] 27 #[inline]
28 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { 28 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
29 into_ref!(pin);
30 // Pin will be in disconnected state. 29 // Pin will be in disconnected state.
31 Self { pin: pin.map_into() } 30 Self { pin: pin.into() }
32 } 31 }
33 32
34 /// Put the pin into input mode. 33 /// Put the pin into input mode.
@@ -310,7 +309,7 @@ pub struct Input<'d> {
310impl<'d> Input<'d> { 309impl<'d> Input<'d> {
311 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. 310 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
312 #[inline] 311 #[inline]
313 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { 312 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
314 let mut pin = Flex::new(pin); 313 let mut pin = Flex::new(pin);
315 pin.set_as_input(pull); 314 pin.set_as_input(pull);
316 Self { pin } 315 Self { pin }
@@ -375,7 +374,7 @@ pub struct Output<'d> {
375impl<'d> Output<'d> { 374impl<'d> Output<'d> {
376 /// Create GPIO output driver for a [Pin] with the provided [Level] and [Speed] configuration. 375 /// Create GPIO output driver for a [Pin] with the provided [Level] and [Speed] configuration.
377 #[inline] 376 #[inline]
378 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed) -> Self { 377 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed) -> Self {
379 let mut pin = Flex::new(pin); 378 let mut pin = Flex::new(pin);
380 match initial_output { 379 match initial_output {
381 Level::High => pin.set_high(), 380 Level::High => pin.set_high(),
@@ -440,7 +439,7 @@ pub struct OutputOpenDrain<'d> {
440impl<'d> OutputOpenDrain<'d> { 439impl<'d> OutputOpenDrain<'d> {
441 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed]. 440 /// Create a new GPIO open drain output driver for a [Pin] with the provided [Level] and [Speed].
442 #[inline] 441 #[inline]
443 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed) -> Self { 442 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed) -> Self {
444 let mut pin = Flex::new(pin); 443 let mut pin = Flex::new(pin);
445 match initial_output { 444 match initial_output {
446 Level::High => pin.set_high(), 445 Level::High => pin.set_high(),
@@ -454,7 +453,7 @@ impl<'d> OutputOpenDrain<'d> {
454 /// and [Pull]. 453 /// and [Pull].
455 #[inline] 454 #[inline]
456 #[cfg(gpio_v2)] 455 #[cfg(gpio_v2)]
457 pub fn new_pull(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { 456 pub fn new_pull(pin: Peri<'d, impl Pin>, initial_output: Level, speed: Speed, pull: Pull) -> Self {
458 let mut pin = Flex::new(pin); 457 let mut pin = Flex::new(pin);
459 match initial_output { 458 match initial_output {
460 Level::High => pin.set_high(), 459 Level::High => pin.set_high(),
@@ -780,7 +779,7 @@ pub(crate) trait SealedPin {
780 779
781/// GPIO pin trait. 780/// GPIO pin trait.
782#[allow(private_bounds)] 781#[allow(private_bounds)]
783pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { 782pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
784 /// EXTI channel assigned to this pin. 783 /// EXTI channel assigned to this pin.
785 /// 784 ///
786 /// For example, PC4 uses EXTI4. 785 /// For example, PC4 uses EXTI4.
@@ -798,18 +797,6 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static
798 fn port(&self) -> u8 { 797 fn port(&self) -> u8 {
799 self._port() 798 self._port()
800 } 799 }
801
802 /// Type-erase (degrade) this pin into an `AnyPin`.
803 ///
804 /// This converts pin singletons (`PA5`, `PB6`, ...), which
805 /// are all different types, into the same type. It is useful for
806 /// creating arrays of pins, or avoiding generics.
807 #[inline]
808 fn degrade(self) -> AnyPin {
809 AnyPin {
810 pin_port: self.pin_port(),
811 }
812 }
813} 800}
814 801
815/// Type-erased GPIO pin 802/// Type-erased GPIO pin
@@ -822,8 +809,8 @@ impl AnyPin {
822 /// 809 ///
823 /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc... 810 /// `pin_port` is `port_num * 16 + pin_num`, where `port_num` is 0 for port `A`, 1 for port `B`, etc...
824 #[inline] 811 #[inline]
825 pub unsafe fn steal(pin_port: u8) -> Self { 812 pub unsafe fn steal(pin_port: u8) -> Peri<'static, Self> {
826 Self { pin_port } 813 Peri::new_unchecked(Self { pin_port })
827 } 814 }
828 815
829 #[inline] 816 #[inline]
@@ -867,8 +854,10 @@ foreach_pin!(
867 } 854 }
868 855
869 impl From<peripherals::$pin_name> for AnyPin { 856 impl From<peripherals::$pin_name> for AnyPin {
870 fn from(x: peripherals::$pin_name) -> Self { 857 fn from(val: peripherals::$pin_name) -> Self {
871 x.degrade() 858 Self {
859 pin_port: val.pin_port(),
860 }
872 } 861 }
873 } 862 }
874 }; 863 };
diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs
index 3c2125498..1258e8923 100644
--- a/embassy-stm32/src/hash/mod.rs
+++ b/embassy-stm32/src/hash/mod.rs
@@ -8,16 +8,18 @@ use core::ptr;
8#[cfg(hash_v2)] 8#[cfg(hash_v2)]
9use core::task::Poll; 9use core::task::Poll;
10 10
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::PeripheralType;
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13use stm32_metapac::hash::regs::*; 13use stm32_metapac::hash::regs::*;
14 14
15use crate::dma::NoDma;
16#[cfg(hash_v2)] 15#[cfg(hash_v2)]
17use crate::dma::Transfer; 16use crate::dma::ChannelAndRequest;
18use crate::interrupt::typelevel::Interrupt; 17use crate::interrupt::typelevel::Interrupt;
18#[cfg(hash_v2)]
19use crate::mode::Async;
20use crate::mode::{Blocking, Mode};
19use crate::peripherals::HASH; 21use crate::peripherals::HASH;
20use crate::{interrupt, pac, peripherals, rcc, Peripheral}; 22use crate::{interrupt, pac, peripherals, rcc, Peri};
21 23
22#[cfg(hash_v1)] 24#[cfg(hash_v1)]
23const NUM_CONTEXT_REGS: usize = 51; 25const NUM_CONTEXT_REGS: usize = 51;
@@ -116,24 +118,25 @@ pub struct Context<'c> {
116type HmacKey<'k> = Option<&'k [u8]>; 118type HmacKey<'k> = Option<&'k [u8]>;
117 119
118/// HASH driver. 120/// HASH driver.
119pub struct Hash<'d, T: Instance, D = NoDma> { 121pub struct Hash<'d, T: Instance, M: Mode> {
120 _peripheral: PeripheralRef<'d, T>, 122 _peripheral: Peri<'d, T>,
121 #[allow(dead_code)] 123 _phantom: PhantomData<M>,
122 dma: PeripheralRef<'d, D>, 124 #[cfg(hash_v2)]
125 dma: Option<ChannelAndRequest<'d>>,
123} 126}
124 127
125impl<'d, T: Instance, D> Hash<'d, T, D> { 128impl<'d, T: Instance> Hash<'d, T, Blocking> {
126 /// Instantiates, resets, and enables the HASH peripheral. 129 /// Instantiates, resets, and enables the HASH peripheral.
127 pub fn new( 130 pub fn new_blocking(
128 peripheral: impl Peripheral<P = T> + 'd, 131 peripheral: Peri<'d, T>,
129 dma: impl Peripheral<P = D> + 'd,
130 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 132 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
131 ) -> Self { 133 ) -> Self {
132 rcc::enable_and_reset::<HASH>(); 134 rcc::enable_and_reset::<HASH>();
133 into_ref!(peripheral, dma);
134 let instance = Self { 135 let instance = Self {
135 _peripheral: peripheral, 136 _peripheral: peripheral,
136 dma: dma, 137 _phantom: PhantomData,
138 #[cfg(hash_v2)]
139 dma: None,
137 }; 140 };
138 141
139 T::Interrupt::unpend(); 142 T::Interrupt::unpend();
@@ -141,7 +144,9 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
141 144
142 instance 145 instance
143 } 146 }
147}
144 148
149impl<'d, T: Instance, M: Mode> Hash<'d, T, M> {
145 /// Starts computation of a new hash and returns the saved peripheral state. 150 /// Starts computation of a new hash and returns the saved peripheral state.
146 pub fn start<'c>(&mut self, algorithm: Algorithm, format: DataType, key: HmacKey<'c>) -> Context<'c> { 151 pub fn start<'c>(&mut self, algorithm: Algorithm, format: DataType, key: HmacKey<'c>) -> Context<'c> {
147 // Define a context for this new computation. 152 // Define a context for this new computation.
@@ -282,14 +287,135 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
282 self.store_context(ctx); 287 self.store_context(ctx);
283 } 288 }
284 289
290 /// Computes a digest for the given context.
291 /// The digest buffer must be large enough to accomodate a digest for the selected algorithm.
292 /// The largest returned digest size is 128 bytes for SHA-512.
293 /// Panics if the supplied digest buffer is too short.
294 pub fn finish_blocking<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize {
295 // Restore the peripheral state.
296 self.load_context(&ctx);
297
298 // Hash the leftover bytes, if any.
299 self.accumulate_blocking(&ctx.buffer[0..ctx.buflen]);
300 ctx.buflen = 0;
301
302 //Start the digest calculation.
303 T::regs().str().write(|w| w.set_dcal(true));
304
305 // Load the HMAC key if provided.
306 if let Some(key) = ctx.key {
307 while !T::regs().sr().read().dinis() {}
308 self.accumulate_blocking(key);
309 T::regs().str().write(|w| w.set_dcal(true));
310 }
311
312 // Block until digest computation is complete.
313 while !T::regs().sr().read().dcis() {}
314
315 // Return the digest.
316 let digest_words = match ctx.algo {
317 Algorithm::SHA1 => 5,
318 #[cfg(any(hash_v1, hash_v2, hash_v4))]
319 Algorithm::MD5 => 4,
320 Algorithm::SHA224 => 7,
321 Algorithm::SHA256 => 8,
322 #[cfg(hash_v3)]
323 Algorithm::SHA384 => 12,
324 #[cfg(hash_v3)]
325 Algorithm::SHA512_224 => 7,
326 #[cfg(hash_v3)]
327 Algorithm::SHA512_256 => 8,
328 #[cfg(hash_v3)]
329 Algorithm::SHA512 => 16,
330 };
331
332 let digest_len_bytes = digest_words * 4;
333 // Panics if the supplied digest buffer is too short.
334 if digest.len() < digest_len_bytes {
335 panic!("Digest buffer must be at least {} bytes long.", digest_words * 4);
336 }
337
338 let mut i = 0;
339 while i < digest_words {
340 let word = T::regs().hr(i).read();
341 digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice());
342 i += 1;
343 }
344 digest_len_bytes
345 }
346
347 /// Push data into the hash core.
348 fn accumulate_blocking(&mut self, input: &[u8]) {
349 // Set the number of valid bits.
350 let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8;
351 T::regs().str().modify(|w| w.set_nblw(num_valid_bits));
352
353 let mut i = 0;
354 while i < input.len() {
355 let mut word: [u8; 4] = [0; 4];
356 let copy_idx = min(i + 4, input.len());
357 word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]);
358 T::regs().din().write_value(u32::from_ne_bytes(word));
359 i += 4;
360 }
361 }
362
363 /// Save the peripheral state to a context.
364 fn store_context<'c>(&mut self, ctx: &mut Context<'c>) {
365 // Block waiting for data in ready.
366 while !T::regs().sr().read().dinis() {}
367
368 // Store peripheral context.
369 ctx.imr = T::regs().imr().read().0;
370 ctx.str = T::regs().str().read().0;
371 ctx.cr = T::regs().cr().read().0;
372 let mut i = 0;
373 while i < NUM_CONTEXT_REGS {
374 ctx.csr[i] = T::regs().csr(i).read();
375 i += 1;
376 }
377 }
378
379 /// Restore the peripheral state from a context.
380 fn load_context(&mut self, ctx: &Context) {
381 // Restore the peripheral state from the context.
382 T::regs().imr().write_value(Imr { 0: ctx.imr });
383 T::regs().str().write_value(Str { 0: ctx.str });
384 T::regs().cr().write_value(Cr { 0: ctx.cr });
385 T::regs().cr().modify(|w| w.set_init(true));
386 let mut i = 0;
387 while i < NUM_CONTEXT_REGS {
388 T::regs().csr(i).write_value(ctx.csr[i]);
389 i += 1;
390 }
391 }
392}
393
394#[cfg(hash_v2)]
395impl<'d, T: Instance> Hash<'d, T, Async> {
396 /// Instantiates, resets, and enables the HASH peripheral.
397 pub fn new(
398 peripheral: Peri<'d, T>,
399 dma: Peri<'d, impl Dma<T>>,
400 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
401 ) -> Self {
402 rcc::enable_and_reset::<HASH>();
403 let instance = Self {
404 _peripheral: peripheral,
405 _phantom: PhantomData,
406 dma: new_dma!(dma),
407 };
408
409 T::Interrupt::unpend();
410 unsafe { T::Interrupt::enable() };
411
412 instance
413 }
414
285 /// Restores the peripheral state using the given context, 415 /// Restores the peripheral state using the given context,
286 /// then updates the state with the provided data. 416 /// then updates the state with the provided data.
287 /// Peripheral state is saved upon return. 417 /// Peripheral state is saved upon return.
288 #[cfg(hash_v2)] 418 pub async fn update(&mut self, ctx: &mut Context<'_>, input: &[u8]) {
289 pub async fn update<'c>(&mut self, ctx: &mut Context<'c>, input: &[u8])
290 where
291 D: crate::hash::Dma<T>,
292 {
293 // Restore the peripheral state. 419 // Restore the peripheral state.
294 self.load_context(&ctx); 420 self.load_context(&ctx);
295 421
@@ -353,68 +479,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
353 /// The digest buffer must be large enough to accomodate a digest for the selected algorithm. 479 /// The digest buffer must be large enough to accomodate a digest for the selected algorithm.
354 /// The largest returned digest size is 128 bytes for SHA-512. 480 /// The largest returned digest size is 128 bytes for SHA-512.
355 /// Panics if the supplied digest buffer is too short. 481 /// Panics if the supplied digest buffer is too short.
356 pub fn finish_blocking<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize { 482 pub async fn finish<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize {
357 // Restore the peripheral state.
358 self.load_context(&ctx);
359
360 // Hash the leftover bytes, if any.
361 self.accumulate_blocking(&ctx.buffer[0..ctx.buflen]);
362 ctx.buflen = 0;
363
364 //Start the digest calculation.
365 T::regs().str().write(|w| w.set_dcal(true));
366
367 // Load the HMAC key if provided.
368 if let Some(key) = ctx.key {
369 while !T::regs().sr().read().dinis() {}
370 self.accumulate_blocking(key);
371 T::regs().str().write(|w| w.set_dcal(true));
372 }
373
374 // Block until digest computation is complete.
375 while !T::regs().sr().read().dcis() {}
376
377 // Return the digest.
378 let digest_words = match ctx.algo {
379 Algorithm::SHA1 => 5,
380 #[cfg(any(hash_v1, hash_v2, hash_v4))]
381 Algorithm::MD5 => 4,
382 Algorithm::SHA224 => 7,
383 Algorithm::SHA256 => 8,
384 #[cfg(hash_v3)]
385 Algorithm::SHA384 => 12,
386 #[cfg(hash_v3)]
387 Algorithm::SHA512_224 => 7,
388 #[cfg(hash_v3)]
389 Algorithm::SHA512_256 => 8,
390 #[cfg(hash_v3)]
391 Algorithm::SHA512 => 16,
392 };
393
394 let digest_len_bytes = digest_words * 4;
395 // Panics if the supplied digest buffer is too short.
396 if digest.len() < digest_len_bytes {
397 panic!("Digest buffer must be at least {} bytes long.", digest_words * 4);
398 }
399
400 let mut i = 0;
401 while i < digest_words {
402 let word = T::regs().hr(i).read();
403 digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice());
404 i += 1;
405 }
406 digest_len_bytes
407 }
408
409 /// Computes a digest for the given context.
410 /// The digest buffer must be large enough to accomodate a digest for the selected algorithm.
411 /// The largest returned digest size is 128 bytes for SHA-512.
412 /// Panics if the supplied digest buffer is too short.
413 #[cfg(hash_v2)]
414 pub async fn finish<'c>(&mut self, mut ctx: Context<'c>, digest: &mut [u8]) -> usize
415 where
416 D: crate::hash::Dma<T>,
417 {
418 // Restore the peripheral state. 483 // Restore the peripheral state.
419 self.load_context(&ctx); 484 self.load_context(&ctx);
420 485
@@ -483,27 +548,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
483 } 548 }
484 549
485 /// Push data into the hash core. 550 /// Push data into the hash core.
486 fn accumulate_blocking(&mut self, input: &[u8]) { 551 async fn accumulate(&mut self, input: &[u8]) {
487 // Set the number of valid bits.
488 let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8;
489 T::regs().str().modify(|w| w.set_nblw(num_valid_bits));
490
491 let mut i = 0;
492 while i < input.len() {
493 let mut word: [u8; 4] = [0; 4];
494 let copy_idx = min(i + 4, input.len());
495 word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]);
496 T::regs().din().write_value(u32::from_ne_bytes(word));
497 i += 4;
498 }
499 }
500
501 /// Push data into the hash core.
502 #[cfg(hash_v2)]
503 async fn accumulate(&mut self, input: &[u8])
504 where
505 D: crate::hash::Dma<T>,
506 {
507 // Ignore an input length of 0. 552 // Ignore an input length of 0.
508 if input.len() == 0 { 553 if input.len() == 0 {
509 return; 554 return;
@@ -514,57 +559,20 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
514 T::regs().str().modify(|w| w.set_nblw(num_valid_bits)); 559 T::regs().str().modify(|w| w.set_nblw(num_valid_bits));
515 560
516 // Configure DMA to transfer input to hash core. 561 // Configure DMA to transfer input to hash core.
517 let dma_request = self.dma.request();
518 let dst_ptr: *mut u32 = T::regs().din().as_ptr(); 562 let dst_ptr: *mut u32 = T::regs().din().as_ptr();
519 let mut num_words = input.len() / 4; 563 let mut num_words = input.len() / 4;
520 if input.len() % 4 > 0 { 564 if input.len() % 4 > 0 {
521 num_words += 1; 565 num_words += 1;
522 } 566 }
523 let src_ptr: *const [u8] = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words); 567 let src_ptr: *const [u8] = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
524 let dma_transfer = unsafe { 568
525 Transfer::new_write_raw( 569 let dma = self.dma.as_mut().unwrap();
526 &mut self.dma, 570 let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr as *mut u32, Default::default()) };
527 dma_request,
528 src_ptr,
529 dst_ptr as *mut u32,
530 Default::default(),
531 )
532 };
533 T::regs().cr().modify(|w| w.set_dmae(true)); 571 T::regs().cr().modify(|w| w.set_dmae(true));
534 572
535 // Wait for the transfer to complete. 573 // Wait for the transfer to complete.
536 dma_transfer.await; 574 dma_transfer.await;
537 } 575 }
538
539 /// Save the peripheral state to a context.
540 fn store_context<'c>(&mut self, ctx: &mut Context<'c>) {
541 // Block waiting for data in ready.
542 while !T::regs().sr().read().dinis() {}
543
544 // Store peripheral context.
545 ctx.imr = T::regs().imr().read().0;
546 ctx.str = T::regs().str().read().0;
547 ctx.cr = T::regs().cr().read().0;
548 let mut i = 0;
549 while i < NUM_CONTEXT_REGS {
550 ctx.csr[i] = T::regs().csr(i).read();
551 i += 1;
552 }
553 }
554
555 /// Restore the peripheral state from a context.
556 fn load_context(&mut self, ctx: &Context) {
557 // Restore the peripheral state from the context.
558 T::regs().imr().write_value(Imr { 0: ctx.imr });
559 T::regs().str().write_value(Str { 0: ctx.str });
560 T::regs().cr().write_value(Cr { 0: ctx.cr });
561 T::regs().cr().modify(|w| w.set_init(true));
562 let mut i = 0;
563 while i < NUM_CONTEXT_REGS {
564 T::regs().csr(i).write_value(ctx.csr[i]);
565 i += 1;
566 }
567 }
568} 576}
569 577
570trait SealedInstance { 578trait SealedInstance {
@@ -573,7 +581,7 @@ trait SealedInstance {
573 581
574/// HASH instance trait. 582/// HASH instance trait.
575#[allow(private_bounds)] 583#[allow(private_bounds)]
576pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 584pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
577 /// Interrupt for this HASH instance. 585 /// Interrupt for this HASH instance.
578 type Interrupt: interrupt::typelevel::Interrupt; 586 type Interrupt: interrupt::typelevel::Interrupt;
579} 587}
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs
index d9b7c16fb..1d0594125 100644
--- a/embassy-stm32/src/hrtim/mod.rs
+++ b/embassy-stm32/src/hrtim/mod.rs
@@ -4,12 +4,12 @@ mod traits;
4 4
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::Peri;
8pub use traits::Instance; 8pub use traits::Instance;
9 9
10use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 10use crate::gpio::{AfType, AnyPin, OutputType, Speed};
11use crate::rcc;
11use crate::time::Hertz; 12use crate::time::Hertz;
12use crate::{rcc, Peripheral};
13 13
14/// HRTIM burst controller instance. 14/// HRTIM burst controller instance.
15pub struct BurstController<T: Instance> { 15pub struct BurstController<T: Instance> {
@@ -62,13 +62,13 @@ pub trait AdvancedChannel<T: Instance>: SealedAdvancedChannel<T> {}
62 62
63/// HRTIM PWM pin. 63/// HRTIM PWM pin.
64pub struct PwmPin<'d, T, C> { 64pub struct PwmPin<'d, T, C> {
65 _pin: PeripheralRef<'d, AnyPin>, 65 _pin: Peri<'d, AnyPin>,
66 phantom: PhantomData<(T, C)>, 66 phantom: PhantomData<(T, C)>,
67} 67}
68 68
69/// HRTIM complementary PWM pin. 69/// HRTIM complementary PWM pin.
70pub struct ComplementaryPwmPin<'d, T, C> { 70pub struct ComplementaryPwmPin<'d, T, C> {
71 _pin: PeripheralRef<'d, AnyPin>, 71 _pin: Peri<'d, AnyPin>,
72 phantom: PhantomData<(T, C)>, 72 phantom: PhantomData<(T, C)>,
73} 73}
74 74
@@ -76,8 +76,7 @@ macro_rules! advanced_channel_impl {
76 ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => { 76 ($new_chx:ident, $channel:tt, $ch_num:expr, $pin_trait:ident, $complementary_pin_trait:ident) => {
77 impl<'d, T: Instance> PwmPin<'d, T, $channel<T>> { 77 impl<'d, T: Instance> PwmPin<'d, T, $channel<T>> {
78 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 78 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
79 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { 79 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
80 into_ref!(pin);
81 critical_section::with(|_| { 80 critical_section::with(|_| {
82 pin.set_low(); 81 pin.set_low();
83 pin.set_as_af( 82 pin.set_as_af(
@@ -86,7 +85,7 @@ macro_rules! advanced_channel_impl {
86 ); 85 );
87 }); 86 });
88 PwmPin { 87 PwmPin {
89 _pin: pin.map_into(), 88 _pin: pin.into(),
90 phantom: PhantomData, 89 phantom: PhantomData,
91 } 90 }
92 } 91 }
@@ -94,8 +93,7 @@ macro_rules! advanced_channel_impl {
94 93
95 impl<'d, T: Instance> ComplementaryPwmPin<'d, T, $channel<T>> { 94 impl<'d, T: Instance> ComplementaryPwmPin<'d, T, $channel<T>> {
96 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] 95 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")]
97 pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<T>> + 'd) -> Self { 96 pub fn $new_chx(pin: Peri<'d, impl $complementary_pin_trait<T>>) -> Self {
98 into_ref!(pin);
99 critical_section::with(|_| { 97 critical_section::with(|_| {
100 pin.set_low(); 98 pin.set_low();
101 pin.set_as_af( 99 pin.set_as_af(
@@ -104,7 +102,7 @@ macro_rules! advanced_channel_impl {
104 ); 102 );
105 }); 103 });
106 ComplementaryPwmPin { 104 ComplementaryPwmPin {
107 _pin: pin.map_into(), 105 _pin: pin.into(),
108 phantom: PhantomData, 106 phantom: PhantomData,
109 } 107 }
110 } 108 }
@@ -129,7 +127,7 @@ advanced_channel_impl!(new_chf, ChF, 5, ChannelFPin, ChannelFComplementaryPin);
129 127
130/// Struct used to divide a high resolution timer into multiple channels 128/// Struct used to divide a high resolution timer into multiple channels
131pub struct AdvancedPwm<'d, T: Instance> { 129pub struct AdvancedPwm<'d, T: Instance> {
132 _inner: PeripheralRef<'d, T>, 130 _inner: Peri<'d, T>,
133 /// Master instance. 131 /// Master instance.
134 pub master: Master<T>, 132 pub master: Master<T>,
135 /// Burst controller. 133 /// Burst controller.
@@ -154,7 +152,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
154 /// 152 ///
155 /// This splits the HRTIM into its constituent parts, which you can then use individually. 153 /// This splits the HRTIM into its constituent parts, which you can then use individually.
156 pub fn new( 154 pub fn new(
157 tim: impl Peripheral<P = T> + 'd, 155 tim: Peri<'d, T>,
158 _cha: Option<PwmPin<'d, T, ChA<T>>>, 156 _cha: Option<PwmPin<'d, T, ChA<T>>>,
159 _chan: Option<ComplementaryPwmPin<'d, T, ChA<T>>>, 157 _chan: Option<ComplementaryPwmPin<'d, T, ChA<T>>>,
160 _chb: Option<PwmPin<'d, T, ChB<T>>>, 158 _chb: Option<PwmPin<'d, T, ChB<T>>>,
@@ -171,9 +169,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
171 Self::new_inner(tim) 169 Self::new_inner(tim)
172 } 170 }
173 171
174 fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { 172 fn new_inner(tim: Peri<'d, T>) -> Self {
175 into_ref!(tim);
176
177 rcc::enable_and_reset::<T>(); 173 rcc::enable_and_reset::<T>();
178 174
179 #[cfg(stm32f334)] 175 #[cfg(stm32f334)]
diff --git a/embassy-stm32/src/hrtim/traits.rs b/embassy-stm32/src/hrtim/traits.rs
index 75f9971e2..6c0661146 100644
--- a/embassy-stm32/src/hrtim/traits.rs
+++ b/embassy-stm32/src/hrtim/traits.rs
@@ -1,3 +1,5 @@
1use embassy_hal_internal::PeripheralType;
2
1use crate::rcc::RccPeripheral; 3use crate::rcc::RccPeripheral;
2use crate::time::Hertz; 4use crate::time::Hertz;
3 5
@@ -153,7 +155,7 @@ pub(crate) trait SealedInstance: RccPeripheral {
153 155
154/// HRTIM instance trait. 156/// HRTIM instance trait.
155#[allow(private_bounds)] 157#[allow(private_bounds)]
156pub trait Instance: SealedInstance + 'static {} 158pub trait Instance: SealedInstance + PeripheralType + 'static {}
157 159
158foreach_interrupt! { 160foreach_interrupt! {
159 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => { 161 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
diff --git a/embassy-stm32/src/hsem/mod.rs b/embassy-stm32/src/hsem/mod.rs
index 06ab7a9bc..31527bcdb 100644
--- a/embassy-stm32/src/hsem/mod.rs
+++ b/embassy-stm32/src/hsem/mod.rs
@@ -1,13 +1,14 @@
1//! Hardware Semaphore (HSEM) 1//! Hardware Semaphore (HSEM)
2 2
3use embassy_hal_internal::PeripheralType;
4
5use crate::pac;
6use crate::rcc::RccPeripheral;
3// TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs. 7// TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs.
4// Those MCUs have a different HSEM implementation (Secure semaphore lock support, 8// Those MCUs have a different HSEM implementation (Secure semaphore lock support,
5// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute), 9// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute),
6// which is not yet supported by this code. 10// which is not yet supported by this code.
7use embassy_hal_internal::{into_ref, PeripheralRef}; 11use crate::Peri;
8
9use crate::rcc::RccPeripheral;
10use crate::{pac, Peripheral};
11 12
12/// HSEM error. 13/// HSEM error.
13#[derive(Debug)] 14#[derive(Debug)]
@@ -73,13 +74,12 @@ fn core_id_to_index(core: CoreId) -> usize {
73 74
74/// HSEM driver 75/// HSEM driver
75pub struct HardwareSemaphore<'d, T: Instance> { 76pub struct HardwareSemaphore<'d, T: Instance> {
76 _peri: PeripheralRef<'d, T>, 77 _peri: Peri<'d, T>,
77} 78}
78 79
79impl<'d, T: Instance> HardwareSemaphore<'d, T> { 80impl<'d, T: Instance> HardwareSemaphore<'d, T> {
80 /// Creates a new HardwareSemaphore instance. 81 /// Creates a new HardwareSemaphore instance.
81 pub fn new(peripheral: impl Peripheral<P = T> + 'd) -> Self { 82 pub fn new(peripheral: Peri<'d, T>) -> Self {
82 into_ref!(peripheral);
83 HardwareSemaphore { _peri: peripheral } 83 HardwareSemaphore { _peri: peripheral }
84 } 84 }
85 85
@@ -177,7 +177,7 @@ trait SealedInstance {
177 177
178/// HSEM instance trait. 178/// HSEM instance trait.
179#[allow(private_bounds)] 179#[allow(private_bounds)]
180pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {} 180pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + Send + 'static {}
181 181
182impl SealedInstance for crate::peripherals::HSEM { 182impl SealedInstance for crate::peripherals::HSEM {
183 fn regs() -> crate::pac::hsem::Hsem { 183 fn regs() -> crate::pac::hsem::Hsem {
diff --git a/embassy-stm32/src/hspi/mod.rs b/embassy-stm32/src/hspi/mod.rs
index 54b442481..62bc0e979 100644
--- a/embassy-stm32/src/hspi/mod.rs
+++ b/embassy-stm32/src/hspi/mod.rs
@@ -13,15 +13,15 @@ pub mod enums;
13use core::marker::PhantomData; 13use core::marker::PhantomData;
14 14
15use embassy_embedded_hal::{GetConfig, SetConfig}; 15use embassy_embedded_hal::{GetConfig, SetConfig};
16use embassy_hal_internal::{into_ref, PeripheralRef}; 16use embassy_hal_internal::{Peri, PeripheralType};
17pub use enums::*; 17pub use enums::*;
18 18
19use crate::dma::{word, ChannelAndRequest}; 19use crate::dma::{word, ChannelAndRequest};
20use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 20use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
21use crate::mode::{Async, Blocking, Mode as PeriMode}; 21use crate::mode::{Async, Blocking, Mode as PeriMode};
22use crate::pac::hspi::Hspi as Regs; 22use crate::pac::hspi::Hspi as Regs;
23use crate::peripherals;
23use crate::rcc::{self, RccPeripheral}; 24use crate::rcc::{self, RccPeripheral};
24use crate::{peripherals, Peripheral};
25 25
26/// HSPI driver config. 26/// HSPI driver config.
27#[derive(Clone, Copy)] 27#[derive(Clone, Copy)]
@@ -163,27 +163,27 @@ pub enum HspiError {
163 163
164/// HSPI driver. 164/// HSPI driver.
165pub struct Hspi<'d, T: Instance, M: PeriMode> { 165pub struct Hspi<'d, T: Instance, M: PeriMode> {
166 _peri: PeripheralRef<'d, T>, 166 _peri: Peri<'d, T>,
167 sck: Option<PeripheralRef<'d, AnyPin>>, 167 sck: Option<Peri<'d, AnyPin>>,
168 d0: Option<PeripheralRef<'d, AnyPin>>, 168 d0: Option<Peri<'d, AnyPin>>,
169 d1: Option<PeripheralRef<'d, AnyPin>>, 169 d1: Option<Peri<'d, AnyPin>>,
170 d2: Option<PeripheralRef<'d, AnyPin>>, 170 d2: Option<Peri<'d, AnyPin>>,
171 d3: Option<PeripheralRef<'d, AnyPin>>, 171 d3: Option<Peri<'d, AnyPin>>,
172 d4: Option<PeripheralRef<'d, AnyPin>>, 172 d4: Option<Peri<'d, AnyPin>>,
173 d5: Option<PeripheralRef<'d, AnyPin>>, 173 d5: Option<Peri<'d, AnyPin>>,
174 d6: Option<PeripheralRef<'d, AnyPin>>, 174 d6: Option<Peri<'d, AnyPin>>,
175 d7: Option<PeripheralRef<'d, AnyPin>>, 175 d7: Option<Peri<'d, AnyPin>>,
176 d8: Option<PeripheralRef<'d, AnyPin>>, 176 d8: Option<Peri<'d, AnyPin>>,
177 d9: Option<PeripheralRef<'d, AnyPin>>, 177 d9: Option<Peri<'d, AnyPin>>,
178 d10: Option<PeripheralRef<'d, AnyPin>>, 178 d10: Option<Peri<'d, AnyPin>>,
179 d11: Option<PeripheralRef<'d, AnyPin>>, 179 d11: Option<Peri<'d, AnyPin>>,
180 d12: Option<PeripheralRef<'d, AnyPin>>, 180 d12: Option<Peri<'d, AnyPin>>,
181 d13: Option<PeripheralRef<'d, AnyPin>>, 181 d13: Option<Peri<'d, AnyPin>>,
182 d14: Option<PeripheralRef<'d, AnyPin>>, 182 d14: Option<Peri<'d, AnyPin>>,
183 d15: Option<PeripheralRef<'d, AnyPin>>, 183 d15: Option<Peri<'d, AnyPin>>,
184 nss: Option<PeripheralRef<'d, AnyPin>>, 184 nss: Option<Peri<'d, AnyPin>>,
185 dqs0: Option<PeripheralRef<'d, AnyPin>>, 185 dqs0: Option<Peri<'d, AnyPin>>,
186 dqs1: Option<PeripheralRef<'d, AnyPin>>, 186 dqs1: Option<Peri<'d, AnyPin>>,
187 dma: Option<ChannelAndRequest<'d>>, 187 dma: Option<ChannelAndRequest<'d>>,
188 _phantom: PhantomData<M>, 188 _phantom: PhantomData<M>,
189 config: Config, 189 config: Config,
@@ -247,34 +247,32 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> {
247 } 247 }
248 248
249 fn new_inner( 249 fn new_inner(
250 peri: impl Peripheral<P = T> + 'd, 250 peri: Peri<'d, T>,
251 d0: Option<PeripheralRef<'d, AnyPin>>, 251 d0: Option<Peri<'d, AnyPin>>,
252 d1: Option<PeripheralRef<'d, AnyPin>>, 252 d1: Option<Peri<'d, AnyPin>>,
253 d2: Option<PeripheralRef<'d, AnyPin>>, 253 d2: Option<Peri<'d, AnyPin>>,
254 d3: Option<PeripheralRef<'d, AnyPin>>, 254 d3: Option<Peri<'d, AnyPin>>,
255 d4: Option<PeripheralRef<'d, AnyPin>>, 255 d4: Option<Peri<'d, AnyPin>>,
256 d5: Option<PeripheralRef<'d, AnyPin>>, 256 d5: Option<Peri<'d, AnyPin>>,
257 d6: Option<PeripheralRef<'d, AnyPin>>, 257 d6: Option<Peri<'d, AnyPin>>,
258 d7: Option<PeripheralRef<'d, AnyPin>>, 258 d7: Option<Peri<'d, AnyPin>>,
259 d8: Option<PeripheralRef<'d, AnyPin>>, 259 d8: Option<Peri<'d, AnyPin>>,
260 d9: Option<PeripheralRef<'d, AnyPin>>, 260 d9: Option<Peri<'d, AnyPin>>,
261 d10: Option<PeripheralRef<'d, AnyPin>>, 261 d10: Option<Peri<'d, AnyPin>>,
262 d11: Option<PeripheralRef<'d, AnyPin>>, 262 d11: Option<Peri<'d, AnyPin>>,
263 d12: Option<PeripheralRef<'d, AnyPin>>, 263 d12: Option<Peri<'d, AnyPin>>,
264 d13: Option<PeripheralRef<'d, AnyPin>>, 264 d13: Option<Peri<'d, AnyPin>>,
265 d14: Option<PeripheralRef<'d, AnyPin>>, 265 d14: Option<Peri<'d, AnyPin>>,
266 d15: Option<PeripheralRef<'d, AnyPin>>, 266 d15: Option<Peri<'d, AnyPin>>,
267 sck: Option<PeripheralRef<'d, AnyPin>>, 267 sck: Option<Peri<'d, AnyPin>>,
268 nss: Option<PeripheralRef<'d, AnyPin>>, 268 nss: Option<Peri<'d, AnyPin>>,
269 dqs0: Option<PeripheralRef<'d, AnyPin>>, 269 dqs0: Option<Peri<'d, AnyPin>>,
270 dqs1: Option<PeripheralRef<'d, AnyPin>>, 270 dqs1: Option<Peri<'d, AnyPin>>,
271 dma: Option<ChannelAndRequest<'d>>, 271 dma: Option<ChannelAndRequest<'d>>,
272 config: Config, 272 config: Config,
273 width: HspiWidth, 273 width: HspiWidth,
274 dual_memory_mode: bool, 274 dual_memory_mode: bool,
275 ) -> Self { 275 ) -> Self {
276 into_ref!(peri);
277
278 // System configuration 276 // System configuration
279 rcc::enable_and_reset::<T>(); 277 rcc::enable_and_reset::<T>();
280 278
@@ -579,11 +577,11 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> {
579impl<'d, T: Instance> Hspi<'d, T, Blocking> { 577impl<'d, T: Instance> Hspi<'d, T, Blocking> {
580 /// Create new blocking HSPI driver for single spi external chip 578 /// Create new blocking HSPI driver for single spi external chip
581 pub fn new_blocking_singlespi( 579 pub fn new_blocking_singlespi(
582 peri: impl Peripheral<P = T> + 'd, 580 peri: Peri<'d, T>,
583 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 581 sck: Peri<'d, impl SckPin<T>>,
584 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 582 d0: Peri<'d, impl D0Pin<T>>,
585 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 583 d1: Peri<'d, impl D1Pin<T>>,
586 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 584 nss: Peri<'d, impl NSSPin<T>>,
587 config: Config, 585 config: Config,
588 ) -> Self { 586 ) -> Self {
589 Self::new_inner( 587 Self::new_inner(
@@ -620,18 +618,18 @@ impl<'d, T: Instance> Hspi<'d, T, Blocking> {
620 618
621 /// Create new blocking HSPI driver for octospi external chip 619 /// Create new blocking HSPI driver for octospi external chip
622 pub fn new_blocking_octospi( 620 pub fn new_blocking_octospi(
623 peri: impl Peripheral<P = T> + 'd, 621 peri: Peri<'d, T>,
624 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 622 sck: Peri<'d, impl SckPin<T>>,
625 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 623 d0: Peri<'d, impl D0Pin<T>>,
626 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 624 d1: Peri<'d, impl D1Pin<T>>,
627 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 625 d2: Peri<'d, impl D2Pin<T>>,
628 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 626 d3: Peri<'d, impl D3Pin<T>>,
629 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 627 d4: Peri<'d, impl D4Pin<T>>,
630 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 628 d5: Peri<'d, impl D5Pin<T>>,
631 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 629 d6: Peri<'d, impl D6Pin<T>>,
632 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 630 d7: Peri<'d, impl D7Pin<T>>,
633 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 631 nss: Peri<'d, impl NSSPin<T>>,
634 dqs0: impl Peripheral<P = impl DQS0Pin<T>> + 'd, 632 dqs0: Peri<'d, impl DQS0Pin<T>>,
635 config: Config, 633 config: Config,
636 ) -> Self { 634 ) -> Self {
637 Self::new_inner( 635 Self::new_inner(
@@ -670,12 +668,12 @@ impl<'d, T: Instance> Hspi<'d, T, Blocking> {
670impl<'d, T: Instance> Hspi<'d, T, Async> { 668impl<'d, T: Instance> Hspi<'d, T, Async> {
671 /// Create new HSPI driver for a single spi external chip 669 /// Create new HSPI driver for a single spi external chip
672 pub fn new_singlespi( 670 pub fn new_singlespi(
673 peri: impl Peripheral<P = T> + 'd, 671 peri: Peri<'d, T>,
674 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 672 sck: Peri<'d, impl SckPin<T>>,
675 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 673 d0: Peri<'d, impl D0Pin<T>>,
676 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 674 d1: Peri<'d, impl D1Pin<T>>,
677 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 675 nss: Peri<'d, impl NSSPin<T>>,
678 dma: impl Peripheral<P = impl HspiDma<T>> + 'd, 676 dma: Peri<'d, impl HspiDma<T>>,
679 config: Config, 677 config: Config,
680 ) -> Self { 678 ) -> Self {
681 Self::new_inner( 679 Self::new_inner(
@@ -712,19 +710,19 @@ impl<'d, T: Instance> Hspi<'d, T, Async> {
712 710
713 /// Create new HSPI driver for octospi external chip 711 /// Create new HSPI driver for octospi external chip
714 pub fn new_octospi( 712 pub fn new_octospi(
715 peri: impl Peripheral<P = T> + 'd, 713 peri: Peri<'d, T>,
716 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 714 sck: Peri<'d, impl SckPin<T>>,
717 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 715 d0: Peri<'d, impl D0Pin<T>>,
718 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 716 d1: Peri<'d, impl D1Pin<T>>,
719 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 717 d2: Peri<'d, impl D2Pin<T>>,
720 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 718 d3: Peri<'d, impl D3Pin<T>>,
721 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 719 d4: Peri<'d, impl D4Pin<T>>,
722 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 720 d5: Peri<'d, impl D5Pin<T>>,
723 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 721 d6: Peri<'d, impl D6Pin<T>>,
724 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 722 d7: Peri<'d, impl D7Pin<T>>,
725 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 723 nss: Peri<'d, impl NSSPin<T>>,
726 dqs0: impl Peripheral<P = impl DQS0Pin<T>> + 'd, 724 dqs0: Peri<'d, impl DQS0Pin<T>>,
727 dma: impl Peripheral<P = impl HspiDma<T>> + 'd, 725 dma: Peri<'d, impl HspiDma<T>>,
728 config: Config, 726 config: Config,
729 ) -> Self { 727 ) -> Self {
730 Self::new_inner( 728 Self::new_inner(
@@ -943,7 +941,7 @@ pub(crate) trait SealedInstance {
943 941
944/// HSPI instance trait. 942/// HSPI instance trait.
945#[allow(private_bounds)] 943#[allow(private_bounds)]
946pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 944pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {}
947 945
948pin_trait!(SckPin, Instance); 946pin_trait!(SckPin, Instance);
949pin_trait!(NckPin, Instance); 947pin_trait!(NckPin, Instance);
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 3a9954663..1689fdb84 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -9,7 +9,7 @@ use core::future::Future;
9use core::iter; 9use core::iter;
10use core::marker::PhantomData; 10use core::marker::PhantomData;
11 11
12use embassy_hal_internal::{Peripheral, PeripheralRef}; 12use embassy_hal_internal::Peri;
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
@@ -131,8 +131,8 @@ pub struct I2c<'d, M: Mode> {
131 info: &'static Info, 131 info: &'static Info,
132 state: &'static State, 132 state: &'static State,
133 kernel_clock: Hertz, 133 kernel_clock: Hertz,
134 scl: Option<PeripheralRef<'d, AnyPin>>, 134 scl: Option<Peri<'d, AnyPin>>,
135 sda: Option<PeripheralRef<'d, AnyPin>>, 135 sda: Option<Peri<'d, AnyPin>>,
136 tx_dma: Option<ChannelAndRequest<'d>>, 136 tx_dma: Option<ChannelAndRequest<'d>>,
137 rx_dma: Option<ChannelAndRequest<'d>>, 137 rx_dma: Option<ChannelAndRequest<'d>>,
138 #[cfg(feature = "time")] 138 #[cfg(feature = "time")]
@@ -143,14 +143,14 @@ pub struct I2c<'d, M: Mode> {
143impl<'d> I2c<'d, Async> { 143impl<'d> I2c<'d, Async> {
144 /// Create a new I2C driver. 144 /// Create a new I2C driver.
145 pub fn new<T: Instance>( 145 pub fn new<T: Instance>(
146 peri: impl Peripheral<P = T> + 'd, 146 peri: Peri<'d, T>,
147 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 147 scl: Peri<'d, impl SclPin<T>>,
148 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 148 sda: Peri<'d, impl SdaPin<T>>,
149 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>> 149 _irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
150 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>> 150 + interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
151 + 'd, 151 + 'd,
152 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 152 tx_dma: Peri<'d, impl TxDma<T>>,
153 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 153 rx_dma: Peri<'d, impl RxDma<T>>,
154 freq: Hertz, 154 freq: Hertz,
155 config: Config, 155 config: Config,
156 ) -> Self { 156 ) -> Self {
@@ -169,9 +169,9 @@ impl<'d> I2c<'d, Async> {
169impl<'d> I2c<'d, Blocking> { 169impl<'d> I2c<'d, Blocking> {
170 /// Create a new blocking I2C driver. 170 /// Create a new blocking I2C driver.
171 pub fn new_blocking<T: Instance>( 171 pub fn new_blocking<T: Instance>(
172 peri: impl Peripheral<P = T> + 'd, 172 peri: Peri<'d, T>,
173 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 173 scl: Peri<'d, impl SclPin<T>>,
174 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 174 sda: Peri<'d, impl SdaPin<T>>,
175 freq: Hertz, 175 freq: Hertz,
176 config: Config, 176 config: Config,
177 ) -> Self { 177 ) -> Self {
@@ -190,9 +190,9 @@ impl<'d> I2c<'d, Blocking> {
190impl<'d, M: Mode> I2c<'d, M> { 190impl<'d, M: Mode> I2c<'d, M> {
191 /// Create a new I2C driver. 191 /// Create a new I2C driver.
192 fn new_inner<T: Instance>( 192 fn new_inner<T: Instance>(
193 _peri: impl Peripheral<P = T> + 'd, 193 _peri: Peri<'d, T>,
194 scl: Option<PeripheralRef<'d, AnyPin>>, 194 scl: Option<Peri<'d, AnyPin>>,
195 sda: Option<PeripheralRef<'d, AnyPin>>, 195 sda: Option<Peri<'d, AnyPin>>,
196 tx_dma: Option<ChannelAndRequest<'d>>, 196 tx_dma: Option<ChannelAndRequest<'d>>,
197 rx_dma: Option<ChannelAndRequest<'d>>, 197 rx_dma: Option<ChannelAndRequest<'d>>,
198 freq: Hertz, 198 freq: Hertz,
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 71769bbc1..1f53a995d 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -855,7 +855,12 @@ impl<'d, M: Mode> SetConfig for I2c<'d, M> {
855 type Config = Hertz; 855 type Config = Hertz;
856 type ConfigError = (); 856 type ConfigError = ();
857 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 857 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
858 self.info.regs.cr1().modify(|reg| {
859 reg.set_pe(false);
860 });
861
858 let timings = Timings::new(self.kernel_clock, *config); 862 let timings = Timings::new(self.kernel_clock, *config);
863
859 self.info.regs.timingr().write(|reg| { 864 self.info.regs.timingr().write(|reg| {
860 reg.set_presc(timings.prescale); 865 reg.set_presc(timings.prescale);
861 reg.set_scll(timings.scll); 866 reg.set_scll(timings.scll);
@@ -864,6 +869,10 @@ impl<'d, M: Mode> SetConfig for I2c<'d, M> {
864 reg.set_scldel(timings.scldel); 869 reg.set_scldel(timings.scldel);
865 }); 870 });
866 871
872 self.info.regs.cr1().modify(|reg| {
873 reg.set_pe(true);
874 });
875
867 Ok(()) 876 Ok(())
868 } 877 }
869} 878}
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs
index ce166d718..5005a5cdb 100644
--- a/embassy-stm32/src/i2s.rs
+++ b/embassy-stm32/src/i2s.rs
@@ -1,7 +1,6 @@
1//! Inter-IC Sound (I2S) 1//! Inter-IC Sound (I2S)
2 2
3use embassy_futures::join::join; 3use embassy_futures::join::join;
4use embassy_hal_internal::into_ref;
5use stm32_metapac::spi::vals; 4use stm32_metapac::spi::vals;
6 5
7use crate::dma::{ringbuffer, ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer}; 6use crate::dma::{ringbuffer, ChannelAndRequest, ReadableRingBuffer, TransferOptions, WritableRingBuffer};
@@ -9,7 +8,7 @@ use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
9use crate::mode::Async; 8use crate::mode::Async;
10use crate::spi::{Config as SpiConfig, RegsExt as _, *}; 9use crate::spi::{Config as SpiConfig, RegsExt as _, *};
11use crate::time::Hertz; 10use crate::time::Hertz;
12use crate::{Peripheral, PeripheralRef}; 11use crate::Peri;
13 12
14/// I2S mode 13/// I2S mode
15#[derive(Copy, Clone)] 14#[derive(Copy, Clone)]
@@ -225,11 +224,11 @@ pub struct I2S<'d, W: Word> {
225 #[allow(dead_code)] 224 #[allow(dead_code)]
226 mode: Mode, 225 mode: Mode,
227 spi: Spi<'d, Async>, 226 spi: Spi<'d, Async>,
228 txsd: Option<PeripheralRef<'d, AnyPin>>, 227 txsd: Option<Peri<'d, AnyPin>>,
229 rxsd: Option<PeripheralRef<'d, AnyPin>>, 228 rxsd: Option<Peri<'d, AnyPin>>,
230 ws: Option<PeripheralRef<'d, AnyPin>>, 229 ws: Option<Peri<'d, AnyPin>>,
231 ck: Option<PeripheralRef<'d, AnyPin>>, 230 ck: Option<Peri<'d, AnyPin>>,
232 mck: Option<PeripheralRef<'d, AnyPin>>, 231 mck: Option<Peri<'d, AnyPin>>,
233 tx_ring_buffer: Option<WritableRingBuffer<'d, W>>, 232 tx_ring_buffer: Option<WritableRingBuffer<'d, W>>,
234 rx_ring_buffer: Option<ReadableRingBuffer<'d, W>>, 233 rx_ring_buffer: Option<ReadableRingBuffer<'d, W>>,
235} 234}
@@ -237,12 +236,12 @@ pub struct I2S<'d, W: Word> {
237impl<'d, W: Word> I2S<'d, W> { 236impl<'d, W: Word> I2S<'d, W> {
238 /// Create a transmitter driver. 237 /// Create a transmitter driver.
239 pub fn new_txonly<T: Instance>( 238 pub fn new_txonly<T: Instance>(
240 peri: impl Peripheral<P = T> + 'd, 239 peri: Peri<'d, T>,
241 sd: impl Peripheral<P = impl MosiPin<T>> + 'd, 240 sd: Peri<'d, impl MosiPin<T>>,
242 ws: impl Peripheral<P = impl WsPin<T>> + 'd, 241 ws: Peri<'d, impl WsPin<T>>,
243 ck: impl Peripheral<P = impl CkPin<T>> + 'd, 242 ck: Peri<'d, impl CkPin<T>>,
244 mck: impl Peripheral<P = impl MckPin<T>> + 'd, 243 mck: Peri<'d, impl MckPin<T>>,
245 txdma: impl Peripheral<P = impl TxDma<T>> + 'd, 244 txdma: Peri<'d, impl TxDma<T>>,
246 txdma_buf: &'d mut [W], 245 txdma_buf: &'d mut [W],
247 freq: Hertz, 246 freq: Hertz,
248 config: Config, 247 config: Config,
@@ -264,11 +263,11 @@ impl<'d, W: Word> I2S<'d, W> {
264 263
265 /// Create a transmitter driver without a master clock pin. 264 /// Create a transmitter driver without a master clock pin.
266 pub fn new_txonly_nomck<T: Instance>( 265 pub fn new_txonly_nomck<T: Instance>(
267 peri: impl Peripheral<P = T> + 'd, 266 peri: Peri<'d, T>,
268 sd: impl Peripheral<P = impl MosiPin<T>> + 'd, 267 sd: Peri<'d, impl MosiPin<T>>,
269 ws: impl Peripheral<P = impl WsPin<T>> + 'd, 268 ws: Peri<'d, impl WsPin<T>>,
270 ck: impl Peripheral<P = impl CkPin<T>> + 'd, 269 ck: Peri<'d, impl CkPin<T>>,
271 txdma: impl Peripheral<P = impl TxDma<T>> + 'd, 270 txdma: Peri<'d, impl TxDma<T>>,
272 txdma_buf: &'d mut [W], 271 txdma_buf: &'d mut [W],
273 freq: Hertz, 272 freq: Hertz,
274 config: Config, 273 config: Config,
@@ -290,12 +289,12 @@ impl<'d, W: Word> I2S<'d, W> {
290 289
291 /// Create a receiver driver. 290 /// Create a receiver driver.
292 pub fn new_rxonly<T: Instance>( 291 pub fn new_rxonly<T: Instance>(
293 peri: impl Peripheral<P = T> + 'd, 292 peri: Peri<'d, T>,
294 sd: impl Peripheral<P = impl MisoPin<T>> + 'd, 293 sd: Peri<'d, impl MisoPin<T>>,
295 ws: impl Peripheral<P = impl WsPin<T>> + 'd, 294 ws: Peri<'d, impl WsPin<T>>,
296 ck: impl Peripheral<P = impl CkPin<T>> + 'd, 295 ck: Peri<'d, impl CkPin<T>>,
297 mck: impl Peripheral<P = impl MckPin<T>> + 'd, 296 mck: Peri<'d, impl MckPin<T>>,
298 rxdma: impl Peripheral<P = impl RxDma<T>> + 'd, 297 rxdma: Peri<'d, impl RxDma<T>>,
299 rxdma_buf: &'d mut [W], 298 rxdma_buf: &'d mut [W],
300 freq: Hertz, 299 freq: Hertz,
301 config: Config, 300 config: Config,
@@ -318,15 +317,15 @@ impl<'d, W: Word> I2S<'d, W> {
318 #[cfg(spi_v3)] 317 #[cfg(spi_v3)]
319 /// Create a full duplex driver. 318 /// Create a full duplex driver.
320 pub fn new_full_duplex<T: Instance>( 319 pub fn new_full_duplex<T: Instance>(
321 peri: impl Peripheral<P = T> + 'd, 320 peri: Peri<'d, T>,
322 txsd: impl Peripheral<P = impl MosiPin<T>> + 'd, 321 txsd: Peri<'d, impl MosiPin<T>>,
323 rxsd: impl Peripheral<P = impl MisoPin<T>> + 'd, 322 rxsd: Peri<'d, impl MisoPin<T>>,
324 ws: impl Peripheral<P = impl WsPin<T>> + 'd, 323 ws: Peri<'d, impl WsPin<T>>,
325 ck: impl Peripheral<P = impl CkPin<T>> + 'd, 324 ck: Peri<'d, impl CkPin<T>>,
326 mck: impl Peripheral<P = impl MckPin<T>> + 'd, 325 mck: Peri<'d, impl MckPin<T>>,
327 txdma: impl Peripheral<P = impl TxDma<T>> + 'd, 326 txdma: Peri<'d, impl TxDma<T>>,
328 txdma_buf: &'d mut [W], 327 txdma_buf: &'d mut [W],
329 rxdma: impl Peripheral<P = impl RxDma<T>> + 'd, 328 rxdma: Peri<'d, impl RxDma<T>>,
330 rxdma_buf: &'d mut [W], 329 rxdma_buf: &'d mut [W],
331 freq: Hertz, 330 freq: Hertz,
332 config: Config, 331 config: Config,
@@ -466,20 +465,18 @@ impl<'d, W: Word> I2S<'d, W> {
466 } 465 }
467 466
468 fn new_inner<T: Instance>( 467 fn new_inner<T: Instance>(
469 peri: impl Peripheral<P = T> + 'd, 468 peri: Peri<'d, T>,
470 txsd: Option<PeripheralRef<'d, AnyPin>>, 469 txsd: Option<Peri<'d, AnyPin>>,
471 rxsd: Option<PeripheralRef<'d, AnyPin>>, 470 rxsd: Option<Peri<'d, AnyPin>>,
472 ws: impl Peripheral<P = impl WsPin<T>> + 'd, 471 ws: Peri<'d, impl WsPin<T>>,
473 ck: impl Peripheral<P = impl CkPin<T>> + 'd, 472 ck: Peri<'d, impl CkPin<T>>,
474 mck: Option<PeripheralRef<'d, AnyPin>>, 473 mck: Option<Peri<'d, AnyPin>>,
475 txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>, 474 txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
476 rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>, 475 rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
477 freq: Hertz, 476 freq: Hertz,
478 config: Config, 477 config: Config,
479 function: Function, 478 function: Function,
480 ) -> Self { 479 ) -> Self {
481 into_ref!(ws, ck);
482
483 ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 480 ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
484 ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 481 ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
485 482
@@ -583,11 +580,11 @@ impl<'d, W: Word> I2S<'d, W> {
583 Self { 580 Self {
584 mode: config.mode, 581 mode: config.mode,
585 spi, 582 spi,
586 txsd: txsd.map(|w| w.map_into()), 583 txsd: txsd.map(|w| w.into()),
587 rxsd: rxsd.map(|w| w.map_into()), 584 rxsd: rxsd.map(|w| w.into()),
588 ws: Some(ws.map_into()), 585 ws: Some(ws.into()),
589 ck: Some(ck.map_into()), 586 ck: Some(ck.into()),
590 mck: mck.map(|w| w.map_into()), 587 mck: mck.map(|w| w.into()),
591 tx_ring_buffer: txdma.map(|(ch, buf)| unsafe { 588 tx_ring_buffer: txdma.map(|(ch, buf)| unsafe {
592 WritableRingBuffer::new(ch.channel, ch.request, regs.tx_ptr(), buf, opts) 589 WritableRingBuffer::new(ch.channel, ch.request, regs.tx_ptr(), buf, opts)
593 }), 590 }),
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index c37908dbc..4d7aac81f 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -211,7 +211,7 @@ macro_rules! bind_interrupts {
211 211
212// Reexports 212// Reexports
213pub use _generated::{peripherals, Peripherals}; 213pub use _generated::{peripherals, Peripherals};
214pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 214pub use embassy_hal_internal::{Peri, PeripheralType};
215#[cfg(feature = "unstable-pac")] 215#[cfg(feature = "unstable-pac")]
216pub use stm32_metapac as pac; 216pub use stm32_metapac as pac;
217#[cfg(not(feature = "unstable-pac"))] 217#[cfg(not(feature = "unstable-pac"))]
diff --git a/embassy-stm32/src/lptim/mod.rs b/embassy-stm32/src/lptim/mod.rs
index 1649cc5b4..e0ddba1c7 100644
--- a/embassy-stm32/src/lptim/mod.rs
+++ b/embassy-stm32/src/lptim/mod.rs
@@ -10,6 +10,7 @@ use crate::rcc::RccPeripheral;
10mod channel; 10mod channel;
11#[cfg(any(lptim_v2a, lptim_v2b))] 11#[cfg(any(lptim_v2a, lptim_v2b))]
12pub use channel::Channel; 12pub use channel::Channel;
13use embassy_hal_internal::PeripheralType;
13 14
14pin_trait!(OutputPin, BasicInstance); 15pin_trait!(OutputPin, BasicInstance);
15pin_trait!(Channel1Pin, BasicInstance); 16pin_trait!(Channel1Pin, BasicInstance);
@@ -22,7 +23,7 @@ pub(crate) trait SealedBasicInstance: RccPeripheral {}
22 23
23/// LPTIM basic instance trait. 24/// LPTIM basic instance trait.
24#[allow(private_bounds)] 25#[allow(private_bounds)]
25pub trait BasicInstance: SealedBasicInstance + 'static {} 26pub trait BasicInstance: PeripheralType + SealedBasicInstance + 'static {}
26 27
27/// LPTIM instance trait. 28/// LPTIM instance trait.
28#[allow(private_bounds)] 29#[allow(private_bounds)]
diff --git a/embassy-stm32/src/lptim/pwm.rs b/embassy-stm32/src/lptim/pwm.rs
index 132f5815e..2f2d7ba01 100644
--- a/embassy-stm32/src/lptim/pwm.rs
+++ b/embassy-stm32/src/lptim/pwm.rs
@@ -2,7 +2,7 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_internal::{into_ref, PeripheralRef}; 5use embassy_hal_internal::Peri;
6 6
7use super::timer::Timer; 7use super::timer::Timer;
8#[cfg(not(any(lptim_v2a, lptim_v2b)))] 8#[cfg(not(any(lptim_v2a, lptim_v2b)))]
@@ -14,7 +14,6 @@ use super::{BasicInstance, Instance};
14use crate::gpio::Pull; 14use crate::gpio::Pull;
15use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 15use crate::gpio::{AfType, AnyPin, OutputType, Speed};
16use crate::time::Hertz; 16use crate::time::Hertz;
17use crate::Peripheral;
18 17
19/// Output marker type. 18/// Output marker type.
20pub enum Output {} 19pub enum Output {}
@@ -27,7 +26,7 @@ pub enum Ch2 {}
27/// 26///
28/// This wraps a pin to make it usable with PWM. 27/// This wraps a pin to make it usable with PWM.
29pub struct PwmPin<'d, T, C> { 28pub struct PwmPin<'d, T, C> {
30 _pin: PeripheralRef<'d, AnyPin>, 29 _pin: Peri<'d, AnyPin>,
31 phantom: PhantomData<(T, C)>, 30 phantom: PhantomData<(T, C)>,
32} 31}
33 32
@@ -48,8 +47,7 @@ macro_rules! channel_impl {
48 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { 47 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => {
49 impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> { 48 impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> {
50 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 49 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
51 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { 50 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
52 into_ref!(pin);
53 critical_section::with(|_| { 51 critical_section::with(|_| {
54 pin.set_low(); 52 pin.set_low();
55 pin.set_as_af( 53 pin.set_as_af(
@@ -58,16 +56,12 @@ macro_rules! channel_impl {
58 ); 56 );
59 }); 57 });
60 PwmPin { 58 PwmPin {
61 _pin: pin.map_into(), 59 _pin: pin.into(),
62 phantom: PhantomData, 60 phantom: PhantomData,
63 } 61 }
64 } 62 }
65 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] 63 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")]
66 pub fn $new_chx_with_config( 64 pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T>>, pin_config: PwmPinConfig) -> Self {
67 pin: impl Peripheral<P = impl $pin_trait<T>> + 'd,
68 pin_config: PwmPinConfig,
69 ) -> Self {
70 into_ref!(pin);
71 critical_section::with(|_| { 65 critical_section::with(|_| {
72 pin.set_low(); 66 pin.set_low();
73 pin.set_as_af( 67 pin.set_as_af(
@@ -79,7 +73,7 @@ macro_rules! channel_impl {
79 ); 73 );
80 }); 74 });
81 PwmPin { 75 PwmPin {
82 _pin: pin.map_into(), 76 _pin: pin.into(),
83 phantom: PhantomData, 77 phantom: PhantomData,
84 } 78 }
85 } 79 }
@@ -102,7 +96,7 @@ pub struct Pwm<'d, T: Instance> {
102#[cfg(not(any(lptim_v2a, lptim_v2b)))] 96#[cfg(not(any(lptim_v2a, lptim_v2b)))]
103impl<'d, T: Instance> Pwm<'d, T> { 97impl<'d, T: Instance> Pwm<'d, T> {
104 /// Create a new PWM driver. 98 /// Create a new PWM driver.
105 pub fn new(tim: impl Peripheral<P = T> + 'd, _output_pin: PwmPin<'d, T, Output>, freq: Hertz) -> Self { 99 pub fn new(tim: Peri<'d, T>, _output_pin: PwmPin<'d, T, Output>, freq: Hertz) -> Self {
106 Self::new_inner(tim, freq) 100 Self::new_inner(tim, freq)
107 } 101 }
108 102
@@ -128,7 +122,7 @@ impl<'d, T: Instance> Pwm<'d, T> {
128impl<'d, T: Instance> Pwm<'d, T> { 122impl<'d, T: Instance> Pwm<'d, T> {
129 /// Create a new PWM driver. 123 /// Create a new PWM driver.
130 pub fn new( 124 pub fn new(
131 tim: impl Peripheral<P = T> + 'd, 125 tim: Peri<'d, T>,
132 _ch1_pin: Option<PwmPin<'d, T, Ch1>>, 126 _ch1_pin: Option<PwmPin<'d, T, Ch1>>,
133 _ch2_pin: Option<PwmPin<'d, T, Ch2>>, 127 _ch2_pin: Option<PwmPin<'d, T, Ch2>>,
134 freq: Hertz, 128 freq: Hertz,
@@ -174,7 +168,7 @@ impl<'d, T: Instance> Pwm<'d, T> {
174} 168}
175 169
176impl<'d, T: Instance> Pwm<'d, T> { 170impl<'d, T: Instance> Pwm<'d, T> {
177 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self { 171 fn new_inner(tim: Peri<'d, T>, freq: Hertz) -> Self {
178 let mut this = Self { inner: Timer::new(tim) }; 172 let mut this = Self { inner: Timer::new(tim) };
179 173
180 this.inner.enable(); 174 this.inner.enable();
diff --git a/embassy-stm32/src/lptim/timer/mod.rs b/embassy-stm32/src/lptim/timer/mod.rs
index e62fcab49..a629be62b 100644
--- a/embassy-stm32/src/lptim/timer/mod.rs
+++ b/embassy-stm32/src/lptim/timer/mod.rs
@@ -1,7 +1,7 @@
1//! Low-level timer driver. 1//! Low-level timer driver.
2mod prescaler; 2mod prescaler;
3 3
4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 4use embassy_hal_internal::Peri;
5 5
6#[cfg(any(lptim_v2a, lptim_v2b))] 6#[cfg(any(lptim_v2a, lptim_v2b))]
7use super::channel::Channel; 7use super::channel::Channel;
@@ -17,14 +17,12 @@ use crate::time::Hertz;
17 17
18/// Low-level timer driver. 18/// Low-level timer driver.
19pub struct Timer<'d, T: Instance> { 19pub struct Timer<'d, T: Instance> {
20 _tim: PeripheralRef<'d, T>, 20 _tim: Peri<'d, T>,
21} 21}
22 22
23impl<'d, T: Instance> Timer<'d, T> { 23impl<'d, T: Instance> Timer<'d, T> {
24 /// Create a new timer driver. 24 /// Create a new timer driver.
25 pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self { 25 pub fn new(tim: Peri<'d, T>) -> Self {
26 into_ref!(tim);
27
28 rcc::enable_and_reset::<T>(); 26 rcc::enable_and_reset::<T>();
29 27
30 Self { _tim: tim } 28 Self { _tim: tim }
diff --git a/embassy-stm32/src/ltdc.rs b/embassy-stm32/src/ltdc.rs
index 16210b7dc..0f6ef569c 100644
--- a/embassy-stm32/src/ltdc.rs
+++ b/embassy-stm32/src/ltdc.rs
@@ -6,7 +6,7 @@ use core::future::poll_fn;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::PeripheralType;
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use stm32_metapac::ltdc::regs::Dccr; 11use stm32_metapac::ltdc::regs::Dccr;
12use stm32_metapac::ltdc::vals::{Bf1, Bf2, Cfuif, Clif, Crrif, Cterrif, Pf, Vbr}; 12use stm32_metapac::ltdc::vals::{Bf1, Bf2, Cfuif, Clif, Crrif, Cterrif, Pf, Vbr};
@@ -14,7 +14,7 @@ use stm32_metapac::ltdc::vals::{Bf1, Bf2, Cfuif, Clif, Crrif, Cterrif, Pf, Vbr};
14use crate::gpio::{AfType, OutputType, Speed}; 14use crate::gpio::{AfType, OutputType, Speed};
15use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
16use crate::interrupt::{self}; 16use crate::interrupt::{self};
17use crate::{peripherals, rcc, Peripheral}; 17use crate::{peripherals, rcc, Peri};
18 18
19static LTDC_WAKER: AtomicWaker = AtomicWaker::new(); 19static LTDC_WAKER: AtomicWaker = AtomicWaker::new();
20 20
@@ -83,7 +83,7 @@ pub enum PolarityActive {
83 83
84/// LTDC driver. 84/// LTDC driver.
85pub struct Ltdc<'d, T: Instance> { 85pub struct Ltdc<'d, T: Instance> {
86 _peri: PeripheralRef<'d, T>, 86 _peri: Peri<'d, T>,
87} 87}
88 88
89/// LTDC interrupt handler. 89/// LTDC interrupt handler.
@@ -178,47 +178,45 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
178impl<'d, T: Instance> Ltdc<'d, T> { 178impl<'d, T: Instance> Ltdc<'d, T> {
179 // Create a new LTDC driver without specifying color and control pins. This is typically used if you want to drive a display though a DsiHost 179 // Create a new LTDC driver without specifying color and control pins. This is typically used if you want to drive a display though a DsiHost
180 /// Note: Full-Duplex modes are not supported at this time 180 /// Note: Full-Duplex modes are not supported at this time
181 pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self { 181 pub fn new(peri: Peri<'d, T>) -> Self {
182 Self::setup_clocks(); 182 Self::setup_clocks();
183 into_ref!(peri);
184 Self { _peri: peri } 183 Self { _peri: peri }
185 } 184 }
186 185
187 /// Create a new LTDC driver. 8 pins per color channel for blue, green and red 186 /// Create a new LTDC driver. 8 pins per color channel for blue, green and red
188 #[allow(clippy::too_many_arguments)] 187 #[allow(clippy::too_many_arguments)]
189 pub fn new_with_pins( 188 pub fn new_with_pins(
190 peri: impl Peripheral<P = T> + 'd, 189 peri: Peri<'d, T>,
191 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 190 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
192 clk: impl Peripheral<P = impl ClkPin<T>> + 'd, 191 clk: Peri<'d, impl ClkPin<T>>,
193 hsync: impl Peripheral<P = impl HsyncPin<T>> + 'd, 192 hsync: Peri<'d, impl HsyncPin<T>>,
194 vsync: impl Peripheral<P = impl VsyncPin<T>> + 'd, 193 vsync: Peri<'d, impl VsyncPin<T>>,
195 b0: impl Peripheral<P = impl B0Pin<T>> + 'd, 194 b0: Peri<'d, impl B0Pin<T>>,
196 b1: impl Peripheral<P = impl B1Pin<T>> + 'd, 195 b1: Peri<'d, impl B1Pin<T>>,
197 b2: impl Peripheral<P = impl B2Pin<T>> + 'd, 196 b2: Peri<'d, impl B2Pin<T>>,
198 b3: impl Peripheral<P = impl B3Pin<T>> + 'd, 197 b3: Peri<'d, impl B3Pin<T>>,
199 b4: impl Peripheral<P = impl B4Pin<T>> + 'd, 198 b4: Peri<'d, impl B4Pin<T>>,
200 b5: impl Peripheral<P = impl B5Pin<T>> + 'd, 199 b5: Peri<'d, impl B5Pin<T>>,
201 b6: impl Peripheral<P = impl B6Pin<T>> + 'd, 200 b6: Peri<'d, impl B6Pin<T>>,
202 b7: impl Peripheral<P = impl B7Pin<T>> + 'd, 201 b7: Peri<'d, impl B7Pin<T>>,
203 g0: impl Peripheral<P = impl G0Pin<T>> + 'd, 202 g0: Peri<'d, impl G0Pin<T>>,
204 g1: impl Peripheral<P = impl G1Pin<T>> + 'd, 203 g1: Peri<'d, impl G1Pin<T>>,
205 g2: impl Peripheral<P = impl G2Pin<T>> + 'd, 204 g2: Peri<'d, impl G2Pin<T>>,
206 g3: impl Peripheral<P = impl G3Pin<T>> + 'd, 205 g3: Peri<'d, impl G3Pin<T>>,
207 g4: impl Peripheral<P = impl G4Pin<T>> + 'd, 206 g4: Peri<'d, impl G4Pin<T>>,
208 g5: impl Peripheral<P = impl G5Pin<T>> + 'd, 207 g5: Peri<'d, impl G5Pin<T>>,
209 g6: impl Peripheral<P = impl G6Pin<T>> + 'd, 208 g6: Peri<'d, impl G6Pin<T>>,
210 g7: impl Peripheral<P = impl G7Pin<T>> + 'd, 209 g7: Peri<'d, impl G7Pin<T>>,
211 r0: impl Peripheral<P = impl R0Pin<T>> + 'd, 210 r0: Peri<'d, impl R0Pin<T>>,
212 r1: impl Peripheral<P = impl R1Pin<T>> + 'd, 211 r1: Peri<'d, impl R1Pin<T>>,
213 r2: impl Peripheral<P = impl R2Pin<T>> + 'd, 212 r2: Peri<'d, impl R2Pin<T>>,
214 r3: impl Peripheral<P = impl R3Pin<T>> + 'd, 213 r3: Peri<'d, impl R3Pin<T>>,
215 r4: impl Peripheral<P = impl R4Pin<T>> + 'd, 214 r4: Peri<'d, impl R4Pin<T>>,
216 r5: impl Peripheral<P = impl R5Pin<T>> + 'd, 215 r5: Peri<'d, impl R5Pin<T>>,
217 r6: impl Peripheral<P = impl R6Pin<T>> + 'd, 216 r6: Peri<'d, impl R6Pin<T>>,
218 r7: impl Peripheral<P = impl R7Pin<T>> + 'd, 217 r7: Peri<'d, impl R7Pin<T>>,
219 ) -> Self { 218 ) -> Self {
220 Self::setup_clocks(); 219 Self::setup_clocks();
221 into_ref!(peri);
222 new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh)); 220 new_pin!(clk, AfType::output(OutputType::PushPull, Speed::VeryHigh));
223 new_pin!(hsync, AfType::output(OutputType::PushPull, Speed::VeryHigh)); 221 new_pin!(hsync, AfType::output(OutputType::PushPull, Speed::VeryHigh));
224 new_pin!(vsync, AfType::output(OutputType::PushPull, Speed::VeryHigh)); 222 new_pin!(vsync, AfType::output(OutputType::PushPull, Speed::VeryHigh));
@@ -529,7 +527,7 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral {
529 527
530/// LTDC instance trait. 528/// LTDC instance trait.
531#[allow(private_bounds)] 529#[allow(private_bounds)]
532pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 530pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
533 /// Interrupt for this LTDC instance. 531 /// Interrupt for this LTDC instance.
534 type Interrupt: interrupt::typelevel::Interrupt; 532 type Interrupt: interrupt::typelevel::Interrupt;
535} 533}
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs
index ae53deb08..2c181a254 100644
--- a/embassy-stm32/src/macros.rs
+++ b/embassy-stm32/src/macros.rs
@@ -14,7 +14,7 @@ macro_rules! peri_trait {
14 14
15 /// Peripheral instance trait. 15 /// Peripheral instance trait.
16 #[allow(private_bounds)] 16 #[allow(private_bounds)]
17 pub trait Instance: crate::Peripheral<P = Self> + SealedInstance + crate::rcc::RccPeripheral { 17 pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
18 $($( 18 $($(
19 /// Interrupt for this peripheral. 19 /// Interrupt for this peripheral.
20 type $irq: crate::interrupt::typelevel::Interrupt; 20 type $irq: crate::interrupt::typelevel::Interrupt;
@@ -85,12 +85,24 @@ macro_rules! dma_trait_impl {
85 }; 85 };
86} 86}
87 87
88#[allow(unused)]
89macro_rules! new_dma_nonopt {
90 ($name:ident) => {{
91 let dma = $name;
92 let request = dma.request();
93 crate::dma::ChannelAndRequest {
94 channel: dma.into(),
95 request,
96 }
97 }};
98}
99
88macro_rules! new_dma { 100macro_rules! new_dma {
89 ($name:ident) => {{ 101 ($name:ident) => {{
90 let dma = $name.into_ref(); 102 let dma = $name;
91 let request = dma.request(); 103 let request = dma.request();
92 Some(crate::dma::ChannelAndRequest { 104 Some(crate::dma::ChannelAndRequest {
93 channel: dma.map_into(), 105 channel: dma.into(),
94 request, 106 request,
95 }) 107 })
96 }}; 108 }};
@@ -98,8 +110,8 @@ macro_rules! new_dma {
98 110
99macro_rules! new_pin { 111macro_rules! new_pin {
100 ($name:ident, $af_type:expr) => {{ 112 ($name:ident, $af_type:expr) => {{
101 let pin = $name.into_ref(); 113 let pin = $name;
102 pin.set_as_af(pin.af_num(), $af_type); 114 pin.set_as_af(pin.af_num(), $af_type);
103 Some(pin.map_into()) 115 Some(pin.into())
104 }}; 116 }};
105} 117}
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index c7610f4b5..a81493c1b 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -1,10 +1,10 @@
1//! Operational Amplifier (OPAMP) 1//! Operational Amplifier (OPAMP)
2#![macro_use] 2#![macro_use]
3 3
4use embassy_hal_internal::{into_ref, PeripheralRef}; 4use embassy_hal_internal::PeripheralType;
5 5
6use crate::pac::opamp::vals::*; 6use crate::pac::opamp::vals::*;
7use crate::Peripheral; 7use crate::Peri;
8 8
9/// Gain 9/// Gain
10#[allow(missing_docs)] 10#[allow(missing_docs)]
@@ -52,16 +52,14 @@ pub struct OpAmpInternalOutput<'d, T: Instance> {
52 52
53/// OpAmp driver. 53/// OpAmp driver.
54pub struct OpAmp<'d, T: Instance> { 54pub struct OpAmp<'d, T: Instance> {
55 _inner: PeripheralRef<'d, T>, 55 _inner: Peri<'d, T>,
56} 56}
57 57
58impl<'d, T: Instance> OpAmp<'d, T> { 58impl<'d, T: Instance> OpAmp<'d, T> {
59 /// Create a new driver instance. 59 /// Create a new driver instance.
60 /// 60 ///
61 /// Does not enable the opamp, but does set the speed mode on some families. 61 /// Does not enable the opamp, but does set the speed mode on some families.
62 pub fn new(opamp: impl Peripheral<P = T> + 'd, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { 62 pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self {
63 into_ref!(opamp);
64
65 #[cfg(opamp_g4)] 63 #[cfg(opamp_g4)]
66 T::regs().csr().modify(|w| { 64 T::regs().csr().modify(|w| {
67 w.set_opahsm(speed.into()); 65 w.set_opahsm(speed.into());
@@ -82,12 +80,10 @@ impl<'d, T: Instance> OpAmp<'d, T> {
82 /// [`OpAmpOutput`] is dropped. 80 /// [`OpAmpOutput`] is dropped.
83 pub fn buffer_ext( 81 pub fn buffer_ext(
84 &mut self, 82 &mut self,
85 in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>, 83 in_pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>,
86 out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin>, 84 out_pin: Peri<'_, impl OutputPin<T> + crate::gpio::Pin>,
87 gain: OpAmpGain, 85 gain: OpAmpGain,
88 ) -> OpAmpOutput<'_, T> { 86 ) -> OpAmpOutput<'_, T> {
89 into_ref!(in_pin);
90 into_ref!(out_pin);
91 in_pin.set_as_analog(); 87 in_pin.set_as_analog();
92 out_pin.set_as_analog(); 88 out_pin.set_as_analog();
93 89
@@ -119,11 +115,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
119 /// directly used as an ADC input. The opamp will be disabled when the 115 /// directly used as an ADC input. The opamp will be disabled when the
120 /// [`OpAmpOutput`] is dropped. 116 /// [`OpAmpOutput`] is dropped.
121 #[cfg(opamp_g4)] 117 #[cfg(opamp_g4)]
122 pub fn buffer_dac( 118 pub fn buffer_dac(&mut self, out_pin: Peri<'_, impl OutputPin<T> + crate::gpio::Pin>) -> OpAmpOutput<'_, T> {
123 &mut self,
124 out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin>,
125 ) -> OpAmpOutput<'_, T> {
126 into_ref!(out_pin);
127 out_pin.set_as_analog(); 119 out_pin.set_as_analog();
128 120
129 T::regs().csr().modify(|w| { 121 T::regs().csr().modify(|w| {
@@ -149,10 +141,9 @@ impl<'d, T: Instance> OpAmp<'d, T> {
149 #[cfg(opamp_g4)] 141 #[cfg(opamp_g4)]
150 pub fn buffer_int( 142 pub fn buffer_int(
151 &mut self, 143 &mut self,
152 pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>, 144 pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>,
153 gain: OpAmpGain, 145 gain: OpAmpGain,
154 ) -> OpAmpInternalOutput<'_, T> { 146 ) -> OpAmpInternalOutput<'_, T> {
155 into_ref!(pin);
156 pin.set_as_analog(); 147 pin.set_as_analog();
157 148
158 // PGA_GAIN value may have different meaning in different MCU serials, use with caution. 149 // PGA_GAIN value may have different meaning in different MCU serials, use with caution.
@@ -211,7 +202,7 @@ pub(crate) trait SealedOutputPin<T: Instance> {}
211 202
212/// Opamp instance trait. 203/// Opamp instance trait.
213#[allow(private_bounds)] 204#[allow(private_bounds)]
214pub trait Instance: SealedInstance + 'static {} 205pub trait Instance: SealedInstance + PeripheralType + 'static {}
215/// Non-inverting pin trait. 206/// Non-inverting pin trait.
216#[allow(private_bounds)] 207#[allow(private_bounds)]
217pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {} 208pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {}
diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs
index 5dff3c4c3..74edfd5e4 100644
--- a/embassy-stm32/src/ospi/mod.rs
+++ b/embassy-stm32/src/ospi/mod.rs
@@ -8,7 +8,7 @@ pub mod enums;
8use core::marker::PhantomData; 8use core::marker::PhantomData;
9 9
10use embassy_embedded_hal::{GetConfig, SetConfig}; 10use embassy_embedded_hal::{GetConfig, SetConfig};
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::PeripheralType;
12pub use enums::*; 12pub use enums::*;
13use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits}; 13use stm32_metapac::octospi::vals::{PhaseMode, SizeInBits};
14 14
@@ -19,7 +19,7 @@ use crate::pac::octospi::{vals, Octospi as Regs};
19#[cfg(octospim_v1)] 19#[cfg(octospim_v1)]
20use crate::pac::octospim::Octospim; 20use crate::pac::octospim::Octospim;
21use crate::rcc::{self, RccPeripheral}; 21use crate::rcc::{self, RccPeripheral};
22use crate::{peripherals, Peripheral}; 22use crate::{peripherals, Peri};
23 23
24/// OPSI driver config. 24/// OPSI driver config.
25#[derive(Clone, Copy)] 25#[derive(Clone, Copy)]
@@ -160,18 +160,18 @@ pub enum OspiError {
160 160
161/// OSPI driver. 161/// OSPI driver.
162pub struct Ospi<'d, T: Instance, M: PeriMode> { 162pub struct Ospi<'d, T: Instance, M: PeriMode> {
163 _peri: PeripheralRef<'d, T>, 163 _peri: Peri<'d, T>,
164 sck: Option<PeripheralRef<'d, AnyPin>>, 164 sck: Option<Peri<'d, AnyPin>>,
165 d0: Option<PeripheralRef<'d, AnyPin>>, 165 d0: Option<Peri<'d, AnyPin>>,
166 d1: Option<PeripheralRef<'d, AnyPin>>, 166 d1: Option<Peri<'d, AnyPin>>,
167 d2: Option<PeripheralRef<'d, AnyPin>>, 167 d2: Option<Peri<'d, AnyPin>>,
168 d3: Option<PeripheralRef<'d, AnyPin>>, 168 d3: Option<Peri<'d, AnyPin>>,
169 d4: Option<PeripheralRef<'d, AnyPin>>, 169 d4: Option<Peri<'d, AnyPin>>,
170 d5: Option<PeripheralRef<'d, AnyPin>>, 170 d5: Option<Peri<'d, AnyPin>>,
171 d6: Option<PeripheralRef<'d, AnyPin>>, 171 d6: Option<Peri<'d, AnyPin>>,
172 d7: Option<PeripheralRef<'d, AnyPin>>, 172 d7: Option<Peri<'d, AnyPin>>,
173 nss: Option<PeripheralRef<'d, AnyPin>>, 173 nss: Option<Peri<'d, AnyPin>>,
174 dqs: Option<PeripheralRef<'d, AnyPin>>, 174 dqs: Option<Peri<'d, AnyPin>>,
175 dma: Option<ChannelAndRequest<'d>>, 175 dma: Option<ChannelAndRequest<'d>>,
176 _phantom: PhantomData<M>, 176 _phantom: PhantomData<M>,
177 config: Config, 177 config: Config,
@@ -245,25 +245,23 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
245 } 245 }
246 246
247 fn new_inner( 247 fn new_inner(
248 peri: impl Peripheral<P = T> + 'd, 248 peri: Peri<'d, T>,
249 d0: Option<PeripheralRef<'d, AnyPin>>, 249 d0: Option<Peri<'d, AnyPin>>,
250 d1: Option<PeripheralRef<'d, AnyPin>>, 250 d1: Option<Peri<'d, AnyPin>>,
251 d2: Option<PeripheralRef<'d, AnyPin>>, 251 d2: Option<Peri<'d, AnyPin>>,
252 d3: Option<PeripheralRef<'d, AnyPin>>, 252 d3: Option<Peri<'d, AnyPin>>,
253 d4: Option<PeripheralRef<'d, AnyPin>>, 253 d4: Option<Peri<'d, AnyPin>>,
254 d5: Option<PeripheralRef<'d, AnyPin>>, 254 d5: Option<Peri<'d, AnyPin>>,
255 d6: Option<PeripheralRef<'d, AnyPin>>, 255 d6: Option<Peri<'d, AnyPin>>,
256 d7: Option<PeripheralRef<'d, AnyPin>>, 256 d7: Option<Peri<'d, AnyPin>>,
257 sck: Option<PeripheralRef<'d, AnyPin>>, 257 sck: Option<Peri<'d, AnyPin>>,
258 nss: Option<PeripheralRef<'d, AnyPin>>, 258 nss: Option<Peri<'d, AnyPin>>,
259 dqs: Option<PeripheralRef<'d, AnyPin>>, 259 dqs: Option<Peri<'d, AnyPin>>,
260 dma: Option<ChannelAndRequest<'d>>, 260 dma: Option<ChannelAndRequest<'d>>,
261 config: Config, 261 config: Config,
262 width: OspiWidth, 262 width: OspiWidth,
263 dual_quad: bool, 263 dual_quad: bool,
264 ) -> Self { 264 ) -> Self {
265 into_ref!(peri);
266
267 #[cfg(octospim_v1)] 265 #[cfg(octospim_v1)]
268 { 266 {
269 // RCC for octospim should be enabled before writing register 267 // RCC for octospim should be enabled before writing register
@@ -685,11 +683,11 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
685impl<'d, T: Instance> Ospi<'d, T, Blocking> { 683impl<'d, T: Instance> Ospi<'d, T, Blocking> {
686 /// Create new blocking OSPI driver for a single spi external chip 684 /// Create new blocking OSPI driver for a single spi external chip
687 pub fn new_blocking_singlespi( 685 pub fn new_blocking_singlespi(
688 peri: impl Peripheral<P = T> + 'd, 686 peri: Peri<'d, T>,
689 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 687 sck: Peri<'d, impl SckPin<T>>,
690 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 688 d0: Peri<'d, impl D0Pin<T>>,
691 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 689 d1: Peri<'d, impl D1Pin<T>>,
692 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 690 nss: Peri<'d, impl NSSPin<T>>,
693 config: Config, 691 config: Config,
694 ) -> Self { 692 ) -> Self {
695 Self::new_inner( 693 Self::new_inner(
@@ -717,11 +715,11 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
717 715
718 /// Create new blocking OSPI driver for a dualspi external chip 716 /// Create new blocking OSPI driver for a dualspi external chip
719 pub fn new_blocking_dualspi( 717 pub fn new_blocking_dualspi(
720 peri: impl Peripheral<P = T> + 'd, 718 peri: Peri<'d, T>,
721 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 719 sck: Peri<'d, impl SckPin<T>>,
722 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 720 d0: Peri<'d, impl D0Pin<T>>,
723 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 721 d1: Peri<'d, impl D1Pin<T>>,
724 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 722 nss: Peri<'d, impl NSSPin<T>>,
725 config: Config, 723 config: Config,
726 ) -> Self { 724 ) -> Self {
727 Self::new_inner( 725 Self::new_inner(
@@ -749,13 +747,13 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
749 747
750 /// Create new blocking OSPI driver for a quadspi external chip 748 /// Create new blocking OSPI driver for a quadspi external chip
751 pub fn new_blocking_quadspi( 749 pub fn new_blocking_quadspi(
752 peri: impl Peripheral<P = T> + 'd, 750 peri: Peri<'d, T>,
753 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 751 sck: Peri<'d, impl SckPin<T>>,
754 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 752 d0: Peri<'d, impl D0Pin<T>>,
755 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 753 d1: Peri<'d, impl D1Pin<T>>,
756 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 754 d2: Peri<'d, impl D2Pin<T>>,
757 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 755 d3: Peri<'d, impl D3Pin<T>>,
758 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 756 nss: Peri<'d, impl NSSPin<T>>,
759 config: Config, 757 config: Config,
760 ) -> Self { 758 ) -> Self {
761 Self::new_inner( 759 Self::new_inner(
@@ -783,17 +781,17 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
783 781
784 /// Create new blocking OSPI driver for two quadspi external chips 782 /// Create new blocking OSPI driver for two quadspi external chips
785 pub fn new_blocking_dualquadspi( 783 pub fn new_blocking_dualquadspi(
786 peri: impl Peripheral<P = T> + 'd, 784 peri: Peri<'d, T>,
787 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 785 sck: Peri<'d, impl SckPin<T>>,
788 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 786 d0: Peri<'d, impl D0Pin<T>>,
789 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 787 d1: Peri<'d, impl D1Pin<T>>,
790 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 788 d2: Peri<'d, impl D2Pin<T>>,
791 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 789 d3: Peri<'d, impl D3Pin<T>>,
792 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 790 d4: Peri<'d, impl D4Pin<T>>,
793 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 791 d5: Peri<'d, impl D5Pin<T>>,
794 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 792 d6: Peri<'d, impl D6Pin<T>>,
795 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 793 d7: Peri<'d, impl D7Pin<T>>,
796 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 794 nss: Peri<'d, impl NSSPin<T>>,
797 config: Config, 795 config: Config,
798 ) -> Self { 796 ) -> Self {
799 Self::new_inner( 797 Self::new_inner(
@@ -821,17 +819,17 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
821 819
822 /// Create new blocking OSPI driver for octospi external chips 820 /// Create new blocking OSPI driver for octospi external chips
823 pub fn new_blocking_octospi( 821 pub fn new_blocking_octospi(
824 peri: impl Peripheral<P = T> + 'd, 822 peri: Peri<'d, T>,
825 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 823 sck: Peri<'d, impl SckPin<T>>,
826 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 824 d0: Peri<'d, impl D0Pin<T>>,
827 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 825 d1: Peri<'d, impl D1Pin<T>>,
828 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 826 d2: Peri<'d, impl D2Pin<T>>,
829 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 827 d3: Peri<'d, impl D3Pin<T>>,
830 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 828 d4: Peri<'d, impl D4Pin<T>>,
831 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 829 d5: Peri<'d, impl D5Pin<T>>,
832 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 830 d6: Peri<'d, impl D6Pin<T>>,
833 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 831 d7: Peri<'d, impl D7Pin<T>>,
834 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 832 nss: Peri<'d, impl NSSPin<T>>,
835 config: Config, 833 config: Config,
836 ) -> Self { 834 ) -> Self {
837 Self::new_inner( 835 Self::new_inner(
@@ -861,12 +859,12 @@ impl<'d, T: Instance> Ospi<'d, T, Blocking> {
861impl<'d, T: Instance> Ospi<'d, T, Async> { 859impl<'d, T: Instance> Ospi<'d, T, Async> {
862 /// Create new blocking OSPI driver for a single spi external chip 860 /// Create new blocking OSPI driver for a single spi external chip
863 pub fn new_singlespi( 861 pub fn new_singlespi(
864 peri: impl Peripheral<P = T> + 'd, 862 peri: Peri<'d, T>,
865 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 863 sck: Peri<'d, impl SckPin<T>>,
866 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 864 d0: Peri<'d, impl D0Pin<T>>,
867 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 865 d1: Peri<'d, impl D1Pin<T>>,
868 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 866 nss: Peri<'d, impl NSSPin<T>>,
869 dma: impl Peripheral<P = impl OctoDma<T>> + 'd, 867 dma: Peri<'d, impl OctoDma<T>>,
870 config: Config, 868 config: Config,
871 ) -> Self { 869 ) -> Self {
872 Self::new_inner( 870 Self::new_inner(
@@ -894,12 +892,12 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
894 892
895 /// Create new blocking OSPI driver for a dualspi external chip 893 /// Create new blocking OSPI driver for a dualspi external chip
896 pub fn new_dualspi( 894 pub fn new_dualspi(
897 peri: impl Peripheral<P = T> + 'd, 895 peri: Peri<'d, T>,
898 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 896 sck: Peri<'d, impl SckPin<T>>,
899 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 897 d0: Peri<'d, impl D0Pin<T>>,
900 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 898 d1: Peri<'d, impl D1Pin<T>>,
901 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 899 nss: Peri<'d, impl NSSPin<T>>,
902 dma: impl Peripheral<P = impl OctoDma<T>> + 'd, 900 dma: Peri<'d, impl OctoDma<T>>,
903 config: Config, 901 config: Config,
904 ) -> Self { 902 ) -> Self {
905 Self::new_inner( 903 Self::new_inner(
@@ -927,14 +925,14 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
927 925
928 /// Create new blocking OSPI driver for a quadspi external chip 926 /// Create new blocking OSPI driver for a quadspi external chip
929 pub fn new_quadspi( 927 pub fn new_quadspi(
930 peri: impl Peripheral<P = T> + 'd, 928 peri: Peri<'d, T>,
931 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 929 sck: Peri<'d, impl SckPin<T>>,
932 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 930 d0: Peri<'d, impl D0Pin<T>>,
933 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 931 d1: Peri<'d, impl D1Pin<T>>,
934 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 932 d2: Peri<'d, impl D2Pin<T>>,
935 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 933 d3: Peri<'d, impl D3Pin<T>>,
936 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 934 nss: Peri<'d, impl NSSPin<T>>,
937 dma: impl Peripheral<P = impl OctoDma<T>> + 'd, 935 dma: Peri<'d, impl OctoDma<T>>,
938 config: Config, 936 config: Config,
939 ) -> Self { 937 ) -> Self {
940 Self::new_inner( 938 Self::new_inner(
@@ -962,18 +960,18 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
962 960
963 /// Create new blocking OSPI driver for two quadspi external chips 961 /// Create new blocking OSPI driver for two quadspi external chips
964 pub fn new_dualquadspi( 962 pub fn new_dualquadspi(
965 peri: impl Peripheral<P = T> + 'd, 963 peri: Peri<'d, T>,
966 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 964 sck: Peri<'d, impl SckPin<T>>,
967 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 965 d0: Peri<'d, impl D0Pin<T>>,
968 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 966 d1: Peri<'d, impl D1Pin<T>>,
969 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 967 d2: Peri<'d, impl D2Pin<T>>,
970 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 968 d3: Peri<'d, impl D3Pin<T>>,
971 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 969 d4: Peri<'d, impl D4Pin<T>>,
972 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 970 d5: Peri<'d, impl D5Pin<T>>,
973 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 971 d6: Peri<'d, impl D6Pin<T>>,
974 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 972 d7: Peri<'d, impl D7Pin<T>>,
975 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 973 nss: Peri<'d, impl NSSPin<T>>,
976 dma: impl Peripheral<P = impl OctoDma<T>> + 'd, 974 dma: Peri<'d, impl OctoDma<T>>,
977 config: Config, 975 config: Config,
978 ) -> Self { 976 ) -> Self {
979 Self::new_inner( 977 Self::new_inner(
@@ -1001,18 +999,18 @@ impl<'d, T: Instance> Ospi<'d, T, Async> {
1001 999
1002 /// Create new blocking OSPI driver for octospi external chips 1000 /// Create new blocking OSPI driver for octospi external chips
1003 pub fn new_octospi( 1001 pub fn new_octospi(
1004 peri: impl Peripheral<P = T> + 'd, 1002 peri: Peri<'d, T>,
1005 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 1003 sck: Peri<'d, impl SckPin<T>>,
1006 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 1004 d0: Peri<'d, impl D0Pin<T>>,
1007 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 1005 d1: Peri<'d, impl D1Pin<T>>,
1008 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 1006 d2: Peri<'d, impl D2Pin<T>>,
1009 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 1007 d3: Peri<'d, impl D3Pin<T>>,
1010 d4: impl Peripheral<P = impl D4Pin<T>> + 'd, 1008 d4: Peri<'d, impl D4Pin<T>>,
1011 d5: impl Peripheral<P = impl D5Pin<T>> + 'd, 1009 d5: Peri<'d, impl D5Pin<T>>,
1012 d6: impl Peripheral<P = impl D6Pin<T>> + 'd, 1010 d6: Peri<'d, impl D6Pin<T>>,
1013 d7: impl Peripheral<P = impl D7Pin<T>> + 'd, 1011 d7: Peri<'d, impl D7Pin<T>>,
1014 nss: impl Peripheral<P = impl NSSPin<T>> + 'd, 1012 nss: Peri<'d, impl NSSPin<T>>,
1015 dma: impl Peripheral<P = impl OctoDma<T>> + 'd, 1013 dma: Peri<'d, impl OctoDma<T>>,
1016 config: Config, 1014 config: Config,
1017 ) -> Self { 1015 ) -> Self {
1018 Self::new_inner( 1016 Self::new_inner(
@@ -1221,12 +1219,12 @@ pub(crate) trait SealedInstance {
1221/// OSPI instance trait. 1219/// OSPI instance trait.
1222#[cfg(octospim_v1)] 1220#[cfg(octospim_v1)]
1223#[allow(private_bounds)] 1221#[allow(private_bounds)]
1224pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral + SealedOctospimInstance {} 1222pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + SealedOctospimInstance {}
1225 1223
1226/// OSPI instance trait. 1224/// OSPI instance trait.
1227#[cfg(not(octospim_v1))] 1225#[cfg(not(octospim_v1))]
1228#[allow(private_bounds)] 1226#[allow(private_bounds)]
1229pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 1227pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {}
1230 1228
1231pin_trait!(SckPin, Instance); 1229pin_trait!(SckPin, Instance);
1232pin_trait!(NckPin, Instance); 1230pin_trait!(NckPin, Instance);
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index 411e533c9..0df057c53 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -6,7 +6,7 @@ pub mod enums;
6 6
7use core::marker::PhantomData; 7use core::marker::PhantomData;
8 8
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::PeripheralType;
10use enums::*; 10use enums::*;
11 11
12use crate::dma::ChannelAndRequest; 12use crate::dma::ChannelAndRequest;
@@ -14,7 +14,7 @@ use crate::gpio::{AfType, AnyPin, OutputType, Pull, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::quadspi::Quadspi as Regs; 15use crate::pac::quadspi::Quadspi as Regs;
16use crate::rcc::{self, RccPeripheral}; 16use crate::rcc::{self, RccPeripheral};
17use crate::{peripherals, Peripheral}; 17use crate::{peripherals, Peri};
18 18
19/// QSPI transfer configuration. 19/// QSPI transfer configuration.
20pub struct TransferConfig { 20pub struct TransferConfig {
@@ -75,13 +75,13 @@ impl Default for Config {
75/// QSPI driver. 75/// QSPI driver.
76#[allow(dead_code)] 76#[allow(dead_code)]
77pub struct Qspi<'d, T: Instance, M: PeriMode> { 77pub struct Qspi<'d, T: Instance, M: PeriMode> {
78 _peri: PeripheralRef<'d, T>, 78 _peri: Peri<'d, T>,
79 sck: Option<PeripheralRef<'d, AnyPin>>, 79 sck: Option<Peri<'d, AnyPin>>,
80 d0: Option<PeripheralRef<'d, AnyPin>>, 80 d0: Option<Peri<'d, AnyPin>>,
81 d1: Option<PeripheralRef<'d, AnyPin>>, 81 d1: Option<Peri<'d, AnyPin>>,
82 d2: Option<PeripheralRef<'d, AnyPin>>, 82 d2: Option<Peri<'d, AnyPin>>,
83 d3: Option<PeripheralRef<'d, AnyPin>>, 83 d3: Option<Peri<'d, AnyPin>>,
84 nss: Option<PeripheralRef<'d, AnyPin>>, 84 nss: Option<Peri<'d, AnyPin>>,
85 dma: Option<ChannelAndRequest<'d>>, 85 dma: Option<ChannelAndRequest<'d>>,
86 _phantom: PhantomData<M>, 86 _phantom: PhantomData<M>,
87 config: Config, 87 config: Config,
@@ -89,19 +89,17 @@ pub struct Qspi<'d, T: Instance, M: PeriMode> {
89 89
90impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { 90impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> {
91 fn new_inner( 91 fn new_inner(
92 peri: impl Peripheral<P = T> + 'd, 92 peri: Peri<'d, T>,
93 d0: Option<PeripheralRef<'d, AnyPin>>, 93 d0: Option<Peri<'d, AnyPin>>,
94 d1: Option<PeripheralRef<'d, AnyPin>>, 94 d1: Option<Peri<'d, AnyPin>>,
95 d2: Option<PeripheralRef<'d, AnyPin>>, 95 d2: Option<Peri<'d, AnyPin>>,
96 d3: Option<PeripheralRef<'d, AnyPin>>, 96 d3: Option<Peri<'d, AnyPin>>,
97 sck: Option<PeripheralRef<'d, AnyPin>>, 97 sck: Option<Peri<'d, AnyPin>>,
98 nss: Option<PeripheralRef<'d, AnyPin>>, 98 nss: Option<Peri<'d, AnyPin>>,
99 dma: Option<ChannelAndRequest<'d>>, 99 dma: Option<ChannelAndRequest<'d>>,
100 config: Config, 100 config: Config,
101 fsel: FlashSelection, 101 fsel: FlashSelection,
102 ) -> Self { 102 ) -> Self {
103 into_ref!(peri);
104
105 rcc::enable_and_reset::<T>(); 103 rcc::enable_and_reset::<T>();
106 104
107 while T::REGS.sr().read().busy() {} 105 while T::REGS.sr().read().busy() {}
@@ -272,13 +270,13 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> {
272impl<'d, T: Instance> Qspi<'d, T, Blocking> { 270impl<'d, T: Instance> Qspi<'d, T, Blocking> {
273 /// Create a new QSPI driver for bank 1, in blocking mode. 271 /// Create a new QSPI driver for bank 1, in blocking mode.
274 pub fn new_blocking_bank1( 272 pub fn new_blocking_bank1(
275 peri: impl Peripheral<P = T> + 'd, 273 peri: Peri<'d, T>,
276 d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, 274 d0: Peri<'d, impl BK1D0Pin<T>>,
277 d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, 275 d1: Peri<'d, impl BK1D1Pin<T>>,
278 d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, 276 d2: Peri<'d, impl BK1D2Pin<T>>,
279 d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, 277 d3: Peri<'d, impl BK1D3Pin<T>>,
280 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 278 sck: Peri<'d, impl SckPin<T>>,
281 nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, 279 nss: Peri<'d, impl BK1NSSPin<T>>,
282 config: Config, 280 config: Config,
283 ) -> Self { 281 ) -> Self {
284 Self::new_inner( 282 Self::new_inner(
@@ -300,13 +298,13 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> {
300 298
301 /// Create a new QSPI driver for bank 2, in blocking mode. 299 /// Create a new QSPI driver for bank 2, in blocking mode.
302 pub fn new_blocking_bank2( 300 pub fn new_blocking_bank2(
303 peri: impl Peripheral<P = T> + 'd, 301 peri: Peri<'d, T>,
304 d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, 302 d0: Peri<'d, impl BK2D0Pin<T>>,
305 d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, 303 d1: Peri<'d, impl BK2D1Pin<T>>,
306 d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, 304 d2: Peri<'d, impl BK2D2Pin<T>>,
307 d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, 305 d3: Peri<'d, impl BK2D3Pin<T>>,
308 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 306 sck: Peri<'d, impl SckPin<T>>,
309 nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, 307 nss: Peri<'d, impl BK2NSSPin<T>>,
310 config: Config, 308 config: Config,
311 ) -> Self { 309 ) -> Self {
312 Self::new_inner( 310 Self::new_inner(
@@ -330,14 +328,14 @@ impl<'d, T: Instance> Qspi<'d, T, Blocking> {
330impl<'d, T: Instance> Qspi<'d, T, Async> { 328impl<'d, T: Instance> Qspi<'d, T, Async> {
331 /// Create a new QSPI driver for bank 1. 329 /// Create a new QSPI driver for bank 1.
332 pub fn new_bank1( 330 pub fn new_bank1(
333 peri: impl Peripheral<P = T> + 'd, 331 peri: Peri<'d, T>,
334 d0: impl Peripheral<P = impl BK1D0Pin<T>> + 'd, 332 d0: Peri<'d, impl BK1D0Pin<T>>,
335 d1: impl Peripheral<P = impl BK1D1Pin<T>> + 'd, 333 d1: Peri<'d, impl BK1D1Pin<T>>,
336 d2: impl Peripheral<P = impl BK1D2Pin<T>> + 'd, 334 d2: Peri<'d, impl BK1D2Pin<T>>,
337 d3: impl Peripheral<P = impl BK1D3Pin<T>> + 'd, 335 d3: Peri<'d, impl BK1D3Pin<T>>,
338 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 336 sck: Peri<'d, impl SckPin<T>>,
339 nss: impl Peripheral<P = impl BK1NSSPin<T>> + 'd, 337 nss: Peri<'d, impl BK1NSSPin<T>>,
340 dma: impl Peripheral<P = impl QuadDma<T>> + 'd, 338 dma: Peri<'d, impl QuadDma<T>>,
341 config: Config, 339 config: Config,
342 ) -> Self { 340 ) -> Self {
343 Self::new_inner( 341 Self::new_inner(
@@ -359,14 +357,14 @@ impl<'d, T: Instance> Qspi<'d, T, Async> {
359 357
360 /// Create a new QSPI driver for bank 2. 358 /// Create a new QSPI driver for bank 2.
361 pub fn new_bank2( 359 pub fn new_bank2(
362 peri: impl Peripheral<P = T> + 'd, 360 peri: Peri<'d, T>,
363 d0: impl Peripheral<P = impl BK2D0Pin<T>> + 'd, 361 d0: Peri<'d, impl BK2D0Pin<T>>,
364 d1: impl Peripheral<P = impl BK2D1Pin<T>> + 'd, 362 d1: Peri<'d, impl BK2D1Pin<T>>,
365 d2: impl Peripheral<P = impl BK2D2Pin<T>> + 'd, 363 d2: Peri<'d, impl BK2D2Pin<T>>,
366 d3: impl Peripheral<P = impl BK2D3Pin<T>> + 'd, 364 d3: Peri<'d, impl BK2D3Pin<T>>,
367 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 365 sck: Peri<'d, impl SckPin<T>>,
368 nss: impl Peripheral<P = impl BK2NSSPin<T>> + 'd, 366 nss: Peri<'d, impl BK2NSSPin<T>>,
369 dma: impl Peripheral<P = impl QuadDma<T>> + 'd, 367 dma: Peri<'d, impl QuadDma<T>>,
370 config: Config, 368 config: Config,
371 ) -> Self { 369 ) -> Self {
372 Self::new_inner( 370 Self::new_inner(
@@ -465,7 +463,7 @@ trait SealedInstance {
465 463
466/// QSPI instance trait. 464/// QSPI instance trait.
467#[allow(private_bounds)] 465#[allow(private_bounds)]
468pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 466pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {}
469 467
470pin_trait!(SckPin, Instance); 468pin_trait!(SckPin, Instance);
471pin_trait!(BK1D0Pin, Instance); 469pin_trait!(BK1D0Pin, Instance);
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index 04cbe83ed..0b749bcff 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -3,6 +3,7 @@ pub use crate::pac::rcc::vals::{
3 Hpre as AHBPrescaler, Hsidiv as HsiSysDiv, Hsikerdiv as HsiKerDiv, Ppre as APBPrescaler, Sw as Sysclk, 3 Hpre as AHBPrescaler, Hsidiv as HsiSysDiv, Hsikerdiv as HsiKerDiv, Ppre as APBPrescaler, Sw as Sysclk,
4}; 4};
5use crate::pac::{FLASH, RCC}; 5use crate::pac::{FLASH, RCC};
6use crate::rcc::LSI_FREQ;
6use crate::time::Hertz; 7use crate::time::Hertz;
7 8
8/// HSI speed 9/// HSI speed
@@ -121,9 +122,16 @@ pub(crate) unsafe fn init(config: Config) {
121 } 122 }
122 }; 123 };
123 124
125 let rtc = config.ls.init();
126
124 let sys = match config.sys { 127 let sys = match config.sys {
125 Sysclk::HSISYS => unwrap!(hsisys), 128 Sysclk::HSISYS => unwrap!(hsisys),
126 Sysclk::HSE => unwrap!(hse), 129 Sysclk::HSE => unwrap!(hse),
130 Sysclk::LSI => {
131 assert!(config.ls.lsi);
132 LSI_FREQ
133 }
134 Sysclk::LSE => unwrap!(config.ls.lse).frequency,
127 _ => unreachable!(), 135 _ => unreachable!(),
128 }; 136 };
129 137
@@ -162,8 +170,6 @@ pub(crate) unsafe fn init(config: Config) {
162 RCC.cr().modify(|w| w.set_hsion(false)); 170 RCC.cr().modify(|w| w.set_hsion(false));
163 } 171 }
164 172
165 let rtc = config.ls.init();
166
167 config.mux.init(); 173 config.mux.init();
168 174
169 set_clocks!( 175 set_clocks!(
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index f55b18290..2dbf62a9f 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -5,6 +5,7 @@ pub use crate::pac::rcc::vals::{
5 Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk, 5 Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as Sysclk,
6}; 6};
7use crate::pac::{FLASH, PWR, RCC}; 7use crate::pac::{FLASH, PWR, RCC};
8use crate::rcc::LSI_FREQ;
8use crate::time::Hertz; 9use crate::time::Hertz;
9 10
10/// HSI speed 11/// HSI speed
@@ -234,10 +235,17 @@ pub(crate) unsafe fn init(config: Config) {
234 }) 235 })
235 .unwrap_or_default(); 236 .unwrap_or_default();
236 237
238 let rtc = config.ls.init();
239
237 let sys = match config.sys { 240 let sys = match config.sys {
238 Sysclk::HSI => unwrap!(hsisys), 241 Sysclk::HSI => unwrap!(hsisys),
239 Sysclk::HSE => unwrap!(hse), 242 Sysclk::HSE => unwrap!(hse),
240 Sysclk::PLL1_R => unwrap!(pll.pll_r), 243 Sysclk::PLL1_R => unwrap!(pll.pll_r),
244 Sysclk::LSI => {
245 assert!(config.ls.lsi);
246 LSI_FREQ
247 }
248 Sysclk::LSE => unwrap!(config.ls.lse).frequency,
241 _ => unreachable!(), 249 _ => unreachable!(),
242 }; 250 };
243 251
@@ -286,8 +294,6 @@ pub(crate) unsafe fn init(config: Config) {
286 PWR.cr1().modify(|w| w.set_lpr(true)); 294 PWR.cr1().modify(|w| w.set_lpr(true));
287 } 295 }
288 296
289 let rtc = config.ls.init();
290
291 config.mux.init(); 297 config.mux.init();
292 298
293 set_clocks!( 299 set_clocks!(
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs
index d1ce14c86..c50e071fb 100644
--- a/embassy-stm32/src/rcc/mco.rs
+++ b/embassy-stm32/src/rcc/mco.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_internal::into_ref; 3use embassy_hal_internal::PeripheralType;
4 4
5use crate::gpio::{AfType, OutputType, Speed}; 5use crate::gpio::{AfType, OutputType, Speed};
6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))] 6#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
@@ -32,7 +32,7 @@ pub use crate::pac::rcc::vals::Mcosel as McoSource;
32))] 32))]
33pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source}; 33pub use crate::pac::rcc::vals::{Mco1sel as Mco1Source, Mco2sel as Mco2Source};
34use crate::pac::RCC; 34use crate::pac::RCC;
35use crate::{peripherals, Peripheral}; 35use crate::{peripherals, Peri};
36 36
37#[cfg(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37))] 37#[cfg(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37))]
38#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] 38#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
@@ -43,7 +43,7 @@ pub enum McoPrescaler {
43pub(crate) trait SealedMcoInstance {} 43pub(crate) trait SealedMcoInstance {}
44 44
45#[allow(private_bounds)] 45#[allow(private_bounds)]
46pub trait McoInstance: SealedMcoInstance + 'static { 46pub trait McoInstance: PeripheralType + SealedMcoInstance + 'static {
47 type Source; 47 type Source;
48 48
49 #[doc(hidden)] 49 #[doc(hidden)]
@@ -91,14 +91,7 @@ pub struct Mco<'d, T: McoInstance> {
91 91
92impl<'d, T: McoInstance> Mco<'d, T> { 92impl<'d, T: McoInstance> Mco<'d, T> {
93 /// Create a new MCO instance. 93 /// Create a new MCO instance.
94 pub fn new( 94 pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, prescaler: McoPrescaler) -> Self {
95 _peri: impl Peripheral<P = T> + 'd,
96 pin: impl Peripheral<P = impl McoPin<T>> + 'd,
97 source: T::Source,
98 prescaler: McoPrescaler,
99 ) -> Self {
100 into_ref!(pin);
101
102 critical_section::with(|_| unsafe { 95 critical_section::with(|_| unsafe {
103 T::_apply_clock_settings(source, prescaler); 96 T::_apply_clock_settings(source, prescaler);
104 pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 97 pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index b96200e5e..250a08a39 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -5,12 +5,12 @@ use core::future::poll_fn;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::PeripheralType;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::{CryptoRng, RngCore}; 10use rand_core::{CryptoRng, RngCore};
11 11
12use crate::interrupt::typelevel::Interrupt; 12use crate::interrupt::typelevel::Interrupt;
13use crate::{interrupt, pac, peripherals, rcc, Peripheral}; 13use crate::{interrupt, pac, peripherals, rcc, Peri};
14 14
15static RNG_WAKER: AtomicWaker = AtomicWaker::new(); 15static RNG_WAKER: AtomicWaker = AtomicWaker::new();
16 16
@@ -43,17 +43,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
43 43
44/// RNG driver. 44/// RNG driver.
45pub struct Rng<'d, T: Instance> { 45pub struct Rng<'d, T: Instance> {
46 _inner: PeripheralRef<'d, T>, 46 _inner: Peri<'d, T>,
47} 47}
48 48
49impl<'d, T: Instance> Rng<'d, T> { 49impl<'d, T: Instance> Rng<'d, T> {
50 /// Create a new RNG driver. 50 /// Create a new RNG driver.
51 pub fn new( 51 pub fn new(
52 inner: impl Peripheral<P = T> + 'd, 52 inner: Peri<'d, T>,
53 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 53 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
54 ) -> Self { 54 ) -> Self {
55 rcc::enable_and_reset::<T>(); 55 rcc::enable_and_reset::<T>();
56 into_ref!(inner);
57 let mut random = Self { _inner: inner }; 56 let mut random = Self { _inner: inner };
58 random.reset(); 57 random.reset();
59 58
@@ -228,7 +227,7 @@ trait SealedInstance {
228 227
229/// RNG instance trait. 228/// RNG instance trait.
230#[allow(private_bounds)] 229#[allow(private_bounds)]
231pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { 230pub trait Instance: SealedInstance + PeripheralType + crate::rcc::RccPeripheral + 'static + Send {
232 /// Interrupt for this RNG instance. 231 /// Interrupt for this RNG instance.
233 type Interrupt: interrupt::typelevel::Interrupt; 232 type Interrupt: interrupt::typelevel::Interrupt;
234} 233}
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index c2919e2bd..b16c6fdca 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -29,9 +29,9 @@ use crate::time::Hertz;
29mod _version; 29mod _version;
30#[allow(unused_imports)] 30#[allow(unused_imports)]
31pub use _version::*; 31pub use _version::*;
32use embassy_hal_internal::Peripheral;
33 32
34use crate::peripherals::RTC; 33use crate::peripherals::RTC;
34use crate::Peri;
35 35
36/// Errors that can occur on methods on [RtcClock] 36/// Errors that can occur on methods on [RtcClock]
37#[non_exhaustive] 37#[non_exhaustive]
@@ -151,7 +151,7 @@ pub enum RtcCalibrationCyclePeriod {
151 151
152impl Rtc { 152impl Rtc {
153 /// Create a new RTC instance. 153 /// Create a new RTC instance.
154 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 154 pub fn new(_rtc: Peri<'static, RTC>, rtc_config: RtcConfig) -> Self {
155 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] 155 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
156 crate::rcc::enable_and_reset::<RTC>(); 156 crate::rcc::enable_and_reset::<RTC>();
157 157
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 39ed44712..0c9c27797 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -4,7 +4,7 @@
4 4
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::PeripheralType;
8 8
9pub use crate::dma::word; 9pub use crate::dma::word;
10#[cfg(not(gpdma))] 10#[cfg(not(gpdma))]
@@ -12,7 +12,7 @@ use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptio
12use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; 12use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed};
13use crate::pac::sai::{vals, Sai as Regs}; 13use crate::pac::sai::{vals, Sai as Regs};
14use crate::rcc::{self, RccPeripheral}; 14use crate::rcc::{self, RccPeripheral};
15use crate::{peripherals, Peripheral}; 15use crate::{peripherals, Peri};
16 16
17/// SAI error 17/// SAI error
18#[derive(Debug, PartialEq, Eq, Clone, Copy)] 18#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -679,7 +679,7 @@ fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AfType, AfType) {
679 679
680#[cfg(not(gpdma))] 680#[cfg(not(gpdma))]
681fn get_ring_buffer<'d, T: Instance, W: word::Word>( 681fn get_ring_buffer<'d, T: Instance, W: word::Word>(
682 dma: impl Peripheral<P = impl Channel> + 'd, 682 dma: Peri<'d, impl Channel>,
683 dma_buf: &'d mut [W], 683 dma_buf: &'d mut [W],
684 request: Request, 684 request: Request,
685 sub_block: WhichSubBlock, 685 sub_block: WhichSubBlock,
@@ -718,16 +718,15 @@ fn update_synchronous_config(config: &mut Config) {
718} 718}
719 719
720/// SAI subblock instance. 720/// SAI subblock instance.
721pub struct SubBlock<'d, T, S: SubBlockInstance> { 721pub struct SubBlock<'d, T: Instance, S: SubBlockInstance> {
722 peri: PeripheralRef<'d, T>, 722 peri: Peri<'d, T>,
723 _phantom: PhantomData<S>, 723 _phantom: PhantomData<S>,
724} 724}
725 725
726/// Split the main SAIx peripheral into the two subblocks. 726/// Split the main SAIx peripheral into the two subblocks.
727/// 727///
728/// You can then create a [`Sai`] driver for each each half. 728/// You can then create a [`Sai`] driver for each each half.
729pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { 729pub fn split_subblocks<'d, T: Instance>(peri: Peri<'d, T>) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) {
730 into_ref!(peri);
731 rcc::enable_and_reset::<T>(); 730 rcc::enable_and_reset::<T>();
732 731
733 ( 732 (
@@ -744,11 +743,11 @@ pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (S
744 743
745/// SAI sub-block driver. 744/// SAI sub-block driver.
746pub struct Sai<'d, T: Instance, W: word::Word> { 745pub struct Sai<'d, T: Instance, W: word::Word> {
747 _peri: PeripheralRef<'d, T>, 746 _peri: Peri<'d, T>,
748 sd: Option<PeripheralRef<'d, AnyPin>>, 747 sd: Option<Peri<'d, AnyPin>>,
749 fs: Option<PeripheralRef<'d, AnyPin>>, 748 fs: Option<Peri<'d, AnyPin>>,
750 sck: Option<PeripheralRef<'d, AnyPin>>, 749 sck: Option<Peri<'d, AnyPin>>,
751 mclk: Option<PeripheralRef<'d, AnyPin>>, 750 mclk: Option<Peri<'d, AnyPin>>,
752 #[cfg(gpdma)] 751 #[cfg(gpdma)]
753 ring_buffer: PhantomData<W>, 752 ring_buffer: PhantomData<W>,
754 #[cfg(not(gpdma))] 753 #[cfg(not(gpdma))]
@@ -763,16 +762,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
763 /// You can obtain the [`SubBlock`] with [`split_subblocks`]. 762 /// You can obtain the [`SubBlock`] with [`split_subblocks`].
764 pub fn new_asynchronous_with_mclk<S: SubBlockInstance>( 763 pub fn new_asynchronous_with_mclk<S: SubBlockInstance>(
765 peri: SubBlock<'d, T, S>, 764 peri: SubBlock<'d, T, S>,
766 sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, 765 sck: Peri<'d, impl SckPin<T, S>>,
767 sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, 766 sd: Peri<'d, impl SdPin<T, S>>,
768 fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, 767 fs: Peri<'d, impl FsPin<T, S>>,
769 mclk: impl Peripheral<P = impl MclkPin<T, S>> + 'd, 768 mclk: Peri<'d, impl MclkPin<T, S>>,
770 dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, 769 dma: Peri<'d, impl Channel + Dma<T, S>>,
771 dma_buf: &'d mut [W], 770 dma_buf: &'d mut [W],
772 mut config: Config, 771 mut config: Config,
773 ) -> Self { 772 ) -> Self {
774 into_ref!(mclk);
775
776 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); 773 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
777 mclk.set_as_af(mclk.af_num(), ck_af_type); 774 mclk.set_as_af(mclk.af_num(), ck_af_type);
778 775
@@ -788,15 +785,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
788 /// You can obtain the [`SubBlock`] with [`split_subblocks`]. 785 /// You can obtain the [`SubBlock`] with [`split_subblocks`].
789 pub fn new_asynchronous<S: SubBlockInstance>( 786 pub fn new_asynchronous<S: SubBlockInstance>(
790 peri: SubBlock<'d, T, S>, 787 peri: SubBlock<'d, T, S>,
791 sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, 788 sck: Peri<'d, impl SckPin<T, S>>,
792 sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, 789 sd: Peri<'d, impl SdPin<T, S>>,
793 fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, 790 fs: Peri<'d, impl FsPin<T, S>>,
794 dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, 791 dma: Peri<'d, impl Channel + Dma<T, S>>,
795 dma_buf: &'d mut [W], 792 dma_buf: &'d mut [W],
796 config: Config, 793 config: Config,
797 ) -> Self { 794 ) -> Self {
798 let peri = peri.peri; 795 let peri = peri.peri;
799 into_ref!(peri, dma, sck, sd, fs);
800 796
801 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); 797 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
802 sd.set_as_af(sd.af_num(), sd_af_type); 798 sd.set_as_af(sd.af_num(), sd_af_type);
@@ -809,10 +805,10 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
809 Self::new_inner( 805 Self::new_inner(
810 peri, 806 peri,
811 sub_block, 807 sub_block,
812 Some(sck.map_into()), 808 Some(sck.into()),
813 None, 809 None,
814 Some(sd.map_into()), 810 Some(sd.into()),
815 Some(fs.map_into()), 811 Some(fs.into()),
816 get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx), 812 get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx),
817 config, 813 config,
818 ) 814 )
@@ -823,15 +819,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
823 /// You can obtain the [`SubBlock`] with [`split_subblocks`]. 819 /// You can obtain the [`SubBlock`] with [`split_subblocks`].
824 pub fn new_synchronous<S: SubBlockInstance>( 820 pub fn new_synchronous<S: SubBlockInstance>(
825 peri: SubBlock<'d, T, S>, 821 peri: SubBlock<'d, T, S>,
826 sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, 822 sd: Peri<'d, impl SdPin<T, S>>,
827 dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, 823 dma: Peri<'d, impl Channel + Dma<T, S>>,
828 dma_buf: &'d mut [W], 824 dma_buf: &'d mut [W],
829 mut config: Config, 825 mut config: Config,
830 ) -> Self { 826 ) -> Self {
831 update_synchronous_config(&mut config); 827 update_synchronous_config(&mut config);
832 828
833 let peri = peri.peri; 829 let peri = peri.peri;
834 into_ref!(dma, peri, sd);
835 830
836 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); 831 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
837 sd.set_as_af(sd.af_num(), sd_af_type); 832 sd.set_as_af(sd.af_num(), sd_af_type);
@@ -844,7 +839,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
844 sub_block, 839 sub_block,
845 None, 840 None,
846 None, 841 None,
847 Some(sd.map_into()), 842 Some(sd.into()),
848 None, 843 None,
849 get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx), 844 get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx),
850 config, 845 config,
@@ -852,12 +847,12 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
852 } 847 }
853 848
854 fn new_inner( 849 fn new_inner(
855 peri: impl Peripheral<P = T> + 'd, 850 peri: Peri<'d, T>,
856 sub_block: WhichSubBlock, 851 sub_block: WhichSubBlock,
857 sck: Option<PeripheralRef<'d, AnyPin>>, 852 sck: Option<Peri<'d, AnyPin>>,
858 mclk: Option<PeripheralRef<'d, AnyPin>>, 853 mclk: Option<Peri<'d, AnyPin>>,
859 sd: Option<PeripheralRef<'d, AnyPin>>, 854 sd: Option<Peri<'d, AnyPin>>,
860 fs: Option<PeripheralRef<'d, AnyPin>>, 855 fs: Option<Peri<'d, AnyPin>>,
861 ring_buffer: RingBuffer<'d, W>, 856 ring_buffer: RingBuffer<'d, W>,
862 config: Config, 857 config: Config,
863 ) -> Self { 858 ) -> Self {
@@ -947,7 +942,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
947 } 942 }
948 943
949 Self { 944 Self {
950 _peri: peri.into_ref(), 945 _peri: peri,
951 sub_block, 946 sub_block,
952 sck, 947 sck,
953 mclk, 948 mclk,
@@ -1106,7 +1101,7 @@ impl SubBlockInstance for B {}
1106 1101
1107/// SAI instance trait. 1102/// SAI instance trait.
1108#[allow(private_bounds)] 1103#[allow(private_bounds)]
1109pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 1104pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {}
1110 1105
1111pin_trait!(SckPin, Instance, SubBlockInstance); 1106pin_trait!(SckPin, Instance, SubBlockInstance);
1112pin_trait!(FsPin, Instance, SubBlockInstance); 1107pin_trait!(FsPin, Instance, SubBlockInstance);
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index 8af2f8381..8f3c45f50 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -8,11 +8,12 @@ use core::ops::{Deref, DerefMut};
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_hal_internal::drop::OnDrop; 10use embassy_hal_internal::drop::OnDrop;
11use embassy_hal_internal::{into_ref, PeripheralRef}; 11use embassy_hal_internal::{Peri, PeripheralType};
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 13use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
14 14
15use crate::dma::NoDma; 15#[cfg(sdmmc_v1)]
16use crate::dma::ChannelAndRequest;
16#[cfg(gpio_v2)] 17#[cfg(gpio_v2)]
17use crate::gpio::Pull; 18use crate::gpio::Pull;
18use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; 19use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
@@ -20,7 +21,7 @@ use crate::interrupt::typelevel::Interrupt;
20use crate::pac::sdmmc::Sdmmc as RegBlock; 21use crate::pac::sdmmc::Sdmmc as RegBlock;
21use crate::rcc::{self, RccPeripheral}; 22use crate::rcc::{self, RccPeripheral};
22use crate::time::Hertz; 23use crate::time::Hertz;
23use crate::{interrupt, peripherals, Peripheral}; 24use crate::{interrupt, peripherals};
24 25
25/// Interrupt handler. 26/// Interrupt handler.
26pub struct InterruptHandler<T: Instance> { 27pub struct InterruptHandler<T: Instance> {
@@ -301,17 +302,17 @@ impl Default for Config {
301} 302}
302 303
303/// Sdmmc device 304/// Sdmmc device
304pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma<T> = NoDma> { 305pub struct Sdmmc<'d, T: Instance> {
305 _peri: PeripheralRef<'d, T>, 306 _peri: Peri<'d, T>,
306 #[allow(unused)] 307 #[cfg(sdmmc_v1)]
307 dma: PeripheralRef<'d, Dma>, 308 dma: ChannelAndRequest<'d>,
308 309
309 clk: PeripheralRef<'d, AnyPin>, 310 clk: Peri<'d, AnyPin>,
310 cmd: PeripheralRef<'d, AnyPin>, 311 cmd: Peri<'d, AnyPin>,
311 d0: PeripheralRef<'d, AnyPin>, 312 d0: Peri<'d, AnyPin>,
312 d1: Option<PeripheralRef<'d, AnyPin>>, 313 d1: Option<Peri<'d, AnyPin>>,
313 d2: Option<PeripheralRef<'d, AnyPin>>, 314 d2: Option<Peri<'d, AnyPin>>,
314 d3: Option<PeripheralRef<'d, AnyPin>>, 315 d3: Option<Peri<'d, AnyPin>>,
315 316
316 config: Config, 317 config: Config,
317 /// Current clock to card 318 /// Current clock to card
@@ -334,19 +335,17 @@ const CMD_AF: AfType = AfType::output_pull(OutputType::PushPull, Speed::VeryHigh
334const DATA_AF: AfType = CMD_AF; 335const DATA_AF: AfType = CMD_AF;
335 336
336#[cfg(sdmmc_v1)] 337#[cfg(sdmmc_v1)]
337impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { 338impl<'d, T: Instance> Sdmmc<'d, T> {
338 /// Create a new SDMMC driver, with 1 data lane. 339 /// Create a new SDMMC driver, with 1 data lane.
339 pub fn new_1bit( 340 pub fn new_1bit(
340 sdmmc: impl Peripheral<P = T> + 'd, 341 sdmmc: Peri<'d, T>,
341 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 342 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
342 dma: impl Peripheral<P = Dma> + 'd, 343 dma: Peri<'d, impl SdmmcDma<T>>,
343 clk: impl Peripheral<P = impl CkPin<T>> + 'd, 344 clk: Peri<'d, impl CkPin<T>>,
344 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, 345 cmd: Peri<'d, impl CmdPin<T>>,
345 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 346 d0: Peri<'d, impl D0Pin<T>>,
346 config: Config, 347 config: Config,
347 ) -> Self { 348 ) -> Self {
348 into_ref!(clk, cmd, d0);
349
350 critical_section::with(|_| { 349 critical_section::with(|_| {
351 clk.set_as_af(clk.af_num(), CLK_AF); 350 clk.set_as_af(clk.af_num(), CLK_AF);
352 cmd.set_as_af(cmd.af_num(), CMD_AF); 351 cmd.set_as_af(cmd.af_num(), CMD_AF);
@@ -355,10 +354,10 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
355 354
356 Self::new_inner( 355 Self::new_inner(
357 sdmmc, 356 sdmmc,
358 dma, 357 new_dma_nonopt!(dma),
359 clk.map_into(), 358 clk.into(),
360 cmd.map_into(), 359 cmd.into(),
361 d0.map_into(), 360 d0.into(),
362 None, 361 None,
363 None, 362 None,
364 None, 363 None,
@@ -368,19 +367,17 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
368 367
369 /// Create a new SDMMC driver, with 4 data lanes. 368 /// Create a new SDMMC driver, with 4 data lanes.
370 pub fn new_4bit( 369 pub fn new_4bit(
371 sdmmc: impl Peripheral<P = T> + 'd, 370 sdmmc: Peri<'d, T>,
372 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 371 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
373 dma: impl Peripheral<P = Dma> + 'd, 372 dma: Peri<'d, impl SdmmcDma<T>>,
374 clk: impl Peripheral<P = impl CkPin<T>> + 'd, 373 clk: Peri<'d, impl CkPin<T>>,
375 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, 374 cmd: Peri<'d, impl CmdPin<T>>,
376 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 375 d0: Peri<'d, impl D0Pin<T>>,
377 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 376 d1: Peri<'d, impl D1Pin<T>>,
378 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 377 d2: Peri<'d, impl D2Pin<T>>,
379 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 378 d3: Peri<'d, impl D3Pin<T>>,
380 config: Config, 379 config: Config,
381 ) -> Self { 380 ) -> Self {
382 into_ref!(clk, cmd, d0, d1, d2, d3);
383
384 critical_section::with(|_| { 381 critical_section::with(|_| {
385 clk.set_as_af(clk.af_num(), CLK_AF); 382 clk.set_as_af(clk.af_num(), CLK_AF);
386 cmd.set_as_af(cmd.af_num(), CMD_AF); 383 cmd.set_as_af(cmd.af_num(), CMD_AF);
@@ -392,64 +389,50 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
392 389
393 Self::new_inner( 390 Self::new_inner(
394 sdmmc, 391 sdmmc,
395 dma, 392 new_dma_nonopt!(dma),
396 clk.map_into(), 393 clk.into(),
397 cmd.map_into(), 394 cmd.into(),
398 d0.map_into(), 395 d0.into(),
399 Some(d1.map_into()), 396 Some(d1.into()),
400 Some(d2.map_into()), 397 Some(d2.into()),
401 Some(d3.map_into()), 398 Some(d3.into()),
402 config, 399 config,
403 ) 400 )
404 } 401 }
405} 402}
406 403
407#[cfg(sdmmc_v2)] 404#[cfg(sdmmc_v2)]
408impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { 405impl<'d, T: Instance> Sdmmc<'d, T> {
409 /// Create a new SDMMC driver, with 1 data lane. 406 /// Create a new SDMMC driver, with 1 data lane.
410 pub fn new_1bit( 407 pub fn new_1bit(
411 sdmmc: impl Peripheral<P = T> + 'd, 408 sdmmc: Peri<'d, T>,
412 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 409 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
413 clk: impl Peripheral<P = impl CkPin<T>> + 'd, 410 clk: Peri<'d, impl CkPin<T>>,
414 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, 411 cmd: Peri<'d, impl CmdPin<T>>,
415 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 412 d0: Peri<'d, impl D0Pin<T>>,
416 config: Config, 413 config: Config,
417 ) -> Self { 414 ) -> Self {
418 into_ref!(clk, cmd, d0);
419
420 critical_section::with(|_| { 415 critical_section::with(|_| {
421 clk.set_as_af(clk.af_num(), CLK_AF); 416 clk.set_as_af(clk.af_num(), CLK_AF);
422 cmd.set_as_af(cmd.af_num(), CMD_AF); 417 cmd.set_as_af(cmd.af_num(), CMD_AF);
423 d0.set_as_af(d0.af_num(), DATA_AF); 418 d0.set_as_af(d0.af_num(), DATA_AF);
424 }); 419 });
425 420
426 Self::new_inner( 421 Self::new_inner(sdmmc, clk.into(), cmd.into(), d0.into(), None, None, None, config)
427 sdmmc,
428 NoDma.into_ref(),
429 clk.map_into(),
430 cmd.map_into(),
431 d0.map_into(),
432 None,
433 None,
434 None,
435 config,
436 )
437 } 422 }
438 423
439 /// Create a new SDMMC driver, with 4 data lanes. 424 /// Create a new SDMMC driver, with 4 data lanes.
440 pub fn new_4bit( 425 pub fn new_4bit(
441 sdmmc: impl Peripheral<P = T> + 'd, 426 sdmmc: Peri<'d, T>,
442 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 427 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
443 clk: impl Peripheral<P = impl CkPin<T>> + 'd, 428 clk: Peri<'d, impl CkPin<T>>,
444 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, 429 cmd: Peri<'d, impl CmdPin<T>>,
445 d0: impl Peripheral<P = impl D0Pin<T>> + 'd, 430 d0: Peri<'d, impl D0Pin<T>>,
446 d1: impl Peripheral<P = impl D1Pin<T>> + 'd, 431 d1: Peri<'d, impl D1Pin<T>>,
447 d2: impl Peripheral<P = impl D2Pin<T>> + 'd, 432 d2: Peri<'d, impl D2Pin<T>>,
448 d3: impl Peripheral<P = impl D3Pin<T>> + 'd, 433 d3: Peri<'d, impl D3Pin<T>>,
449 config: Config, 434 config: Config,
450 ) -> Self { 435 ) -> Self {
451 into_ref!(clk, cmd, d0, d1, d2, d3);
452
453 critical_section::with(|_| { 436 critical_section::with(|_| {
454 clk.set_as_af(clk.af_num(), CLK_AF); 437 clk.set_as_af(clk.af_num(), CLK_AF);
455 cmd.set_as_af(cmd.af_num(), CMD_AF); 438 cmd.set_as_af(cmd.af_num(), CMD_AF);
@@ -461,32 +444,29 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
461 444
462 Self::new_inner( 445 Self::new_inner(
463 sdmmc, 446 sdmmc,
464 NoDma.into_ref(), 447 clk.into(),
465 clk.map_into(), 448 cmd.into(),
466 cmd.map_into(), 449 d0.into(),
467 d0.map_into(), 450 Some(d1.into()),
468 Some(d1.map_into()), 451 Some(d2.into()),
469 Some(d2.map_into()), 452 Some(d3.into()),
470 Some(d3.map_into()),
471 config, 453 config,
472 ) 454 )
473 } 455 }
474} 456}
475 457
476impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> { 458impl<'d, T: Instance> Sdmmc<'d, T> {
477 fn new_inner( 459 fn new_inner(
478 sdmmc: impl Peripheral<P = T> + 'd, 460 sdmmc: Peri<'d, T>,
479 dma: impl Peripheral<P = Dma> + 'd, 461 #[cfg(sdmmc_v1)] dma: ChannelAndRequest<'d>,
480 clk: PeripheralRef<'d, AnyPin>, 462 clk: Peri<'d, AnyPin>,
481 cmd: PeripheralRef<'d, AnyPin>, 463 cmd: Peri<'d, AnyPin>,
482 d0: PeripheralRef<'d, AnyPin>, 464 d0: Peri<'d, AnyPin>,
483 d1: Option<PeripheralRef<'d, AnyPin>>, 465 d1: Option<Peri<'d, AnyPin>>,
484 d2: Option<PeripheralRef<'d, AnyPin>>, 466 d2: Option<Peri<'d, AnyPin>>,
485 d3: Option<PeripheralRef<'d, AnyPin>>, 467 d3: Option<Peri<'d, AnyPin>>,
486 config: Config, 468 config: Config,
487 ) -> Self { 469 ) -> Self {
488 into_ref!(sdmmc, dma);
489
490 rcc::enable_and_reset::<T>(); 470 rcc::enable_and_reset::<T>();
491 471
492 T::Interrupt::unpend(); 472 T::Interrupt::unpend();
@@ -514,6 +494,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
514 494
515 Self { 495 Self {
516 _peri: sdmmc, 496 _peri: sdmmc,
497 #[cfg(sdmmc_v1)]
517 dma, 498 dma,
518 499
519 clk, 500 clk,
@@ -567,7 +548,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
567 #[allow(unused_variables)] 548 #[allow(unused_variables)]
568 fn prepare_datapath_read<'a>( 549 fn prepare_datapath_read<'a>(
569 config: &Config, 550 config: &Config,
570 dma: &'a mut PeripheralRef<'d, Dma>, 551 #[cfg(sdmmc_v1)] dma: &'a mut ChannelAndRequest<'d>,
571 buffer: &'a mut [u32], 552 buffer: &'a mut [u32],
572 length_bytes: u32, 553 length_bytes: u32,
573 block_size: u8, 554 block_size: u8,
@@ -583,16 +564,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
583 regs.dlenr().write(|w| w.set_datalength(length_bytes)); 564 regs.dlenr().write(|w| w.set_datalength(length_bytes));
584 565
585 #[cfg(sdmmc_v1)] 566 #[cfg(sdmmc_v1)]
586 let transfer = unsafe { 567 let transfer = unsafe { dma.read(regs.fifor().as_ptr() as *mut u32, buffer, DMA_TRANSFER_OPTIONS) };
587 let request = dma.request();
588 Transfer::new_read(
589 dma,
590 request,
591 regs.fifor().as_ptr() as *mut u32,
592 buffer,
593 DMA_TRANSFER_OPTIONS,
594 )
595 };
596 #[cfg(sdmmc_v2)] 568 #[cfg(sdmmc_v2)]
597 let transfer = { 569 let transfer = {
598 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32)); 570 regs.idmabase0r().write(|w| w.set_idmabase0(buffer.as_mut_ptr() as u32));
@@ -632,14 +604,8 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
632 604
633 #[cfg(sdmmc_v1)] 605 #[cfg(sdmmc_v1)]
634 let transfer = unsafe { 606 let transfer = unsafe {
635 let request = self.dma.request(); 607 self.dma
636 Transfer::new_write( 608 .write(buffer, regs.fifor().as_ptr() as *mut u32, DMA_TRANSFER_OPTIONS)
637 &mut self.dma,
638 request,
639 buffer,
640 regs.fifor().as_ptr() as *mut u32,
641 DMA_TRANSFER_OPTIONS,
642 )
643 }; 609 };
644 #[cfg(sdmmc_v2)] 610 #[cfg(sdmmc_v2)]
645 let transfer = { 611 let transfer = {
@@ -735,7 +701,14 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
735 let regs = T::regs(); 701 let regs = T::regs();
736 let on_drop = OnDrop::new(|| Self::on_drop()); 702 let on_drop = OnDrop::new(|| Self::on_drop());
737 703
738 let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, status.as_mut(), 64, 6); 704 let transfer = Self::prepare_datapath_read(
705 &self.config,
706 #[cfg(sdmmc_v1)]
707 &mut self.dma,
708 status.as_mut(),
709 64,
710 6,
711 );
739 InterruptHandler::<T>::data_interrupts(true); 712 InterruptHandler::<T>::data_interrupts(true);
740 Self::cmd(Cmd::cmd6(set_function), true)?; // CMD6 713 Self::cmd(Cmd::cmd6(set_function), true)?; // CMD6
741 714
@@ -821,7 +794,14 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
821 let regs = T::regs(); 794 let regs = T::regs();
822 let on_drop = OnDrop::new(|| Self::on_drop()); 795 let on_drop = OnDrop::new(|| Self::on_drop());
823 796
824 let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, status.as_mut(), 64, 6); 797 let transfer = Self::prepare_datapath_read(
798 &self.config,
799 #[cfg(sdmmc_v1)]
800 &mut self.dma,
801 status.as_mut(),
802 64,
803 6,
804 );
825 InterruptHandler::<T>::data_interrupts(true); 805 InterruptHandler::<T>::data_interrupts(true);
826 Self::cmd(Cmd::card_status(0), true)?; 806 Self::cmd(Cmd::card_status(0), true)?;
827 807
@@ -924,7 +904,14 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
924 let regs = T::regs(); 904 let regs = T::regs();
925 let on_drop = OnDrop::new(|| Self::on_drop()); 905 let on_drop = OnDrop::new(|| Self::on_drop());
926 906
927 let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, scr, 8, 3); 907 let transfer = Self::prepare_datapath_read(
908 &self.config,
909 #[cfg(sdmmc_v1)]
910 &mut self.dma,
911 scr,
912 8,
913 3,
914 );
928 InterruptHandler::<T>::data_interrupts(true); 915 InterruptHandler::<T>::data_interrupts(true);
929 Self::cmd(Cmd::cmd51(), true)?; 916 Self::cmd(Cmd::cmd51(), true)?;
930 917
@@ -1214,7 +1201,14 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
1214 let regs = T::regs(); 1201 let regs = T::regs();
1215 let on_drop = OnDrop::new(|| Self::on_drop()); 1202 let on_drop = OnDrop::new(|| Self::on_drop());
1216 1203
1217 let transfer = Self::prepare_datapath_read(&self.config, &mut self.dma, buffer, 512, 9); 1204 let transfer = Self::prepare_datapath_read(
1205 &self.config,
1206 #[cfg(sdmmc_v1)]
1207 &mut self.dma,
1208 buffer,
1209 512,
1210 9,
1211 );
1218 InterruptHandler::<T>::data_interrupts(true); 1212 InterruptHandler::<T>::data_interrupts(true);
1219 Self::cmd(Cmd::read_single_block(address), true)?; 1213 Self::cmd(Cmd::read_single_block(address), true)?;
1220 1214
@@ -1347,7 +1341,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
1347 } 1341 }
1348} 1342}
1349 1343
1350impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Drop for Sdmmc<'d, T, Dma> { 1344impl<'d, T: Instance> Drop for Sdmmc<'d, T> {
1351 fn drop(&mut self) { 1345 fn drop(&mut self) {
1352 T::Interrupt::disable(); 1346 T::Interrupt::disable();
1353 Self::on_drop(); 1347 Self::on_drop();
@@ -1465,7 +1459,7 @@ trait SealedInstance {
1465 1459
1466/// SDMMC instance trait. 1460/// SDMMC instance trait.
1467#[allow(private_bounds)] 1461#[allow(private_bounds)]
1468pub trait Instance: SealedInstance + RccPeripheral + 'static { 1462pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
1469 /// Interrupt for this instance. 1463 /// Interrupt for this instance.
1470 type Interrupt: interrupt::typelevel::Interrupt; 1464 type Interrupt: interrupt::typelevel::Interrupt;
1471} 1465}
@@ -1484,15 +1478,6 @@ pin_trait!(D7Pin, Instance);
1484#[cfg(sdmmc_v1)] 1478#[cfg(sdmmc_v1)]
1485dma_trait!(SdmmcDma, Instance); 1479dma_trait!(SdmmcDma, Instance);
1486 1480
1487/// DMA instance trait.
1488///
1489/// This is only implemented for `NoDma`, since SDMMCv2 has DMA built-in, instead of
1490/// using ST's system-wide DMA peripheral.
1491#[cfg(sdmmc_v2)]
1492pub trait SdmmcDma<T: Instance> {}
1493#[cfg(sdmmc_v2)]
1494impl<T: Instance> SdmmcDma<T> for NoDma {}
1495
1496foreach_peripheral!( 1481foreach_peripheral!(
1497 (sdmmc, $inst:ident) => { 1482 (sdmmc, $inst:ident) => {
1498 impl SealedInstance for peripherals::$inst { 1483 impl SealedInstance for peripherals::$inst {
@@ -1512,7 +1497,7 @@ foreach_peripheral!(
1512 }; 1497 };
1513); 1498);
1514 1499
1515impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> block_device_driver::BlockDevice<512> for Sdmmc<'d, T, Dma> { 1500impl<'d, T: Instance> block_device_driver::BlockDevice<512> for Sdmmc<'d, T> {
1516 type Error = Error; 1501 type Error = Error;
1517 type Align = aligned::A4; 1502 type Align = aligned::A4;
1518 1503
diff --git a/embassy-stm32/src/spdifrx/mod.rs b/embassy-stm32/src/spdifrx/mod.rs
index a205780ad..08dba04fe 100644
--- a/embassy-stm32/src/spdifrx/mod.rs
+++ b/embassy-stm32/src/spdifrx/mod.rs
@@ -4,7 +4,6 @@
4 4
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
9 8
10use crate::dma::ringbuffer::Error as RingbufferError; 9use crate::dma::ringbuffer::Error as RingbufferError;
@@ -16,7 +15,7 @@ use crate::gpio::{AfType, AnyPin, Pull, SealedPin as _};
16use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
17use crate::pac::spdifrx::Spdifrx as Regs; 16use crate::pac::spdifrx::Spdifrx as Regs;
18use crate::rcc::{RccInfo, SealedRccPeripheral}; 17use crate::rcc::{RccInfo, SealedRccPeripheral};
19use crate::{interrupt, peripherals, Peripheral}; 18use crate::{interrupt, peripherals, Peri};
20 19
21/// Possible S/PDIF preamble types. 20/// Possible S/PDIF preamble types.
22#[allow(dead_code)] 21#[allow(dead_code)]
@@ -36,10 +35,10 @@ enum PreambleType {
36 35
37macro_rules! new_spdifrx_pin { 36macro_rules! new_spdifrx_pin {
38 ($name:ident, $af_type:expr) => {{ 37 ($name:ident, $af_type:expr) => {{
39 let pin = $name.into_ref(); 38 let pin = $name;
40 let input_sel = pin.input_sel(); 39 let input_sel = pin.input_sel();
41 pin.set_as_af(pin.af_num(), $af_type); 40 pin.set_as_af(pin.af_num(), $af_type);
42 (Some(pin.map_into()), input_sel) 41 (Some(pin.into()), input_sel)
43 }}; 42 }};
44} 43}
45 44
@@ -61,8 +60,8 @@ macro_rules! impl_spdifrx_pin {
61/// Data is read by DMAs and stored in a ring buffer. 60/// Data is read by DMAs and stored in a ring buffer.
62#[cfg(not(gpdma))] 61#[cfg(not(gpdma))]
63pub struct Spdifrx<'d, T: Instance> { 62pub struct Spdifrx<'d, T: Instance> {
64 _peri: PeripheralRef<'d, T>, 63 _peri: Peri<'d, T>,
65 spdifrx_in: Option<PeripheralRef<'d, AnyPin>>, 64 spdifrx_in: Option<Peri<'d, AnyPin>>,
66 data_ring_buffer: ReadableRingBuffer<'d, u32>, 65 data_ring_buffer: ReadableRingBuffer<'d, u32>,
67} 66}
68 67
@@ -131,18 +130,16 @@ impl<'d, T: Instance> Spdifrx<'d, T> {
131 130
132 /// Create a new `Spdifrx` instance. 131 /// Create a new `Spdifrx` instance.
133 pub fn new( 132 pub fn new(
134 peri: impl Peripheral<P = T> + 'd, 133 peri: Peri<'d, T>,
135 _irq: impl interrupt::typelevel::Binding<T::GlobalInterrupt, GlobalInterruptHandler<T>> + 'd, 134 _irq: impl interrupt::typelevel::Binding<T::GlobalInterrupt, GlobalInterruptHandler<T>> + 'd,
136 config: Config, 135 config: Config,
137 spdifrx_in: impl Peripheral<P = impl InPin<T>> + 'd, 136 spdifrx_in: Peri<'d, impl InPin<T>>,
138 data_dma: impl Peripheral<P = impl Channel + Dma<T>> + 'd, 137 data_dma: Peri<'d, impl Channel + Dma<T>>,
139 data_dma_buf: &'d mut [u32], 138 data_dma_buf: &'d mut [u32],
140 ) -> Self { 139 ) -> Self {
141 let (spdifrx_in, input_sel) = new_spdifrx_pin!(spdifrx_in, AfType::input(Pull::None)); 140 let (spdifrx_in, input_sel) = new_spdifrx_pin!(spdifrx_in, AfType::input(Pull::None));
142 Self::setup(config, input_sel); 141 Self::setup(config, input_sel);
143 142
144 into_ref!(peri, data_dma);
145
146 let regs = T::info().regs; 143 let regs = T::info().regs;
147 let dr_request = data_dma.request(); 144 let dr_request = data_dma.request();
148 let dr_ring_buffer = 145 let dr_ring_buffer =
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 44dda6a9e..6578aa1aa 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -6,7 +6,6 @@ use core::ptr;
6 6
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
8use embassy_futures::join::join; 8use embassy_futures::join::join;
9use embassy_hal_internal::PeripheralRef;
10pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
11 10
12use crate::dma::{word, ChannelAndRequest}; 11use crate::dma::{word, ChannelAndRequest};
@@ -15,7 +14,7 @@ use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 14use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::{RccInfo, SealedRccPeripheral}; 15use crate::rcc::{RccInfo, SealedRccPeripheral};
17use crate::time::Hertz; 16use crate::time::Hertz;
18use crate::Peripheral; 17use crate::Peri;
19 18
20/// SPI error. 19/// SPI error.
21#[derive(Debug, PartialEq, Eq, Clone, Copy)] 20#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -130,9 +129,9 @@ impl Config {
130pub struct Spi<'d, M: PeriMode> { 129pub struct Spi<'d, M: PeriMode> {
131 pub(crate) info: &'static Info, 130 pub(crate) info: &'static Info,
132 kernel_clock: Hertz, 131 kernel_clock: Hertz,
133 sck: Option<PeripheralRef<'d, AnyPin>>, 132 sck: Option<Peri<'d, AnyPin>>,
134 mosi: Option<PeripheralRef<'d, AnyPin>>, 133 mosi: Option<Peri<'d, AnyPin>>,
135 miso: Option<PeripheralRef<'d, AnyPin>>, 134 miso: Option<Peri<'d, AnyPin>>,
136 tx_dma: Option<ChannelAndRequest<'d>>, 135 tx_dma: Option<ChannelAndRequest<'d>>,
137 rx_dma: Option<ChannelAndRequest<'d>>, 136 rx_dma: Option<ChannelAndRequest<'d>>,
138 _phantom: PhantomData<M>, 137 _phantom: PhantomData<M>,
@@ -142,10 +141,10 @@ pub struct Spi<'d, M: PeriMode> {
142 141
143impl<'d, M: PeriMode> Spi<'d, M> { 142impl<'d, M: PeriMode> Spi<'d, M> {
144 fn new_inner<T: Instance>( 143 fn new_inner<T: Instance>(
145 _peri: impl Peripheral<P = T> + 'd, 144 _peri: Peri<'d, T>,
146 sck: Option<PeripheralRef<'d, AnyPin>>, 145 sck: Option<Peri<'d, AnyPin>>,
147 mosi: Option<PeripheralRef<'d, AnyPin>>, 146 mosi: Option<Peri<'d, AnyPin>>,
148 miso: Option<PeripheralRef<'d, AnyPin>>, 147 miso: Option<Peri<'d, AnyPin>>,
149 tx_dma: Option<ChannelAndRequest<'d>>, 148 tx_dma: Option<ChannelAndRequest<'d>>,
150 rx_dma: Option<ChannelAndRequest<'d>>, 149 rx_dma: Option<ChannelAndRequest<'d>>,
151 config: Config, 150 config: Config,
@@ -465,10 +464,10 @@ impl<'d, M: PeriMode> Spi<'d, M> {
465impl<'d> Spi<'d, Blocking> { 464impl<'d> Spi<'d, Blocking> {
466 /// Create a new blocking SPI driver. 465 /// Create a new blocking SPI driver.
467 pub fn new_blocking<T: Instance>( 466 pub fn new_blocking<T: Instance>(
468 peri: impl Peripheral<P = T> + 'd, 467 peri: Peri<'d, T>,
469 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 468 sck: Peri<'d, impl SckPin<T>>,
470 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 469 mosi: Peri<'d, impl MosiPin<T>>,
471 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 470 miso: Peri<'d, impl MisoPin<T>>,
472 config: Config, 471 config: Config,
473 ) -> Self { 472 ) -> Self {
474 Self::new_inner( 473 Self::new_inner(
@@ -484,9 +483,9 @@ impl<'d> Spi<'d, Blocking> {
484 483
485 /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI). 484 /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI).
486 pub fn new_blocking_rxonly<T: Instance>( 485 pub fn new_blocking_rxonly<T: Instance>(
487 peri: impl Peripheral<P = T> + 'd, 486 peri: Peri<'d, T>,
488 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 487 sck: Peri<'d, impl SckPin<T>>,
489 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 488 miso: Peri<'d, impl MisoPin<T>>,
490 config: Config, 489 config: Config,
491 ) -> Self { 490 ) -> Self {
492 Self::new_inner( 491 Self::new_inner(
@@ -502,9 +501,9 @@ impl<'d> Spi<'d, Blocking> {
502 501
503 /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO). 502 /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO).
504 pub fn new_blocking_txonly<T: Instance>( 503 pub fn new_blocking_txonly<T: Instance>(
505 peri: impl Peripheral<P = T> + 'd, 504 peri: Peri<'d, T>,
506 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 505 sck: Peri<'d, impl SckPin<T>>,
507 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 506 mosi: Peri<'d, impl MosiPin<T>>,
508 config: Config, 507 config: Config,
509 ) -> Self { 508 ) -> Self {
510 Self::new_inner( 509 Self::new_inner(
@@ -522,8 +521,8 @@ impl<'d> Spi<'d, Blocking> {
522 /// 521 ///
523 /// This can be useful for bit-banging non-SPI protocols. 522 /// This can be useful for bit-banging non-SPI protocols.
524 pub fn new_blocking_txonly_nosck<T: Instance>( 523 pub fn new_blocking_txonly_nosck<T: Instance>(
525 peri: impl Peripheral<P = T> + 'd, 524 peri: Peri<'d, T>,
526 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 525 mosi: Peri<'d, impl MosiPin<T>>,
527 config: Config, 526 config: Config,
528 ) -> Self { 527 ) -> Self {
529 Self::new_inner( 528 Self::new_inner(
@@ -541,12 +540,12 @@ impl<'d> Spi<'d, Blocking> {
541impl<'d> Spi<'d, Async> { 540impl<'d> Spi<'d, Async> {
542 /// Create a new SPI driver. 541 /// Create a new SPI driver.
543 pub fn new<T: Instance>( 542 pub fn new<T: Instance>(
544 peri: impl Peripheral<P = T> + 'd, 543 peri: Peri<'d, T>,
545 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 544 sck: Peri<'d, impl SckPin<T>>,
546 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 545 mosi: Peri<'d, impl MosiPin<T>>,
547 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 546 miso: Peri<'d, impl MisoPin<T>>,
548 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 547 tx_dma: Peri<'d, impl TxDma<T>>,
549 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 548 rx_dma: Peri<'d, impl RxDma<T>>,
550 config: Config, 549 config: Config,
551 ) -> Self { 550 ) -> Self {
552 Self::new_inner( 551 Self::new_inner(
@@ -562,11 +561,11 @@ impl<'d> Spi<'d, Async> {
562 561
563 /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). 562 /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI).
564 pub fn new_rxonly<T: Instance>( 563 pub fn new_rxonly<T: Instance>(
565 peri: impl Peripheral<P = T> + 'd, 564 peri: Peri<'d, T>,
566 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 565 sck: Peri<'d, impl SckPin<T>>,
567 miso: impl Peripheral<P = impl MisoPin<T>> + 'd, 566 miso: Peri<'d, impl MisoPin<T>>,
568 #[cfg(any(spi_v1, spi_f1, spi_v2))] tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 567 #[cfg(any(spi_v1, spi_f1, spi_v2))] tx_dma: Peri<'d, impl TxDma<T>>,
569 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 568 rx_dma: Peri<'d, impl RxDma<T>>,
570 config: Config, 569 config: Config,
571 ) -> Self { 570 ) -> Self {
572 Self::new_inner( 571 Self::new_inner(
@@ -585,10 +584,10 @@ impl<'d> Spi<'d, Async> {
585 584
586 /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). 585 /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO).
587 pub fn new_txonly<T: Instance>( 586 pub fn new_txonly<T: Instance>(
588 peri: impl Peripheral<P = T> + 'd, 587 peri: Peri<'d, T>,
589 sck: impl Peripheral<P = impl SckPin<T>> + 'd, 588 sck: Peri<'d, impl SckPin<T>>,
590 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 589 mosi: Peri<'d, impl MosiPin<T>>,
591 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 590 tx_dma: Peri<'d, impl TxDma<T>>,
592 config: Config, 591 config: Config,
593 ) -> Self { 592 ) -> Self {
594 Self::new_inner( 593 Self::new_inner(
@@ -606,9 +605,9 @@ impl<'d> Spi<'d, Async> {
606 /// 605 ///
607 /// This can be useful for bit-banging non-SPI protocols. 606 /// This can be useful for bit-banging non-SPI protocols.
608 pub fn new_txonly_nosck<T: Instance>( 607 pub fn new_txonly_nosck<T: Instance>(
609 peri: impl Peripheral<P = T> + 'd, 608 peri: Peri<'d, T>,
610 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, 609 mosi: Peri<'d, impl MosiPin<T>>,
611 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 610 tx_dma: Peri<'d, impl TxDma<T>>,
612 config: Config, 611 config: Config,
613 ) -> Self { 612 ) -> Self {
614 Self::new_inner( 613 Self::new_inner(
@@ -625,9 +624,9 @@ impl<'d> Spi<'d, Async> {
625 #[cfg(stm32wl)] 624 #[cfg(stm32wl)]
626 /// Useful for on chip peripherals like SUBGHZ which are hardwired. 625 /// Useful for on chip peripherals like SUBGHZ which are hardwired.
627 pub fn new_subghz<T: Instance>( 626 pub fn new_subghz<T: Instance>(
628 peri: impl Peripheral<P = T> + 'd, 627 peri: Peri<'d, T>,
629 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 628 tx_dma: Peri<'d, impl TxDma<T>>,
630 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 629 rx_dma: Peri<'d, impl RxDma<T>>,
631 ) -> Self { 630 ) -> Self {
632 // see RM0453 rev 1 section 7.2.13 page 291 631 // see RM0453 rev 1 section 7.2.13 page 291
633 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. 632 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two.
@@ -644,7 +643,7 @@ impl<'d> Spi<'d, Async> {
644 643
645 #[allow(dead_code)] 644 #[allow(dead_code)]
646 pub(crate) fn new_internal<T: Instance>( 645 pub(crate) fn new_internal<T: Instance>(
647 peri: impl Peripheral<P = T> + 'd, 646 peri: Peri<'d, T>,
648 tx_dma: Option<ChannelAndRequest<'d>>, 647 tx_dma: Option<ChannelAndRequest<'d>>,
649 rx_dma: Option<ChannelAndRequest<'d>>, 648 rx_dma: Option<ChannelAndRequest<'d>>,
650 config: Config, 649 config: Config,
@@ -839,7 +838,7 @@ impl<'d> Spi<'d, Async> {
839 let rx_src = self.info.regs.rx_ptr(); 838 let rx_src = self.info.regs.rx_ptr();
840 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; 839 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
841 840
842 let tx_dst = self.info.regs.tx_ptr(); 841 let tx_dst: *mut W = self.info.regs.tx_ptr();
843 let tx_f = unsafe { 842 let tx_f = unsafe {
844 self.tx_dma 843 self.tx_dma
845 .as_mut() 844 .as_mut()
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs
index 02c01e900..f543bafab 100644
--- a/embassy-stm32/src/timer/complementary_pwm.rs
+++ b/embassy-stm32/src/timer/complementary_pwm.rs
@@ -2,7 +2,6 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_internal::{into_ref, PeripheralRef};
6use stm32_metapac::timer::vals::Ckd; 5use stm32_metapac::timer::vals::Ckd;
7 6
8use super::low_level::{CountingMode, OutputPolarity, Timer}; 7use super::low_level::{CountingMode, OutputPolarity, Timer};
@@ -14,13 +13,13 @@ use super::{
14use crate::gpio::{AnyPin, OutputType}; 13use crate::gpio::{AnyPin, OutputType};
15use crate::time::Hertz; 14use crate::time::Hertz;
16use crate::timer::low_level::OutputCompareMode; 15use crate::timer::low_level::OutputCompareMode;
17use crate::Peripheral; 16use crate::Peri;
18 17
19/// Complementary PWM pin wrapper. 18/// Complementary PWM pin wrapper.
20/// 19///
21/// This wraps a pin to make it usable with PWM. 20/// This wraps a pin to make it usable with PWM.
22pub struct ComplementaryPwmPin<'d, T, C> { 21pub struct ComplementaryPwmPin<'d, T, C> {
23 _pin: PeripheralRef<'d, AnyPin>, 22 _pin: Peri<'d, AnyPin>,
24 phantom: PhantomData<(T, C)>, 23 phantom: PhantomData<(T, C)>,
25} 24}
26 25
@@ -28,8 +27,7 @@ macro_rules! complementary_channel_impl {
28 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 27 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
29 impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> { 28 impl<'d, T: AdvancedInstance4Channel> ComplementaryPwmPin<'d, T, $channel> {
30 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")] 29 #[doc = concat!("Create a new ", stringify!($channel), " complementary PWM pin instance.")]
31 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 30 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, output_type: OutputType) -> Self {
32 into_ref!(pin);
33 critical_section::with(|_| { 31 critical_section::with(|_| {
34 pin.set_low(); 32 pin.set_low();
35 pin.set_as_af( 33 pin.set_as_af(
@@ -38,7 +36,7 @@ macro_rules! complementary_channel_impl {
38 ); 36 );
39 }); 37 });
40 ComplementaryPwmPin { 38 ComplementaryPwmPin {
41 _pin: pin.map_into(), 39 _pin: pin.into(),
42 phantom: PhantomData, 40 phantom: PhantomData,
43 } 41 }
44 } 42 }
@@ -60,7 +58,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
60 /// Create a new complementary PWM driver. 58 /// Create a new complementary PWM driver.
61 #[allow(clippy::too_many_arguments)] 59 #[allow(clippy::too_many_arguments)]
62 pub fn new( 60 pub fn new(
63 tim: impl Peripheral<P = T> + 'd, 61 tim: Peri<'d, T>,
64 _ch1: Option<PwmPin<'d, T, Ch1>>, 62 _ch1: Option<PwmPin<'d, T, Ch1>>,
65 _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>, 63 _ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>,
66 _ch2: Option<PwmPin<'d, T, Ch2>>, 64 _ch2: Option<PwmPin<'d, T, Ch2>>,
@@ -75,7 +73,7 @@ impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
75 Self::new_inner(tim, freq, counting_mode) 73 Self::new_inner(tim, freq, counting_mode)
76 } 74 }
77 75
78 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { 76 fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self {
79 let mut this = Self { inner: Timer::new(tim) }; 77 let mut this = Self { inner: Timer::new(tim) };
80 78
81 this.inner.set_counting_mode(counting_mode); 79 this.inner.set_counting_mode(counting_mode);
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs
index b7c13343c..0450f14fa 100644
--- a/embassy-stm32/src/timer/input_capture.rs
+++ b/embassy-stm32/src/timer/input_capture.rs
@@ -5,8 +5,6 @@ use core::marker::PhantomData;
5use core::pin::Pin; 5use core::pin::Pin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef};
9
10use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer}; 8use super::low_level::{CountingMode, FilterValue, InputCaptureMode, InputTISelection, Timer};
11use super::{ 9use super::{
12 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, 10 CaptureCompareInterruptHandler, Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin,
@@ -15,7 +13,7 @@ use super::{
15use crate::gpio::{AfType, AnyPin, Pull}; 13use crate::gpio::{AfType, AnyPin, Pull};
16use crate::interrupt::typelevel::{Binding, Interrupt}; 14use crate::interrupt::typelevel::{Binding, Interrupt};
17use crate::time::Hertz; 15use crate::time::Hertz;
18use crate::Peripheral; 16use crate::Peri;
19 17
20/// Channel 1 marker type. 18/// Channel 1 marker type.
21pub enum Ch1 {} 19pub enum Ch1 {}
@@ -30,7 +28,7 @@ pub enum Ch4 {}
30/// 28///
31/// This wraps a pin to make it usable with capture. 29/// This wraps a pin to make it usable with capture.
32pub struct CapturePin<'d, T, C> { 30pub struct CapturePin<'d, T, C> {
33 _pin: PeripheralRef<'d, AnyPin>, 31 _pin: Peri<'d, AnyPin>,
34 phantom: PhantomData<(T, C)>, 32 phantom: PhantomData<(T, C)>,
35} 33}
36 34
@@ -38,11 +36,10 @@ macro_rules! channel_impl {
38 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 36 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
39 impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> { 37 impl<'d, T: GeneralInstance4Channel> CapturePin<'d, T, $channel> {
40 #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")] 38 #[doc = concat!("Create a new ", stringify!($channel), " capture pin instance.")]
41 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, pull: Pull) -> Self { 39 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, pull: Pull) -> Self {
42 into_ref!(pin);
43 pin.set_as_af(pin.af_num(), AfType::input(pull)); 40 pin.set_as_af(pin.af_num(), AfType::input(pull));
44 CapturePin { 41 CapturePin {
45 _pin: pin.map_into(), 42 _pin: pin.into(),
46 phantom: PhantomData, 43 phantom: PhantomData,
47 } 44 }
48 } 45 }
@@ -63,7 +60,7 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> {
63impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { 60impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
64 /// Create a new input capture driver. 61 /// Create a new input capture driver.
65 pub fn new( 62 pub fn new(
66 tim: impl Peripheral<P = T> + 'd, 63 tim: Peri<'d, T>,
67 _ch1: Option<CapturePin<'d, T, Ch1>>, 64 _ch1: Option<CapturePin<'d, T, Ch1>>,
68 _ch2: Option<CapturePin<'d, T, Ch2>>, 65 _ch2: Option<CapturePin<'d, T, Ch2>>,
69 _ch3: Option<CapturePin<'d, T, Ch3>>, 66 _ch3: Option<CapturePin<'d, T, Ch3>>,
@@ -75,7 +72,7 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
75 Self::new_inner(tim, freq, counting_mode) 72 Self::new_inner(tim, freq, counting_mode)
76 } 73 }
77 74
78 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { 75 fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self {
79 let mut this = Self { inner: Timer::new(tim) }; 76 let mut this = Self { inner: Timer::new(tim) };
80 77
81 this.inner.set_counting_mode(counting_mode); 78 this.inner.set_counting_mode(counting_mode);
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index 5b0c95109..8fc32c1f3 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -8,7 +8,7 @@
8 8
9use core::mem::ManuallyDrop; 9use core::mem::ManuallyDrop;
10 10
11use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 11use embassy_hal_internal::Peri;
12// Re-export useful enums 12// Re-export useful enums
13pub use stm32_metapac::timer::vals::{FilterValue, Sms as SlaveMode, Ts as TriggerSource}; 13pub use stm32_metapac::timer::vals::{FilterValue, Sms as SlaveMode, Ts as TriggerSource};
14 14
@@ -181,7 +181,7 @@ impl From<OutputPolarity> for bool {
181 181
182/// Low-level timer driver. 182/// Low-level timer driver.
183pub struct Timer<'d, T: CoreInstance> { 183pub struct Timer<'d, T: CoreInstance> {
184 tim: PeripheralRef<'d, T>, 184 tim: Peri<'d, T>,
185} 185}
186 186
187impl<'d, T: CoreInstance> Drop for Timer<'d, T> { 187impl<'d, T: CoreInstance> Drop for Timer<'d, T> {
@@ -192,9 +192,7 @@ impl<'d, T: CoreInstance> Drop for Timer<'d, T> {
192 192
193impl<'d, T: CoreInstance> Timer<'d, T> { 193impl<'d, T: CoreInstance> Timer<'d, T> {
194 /// Create a new timer driver. 194 /// Create a new timer driver.
195 pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self { 195 pub fn new(tim: Peri<'d, T>) -> Self {
196 into_ref!(tim);
197
198 rcc::enable_and_reset::<T>(); 196 rcc::enable_and_reset::<T>();
199 197
200 Self { tim } 198 Self { tim }
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs
index 97740c2ed..765a3d9fa 100644
--- a/embassy-stm32/src/timer/mod.rs
+++ b/embassy-stm32/src/timer/mod.rs
@@ -2,7 +2,7 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_internal::Peripheral; 5use embassy_hal_internal::PeripheralType;
6use embassy_sync::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
7 7
8#[cfg(not(stm32l0))] 8#[cfg(not(stm32l0))]
@@ -66,7 +66,7 @@ impl State {
66 } 66 }
67} 67}
68 68
69trait SealedInstance: RccPeripheral + Peripheral<P = Self> { 69trait SealedInstance: RccPeripheral + PeripheralType {
70 /// Async state for this timer 70 /// Async state for this timer
71 fn state() -> &'static State; 71 fn state() -> &'static State;
72} 72}
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs
index e3eb6042a..98b798634 100644
--- a/embassy-stm32/src/timer/pwm_input.rs
+++ b/embassy-stm32/src/timer/pwm_input.rs
@@ -1,12 +1,10 @@
1//! PWM Input driver. 1//! PWM Input driver.
2 2
3use embassy_hal_internal::into_ref;
4
5use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource}; 3use super::low_level::{CountingMode, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource};
6use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 4use super::{Channel, Channel1Pin, Channel2Pin, GeneralInstance4Channel};
7use crate::gpio::{AfType, Pull}; 5use crate::gpio::{AfType, Pull};
8use crate::time::Hertz; 6use crate::time::Hertz;
9use crate::Peripheral; 7use crate::Peri;
10 8
11/// PWM Input driver. 9/// PWM Input driver.
12pub struct PwmInput<'d, T: GeneralInstance4Channel> { 10pub struct PwmInput<'d, T: GeneralInstance4Channel> {
@@ -16,34 +14,20 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> {
16 14
17impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { 15impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
18 /// Create a new PWM input driver. 16 /// Create a new PWM input driver.
19 pub fn new( 17 pub fn new(tim: Peri<'d, T>, pin: Peri<'d, impl Channel1Pin<T>>, pull: Pull, freq: Hertz) -> Self {
20 tim: impl Peripheral<P = T> + 'd,
21 pin: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
22 pull: Pull,
23 freq: Hertz,
24 ) -> Self {
25 into_ref!(pin);
26
27 pin.set_as_af(pin.af_num(), AfType::input(pull)); 18 pin.set_as_af(pin.af_num(), AfType::input(pull));
28 19
29 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) 20 Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2)
30 } 21 }
31 22
32 /// Create a new PWM input driver. 23 /// Create a new PWM input driver.
33 pub fn new_alt( 24 pub fn new_alt(tim: Peri<'d, T>, pin: Peri<'d, impl Channel2Pin<T>>, pull: Pull, freq: Hertz) -> Self {
34 tim: impl Peripheral<P = T> + 'd,
35 pin: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
36 pull: Pull,
37 freq: Hertz,
38 ) -> Self {
39 into_ref!(pin);
40
41 pin.set_as_af(pin.af_num(), AfType::input(pull)); 25 pin.set_as_af(pin.af_num(), AfType::input(pull));
42 26
43 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) 27 Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1)
44 } 28 }
45 29
46 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, ch1: Channel, ch2: Channel) -> Self { 30 fn new_inner(tim: Peri<'d, T>, freq: Hertz, ch1: Channel, ch2: Channel) -> Self {
47 let mut inner = Timer::new(tim); 31 let mut inner = Timer::new(tim);
48 32
49 inner.set_counting_mode(CountingMode::EdgeAlignedUp); 33 inner.set_counting_mode(CountingMode::EdgeAlignedUp);
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs
index fc5835414..bac290f28 100644
--- a/embassy-stm32/src/timer/qei.rs
+++ b/embassy-stm32/src/timer/qei.rs
@@ -2,13 +2,12 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_internal::{into_ref, PeripheralRef};
6use stm32_metapac::timer::vals; 5use stm32_metapac::timer::vals;
7 6
8use super::low_level::Timer; 7use super::low_level::Timer;
9use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel}; 8use super::{Channel1Pin, Channel2Pin, GeneralInstance4Channel};
10use crate::gpio::{AfType, AnyPin, Pull}; 9use crate::gpio::{AfType, AnyPin, Pull};
11use crate::Peripheral; 10use crate::Peri;
12 11
13/// Counting direction 12/// Counting direction
14pub enum Direction { 13pub enum Direction {
@@ -25,7 +24,7 @@ pub enum Ch2 {}
25 24
26/// Wrapper for using a pin with QEI. 25/// Wrapper for using a pin with QEI.
27pub struct QeiPin<'d, T, Channel> { 26pub struct QeiPin<'d, T, Channel> {
28 _pin: PeripheralRef<'d, AnyPin>, 27 _pin: Peri<'d, AnyPin>,
29 phantom: PhantomData<(T, Channel)>, 28 phantom: PhantomData<(T, Channel)>,
30} 29}
31 30
@@ -33,14 +32,13 @@ macro_rules! channel_impl {
33 ($new_chx:ident, $channel:ident, $pin_trait:ident) => { 32 ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
34 impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> { 33 impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> {
35 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")] 34 #[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")]
36 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { 35 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
37 into_ref!(pin);
38 critical_section::with(|_| { 36 critical_section::with(|_| {
39 pin.set_low(); 37 pin.set_low();
40 pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); 38 pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
41 }); 39 });
42 QeiPin { 40 QeiPin {
43 _pin: pin.map_into(), 41 _pin: pin.into(),
44 phantom: PhantomData, 42 phantom: PhantomData,
45 } 43 }
46 } 44 }
@@ -58,11 +56,11 @@ pub struct Qei<'d, T: GeneralInstance4Channel> {
58 56
59impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { 57impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
60 /// Create a new quadrature decoder driver. 58 /// Create a new quadrature decoder driver.
61 pub fn new(tim: impl Peripheral<P = T> + 'd, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self { 59 pub fn new(tim: Peri<'d, T>, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self {
62 Self::new_inner(tim) 60 Self::new_inner(tim)
63 } 61 }
64 62
65 fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { 63 fn new_inner(tim: Peri<'d, T>) -> Self {
66 let inner = Timer::new(tim); 64 let inner = Timer::new(tim);
67 let r = inner.regs_gp16(); 65 let r = inner.regs_gp16();
68 66
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs
index c5a366cd5..54ab7d0d5 100644
--- a/embassy-stm32/src/timer/simple_pwm.rs
+++ b/embassy-stm32/src/timer/simple_pwm.rs
@@ -3,15 +3,13 @@
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::mem::ManuallyDrop; 4use core::mem::ManuallyDrop;
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef};
7
8use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; 6use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
9use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; 7use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits};
10#[cfg(gpio_v2)] 8#[cfg(gpio_v2)]
11use crate::gpio::Pull; 9use crate::gpio::Pull;
12use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 10use crate::gpio::{AfType, AnyPin, OutputType, Speed};
13use crate::time::Hertz; 11use crate::time::Hertz;
14use crate::Peripheral; 12use crate::Peri;
15 13
16/// Channel 1 marker type. 14/// Channel 1 marker type.
17pub enum Ch1 {} 15pub enum Ch1 {}
@@ -26,7 +24,7 @@ pub enum Ch4 {}
26/// 24///
27/// This wraps a pin to make it usable with PWM. 25/// This wraps a pin to make it usable with PWM.
28pub struct PwmPin<'d, T, C> { 26pub struct PwmPin<'d, T, C> {
29 _pin: PeripheralRef<'d, AnyPin>, 27 _pin: Peri<'d, AnyPin>,
30 phantom: PhantomData<(T, C)>, 28 phantom: PhantomData<(T, C)>,
31} 29}
32 30
@@ -47,24 +45,19 @@ macro_rules! channel_impl {
47 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { 45 ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => {
48 impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { 46 impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> {
49 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] 47 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
50 pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { 48 pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>, output_type: OutputType) -> Self {
51 into_ref!(pin);
52 critical_section::with(|_| { 49 critical_section::with(|_| {
53 pin.set_low(); 50 pin.set_low();
54 pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); 51 pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh));
55 }); 52 });
56 PwmPin { 53 PwmPin {
57 _pin: pin.map_into(), 54 _pin: pin.into(),
58 phantom: PhantomData, 55 phantom: PhantomData,
59 } 56 }
60 } 57 }
61 58
62 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] 59 #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")]
63 pub fn $new_chx_with_config( 60 pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T>>, pin_config: PwmPinConfig) -> Self {
64 pin: impl Peripheral<P = impl $pin_trait<T>> + 'd,
65 pin_config: PwmPinConfig,
66 ) -> Self {
67 into_ref!(pin);
68 critical_section::with(|_| { 61 critical_section::with(|_| {
69 pin.set_low(); 62 pin.set_low();
70 pin.set_as_af( 63 pin.set_as_af(
@@ -76,7 +69,7 @@ macro_rules! channel_impl {
76 ); 69 );
77 }); 70 });
78 PwmPin { 71 PwmPin {
79 _pin: pin.map_into(), 72 _pin: pin.into(),
80 phantom: PhantomData, 73 phantom: PhantomData,
81 } 74 }
82 } 75 }
@@ -202,7 +195,7 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> {
202impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { 195impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
203 /// Create a new simple PWM driver. 196 /// Create a new simple PWM driver.
204 pub fn new( 197 pub fn new(
205 tim: impl Peripheral<P = T> + 'd, 198 tim: Peri<'d, T>,
206 _ch1: Option<PwmPin<'d, T, Ch1>>, 199 _ch1: Option<PwmPin<'d, T, Ch1>>,
207 _ch2: Option<PwmPin<'d, T, Ch2>>, 200 _ch2: Option<PwmPin<'d, T, Ch2>>,
208 _ch3: Option<PwmPin<'d, T, Ch3>>, 201 _ch3: Option<PwmPin<'d, T, Ch3>>,
@@ -213,7 +206,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
213 Self::new_inner(tim, freq, counting_mode) 206 Self::new_inner(tim, freq, counting_mode)
214 } 207 }
215 208
216 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self { 209 fn new_inner(tim: Peri<'d, T>, freq: Hertz, counting_mode: CountingMode) -> Self {
217 let mut this = Self { inner: Timer::new(tim) }; 210 let mut this = Self { inner: Timer::new(tim) };
218 211
219 this.inner.set_counting_mode(counting_mode); 212 this.inner.set_counting_mode(counting_mode);
@@ -331,14 +324,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
331 /// 324 ///
332 /// Note: 325 /// Note:
333 /// you will need to provide corresponding TIMx_UP DMA channel to use this method. 326 /// you will need to provide corresponding TIMx_UP DMA channel to use this method.
334 pub async fn waveform_up( 327 pub async fn waveform_up(&mut self, dma: Peri<'_, impl super::UpDma<T>>, channel: Channel, duty: &[u16]) {
335 &mut self,
336 dma: impl Peripheral<P = impl super::UpDma<T>>,
337 channel: Channel,
338 duty: &[u16],
339 ) {
340 into_ref!(dma);
341
342 #[allow(clippy::let_unit_value)] // eg. stm32f334 328 #[allow(clippy::let_unit_value)] // eg. stm32f334
343 let req = dma.request(); 329 let req = dma.request();
344 330
@@ -368,7 +354,7 @@ impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
368 }; 354 };
369 355
370 Transfer::new_write( 356 Transfer::new_write(
371 &mut dma, 357 dma,
372 req, 358 req,
373 duty, 359 duty,
374 self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16, 360 self.inner.regs_1ch().ccr(channel.index()).as_ptr() as *mut u16,
@@ -399,11 +385,9 @@ macro_rules! impl_waveform_chx {
399 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => { 385 ($fn_name:ident, $dma_ch:ident, $cc_ch:ident) => {
400 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { 386 impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
401 /// Generate a sequence of PWM waveform 387 /// Generate a sequence of PWM waveform
402 pub async fn $fn_name(&mut self, dma: impl Peripheral<P = impl super::$dma_ch<T>>, duty: &[u16]) { 388 pub async fn $fn_name(&mut self, dma: Peri<'_, impl super::$dma_ch<T>>, duty: &[u16]) {
403 use crate::pac::timer::vals::Ccds; 389 use crate::pac::timer::vals::Ccds;
404 390
405 into_ref!(dma);
406
407 #[allow(clippy::let_unit_value)] // eg. stm32f334 391 #[allow(clippy::let_unit_value)] // eg. stm32f334
408 let req = dma.request(); 392 let req = dma.request();
409 393
@@ -443,7 +427,7 @@ macro_rules! impl_waveform_chx {
443 match self.inner.bits() { 427 match self.inner.bits() {
444 TimerBits::Bits16 => { 428 TimerBits::Bits16 => {
445 Transfer::new_write( 429 Transfer::new_write(
446 &mut dma, 430 dma,
447 req, 431 req,
448 duty, 432 duty,
449 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16, 433 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u16,
@@ -458,7 +442,7 @@ macro_rules! impl_waveform_chx {
458 442
459 #[cfg(any(bdma, gpdma))] 443 #[cfg(any(bdma, gpdma))]
460 Transfer::new_write( 444 Transfer::new_write(
461 &mut dma, 445 dma,
462 req, 446 req,
463 duty, 447 duty,
464 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32, 448 self.inner.regs_gp16().ccr(cc_channel.index()).as_ptr() as *mut u32,
diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs
index 0d5c27465..9359d83e9 100644
--- a/embassy-stm32/src/tsc/mod.rs
+++ b/embassy-stm32/src/tsc/mod.rs
@@ -98,6 +98,7 @@ use core::marker::PhantomData;
98 98
99pub use acquisition_banks::*; 99pub use acquisition_banks::*;
100pub use config::*; 100pub use config::*;
101use embassy_hal_internal::PeripheralType;
101use embassy_sync::waitqueue::AtomicWaker; 102use embassy_sync::waitqueue::AtomicWaker;
102pub use errors::*; 103pub use errors::*;
103pub use io_pin::*; 104pub use io_pin::*;
@@ -106,7 +107,7 @@ pub use tsc::*;
106pub use types::*; 107pub use types::*;
107 108
108use crate::rcc::RccPeripheral; 109use crate::rcc::RccPeripheral;
109use crate::{interrupt, peripherals, Peripheral}; 110use crate::{interrupt, peripherals};
110 111
111#[cfg(tsc_v1)] 112#[cfg(tsc_v1)]
112const TSC_NUM_GROUPS: usize = 6; 113const TSC_NUM_GROUPS: usize = 6;
@@ -142,7 +143,7 @@ pub(crate) trait SealedInstance {
142 143
143/// TSC instance trait 144/// TSC instance trait
144#[allow(private_bounds)] 145#[allow(private_bounds)]
145pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral { 146pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {
146 /// Interrupt for this TSC instance 147 /// Interrupt for this TSC instance
147 type Interrupt: interrupt::typelevel::Interrupt; 148 type Interrupt: interrupt::typelevel::Interrupt;
148} 149}
diff --git a/embassy-stm32/src/tsc/pin_groups.rs b/embassy-stm32/src/tsc/pin_groups.rs
index 1f3aafa35..6f914a94e 100644
--- a/embassy-stm32/src/tsc/pin_groups.rs
+++ b/embassy-stm32/src/tsc/pin_groups.rs
@@ -1,13 +1,11 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::ops::BitOr; 2use core::ops::BitOr;
3 3
4use embassy_hal_internal::{into_ref, PeripheralRef};
5
6use super::errors::GroupError; 4use super::errors::GroupError;
7use super::io_pin::*; 5use super::io_pin::*;
8use super::Instance; 6use super::Instance;
9use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 7use crate::gpio::{AfType, AnyPin, OutputType, Speed};
10use crate::Peripheral; 8use crate::Peri;
11 9
12/// Pin type definition to control IO parameters 10/// Pin type definition to control IO parameters
13#[derive(PartialEq, Clone, Copy)] 11#[derive(PartialEq, Clone, Copy)]
@@ -23,7 +21,7 @@ pub enum PinType {
23/// Pin struct that maintains usage 21/// Pin struct that maintains usage
24#[allow(missing_docs)] 22#[allow(missing_docs)]
25pub struct Pin<'d, T, Group> { 23pub struct Pin<'d, T, Group> {
26 _pin: PeripheralRef<'d, AnyPin>, 24 _pin: Peri<'d, AnyPin>,
27 role: PinType, 25 role: PinType,
28 tsc_io_pin: IOPin, 26 tsc_io_pin: IOPin,
29 phantom: PhantomData<(T, Group)>, 27 phantom: PhantomData<(T, Group)>,
@@ -426,17 +424,13 @@ macro_rules! trait_to_io_pin {
426macro_rules! impl_set_io { 424macro_rules! impl_set_io {
427 ($method:ident, $group:ident, $trait:ident, $index:expr) => { 425 ($method:ident, $group:ident, $trait:ident, $index:expr) => {
428 #[doc = concat!("Create a new pin1 for ", stringify!($group), " TSC group instance.")] 426 #[doc = concat!("Create a new pin1 for ", stringify!($group), " TSC group instance.")]
429 pub fn $method<Role: pin_roles::Role>( 427 pub fn $method<Role: pin_roles::Role>(&mut self, pin: Peri<'d, impl $trait<T>>) -> IOPinWithRole<$group, Role> {
430 &mut self,
431 pin: impl Peripheral<P = impl $trait<T>> + 'd,
432 ) -> IOPinWithRole<$group, Role> {
433 into_ref!(pin);
434 critical_section::with(|_| { 428 critical_section::with(|_| {
435 pin.set_low(); 429 pin.set_low();
436 pin.set_as_af(pin.af_num(), AfType::output(Role::output_type(), Speed::VeryHigh)); 430 pin.set_as_af(pin.af_num(), AfType::output(Role::output_type(), Speed::VeryHigh));
437 let tsc_io_pin = trait_to_io_pin!($trait); 431 let tsc_io_pin = trait_to_io_pin!($trait);
438 let new_pin = Pin { 432 let new_pin = Pin {
439 _pin: pin.map_into(), 433 _pin: pin.into(),
440 role: Role::pin_type(), 434 role: Role::pin_type(),
441 tsc_io_pin, 435 tsc_io_pin,
442 phantom: PhantomData, 436 phantom: PhantomData,
diff --git a/embassy-stm32/src/tsc/tsc.rs b/embassy-stm32/src/tsc/tsc.rs
index 17d2da82f..e92479c26 100644
--- a/embassy-stm32/src/tsc/tsc.rs
+++ b/embassy-stm32/src/tsc/tsc.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
3use core::ops::BitOr; 3use core::ops::BitOr;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::Peri;
7 7
8use super::acquisition_banks::*; 8use super::acquisition_banks::*;
9use super::config::*; 9use super::config::*;
@@ -14,7 +14,7 @@ use super::types::*;
14use super::{Instance, InterruptHandler, TSC_NUM_GROUPS}; 14use super::{Instance, InterruptHandler, TSC_NUM_GROUPS};
15use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
16use crate::mode::{Async, Blocking, Mode as PeriMode}; 16use crate::mode::{Async, Blocking, Mode as PeriMode};
17use crate::{interrupt, rcc, Peripheral}; 17use crate::{interrupt, rcc};
18 18
19/// Internal structure holding masks for different types of TSC IOs. 19/// Internal structure holding masks for different types of TSC IOs.
20/// 20///
@@ -31,7 +31,7 @@ struct IOMasks {
31 31
32/// TSC driver 32/// TSC driver
33pub struct Tsc<'d, T: Instance, K: PeriMode> { 33pub struct Tsc<'d, T: Instance, K: PeriMode> {
34 _peri: PeripheralRef<'d, T>, 34 _peri: Peri<'d, T>,
35 _pin_groups: PinGroups<'d, T>, 35 _pin_groups: PinGroups<'d, T>,
36 state: State, 36 state: State,
37 config: Config, 37 config: Config,
@@ -218,13 +218,7 @@ impl<'d, T: Instance, K: PeriMode> Tsc<'d, T, K> {
218 groups 218 groups
219 } 219 }
220 220
221 fn new_inner( 221 fn new_inner(peri: Peri<'d, T>, pin_groups: PinGroups<'d, T>, config: Config) -> Result<Self, GroupError> {
222 peri: impl Peripheral<P = T> + 'd,
223 pin_groups: PinGroups<'d, T>,
224 config: Config,
225 ) -> Result<Self, GroupError> {
226 into_ref!(peri);
227
228 pin_groups.check()?; 222 pin_groups.check()?;
229 223
230 let masks = IOMasks { 224 let masks = IOMasks {
@@ -410,7 +404,7 @@ impl<'d, T: Instance, K: PeriMode> Drop for Tsc<'d, T, K> {
410impl<'d, T: Instance> Tsc<'d, T, Async> { 404impl<'d, T: Instance> Tsc<'d, T, Async> {
411 /// Create a Tsc instance that can be awaited for completion 405 /// Create a Tsc instance that can be awaited for completion
412 pub fn new_async( 406 pub fn new_async(
413 peri: impl Peripheral<P = T> + 'd, 407 peri: Peri<'d, T>,
414 pin_groups: PinGroups<'d, T>, 408 pin_groups: PinGroups<'d, T>,
415 config: Config, 409 config: Config,
416 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 410 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@@ -441,11 +435,7 @@ impl<'d, T: Instance> Tsc<'d, T, Async> {
441 435
442impl<'d, T: Instance> Tsc<'d, T, Blocking> { 436impl<'d, T: Instance> Tsc<'d, T, Blocking> {
443 /// Create a Tsc instance that must be polled for completion 437 /// Create a Tsc instance that must be polled for completion
444 pub fn new_blocking( 438 pub fn new_blocking(peri: Peri<'d, T>, pin_groups: PinGroups<'d, T>, config: Config) -> Result<Self, GroupError> {
445 peri: impl Peripheral<P = T> + 'd,
446 pin_groups: PinGroups<'d, T>,
447 config: Config,
448 ) -> Result<Self, GroupError> {
449 Self::new_inner(peri, pin_groups, config) 439 Self::new_inner(peri, pin_groups, config)
450 } 440 }
451 441
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs
index c40ee8ad0..87693f148 100644
--- a/embassy-stm32/src/ucpd.rs
+++ b/embassy-stm32/src/ucpd.rs
@@ -20,15 +20,15 @@ use core::sync::atomic::{AtomicBool, Ordering};
20use core::task::Poll; 20use core::task::Poll;
21 21
22use embassy_hal_internal::drop::OnDrop; 22use embassy_hal_internal::drop::OnDrop;
23use embassy_hal_internal::{into_ref, Peripheral}; 23use embassy_hal_internal::PeripheralType;
24use embassy_sync::waitqueue::AtomicWaker; 24use embassy_sync::waitqueue::AtomicWaker;
25 25
26use crate::dma::{ChannelAndRequest, TransferOptions}; 26use crate::dma::{ChannelAndRequest, TransferOptions};
27use crate::interrupt;
28use crate::interrupt::typelevel::Interrupt; 27use crate::interrupt::typelevel::Interrupt;
29use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode}; 28use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode};
30pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, Rxordset, TypecVstateCc as CcVState}; 29pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, Rxordset, TypecVstateCc as CcVState};
31use crate::rcc::{self, RccPeripheral}; 30use crate::rcc::{self, RccPeripheral};
31use crate::{interrupt, Peri};
32 32
33pub(crate) fn init( 33pub(crate) fn init(
34 _cs: critical_section::CriticalSection, 34 _cs: critical_section::CriticalSection,
@@ -122,13 +122,12 @@ pub struct Ucpd<'d, T: Instance> {
122impl<'d, T: Instance> Ucpd<'d, T> { 122impl<'d, T: Instance> Ucpd<'d, T> {
123 /// Creates a new UCPD driver instance. 123 /// Creates a new UCPD driver instance.
124 pub fn new( 124 pub fn new(
125 _peri: impl Peripheral<P = T> + 'd, 125 _peri: Peri<'d, T>,
126 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 126 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
127 cc1: impl Peripheral<P = impl Cc1Pin<T>> + 'd, 127 cc1: Peri<'d, impl Cc1Pin<T>>,
128 cc2: impl Peripheral<P = impl Cc2Pin<T>> + 'd, 128 cc2: Peri<'d, impl Cc2Pin<T>>,
129 config: Config, 129 config: Config,
130 ) -> Self { 130 ) -> Self {
131 into_ref!(cc1, cc2);
132 cc1.set_as_analog(); 131 cc1.set_as_analog();
133 cc2.set_as_analog(); 132 cc2.set_as_analog();
134 133
@@ -208,8 +207,8 @@ impl<'d, T: Instance> Ucpd<'d, T> {
208 /// and a Power Delivery (PD) PHY with receiver and transmitter. 207 /// and a Power Delivery (PD) PHY with receiver and transmitter.
209 pub fn split_pd_phy( 208 pub fn split_pd_phy(
210 self, 209 self,
211 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 210 rx_dma: Peri<'d, impl RxDma<T>>,
212 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 211 tx_dma: Peri<'d, impl TxDma<T>>,
213 cc_sel: CcSel, 212 cc_sel: CcSel,
214 ) -> (CcPhy<'d, T>, PdPhy<'d, T>) { 213 ) -> (CcPhy<'d, T>, PdPhy<'d, T>) {
215 let r = T::REGS; 214 let r = T::REGS;
@@ -229,7 +228,6 @@ impl<'d, T: Instance> Ucpd<'d, T> {
229 // Both parts must be dropped before the peripheral can be disabled. 228 // Both parts must be dropped before the peripheral can be disabled.
230 T::state().drop_not_ready.store(true, Ordering::Relaxed); 229 T::state().drop_not_ready.store(true, Ordering::Relaxed);
231 230
232 into_ref!(rx_dma, tx_dma);
233 let rx_dma_req = rx_dma.request(); 231 let rx_dma_req = rx_dma.request();
234 let tx_dma_req = tx_dma.request(); 232 let tx_dma_req = tx_dma.request();
235 ( 233 (
@@ -237,11 +235,11 @@ impl<'d, T: Instance> Ucpd<'d, T> {
237 PdPhy { 235 PdPhy {
238 _lifetime: PhantomData, 236 _lifetime: PhantomData,
239 rx_dma: ChannelAndRequest { 237 rx_dma: ChannelAndRequest {
240 channel: rx_dma.map_into(), 238 channel: rx_dma.into(),
241 request: rx_dma_req, 239 request: rx_dma_req,
242 }, 240 },
243 tx_dma: ChannelAndRequest { 241 tx_dma: ChannelAndRequest {
244 channel: tx_dma.map_into(), 242 channel: tx_dma.into(),
245 request: tx_dma_req, 243 request: tx_dma_req,
246 }, 244 },
247 }, 245 },
@@ -689,7 +687,7 @@ trait SealedInstance {
689 687
690/// UCPD instance trait. 688/// UCPD instance trait.
691#[allow(private_bounds)] 689#[allow(private_bounds)]
692pub trait Instance: SealedInstance + RccPeripheral { 690pub trait Instance: SealedInstance + PeripheralType + RccPeripheral {
693 /// Interrupt for this instance. 691 /// Interrupt for this instance.
694 type Interrupt: crate::interrupt::typelevel::Interrupt; 692 type Interrupt: crate::interrupt::typelevel::Interrupt;
695} 693}
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 7fa9ee08e..b1640b6dc 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -6,7 +6,7 @@ use core::task::Poll;
6 6
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
8use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 8use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
9use embassy_hal_internal::{Peripheral, PeripheralRef}; 9use embassy_hal_internal::Peri;
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12#[cfg(not(any(usart_v1, usart_v2)))] 12#[cfg(not(any(usart_v1, usart_v2)))]
@@ -159,9 +159,9 @@ pub struct BufferedUartTx<'d> {
159 info: &'static Info, 159 info: &'static Info,
160 state: &'static State, 160 state: &'static State,
161 kernel_clock: Hertz, 161 kernel_clock: Hertz,
162 tx: Option<PeripheralRef<'d, AnyPin>>, 162 tx: Option<Peri<'d, AnyPin>>,
163 cts: Option<PeripheralRef<'d, AnyPin>>, 163 cts: Option<Peri<'d, AnyPin>>,
164 de: Option<PeripheralRef<'d, AnyPin>>, 164 de: Option<Peri<'d, AnyPin>>,
165 is_borrowed: bool, 165 is_borrowed: bool,
166} 166}
167 167
@@ -172,8 +172,8 @@ pub struct BufferedUartRx<'d> {
172 info: &'static Info, 172 info: &'static Info,
173 state: &'static State, 173 state: &'static State,
174 kernel_clock: Hertz, 174 kernel_clock: Hertz,
175 rx: Option<PeripheralRef<'d, AnyPin>>, 175 rx: Option<Peri<'d, AnyPin>>,
176 rts: Option<PeripheralRef<'d, AnyPin>>, 176 rts: Option<Peri<'d, AnyPin>>,
177 is_borrowed: bool, 177 is_borrowed: bool,
178} 178}
179 179
@@ -207,10 +207,10 @@ impl<'d> SetConfig for BufferedUartTx<'d> {
207impl<'d> BufferedUart<'d> { 207impl<'d> BufferedUart<'d> {
208 /// Create a new bidirectional buffered UART driver 208 /// Create a new bidirectional buffered UART driver
209 pub fn new<T: Instance>( 209 pub fn new<T: Instance>(
210 peri: impl Peripheral<P = T> + 'd, 210 peri: Peri<'d, T>,
211 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 211 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
212 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 212 rx: Peri<'d, impl RxPin<T>>,
213 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 213 tx: Peri<'d, impl TxPin<T>>,
214 tx_buffer: &'d mut [u8], 214 tx_buffer: &'d mut [u8],
215 rx_buffer: &'d mut [u8], 215 rx_buffer: &'d mut [u8],
216 config: Config, 216 config: Config,
@@ -230,12 +230,12 @@ impl<'d> BufferedUart<'d> {
230 230
231 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins 231 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
232 pub fn new_with_rtscts<T: Instance>( 232 pub fn new_with_rtscts<T: Instance>(
233 peri: impl Peripheral<P = T> + 'd, 233 peri: Peri<'d, T>,
234 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 234 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
235 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 235 rx: Peri<'d, impl RxPin<T>>,
236 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 236 tx: Peri<'d, impl TxPin<T>>,
237 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 237 rts: Peri<'d, impl RtsPin<T>>,
238 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 238 cts: Peri<'d, impl CtsPin<T>>,
239 tx_buffer: &'d mut [u8], 239 tx_buffer: &'d mut [u8],
240 rx_buffer: &'d mut [u8], 240 rx_buffer: &'d mut [u8],
241 config: Config, 241 config: Config,
@@ -255,11 +255,11 @@ impl<'d> BufferedUart<'d> {
255 255
256 /// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin 256 /// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin
257 pub fn new_with_rts_as_de<T: Instance>( 257 pub fn new_with_rts_as_de<T: Instance>(
258 peri: impl Peripheral<P = T> + 'd, 258 peri: Peri<'d, T>,
259 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 259 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
260 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 260 rx: Peri<'d, impl RxPin<T>>,
261 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 261 tx: Peri<'d, impl TxPin<T>>,
262 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 262 rts: Peri<'d, impl RtsPin<T>>,
263 tx_buffer: &'d mut [u8], 263 tx_buffer: &'d mut [u8],
264 rx_buffer: &'d mut [u8], 264 rx_buffer: &'d mut [u8],
265 config: Config, 265 config: Config,
@@ -279,11 +279,11 @@ impl<'d> BufferedUart<'d> {
279 279
280 /// Create a new bidirectional buffered UART driver with only the request-to-send pin 280 /// Create a new bidirectional buffered UART driver with only the request-to-send pin
281 pub fn new_with_rts<T: Instance>( 281 pub fn new_with_rts<T: Instance>(
282 peri: impl Peripheral<P = T> + 'd, 282 peri: Peri<'d, T>,
283 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 283 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
284 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 284 rx: Peri<'d, impl RxPin<T>>,
285 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 285 tx: Peri<'d, impl TxPin<T>>,
286 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 286 rts: Peri<'d, impl RtsPin<T>>,
287 tx_buffer: &'d mut [u8], 287 tx_buffer: &'d mut [u8],
288 rx_buffer: &'d mut [u8], 288 rx_buffer: &'d mut [u8],
289 config: Config, 289 config: Config,
@@ -304,11 +304,11 @@ impl<'d> BufferedUart<'d> {
304 /// Create a new bidirectional buffered UART driver with a driver-enable pin 304 /// Create a new bidirectional buffered UART driver with a driver-enable pin
305 #[cfg(not(any(usart_v1, usart_v2)))] 305 #[cfg(not(any(usart_v1, usart_v2)))]
306 pub fn new_with_de<T: Instance>( 306 pub fn new_with_de<T: Instance>(
307 peri: impl Peripheral<P = T> + 'd, 307 peri: Peri<'d, T>,
308 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 308 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
309 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 309 rx: Peri<'d, impl RxPin<T>>,
310 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 310 tx: Peri<'d, impl TxPin<T>>,
311 de: impl Peripheral<P = impl DePin<T>> + 'd, 311 de: Peri<'d, impl DePin<T>>,
312 tx_buffer: &'d mut [u8], 312 tx_buffer: &'d mut [u8],
313 rx_buffer: &'d mut [u8], 313 rx_buffer: &'d mut [u8],
314 config: Config, 314 config: Config,
@@ -339,8 +339,8 @@ impl<'d> BufferedUart<'d> {
339 /// on the line must be managed by software (for instance by using a centralized arbiter). 339 /// on the line must be managed by software (for instance by using a centralized arbiter).
340 #[doc(alias("HDSEL"))] 340 #[doc(alias("HDSEL"))]
341 pub fn new_half_duplex<T: Instance>( 341 pub fn new_half_duplex<T: Instance>(
342 peri: impl Peripheral<P = T> + 'd, 342 peri: Peri<'d, T>,
343 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 343 tx: Peri<'d, impl TxPin<T>>,
344 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 344 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
345 tx_buffer: &'d mut [u8], 345 tx_buffer: &'d mut [u8],
346 rx_buffer: &'d mut [u8], 346 rx_buffer: &'d mut [u8],
@@ -379,8 +379,8 @@ impl<'d> BufferedUart<'d> {
379 #[cfg(not(any(usart_v1, usart_v2)))] 379 #[cfg(not(any(usart_v1, usart_v2)))]
380 #[doc(alias("HDSEL"))] 380 #[doc(alias("HDSEL"))]
381 pub fn new_half_duplex_on_rx<T: Instance>( 381 pub fn new_half_duplex_on_rx<T: Instance>(
382 peri: impl Peripheral<P = T> + 'd, 382 peri: Peri<'d, T>,
383 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 383 rx: Peri<'d, impl RxPin<T>>,
384 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 384 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
385 tx_buffer: &'d mut [u8], 385 tx_buffer: &'d mut [u8],
386 rx_buffer: &'d mut [u8], 386 rx_buffer: &'d mut [u8],
@@ -405,12 +405,12 @@ impl<'d> BufferedUart<'d> {
405 } 405 }
406 406
407 fn new_inner<T: Instance>( 407 fn new_inner<T: Instance>(
408 _peri: impl Peripheral<P = T> + 'd, 408 _peri: Peri<'d, T>,
409 rx: Option<PeripheralRef<'d, AnyPin>>, 409 rx: Option<Peri<'d, AnyPin>>,
410 tx: Option<PeripheralRef<'d, AnyPin>>, 410 tx: Option<Peri<'d, AnyPin>>,
411 rts: Option<PeripheralRef<'d, AnyPin>>, 411 rts: Option<Peri<'d, AnyPin>>,
412 cts: Option<PeripheralRef<'d, AnyPin>>, 412 cts: Option<Peri<'d, AnyPin>>,
413 de: Option<PeripheralRef<'d, AnyPin>>, 413 de: Option<Peri<'d, AnyPin>>,
414 tx_buffer: &'d mut [u8], 414 tx_buffer: &'d mut [u8],
415 rx_buffer: &'d mut [u8], 415 rx_buffer: &'d mut [u8],
416 config: Config, 416 config: Config,
@@ -505,17 +505,17 @@ impl<'d> BufferedUart<'d> {
505 info: self.tx.info, 505 info: self.tx.info,
506 state: self.tx.state, 506 state: self.tx.state,
507 kernel_clock: self.tx.kernel_clock, 507 kernel_clock: self.tx.kernel_clock,
508 tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow), 508 tx: self.tx.tx.as_mut().map(Peri::reborrow),
509 cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow), 509 cts: self.tx.cts.as_mut().map(Peri::reborrow),
510 de: self.tx.de.as_mut().map(PeripheralRef::reborrow), 510 de: self.tx.de.as_mut().map(Peri::reborrow),
511 is_borrowed: true, 511 is_borrowed: true,
512 }, 512 },
513 BufferedUartRx { 513 BufferedUartRx {
514 info: self.rx.info, 514 info: self.rx.info,
515 state: self.rx.state, 515 state: self.rx.state,
516 kernel_clock: self.rx.kernel_clock, 516 kernel_clock: self.rx.kernel_clock,
517 rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow), 517 rx: self.rx.rx.as_mut().map(Peri::reborrow),
518 rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow), 518 rts: self.rx.rts.as_mut().map(Peri::reborrow),
519 is_borrowed: true, 519 is_borrowed: true,
520 }, 520 },
521 ) 521 )
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 803a5d579..5b7f8dc26 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -9,7 +9,7 @@ use core::task::Poll;
9 9
10use embassy_embedded_hal::SetConfig; 10use embassy_embedded_hal::SetConfig;
11use embassy_hal_internal::drop::OnDrop; 11use embassy_hal_internal::drop::OnDrop;
12use embassy_hal_internal::PeripheralRef; 12use embassy_hal_internal::PeripheralType;
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14use futures_util::future::{select, Either}; 14use futures_util::future::{select, Either};
15 15
@@ -25,7 +25,7 @@ use crate::pac::usart::Usart as Regs;
25use crate::pac::usart::{regs, vals}; 25use crate::pac::usart::{regs, vals};
26use crate::rcc::{RccInfo, SealedRccPeripheral}; 26use crate::rcc::{RccInfo, SealedRccPeripheral};
27use crate::time::Hertz; 27use crate::time::Hertz;
28use crate::Peripheral; 28use crate::Peri;
29 29
30/// Interrupt handler. 30/// Interrupt handler.
31pub struct InterruptHandler<T: Instance> { 31pub struct InterruptHandler<T: Instance> {
@@ -343,9 +343,9 @@ pub struct UartTx<'d, M: Mode> {
343 info: &'static Info, 343 info: &'static Info,
344 state: &'static State, 344 state: &'static State,
345 kernel_clock: Hertz, 345 kernel_clock: Hertz,
346 tx: Option<PeripheralRef<'d, AnyPin>>, 346 tx: Option<Peri<'d, AnyPin>>,
347 cts: Option<PeripheralRef<'d, AnyPin>>, 347 cts: Option<Peri<'d, AnyPin>>,
348 de: Option<PeripheralRef<'d, AnyPin>>, 348 de: Option<Peri<'d, AnyPin>>,
349 tx_dma: Option<ChannelAndRequest<'d>>, 349 tx_dma: Option<ChannelAndRequest<'d>>,
350 duplex: Duplex, 350 duplex: Duplex,
351 _phantom: PhantomData<M>, 351 _phantom: PhantomData<M>,
@@ -393,8 +393,8 @@ pub struct UartRx<'d, M: Mode> {
393 info: &'static Info, 393 info: &'static Info,
394 state: &'static State, 394 state: &'static State,
395 kernel_clock: Hertz, 395 kernel_clock: Hertz,
396 rx: Option<PeripheralRef<'d, AnyPin>>, 396 rx: Option<Peri<'d, AnyPin>>,
397 rts: Option<PeripheralRef<'d, AnyPin>>, 397 rts: Option<Peri<'d, AnyPin>>,
398 rx_dma: Option<ChannelAndRequest<'d>>, 398 rx_dma: Option<ChannelAndRequest<'d>>,
399 detect_previous_overrun: bool, 399 detect_previous_overrun: bool,
400 #[cfg(any(usart_v1, usart_v2))] 400 #[cfg(any(usart_v1, usart_v2))]
@@ -414,9 +414,9 @@ impl<'d, M: Mode> SetConfig for UartRx<'d, M> {
414impl<'d> UartTx<'d, Async> { 414impl<'d> UartTx<'d, Async> {
415 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. 415 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
416 pub fn new<T: Instance>( 416 pub fn new<T: Instance>(
417 peri: impl Peripheral<P = T> + 'd, 417 peri: Peri<'d, T>,
418 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 418 tx: Peri<'d, impl TxPin<T>>,
419 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 419 tx_dma: Peri<'d, impl TxDma<T>>,
420 config: Config, 420 config: Config,
421 ) -> Result<Self, ConfigError> { 421 ) -> Result<Self, ConfigError> {
422 Self::new_inner( 422 Self::new_inner(
@@ -430,10 +430,10 @@ impl<'d> UartTx<'d, Async> {
430 430
431 /// Create a new tx-only UART with a clear-to-send pin 431 /// Create a new tx-only UART with a clear-to-send pin
432 pub fn new_with_cts<T: Instance>( 432 pub fn new_with_cts<T: Instance>(
433 peri: impl Peripheral<P = T> + 'd, 433 peri: Peri<'d, T>,
434 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 434 tx: Peri<'d, impl TxPin<T>>,
435 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 435 cts: Peri<'d, impl CtsPin<T>>,
436 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 436 tx_dma: Peri<'d, impl TxDma<T>>,
437 config: Config, 437 config: Config,
438 ) -> Result<Self, ConfigError> { 438 ) -> Result<Self, ConfigError> {
439 Self::new_inner( 439 Self::new_inner(
@@ -473,8 +473,8 @@ impl<'d> UartTx<'d, Blocking> {
473 /// 473 ///
474 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. 474 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
475 pub fn new_blocking<T: Instance>( 475 pub fn new_blocking<T: Instance>(
476 peri: impl Peripheral<P = T> + 'd, 476 peri: Peri<'d, T>,
477 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 477 tx: Peri<'d, impl TxPin<T>>,
478 config: Config, 478 config: Config,
479 ) -> Result<Self, ConfigError> { 479 ) -> Result<Self, ConfigError> {
480 Self::new_inner( 480 Self::new_inner(
@@ -488,9 +488,9 @@ impl<'d> UartTx<'d, Blocking> {
488 488
489 /// Create a new blocking tx-only UART with a clear-to-send pin 489 /// Create a new blocking tx-only UART with a clear-to-send pin
490 pub fn new_blocking_with_cts<T: Instance>( 490 pub fn new_blocking_with_cts<T: Instance>(
491 peri: impl Peripheral<P = T> + 'd, 491 peri: Peri<'d, T>,
492 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 492 tx: Peri<'d, impl TxPin<T>>,
493 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 493 cts: Peri<'d, impl CtsPin<T>>,
494 config: Config, 494 config: Config,
495 ) -> Result<Self, ConfigError> { 495 ) -> Result<Self, ConfigError> {
496 Self::new_inner( 496 Self::new_inner(
@@ -505,9 +505,9 @@ impl<'d> UartTx<'d, Blocking> {
505 505
506impl<'d, M: Mode> UartTx<'d, M> { 506impl<'d, M: Mode> UartTx<'d, M> {
507 fn new_inner<T: Instance>( 507 fn new_inner<T: Instance>(
508 _peri: impl Peripheral<P = T> + 'd, 508 _peri: Peri<'d, T>,
509 tx: Option<PeripheralRef<'d, AnyPin>>, 509 tx: Option<Peri<'d, AnyPin>>,
510 cts: Option<PeripheralRef<'d, AnyPin>>, 510 cts: Option<Peri<'d, AnyPin>>,
511 tx_dma: Option<ChannelAndRequest<'d>>, 511 tx_dma: Option<ChannelAndRequest<'d>>,
512 config: Config, 512 config: Config,
513 ) -> Result<Self, ConfigError> { 513 ) -> Result<Self, ConfigError> {
@@ -645,10 +645,10 @@ impl<'d> UartRx<'d, Async> {
645 /// 645 ///
646 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. 646 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
647 pub fn new<T: Instance>( 647 pub fn new<T: Instance>(
648 peri: impl Peripheral<P = T> + 'd, 648 peri: Peri<'d, T>,
649 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 649 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
650 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 650 rx: Peri<'d, impl RxPin<T>>,
651 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 651 rx_dma: Peri<'d, impl RxDma<T>>,
652 config: Config, 652 config: Config,
653 ) -> Result<Self, ConfigError> { 653 ) -> Result<Self, ConfigError> {
654 Self::new_inner( 654 Self::new_inner(
@@ -662,11 +662,11 @@ impl<'d> UartRx<'d, Async> {
662 662
663 /// Create a new rx-only UART with a request-to-send pin 663 /// Create a new rx-only UART with a request-to-send pin
664 pub fn new_with_rts<T: Instance>( 664 pub fn new_with_rts<T: Instance>(
665 peri: impl Peripheral<P = T> + 'd, 665 peri: Peri<'d, T>,
666 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 666 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
667 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 667 rx: Peri<'d, impl RxPin<T>>,
668 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 668 rts: Peri<'d, impl RtsPin<T>>,
669 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 669 rx_dma: Peri<'d, impl RxDma<T>>,
670 config: Config, 670 config: Config,
671 ) -> Result<Self, ConfigError> { 671 ) -> Result<Self, ConfigError> {
672 Self::new_inner( 672 Self::new_inner(
@@ -903,8 +903,8 @@ impl<'d> UartRx<'d, Blocking> {
903 /// 903 ///
904 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. 904 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
905 pub fn new_blocking<T: Instance>( 905 pub fn new_blocking<T: Instance>(
906 peri: impl Peripheral<P = T> + 'd, 906 peri: Peri<'d, T>,
907 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 907 rx: Peri<'d, impl RxPin<T>>,
908 config: Config, 908 config: Config,
909 ) -> Result<Self, ConfigError> { 909 ) -> Result<Self, ConfigError> {
910 Self::new_inner(peri, new_pin!(rx, AfType::input(config.rx_pull)), None, None, config) 910 Self::new_inner(peri, new_pin!(rx, AfType::input(config.rx_pull)), None, None, config)
@@ -912,9 +912,9 @@ impl<'d> UartRx<'d, Blocking> {
912 912
913 /// Create a new rx-only UART with a request-to-send pin 913 /// Create a new rx-only UART with a request-to-send pin
914 pub fn new_blocking_with_rts<T: Instance>( 914 pub fn new_blocking_with_rts<T: Instance>(
915 peri: impl Peripheral<P = T> + 'd, 915 peri: Peri<'d, T>,
916 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 916 rx: Peri<'d, impl RxPin<T>>,
917 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 917 rts: Peri<'d, impl RtsPin<T>>,
918 config: Config, 918 config: Config,
919 ) -> Result<Self, ConfigError> { 919 ) -> Result<Self, ConfigError> {
920 Self::new_inner( 920 Self::new_inner(
@@ -929,9 +929,9 @@ impl<'d> UartRx<'d, Blocking> {
929 929
930impl<'d, M: Mode> UartRx<'d, M> { 930impl<'d, M: Mode> UartRx<'d, M> {
931 fn new_inner<T: Instance>( 931 fn new_inner<T: Instance>(
932 _peri: impl Peripheral<P = T> + 'd, 932 _peri: Peri<'d, T>,
933 rx: Option<PeripheralRef<'d, AnyPin>>, 933 rx: Option<Peri<'d, AnyPin>>,
934 rts: Option<PeripheralRef<'d, AnyPin>>, 934 rts: Option<Peri<'d, AnyPin>>,
935 rx_dma: Option<ChannelAndRequest<'d>>, 935 rx_dma: Option<ChannelAndRequest<'d>>,
936 config: Config, 936 config: Config,
937 ) -> Result<Self, ConfigError> { 937 ) -> Result<Self, ConfigError> {
@@ -1099,12 +1099,12 @@ fn drop_tx_rx(info: &Info, state: &State) {
1099impl<'d> Uart<'d, Async> { 1099impl<'d> Uart<'d, Async> {
1100 /// Create a new bidirectional UART 1100 /// Create a new bidirectional UART
1101 pub fn new<T: Instance>( 1101 pub fn new<T: Instance>(
1102 peri: impl Peripheral<P = T> + 'd, 1102 peri: Peri<'d, T>,
1103 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1103 rx: Peri<'d, impl RxPin<T>>,
1104 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1104 tx: Peri<'d, impl TxPin<T>>,
1105 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1105 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1106 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 1106 tx_dma: Peri<'d, impl TxDma<T>>,
1107 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 1107 rx_dma: Peri<'d, impl RxDma<T>>,
1108 config: Config, 1108 config: Config,
1109 ) -> Result<Self, ConfigError> { 1109 ) -> Result<Self, ConfigError> {
1110 Self::new_inner( 1110 Self::new_inner(
@@ -1122,14 +1122,14 @@ impl<'d> Uart<'d, Async> {
1122 1122
1123 /// Create a new bidirectional UART with request-to-send and clear-to-send pins 1123 /// Create a new bidirectional UART with request-to-send and clear-to-send pins
1124 pub fn new_with_rtscts<T: Instance>( 1124 pub fn new_with_rtscts<T: Instance>(
1125 peri: impl Peripheral<P = T> + 'd, 1125 peri: Peri<'d, T>,
1126 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1126 rx: Peri<'d, impl RxPin<T>>,
1127 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1127 tx: Peri<'d, impl TxPin<T>>,
1128 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1128 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1129 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 1129 rts: Peri<'d, impl RtsPin<T>>,
1130 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 1130 cts: Peri<'d, impl CtsPin<T>>,
1131 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 1131 tx_dma: Peri<'d, impl TxDma<T>>,
1132 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 1132 rx_dma: Peri<'d, impl RxDma<T>>,
1133 config: Config, 1133 config: Config,
1134 ) -> Result<Self, ConfigError> { 1134 ) -> Result<Self, ConfigError> {
1135 Self::new_inner( 1135 Self::new_inner(
@@ -1148,13 +1148,13 @@ impl<'d> Uart<'d, Async> {
1148 #[cfg(not(any(usart_v1, usart_v2)))] 1148 #[cfg(not(any(usart_v1, usart_v2)))]
1149 /// Create a new bidirectional UART with a driver-enable pin 1149 /// Create a new bidirectional UART with a driver-enable pin
1150 pub fn new_with_de<T: Instance>( 1150 pub fn new_with_de<T: Instance>(
1151 peri: impl Peripheral<P = T> + 'd, 1151 peri: Peri<'d, T>,
1152 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1152 rx: Peri<'d, impl RxPin<T>>,
1153 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1153 tx: Peri<'d, impl TxPin<T>>,
1154 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1154 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1155 de: impl Peripheral<P = impl DePin<T>> + 'd, 1155 de: Peri<'d, impl DePin<T>>,
1156 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 1156 tx_dma: Peri<'d, impl TxDma<T>>,
1157 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 1157 rx_dma: Peri<'d, impl RxDma<T>>,
1158 config: Config, 1158 config: Config,
1159 ) -> Result<Self, ConfigError> { 1159 ) -> Result<Self, ConfigError> {
1160 Self::new_inner( 1160 Self::new_inner(
@@ -1183,11 +1183,11 @@ impl<'d> Uart<'d, Async> {
1183 /// on the line must be managed by software (for instance by using a centralized arbiter). 1183 /// on the line must be managed by software (for instance by using a centralized arbiter).
1184 #[doc(alias("HDSEL"))] 1184 #[doc(alias("HDSEL"))]
1185 pub fn new_half_duplex<T: Instance>( 1185 pub fn new_half_duplex<T: Instance>(
1186 peri: impl Peripheral<P = T> + 'd, 1186 peri: Peri<'d, T>,
1187 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1187 tx: Peri<'d, impl TxPin<T>>,
1188 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1188 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1189 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 1189 tx_dma: Peri<'d, impl TxDma<T>>,
1190 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 1190 rx_dma: Peri<'d, impl RxDma<T>>,
1191 mut config: Config, 1191 mut config: Config,
1192 readback: HalfDuplexReadback, 1192 readback: HalfDuplexReadback,
1193 half_duplex: HalfDuplexConfig, 1193 half_duplex: HalfDuplexConfig,
@@ -1223,11 +1223,11 @@ impl<'d> Uart<'d, Async> {
1223 #[cfg(not(any(usart_v1, usart_v2)))] 1223 #[cfg(not(any(usart_v1, usart_v2)))]
1224 #[doc(alias("HDSEL"))] 1224 #[doc(alias("HDSEL"))]
1225 pub fn new_half_duplex_on_rx<T: Instance>( 1225 pub fn new_half_duplex_on_rx<T: Instance>(
1226 peri: impl Peripheral<P = T> + 'd, 1226 peri: Peri<'d, T>,
1227 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1227 rx: Peri<'d, impl RxPin<T>>,
1228 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1228 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1229 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 1229 tx_dma: Peri<'d, impl TxDma<T>>,
1230 rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, 1230 rx_dma: Peri<'d, impl RxDma<T>>,
1231 mut config: Config, 1231 mut config: Config,
1232 readback: HalfDuplexReadback, 1232 readback: HalfDuplexReadback,
1233 half_duplex: HalfDuplexConfig, 1233 half_duplex: HalfDuplexConfig,
@@ -1272,9 +1272,9 @@ impl<'d> Uart<'d, Async> {
1272impl<'d> Uart<'d, Blocking> { 1272impl<'d> Uart<'d, Blocking> {
1273 /// Create a new blocking bidirectional UART. 1273 /// Create a new blocking bidirectional UART.
1274 pub fn new_blocking<T: Instance>( 1274 pub fn new_blocking<T: Instance>(
1275 peri: impl Peripheral<P = T> + 'd, 1275 peri: Peri<'d, T>,
1276 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1276 rx: Peri<'d, impl RxPin<T>>,
1277 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1277 tx: Peri<'d, impl TxPin<T>>,
1278 config: Config, 1278 config: Config,
1279 ) -> Result<Self, ConfigError> { 1279 ) -> Result<Self, ConfigError> {
1280 Self::new_inner( 1280 Self::new_inner(
@@ -1292,11 +1292,11 @@ impl<'d> Uart<'d, Blocking> {
1292 1292
1293 /// Create a new bidirectional UART with request-to-send and clear-to-send pins 1293 /// Create a new bidirectional UART with request-to-send and clear-to-send pins
1294 pub fn new_blocking_with_rtscts<T: Instance>( 1294 pub fn new_blocking_with_rtscts<T: Instance>(
1295 peri: impl Peripheral<P = T> + 'd, 1295 peri: Peri<'d, T>,
1296 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1296 rx: Peri<'d, impl RxPin<T>>,
1297 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1297 tx: Peri<'d, impl TxPin<T>>,
1298 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 1298 rts: Peri<'d, impl RtsPin<T>>,
1299 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 1299 cts: Peri<'d, impl CtsPin<T>>,
1300 config: Config, 1300 config: Config,
1301 ) -> Result<Self, ConfigError> { 1301 ) -> Result<Self, ConfigError> {
1302 Self::new_inner( 1302 Self::new_inner(
@@ -1315,10 +1315,10 @@ impl<'d> Uart<'d, Blocking> {
1315 #[cfg(not(any(usart_v1, usart_v2)))] 1315 #[cfg(not(any(usart_v1, usart_v2)))]
1316 /// Create a new bidirectional UART with a driver-enable pin 1316 /// Create a new bidirectional UART with a driver-enable pin
1317 pub fn new_blocking_with_de<T: Instance>( 1317 pub fn new_blocking_with_de<T: Instance>(
1318 peri: impl Peripheral<P = T> + 'd, 1318 peri: Peri<'d, T>,
1319 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1319 rx: Peri<'d, impl RxPin<T>>,
1320 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1320 tx: Peri<'d, impl TxPin<T>>,
1321 de: impl Peripheral<P = impl DePin<T>> + 'd, 1321 de: Peri<'d, impl DePin<T>>,
1322 config: Config, 1322 config: Config,
1323 ) -> Result<Self, ConfigError> { 1323 ) -> Result<Self, ConfigError> {
1324 Self::new_inner( 1324 Self::new_inner(
@@ -1346,8 +1346,8 @@ impl<'d> Uart<'d, Blocking> {
1346 /// on the line must be managed by software (for instance by using a centralized arbiter). 1346 /// on the line must be managed by software (for instance by using a centralized arbiter).
1347 #[doc(alias("HDSEL"))] 1347 #[doc(alias("HDSEL"))]
1348 pub fn new_blocking_half_duplex<T: Instance>( 1348 pub fn new_blocking_half_duplex<T: Instance>(
1349 peri: impl Peripheral<P = T> + 'd, 1349 peri: Peri<'d, T>,
1350 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1350 tx: Peri<'d, impl TxPin<T>>,
1351 mut config: Config, 1351 mut config: Config,
1352 readback: HalfDuplexReadback, 1352 readback: HalfDuplexReadback,
1353 half_duplex: HalfDuplexConfig, 1353 half_duplex: HalfDuplexConfig,
@@ -1383,8 +1383,8 @@ impl<'d> Uart<'d, Blocking> {
1383 #[cfg(not(any(usart_v1, usart_v2)))] 1383 #[cfg(not(any(usart_v1, usart_v2)))]
1384 #[doc(alias("HDSEL"))] 1384 #[doc(alias("HDSEL"))]
1385 pub fn new_blocking_half_duplex_on_rx<T: Instance>( 1385 pub fn new_blocking_half_duplex_on_rx<T: Instance>(
1386 peri: impl Peripheral<P = T> + 'd, 1386 peri: Peri<'d, T>,
1387 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1387 rx: Peri<'d, impl RxPin<T>>,
1388 mut config: Config, 1388 mut config: Config,
1389 readback: HalfDuplexReadback, 1389 readback: HalfDuplexReadback,
1390 half_duplex: HalfDuplexConfig, 1390 half_duplex: HalfDuplexConfig,
@@ -1408,12 +1408,12 @@ impl<'d> Uart<'d, Blocking> {
1408 1408
1409impl<'d, M: Mode> Uart<'d, M> { 1409impl<'d, M: Mode> Uart<'d, M> {
1410 fn new_inner<T: Instance>( 1410 fn new_inner<T: Instance>(
1411 _peri: impl Peripheral<P = T> + 'd, 1411 _peri: Peri<'d, T>,
1412 rx: Option<PeripheralRef<'d, AnyPin>>, 1412 rx: Option<Peri<'d, AnyPin>>,
1413 tx: Option<PeripheralRef<'d, AnyPin>>, 1413 tx: Option<Peri<'d, AnyPin>>,
1414 rts: Option<PeripheralRef<'d, AnyPin>>, 1414 rts: Option<Peri<'d, AnyPin>>,
1415 cts: Option<PeripheralRef<'d, AnyPin>>, 1415 cts: Option<Peri<'d, AnyPin>>,
1416 de: Option<PeripheralRef<'d, AnyPin>>, 1416 de: Option<Peri<'d, AnyPin>>,
1417 tx_dma: Option<ChannelAndRequest<'d>>, 1417 tx_dma: Option<ChannelAndRequest<'d>>,
1418 rx_dma: Option<ChannelAndRequest<'d>>, 1418 rx_dma: Option<ChannelAndRequest<'d>>,
1419 config: Config, 1419 config: Config,
@@ -2045,7 +2045,7 @@ pub(crate) trait SealedInstance: crate::rcc::RccPeripheral {
2045 2045
2046/// USART peripheral instance trait. 2046/// USART peripheral instance trait.
2047#[allow(private_bounds)] 2047#[allow(private_bounds)]
2048pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { 2048pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
2049 /// Interrupt for this peripheral. 2049 /// Interrupt for this peripheral.
2050 type Interrupt: interrupt::typelevel::Interrupt; 2050 type Interrupt: interrupt::typelevel::Interrupt;
2051} 2051}
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index 69423c940..8e42d5917 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -4,7 +4,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
7use embassy_hal_internal::PeripheralRef;
8use embedded_io_async::ReadReady; 7use embedded_io_async::ReadReady;
9use futures_util::future::{select, Either}; 8use futures_util::future::{select, Either};
10 9
@@ -14,6 +13,7 @@ use crate::gpio::{AnyPin, SealedPin as _};
14use crate::mode::Async; 13use crate::mode::Async;
15use crate::time::Hertz; 14use crate::time::Hertz;
16use crate::usart::Regs; 15use crate::usart::Regs;
16use crate::Peri;
17 17
18/// Rx-only Ring-buffered UART Driver 18/// Rx-only Ring-buffered UART Driver
19/// 19///
@@ -22,8 +22,8 @@ pub struct RingBufferedUartRx<'d> {
22 info: &'static Info, 22 info: &'static Info,
23 state: &'static State, 23 state: &'static State,
24 kernel_clock: Hertz, 24 kernel_clock: Hertz,
25 rx: Option<PeripheralRef<'d, AnyPin>>, 25 rx: Option<Peri<'d, AnyPin>>,
26 rts: Option<PeripheralRef<'d, AnyPin>>, 26 rts: Option<Peri<'d, AnyPin>>,
27 ring_buf: ReadableRingBuffer<'d, u8>, 27 ring_buf: ReadableRingBuffer<'d, u8>,
28} 28}
29 29
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index d3c7978e4..51429b8cc 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_internal::{into_ref, Peripheral}; 3use embassy_hal_internal::PeripheralType;
4use embassy_usb_driver::{EndpointAddress, EndpointAllocError, EndpointType, Event, Unsupported}; 4use embassy_usb_driver::{EndpointAddress, EndpointAllocError, EndpointType, Event, Unsupported};
5use embassy_usb_synopsys_otg::otg_v1::vals::Dspd; 5use embassy_usb_synopsys_otg::otg_v1::vals::Dspd;
6use embassy_usb_synopsys_otg::otg_v1::Otg; 6use embassy_usb_synopsys_otg::otg_v1::Otg;
@@ -11,9 +11,9 @@ use embassy_usb_synopsys_otg::{
11}; 11};
12 12
13use crate::gpio::{AfType, OutputType, Speed}; 13use crate::gpio::{AfType, OutputType, Speed};
14use crate::interrupt;
15use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
16use crate::rcc::{self, RccPeripheral}; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, Peri};
17 17
18const MAX_EP_COUNT: usize = 9; 18const MAX_EP_COUNT: usize = 9;
19 19
@@ -32,8 +32,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
32 32
33macro_rules! config_ulpi_pins { 33macro_rules! config_ulpi_pins {
34 ($($pin:ident),*) => { 34 ($($pin:ident),*) => {
35 into_ref!($($pin),*); 35 critical_section::with(|_| {
36 critical_section::with(|_| {
37 $( 36 $(
38 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 37 $pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
39 )* 38 )*
@@ -62,15 +61,13 @@ impl<'d, T: Instance> Driver<'d, T> {
62 /// Must be large enough to fit all OUT endpoint max packet sizes. 61 /// Must be large enough to fit all OUT endpoint max packet sizes.
63 /// Endpoint allocation will fail if it is too small. 62 /// Endpoint allocation will fail if it is too small.
64 pub fn new_fs( 63 pub fn new_fs(
65 _peri: impl Peripheral<P = T> + 'd, 64 _peri: Peri<'d, T>,
66 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 65 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
67 dp: impl Peripheral<P = impl DpPin<T>> + 'd, 66 dp: Peri<'d, impl DpPin<T>>,
68 dm: impl Peripheral<P = impl DmPin<T>> + 'd, 67 dm: Peri<'d, impl DmPin<T>>,
69 ep_out_buffer: &'d mut [u8], 68 ep_out_buffer: &'d mut [u8],
70 config: Config, 69 config: Config,
71 ) -> Self { 70 ) -> Self {
72 into_ref!(dp, dm);
73
74 dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 71 dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
75 dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 72 dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
76 73
@@ -100,17 +97,16 @@ impl<'d, T: Instance> Driver<'d, T> {
100 /// Must be large enough to fit all OUT endpoint max packet sizes. 97 /// Must be large enough to fit all OUT endpoint max packet sizes.
101 /// Endpoint allocation will fail if it is too small. 98 /// Endpoint allocation will fail if it is too small.
102 pub fn new_hs( 99 pub fn new_hs(
103 _peri: impl Peripheral<P = T> + 'd, 100 _peri: Peri<'d, T>,
104 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 101 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
105 _dp: impl Peripheral<P = impl DpPin<T>> + 'd, 102 _dp: Peri<'d, impl DpPin<T>>,
106 _dm: impl Peripheral<P = impl DmPin<T>> + 'd, 103 _dm: Peri<'d, impl DmPin<T>>,
107 ep_out_buffer: &'d mut [u8], 104 ep_out_buffer: &'d mut [u8],
108 config: Config, 105 config: Config,
109 ) -> Self { 106 ) -> Self {
110 // For STM32U5 High speed pins need to be left in analog mode 107 // For STM32U5 High speed pins need to be left in analog mode
111 #[cfg(not(all(stm32u5, peri_usb_otg_hs)))] 108 #[cfg(not(all(stm32u5, peri_usb_otg_hs)))]
112 { 109 {
113 into_ref!(_dp, _dm);
114 _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 110 _dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
115 _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 111 _dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
116 } 112 }
@@ -139,20 +135,20 @@ impl<'d, T: Instance> Driver<'d, T> {
139 /// Must be large enough to fit all OUT endpoint max packet sizes. 135 /// Must be large enough to fit all OUT endpoint max packet sizes.
140 /// Endpoint allocation will fail if it is too small. 136 /// Endpoint allocation will fail if it is too small.
141 pub fn new_fs_ulpi( 137 pub fn new_fs_ulpi(
142 _peri: impl Peripheral<P = T> + 'd, 138 _peri: Peri<'d, T>,
143 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 139 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
144 ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd, 140 ulpi_clk: Peri<'d, impl UlpiClkPin<T>>,
145 ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd, 141 ulpi_dir: Peri<'d, impl UlpiDirPin<T>>,
146 ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd, 142 ulpi_nxt: Peri<'d, impl UlpiNxtPin<T>>,
147 ulpi_stp: impl Peripheral<P = impl UlpiStpPin<T>> + 'd, 143 ulpi_stp: Peri<'d, impl UlpiStpPin<T>>,
148 ulpi_d0: impl Peripheral<P = impl UlpiD0Pin<T>> + 'd, 144 ulpi_d0: Peri<'d, impl UlpiD0Pin<T>>,
149 ulpi_d1: impl Peripheral<P = impl UlpiD1Pin<T>> + 'd, 145 ulpi_d1: Peri<'d, impl UlpiD1Pin<T>>,
150 ulpi_d2: impl Peripheral<P = impl UlpiD2Pin<T>> + 'd, 146 ulpi_d2: Peri<'d, impl UlpiD2Pin<T>>,
151 ulpi_d3: impl Peripheral<P = impl UlpiD3Pin<T>> + 'd, 147 ulpi_d3: Peri<'d, impl UlpiD3Pin<T>>,
152 ulpi_d4: impl Peripheral<P = impl UlpiD4Pin<T>> + 'd, 148 ulpi_d4: Peri<'d, impl UlpiD4Pin<T>>,
153 ulpi_d5: impl Peripheral<P = impl UlpiD5Pin<T>> + 'd, 149 ulpi_d5: Peri<'d, impl UlpiD5Pin<T>>,
154 ulpi_d6: impl Peripheral<P = impl UlpiD6Pin<T>> + 'd, 150 ulpi_d6: Peri<'d, impl UlpiD6Pin<T>>,
155 ulpi_d7: impl Peripheral<P = impl UlpiD7Pin<T>> + 'd, 151 ulpi_d7: Peri<'d, impl UlpiD7Pin<T>>,
156 ep_out_buffer: &'d mut [u8], 152 ep_out_buffer: &'d mut [u8],
157 config: Config, 153 config: Config,
158 ) -> Self { 154 ) -> Self {
@@ -185,20 +181,20 @@ impl<'d, T: Instance> Driver<'d, T> {
185 /// Must be large enough to fit all OUT endpoint max packet sizes. 181 /// Must be large enough to fit all OUT endpoint max packet sizes.
186 /// Endpoint allocation will fail if it is too small. 182 /// Endpoint allocation will fail if it is too small.
187 pub fn new_hs_ulpi( 183 pub fn new_hs_ulpi(
188 _peri: impl Peripheral<P = T> + 'd, 184 _peri: Peri<'d, T>,
189 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 185 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
190 ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd, 186 ulpi_clk: Peri<'d, impl UlpiClkPin<T>>,
191 ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd, 187 ulpi_dir: Peri<'d, impl UlpiDirPin<T>>,
192 ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd, 188 ulpi_nxt: Peri<'d, impl UlpiNxtPin<T>>,
193 ulpi_stp: impl Peripheral<P = impl UlpiStpPin<T>> + 'd, 189 ulpi_stp: Peri<'d, impl UlpiStpPin<T>>,
194 ulpi_d0: impl Peripheral<P = impl UlpiD0Pin<T>> + 'd, 190 ulpi_d0: Peri<'d, impl UlpiD0Pin<T>>,
195 ulpi_d1: impl Peripheral<P = impl UlpiD1Pin<T>> + 'd, 191 ulpi_d1: Peri<'d, impl UlpiD1Pin<T>>,
196 ulpi_d2: impl Peripheral<P = impl UlpiD2Pin<T>> + 'd, 192 ulpi_d2: Peri<'d, impl UlpiD2Pin<T>>,
197 ulpi_d3: impl Peripheral<P = impl UlpiD3Pin<T>> + 'd, 193 ulpi_d3: Peri<'d, impl UlpiD3Pin<T>>,
198 ulpi_d4: impl Peripheral<P = impl UlpiD4Pin<T>> + 'd, 194 ulpi_d4: Peri<'d, impl UlpiD4Pin<T>>,
199 ulpi_d5: impl Peripheral<P = impl UlpiD5Pin<T>> + 'd, 195 ulpi_d5: Peri<'d, impl UlpiD5Pin<T>>,
200 ulpi_d6: impl Peripheral<P = impl UlpiD6Pin<T>> + 'd, 196 ulpi_d6: Peri<'d, impl UlpiD6Pin<T>>,
201 ulpi_d7: impl Peripheral<P = impl UlpiD7Pin<T>> + 'd, 197 ulpi_d7: Peri<'d, impl UlpiD7Pin<T>>,
202 ep_out_buffer: &'d mut [u8], 198 ep_out_buffer: &'d mut [u8],
203 config: Config, 199 config: Config,
204 ) -> Self { 200 ) -> Self {
@@ -411,7 +407,7 @@ trait SealedInstance {
411 407
412/// USB instance trait. 408/// USB instance trait.
413#[allow(private_bounds)] 409#[allow(private_bounds)]
414pub trait Instance: SealedInstance + RccPeripheral + 'static { 410pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
415 /// Interrupt for this USB instance. 411 /// Interrupt for this USB instance.
416 type Interrupt: interrupt::typelevel::Interrupt; 412 type Interrupt: interrupt::typelevel::Interrupt;
417} 413}
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 24983cf3c..0b878915a 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomData;
5use core::sync::atomic::{AtomicBool, Ordering}; 5use core::sync::atomic::{AtomicBool, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::into_ref; 8use embassy_hal_internal::PeripheralType;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use embassy_usb_driver as driver; 10use embassy_usb_driver as driver;
11use embassy_usb_driver::{ 11use embassy_usb_driver::{
@@ -16,7 +16,7 @@ use crate::pac::usb::regs;
16use crate::pac::usb::vals::{EpType, Stat}; 16use crate::pac::usb::vals::{EpType, Stat};
17use crate::pac::USBRAM; 17use crate::pac::USBRAM;
18use crate::rcc::RccPeripheral; 18use crate::rcc::RccPeripheral;
19use crate::{interrupt, Peripheral}; 19use crate::{interrupt, Peri};
20 20
21/// Interrupt handler. 21/// Interrupt handler.
22pub struct InterruptHandler<T: Instance> { 22pub struct InterruptHandler<T: Instance> {
@@ -290,13 +290,12 @@ impl<'d, T: Instance> Driver<'d, T> {
290 /// Create a new USB driver with start-of-frame (SOF) output. 290 /// Create a new USB driver with start-of-frame (SOF) output.
291 #[cfg(not(stm32l1))] 291 #[cfg(not(stm32l1))]
292 pub fn new_with_sof( 292 pub fn new_with_sof(
293 _usb: impl Peripheral<P = T> + 'd, 293 _usb: Peri<'d, T>,
294 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 294 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
295 dp: impl Peripheral<P = impl DpPin<T>> + 'd, 295 dp: Peri<'d, impl DpPin<T>>,
296 dm: impl Peripheral<P = impl DmPin<T>> + 'd, 296 dm: Peri<'d, impl DmPin<T>>,
297 sof: impl Peripheral<P = impl SofPin<T>> + 'd, 297 sof: Peri<'d, impl SofPin<T>>,
298 ) -> Self { 298 ) -> Self {
299 into_ref!(sof);
300 { 299 {
301 use crate::gpio::{AfType, OutputType, Speed}; 300 use crate::gpio::{AfType, OutputType, Speed};
302 sof.set_as_af(sof.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh)); 301 sof.set_as_af(sof.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
@@ -307,13 +306,11 @@ impl<'d, T: Instance> Driver<'d, T> {
307 306
308 /// Create a new USB driver. 307 /// Create a new USB driver.
309 pub fn new( 308 pub fn new(
310 _usb: impl Peripheral<P = T> + 'd, 309 _usb: Peri<'d, T>,
311 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 310 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
312 dp: impl Peripheral<P = impl DpPin<T>> + 'd, 311 dp: Peri<'d, impl DpPin<T>>,
313 dm: impl Peripheral<P = impl DmPin<T>> + 'd, 312 dm: Peri<'d, impl DmPin<T>>,
314 ) -> Self { 313 ) -> Self {
315 into_ref!(dp, dm);
316
317 super::common_init::<T>(); 314 super::common_init::<T>();
318 315
319 let regs = T::regs(); 316 let regs = T::regs();
@@ -887,6 +884,16 @@ impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
887 }) 884 })
888 .await; 885 .await;
889 886
887 // Errata for STM32H5, 2.20.1:
888 // During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses
889 // have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct.
890 //
891 // Workaround:
892 // Software should ensure that a small delay is included before accessing the SRAM contents. This delay should be
893 // 800 ns in Full Speed mode and 6.4 μs in Low Speed mode.
894 #[cfg(stm32h5)]
895 embassy_time::block_for(embassy_time::Duration::from_nanos(800));
896
890 RX_COMPLETE[index].store(false, Ordering::Relaxed); 897 RX_COMPLETE[index].store(false, Ordering::Relaxed);
891 898
892 if stat == Stat::DISABLED { 899 if stat == Stat::DISABLED {
@@ -1226,7 +1233,7 @@ trait SealedInstance {
1226 1233
1227/// USB instance trait. 1234/// USB instance trait.
1228#[allow(private_bounds)] 1235#[allow(private_bounds)]
1229pub trait Instance: SealedInstance + RccPeripheral + 'static { 1236pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
1230 /// Interrupt for this USB instance. 1237 /// Interrupt for this USB instance.
1231 type Interrupt: interrupt::typelevel::Interrupt; 1238 type Interrupt: interrupt::typelevel::Interrupt;
1232} 1239}
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index ab21c4b6b..fb5c3d930 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -1,10 +1,11 @@
1//! Watchdog Timer (IWDG, WWDG) 1//! Watchdog Timer (IWDG, WWDG)
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3 3
4use embassy_hal_internal::{into_ref, Peripheral}; 4use embassy_hal_internal::PeripheralType;
5use stm32_metapac::iwdg::vals::{Key, Pr}; 5use stm32_metapac::iwdg::vals::{Key, Pr};
6 6
7use crate::rcc::LSI_FREQ; 7use crate::rcc::LSI_FREQ;
8use crate::Peri;
8 9
9/// Independent watchdog (IWDG) driver. 10/// Independent watchdog (IWDG) driver.
10pub struct IndependentWatchdog<'d, T: Instance> { 11pub struct IndependentWatchdog<'d, T: Instance> {
@@ -29,9 +30,7 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
29 /// 30 ///
30 /// [Self] has to be started with [Self::unleash()]. 31 /// [Self] has to be started with [Self::unleash()].
31 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval. 32 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval.
32 pub fn new(_instance: impl Peripheral<P = T> + 'd, timeout_us: u32) -> Self { 33 pub fn new(_instance: Peri<'d, T>, timeout_us: u32) -> Self {
33 into_ref!(_instance);
34
35 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout. 34 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
36 // This iterates from 4 (2^2) to 256 (2^8). 35 // This iterates from 4 (2^2) to 256 (2^8).
37 let psc_power = unwrap!((2..=8).find(|psc_power| { 36 let psc_power = unwrap!((2..=8).find(|psc_power| {
@@ -86,7 +85,7 @@ trait SealedInstance {
86 85
87/// IWDG instance trait. 86/// IWDG instance trait.
88#[allow(private_bounds)] 87#[allow(private_bounds)]
89pub trait Instance: SealedInstance {} 88pub trait Instance: SealedInstance + PeripheralType {}
90 89
91foreach_peripheral!( 90foreach_peripheral!(
92 (iwdg, $inst:ident) => { 91 (iwdg, $inst:ident) => {
diff --git a/embassy-sync/src/blocking_mutex/mod.rs b/embassy-sync/src/blocking_mutex/mod.rs
index beafdb43d..a41bc3569 100644
--- a/embassy-sync/src/blocking_mutex/mod.rs
+++ b/embassy-sync/src/blocking_mutex/mod.rs
@@ -50,6 +50,23 @@ impl<R: RawMutex, T> Mutex<R, T> {
50 f(inner) 50 f(inner)
51 }) 51 })
52 } 52 }
53
54 /// Creates a critical section and grants temporary mutable access to the protected data.
55 ///
56 /// # Safety
57 ///
58 /// This method is marked unsafe because calling this method re-entrantly, i.e. within
59 /// another `lock_mut` or `lock` closure, violates Rust's aliasing rules. Calling this
60 /// method at the same time from different tasks is safe. For a safe alternative with
61 /// mutable access that never causes UB, use a `RefCell` in a `Mutex`.
62 pub unsafe fn lock_mut<U>(&self, f: impl FnOnce(&mut T) -> U) -> U {
63 self.raw.lock(|| {
64 let ptr = self.data.get() as *mut T;
65 // Safety: we have exclusive access to the data, as long as this mutex is not locked re-entrantly
66 let inner = unsafe { &mut *ptr };
67 f(inner)
68 })
69 }
53} 70}
54 71
55impl<R, T> Mutex<R, T> { 72impl<R, T> Mutex<R, T> {
diff --git a/embassy-sync/src/zerocopy_channel.rs b/embassy-sync/src/zerocopy_channel.rs
index ad6fe74c5..e3e5b2538 100644
--- a/embassy-sync/src/zerocopy_channel.rs
+++ b/embassy-sync/src/zerocopy_channel.rs
@@ -195,7 +195,7 @@ pub struct Receiver<'a, M: RawMutex, T> {
195} 195}
196 196
197impl<'a, M: RawMutex, T> Receiver<'a, M, T> { 197impl<'a, M: RawMutex, T> Receiver<'a, M, T> {
198 /// Creates one further [`Sender`] over the same channel. 198 /// Creates one further [`Receiver`] over the same channel.
199 pub fn borrow(&mut self) -> Receiver<'_, M, T> { 199 pub fn borrow(&mut self) -> Receiver<'_, M, T> {
200 Receiver { channel: self.channel } 200 Receiver { channel: self.channel }
201 } 201 }
diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs
index c5b1a56fe..ea9d9fb7b 100644
--- a/embassy-usb/src/class/cdc_acm.rs
+++ b/embassy-usb/src/class/cdc_acm.rs
@@ -47,10 +47,10 @@ impl<'a> Default for State<'a> {
47 47
48impl<'a> State<'a> { 48impl<'a> State<'a> {
49 /// Create a new `State`. 49 /// Create a new `State`.
50 pub fn new() -> Self { 50 pub const fn new() -> Self {
51 Self { 51 Self {
52 control: MaybeUninit::uninit(), 52 control: MaybeUninit::uninit(),
53 shared: ControlShared::default(), 53 shared: ControlShared::new(),
54 } 54 }
55 } 55 }
56} 56}
@@ -92,6 +92,12 @@ struct ControlShared {
92 92
93impl Default for ControlShared { 93impl Default for ControlShared {
94 fn default() -> Self { 94 fn default() -> Self {
95 Self::new()
96 }
97}
98
99impl ControlShared {
100 const fn new() -> Self {
95 ControlShared { 101 ControlShared {
96 dtr: AtomicBool::new(false), 102 dtr: AtomicBool::new(false),
97 rts: AtomicBool::new(false), 103 rts: AtomicBool::new(false),
@@ -105,9 +111,7 @@ impl Default for ControlShared {
105 changed: AtomicBool::new(false), 111 changed: AtomicBool::new(false),
106 } 112 }
107 } 113 }
108}
109 114
110impl ControlShared {
111 fn changed(&self) -> impl Future<Output = ()> + '_ { 115 fn changed(&self) -> impl Future<Output = ()> + '_ {
112 poll_fn(|cx| { 116 poll_fn(|cx| {
113 if self.changed.load(Ordering::Relaxed) { 117 if self.changed.load(Ordering::Relaxed) {
diff --git a/embassy-usb/src/class/uac1/speaker.rs b/embassy-usb/src/class/uac1/speaker.rs
index 25de25d9c..1ff29088c 100644
--- a/embassy-usb/src/class/uac1/speaker.rs
+++ b/embassy-usb/src/class/uac1/speaker.rs
@@ -348,7 +348,7 @@ pub struct AudioSettings {
348impl Default for AudioSettings { 348impl Default for AudioSettings {
349 fn default() -> Self { 349 fn default() -> Self {
350 AudioSettings { 350 AudioSettings {
351 muted: [true; MAX_AUDIO_CHANNEL_COUNT], 351 muted: [false; MAX_AUDIO_CHANNEL_COUNT],
352 volume_8q8_db: [MAX_VOLUME_DB * VOLUME_STEPS_PER_DB; MAX_AUDIO_CHANNEL_COUNT], 352 volume_8q8_db: [MAX_VOLUME_DB * VOLUME_STEPS_PER_DB; MAX_AUDIO_CHANNEL_COUNT],
353 } 353 }
354 } 354 }
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index 78227c49c..4ae0e6a77 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] }
11embassy-nrf = { version = "0.3.1", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } 11embassy-nrf = { version = "0.3.1", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] }
12embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features = [] } 12embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features = [] }
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml
index 3f0d4cd78..fa4a7d44f 100644
--- a/examples/boot/application/rp/Cargo.toml
+++ b/examples/boot/application/rp/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] }
11embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = ["time-driver", "rp2040"] } 11embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = ["time-driver", "rp2040"] }
12embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] } 12embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] }
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 2590e9c49..f32727ea8 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" }
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index fac73afd7..6a5a500de 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 587d303ab..dd3a32e45 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index b3c580d3d..0b9e9b96a 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 8c49be914..490541a2e 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 28c74303a..c3aa31161 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml
index deaf4c388..a89e2bb6e 100644
--- a/examples/boot/application/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/application/stm32wb-dfu/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 890d0b510..f4d7ae712 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.6.2", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
diff --git a/examples/lpc55s69/Cargo.toml b/examples/lpc55s69/Cargo.toml
index afd76f9ac..f5a6e6995 100644
--- a/examples/lpc55s69/Cargo.toml
+++ b/examples/lpc55s69/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"] } 9embassy-nxp = { version = "0.1.0", path = "../../embassy-nxp", features = ["rt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
13panic-halt = "0.2.0" 13panic-halt = "0.2.0"
diff --git a/examples/mspm0c1104/.cargo/config.toml b/examples/mspm0c1104/.cargo/config.toml
new file mode 100644
index 000000000..204a56b1c
--- /dev/null
+++ b/examples/mspm0c1104/.cargo/config.toml
@@ -0,0 +1,11 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace MSPM0C1104 with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip MSPM0C1104 --protocol=swd"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "debug"
10# defmt's buffer needs to be shrunk since the MSPM0C1104 only has 1KB of ram.
11DEFMT_RTT_BUFFER_SIZE = "72"
diff --git a/examples/mspm0c1104/Cargo.toml b/examples/mspm0c1104/Cargo.toml
new file mode 100644
index 000000000..7c382482a
--- /dev/null
+++ b/examples/mspm0c1104/Cargo.toml
@@ -0,0 +1,32 @@
1[package]
2edition = "2021"
3name = "embassy-mspm0-c1104-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0c110x", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] }
18panic-semihosting = "0.6.0"
19
20# The chip only has 1KB of ram, so we must optimize binaries regardless
21[profile.dev]
22debug = 0
23opt-level = "z"
24lto = true
25codegen-units = 1
26# strip = true
27
28[profile.release]
29debug = 0
30opt-level = "z"
31lto = true
32codegen-units = 1
diff --git a/examples/mspm0c1104/README.md b/examples/mspm0c1104/README.md
new file mode 100644
index 000000000..e5c9f961d
--- /dev/null
+++ b/examples/mspm0c1104/README.md
@@ -0,0 +1,27 @@
1# Examples for MSPM0C110x family
2
3Run individual examples with
4```
5cargo run --bin <module-name>
6```
7for example
8```
9cargo run --bin blinky
10```
11
12## Checklist before running examples
13A large number of the examples are written for the [LP-MSPM0C1104](https://www.ti.com/tool/LP-MSPM0C1104) board.
14
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for C1104 it should be `probe-rs run --chip MSPM0C1104`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for C1104 it should be `mspm0c1104`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21
22If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
23
24* Which example you are trying to run
25* Which chip and board you are using
26
27Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/mspm0c1104/build.rs b/examples/mspm0c1104/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/mspm0c1104/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/mspm0c1104/memory.x b/examples/mspm0c1104/memory.x
new file mode 100644
index 000000000..a9108835a
--- /dev/null
+++ b/examples/mspm0c1104/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 16K
4 RAM : ORIGIN = 0x20000000, LENGTH = 1K
5}
diff --git a/examples/mspm0c1104/src/bin/blinky.rs b/examples/mspm0c1104/src/bin/blinky.rs
new file mode 100644
index 000000000..0d974cc5e
--- /dev/null
+++ b/examples/mspm0c1104/src/bin/blinky.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Level, Output};
7use embassy_mspm0::Config;
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) -> ! {
13 info!("Hello world!");
14 let p = embassy_mspm0::init(Config::default());
15
16 let mut led1 = Output::new(p.PA22, Level::Low);
17 led1.set_inversion(true);
18
19 loop {
20 Timer::after_millis(400).await;
21
22 info!("Toggle");
23 led1.toggle();
24 }
25}
diff --git a/examples/mspm0c1104/src/bin/button.rs b/examples/mspm0c1104/src/bin/button.rs
new file mode 100644
index 000000000..7face1618
--- /dev/null
+++ b/examples/mspm0c1104/src/bin/button.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Input, Level, Output, Pull};
7use embassy_mspm0::Config;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) -> ! {
12 info!("Hello world!");
13
14 let p = embassy_mspm0::init(Config::default());
15
16 let led1 = p.PA22;
17 let s2 = p.PA16;
18
19 let mut led1 = Output::new(led1, Level::Low);
20
21 let mut s2 = Input::new(s2, Pull::Up);
22
23 // led1 is active low
24 led1.set_high();
25
26 loop {
27 s2.wait_for_falling_edge().await;
28
29 info!("Switch 2 was pressed");
30
31 led1.toggle();
32 }
33}
diff --git a/examples/mspm0g3507/.cargo/config.toml b/examples/mspm0g3507/.cargo/config.toml
new file mode 100644
index 000000000..34c720cdd
--- /dev/null
+++ b/examples/mspm0g3507/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace MSPM0G3507 with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip MSPM0G3507 --protocol=swd"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "debug"
diff --git a/examples/mspm0g3507/Cargo.toml b/examples/mspm0g3507/Cargo.toml
new file mode 100644
index 000000000..9bc82151c
--- /dev/null
+++ b/examples/mspm0g3507/Cargo.toml
@@ -0,0 +1,21 @@
1[package]
2edition = "2021"
3name = "embassy-mspm0-g3507-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g350x", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] }
18panic-semihosting = "0.6.0"
19
20[profile.release]
21debug = 2
diff --git a/examples/mspm0g3507/README.md b/examples/mspm0g3507/README.md
new file mode 100644
index 000000000..5e8a83212
--- /dev/null
+++ b/examples/mspm0g3507/README.md
@@ -0,0 +1,27 @@
1# Examples for MSPM0C350x family
2
3Run individual examples with
4```
5cargo run --bin <module-name>
6```
7for example
8```
9cargo run --bin blinky
10```
11
12## Checklist before running examples
13A large number of the examples are written for the [LP-MSPM0G3507](https://www.ti.com/tool/LP-MSPM0G3507) board.
14
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3507 it should be `probe-rs run --chip MSPM0G3507`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3507 it should be `mspm0g3507`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21
22If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
23
24* Which example you are trying to run
25* Which chip and board you are using
26
27Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/mspm0g3507/build.rs b/examples/mspm0g3507/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/mspm0g3507/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/mspm0g3507/memory.x b/examples/mspm0g3507/memory.x
new file mode 100644
index 000000000..37e381fbd
--- /dev/null
+++ b/examples/mspm0g3507/memory.x
@@ -0,0 +1,6 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 128K
4 /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */
5 RAM : ORIGIN = 0x20200000, LENGTH = 32K
6}
diff --git a/examples/mspm0g3507/src/bin/blinky.rs b/examples/mspm0g3507/src/bin/blinky.rs
new file mode 100644
index 000000000..055a5cd81
--- /dev/null
+++ b/examples/mspm0g3507/src/bin/blinky.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Level, Output};
7use embassy_mspm0::Config;
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) -> ! {
13 info!("Hello world!");
14 let p = embassy_mspm0::init(Config::default());
15
16 let mut led1 = Output::new(p.PA0, Level::Low);
17 led1.set_inversion(true);
18
19 loop {
20 Timer::after_millis(400).await;
21
22 info!("Toggle");
23 led1.toggle();
24 }
25}
diff --git a/examples/mspm0g3507/src/bin/button.rs b/examples/mspm0g3507/src/bin/button.rs
new file mode 100644
index 000000000..cde1f2892
--- /dev/null
+++ b/examples/mspm0g3507/src/bin/button.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Input, Level, Output, Pull};
7use embassy_mspm0::Config;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) -> ! {
12 info!("Hello world!");
13
14 let p = embassy_mspm0::init(Config::default());
15
16 let led1 = p.PA0;
17 let s2 = p.PB21;
18
19 let mut led1 = Output::new(led1, Level::Low);
20
21 let mut s2 = Input::new(s2, Pull::Up);
22
23 // led1 is active low
24 led1.set_high();
25
26 loop {
27 s2.wait_for_falling_edge().await;
28
29 info!("Switch 2 was pressed");
30
31 led1.toggle();
32 }
33}
diff --git a/examples/mspm0g3519/.cargo/config.toml b/examples/mspm0g3519/.cargo/config.toml
new file mode 100644
index 000000000..7bba4646f
--- /dev/null
+++ b/examples/mspm0g3519/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace MSPM0G3519 with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --restore-unwritten --verify --chip MSPM0G3519 --protocol=swd"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/mspm0g3519/Cargo.toml b/examples/mspm0g3519/Cargo.toml
new file mode 100644
index 000000000..a28ce2f11
--- /dev/null
+++ b/examples/mspm0g3519/Cargo.toml
@@ -0,0 +1,21 @@
1[package]
2edition = "2021"
3name = "embassy-mspm0-g3519-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0g351x", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] }
18panic-semihosting = "0.6.0"
19
20[profile.release]
21debug = 2
diff --git a/examples/mspm0g3519/README.md b/examples/mspm0g3519/README.md
new file mode 100644
index 000000000..5034b1913
--- /dev/null
+++ b/examples/mspm0g3519/README.md
@@ -0,0 +1,27 @@
1# Examples for MSPM0G351x family
2
3Run individual examples with
4```
5cargo run --bin <module-name>
6```
7for example
8```
9cargo run --bin blinky
10```
11
12## Checklist before running examples
13A large number of the examples are written for the [LP-MSPM0G3519](https://www.ti.com/tool/LP-MSPM0G3519) board.
14
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for G3519 it should be `probe-rs run --chip MSPM0G3519`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for G3519 it should be `mspm0g3519`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21
22If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
23
24* Which example you are trying to run
25* Which chip and board you are using
26
27Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/mspm0g3519/build.rs b/examples/mspm0g3519/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/mspm0g3519/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/mspm0g3519/memory.x b/examples/mspm0g3519/memory.x
new file mode 100644
index 000000000..e6e0ec9e9
--- /dev/null
+++ b/examples/mspm0g3519/memory.x
@@ -0,0 +1,6 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 512K
4 /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */
5 RAM : ORIGIN = 0x20200000, LENGTH = 128K
6}
diff --git a/examples/mspm0g3519/src/bin/blinky.rs b/examples/mspm0g3519/src/bin/blinky.rs
new file mode 100644
index 000000000..055a5cd81
--- /dev/null
+++ b/examples/mspm0g3519/src/bin/blinky.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Level, Output};
7use embassy_mspm0::Config;
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) -> ! {
13 info!("Hello world!");
14 let p = embassy_mspm0::init(Config::default());
15
16 let mut led1 = Output::new(p.PA0, Level::Low);
17 led1.set_inversion(true);
18
19 loop {
20 Timer::after_millis(400).await;
21
22 info!("Toggle");
23 led1.toggle();
24 }
25}
diff --git a/examples/mspm0g3519/src/bin/button.rs b/examples/mspm0g3519/src/bin/button.rs
new file mode 100644
index 000000000..c81cc2918
--- /dev/null
+++ b/examples/mspm0g3519/src/bin/button.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Input, Level, Output, Pull};
7use embassy_mspm0::Config;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) -> ! {
12 info!("Hello world!");
13
14 let p = embassy_mspm0::init(Config::default());
15
16 let led1 = p.PA0;
17 let s2 = p.PB3;
18
19 let mut led1 = Output::new(led1, Level::Low);
20
21 let mut s2 = Input::new(s2, Pull::Up);
22
23 // led1 is active low
24 led1.set_high();
25
26 loop {
27 s2.wait_for_falling_edge().await;
28
29 info!("Switch 2 was pressed");
30
31 led1.toggle();
32 }
33}
diff --git a/examples/mspm0l1306/.cargo/config.toml b/examples/mspm0l1306/.cargo/config.toml
new file mode 100644
index 000000000..93f148a71
--- /dev/null
+++ b/examples/mspm0l1306/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace MSPM0L1306 with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip MSPM0L1306 --protocol=swd"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/mspm0l1306/Cargo.toml b/examples/mspm0l1306/Cargo.toml
new file mode 100644
index 000000000..3962eb156
--- /dev/null
+++ b/examples/mspm0l1306/Cargo.toml
@@ -0,0 +1,21 @@
1[package]
2edition = "2021"
3name = "embassy-mspm0-l1306-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l130x", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] }
18panic-semihosting = "0.6.0"
19
20[profile.release]
21debug = 2
diff --git a/examples/mspm0l1306/README.md b/examples/mspm0l1306/README.md
new file mode 100644
index 000000000..5a55d721e
--- /dev/null
+++ b/examples/mspm0l1306/README.md
@@ -0,0 +1,27 @@
1# Examples for MSPM0L130x family
2
3Run individual examples with
4```
5cargo run --bin <module-name>
6```
7for example
8```
9cargo run --bin blinky
10```
11
12## Checklist before running examples
13A large number of the examples are written for the [LP-MSPM0L1306](https://www.ti.com/tool/LP-MSPM0L1306) board.
14
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L1306 it should be `probe-rs run --chip MSPM0L1306`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L1306 it should be `mspm0l1306`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21
22If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
23
24* Which example you are trying to run
25* Which chip and board you are using
26
27Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/mspm0l1306/build.rs b/examples/mspm0l1306/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/mspm0l1306/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/mspm0l1306/memory.x b/examples/mspm0l1306/memory.x
new file mode 100644
index 000000000..d93b61f44
--- /dev/null
+++ b/examples/mspm0l1306/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 64K
4 RAM : ORIGIN = 0x20000000, LENGTH = 4K
5}
diff --git a/examples/mspm0l1306/src/bin/blinky.rs b/examples/mspm0l1306/src/bin/blinky.rs
new file mode 100644
index 000000000..055a5cd81
--- /dev/null
+++ b/examples/mspm0l1306/src/bin/blinky.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Level, Output};
7use embassy_mspm0::Config;
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) -> ! {
13 info!("Hello world!");
14 let p = embassy_mspm0::init(Config::default());
15
16 let mut led1 = Output::new(p.PA0, Level::Low);
17 led1.set_inversion(true);
18
19 loop {
20 Timer::after_millis(400).await;
21
22 info!("Toggle");
23 led1.toggle();
24 }
25}
diff --git a/examples/mspm0l1306/src/bin/button.rs b/examples/mspm0l1306/src/bin/button.rs
new file mode 100644
index 000000000..d8c85947f
--- /dev/null
+++ b/examples/mspm0l1306/src/bin/button.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Input, Level, Output, Pull};
7use embassy_mspm0::Config;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) -> ! {
12 info!("Hello world!");
13
14 let p = embassy_mspm0::init(Config::default());
15
16 let led1 = p.PA0;
17 let s2 = p.PA14;
18
19 let mut led1 = Output::new(led1, Level::Low);
20
21 let mut s2 = Input::new(s2, Pull::Up);
22
23 // led1 is active low
24 led1.set_high();
25
26 loop {
27 s2.wait_for_falling_edge().await;
28
29 info!("Switch 2 was pressed");
30
31 led1.toggle();
32 }
33}
diff --git a/examples/mspm0l2228/.cargo/config.toml b/examples/mspm0l2228/.cargo/config.toml
new file mode 100644
index 000000000..f383afd9e
--- /dev/null
+++ b/examples/mspm0l2228/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace MSPM0L2228 with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --restore-unwritten --verify --chip MSPM0L2228 --protocol=swd"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/mspm0l2228/Cargo.toml b/examples/mspm0l2228/Cargo.toml
new file mode 100644
index 000000000..abebcc00d
--- /dev/null
+++ b/examples/mspm0l2228/Cargo.toml
@@ -0,0 +1,21 @@
1[package]
2edition = "2021"
3name = "embassy-mspm0-l2228-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-mspm0 = { version = "0.1.0", path = "../../embassy-mspm0", features = ["mspm0l222x", "rt", "time-driver-any"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt"] }
12panic-halt = "0.2.0"
13cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
14cortex-m-rt = { version = "0.7.0"}
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3.2", features = ["print-defmt"] }
18panic-semihosting = "0.6.0"
19
20[profile.release]
21debug = 2
diff --git a/examples/mspm0l2228/README.md b/examples/mspm0l2228/README.md
new file mode 100644
index 000000000..c73fa13b6
--- /dev/null
+++ b/examples/mspm0l2228/README.md
@@ -0,0 +1,27 @@
1# Examples for MSPM0L222x family
2
3Run individual examples with
4```
5cargo run --bin <module-name>
6```
7for example
8```
9cargo run --bin blinky
10```
11
12## Checklist before running examples
13A large number of the examples are written for the [LP-MSPM0L2228](https://www.ti.com/tool/LP-MSPM0L2228) board.
14
15You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
16
17* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L2228 it should be `probe-rs run --chip MSPM0L2228`. (use `probe-rs chip list` to find your chip)
18* [ ] Update Cargo.toml to have the correct `embassy-mspm0` feature. For example for L2228 it should be `mspm0l2228`. Look in the `Cargo.toml` file of the `embassy-mspm0` project to find the correct feature flag for your chip.
19* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
20* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
21
22If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
23
24* Which example you are trying to run
25* Which chip and board you are using
26
27Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/mspm0l2228/build.rs b/examples/mspm0l2228/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/mspm0l2228/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/mspm0l2228/memory.x b/examples/mspm0l2228/memory.x
new file mode 100644
index 000000000..aba414a88
--- /dev/null
+++ b/examples/mspm0l2228/memory.x
@@ -0,0 +1,6 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 256K
4 /* Select non-parity range of SRAM due to SRAM_ERR_01 errata in SLAZ758 */
5 RAM : ORIGIN = 0x20200000, LENGTH = 32K
6}
diff --git a/examples/mspm0l2228/src/bin/blinky.rs b/examples/mspm0l2228/src/bin/blinky.rs
new file mode 100644
index 000000000..055a5cd81
--- /dev/null
+++ b/examples/mspm0l2228/src/bin/blinky.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Level, Output};
7use embassy_mspm0::Config;
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_halt as _};
10
11#[embassy_executor::main]
12async fn main(_spawner: Spawner) -> ! {
13 info!("Hello world!");
14 let p = embassy_mspm0::init(Config::default());
15
16 let mut led1 = Output::new(p.PA0, Level::Low);
17 led1.set_inversion(true);
18
19 loop {
20 Timer::after_millis(400).await;
21
22 info!("Toggle");
23 led1.toggle();
24 }
25}
diff --git a/examples/mspm0l2228/src/bin/button.rs b/examples/mspm0l2228/src/bin/button.rs
new file mode 100644
index 000000000..47bfd274b
--- /dev/null
+++ b/examples/mspm0l2228/src/bin/button.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_mspm0::gpio::{Input, Level, Output, Pull};
7use embassy_mspm0::Config;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) -> ! {
12 info!("Hello world!");
13
14 let p = embassy_mspm0::init(Config::default());
15
16 let led1 = p.PA0;
17 let s2 = p.PB8;
18
19 let mut led1 = Output::new(led1, Level::Low);
20
21 let mut s2 = Input::new(s2, Pull::Up);
22
23 // led1 is active low
24 led1.set_high();
25
26 loop {
27 s2.wait_for_falling_edge().await;
28
29 info!("Switch 2 was pressed");
30
31 led1.toggle();
32 }
33}
diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml
index b6760a428..97b5b924a 100644
--- a/examples/nrf51/Cargo.toml
+++ b/examples/nrf51/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } 10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] }
11 11
diff --git a/examples/nrf52810/Cargo.toml b/examples/nrf52810/Cargo.toml
index 297a52537..cd59b86c3 100644
--- a/examples/nrf52810/Cargo.toml
+++ b/examples/nrf52810/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52810", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
13 13
diff --git a/examples/nrf52840-rtic/src/bin/blinky.rs b/examples/nrf52840-rtic/src/bin/blinky.rs
index 5a074ea17..719e22729 100644
--- a/examples/nrf52840-rtic/src/bin/blinky.rs
+++ b/examples/nrf52840-rtic/src/bin/blinky.rs
@@ -8,7 +8,7 @@ use {defmt_rtt as _, panic_probe as _};
8mod app { 8mod app {
9 use defmt::info; 9 use defmt::info;
10 use embassy_nrf::gpio::{Level, Output, OutputDrive}; 10 use embassy_nrf::gpio::{Level, Output, OutputDrive};
11 use embassy_nrf::peripherals; 11 use embassy_nrf::{peripherals, Peri};
12 use embassy_time::Timer; 12 use embassy_time::Timer;
13 13
14 #[shared] 14 #[shared]
@@ -28,7 +28,7 @@ mod app {
28 } 28 }
29 29
30 #[task(priority = 1)] 30 #[task(priority = 1)]
31 async fn blink(_cx: blink::Context, pin: peripherals::P0_13) { 31 async fn blink(_cx: blink::Context, pin: Peri<'static, peripherals::P0_13>) {
32 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); 32 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
33 33
34 loop { 34 loop {
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml
index f479d6af6..902193f3a 100644
--- a/examples/nrf52840/Cargo.toml
+++ b/examples/nrf52840/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs
index 29f70f91c..74c62ca20 100644
--- a/examples/nrf52840/src/bin/channel_sender_receiver.rs
+++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs
@@ -3,7 +3,8 @@
3 3
4use defmt::unwrap; 4use defmt::unwrap;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; 6use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive};
7use embassy_nrf::Peri;
7use embassy_sync::blocking_mutex::raw::NoopRawMutex; 8use embassy_sync::blocking_mutex::raw::NoopRawMutex;
8use embassy_sync::channel::{Channel, Receiver, Sender}; 9use embassy_sync::channel::{Channel, Receiver, Sender};
9use embassy_time::Timer; 10use embassy_time::Timer;
@@ -28,7 +29,7 @@ async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
28} 29}
29 30
30#[embassy_executor::task] 31#[embassy_executor::task]
31async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) { 32async fn recv_task(led: Peri<'static, AnyPin>, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) {
32 let mut led = Output::new(led, Level::Low, OutputDrive::Standard); 33 let mut led = Output::new(led, Level::Low, OutputDrive::Standard);
33 34
34 loop { 35 loop {
@@ -45,5 +46,5 @@ async fn main(spawner: Spawner) {
45 let channel = CHANNEL.init(Channel::new()); 46 let channel = CHANNEL.init(Channel::new());
46 47
47 unwrap!(spawner.spawn(send_task(channel.sender()))); 48 unwrap!(spawner.spawn(send_task(channel.sender())));
48 unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver()))); 49 unwrap!(spawner.spawn(recv_task(p.P0_13.into(), channel.receiver())));
49} 50}
diff --git a/examples/nrf52840/src/bin/pdm_continuous.rs b/examples/nrf52840/src/bin/pdm_continuous.rs
index e948203a5..0d76636b0 100644
--- a/examples/nrf52840/src/bin/pdm_continuous.rs
+++ b/examples/nrf52840/src/bin/pdm_continuous.rs
@@ -20,14 +20,14 @@ bind_interrupts!(struct Irqs {
20 20
21#[embassy_executor::main] 21#[embassy_executor::main]
22async fn main(_p: Spawner) { 22async fn main(_p: Spawner) {
23 let mut p = embassy_nrf::init(Default::default()); 23 let p = embassy_nrf::init(Default::default());
24 let mut config = Config::default(); 24 let mut config = Config::default();
25 // Pins are correct for the onboard microphone on the Feather nRF52840 Sense. 25 // Pins are correct for the onboard microphone on the Feather nRF52840 Sense.
26 config.frequency = Frequency::_1280K; // 16 kHz sample rate 26 config.frequency = Frequency::_1280K; // 16 kHz sample rate
27 config.ratio = Ratio::RATIO80; 27 config.ratio = Ratio::RATIO80;
28 config.operation_mode = OperationMode::Mono; 28 config.operation_mode = OperationMode::Mono;
29 config.gain_left = I7F1::from_bits(5); // 2.5 dB 29 config.gain_left = I7F1::from_bits(5); // 2.5 dB
30 let mut pdm = Pdm::new(p.PDM, Irqs, &mut p.P0_00, &mut p.P0_01, config); 30 let mut pdm = Pdm::new(p.PDM, Irqs, p.P0_00, p.P0_01, config);
31 31
32 let mut bufs = [[0; 1024]; 2]; 32 let mut bufs = [[0; 1024]; 2];
33 33
diff --git a/examples/nrf52840/src/bin/qspi_lowpower.rs b/examples/nrf52840/src/bin/qspi_lowpower.rs
index 516c9b481..238a0d941 100644
--- a/examples/nrf52840/src/bin/qspi_lowpower.rs
+++ b/examples/nrf52840/src/bin/qspi_lowpower.rs
@@ -37,14 +37,14 @@ async fn main(_p: Spawner) {
37 }); 37 });
38 38
39 let mut q = qspi::Qspi::new( 39 let mut q = qspi::Qspi::new(
40 &mut p.QSPI, 40 p.QSPI.reborrow(),
41 Irqs, 41 Irqs,
42 &mut p.P0_19, 42 p.P0_19.reborrow(),
43 &mut p.P0_17, 43 p.P0_17.reborrow(),
44 &mut p.P0_20, 44 p.P0_20.reborrow(),
45 &mut p.P0_21, 45 p.P0_21.reborrow(),
46 &mut p.P0_22, 46 p.P0_22.reborrow(),
47 &mut p.P0_23, 47 p.P0_23.reborrow(),
48 config, 48 config,
49 ); 49 );
50 50
diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs
index 653b7d606..cf2d860ab 100644
--- a/examples/nrf52840/src/bin/saadc.rs
+++ b/examples/nrf52840/src/bin/saadc.rs
@@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs {
16async fn main(_p: Spawner) { 16async fn main(_p: Spawner) {
17 let mut p = embassy_nrf::init(Default::default()); 17 let mut p = embassy_nrf::init(Default::default());
18 let config = Config::default(); 18 let config = Config::default();
19 let channel_config = ChannelConfig::single_ended(&mut p.P0_02); 19 let channel_config = ChannelConfig::single_ended(p.P0_02.reborrow());
20 let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]); 20 let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]);
21 21
22 loop { 22 loop {
diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs
index f76fa3570..e8f169c8c 100644
--- a/examples/nrf52840/src/bin/saadc_continuous.rs
+++ b/examples/nrf52840/src/bin/saadc_continuous.rs
@@ -18,9 +18,9 @@ bind_interrupts!(struct Irqs {
18async fn main(_p: Spawner) { 18async fn main(_p: Spawner) {
19 let mut p = embassy_nrf::init(Default::default()); 19 let mut p = embassy_nrf::init(Default::default());
20 let config = Config::default(); 20 let config = Config::default();
21 let channel_1_config = ChannelConfig::single_ended(&mut p.P0_02); 21 let channel_1_config = ChannelConfig::single_ended(p.P0_02.reborrow());
22 let channel_2_config = ChannelConfig::single_ended(&mut p.P0_03); 22 let channel_2_config = ChannelConfig::single_ended(p.P0_03.reborrow());
23 let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04); 23 let channel_3_config = ChannelConfig::single_ended(p.P0_04.reborrow());
24 let mut saadc = Saadc::new( 24 let mut saadc = Saadc::new(
25 p.SAADC, 25 p.SAADC,
26 Irqs, 26 Irqs,
@@ -40,9 +40,9 @@ async fn main(_p: Spawner) {
40 40
41 saadc 41 saadc
42 .run_task_sampler( 42 .run_task_sampler(
43 &mut p.TIMER0, 43 p.TIMER0.reborrow(),
44 &mut p.PPI_CH0, 44 p.PPI_CH0.reborrow(),
45 &mut p.PPI_CH1, 45 p.PPI_CH1.reborrow(),
46 Frequency::F1MHz, 46 Frequency::F1MHz,
47 1000, // We want to sample at 1KHz 47 1000, // We want to sample at 1KHz
48 &mut bufs, 48 &mut bufs,
diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs
index e2efbdd8d..8a6f958eb 100644
--- a/examples/nrf52840/src/bin/twim_lowpower.rs
+++ b/examples/nrf52840/src/bin/twim_lowpower.rs
@@ -32,7 +32,13 @@ async fn main(_p: Spawner) {
32 let config = twim::Config::default(); 32 let config = twim::Config::default();
33 33
34 // Create the TWIM instance with borrowed singletons, so they're not consumed. 34 // Create the TWIM instance with borrowed singletons, so they're not consumed.
35 let mut twi = Twim::new(&mut p.TWISPI0, Irqs, &mut p.P0_03, &mut p.P0_04, config); 35 let mut twi = Twim::new(
36 p.TWISPI0.reborrow(),
37 Irqs,
38 p.P0_03.reborrow(),
39 p.P0_04.reborrow(),
40 config,
41 );
36 42
37 info!("Reading..."); 43 info!("Reading...");
38 44
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml
index 2a83633b4..459c43221 100644
--- a/examples/nrf5340/Cargo.toml
+++ b/examples/nrf5340/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } 12embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml
index 12808fc2a..8848065d8 100644
--- a/examples/nrf54l15/Cargo.toml
+++ b/examples/nrf54l15/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
diff --git a/examples/nrf9151/ns/Cargo.toml b/examples/nrf9151/ns/Cargo.toml
index 27def8455..03f38fd63 100644
--- a/examples/nrf9151/ns/Cargo.toml
+++ b/examples/nrf9151/ns/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 8embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-ns", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
diff --git a/examples/nrf9151/s/Cargo.toml b/examples/nrf9151/s/Cargo.toml
index e57f199c6..ba88f6da3 100644
--- a/examples/nrf9151/s/Cargo.toml
+++ b/examples/nrf9151/s/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 8embassy-executor = { version = "0.7.0", path = "../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../../embassy-nrf", features = ["defmt", "nrf9120-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11 11
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml
index 6965ce202..a720f2d61 100644
--- a/examples/nrf9160/Cargo.toml
+++ b/examples/nrf9160/Cargo.toml
@@ -5,7 +5,7 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 8embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 10embassy-nrf = { version = "0.3.1", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] } 11embassy-net-nrf91 = { version = "0.1.0", path = "../../embassy-net-nrf91", features = ["defmt"] }
diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs
index 35900cdd8..2ba964b1f 100644
--- a/examples/nrf9160/src/bin/modem_tcp_client.rs
+++ b/examples/nrf9160/src/bin/modem_tcp_client.rs
@@ -13,9 +13,9 @@ use embassy_net::{Ipv4Cidr, Stack, StackResources};
13use embassy_net_nrf91::context::Status; 13use embassy_net_nrf91::context::Status;
14use embassy_net_nrf91::{context, Runner, State, TraceBuffer, TraceReader}; 14use embassy_net_nrf91::{context, Runner, State, TraceBuffer, TraceReader};
15use embassy_nrf::buffered_uarte::{self, BufferedUarteTx}; 15use embassy_nrf::buffered_uarte::{self, BufferedUarteTx};
16use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; 16use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive};
17use embassy_nrf::uarte::Baudrate; 17use embassy_nrf::uarte::Baudrate;
18use embassy_nrf::{bind_interrupts, interrupt, peripherals, uarte}; 18use embassy_nrf::{bind_interrupts, interrupt, peripherals, uarte, Peri};
19use embassy_time::{Duration, Timer}; 19use embassy_time::{Duration, Timer};
20use embedded_io_async::Write; 20use embedded_io_async::Write;
21use heapless::Vec; 21use heapless::Vec;
@@ -91,7 +91,7 @@ fn status_to_config(status: &Status) -> embassy_net::ConfigV4 {
91} 91}
92 92
93#[embassy_executor::task] 93#[embassy_executor::task]
94async fn blink_task(pin: AnyPin) { 94async fn blink_task(pin: Peri<'static, AnyPin>) {
95 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard); 95 let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
96 loop { 96 loop {
97 led.set_high(); 97 led.set_high();
@@ -112,7 +112,7 @@ async fn main(spawner: Spawner) {
112 112
113 info!("Hello World!"); 113 info!("Hello World!");
114 114
115 unwrap!(spawner.spawn(blink_task(p.P0_02.degrade()))); 115 unwrap!(spawner.spawn(blink_task(p.P0_02.into())));
116 116
117 let ipc_mem = unsafe { 117 let ipc_mem = unsafe {
118 let ipc_start = &__start_ipc as *const u8 as *mut MaybeUninit<u8>; 118 let ipc_start = &__start_ipc as *const u8 as *mut MaybeUninit<u8>;
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index cde804a15..45ca30e4c 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8[dependencies] 8[dependencies]
9embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] } 9embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
13embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp2040"] } 13embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp2040"] }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
@@ -30,7 +30,7 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] }
30serde-json-core = "0.5.1" 30serde-json-core = "0.5.1"
31 31
32# for assign resources example 32# for assign resources example
33assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" } 33assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "bd22cb7a92031fb16f74a5da42469d466c33383e" }
34 34
35#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 35#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
36cortex-m = { version = "0.7.6", features = ["inline-asm"] } 36cortex-m = { version = "0.7.6", features = ["inline-asm"] }
diff --git a/examples/rp/src/bin/adc_dma.rs b/examples/rp/src/bin/adc_dma.rs
index f755cf5bf..b42c13fde 100644
--- a/examples/rp/src/bin/adc_dma.rs
+++ b/examples/rp/src/bin/adc_dma.rs
@@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) {
38 // Read 100 samples from a single channel 38 // Read 100 samples from a single channel
39 let mut buf = [0_u16; BLOCK_SIZE]; 39 let mut buf = [0_u16; BLOCK_SIZE];
40 let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1) 40 let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1)
41 adc.read_many(&mut pin, &mut buf, div, &mut dma).await.unwrap(); 41 adc.read_many(&mut pin, &mut buf, div, dma.reborrow()).await.unwrap();
42 info!("single: {:?} ...etc", buf[..8]); 42 info!("single: {:?} ...etc", buf[..8]);
43 43
44 // Read 100 samples from 4 channels interleaved 44 // Read 100 samples from 4 channels interleaved
45 let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }]; 45 let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }];
46 let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1) 46 let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1)
47 adc.read_many_multichannel(&mut pins, &mut buf, div, &mut dma) 47 adc.read_many_multichannel(&mut pins, &mut buf, div, dma.reborrow())
48 .await 48 .await
49 .unwrap(); 49 .unwrap();
50 info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]); 50 info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]);
diff --git a/examples/rp/src/bin/assign_resources.rs b/examples/rp/src/bin/assign_resources.rs
index ff6eff4a2..341f54d22 100644
--- a/examples/rp/src/bin/assign_resources.rs
+++ b/examples/rp/src/bin/assign_resources.rs
@@ -16,6 +16,7 @@ use defmt::*;
16use embassy_executor::Spawner; 16use embassy_executor::Spawner;
17use embassy_rp::gpio::{Level, Output}; 17use embassy_rp::gpio::{Level, Output};
18use embassy_rp::peripherals::{self, PIN_20, PIN_21}; 18use embassy_rp::peripherals::{self, PIN_20, PIN_21};
19use embassy_rp::Peri;
19use embassy_time::Timer; 20use embassy_time::Timer;
20use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
21 22
@@ -38,7 +39,11 @@ async fn main(spawner: Spawner) {
38 39
39// 1) Assigning a resource to a task by passing parts of the peripherals. 40// 1) Assigning a resource to a task by passing parts of the peripherals.
40#[embassy_executor::task] 41#[embassy_executor::task]
41async fn double_blinky_manually_assigned(_spawner: Spawner, pin_20: PIN_20, pin_21: PIN_21) { 42async fn double_blinky_manually_assigned(
43 _spawner: Spawner,
44 pin_20: Peri<'static, PIN_20>,
45 pin_21: Peri<'static, PIN_21>,
46) {
42 let mut led_20 = Output::new(pin_20, Level::Low); 47 let mut led_20 = Output::new(pin_20, Level::Low);
43 let mut led_21 = Output::new(pin_21, Level::High); 48 let mut led_21 = Output::new(pin_21, Level::High);
44 49
diff --git a/examples/rp/src/bin/blinky_two_channels.rs b/examples/rp/src/bin/blinky_two_channels.rs
index b2eec2a21..51e139e94 100644
--- a/examples/rp/src/bin/blinky_two_channels.rs
+++ b/examples/rp/src/bin/blinky_two_channels.rs
@@ -11,7 +11,7 @@ use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::channel::{Channel, Sender}; 12use embassy_sync::channel::{Channel, Sender};
13use embassy_time::{Duration, Ticker}; 13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output}; 14use gpio::{Level, Output};
15use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
16 16
17enum LedState { 17enum LedState {
@@ -22,7 +22,7 @@ static CHANNEL: Channel<ThreadModeRawMutex, LedState, 64> = Channel::new();
22#[embassy_executor::main] 22#[embassy_executor::main]
23async fn main(spawner: Spawner) { 23async fn main(spawner: Spawner) {
24 let p = embassy_rp::init(Default::default()); 24 let p = embassy_rp::init(Default::default());
25 let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High); 25 let mut led = Output::new(p.PIN_25, Level::High);
26 26
27 let dt = 100 * 1_000_000; 27 let dt = 100 * 1_000_000;
28 let k = 1.003; 28 let k = 1.003;
diff --git a/examples/rp/src/bin/blinky_two_tasks.rs b/examples/rp/src/bin/blinky_two_tasks.rs
index a57b513d6..67a9108c0 100644
--- a/examples/rp/src/bin/blinky_two_tasks.rs
+++ b/examples/rp/src/bin/blinky_two_tasks.rs
@@ -11,7 +11,7 @@ use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
13use embassy_time::{Duration, Ticker}; 13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output}; 14use gpio::{Level, Output};
15use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
16 16
17type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>; 17type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>;
@@ -21,7 +21,7 @@ static LED: LedType = Mutex::new(None);
21async fn main(spawner: Spawner) { 21async fn main(spawner: Spawner) {
22 let p = embassy_rp::init(Default::default()); 22 let p = embassy_rp::init(Default::default());
23 // set the content of the global LED reference to the real LED pin 23 // set the content of the global LED reference to the real LED pin
24 let led = Output::new(AnyPin::from(p.PIN_25), Level::High); 24 let led = Output::new(p.PIN_25, Level::High);
25 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the 25 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the
26 // Mutex is released 26 // Mutex is released
27 { 27 {
diff --git a/examples/rp/src/bin/orchestrate_tasks.rs b/examples/rp/src/bin/orchestrate_tasks.rs
index 7ff004860..5e2775793 100644
--- a/examples/rp/src/bin/orchestrate_tasks.rs
+++ b/examples/rp/src/bin/orchestrate_tasks.rs
@@ -24,7 +24,7 @@ use embassy_futures::select::{select, Either};
24use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; 24use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler};
25use embassy_rp::clocks::RoscRng; 25use embassy_rp::clocks::RoscRng;
26use embassy_rp::gpio::{Input, Pull}; 26use embassy_rp::gpio::{Input, Pull};
27use embassy_rp::{bind_interrupts, peripherals}; 27use embassy_rp::{bind_interrupts, peripherals, Peri};
28use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 28use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
29use embassy_sync::mutex::Mutex; 29use embassy_sync::mutex::Mutex;
30use embassy_sync::{channel, signal}; 30use embassy_sync::{channel, signal};
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index 08c702347..bf6dbee69 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -4,10 +4,10 @@
4#![no_main] 4#![no_main]
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 7use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::program::pio_asm; 8use embassy_rp::pio::program::pio_asm;
10use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 9use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
10use embassy_rp::{bind_interrupts, Peri};
11use fixed::traits::ToFixed; 11use fixed::traits::ToFixed;
12use fixed_macro::types::U56F8; 12use fixed_macro::types::U56F8;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs {
16 PIO0_IRQ_0 => InterruptHandler<PIO0>; 16 PIO0_IRQ_0 => InterruptHandler<PIO0>;
17}); 17});
18 18
19fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { 19fn setup_pio_task_sm0<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 0>, pin: Peri<'d, impl PioPin>) {
20 // Setup sm0 20 // Setup sm0
21 21
22 // Send data serially to pin 22 // Send data serially to pin
@@ -50,7 +50,7 @@ async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) {
50 } 50 }
51} 51}
52 52
53fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 1>) { 53fn setup_pio_task_sm1<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 1>) {
54 // Setupm sm1 54 // Setupm sm1
55 55
56 // Read 0b10101 repeatedly until ISR is full 56 // Read 0b10101 repeatedly until ISR is full
@@ -80,7 +80,7 @@ async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) {
80 } 80 }
81} 81}
82 82
83fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 2>) { 83fn setup_pio_task_sm2<'d>(pio: &mut Common<'d, PIO0>, sm: &mut StateMachine<'d, PIO0, 2>) {
84 // Setup sm2 84 // Setup sm2
85 85
86 // Repeatedly trigger IRQ 3 86 // Repeatedly trigger IRQ 3
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index da6e47a1b..64d603ba4 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -5,10 +5,10 @@
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_futures::join::join; 7use embassy_futures::join::join;
8use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::program::pio_asm; 10use embassy_rp::pio::program::pio_asm;
10use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; 11use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
11use embassy_rp::{bind_interrupts, Peripheral};
12use fixed::traits::ToFixed; 12use fixed::traits::ToFixed;
13use fixed_macro::types::U56F8; 13use fixed_macro::types::U56F8;
14use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
@@ -62,8 +62,8 @@ async fn main(_spawner: Spawner) {
62 sm.set_config(&cfg); 62 sm.set_config(&cfg);
63 sm.set_enable(true); 63 sm.set_enable(true);
64 64
65 let mut dma_out_ref = p.DMA_CH0.into_ref(); 65 let mut dma_out_ref = p.DMA_CH0;
66 let mut dma_in_ref = p.DMA_CH1.into_ref(); 66 let mut dma_in_ref = p.DMA_CH1;
67 let mut dout = [0x12345678u32; 29]; 67 let mut dout = [0x12345678u32; 29];
68 for i in 1..dout.len() { 68 for i in 1..dout.len() {
69 dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7; 69 dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7;
diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs
index 447100ddf..192c8f854 100644
--- a/examples/rp/src/bin/pio_i2s.rs
+++ b/examples/rp/src/bin/pio_i2s.rs
@@ -14,6 +14,7 @@ use core::mem;
14 14
15use embassy_executor::Spawner; 15use embassy_executor::Spawner;
16use embassy_rp::bind_interrupts; 16use embassy_rp::bind_interrupts;
17use embassy_rp::bootsel::is_bootsel_pressed;
17use embassy_rp::peripherals::PIO0; 18use embassy_rp::peripherals::PIO0;
18use embassy_rp::pio::{InterruptHandler, Pio}; 19use embassy_rp::pio::{InterruptHandler, Pio};
19use embassy_rp::pio_programs::i2s::{PioI2sOut, PioI2sOutProgram}; 20use embassy_rp::pio_programs::i2s::{PioI2sOut, PioI2sOutProgram};
@@ -70,7 +71,11 @@ async fn main(_spawner: Spawner) {
70 let dma_future = i2s.write(front_buffer); 71 let dma_future = i2s.write(front_buffer);
71 72
72 // fade in audio when bootsel is pressed 73 // fade in audio when bootsel is pressed
73 let fade_target = if p.BOOTSEL.is_pressed() { i32::MAX } else { 0 }; 74 let fade_target = if is_bootsel_pressed(p.BOOTSEL.reborrow()) {
75 i32::MAX
76 } else {
77 0
78 };
74 79
75 // fill back buffer with fresh audio samples before awaiting the dma future 80 // fill back buffer with fresh audio samples before awaiting the dma future
76 for s in back_buffer.iter_mut() { 81 for s in back_buffer.iter_mut() {
diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs
index 2f5f94870..04374323d 100644
--- a/examples/rp/src/bin/pwm.rs
+++ b/examples/rp/src/bin/pwm.rs
@@ -11,6 +11,7 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4}; 12use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4};
13use embassy_rp::pwm::{Config, Pwm, SetDutyCycle}; 13use embassy_rp::pwm::{Config, Pwm, SetDutyCycle};
14use embassy_rp::Peri;
14use embassy_time::Timer; 15use embassy_time::Timer;
15use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
16 17
@@ -26,7 +27,7 @@ async fn main(spawner: Spawner) {
26/// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant) 27/// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant)
27/// you must use another slice & pin and an appropriate resistor. 28/// you must use another slice & pin and an appropriate resistor.
28#[embassy_executor::task] 29#[embassy_executor::task]
29async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { 30async fn pwm_set_config(slice4: Peri<'static, PWM_SLICE4>, pin25: Peri<'static, PIN_25>) {
30 let mut c = Config::default(); 31 let mut c = Config::default();
31 c.top = 32_768; 32 c.top = 32_768;
32 c.compare_b = 8; 33 c.compare_b = 8;
@@ -44,7 +45,7 @@ async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) {
44/// 45///
45/// Using GP4 in Slice2, make sure to use an appropriate resistor. 46/// Using GP4 in Slice2, make sure to use an appropriate resistor.
46#[embassy_executor::task] 47#[embassy_executor::task]
47async fn pwm_set_dutycycle(slice2: PWM_SLICE2, pin4: PIN_4) { 48async fn pwm_set_dutycycle(slice2: Peri<'static, PWM_SLICE2>, pin4: Peri<'static, PIN_4>) {
48 // If we aim for a specific frequency, here is how we can calculate the top value. 49 // If we aim for a specific frequency, here is how we can calculate the top value.
49 // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0. 50 // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0.
50 // Every such wraparound is one PWM cycle. So here is how we get 25KHz: 51 // Every such wraparound is one PWM cycle. So here is how we get 25KHz:
diff --git a/examples/rp/src/bin/shared_bus.rs b/examples/rp/src/bin/shared_bus.rs
index c6cb5d64c..9267dfccb 100644
--- a/examples/rp/src/bin/shared_bus.rs
+++ b/examples/rp/src/bin/shared_bus.rs
@@ -8,7 +8,7 @@ use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
8use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice; 8use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
11use embassy_rp::gpio::{AnyPin, Level, Output}; 11use embassy_rp::gpio::{Level, Output};
12use embassy_rp::i2c::{self, I2c, InterruptHandler}; 12use embassy_rp::i2c::{self, I2c, InterruptHandler};
13use embassy_rp::peripherals::{I2C1, SPI1}; 13use embassy_rp::peripherals::{I2C1, SPI1};
14use embassy_rp::spi::{self, Spi}; 14use embassy_rp::spi::{self, Spi};
@@ -45,8 +45,8 @@ async fn main(spawner: Spawner) {
45 let spi_bus = SPI_BUS.init(Mutex::new(spi)); 45 let spi_bus = SPI_BUS.init(Mutex::new(spi));
46 46
47 // Chip select pins for the SPI devices 47 // Chip select pins for the SPI devices
48 let cs_a = Output::new(AnyPin::from(p.PIN_0), Level::High); 48 let cs_a = Output::new(p.PIN_0, Level::High);
49 let cs_b = Output::new(AnyPin::from(p.PIN_1), Level::High); 49 let cs_b = Output::new(p.PIN_1, Level::High);
50 50
51 spawner.must_spawn(spi_task_a(spi_bus, cs_a)); 51 spawner.must_spawn(spi_task_a(spi_bus, cs_a));
52 spawner.must_spawn(spi_task_b(spi_bus, cs_b)); 52 spawner.must_spawn(spi_task_b(spi_bus, cs_b));
diff --git a/examples/rp/src/bin/zerocopy.rs b/examples/rp/src/bin/zerocopy.rs
index 39f03c8e4..d1fb0eb00 100644
--- a/examples/rp/src/bin/zerocopy.rs
+++ b/examples/rp/src/bin/zerocopy.rs
@@ -9,9 +9,9 @@ use core::sync::atomic::{AtomicU16, Ordering};
9use defmt::*; 9use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler}; 11use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler};
12use embassy_rp::bind_interrupts;
13use embassy_rp::gpio::Pull; 12use embassy_rp::gpio::Pull;
14use embassy_rp::peripherals::DMA_CH0; 13use embassy_rp::peripherals::DMA_CH0;
14use embassy_rp::{bind_interrupts, Peri};
15use embassy_sync::blocking_mutex::raw::NoopRawMutex; 15use embassy_sync::blocking_mutex::raw::NoopRawMutex;
16use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender}; 16use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender};
17use embassy_time::{Duration, Ticker, Timer}; 17use embassy_time::{Duration, Ticker, Timer};
@@ -31,7 +31,7 @@ static MAX: AtomicU16 = AtomicU16::new(0);
31struct AdcParts { 31struct AdcParts {
32 adc: Adc<'static, Async>, 32 adc: Adc<'static, Async>,
33 pin: adc::Channel<'static>, 33 pin: adc::Channel<'static>,
34 dma: DMA_CH0, 34 dma: Peri<'static, DMA_CH0>,
35} 35}
36 36
37#[embassy_executor::main] 37#[embassy_executor::main]
@@ -70,7 +70,10 @@ async fn producer(mut sender: Sender<'static, NoopRawMutex, SampleBuffer>, mut a
70 let buf = sender.send().await; 70 let buf = sender.send().await;
71 71
72 // Fill it with data 72 // Fill it with data
73 adc.adc.read_many(&mut adc.pin, buf, 1, &mut adc.dma).await.unwrap(); 73 adc.adc
74 .read_many(&mut adc.pin, buf, 1, adc.dma.reborrow())
75 .await
76 .unwrap();
74 77
75 // Notify the channel that the buffer is now ready to be received 78 // Notify the channel that the buffer is now ready to be received
76 sender.send_done(); 79 sender.send_done();
diff --git a/examples/rp235x/Cargo.toml b/examples/rp235x/Cargo.toml
index 4e9c93e7c..345a915af 100644
--- a/examples/rp235x/Cargo.toml
+++ b/examples/rp235x/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8[dependencies] 8[dependencies]
9embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] } 9embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal", features = ["defmt"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-98304", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
13embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] } 13embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl", "rp235xa", "binary-info"] }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
@@ -28,7 +28,7 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] }
28serde-json-core = "0.5.1" 28serde-json-core = "0.5.1"
29 29
30# for assign resources example 30# for assign resources example
31assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "94ad10e2729afdf0fd5a77cd12e68409a982f58a" } 31assign-resources = { git = "https://github.com/adamgreig/assign-resources", rev = "bd22cb7a92031fb16f74a5da42469d466c33383e" }
32 32
33# for TB6612FNG example 33# for TB6612FNG example
34tb6612fng = "1.0.0" 34tb6612fng = "1.0.0"
diff --git a/examples/rp235x/src/bin/adc_dma.rs b/examples/rp235x/src/bin/adc_dma.rs
index f755cf5bf..b42c13fde 100644
--- a/examples/rp235x/src/bin/adc_dma.rs
+++ b/examples/rp235x/src/bin/adc_dma.rs
@@ -38,13 +38,13 @@ async fn main(_spawner: Spawner) {
38 // Read 100 samples from a single channel 38 // Read 100 samples from a single channel
39 let mut buf = [0_u16; BLOCK_SIZE]; 39 let mut buf = [0_u16; BLOCK_SIZE];
40 let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1) 40 let div = 479; // 100kHz sample rate (48Mhz / 100kHz - 1)
41 adc.read_many(&mut pin, &mut buf, div, &mut dma).await.unwrap(); 41 adc.read_many(&mut pin, &mut buf, div, dma.reborrow()).await.unwrap();
42 info!("single: {:?} ...etc", buf[..8]); 42 info!("single: {:?} ...etc", buf[..8]);
43 43
44 // Read 100 samples from 4 channels interleaved 44 // Read 100 samples from 4 channels interleaved
45 let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }]; 45 let mut buf = [0_u16; { BLOCK_SIZE * NUM_CHANNELS }];
46 let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1) 46 let div = 119; // 100kHz sample rate (48Mhz / 100kHz * 4ch - 1)
47 adc.read_many_multichannel(&mut pins, &mut buf, div, &mut dma) 47 adc.read_many_multichannel(&mut pins, &mut buf, div, dma.reborrow())
48 .await 48 .await
49 .unwrap(); 49 .unwrap();
50 info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]); 50 info!("multi: {:?} ...etc", buf[..NUM_CHANNELS * 2]);
diff --git a/examples/rp235x/src/bin/assign_resources.rs b/examples/rp235x/src/bin/assign_resources.rs
index ff6eff4a2..341f54d22 100644
--- a/examples/rp235x/src/bin/assign_resources.rs
+++ b/examples/rp235x/src/bin/assign_resources.rs
@@ -16,6 +16,7 @@ use defmt::*;
16use embassy_executor::Spawner; 16use embassy_executor::Spawner;
17use embassy_rp::gpio::{Level, Output}; 17use embassy_rp::gpio::{Level, Output};
18use embassy_rp::peripherals::{self, PIN_20, PIN_21}; 18use embassy_rp::peripherals::{self, PIN_20, PIN_21};
19use embassy_rp::Peri;
19use embassy_time::Timer; 20use embassy_time::Timer;
20use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
21 22
@@ -38,7 +39,11 @@ async fn main(spawner: Spawner) {
38 39
39// 1) Assigning a resource to a task by passing parts of the peripherals. 40// 1) Assigning a resource to a task by passing parts of the peripherals.
40#[embassy_executor::task] 41#[embassy_executor::task]
41async fn double_blinky_manually_assigned(_spawner: Spawner, pin_20: PIN_20, pin_21: PIN_21) { 42async fn double_blinky_manually_assigned(
43 _spawner: Spawner,
44 pin_20: Peri<'static, PIN_20>,
45 pin_21: Peri<'static, PIN_21>,
46) {
42 let mut led_20 = Output::new(pin_20, Level::Low); 47 let mut led_20 = Output::new(pin_20, Level::Low);
43 let mut led_21 = Output::new(pin_21, Level::High); 48 let mut led_21 = Output::new(pin_21, Level::High);
44 49
diff --git a/examples/rp235x/src/bin/blinky_two_channels.rs b/examples/rp235x/src/bin/blinky_two_channels.rs
index b2eec2a21..51e139e94 100644
--- a/examples/rp235x/src/bin/blinky_two_channels.rs
+++ b/examples/rp235x/src/bin/blinky_two_channels.rs
@@ -11,7 +11,7 @@ use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::channel::{Channel, Sender}; 12use embassy_sync::channel::{Channel, Sender};
13use embassy_time::{Duration, Ticker}; 13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output}; 14use gpio::{Level, Output};
15use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
16 16
17enum LedState { 17enum LedState {
@@ -22,7 +22,7 @@ static CHANNEL: Channel<ThreadModeRawMutex, LedState, 64> = Channel::new();
22#[embassy_executor::main] 22#[embassy_executor::main]
23async fn main(spawner: Spawner) { 23async fn main(spawner: Spawner) {
24 let p = embassy_rp::init(Default::default()); 24 let p = embassy_rp::init(Default::default());
25 let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High); 25 let mut led = Output::new(p.PIN_25, Level::High);
26 26
27 let dt = 100 * 1_000_000; 27 let dt = 100 * 1_000_000;
28 let k = 1.003; 28 let k = 1.003;
diff --git a/examples/rp235x/src/bin/blinky_two_tasks.rs b/examples/rp235x/src/bin/blinky_two_tasks.rs
index a57b513d6..67a9108c0 100644
--- a/examples/rp235x/src/bin/blinky_two_tasks.rs
+++ b/examples/rp235x/src/bin/blinky_two_tasks.rs
@@ -11,7 +11,7 @@ use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
13use embassy_time::{Duration, Ticker}; 13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output}; 14use gpio::{Level, Output};
15use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
16 16
17type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>; 17type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>;
@@ -21,7 +21,7 @@ static LED: LedType = Mutex::new(None);
21async fn main(spawner: Spawner) { 21async fn main(spawner: Spawner) {
22 let p = embassy_rp::init(Default::default()); 22 let p = embassy_rp::init(Default::default());
23 // set the content of the global LED reference to the real LED pin 23 // set the content of the global LED reference to the real LED pin
24 let led = Output::new(AnyPin::from(p.PIN_25), Level::High); 24 let led = Output::new(p.PIN_25, Level::High);
25 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the 25 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the
26 // Mutex is released 26 // Mutex is released
27 { 27 {
diff --git a/examples/rp235x/src/bin/pio_async.rs b/examples/rp235x/src/bin/pio_async.rs
index 08c702347..baf567b58 100644
--- a/examples/rp235x/src/bin/pio_async.rs
+++ b/examples/rp235x/src/bin/pio_async.rs
@@ -4,10 +4,10 @@
4#![no_main] 4#![no_main]
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 7use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::program::pio_asm; 8use embassy_rp::pio::program::pio_asm;
10use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 9use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
10use embassy_rp::{bind_interrupts, Peri};
11use fixed::traits::ToFixed; 11use fixed::traits::ToFixed;
12use fixed_macro::types::U56F8; 12use fixed_macro::types::U56F8;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs {
16 PIO0_IRQ_0 => InterruptHandler<PIO0>; 16 PIO0_IRQ_0 => InterruptHandler<PIO0>;
17}); 17});
18 18
19fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { 19fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: Peri<'a, impl PioPin>) {
20 // Setup sm0 20 // Setup sm0
21 21
22 // Send data serially to pin 22 // Send data serially to pin
diff --git a/examples/rp235x/src/bin/pio_dma.rs b/examples/rp235x/src/bin/pio_dma.rs
index da6e47a1b..64d603ba4 100644
--- a/examples/rp235x/src/bin/pio_dma.rs
+++ b/examples/rp235x/src/bin/pio_dma.rs
@@ -5,10 +5,10 @@
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_futures::join::join; 7use embassy_futures::join::join;
8use embassy_rp::bind_interrupts;
8use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::program::pio_asm; 10use embassy_rp::pio::program::pio_asm;
10use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; 11use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
11use embassy_rp::{bind_interrupts, Peripheral};
12use fixed::traits::ToFixed; 12use fixed::traits::ToFixed;
13use fixed_macro::types::U56F8; 13use fixed_macro::types::U56F8;
14use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
@@ -62,8 +62,8 @@ async fn main(_spawner: Spawner) {
62 sm.set_config(&cfg); 62 sm.set_config(&cfg);
63 sm.set_enable(true); 63 sm.set_enable(true);
64 64
65 let mut dma_out_ref = p.DMA_CH0.into_ref(); 65 let mut dma_out_ref = p.DMA_CH0;
66 let mut dma_in_ref = p.DMA_CH1.into_ref(); 66 let mut dma_in_ref = p.DMA_CH1;
67 let mut dout = [0x12345678u32; 29]; 67 let mut dout = [0x12345678u32; 29];
68 for i in 1..dout.len() { 68 for i in 1..dout.len() {
69 dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7; 69 dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7;
diff --git a/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
index 0216c131b..ccc601661 100644
--- a/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
+++ b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
@@ -9,7 +9,7 @@ use embassy_executor::Spawner;
9use embassy_rp::gpio::Pull; 9use embassy_rp::gpio::Pull;
10use embassy_rp::peripherals::PIO0; 10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::program::pio_asm; 11use embassy_rp::pio::program::pio_asm;
12use embassy_rp::{bind_interrupts, pio}; 12use embassy_rp::{bind_interrupts, pio, Peri};
13use embassy_time::Timer; 13use embassy_time::Timer;
14use fixed::traits::ToFixed; 14use fixed::traits::ToFixed;
15use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine}; 15use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
@@ -37,8 +37,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
37 pub fn new( 37 pub fn new(
38 pio: &mut Common<'d, T>, 38 pio: &mut Common<'d, T>,
39 mut sm: StateMachine<'d, T, SM>, 39 mut sm: StateMachine<'d, T, SM>,
40 pin_a: impl PioPin, 40 pin_a: Peri<'d, impl PioPin>,
41 pin_b: impl PioPin, 41 pin_b: Peri<'d, impl PioPin>,
42 ) -> Self { 42 ) -> Self {
43 let mut pin_a = pio.make_pio_pin(pin_a); 43 let mut pin_a = pio.make_pio_pin(pin_a);
44 let mut pin_b = pio.make_pio_pin(pin_b); 44 let mut pin_b = pio.make_pio_pin(pin_b);
diff --git a/examples/rp235x/src/bin/pwm.rs b/examples/rp235x/src/bin/pwm.rs
index a3c0f7e49..da1acc18a 100644
--- a/examples/rp235x/src/bin/pwm.rs
+++ b/examples/rp235x/src/bin/pwm.rs
@@ -11,6 +11,7 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4}; 12use embassy_rp::peripherals::{PIN_25, PIN_4, PWM_SLICE2, PWM_SLICE4};
13use embassy_rp::pwm::{Config, Pwm, SetDutyCycle}; 13use embassy_rp::pwm::{Config, Pwm, SetDutyCycle};
14use embassy_rp::Peri;
14use embassy_time::Timer; 15use embassy_time::Timer;
15use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
16 17
@@ -26,7 +27,7 @@ async fn main(spawner: Spawner) {
26/// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant) 27/// Using the onboard led, if You are using a different Board than plain Pico2 (i.e. W variant)
27/// you must use another slice & pin and an appropriate resistor. 28/// you must use another slice & pin and an appropriate resistor.
28#[embassy_executor::task] 29#[embassy_executor::task]
29async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) { 30async fn pwm_set_config(slice4: Peri<'static, PWM_SLICE4>, pin25: Peri<'static, PIN_25>) {
30 let mut c = Config::default(); 31 let mut c = Config::default();
31 c.top = 32_768; 32 c.top = 32_768;
32 c.compare_b = 8; 33 c.compare_b = 8;
@@ -44,7 +45,7 @@ async fn pwm_set_config(slice4: PWM_SLICE4, pin25: PIN_25) {
44/// 45///
45/// Using GP4 in Slice2, make sure to use an appropriate resistor. 46/// Using GP4 in Slice2, make sure to use an appropriate resistor.
46#[embassy_executor::task] 47#[embassy_executor::task]
47async fn pwm_set_dutycycle(slice2: PWM_SLICE2, pin4: PIN_4) { 48async fn pwm_set_dutycycle(slice2: Peri<'static, PWM_SLICE2>, pin4: Peri<'static, PIN_4>) {
48 // If we aim for a specific frequency, here is how we can calculate the top value. 49 // If we aim for a specific frequency, here is how we can calculate the top value.
49 // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0. 50 // The top value sets the period of the PWM cycle, so a counter goes from 0 to top and then wraps around to 0.
50 // Every such wraparound is one PWM cycle. So here is how we get 25KHz: 51 // Every such wraparound is one PWM cycle. So here is how we get 25KHz:
diff --git a/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs b/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs
index 3b700884c..2cfb2038d 100644
--- a/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs
+++ b/examples/rp235x/src/bin/pwm_tb6612fng_motor_driver.rs
@@ -10,7 +10,7 @@ use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_rp::config::Config; 11use embassy_rp::config::Config;
12use embassy_rp::gpio::Output; 12use embassy_rp::gpio::Output;
13use embassy_rp::{gpio, peripherals, pwm}; 13use embassy_rp::{gpio, peripherals, pwm, Peri};
14use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
15use tb6612fng::{DriveCommand, Motor, Tb6612fng}; 15use tb6612fng::{DriveCommand, Motor, Tb6612fng};
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
diff --git a/examples/rp235x/src/bin/shared_bus.rs b/examples/rp235x/src/bin/shared_bus.rs
index c6cb5d64c..9267dfccb 100644
--- a/examples/rp235x/src/bin/shared_bus.rs
+++ b/examples/rp235x/src/bin/shared_bus.rs
@@ -8,7 +8,7 @@ use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
8use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice; 8use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
11use embassy_rp::gpio::{AnyPin, Level, Output}; 11use embassy_rp::gpio::{Level, Output};
12use embassy_rp::i2c::{self, I2c, InterruptHandler}; 12use embassy_rp::i2c::{self, I2c, InterruptHandler};
13use embassy_rp::peripherals::{I2C1, SPI1}; 13use embassy_rp::peripherals::{I2C1, SPI1};
14use embassy_rp::spi::{self, Spi}; 14use embassy_rp::spi::{self, Spi};
@@ -45,8 +45,8 @@ async fn main(spawner: Spawner) {
45 let spi_bus = SPI_BUS.init(Mutex::new(spi)); 45 let spi_bus = SPI_BUS.init(Mutex::new(spi));
46 46
47 // Chip select pins for the SPI devices 47 // Chip select pins for the SPI devices
48 let cs_a = Output::new(AnyPin::from(p.PIN_0), Level::High); 48 let cs_a = Output::new(p.PIN_0, Level::High);
49 let cs_b = Output::new(AnyPin::from(p.PIN_1), Level::High); 49 let cs_b = Output::new(p.PIN_1, Level::High);
50 50
51 spawner.must_spawn(spi_task_a(spi_bus, cs_a)); 51 spawner.must_spawn(spi_task_a(spi_bus, cs_a));
52 spawner.must_spawn(spi_task_b(spi_bus, cs_b)); 52 spawner.must_spawn(spi_task_b(spi_bus, cs_b));
diff --git a/examples/rp235x/src/bin/zerocopy.rs b/examples/rp235x/src/bin/zerocopy.rs
index 39f03c8e4..d1fb0eb00 100644
--- a/examples/rp235x/src/bin/zerocopy.rs
+++ b/examples/rp235x/src/bin/zerocopy.rs
@@ -9,9 +9,9 @@ use core::sync::atomic::{AtomicU16, Ordering};
9use defmt::*; 9use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler}; 11use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler};
12use embassy_rp::bind_interrupts;
13use embassy_rp::gpio::Pull; 12use embassy_rp::gpio::Pull;
14use embassy_rp::peripherals::DMA_CH0; 13use embassy_rp::peripherals::DMA_CH0;
14use embassy_rp::{bind_interrupts, Peri};
15use embassy_sync::blocking_mutex::raw::NoopRawMutex; 15use embassy_sync::blocking_mutex::raw::NoopRawMutex;
16use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender}; 16use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender};
17use embassy_time::{Duration, Ticker, Timer}; 17use embassy_time::{Duration, Ticker, Timer};
@@ -31,7 +31,7 @@ static MAX: AtomicU16 = AtomicU16::new(0);
31struct AdcParts { 31struct AdcParts {
32 adc: Adc<'static, Async>, 32 adc: Adc<'static, Async>,
33 pin: adc::Channel<'static>, 33 pin: adc::Channel<'static>,
34 dma: DMA_CH0, 34 dma: Peri<'static, DMA_CH0>,
35} 35}
36 36
37#[embassy_executor::main] 37#[embassy_executor::main]
@@ -70,7 +70,10 @@ async fn producer(mut sender: Sender<'static, NoopRawMutex, SampleBuffer>, mut a
70 let buf = sender.send().await; 70 let buf = sender.send().await;
71 71
72 // Fill it with data 72 // Fill it with data
73 adc.adc.read_many(&mut adc.pin, buf, 1, &mut adc.dma).await.unwrap(); 73 adc.adc
74 .read_many(&mut adc.pin, buf, 1, adc.dma.reborrow())
75 .await
76 .unwrap();
74 77
75 // Notify the channel that the buffer is now ready to be received 78 // Notify the channel that the buffer is now ready to be received
76 sender.send_done(); 79 sender.send_done();
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index a32e75d08..f00953167 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["log"] } 8embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["log"] }
9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log"] } 9embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log"] }
10embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["log", "std", ] } 10embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["log", "std", ] }
11embassy-net = { version = "0.7.0", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } 11embassy-net = { version = "0.7.0", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] }
12embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } 12embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" }
diff --git a/examples/stm32c0/src/bin/adc.rs b/examples/stm32c0/src/bin/adc.rs
index 10481f4d2..1f54b0b18 100644
--- a/examples/stm32c0/src/bin/adc.rs
+++ b/examples/stm32c0/src/bin/adc.rs
@@ -36,7 +36,8 @@ async fn main(_spawner: Spawner) {
36 ); 36 );
37 37
38 let channels_seqence: [&mut AnyAdcChannel<ADC1>; 3] = [&mut vref, &mut temp, &mut pin0]; 38 let channels_seqence: [&mut AnyAdcChannel<ADC1>; 3] = [&mut vref, &mut temp, &mut pin0];
39 adc.read(&mut dma, channels_seqence.into_iter(), &mut read_buffer).await; 39 adc.read(dma.reborrow(), channels_seqence.into_iter(), &mut read_buffer)
40 .await;
40 // Values are ordered according to hardware ADC channel number! 41 // Values are ordered according to hardware ADC channel number!
41 info!( 42 info!(
42 "DMA ADC read in set: vref = {}, temp = {}, pin0 = {}.", 43 "DMA ADC read in set: vref = {}, temp = {}, pin0 = {}.",
@@ -45,7 +46,7 @@ async fn main(_spawner: Spawner) {
45 46
46 let hw_channel_selection: u32 = 47 let hw_channel_selection: u32 =
47 (1 << temp.get_hw_channel()) + (1 << vref.get_hw_channel()) + (1 << pin0.get_hw_channel()); 48 (1 << temp.get_hw_channel()) + (1 << vref.get_hw_channel()) + (1 << pin0.get_hw_channel());
48 adc.read_in_hw_order(&mut dma, hw_channel_selection, Scandir::UP, &mut read_buffer) 49 adc.read_in_hw_order(dma.reborrow(), hw_channel_selection, Scandir::UP, &mut read_buffer)
49 .await; 50 .await;
50 info!( 51 info!(
51 "DMA ADC read in hardware order: vref = {}, temp = {}, pin0 = {}.", 52 "DMA ADC read in hardware order: vref = {}, temp = {}, pin0 = {}.",
diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs
index 4465483d9..744df3e3b 100644
--- a/examples/stm32f0/src/bin/button_controlled_blink.rs
+++ b/examples/stm32f0/src/bin/button_controlled_blink.rs
@@ -8,14 +8,15 @@ use core::sync::atomic::{AtomicU32, Ordering};
8use defmt::info; 8use defmt::info;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Pull, Speed}; 11use embassy_stm32::gpio::{AnyPin, Level, Output, Pull, Speed};
12use embassy_stm32::Peri;
12use embassy_time::Timer; 13use embassy_time::Timer;
13use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
14 15
15static BLINK_MS: AtomicU32 = AtomicU32::new(0); 16static BLINK_MS: AtomicU32 = AtomicU32::new(0);
16 17
17#[embassy_executor::task] 18#[embassy_executor::task]
18async fn led_task(led: AnyPin) { 19async fn led_task(led: Peri<'static, AnyPin>) {
19 // Configure the LED pin as a push pull output and obtain handler. 20 // Configure the LED pin as a push pull output and obtain handler.
20 // On the Nucleo F091RC there's an on-board LED connected to pin PA5. 21 // On the Nucleo F091RC there's an on-board LED connected to pin PA5.
21 let mut led = Output::new(led, Level::Low, Speed::Low); 22 let mut led = Output::new(led, Level::Low, Speed::Low);
@@ -45,7 +46,7 @@ async fn main(spawner: Spawner) {
45 BLINK_MS.store(del_var, Ordering::Relaxed); 46 BLINK_MS.store(del_var, Ordering::Relaxed);
46 47
47 // Spawn LED blinking task 48 // Spawn LED blinking task
48 spawner.spawn(led_task(p.PA5.degrade())).unwrap(); 49 spawner.spawn(led_task(p.PA5.into())).unwrap();
49 50
50 loop { 51 loop {
51 // Check if button got pressed 52 // Check if button got pressed
diff --git a/examples/stm32f1/src/bin/input_capture.rs b/examples/stm32f1/src/bin/input_capture.rs
index 5e2dab9e6..6fe8e0b50 100644
--- a/examples/stm32f1/src/bin/input_capture.rs
+++ b/examples/stm32f1/src/bin/input_capture.rs
@@ -7,14 +7,14 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed};
7use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; 8use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
9use embassy_stm32::timer::{self, Channel}; 9use embassy_stm32::timer::{self, Channel};
10use embassy_stm32::{bind_interrupts, peripherals}; 10use embassy_stm32::{bind_interrupts, peripherals, Peri};
11use embassy_time::Timer; 11use embassy_time::Timer;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14/// Connect PA2 and PC13 with a 1k Ohm resistor 14/// Connect PA2 and PC13 with a 1k Ohm resistor
15 15
16#[embassy_executor::task] 16#[embassy_executor::task]
17async fn blinky(led: peripherals::PC13) { 17async fn blinky(led: Peri<'static, peripherals::PC13>) {
18 let mut led = Output::new(led, Level::High, Speed::Low); 18 let mut led = Output::new(led, Level::High, Speed::Low);
19 19
20 loop { 20 loop {
diff --git a/examples/stm32f1/src/bin/pwm_input.rs b/examples/stm32f1/src/bin/pwm_input.rs
index f74853d4e..afbef3edb 100644
--- a/examples/stm32f1/src/bin/pwm_input.rs
+++ b/examples/stm32f1/src/bin/pwm_input.rs
@@ -6,14 +6,14 @@ use embassy_executor::Spawner;
6use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 6use embassy_stm32::gpio::{Level, Output, Pull, Speed};
7use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::pwm_input::PwmInput; 8use embassy_stm32::timer::pwm_input::PwmInput;
9use embassy_stm32::{bind_interrupts, peripherals, timer}; 9use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
10use embassy_time::Timer; 10use embassy_time::Timer;
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13/// Connect PA0 and PC13 with a 1k Ohm resistor 13/// Connect PA0 and PC13 with a 1k Ohm resistor
14 14
15#[embassy_executor::task] 15#[embassy_executor::task]
16async fn blinky(led: peripherals::PC13) { 16async fn blinky(led: Peri<'static, peripherals::PC13>) {
17 let mut led = Output::new(led, Level::High, Speed::Low); 17 let mut led = Output::new(led, Level::High, Speed::Low);
18 18
19 loop { 19 loop {
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs
index ee99acf41..77ec307b9 100644
--- a/examples/stm32f1/src/bin/usb_serial.rs
+++ b/examples/stm32f1/src/bin/usb_serial.rs
@@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) {
47 // Pull the D+ pin down to send a RESET condition to the USB bus. 47 // Pull the D+ pin down to send a RESET condition to the USB bus.
48 // This forced reset is needed only for development, without it host 48 // This forced reset is needed only for development, without it host
49 // will not reset your device when you upload new firmware. 49 // will not reset your device when you upload new firmware.
50 let _dp = Output::new(&mut p.PA12, Level::Low, Speed::Low); 50 let _dp = Output::new(p.PA12.reborrow(), Level::Low, Speed::Low);
51 Timer::after_millis(10).await; 51 Timer::after_millis(10).await;
52 } 52 }
53 53
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs
index 2dbf1bdab..b30445ead 100644
--- a/examples/stm32f334/src/bin/opamp.rs
+++ b/examples/stm32f334/src/bin/opamp.rs
@@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) -> ! {
48 48
49 let mut vrefint = adc.enable_vref(); 49 let mut vrefint = adc.enable_vref();
50 let mut temperature = adc.enable_temperature(); 50 let mut temperature = adc.enable_temperature();
51 let mut buffer = opamp.buffer_ext(&mut p.PA7, &mut p.PA6, OpAmpGain::Mul1); 51 let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow(), OpAmpGain::Mul1);
52 52
53 loop { 53 loop {
54 let vref = adc.read(&mut vrefint).await; 54 let vref = adc.read(&mut vrefint).await;
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index e611564eb..7aa4354ca 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32f429zi to your chip name, if necessary. 8# Change stm32f429zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-tim4", "exti", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-tim4", "exti", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt" ] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt" ] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index 8e3beee24..fd90e0d6d 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) {
30 // To synchronise to the bus the RX input needs to see a high level. 30 // To synchronise to the bus the RX input needs to see a high level.
31 // Use `mem::forget()` to release the borrow on the pin but keep the 31 // Use `mem::forget()` to release the borrow on the pin but keep the
32 // pull-up resistor enabled. 32 // pull-up resistor enabled.
33 let rx_pin = Input::new(&mut p.PA11, Pull::Up); 33 let rx_pin = Input::new(p.PA11.reborrow(), Pull::Up);
34 core::mem::forget(rx_pin); 34 core::mem::forget(rx_pin);
35 35
36 let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs); 36 let mut can = Can::new(p.CAN1, p.PA11, p.PA12, Irqs);
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs
index dd2a45718..68fe6cabd 100644
--- a/examples/stm32f4/src/bin/dac.rs
+++ b/examples/stm32f4/src/bin/dac.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dac::{DacCh1, Value}; 6use embassy_stm32::dac::{DacCh1, Value};
7use embassy_stm32::dma::NoDma;
8use {defmt_rtt as _, panic_probe as _}; 7use {defmt_rtt as _, panic_probe as _};
9 8
10#[embassy_executor::main] 9#[embassy_executor::main]
@@ -12,7 +11,7 @@ async fn main(_spawner: Spawner) -> ! {
12 let p = embassy_stm32::init(Default::default()); 11 let p = embassy_stm32::init(Default::default());
13 info!("Hello World, dude!"); 12 info!("Hello World, dude!");
14 13
15 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 14 let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4);
16 15
17 loop { 16 loop {
18 for v in 0..=255 { 17 for v in 0..=255 {
diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs
index 493a536f3..755713542 100644
--- a/examples/stm32f4/src/bin/flash_async.rs
+++ b/examples/stm32f4/src/bin/flash_async.rs
@@ -3,9 +3,9 @@
3 3
4use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::bind_interrupts;
7use embassy_stm32::flash::{Flash, InterruptHandler}; 6use embassy_stm32::flash::{Flash, InterruptHandler};
8use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Speed}; 7use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
8use embassy_stm32::{bind_interrupts, Peri};
9use embassy_time::Timer; 9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
@@ -21,14 +21,14 @@ async fn main(spawner: Spawner) {
21 let mut f = Flash::new(p.FLASH, Irqs); 21 let mut f = Flash::new(p.FLASH, Irqs);
22 22
23 // Led should blink uninterrupted during ~2sec erase operation 23 // Led should blink uninterrupted during ~2sec erase operation
24 spawner.spawn(blinky(p.PB7.degrade())).unwrap(); 24 spawner.spawn(blinky(p.PB7.into())).unwrap();
25 25
26 // Test on bank 2 in order not to stall CPU. 26 // Test on bank 2 in order not to stall CPU.
27 test_flash(&mut f, 1024 * 1024, 128 * 1024).await; 27 test_flash(&mut f, 1024 * 1024, 128 * 1024).await;
28} 28}
29 29
30#[embassy_executor::task] 30#[embassy_executor::task]
31async fn blinky(p: AnyPin) { 31async fn blinky(p: Peri<'static, AnyPin>) {
32 let mut led = Output::new(p, Level::High, Speed::Low); 32 let mut led = Output::new(p, Level::High, Speed::Low);
33 33
34 loop { 34 loop {
diff --git a/examples/stm32f4/src/bin/input_capture.rs b/examples/stm32f4/src/bin/input_capture.rs
index 49de33d2b..fe5e2bdfc 100644
--- a/examples/stm32f4/src/bin/input_capture.rs
+++ b/examples/stm32f4/src/bin/input_capture.rs
@@ -7,14 +7,14 @@ use embassy_stm32::gpio::{Level, Output, Pull, Speed};
7use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; 8use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
9use embassy_stm32::timer::{self, Channel}; 9use embassy_stm32::timer::{self, Channel};
10use embassy_stm32::{bind_interrupts, peripherals}; 10use embassy_stm32::{bind_interrupts, peripherals, Peri};
11use embassy_time::Timer; 11use embassy_time::Timer;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14/// Connect PB2 and PB10 with a 1k Ohm resistor 14/// Connect PB2 and PB10 with a 1k Ohm resistor
15 15
16#[embassy_executor::task] 16#[embassy_executor::task]
17async fn blinky(led: peripherals::PB2) { 17async fn blinky(led: Peri<'static, peripherals::PB2>) {
18 let mut led = Output::new(led, Level::High, Speed::Low); 18 let mut led = Output::new(led, Level::High, Speed::Low);
19 19
20 loop { 20 loop {
diff --git a/examples/stm32f4/src/bin/pwm_input.rs b/examples/stm32f4/src/bin/pwm_input.rs
index ce200549d..465cbe4f5 100644
--- a/examples/stm32f4/src/bin/pwm_input.rs
+++ b/examples/stm32f4/src/bin/pwm_input.rs
@@ -6,14 +6,14 @@ use embassy_executor::Spawner;
6use embassy_stm32::gpio::{Level, Output, Pull, Speed}; 6use embassy_stm32::gpio::{Level, Output, Pull, Speed};
7use embassy_stm32::time::khz; 7use embassy_stm32::time::khz;
8use embassy_stm32::timer::pwm_input::PwmInput; 8use embassy_stm32::timer::pwm_input::PwmInput;
9use embassy_stm32::{bind_interrupts, peripherals, timer}; 9use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
10use embassy_time::Timer; 10use embassy_time::Timer;
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13/// Connect PB2 and PA6 with a 1k Ohm resistor 13/// Connect PB2 and PA6 with a 1k Ohm resistor
14 14
15#[embassy_executor::task] 15#[embassy_executor::task]
16async fn blinky(led: peripherals::PB2) { 16async fn blinky(led: Peri<'static, peripherals::PB2>) {
17 let mut led = Output::new(led, Level::High, Speed::Low); 17 let mut led = Output::new(led, Level::High, Speed::Low);
18 18
19 loop { 19 loop {
diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs
index 3ab93d6e0..ca924e181 100644
--- a/examples/stm32f4/src/bin/ws2812_pwm.rs
+++ b/examples/stm32f4/src/bin/ws2812_pwm.rs
@@ -92,7 +92,7 @@ async fn main(_spawner: Spawner) {
92 loop { 92 loop {
93 for &color in color_list { 93 for &color in color_list {
94 // with &mut, we can easily reuse same DMA channel multiple times 94 // with &mut, we can easily reuse same DMA channel multiple times
95 ws2812_pwm.waveform_up(&mut dp.DMA1_CH2, pwm_channel, color).await; 95 ws2812_pwm.waveform_up(dp.DMA1_CH2.reborrow(), pwm_channel, color).await;
96 // ws2812 need at least 50 us low level input to confirm the input data and change it's state 96 // ws2812 need at least 50 us low level input to confirm the input data and change it's state
97 Timer::after_micros(50).await; 97 Timer::after_micros(50).await;
98 // wait until ticker tick 98 // wait until ticker tick
diff --git a/examples/stm32f469/Cargo.toml b/examples/stm32f469/Cargo.toml
index 2c0c9a6c8..4d403bae8 100644
--- a/examples/stm32f469/Cargo.toml
+++ b/examples/stm32f469/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8# Specific examples only for stm32f469 8# Specific examples only for stm32f469
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f469ni", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12 12
13defmt = "0.3" 13defmt = "0.3"
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index e8b246184..9fbe2efc3 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32f777zi to your chip name, if necessary. 8# Change stm32f777zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
14embedded-io-async = { version = "0.6.1" } 14embedded-io-async = { version = "0.6.1" }
diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs
index a82e335a9..58ba940a8 100644
--- a/examples/stm32f7/src/bin/can.rs
+++ b/examples/stm32f7/src/bin/can.rs
@@ -42,7 +42,7 @@ async fn main(spawner: Spawner) {
42 // To synchronise to the bus the RX input needs to see a high level. 42 // To synchronise to the bus the RX input needs to see a high level.
43 // Use `mem::forget()` to release the borrow on the pin but keep the 43 // Use `mem::forget()` to release the borrow on the pin but keep the
44 // pull-up resistor enabled. 44 // pull-up resistor enabled.
45 let rx_pin = Input::new(&mut p.PA15, Pull::Up); 45 let rx_pin = Input::new(p.PA15.reborrow(), Pull::Up);
46 core::mem::forget(rx_pin); 46 core::mem::forget(rx_pin);
47 47
48 static CAN: StaticCell<Can<'static>> = StaticCell::new(); 48 static CAN: StaticCell<Can<'static>> = StaticCell::new();
diff --git a/examples/stm32g0/src/bin/adc_dma.rs b/examples/stm32g0/src/bin/adc_dma.rs
index 3713e5a21..d7515933c 100644
--- a/examples/stm32g0/src/bin/adc_dma.rs
+++ b/examples/stm32g0/src/bin/adc_dma.rs
@@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) {
25 25
26 loop { 26 loop {
27 adc.read( 27 adc.read(
28 &mut dma, 28 dma.reborrow(),
29 [ 29 [
30 (&mut vrefint_channel, SampleTime::CYCLES160_5), 30 (&mut vrefint_channel, SampleTime::CYCLES160_5),
31 (&mut pa0, SampleTime::CYCLES160_5), 31 (&mut pa0, SampleTime::CYCLES160_5),
diff --git a/examples/stm32g0/src/bin/input_capture.rs b/examples/stm32g0/src/bin/input_capture.rs
index bc814cb13..08df4e043 100644
--- a/examples/stm32g0/src/bin/input_capture.rs
+++ b/examples/stm32g0/src/bin/input_capture.rs
@@ -16,14 +16,14 @@ use embassy_stm32::time::khz;
16use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; 16use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
17use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; 17use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
18use embassy_stm32::timer::Channel; 18use embassy_stm32::timer::Channel;
19use embassy_stm32::{bind_interrupts, peripherals, timer}; 19use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
20use embassy_time::Timer; 20use embassy_time::Timer;
21use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
22 22
23// Connect PB1 and PA6 with a 1k Ohm resistor 23// Connect PB1 and PA6 with a 1k Ohm resistor
24 24
25#[embassy_executor::task] 25#[embassy_executor::task]
26async fn blinky(led: peripherals::PB1) { 26async fn blinky(led: Peri<'static, peripherals::PB1>) {
27 let mut led = Output::new(led, Level::High, Speed::Low); 27 let mut led = Output::new(led, Level::High, Speed::Low);
28 28
29 loop { 29 loop {
diff --git a/examples/stm32g0/src/bin/pwm_input.rs b/examples/stm32g0/src/bin/pwm_input.rs
index db9cf4f8a..9d6b5fe97 100644
--- a/examples/stm32g0/src/bin/pwm_input.rs
+++ b/examples/stm32g0/src/bin/pwm_input.rs
@@ -14,13 +14,13 @@ use embassy_stm32::gpio::{Level, Output, OutputType, Pull, Speed};
14use embassy_stm32::time::khz; 14use embassy_stm32::time::khz;
15use embassy_stm32::timer::pwm_input::PwmInput; 15use embassy_stm32::timer::pwm_input::PwmInput;
16use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; 16use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
17use embassy_stm32::{bind_interrupts, peripherals, timer}; 17use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
18use embassy_time::Timer; 18use embassy_time::Timer;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21// Connect PB1 and PA6 with a 1k Ohm resistor 21// Connect PB1 and PA6 with a 1k Ohm resistor
22#[embassy_executor::task] 22#[embassy_executor::task]
23async fn blinky(led: peripherals::PB1) { 23async fn blinky(led: Peri<'static, peripherals::PB1>) {
24 let mut led = Output::new(led, Level::High, Speed::Low); 24 let mut led = Output::new(led, Level::High, Speed::Low);
25 25
26 loop { 26 loop {
diff --git a/examples/stm32g4/src/bin/adc_dma.rs b/examples/stm32g4/src/bin/adc_dma.rs
index 970623b32..202704085 100644
--- a/examples/stm32g4/src/bin/adc_dma.rs
+++ b/examples/stm32g4/src/bin/adc_dma.rs
@@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) {
41 41
42 loop { 42 loop {
43 adc.read( 43 adc.read(
44 &mut dma, 44 dma.reborrow(),
45 [ 45 [
46 (&mut vrefint_channel, SampleTime::CYCLES247_5), 46 (&mut vrefint_channel, SampleTime::CYCLES247_5),
47 (&mut pa0, SampleTime::CYCLES247_5), 47 (&mut pa0, SampleTime::CYCLES247_5),
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 5b80e5486..5631ff746 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32h563zi to your chip name, if necessary. 8# Change stm32h563zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac", "low-power"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h5/src/bin/cordic.rs b/examples/stm32h5/src/bin/cordic.rs
index 73e873574..cbf854704 100644
--- a/examples/stm32h5/src/bin/cordic.rs
+++ b/examples/stm32h5/src/bin/cordic.rs
@@ -11,7 +11,7 @@ async fn main(_spawner: Spawner) {
11 let mut dp = embassy_stm32::init(Default::default()); 11 let mut dp = embassy_stm32::init(Default::default());
12 12
13 let mut cordic = cordic::Cordic::new( 13 let mut cordic = cordic::Cordic::new(
14 &mut dp.CORDIC, 14 dp.CORDIC.reborrow(),
15 unwrap!(cordic::Config::new( 15 unwrap!(cordic::Config::new(
16 cordic::Function::Sin, 16 cordic::Function::Sin,
17 Default::default(), 17 Default::default(),
@@ -59,8 +59,8 @@ async fn main(_spawner: Spawner) {
59 let cnt1 = unwrap!( 59 let cnt1 = unwrap!(
60 cordic 60 cordic
61 .async_calc_32bit( 61 .async_calc_32bit(
62 &mut dp.GPDMA1_CH0, 62 dp.GPDMA1_CH0.reborrow(),
63 &mut dp.GPDMA1_CH1, 63 dp.GPDMA1_CH1.reborrow(),
64 &input_buf[..arg1.len() - 1], // limit input buf to its actual length 64 &input_buf[..arg1.len() - 1], // limit input buf to its actual length
65 &mut output_u32, 65 &mut output_u32,
66 true, 66 true,
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs
index 0d14c0668..e650791c5 100644
--- a/examples/stm32h5/src/bin/stop.rs
+++ b/examples/stm32h5/src/bin/stop.rs
@@ -10,7 +10,7 @@ use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
10use embassy_stm32::low_power::Executor; 10use embassy_stm32::low_power::Executor;
11use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; 11use embassy_stm32::rcc::{HSIPrescaler, LsConfig};
12use embassy_stm32::rtc::{Rtc, RtcConfig}; 12use embassy_stm32::rtc::{Rtc, RtcConfig};
13use embassy_stm32::Config; 13use embassy_stm32::{Config, Peri};
14use embassy_time::Timer; 14use embassy_time::Timer;
15use static_cell::StaticCell; 15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
@@ -48,7 +48,7 @@ async fn async_main(spawner: Spawner) {
48} 48}
49 49
50#[embassy_executor::task] 50#[embassy_executor::task]
51async fn blinky(led: AnyPin) { 51async fn blinky(led: Peri<'static, AnyPin>) {
52 let mut led = Output::new(led, Level::Low, Speed::Low); 52 let mut led = Output::new(led, Level::Low, Speed::Low);
53 loop { 53 loop {
54 info!("high"); 54 info!("high");
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 4c18bb21c..2f98542bb 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h7/src/bin/adc_dma.rs b/examples/stm32h7/src/bin/adc_dma.rs
index 0b905d227..dc775f18a 100644
--- a/examples/stm32h7/src/bin/adc_dma.rs
+++ b/examples/stm32h7/src/bin/adc_dma.rs
@@ -57,7 +57,7 @@ async fn main(_spawner: Spawner) {
57 57
58 loop { 58 loop {
59 adc.read( 59 adc.read(
60 &mut dma, 60 dma.reborrow(),
61 [ 61 [
62 (&mut vrefint_channel, SampleTime::CYCLES387_5), 62 (&mut vrefint_channel, SampleTime::CYCLES387_5),
63 (&mut pc0, SampleTime::CYCLES810_5), 63 (&mut pc0, SampleTime::CYCLES810_5),
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index a6f969aba..27df80336 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -4,7 +4,6 @@
4use cortex_m_rt::entry; 4use cortex_m_rt::entry;
5use defmt::*; 5use defmt::*;
6use embassy_stm32::dac::{DacCh1, Value}; 6use embassy_stm32::dac::{DacCh1, Value};
7use embassy_stm32::dma::NoDma;
8use embassy_stm32::Config; 7use embassy_stm32::Config;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
@@ -44,7 +43,7 @@ fn main() -> ! {
44 } 43 }
45 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
46 45
47 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 46 let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4);
48 47
49 loop { 48 loop {
50 for v in 0..=255 { 49 for v in 0..=255 {
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index 3a9887e3c..8314754bc 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -4,11 +4,13 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
7use embassy_stm32::mode::Async;
7use embassy_stm32::pac::timer::vals::Mms; 8use embassy_stm32::pac::timer::vals::Mms;
8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 9use embassy_stm32::peripherals::{DAC1, TIM6, TIM7};
9use embassy_stm32::rcc::frequency; 10use embassy_stm32::rcc::frequency;
10use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
11use embassy_stm32::timer::low_level::Timer; 12use embassy_stm32::timer::low_level::Timer;
13use embassy_stm32::Peri;
12use micromath::F32Ext; 14use micromath::F32Ext;
13use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
14 16
@@ -56,7 +58,7 @@ async fn main(spawner: Spawner) {
56} 58}
57 59
58#[embassy_executor::task] 60#[embassy_executor::task]
59async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 61async fn dac_task1(tim: Peri<'static, TIM6>, mut dac: DacCh1<'static, DAC1, Async>) {
60 let data: &[u8; 256] = &calculate_array::<256>(); 62 let data: &[u8; 256] = &calculate_array::<256>();
61 63
62 info!("TIM6 frequency is {}", frequency::<TIM6>()); 64 info!("TIM6 frequency is {}", frequency::<TIM6>());
@@ -99,7 +101,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
99} 101}
100 102
101#[embassy_executor::task] 103#[embassy_executor::task]
102async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 104async fn dac_task2(tim: Peri<'static, TIM7>, mut dac: DacCh2<'static, DAC1, Async>) {
103 let data: &[u8; 256] = &calculate_array::<256>(); 105 let data: &[u8; 256] = &calculate_array::<256>();
104 106
105 info!("TIM7 frequency is {}", frequency::<TIM6>()); 107 info!("TIM7 frequency is {}", frequency::<TIM6>());
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index b796996ea..8de31ea5b 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -7,7 +7,7 @@ use embassy_stm32::gpio::{AfType, Flex, OutputType, Speed};
7use embassy_stm32::time::{khz, Hertz}; 7use embassy_stm32::time::{khz, Hertz};
8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer}; 8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel}; 9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
10use embassy_stm32::{into_ref, Config, Peripheral}; 10use embassy_stm32::{Config, Peri};
11use embassy_time::Timer; 11use embassy_time::Timer;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
@@ -66,15 +66,13 @@ pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> {
66 66
67impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> { 67impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
68 pub fn new( 68 pub fn new(
69 tim: impl Peripheral<P = T> + 'd, 69 tim: Peri<'d, T>,
70 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, 70 ch1: Peri<'d, impl Channel1Pin<T>>,
71 ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd, 71 ch2: Peri<'d, impl Channel2Pin<T>>,
72 ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd, 72 ch3: Peri<'d, impl Channel3Pin<T>>,
73 ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, 73 ch4: Peri<'d, impl Channel4Pin<T>>,
74 freq: Hertz, 74 freq: Hertz,
75 ) -> Self { 75 ) -> Self {
76 into_ref!(ch1, ch2, ch3, ch4);
77
78 let af1 = ch1.af_num(); 76 let af1 = ch1.af_num();
79 let af2 = ch2.af_num(); 77 let af2 = ch2.af_num();
80 let af3 = ch3.af_num(); 78 let af3 = ch3.af_num();
diff --git a/examples/stm32h723/Cargo.toml b/examples/stm32h723/Cargo.toml
index 148d09dd6..749fd78ae 100644
--- a/examples/stm32h723/Cargo.toml
+++ b/examples/stm32h723/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32h723zg to your chip name, if necessary. 8# Change stm32h723zg to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h723zg", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h723zg", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
diff --git a/examples/stm32h723/src/bin/spdifrx.rs b/examples/stm32h723/src/bin/spdifrx.rs
index 69ef5cd07..bc8249ced 100644
--- a/examples/stm32h723/src/bin/spdifrx.rs
+++ b/examples/stm32h723/src/bin/spdifrx.rs
@@ -77,14 +77,19 @@ async fn main(_spawner: Spawner) {
77 }; 77 };
78 78
79 let mut sai_transmitter = new_sai_transmitter( 79 let mut sai_transmitter = new_sai_transmitter(
80 &mut p.SAI4, 80 p.SAI4.reborrow(),
81 &mut p.PD13, 81 p.PD13.reborrow(),
82 &mut p.PC1, 82 p.PC1.reborrow(),
83 &mut p.PD12, 83 p.PD12.reborrow(),
84 &mut p.BDMA_CH0, 84 p.BDMA_CH0.reborrow(),
85 sai_buffer, 85 sai_buffer,
86 ); 86 );
87 let mut spdif_receiver = new_spdif_receiver(&mut p.SPDIFRX1, &mut p.PD7, &mut p.DMA2_CH7, spdifrx_buffer); 87 let mut spdif_receiver = new_spdif_receiver(
88 p.SPDIFRX1.reborrow(),
89 p.PD7.reborrow(),
90 p.DMA2_CH7.reborrow(),
91 spdifrx_buffer,
92 );
88 spdif_receiver.start(); 93 spdif_receiver.start();
89 94
90 let mut renew_sai = false; 95 let mut renew_sai = false;
@@ -96,11 +101,11 @@ async fn main(_spawner: Spawner) {
96 trace!("Renew SAI."); 101 trace!("Renew SAI.");
97 drop(sai_transmitter); 102 drop(sai_transmitter);
98 sai_transmitter = new_sai_transmitter( 103 sai_transmitter = new_sai_transmitter(
99 &mut p.SAI4, 104 p.SAI4.reborrow(),
100 &mut p.PD13, 105 p.PD13.reborrow(),
101 &mut p.PC1, 106 p.PC1.reborrow(),
102 &mut p.PD12, 107 p.PD12.reborrow(),
103 &mut p.BDMA_CH0, 108 p.BDMA_CH0.reborrow(),
104 sai_buffer, 109 sai_buffer,
105 ); 110 );
106 } 111 }
@@ -111,7 +116,12 @@ async fn main(_spawner: Spawner) {
111 Err(spdifrx::Error::RingbufferError(_)) => { 116 Err(spdifrx::Error::RingbufferError(_)) => {
112 trace!("SPDIFRX ringbuffer error. Renew."); 117 trace!("SPDIFRX ringbuffer error. Renew.");
113 drop(spdif_receiver); 118 drop(spdif_receiver);
114 spdif_receiver = new_spdif_receiver(&mut p.SPDIFRX1, &mut p.PD7, &mut p.DMA2_CH7, spdifrx_buffer); 119 spdif_receiver = new_spdif_receiver(
120 p.SPDIFRX1.reborrow(),
121 p.PD7.reborrow(),
122 p.DMA2_CH7.reborrow(),
123 spdifrx_buffer,
124 );
115 spdif_receiver.start(); 125 spdif_receiver.start();
116 continue; 126 continue;
117 } 127 }
diff --git a/examples/stm32h735/Cargo.toml b/examples/stm32h735/Cargo.toml
index 1ae6ed253..4d31dedf1 100644
--- a/examples/stm32h735/Cargo.toml
+++ b/examples/stm32h735/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h735ig", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h735ig", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 10embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
14 14
diff --git a/examples/stm32h755cm4/Cargo.toml b/examples/stm32h755cm4/Cargo.toml
index e3efa0aa2..7c17bc766 100644
--- a/examples/stm32h755cm4/Cargo.toml
+++ b/examples/stm32h755cm4/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm4", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm4", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h755cm7/Cargo.toml b/examples/stm32h755cm7/Cargo.toml
index 1f05c71b5..3186929a8 100644
--- a/examples/stm32h755cm7/Cargo.toml
+++ b/examples/stm32h755cm7/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm7", "time-driver-tim3", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h755zi-cm7", "time-driver-tim3", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 11embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h7b0/Cargo.toml b/examples/stm32h7b0/Cargo.toml
index e0db3c0cd..e5f2dfe86 100644
--- a/examples/stm32h7b0/Cargo.toml
+++ b/examples/stm32h7b0/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7b0vb", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7b0vb", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 10embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32h7rs/Cargo.toml b/examples/stm32h7rs/Cargo.toml
index a47dbe21e..22d59be04 100644
--- a/examples/stm32h7rs/Cargo.toml
+++ b/examples/stm32h7rs/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32h743bi to your chip name, if necessary. 8# Change stm32h743bi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32h7s3l8", "time-driver-tim2", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "medium-ethernet", "medium-ip", "proto-ipv4"] } 13embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "medium-ethernet", "medium-ip", "proto-ipv4"] }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index 495c12936..b609110af 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32l4s5vi to your chip name, if necessary. 8# Change stm32l4s5vi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4r5zi", "memory-x", "time-driver-any", "exti", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4r5zi", "memory-x", "time-driver-any", "exti", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs
index fdbf1d374..50db0e082 100644
--- a/examples/stm32l4/src/bin/dac.rs
+++ b/examples/stm32l4/src/bin/dac.rs
@@ -3,7 +3,6 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::dac::{DacCh1, Value}; 5use embassy_stm32::dac::{DacCh1, Value};
6use embassy_stm32::dma::NoDma;
7use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
8 7
9#[cortex_m_rt::entry] 8#[cortex_m_rt::entry]
@@ -11,7 +10,7 @@ fn main() -> ! {
11 let p = embassy_stm32::init(Default::default()); 10 let p = embassy_stm32::init(Default::default());
12 info!("Hello World!"); 11 info!("Hello World!");
13 12
14 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 13 let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4);
15 14
16 loop { 15 loop {
17 for v in 0..=255 { 16 for v in 0..=255 {
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs
index d01b016c0..cde24f411 100644
--- a/examples/stm32l4/src/bin/dac_dma.rs
+++ b/examples/stm32l4/src/bin/dac_dma.rs
@@ -4,11 +4,13 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
7use embassy_stm32::mode::Async;
7use embassy_stm32::pac::timer::vals::Mms; 8use embassy_stm32::pac::timer::vals::Mms;
8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 9use embassy_stm32::peripherals::{DAC1, TIM6, TIM7};
9use embassy_stm32::rcc::frequency; 10use embassy_stm32::rcc::frequency;
10use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
11use embassy_stm32::timer::low_level::Timer; 12use embassy_stm32::timer::low_level::Timer;
13use embassy_stm32::Peri;
12use micromath::F32Ext; 14use micromath::F32Ext;
13use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
14 16
@@ -27,7 +29,7 @@ async fn main(spawner: Spawner) {
27} 29}
28 30
29#[embassy_executor::task] 31#[embassy_executor::task]
30async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 32async fn dac_task1(tim: Peri<'static, TIM6>, mut dac: DacCh1<'static, DAC1, Async>) {
31 let data: &[u8; 256] = &calculate_array::<256>(); 33 let data: &[u8; 256] = &calculate_array::<256>();
32 34
33 info!("TIM6 frequency is {}", frequency::<TIM6>()); 35 info!("TIM6 frequency is {}", frequency::<TIM6>());
@@ -70,7 +72,7 @@ async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
70} 72}
71 73
72#[embassy_executor::task] 74#[embassy_executor::task]
73async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 75async fn dac_task2(tim: Peri<'static, TIM7>, mut dac: DacCh2<'static, DAC1, Async>) {
74 let data: &[u8; 256] = &calculate_array::<256>(); 76 let data: &[u8; 256] = &calculate_array::<256>();
75 77
76 info!("TIM7 frequency is {}", frequency::<TIM7>()); 78 info!("TIM7 frequency is {}", frequency::<TIM7>());
diff --git a/examples/stm32l432/Cargo.toml b/examples/stm32l432/Cargo.toml
index 71bff8667..e155b3e66 100644
--- a/examples/stm32l432/Cargo.toml
+++ b/examples/stm32l432/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32l4s5vi to your chip name, if necessary. 8# Change stm32l4s5vi to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l432kc", "memory-x", "time-driver-any", "exti", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l432kc", "memory-x", "time-driver-any", "exti", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = [ "defmt" ] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt" ] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = [ "arch-cortex-m", "executor-thread", "defmt" ] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "tick-hz-32_768" ] }
13defmt = "0.3" 13defmt = "0.3"
14defmt-rtt = "0.4" 14defmt-rtt = "0.4"
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 7894abb38..fbf68c890 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32l552ze to your chip name, if necessary. 8# Change stm32l552ze to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs
index 32a736de8..d7a1efea9 100644
--- a/examples/stm32l5/src/bin/stop.rs
+++ b/examples/stm32l5/src/bin/stop.rs
@@ -7,7 +7,7 @@ use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
7use embassy_stm32::low_power::Executor; 7use embassy_stm32::low_power::Executor;
8use embassy_stm32::rcc::LsConfig; 8use embassy_stm32::rcc::LsConfig;
9use embassy_stm32::rtc::{Rtc, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::Config; 10use embassy_stm32::{Config, Peri};
11use embassy_time::Timer; 11use embassy_time::Timer;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -39,7 +39,7 @@ async fn async_main(spawner: Spawner) {
39} 39}
40 40
41#[embassy_executor::task] 41#[embassy_executor::task]
42async fn blinky(led: AnyPin) -> ! { 42async fn blinky(led: Peri<'static, AnyPin>) -> ! {
43 let mut led = Output::new(led, Level::Low, Speed::Low); 43 let mut led = Output::new(led, Level::Low, Speed::Low);
44 loop { 44 loop {
45 info!("high"); 45 info!("high");
diff --git a/examples/stm32u0/src/bin/dac.rs b/examples/stm32u0/src/bin/dac.rs
index fdbf1d374..50db0e082 100644
--- a/examples/stm32u0/src/bin/dac.rs
+++ b/examples/stm32u0/src/bin/dac.rs
@@ -3,7 +3,6 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::dac::{DacCh1, Value}; 5use embassy_stm32::dac::{DacCh1, Value};
6use embassy_stm32::dma::NoDma;
7use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
8 7
9#[cortex_m_rt::entry] 8#[cortex_m_rt::entry]
@@ -11,7 +10,7 @@ fn main() -> ! {
11 let p = embassy_stm32::init(Default::default()); 10 let p = embassy_stm32::init(Default::default());
12 info!("Hello World!"); 11 info!("Hello World!");
13 12
14 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); 13 let mut dac = DacCh1::new_blocking(p.DAC1, p.PA4);
15 14
16 loop { 15 loop {
17 for v in 0..=255 { 16 for v in 0..=255 {
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 33e75cf1e..886c5cb2e 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32u5g9zj to your chip name, if necessary. 8# Change stm32u5g9zj to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u5g9zj", "time-driver-any", "memory-x" ] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u5g9zj", "time-driver-any", "memory-x" ] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.4.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
diff --git a/examples/stm32u5/src/bin/adc.rs b/examples/stm32u5/src/bin/adc.rs
index 6ba21cc63..d2aa28087 100644
--- a/examples/stm32u5/src/bin/adc.rs
+++ b/examples/stm32u5/src/bin/adc.rs
@@ -72,7 +72,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
72 let mut measurements = [0u16; 2]; 72 let mut measurements = [0u16; 2];
73 73
74 adc1.read( 74 adc1.read(
75 &mut p.GPDMA1_CH0, 75 p.GPDMA1_CH0.reborrow(),
76 [ 76 [
77 (&mut degraded11, adc::SampleTime::CYCLES160_5), 77 (&mut degraded11, adc::SampleTime::CYCLES160_5),
78 (&mut degraded12, adc::SampleTime::CYCLES160_5), 78 (&mut degraded12, adc::SampleTime::CYCLES160_5),
@@ -96,7 +96,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
96 96
97 // The channels must be in ascending order and can't repeat for ADC4 97 // The channels must be in ascending order and can't repeat for ADC4
98 adc4.read( 98 adc4.read(
99 &mut p.GPDMA1_CH1, 99 p.GPDMA1_CH1.reborrow(),
100 [&mut degraded42, &mut degraded41].into_iter(), 100 [&mut degraded42, &mut degraded41].into_iter(),
101 &mut measurements, 101 &mut measurements,
102 ) 102 )
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index e9959b905..96f66f3af 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] }
10embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] } 10embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", features = ["defmt", "stm32wb55rg"] }
11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 12embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 14embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true }
15 15
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml
index 0f55bee39..60b09adb4 100644
--- a/examples/stm32wba/Cargo.toml
+++ b/examples/stm32wba/Cargo.toml
@@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba55cg", "time-driver-any", "memory-x", "exti"] } 8embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba55cg", "time-driver-any", "memory-x", "exti"] }
9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 10embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 11embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 12embassy-net = { version = "0.7.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true }
13 13
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index 194e58459..6b677914e 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
8# Change stm32wl55jc-cm4 to your chip name, if necessary. 8# Change stm32wl55jc-cm4 to your chip name, if necessary.
9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } 9embassy-stm32 = { version = "0.2.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "defmt"] } 11embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../embassy-embedded-hal" }
14 14
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml
index 6aa5e2bcc..410d62bdd 100644
--- a/tests/nrf/Cargo.toml
+++ b/tests/nrf/Cargo.toml
@@ -33,7 +33,7 @@ portable-atomic = { version = "1.6.0" }
33nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] 33nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"]
34nrf52832 = ["embassy-nrf/nrf52832", "easydma"] 34nrf52832 = ["embassy-nrf/nrf52832", "easydma"]
35nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"] 35nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"]
36nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts", "embassy-executor/task-arena-size-16384"] 36nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"]
37nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"] 37nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"]
38nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"] 38nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"]
39 39
diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs
index 04f32832f..2eecafb95 100644
--- a/tests/nrf/src/bin/buffered_uart.rs
+++ b/tests/nrf/src/bin/buffered_uart.rs
@@ -25,14 +25,14 @@ async fn main(_spawner: Spawner) {
25 // test teardown + recreate of the buffereduarte works fine. 25 // test teardown + recreate of the buffereduarte works fine.
26 for _ in 0..2 { 26 for _ in 0..2 {
27 let u = BufferedUarte::new( 27 let u = BufferedUarte::new(
28 &mut peri!(p, UART0), 28 peri!(p, UART0).reborrow(),
29 &mut p.TIMER0, 29 p.TIMER0.reborrow(),
30 &mut p.PPI_CH0, 30 p.PPI_CH0.reborrow(),
31 &mut p.PPI_CH1, 31 p.PPI_CH1.reborrow(),
32 &mut p.PPI_GROUP0, 32 p.PPI_GROUP0.reborrow(),
33 irqs!(UART0_BUFFERED), 33 irqs!(UART0_BUFFERED),
34 &mut peri!(p, PIN_A), 34 peri!(p, PIN_A).reborrow(),
35 &mut peri!(p, PIN_B), 35 peri!(p, PIN_B).reborrow(),
36 config.clone(), 36 config.clone(),
37 &mut rx_buffer, 37 &mut rx_buffer,
38 &mut tx_buffer, 38 &mut tx_buffer,
diff --git a/tests/nrf/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs
index bdf5ad726..adfba509d 100644
--- a/tests/nrf/src/bin/buffered_uart_halves.rs
+++ b/tests/nrf/src/bin/buffered_uart_halves.rs
@@ -27,21 +27,21 @@ async fn main(_spawner: Spawner) {
27 const COUNT: usize = 40_000; 27 const COUNT: usize = 40_000;
28 28
29 let mut tx = BufferedUarteTx::new( 29 let mut tx = BufferedUarteTx::new(
30 &mut peri!(p, UART1), 30 peri!(p, UART1).reborrow(),
31 irqs!(UART1_BUFFERED), 31 irqs!(UART1_BUFFERED),
32 &mut peri!(p, PIN_A), 32 peri!(p, PIN_A).reborrow(),
33 config.clone(), 33 config.clone(),
34 &mut tx_buffer, 34 &mut tx_buffer,
35 ); 35 );
36 36
37 let mut rx = BufferedUarteRx::new( 37 let mut rx = BufferedUarteRx::new(
38 &mut peri!(p, UART0), 38 peri!(p, UART0).reborrow(),
39 &mut p.TIMER0, 39 p.TIMER0.reborrow(),
40 &mut p.PPI_CH0, 40 p.PPI_CH0.reborrow(),
41 &mut p.PPI_CH1, 41 p.PPI_CH1.reborrow(),
42 &mut p.PPI_GROUP0, 42 p.PPI_GROUP0.reborrow(),
43 irqs!(UART0_BUFFERED), 43 irqs!(UART0_BUFFERED),
44 &mut peri!(p, PIN_B), 44 peri!(p, PIN_B).reborrow(),
45 config.clone(), 45 config.clone(),
46 &mut rx_buffer, 46 &mut rx_buffer,
47 ); 47 );
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs
index cf9ca50d2..24ddd06f3 100644
--- a/tests/nrf/src/bin/buffered_uart_spam.rs
+++ b/tests/nrf/src/bin/buffered_uart_spam.rs
@@ -27,7 +27,11 @@ async fn main(_spawner: Spawner) {
27 27
28 let mut rx_buffer = [0u8; 1024]; 28 let mut rx_buffer = [0u8; 1024];
29 29
30 mem::forget(Output::new(&mut peri!(p, PIN_A), Level::High, OutputDrive::Standard)); 30 mem::forget(Output::new(
31 peri!(p, PIN_A).reborrow(),
32 Level::High,
33 OutputDrive::Standard,
34 ));
31 35
32 let mut u = BufferedUarteRx::new( 36 let mut u = BufferedUarteRx::new(
33 peri!(p, UART0), 37 peri!(p, UART0),
diff --git a/tests/nrf/src/bin/spim.rs b/tests/nrf/src/bin/spim.rs
index c2ec90b88..2b38f0409 100644
--- a/tests/nrf/src/bin/spim.rs
+++ b/tests/nrf/src/bin/spim.rs
@@ -17,11 +17,11 @@ async fn main(_spawner: Spawner) {
17 let mut config = spim::Config::default(); 17 let mut config = spim::Config::default();
18 config.frequency = spim::Frequency::M1; 18 config.frequency = spim::Frequency::M1;
19 let mut spim = Spim::new( 19 let mut spim = Spim::new(
20 &mut peri!(p, SPIM0), 20 peri!(p, SPIM0).reborrow(),
21 irqs!(SPIM0), 21 irqs!(SPIM0),
22 &mut peri!(p, PIN_X), 22 peri!(p, PIN_X).reborrow(),
23 &mut peri!(p, PIN_A), // MISO 23 peri!(p, PIN_A).reborrow(), // MISO
24 &mut peri!(p, PIN_B), // MOSI 24 peri!(p, PIN_B).reborrow(), // MOSI
25 config.clone(), 25 config.clone(),
26 ); 26 );
27 let data = [ 27 let data = [
diff --git a/tests/nrf/src/bin/uart_halves.rs b/tests/nrf/src/bin/uart_halves.rs
index f48ea43a1..a462f80ce 100644
--- a/tests/nrf/src/bin/uart_halves.rs
+++ b/tests/nrf/src/bin/uart_halves.rs
@@ -19,8 +19,18 @@ async fn main(_spawner: Spawner) {
19 config.parity = uarte::Parity::EXCLUDED; 19 config.parity = uarte::Parity::EXCLUDED;
20 config.baudrate = uarte::Baudrate::BAUD1M; 20 config.baudrate = uarte::Baudrate::BAUD1M;
21 21
22 let mut tx = UarteTx::new(&mut peri!(p, UART0), irqs!(UART0), &mut peri!(p, PIN_A), config.clone()); 22 let mut tx = UarteTx::new(
23 let mut rx = UarteRx::new(&mut peri!(p, UART1), irqs!(UART1), &mut peri!(p, PIN_B), config.clone()); 23 peri!(p, UART0).reborrow(),
24 irqs!(UART0),
25 peri!(p, PIN_A).reborrow(),
26 config.clone(),
27 );
28 let mut rx = UarteRx::new(
29 peri!(p, UART1).reborrow(),
30 irqs!(UART1),
31 peri!(p, PIN_B).reborrow(),
32 config.clone(),
33 );
24 34
25 let data = [ 35 let data = [
26 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, 36 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs
index 70d8b2e33..f24903297 100644
--- a/tests/nrf/src/bin/uart_split.rs
+++ b/tests/nrf/src/bin/uart_split.rs
@@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) {
21 config.baudrate = uarte::Baudrate::BAUD9600; 21 config.baudrate = uarte::Baudrate::BAUD9600;
22 22
23 let uarte = Uarte::new( 23 let uarte = Uarte::new(
24 &mut peri!(p, UART0), 24 peri!(p, UART0).reborrow(),
25 irqs!(UART0), 25 irqs!(UART0),
26 &mut peri!(p, PIN_A), 26 peri!(p, PIN_A).reborrow(),
27 &mut peri!(p, PIN_B), 27 peri!(p, PIN_B).reborrow(),
28 config.clone(), 28 config.clone(),
29 ); 29 );
30 let (mut tx, mut rx) = uarte.split(); 30 let (mut tx, mut rx) = uarte.split();
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 503c4d67b..1335aa84b 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -13,7 +13,7 @@ rp235xb = ["embassy-rp/rp235xb"]
13teleprobe-meta = "1.1" 13teleprobe-meta = "1.1"
14 14
15embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } 15embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] }
16embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt"] } 16embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
17embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] } 17embassy-time = { version = "0.4.0", path = "../../embassy-time", features = ["defmt", ] }
18embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } 18embassy-rp = { version = "0.4.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] }
19embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 19embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs
index 87e9709cc..c2175bc03 100644
--- a/tests/rp/src/bin/adc.rs
+++ b/tests/rp/src/bin/adc.rs
@@ -30,12 +30,12 @@ async fn main(_spawner: Spawner) {
30 30
31 { 31 {
32 { 32 {
33 let mut p = Channel::new_pin(&mut a, Pull::Down); 33 let mut p = Channel::new_pin(a.reborrow(), Pull::Down);
34 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 34 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
35 defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); 35 defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000);
36 } 36 }
37 { 37 {
38 let mut p = Channel::new_pin(&mut a, Pull::Up); 38 let mut p = Channel::new_pin(a.reborrow(), Pull::Up);
39 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 39 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
40 defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); 40 defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000);
41 } 41 }
@@ -43,21 +43,21 @@ async fn main(_spawner: Spawner) {
43 // not bothering with async reads from now on 43 // not bothering with async reads from now on
44 { 44 {
45 { 45 {
46 let mut p = Channel::new_pin(&mut b, Pull::Down); 46 let mut p = Channel::new_pin(b.reborrow(), Pull::Down);
47 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 47 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
48 } 48 }
49 { 49 {
50 let mut p = Channel::new_pin(&mut b, Pull::Up); 50 let mut p = Channel::new_pin(b.reborrow(), Pull::Up);
51 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 51 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
52 } 52 }
53 } 53 }
54 { 54 {
55 { 55 {
56 let mut p = Channel::new_pin(&mut c, Pull::Down); 56 let mut p = Channel::new_pin(c.reborrow(), Pull::Down);
57 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); 57 defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000);
58 } 58 }
59 { 59 {
60 let mut p = Channel::new_pin(&mut c, Pull::Up); 60 let mut p = Channel::new_pin(c.reborrow(), Pull::Up);
61 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); 61 defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000);
62 } 62 }
63 } 63 }
@@ -65,15 +65,15 @@ async fn main(_spawner: Spawner) {
65 // gp29 is connected to vsys through a 200k/100k divider, 65 // gp29 is connected to vsys through a 200k/100k divider,
66 // adding pulls should change the value 66 // adding pulls should change the value
67 let low = { 67 let low = {
68 let mut p = Channel::new_pin(&mut d, Pull::Down); 68 let mut p = Channel::new_pin(d.reborrow(), Pull::Down);
69 adc.blocking_read(&mut p).unwrap() 69 adc.blocking_read(&mut p).unwrap()
70 }; 70 };
71 let none = { 71 let none = {
72 let mut p = Channel::new_pin(&mut d, Pull::None); 72 let mut p = Channel::new_pin(d.reborrow(), Pull::None);
73 adc.blocking_read(&mut p).unwrap() 73 adc.blocking_read(&mut p).unwrap()
74 }; 74 };
75 let up = { 75 let up = {
76 let mut p = Channel::new_pin(&mut d, Pull::Up); 76 let mut p = Channel::new_pin(d.reborrow(), Pull::Up);
77 adc.blocking_read(&mut p).unwrap() 77 adc.blocking_read(&mut p).unwrap()
78 }; 78 };
79 defmt::assert!(low < none); 79 defmt::assert!(low < none);
@@ -81,7 +81,7 @@ async fn main(_spawner: Spawner) {
81 } 81 }
82 { 82 {
83 let temp = convert_to_celsius( 83 let temp = convert_to_celsius(
84 adc.read(&mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR)) 84 adc.read(&mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()))
85 .await 85 .await
86 .unwrap(), 86 .unwrap(),
87 ); 87 );
@@ -97,14 +97,29 @@ async fn main(_spawner: Spawner) {
97 let mut low = [0u16; 16]; 97 let mut low = [0u16; 16];
98 let mut none = [0u8; 16]; 98 let mut none = [0u8; 16];
99 let mut up = [Sample::default(); 16]; 99 let mut up = [Sample::default(); 16];
100 adc.read_many(&mut Channel::new_pin(&mut d, Pull::Down), &mut low, 1, &mut p.DMA_CH0) 100 adc.read_many(
101 .await 101 &mut Channel::new_pin(d.reborrow(), Pull::Down),
102 .unwrap(); 102 &mut low,
103 adc.read_many(&mut Channel::new_pin(&mut d, Pull::None), &mut none, 1, &mut p.DMA_CH0) 103 1,
104 .await 104 p.DMA_CH0.reborrow(),
105 .unwrap(); 105 )
106 adc.read_many_raw(&mut Channel::new_pin(&mut d, Pull::Up), &mut up, 1, &mut p.DMA_CH0) 106 .await
107 .await; 107 .unwrap();
108 adc.read_many(
109 &mut Channel::new_pin(d.reborrow(), Pull::None),
110 &mut none,
111 1,
112 p.DMA_CH0.reborrow(),
113 )
114 .await
115 .unwrap();
116 adc.read_many_raw(
117 &mut Channel::new_pin(d.reborrow(), Pull::Up),
118 &mut up,
119 1,
120 p.DMA_CH0.reborrow(),
121 )
122 .await;
108 defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); 123 defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16));
109 defmt::assert!(up.iter().all(|s| s.good())); 124 defmt::assert!(up.iter().all(|s| s.good()));
110 defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value())); 125 defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value()));
@@ -112,10 +127,10 @@ async fn main(_spawner: Spawner) {
112 { 127 {
113 let mut temp = [0u16; 16]; 128 let mut temp = [0u16; 16];
114 adc.read_many( 129 adc.read_many(
115 &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), 130 &mut Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()),
116 &mut temp, 131 &mut temp,
117 1, 132 1,
118 &mut p.DMA_CH0, 133 p.DMA_CH0.reborrow(),
119 ) 134 )
120 .await 135 .await
121 .unwrap(); 136 .unwrap();
@@ -126,10 +141,10 @@ async fn main(_spawner: Spawner) {
126 { 141 {
127 let mut multi = [0u16; 2]; 142 let mut multi = [0u16; 2];
128 let mut channels = [ 143 let mut channels = [
129 Channel::new_pin(&mut a, Pull::Up), 144 Channel::new_pin(a.reborrow(), Pull::Up),
130 Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), 145 Channel::new_temp_sensor(p.ADC_TEMP_SENSOR.reborrow()),
131 ]; 146 ];
132 adc.read_many_multichannel(&mut channels, &mut multi, 1, &mut p.DMA_CH0) 147 adc.read_many_multichannel(&mut channels, &mut multi, 1, p.DMA_CH0.reborrow())
133 .await 148 .await
134 .unwrap(); 149 .unwrap();
135 defmt::assert!(multi[0] > 3_000); 150 defmt::assert!(multi[0] > 3_000);
diff --git a/tests/rp/src/bin/bootsel.rs b/tests/rp/src/bin/bootsel.rs
index e88d8bf6c..aa123ab03 100644
--- a/tests/rp/src/bin/bootsel.rs
+++ b/tests/rp/src/bin/bootsel.rs
@@ -4,12 +4,13 @@ teleprobe_meta::target!(b"rpi-pico");
4 4
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::bootsel::is_bootsel_pressed;
7use embassy_time::Timer; 8use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
9 10
10#[embassy_executor::main] 11#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
12 let mut p = embassy_rp::init(Default::default()); 13 let p = embassy_rp::init(Default::default());
13 info!("Hello World!"); 14 info!("Hello World!");
14 15
15 // add some delay to give an attached debug probe time to parse the 16 // add some delay to give an attached debug probe time to parse the
@@ -18,7 +19,7 @@ async fn main(_spawner: Spawner) {
18 // https://github.com/knurling-rs/defmt/pull/683 19 // https://github.com/knurling-rs/defmt/pull/683
19 Timer::after_millis(10).await; 20 Timer::after_millis(10).await;
20 21
21 assert_eq!(p.BOOTSEL.is_pressed(), false); 22 assert_eq!(is_bootsel_pressed(p.BOOTSEL), false);
22 23
23 info!("Test OK"); 24 info!("Test OK");
24 cortex_m::asm::bkpt(); 25 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs
index 6c37ac5be..614b6317a 100644
--- a/tests/rp/src/bin/gpio.rs
+++ b/tests/rp/src/bin/gpio.rs
@@ -21,10 +21,10 @@ async fn main(_spawner: Spawner) {
21 21
22 // Test initial output 22 // Test initial output
23 { 23 {
24 let b = Input::new(&mut b, Pull::None); 24 let b = Input::new(b.reborrow(), Pull::None);
25 25
26 { 26 {
27 let a = Output::new(&mut a, Level::Low); 27 let a = Output::new(a.reborrow(), Level::Low);
28 delay(); 28 delay();
29 assert!(b.is_low()); 29 assert!(b.is_low());
30 assert!(!b.is_high()); 30 assert!(!b.is_high());
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
32 assert!(!a.is_set_high()); 32 assert!(!a.is_set_high());
33 } 33 }
34 { 34 {
35 let mut a = Output::new(&mut a, Level::High); 35 let mut a = Output::new(a.reborrow(), Level::High);
36 delay(); 36 delay();
37 assert!(!b.is_low()); 37 assert!(!b.is_low());
38 assert!(b.is_high()); 38 assert!(b.is_high());
@@ -69,10 +69,10 @@ async fn main(_spawner: Spawner) {
69 69
70 // Test input no pull 70 // Test input no pull
71 { 71 {
72 let b = Input::new(&mut b, Pull::None); 72 let b = Input::new(b.reborrow(), Pull::None);
73 // no pull, the status is undefined 73 // no pull, the status is undefined
74 74
75 let mut a = Output::new(&mut a, Level::Low); 75 let mut a = Output::new(a.reborrow(), Level::Low);
76 delay(); 76 delay();
77 assert!(b.is_low()); 77 assert!(b.is_low());
78 a.set_high(); 78 a.set_high();
@@ -83,11 +83,11 @@ async fn main(_spawner: Spawner) {
83 // Test input pulldown 83 // Test input pulldown
84 #[cfg(feature = "rp2040")] 84 #[cfg(feature = "rp2040")]
85 { 85 {
86 let b = Input::new(&mut b, Pull::Down); 86 let b = Input::new(b.reborrow(), Pull::Down);
87 delay(); 87 delay();
88 assert!(b.is_low()); 88 assert!(b.is_low());
89 89
90 let mut a = Output::new(&mut a, Level::Low); 90 let mut a = Output::new(a.reborrow(), Level::Low);
91 delay(); 91 delay();
92 assert!(b.is_low()); 92 assert!(b.is_low());
93 a.set_high(); 93 a.set_high();
@@ -97,11 +97,11 @@ async fn main(_spawner: Spawner) {
97 97
98 // Test input pullup 98 // Test input pullup
99 { 99 {
100 let b = Input::new(&mut b, Pull::Up); 100 let b = Input::new(b.reborrow(), Pull::Up);
101 delay(); 101 delay();
102 assert!(b.is_high()); 102 assert!(b.is_high());
103 103
104 let mut a = Output::new(&mut a, Level::Low); 104 let mut a = Output::new(a.reborrow(), Level::Low);
105 delay(); 105 delay();
106 assert!(b.is_low()); 106 assert!(b.is_low());
107 a.set_high(); 107 a.set_high();
@@ -112,8 +112,8 @@ async fn main(_spawner: Spawner) {
112 // OUTPUT OPEN DRAIN 112 // OUTPUT OPEN DRAIN
113 #[cfg(feature = "rp2040")] 113 #[cfg(feature = "rp2040")]
114 { 114 {
115 let mut b = OutputOpenDrain::new(&mut b, Level::High); 115 let mut b = OutputOpenDrain::new(b.reborrow(), Level::High);
116 let mut a = Flex::new(&mut a); 116 let mut a = Flex::new(a.reborrow());
117 a.set_as_input(); 117 a.set_as_input();
118 118
119 // When an OutputOpenDrain is high, it doesn't drive the pin. 119 // When an OutputOpenDrain is high, it doesn't drive the pin.
@@ -170,12 +170,12 @@ async fn main(_spawner: Spawner) {
170 // Test initial output 170 // Test initial output
171 { 171 {
172 //Flex pin configured as input 172 //Flex pin configured as input
173 let mut b = Flex::new(&mut b); 173 let mut b = Flex::new(b.reborrow());
174 b.set_as_input(); 174 b.set_as_input();
175 175
176 { 176 {
177 //Flex pin configured as output 177 //Flex pin configured as output
178 let mut a = Flex::new(&mut a); //Flex pin configured as output 178 let mut a = Flex::new(a.reborrow()); //Flex pin configured as output
179 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state 179 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state
180 a.set_as_output(); 180 a.set_as_output();
181 delay(); 181 delay();
@@ -183,7 +183,7 @@ async fn main(_spawner: Spawner) {
183 } 183 }
184 { 184 {
185 //Flex pin configured as output 185 //Flex pin configured as output
186 let mut a = Flex::new(&mut a); 186 let mut a = Flex::new(a.reborrow());
187 a.set_high(); 187 a.set_high();
188 a.set_as_output(); 188 a.set_as_output();
189 189
@@ -194,10 +194,10 @@ async fn main(_spawner: Spawner) {
194 194
195 // Test input no pull 195 // Test input no pull
196 { 196 {
197 let mut b = Flex::new(&mut b); 197 let mut b = Flex::new(b.reborrow());
198 b.set_as_input(); // no pull by default. 198 b.set_as_input(); // no pull by default.
199 199
200 let mut a = Flex::new(&mut a); 200 let mut a = Flex::new(a.reborrow());
201 a.set_low(); 201 a.set_low();
202 a.set_as_output(); 202 a.set_as_output();
203 203
@@ -211,13 +211,13 @@ async fn main(_spawner: Spawner) {
211 // Test input pulldown 211 // Test input pulldown
212 #[cfg(feature = "rp2040")] 212 #[cfg(feature = "rp2040")]
213 { 213 {
214 let mut b = Flex::new(&mut b); 214 let mut b = Flex::new(b.reborrow());
215 b.set_as_input(); 215 b.set_as_input();
216 b.set_pull(Pull::Down); 216 b.set_pull(Pull::Down);
217 delay(); 217 delay();
218 assert!(b.is_low()); 218 assert!(b.is_low());
219 219
220 let mut a = Flex::new(&mut a); 220 let mut a = Flex::new(a.reborrow());
221 a.set_low(); 221 a.set_low();
222 a.set_as_output(); 222 a.set_as_output();
223 delay(); 223 delay();
@@ -229,13 +229,13 @@ async fn main(_spawner: Spawner) {
229 229
230 // Test input pullup 230 // Test input pullup
231 { 231 {
232 let mut b = Flex::new(&mut b); 232 let mut b = Flex::new(b.reborrow());
233 b.set_as_input(); 233 b.set_as_input();
234 b.set_pull(Pull::Up); 234 b.set_pull(Pull::Up);
235 delay(); 235 delay();
236 assert!(b.is_high()); 236 assert!(b.is_high());
237 237
238 let mut a = Flex::new(&mut a); 238 let mut a = Flex::new(a.reborrow());
239 a.set_high(); 239 a.set_high();
240 a.set_as_output(); 240 a.set_as_output();
241 delay(); 241 delay();
diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs
index 39e3d6337..72fb0910d 100644
--- a/tests/rp/src/bin/gpio_async.rs
+++ b/tests/rp/src/bin/gpio_async.rs
@@ -22,8 +22,8 @@ async fn main(_spawner: Spawner) {
22 22
23 { 23 {
24 info!("test wait_for_high"); 24 info!("test wait_for_high");
25 let mut output = Output::new(&mut output_pin, Level::Low); 25 let mut output = Output::new(output_pin.reborrow(), Level::Low);
26 let mut input = Input::new(&mut input_pin, Pull::None); 26 let mut input = Input::new(input_pin.reborrow(), Pull::None);
27 27
28 assert!(input.is_low(), "input was expected to be low"); 28 assert!(input.is_low(), "input was expected to be low");
29 29
@@ -43,8 +43,8 @@ async fn main(_spawner: Spawner) {
43 43
44 { 44 {
45 info!("test wait_for_low"); 45 info!("test wait_for_low");
46 let mut output = Output::new(&mut output_pin, Level::High); 46 let mut output = Output::new(output_pin.reborrow(), Level::High);
47 let mut input = Input::new(&mut input_pin, Pull::None); 47 let mut input = Input::new(input_pin.reborrow(), Pull::None);
48 48
49 assert!(input.is_high(), "input was expected to be high"); 49 assert!(input.is_high(), "input was expected to be high");
50 50
@@ -63,8 +63,8 @@ async fn main(_spawner: Spawner) {
63 63
64 { 64 {
65 info!("test wait_for_rising_edge"); 65 info!("test wait_for_rising_edge");
66 let mut output = Output::new(&mut output_pin, Level::Low); 66 let mut output = Output::new(output_pin.reborrow(), Level::Low);
67 let mut input = Input::new(&mut input_pin, Pull::None); 67 let mut input = Input::new(input_pin.reborrow(), Pull::None);
68 68
69 assert!(input.is_low(), "input was expected to be low"); 69 assert!(input.is_low(), "input was expected to be low");
70 70
@@ -83,8 +83,8 @@ async fn main(_spawner: Spawner) {
83 83
84 { 84 {
85 info!("test wait_for_falling_edge"); 85 info!("test wait_for_falling_edge");
86 let mut output = Output::new(&mut output_pin, Level::High); 86 let mut output = Output::new(output_pin.reborrow(), Level::High);
87 let mut input = Input::new(&mut input_pin, Pull::None); 87 let mut input = Input::new(input_pin.reborrow(), Pull::None);
88 88
89 assert!(input.is_high(), "input was expected to be high"); 89 assert!(input.is_high(), "input was expected to be high");
90 90
@@ -103,8 +103,8 @@ async fn main(_spawner: Spawner) {
103 103
104 { 104 {
105 info!("test wait_for_any_edge (falling)"); 105 info!("test wait_for_any_edge (falling)");
106 let mut output = Output::new(&mut output_pin, Level::High); 106 let mut output = Output::new(output_pin.reborrow(), Level::High);
107 let mut input = Input::new(&mut input_pin, Pull::None); 107 let mut input = Input::new(input_pin.reborrow(), Pull::None);
108 108
109 assert!(input.is_high(), "input was expected to be high"); 109 assert!(input.is_high(), "input was expected to be high");
110 110
@@ -123,8 +123,8 @@ async fn main(_spawner: Spawner) {
123 123
124 { 124 {
125 info!("test wait_for_any_edge (rising)"); 125 info!("test wait_for_any_edge (rising)");
126 let mut output = Output::new(&mut output_pin, Level::Low); 126 let mut output = Output::new(output_pin.reborrow(), Level::Low);
127 let mut input = Input::new(&mut input_pin, Pull::None); 127 let mut input = Input::new(input_pin.reborrow(), Pull::None);
128 128
129 assert!(input.is_low(), "input was expected to be low"); 129 assert!(input.is_low(), "input was expected to be low");
130 130
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs
index 3caa8ef35..857f36975 100644
--- a/tests/rp/src/bin/gpio_multicore.rs
+++ b/tests/rp/src/bin/gpio_multicore.rs
@@ -10,6 +10,7 @@ use embassy_executor::Executor;
10use embassy_rp::gpio::{Input, Level, Output, Pull}; 10use embassy_rp::gpio::{Input, Level, Output, Pull};
11use embassy_rp::multicore::{spawn_core1, Stack}; 11use embassy_rp::multicore::{spawn_core1, Stack};
12use embassy_rp::peripherals::{PIN_0, PIN_1}; 12use embassy_rp::peripherals::{PIN_0, PIN_1};
13use embassy_rp::Peri;
13use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
14use embassy_sync::channel::Channel; 15use embassy_sync::channel::Channel;
15use static_cell::StaticCell; 16use static_cell::StaticCell;
@@ -37,7 +38,7 @@ fn main() -> ! {
37} 38}
38 39
39#[embassy_executor::task] 40#[embassy_executor::task]
40async fn core0_task(p: PIN_0) { 41async fn core0_task(p: Peri<'static, PIN_0>) {
41 info!("CORE0 is running"); 42 info!("CORE0 is running");
42 43
43 let mut pin = Output::new(p, Level::Low); 44 let mut pin = Output::new(p, Level::Low);
@@ -54,7 +55,7 @@ async fn core0_task(p: PIN_0) {
54} 55}
55 56
56#[embassy_executor::task] 57#[embassy_executor::task]
57async fn core1_task(p: PIN_1) { 58async fn core1_task(p: Peri<'static, PIN_1>) {
58 info!("CORE1 is running"); 59 info!("CORE1 is running");
59 60
60 CHANNEL0.receive().await; 61 CHANNEL0.receive().await;
diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs
index d8ee78dcd..5f890cd50 100644
--- a/tests/rp/src/bin/pwm.rs
+++ b/tests/rp/src/bin/pwm.rs
@@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) {
33 33
34 // Test free-running clock 34 // Test free-running clock
35 { 35 {
36 let pwm = Pwm::new_free(&mut p.PWM_SLICE3, cfg.clone()); 36 let pwm = Pwm::new_free(p.PWM_SLICE3.reborrow(), cfg.clone());
37 cortex_m::asm::delay(125); 37 cortex_m::asm::delay(125);
38 let ctr = pwm.counter(); 38 let ctr = pwm.counter();
39 assert!(ctr > 0); 39 assert!(ctr > 0);
@@ -50,8 +50,8 @@ async fn main(_spawner: Spawner) {
50 50
51 // Test output from A 51 // Test output from A
52 { 52 {
53 let pin1 = Input::new(&mut p9, Pull::None); 53 let pin1 = Input::new(p9.reborrow(), Pull::None);
54 let _pwm = Pwm::new_output_a(&mut p.PWM_SLICE3, &mut p6, cfg.clone()); 54 let _pwm = Pwm::new_output_a(p.PWM_SLICE3.reborrow(), p6.reborrow(), cfg.clone());
55 Timer::after_millis(1).await; 55 Timer::after_millis(1).await;
56 assert_eq!(pin1.is_low(), invert_a); 56 assert_eq!(pin1.is_low(), invert_a);
57 Timer::after_millis(5).await; 57 Timer::after_millis(5).await;
@@ -64,8 +64,8 @@ async fn main(_spawner: Spawner) {
64 64
65 // Test output from B 65 // Test output from B
66 { 66 {
67 let pin2 = Input::new(&mut p11, Pull::None); 67 let pin2 = Input::new(p11.reborrow(), Pull::None);
68 let _pwm = Pwm::new_output_b(&mut p.PWM_SLICE3, &mut p7, cfg.clone()); 68 let _pwm = Pwm::new_output_b(p.PWM_SLICE3.reborrow(), p7.reborrow(), cfg.clone());
69 Timer::after_millis(1).await; 69 Timer::after_millis(1).await;
70 assert_ne!(pin2.is_low(), invert_a); 70 assert_ne!(pin2.is_low(), invert_a);
71 Timer::after_millis(5).await; 71 Timer::after_millis(5).await;
@@ -78,9 +78,9 @@ async fn main(_spawner: Spawner) {
78 78
79 // Test output from A+B 79 // Test output from A+B
80 { 80 {
81 let pin1 = Input::new(&mut p9, Pull::None); 81 let pin1 = Input::new(p9.reborrow(), Pull::None);
82 let pin2 = Input::new(&mut p11, Pull::None); 82 let pin2 = Input::new(p11.reborrow(), Pull::None);
83 let _pwm = Pwm::new_output_ab(&mut p.PWM_SLICE3, &mut p6, &mut p7, cfg.clone()); 83 let _pwm = Pwm::new_output_ab(p.PWM_SLICE3.reborrow(), p6.reborrow(), p7.reborrow(), cfg.clone());
84 Timer::after_millis(1).await; 84 Timer::after_millis(1).await;
85 assert_eq!(pin1.is_low(), invert_a); 85 assert_eq!(pin1.is_low(), invert_a);
86 assert_ne!(pin2.is_low(), invert_a); 86 assert_ne!(pin2.is_low(), invert_a);
@@ -99,8 +99,14 @@ async fn main(_spawner: Spawner) {
99 // Test level-gated 99 // Test level-gated
100 #[cfg(feature = "rp2040")] 100 #[cfg(feature = "rp2040")]
101 { 101 {
102 let mut pin2 = Output::new(&mut p11, Level::Low); 102 let mut pin2 = Output::new(p11.reborrow(), Level::Low);
103 let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, Pull::None, InputMode::Level, cfg.clone()); 103 let pwm = Pwm::new_input(
104 p.PWM_SLICE3.reborrow(),
105 p7.reborrow(),
106 Pull::None,
107 InputMode::Level,
108 cfg.clone(),
109 );
104 assert_eq!(pwm.counter(), 0); 110 assert_eq!(pwm.counter(), 0);
105 Timer::after_millis(5).await; 111 Timer::after_millis(5).await;
106 assert_eq!(pwm.counter(), 0); 112 assert_eq!(pwm.counter(), 0);
@@ -117,10 +123,10 @@ async fn main(_spawner: Spawner) {
117 // Test rising-gated 123 // Test rising-gated
118 #[cfg(feature = "rp2040")] 124 #[cfg(feature = "rp2040")]
119 { 125 {
120 let mut pin2 = Output::new(&mut p11, Level::Low); 126 let mut pin2 = Output::new(p11.reborrow(), Level::Low);
121 let pwm = Pwm::new_input( 127 let pwm = Pwm::new_input(
122 &mut p.PWM_SLICE3, 128 p.PWM_SLICE3.reborrow(),
123 &mut p7, 129 p7.reborrow(),
124 Pull::None, 130 Pull::None,
125 InputMode::RisingEdge, 131 InputMode::RisingEdge,
126 cfg.clone(), 132 cfg.clone(),
@@ -139,10 +145,10 @@ async fn main(_spawner: Spawner) {
139 // Test falling-gated 145 // Test falling-gated
140 #[cfg(feature = "rp2040")] 146 #[cfg(feature = "rp2040")]
141 { 147 {
142 let mut pin2 = Output::new(&mut p11, Level::High); 148 let mut pin2 = Output::new(p11.reborrow(), Level::High);
143 let pwm = Pwm::new_input( 149 let pwm = Pwm::new_input(
144 &mut p.PWM_SLICE3, 150 p.PWM_SLICE3.reborrow(),
145 &mut p7, 151 p7.reborrow(),
146 Pull::None, 152 Pull::None,
147 InputMode::FallingEdge, 153 InputMode::FallingEdge,
148 cfg.clone(), 154 cfg.clone(),
@@ -160,10 +166,10 @@ async fn main(_spawner: Spawner) {
160 166
161 // pull-down 167 // pull-down
162 { 168 {
163 let pin2 = Input::new(&mut p11, Pull::None); 169 let pin2 = Input::new(p11.reborrow(), Pull::None);
164 Pwm::new_input( 170 Pwm::new_input(
165 &mut p.PWM_SLICE3, 171 p.PWM_SLICE3.reborrow(),
166 &mut p7, 172 p7.reborrow(),
167 Pull::Down, 173 Pull::Down,
168 InputMode::FallingEdge, 174 InputMode::FallingEdge,
169 cfg.clone(), 175 cfg.clone(),
@@ -174,10 +180,10 @@ async fn main(_spawner: Spawner) {
174 180
175 // pull-up 181 // pull-up
176 { 182 {
177 let pin2 = Input::new(&mut p11, Pull::None); 183 let pin2 = Input::new(p11.reborrow(), Pull::None);
178 Pwm::new_input( 184 Pwm::new_input(
179 &mut p.PWM_SLICE3, 185 p.PWM_SLICE3.reborrow(),
180 &mut p7, 186 p7.reborrow(),
181 Pull::Up, 187 Pull::Up,
182 InputMode::FallingEdge, 188 InputMode::FallingEdge,
183 cfg.clone(), 189 cfg.clone(),
diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs
index 67cfa6bc8..84744ab77 100644
--- a/tests/rp/src/bin/uart.rs
+++ b/tests/rp/src/bin/uart.rs
@@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) {
56 56
57 { 57 {
58 let config = Config::default(); 58 let config = Config::default();
59 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 59 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
60 60
61 // We can't send too many bytes, they have to fit in the FIFO. 61 // We can't send too many bytes, they have to fit in the FIFO.
62 // This is because we aren't sending+receiving at the same time. 62 // This is because we aren't sending+receiving at the same time.
@@ -69,7 +69,7 @@ async fn main(_spawner: Spawner) {
69 info!("test overflow detection"); 69 info!("test overflow detection");
70 { 70 {
71 let config = Config::default(); 71 let config = Config::default();
72 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 72 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
73 73
74 let data = [ 74 let data = [
75 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 75 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
@@ -93,7 +93,7 @@ async fn main(_spawner: Spawner) {
93 info!("test break detection"); 93 info!("test break detection");
94 { 94 {
95 let config = Config::default(); 95 let config = Config::default();
96 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config); 96 let mut uart = Uart::new_blocking(uart.reborrow(), tx.reborrow(), rx.reborrow(), config);
97 97
98 // break on empty fifo 98 // break on empty fifo
99 uart.send_break(20).await; 99 uart.send_break(20).await;
@@ -113,11 +113,11 @@ async fn main(_spawner: Spawner) {
113 // parity detection. here we bitbang to not require two uarts. 113 // parity detection. here we bitbang to not require two uarts.
114 info!("test parity error detection"); 114 info!("test parity error detection");
115 { 115 {
116 let mut pin = Output::new(&mut tx, Level::High); 116 let mut pin = Output::new(tx.reborrow(), Level::High);
117 let mut config = Config::default(); 117 let mut config = Config::default();
118 config.baudrate = 1000; 118 config.baudrate = 1000;
119 config.parity = Parity::ParityEven; 119 config.parity = Parity::ParityEven;
120 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); 120 let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config);
121 121
122 async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { 122 async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) {
123 send(pin, v, Some(parity != 0)).await; 123 send(pin, v, Some(parity != 0)).await;
@@ -140,10 +140,10 @@ async fn main(_spawner: Spawner) {
140 // framing error detection. here we bitbang because there's no other way. 140 // framing error detection. here we bitbang because there's no other way.
141 info!("test framing error detection"); 141 info!("test framing error detection");
142 { 142 {
143 let mut pin = Output::new(&mut tx, Level::High); 143 let mut pin = Output::new(tx.reborrow(), Level::High);
144 let mut config = Config::default(); 144 let mut config = Config::default();
145 config.baudrate = 1000; 145 config.baudrate = 1000;
146 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); 146 let mut uart = UartRx::new_blocking(uart.reborrow(), rx.reborrow(), config);
147 147
148 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 148 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
149 if good { 149 if good {
diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs
index a543320e0..b270a60ce 100644
--- a/tests/rp/src/bin/uart_buffered.rs
+++ b/tests/rp/src/bin/uart_buffered.rs
@@ -73,7 +73,15 @@ async fn main(_spawner: Spawner) {
73 let config = Config::default(); 73 let config = Config::default();
74 let tx_buf = &mut [0u8; 16]; 74 let tx_buf = &mut [0u8; 16];
75 let rx_buf = &mut [0u8; 16]; 75 let rx_buf = &mut [0u8; 16];
76 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 76 let mut uart = BufferedUart::new(
77 uart.reborrow(),
78 Irqs,
79 tx.reborrow(),
80 rx.reborrow(),
81 tx_buf,
82 rx_buf,
83 config,
84 );
77 85
78 // Make sure we send more bytes than fits in the FIFO, to test the actual 86 // Make sure we send more bytes than fits in the FIFO, to test the actual
79 // bufferedUart. 87 // bufferedUart.
@@ -93,7 +101,15 @@ async fn main(_spawner: Spawner) {
93 let config = Config::default(); 101 let config = Config::default();
94 let tx_buf = &mut [0u8; 16]; 102 let tx_buf = &mut [0u8; 16];
95 let rx_buf = &mut [0u8; 16]; 103 let rx_buf = &mut [0u8; 16];
96 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 104 let mut uart = BufferedUart::new(
105 uart.reborrow(),
106 Irqs,
107 tx.reborrow(),
108 rx.reborrow(),
109 tx_buf,
110 rx_buf,
111 config,
112 );
97 113
98 // Make sure we send more bytes than fits in the FIFO, to test the actual 114 // Make sure we send more bytes than fits in the FIFO, to test the actual
99 // bufferedUart. 115 // bufferedUart.
@@ -128,7 +144,15 @@ async fn main(_spawner: Spawner) {
128 config.baudrate = 1000; 144 config.baudrate = 1000;
129 let tx_buf = &mut [0u8; 16]; 145 let tx_buf = &mut [0u8; 16];
130 let rx_buf = &mut [0u8; 16]; 146 let rx_buf = &mut [0u8; 16];
131 let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config); 147 let mut uart = BufferedUart::new(
148 uart.reborrow(),
149 Irqs,
150 tx.reborrow(),
151 rx.reborrow(),
152 tx_buf,
153 rx_buf,
154 config,
155 );
132 156
133 // break on empty buffer 157 // break on empty buffer
134 uart.send_break(20).await; 158 uart.send_break(20).await;
@@ -156,13 +180,13 @@ async fn main(_spawner: Spawner) {
156 // parity detection. here we bitbang to not require two uarts. 180 // parity detection. here we bitbang to not require two uarts.
157 info!("test parity error detection"); 181 info!("test parity error detection");
158 { 182 {
159 let mut pin = Output::new(&mut tx, Level::High); 183 let mut pin = Output::new(tx.reborrow(), Level::High);
160 // choose a very slow baud rate to make tests reliable even with O0 184 // choose a very slow baud rate to make tests reliable even with O0
161 let mut config = Config::default(); 185 let mut config = Config::default();
162 config.baudrate = 1000; 186 config.baudrate = 1000;
163 config.parity = Parity::ParityEven; 187 config.parity = Parity::ParityEven;
164 let rx_buf = &mut [0u8; 16]; 188 let rx_buf = &mut [0u8; 16];
165 let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); 189 let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config);
166 190
167 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { 191 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) {
168 send(pin, v, Some(parity != 0)).await; 192 send(pin, v, Some(parity != 0)).await;
@@ -204,12 +228,12 @@ async fn main(_spawner: Spawner) {
204 // framing error detection. here we bitbang because there's no other way. 228 // framing error detection. here we bitbang because there's no other way.
205 info!("test framing error detection"); 229 info!("test framing error detection");
206 { 230 {
207 let mut pin = Output::new(&mut tx, Level::High); 231 let mut pin = Output::new(tx.reborrow(), Level::High);
208 // choose a very slow baud rate to make tests reliable even with O0 232 // choose a very slow baud rate to make tests reliable even with O0
209 let mut config = Config::default(); 233 let mut config = Config::default();
210 config.baudrate = 1000; 234 config.baudrate = 1000;
211 let rx_buf = &mut [0u8; 16]; 235 let rx_buf = &mut [0u8; 16];
212 let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); 236 let mut uart = BufferedUartRx::new(uart.reborrow(), Irqs, rx.reborrow(), rx_buf, config);
213 237
214 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 238 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
215 if good { 239 if good {
diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs
index bdf94e78c..a09101223 100644
--- a/tests/rp/src/bin/uart_dma.rs
+++ b/tests/rp/src/bin/uart_dma.rs
@@ -65,12 +65,12 @@ async fn main(_spawner: Spawner) {
65 { 65 {
66 let config = Config::default(); 66 let config = Config::default();
67 let mut uart = Uart::new( 67 let mut uart = Uart::new(
68 &mut uart, 68 uart.reborrow(),
69 &mut tx, 69 tx.reborrow(),
70 &mut rx, 70 rx.reborrow(),
71 Irqs, 71 Irqs,
72 &mut p.DMA_CH0, 72 p.DMA_CH0.reborrow(),
73 &mut p.DMA_CH1, 73 p.DMA_CH1.reborrow(),
74 config, 74 config,
75 ); 75 );
76 76
@@ -86,12 +86,12 @@ async fn main(_spawner: Spawner) {
86 { 86 {
87 let config = Config::default(); 87 let config = Config::default();
88 let mut uart = Uart::new( 88 let mut uart = Uart::new(
89 &mut uart, 89 uart.reborrow(),
90 &mut tx, 90 tx.reborrow(),
91 &mut rx, 91 rx.reborrow(),
92 Irqs, 92 Irqs,
93 &mut p.DMA_CH0, 93 p.DMA_CH0.reborrow(),
94 &mut p.DMA_CH1, 94 p.DMA_CH1.reborrow(),
95 config, 95 config,
96 ); 96 );
97 97
@@ -115,12 +115,12 @@ async fn main(_spawner: Spawner) {
115 { 115 {
116 let config = Config::default(); 116 let config = Config::default();
117 let (mut tx, mut rx) = Uart::new( 117 let (mut tx, mut rx) = Uart::new(
118 &mut uart, 118 uart.reborrow(),
119 &mut tx, 119 tx.reborrow(),
120 &mut rx, 120 rx.reborrow(),
121 Irqs, 121 Irqs,
122 &mut p.DMA_CH0, 122 p.DMA_CH0.reborrow(),
123 &mut p.DMA_CH1, 123 p.DMA_CH1.reborrow(),
124 config, 124 config,
125 ) 125 )
126 .split(); 126 .split();
@@ -156,12 +156,12 @@ async fn main(_spawner: Spawner) {
156 // parity detection. here we bitbang to not require two uarts. 156 // parity detection. here we bitbang to not require two uarts.
157 info!("test parity error detection"); 157 info!("test parity error detection");
158 { 158 {
159 let mut pin = Output::new(&mut tx, Level::High); 159 let mut pin = Output::new(tx.reborrow(), Level::High);
160 // choose a very slow baud rate to make tests reliable even with O0 160 // choose a very slow baud rate to make tests reliable even with O0
161 let mut config = Config::default(); 161 let mut config = Config::default();
162 config.baudrate = 1000; 162 config.baudrate = 1000;
163 config.parity = Parity::ParityEven; 163 config.parity = Parity::ParityEven;
164 let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); 164 let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config);
165 165
166 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { 166 async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) {
167 send(pin, v, Some(parity != 0)).await; 167 send(pin, v, Some(parity != 0)).await;
@@ -202,11 +202,11 @@ async fn main(_spawner: Spawner) {
202 // framing error detection. here we bitbang because there's no other way. 202 // framing error detection. here we bitbang because there's no other way.
203 info!("test framing error detection"); 203 info!("test framing error detection");
204 { 204 {
205 let mut pin = Output::new(&mut tx, Level::High); 205 let mut pin = Output::new(tx.reborrow(), Level::High);
206 // choose a very slow baud rate to make tests reliable even with O0 206 // choose a very slow baud rate to make tests reliable even with O0
207 let mut config = Config::default(); 207 let mut config = Config::default();
208 config.baudrate = 1000; 208 config.baudrate = 1000;
209 let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); 209 let mut uart = UartRx::new(uart.reborrow(), rx.reborrow(), Irqs, p.DMA_CH0.reborrow(), config);
210 210
211 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { 211 async fn chr(pin: &mut Output<'_>, v: u8, good: bool) {
212 if good { 212 if good {
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 9c3b2780a..a676aee53 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -39,7 +39,7 @@ spi-v1 = []
39spi-v345 = [] 39spi-v345 = []
40cryp = [] 40cryp = []
41hash = [] 41hash = []
42eth = ["embassy-executor/task-arena-size-16384"] 42eth = []
43rng = [] 43rng = []
44sdmmc = [] 44sdmmc = []
45stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] 45stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"]
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index 85a5f8d83..778d88a7b 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -43,7 +43,7 @@ async fn main(_spawner: Spawner) {
43 // To synchronise to the bus the RX input needs to see a high level. 43 // To synchronise to the bus the RX input needs to see a high level.
44 // Use `mem::forget()` to release the borrow on the pin but keep the 44 // Use `mem::forget()` to release the borrow on the pin but keep the
45 // pull-up resistor enabled. 45 // pull-up resistor enabled.
46 let rx_pin = Input::new(&mut rx, Pull::Up); 46 let rx_pin = Input::new(rx.reborrow(), Pull::Up);
47 core::mem::forget(rx_pin); 47 core::mem::forget(rx_pin);
48 48
49 let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs); 49 let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs);
diff --git a/tests/stm32/src/bin/cordic.rs b/tests/stm32/src/bin/cordic.rs
index 879ad56b6..e86eea58b 100644
--- a/tests/stm32/src/bin/cordic.rs
+++ b/tests/stm32/src/bin/cordic.rs
@@ -82,8 +82,8 @@ async fn main(_spawner: Spawner) {
82 let cnt1 = defmt::unwrap!( 82 let cnt1 = defmt::unwrap!(
83 cordic 83 cordic
84 .async_calc_32bit( 84 .async_calc_32bit(
85 &mut write_dma, 85 write_dma.reborrow(),
86 &mut read_dma, 86 read_dma.reborrow(),
87 &input_q1_31[2..], 87 &input_q1_31[2..],
88 &mut output_q1_31[cnt0..], 88 &mut output_q1_31[cnt0..],
89 true, 89 true,
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
index 88e661525..d34bbb255 100644
--- a/tests/stm32/src/bin/dac.rs
+++ b/tests/stm32/src/bin/dac.rs
@@ -12,7 +12,6 @@ use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::Adc;
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma;
16use embassy_time::Timer; 15use embassy_time::Timer;
17use micromath::F32Ext; 16use micromath::F32Ext;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
@@ -27,7 +26,7 @@ async fn main(_spawner: Spawner) {
27 let dac_pin = peri!(p, DAC_PIN); 26 let dac_pin = peri!(p, DAC_PIN);
28 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; 27 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
29 28
30 let mut dac = DacCh1::new(dac, NoDma, dac_pin); 29 let mut dac = DacCh1::new_blocking(dac, dac_pin);
31 let mut adc = Adc::new(adc); 30 let mut adc = Adc::new(adc);
32 31
33 #[cfg(feature = "stm32h755zi")] 32 #[cfg(feature = "stm32h755zi")]
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs
index 925db617d..e6400f28e 100644
--- a/tests/stm32/src/bin/dac_l1.rs
+++ b/tests/stm32/src/bin/dac_l1.rs
@@ -12,7 +12,6 @@ use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc; 13use embassy_stm32::adc::Adc;
14use embassy_stm32::dac::{DacCh1, Value}; 14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma;
16use embassy_stm32::{bind_interrupts, peripherals}; 15use embassy_stm32::{bind_interrupts, peripherals};
17use embassy_time::Timer; 16use embassy_time::Timer;
18use micromath::F32Ext; 17use micromath::F32Ext;
@@ -32,7 +31,7 @@ async fn main(_spawner: Spawner) {
32 let dac_pin = peri!(p, DAC_PIN); 31 let dac_pin = peri!(p, DAC_PIN);
33 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; 32 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
34 33
35 let mut dac = DacCh1::new(dac, NoDma, dac_pin); 34 let mut dac = DacCh1::new_blocking(dac, dac_pin);
36 let mut adc = Adc::new(adc, Irqs); 35 let mut adc = Adc::new(adc, Irqs);
37 36
38 #[cfg(feature = "stm32h755zi")] 37 #[cfg(feature = "stm32h755zi")]
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs
index 4a2584b4e..40b03201c 100644
--- a/tests/stm32/src/bin/gpio.rs
+++ b/tests/stm32/src/bin/gpio.rs
@@ -20,10 +20,10 @@ async fn main(_spawner: Spawner) {
20 20
21 // Test initial output 21 // Test initial output
22 { 22 {
23 let b = Input::new(&mut b, Pull::None); 23 let b = Input::new(b.reborrow(), Pull::None);
24 24
25 { 25 {
26 let a = Output::new(&mut a, Level::Low, Speed::Low); 26 let a = Output::new(a.reborrow(), Level::Low, Speed::Low);
27 delay(); 27 delay();
28 assert!(b.is_low()); 28 assert!(b.is_low());
29 assert!(!b.is_high()); 29 assert!(!b.is_high());
@@ -31,7 +31,7 @@ async fn main(_spawner: Spawner) {
31 assert!(!a.is_set_high()); 31 assert!(!a.is_set_high());
32 } 32 }
33 { 33 {
34 let mut a = Output::new(&mut a, Level::High, Speed::Low); 34 let mut a = Output::new(a.reborrow(), Level::High, Speed::Low);
35 delay(); 35 delay();
36 assert!(!b.is_low()); 36 assert!(!b.is_low());
37 assert!(b.is_high()); 37 assert!(b.is_high());
@@ -68,10 +68,10 @@ async fn main(_spawner: Spawner) {
68 68
69 // Test input no pull 69 // Test input no pull
70 { 70 {
71 let b = Input::new(&mut b, Pull::None); 71 let b = Input::new(b.reborrow(), Pull::None);
72 // no pull, the status is undefined 72 // no pull, the status is undefined
73 73
74 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 74 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
75 delay(); 75 delay();
76 assert!(b.is_low()); 76 assert!(b.is_low());
77 a.set_high(); 77 a.set_high();
@@ -81,11 +81,11 @@ async fn main(_spawner: Spawner) {
81 81
82 // Test input pulldown 82 // Test input pulldown
83 { 83 {
84 let b = Input::new(&mut b, Pull::Down); 84 let b = Input::new(b.reborrow(), Pull::Down);
85 delay(); 85 delay();
86 assert!(b.is_low()); 86 assert!(b.is_low());
87 87
88 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 88 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
89 delay(); 89 delay();
90 assert!(b.is_low()); 90 assert!(b.is_low());
91 a.set_high(); 91 a.set_high();
@@ -95,11 +95,11 @@ async fn main(_spawner: Spawner) {
95 95
96 // Test input pullup 96 // Test input pullup
97 { 97 {
98 let b = Input::new(&mut b, Pull::Up); 98 let b = Input::new(b.reborrow(), Pull::Up);
99 delay(); 99 delay();
100 assert!(b.is_high()); 100 assert!(b.is_high());
101 101
102 let mut a = Output::new(&mut a, Level::Low, Speed::Low); 102 let mut a = Output::new(a.reborrow(), Level::Low, Speed::Low);
103 delay(); 103 delay();
104 assert!(b.is_low()); 104 assert!(b.is_low());
105 a.set_high(); 105 a.set_high();
@@ -109,10 +109,10 @@ async fn main(_spawner: Spawner) {
109 109
110 // Test output open drain 110 // Test output open drain
111 { 111 {
112 let b = Input::new(&mut b, Pull::Down); 112 let b = Input::new(b.reborrow(), Pull::Down);
113 // no pull, the status is undefined 113 // no pull, the status is undefined
114 114
115 let mut a = OutputOpenDrain::new(&mut a, Level::Low, Speed::Low); 115 let mut a = OutputOpenDrain::new(a.reborrow(), Level::Low, Speed::Low);
116 delay(); 116 delay();
117 assert!(b.is_low()); 117 assert!(b.is_low());
118 a.set_high(); // High-Z output 118 a.set_high(); // High-Z output
@@ -124,12 +124,12 @@ async fn main(_spawner: Spawner) {
124 // Test initial output 124 // Test initial output
125 { 125 {
126 //Flex pin configured as input 126 //Flex pin configured as input
127 let mut b = Flex::new(&mut b); 127 let mut b = Flex::new(b.reborrow());
128 b.set_as_input(Pull::None); 128 b.set_as_input(Pull::None);
129 129
130 { 130 {
131 //Flex pin configured as output 131 //Flex pin configured as output
132 let mut a = Flex::new(&mut a); //Flex pin configured as output 132 let mut a = Flex::new(a.reborrow()); //Flex pin configured as output
133 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state 133 a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state
134 a.set_as_output(Speed::Low); 134 a.set_as_output(Speed::Low);
135 delay(); 135 delay();
@@ -137,7 +137,7 @@ async fn main(_spawner: Spawner) {
137 } 137 }
138 { 138 {
139 //Flex pin configured as output 139 //Flex pin configured as output
140 let mut a = Flex::new(&mut a); 140 let mut a = Flex::new(a.reborrow());
141 a.set_high(); 141 a.set_high();
142 a.set_as_output(Speed::Low); 142 a.set_as_output(Speed::Low);
143 143
@@ -148,10 +148,10 @@ async fn main(_spawner: Spawner) {
148 148
149 // Test input no pull 149 // Test input no pull
150 { 150 {
151 let mut b = Flex::new(&mut b); 151 let mut b = Flex::new(b.reborrow());
152 b.set_as_input(Pull::None); // no pull, the status is undefined 152 b.set_as_input(Pull::None); // no pull, the status is undefined
153 153
154 let mut a = Flex::new(&mut a); 154 let mut a = Flex::new(a.reborrow());
155 a.set_low(); 155 a.set_low();
156 a.set_as_output(Speed::Low); 156 a.set_as_output(Speed::Low);
157 157
@@ -164,12 +164,12 @@ async fn main(_spawner: Spawner) {
164 164
165 // Test input pulldown 165 // Test input pulldown
166 { 166 {
167 let mut b = Flex::new(&mut b); 167 let mut b = Flex::new(b.reborrow());
168 b.set_as_input(Pull::Down); 168 b.set_as_input(Pull::Down);
169 delay(); 169 delay();
170 assert!(b.is_low()); 170 assert!(b.is_low());
171 171
172 let mut a = Flex::new(&mut a); 172 let mut a = Flex::new(a.reborrow());
173 a.set_low(); 173 a.set_low();
174 a.set_as_output(Speed::Low); 174 a.set_as_output(Speed::Low);
175 delay(); 175 delay();
@@ -181,12 +181,12 @@ async fn main(_spawner: Spawner) {
181 181
182 // Test input pullup 182 // Test input pullup
183 { 183 {
184 let mut b = Flex::new(&mut b); 184 let mut b = Flex::new(b.reborrow());
185 b.set_as_input(Pull::Up); 185 b.set_as_input(Pull::Up);
186 delay(); 186 delay();
187 assert!(b.is_high()); 187 assert!(b.is_high());
188 188
189 let mut a = Flex::new(&mut a); 189 let mut a = Flex::new(a.reborrow());
190 a.set_high(); 190 a.set_high();
191 a.set_as_output(Speed::Low); 191 a.set_as_output(Speed::Low);
192 delay(); 192 delay();
@@ -198,10 +198,10 @@ async fn main(_spawner: Spawner) {
198 198
199 // Test output open drain 199 // Test output open drain
200 { 200 {
201 let mut b = Flex::new(&mut b); 201 let mut b = Flex::new(b.reborrow());
202 b.set_as_input(Pull::Down); 202 b.set_as_input(Pull::Down);
203 203
204 let mut a = Flex::new(&mut a); 204 let mut a = Flex::new(a.reborrow());
205 a.set_low(); 205 a.set_low();
206 a.set_as_input_output(Speed::Low); 206 a.set_as_input_output(Speed::Low);
207 delay(); 207 delay();
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs
index bdb3c9a69..52b84a499 100644
--- a/tests/stm32/src/bin/hash.rs
+++ b/tests/stm32/src/bin/hash.rs
@@ -6,7 +6,6 @@
6mod common; 6mod common;
7use common::*; 7use common::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::dma::NoDma;
10use embassy_stm32::hash::*; 9use embassy_stm32::hash::*;
11use embassy_stm32::{bind_interrupts, hash, peripherals}; 10use embassy_stm32::{bind_interrupts, hash, peripherals};
12use hmac::{Hmac, Mac}; 11use hmac::{Hmac, Mac};
@@ -36,7 +35,7 @@ bind_interrupts!(struct Irqs {
36#[embassy_executor::main] 35#[embassy_executor::main]
37async fn main(_spawner: Spawner) { 36async fn main(_spawner: Spawner) {
38 let p: embassy_stm32::Peripherals = init(); 37 let p: embassy_stm32::Peripherals = init();
39 let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); 38 let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs);
40 39
41 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; 40 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
42 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; 41 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs
index a6bc117c0..07f17b569 100644
--- a/tests/stm32/src/bin/sdmmc.rs
+++ b/tests/stm32/src/bin/sdmmc.rs
@@ -40,15 +40,15 @@ async fn main(_spawner: Spawner) {
40 // ======== Try 4bit. ============== 40 // ======== Try 4bit. ==============
41 info!("initializing in 4-bit mode..."); 41 info!("initializing in 4-bit mode...");
42 let mut s = Sdmmc::new_4bit( 42 let mut s = Sdmmc::new_4bit(
43 &mut sdmmc, 43 sdmmc.reborrow(),
44 Irqs, 44 Irqs,
45 &mut dma, 45 dma.reborrow(),
46 &mut clk, 46 clk.reborrow(),
47 &mut cmd, 47 cmd.reborrow(),
48 &mut d0, 48 d0.reborrow(),
49 &mut d1, 49 d1.reborrow(),
50 &mut d2, 50 d2.reborrow(),
51 &mut d3, 51 d3.reborrow(),
52 Default::default(), 52 Default::default(),
53 ); 53 );
54 54
@@ -89,12 +89,12 @@ async fn main(_spawner: Spawner) {
89 // ======== Try 1bit. ============== 89 // ======== Try 1bit. ==============
90 info!("initializing in 1-bit mode..."); 90 info!("initializing in 1-bit mode...");
91 let mut s = Sdmmc::new_1bit( 91 let mut s = Sdmmc::new_1bit(
92 &mut sdmmc, 92 sdmmc.reborrow(),
93 Irqs, 93 Irqs,
94 &mut dma, 94 dma.reborrow(),
95 &mut clk, 95 clk.reborrow(),
96 &mut cmd, 96 cmd.reborrow(),
97 &mut d0, 97 d0.reborrow(),
98 Default::default(), 98 Default::default(),
99 ); 99 );
100 100
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs
index 9712a8c5a..e8310866a 100644
--- a/tests/stm32/src/bin/spi.rs
+++ b/tests/stm32/src/bin/spi.rs
@@ -25,10 +25,10 @@ async fn main(_spawner: Spawner) {
25 spi_config.frequency = Hertz(1_000_000); 25 spi_config.frequency = Hertz(1_000_000);
26 26
27 let mut spi = Spi::new_blocking( 27 let mut spi = Spi::new_blocking(
28 &mut spi_peri, 28 spi_peri.reborrow(),
29 &mut sck, // Arduino D13 29 sck.reborrow(), // Arduino D13
30 &mut mosi, // Arduino D11 30 mosi.reborrow(), // Arduino D11
31 &mut miso, // Arduino D12 31 miso.reborrow(), // Arduino D12
32 spi_config, 32 spi_config,
33 ); 33 );
34 34
@@ -43,20 +43,20 @@ async fn main(_spawner: Spawner) {
43 defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en()); 43 defmt::assert!(!embassy_stm32::pac::RCC.apb2enr().read().spi1en());
44 44
45 // test rx-only configuration 45 // test rx-only configuration
46 let mut spi = Spi::new_blocking_rxonly(&mut spi_peri, &mut sck, &mut miso, spi_config); 46 let mut spi = Spi::new_blocking_rxonly(spi_peri.reborrow(), sck.reborrow(), miso.reborrow(), spi_config);
47 let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); 47 let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh);
48 48
49 test_rx::<u8>(&mut spi, &mut mosi_out); 49 test_rx::<u8>(&mut spi, &mut mosi_out);
50 test_rx::<u16>(&mut spi, &mut mosi_out); 50 test_rx::<u16>(&mut spi, &mut mosi_out);
51 drop(spi); 51 drop(spi);
52 drop(mosi_out); 52 drop(mosi_out);
53 53
54 let mut spi = Spi::new_blocking_txonly(&mut spi_peri, &mut sck, &mut mosi, spi_config); 54 let mut spi = Spi::new_blocking_txonly(spi_peri.reborrow(), sck.reborrow(), mosi.reborrow(), spi_config);
55 test_tx::<u8>(&mut spi); 55 test_tx::<u8>(&mut spi);
56 test_tx::<u16>(&mut spi); 56 test_tx::<u16>(&mut spi);
57 drop(spi); 57 drop(spi);
58 58
59 let mut spi = Spi::new_blocking_txonly_nosck(&mut spi_peri, &mut mosi, spi_config); 59 let mut spi = Spi::new_blocking_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), spi_config);
60 test_tx::<u8>(&mut spi); 60 test_tx::<u8>(&mut spi);
61 test_tx::<u16>(&mut spi); 61 test_tx::<u16>(&mut spi);
62 drop(spi); 62 drop(spi);
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs
index 307409a16..b4fdb8faa 100644
--- a/tests/stm32/src/bin/spi_dma.rs
+++ b/tests/stm32/src/bin/spi_dma.rs
@@ -27,12 +27,12 @@ async fn main(_spawner: Spawner) {
27 spi_config.frequency = Hertz(1_000_000); 27 spi_config.frequency = Hertz(1_000_000);
28 28
29 let mut spi = Spi::new( 29 let mut spi = Spi::new(
30 &mut spi_peri, 30 spi_peri.reborrow(),
31 &mut sck, // Arduino D13 31 sck.reborrow(), // Arduino D13
32 &mut mosi, // Arduino D11 32 mosi.reborrow(), // Arduino D11
33 &mut miso, // Arduino D12 33 miso.reborrow(), // Arduino D12
34 &mut tx_dma, 34 tx_dma.reborrow(),
35 &mut rx_dma, 35 rx_dma.reborrow(),
36 spi_config, 36 spi_config,
37 ); 37 );
38 38
@@ -42,28 +42,34 @@ async fn main(_spawner: Spawner) {
42 42
43 // test rx-only configuration 43 // test rx-only configuration
44 let mut spi = Spi::new_rxonly( 44 let mut spi = Spi::new_rxonly(
45 &mut spi_peri, 45 spi_peri.reborrow(),
46 &mut sck, 46 sck.reborrow(),
47 &mut miso, 47 miso.reborrow(),
48 // SPIv1/f1 requires txdma even if rxonly. 48 // SPIv1/f1 requires txdma even if rxonly.
49 #[cfg(not(feature = "spi-v345"))] 49 #[cfg(not(feature = "spi-v345"))]
50 &mut tx_dma, 50 tx_dma.reborrow(),
51 &mut rx_dma, 51 rx_dma.reborrow(),
52 spi_config, 52 spi_config,
53 ); 53 );
54 let mut mosi_out = Output::new(&mut mosi, Level::Low, Speed::VeryHigh); 54 let mut mosi_out = Output::new(mosi.reborrow(), Level::Low, Speed::VeryHigh);
55 55
56 test_rx::<u8>(&mut spi, &mut mosi_out).await; 56 test_rx::<u8>(&mut spi, &mut mosi_out).await;
57 test_rx::<u16>(&mut spi, &mut mosi_out).await; 57 test_rx::<u16>(&mut spi, &mut mosi_out).await;
58 drop(spi); 58 drop(spi);
59 drop(mosi_out); 59 drop(mosi_out);
60 60
61 let mut spi = Spi::new_txonly(&mut spi_peri, &mut sck, &mut mosi, &mut tx_dma, spi_config); 61 let mut spi = Spi::new_txonly(
62 spi_peri.reborrow(),
63 sck.reborrow(),
64 mosi.reborrow(),
65 tx_dma.reborrow(),
66 spi_config,
67 );
62 test_tx::<u8>(&mut spi).await; 68 test_tx::<u8>(&mut spi).await;
63 test_tx::<u16>(&mut spi).await; 69 test_tx::<u16>(&mut spi).await;
64 drop(spi); 70 drop(spi);
65 71
66 let mut spi = Spi::new_txonly_nosck(&mut spi_peri, &mut mosi, &mut tx_dma, spi_config); 72 let mut spi = Spi::new_txonly_nosck(spi_peri.reborrow(), mosi.reborrow(), tx_dma.reborrow(), spi_config);
67 test_tx::<u8>(&mut spi).await; 73 test_tx::<u8>(&mut spi).await;
68 test_tx::<u16>(&mut spi).await; 74 test_tx::<u16>(&mut spi).await;
69 drop(spi); 75 drop(spi);
diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs
index bd7b35d6b..97aefe1a0 100644
--- a/tests/stm32/src/bin/ucpd.rs
+++ b/tests/stm32/src/bin/ucpd.rs
@@ -9,7 +9,7 @@ use defmt::{assert, assert_eq};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_futures::join::join; 10use embassy_futures::join::join;
11use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; 11use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd};
12use embassy_stm32::{bind_interrupts, peripherals}; 12use embassy_stm32::{bind_interrupts, peripherals, Peri};
13use embassy_time::Timer; 13use embassy_time::Timer;
14 14
15bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
@@ -28,8 +28,8 @@ async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: C
28 28
29async fn source( 29async fn source(
30 mut ucpd: Ucpd<'static, peripherals::UCPD1>, 30 mut ucpd: Ucpd<'static, peripherals::UCPD1>,
31 rx_dma: peripherals::DMA1_CH1, 31 rx_dma: Peri<'static, peripherals::DMA1_CH1>,
32 tx_dma: peripherals::DMA1_CH2, 32 tx_dma: Peri<'static, peripherals::DMA1_CH2>,
33) { 33) {
34 debug!("source: setting default current pull-up"); 34 debug!("source: setting default current pull-up");
35 ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); 35 ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb);
@@ -65,8 +65,8 @@ async fn source(
65 65
66async fn sink( 66async fn sink(
67 mut ucpd: Ucpd<'static, peripherals::UCPD2>, 67 mut ucpd: Ucpd<'static, peripherals::UCPD2>,
68 rx_dma: peripherals::DMA1_CH3, 68 rx_dma: Peri<'static, peripherals::DMA1_CH3>,
69 tx_dma: peripherals::DMA1_CH4, 69 tx_dma: Peri<'static, peripherals::DMA1_CH4>,
70) { 70) {
71 debug!("sink: setting pull down"); 71 debug!("sink: setting pull down");
72 ucpd.cc_phy().set_pull(CcPull::Sink); 72 ucpd.cc_phy().set_pull(CcPull::Sink);
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs
index 2f601ad0e..129c7b692 100644
--- a/tests/stm32/src/bin/usart.rs
+++ b/tests/stm32/src/bin/usart.rs
@@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) {
22 22
23 { 23 {
24 let config = Config::default(); 24 let config = Config::default();
25 let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); 25 let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap();
26 26
27 // We can't send too many bytes, they have to fit in the FIFO. 27 // We can't send too many bytes, they have to fit in the FIFO.
28 // This is because we aren't sending+receiving at the same time. 28 // This is because we aren't sending+receiving at the same time.
@@ -45,7 +45,7 @@ async fn main(_spawner: Spawner) {
45 // Test error handling with with an overflow error 45 // Test error handling with with an overflow error
46 { 46 {
47 let config = Config::default(); 47 let config = Config::default();
48 let mut usart = Uart::new_blocking(&mut usart, &mut rx, &mut tx, config).unwrap(); 48 let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap();
49 49
50 // Send enough bytes to fill the RX FIFOs off all USART versions. 50 // Send enough bytes to fill the RX FIFOs off all USART versions.
51 let data = [0; 64]; 51 let data = [0; 64];
@@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) {
75 75
76 let mut config = Config::default(); 76 let mut config = Config::default();
77 config.baudrate = baudrate; 77 config.baudrate = baudrate;
78 let mut usart = match Uart::new_blocking(&mut usart, &mut rx, &mut tx, config) { 78 let mut usart = match Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config) {
79 Ok(x) => x, 79 Ok(x) => x,
80 Err(ConfigError::BaudrateTooHigh) => { 80 Err(ConfigError::BaudrateTooHigh) => {
81 info!("baudrate too high"); 81 info!("baudrate too high");