aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/boot/.cargo/config.toml4
-rw-r--r--examples/boot/application/nrf/Cargo.toml8
-rw-r--r--examples/boot/application/nrf/src/bin/a.rs3
-rw-r--r--examples/boot/application/nrf/src/bin/b.rs1
-rw-r--r--examples/boot/application/rp/.cargo/config.toml4
-rw-r--r--examples/boot/application/rp/Cargo.toml6
-rw-r--r--examples/boot/application/rp/src/bin/a.rs3
-rw-r--r--examples/boot/application/rp/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml6
-rw-r--r--examples/boot/application/stm32f3/memory.x4
-rw-r--r--examples/boot/application/stm32f3/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32f3/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml6
-rw-r--r--examples/boot/application/stm32f7/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32f7/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml6
-rw-r--r--examples/boot/application/stm32h7/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32h7/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml6
-rw-r--r--examples/boot/application/stm32l0/memory.x4
-rw-r--r--examples/boot/application/stm32l0/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32l0/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml6
-rw-r--r--examples/boot/application/stm32l1/memory.x4
-rw-r--r--examples/boot/application/stm32l1/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32l1/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml6
-rw-r--r--examples/boot/application/stm32l4/memory.x4
-rw-r--r--examples/boot/application/stm32l4/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32l4/src/bin/b.rs1
-rw-r--r--examples/boot/application/stm32wb-dfu/.cargo/config.toml9
-rw-r--r--examples/boot/application/stm32wb-dfu/Cargo.toml32
-rw-r--r--examples/boot/application/stm32wb-dfu/README.md9
-rw-r--r--examples/boot/application/stm32wb-dfu/build.rs37
-rw-r--r--examples/boot/application/stm32wb-dfu/memory.x15
-rw-r--r--examples/boot/application/stm32wb-dfu/src/main.rs61
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml6
-rw-r--r--examples/boot/application/stm32wl/memory.x4
-rw-r--r--examples/boot/application/stm32wl/src/bin/a.rs8
-rw-r--r--examples/boot/application/stm32wl/src/bin/b.rs1
-rw-r--r--examples/boot/bootloader/nrf/.cargo/config.toml6
-rw-r--r--examples/boot/bootloader/nrf/Cargo.toml2
-rw-r--r--examples/boot/bootloader/nrf/src/main.rs2
-rw-r--r--examples/boot/bootloader/rp/Cargo.toml2
-rw-r--r--examples/boot/bootloader/rp/src/main.rs2
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/Cargo.toml57
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/README.md44
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/build.rs27
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/memory.x18
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/src/main.rs53
-rw-r--r--examples/boot/bootloader/stm32/Cargo.toml2
-rw-r--r--examples/boot/bootloader/stm32/src/main.rs2
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/Cargo.toml63
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/README.md11
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/build.rs27
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/memory.x18
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/src/main.rs91
-rw-r--r--examples/nrf-rtos-trace/Cargo.toml4
-rw-r--r--examples/nrf-rtos-trace/src/bin/rtos_trace.rs1
-rw-r--r--examples/nrf51/.cargo/config.toml9
-rw-r--r--examples/nrf51/Cargo.toml20
-rw-r--r--examples/nrf51/build.rs35
-rw-r--r--examples/nrf51/memory.x5
-rw-r--r--examples/nrf51/src/bin/blinky.rs20
-rw-r--r--examples/nrf52840-rtic/Cargo.toml2
-rw-r--r--examples/nrf52840/Cargo.toml20
-rw-r--r--examples/nrf52840/src/bin/blinky.rs1
-rw-r--r--examples/nrf52840/src/bin/buffered_uart.rs1
-rw-r--r--examples/nrf52840/src/bin/channel.rs1
-rw-r--r--examples/nrf52840/src/bin/channel_sender_receiver.rs1
-rw-r--r--examples/nrf52840/src/bin/ethernet_enc28j60.rs18
-rw-r--r--examples/nrf52840/src/bin/executor_fairness_test.rs1
-rw-r--r--examples/nrf52840/src/bin/gpiote_channel.rs1
-rw-r--r--examples/nrf52840/src/bin/gpiote_port.rs13
-rw-r--r--examples/nrf52840/src/bin/i2s_effect.rs1
-rw-r--r--examples/nrf52840/src/bin/i2s_monitor.rs1
-rw-r--r--examples/nrf52840/src/bin/i2s_waveform.rs1
-rw-r--r--examples/nrf52840/src/bin/manually_create_executor.rs1
-rw-r--r--examples/nrf52840/src/bin/multiprio.rs1
-rw-r--r--examples/nrf52840/src/bin/mutex.rs1
-rw-r--r--examples/nrf52840/src/bin/nvmc.rs1
-rw-r--r--examples/nrf52840/src/bin/pdm.rs1
-rw-r--r--examples/nrf52840/src/bin/pdm_continuous.rs1
-rw-r--r--examples/nrf52840/src/bin/ppi.rs1
-rw-r--r--examples/nrf52840/src/bin/pubsub.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm_double_sequence.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm_sequence.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm_sequence_ppi.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs1
-rw-r--r--examples/nrf52840/src/bin/pwm_servo.rs1
-rw-r--r--examples/nrf52840/src/bin/qdec.rs1
-rw-r--r--examples/nrf52840/src/bin/qspi.rs1
-rw-r--r--examples/nrf52840/src/bin/qspi_lowpower.rs1
-rw-r--r--examples/nrf52840/src/bin/rng.rs1
-rw-r--r--examples/nrf52840/src/bin/saadc.rs1
-rw-r--r--examples/nrf52840/src/bin/saadc_continuous.rs1
-rw-r--r--examples/nrf52840/src/bin/self_spawn.rs1
-rw-r--r--examples/nrf52840/src/bin/self_spawn_current_executor.rs1
-rw-r--r--examples/nrf52840/src/bin/spim.rs1
-rw-r--r--examples/nrf52840/src/bin/spis.rs1
-rw-r--r--examples/nrf52840/src/bin/temp.rs1
-rw-r--r--examples/nrf52840/src/bin/timer.rs1
-rw-r--r--examples/nrf52840/src/bin/twim.rs1
-rw-r--r--examples/nrf52840/src/bin/twim_lowpower.rs1
-rw-r--r--examples/nrf52840/src/bin/twis.rs1
-rw-r--r--examples/nrf52840/src/bin/uart.rs1
-rw-r--r--examples/nrf52840/src/bin/uart_idle.rs1
-rw-r--r--examples/nrf52840/src/bin/uart_split.rs1
-rw-r--r--examples/nrf52840/src/bin/usb_ethernet.rs31
-rw-r--r--examples/nrf52840/src/bin/usb_hid_keyboard.rs7
-rw-r--r--examples/nrf52840/src/bin/usb_hid_mouse.rs3
-rw-r--r--examples/nrf52840/src/bin/usb_serial.rs3
-rw-r--r--examples/nrf52840/src/bin/usb_serial_multitask.rs19
-rw-r--r--examples/nrf52840/src/bin/usb_serial_winusb.rs3
-rw-r--r--examples/nrf52840/src/bin/wdt.rs1
-rw-r--r--examples/nrf52840/src/bin/wifi_esp_hosted.rs26
-rw-r--r--examples/nrf5340/Cargo.toml10
-rw-r--r--examples/nrf5340/src/bin/blinky.rs1
-rw-r--r--examples/nrf5340/src/bin/gpiote_channel.rs1
-rw-r--r--examples/nrf5340/src/bin/uart.rs1
-rw-r--r--examples/nrf9160/.cargo/config.toml9
-rw-r--r--examples/nrf9160/Cargo.toml20
-rw-r--r--examples/nrf9160/build.rs35
-rw-r--r--examples/nrf9160/memory.x5
-rw-r--r--examples/nrf9160/src/bin/blinky.rs20
-rw-r--r--examples/rp/Cargo.toml20
-rw-r--r--examples/rp/src/bin/adc.rs1
-rw-r--r--examples/rp/src/bin/blinky.rs1
-rw-r--r--examples/rp/src/bin/blinky_two_channels.rs50
-rw-r--r--examples/rp/src/bin/blinky_two_tasks.rs49
-rw-r--r--examples/rp/src/bin/button.rs1
-rw-r--r--examples/rp/src/bin/debounce.rs80
-rw-r--r--examples/rp/src/bin/ethernet_w5500_multisocket.rs22
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_client.rs22
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_server.rs22
-rw-r--r--examples/rp/src/bin/ethernet_w5500_udp.rs22
-rw-r--r--examples/rp/src/bin/flash.rs1
-rw-r--r--examples/rp/src/bin/gpio_async.rs1
-rw-r--r--examples/rp/src/bin/gpout.rs1
-rw-r--r--examples/rp/src/bin/i2c_async.rs1
-rw-r--r--examples/rp/src/bin/i2c_blocking.rs1
-rw-r--r--examples/rp/src/bin/i2c_slave.rs9
-rw-r--r--examples/rp/src/bin/multicore.rs16
-rw-r--r--examples/rp/src/bin/multiprio.rs1
-rw-r--r--examples/rp/src/bin/pio_async.rs1
-rw-r--r--examples/rp/src/bin/pio_dma.rs1
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs1
-rw-r--r--examples/rp/src/bin/pio_i2s.rs125
-rw-r--r--examples/rp/src/bin/pio_rotary_encoder.rs1
-rw-r--r--examples/rp/src/bin/pio_stepper.rs1
-rw-r--r--examples/rp/src/bin/pio_uart.rs3
-rw-r--r--examples/rp/src/bin/pio_ws2812.rs8
-rw-r--r--examples/rp/src/bin/pwm.rs1
-rw-r--r--examples/rp/src/bin/pwm_input.rs1
-rw-r--r--examples/rp/src/bin/rosc.rs1
-rw-r--r--examples/rp/src/bin/rtc.rs1
-rw-r--r--examples/rp/src/bin/spi.rs1
-rw-r--r--examples/rp/src/bin/spi_async.rs1
-rw-r--r--examples/rp/src/bin/spi_display.rs1
-rw-r--r--examples/rp/src/bin/uart.rs1
-rw-r--r--examples/rp/src/bin/uart_buffered_split.rs9
-rw-r--r--examples/rp/src/bin/uart_unidir.rs1
-rw-r--r--examples/rp/src/bin/usb_ethernet.rs27
-rw-r--r--examples/rp/src/bin/usb_hid_keyboard.rs3
-rw-r--r--examples/rp/src/bin/usb_hid_mouse.rs180
-rw-r--r--examples/rp/src/bin/usb_logger.rs1
-rw-r--r--examples/rp/src/bin/usb_midi.rs3
-rw-r--r--examples/rp/src/bin/usb_raw.rs3
-rw-r--r--examples/rp/src/bin/usb_raw_bulk.rs3
-rw-r--r--examples/rp/src/bin/usb_serial.rs3
-rw-r--r--examples/rp/src/bin/usb_serial_with_logger.rs115
-rw-r--r--examples/rp/src/bin/watchdog.rs1
-rw-r--r--examples/rp/src/bin/wifi_ap_tcp_server.rs20
-rw-r--r--examples/rp/src/bin/wifi_blinky.rs12
-rw-r--r--examples/rp/src/bin/wifi_scan.rs14
-rw-r--r--examples/rp/src/bin/wifi_tcp_server.rs20
-rw-r--r--examples/std/Cargo.toml8
-rw-r--r--examples/std/README.md4
-rw-r--r--examples/std/src/bin/net.rs14
-rw-r--r--examples/std/src/bin/net_dns.rs14
-rw-r--r--examples/std/src/bin/net_ppp.rs14
-rw-r--r--examples/std/src/bin/net_udp.rs12
-rw-r--r--examples/std/src/bin/serial.rs3
-rw-r--r--examples/std/src/bin/tcp_accept.rs13
-rw-r--r--examples/std/src/bin/tick.rs2
-rw-r--r--examples/stm32c0/Cargo.toml4
-rw-r--r--examples/stm32c0/src/bin/blinky.rs1
-rw-r--r--examples/stm32c0/src/bin/button.rs1
-rw-r--r--examples/stm32c0/src/bin/button_exti.rs6
-rw-r--r--examples/stm32f0/Cargo.toml8
-rw-r--r--examples/stm32f0/src/bin/adc.rs3
-rw-r--r--examples/stm32f0/src/bin/blinky.rs1
-rw-r--r--examples/stm32f0/src/bin/button_controlled_blink.rs6
-rw-r--r--examples/stm32f0/src/bin/button_exti.rs6
-rw-r--r--examples/stm32f0/src/bin/hello.rs1
-rw-r--r--examples/stm32f0/src/bin/multiprio.rs1
-rw-r--r--examples/stm32f0/src/bin/wdg.rs1
-rw-r--r--examples/stm32f1/Cargo.toml5
-rw-r--r--examples/stm32f1/src/bin/adc.rs1
-rw-r--r--examples/stm32f1/src/bin/blinky.rs1
-rw-r--r--examples/stm32f1/src/bin/can.rs143
-rw-r--r--examples/stm32f1/src/bin/hello.rs5
-rw-r--r--examples/stm32f1/src/bin/usb_serial.rs23
-rw-r--r--examples/stm32f2/Cargo.toml4
-rw-r--r--examples/stm32f2/src/bin/blinky.rs1
-rw-r--r--examples/stm32f2/src/bin/pll.rs3
-rw-r--r--examples/stm32f3/Cargo.toml6
-rw-r--r--examples/stm32f3/src/bin/blinky.rs1
-rw-r--r--examples/stm32f3/src/bin/button.rs1
-rw-r--r--examples/stm32f3/src/bin/button_events.rs29
-rw-r--r--examples/stm32f3/src/bin/button_exti.rs6
-rw-r--r--examples/stm32f3/src/bin/flash.rs1
-rw-r--r--examples/stm32f3/src/bin/hello.rs6
-rw-r--r--examples/stm32f3/src/bin/multiprio.rs1
-rw-r--r--examples/stm32f3/src/bin/spi_dma.rs1
-rw-r--r--examples/stm32f3/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32f3/src/bin/usb_serial.rs24
-rw-r--r--examples/stm32f334/Cargo.toml6
-rw-r--r--examples/stm32f334/src/bin/adc.rs27
-rw-r--r--examples/stm32f334/src/bin/button.rs1
-rw-r--r--examples/stm32f334/src/bin/hello.rs6
-rw-r--r--examples/stm32f334/src/bin/opamp.rs27
-rw-r--r--examples/stm32f334/src/bin/pwm.rs27
-rw-r--r--examples/stm32f4/Cargo.toml11
-rw-r--r--examples/stm32f4/src/bin/adc.rs1
-rw-r--r--examples/stm32f4/src/bin/blinky.rs1
-rw-r--r--examples/stm32f4/src/bin/button.rs1
-rw-r--r--examples/stm32f4/src/bin/button_exti.rs6
-rw-r--r--examples/stm32f4/src/bin/can.rs12
-rw-r--r--examples/stm32f4/src/bin/dac.rs1
-rw-r--r--examples/stm32f4/src/bin/eth.rs14
-rw-r--r--examples/stm32f4/src/bin/flash.rs7
-rw-r--r--examples/stm32f4/src/bin/flash_async.rs7
-rw-r--r--examples/stm32f4/src/bin/hello.rs1
-rw-r--r--examples/stm32f4/src/bin/i2c.rs1
-rw-r--r--examples/stm32f4/src/bin/i2c_async.rs1
-rw-r--r--examples/stm32f4/src/bin/i2c_comparison.rs1
-rw-r--r--examples/stm32f4/src/bin/i2s_dma.rs1
-rw-r--r--examples/stm32f4/src/bin/mco.rs1
-rw-r--r--examples/stm32f4/src/bin/multiprio.rs1
-rw-r--r--examples/stm32f4/src/bin/pwm.rs1
-rw-r--r--examples/stm32f4/src/bin/pwm_complementary.rs1
-rw-r--r--examples/stm32f4/src/bin/rtc.rs3
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs1
-rw-r--r--examples/stm32f4/src/bin/spi.rs1
-rw-r--r--examples/stm32f4/src/bin/spi_dma.rs1
-rw-r--r--examples/stm32f4/src/bin/usart.rs1
-rw-r--r--examples/stm32f4/src/bin/usart_buffered.rs1
-rw-r--r--examples/stm32f4/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32f4/src/bin/usb_ethernet.rs39
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs221
-rw-r--r--examples/stm32f4/src/bin/usb_hid_mouse.rs147
-rw-r--r--examples/stm32f4/src/bin/usb_raw.rs12
-rw-r--r--examples/stm32f4/src/bin/usb_serial.rs12
-rw-r--r--examples/stm32f4/src/bin/wdt.rs1
-rw-r--r--examples/stm32f4/src/bin/ws2812_pwm.rs102
-rw-r--r--examples/stm32f4/src/bin/ws2812_spi.rs95
-rw-r--r--examples/stm32f7/.cargo/config.toml2
-rw-r--r--examples/stm32f7/Cargo.toml15
-rw-r--r--examples/stm32f7/src/bin/adc.rs1
-rw-r--r--examples/stm32f7/src/bin/blinky.rs1
-rw-r--r--examples/stm32f7/src/bin/button.rs1
-rw-r--r--examples/stm32f7/src/bin/button_exti.rs6
-rw-r--r--examples/stm32f7/src/bin/can.rs29
-rw-r--r--examples/stm32f7/src/bin/cryp.rs80
-rw-r--r--examples/stm32f7/src/bin/eth.rs16
-rw-r--r--examples/stm32f7/src/bin/flash.rs1
-rw-r--r--examples/stm32f7/src/bin/hash.rs78
-rw-r--r--examples/stm32f7/src/bin/hello.rs1
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs1
-rw-r--r--examples/stm32f7/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32f7/src/bin/usb_serial.rs12
-rw-r--r--examples/stm32g0/.cargo/config.toml4
-rw-r--r--examples/stm32g0/Cargo.toml10
-rw-r--r--examples/stm32g0/src/bin/blinky.rs1
-rw-r--r--examples/stm32g0/src/bin/button.rs1
-rw-r--r--examples/stm32g0/src/bin/button_exti.rs6
-rw-r--r--examples/stm32g0/src/bin/flash.rs1
-rw-r--r--examples/stm32g0/src/bin/hf_timer.rs62
-rw-r--r--examples/stm32g0/src/bin/spi_neopixel.rs1
-rw-r--r--examples/stm32g0/src/bin/usb_serial.rs97
-rw-r--r--examples/stm32g4/Cargo.toml8
-rw-r--r--examples/stm32g4/src/bin/adc.rs32
-rw-r--r--examples/stm32g4/src/bin/blinky.rs1
-rw-r--r--examples/stm32g4/src/bin/button.rs1
-rw-r--r--examples/stm32g4/src/bin/button_exti.rs6
-rw-r--r--examples/stm32g4/src/bin/can.rs234
-rw-r--r--examples/stm32g4/src/bin/pll.rs29
-rw-r--r--examples/stm32g4/src/bin/pwm.rs1
-rw-r--r--examples/stm32g4/src/bin/usb_c_pd.rs86
-rw-r--r--examples/stm32g4/src/bin/usb_serial.rs46
-rw-r--r--examples/stm32h5/Cargo.toml14
-rw-r--r--examples/stm32h5/src/bin/blinky.rs1
-rw-r--r--examples/stm32h5/src/bin/button_exti.rs6
-rw-r--r--examples/stm32h5/src/bin/can.rs98
-rw-r--r--examples/stm32h5/src/bin/eth.rs14
-rw-r--r--examples/stm32h5/src/bin/i2c.rs1
-rw-r--r--examples/stm32h5/src/bin/rng.rs1
-rw-r--r--examples/stm32h5/src/bin/usart.rs1
-rw-r--r--examples/stm32h5/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32h5/src/bin/usart_split.rs1
-rw-r--r--examples/stm32h5/src/bin/usb_serial.rs10
-rw-r--r--examples/stm32h7/Cargo.toml12
-rw-r--r--examples/stm32h7/src/bin/adc.rs5
-rw-r--r--examples/stm32h7/src/bin/blinky.rs1
-rw-r--r--examples/stm32h7/src/bin/button_exti.rs6
-rw-r--r--examples/stm32h7/src/bin/camera.rs5
-rw-r--r--examples/stm32h7/src/bin/can.rs98
-rw-r--r--examples/stm32h7/src/bin/dac.rs3
-rw-r--r--examples/stm32h7/src/bin/dac_dma.rs49
-rw-r--r--examples/stm32h7/src/bin/eth.rs34
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs15
-rw-r--r--examples/stm32h7/src/bin/eth_client_mii.rs142
-rw-r--r--examples/stm32h7/src/bin/flash.rs1
-rw-r--r--examples/stm32h7/src/bin/fmc.rs1
-rw-r--r--examples/stm32h7/src/bin/i2c.rs1
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs80
-rw-r--r--examples/stm32h7/src/bin/mco.rs1
-rw-r--r--examples/stm32h7/src/bin/pwm.rs1
-rw-r--r--examples/stm32h7/src/bin/rng.rs1
-rw-r--r--examples/stm32h7/src/bin/rtc.rs5
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs1
-rw-r--r--examples/stm32h7/src/bin/signal.rs1
-rw-r--r--examples/stm32h7/src/bin/spi.rs1
-rw-r--r--examples/stm32h7/src/bin/spi_dma.rs1
-rw-r--r--examples/stm32h7/src/bin/usart.rs1
-rw-r--r--examples/stm32h7/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32h7/src/bin/usart_split.rs1
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs12
-rw-r--r--examples/stm32h7/src/bin/wdg.rs1
-rw-r--r--examples/stm32l0/Cargo.toml8
-rw-r--r--examples/stm32l0/src/bin/adc.rs40
-rw-r--r--examples/stm32l0/src/bin/blinky.rs1
-rw-r--r--examples/stm32l0/src/bin/button.rs1
-rw-r--r--examples/stm32l0/src/bin/button_exti.rs6
-rw-r--r--examples/stm32l0/src/bin/flash.rs1
-rw-r--r--examples/stm32l0/src/bin/spi.rs1
-rw-r--r--examples/stm32l0/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32l0/src/bin/usart_irq.rs1
-rw-r--r--examples/stm32l1/Cargo.toml5
-rw-r--r--examples/stm32l1/src/bin/blinky.rs1
-rw-r--r--examples/stm32l1/src/bin/flash.rs1
-rw-r--r--examples/stm32l1/src/bin/spi.rs1
-rw-r--r--examples/stm32l1/src/bin/usb_serial.rs101
-rw-r--r--examples/stm32l4/Cargo.toml14
-rw-r--r--examples/stm32l4/src/bin/adc.rs17
-rw-r--r--examples/stm32l4/src/bin/blinky.rs1
-rw-r--r--examples/stm32l4/src/bin/button.rs1
-rw-r--r--examples/stm32l4/src/bin/button_exti.rs6
-rw-r--r--examples/stm32l4/src/bin/dac.rs1
-rw-r--r--examples/stm32l4/src/bin/dac_dma.rs47
-rw-r--r--examples/stm32l4/src/bin/i2c.rs1
-rw-r--r--examples/stm32l4/src/bin/i2c_blocking_async.rs1
-rw-r--r--examples/stm32l4/src/bin/i2c_dma.rs1
-rw-r--r--examples/stm32l4/src/bin/mco.rs1
-rw-r--r--examples/stm32l4/src/bin/rng.rs5
-rw-r--r--examples/stm32l4/src/bin/rtc.rs7
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs43
-rw-r--r--examples/stm32l4/src/bin/spi.rs1
-rw-r--r--examples/stm32l4/src/bin/spi_blocking_async.rs1
-rw-r--r--examples/stm32l4/src/bin/spi_dma.rs1
-rw-r--r--examples/stm32l4/src/bin/usart.rs1
-rw-r--r--examples/stm32l4/src/bin/usart_dma.rs1
-rw-r--r--examples/stm32l4/src/bin/usb_serial.rs39
-rw-r--r--examples/stm32l5/Cargo.toml16
-rw-r--r--examples/stm32l5/src/bin/button_exti.rs6
-rw-r--r--examples/stm32l5/src/bin/rng.rs5
-rw-r--r--examples/stm32l5/src/bin/stop.rs61
-rw-r--r--examples/stm32l5/src/bin/usb_ethernet.rs55
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs31
-rw-r--r--examples/stm32l5/src/bin/usb_serial.rs31
-rw-r--r--examples/stm32u5/Cargo.toml6
-rw-r--r--examples/stm32u5/src/bin/blinky.rs1
-rw-r--r--examples/stm32u5/src/bin/boot.rs1
-rw-r--r--examples/stm32u5/src/bin/flash.rs55
-rw-r--r--examples/stm32u5/src/bin/i2c.rs41
-rw-r--r--examples/stm32u5/src/bin/rng.rs25
-rw-r--r--examples/stm32u5/src/bin/usb_serial.rs37
-rw-r--r--examples/stm32wb/Cargo.toml8
-rw-r--r--examples/stm32wb/src/bin/blinky.rs1
-rw-r--r--examples/stm32wb/src/bin/button_exti.rs6
-rw-r--r--examples/stm32wb/src/bin/eddystone_beacon.rs9
-rw-r--r--examples/stm32wb/src/bin/gatt_server.rs27
-rw-r--r--examples/stm32wb/src/bin/mac_ffd.rs1
-rw-r--r--examples/stm32wb/src/bin/mac_ffd_net.rs21
-rw-r--r--examples/stm32wb/src/bin/mac_rfd.rs1
-rw-r--r--examples/stm32wb/src/bin/tl_mbox.rs1
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_ble.rs1
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_mac.rs1
-rw-r--r--examples/stm32wba/Cargo.toml8
-rw-r--r--examples/stm32wba/src/bin/blinky.rs1
-rw-r--r--examples/stm32wba/src/bin/button_exti.rs6
-rw-r--r--examples/stm32wl/Cargo.toml4
-rw-r--r--examples/stm32wl/src/bin/blinky.rs1
-rw-r--r--examples/stm32wl/src/bin/button.rs1
-rw-r--r--examples/stm32wl/src/bin/button_exti.rs6
-rw-r--r--examples/stm32wl/src/bin/flash.rs1
-rw-r--r--examples/stm32wl/src/bin/random.rs3
-rw-r--r--examples/stm32wl/src/bin/rtc.rs7
-rw-r--r--examples/stm32wl/src/bin/uart_async.rs3
-rw-r--r--examples/wasm/Cargo.toml4
-rw-r--r--examples/wasm/src/lib.rs2
403 files changed, 4352 insertions, 1204 deletions
diff --git a/examples/boot/.cargo/config.toml b/examples/boot/.cargo/config.toml
index de3a814f7..be1b73e45 100644
--- a/examples/boot/.cargo/config.toml
+++ b/examples/boot/.cargo/config.toml
@@ -1,6 +1,6 @@
1[unstable] 1[unstable]
2build-std = ["core"] 2#build-std = ["core"]
3build-std-features = ["panic_immediate_abort"] 3#build-std-features = ["panic_immediate_abort"]
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabi" 6target = "thumbv7em-none-eabi"
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index 5f11750b2..86f6676cb 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] }
11embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } 11embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] }
12embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot", features = [] } 12embassy-boot = { version = "0.2.0", path = "../../../../embassy-boot", features = [] }
13embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf", features = [] } 13embassy-boot-nrf = { version = "0.2.0", path = "../../../../embassy-boot-nrf", features = [] }
14embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 14embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
15 15
16defmt = { version = "0.3", optional = true } 16defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/nrf/src/bin/a.rs b/examples/boot/application/nrf/src/bin/a.rs
index 8b510ed35..851a3d721 100644
--- a/examples/boot/application/nrf/src/bin/a.rs
+++ b/examples/boot/application/nrf/src/bin/a.rs
@@ -1,7 +1,6 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![macro_use] 3#![macro_use]
4#![feature(type_alias_impl_trait)]
5 4
6use embassy_boot_nrf::{FirmwareUpdater, FirmwareUpdaterConfig}; 5use embassy_boot_nrf::{FirmwareUpdater, FirmwareUpdaterConfig};
7use embassy_embedded_hal::adapter::BlockingAsync; 6use embassy_embedded_hal::adapter::BlockingAsync;
@@ -51,7 +50,7 @@ async fn main(_spawner: Spawner) {
51 let nvmc = Nvmc::new(p.NVMC); 50 let nvmc = Nvmc::new(p.NVMC);
52 let nvmc = Mutex::new(BlockingAsync::new(nvmc)); 51 let nvmc = Mutex::new(BlockingAsync::new(nvmc));
53 52
54 let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc); 53 let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc, &nvmc);
55 let mut magic = [0; 4]; 54 let mut magic = [0; 4];
56 let mut updater = FirmwareUpdater::new(config, &mut magic); 55 let mut updater = FirmwareUpdater::new(config, &mut magic);
57 loop { 56 loop {
diff --git a/examples/boot/application/nrf/src/bin/b.rs b/examples/boot/application/nrf/src/bin/b.rs
index a88c3c56c..de97b6a22 100644
--- a/examples/boot/application/nrf/src/bin/b.rs
+++ b/examples/boot/application/nrf/src/bin/b.rs
@@ -1,7 +1,6 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![macro_use] 3#![macro_use]
4#![feature(type_alias_impl_trait)]
5 4
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_nrf::gpio::{Level, Output, OutputDrive}; 6use embassy_nrf::gpio::{Level, Output, OutputDrive};
diff --git a/examples/boot/application/rp/.cargo/config.toml b/examples/boot/application/rp/.cargo/config.toml
index cd8d1ef02..22ab3a5c1 100644
--- a/examples/boot/application/rp/.cargo/config.toml
+++ b/examples/boot/application/rp/.cargo/config.toml
@@ -1,6 +1,6 @@
1[unstable] 1[unstable]
2build-std = ["core"] 2#build-std = ["core"]
3build-std-features = ["panic_immediate_abort"] 3#build-std-features = ["panic_immediate_abort"]
4 4
5[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 5[target.'cfg(all(target_arch = "arm", target_os = "none"))']
6runner = "probe-rs run --chip RP2040" 6runner = "probe-rs run --chip RP2040"
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml
index 89ac5a8f6..70741a0ce 100644
--- a/examples/boot/application/rp/Cargo.toml
+++ b/examples/boot/application/rp/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [] }
11embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", ] } 11embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", ] }
12embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp", features = [] } 12embassy-boot-rp = { version = "0.2.0", path = "../../../../embassy-boot-rp", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = "0.3" 15defmt = "0.3"
diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs
index 6fd5d7f60..ede0c07da 100644
--- a/examples/boot/application/rp/src/bin/a.rs
+++ b/examples/boot/application/rp/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::cell::RefCell; 4use core::cell::RefCell;
6 5
@@ -37,7 +36,7 @@ async fn main(_s: Spawner) {
37 let flash = Flash::<_, _, FLASH_SIZE>::new_blocking(p.FLASH); 36 let flash = Flash::<_, _, FLASH_SIZE>::new_blocking(p.FLASH);
38 let flash = Mutex::new(RefCell::new(flash)); 37 let flash = Mutex::new(RefCell::new(flash));
39 38
40 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); 39 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash);
41 let mut aligned = AlignedBuffer([0; 1]); 40 let mut aligned = AlignedBuffer([0; 1]);
42 let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0); 41 let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0);
43 42
diff --git a/examples/boot/application/rp/src/bin/b.rs b/examples/boot/application/rp/src/bin/b.rs
index 1eca5b4a2..a46d095bf 100644
--- a/examples/boot/application/rp/src/bin/b.rs
+++ b/examples/boot/application/rp/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use embassy_executor::Spawner; 4use embassy_executor::Spawner;
6use embassy_rp::gpio; 5use embassy_rp::gpio;
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 1a0f8cee5..1cb143820 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32f3/memory.x b/examples/boot/application/stm32f3/memory.x
index f51875766..02ebe3ecf 100644
--- a/examples/boot/application/stm32f3/memory.x
+++ b/examples/boot/application/stm32f3/memory.x
@@ -3,8 +3,8 @@ MEMORY
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 32K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K
7 DFU : ORIGIN = 0x08010000, LENGTH = 36K 7 DFU : ORIGIN = 0x08018000, LENGTH = 66K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs
index 8be39bfb7..8858ae3da 100644
--- a/examples/boot/application/stm32f3/src/bin/a.rs
+++ b/examples/boot/application/stm32f3/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
@@ -9,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 10use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
14use panic_reset as _; 13use panic_reset as _;
15 14
@@ -24,13 +23,12 @@ async fn main(_spawner: Spawner) {
24 let flash = Flash::new_blocking(p.FLASH); 23 let flash = Flash::new_blocking(p.FLASH);
25 let flash = Mutex::new(BlockingAsync::new(flash)); 24 let flash = Mutex::new(BlockingAsync::new(flash));
26 25
27 let button = Input::new(p.PC13, Pull::Up); 26 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
28 let mut button = ExtiInput::new(button, p.EXTI13);
29 27
30 let mut led = Output::new(p.PA5, Level::Low, Speed::Low); 28 let mut led = Output::new(p.PA5, Level::Low, Speed::Low);
31 led.set_high(); 29 led.set_high();
32 30
33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash); 31 let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash);
34 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 32 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
35 let mut updater = FirmwareUpdater::new(config, &mut magic.0); 33 let mut updater = FirmwareUpdater::new(config, &mut magic.0);
36 button.wait_for_falling_edge().await; 34 button.wait_for_falling_edge().await;
diff --git a/examples/boot/application/stm32f3/src/bin/b.rs b/examples/boot/application/stm32f3/src/bin/b.rs
index 8411f384c..22ba82d5e 100644
--- a/examples/boot/application/stm32f3/src/bin/b.rs
+++ b/examples/boot/application/stm32f3/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index e42d1d421..c4ae461a5 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs
index 0c3819bed..d3df11fe4 100644
--- a/examples/boot/application/stm32f7/src/bin/a.rs
+++ b/examples/boot/application/stm32f7/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::cell::RefCell; 4use core::cell::RefCell;
6 5
@@ -10,7 +9,7 @@ use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdater
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
13use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
14use embassy_sync::blocking_mutex::Mutex; 13use embassy_sync::blocking_mutex::Mutex;
15use embedded_storage::nor_flash::NorFlash; 14use embedded_storage::nor_flash::NorFlash;
16use panic_reset as _; 15use panic_reset as _;
@@ -26,13 +25,12 @@ async fn main(_spawner: Spawner) {
26 let flash = Flash::new_blocking(p.FLASH); 25 let flash = Flash::new_blocking(p.FLASH);
27 let flash = Mutex::new(RefCell::new(flash)); 26 let flash = Mutex::new(RefCell::new(flash));
28 27
29 let button = Input::new(p.PC13, Pull::Down); 28 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
30 let mut button = ExtiInput::new(button, p.EXTI13);
31 29
32 let mut led = Output::new(p.PB7, Level::Low, Speed::Low); 30 let mut led = Output::new(p.PB7, Level::Low, Speed::Low);
33 led.set_high(); 31 led.set_high();
34 32
35 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); 33 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash);
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 34 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
37 let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); 35 let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0);
38 let writer = updater.prepare_update().unwrap(); 36 let writer = updater.prepare_update().unwrap();
diff --git a/examples/boot/application/stm32f7/src/bin/b.rs b/examples/boot/application/stm32f7/src/bin/b.rs
index 4c2ad06a2..190477204 100644
--- a/examples/boot/application/stm32f7/src/bin/b.rs
+++ b/examples/boot/application/stm32f7/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 8450d8639..995487cdd 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs
index f239e3732..f61ac1f71 100644
--- a/examples/boot/application/stm32h7/src/bin/a.rs
+++ b/examples/boot/application/stm32h7/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::cell::RefCell; 4use core::cell::RefCell;
6 5
@@ -10,7 +9,7 @@ use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdater
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::flash::{Flash, WRITE_SIZE}; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
13use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Level, Output, Pull, Speed};
14use embassy_sync::blocking_mutex::Mutex; 13use embassy_sync::blocking_mutex::Mutex;
15use embedded_storage::nor_flash::NorFlash; 14use embedded_storage::nor_flash::NorFlash;
16use panic_reset as _; 15use panic_reset as _;
@@ -26,13 +25,12 @@ async fn main(_spawner: Spawner) {
26 let flash = Flash::new_blocking(p.FLASH); 25 let flash = Flash::new_blocking(p.FLASH);
27 let flash = Mutex::new(RefCell::new(flash)); 26 let flash = Mutex::new(RefCell::new(flash));
28 27
29 let button = Input::new(p.PC13, Pull::Down); 28 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
30 let mut button = ExtiInput::new(button, p.EXTI13);
31 29
32 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 30 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
33 led.set_high(); 31 led.set_high();
34 32
35 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); 33 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash);
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 34 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
37 let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); 35 let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0);
38 let writer = updater.prepare_update().unwrap(); 36 let writer = updater.prepare_update().unwrap();
diff --git a/examples/boot/application/stm32h7/src/bin/b.rs b/examples/boot/application/stm32h7/src/bin/b.rs
index 5c03e2d0c..5f3f35207 100644
--- a/examples/boot/application/stm32h7/src/bin/b.rs
+++ b/examples/boot/application/stm32h7/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index d6684bedb..b2abc005c 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32l0/memory.x b/examples/boot/application/stm32l0/memory.x
index a99330145..8866506a8 100644
--- a/examples/boot/application/stm32l0/memory.x
+++ b/examples/boot/application/stm32l0/memory.x
@@ -3,8 +3,8 @@ MEMORY
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 32K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K
7 DFU : ORIGIN = 0x08010000, LENGTH = 36K 7 DFU : ORIGIN = 0x08018000, LENGTH = 66K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
9} 9}
10 10
diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs
index 42e1a71eb..f066c1139 100644
--- a/examples/boot/application/stm32l0/src/bin/a.rs
+++ b/examples/boot/application/stm32l0/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
@@ -9,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 10use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
14use embassy_time::Timer; 13use embassy_time::Timer;
15use panic_reset as _; 14use panic_reset as _;
@@ -25,14 +24,13 @@ async fn main(_spawner: Spawner) {
25 let flash = Flash::new_blocking(p.FLASH); 24 let flash = Flash::new_blocking(p.FLASH);
26 let flash = Mutex::new(BlockingAsync::new(flash)); 25 let flash = Mutex::new(BlockingAsync::new(flash));
27 26
28 let button = Input::new(p.PB2, Pull::Up); 27 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up);
29 let mut button = ExtiInput::new(button, p.EXTI2);
30 28
31 let mut led = Output::new(p.PB5, Level::Low, Speed::Low); 29 let mut led = Output::new(p.PB5, Level::Low, Speed::Low);
32 30
33 led.set_high(); 31 led.set_high();
34 32
35 let config = FirmwareUpdaterConfig::from_linkerfile(&flash); 33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash);
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 34 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
37 let mut updater = FirmwareUpdater::new(config, &mut magic.0); 35 let mut updater = FirmwareUpdater::new(config, &mut magic.0);
38 button.wait_for_falling_edge().await; 36 button.wait_for_falling_edge().await;
diff --git a/examples/boot/application/stm32l0/src/bin/b.rs b/examples/boot/application/stm32l0/src/bin/b.rs
index 52d42395f..6bf00f41a 100644
--- a/examples/boot/application/stm32l0/src/bin/b.rs
+++ b/examples/boot/application/stm32l0/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index cca8bf443..7203e6350 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32l1/memory.x b/examples/boot/application/stm32l1/memory.x
index a99330145..caa525278 100644
--- a/examples/boot/application/stm32l1/memory.x
+++ b/examples/boot/application/stm32l1/memory.x
@@ -3,8 +3,8 @@ MEMORY
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 32K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 46K
7 DFU : ORIGIN = 0x08010000, LENGTH = 36K 7 DFU : ORIGIN = 0x08013800, LENGTH = 54K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
9} 9}
10 10
diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs
index 42e1a71eb..f066c1139 100644
--- a/examples/boot/application/stm32l1/src/bin/a.rs
+++ b/examples/boot/application/stm32l1/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
@@ -9,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 10use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
14use embassy_time::Timer; 13use embassy_time::Timer;
15use panic_reset as _; 14use panic_reset as _;
@@ -25,14 +24,13 @@ async fn main(_spawner: Spawner) {
25 let flash = Flash::new_blocking(p.FLASH); 24 let flash = Flash::new_blocking(p.FLASH);
26 let flash = Mutex::new(BlockingAsync::new(flash)); 25 let flash = Mutex::new(BlockingAsync::new(flash));
27 26
28 let button = Input::new(p.PB2, Pull::Up); 27 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up);
29 let mut button = ExtiInput::new(button, p.EXTI2);
30 28
31 let mut led = Output::new(p.PB5, Level::Low, Speed::Low); 29 let mut led = Output::new(p.PB5, Level::Low, Speed::Low);
32 30
33 led.set_high(); 31 led.set_high();
34 32
35 let config = FirmwareUpdaterConfig::from_linkerfile(&flash); 33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash);
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 34 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
37 let mut updater = FirmwareUpdater::new(config, &mut magic.0); 35 let mut updater = FirmwareUpdater::new(config, &mut magic.0);
38 button.wait_for_falling_edge().await; 36 button.wait_for_falling_edge().await;
diff --git a/examples/boot/application/stm32l1/src/bin/b.rs b/examples/boot/application/stm32l1/src/bin/b.rs
index 52d42395f..6bf00f41a 100644
--- a/examples/boot/application/stm32l1/src/bin/b.rs
+++ b/examples/boot/application/stm32l1/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 30d61056c..ec134f394 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32l4/memory.x b/examples/boot/application/stm32l4/memory.x
index f51875766..e1d4e7fa8 100644
--- a/examples/boot/application/stm32l4/memory.x
+++ b/examples/boot/application/stm32l4/memory.x
@@ -3,8 +3,8 @@ MEMORY
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 32K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K
7 DFU : ORIGIN = 0x08010000, LENGTH = 36K 7 DFU : ORIGIN = 0x08018000, LENGTH = 68K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs
index eefa25f75..a0079ee33 100644
--- a/examples/boot/application/stm32l4/src/bin/a.rs
+++ b/examples/boot/application/stm32l4/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
@@ -9,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 10use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
14use panic_reset as _; 13use panic_reset as _;
15 14
@@ -24,13 +23,12 @@ async fn main(_spawner: Spawner) {
24 let flash = Flash::new_blocking(p.FLASH); 23 let flash = Flash::new_blocking(p.FLASH);
25 let flash = Mutex::new(BlockingAsync::new(flash)); 24 let flash = Mutex::new(BlockingAsync::new(flash));
26 25
27 let button = Input::new(p.PC13, Pull::Up); 26 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
28 let mut button = ExtiInput::new(button, p.EXTI13);
29 27
30 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 28 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
31 led.set_high(); 29 led.set_high();
32 30
33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash); 31 let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash);
34 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 32 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
35 let mut updater = FirmwareUpdater::new(config, &mut magic.0); 33 let mut updater = FirmwareUpdater::new(config, &mut magic.0);
36 button.wait_for_falling_edge().await; 34 button.wait_for_falling_edge().await;
diff --git a/examples/boot/application/stm32l4/src/bin/b.rs b/examples/boot/application/stm32l4/src/bin/b.rs
index 8411f384c..22ba82d5e 100644
--- a/examples/boot/application/stm32l4/src/bin/b.rs
+++ b/examples/boot/application/stm32l4/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/application/stm32wb-dfu/.cargo/config.toml b/examples/boot/application/stm32wb-dfu/.cargo/config.toml
new file mode 100644
index 000000000..4f8094ff2
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip STM32WLE5JCIx"
4
5[build]
6target = "thumbv7em-none-eabihf"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml
new file mode 100644
index 000000000..0bdf94331
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/Cargo.toml
@@ -0,0 +1,32 @@
1[package]
2edition = "2021"
3name = "embassy-boot-stm32wb-dfu-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb" }
15embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] }
16
17defmt = { version = "0.3", optional = true }
18defmt-rtt = { version = "0.4", optional = true }
19panic-reset = { version = "0.1.1" }
20embedded-hal = { version = "0.2.6" }
21
22cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
23cortex-m-rt = "0.7.0"
24
25[features]
26defmt = [
27 "dep:defmt",
28 "dep:defmt-rtt",
29 "embassy-stm32/defmt",
30 "embassy-boot-stm32/defmt",
31 "embassy-sync/defmt",
32]
diff --git a/examples/boot/application/stm32wb-dfu/README.md b/examples/boot/application/stm32wb-dfu/README.md
new file mode 100644
index 000000000..7f656cde6
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/README.md
@@ -0,0 +1,9 @@
1# Examples using bootloader
2
3Example for STM32WB demonstrating the USB DFU application.
4
5## Usage
6
7```
8cargo flash --release --chip STM32WB55RGVx
9```
diff --git a/examples/boot/application/stm32wb-dfu/build.rs b/examples/boot/application/stm32wb-dfu/build.rs
new file mode 100644
index 000000000..e1da69328
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/build.rs
@@ -0,0 +1,37 @@
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 if env::var("CARGO_FEATURE_DEFMT").is_ok() {
35 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
36 }
37}
diff --git a/examples/boot/application/stm32wb-dfu/memory.x b/examples/boot/application/stm32wb-dfu/memory.x
new file mode 100644
index 000000000..ff1b800d2
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/memory.x
@@ -0,0 +1,15 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 128K
7 DFU : ORIGIN = 0x08028000, LENGTH = 132K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9}
10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER);
12__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER);
13
14__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOTLOADER);
15__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOTLOADER);
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs
new file mode 100644
index 000000000..929d6802c
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/src/main.rs
@@ -0,0 +1,61 @@
1#![no_std]
2#![no_main]
3
4use core::cell::RefCell;
5
6#[cfg(feature = "defmt-rtt")]
7use defmt_rtt::*;
8use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareState, FirmwareUpdaterConfig};
9use embassy_executor::Spawner;
10use embassy_stm32::flash::{Flash, WRITE_SIZE};
11use embassy_stm32::rcc::WPAN_DEFAULT;
12use embassy_stm32::usb::{self, Driver};
13use embassy_stm32::{bind_interrupts, peripherals};
14use embassy_sync::blocking_mutex::Mutex;
15use embassy_time::Duration;
16use embassy_usb::Builder;
17use embassy_usb_dfu::consts::DfuAttributes;
18use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate};
19use panic_reset as _;
20
21bind_interrupts!(struct Irqs {
22 USB_LP => usb::InterruptHandler<peripherals::USB>;
23});
24
25#[embassy_executor::main]
26async fn main(_spawner: Spawner) {
27 let mut config = embassy_stm32::Config::default();
28 config.rcc = WPAN_DEFAULT;
29 let p = embassy_stm32::init(config);
30 let flash = Flash::new_blocking(p.FLASH);
31 let flash = Mutex::new(RefCell::new(flash));
32
33 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash);
34 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
35 let mut firmware_state = BlockingFirmwareState::from_config(config, &mut magic.0);
36 firmware_state.mark_booted().expect("Failed to mark booted");
37
38 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
39 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
40 config.manufacturer = Some("Embassy");
41 config.product = Some("USB-DFU Runtime example");
42 config.serial_number = Some("1235678");
43
44 let mut config_descriptor = [0; 256];
45 let mut bos_descriptor = [0; 256];
46 let mut control_buf = [0; 64];
47 let mut state = Control::new(firmware_state, DfuAttributes::CAN_DOWNLOAD);
48 let mut builder = Builder::new(
49 driver,
50 config,
51 &mut config_descriptor,
52 &mut bos_descriptor,
53 &mut [],
54 &mut control_buf,
55 );
56
57 usb_dfu::<_, _, ResetImmediate>(&mut builder, &mut state, Duration::from_millis(2500));
58
59 let mut dev = builder.build();
60 dev.run().await
61}
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 7489a2fe9..e38e9f3af 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.4.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = [] } 12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/boot/application/stm32wl/memory.x b/examples/boot/application/stm32wl/memory.x
index f51875766..e1d4e7fa8 100644
--- a/examples/boot/application/stm32wl/memory.x
+++ b/examples/boot/application/stm32wl/memory.x
@@ -3,8 +3,8 @@ MEMORY
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 32K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K
7 DFU : ORIGIN = 0x08010000, LENGTH = 36K 7 DFU : ORIGIN = 0x08018000, LENGTH = 68K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs
index c837e47b5..2fb16bdc4 100644
--- a/examples/boot/application/stm32wl/src/bin/a.rs
+++ b/examples/boot/application/stm32wl/src/bin/a.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
@@ -9,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 9use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::{Flash, WRITE_SIZE}; 10use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 11use embassy_stm32::gpio::{Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex; 12use embassy_sync::mutex::Mutex;
14use panic_reset as _; 13use panic_reset as _;
15 14
@@ -24,13 +23,12 @@ async fn main(_spawner: Spawner) {
24 let flash = Flash::new_blocking(p.FLASH); 23 let flash = Flash::new_blocking(p.FLASH);
25 let flash = Mutex::new(BlockingAsync::new(flash)); 24 let flash = Mutex::new(BlockingAsync::new(flash));
26 25
27 let button = Input::new(p.PA0, Pull::Up); 26 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up);
28 let mut button = ExtiInput::new(button, p.EXTI0);
29 27
30 let mut led = Output::new(p.PB9, Level::Low, Speed::Low); 28 let mut led = Output::new(p.PB9, Level::Low, Speed::Low);
31 led.set_high(); 29 led.set_high();
32 30
33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash); 31 let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash);
34 let mut magic = AlignedBuffer([0; WRITE_SIZE]); 32 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
35 let mut updater = FirmwareUpdater::new(config, &mut magic.0); 33 let mut updater = FirmwareUpdater::new(config, &mut magic.0);
36 button.wait_for_falling_edge().await; 34 button.wait_for_falling_edge().await;
diff --git a/examples/boot/application/stm32wl/src/bin/b.rs b/examples/boot/application/stm32wl/src/bin/b.rs
index 1ca3c6ea8..8dd15d8cd 100644
--- a/examples/boot/application/stm32wl/src/bin/b.rs
+++ b/examples/boot/application/stm32wl/src/bin/b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5#[cfg(feature = "defmt-rtt")] 4#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 5use defmt_rtt::*;
diff --git a/examples/boot/bootloader/nrf/.cargo/config.toml b/examples/boot/bootloader/nrf/.cargo/config.toml
index c292846aa..58acd1a49 100644
--- a/examples/boot/bootloader/nrf/.cargo/config.toml
+++ b/examples/boot/bootloader/nrf/.cargo/config.toml
@@ -1,6 +1,6 @@
1[unstable] 1[unstable]
2build-std = ["core"] 2#build-std = ["core"]
3build-std-features = ["panic_immediate_abort"] 3#build-std-features = ["panic_immediate_abort"]
4 4
5[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 5[target.'cfg(all(target_arch = "arm", target_os = "none"))']
6#runner = "./fruitrunner" 6#runner = "./fruitrunner"
@@ -8,7 +8,7 @@ runner = "probe-rs run --chip nrf52840_xxAA"
8 8
9rustflags = [ 9rustflags = [
10 # Code-size optimizations. 10 # Code-size optimizations.
11 "-Z", "trap-unreachable=no", 11 #"-Z", "trap-unreachable=no",
12 #"-C", "no-vectorize-loops", 12 #"-C", "no-vectorize-loops",
13 "-C", "force-frame-pointers=yes", 13 "-C", "force-frame-pointers=yes",
14] 14]
diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml
index a7273175f..3e41d1479 100644
--- a/examples/boot/bootloader/nrf/Cargo.toml
+++ b/examples/boot/bootloader/nrf/Cargo.toml
@@ -10,7 +10,7 @@ defmt = { version = "0.3", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "0.4", optional = true }
11 11
12embassy-nrf = { path = "../../../../embassy-nrf", features = [] } 12embassy-nrf = { path = "../../../../embassy-nrf", features = [] }
13embassy-boot-nrf = { path = "../../../../embassy-boot/nrf" } 13embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 15embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" } 16cortex-m-rt = { version = "0.7" }
diff --git a/examples/boot/bootloader/nrf/src/main.rs b/examples/boot/bootloader/nrf/src/main.rs
index 74e2e293f..67c700437 100644
--- a/examples/boot/bootloader/nrf/src/main.rs
+++ b/examples/boot/bootloader/nrf/src/main.rs
@@ -31,7 +31,7 @@ fn main() -> ! {
31 let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); 31 let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config);
32 let flash = Mutex::new(RefCell::new(flash)); 32 let flash = Mutex::new(RefCell::new(flash));
33 33
34 let config = BootLoaderConfig::from_linkerfile_blocking(&flash); 34 let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash);
35 let active_offset = config.active.offset(); 35 let active_offset = config.active.offset();
36 let bl: BootLoader = BootLoader::prepare(config); 36 let bl: BootLoader = BootLoader::prepare(config);
37 37
diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml
index 5bc61e9ec..3cf61a002 100644
--- a/examples/boot/bootloader/rp/Cargo.toml
+++ b/examples/boot/bootloader/rp/Cargo.toml
@@ -10,7 +10,7 @@ defmt = { version = "0.3", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "0.4", optional = true }
11 11
12embassy-rp = { path = "../../../../embassy-rp", features = [] } 12embassy-rp = { path = "../../../../embassy-rp", features = [] }
13embassy-boot-rp = { path = "../../../../embassy-boot/rp" } 13embassy-boot-rp = { path = "../../../../embassy-boot-rp" }
14embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 14embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
15embassy-time = { path = "../../../../embassy-time", features = [] } 15embassy-time = { path = "../../../../embassy-time", features = [] }
16 16
diff --git a/examples/boot/bootloader/rp/src/main.rs b/examples/boot/bootloader/rp/src/main.rs
index c0e75d1ea..25b1657b8 100644
--- a/examples/boot/bootloader/rp/src/main.rs
+++ b/examples/boot/bootloader/rp/src/main.rs
@@ -27,7 +27,7 @@ fn main() -> ! {
27 let flash = WatchdogFlash::<FLASH_SIZE>::start(p.FLASH, p.WATCHDOG, Duration::from_secs(8)); 27 let flash = WatchdogFlash::<FLASH_SIZE>::start(p.FLASH, p.WATCHDOG, Duration::from_secs(8));
28 let flash = Mutex::new(RefCell::new(flash)); 28 let flash = Mutex::new(RefCell::new(flash));
29 29
30 let config = BootLoaderConfig::from_linkerfile_blocking(&flash); 30 let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash);
31 let active_offset = config.active.offset(); 31 let active_offset = config.active.offset();
32 let bl: BootLoader = BootLoader::prepare(config); 32 let bl: BootLoader = BootLoader::prepare(config);
33 33
diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
new file mode 100644
index 000000000..313187adc
--- /dev/null
+++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
@@ -0,0 +1,57 @@
1[package]
2edition = "2021"
3name = "stm32-bootloader-dual-bank-flash-example"
4version = "0.1.0"
5description = "Example bootloader for dual-bank flash STM32 chips"
6license = "MIT OR Apache-2.0"
7
8[dependencies]
9defmt = { version = "0.3", optional = true }
10defmt-rtt = { version = "0.4", optional = true }
11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
14cortex-m = { version = "0.7.6", features = [
15 "inline-asm",
16 "critical-section-single-core",
17] }
18embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
19cortex-m-rt = { version = "0.7" }
20embedded-storage = "0.3.1"
21embedded-storage-async = "0.4.0"
22cfg-if = "1.0.0"
23
24[features]
25defmt = ["dep:defmt", "embassy-boot-stm32/defmt", "embassy-stm32/defmt"]
26debug = ["defmt-rtt", "defmt"]
27
28[profile.dev]
29debug = 2
30debug-assertions = true
31incremental = false
32opt-level = 'z'
33overflow-checks = true
34
35[profile.release]
36codegen-units = 1
37debug = 2
38debug-assertions = false
39incremental = false
40lto = 'fat'
41opt-level = 'z'
42overflow-checks = false
43
44# do not optimize proc-macro crates = faster builds from scratch
45[profile.dev.build-override]
46codegen-units = 8
47debug = false
48debug-assertions = false
49opt-level = 0
50overflow-checks = false
51
52[profile.release.build-override]
53codegen-units = 8
54debug = false
55debug-assertions = false
56opt-level = 0
57overflow-checks = false
diff --git a/examples/boot/bootloader/stm32-dual-bank/README.md b/examples/boot/bootloader/stm32-dual-bank/README.md
new file mode 100644
index 000000000..3de3171cd
--- /dev/null
+++ b/examples/boot/bootloader/stm32-dual-bank/README.md
@@ -0,0 +1,44 @@
1# STM32 dual-bank flash Bootloader
2
3## Overview
4
5This bootloader leverages `embassy-boot` to interact with the flash.
6This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series.
7Users must modify the `memory.x` configuration file to match with the memory layout of their specific STM32 device.
8
9Additionally, this example can be extended to utilize external flash memory, such as QSPI, for storing partitions.
10
11## Memory Configuration
12
13In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment.
14For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks.
15
16### Symbol Definitions
17
18The bootloader's state and active symbols are anchored to the flash origin of **bank 1**:
19
20- `__bootloader_state_start` and `__bootloader_state_end`
21- `__bootloader_active_start` and `__bootloader_active_end`
22
23In contrast, the Device Firmware Upgrade (DFU) symbols are aligned with the DFU flash origin in **bank 2**:
24
25- `__bootloader_dfu_start` and `__bootloader_dfu_end`
26
27```rust
28__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(**FLASH**);
29__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(**FLASH**);
30
31__bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(**FLASH**);
32__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(**FLASH**);
33
34__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(**DFU**);
35__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(**DFU**);
36```
37
38## Flashing the Bootloader
39
40To flash the bootloader onto your STM32H747XI device, use the following command:
41
42```bash
43cargo flash --features embassy-stm32/stm32h747xi-cm7 --release --chip STM32H747XIHx
44```
diff --git a/examples/boot/bootloader/stm32-dual-bank/build.rs b/examples/boot/bootloader/stm32-dual-bank/build.rs
new file mode 100644
index 000000000..fd605991f
--- /dev/null
+++ b/examples/boot/bootloader/stm32-dual-bank/build.rs
@@ -0,0 +1,27 @@
1use std::env;
2use std::fs::File;
3use std::io::Write;
4use std::path::PathBuf;
5
6fn main() {
7 // Put `memory.x` in our output directory and ensure it's
8 // on the linker search path.
9 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
10 File::create(out.join("memory.x"))
11 .unwrap()
12 .write_all(include_bytes!("memory.x"))
13 .unwrap();
14 println!("cargo:rustc-link-search={}", out.display());
15
16 // By default, Cargo will re-run a build script whenever
17 // any file in the project changes. By specifying `memory.x`
18 // here, we ensure the build script is only re-run when
19 // `memory.x` is changed.
20 println!("cargo:rerun-if-changed=memory.x");
21
22 println!("cargo:rustc-link-arg-bins=--nmagic");
23 println!("cargo:rustc-link-arg-bins=-Tlink.x");
24 if env::var("CARGO_FEATURE_DEFMT").is_ok() {
25 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
26 }
27}
diff --git a/examples/boot/bootloader/stm32-dual-bank/memory.x b/examples/boot/bootloader/stm32-dual-bank/memory.x
new file mode 100644
index 000000000..665da7139
--- /dev/null
+++ b/examples/boot/bootloader/stm32-dual-bank/memory.x
@@ -0,0 +1,18 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 FLASH : ORIGIN = 0x08000000, LENGTH = 128K
5 BOOTLOADER_STATE : ORIGIN = 0x08020000, LENGTH = 128K
6 ACTIVE : ORIGIN = 0x08040000, LENGTH = 512K
7 DFU : ORIGIN = 0x08100000, LENGTH = 640K
8 RAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K
9}
10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(FLASH);
12__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(FLASH);
13
14__bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(FLASH);
15__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(FLASH);
16
17__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(DFU);
18__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(DFU);
diff --git a/examples/boot/bootloader/stm32-dual-bank/src/main.rs b/examples/boot/bootloader/stm32-dual-bank/src/main.rs
new file mode 100644
index 000000000..4d2e82d26
--- /dev/null
+++ b/examples/boot/bootloader/stm32-dual-bank/src/main.rs
@@ -0,0 +1,53 @@
1#![no_std]
2#![no_main]
3
4use core::cell::RefCell;
5
6use cortex_m_rt::{entry, exception};
7#[cfg(feature = "defmt")]
8use defmt_rtt as _;
9use embassy_boot_stm32::*;
10use embassy_stm32::flash::{Flash, BANK1_REGION};
11use embassy_sync::blocking_mutex::Mutex;
12
13#[entry]
14fn main() -> ! {
15 let p = embassy_stm32::init(Default::default());
16
17 // Uncomment this if you are debugging the bootloader with debugger/RTT attached,
18 // as it prevents a hard fault when accessing flash 'too early' after boot.
19 /*
20 for i in 0..10000000 {
21 cortex_m::asm::nop();
22 }
23 */
24
25 let layout = Flash::new_blocking(p.FLASH).into_blocking_regions();
26 let flash_bank1 = Mutex::new(RefCell::new(layout.bank1_region));
27 let flash_bank2 = Mutex::new(RefCell::new(layout.bank2_region));
28
29 let config = BootLoaderConfig::from_linkerfile_blocking(&flash_bank1, &flash_bank2, &flash_bank1);
30 let active_offset = config.active.offset();
31 let bl = BootLoader::prepare::<_, _, _, 2048>(config);
32
33 unsafe { bl.load(BANK1_REGION.base + active_offset) }
34}
35
36#[no_mangle]
37#[cfg_attr(target_os = "none", link_section = ".HardFault.user")]
38unsafe extern "C" fn HardFault() {
39 cortex_m::peripheral::SCB::sys_reset();
40}
41
42#[exception]
43unsafe fn DefaultHandler(_: i16) -> ! {
44 const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32;
45 let irqn = core::ptr::read_volatile(SCB_ICSR) as u8 as i16 - 16;
46
47 panic!("DefaultHandler #{:?}", irqn);
48}
49
50#[panic_handler]
51fn panic(_info: &core::panic::PanicInfo) -> ! {
52 cortex_m::asm::udf();
53}
diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml
index 2d88b0f78..74c01b0f4 100644
--- a/examples/boot/bootloader/stm32/Cargo.toml
+++ b/examples/boot/bootloader/stm32/Cargo.toml
@@ -10,7 +10,7 @@ defmt = { version = "0.3", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "0.4", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot/stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } 15embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" } 16cortex-m-rt = { version = "0.7" }
diff --git a/examples/boot/bootloader/stm32/src/main.rs b/examples/boot/bootloader/stm32/src/main.rs
index 5fd9ea588..99a7a6a6b 100644
--- a/examples/boot/bootloader/stm32/src/main.rs
+++ b/examples/boot/bootloader/stm32/src/main.rs
@@ -25,7 +25,7 @@ fn main() -> ! {
25 let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); 25 let layout = Flash::new_blocking(p.FLASH).into_blocking_regions();
26 let flash = Mutex::new(RefCell::new(layout.bank1_region)); 26 let flash = Mutex::new(RefCell::new(layout.bank1_region));
27 27
28 let config = BootLoaderConfig::from_linkerfile_blocking(&flash); 28 let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash);
29 let active_offset = config.active.offset(); 29 let active_offset = config.active.offset();
30 let bl = BootLoader::prepare::<_, _, _, 2048>(config); 30 let bl = BootLoader::prepare::<_, _, _, 2048>(config);
31 31
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
new file mode 100644
index 000000000..854f94d85
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
@@ -0,0 +1,63 @@
1[package]
2edition = "2021"
3name = "stm32wb-dfu-bootloader-example"
4version = "0.1.0"
5description = "Example USB DFUbootloader for the STM32WB series of chips"
6license = "MIT OR Apache-2.0"
7
8[dependencies]
9defmt = { version = "0.3", optional = true }
10defmt-rtt = { version = "0.4", optional = true }
11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" }
17embedded-storage = "0.3.1"
18embedded-storage-async = "0.4.0"
19cfg-if = "1.0.0"
20embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] }
21embassy-usb = { version = "0.1.0", path = "../../../../embassy-usb", default-features = false }
22embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" }
23
24[features]
25defmt = [
26 "dep:defmt",
27 "embassy-boot-stm32/defmt",
28 "embassy-stm32/defmt",
29 "embassy-usb/defmt",
30 "embassy-usb-dfu/defmt"
31]
32debug = ["defmt-rtt", "defmt"]
33
34[profile.dev]
35debug = 2
36debug-assertions = true
37incremental = false
38opt-level = 'z'
39overflow-checks = true
40
41[profile.release]
42codegen-units = 1
43debug = 2
44debug-assertions = false
45incremental = false
46lto = 'fat'
47opt-level = 'z'
48overflow-checks = false
49
50# do not optimize proc-macro crates = faster builds from scratch
51[profile.dev.build-override]
52codegen-units = 8
53debug = false
54debug-assertions = false
55opt-level = 0
56overflow-checks = false
57
58[profile.release.build-override]
59codegen-units = 8
60debug = false
61debug-assertions = false
62opt-level = 0
63overflow-checks = false
diff --git a/examples/boot/bootloader/stm32wb-dfu/README.md b/examples/boot/bootloader/stm32wb-dfu/README.md
new file mode 100644
index 000000000..d5c6ea57c
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/README.md
@@ -0,0 +1,11 @@
1# Bootloader for STM32
2
3The bootloader uses `embassy-boot` to interact with the flash.
4
5# Usage
6
7Flash the bootloader
8
9```
10cargo flash --features embassy-stm32/stm32wb55rg --release --chip STM32WB55RGVx
11```
diff --git a/examples/boot/bootloader/stm32wb-dfu/build.rs b/examples/boot/bootloader/stm32wb-dfu/build.rs
new file mode 100644
index 000000000..fd605991f
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/build.rs
@@ -0,0 +1,27 @@
1use std::env;
2use std::fs::File;
3use std::io::Write;
4use std::path::PathBuf;
5
6fn main() {
7 // Put `memory.x` in our output directory and ensure it's
8 // on the linker search path.
9 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
10 File::create(out.join("memory.x"))
11 .unwrap()
12 .write_all(include_bytes!("memory.x"))
13 .unwrap();
14 println!("cargo:rustc-link-search={}", out.display());
15
16 // By default, Cargo will re-run a build script whenever
17 // any file in the project changes. By specifying `memory.x`
18 // here, we ensure the build script is only re-run when
19 // `memory.x` is changed.
20 println!("cargo:rerun-if-changed=memory.x");
21
22 println!("cargo:rustc-link-arg-bins=--nmagic");
23 println!("cargo:rustc-link-arg-bins=-Tlink.x");
24 if env::var("CARGO_FEATURE_DEFMT").is_ok() {
25 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
26 }
27}
diff --git a/examples/boot/bootloader/stm32wb-dfu/memory.x b/examples/boot/bootloader/stm32wb-dfu/memory.x
new file mode 100644
index 000000000..858062631
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/memory.x
@@ -0,0 +1,18 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 FLASH : ORIGIN = 0x08000000, LENGTH = 24K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 ACTIVE : ORIGIN = 0x08008000, LENGTH = 128K
7 DFU : ORIGIN = 0x08028000, LENGTH = 132K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
9}
10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(FLASH);
12__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(FLASH);
13
14__bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(FLASH);
15__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(FLASH);
16
17__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(FLASH);
18__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(FLASH);
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
new file mode 100644
index 000000000..093b39f9d
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
@@ -0,0 +1,91 @@
1#![no_std]
2#![no_main]
3
4use core::cell::RefCell;
5
6use cortex_m_rt::{entry, exception};
7#[cfg(feature = "defmt")]
8use defmt_rtt as _;
9use embassy_boot_stm32::*;
10use embassy_stm32::flash::{Flash, BANK1_REGION, WRITE_SIZE};
11use embassy_stm32::rcc::WPAN_DEFAULT;
12use embassy_stm32::usb::Driver;
13use embassy_stm32::{bind_interrupts, peripherals, usb};
14use embassy_sync::blocking_mutex::Mutex;
15use embassy_usb::Builder;
16use embassy_usb_dfu::consts::DfuAttributes;
17use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate};
18
19bind_interrupts!(struct Irqs {
20 USB_LP => usb::InterruptHandler<peripherals::USB>;
21});
22
23#[entry]
24fn main() -> ! {
25 let mut config = embassy_stm32::Config::default();
26 config.rcc = WPAN_DEFAULT;
27 let p = embassy_stm32::init(config);
28
29 // Prevent a hard fault when accessing flash 'too early' after boot.
30 #[cfg(feature = "defmt")]
31 for _ in 0..10000000 {
32 cortex_m::asm::nop();
33 }
34
35 let layout = Flash::new_blocking(p.FLASH).into_blocking_regions();
36 let flash = Mutex::new(RefCell::new(layout.bank1_region));
37
38 let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash);
39 let active_offset = config.active.offset();
40 let bl = BootLoader::prepare::<_, _, _, 2048>(config);
41 if bl.state == State::DfuDetach {
42 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
43 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
44 config.manufacturer = Some("Embassy");
45 config.product = Some("USB-DFU Bootloader example");
46 config.serial_number = Some("1235678");
47
48 let fw_config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash);
49 let mut buffer = AlignedBuffer([0; WRITE_SIZE]);
50 let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]);
51
52 let mut config_descriptor = [0; 256];
53 let mut bos_descriptor = [0; 256];
54 let mut control_buf = [0; 4096];
55 let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD);
56 let mut builder = Builder::new(
57 driver,
58 config,
59 &mut config_descriptor,
60 &mut bos_descriptor,
61 &mut [],
62 &mut control_buf,
63 );
64
65 usb_dfu::<_, _, _, ResetImmediate, 4096>(&mut builder, &mut state);
66
67 let mut dev = builder.build();
68 embassy_futures::block_on(dev.run());
69 }
70
71 unsafe { bl.load(BANK1_REGION.base + active_offset) }
72}
73
74#[no_mangle]
75#[cfg_attr(target_os = "none", link_section = ".HardFault.user")]
76unsafe extern "C" fn HardFault() {
77 cortex_m::peripheral::SCB::sys_reset();
78}
79
80#[exception]
81unsafe fn DefaultHandler(_: i16) -> ! {
82 const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32;
83 let irqn = core::ptr::read_volatile(SCB_ICSR) as u8 as i16 - 16;
84
85 panic!("DefaultHandler #{:?}", irqn);
86}
87
88#[panic_handler]
89fn panic(_info: &core::panic::PanicInfo) -> ! {
90 cortex_m::asm::udf();
91}
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml
index bfbec028a..17210994b 100644
--- a/examples/nrf-rtos-trace/Cargo.toml
+++ b/examples/nrf-rtos-trace/Cargo.toml
@@ -16,8 +16,8 @@ log = [
16 16
17[dependencies] 17[dependencies]
18embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } 18embassy-sync = { version = "0.5.0", path = "../../embassy-sync" }
19embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] } 19embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "integrated-timers"] }
20embassy-time = { version = "0.2", path = "../../embassy-time" } 20embassy-time = { version = "0.3.0", path = "../../embassy-time" }
21embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } 21embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
22 22
23cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 23cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
diff --git a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs
index 888375693..41cc06417 100644
--- a/examples/nrf-rtos-trace/src/bin/rtos_trace.rs
+++ b/examples/nrf-rtos-trace/src/bin/rtos_trace.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::future::poll_fn; 4use core::future::poll_fn;
6use core::task::Poll; 5use core::task::Poll;
diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml
new file mode 100644
index 000000000..1671f5db1
--- /dev/null
+++ b/examples/nrf51/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace nRF51422_xxAA with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip nRF51422_xxAA"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml
new file mode 100644
index 000000000..06c3d20cb
--- /dev/null
+++ b/examples/nrf51/Cargo.toml
@@ -0,0 +1,20 @@
1[package]
2edition = "2021"
3name = "embassy-nrf51-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
9embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] }
11
12defmt = "0.3"
13defmt-rtt = "0.4"
14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7"
17panic-probe = { version = "0.3", features = ["print-defmt"] }
18
19[profile.release]
20debug = 2
diff --git a/examples/nrf51/build.rs b/examples/nrf51/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/nrf51/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/nrf51/memory.x b/examples/nrf51/memory.x
new file mode 100644
index 000000000..98b3c792f
--- /dev/null
+++ b/examples/nrf51/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 128K
4 RAM : ORIGIN = 0x20000000, LENGTH = 16K
5}
diff --git a/examples/nrf51/src/bin/blinky.rs b/examples/nrf51/src/bin/blinky.rs
new file mode 100644
index 000000000..7c12ffcbc
--- /dev/null
+++ b/examples/nrf51/src/bin/blinky.rs
@@ -0,0 +1,20 @@
1#![no_std]
2#![no_main]
3
4use embassy_executor::Spawner;
5use embassy_nrf::gpio::{Level, Output, OutputDrive};
6use embassy_time::Timer;
7use {defmt_rtt as _, panic_probe as _};
8
9#[embassy_executor::main]
10async fn main(_spawner: Spawner) {
11 let p = embassy_nrf::init(Default::default());
12 let mut led = Output::new(p.P0_21, Level::Low, OutputDrive::Standard);
13
14 loop {
15 led.set_high();
16 Timer::after_millis(300).await;
17 led.set_low();
18 Timer::after_millis(300).await;
19 }
20}
diff --git a/examples/nrf52840-rtic/Cargo.toml b/examples/nrf52840-rtic/Cargo.toml
index f5d49f0a1..d91f58d0e 100644
--- a/examples/nrf52840-rtic/Cargo.toml
+++ b/examples/nrf52840-rtic/Cargo.toml
@@ -9,7 +9,7 @@ rtic = { version = "2", features = ["thumbv7-backend"] }
9 9
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "generic-queue"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = [ "defmt", "defmt-timestamp-uptime", "generic-queue"] }
13embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 13embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
14 14
15defmt = "0.3" 15defmt = "0.3"
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml
index 65cd631f8..4ab5c7b7c 100644
--- a/examples/nrf52840/Cargo.toml
+++ b/examples/nrf52840/Cargo.toml
@@ -4,19 +4,13 @@ name = "embassy-nrf52840-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[features]
8default = ["nightly"]
9nightly = [
10 "static_cell/nightly",
11]
12
13[dependencies] 7[dependencies]
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 8embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
16embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 10embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
17embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
18embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 12embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
19embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
20embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
21embedded-io = { version = "0.6.0", features = ["defmt-03"] } 15embedded-io = { version = "0.6.0", features = ["defmt-03"] }
22embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 16embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
@@ -34,11 +28,11 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
34futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 28futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
35rand = { version = "0.8.4", default-features = false } 29rand = { version = "0.8.4", default-features = false }
36embedded-storage = "0.3.1" 30embedded-storage = "0.3.1"
37usbd-hid = "0.6.0" 31usbd-hid = "0.7.0"
38serde = { version = "1.0.136", default-features = false } 32serde = { version = "1.0.136", default-features = false }
39embedded-hal = { version = "1.0.0-rc.2" } 33embedded-hal = { version = "1.0" }
40embedded-hal-async = { version = "1.0.0-rc.2" } 34embedded-hal-async = { version = "1.0" }
41embedded-hal-bus = { version = "0.1.0-rc.2", features = ["async"] } 35embedded-hal-bus = { version = "0.1", features = ["async"] }
42num-integer = { version = "0.1.45", default-features = false } 36num-integer = { version = "0.1.45", default-features = false }
43microfft = "0.5.0" 37microfft = "0.5.0"
44 38
diff --git a/examples/nrf52840/src/bin/blinky.rs b/examples/nrf52840/src/bin/blinky.rs
index d3d1a7122..58a3d2cd9 100644
--- a/examples/nrf52840/src/bin/blinky.rs
+++ b/examples/nrf52840/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use embassy_executor::Spawner; 4use embassy_executor::Spawner;
6use embassy_nrf::gpio::{Level, Output, OutputDrive}; 5use embassy_nrf::gpio::{Level, Output, OutputDrive};
diff --git a/examples/nrf52840/src/bin/buffered_uart.rs b/examples/nrf52840/src/bin/buffered_uart.rs
index d9c505786..6ac72bcaf 100644
--- a/examples/nrf52840/src/bin/buffered_uart.rs
+++ b/examples/nrf52840/src/bin/buffered_uart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/channel.rs b/examples/nrf52840/src/bin/channel.rs
index d3c7b47d2..7fcea9dbd 100644
--- a/examples/nrf52840/src/bin/channel.rs
+++ b/examples/nrf52840/src/bin/channel.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::unwrap; 4use defmt::unwrap;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs
index 79d2c4048..3095a04ec 100644
--- a/examples/nrf52840/src/bin/channel_sender_receiver.rs
+++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::unwrap; 4use defmt::unwrap;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/ethernet_enc28j60.rs b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
index d1b796fab..279f32edc 100644
--- a/examples/nrf52840/src/bin/ethernet_enc28j60.rs
+++ b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -14,7 +13,7 @@ use embassy_nrf::{bind_interrupts, peripherals, spim};
14use embassy_time::Delay; 13use embassy_time::Delay;
15use embedded_hal_bus::spi::ExclusiveDevice; 14use embedded_hal_bus::spi::ExclusiveDevice;
16use embedded_io_async::Write; 15use embedded_io_async::Write;
17use static_cell::make_static; 16use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
20bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -25,10 +24,7 @@ bind_interrupts!(struct Irqs {
25#[embassy_executor::task] 24#[embassy_executor::task]
26async fn net_task( 25async fn net_task(
27 stack: &'static Stack< 26 stack: &'static Stack<
28 Enc28j60< 27 Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>,
29 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>,
30 Output<'static, peripherals::P0_13>,
31 >,
32 >, 28 >,
33) -> ! { 29) -> ! {
34 stack.run().await 30 stack.run().await
@@ -70,11 +66,15 @@ async fn main(spawner: Spawner) {
70 let seed = u64::from_le_bytes(seed); 66 let seed = u64::from_le_bytes(seed);
71 67
72 // Init network stack 68 // Init network stack
73 let stack = &*make_static!(Stack::new( 69 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
70 static STACK: StaticCell<
71 Stack<Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>>,
72 > = StaticCell::new();
73 let stack = STACK.init(Stack::new(
74 device, 74 device,
75 config, 75 config,
76 make_static!(StackResources::<2>::new()), 76 RESOURCES.init(StackResources::<2>::new()),
77 seed 77 seed,
78 )); 78 ));
79 79
80 unwrap!(spawner.spawn(net_task(stack))); 80 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/nrf52840/src/bin/executor_fairness_test.rs b/examples/nrf52840/src/bin/executor_fairness_test.rs
index f111b272e..df6e7af3f 100644
--- a/examples/nrf52840/src/bin/executor_fairness_test.rs
+++ b/examples/nrf52840/src/bin/executor_fairness_test.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::future::poll_fn; 4use core::future::poll_fn;
6use core::task::Poll; 5use core::task::Poll;
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs
index 5bfd02465..e254d613d 100644
--- a/examples/nrf52840/src/bin/gpiote_channel.rs
+++ b/examples/nrf52840/src/bin/gpiote_channel.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/gpiote_port.rs b/examples/nrf52840/src/bin/gpiote_port.rs
index 0155d539e..0dddb1a97 100644
--- a/examples/nrf52840/src/bin/gpiote_port.rs
+++ b/examples/nrf52840/src/bin/gpiote_port.rs
@@ -1,14 +1,13 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; 6use embassy_nrf::gpio::{Input, Pull};
8use {defmt_rtt as _, panic_probe as _}; 7use {defmt_rtt as _, panic_probe as _};
9 8
10#[embassy_executor::task(pool_size = 4)] 9#[embassy_executor::task(pool_size = 4)]
11async fn button_task(n: usize, mut pin: Input<'static, AnyPin>) { 10async fn button_task(n: usize, mut pin: Input<'static>) {
12 loop { 11 loop {
13 pin.wait_for_low().await; 12 pin.wait_for_low().await;
14 info!("Button {:?} pressed!", n); 13 info!("Button {:?} pressed!", n);
@@ -22,10 +21,10 @@ async fn main(spawner: Spawner) {
22 let p = embassy_nrf::init(Default::default()); 21 let p = embassy_nrf::init(Default::default());
23 info!("Starting!"); 22 info!("Starting!");
24 23
25 let btn1 = Input::new(p.P0_11.degrade(), Pull::Up); 24 let btn1 = Input::new(p.P0_11, Pull::Up);
26 let btn2 = Input::new(p.P0_12.degrade(), Pull::Up); 25 let btn2 = Input::new(p.P0_12, Pull::Up);
27 let btn3 = Input::new(p.P0_24.degrade(), Pull::Up); 26 let btn3 = Input::new(p.P0_24, Pull::Up);
28 let btn4 = Input::new(p.P0_25.degrade(), Pull::Up); 27 let btn4 = Input::new(p.P0_25, Pull::Up);
29 28
30 unwrap!(spawner.spawn(button_task(1, btn1))); 29 unwrap!(spawner.spawn(button_task(1, btn1)));
31 unwrap!(spawner.spawn(button_task(2, btn2))); 30 unwrap!(spawner.spawn(button_task(2, btn2)));
diff --git a/examples/nrf52840/src/bin/i2s_effect.rs b/examples/nrf52840/src/bin/i2s_effect.rs
index 391514d93..9eadeb4e4 100644
--- a/examples/nrf52840/src/bin/i2s_effect.rs
+++ b/examples/nrf52840/src/bin/i2s_effect.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::f32::consts::PI; 4use core::f32::consts::PI;
6 5
diff --git a/examples/nrf52840/src/bin/i2s_monitor.rs b/examples/nrf52840/src/bin/i2s_monitor.rs
index 4ed597c0d..799be351f 100644
--- a/examples/nrf52840/src/bin/i2s_monitor.rs
+++ b/examples/nrf52840/src/bin/i2s_monitor.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{debug, error, info}; 4use defmt::{debug, error, info};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/i2s_waveform.rs b/examples/nrf52840/src/bin/i2s_waveform.rs
index f2c1166b1..137d82840 100644
--- a/examples/nrf52840/src/bin/i2s_waveform.rs
+++ b/examples/nrf52840/src/bin/i2s_waveform.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::f32::consts::PI; 4use core::f32::consts::PI;
6 5
diff --git a/examples/nrf52840/src/bin/manually_create_executor.rs b/examples/nrf52840/src/bin/manually_create_executor.rs
index 80364d34a..7ca39348e 100644
--- a/examples/nrf52840/src/bin/manually_create_executor.rs
+++ b/examples/nrf52840/src/bin/manually_create_executor.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7 6
8use cortex_m_rt::entry; 7use cortex_m_rt::entry;
9use defmt::{info, unwrap}; 8use defmt::{info, unwrap};
diff --git a/examples/nrf52840/src/bin/multiprio.rs b/examples/nrf52840/src/bin/multiprio.rs
index 352f62bf2..b634d8569 100644
--- a/examples/nrf52840/src/bin/multiprio.rs
+++ b/examples/nrf52840/src/bin/multiprio.rs
@@ -55,7 +55,6 @@
55 55
56#![no_std] 56#![no_std]
57#![no_main] 57#![no_main]
58#![feature(type_alias_impl_trait)]
59 58
60use cortex_m_rt::entry; 59use cortex_m_rt::entry;
61use defmt::{info, unwrap}; 60use defmt::{info, unwrap};
diff --git a/examples/nrf52840/src/bin/mutex.rs b/examples/nrf52840/src/bin/mutex.rs
index 11b47d991..5c22279b5 100644
--- a/examples/nrf52840/src/bin/mutex.rs
+++ b/examples/nrf52840/src/bin/mutex.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/nvmc.rs b/examples/nrf52840/src/bin/nvmc.rs
index 624829863..a79385b98 100644
--- a/examples/nrf52840/src/bin/nvmc.rs
+++ b/examples/nrf52840/src/bin/nvmc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pdm.rs b/examples/nrf52840/src/bin/pdm.rs
index bff323974..52dadc805 100644
--- a/examples/nrf52840/src/bin/pdm.rs
+++ b/examples/nrf52840/src/bin/pdm.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pdm_continuous.rs b/examples/nrf52840/src/bin/pdm_continuous.rs
index 7d8531475..e948203a5 100644
--- a/examples/nrf52840/src/bin/pdm_continuous.rs
+++ b/examples/nrf52840/src/bin/pdm_continuous.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::cmp::Ordering; 4use core::cmp::Ordering;
6 5
diff --git a/examples/nrf52840/src/bin/ppi.rs b/examples/nrf52840/src/bin/ppi.rs
index d74ce4064..129ad06e7 100644
--- a/examples/nrf52840/src/bin/ppi.rs
+++ b/examples/nrf52840/src/bin/ppi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::future::pending; 4use core::future::pending;
6 5
diff --git a/examples/nrf52840/src/bin/pubsub.rs b/examples/nrf52840/src/bin/pubsub.rs
index 17d902227..5ebea9220 100644
--- a/examples/nrf52840/src/bin/pubsub.rs
+++ b/examples/nrf52840/src/bin/pubsub.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::unwrap; 4use defmt::unwrap;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pwm.rs b/examples/nrf52840/src/bin/pwm.rs
index 9750935c8..a5bb1347a 100644
--- a/examples/nrf52840/src/bin/pwm.rs
+++ b/examples/nrf52840/src/bin/pwm.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pwm_double_sequence.rs b/examples/nrf52840/src/bin/pwm_double_sequence.rs
index 1bfe6e15a..386c483b8 100644
--- a/examples/nrf52840/src/bin/pwm_double_sequence.rs
+++ b/examples/nrf52840/src/bin/pwm_double_sequence.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pwm_sequence.rs b/examples/nrf52840/src/bin/pwm_sequence.rs
index f282cf910..87eda265f 100644
--- a/examples/nrf52840/src/bin/pwm_sequence.rs
+++ b/examples/nrf52840/src/bin/pwm_sequence.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
index 6594fa348..60ea712b5 100644
--- a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
+++ b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::future::pending; 4use core::future::pending;
6 5
diff --git a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs
index 8596e6545..751cf4425 100644
--- a/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs
+++ b/examples/nrf52840/src/bin/pwm_sequence_ws2812b.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/pwm_servo.rs b/examples/nrf52840/src/bin/pwm_servo.rs
index 92ded1f88..d772d2f5d 100644
--- a/examples/nrf52840/src/bin/pwm_servo.rs
+++ b/examples/nrf52840/src/bin/pwm_servo.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/qdec.rs b/examples/nrf52840/src/bin/qdec.rs
index 59783d312..ea849be63 100644
--- a/examples/nrf52840/src/bin/qdec.rs
+++ b/examples/nrf52840/src/bin/qdec.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/qspi.rs b/examples/nrf52840/src/bin/qspi.rs
index 9e8a01f4e..4539dd0e3 100644
--- a/examples/nrf52840/src/bin/qspi.rs
+++ b/examples/nrf52840/src/bin/qspi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{assert_eq, info, unwrap}; 4use defmt::{assert_eq, info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/qspi_lowpower.rs b/examples/nrf52840/src/bin/qspi_lowpower.rs
index 42b5454e0..516c9b481 100644
--- a/examples/nrf52840/src/bin/qspi_lowpower.rs
+++ b/examples/nrf52840/src/bin/qspi_lowpower.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
diff --git a/examples/nrf52840/src/bin/rng.rs b/examples/nrf52840/src/bin/rng.rs
index 855743f50..326054c9a 100644
--- a/examples/nrf52840/src/bin/rng.rs
+++ b/examples/nrf52840/src/bin/rng.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use embassy_executor::Spawner; 4use embassy_executor::Spawner;
6use embassy_nrf::rng::Rng; 5use embassy_nrf::rng::Rng;
diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs
index d651834f5..653b7d606 100644
--- a/examples/nrf52840/src/bin/saadc.rs
+++ b/examples/nrf52840/src/bin/saadc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs
index a5f8a4dd7..f76fa3570 100644
--- a/examples/nrf52840/src/bin/saadc_continuous.rs
+++ b/examples/nrf52840/src/bin/saadc_continuous.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/self_spawn.rs b/examples/nrf52840/src/bin/self_spawn.rs
index 8a58396a4..5bfefc2af 100644
--- a/examples/nrf52840/src/bin/self_spawn.rs
+++ b/examples/nrf52840/src/bin/self_spawn.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/self_spawn_current_executor.rs b/examples/nrf52840/src/bin/self_spawn_current_executor.rs
index 65d50f8c3..ec9569a64 100644
--- a/examples/nrf52840/src/bin/self_spawn_current_executor.rs
+++ b/examples/nrf52840/src/bin/self_spawn_current_executor.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/spim.rs b/examples/nrf52840/src/bin/spim.rs
index 9d1843a8f..131187660 100644
--- a/examples/nrf52840/src/bin/spim.rs
+++ b/examples/nrf52840/src/bin/spim.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/spis.rs b/examples/nrf52840/src/bin/spis.rs
index 77b6e8b64..613cd37ab 100644
--- a/examples/nrf52840/src/bin/spis.rs
+++ b/examples/nrf52840/src/bin/spis.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/temp.rs b/examples/nrf52840/src/bin/temp.rs
index d94dea38d..1d28f8ecf 100644
--- a/examples/nrf52840/src/bin/temp.rs
+++ b/examples/nrf52840/src/bin/temp.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/timer.rs b/examples/nrf52840/src/bin/timer.rs
index 9b9bb3eb4..365695a20 100644
--- a/examples/nrf52840/src/bin/timer.rs
+++ b/examples/nrf52840/src/bin/timer.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/twim.rs b/examples/nrf52840/src/bin/twim.rs
index 959e3a4be..a9a0765e8 100644
--- a/examples/nrf52840/src/bin/twim.rs
+++ b/examples/nrf52840/src/bin/twim.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/twim_lowpower.rs b/examples/nrf52840/src/bin/twim_lowpower.rs
index bf9f966ef..c743614b8 100644
--- a/examples/nrf52840/src/bin/twim_lowpower.rs
+++ b/examples/nrf52840/src/bin/twim_lowpower.rs
@@ -6,7 +6,6 @@
6 6
7#![no_std] 7#![no_std]
8#![no_main] 8#![no_main]
9#![feature(type_alias_impl_trait)]
10 9
11use core::mem; 10use core::mem;
12 11
diff --git a/examples/nrf52840/src/bin/twis.rs b/examples/nrf52840/src/bin/twis.rs
index aa42b679e..88bd4cceb 100644
--- a/examples/nrf52840/src/bin/twis.rs
+++ b/examples/nrf52840/src/bin/twis.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use defmt::*; 6use defmt::*;
8use embassy_executor::Spawner; 7use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/uart.rs b/examples/nrf52840/src/bin/uart.rs
index 50d5cab8c..accaccea1 100644
--- a/examples/nrf52840/src/bin/uart.rs
+++ b/examples/nrf52840/src/bin/uart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/uart_idle.rs b/examples/nrf52840/src/bin/uart_idle.rs
index e1f42fa6c..fa93bcf21 100644
--- a/examples/nrf52840/src/bin/uart_idle.rs
+++ b/examples/nrf52840/src/bin/uart_idle.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/uart_split.rs b/examples/nrf52840/src/bin/uart_split.rs
index b748bfcd8..c7510a9a8 100644
--- a/examples/nrf52840/src/bin/uart_split.rs
+++ b/examples/nrf52840/src/bin/uart_split.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs
index b7806f418..a7e5c2668 100644
--- a/examples/nrf52840/src/bin/usb_ethernet.rs
+++ b/examples/nrf52840/src/bin/usb_ethernet.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
@@ -16,7 +15,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState
16use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 15use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
17use embassy_usb::{Builder, Config, UsbDevice}; 16use embassy_usb::{Builder, Config, UsbDevice};
18use embedded_io_async::Write; 17use embedded_io_async::Write;
19use static_cell::make_static; 18use static_cell::StaticCell;
20use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
21 20
22bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
@@ -71,14 +70,17 @@ async fn main(spawner: Spawner) {
71 config.device_protocol = 0x01; 70 config.device_protocol = 0x01;
72 71
73 // Create embassy-usb DeviceBuilder using the driver and config. 72 // Create embassy-usb DeviceBuilder using the driver and config.
73 static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
74 static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
75 static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
76 static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
74 let mut builder = Builder::new( 77 let mut builder = Builder::new(
75 driver, 78 driver,
76 config, 79 config,
77 &mut make_static!([0; 256])[..], 80 &mut CONFIG_DESC.init([0; 256])[..],
78 &mut make_static!([0; 256])[..], 81 &mut BOS_DESC.init([0; 256])[..],
79 &mut make_static!([0; 256])[..], 82 &mut MSOS_DESC.init([0; 128])[..],
80 &mut make_static!([0; 128])[..], 83 &mut CONTROL_BUF.init([0; 128])[..],
81 &mut make_static!([0; 128])[..],
82 ); 84 );
83 85
84 // Our MAC addr. 86 // Our MAC addr.
@@ -87,14 +89,16 @@ async fn main(spawner: Spawner) {
87 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; 89 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88];
88 90
89 // Create classes on the builder. 91 // Create classes on the builder.
90 let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); 92 static STATE: StaticCell<State> = StaticCell::new();
93 let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64);
91 94
92 // Build the builder. 95 // Build the builder.
93 let usb = builder.build(); 96 let usb = builder.build();
94 97
95 unwrap!(spawner.spawn(usb_task(usb))); 98 unwrap!(spawner.spawn(usb_task(usb)));
96 99
97 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); 100 static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
101 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
98 unwrap!(spawner.spawn(usb_ncm_task(runner))); 102 unwrap!(spawner.spawn(usb_ncm_task(runner)));
99 103
100 let config = embassy_net::Config::dhcpv4(Default::default()); 104 let config = embassy_net::Config::dhcpv4(Default::default());
@@ -111,12 +115,9 @@ async fn main(spawner: Spawner) {
111 let seed = u64::from_le_bytes(seed); 115 let seed = u64::from_le_bytes(seed);
112 116
113 // Init network stack 117 // Init network stack
114 let stack = &*make_static!(Stack::new( 118 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
115 device, 119 static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
116 config, 120 let stack = &*STACK.init(Stack::new(device, config, RESOURCES.init(StackResources::new()), seed));
117 make_static!(StackResources::<2>::new()),
118 seed
119 ));
120 121
121 unwrap!(spawner.spawn(net_task(stack))); 122 unwrap!(spawner.spawn(net_task(stack)));
122 123
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
index 7ccd2946a..52f081487 100644
--- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6use core::sync::atomic::{AtomicBool, Ordering}; 5use core::sync::atomic::{AtomicBool, Ordering};
@@ -9,7 +8,7 @@ use defmt::*;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_futures::join::join; 9use embassy_futures::join::join;
11use embassy_futures::select::{select, Either}; 10use embassy_futures::select::{select, Either};
12use embassy_nrf::gpio::{Input, Pin, Pull}; 11use embassy_nrf::gpio::{Input, Pull};
13use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; 12use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
14use embassy_nrf::usb::Driver; 13use embassy_nrf::usb::Driver;
15use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; 14use embassy_nrf::{bind_interrupts, pac, peripherals, usb};
@@ -51,7 +50,6 @@ async fn main(_spawner: Spawner) {
51 50
52 // Create embassy-usb DeviceBuilder using the driver and config. 51 // Create embassy-usb DeviceBuilder using the driver and config.
53 // It needs some buffers for building the descriptors. 52 // It needs some buffers for building the descriptors.
54 let mut device_descriptor = [0; 256];
55 let mut config_descriptor = [0; 256]; 53 let mut config_descriptor = [0; 256];
56 let mut bos_descriptor = [0; 256]; 54 let mut bos_descriptor = [0; 256];
57 let mut msos_descriptor = [0; 256]; 55 let mut msos_descriptor = [0; 256];
@@ -64,7 +62,6 @@ async fn main(_spawner: Spawner) {
64 let mut builder = Builder::new( 62 let mut builder = Builder::new(
65 driver, 63 driver,
66 config, 64 config,
67 &mut device_descriptor,
68 &mut config_descriptor, 65 &mut config_descriptor,
69 &mut bos_descriptor, 66 &mut bos_descriptor,
70 &mut msos_descriptor, 67 &mut msos_descriptor,
@@ -98,7 +95,7 @@ async fn main(_spawner: Spawner) {
98 } 95 }
99 }; 96 };
100 97
101 let mut button = Input::new(p.P0_11.degrade(), Pull::Up); 98 let mut button = Input::new(p.P0_11, Pull::Up);
102 99
103 let (reader, mut writer) = hid.split(); 100 let (reader, mut writer) = hid.split();
104 101
diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs
index 96fcf8a66..5d2837793 100644
--- a/examples/nrf52840/src/bin/usb_hid_mouse.rs
+++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
@@ -44,7 +43,6 @@ async fn main(_spawner: Spawner) {
44 43
45 // Create embassy-usb DeviceBuilder using the driver and config. 44 // Create embassy-usb DeviceBuilder using the driver and config.
46 // It needs some buffers for building the descriptors. 45 // It needs some buffers for building the descriptors.
47 let mut device_descriptor = [0; 256];
48 let mut config_descriptor = [0; 256]; 46 let mut config_descriptor = [0; 256];
49 let mut bos_descriptor = [0; 256]; 47 let mut bos_descriptor = [0; 256];
50 let mut msos_descriptor = [0; 256]; 48 let mut msos_descriptor = [0; 256];
@@ -56,7 +54,6 @@ async fn main(_spawner: Spawner) {
56 let mut builder = Builder::new( 54 let mut builder = Builder::new(
57 driver, 55 driver,
58 config, 56 config,
59 &mut device_descriptor,
60 &mut config_descriptor, 57 &mut config_descriptor,
61 &mut bos_descriptor, 58 &mut bos_descriptor,
62 &mut msos_descriptor, 59 &mut msos_descriptor,
diff --git a/examples/nrf52840/src/bin/usb_serial.rs b/examples/nrf52840/src/bin/usb_serial.rs
index dc95cde84..02048e692 100644
--- a/examples/nrf52840/src/bin/usb_serial.rs
+++ b/examples/nrf52840/src/bin/usb_serial.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
@@ -49,7 +48,6 @@ async fn main(_spawner: Spawner) {
49 48
50 // Create embassy-usb DeviceBuilder using the driver and config. 49 // Create embassy-usb DeviceBuilder using the driver and config.
51 // It needs some buffers for building the descriptors. 50 // It needs some buffers for building the descriptors.
52 let mut device_descriptor = [0; 256];
53 let mut config_descriptor = [0; 256]; 51 let mut config_descriptor = [0; 256];
54 let mut bos_descriptor = [0; 256]; 52 let mut bos_descriptor = [0; 256];
55 let mut msos_descriptor = [0; 256]; 53 let mut msos_descriptor = [0; 256];
@@ -60,7 +58,6 @@ async fn main(_spawner: Spawner) {
60 let mut builder = Builder::new( 58 let mut builder = Builder::new(
61 driver, 59 driver,
62 config, 60 config,
63 &mut device_descriptor,
64 &mut config_descriptor, 61 &mut config_descriptor,
65 &mut bos_descriptor, 62 &mut bos_descriptor,
66 &mut msos_descriptor, 63 &mut msos_descriptor,
diff --git a/examples/nrf52840/src/bin/usb_serial_multitask.rs b/examples/nrf52840/src/bin/usb_serial_multitask.rs
index cd4392903..895cca8b9 100644
--- a/examples/nrf52840/src/bin/usb_serial_multitask.rs
+++ b/examples/nrf52840/src/bin/usb_serial_multitask.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
@@ -12,7 +11,7 @@ use embassy_nrf::{bind_interrupts, pac, peripherals, usb};
12use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 11use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
13use embassy_usb::driver::EndpointError; 12use embassy_usb::driver::EndpointError;
14use embassy_usb::{Builder, Config, UsbDevice}; 13use embassy_usb::{Builder, Config, UsbDevice};
15use static_cell::make_static; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
18bind_interrupts!(struct Irqs { 17bind_interrupts!(struct Irqs {
@@ -64,17 +63,21 @@ async fn main(spawner: Spawner) {
64 config.device_protocol = 0x01; 63 config.device_protocol = 0x01;
65 config.composite_with_iads = true; 64 config.composite_with_iads = true;
66 65
67 let state = make_static!(State::new()); 66 static STATE: StaticCell<State> = StaticCell::new();
67 let state = STATE.init(State::new());
68 68
69 // Create embassy-usb DeviceBuilder using the driver and config. 69 // Create embassy-usb DeviceBuilder using the driver and config.
70 static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
71 static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
72 static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
73 static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
70 let mut builder = Builder::new( 74 let mut builder = Builder::new(
71 driver, 75 driver,
72 config, 76 config,
73 &mut make_static!([0; 256])[..], 77 &mut CONFIG_DESC.init([0; 256])[..],
74 &mut make_static!([0; 256])[..], 78 &mut BOS_DESC.init([0; 256])[..],
75 &mut make_static!([0; 256])[..], 79 &mut MSOS_DESC.init([0; 128])[..],
76 &mut make_static!([0; 128])[..], 80 &mut CONTROL_BUF.init([0; 128])[..],
77 &mut make_static!([0; 128])[..],
78 ); 81 );
79 82
80 // Create classes on the builder. 83 // Create classes on the builder.
diff --git a/examples/nrf52840/src/bin/usb_serial_winusb.rs b/examples/nrf52840/src/bin/usb_serial_winusb.rs
index 1d39d3841..c6675a3d3 100644
--- a/examples/nrf52840/src/bin/usb_serial_winusb.rs
+++ b/examples/nrf52840/src/bin/usb_serial_winusb.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::mem; 4use core::mem;
6 5
@@ -54,7 +53,6 @@ async fn main(_spawner: Spawner) {
54 53
55 // Create embassy-usb DeviceBuilder using the driver and config. 54 // Create embassy-usb DeviceBuilder using the driver and config.
56 // It needs some buffers for building the descriptors. 55 // It needs some buffers for building the descriptors.
57 let mut device_descriptor = [0; 256];
58 let mut config_descriptor = [0; 256]; 56 let mut config_descriptor = [0; 256];
59 let mut bos_descriptor = [0; 256]; 57 let mut bos_descriptor = [0; 256];
60 let mut msos_descriptor = [0; 256]; 58 let mut msos_descriptor = [0; 256];
@@ -65,7 +63,6 @@ async fn main(_spawner: Spawner) {
65 let mut builder = Builder::new( 63 let mut builder = Builder::new(
66 driver, 64 driver,
67 config, 65 config,
68 &mut device_descriptor,
69 &mut config_descriptor, 66 &mut config_descriptor,
70 &mut bos_descriptor, 67 &mut bos_descriptor,
71 &mut msos_descriptor, 68 &mut msos_descriptor,
diff --git a/examples/nrf52840/src/bin/wdt.rs b/examples/nrf52840/src/bin/wdt.rs
index 058746518..ede88cc26 100644
--- a/examples/nrf52840/src/bin/wdt.rs
+++ b/examples/nrf52840/src/bin/wdt.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
index a60822fd9..00bd50081 100644
--- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs
+++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
@@ -1,19 +1,18 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap, warn}; 4use defmt::{info, unwrap, warn};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_net::tcp::TcpSocket; 6use embassy_net::tcp::TcpSocket;
8use embassy_net::{Stack, StackResources}; 7use embassy_net::{Stack, StackResources};
9use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; 8use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
10use embassy_nrf::rng::Rng; 9use embassy_nrf::rng::Rng;
11use embassy_nrf::spim::{self, Spim}; 10use embassy_nrf::spim::{self, Spim};
12use embassy_nrf::{bind_interrupts, peripherals}; 11use embassy_nrf::{bind_interrupts, peripherals};
13use embassy_time::Delay; 12use embassy_time::Delay;
14use embedded_hal_bus::spi::ExclusiveDevice; 13use embedded_hal_bus::spi::ExclusiveDevice;
15use embedded_io_async::Write; 14use embedded_io_async::Write;
16use static_cell::make_static; 15use static_cell::StaticCell;
17use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; 16use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _};
18 17
19const WIFI_NETWORK: &str = "EmbassyTest"; 18const WIFI_NETWORK: &str = "EmbassyTest";
@@ -28,9 +27,9 @@ bind_interrupts!(struct Irqs {
28async fn wifi_task( 27async fn wifi_task(
29 runner: hosted::Runner< 28 runner: hosted::Runner<
30 'static, 29 'static,
31 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_31>, Delay>, 30 ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>,
32 Input<'static, AnyPin>, 31 Input<'static>,
33 Output<'static, peripherals::P1_05>, 32 Output<'static>,
34 >, 33 >,
35) -> ! { 34) -> ! {
36 runner.run().await 35 runner.run().await
@@ -51,8 +50,8 @@ async fn main(spawner: Spawner) {
51 let sck = p.P0_29; 50 let sck = p.P0_29;
52 let mosi = p.P0_30; 51 let mosi = p.P0_30;
53 let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive); 52 let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive);
54 let handshake = Input::new(p.P1_01.degrade(), Pull::Up); 53 let handshake = Input::new(p.P1_01, Pull::Up);
55 let ready = Input::new(p.P1_04.degrade(), Pull::None); 54 let ready = Input::new(p.P1_04, Pull::None);
56 let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); 55 let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard);
57 56
58 let mut config = spim::Config::default(); 57 let mut config = spim::Config::default();
@@ -61,8 +60,9 @@ async fn main(spawner: Spawner) {
61 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); 60 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config);
62 let spi = ExclusiveDevice::new(spi, cs, Delay); 61 let spi = ExclusiveDevice::new(spi, cs, Delay);
63 62
63 static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new();
64 let (device, mut control, runner) = embassy_net_esp_hosted::new( 64 let (device, mut control, runner) = embassy_net_esp_hosted::new(
65 make_static!(embassy_net_esp_hosted::State::new()), 65 ESP_STATE.init(embassy_net_esp_hosted::State::new()),
66 spi, 66 spi,
67 handshake, 67 handshake,
68 ready, 68 ready,
@@ -89,11 +89,13 @@ async fn main(spawner: Spawner) {
89 let seed = u64::from_le_bytes(seed); 89 let seed = u64::from_le_bytes(seed);
90 90
91 // Init network stack 91 // Init network stack
92 let stack = &*make_static!(Stack::new( 92 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
93 static STACK: StaticCell<Stack<hosted::NetDriver<'static>>> = StaticCell::new();
94 let stack = &*STACK.init(Stack::new(
93 device, 95 device,
94 config, 96 config,
95 make_static!(StackResources::<2>::new()), 97 RESOURCES.init(StackResources::<2>::new()),
96 seed 98 seed,
97 )); 99 ));
98 100
99 unwrap!(spawner.spawn(net_task(stack))); 101 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml
index 17d3e30e4..24aa560d5 100644
--- a/examples/nrf5340/Cargo.toml
+++ b/examples/nrf5340/Cargo.toml
@@ -7,24 +7,24 @@ 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.5.0", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "defmt", "integrated-timers"] } 10embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
11embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] } 12embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf5340-app-s", "time-driver-rtc1", "gpiote", "unstable-pac"] }
13embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15embedded-io-async = { version = "0.6.1" } 15embedded-io-async = { version = "0.6.1" }
16 16
17defmt = "0.3" 17defmt = "0.3"
18defmt-rtt = "0.4" 18defmt-rtt = "0.4"
19 19
20static_cell = { version = "2", features = ["nightly"]} 20static_cell = "2"
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
23panic-probe = { version = "0.3", features = ["print-defmt"] } 23panic-probe = { version = "0.3", features = ["print-defmt"] }
24futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 24futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
25rand = { version = "0.8.4", default-features = false } 25rand = { version = "0.8.4", default-features = false }
26embedded-storage = "0.3.1" 26embedded-storage = "0.3.1"
27usbd-hid = "0.6.0" 27usbd-hid = "0.7.0"
28serde = { version = "1.0.136", default-features = false } 28serde = { version = "1.0.136", default-features = false }
29 29
30[profile.release] 30[profile.release]
diff --git a/examples/nrf5340/src/bin/blinky.rs b/examples/nrf5340/src/bin/blinky.rs
index b784564a5..5c533c9b1 100644
--- a/examples/nrf5340/src/bin/blinky.rs
+++ b/examples/nrf5340/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use embassy_executor::Spawner; 4use embassy_executor::Spawner;
6use embassy_nrf::gpio::{Level, Output, OutputDrive}; 5use embassy_nrf::gpio::{Level, Output, OutputDrive};
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs
index ceab1194a..c0a55142f 100644
--- a/examples/nrf5340/src/bin/gpiote_channel.rs
+++ b/examples/nrf5340/src/bin/gpiote_channel.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf5340/src/bin/uart.rs b/examples/nrf5340/src/bin/uart.rs
index d68539702..7b41d7463 100644
--- a/examples/nrf5340/src/bin/uart.rs
+++ b/examples/nrf5340/src/bin/uart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/nrf9160/.cargo/config.toml b/examples/nrf9160/.cargo/config.toml
new file mode 100644
index 000000000..1444b0cd1
--- /dev/null
+++ b/examples/nrf9160/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip nRF9160_xxAA"
4
5[build]
6target = "thumbv8m.main-none-eabihf"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml
new file mode 100644
index 000000000..af2385960
--- /dev/null
+++ b/examples/nrf9160/Cargo.toml
@@ -0,0 +1,20 @@
1[package]
2edition = "2021"
3name = "embassy-nrf9160-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
9embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf9160-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
11
12defmt = "0.3"
13defmt-rtt = "0.4"
14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7.0"
17panic-probe = { version = "0.3", features = ["print-defmt"] }
18
19[profile.release]
20debug = 2
diff --git a/examples/nrf9160/build.rs b/examples/nrf9160/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/nrf9160/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/nrf9160/memory.x b/examples/nrf9160/memory.x
new file mode 100644
index 000000000..4c7d4ebf0
--- /dev/null
+++ b/examples/nrf9160/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 1024K
4 RAM : ORIGIN = 0x20018000, LENGTH = 160K
5}
diff --git a/examples/nrf9160/src/bin/blinky.rs b/examples/nrf9160/src/bin/blinky.rs
new file mode 100644
index 000000000..7ac5c31e1
--- /dev/null
+++ b/examples/nrf9160/src/bin/blinky.rs
@@ -0,0 +1,20 @@
1#![no_std]
2#![no_main]
3
4use embassy_executor::Spawner;
5use embassy_nrf::gpio::{Level, Output, OutputDrive};
6use embassy_time::Timer;
7use {defmt_rtt as _, panic_probe as _};
8
9#[embassy_executor::main]
10async fn main(_spawner: Spawner) {
11 let p = embassy_nrf::init(Default::default());
12 let mut led = Output::new(p.P0_02, Level::Low, OutputDrive::Standard);
13
14 loop {
15 led.set_high();
16 Timer::after_millis(300).await;
17 led.set_low();
18 Timer::after_millis(300).await;
19 }
20}
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 7f637758d..585349506 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -8,16 +8,16 @@ license = "MIT OR Apache-2.0"
8[dependencies] 8[dependencies]
9embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] } 9embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal", features = ["defmt"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
13embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] } 13embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 15embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
17embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 17embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
18embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } 18embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" }
19cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } 19cyw43 = { version = "0.1.0", path = "../../cyw43", features = ["defmt", "firmware-logs"] }
20cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } 20cyw43-pio = { version = "0.1.0", path = "../../cyw43-pio", features = ["defmt", "overclock"] }
21 21
22defmt = "0.3" 22defmt = "0.3"
23defmt-rtt = "0.4" 23defmt-rtt = "0.4"
@@ -36,14 +36,14 @@ display-interface = "0.4.1"
36byte-slice-cast = { version = "1.2.0", default-features = false } 36byte-slice-cast = { version = "1.2.0", default-features = false }
37smart-leds = "0.3.0" 37smart-leds = "0.3.0"
38heapless = "0.8" 38heapless = "0.8"
39usbd-hid = "0.6.1" 39usbd-hid = "0.7.0"
40 40
41embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } 41embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
42embedded-hal-async = "1.0.0-rc.2" 42embedded-hal-async = "1.0"
43embedded-hal-bus = { version = "0.1.0-rc.2", features = ["async"] } 43embedded-hal-bus = { version = "0.1", features = ["async"] }
44embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 44embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
45embedded-storage = { version = "0.3" } 45embedded-storage = { version = "0.3" }
46static_cell = { version = "2", features = ["nightly"]} 46static_cell = "2"
47portable-atomic = { version = "1.5", features = ["critical-section"] } 47portable-atomic = { version = "1.5", features = ["critical-section"] }
48log = "0.4" 48log = "0.4"
49pio-proc = "0.2" 49pio-proc = "0.2"
diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs
index a579be139..1bb7c2249 100644
--- a/examples/rp/src/bin/adc.rs
+++ b/examples/rp/src/bin/adc.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7 6
8use defmt::*; 7use defmt::*;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/blinky.rs b/examples/rp/src/bin/blinky.rs
index 66c8773fa..60fc45a70 100644
--- a/examples/rp/src/bin/blinky.rs
+++ b/examples/rp/src/bin/blinky.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/blinky_two_channels.rs b/examples/rp/src/bin/blinky_two_channels.rs
new file mode 100644
index 000000000..b2eec2a21
--- /dev/null
+++ b/examples/rp/src/bin/blinky_two_channels.rs
@@ -0,0 +1,50 @@
1#![no_std]
2#![no_main]
3/// This example demonstrates how to access a given pin from more than one embassy task
4/// The on-board LED is toggled by two tasks with slightly different periods, leading to the
5/// apparent duty cycle of the LED increasing, then decreasing, linearly. The phenomenon is similar
6/// to interference and the 'beats' you can hear if you play two frequencies close to one another
7/// [Link explaining it](https://www.physicsclassroom.com/class/sound/Lesson-3/Interference-and-Beats)
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::channel::{Channel, Sender};
13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output};
15use {defmt_rtt as _, panic_probe as _};
16
17enum LedState {
18 Toggle,
19}
20static CHANNEL: Channel<ThreadModeRawMutex, LedState, 64> = Channel::new();
21
22#[embassy_executor::main]
23async fn main(spawner: Spawner) {
24 let p = embassy_rp::init(Default::default());
25 let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High);
26
27 let dt = 100 * 1_000_000;
28 let k = 1.003;
29
30 unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt))));
31 unwrap!(spawner.spawn(toggle_led(
32 CHANNEL.sender(),
33 Duration::from_nanos((dt as f64 * k) as u64)
34 )));
35
36 loop {
37 match CHANNEL.receive().await {
38 LedState::Toggle => led.toggle(),
39 }
40 }
41}
42
43#[embassy_executor::task(pool_size = 2)]
44async fn toggle_led(control: Sender<'static, ThreadModeRawMutex, LedState, 64>, delay: Duration) {
45 let mut ticker = Ticker::every(delay);
46 loop {
47 control.send(LedState::Toggle).await;
48 ticker.next().await;
49 }
50}
diff --git a/examples/rp/src/bin/blinky_two_tasks.rs b/examples/rp/src/bin/blinky_two_tasks.rs
new file mode 100644
index 000000000..a57b513d6
--- /dev/null
+++ b/examples/rp/src/bin/blinky_two_tasks.rs
@@ -0,0 +1,49 @@
1#![no_std]
2#![no_main]
3/// This example demonstrates how to access a given pin from more than one embassy task
4/// The on-board LED is toggled by two tasks with slightly different periods, leading to the
5/// apparent duty cycle of the LED increasing, then decreasing, linearly. The phenomenon is similar
6/// to interference and the 'beats' you can hear if you play two frequencies close to one another
7/// [Link explaining it](https://www.physicsclassroom.com/class/sound/Lesson-3/Interference-and-Beats)
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_rp::gpio;
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::mutex::Mutex;
13use embassy_time::{Duration, Ticker};
14use gpio::{AnyPin, Level, Output};
15use {defmt_rtt as _, panic_probe as _};
16
17type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>;
18static LED: LedType = Mutex::new(None);
19
20#[embassy_executor::main]
21async fn main(spawner: Spawner) {
22 let p = embassy_rp::init(Default::default());
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);
25 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the
26 // Mutex is released
27 {
28 *(LED.lock().await) = Some(led);
29 }
30 let dt = 100 * 1_000_000;
31 let k = 1.003;
32
33 unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt))));
34 unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64))));
35}
36
37#[embassy_executor::task(pool_size = 2)]
38async fn toggle_led(led: &'static LedType, delay: Duration) {
39 let mut ticker = Ticker::every(delay);
40 loop {
41 {
42 let mut led_unlocked = led.lock().await;
43 if let Some(pin_ref) = led_unlocked.as_mut() {
44 pin_ref.toggle();
45 }
46 }
47 ticker.next().await;
48 }
49}
diff --git a/examples/rp/src/bin/button.rs b/examples/rp/src/bin/button.rs
index d7aa89410..4ad2ca3b7 100644
--- a/examples/rp/src/bin/button.rs
+++ b/examples/rp/src/bin/button.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_rp::gpio::{Input, Level, Output, Pull}; 9use embassy_rp::gpio::{Input, Level, Output, Pull};
diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs
new file mode 100644
index 000000000..0077f19fc
--- /dev/null
+++ b/examples/rp/src/bin/debounce.rs
@@ -0,0 +1,80 @@
1//! This example shows the ease of debouncing a button with async rust.
2//! Hook up a button or switch between pin 9 and ground.
3
4#![no_std]
5#![no_main]
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::gpio::{Input, Level, Pull};
10use embassy_time::{with_deadline, Duration, Instant, Timer};
11use {defmt_rtt as _, panic_probe as _};
12
13pub struct Debouncer<'a> {
14 input: Input<'a>,
15 debounce: Duration,
16}
17
18impl<'a> Debouncer<'a> {
19 pub fn new(input: Input<'a>, debounce: Duration) -> Self {
20 Self { input, debounce }
21 }
22
23 pub async fn debounce(&mut self) -> Level {
24 loop {
25 let l1 = self.input.get_level();
26
27 self.input.wait_for_any_edge().await;
28
29 Timer::after(self.debounce).await;
30
31 let l2 = self.input.get_level();
32 if l1 != l2 {
33 break l2;
34 }
35 }
36 }
37}
38
39#[embassy_executor::main]
40async fn main(_spawner: Spawner) {
41 let p = embassy_rp::init(Default::default());
42 let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20));
43
44 info!("Debounce Demo");
45
46 loop {
47 // button pressed
48 btn.debounce().await;
49 let start = Instant::now();
50 info!("Button Press");
51
52 match with_deadline(start + Duration::from_secs(1), btn.debounce()).await {
53 // Button Released < 1s
54 Ok(_) => {
55 info!("Button pressed for: {}ms", start.elapsed().as_millis());
56 continue;
57 }
58 // button held for > 1s
59 Err(_) => {
60 info!("Button Held");
61 }
62 }
63
64 match with_deadline(start + Duration::from_secs(5), btn.debounce()).await {
65 // Button released <5s
66 Ok(_) => {
67 info!("Button pressed for: {}ms", start.elapsed().as_millis());
68 continue;
69 }
70 // button held for > >5s
71 Err(_) => {
72 info!("Button Long Held");
73 }
74 }
75
76 // wait for button release before handling another press
77 btn.debounce().await;
78 info!("Button pressed for: {}ms", start.elapsed().as_millis());
79 }
80}
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
index c0fde62ab..bd52cadca 100644
--- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs
+++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -14,13 +13,13 @@ use embassy_net_wiznet::chip::W5500;
14use embassy_net_wiznet::*; 13use embassy_net_wiznet::*;
15use embassy_rp::clocks::RoscRng; 14use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull}; 15use embassy_rp::gpio::{Input, Level, Output, Pull};
17use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; 16use embassy_rp::peripherals::SPI0;
18use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 17use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::{Delay, Duration}; 18use embassy_time::{Delay, Duration};
20use embedded_hal_bus::spi::ExclusiveDevice; 19use embedded_hal_bus::spi::ExclusiveDevice;
21use embedded_io_async::Write; 20use embedded_io_async::Write;
22use rand::RngCore; 21use rand::RngCore;
23use static_cell::make_static; 22use static_cell::StaticCell;
24use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
25 24
26#[embassy_executor::task] 25#[embassy_executor::task]
@@ -28,9 +27,9 @@ async fn ethernet_task(
28 runner: Runner< 27 runner: Runner<
29 'static, 28 'static,
30 W5500, 29 W5500,
31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 30 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
32 Input<'static, PIN_21>, 31 Input<'static>,
33 Output<'static, PIN_20>, 32 Output<'static>,
34 >, 33 >,
35) -> ! { 34) -> ! {
36 runner.run().await 35 runner.run().await
@@ -55,7 +54,8 @@ async fn main(spawner: Spawner) {
55 let w5500_reset = Output::new(p.PIN_20, Level::High); 54 let w5500_reset = Output::new(p.PIN_20, Level::High);
56 55
57 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; 56 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
58 let state = make_static!(State::<8, 8>::new()); 57 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
58 let state = STATE.init(State::<8, 8>::new());
59 let (device, runner) = embassy_net_wiznet::new( 59 let (device, runner) = embassy_net_wiznet::new(
60 mac_addr, 60 mac_addr,
61 state, 61 state,
@@ -70,11 +70,13 @@ async fn main(spawner: Spawner) {
70 let seed = rng.next_u64(); 70 let seed = rng.next_u64();
71 71
72 // Init network stack 72 // Init network stack
73 let stack = &*make_static!(Stack::new( 73 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
74 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
75 let stack = &*STACK.init(Stack::new(
74 device, 76 device,
75 embassy_net::Config::dhcpv4(Default::default()), 77 embassy_net::Config::dhcpv4(Default::default()),
76 make_static!(StackResources::<3>::new()), 78 RESOURCES.init(StackResources::<3>::new()),
77 seed 79 seed,
78 )); 80 ));
79 81
80 // Launch network task 82 // Launch network task
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
index b19362fc1..3e4fbd2e6 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use core::str::FromStr; 8use core::str::FromStr;
10 9
@@ -16,13 +15,13 @@ use embassy_net_wiznet::chip::W5500;
16use embassy_net_wiznet::*; 15use embassy_net_wiznet::*;
17use embassy_rp::clocks::RoscRng; 16use embassy_rp::clocks::RoscRng;
18use embassy_rp::gpio::{Input, Level, Output, Pull}; 17use embassy_rp::gpio::{Input, Level, Output, Pull};
19use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; 18use embassy_rp::peripherals::SPI0;
20use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 19use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
21use embassy_time::{Delay, Duration, Timer}; 20use embassy_time::{Delay, Duration, Timer};
22use embedded_hal_bus::spi::ExclusiveDevice; 21use embedded_hal_bus::spi::ExclusiveDevice;
23use embedded_io_async::Write; 22use embedded_io_async::Write;
24use rand::RngCore; 23use rand::RngCore;
25use static_cell::make_static; 24use static_cell::StaticCell;
26use {defmt_rtt as _, panic_probe as _}; 25use {defmt_rtt as _, panic_probe as _};
27 26
28#[embassy_executor::task] 27#[embassy_executor::task]
@@ -30,9 +29,9 @@ async fn ethernet_task(
30 runner: Runner< 29 runner: Runner<
31 'static, 30 'static,
32 W5500, 31 W5500,
33 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 32 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
34 Input<'static, PIN_21>, 33 Input<'static>,
35 Output<'static, PIN_20>, 34 Output<'static>,
36 >, 35 >,
37) -> ! { 36) -> ! {
38 runner.run().await 37 runner.run().await
@@ -58,7 +57,8 @@ async fn main(spawner: Spawner) {
58 let w5500_reset = Output::new(p.PIN_20, Level::High); 57 let w5500_reset = Output::new(p.PIN_20, Level::High);
59 58
60 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; 59 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
61 let state = make_static!(State::<8, 8>::new()); 60 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
61 let state = STATE.init(State::<8, 8>::new());
62 let (device, runner) = embassy_net_wiznet::new( 62 let (device, runner) = embassy_net_wiznet::new(
63 mac_addr, 63 mac_addr,
64 state, 64 state,
@@ -73,11 +73,13 @@ async fn main(spawner: Spawner) {
73 let seed = rng.next_u64(); 73 let seed = rng.next_u64();
74 74
75 // Init network stack 75 // Init network stack
76 let stack = &*make_static!(Stack::new( 76 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
77 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
78 let stack = &*STACK.init(Stack::new(
77 device, 79 device,
78 embassy_net::Config::dhcpv4(Default::default()), 80 embassy_net::Config::dhcpv4(Default::default()),
79 make_static!(StackResources::<2>::new()), 81 RESOURCES.init(StackResources::<2>::new()),
80 seed 82 seed,
81 )); 83 ));
82 84
83 // Launch network task 85 // Launch network task
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
index c62caed7a..5532851f3 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
@@ -5,7 +5,6 @@
5 5
6#![no_std] 6#![no_std]
7#![no_main] 7#![no_main]
8#![feature(type_alias_impl_trait)]
9 8
10use defmt::*; 9use defmt::*;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
@@ -15,13 +14,13 @@ use embassy_net_wiznet::chip::W5500;
15use embassy_net_wiznet::*; 14use embassy_net_wiznet::*;
16use embassy_rp::clocks::RoscRng; 15use embassy_rp::clocks::RoscRng;
17use embassy_rp::gpio::{Input, Level, Output, Pull}; 16use embassy_rp::gpio::{Input, Level, Output, Pull};
18use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; 17use embassy_rp::peripherals::SPI0;
19use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
20use embassy_time::{Delay, Duration}; 19use embassy_time::{Delay, Duration};
21use embedded_hal_bus::spi::ExclusiveDevice; 20use embedded_hal_bus::spi::ExclusiveDevice;
22use embedded_io_async::Write; 21use embedded_io_async::Write;
23use rand::RngCore; 22use rand::RngCore;
24use static_cell::make_static; 23use static_cell::StaticCell;
25use {defmt_rtt as _, panic_probe as _}; 24use {defmt_rtt as _, panic_probe as _};
26 25
27#[embassy_executor::task] 26#[embassy_executor::task]
@@ -29,9 +28,9 @@ async fn ethernet_task(
29 runner: Runner< 28 runner: Runner<
30 'static, 29 'static,
31 W5500, 30 W5500,
32 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
33 Input<'static, PIN_21>, 32 Input<'static>,
34 Output<'static, PIN_20>, 33 Output<'static>,
35 >, 34 >,
36) -> ! { 35) -> ! {
37 runner.run().await 36 runner.run().await
@@ -57,7 +56,8 @@ async fn main(spawner: Spawner) {
57 let w5500_reset = Output::new(p.PIN_20, Level::High); 56 let w5500_reset = Output::new(p.PIN_20, Level::High);
58 57
59 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; 58 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
60 let state = make_static!(State::<8, 8>::new()); 59 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
60 let state = STATE.init(State::<8, 8>::new());
61 let (device, runner) = embassy_net_wiznet::new( 61 let (device, runner) = embassy_net_wiznet::new(
62 mac_addr, 62 mac_addr,
63 state, 63 state,
@@ -72,11 +72,13 @@ async fn main(spawner: Spawner) {
72 let seed = rng.next_u64(); 72 let seed = rng.next_u64();
73 73
74 // Init network stack 74 // Init network stack
75 let stack = &*make_static!(Stack::new( 75 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
76 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
77 let stack = &*STACK.init(Stack::new(
76 device, 78 device,
77 embassy_net::Config::dhcpv4(Default::default()), 79 embassy_net::Config::dhcpv4(Default::default()),
78 make_static!(StackResources::<2>::new()), 80 RESOURCES.init(StackResources::<2>::new()),
79 seed 81 seed,
80 )); 82 ));
81 83
82 // Launch network task 84 // Launch network task
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs
index 76dabce1c..adb1d8941 100644
--- a/examples/rp/src/bin/ethernet_w5500_udp.rs
+++ b/examples/rp/src/bin/ethernet_w5500_udp.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -15,12 +14,12 @@ use embassy_net_wiznet::chip::W5500;
15use embassy_net_wiznet::*; 14use embassy_net_wiznet::*;
16use embassy_rp::clocks::RoscRng; 15use embassy_rp::clocks::RoscRng;
17use embassy_rp::gpio::{Input, Level, Output, Pull}; 16use embassy_rp::gpio::{Input, Level, Output, Pull};
18use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; 17use embassy_rp::peripherals::SPI0;
19use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
20use embassy_time::Delay; 19use embassy_time::Delay;
21use embedded_hal_bus::spi::ExclusiveDevice; 20use embedded_hal_bus::spi::ExclusiveDevice;
22use rand::RngCore; 21use rand::RngCore;
23use static_cell::make_static; 22use static_cell::StaticCell;
24use {defmt_rtt as _, panic_probe as _}; 23use {defmt_rtt as _, panic_probe as _};
25 24
26#[embassy_executor::task] 25#[embassy_executor::task]
@@ -28,9 +27,9 @@ async fn ethernet_task(
28 runner: Runner< 27 runner: Runner<
29 'static, 28 'static,
30 W5500, 29 W5500,
31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 30 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
32 Input<'static, PIN_21>, 31 Input<'static>,
33 Output<'static, PIN_20>, 32 Output<'static>,
34 >, 33 >,
35) -> ! { 34) -> ! {
36 runner.run().await 35 runner.run().await
@@ -55,7 +54,8 @@ async fn main(spawner: Spawner) {
55 let w5500_reset = Output::new(p.PIN_20, Level::High); 54 let w5500_reset = Output::new(p.PIN_20, Level::High);
56 55
57 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; 56 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
58 let state = make_static!(State::<8, 8>::new()); 57 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
58 let state = STATE.init(State::<8, 8>::new());
59 let (device, runner) = embassy_net_wiznet::new( 59 let (device, runner) = embassy_net_wiznet::new(
60 mac_addr, 60 mac_addr,
61 state, 61 state,
@@ -70,11 +70,13 @@ async fn main(spawner: Spawner) {
70 let seed = rng.next_u64(); 70 let seed = rng.next_u64();
71 71
72 // Init network stack 72 // Init network stack
73 let stack = &*make_static!(Stack::new( 73 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
74 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
75 let stack = &*STACK.init(Stack::new(
74 device, 76 device,
75 embassy_net::Config::dhcpv4(Default::default()), 77 embassy_net::Config::dhcpv4(Default::default()),
76 make_static!(StackResources::<2>::new()), 78 RESOURCES.init(StackResources::<2>::new()),
77 seed 79 seed,
78 )); 80 ));
79 81
80 // Launch network task 82 // Launch network task
diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs
index 129a8497f..eb3e6a2b9 100644
--- a/examples/rp/src/bin/flash.rs
+++ b/examples/rp/src/bin/flash.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use defmt::*; 6use defmt::*;
8use embassy_executor::Spawner; 7use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/gpio_async.rs b/examples/rp/src/bin/gpio_async.rs
index 98209fe41..b79fb2a15 100644
--- a/examples/rp/src/bin/gpio_async.rs
+++ b/examples/rp/src/bin/gpio_async.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs
index 896cc15ee..011359253 100644
--- a/examples/rp/src/bin/gpout.rs
+++ b/examples/rp/src/bin/gpout.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs
index 7b53aae72..e31cc894c 100644
--- a/examples/rp/src/bin/i2c_async.rs
+++ b/examples/rp/src/bin/i2c_async.rs
@@ -5,7 +5,6 @@
5 5
6#![no_std] 6#![no_std]
7#![no_main] 7#![no_main]
8#![feature(type_alias_impl_trait)]
9 8
10use defmt::*; 9use defmt::*;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs
index 9ddb48d69..c9c8a2760 100644
--- a/examples/rp/src/bin/i2c_blocking.rs
+++ b/examples/rp/src/bin/i2c_blocking.rs
@@ -5,7 +5,6 @@
5 5
6#![no_std] 6#![no_std]
7#![no_main] 7#![no_main]
8#![feature(type_alias_impl_trait)]
9 8
10use defmt::*; 9use defmt::*;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs
index 151b083a4..9fffb4646 100644
--- a/examples/rp/src/bin/i2c_slave.rs
+++ b/examples/rp/src/bin/i2c_slave.rs
@@ -1,7 +1,6 @@
1//! This example shows how to use the 2040 as an i2c slave. 1//! This example shows how to use the 2040 as an i2c slave.
2#![no_std] 2#![no_std]
3#![no_main] 3#![no_main]
4#![feature(type_alias_impl_trait)]
5 4
6use defmt::*; 5use defmt::*;
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
@@ -27,7 +26,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
27 loop { 26 loop {
28 let mut buf = [0u8; 128]; 27 let mut buf = [0u8; 128];
29 match dev.listen(&mut buf).await { 28 match dev.listen(&mut buf).await {
30 Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device recieved general call write: {}", buf[..len]), 29 Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]),
31 Ok(i2c_slave::Command::Read) => loop { 30 Ok(i2c_slave::Command::Read) => loop {
32 match dev.respond_to_read(&[state]).await { 31 match dev.respond_to_read(&[state]).await {
33 Ok(x) => match x { 32 Ok(x) => match x {
@@ -41,9 +40,9 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
41 Err(e) => error!("error while responding {}", e), 40 Err(e) => error!("error while responding {}", e),
42 } 41 }
43 }, 42 },
44 Ok(i2c_slave::Command::Write(len)) => info!("Device recieved write: {}", buf[..len]), 43 Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]),
45 Ok(i2c_slave::Command::WriteRead(len)) => { 44 Ok(i2c_slave::Command::WriteRead(len)) => {
46 info!("device recieved write read: {:x}", buf[..len]); 45 info!("device received write read: {:x}", buf[..len]);
47 match buf[0] { 46 match buf[0] {
48 // Set the state 47 // Set the state
49 0xC2 => { 48 0xC2 => {
@@ -111,7 +110,7 @@ async fn main(spawner: Spawner) {
111 let c_sda = p.PIN_1; 110 let c_sda = p.PIN_1;
112 let c_scl = p.PIN_0; 111 let c_scl = p.PIN_0;
113 let mut config = i2c::Config::default(); 112 let mut config = i2c::Config::default();
114 config.frequency = 5_000; 113 config.frequency = 1_000_000;
115 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); 114 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config);
116 115
117 unwrap!(spawner.spawn(controller_task(controller))); 116 unwrap!(spawner.spawn(controller_task(controller)));
diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs
index 43eaf8b0a..7cb546c91 100644
--- a/examples/rp/src/bin/multicore.rs
+++ b/examples/rp/src/bin/multicore.rs
@@ -4,13 +4,11 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Executor; 9use embassy_executor::Executor;
11use embassy_rp::gpio::{Level, Output}; 10use embassy_rp::gpio::{Level, Output};
12use embassy_rp::multicore::{spawn_core1, Stack}; 11use embassy_rp::multicore::{spawn_core1, Stack};
13use embassy_rp::peripherals::PIN_25;
14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 12use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
15use embassy_sync::channel::Channel; 13use embassy_sync::channel::Channel;
16use embassy_time::Timer; 14use embassy_time::Timer;
@@ -32,10 +30,14 @@ fn main() -> ! {
32 let p = embassy_rp::init(Default::default()); 30 let p = embassy_rp::init(Default::default());
33 let led = Output::new(p.PIN_25, Level::Low); 31 let led = Output::new(p.PIN_25, Level::Low);
34 32
35 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { 33 spawn_core1(
36 let executor1 = EXECUTOR1.init(Executor::new()); 34 p.CORE1,
37 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); 35 unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) },
38 }); 36 move || {
37 let executor1 = EXECUTOR1.init(Executor::new());
38 executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led))));
39 },
40 );
39 41
40 let executor0 = EXECUTOR0.init(Executor::new()); 42 let executor0 = EXECUTOR0.init(Executor::new());
41 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); 43 executor0.run(|spawner| unwrap!(spawner.spawn(core0_task())));
@@ -53,7 +55,7 @@ async fn core0_task() {
53} 55}
54 56
55#[embassy_executor::task] 57#[embassy_executor::task]
56async fn core1_task(mut led: Output<'static, PIN_25>) { 58async fn core1_task(mut led: Output<'static>) {
57 info!("Hello from core 1"); 59 info!("Hello from core 1");
58 loop { 60 loop {
59 match CHANNEL.receive().await { 61 match CHANNEL.receive().await {
diff --git a/examples/rp/src/bin/multiprio.rs b/examples/rp/src/bin/multiprio.rs
index 28f621437..26b80c11d 100644
--- a/examples/rp/src/bin/multiprio.rs
+++ b/examples/rp/src/bin/multiprio.rs
@@ -55,7 +55,6 @@
55 55
56#![no_std] 56#![no_std]
57#![no_main] 57#![no_main]
58#![feature(type_alias_impl_trait)]
59 58
60use cortex_m_rt::entry; 59use cortex_m_rt::entry;
61use defmt::{info, unwrap}; 60use defmt::{info, unwrap};
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index a6d6144be..ee248591b 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6use defmt::info; 5use defmt::info;
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
8use embassy_rp::bind_interrupts; 7use embassy_rp::bind_interrupts;
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index 86e5017ac..02700269c 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6use defmt::info; 5use defmt::info;
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
8use embassy_futures::join::join; 7use embassy_futures::join::join;
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs
index 5e5a6f9a3..3fab7b5f2 100644
--- a/examples/rp/src/bin/pio_hd44780.rs
+++ b/examples/rp/src/bin/pio_hd44780.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7 6
8use core::fmt::Write; 7use core::fmt::Write;
9 8
diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs
new file mode 100644
index 000000000..cf60e5b30
--- /dev/null
+++ b/examples/rp/src/bin/pio_i2s.rs
@@ -0,0 +1,125 @@
1//! This example shows generating audio and sending it to a connected i2s DAC using the PIO
2//! module of the RP2040.
3//!
4//! Connect the i2s DAC as follows:
5//! bclk : GPIO 18
6//! lrc : GPIO 19
7//! din : GPIO 20
8//! Then hold down the boot select button to trigger a rising triangle waveform.
9
10#![no_std]
11#![no_main]
12
13use core::mem;
14
15use embassy_executor::Spawner;
16use embassy_rp::peripherals::PIO0;
17use embassy_rp::pio::{Config, FifoJoin, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
18use embassy_rp::{bind_interrupts, Peripheral};
19use fixed::traits::ToFixed;
20use static_cell::StaticCell;
21use {defmt_rtt as _, panic_probe as _};
22
23bind_interrupts!(struct Irqs {
24 PIO0_IRQ_0 => InterruptHandler<PIO0>;
25});
26
27const SAMPLE_RATE: u32 = 48_000;
28
29#[embassy_executor::main]
30async fn main(_spawner: Spawner) {
31 let mut p = embassy_rp::init(Default::default());
32
33 // Setup pio state machine for i2s output
34 let mut pio = Pio::new(p.PIO0, Irqs);
35
36 #[rustfmt::skip]
37 let pio_program = pio_proc::pio_asm!(
38 ".side_set 2",
39 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock
40 "left_data:",
41 " out pins, 1 side 0b00",
42 " jmp x-- left_data side 0b01",
43 " out pins 1 side 0b10",
44 " set x, 14 side 0b11",
45 "right_data:",
46 " out pins 1 side 0b10",
47 " jmp x-- right_data side 0b11",
48 " out pins 1 side 0b00",
49 );
50
51 let bit_clock_pin = p.PIN_18;
52 let left_right_clock_pin = p.PIN_19;
53 let data_pin = p.PIN_20;
54
55 let data_pin = pio.common.make_pio_pin(data_pin);
56 let bit_clock_pin = pio.common.make_pio_pin(bit_clock_pin);
57 let left_right_clock_pin = pio.common.make_pio_pin(left_right_clock_pin);
58
59 let cfg = {
60 let mut cfg = Config::default();
61 cfg.use_program(
62 &pio.common.load_program(&pio_program.program),
63 &[&bit_clock_pin, &left_right_clock_pin],
64 );
65 cfg.set_out_pins(&[&data_pin]);
66 const BIT_DEPTH: u32 = 16;
67 const CHANNELS: u32 = 2;
68 let clock_frequency = SAMPLE_RATE * BIT_DEPTH * CHANNELS;
69 cfg.clock_divider = (125_000_000. / clock_frequency as f64 / 2.).to_fixed();
70 cfg.shift_out = ShiftConfig {
71 threshold: 32,
72 direction: ShiftDirection::Left,
73 auto_fill: true,
74 };
75 // join fifos to have twice the time to start the next dma transfer
76 cfg.fifo_join = FifoJoin::TxOnly;
77 cfg
78 };
79 pio.sm0.set_config(&cfg);
80 pio.sm0.set_pin_dirs(
81 embassy_rp::pio::Direction::Out,
82 &[&data_pin, &left_right_clock_pin, &bit_clock_pin],
83 );
84
85 // create two audio buffers (back and front) which will take turns being
86 // filled with new audio data and being sent to the pio fifo using dma
87 const BUFFER_SIZE: usize = 960;
88 static DMA_BUFFER: StaticCell<[u32; BUFFER_SIZE * 2]> = StaticCell::new();
89 let dma_buffer = DMA_BUFFER.init_with(|| [0u32; BUFFER_SIZE * 2]);
90 let (mut back_buffer, mut front_buffer) = dma_buffer.split_at_mut(BUFFER_SIZE);
91
92 // start pio state machine
93 pio.sm0.set_enable(true);
94 let tx = pio.sm0.tx();
95 let mut dma_ref = p.DMA_CH0.into_ref();
96
97 let mut fade_value: i32 = 0;
98 let mut phase: i32 = 0;
99
100 loop {
101 // trigger transfer of front buffer data to the pio fifo
102 // but don't await the returned future, yet
103 let dma_future = tx.dma_push(dma_ref.reborrow(), front_buffer);
104
105 // fade in audio when bootsel is pressed
106 let fade_target = if p.BOOTSEL.is_pressed() { i32::MAX } else { 0 };
107
108 // fill back buffer with fresh audio samples before awaiting the dma future
109 for s in back_buffer.iter_mut() {
110 // exponential approach of fade_value => fade_target
111 fade_value += (fade_target - fade_value) >> 14;
112 // generate triangle wave with amplitude and frequency based on fade value
113 phase = (phase + (fade_value >> 22)) & 0xffff;
114 let triangle_sample = (phase as i16 as i32).abs() - 16384;
115 let sample = (triangle_sample * (fade_value >> 15)) >> 16;
116 // duplicate mono sample into lower and upper half of dma word
117 *s = (sample as u16 as u32) * 0x10001;
118 }
119
120 // now await the dma future. once the dma finishes, the next buffer needs to be queued
121 // within DMA_DEPTH / SAMPLE_RATE = 8 / 48000 seconds = 166us
122 dma_future.await;
123 mem::swap(&mut back_buffer, &mut front_buffer);
124 }
125}
diff --git a/examples/rp/src/bin/pio_rotary_encoder.rs b/examples/rp/src/bin/pio_rotary_encoder.rs
index 6d9d59df6..58bdadbc0 100644
--- a/examples/rp/src/bin/pio_rotary_encoder.rs
+++ b/examples/rp/src/bin/pio_rotary_encoder.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use defmt::info; 6use defmt::info;
8use embassy_executor::Spawner; 7use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/pio_stepper.rs b/examples/rp/src/bin/pio_stepper.rs
index 02fb20699..ab9ecf623 100644
--- a/examples/rp/src/bin/pio_stepper.rs
+++ b/examples/rp/src/bin/pio_stepper.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7use core::mem::{self, MaybeUninit}; 6use core::mem::{self, MaybeUninit};
8 7
9use defmt::info; 8use defmt::info;
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs
index c0ea23607..53b696309 100644
--- a/examples/rp/src/bin/pio_uart.rs
+++ b/examples/rp/src/bin/pio_uart.rs
@@ -8,7 +8,6 @@
8 8
9#![no_std] 9#![no_std]
10#![no_main] 10#![no_main]
11#![feature(type_alias_impl_trait)]
12#![allow(async_fn_in_trait)] 11#![allow(async_fn_in_trait)]
13 12
14use defmt::{info, panic, trace}; 13use defmt::{info, panic, trace};
@@ -61,7 +60,6 @@ async fn main(_spawner: Spawner) {
61 60
62 // Create embassy-usb DeviceBuilder using the driver and config. 61 // Create embassy-usb DeviceBuilder using the driver and config.
63 // It needs some buffers for building the descriptors. 62 // It needs some buffers for building the descriptors.
64 let mut device_descriptor = [0; 256];
65 let mut config_descriptor = [0; 256]; 63 let mut config_descriptor = [0; 256];
66 let mut bos_descriptor = [0; 256]; 64 let mut bos_descriptor = [0; 256];
67 let mut control_buf = [0; 64]; 65 let mut control_buf = [0; 64];
@@ -71,7 +69,6 @@ async fn main(_spawner: Spawner) {
71 let mut builder = Builder::new( 69 let mut builder = Builder::new(
72 driver, 70 driver,
73 config, 71 config,
74 &mut device_descriptor,
75 &mut config_descriptor, 72 &mut config_descriptor,
76 &mut bos_descriptor, 73 &mut bos_descriptor,
77 &mut [], // no msos descriptors 74 &mut [], // no msos descriptors
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs
index 7b3259538..ac145933c 100644
--- a/examples/rp/src/bin/pio_ws2812.rs
+++ b/examples/rp/src/bin/pio_ws2812.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7 6
8use defmt::*; 7use defmt::*;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
@@ -13,7 +12,7 @@ use embassy_rp::pio::{
13 Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, 12 Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
14}; 13};
15use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; 14use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef};
16use embassy_time::Timer; 15use embassy_time::{Duration, Ticker, Timer};
17use fixed::types::U24F8; 16use fixed::types::U24F8;
18use fixed_macro::fixed; 17use fixed_macro::fixed;
19use smart_leds::RGB8; 18use smart_leds::RGB8;
@@ -108,6 +107,8 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> {
108 107
109 // DMA transfer 108 // DMA transfer
110 self.sm.tx().dma_push(self.dma.reborrow(), &words).await; 109 self.sm.tx().dma_push(self.dma.reborrow(), &words).await;
110
111 Timer::after_micros(55).await;
111 } 112 }
112} 113}
113 114
@@ -144,6 +145,7 @@ async fn main(_spawner: Spawner) {
144 let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16); 145 let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16);
145 146
146 // Loop forever making RGB values and pushing them out to the WS2812. 147 // Loop forever making RGB values and pushing them out to the WS2812.
148 let mut ticker = Ticker::every(Duration::from_millis(10));
147 loop { 149 loop {
148 for j in 0..(256 * 5) { 150 for j in 0..(256 * 5) {
149 debug!("New Colors:"); 151 debug!("New Colors:");
@@ -153,7 +155,7 @@ async fn main(_spawner: Spawner) {
153 } 155 }
154 ws2812.write(&data).await; 156 ws2812.write(&data).await;
155 157
156 Timer::after_millis(10).await; 158 ticker.next().await;
157 } 159 }
158 } 160 }
159} 161}
diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs
index a99e88003..4fb62546d 100644
--- a/examples/rp/src/bin/pwm.rs
+++ b/examples/rp/src/bin/pwm.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/pwm_input.rs b/examples/rp/src/bin/pwm_input.rs
index 0fc2e40c3..e7bcbfbd4 100644
--- a/examples/rp/src/bin/pwm_input.rs
+++ b/examples/rp/src/bin/pwm_input.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use defmt::*; 6use defmt::*;
8use embassy_executor::Spawner; 7use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/rosc.rs b/examples/rp/src/bin/rosc.rs
index f841043b6..942b72319 100644
--- a/examples/rp/src/bin/rosc.rs
+++ b/examples/rp/src/bin/rosc.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs
index 667876db5..e9a5e43a8 100644
--- a/examples/rp/src/bin/rtc.rs
+++ b/examples/rp/src/bin/rtc.rs
@@ -2,7 +2,6 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use defmt::*; 6use defmt::*;
8use embassy_executor::Spawner; 7use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/spi.rs b/examples/rp/src/bin/spi.rs
index 602348f7a..4cc4f5210 100644
--- a/examples/rp/src/bin/spi.rs
+++ b/examples/rp/src/bin/spi.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/spi_async.rs b/examples/rp/src/bin/spi_async.rs
index f5a2d334e..266584efc 100644
--- a/examples/rp/src/bin/spi_async.rs
+++ b/examples/rp/src/bin/spi_async.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7 6
8use defmt::*; 7use defmt::*;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs
index 26c258e1c..e937b9d0a 100644
--- a/examples/rp/src/bin/spi_display.rs
+++ b/examples/rp/src/bin/spi_display.rs
@@ -5,7 +5,6 @@
5 5
6#![no_std] 6#![no_std]
7#![no_main] 7#![no_main]
8#![feature(type_alias_impl_trait)]
9 8
10use core::cell::RefCell; 9use core::cell::RefCell;
11 10
diff --git a/examples/rp/src/bin/uart.rs b/examples/rp/src/bin/uart.rs
index 451c3c396..6a2816cd0 100644
--- a/examples/rp/src/bin/uart.rs
+++ b/examples/rp/src/bin/uart.rs
@@ -6,7 +6,6 @@
6 6
7#![no_std] 7#![no_std]
8#![no_main] 8#![no_main]
9#![feature(type_alias_impl_trait)]
10 9
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
12use embassy_rp::uart; 11use embassy_rp::uart;
diff --git a/examples/rp/src/bin/uart_buffered_split.rs b/examples/rp/src/bin/uart_buffered_split.rs
index 14e8810a4..fac61aa04 100644
--- a/examples/rp/src/bin/uart_buffered_split.rs
+++ b/examples/rp/src/bin/uart_buffered_split.rs
@@ -6,7 +6,6 @@
6 6
7#![no_std] 7#![no_std]
8#![no_main] 8#![no_main]
9#![feature(type_alias_impl_trait)]
10 9
11use defmt::*; 10use defmt::*;
12use embassy_executor::Spawner; 11use embassy_executor::Spawner;
@@ -15,7 +14,7 @@ use embassy_rp::peripherals::UART0;
15use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; 14use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config};
16use embassy_time::Timer; 15use embassy_time::Timer;
17use embedded_io_async::{Read, Write}; 16use embedded_io_async::{Read, Write};
18use static_cell::make_static; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
21bind_interrupts!(struct Irqs { 20bind_interrupts!(struct Irqs {
@@ -27,8 +26,10 @@ async fn main(spawner: Spawner) {
27 let p = embassy_rp::init(Default::default()); 26 let p = embassy_rp::init(Default::default());
28 let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0); 27 let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0);
29 28
30 let tx_buf = &mut make_static!([0u8; 16])[..]; 29 static TX_BUF: StaticCell<[u8; 16]> = StaticCell::new();
31 let rx_buf = &mut make_static!([0u8; 16])[..]; 30 let tx_buf = &mut TX_BUF.init([0; 16])[..];
31 static RX_BUF: StaticCell<[u8; 16]> = StaticCell::new();
32 let rx_buf = &mut RX_BUF.init([0; 16])[..];
32 let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default()); 33 let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default());
33 let (rx, mut tx) = uart.split(); 34 let (rx, mut tx) = uart.split();
34 35
diff --git a/examples/rp/src/bin/uart_unidir.rs b/examples/rp/src/bin/uart_unidir.rs
index 42c8b432e..a45f40756 100644
--- a/examples/rp/src/bin/uart_unidir.rs
+++ b/examples/rp/src/bin/uart_unidir.rs
@@ -7,7 +7,6 @@
7 7
8#![no_std] 8#![no_std]
9#![no_main] 9#![no_main]
10#![feature(type_alias_impl_trait)]
11 10
12use defmt::*; 11use defmt::*;
13use embassy_executor::Spawner; 12use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs
index cc63029fb..f1b124efa 100644
--- a/examples/rp/src/bin/usb_ethernet.rs
+++ b/examples/rp/src/bin/usb_ethernet.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::*; 8use defmt::*;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -17,7 +16,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState
17use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 16use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
18use embassy_usb::{Builder, Config, UsbDevice}; 17use embassy_usb::{Builder, Config, UsbDevice};
19use embedded_io_async::Write; 18use embedded_io_async::Write;
20use static_cell::make_static; 19use static_cell::StaticCell;
21use {defmt_rtt as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _};
22 21
23bind_interrupts!(struct Irqs { 22bind_interrupts!(struct Irqs {
@@ -65,14 +64,16 @@ async fn main(spawner: Spawner) {
65 config.device_protocol = 0x01; 64 config.device_protocol = 0x01;
66 65
67 // Create embassy-usb DeviceBuilder using the driver and config. 66 // Create embassy-usb DeviceBuilder using the driver and config.
67 static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
68 static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
69 static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
68 let mut builder = Builder::new( 70 let mut builder = Builder::new(
69 driver, 71 driver,
70 config, 72 config,
71 &mut make_static!([0; 256])[..], 73 &mut CONFIG_DESC.init([0; 256])[..],
72 &mut make_static!([0; 256])[..], 74 &mut BOS_DESC.init([0; 256])[..],
73 &mut make_static!([0; 256])[..],
74 &mut [], // no msos descriptors 75 &mut [], // no msos descriptors
75 &mut make_static!([0; 128])[..], 76 &mut CONTROL_BUF.init([0; 128])[..],
76 ); 77 );
77 78
78 // Our MAC addr. 79 // Our MAC addr.
@@ -81,14 +82,16 @@ async fn main(spawner: Spawner) {
81 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; 82 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88];
82 83
83 // Create classes on the builder. 84 // Create classes on the builder.
84 let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); 85 static STATE: StaticCell<State> = StaticCell::new();
86 let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64);
85 87
86 // Build the builder. 88 // Build the builder.
87 let usb = builder.build(); 89 let usb = builder.build();
88 90
89 unwrap!(spawner.spawn(usb_task(usb))); 91 unwrap!(spawner.spawn(usb_task(usb)));
90 92
91 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); 93 static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
94 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
92 unwrap!(spawner.spawn(usb_ncm_task(runner))); 95 unwrap!(spawner.spawn(usb_ncm_task(runner)));
93 96
94 let config = embassy_net::Config::dhcpv4(Default::default()); 97 let config = embassy_net::Config::dhcpv4(Default::default());
@@ -102,11 +105,13 @@ async fn main(spawner: Spawner) {
102 let seed = 1234; // guaranteed random, chosen by a fair dice roll 105 let seed = 1234; // guaranteed random, chosen by a fair dice roll
103 106
104 // Init network stack 107 // Init network stack
105 let stack = &*make_static!(Stack::new( 108 static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
109 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
110 let stack = &*STACK.init(Stack::new(
106 device, 111 device,
107 config, 112 config,
108 make_static!(StackResources::<2>::new()), 113 RESOURCES.init(StackResources::<2>::new()),
109 seed 114 seed,
110 )); 115 ));
111 116
112 unwrap!(spawner.spawn(net_task(stack))); 117 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs
index 569c9b12b..710be8d13 100644
--- a/examples/rp/src/bin/usb_hid_keyboard.rs
+++ b/examples/rp/src/bin/usb_hid_keyboard.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, Ordering};
6 5
@@ -37,7 +36,6 @@ async fn main(_spawner: Spawner) {
37 36
38 // Create embassy-usb DeviceBuilder using the driver and config. 37 // Create embassy-usb DeviceBuilder using the driver and config.
39 // It needs some buffers for building the descriptors. 38 // It needs some buffers for building the descriptors.
40 let mut device_descriptor = [0; 256];
41 let mut config_descriptor = [0; 256]; 39 let mut config_descriptor = [0; 256];
42 let mut bos_descriptor = [0; 256]; 40 let mut bos_descriptor = [0; 256];
43 // You can also add a Microsoft OS descriptor. 41 // You can also add a Microsoft OS descriptor.
@@ -51,7 +49,6 @@ async fn main(_spawner: Spawner) {
51 let mut builder = Builder::new( 49 let mut builder = Builder::new(
52 driver, 50 driver,
53 config, 51 config,
54 &mut device_descriptor,
55 &mut config_descriptor, 52 &mut config_descriptor,
56 &mut bos_descriptor, 53 &mut bos_descriptor,
57 &mut msos_descriptor, 54 &mut msos_descriptor,
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs
new file mode 100644
index 000000000..e8b399cb1
--- /dev/null
+++ b/examples/rp/src/bin/usb_hid_mouse.rs
@@ -0,0 +1,180 @@
1#![no_std]
2#![no_main]
3
4use core::sync::atomic::{AtomicBool, Ordering};
5
6use defmt::*;
7use embassy_executor::Spawner;
8use embassy_futures::join::join;
9use embassy_rp::bind_interrupts;
10use embassy_rp::clocks::RoscRng;
11use embassy_rp::gpio::{Input, Pull};
12use embassy_rp::peripherals::USB;
13use embassy_rp::usb::{Driver, InterruptHandler};
14use embassy_time::Timer;
15use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
16use embassy_usb::control::OutResponse;
17use embassy_usb::{Builder, Config, Handler};
18use rand::Rng;
19use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
20use {defmt_rtt as _, panic_probe as _};
21
22bind_interrupts!(struct Irqs {
23 USBCTRL_IRQ => InterruptHandler<USB>;
24});
25
26#[embassy_executor::main]
27async fn main(_spawner: Spawner) {
28 let p = embassy_rp::init(Default::default());
29 // Create the driver, from the HAL.
30 let driver = Driver::new(p.USB, Irqs);
31
32 // Create embassy-usb Config
33 let mut config = Config::new(0xc0de, 0xcafe);
34 config.manufacturer = Some("Embassy");
35 config.product = Some("HID keyboard example");
36 config.serial_number = Some("12345678");
37 config.max_power = 100;
38 config.max_packet_size_0 = 64;
39
40 // Create embassy-usb DeviceBuilder using the driver and config.
41 // It needs some buffers for building the descriptors.
42 let mut config_descriptor = [0; 256];
43 let mut bos_descriptor = [0; 256];
44 // You can also add a Microsoft OS descriptor.
45 let mut msos_descriptor = [0; 256];
46 let mut control_buf = [0; 64];
47 let request_handler = MyRequestHandler {};
48 let mut device_handler = MyDeviceHandler::new();
49
50 let mut state = State::new();
51
52 let mut builder = Builder::new(
53 driver,
54 config,
55 &mut config_descriptor,
56 &mut bos_descriptor,
57 &mut msos_descriptor,
58 &mut control_buf,
59 );
60
61 builder.handler(&mut device_handler);
62
63 // Create classes on the builder.
64 let config = embassy_usb::class::hid::Config {
65 report_descriptor: MouseReport::desc(),
66 request_handler: Some(&request_handler),
67 poll_ms: 60,
68 max_packet_size: 64,
69 };
70 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
71
72 // Build the builder.
73 let mut usb = builder.build();
74
75 // Run the USB device.
76 let usb_fut = usb.run();
77
78 // Set up the signal pin that will be used to trigger the keyboard.
79 let mut signal_pin = Input::new(p.PIN_16, Pull::None);
80
81 // Enable the schmitt trigger to slightly debounce.
82 signal_pin.set_schmitt(true);
83
84 let (reader, mut writer) = hid.split();
85
86 // Do stuff with the class!
87 let in_fut = async {
88 let mut rng = RoscRng;
89
90 loop {
91 // every 1 second
92 _ = Timer::after_secs(1).await;
93 let report = MouseReport {
94 buttons: 0,
95 x: rng.gen_range(-100..100), // random small x movement
96 y: rng.gen_range(-100..100), // random small y movement
97 wheel: 0,
98 pan: 0,
99 };
100 // Send the report.
101 match writer.write_serialize(&report).await {
102 Ok(()) => {}
103 Err(e) => warn!("Failed to send report: {:?}", e),
104 }
105 }
106 };
107
108 let out_fut = async {
109 reader.run(false, &request_handler).await;
110 };
111
112 // Run everything concurrently.
113 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
114 join(usb_fut, join(in_fut, out_fut)).await;
115}
116
117struct MyRequestHandler {}
118
119impl RequestHandler for MyRequestHandler {
120 fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> {
121 info!("Get report for {:?}", id);
122 None
123 }
124
125 fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse {
126 info!("Set report for {:?}: {=[u8]}", id, data);
127 OutResponse::Accepted
128 }
129
130 fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) {
131 info!("Set idle rate for {:?} to {:?}", id, dur);
132 }
133
134 fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> {
135 info!("Get idle rate for {:?}", id);
136 None
137 }
138}
139
140struct MyDeviceHandler {
141 configured: AtomicBool,
142}
143
144impl MyDeviceHandler {
145 fn new() -> Self {
146 MyDeviceHandler {
147 configured: AtomicBool::new(false),
148 }
149 }
150}
151
152impl Handler for MyDeviceHandler {
153 fn enabled(&mut self, enabled: bool) {
154 self.configured.store(false, Ordering::Relaxed);
155 if enabled {
156 info!("Device enabled");
157 } else {
158 info!("Device disabled");
159 }
160 }
161
162 fn reset(&mut self) {
163 self.configured.store(false, Ordering::Relaxed);
164 info!("Bus reset, the Vbus current limit is 100mA");
165 }
166
167 fn addressed(&mut self, addr: u8) {
168 self.configured.store(false, Ordering::Relaxed);
169 info!("USB address set to: {}", addr);
170 }
171
172 fn configured(&mut self, configured: bool) {
173 self.configured.store(configured, Ordering::Relaxed);
174 if configured {
175 info!("Device configured, it may now draw up to the configured current limit from Vbus.")
176 } else {
177 info!("Device is no longer configured, the Vbus current limit is 100mA.");
178 }
179 }
180}
diff --git a/examples/rp/src/bin/usb_logger.rs b/examples/rp/src/bin/usb_logger.rs
index 791f15e56..af401ed63 100644
--- a/examples/rp/src/bin/usb_logger.rs
+++ b/examples/rp/src/bin/usb_logger.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_rp::bind_interrupts; 9use embassy_rp::bind_interrupts;
diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs
index d5cdae319..11db1b2e1 100644
--- a/examples/rp/src/bin/usb_midi.rs
+++ b/examples/rp/src/bin/usb_midi.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::{info, panic}; 8use defmt::{info, panic};
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -47,7 +46,6 @@ async fn main(_spawner: Spawner) {
47 46
48 // Create embassy-usb DeviceBuilder using the driver and config. 47 // Create embassy-usb DeviceBuilder using the driver and config.
49 // It needs some buffers for building the descriptors. 48 // It needs some buffers for building the descriptors.
50 let mut device_descriptor = [0; 256];
51 let mut config_descriptor = [0; 256]; 49 let mut config_descriptor = [0; 256];
52 let mut bos_descriptor = [0; 256]; 50 let mut bos_descriptor = [0; 256];
53 let mut control_buf = [0; 64]; 51 let mut control_buf = [0; 64];
@@ -55,7 +53,6 @@ async fn main(_spawner: Spawner) {
55 let mut builder = Builder::new( 53 let mut builder = Builder::new(
56 driver, 54 driver,
57 config, 55 config,
58 &mut device_descriptor,
59 &mut config_descriptor, 56 &mut config_descriptor,
60 &mut bos_descriptor, 57 &mut bos_descriptor,
61 &mut [], // no msos descriptors 58 &mut [], // no msos descriptors
diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs
index f59262e5c..97e7e0244 100644
--- a/examples/rp/src/bin/usb_raw.rs
+++ b/examples/rp/src/bin/usb_raw.rs
@@ -48,7 +48,6 @@
48 48
49#![no_std] 49#![no_std]
50#![no_main] 50#![no_main]
51#![feature(type_alias_impl_trait)]
52 51
53use defmt::info; 52use defmt::info;
54use embassy_executor::Spawner; 53use embassy_executor::Spawner;
@@ -94,7 +93,6 @@ async fn main(_spawner: Spawner) {
94 93
95 // Create embassy-usb DeviceBuilder using the driver and config. 94 // Create embassy-usb DeviceBuilder using the driver and config.
96 // It needs some buffers for building the descriptors. 95 // It needs some buffers for building the descriptors.
97 let mut device_descriptor = [0; 256];
98 let mut config_descriptor = [0; 256]; 96 let mut config_descriptor = [0; 256];
99 let mut bos_descriptor = [0; 256]; 97 let mut bos_descriptor = [0; 256];
100 let mut msos_descriptor = [0; 256]; 98 let mut msos_descriptor = [0; 256];
@@ -107,7 +105,6 @@ async fn main(_spawner: Spawner) {
107 let mut builder = Builder::new( 105 let mut builder = Builder::new(
108 driver, 106 driver,
109 config, 107 config,
110 &mut device_descriptor,
111 &mut config_descriptor, 108 &mut config_descriptor,
112 &mut bos_descriptor, 109 &mut bos_descriptor,
113 &mut msos_descriptor, 110 &mut msos_descriptor,
diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs
index 288be5a4e..331c3da4c 100644
--- a/examples/rp/src/bin/usb_raw_bulk.rs
+++ b/examples/rp/src/bin/usb_raw_bulk.rs
@@ -26,7 +26,6 @@
26 26
27#![no_std] 27#![no_std]
28#![no_main] 28#![no_main]
29#![feature(type_alias_impl_trait)]
30 29
31use defmt::info; 30use defmt::info;
32use embassy_executor::Spawner; 31use embassy_executor::Spawner;
@@ -72,7 +71,6 @@ async fn main(_spawner: Spawner) {
72 71
73 // Create embassy-usb DeviceBuilder using the driver and config. 72 // Create embassy-usb DeviceBuilder using the driver and config.
74 // It needs some buffers for building the descriptors. 73 // It needs some buffers for building the descriptors.
75 let mut device_descriptor = [0; 256];
76 let mut config_descriptor = [0; 256]; 74 let mut config_descriptor = [0; 256];
77 let mut bos_descriptor = [0; 256]; 75 let mut bos_descriptor = [0; 256];
78 let mut msos_descriptor = [0; 256]; 76 let mut msos_descriptor = [0; 256];
@@ -81,7 +79,6 @@ async fn main(_spawner: Spawner) {
81 let mut builder = Builder::new( 79 let mut builder = Builder::new(
82 driver, 80 driver,
83 config, 81 config,
84 &mut device_descriptor,
85 &mut config_descriptor, 82 &mut config_descriptor,
86 &mut bos_descriptor, 83 &mut bos_descriptor,
87 &mut msos_descriptor, 84 &mut msos_descriptor,
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs
index 30347d920..3c9bc96dd 100644
--- a/examples/rp/src/bin/usb_serial.rs
+++ b/examples/rp/src/bin/usb_serial.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::{info, panic}; 8use defmt::{info, panic};
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
@@ -47,7 +46,6 @@ async fn main(_spawner: Spawner) {
47 46
48 // Create embassy-usb DeviceBuilder using the driver and config. 47 // Create embassy-usb DeviceBuilder using the driver and config.
49 // It needs some buffers for building the descriptors. 48 // It needs some buffers for building the descriptors.
50 let mut device_descriptor = [0; 256];
51 let mut config_descriptor = [0; 256]; 49 let mut config_descriptor = [0; 256];
52 let mut bos_descriptor = [0; 256]; 50 let mut bos_descriptor = [0; 256];
53 let mut control_buf = [0; 64]; 51 let mut control_buf = [0; 64];
@@ -57,7 +55,6 @@ async fn main(_spawner: Spawner) {
57 let mut builder = Builder::new( 55 let mut builder = Builder::new(
58 driver, 56 driver,
59 config, 57 config,
60 &mut device_descriptor,
61 &mut config_descriptor, 58 &mut config_descriptor,
62 &mut bos_descriptor, 59 &mut bos_descriptor,
63 &mut [], // no msos descriptors 60 &mut [], // no msos descriptors
diff --git a/examples/rp/src/bin/usb_serial_with_logger.rs b/examples/rp/src/bin/usb_serial_with_logger.rs
new file mode 100644
index 000000000..f9cfdef94
--- /dev/null
+++ b/examples/rp/src/bin/usb_serial_with_logger.rs
@@ -0,0 +1,115 @@
1//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip as well as how to create multiple usb classes for one device
2//!
3//! This creates a USB serial port that echos. It will also print out logging information on a separate serial device
4
5#![no_std]
6#![no_main]
7
8use defmt::{info, panic};
9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_rp::bind_interrupts;
12use embassy_rp::peripherals::USB;
13use embassy_rp::usb::{Driver, Instance, InterruptHandler};
14use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
15use embassy_usb::driver::EndpointError;
16use embassy_usb::{Builder, Config};
17use {defmt_rtt as _, panic_probe as _};
18
19bind_interrupts!(struct Irqs {
20 USBCTRL_IRQ => InterruptHandler<USB>;
21});
22
23#[embassy_executor::main]
24async fn main(_spawner: Spawner) {
25 info!("Hello there!");
26
27 let p = embassy_rp::init(Default::default());
28
29 // Create the driver, from the HAL.
30 let driver = Driver::new(p.USB, Irqs);
31
32 // Create embassy-usb Config
33 let mut config = Config::new(0xc0de, 0xcafe);
34 config.manufacturer = Some("Embassy");
35 config.product = Some("USB-serial example");
36 config.serial_number = Some("12345678");
37 config.max_power = 100;
38 config.max_packet_size_0 = 64;
39
40 // Required for windows compatibility.
41 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
42 config.device_class = 0xEF;
43 config.device_sub_class = 0x02;
44 config.device_protocol = 0x01;
45 config.composite_with_iads = true;
46
47 // Create embassy-usb DeviceBuilder using the driver and config.
48 // It needs some buffers for building the descriptors.
49 let mut config_descriptor = [0; 256];
50 let mut bos_descriptor = [0; 256];
51 let mut control_buf = [0; 64];
52
53 let mut state = State::new();
54 let mut logger_state = State::new();
55
56 let mut builder = Builder::new(
57 driver,
58 config,
59 &mut config_descriptor,
60 &mut bos_descriptor,
61 &mut [], // no msos descriptors
62 &mut control_buf,
63 );
64
65 // Create classes on the builder.
66 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
67
68 // Create a class for the logger
69 let logger_class = CdcAcmClass::new(&mut builder, &mut logger_state, 64);
70
71 // Creates the logger and returns the logger future
72 // Note: You'll need to use log::info! afterwards instead of info! for this to work (this also applies to all the other log::* macros)
73 let log_fut = embassy_usb_logger::with_class!(1024, log::LevelFilter::Info, logger_class);
74
75 // Build the builder.
76 let mut usb = builder.build();
77
78 // Run the USB device.
79 let usb_fut = usb.run();
80
81 // Do stuff with the class!
82 let echo_fut = async {
83 loop {
84 class.wait_connection().await;
85 log::info!("Connected");
86 let _ = echo(&mut class).await;
87 log::info!("Disconnected");
88 }
89 };
90
91 // Run everything concurrently.
92 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
93 join(usb_fut, join(echo_fut, log_fut)).await;
94}
95
96struct Disconnected {}
97
98impl From<EndpointError> for Disconnected {
99 fn from(val: EndpointError) -> Self {
100 match val {
101 EndpointError::BufferOverflow => panic!("Buffer overflow"),
102 EndpointError::Disabled => Disconnected {},
103 }
104 }
105}
106
107async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
108 let mut buf = [0; 64];
109 loop {
110 let n = class.read_packet(&mut buf).await?;
111 let data = &buf[..n];
112 info!("data: {:x}", data);
113 class.write_packet(data).await?;
114 }
115}
diff --git a/examples/rp/src/bin/watchdog.rs b/examples/rp/src/bin/watchdog.rs
index b6af518af..b9d4ef22f 100644
--- a/examples/rp/src/bin/watchdog.rs
+++ b/examples/rp/src/bin/watchdog.rs
@@ -4,7 +4,6 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use defmt::info; 8use defmt::info;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs
index ad1fa6462..b60852359 100644
--- a/examples/rp/src/bin/wifi_ap_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7#![allow(async_fn_in_trait)] 6#![allow(async_fn_in_trait)]
8 7
9use core::str::from_utf8; 8use core::str::from_utf8;
@@ -15,11 +14,11 @@ use embassy_net::tcp::TcpSocket;
15use embassy_net::{Config, Stack, StackResources}; 14use embassy_net::{Config, Stack, StackResources};
16use embassy_rp::bind_interrupts; 15use embassy_rp::bind_interrupts;
17use embassy_rp::gpio::{Level, Output}; 16use embassy_rp::gpio::{Level, Output};
18use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 17use embassy_rp::peripherals::{DMA_CH0, PIO0};
19use embassy_rp::pio::{InterruptHandler, Pio}; 18use embassy_rp::pio::{InterruptHandler, Pio};
20use embassy_time::Duration; 19use embassy_time::Duration;
21use embedded_io_async::Write; 20use embedded_io_async::Write;
22use static_cell::make_static; 21use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _}; 22use {defmt_rtt as _, panic_probe as _};
24 23
25bind_interrupts!(struct Irqs { 24bind_interrupts!(struct Irqs {
@@ -27,9 +26,7 @@ bind_interrupts!(struct Irqs {
27}); 26});
28 27
29#[embassy_executor::task] 28#[embassy_executor::task]
30async fn wifi_task( 29async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! {
31 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
32) -> ! {
33 runner.run().await 30 runner.run().await
34} 31}
35 32
@@ -59,7 +56,8 @@ async fn main(spawner: Spawner) {
59 let mut pio = Pio::new(p.PIO0, Irqs); 56 let mut pio = Pio::new(p.PIO0, Irqs);
60 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 57 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
61 58
62 let state = make_static!(cyw43::State::new()); 59 static STATE: StaticCell<cyw43::State> = StaticCell::new();
60 let state = STATE.init(cyw43::State::new());
63 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 61 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
64 unwrap!(spawner.spawn(wifi_task(runner))); 62 unwrap!(spawner.spawn(wifi_task(runner)));
65 63
@@ -79,11 +77,13 @@ async fn main(spawner: Spawner) {
79 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. 77 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
80 78
81 // Init network stack 79 // Init network stack
82 let stack = &*make_static!(Stack::new( 80 static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
81 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
82 let stack = &*STACK.init(Stack::new(
83 net_device, 83 net_device,
84 config, 84 config,
85 make_static!(StackResources::<2>::new()), 85 RESOURCES.init(StackResources::<2>::new()),
86 seed 86 seed,
87 )); 87 ));
88 88
89 unwrap!(spawner.spawn(net_task(stack))); 89 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs
index 14ace74e9..18eefe41f 100644
--- a/examples/rp/src/bin/wifi_blinky.rs
+++ b/examples/rp/src/bin/wifi_blinky.rs
@@ -4,17 +4,16 @@
4 4
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7#![feature(type_alias_impl_trait)]
8 7
9use cyw43_pio::PioSpi; 8use cyw43_pio::PioSpi;
10use defmt::*; 9use defmt::*;
11use embassy_executor::Spawner; 10use embassy_executor::Spawner;
12use embassy_rp::bind_interrupts; 11use embassy_rp::bind_interrupts;
13use embassy_rp::gpio::{Level, Output}; 12use embassy_rp::gpio::{Level, Output};
14use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 13use embassy_rp::peripherals::{DMA_CH0, PIO0};
15use embassy_rp::pio::{InterruptHandler, Pio}; 14use embassy_rp::pio::{InterruptHandler, Pio};
16use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
17use static_cell::make_static; 16use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
20bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -22,9 +21,7 @@ bind_interrupts!(struct Irqs {
22}); 21});
23 22
24#[embassy_executor::task] 23#[embassy_executor::task]
25async fn wifi_task( 24async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! {
26 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
27) -> ! {
28 runner.run().await 25 runner.run().await
29} 26}
30 27
@@ -46,7 +43,8 @@ async fn main(spawner: Spawner) {
46 let mut pio = Pio::new(p.PIO0, Irqs); 43 let mut pio = Pio::new(p.PIO0, Irqs);
47 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 44 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
48 45
49 let state = make_static!(cyw43::State::new()); 46 static STATE: StaticCell<cyw43::State> = StaticCell::new();
47 let state = STATE.init(cyw43::State::new());
50 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 48 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
51 unwrap!(spawner.spawn(wifi_task(runner))); 49 unwrap!(spawner.spawn(wifi_task(runner)));
52 50
diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs
index 7adf52b88..e0f85a6b0 100644
--- a/examples/rp/src/bin/wifi_scan.rs
+++ b/examples/rp/src/bin/wifi_scan.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7#![allow(async_fn_in_trait)] 6#![allow(async_fn_in_trait)]
8 7
9use core::str; 8use core::str;
@@ -14,9 +13,9 @@ use embassy_executor::Spawner;
14use embassy_net::Stack; 13use embassy_net::Stack;
15use embassy_rp::bind_interrupts; 14use embassy_rp::bind_interrupts;
16use embassy_rp::gpio::{Level, Output}; 15use embassy_rp::gpio::{Level, Output};
17use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 16use embassy_rp::peripherals::{DMA_CH0, PIO0};
18use embassy_rp::pio::{InterruptHandler, Pio}; 17use embassy_rp::pio::{InterruptHandler, Pio};
19use static_cell::make_static; 18use static_cell::StaticCell;
20use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
21 20
22bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
@@ -24,9 +23,7 @@ bind_interrupts!(struct Irqs {
24}); 23});
25 24
26#[embassy_executor::task] 25#[embassy_executor::task]
27async fn wifi_task( 26async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! {
28 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
29) -> ! {
30 runner.run().await 27 runner.run().await
31} 28}
32 29
@@ -56,7 +53,8 @@ async fn main(spawner: Spawner) {
56 let mut pio = Pio::new(p.PIO0, Irqs); 53 let mut pio = Pio::new(p.PIO0, Irqs);
57 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 54 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
58 55
59 let state = make_static!(cyw43::State::new()); 56 static STATE: StaticCell<cyw43::State> = StaticCell::new();
57 let state = STATE.init(cyw43::State::new());
60 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 58 let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
61 unwrap!(spawner.spawn(wifi_task(runner))); 59 unwrap!(spawner.spawn(wifi_task(runner)));
62 60
@@ -65,7 +63,7 @@ async fn main(spawner: Spawner) {
65 .set_power_management(cyw43::PowerManagementMode::PowerSave) 63 .set_power_management(cyw43::PowerManagementMode::PowerSave)
66 .await; 64 .await;
67 65
68 let mut scanner = control.scan().await; 66 let mut scanner = control.scan(Default::default()).await;
69 while let Some(bss) = scanner.next().await { 67 while let Some(bss) = scanner.next().await {
70 if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { 68 if let Ok(ssid_str) = str::from_utf8(&bss.ssid) {
71 info!("scanned {} == {:x}", ssid_str, bss.bssid); 69 info!("scanned {} == {:x}", ssid_str, bss.bssid);
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs
index ec6b4ee74..f1afc4a00 100644
--- a/examples/rp/src/bin/wifi_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_tcp_server.rs
@@ -3,7 +3,6 @@
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![feature(type_alias_impl_trait)]
7#![allow(async_fn_in_trait)] 6#![allow(async_fn_in_trait)]
8 7
9use core::str::from_utf8; 8use core::str::from_utf8;
@@ -15,11 +14,11 @@ use embassy_net::tcp::TcpSocket;
15use embassy_net::{Config, Stack, StackResources}; 14use embassy_net::{Config, Stack, StackResources};
16use embassy_rp::bind_interrupts; 15use embassy_rp::bind_interrupts;
17use embassy_rp::gpio::{Level, Output}; 16use embassy_rp::gpio::{Level, Output};
18use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 17use embassy_rp::peripherals::{DMA_CH0, PIO0};
19use embassy_rp::pio::{InterruptHandler, Pio}; 18use embassy_rp::pio::{InterruptHandler, Pio};
20use embassy_time::{Duration, Timer}; 19use embassy_time::{Duration, Timer};
21use embedded_io_async::Write; 20use embedded_io_async::Write;
22use static_cell::make_static; 21use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _}; 22use {defmt_rtt as _, panic_probe as _};
24 23
25bind_interrupts!(struct Irqs { 24bind_interrupts!(struct Irqs {
@@ -30,9 +29,7 @@ const WIFI_NETWORK: &str = "EmbassyTest";
30const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; 29const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
31 30
32#[embassy_executor::task] 31#[embassy_executor::task]
33async fn wifi_task( 32async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! {
34 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
35) -> ! {
36 runner.run().await 33 runner.run().await
37} 34}
38 35
@@ -62,7 +59,8 @@ async fn main(spawner: Spawner) {
62 let mut pio = Pio::new(p.PIO0, Irqs); 59 let mut pio = Pio::new(p.PIO0, Irqs);
63 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 60 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
64 61
65 let state = make_static!(cyw43::State::new()); 62 static STATE: StaticCell<cyw43::State> = StaticCell::new();
63 let state = STATE.init(cyw43::State::new());
66 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; 64 let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
67 unwrap!(spawner.spawn(wifi_task(runner))); 65 unwrap!(spawner.spawn(wifi_task(runner)));
68 66
@@ -82,11 +80,13 @@ async fn main(spawner: Spawner) {
82 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. 80 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
83 81
84 // Init network stack 82 // Init network stack
85 let stack = &*make_static!(Stack::new( 83 static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new();
84 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
85 let stack = &*STACK.init(Stack::new(
86 net_device, 86 net_device,
87 config, 87 config,
88 make_static!(StackResources::<2>::new()), 88 RESOURCES.init(StackResources::<2>::new()),
89 seed 89 seed,
90 )); 90 ));
91 91
92 unwrap!(spawner.spawn(net_task(stack))); 92 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index ccc0a4afc..f05565e84 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -6,9 +6,9 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } 8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] }
9embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../embassy-time", features = ["log", "std", ] } 10embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "std", ] }
11embassy-net = { version = "0.2.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } 11embassy-net = { version = "0.4.0", path = "../../embassy-net", features=[ "std", "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" }
13embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]} 13embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]}
14embedded-io-async = { version = "0.6.1" } 14embedded-io-async = { version = "0.6.1" }
@@ -23,7 +23,7 @@ nix = "0.26.2"
23clap = { version = "3.0.0-beta.5", features = ["derive"] } 23clap = { version = "3.0.0-beta.5", features = ["derive"] }
24rand_core = { version = "0.6.3", features = ["std"] } 24rand_core = { version = "0.6.3", features = ["std"] }
25heapless = { version = "0.8", default-features = false } 25heapless = { version = "0.8", default-features = false }
26static_cell = { version = "2", features = ["nightly"]} 26static_cell = "2"
27 27
28[profile.release] 28[profile.release]
29debug = 2 29debug = 2
diff --git a/examples/std/README.md b/examples/std/README.md
index adc795928..e3a59d6ea 100644
--- a/examples/std/README.md
+++ b/examples/std/README.md
@@ -13,11 +13,11 @@ sudo ip -6 route add fe80::/64 dev tap0
13sudo ip -6 route add fdaa::/64 dev tap0 13sudo ip -6 route add fdaa::/64 dev tap0
14``` 14```
15 15
16Second, have something listening there. For example `nc -l 8000` 16Second, have something listening there. For example `nc -lp 8000`
17 17
18Then run the example located in the `examples` folder: 18Then run the example located in the `examples` folder:
19 19
20```sh 20```sh
21cd $EMBASSY_ROOT/examples/std/ 21cd $EMBASSY_ROOT/examples/std/
22cargo run --bin net -- --static-ip 22cargo run --bin net -- --static-ip
23``` \ No newline at end of file 23```
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 8d8345057..59813d8cb 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -1,7 +1,3 @@
1#![feature(type_alias_impl_trait)]
2
3use std::default::Default;
4
5use clap::Parser; 1use clap::Parser;
6use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
7use embassy_net::tcp::TcpSocket; 3use embassy_net::tcp::TcpSocket;
@@ -12,7 +8,7 @@ use embedded_io_async::Write;
12use heapless::Vec; 8use heapless::Vec;
13use log::*; 9use log::*;
14use rand_core::{OsRng, RngCore}; 10use rand_core::{OsRng, RngCore};
15use static_cell::{make_static, StaticCell}; 11use static_cell::StaticCell;
16 12
17#[derive(Parser)] 13#[derive(Parser)]
18#[clap(version = "1.0")] 14#[clap(version = "1.0")]
@@ -54,11 +50,13 @@ async fn main_task(spawner: Spawner) {
54 let seed = u64::from_le_bytes(seed); 50 let seed = u64::from_le_bytes(seed);
55 51
56 // Init network stack 52 // Init network stack
57 let stack = &*make_static!(Stack::new( 53 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
54 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
55 let stack = &*STACK.init(Stack::new(
58 device, 56 device,
59 config, 57 config,
60 make_static!(StackResources::<3>::new()), 58 RESOURCES.init(StackResources::<3>::new()),
61 seed 59 seed,
62 )); 60 ));
63 61
64 // Launch network task 62 // Launch network task
diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs
index 6c19874d5..3b6a3de37 100644
--- a/examples/std/src/bin/net_dns.rs
+++ b/examples/std/src/bin/net_dns.rs
@@ -1,7 +1,3 @@
1#![feature(type_alias_impl_trait)]
2
3use std::default::Default;
4
5use clap::Parser; 1use clap::Parser;
6use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
7use embassy_net::dns::DnsQueryType; 3use embassy_net::dns::DnsQueryType;
@@ -10,7 +6,7 @@ use embassy_net_tuntap::TunTapDevice;
10use heapless::Vec; 6use heapless::Vec;
11use log::*; 7use log::*;
12use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, RngCore};
13use static_cell::{make_static, StaticCell}; 9use static_cell::StaticCell;
14 10
15#[derive(Parser)] 11#[derive(Parser)]
16#[clap(version = "1.0")] 12#[clap(version = "1.0")]
@@ -53,11 +49,13 @@ async fn main_task(spawner: Spawner) {
53 let seed = u64::from_le_bytes(seed); 49 let seed = u64::from_le_bytes(seed);
54 50
55 // Init network stack 51 // Init network stack
56 let stack: &Stack<_> = &*make_static!(Stack::new( 52 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
53 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
54 let stack: &Stack<_> = &*STACK.init(Stack::new(
57 device, 55 device,
58 config, 56 config,
59 make_static!(StackResources::<3>::new()), 57 RESOURCES.init(StackResources::<3>::new()),
60 seed 58 seed,
61 )); 59 ));
62 60
63 // Launch network task 61 // Launch network task
diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs
index cee04e558..9ec0ea91f 100644
--- a/examples/std/src/bin/net_ppp.rs
+++ b/examples/std/src/bin/net_ppp.rs
@@ -7,7 +7,6 @@
7//! ping 192.168.7.10 7//! ping 192.168.7.10
8//! nc 192.168.7.10 1234 8//! nc 192.168.7.10 1234
9 9
10#![feature(type_alias_impl_trait)]
11#![allow(async_fn_in_trait)] 10#![allow(async_fn_in_trait)]
12 11
13#[path = "../serial_port.rs"] 12#[path = "../serial_port.rs"]
@@ -25,7 +24,7 @@ use heapless::Vec;
25use log::*; 24use log::*;
26use nix::sys::termios; 25use nix::sys::termios;
27use rand_core::{OsRng, RngCore}; 26use rand_core::{OsRng, RngCore};
28use static_cell::{make_static, StaticCell}; 27use static_cell::StaticCell;
29 28
30use crate::serial_port::SerialPort; 29use crate::serial_port::SerialPort;
31 30
@@ -88,7 +87,8 @@ async fn main_task(spawner: Spawner) {
88 let port = SerialPort::new(opts.device.as_str(), baudrate).unwrap(); 87 let port = SerialPort::new(opts.device.as_str(), baudrate).unwrap();
89 88
90 // Init network device 89 // Init network device
91 let state = make_static!(embassy_net_ppp::State::<4, 4>::new()); 90 static STATE: StaticCell<embassy_net_ppp::State<4, 4>> = StaticCell::new();
91 let state = STATE.init(embassy_net_ppp::State::<4, 4>::new());
92 let (device, runner) = embassy_net_ppp::new(state); 92 let (device, runner) = embassy_net_ppp::new(state);
93 93
94 // Generate random seed 94 // Generate random seed
@@ -97,11 +97,13 @@ async fn main_task(spawner: Spawner) {
97 let seed = u64::from_le_bytes(seed); 97 let seed = u64::from_le_bytes(seed);
98 98
99 // Init network stack 99 // Init network stack
100 let stack = &*make_static!(Stack::new( 100 static STACK: StaticCell<Stack<embassy_net_ppp::Device<'static>>> = StaticCell::new();
101 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
102 let stack = &*STACK.init(Stack::new(
101 device, 103 device,
102 Config::default(), // don't configure IP yet 104 Config::default(), // don't configure IP yet
103 make_static!(StackResources::<3>::new()), 105 RESOURCES.init(StackResources::<3>::new()),
104 seed 106 seed,
105 )); 107 ));
106 108
107 // Launch network task 109 // Launch network task
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index 98dcc9925..bee91990d 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -1,5 +1,3 @@
1#![feature(type_alias_impl_trait)]
2
3use clap::Parser; 1use clap::Parser;
4use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
5use embassy_net::udp::{PacketMetadata, UdpSocket}; 3use embassy_net::udp::{PacketMetadata, UdpSocket};
@@ -8,7 +6,7 @@ use embassy_net_tuntap::TunTapDevice;
8use heapless::Vec; 6use heapless::Vec;
9use log::*; 7use log::*;
10use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, RngCore};
11use static_cell::{make_static, StaticCell}; 9use static_cell::StaticCell;
12 10
13#[derive(Parser)] 11#[derive(Parser)]
14#[clap(version = "1.0")] 12#[clap(version = "1.0")]
@@ -50,11 +48,13 @@ async fn main_task(spawner: Spawner) {
50 let seed = u64::from_le_bytes(seed); 48 let seed = u64::from_le_bytes(seed);
51 49
52 // Init network stack 50 // Init network stack
53 let stack = &*make_static!(Stack::new( 51 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
52 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
53 let stack = &*STACK.init(Stack::new(
54 device, 54 device,
55 config, 55 config,
56 make_static!(StackResources::<3>::new()), 56 RESOURCES.init(StackResources::<3>::new()),
57 seed 57 seed,
58 )); 58 ));
59 59
60 // Launch network task 60 // Launch network task
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index 0b289c74d..10c85511d 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -1,10 +1,9 @@
1#![feature(type_alias_impl_trait)]
2
3#[path = "../serial_port.rs"] 1#[path = "../serial_port.rs"]
4mod serial_port; 2mod serial_port;
5 3
6use async_io::Async; 4use async_io::Async;
7use embassy_executor::Executor; 5use embassy_executor::Executor;
6use embassy_time as _;
8use embedded_io_async::Read; 7use embedded_io_async::Read;
9use log::*; 8use log::*;
10use nix::sys::termios; 9use nix::sys::termios;
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
index 79fa375cd..e8b6eaa6c 100644
--- a/examples/std/src/bin/tcp_accept.rs
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -1,7 +1,4 @@
1#![feature(type_alias_impl_trait)]
2
3use core::fmt::Write as _; 1use core::fmt::Write as _;
4use std::default::Default;
5 2
6use clap::Parser; 3use clap::Parser;
7use embassy_executor::{Executor, Spawner}; 4use embassy_executor::{Executor, Spawner};
@@ -13,7 +10,7 @@ use embedded_io_async::Write as _;
13use heapless::Vec; 10use heapless::Vec;
14use log::*; 11use log::*;
15use rand_core::{OsRng, RngCore}; 12use rand_core::{OsRng, RngCore};
16use static_cell::{make_static, StaticCell}; 13use static_cell::StaticCell;
17 14
18#[derive(Parser)] 15#[derive(Parser)]
19#[clap(version = "1.0")] 16#[clap(version = "1.0")]
@@ -65,11 +62,13 @@ async fn main_task(spawner: Spawner) {
65 let seed = u64::from_le_bytes(seed); 62 let seed = u64::from_le_bytes(seed);
66 63
67 // Init network stack 64 // Init network stack
68 let stack = &*make_static!(Stack::new( 65 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
66 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
67 let stack = &*STACK.init(Stack::new(
69 device, 68 device,
70 config, 69 config,
71 make_static!(StackResources::<3>::new()), 70 RESOURCES.init(StackResources::<3>::new()),
72 seed 71 seed,
73 )); 72 ));
74 73
75 // Launch network task 74 // Launch network task
diff --git a/examples/std/src/bin/tick.rs b/examples/std/src/bin/tick.rs
index a3f99067e..f23cf3549 100644
--- a/examples/std/src/bin/tick.rs
+++ b/examples/std/src/bin/tick.rs
@@ -1,5 +1,3 @@
1#![feature(type_alias_impl_trait)]
2
3use embassy_executor::Spawner; 1use embassy_executor::Spawner;
4use embassy_time::Timer; 2use embassy_time::Timer;
5use log::*; 3use log::*;
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml
index 2d831ba5d..7a3e03b75 100644
--- a/examples/stm32c0/Cargo.toml
+++ b/examples/stm32c0/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
8# Change stm32c031c6 to your chip name, if necessary. 8# Change stm32c031c6 to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13 13
14defmt = "0.3" 14defmt = "0.3"
15defmt-rtt = "0.4" 15defmt-rtt = "0.4"
diff --git a/examples/stm32c0/src/bin/blinky.rs b/examples/stm32c0/src/bin/blinky.rs
index cbeb0dee1..90e479aae 100644
--- a/examples/stm32c0/src/bin/blinky.rs
+++ b/examples/stm32c0/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32c0/src/bin/button.rs b/examples/stm32c0/src/bin/button.rs
index 72a3f5cbf..8017f0274 100644
--- a/examples/stm32c0/src/bin/button.rs
+++ b/examples/stm32c0/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32c0/src/bin/button_exti.rs b/examples/stm32c0/src/bin/button_exti.rs
index ef32d4c4a..34a08bbc6 100644
--- a/examples/stm32c0/src/bin/button_exti.rs
+++ b/examples/stm32c0/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Up); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index 2b066d731..c74980dc4 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -13,11 +13,11 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing
13cortex-m-rt = "0.7.0" 13cortex-m-rt = "0.7.0"
14defmt = "0.3" 14defmt = "0.3"
15defmt-rtt = "0.4" 15defmt-rtt = "0.4"
16panic-probe = "0.3" 16panic-probe = { version = "0.3", features = ["print-defmt"] }
17embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 17embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
18embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 18embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
19embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 19embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
20static_cell = { version = "2", features = ["nightly"]} 20static_cell = "2"
21portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } 21portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] }
22 22
23[profile.release] 23[profile.release]
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs
index 96f234402..c2fb143cd 100644
--- a/examples/stm32f0/src/bin/adc.rs
+++ b/examples/stm32f0/src/bin/adc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -20,7 +19,7 @@ async fn main(_spawner: Spawner) {
20 info!("Hello World!"); 19 info!("Hello World!");
21 20
22 let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); 21 let mut adc = Adc::new(p.ADC, Irqs, &mut Delay);
23 adc.set_sample_time(SampleTime::Cycles71_5); 22 adc.set_sample_time(SampleTime::CYCLES71_5);
24 let mut pin = p.PA1; 23 let mut pin = p.PA1;
25 24
26 let mut vrefint = adc.enable_vref(&mut Delay); 25 let mut vrefint = adc.enable_vref(&mut Delay);
diff --git a/examples/stm32f0/src/bin/blinky.rs b/examples/stm32f0/src/bin/blinky.rs
index 899394546..2572be1bc 100644
--- a/examples/stm32f0/src/bin/blinky.rs
+++ b/examples/stm32f0/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs
index 306df1752..4465483d9 100644
--- a/examples/stm32f0/src/bin/button_controlled_blink.rs
+++ b/examples/stm32f0/src/bin/button_controlled_blink.rs
@@ -2,14 +2,13 @@
2 2
3#![no_std] 3#![no_std]
4#![no_main] 4#![no_main]
5#![feature(type_alias_impl_trait)]
6 5
7use core::sync::atomic::{AtomicU32, Ordering}; 6use core::sync::atomic::{AtomicU32, Ordering};
8 7
9use defmt::info; 8use defmt::info;
10use embassy_executor::Spawner; 9use embassy_executor::Spawner;
11use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
12use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; 11use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Pull, Speed};
13use embassy_time::Timer; 12use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
@@ -37,8 +36,7 @@ async fn main(spawner: Spawner) {
37 36
38 // Configure the button pin and obtain handler. 37 // Configure the button pin and obtain handler.
39 // On the Nucleo F091RC there is a button connected to pin PC13. 38 // On the Nucleo F091RC there is a button connected to pin PC13.
40 let button = Input::new(p.PC13, Pull::None); 39 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::None);
41 let mut button = ExtiInput::new(button, p.EXTI13);
42 40
43 // Create and initialize a delay variable to manage delay loop 41 // Create and initialize a delay variable to manage delay loop
44 let mut del_var = 2000; 42 let mut del_var = 2000;
diff --git a/examples/stm32f0/src/bin/button_exti.rs b/examples/stm32f0/src/bin/button_exti.rs
index 40c0d5848..fd615a215 100644
--- a/examples/stm32f0/src/bin/button_exti.rs
+++ b/examples/stm32f0/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -14,8 +13,7 @@ async fn main(_spawner: Spawner) {
14 let p = embassy_stm32::init(Default::default()); 13 let p = embassy_stm32::init(Default::default());
15 // Configure the button pin and obtain handler. 14 // Configure the button pin and obtain handler.
16 // On the Nucleo F091RC there is a button connected to pin PC13. 15 // On the Nucleo F091RC there is a button connected to pin PC13.
17 let button = Input::new(p.PC13, Pull::Down); 16 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
18 let mut button = ExtiInput::new(button, p.EXTI13);
19 17
20 info!("Press the USER button..."); 18 info!("Press the USER button...");
21 loop { 19 loop {
diff --git a/examples/stm32f0/src/bin/hello.rs b/examples/stm32f0/src/bin/hello.rs
index 0f98d9865..ccd6a0a39 100644
--- a/examples/stm32f0/src/bin/hello.rs
+++ b/examples/stm32f0/src/bin/hello.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f0/src/bin/multiprio.rs b/examples/stm32f0/src/bin/multiprio.rs
index 870c7c45b..e49951726 100644
--- a/examples/stm32f0/src/bin/multiprio.rs
+++ b/examples/stm32f0/src/bin/multiprio.rs
@@ -55,7 +55,6 @@
55 55
56#![no_std] 56#![no_std]
57#![no_main] 57#![no_main]
58#![feature(type_alias_impl_trait)]
59 58
60use cortex_m_rt::entry; 59use cortex_m_rt::entry;
61use defmt::*; 60use defmt::*;
diff --git a/examples/stm32f0/src/bin/wdg.rs b/examples/stm32f0/src/bin/wdg.rs
index b51dee8ee..b974bff91 100644
--- a/examples/stm32f0/src/bin/wdg.rs
+++ b/examples/stm32f0/src/bin/wdg.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml
index f04d41317..4f282f326 100644
--- a/examples/stm32f1/Cargo.toml
+++ b/examples/stm32f1/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
8# Change stm32f103c8 to your chip name, if necessary. 8# Change stm32f103c8 to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any" ] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
@@ -23,6 +23,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
23futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 23futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
24heapless = { version = "0.8", default-features = false } 24heapless = { version = "0.8", default-features = false }
25nb = "1.0.0" 25nb = "1.0.0"
26static_cell = "2.0.0"
26 27
27[profile.dev] 28[profile.dev]
28opt-level = "s" 29opt-level = "s"
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs
index 1edac3d83..1440460a9 100644
--- a/examples/stm32f1/src/bin/adc.rs
+++ b/examples/stm32f1/src/bin/adc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f1/src/bin/blinky.rs b/examples/stm32f1/src/bin/blinky.rs
index 3425b0536..cc43f85f4 100644
--- a/examples/stm32f1/src/bin/blinky.rs
+++ b/examples/stm32f1/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f1/src/bin/can.rs b/examples/stm32f1/src/bin/can.rs
new file mode 100644
index 000000000..90cb9e46b
--- /dev/null
+++ b/examples/stm32f1/src/bin/can.rs
@@ -0,0 +1,143 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::can::{
7 filter, Can, Envelope, Fifo, Frame, Id, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, StandardId,
8 TxInterruptHandler,
9};
10use embassy_stm32::peripherals::CAN;
11use embassy_stm32::{bind_interrupts, Config};
12use static_cell::StaticCell;
13use {defmt_rtt as _, panic_probe as _};
14
15bind_interrupts!(struct Irqs {
16 USB_LP_CAN1_RX0 => Rx0InterruptHandler<CAN>;
17 CAN1_RX1 => Rx1InterruptHandler<CAN>;
18 CAN1_SCE => SceInterruptHandler<CAN>;
19 USB_HP_CAN1_TX => TxInterruptHandler<CAN>;
20});
21
22// This example is configured to work with real CAN transceivers on B8/B9.
23// See other examples for loopback.
24
25fn handle_frame(env: Envelope, read_mode: &str) {
26 match env.frame.id() {
27 Id::Extended(id) => {
28 defmt::println!(
29 "{} Extended Frame id={:x} {:02x}",
30 read_mode,
31 id.as_raw(),
32 env.frame.data()
33 );
34 }
35 Id::Standard(id) => {
36 defmt::println!(
37 "{} Standard Frame id={:x} {:02x}",
38 read_mode,
39 id.as_raw(),
40 env.frame.data()
41 );
42 }
43 }
44}
45
46#[embassy_executor::main]
47async fn main(_spawner: Spawner) {
48 let p = embassy_stm32::init(Config::default());
49
50 // Set alternate pin mapping to B8/B9
51 embassy_stm32::pac::AFIO.mapr().modify(|w| w.set_can1_remap(2));
52
53 static RX_BUF: StaticCell<embassy_stm32::can::RxBuf<10>> = StaticCell::new();
54 static TX_BUF: StaticCell<embassy_stm32::can::TxBuf<10>> = StaticCell::new();
55
56 let mut can = Can::new(p.CAN, p.PB8, p.PB9, Irqs);
57
58 can.as_mut()
59 .modify_filters()
60 .enable_bank(0, Fifo::Fifo0, filter::Mask32::accept_all());
61
62 can.as_mut()
63 .modify_config()
64 .set_loopback(false)
65 .set_silent(false)
66 .leave_disabled();
67
68 can.set_bitrate(250_000);
69
70 can.enable().await;
71 let mut i: u8 = 0;
72
73 /*
74 // Example for using buffered Tx and Rx without needing to
75 // split first as is done below.
76 let mut can = can.buffered(
77 TX_BUF.init(embassy_stm32::can::TxBuf::<10>::new()),
78 RX_BUF.init(embassy_stm32::can::RxBuf::<10>::new()));
79 loop {
80 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
81 can.write(&tx_frame).await;
82
83 match can.read().await {
84 Ok((frame, ts)) => {
85 handle_frame(Envelope { ts, frame }, "Buf");
86 }
87 Err(err) => {
88 defmt::println!("Error {}", err);
89 }
90 }
91 i += 1;
92 }
93
94 */
95 let (mut tx, mut rx) = can.split();
96
97 // This example shows using the wait_not_empty API before try read
98 while i < 3 {
99 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
100 tx.write(&tx_frame).await;
101
102 rx.wait_not_empty().await;
103 let env = rx.try_read().unwrap();
104 handle_frame(env, "Wait");
105 i += 1;
106 }
107
108 // This example shows using the full async non-buffered API
109 while i < 6 {
110 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
111 tx.write(&tx_frame).await;
112
113 match rx.read().await {
114 Ok(env) => {
115 handle_frame(env, "NoBuf");
116 }
117 Err(err) => {
118 defmt::println!("Error {}", err);
119 }
120 }
121 i += 1;
122 }
123
124 // This example shows using buffered RX and TX. User passes in desired buffer (size)
125 // It's possible this way to have just RX or TX buffered.
126 let mut rx = rx.buffered(RX_BUF.init(embassy_stm32::can::RxBuf::<10>::new()));
127 let mut tx = tx.buffered(TX_BUF.init(embassy_stm32::can::TxBuf::<10>::new()));
128
129 loop {
130 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i, 0, 1, 2, 3, 4, 5, 6]).unwrap();
131 tx.write(&tx_frame).await;
132
133 match rx.read().await {
134 Ok(envelope) => {
135 handle_frame(envelope, "Buf");
136 }
137 Err(err) => {
138 defmt::println!("Error {}", err);
139 }
140 }
141 i += 1;
142 }
143}
diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs
index e63bcaae0..3c295612c 100644
--- a/examples/stm32f1/src/bin/hello.rs
+++ b/examples/stm32f1/src/bin/hello.rs
@@ -1,18 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz;
8use embassy_stm32::Config; 6use embassy_stm32::Config;
9use embassy_time::Timer; 7use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12#[embassy_executor::main] 10#[embassy_executor::main]
13async fn main(_spawner: Spawner) -> ! { 11async fn main(_spawner: Spawner) -> ! {
14 let mut config = Config::default(); 12 let config = Config::default();
15 config.rcc.sys_ck = Some(Hertz(36_000_000));
16 let _p = embassy_stm32::init(config); 13 let _p = embassy_stm32::init(config);
17 14
18 loop { 15 loop {
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs
index 31519555f..ee99acf41 100644
--- a/examples/stm32f1/src/bin/usb_serial.rs
+++ b/examples/stm32f1/src/bin/usb_serial.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -22,9 +21,23 @@ bind_interrupts!(struct Irqs {
22#[embassy_executor::main] 21#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
24 let mut config = Config::default(); 23 let mut config = Config::default();
25 config.rcc.hse = Some(Hertz(8_000_000)); 24 {
26 config.rcc.sys_ck = Some(Hertz(48_000_000)); 25 use embassy_stm32::rcc::*;
27 config.rcc.pclk1 = Some(Hertz(24_000_000)); 26 config.rcc.hse = Some(Hse {
27 freq: Hertz(8_000_000),
28 // Oscillator for bluepill, Bypass for nucleos.
29 mode: HseMode::Oscillator,
30 });
31 config.rcc.pll = Some(Pll {
32 src: PllSource::HSE,
33 prediv: PllPreDiv::DIV1,
34 mul: PllMul::MUL9,
35 });
36 config.rcc.sys = Sysclk::PLL1_P;
37 config.rcc.ahb_pre = AHBPrescaler::DIV1;
38 config.rcc.apb1_pre = APBPrescaler::DIV2;
39 config.rcc.apb2_pre = APBPrescaler::DIV1;
40 }
28 let mut p = embassy_stm32::init(config); 41 let mut p = embassy_stm32::init(config);
29 42
30 info!("Hello World!"); 43 info!("Hello World!");
@@ -47,7 +60,6 @@ async fn main(_spawner: Spawner) {
47 60
48 // Create embassy-usb DeviceBuilder using the driver and config. 61 // Create embassy-usb DeviceBuilder using the driver and config.
49 // It needs some buffers for building the descriptors. 62 // It needs some buffers for building the descriptors.
50 let mut device_descriptor = [0; 256];
51 let mut config_descriptor = [0; 256]; 63 let mut config_descriptor = [0; 256];
52 let mut bos_descriptor = [0; 256]; 64 let mut bos_descriptor = [0; 256];
53 let mut control_buf = [0; 7]; 65 let mut control_buf = [0; 7];
@@ -57,7 +69,6 @@ async fn main(_spawner: Spawner) {
57 let mut builder = Builder::new( 69 let mut builder = Builder::new(
58 driver, 70 driver,
59 config, 71 config,
60 &mut device_descriptor,
61 &mut config_descriptor, 72 &mut config_descriptor,
62 &mut bos_descriptor, 73 &mut bos_descriptor,
63 &mut [], // no msos descriptors 74 &mut [], // no msos descriptors
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml
index 66cc1e15b..4cbf1dc84 100644
--- a/examples/stm32f2/Cargo.toml
+++ b/examples/stm32f2/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
8# Change stm32f207zg to your chip name, if necessary. 8# Change stm32f207zg to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13 13
14defmt = "0.3" 14defmt = "0.3"
15defmt-rtt = "0.4" 15defmt-rtt = "0.4"
diff --git a/examples/stm32f2/src/bin/blinky.rs b/examples/stm32f2/src/bin/blinky.rs
index f6d7a0005..d9833ba8b 100644
--- a/examples/stm32f2/src/bin/blinky.rs
+++ b/examples/stm32f2/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs
index aae7637dc..e39e2daec 100644
--- a/examples/stm32f2/src/bin/pll.rs
+++ b/examples/stm32f2/src/bin/pll.rs
@@ -1,8 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use core::convert::TryFrom;
6 3
7use defmt::*; 4use defmt::*;
8use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml
index ed1367858..64bb2e560 100644
--- a/examples/stm32f3/Cargo.toml
+++ b/examples/stm32f3/Cargo.toml
@@ -8,8 +8,8 @@ license = "MIT OR Apache-2.0"
8# Change stm32f303ze to your chip name, if necessary. 8# Change stm32f303ze to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15 15
@@ -24,7 +24,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
24heapless = { version = "0.8", default-features = false } 24heapless = { version = "0.8", default-features = false }
25nb = "1.0.0" 25nb = "1.0.0"
26embedded-storage = "0.3.1" 26embedded-storage = "0.3.1"
27static_cell = { version = "2", features = ["nightly"]} 27static_cell = "2"
28 28
29[profile.release] 29[profile.release]
30debug = 2 30debug = 2
diff --git a/examples/stm32f3/src/bin/blinky.rs b/examples/stm32f3/src/bin/blinky.rs
index e71031b30..0ea10522d 100644
--- a/examples/stm32f3/src/bin/blinky.rs
+++ b/examples/stm32f3/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f3/src/bin/button.rs b/examples/stm32f3/src/bin/button.rs
index b55bf3901..406730aae 100644
--- a/examples/stm32f3/src/bin/button.rs
+++ b/examples/stm32f3/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs
index 9df6d680d..f5ed5d2c9 100644
--- a/examples/stm32f3/src/bin/button_events.rs
+++ b/examples/stm32f3/src/bin/button_events.rs
@@ -8,26 +8,24 @@
8 8
9#![no_std] 9#![no_std]
10#![no_main] 10#![no_main]
11#![feature(type_alias_impl_trait)]
12 11
13use defmt::*; 12use defmt::*;
14use embassy_executor::Spawner; 13use embassy_executor::Spawner;
15use embassy_stm32::exti::ExtiInput; 14use embassy_stm32::exti::ExtiInput;
16use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; 15use embassy_stm32::gpio::{Level, Output, Pull, Speed};
17use embassy_stm32::peripherals::PA0;
18use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 16use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
19use embassy_sync::channel::Channel; 17use embassy_sync::channel::Channel;
20use embassy_time::{with_timeout, Duration, Timer}; 18use embassy_time::{with_timeout, Duration, Timer};
21use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
22 20
23struct Leds<'a> { 21struct Leds<'a> {
24 leds: [Output<'a, AnyPin>; 8], 22 leds: [Output<'a>; 8],
25 direction: i8, 23 direction: i8,
26 current_led: usize, 24 current_led: usize,
27} 25}
28 26
29impl<'a> Leds<'a> { 27impl<'a> Leds<'a> {
30 fn new(pins: [Output<'a, AnyPin>; 8]) -> Self { 28 fn new(pins: [Output<'a>; 8]) -> Self {
31 Self { 29 Self {
32 leds: pins, 30 leds: pins,
33 direction: 1, 31 direction: 1,
@@ -101,18 +99,17 @@ static CHANNEL: Channel<ThreadModeRawMutex, ButtonEvent, 4> = Channel::new();
101#[embassy_executor::main] 99#[embassy_executor::main]
102async fn main(spawner: Spawner) { 100async fn main(spawner: Spawner) {
103 let p = embassy_stm32::init(Default::default()); 101 let p = embassy_stm32::init(Default::default());
104 let button = Input::new(p.PA0, Pull::Down); 102 let button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down);
105 let button = ExtiInput::new(button, p.EXTI0);
106 info!("Press the USER button..."); 103 info!("Press the USER button...");
107 let leds = [ 104 let leds = [
108 Output::new(p.PE9.degrade(), Level::Low, Speed::Low), 105 Output::new(p.PE9, Level::Low, Speed::Low),
109 Output::new(p.PE10.degrade(), Level::Low, Speed::Low), 106 Output::new(p.PE10, Level::Low, Speed::Low),
110 Output::new(p.PE11.degrade(), Level::Low, Speed::Low), 107 Output::new(p.PE11, Level::Low, Speed::Low),
111 Output::new(p.PE12.degrade(), Level::Low, Speed::Low), 108 Output::new(p.PE12, Level::Low, Speed::Low),
112 Output::new(p.PE13.degrade(), Level::Low, Speed::Low), 109 Output::new(p.PE13, Level::Low, Speed::Low),
113 Output::new(p.PE14.degrade(), Level::Low, Speed::Low), 110 Output::new(p.PE14, Level::Low, Speed::Low),
114 Output::new(p.PE15.degrade(), Level::Low, Speed::Low), 111 Output::new(p.PE15, Level::Low, Speed::Low),
115 Output::new(p.PE8.degrade(), Level::Low, Speed::Low), 112 Output::new(p.PE8, Level::Low, Speed::Low),
116 ]; 113 ];
117 let leds = Leds::new(leds); 114 let leds = Leds::new(leds);
118 115
@@ -128,7 +125,7 @@ async fn led_blinker(mut leds: Leds<'static>) {
128} 125}
129 126
130#[embassy_executor::task] 127#[embassy_executor::task]
131async fn button_waiter(mut button: ExtiInput<'static, PA0>) { 128async fn button_waiter(mut button: ExtiInput<'static>) {
132 const DOUBLE_CLICK_DELAY: u64 = 250; 129 const DOUBLE_CLICK_DELAY: u64 = 250;
133 const HOLD_DELAY: u64 = 1000; 130 const HOLD_DELAY: u64 = 1000;
134 131
diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs
index 1266778c1..a55530e0e 100644
--- a/examples/stm32f3/src/bin/button_exti.rs
+++ b/examples/stm32f3/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PA0, Pull::Down); 15 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI0);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32f3/src/bin/flash.rs b/examples/stm32f3/src/bin/flash.rs
index 236fb36c1..28125697d 100644
--- a/examples/stm32f3/src/bin/flash.rs
+++ b/examples/stm32f3/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f3/src/bin/hello.rs b/examples/stm32f3/src/bin/hello.rs
index b3285f3c1..3c295612c 100644
--- a/examples/stm32f3/src/bin/hello.rs
+++ b/examples/stm32f3/src/bin/hello.rs
@@ -1,19 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz;
8use embassy_stm32::Config; 6use embassy_stm32::Config;
9use embassy_time::Timer; 7use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12#[embassy_executor::main] 10#[embassy_executor::main]
13async fn main(_spawner: Spawner) -> ! { 11async fn main(_spawner: Spawner) -> ! {
14 let mut config = Config::default(); 12 let config = Config::default();
15 config.rcc.hse = Some(Hertz(8_000_000));
16 config.rcc.sysclk = Some(Hertz(16_000_000));
17 let _p = embassy_stm32::init(config); 13 let _p = embassy_stm32::init(config);
18 14
19 loop { 15 loop {
diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs
index 74f3bb1c5..328447210 100644
--- a/examples/stm32f3/src/bin/multiprio.rs
+++ b/examples/stm32f3/src/bin/multiprio.rs
@@ -55,7 +55,6 @@
55 55
56#![no_std] 56#![no_std]
57#![no_main] 57#![no_main]
58#![feature(type_alias_impl_trait)]
59 58
60use cortex_m_rt::entry; 59use cortex_m_rt::entry;
61use defmt::*; 60use defmt::*;
diff --git a/examples/stm32f3/src/bin/spi_dma.rs b/examples/stm32f3/src/bin/spi_dma.rs
index a27c1d547..54498d53d 100644
--- a/examples/stm32f3/src/bin/spi_dma.rs
+++ b/examples/stm32f3/src/bin/spi_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6use core::str::from_utf8; 5use core::str::from_utf8;
diff --git a/examples/stm32f3/src/bin/usart_dma.rs b/examples/stm32f3/src/bin/usart_dma.rs
index ce8c212ae..5234e53b9 100644
--- a/examples/stm32f3/src/bin/usart_dma.rs
+++ b/examples/stm32f3/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs
index d5d068d62..5760f2c1c 100644
--- a/examples/stm32f3/src/bin/usb_serial.rs
+++ b/examples/stm32f3/src/bin/usb_serial.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -22,11 +21,22 @@ bind_interrupts!(struct Irqs {
22#[embassy_executor::main] 21#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
24 let mut config = Config::default(); 23 let mut config = Config::default();
25 config.rcc.hse = Some(mhz(8)); 24 {
26 config.rcc.sysclk = Some(mhz(48)); 25 use embassy_stm32::rcc::*;
27 config.rcc.pclk1 = Some(mhz(24)); 26 config.rcc.hse = Some(Hse {
28 config.rcc.pclk2 = Some(mhz(24)); 27 freq: mhz(8),
29 config.rcc.pll48 = true; 28 mode: HseMode::Bypass,
29 });
30 config.rcc.pll = Some(Pll {
31 src: PllSource::HSE,
32 prediv: PllPreDiv::DIV1,
33 mul: PllMul::MUL9,
34 });
35 config.rcc.sys = Sysclk::PLL1_P;
36 config.rcc.ahb_pre = AHBPrescaler::DIV1;
37 config.rcc.apb1_pre = APBPrescaler::DIV2;
38 config.rcc.apb2_pre = APBPrescaler::DIV1;
39 }
30 let p = embassy_stm32::init(config); 40 let p = embassy_stm32::init(config);
31 41
32 info!("Hello World!"); 42 info!("Hello World!");
@@ -44,7 +54,6 @@ async fn main(_spawner: Spawner) {
44 54
45 // Create embassy-usb DeviceBuilder using the driver and config. 55 // Create embassy-usb DeviceBuilder using the driver and config.
46 // It needs some buffers for building the descriptors. 56 // It needs some buffers for building the descriptors.
47 let mut device_descriptor = [0; 256];
48 let mut config_descriptor = [0; 256]; 57 let mut config_descriptor = [0; 256];
49 let mut bos_descriptor = [0; 256]; 58 let mut bos_descriptor = [0; 256];
50 let mut control_buf = [0; 7]; 59 let mut control_buf = [0; 7];
@@ -54,7 +63,6 @@ async fn main(_spawner: Spawner) {
54 let mut builder = Builder::new( 63 let mut builder = Builder::new(
55 driver, 64 driver,
56 config, 65 config,
57 &mut device_descriptor,
58 &mut config_descriptor, 66 &mut config_descriptor,
59 &mut bos_descriptor, 67 &mut bos_descriptor,
60 &mut [], // no msos descriptors 68 &mut [], // no msos descriptors
diff --git a/examples/stm32f334/Cargo.toml b/examples/stm32f334/Cargo.toml
index 320cf7d7b..3e5a7cc8c 100644
--- a/examples/stm32f334/Cargo.toml
+++ b/examples/stm32f334/Cargo.toml
@@ -6,8 +6,8 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.2.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f334r8", "unstable-pac", "memory-x", "time-driver-any", "exti"] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 13embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
@@ -23,4 +23,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
23heapless = { version = "0.8", default-features = false } 23heapless = { version = "0.8", default-features = false }
24nb = "1.0.0" 24nb = "1.0.0"
25embedded-storage = "0.3.1" 25embedded-storage = "0.3.1"
26static_cell = { version = "2", features = ["nightly"]} 26static_cell = "2"
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs
index f259135d2..bd126ce68 100644
--- a/examples/stm32f334/src/bin/adc.rs
+++ b/examples/stm32f334/src/bin/adc.rs
@@ -1,12 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
8use embassy_stm32::peripherals::ADC1; 7use embassy_stm32::peripherals::ADC1;
9use embassy_stm32::rcc::{AdcClockSource, Adcpres};
10use embassy_stm32::time::mhz; 8use embassy_stm32::time::mhz;
11use embassy_stm32::{adc, bind_interrupts, Config}; 9use embassy_stm32::{adc, bind_interrupts, Config};
12use embassy_time::{Delay, Timer}; 10use embassy_time::{Delay, Timer};
@@ -19,19 +17,30 @@ bind_interrupts!(struct Irqs {
19#[embassy_executor::main] 17#[embassy_executor::main]
20async fn main(_spawner: Spawner) -> ! { 18async fn main(_spawner: Spawner) -> ! {
21 let mut config = Config::default(); 19 let mut config = Config::default();
22 config.rcc.sysclk = Some(mhz(64)); 20 {
23 config.rcc.hclk = Some(mhz(64)); 21 use embassy_stm32::rcc::*;
24 config.rcc.pclk1 = Some(mhz(32)); 22 config.rcc.hse = Some(Hse {
25 config.rcc.pclk2 = Some(mhz(64)); 23 freq: mhz(8),
26 config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); 24 mode: HseMode::Bypass,
27 25 });
26 config.rcc.pll = Some(Pll {
27 src: PllSource::HSE,
28 prediv: PllPreDiv::DIV1,
29 mul: PllMul::MUL9,
30 });
31 config.rcc.sys = Sysclk::PLL1_P;
32 config.rcc.ahb_pre = AHBPrescaler::DIV1;
33 config.rcc.apb1_pre = APBPrescaler::DIV2;
34 config.rcc.apb2_pre = APBPrescaler::DIV1;
35 config.rcc.adc = AdcClockSource::Pll(AdcPllPrescaler::DIV1);
36 }
28 let mut p = embassy_stm32::init(config); 37 let mut p = embassy_stm32::init(config);
29 38
30 info!("create adc..."); 39 info!("create adc...");
31 40
32 let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay); 41 let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay);
33 42
34 adc.set_sample_time(SampleTime::Cycles601_5); 43 adc.set_sample_time(SampleTime::CYCLES601_5);
35 44
36 info!("enable vrefint..."); 45 info!("enable vrefint...");
37 46
diff --git a/examples/stm32f334/src/bin/button.rs b/examples/stm32f334/src/bin/button.rs
index 501fb080c..256f9a44a 100644
--- a/examples/stm32f334/src/bin/button.rs
+++ b/examples/stm32f334/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f334/src/bin/hello.rs b/examples/stm32f334/src/bin/hello.rs
index b3285f3c1..3c295612c 100644
--- a/examples/stm32f334/src/bin/hello.rs
+++ b/examples/stm32f334/src/bin/hello.rs
@@ -1,19 +1,15 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz;
8use embassy_stm32::Config; 6use embassy_stm32::Config;
9use embassy_time::Timer; 7use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
11 9
12#[embassy_executor::main] 10#[embassy_executor::main]
13async fn main(_spawner: Spawner) -> ! { 11async fn main(_spawner: Spawner) -> ! {
14 let mut config = Config::default(); 12 let config = Config::default();
15 config.rcc.hse = Some(Hertz(8_000_000));
16 config.rcc.sysclk = Some(Hertz(16_000_000));
17 let _p = embassy_stm32::init(config); 13 let _p = embassy_stm32::init(config);
18 14
19 loop { 15 loop {
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs
index 10e7b3543..a5c710aa2 100644
--- a/examples/stm32f334/src/bin/opamp.rs
+++ b/examples/stm32f334/src/bin/opamp.rs
@@ -1,13 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
8use embassy_stm32::opamp::{OpAmp, OpAmpGain}; 7use embassy_stm32::opamp::{OpAmp, OpAmpGain};
9use embassy_stm32::peripherals::ADC2; 8use embassy_stm32::peripherals::ADC2;
10use embassy_stm32::rcc::{AdcClockSource, Adcpres};
11use embassy_stm32::time::mhz; 9use embassy_stm32::time::mhz;
12use embassy_stm32::{adc, bind_interrupts, Config}; 10use embassy_stm32::{adc, bind_interrupts, Config};
13use embassy_time::{Delay, Timer}; 11use embassy_time::{Delay, Timer};
@@ -20,12 +18,23 @@ bind_interrupts!(struct Irqs {
20#[embassy_executor::main] 18#[embassy_executor::main]
21async fn main(_spawner: Spawner) -> ! { 19async fn main(_spawner: Spawner) -> ! {
22 let mut config = Config::default(); 20 let mut config = Config::default();
23 config.rcc.sysclk = Some(mhz(64)); 21 {
24 config.rcc.hclk = Some(mhz(64)); 22 use embassy_stm32::rcc::*;
25 config.rcc.pclk1 = Some(mhz(32)); 23 config.rcc.hse = Some(Hse {
26 config.rcc.pclk2 = Some(mhz(64)); 24 freq: mhz(8),
27 config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); 25 mode: HseMode::Bypass,
28 26 });
27 config.rcc.pll = Some(Pll {
28 src: PllSource::HSE,
29 prediv: PllPreDiv::DIV1,
30 mul: PllMul::MUL9,
31 });
32 config.rcc.sys = Sysclk::PLL1_P;
33 config.rcc.ahb_pre = AHBPrescaler::DIV1;
34 config.rcc.apb1_pre = APBPrescaler::DIV2;
35 config.rcc.apb2_pre = APBPrescaler::DIV1;
36 config.rcc.adc = AdcClockSource::Pll(AdcPllPrescaler::DIV1);
37 }
29 let mut p = embassy_stm32::init(config); 38 let mut p = embassy_stm32::init(config);
30 39
31 info!("create adc..."); 40 info!("create adc...");
@@ -33,7 +42,7 @@ async fn main(_spawner: Spawner) -> ! {
33 let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); 42 let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay);
34 let mut opamp = OpAmp::new(p.OPAMP2); 43 let mut opamp = OpAmp::new(p.OPAMP2);
35 44
36 adc.set_sample_time(SampleTime::Cycles601_5); 45 adc.set_sample_time(SampleTime::CYCLES601_5);
37 46
38 info!("enable vrefint..."); 47 info!("enable vrefint...");
39 48
diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs
index 8040c3f18..e6d1a6c02 100644
--- a/examples/stm32f334/src/bin/pwm.rs
+++ b/examples/stm32f334/src/bin/pwm.rs
@@ -1,11 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::hrtim::*; 6use embassy_stm32::hrtim::*;
8use embassy_stm32::rcc::HrtimClockSource;
9use embassy_stm32::time::{khz, mhz}; 7use embassy_stm32::time::{khz, mhz};
10use embassy_stm32::Config; 8use embassy_stm32::Config;
11use embassy_time::Timer; 9use embassy_time::Timer;
@@ -13,14 +11,27 @@ use {defmt_rtt as _, panic_probe as _};
13 11
14#[embassy_executor::main] 12#[embassy_executor::main]
15async fn main(_spawner: Spawner) { 13async fn main(_spawner: Spawner) {
16 let mut config: Config = Default::default(); 14 let mut config = Config::default();
17 config.rcc.sysclk = Some(mhz(64)); 15 {
18 config.rcc.hclk = Some(mhz(64)); 16 use embassy_stm32::rcc::*;
19 config.rcc.pclk1 = Some(mhz(32)); 17 config.rcc.hse = Some(Hse {
20 config.rcc.pclk2 = Some(mhz(64)); 18 freq: mhz(8),
21 config.rcc.hrtim = HrtimClockSource::PllClk; 19 mode: HseMode::Bypass,
20 });
21 config.rcc.pll = Some(Pll {
22 src: PllSource::HSE,
23 prediv: PllPreDiv::DIV1,
24 mul: PllMul::MUL9,
25 });
26 config.rcc.sys = Sysclk::PLL1_P;
27 config.rcc.ahb_pre = AHBPrescaler::DIV1;
28 config.rcc.apb1_pre = APBPrescaler::DIV2;
29 config.rcc.apb2_pre = APBPrescaler::DIV1;
22 30
31 config.rcc.mux.hrtim1sw = embassy_stm32::rcc::mux::Timsw::PLL1_P;
32 }
23 let p = embassy_stm32::init(config); 33 let p = embassy_stm32::init(config);
34
24 info!("Hello World!"); 35 info!("Hello World!");
25 36
26 let ch1 = PwmPin::new_cha(p.PA8); 37 let ch1 = PwmPin::new_cha(p.PA8);
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index 6ea0018cd..512158bef 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -6,12 +6,12 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f429zi to your chip name, if necessary. 8# Change stm32f429zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "chrono"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt" ] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt" ] }
14embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } 14embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
15 15
16defmt = "0.3" 16defmt = "0.3"
17defmt-rtt = "0.4" 17defmt-rtt = "0.4"
@@ -27,7 +27,8 @@ heapless = { version = "0.8", default-features = false }
27nb = "1.0.0" 27nb = "1.0.0"
28embedded-storage = "0.3.1" 28embedded-storage = "0.3.1"
29micromath = "2.0.0" 29micromath = "2.0.0"
30static_cell = { version = "2", features = ["nightly"]} 30usbd-hid = "0.7.0"
31static_cell = "2"
31chrono = { version = "^0.4", default-features = false} 32chrono = { version = "^0.4", default-features = false}
32 33
33[profile.release] 34[profile.release]
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index f19328727..699c29c05 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs; 4use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f4/src/bin/blinky.rs b/examples/stm32f4/src/bin/blinky.rs
index 4bfc5a50d..31cce8225 100644
--- a/examples/stm32f4/src/bin/blinky.rs
+++ b/examples/stm32f4/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/button.rs b/examples/stm32f4/src/bin/button.rs
index b13e64531..564908998 100644
--- a/examples/stm32f4/src/bin/button.rs
+++ b/examples/stm32f4/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs
index dfe587d41..2a546dac5 100644
--- a/examples/stm32f4/src/bin/button_exti.rs
+++ b/examples/stm32f4/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32f4/src/bin/can.rs b/examples/stm32f4/src/bin/can.rs
index 20ce4edce..71b9453eb 100644
--- a/examples/stm32f4/src/bin/can.rs
+++ b/examples/stm32f4/src/bin/can.rs
@@ -1,13 +1,13 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts; 6use embassy_stm32::bind_interrupts;
8use embassy_stm32::can::bxcan::filter::Mask32; 7use embassy_stm32::can::filter::Mask32;
9use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; 8use embassy_stm32::can::{
10use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; 9 Can, Fifo, Frame, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, StandardId, TxInterruptHandler,
10};
11use embassy_stm32::gpio::{Input, Pull}; 11use embassy_stm32::gpio::{Input, Pull};
12use embassy_stm32::peripherals::CAN1; 12use embassy_stm32::peripherals::CAN1;
13use embassy_time::Instant; 13use embassy_time::Instant;
@@ -51,7 +51,7 @@ async fn main(_spawner: Spawner) {
51 51
52 let mut i: u8 = 0; 52 let mut i: u8 = 0;
53 loop { 53 loop {
54 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), [i]); 54 let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap();
55 let tx_ts = Instant::now(); 55 let tx_ts = Instant::now();
56 can.write(&tx_frame).await; 56 can.write(&tx_frame).await;
57 57
@@ -65,7 +65,7 @@ async fn main(_spawner: Spawner) {
65 65
66 info!( 66 info!(
67 "loopback frame {=u8}, latency: {} us", 67 "loopback frame {=u8}, latency: {} us",
68 unwrap!(envelope.frame.data())[0], 68 envelope.frame.data()[0],
69 latency.as_micros() 69 latency.as_micros()
70 ); 70 );
71 i += 1; 71 i += 1;
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs
index 8f14d6078..9c7754c4f 100644
--- a/examples/stm32f4/src/bin/dac.rs
+++ b/examples/stm32f4/src/bin/dac.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs
index 088d83c06..7f5c8fdb1 100644
--- a/examples/stm32f4/src/bin/eth.rs
+++ b/examples/stm32f4/src/bin/eth.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -14,7 +13,7 @@ use embassy_stm32::time::Hertz;
14use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; 13use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
15use embassy_time::Timer; 14use embassy_time::Timer;
16use embedded_io_async::Write; 15use embedded_io_async::Write;
17use static_cell::make_static; 16use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
20bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -63,8 +62,9 @@ async fn main(spawner: Spawner) -> ! {
63 62
64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 63 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
65 64
65 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
66 let device = Ethernet::new( 66 let device = Ethernet::new(
67 make_static!(PacketQueue::<16, 16>::new()), 67 PACKETS.init(PacketQueue::<16, 16>::new()),
68 p.ETH, 68 p.ETH,
69 Irqs, 69 Irqs,
70 p.PA1, 70 p.PA1,
@@ -88,11 +88,13 @@ async fn main(spawner: Spawner) -> ! {
88 //}); 88 //});
89 89
90 // Init network stack 90 // Init network stack
91 let stack = &*make_static!(Stack::new( 91 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
92 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
93 let stack = &*STACK.init(Stack::new(
92 device, 94 device,
93 config, 95 config,
94 make_static!(StackResources::<2>::new()), 96 RESOURCES.init(StackResources::<2>::new()),
95 seed 97 seed,
96 )); 98 ));
97 99
98 // Launch network task 100 // Launch network task
diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs
index 93c54e943..1e8cabab4 100644
--- a/examples/stm32f4/src/bin/flash.rs
+++ b/examples/stm32f4/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -31,7 +30,7 @@ fn test_flash(f: &mut Flash<'_, Blocking>, offset: u32, size: u32) {
31 30
32 info!("Reading..."); 31 info!("Reading...");
33 let mut buf = [0u8; 32]; 32 let mut buf = [0u8; 32];
34 unwrap!(f.read(offset, &mut buf)); 33 unwrap!(f.blocking_read(offset, &mut buf));
35 info!("Read: {=[u8]:x}", buf); 34 info!("Read: {=[u8]:x}", buf);
36 35
37 info!("Erasing..."); 36 info!("Erasing...");
@@ -39,7 +38,7 @@ fn test_flash(f: &mut Flash<'_, Blocking>, offset: u32, size: u32) {
39 38
40 info!("Reading..."); 39 info!("Reading...");
41 let mut buf = [0u8; 32]; 40 let mut buf = [0u8; 32];
42 unwrap!(f.read(offset, &mut buf)); 41 unwrap!(f.blocking_read(offset, &mut buf));
43 info!("Read after erase: {=[u8]:x}", buf); 42 info!("Read after erase: {=[u8]:x}", buf);
44 43
45 info!("Writing..."); 44 info!("Writing...");
@@ -53,7 +52,7 @@ fn test_flash(f: &mut Flash<'_, Blocking>, offset: u32, size: u32) {
53 52
54 info!("Reading..."); 53 info!("Reading...");
55 let mut buf = [0u8; 32]; 54 let mut buf = [0u8; 32];
56 unwrap!(f.read(offset, &mut buf)); 55 unwrap!(f.blocking_read(offset, &mut buf));
57 info!("Read: {=[u8]:x}", buf); 56 info!("Read: {=[u8]:x}", buf);
58 assert_eq!( 57 assert_eq!(
59 &buf[..], 58 &buf[..],
diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs
index f0a65a725..493a536f3 100644
--- a/examples/stm32f4/src/bin/flash_async.rs
+++ b/examples/stm32f4/src/bin/flash_async.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -48,7 +47,7 @@ async fn test_flash<'a>(f: &mut Flash<'a>, offset: u32, size: u32) {
48 47
49 info!("Reading..."); 48 info!("Reading...");
50 let mut buf = [0u8; 32]; 49 let mut buf = [0u8; 32];
51 unwrap!(f.read(offset, &mut buf)); 50 unwrap!(f.blocking_read(offset, &mut buf));
52 info!("Read: {=[u8]:x}", buf); 51 info!("Read: {=[u8]:x}", buf);
53 52
54 info!("Erasing..."); 53 info!("Erasing...");
@@ -56,7 +55,7 @@ async fn test_flash<'a>(f: &mut Flash<'a>, offset: u32, size: u32) {
56 55
57 info!("Reading..."); 56 info!("Reading...");
58 let mut buf = [0u8; 32]; 57 let mut buf = [0u8; 32];
59 unwrap!(f.read(offset, &mut buf)); 58 unwrap!(f.blocking_read(offset, &mut buf));
60 info!("Read after erase: {=[u8]:x}", buf); 59 info!("Read after erase: {=[u8]:x}", buf);
61 60
62 info!("Writing..."); 61 info!("Writing...");
@@ -73,7 +72,7 @@ async fn test_flash<'a>(f: &mut Flash<'a>, offset: u32, size: u32) {
73 72
74 info!("Reading..."); 73 info!("Reading...");
75 let mut buf = [0u8; 32]; 74 let mut buf = [0u8; 32];
76 unwrap!(f.read(offset, &mut buf)); 75 unwrap!(f.blocking_read(offset, &mut buf));
77 info!("Read: {=[u8]:x}", buf); 76 info!("Read: {=[u8]:x}", buf);
78 assert_eq!( 77 assert_eq!(
79 &buf[..], 78 &buf[..],
diff --git a/examples/stm32f4/src/bin/hello.rs b/examples/stm32f4/src/bin/hello.rs
index a2a287110..3c295612c 100644
--- a/examples/stm32f4/src/bin/hello.rs
+++ b/examples/stm32f4/src/bin/hello.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/i2c.rs b/examples/stm32f4/src/bin/i2c.rs
index 4f4adde28..4b5da774d 100644
--- a/examples/stm32f4/src/bin/i2c.rs
+++ b/examples/stm32f4/src/bin/i2c.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/i2c_async.rs b/examples/stm32f4/src/bin/i2c_async.rs
index 9f59e4d41..90d11d4b4 100644
--- a/examples/stm32f4/src/bin/i2c_async.rs
+++ b/examples/stm32f4/src/bin/i2c_async.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5// Example originally designed for stm32f411ceu6 reading an A1454 hall effect sensor on I2C1 4// Example originally designed for stm32f411ceu6 reading an A1454 hall effect sensor on I2C1
6// DMA peripherals changed to compile for stm32f429zi, for the CI. 5// DMA peripherals changed to compile for stm32f429zi, for the CI.
diff --git a/examples/stm32f4/src/bin/i2c_comparison.rs b/examples/stm32f4/src/bin/i2c_comparison.rs
index 6d23c0ed8..30cfbdf57 100644
--- a/examples/stm32f4/src/bin/i2c_comparison.rs
+++ b/examples/stm32f4/src/bin/i2c_comparison.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5// Example originally designed for stm32f411ceu6 with three A1454 hall effect sensors, connected to I2C1, 2 and 3 4// Example originally designed for stm32f411ceu6 with three A1454 hall effect sensors, connected to I2C1, 2 and 3
6// on the pins referenced in the peripheral definitions. 5// on the pins referenced in the peripheral definitions.
diff --git a/examples/stm32f4/src/bin/i2s_dma.rs b/examples/stm32f4/src/bin/i2s_dma.rs
index e8d7b5f77..97a04b2aa 100644
--- a/examples/stm32f4/src/bin/i2s_dma.rs
+++ b/examples/stm32f4/src/bin/i2s_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs
index 3315e7652..eb7bb6261 100644
--- a/examples/stm32f4/src/bin/mco.rs
+++ b/examples/stm32f4/src/bin/mco.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs
index 74f3bb1c5..328447210 100644
--- a/examples/stm32f4/src/bin/multiprio.rs
+++ b/examples/stm32f4/src/bin/multiprio.rs
@@ -55,7 +55,6 @@
55 55
56#![no_std] 56#![no_std]
57#![no_main] 57#![no_main]
58#![feature(type_alias_impl_trait)]
59 58
60use cortex_m_rt::entry; 59use cortex_m_rt::entry;
61use defmt::*; 60use defmt::*;
diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs
index 8e41d0e78..8844a9f0e 100644
--- a/examples/stm32f4/src/bin/pwm.rs
+++ b/examples/stm32f4/src/bin/pwm.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs
index d925f26d9..161f43c48 100644
--- a/examples/stm32f4/src/bin/pwm_complementary.rs
+++ b/examples/stm32f4/src/bin/pwm_complementary.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs
index 44b4303c0..82d8a37ba 100644
--- a/examples/stm32f4/src/bin/rtc.rs
+++ b/examples/stm32f4/src/bin/rtc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use chrono::{NaiveDate, NaiveDateTime}; 4use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 5use defmt::*;
@@ -29,7 +28,7 @@ async fn main(_spawner: Spawner) {
29 loop { 28 loop {
30 let now: NaiveDateTime = rtc.now().unwrap().into(); 29 let now: NaiveDateTime = rtc.now().unwrap().into();
31 30
32 info!("{}", now.timestamp()); 31 info!("{}", now.and_utc().timestamp());
33 32
34 Timer::after_millis(1000).await; 33 Timer::after_millis(1000).await;
35 } 34 }
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index 91747b2d5..66e4e527c 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/spi.rs b/examples/stm32f4/src/bin/spi.rs
index 0919e9874..dc9141c62 100644
--- a/examples/stm32f4/src/bin/spi.rs
+++ b/examples/stm32f4/src/bin/spi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f4/src/bin/spi_dma.rs b/examples/stm32f4/src/bin/spi_dma.rs
index f291f7dba..7249c831a 100644
--- a/examples/stm32f4/src/bin/spi_dma.rs
+++ b/examples/stm32f4/src/bin/spi_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6use core::str::from_utf8; 5use core::str::from_utf8;
diff --git a/examples/stm32f4/src/bin/usart.rs b/examples/stm32f4/src/bin/usart.rs
index 45e94715f..40d9d70f1 100644
--- a/examples/stm32f4/src/bin/usart.rs
+++ b/examples/stm32f4/src/bin/usart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f4/src/bin/usart_buffered.rs b/examples/stm32f4/src/bin/usart_buffered.rs
index 71abc2893..c99807f11 100644
--- a/examples/stm32f4/src/bin/usart_buffered.rs
+++ b/examples/stm32f4/src/bin/usart_buffered.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/usart_dma.rs b/examples/stm32f4/src/bin/usart_dma.rs
index dca25a78c..dd6de599c 100644
--- a/examples/stm32f4/src/bin/usart_dma.rs
+++ b/examples/stm32f4/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs
index 6bf5b1cba..d2cbeea1b 100644
--- a/examples/stm32f4/src/bin/usb_ethernet.rs
+++ b/examples/stm32f4/src/bin/usb_ethernet.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -8,13 +7,13 @@ use embassy_net::tcp::TcpSocket;
8use embassy_net::{Stack, StackResources}; 7use embassy_net::{Stack, StackResources};
9use embassy_stm32::rng::{self, Rng}; 8use embassy_stm32::rng::{self, Rng};
10use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
11use embassy_stm32::usb_otg::Driver; 10use embassy_stm32::usb::Driver;
12use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 11use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
13use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; 12use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
14use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; 13use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
15use embassy_usb::{Builder, UsbDevice}; 14use embassy_usb::{Builder, UsbDevice};
16use embedded_io_async::Write; 15use embedded_io_async::Write;
17use static_cell::make_static; 16use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
20type UsbDriver = Driver<'static, embassy_stm32::peripherals::USB_OTG_FS>; 19type UsbDriver = Driver<'static, embassy_stm32::peripherals::USB_OTG_FS>;
@@ -37,7 +36,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
37} 36}
38 37
39bind_interrupts!(struct Irqs { 38bind_interrupts!(struct Irqs {
40 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 39 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
41 HASH_RNG => rng::InterruptHandler<peripherals::RNG>; 40 HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
42}); 41});
43 42
@@ -64,12 +63,14 @@ async fn main(spawner: Spawner) {
64 config.rcc.apb1_pre = APBPrescaler::DIV4; 63 config.rcc.apb1_pre = APBPrescaler::DIV4;
65 config.rcc.apb2_pre = APBPrescaler::DIV2; 64 config.rcc.apb2_pre = APBPrescaler::DIV2;
66 config.rcc.sys = Sysclk::PLL1_P; 65 config.rcc.sys = Sysclk::PLL1_P;
66 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
67 } 67 }
68 let p = embassy_stm32::init(config); 68 let p = embassy_stm32::init(config);
69 69
70 // Create the driver, from the HAL. 70 // Create the driver, from the HAL.
71 let ep_out_buffer = &mut make_static!([0; 256])[..]; 71 static OUTPUT_BUFFER: StaticCell<[u8; 256]> = StaticCell::new();
72 let mut config = embassy_stm32::usb_otg::Config::default(); 72 let ep_out_buffer = &mut OUTPUT_BUFFER.init([0; 256])[..];
73 let mut config = embassy_stm32::usb::Config::default();
73 config.vbus_detection = true; 74 config.vbus_detection = true;
74 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config); 75 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, ep_out_buffer, config);
75 76
@@ -88,14 +89,16 @@ async fn main(spawner: Spawner) {
88 config.device_protocol = 0x01; 89 config.device_protocol = 0x01;
89 90
90 // Create embassy-usb DeviceBuilder using the driver and config. 91 // Create embassy-usb DeviceBuilder using the driver and config.
92 static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
93 static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
94 static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
91 let mut builder = Builder::new( 95 let mut builder = Builder::new(
92 driver, 96 driver,
93 config, 97 config,
94 &mut make_static!([0; 256])[..], 98 &mut CONFIG_DESC.init([0; 256])[..],
95 &mut make_static!([0; 256])[..], 99 &mut BOS_DESC.init([0; 256])[..],
96 &mut make_static!([0; 256])[..],
97 &mut [], // no msos descriptors 100 &mut [], // no msos descriptors
98 &mut make_static!([0; 128])[..], 101 &mut CONTROL_BUF.init([0; 128])[..],
99 ); 102 );
100 103
101 // Our MAC addr. 104 // Our MAC addr.
@@ -104,14 +107,16 @@ async fn main(spawner: Spawner) {
104 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; 107 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88];
105 108
106 // Create classes on the builder. 109 // Create classes on the builder.
107 let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); 110 static STATE: StaticCell<State> = StaticCell::new();
111 let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64);
108 112
109 // Build the builder. 113 // Build the builder.
110 let usb = builder.build(); 114 let usb = builder.build();
111 115
112 unwrap!(spawner.spawn(usb_task(usb))); 116 unwrap!(spawner.spawn(usb_task(usb)));
113 117
114 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); 118 static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
119 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
115 unwrap!(spawner.spawn(usb_ncm_task(runner))); 120 unwrap!(spawner.spawn(usb_ncm_task(runner)));
116 121
117 let config = embassy_net::Config::dhcpv4(Default::default()); 122 let config = embassy_net::Config::dhcpv4(Default::default());
@@ -128,11 +133,13 @@ async fn main(spawner: Spawner) {
128 let seed = u64::from_le_bytes(seed); 133 let seed = u64::from_le_bytes(seed);
129 134
130 // Init network stack 135 // Init network stack
131 let stack = &*make_static!(Stack::new( 136 static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
137 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
138 let stack = &*STACK.init(Stack::new(
132 device, 139 device,
133 config, 140 config,
134 make_static!(StackResources::<2>::new()), 141 RESOURCES.init(StackResources::<2>::new()),
135 seed 142 seed,
136 )); 143 ));
137 144
138 unwrap!(spawner.spawn(net_task(stack))); 145 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
new file mode 100644
index 000000000..a799b4e72
--- /dev/null
+++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
@@ -0,0 +1,221 @@
1#![no_std]
2#![no_main]
3
4use core::sync::atomic::{AtomicBool, Ordering};
5
6use defmt::*;
7use embassy_executor::Spawner;
8use embassy_stm32::exti::ExtiInput;
9use embassy_stm32::gpio::Pull;
10use embassy_stm32::time::Hertz;
11use embassy_stm32::usb::Driver;
12use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
13use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
14use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Handler};
16use futures::future::join;
17use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
18use {defmt_rtt as _, panic_probe as _};
19
20bind_interrupts!(struct Irqs {
21 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
22});
23
24#[embassy_executor::main]
25async fn main(_spawner: Spawner) {
26 let mut config = Config::default();
27 {
28 use embassy_stm32::rcc::*;
29 config.rcc.hse = Some(Hse {
30 freq: Hertz(8_000_000),
31 mode: HseMode::Bypass,
32 });
33 config.rcc.pll_src = PllSource::HSE;
34 config.rcc.pll = Some(Pll {
35 prediv: PllPreDiv::DIV4,
36 mul: PllMul::MUL168,
37 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
38 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
39 divr: None,
40 });
41 config.rcc.ahb_pre = AHBPrescaler::DIV1;
42 config.rcc.apb1_pre = APBPrescaler::DIV4;
43 config.rcc.apb2_pre = APBPrescaler::DIV2;
44 config.rcc.sys = Sysclk::PLL1_P;
45 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
46 }
47 let p = embassy_stm32::init(config);
48
49 // Create the driver, from the HAL.
50 let mut ep_out_buffer = [0u8; 256];
51 let mut config = embassy_stm32::usb::Config::default();
52 config.vbus_detection = true;
53 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
54
55 // Create embassy-usb Config
56 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
57 config.manufacturer = Some("Embassy");
58 config.product = Some("HID keyboard example");
59 config.serial_number = Some("12345678");
60 config.max_power = 100;
61 config.max_packet_size_0 = 64;
62
63 // Required for windows compatibility.
64 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
65 config.device_class = 0xEF;
66 config.device_sub_class = 0x02;
67 config.device_protocol = 0x01;
68 config.composite_with_iads = true;
69
70 // Create embassy-usb DeviceBuilder using the driver and config.
71 // It needs some buffers for building the descriptors.
72 let mut config_descriptor = [0; 256];
73 let mut bos_descriptor = [0; 256];
74 // You can also add a Microsoft OS descriptor.
75 let mut msos_descriptor = [0; 256];
76 let mut control_buf = [0; 64];
77
78 let request_handler = MyRequestHandler {};
79 let mut device_handler = MyDeviceHandler::new();
80
81 let mut state = State::new();
82
83 let mut builder = Builder::new(
84 driver,
85 config,
86 &mut config_descriptor,
87 &mut bos_descriptor,
88 &mut msos_descriptor,
89 &mut control_buf,
90 );
91
92 builder.handler(&mut device_handler);
93
94 // Create classes on the builder.
95 let config = embassy_usb::class::hid::Config {
96 report_descriptor: KeyboardReport::desc(),
97 request_handler: Some(&request_handler),
98 poll_ms: 60,
99 max_packet_size: 8,
100 };
101
102 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
103
104 // Build the builder.
105 let mut usb = builder.build();
106
107 // Run the USB device.
108 let usb_fut = usb.run();
109
110 let (reader, mut writer) = hid.split();
111
112 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
113
114 // Do stuff with the class!
115 let in_fut = async {
116 loop {
117 button.wait_for_rising_edge().await;
118 // signal_pin.wait_for_high().await;
119 info!("Button pressed!");
120 // Create a report with the A key pressed. (no shift modifier)
121 let report = KeyboardReport {
122 keycodes: [4, 0, 0, 0, 0, 0],
123 leds: 0,
124 modifier: 0,
125 reserved: 0,
126 };
127 // Send the report.
128 match writer.write_serialize(&report).await {
129 Ok(()) => {}
130 Err(e) => warn!("Failed to send report: {:?}", e),
131 };
132
133 button.wait_for_falling_edge().await;
134 // signal_pin.wait_for_low().await;
135 info!("Button released!");
136 let report = KeyboardReport {
137 keycodes: [0, 0, 0, 0, 0, 0],
138 leds: 0,
139 modifier: 0,
140 reserved: 0,
141 };
142 match writer.write_serialize(&report).await {
143 Ok(()) => {}
144 Err(e) => warn!("Failed to send report: {:?}", e),
145 };
146 }
147 };
148
149 let out_fut = async {
150 reader.run(false, &request_handler).await;
151 };
152
153 // Run everything concurrently.
154 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
155 join(usb_fut, join(in_fut, out_fut)).await;
156}
157
158struct MyRequestHandler {}
159
160impl RequestHandler for MyRequestHandler {
161 fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> {
162 info!("Get report for {:?}", id);
163 None
164 }
165
166 fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse {
167 info!("Set report for {:?}: {=[u8]}", id, data);
168 OutResponse::Accepted
169 }
170
171 fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) {
172 info!("Set idle rate for {:?} to {:?}", id, dur);
173 }
174
175 fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> {
176 info!("Get idle rate for {:?}", id);
177 None
178 }
179}
180
181struct MyDeviceHandler {
182 configured: AtomicBool,
183}
184
185impl MyDeviceHandler {
186 fn new() -> Self {
187 MyDeviceHandler {
188 configured: AtomicBool::new(false),
189 }
190 }
191}
192
193impl Handler for MyDeviceHandler {
194 fn enabled(&mut self, enabled: bool) {
195 self.configured.store(false, Ordering::Relaxed);
196 if enabled {
197 info!("Device enabled");
198 } else {
199 info!("Device disabled");
200 }
201 }
202
203 fn reset(&mut self) {
204 self.configured.store(false, Ordering::Relaxed);
205 info!("Bus reset, the Vbus current limit is 100mA");
206 }
207
208 fn addressed(&mut self, addr: u8) {
209 self.configured.store(false, Ordering::Relaxed);
210 info!("USB address set to: {}", addr);
211 }
212
213 fn configured(&mut self, configured: bool) {
214 self.configured.store(configured, Ordering::Relaxed);
215 if configured {
216 info!("Device configured, it may now draw up to the configured current limit from Vbus.")
217 } else {
218 info!("Device is no longer configured, the Vbus current limit is 100mA.");
219 }
220 }
221}
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs
new file mode 100644
index 000000000..0bc236119
--- /dev/null
+++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs
@@ -0,0 +1,147 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::time::Hertz;
7use embassy_stm32::usb::Driver;
8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_time::Timer;
10use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State};
11use embassy_usb::control::OutResponse;
12use embassy_usb::Builder;
13use futures::future::join;
14use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
15use {defmt_rtt as _, panic_probe as _};
16
17bind_interrupts!(struct Irqs {
18 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19});
20
21#[embassy_executor::main]
22async fn main(_spawner: Spawner) {
23 let mut config = Config::default();
24 {
25 use embassy_stm32::rcc::*;
26 config.rcc.hse = Some(Hse {
27 freq: Hertz(8_000_000),
28 mode: HseMode::Bypass,
29 });
30 config.rcc.pll_src = PllSource::HSE;
31 config.rcc.pll = Some(Pll {
32 prediv: PllPreDiv::DIV4,
33 mul: PllMul::MUL168,
34 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz.
35 divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz.
36 divr: None,
37 });
38 config.rcc.ahb_pre = AHBPrescaler::DIV1;
39 config.rcc.apb1_pre = APBPrescaler::DIV4;
40 config.rcc.apb2_pre = APBPrescaler::DIV2;
41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
43 }
44 let p = embassy_stm32::init(config);
45
46 // Create the driver, from the HAL.
47 let mut ep_out_buffer = [0u8; 256];
48 let mut config = embassy_stm32::usb::Config::default();
49 config.vbus_detection = true;
50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
51
52 // Create embassy-usb Config
53 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
54 config.manufacturer = Some("Embassy");
55 config.product = Some("HID mouse example");
56 config.serial_number = Some("12345678");
57
58 // Required for windows compatibility.
59 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
60 config.device_class = 0xEF;
61 config.device_sub_class = 0x02;
62 config.device_protocol = 0x01;
63 config.composite_with_iads = true;
64
65 // Create embassy-usb DeviceBuilder using the driver and config.
66 // It needs some buffers for building the descriptors.
67 let mut config_descriptor = [0; 256];
68 let mut bos_descriptor = [0; 256];
69 let mut control_buf = [0; 64];
70
71 let request_handler = MyRequestHandler {};
72
73 let mut state = State::new();
74
75 let mut builder = Builder::new(
76 driver,
77 config,
78 &mut config_descriptor,
79 &mut bos_descriptor,
80 &mut [], // no msos descriptors
81 &mut control_buf,
82 );
83
84 // Create classes on the builder.
85 let config = embassy_usb::class::hid::Config {
86 report_descriptor: MouseReport::desc(),
87 request_handler: Some(&request_handler),
88 poll_ms: 60,
89 max_packet_size: 8,
90 };
91
92 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
93
94 // Build the builder.
95 let mut usb = builder.build();
96
97 // Run the USB device.
98 let usb_fut = usb.run();
99
100 // Do stuff with the class!
101 let hid_fut = async {
102 let mut y: i8 = 5;
103 loop {
104 Timer::after_millis(500).await;
105
106 y = -y;
107 let report = MouseReport {
108 buttons: 0,
109 x: 0,
110 y,
111 wheel: 0,
112 pan: 0,
113 };
114 match writer.write_serialize(&report).await {
115 Ok(()) => {}
116 Err(e) => warn!("Failed to send report: {:?}", e),
117 }
118 }
119 };
120
121 // Run everything concurrently.
122 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
123 join(usb_fut, hid_fut).await;
124}
125
126struct MyRequestHandler {}
127
128impl RequestHandler for MyRequestHandler {
129 fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> {
130 info!("Get report for {:?}", id);
131 None
132 }
133
134 fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse {
135 info!("Set report for {:?}: {=[u8]}", id, data);
136 OutResponse::Accepted
137 }
138
139 fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) {
140 info!("Set idle rate for {:?} to {:?}", id, dur);
141 }
142
143 fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> {
144 info!("Get idle rate for {:?}", id);
145 None
146 }
147}
diff --git a/examples/stm32f4/src/bin/usb_raw.rs b/examples/stm32f4/src/bin/usb_raw.rs
index 719b22bb9..4e583aeb8 100644
--- a/examples/stm32f4/src/bin/usb_raw.rs
+++ b/examples/stm32f4/src/bin/usb_raw.rs
@@ -48,13 +48,12 @@
48 48
49#![no_std] 49#![no_std]
50#![no_main] 50#![no_main]
51#![feature(type_alias_impl_trait)]
52 51
53use defmt::*; 52use defmt::*;
54use embassy_executor::Spawner; 53use embassy_executor::Spawner;
55use embassy_stm32::time::Hertz; 54use embassy_stm32::time::Hertz;
56use embassy_stm32::usb_otg::Driver; 55use embassy_stm32::usb::Driver;
57use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 56use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
58use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType}; 57use embassy_usb::control::{InResponse, OutResponse, Recipient, Request, RequestType};
59use embassy_usb::msos::{self, windows_version}; 58use embassy_usb::msos::{self, windows_version};
60use embassy_usb::types::InterfaceNumber; 59use embassy_usb::types::InterfaceNumber;
@@ -67,7 +66,7 @@ use {defmt_rtt as _, panic_probe as _};
67const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; 66const DEVICE_INTERFACE_GUIDS: &[&str] = &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"];
68 67
69bind_interrupts!(struct Irqs { 68bind_interrupts!(struct Irqs {
70 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 69 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
71}); 70});
72 71
73#[embassy_executor::main] 72#[embassy_executor::main]
@@ -93,12 +92,13 @@ async fn main(_spawner: Spawner) {
93 config.rcc.apb1_pre = APBPrescaler::DIV4; 92 config.rcc.apb1_pre = APBPrescaler::DIV4;
94 config.rcc.apb2_pre = APBPrescaler::DIV2; 93 config.rcc.apb2_pre = APBPrescaler::DIV2;
95 config.rcc.sys = Sysclk::PLL1_P; 94 config.rcc.sys = Sysclk::PLL1_P;
95 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
96 } 96 }
97 let p = embassy_stm32::init(config); 97 let p = embassy_stm32::init(config);
98 98
99 // Create the driver, from the HAL. 99 // Create the driver, from the HAL.
100 let mut ep_out_buffer = [0u8; 256]; 100 let mut ep_out_buffer = [0u8; 256];
101 let mut config = embassy_stm32::usb_otg::Config::default(); 101 let mut config = embassy_stm32::usb::Config::default();
102 config.vbus_detection = true; 102 config.vbus_detection = true;
103 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 103 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
104 104
@@ -117,7 +117,6 @@ async fn main(_spawner: Spawner) {
117 117
118 // Create embassy-usb DeviceBuilder using the driver and config. 118 // Create embassy-usb DeviceBuilder using the driver and config.
119 // It needs some buffers for building the descriptors. 119 // It needs some buffers for building the descriptors.
120 let mut device_descriptor = [0; 256];
121 let mut config_descriptor = [0; 256]; 120 let mut config_descriptor = [0; 256];
122 let mut bos_descriptor = [0; 256]; 121 let mut bos_descriptor = [0; 256];
123 let mut msos_descriptor = [0; 256]; 122 let mut msos_descriptor = [0; 256];
@@ -130,7 +129,6 @@ async fn main(_spawner: Spawner) {
130 let mut builder = Builder::new( 129 let mut builder = Builder::new(
131 driver, 130 driver,
132 config, 131 config,
133 &mut device_descriptor,
134 &mut config_descriptor, 132 &mut config_descriptor,
135 &mut bos_descriptor, 133 &mut bos_descriptor,
136 &mut msos_descriptor, 134 &mut msos_descriptor,
diff --git a/examples/stm32f4/src/bin/usb_serial.rs b/examples/stm32f4/src/bin/usb_serial.rs
index e2ccc9142..f3a375d31 100644
--- a/examples/stm32f4/src/bin/usb_serial.rs
+++ b/examples/stm32f4/src/bin/usb_serial.rs
@@ -1,12 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
8use embassy_stm32::usb_otg::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -14,7 +13,7 @@ use futures::future::join;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
17 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
18}); 17});
19 18
20#[embassy_executor::main] 19#[embassy_executor::main]
@@ -40,12 +39,13 @@ async fn main(_spawner: Spawner) {
40 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 config.rcc.apb1_pre = APBPrescaler::DIV4;
41 config.rcc.apb2_pre = APBPrescaler::DIV2; 40 config.rcc.apb2_pre = APBPrescaler::DIV2;
42 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
43 } 43 }
44 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
45 45
46 // Create the driver, from the HAL. 46 // Create the driver, from the HAL.
47 let mut ep_out_buffer = [0u8; 256]; 47 let mut ep_out_buffer = [0u8; 256];
48 let mut config = embassy_stm32::usb_otg::Config::default(); 48 let mut config = embassy_stm32::usb::Config::default();
49 config.vbus_detection = true; 49 config.vbus_detection = true;
50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
51 51
@@ -64,7 +64,6 @@ async fn main(_spawner: Spawner) {
64 64
65 // Create embassy-usb DeviceBuilder using the driver and config. 65 // Create embassy-usb DeviceBuilder using the driver and config.
66 // It needs some buffers for building the descriptors. 66 // It needs some buffers for building the descriptors.
67 let mut device_descriptor = [0; 256];
68 let mut config_descriptor = [0; 256]; 67 let mut config_descriptor = [0; 256];
69 let mut bos_descriptor = [0; 256]; 68 let mut bos_descriptor = [0; 256];
70 let mut control_buf = [0; 64]; 69 let mut control_buf = [0; 64];
@@ -74,7 +73,6 @@ async fn main(_spawner: Spawner) {
74 let mut builder = Builder::new( 73 let mut builder = Builder::new(
75 driver, 74 driver,
76 config, 75 config,
77 &mut device_descriptor,
78 &mut config_descriptor, 76 &mut config_descriptor,
79 &mut bos_descriptor, 77 &mut bos_descriptor,
80 &mut [], // no msos descriptors 78 &mut [], // no msos descriptors
diff --git a/examples/stm32f4/src/bin/wdt.rs b/examples/stm32f4/src/bin/wdt.rs
index 0443b61c5..ea27ebce0 100644
--- a/examples/stm32f4/src/bin/wdt.rs
+++ b/examples/stm32f4/src/bin/wdt.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs
new file mode 100644
index 000000000..cbaff75fc
--- /dev/null
+++ b/examples/stm32f4/src/bin/ws2812_pwm.rs
@@ -0,0 +1,102 @@
1// Configure TIM3 in PWM mode, and start DMA Transfer(s) to send color data into ws2812.
2// We assume the DIN pin of ws2812 connect to GPIO PB4, and ws2812 is properly powered.
3//
4// The idea is that the data rate of ws2812 is 800 kHz, and it use different duty ratio to represent bit 0 and bit 1.
5// Thus we can set TIM overflow at 800 kHz, and change duty ratio of TIM to meet the bit representation of ws2812.
6//
7// you may also want to take a look at `ws2812_spi.rs` file, which make use of SPI instead.
8//
9// Warning:
10// DO NOT stare at ws2812 directy (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn.
11
12#![no_std]
13#![no_main]
14
15use embassy_executor::Spawner;
16use embassy_stm32::gpio::OutputType;
17use embassy_stm32::time::khz;
18use embassy_stm32::timer::low_level::CountingMode;
19use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
20use embassy_stm32::timer::Channel;
21use embassy_time::{Duration, Ticker, Timer};
22use {defmt_rtt as _, panic_probe as _};
23
24#[embassy_executor::main]
25async fn main(_spawner: Spawner) {
26 let mut device_config = embassy_stm32::Config::default();
27
28 // set SYSCLK/HCLK/PCLK2 to 20 MHz, thus each tick is 0.05 us,
29 // and ws2812 timings are integer multiples of 0.05 us
30 {
31 use embassy_stm32::rcc::*;
32 use embassy_stm32::time::*;
33 device_config.enable_debug_during_sleep = true;
34 device_config.rcc.hse = Some(Hse {
35 freq: mhz(12),
36 mode: HseMode::Oscillator,
37 });
38 device_config.rcc.pll_src = PllSource::HSE;
39 device_config.rcc.pll = Some(Pll {
40 prediv: PllPreDiv::DIV6,
41 mul: PllMul::MUL80,
42 divp: Some(PllPDiv::DIV8),
43 divq: None,
44 divr: None,
45 });
46 device_config.rcc.sys = Sysclk::PLL1_P;
47 }
48
49 let mut dp = embassy_stm32::init(device_config);
50
51 let mut ws2812_pwm = SimplePwm::new(
52 dp.TIM3,
53 Some(PwmPin::new_ch1(dp.PB4, OutputType::PushPull)),
54 None,
55 None,
56 None,
57 khz(800), // data rate of ws2812
58 CountingMode::EdgeAlignedUp,
59 );
60
61 // construct ws2812 non-return-to-zero (NRZ) code bit by bit
62 // ws2812 only need 24 bits for each LED, but we add one bit more to keep PWM output low
63
64 let max_duty = ws2812_pwm.get_max_duty() as u16;
65 let n0 = 8 * max_duty / 25; // ws2812 Bit 0 high level timing
66 let n1 = 2 * n0; // ws2812 Bit 1 high level timing
67
68 let turn_off = [
69 n0, n0, n0, n0, n0, n0, n0, n0, // Green
70 n0, n0, n0, n0, n0, n0, n0, n0, // Red
71 n0, n0, n0, n0, n0, n0, n0, n0, // Blue
72 0, // keep PWM output low after a transfer
73 ];
74
75 let dim_white = [
76 n0, n0, n0, n0, n0, n0, n1, n0, // Green
77 n0, n0, n0, n0, n0, n0, n1, n0, // Red
78 n0, n0, n0, n0, n0, n0, n1, n0, // Blue
79 0, // keep PWM output low after a transfer
80 ];
81
82 let color_list = &[&turn_off, &dim_white];
83
84 let pwm_channel = Channel::Ch1;
85
86 // make sure PWM output keep low on first start
87 ws2812_pwm.set_duty(pwm_channel, 0);
88
89 // flip color at 2 Hz
90 let mut ticker = Ticker::every(Duration::from_millis(500));
91
92 loop {
93 for &color in color_list {
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;
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;
98 // wait until ticker tick
99 ticker.next().await;
100 }
101 }
102}
diff --git a/examples/stm32f4/src/bin/ws2812_spi.rs b/examples/stm32f4/src/bin/ws2812_spi.rs
new file mode 100644
index 000000000..a280a3b77
--- /dev/null
+++ b/examples/stm32f4/src/bin/ws2812_spi.rs
@@ -0,0 +1,95 @@
1// Mimic PWM with SPI, to control ws2812
2// We assume the DIN pin of ws2812 connect to GPIO PB5, and ws2812 is properly powered.
3//
4// The idea is that the data rate of ws2812 is 800 kHz, and it use different duty ratio to represent bit 0 and bit 1.
5// Thus we can adjust SPI to send each *round* of data at 800 kHz, and in each *round*, we can adjust each *bit* to mimic 2 different PWM waveform.
6// such that the output waveform meet the bit representation of ws2812.
7//
8// If you want to save SPI for other purpose, you may want to take a look at `ws2812_pwm_dma.rs` file, which make use of TIM and DMA.
9//
10// Warning:
11// DO NOT stare at ws2812 directy (especially after each MCU Reset), its (max) brightness could easily make your eyes feel burn.
12
13#![no_std]
14#![no_main]
15
16use embassy_stm32::time::khz;
17use embassy_stm32::{dma, spi};
18use embassy_time::{Duration, Ticker, Timer};
19use {defmt_rtt as _, panic_probe as _};
20
21// we use 16 bit data frame format of SPI, to let timing as accurate as possible.
22// thanks to loose tolerance of ws2812 timing, you can also use 8 bit data frame format, thus you will need to adjust the bit representation.
23const N0: u16 = 0b1111100000000000u16; // ws2812 Bit 0 high level timing
24const N1: u16 = 0b1111111111000000u16; // ws2812 Bit 1 high level timing
25
26// ws2812 only need 24 bits for each LED,
27// but we add one bit more to keep SPI output low at the end
28
29static TURN_OFF: [u16; 25] = [
30 N0, N0, N0, N0, N0, N0, N0, N0, // Green
31 N0, N0, N0, N0, N0, N0, N0, N0, // Red
32 N0, N0, N0, N0, N0, N0, N0, N0, // Blue
33 0, // keep SPI output low after last bit
34];
35
36static DIM_WHITE: [u16; 25] = [
37 N0, N0, N0, N0, N0, N0, N1, N0, // Green
38 N0, N0, N0, N0, N0, N0, N1, N0, // Red
39 N0, N0, N0, N0, N0, N0, N1, N0, // Blue
40 0, // keep SPI output low after last bit
41];
42
43static COLOR_LIST: &[&[u16]] = &[&TURN_OFF, &DIM_WHITE];
44
45#[embassy_executor::main]
46async fn main(_spawner: embassy_executor::Spawner) {
47 let mut device_config = embassy_stm32::Config::default();
48
49 // Since we use 16 bit SPI, and we need each round 800 kHz,
50 // thus SPI output speed should be 800 kHz * 16 = 12.8 MHz, and APB clock should be 2 * 12.8 MHz = 25.6 MHz.
51 //
52 // As for my setup, with 12 MHz HSE, I got 25.5 MHz SYSCLK, which is slightly slower, but it's ok for ws2812.
53 {
54 use embassy_stm32::rcc::{Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllSource, Sysclk};
55 use embassy_stm32::time::mhz;
56 device_config.enable_debug_during_sleep = true;
57 device_config.rcc.hse = Some(Hse {
58 freq: mhz(12),
59 mode: HseMode::Oscillator,
60 });
61 device_config.rcc.pll_src = PllSource::HSE;
62 device_config.rcc.pll = Some(Pll {
63 prediv: PllPreDiv::DIV6,
64 mul: PllMul::MUL102,
65 divp: Some(PllPDiv::DIV8),
66 divq: None,
67 divr: None,
68 });
69 device_config.rcc.sys = Sysclk::PLL1_P;
70 }
71
72 let dp = embassy_stm32::init(device_config);
73
74 // Set SPI output speed.
75 // It's ok to blindly set frequency to 12800 kHz, the hal crate will take care of the SPI CR1 BR field.
76 // And in my case, the real bit rate will be 25.5 MHz / 2 = 12_750 kHz
77 let mut spi_config = spi::Config::default();
78 spi_config.frequency = khz(12_800);
79
80 // Since we only output waveform, then the Rx and Sck and RxDma it is not considered
81 let mut ws2812_spi = spi::Spi::new_txonly_nosck(dp.SPI1, dp.PB5, dp.DMA2_CH3, dma::NoDma, spi_config);
82
83 // flip color at 2 Hz
84 let mut ticker = Ticker::every(Duration::from_millis(500));
85
86 loop {
87 for &color in COLOR_LIST {
88 ws2812_spi.write(color).await.unwrap();
89 // ws2812 need at least 50 us low level input to confirm the input data and change it's state
90 Timer::after_micros(50).await;
91 // wait until ticker tick
92 ticker.next().await;
93 }
94 }
95}
diff --git a/examples/stm32f7/.cargo/config.toml b/examples/stm32f7/.cargo/config.toml
index 9088eea6e..086da2d78 100644
--- a/examples/stm32f7/.cargo/config.toml
+++ b/examples/stm32f7/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32F429ZITx with your chip as listed in `probe-rs chip list` 2# replace STM32F429ZITx with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip STM32F767ZITx" 3runner = "probe-rs run --chip STM32F777ZITx"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 4cca0d93c..305816a2b 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -5,12 +5,12 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32f767zi to your chip name, if necessary. 8# Change stm32f777zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 13embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
14embedded-io-async = { version = "0.6.1" } 14embedded-io-async = { version = "0.6.1" }
15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 15embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
16 16
@@ -27,7 +27,10 @@ nb = "1.0.0"
27rand_core = "0.6.3" 27rand_core = "0.6.3"
28critical-section = "1.1" 28critical-section = "1.1"
29embedded-storage = "0.3.1" 29embedded-storage = "0.3.1"
30static_cell = { version = "2", features = ["nightly"]} 30static_cell = "2"
31sha2 = { version = "0.10.8", default-features = false }
32hmac = "0.12.1"
33aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] }
31 34
32[profile.release] 35[profile.release]
33debug = 2 36debug = 2
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs
index 48c59eaf0..f8d7b691f 100644
--- a/examples/stm32f7/src/bin/adc.rs
+++ b/examples/stm32f7/src/bin/adc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f7/src/bin/blinky.rs b/examples/stm32f7/src/bin/blinky.rs
index 4bfc5a50d..31cce8225 100644
--- a/examples/stm32f7/src/bin/blinky.rs
+++ b/examples/stm32f7/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f7/src/bin/button.rs b/examples/stm32f7/src/bin/button.rs
index b13e64531..564908998 100644
--- a/examples/stm32f7/src/bin/button.rs
+++ b/examples/stm32f7/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs
index dfe587d41..2a546dac5 100644
--- a/examples/stm32f7/src/bin/button_exti.rs
+++ b/examples/stm32f7/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32f7/src/bin/can.rs b/examples/stm32f7/src/bin/can.rs
index 78b21ceaa..221ac2a05 100644
--- a/examples/stm32f7/src/bin/can.rs
+++ b/examples/stm32f7/src/bin/can.rs
@@ -1,17 +1,19 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3
4use core::num::{NonZeroU16, NonZeroU8};
4 5
5use defmt::*; 6use defmt::*;
6use embassy_executor::Spawner; 7use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts; 8use embassy_stm32::can::filter::Mask32;
8use embassy_stm32::can::bxcan::filter::Mask32;
9use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId};
10use embassy_stm32::can::{ 9use embassy_stm32::can::{
11 Can, CanTx, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler, 10 Can, CanTx, Fifo, Frame, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, StandardId,
11 TxInterruptHandler,
12}; 12};
13use embassy_stm32::gpio::{Input, Pull}; 13use embassy_stm32::gpio::{Input, Pull};
14use embassy_stm32::peripherals::CAN3; 14use embassy_stm32::peripherals::CAN3;
15use embassy_stm32::{bind_interrupts, can};
16use static_cell::StaticCell;
15use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
16 18
17bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -22,9 +24,9 @@ bind_interrupts!(struct Irqs {
22}); 24});
23 25
24#[embassy_executor::task] 26#[embassy_executor::task]
25pub async fn send_can_message(tx: &'static mut CanTx<'static, 'static, CAN3>) { 27pub async fn send_can_message(tx: &'static mut CanTx<'static, CAN3>) {
26 loop { 28 loop {
27 let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), [0]); 29 let frame = Frame::new_data(unwrap!(StandardId::new(0 as _)), &[0]).unwrap();
28 tx.write(&frame).await; 30 tx.write(&frame).await;
29 embassy_time::Timer::after_secs(1).await; 31 embassy_time::Timer::after_secs(1).await;
30 } 32 }
@@ -43,20 +45,27 @@ async fn main(spawner: Spawner) {
43 let rx_pin = Input::new(&mut p.PA15, Pull::Up); 45 let rx_pin = Input::new(&mut p.PA15, Pull::Up);
44 core::mem::forget(rx_pin); 46 core::mem::forget(rx_pin);
45 47
46 let can: &'static mut Can<'static, CAN3> = static_cell::make_static!(Can::new(p.CAN3, p.PA8, p.PA15, Irqs)); 48 static CAN: StaticCell<Can<'static, CAN3>> = StaticCell::new();
49 let can = CAN.init(Can::new(p.CAN3, p.PA8, p.PA15, Irqs));
47 can.as_mut() 50 can.as_mut()
48 .modify_filters() 51 .modify_filters()
49 .enable_bank(0, Fifo::Fifo0, Mask32::accept_all()); 52 .enable_bank(0, Fifo::Fifo0, Mask32::accept_all());
50 53
51 can.as_mut() 54 can.as_mut()
52 .modify_config() 55 .modify_config()
53 .set_bit_timing(0x001c0001) // http://www.bittiming.can-wiki.info/ 56 .set_bit_timing(can::util::NominalBitTiming {
57 prescaler: NonZeroU16::new(2).unwrap(),
58 seg1: NonZeroU8::new(13).unwrap(),
59 seg2: NonZeroU8::new(2).unwrap(),
60 sync_jump_width: NonZeroU8::new(1).unwrap(),
61 }) // http://www.bittiming.can-wiki.info/
54 .set_loopback(true) 62 .set_loopback(true)
55 .enable(); 63 .enable();
56 64
57 let (tx, mut rx) = can.split(); 65 let (tx, mut rx) = can.split();
58 66
59 let tx: &'static mut CanTx<'static, 'static, CAN3> = static_cell::make_static!(tx); 67 static CAN_TX: StaticCell<CanTx<'static, CAN3>> = StaticCell::new();
68 let tx = CAN_TX.init(tx);
60 spawner.spawn(send_can_message(tx)).unwrap(); 69 spawner.spawn(send_can_message(tx)).unwrap();
61 70
62 loop { 71 loop {
diff --git a/examples/stm32f7/src/bin/cryp.rs b/examples/stm32f7/src/bin/cryp.rs
new file mode 100644
index 000000000..235853cb9
--- /dev/null
+++ b/examples/stm32f7/src/bin/cryp.rs
@@ -0,0 +1,80 @@
1#![no_std]
2#![no_main]
3
4use aes_gcm::aead::heapless::Vec;
5use aes_gcm::aead::{AeadInPlace, KeyInit};
6use aes_gcm::Aes128Gcm;
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_stm32::cryp::{self, *};
10use embassy_stm32::{bind_interrupts, peripherals, Config};
11use embassy_time::Instant;
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 CRYP => cryp::InterruptHandler<peripherals::CRYP>;
16});
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) -> ! {
20 let config = Config::default();
21 let p = embassy_stm32::init(config);
22
23 let payload: &[u8] = b"hello world";
24 let aad: &[u8] = b"additional data";
25
26 let mut hw_cryp = Cryp::new(p.CRYP, p.DMA2_CH6, p.DMA2_CH5, Irqs);
27 let key: [u8; 16] = [0; 16];
28 let mut ciphertext: [u8; 11] = [0; 11];
29 let mut plaintext: [u8; 11] = [0; 11];
30 let iv: [u8; 12] = [0; 12];
31
32 let hw_start_time = Instant::now();
33
34 // Encrypt in hardware using AES-GCM 128-bit
35 let aes_gcm = AesGcm::new(&key, &iv);
36 let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt).await;
37 hw_cryp.aad(&mut gcm_encrypt, aad, true).await;
38 hw_cryp.payload(&mut gcm_encrypt, payload, &mut ciphertext, true).await;
39 let encrypt_tag = hw_cryp.finish(gcm_encrypt).await;
40
41 // Decrypt in hardware using AES-GCM 128-bit
42 let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt).await;
43 hw_cryp.aad(&mut gcm_decrypt, aad, true).await;
44 hw_cryp
45 .payload(&mut gcm_decrypt, &ciphertext, &mut plaintext, true)
46 .await;
47 let decrypt_tag = hw_cryp.finish(gcm_decrypt).await;
48
49 let hw_end_time = Instant::now();
50 let hw_execution_time = hw_end_time - hw_start_time;
51
52 info!("AES-GCM Ciphertext: {:?}", ciphertext);
53 info!("AES-GCM Plaintext: {:?}", plaintext);
54 assert_eq!(payload, plaintext);
55 assert_eq!(encrypt_tag, decrypt_tag);
56
57 let sw_start_time = Instant::now();
58
59 // Encrypt in software using AES-GCM 128-bit
60 let mut payload_vec: Vec<u8, 32> = Vec::from_slice(&payload).unwrap();
61 let cipher = Aes128Gcm::new(&key.into());
62 let _ = cipher.encrypt_in_place(&iv.into(), aad.into(), &mut payload_vec);
63
64 assert_eq!(ciphertext, payload_vec[0..ciphertext.len()]);
65 assert_eq!(
66 encrypt_tag,
67 payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]
68 );
69
70 // Decrypt in software using AES-GCM 128-bit
71 let _ = cipher.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec);
72
73 let sw_end_time = Instant::now();
74 let sw_execution_time = sw_end_time - sw_start_time;
75
76 info!("Hardware Execution Time: {:?}", hw_execution_time);
77 info!("Software Execution Time: {:?}", sw_execution_time);
78
79 loop {}
80}
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index dd0069447..9a608e909 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -15,12 +14,12 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
15use embassy_time::Timer; 14use embassy_time::Timer;
16use embedded_io_async::Write; 15use embedded_io_async::Write;
17use rand_core::RngCore; 16use rand_core::RngCore;
18use static_cell::make_static; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
21bind_interrupts!(struct Irqs { 20bind_interrupts!(struct Irqs {
22 ETH => eth::InterruptHandler; 21 ETH => eth::InterruptHandler;
23 RNG => rng::InterruptHandler<peripherals::RNG>; 22 HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
24}); 23});
25 24
26type Device = Ethernet<'static, ETH, GenericSMI>; 25type Device = Ethernet<'static, ETH, GenericSMI>;
@@ -64,8 +63,9 @@ async fn main(spawner: Spawner) -> ! {
64 63
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66 65
66 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
67 let device = Ethernet::new( 67 let device = Ethernet::new(
68 make_static!(PacketQueue::<16, 16>::new()), 68 PACKETS.init(PacketQueue::<16, 16>::new()),
69 p.ETH, 69 p.ETH,
70 Irqs, 70 Irqs,
71 p.PA1, 71 p.PA1,
@@ -89,11 +89,13 @@ async fn main(spawner: Spawner) -> ! {
89 //}); 89 //});
90 90
91 // Init network stack 91 // Init network stack
92 let stack = &*make_static!(Stack::new( 92 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
93 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
94 let stack = &*STACK.init(Stack::new(
93 device, 95 device,
94 config, 96 config,
95 make_static!(StackResources::<2>::new()), 97 RESOURCES.init(StackResources::<2>::new()),
96 seed 98 seed,
97 )); 99 ));
98 100
99 // Launch network task 101 // Launch network task
diff --git a/examples/stm32f7/src/bin/flash.rs b/examples/stm32f7/src/bin/flash.rs
index 06a94f1c8..885570478 100644
--- a/examples/stm32f7/src/bin/flash.rs
+++ b/examples/stm32f7/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f7/src/bin/hash.rs b/examples/stm32f7/src/bin/hash.rs
new file mode 100644
index 000000000..c2d1a7158
--- /dev/null
+++ b/examples/stm32f7/src/bin/hash.rs
@@ -0,0 +1,78 @@
1#![no_std]
2#![no_main]
3
4use defmt::info;
5use embassy_executor::Spawner;
6use embassy_stm32::hash::*;
7use embassy_stm32::{bind_interrupts, hash, peripherals, Config};
8use embassy_time::Instant;
9use hmac::{Hmac, Mac};
10use sha2::{Digest, Sha256};
11use {defmt_rtt as _, panic_probe as _};
12
13type HmacSha256 = Hmac<Sha256>;
14
15bind_interrupts!(struct Irqs {
16 HASH_RNG => hash::InterruptHandler<peripherals::HASH>;
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) -> ! {
21 let config = Config::default();
22 let p = embassy_stm32::init(config);
23
24 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
25 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
26
27 let mut hw_hasher = Hash::new(p.HASH, p.DMA2_CH7, Irqs);
28
29 let hw_start_time = Instant::now();
30
31 // Compute a digest in hardware.
32 let mut context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, None);
33 hw_hasher.update(&mut context, test_1).await;
34 hw_hasher.update(&mut context, test_2).await;
35 let mut hw_digest: [u8; 32] = [0; 32];
36 hw_hasher.finish(context, &mut hw_digest).await;
37
38 let hw_end_time = Instant::now();
39 let hw_execution_time = hw_end_time - hw_start_time;
40
41 let sw_start_time = Instant::now();
42
43 // Compute a digest in software.
44 let mut sw_hasher = Sha256::new();
45 sw_hasher.update(test_1);
46 sw_hasher.update(test_2);
47 let sw_digest = sw_hasher.finalize();
48
49 let sw_end_time = Instant::now();
50 let sw_execution_time = sw_end_time - sw_start_time;
51
52 info!("Hardware Digest: {:?}", hw_digest);
53 info!("Software Digest: {:?}", sw_digest[..]);
54 info!("Hardware Execution Time: {:?}", hw_execution_time);
55 info!("Software Execution Time: {:?}", sw_execution_time);
56 assert_eq!(hw_digest, sw_digest[..]);
57
58 let hmac_key: [u8; 64] = [0x55; 64];
59
60 // Compute HMAC in hardware.
61 let mut sha256hmac_context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, Some(&hmac_key));
62 hw_hasher.update(&mut sha256hmac_context, test_1).await;
63 hw_hasher.update(&mut sha256hmac_context, test_2).await;
64 let mut hw_hmac: [u8; 32] = [0; 32];
65 hw_hasher.finish(sha256hmac_context, &mut hw_hmac).await;
66
67 // Compute HMAC in software.
68 let mut sw_mac = HmacSha256::new_from_slice(&hmac_key).unwrap();
69 sw_mac.update(test_1);
70 sw_mac.update(test_2);
71 let sw_hmac = sw_mac.finalize().into_bytes();
72
73 info!("Hardware HMAC: {:?}", hw_hmac);
74 info!("Software HMAC: {:?}", sw_hmac[..]);
75 assert_eq!(hw_hmac, sw_hmac[..]);
76
77 loop {}
78}
diff --git a/examples/stm32f7/src/bin/hello.rs b/examples/stm32f7/src/bin/hello.rs
index a2a287110..3c295612c 100644
--- a/examples/stm32f7/src/bin/hello.rs
+++ b/examples/stm32f7/src/bin/hello.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::info; 4use defmt::info;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 990de0ab1..6d36ef518 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32f7/src/bin/usart_dma.rs b/examples/stm32f7/src/bin/usart_dma.rs
index ba064081e..fb604b34f 100644
--- a/examples/stm32f7/src/bin/usart_dma.rs
+++ b/examples/stm32f7/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32f7/src/bin/usb_serial.rs b/examples/stm32f7/src/bin/usb_serial.rs
index 4991edbf0..39a5512f4 100644
--- a/examples/stm32f7/src/bin/usb_serial.rs
+++ b/examples/stm32f7/src/bin/usb_serial.rs
@@ -1,12 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
8use embassy_stm32::usb_otg::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -14,7 +13,7 @@ use futures::future::join;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
17 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
18}); 17});
19 18
20#[embassy_executor::main] 19#[embassy_executor::main]
@@ -40,12 +39,13 @@ async fn main(_spawner: Spawner) {
40 config.rcc.apb1_pre = APBPrescaler::DIV4; 39 config.rcc.apb1_pre = APBPrescaler::DIV4;
41 config.rcc.apb2_pre = APBPrescaler::DIV2; 40 config.rcc.apb2_pre = APBPrescaler::DIV2;
42 config.rcc.sys = Sysclk::PLL1_P; 41 config.rcc.sys = Sysclk::PLL1_P;
42 config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q;
43 } 43 }
44 let p = embassy_stm32::init(config); 44 let p = embassy_stm32::init(config);
45 45
46 // Create the driver, from the HAL. 46 // Create the driver, from the HAL.
47 let mut ep_out_buffer = [0u8; 256]; 47 let mut ep_out_buffer = [0u8; 256];
48 let mut config = embassy_stm32::usb_otg::Config::default(); 48 let mut config = embassy_stm32::usb::Config::default();
49 config.vbus_detection = true; 49 config.vbus_detection = true;
50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 50 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
51 51
@@ -64,7 +64,6 @@ async fn main(_spawner: Spawner) {
64 64
65 // Create embassy-usb DeviceBuilder using the driver and config. 65 // Create embassy-usb DeviceBuilder using the driver and config.
66 // It needs some buffers for building the descriptors. 66 // It needs some buffers for building the descriptors.
67 let mut device_descriptor = [0; 256];
68 let mut config_descriptor = [0; 256]; 67 let mut config_descriptor = [0; 256];
69 let mut bos_descriptor = [0; 256]; 68 let mut bos_descriptor = [0; 256];
70 let mut control_buf = [0; 64]; 69 let mut control_buf = [0; 64];
@@ -74,7 +73,6 @@ async fn main(_spawner: Spawner) {
74 let mut builder = Builder::new( 73 let mut builder = Builder::new(
75 driver, 74 driver,
76 config, 75 config,
77 &mut device_descriptor,
78 &mut config_descriptor, 76 &mut config_descriptor,
79 &mut bos_descriptor, 77 &mut bos_descriptor,
80 &mut [], // no msos descriptors 78 &mut [], // no msos descriptors
diff --git a/examples/stm32g0/.cargo/config.toml b/examples/stm32g0/.cargo/config.toml
index 35cca5412..f395d8920 100644
--- a/examples/stm32g0/.cargo/config.toml
+++ b/examples/stm32g0/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32G071C8Rx with your chip as listed in `probe-rs chip list` 2# replace STM32G0B1RETx with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip STM32G071RBTx" 3runner = "probe-rs run --chip STM32G0B1RETx"
4 4
5[build] 5[build]
6target = "thumbv6m-none-eabi" 6target = "thumbv6m-none-eabi"
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml
index b1e749440..6ce3418e5 100644
--- a/examples/stm32g0/Cargo.toml
+++ b/examples/stm32g0/Cargo.toml
@@ -5,11 +5,13 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32g071rb to your chip name, if necessary. 8# Change stm32g0b1re to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g0b1re", "memory-x", "unstable-pac", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", default-features = false, features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
13 15
14defmt = "0.3" 16defmt = "0.3"
15defmt-rtt = "0.4" 17defmt-rtt = "0.4"
diff --git a/examples/stm32g0/src/bin/blinky.rs b/examples/stm32g0/src/bin/blinky.rs
index 4bfc5a50d..31cce8225 100644
--- a/examples/stm32g0/src/bin/blinky.rs
+++ b/examples/stm32g0/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32g0/src/bin/button.rs b/examples/stm32g0/src/bin/button.rs
index 72a3f5cbf..8017f0274 100644
--- a/examples/stm32g0/src/bin/button.rs
+++ b/examples/stm32g0/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs
index ef32d4c4a..34a08bbc6 100644
--- a/examples/stm32g0/src/bin/button_exti.rs
+++ b/examples/stm32g0/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Up); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32g0/src/bin/flash.rs b/examples/stm32g0/src/bin/flash.rs
index ed9f2e843..acef87b92 100644
--- a/examples/stm32g0/src/bin/flash.rs
+++ b/examples/stm32g0/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32g0/src/bin/hf_timer.rs b/examples/stm32g0/src/bin/hf_timer.rs
new file mode 100644
index 000000000..3ea06cdee
--- /dev/null
+++ b/examples/stm32g0/src/bin/hf_timer.rs
@@ -0,0 +1,62 @@
1#![no_std]
2#![no_main]
3
4use defmt::info;
5use embassy_executor::Spawner;
6use embassy_stm32::gpio::OutputType;
7use embassy_stm32::time::khz;
8use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
9use embassy_stm32::timer::simple_pwm::PwmPin;
10use embassy_stm32::timer::Channel;
11use embassy_stm32::Config as PeripheralConfig;
12use {defmt_rtt as _, panic_probe as _};
13
14#[embassy_executor::main]
15async fn main(_spawner: Spawner) {
16 let mut config = PeripheralConfig::default();
17 {
18 use embassy_stm32::rcc::*;
19 config.rcc.hsi = true;
20 config.rcc.pll = Some(Pll {
21 source: PllSource::HSI,
22 prediv: PllPreDiv::DIV1,
23 mul: PllMul::MUL16,
24 divp: None,
25 divq: Some(PllQDiv::DIV2), // 16 / 1 * 16 / 2 = 128 Mhz
26 divr: Some(PllRDiv::DIV4), // 16 / 1 * 16 / 4 = 64 Mhz
27 });
28 config.rcc.sys = Sysclk::PLL1_R;
29
30 // configure TIM1 mux to select PLLQ as clock source
31 // https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
32 // RM0444 page 210
33 // RCC - Peripherals Independent Clock Control Register - bit 22 -> 1
34 config.rcc.mux.tim1sel = embassy_stm32::rcc::mux::Tim1sel::PLL1_Q;
35 }
36 let p = embassy_stm32::init(config);
37
38 let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull);
39 let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull);
40
41 let mut pwm = ComplementaryPwm::new(
42 p.TIM1,
43 Some(ch1),
44 Some(ch1n),
45 None,
46 None,
47 None,
48 None,
49 None,
50 None,
51 khz(512),
52 Default::default(),
53 );
54
55 let max = pwm.get_max_duty();
56 info!("Max duty: {}", max);
57
58 pwm.set_duty(Channel::Ch1, max / 2);
59 pwm.enable(Channel::Ch1);
60
61 loop {}
62}
diff --git a/examples/stm32g0/src/bin/spi_neopixel.rs b/examples/stm32g0/src/bin/spi_neopixel.rs
index 214462d0e..c5ea51721 100644
--- a/examples/stm32g0/src/bin/spi_neopixel.rs
+++ b/examples/stm32g0/src/bin/spi_neopixel.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32g0/src/bin/usb_serial.rs b/examples/stm32g0/src/bin/usb_serial.rs
new file mode 100644
index 000000000..162dfd86b
--- /dev/null
+++ b/examples/stm32g0/src/bin/usb_serial.rs
@@ -0,0 +1,97 @@
1#![no_std]
2#![no_main]
3
4use defmt::{panic, *};
5use embassy_executor::Spawner;
6use embassy_futures::join::join;
7use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder;
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 USB_UCPD1_2 => usb::InterruptHandler<peripherals::USB>;
16});
17
18#[embassy_executor::main]
19async fn main(_spawner: Spawner) {
20 let mut config = Config::default();
21 {
22 use embassy_stm32::rcc::*;
23 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
24 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
25 }
26 let p = embassy_stm32::init(config);
27
28 info!("Hello World!");
29
30 // Create the driver, from the HAL.
31 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
32
33 // Create embassy-usb Config
34 let config = embassy_usb::Config::new(0xc0de, 0xcafe);
35 //config.max_packet_size_0 = 64;
36
37 // Create embassy-usb DeviceBuilder using the driver and config.
38 // It needs some buffers for building the descriptors.
39 let mut config_descriptor = [0; 256];
40 let mut bos_descriptor = [0; 256];
41 let mut control_buf = [0; 7];
42
43 let mut state = State::new();
44
45 let mut builder = Builder::new(
46 driver,
47 config,
48 &mut config_descriptor,
49 &mut bos_descriptor,
50 &mut [], // no msos descriptors
51 &mut control_buf,
52 );
53
54 // Create classes on the builder.
55 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
56
57 // Build the builder.
58 let mut usb = builder.build();
59
60 // Run the USB device.
61 let usb_fut = usb.run();
62
63 // Do stuff with the class!
64 let echo_fut = async {
65 loop {
66 class.wait_connection().await;
67 info!("Connected");
68 let _ = echo(&mut class).await;
69 info!("Disconnected");
70 }
71 };
72
73 // Run everything concurrently.
74 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
75 join(usb_fut, echo_fut).await;
76}
77
78struct Disconnected {}
79
80impl From<EndpointError> for Disconnected {
81 fn from(val: EndpointError) -> Self {
82 match val {
83 EndpointError::BufferOverflow => panic!("Buffer overflow"),
84 EndpointError::Disabled => Disconnected {},
85 }
86 }
87}
88
89async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
90 let mut buf = [0; 64];
91 loop {
92 let n = class.read_packet(&mut buf).await?;
93 let data = &buf[..n];
94 info!("data: {:x}", data);
95 class.write_packet(data).await?;
96 }
97}
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml
index c56a63623..64c749b9b 100644
--- a/examples/stm32g4/Cargo.toml
+++ b/examples/stm32g4/Cargo.toml
@@ -8,11 +8,11 @@ license = "MIT OR Apache-2.0"
8# Change stm32g491re to your chip name, if necessary. 8# Change stm32g491re to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15usbd-hid = "0.6.0" 15usbd-hid = "0.7.0"
16 16
17defmt = "0.3" 17defmt = "0.3"
18defmt-rtt = "0.4" 18defmt-rtt = "0.4"
@@ -20,9 +20,11 @@ defmt-rtt = "0.4"
20cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
22embedded-hal = "0.2.6" 22embedded-hal = "0.2.6"
23embedded-can = { version = "0.4" }
23panic-probe = { version = "0.3", features = ["print-defmt"] } 24panic-probe = { version = "0.3", features = ["print-defmt"] }
24futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 25futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
25heapless = { version = "0.8", default-features = false } 26heapless = { version = "0.8", default-features = false }
27static_cell = "2.0.0"
26 28
27[profile.release] 29[profile.release]
28debug = 2 30debug = 2
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 63b20c0d4..ae64bc8e4 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -1,11 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
8use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource};
9use embassy_stm32::Config; 7use embassy_stm32::Config;
10use embassy_time::{Delay, Timer}; 8use embassy_time::{Delay, Timer};
11use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -13,25 +11,25 @@ use {defmt_rtt as _, panic_probe as _};
13#[embassy_executor::main] 11#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
15 let mut config = Config::default(); 13 let mut config = Config::default();
16 14 {
17 config.rcc.pll = Some(Pll { 15 use embassy_stm32::rcc::*;
18 source: PllSource::HSI, 16 config.rcc.pll = Some(Pll {
19 prediv_m: PllM::DIV4, 17 source: PllSource::HSI,
20 mul_n: PllN::MUL85, 18 prediv: PllPreDiv::DIV4,
21 div_p: None, 19 mul: PllMul::MUL85,
22 div_q: None, 20 divp: None,
23 // Main system clock at 170 MHz 21 divq: None,
24 div_r: Some(PllR::DIV2), 22 // Main system clock at 170 MHz
25 }); 23 divr: Some(PllRDiv::DIV2),
26 24 });
27 config.rcc.adc12_clock_source = AdcClockSource::SYS; 25 config.rcc.mux.adc12sel = mux::Adcsel::SYS;
28 config.rcc.mux = ClockSrc::PLL; 26 config.rcc.sys = Sysclk::PLL1_R;
29 27 }
30 let mut p = embassy_stm32::init(config); 28 let mut p = embassy_stm32::init(config);
31 info!("Hello World!"); 29 info!("Hello World!");
32 30
33 let mut adc = Adc::new(p.ADC2, &mut Delay); 31 let mut adc = Adc::new(p.ADC2, &mut Delay);
34 adc.set_sample_time(SampleTime::Cycles32_5); 32 adc.set_sample_time(SampleTime::CYCLES32_5);
35 33
36 loop { 34 loop {
37 let measured = adc.read(&mut p.PA7); 35 let measured = adc.read(&mut p.PA7);
diff --git a/examples/stm32g4/src/bin/blinky.rs b/examples/stm32g4/src/bin/blinky.rs
index cbeb0dee1..90e479aae 100644
--- a/examples/stm32g4/src/bin/blinky.rs
+++ b/examples/stm32g4/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32g4/src/bin/button.rs b/examples/stm32g4/src/bin/button.rs
index 15abd86d9..daebdd04d 100644
--- a/examples/stm32g4/src/bin/button.rs
+++ b/examples/stm32g4/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs
index dfe587d41..2a546dac5 100644
--- a/examples/stm32g4/src/bin/button_exti.rs
+++ b/examples/stm32g4/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs
new file mode 100644
index 000000000..2ed632a93
--- /dev/null
+++ b/examples/stm32g4/src/bin/can.rs
@@ -0,0 +1,234 @@
1#![no_std]
2#![no_main]
3use defmt::*;
4use embassy_executor::Spawner;
5use embassy_stm32::peripherals::*;
6use embassy_stm32::time::Hertz;
7use embassy_stm32::{bind_interrupts, can, Config};
8use embassy_time::Timer;
9use static_cell::StaticCell;
10use {defmt_rtt as _, panic_probe as _};
11
12bind_interrupts!(struct Irqs {
13 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
14 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
15});
16
17#[embassy_executor::main]
18async fn main(_spawner: Spawner) {
19 let mut config = Config::default();
20 {
21 use embassy_stm32::rcc::*;
22 config.rcc.hse = Some(Hse {
23 freq: Hertz(24_000_000),
24 mode: HseMode::Oscillator,
25 });
26 config.rcc.pll = Some(Pll {
27 source: PllSource::HSE,
28 prediv: PllPreDiv::DIV6,
29 mul: PllMul::MUL85,
30 divp: None,
31 divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan.
32 divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz
33 });
34 config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q;
35 config.rcc.sys = Sysclk::PLL1_R;
36 }
37 let peripherals = embassy_stm32::init(config);
38
39 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
40
41 can.set_extended_filter(
42 can::filter::ExtendedFilterSlot::_0,
43 can::filter::ExtendedFilter::accept_all_into_fifo1(),
44 );
45
46 // 250k bps
47 can.set_bitrate(250_000);
48
49 let use_fd = false;
50
51 // 1M bps
52 if use_fd {
53 can.set_fd_data_bitrate(1_000_000, false);
54 }
55
56 info!("Configured");
57
58 let mut can = can.start(match use_fd {
59 true => can::OperatingMode::InternalLoopbackMode,
60 false => can::OperatingMode::NormalOperationMode,
61 });
62
63 let mut i = 0;
64 let mut last_read_ts = embassy_time::Instant::now();
65
66 loop {
67 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
68 info!("Writing frame");
69
70 _ = can.write(&frame).await;
71
72 match can.read().await {
73 Ok(envelope) => {
74 let (ts, rx_frame) = (envelope.ts, envelope.frame);
75 let delta = (ts - last_read_ts).as_millis();
76 last_read_ts = ts;
77 info!(
78 "Rx: {} {:02x} --- {}ms",
79 rx_frame.header().len(),
80 rx_frame.data()[0..rx_frame.header().len() as usize],
81 delta,
82 )
83 }
84 Err(_err) => error!("Error in frame"),
85 }
86
87 Timer::after_millis(250).await;
88
89 i += 1;
90 if i > 2 {
91 break;
92 }
93 }
94
95 // Use the FD API's even if we don't get FD packets.
96
97 loop {
98 if use_fd {
99 let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 16]).unwrap();
100 info!("Writing frame using FD API");
101 _ = can.write_fd(&frame).await;
102 } else {
103 let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 8]).unwrap();
104 info!("Writing frame using FD API");
105 _ = can.write_fd(&frame).await;
106 }
107
108 match can.read_fd().await {
109 Ok(envelope) => {
110 let (ts, rx_frame) = (envelope.ts, envelope.frame);
111 let delta = (ts - last_read_ts).as_millis();
112 last_read_ts = ts;
113 info!(
114 "Rx: {} {:02x} --- using FD API {}ms",
115 rx_frame.header().len(),
116 rx_frame.data()[0..rx_frame.header().len() as usize],
117 delta,
118 )
119 }
120 Err(_err) => error!("Error in frame"),
121 }
122
123 Timer::after_millis(250).await;
124
125 i += 1;
126 if i > 4 {
127 break;
128 }
129 }
130 i = 0;
131 let (mut tx, mut rx) = can.split();
132 // With split
133 loop {
134 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
135 info!("Writing frame");
136 _ = tx.write(&frame).await;
137
138 match rx.read().await {
139 Ok(envelope) => {
140 let (ts, rx_frame) = (envelope.ts, envelope.frame);
141 let delta = (ts - last_read_ts).as_millis();
142 last_read_ts = ts;
143 info!(
144 "Rx: {} {:02x} --- {}ms",
145 rx_frame.header().len(),
146 rx_frame.data()[0..rx_frame.header().len() as usize],
147 delta,
148 )
149 }
150 Err(_err) => error!("Error in frame"),
151 }
152
153 Timer::after_millis(250).await;
154
155 i += 1;
156
157 if i > 2 {
158 break;
159 }
160 }
161
162 let can = can::Can::join(tx, rx);
163
164 info!("\n\n\nBuffered\n");
165 if use_fd {
166 static TX_BUF: StaticCell<can::TxFdBuf<8>> = StaticCell::new();
167 static RX_BUF: StaticCell<can::RxFdBuf<10>> = StaticCell::new();
168 let mut can = can.buffered_fd(
169 TX_BUF.init(can::TxFdBuf::<8>::new()),
170 RX_BUF.init(can::RxFdBuf::<10>::new()),
171 );
172 loop {
173 let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 16]).unwrap();
174 info!("Writing frame");
175
176 _ = can.write(frame).await;
177
178 match can.read().await {
179 Ok(envelope) => {
180 let (ts, rx_frame) = (envelope.ts, envelope.frame);
181 let delta = (ts - last_read_ts).as_millis();
182 last_read_ts = ts;
183 info!(
184 "Rx: {} {:02x} --- {}ms",
185 rx_frame.header().len(),
186 rx_frame.data()[0..rx_frame.header().len() as usize],
187 delta,
188 )
189 }
190 Err(_err) => error!("Error in frame"),
191 }
192
193 Timer::after_millis(250).await;
194
195 i += 1;
196 }
197 } else {
198 static TX_BUF: StaticCell<can::TxBuf<8>> = StaticCell::new();
199 static RX_BUF: StaticCell<can::RxBuf<10>> = StaticCell::new();
200 let mut can = can.buffered(
201 TX_BUF.init(can::TxBuf::<8>::new()),
202 RX_BUF.init(can::RxBuf::<10>::new()),
203 );
204 loop {
205 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
206 info!("Writing frame");
207
208 // You can use any of these approaches to send. The writer makes it
209 // easy to share sending from multiple tasks.
210 //_ = can.write(frame).await;
211 //can.writer().try_write(frame).unwrap();
212 can.writer().write(frame).await;
213
214 match can.read().await {
215 Ok(envelope) => {
216 let (ts, rx_frame) = (envelope.ts, envelope.frame);
217 let delta = (ts - last_read_ts).as_millis();
218 last_read_ts = ts;
219 info!(
220 "Rx: {} {:02x} --- {}ms",
221 rx_frame.header().len(),
222 rx_frame.data()[0..rx_frame.header().len() as usize],
223 delta,
224 )
225 }
226 Err(_err) => error!("Error in frame"),
227 }
228
229 Timer::after_millis(250).await;
230
231 i += 1;
232 }
233 }
234}
diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs
index 09ef59d44..08ed95b34 100644
--- a/examples/stm32g4/src/bin/pll.rs
+++ b/examples/stm32g4/src/bin/pll.rs
@@ -1,10 +1,8 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource};
8use embassy_stm32::Config; 6use embassy_stm32::Config;
9use embassy_time::Timer; 7use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
@@ -12,19 +10,20 @@ use {defmt_rtt as _, panic_probe as _};
12#[embassy_executor::main] 10#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 11async fn main(_spawner: Spawner) {
14 let mut config = Config::default(); 12 let mut config = Config::default();
15 13 {
16 config.rcc.pll = Some(Pll { 14 use embassy_stm32::rcc::*;
17 source: PllSource::HSI, 15 config.rcc.hsi = true;
18 prediv_m: PllM::DIV4, 16 config.rcc.pll = Some(Pll {
19 mul_n: PllN::MUL85, 17 source: PllSource::HSI,
20 div_p: None, 18 prediv: PllPreDiv::DIV4,
21 div_q: None, 19 mul: PllMul::MUL85,
22 // Main system clock at 170 MHz 20 divp: None,
23 div_r: Some(PllR::DIV2), 21 divq: None,
24 }); 22 // Main system clock at 170 MHz
25 23 divr: Some(PllRDiv::DIV2),
26 config.rcc.mux = ClockSrc::PLL; 24 });
27 25 config.rcc.sys = Sysclk::PLL1_R;
26 }
28 let _p = embassy_stm32::init(config); 27 let _p = embassy_stm32::init(config);
29 info!("Hello World!"); 28 info!("Hello World!");
30 29
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs
index a84394005..d4809a481 100644
--- a/examples/stm32g4/src/bin/pwm.rs
+++ b/examples/stm32g4/src/bin/pwm.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32g4/src/bin/usb_c_pd.rs b/examples/stm32g4/src/bin/usb_c_pd.rs
new file mode 100644
index 000000000..7caea634f
--- /dev/null
+++ b/examples/stm32g4/src/bin/usb_c_pd.rs
@@ -0,0 +1,86 @@
1#![no_std]
2#![no_main]
3
4use defmt::{error, info, Format};
5use embassy_executor::Spawner;
6use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, Ucpd};
7use embassy_stm32::{bind_interrupts, peripherals, Config};
8use embassy_time::{with_timeout, Duration};
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 UCPD1 => ucpd::InterruptHandler<peripherals::UCPD1>;
13});
14
15#[derive(Debug, Format)]
16enum CableOrientation {
17 Normal,
18 Flipped,
19 DebugAccessoryMode,
20}
21
22// Returns true when the cable
23async fn wait_attached<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>) -> CableOrientation {
24 loop {
25 let (cc1, cc2) = cc_phy.vstate();
26 if cc1 == CcVState::LOWEST && cc2 == CcVState::LOWEST {
27 // Detached, wait until attached by monitoring the CC lines.
28 cc_phy.wait_for_vstate_change().await;
29 continue;
30 }
31
32 // Attached, wait for CC lines to be stable for tCCDebounce (100..200ms).
33 if with_timeout(Duration::from_millis(100), cc_phy.wait_for_vstate_change())
34 .await
35 .is_ok()
36 {
37 // State has changed, restart detection procedure.
38 continue;
39 };
40
41 // State was stable for the complete debounce period, check orientation.
42 return match (cc1, cc2) {
43 (_, CcVState::LOWEST) => CableOrientation::Normal, // CC1 connected
44 (CcVState::LOWEST, _) => CableOrientation::Flipped, // CC2 connected
45 _ => CableOrientation::DebugAccessoryMode, // Both connected (special cable)
46 };
47 }
48}
49
50#[embassy_executor::main]
51async fn main(_spawner: Spawner) {
52 let mut config = Config::default();
53 config.enable_ucpd1_dead_battery = true;
54 let p = embassy_stm32::init(config);
55
56 info!("Hello World!");
57
58 let mut ucpd = Ucpd::new(p.UCPD1, Irqs {}, p.PB6, p.PB4);
59 ucpd.cc_phy().set_pull(CcPull::Sink);
60
61 info!("Waiting for USB connection...");
62 let cable_orientation = wait_attached(ucpd.cc_phy()).await;
63 info!("USB cable connected, orientation: {}", cable_orientation);
64
65 let cc_sel = match cable_orientation {
66 CableOrientation::Normal => {
67 info!("Starting PD communication on CC1 pin");
68 CcSel::CC1
69 }
70 CableOrientation::Flipped => {
71 info!("Starting PD communication on CC2 pin");
72 CcSel::CC2
73 }
74 CableOrientation::DebugAccessoryMode => panic!("No PD communication in DAM"),
75 };
76 let (_cc_phy, mut pd_phy) = ucpd.split_pd_phy(p.DMA1_CH1, p.DMA1_CH2, cc_sel);
77
78 loop {
79 // Enough space for the longest non-extended data message.
80 let mut buf = [0_u8; 30];
81 match pd_phy.receive(buf.as_mut()).await {
82 Ok(n) => info!("USB PD RX: {=[u8]:?}", &buf[..n]),
83 Err(e) => error!("USB PD RX: {}", e),
84 }
85 }
86}
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs
index 565b25d60..dbe8f27c1 100644
--- a/examples/stm32g4/src/bin/usb_serial.rs
+++ b/examples/stm32g4/src/bin/usb_serial.rs
@@ -1,10 +1,8 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource};
8use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
9use embassy_stm32::usb::{self, Driver, Instance}; 7use embassy_stm32::usb::{self, Driver, Instance};
10use embassy_stm32::{bind_interrupts, peripherals, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, Config};
@@ -21,31 +19,27 @@ bind_interrupts!(struct Irqs {
21#[embassy_executor::main] 19#[embassy_executor::main]
22async fn main(_spawner: Spawner) { 20async fn main(_spawner: Spawner) {
23 let mut config = Config::default(); 21 let mut config = Config::default();
24 22 {
25 // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. 23 use embassy_stm32::rcc::*;
26 const USE_HSI48: bool = true;
27
28 let plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) };
29
30 config.rcc.pll = Some(Pll {
31 source: PllSource::HSE(Hertz(8_000_000)),
32 prediv_m: PllM::DIV2,
33 mul_n: PllN::MUL72,
34 div_p: None,
35 div_q: plldivq,
36 // Main system clock at 144 MHz
37 div_r: Some(PllR::DIV2),
38 });
39
40 config.rcc.mux = ClockSrc::PLL;
41
42 if USE_HSI48 {
43 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. 24 // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
44 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); 25 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
45 } else { 26 config.rcc.hse = Some(Hse {
46 config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); 27 freq: Hertz(8_000_000),
28 mode: HseMode::Oscillator,
29 });
30 config.rcc.pll = Some(Pll {
31 source: PllSource::HSE,
32 prediv: PllPreDiv::DIV2,
33 mul: PllMul::MUL72,
34 divp: None,
35 divq: Some(PllQDiv::DIV6), // 48mhz
36 divr: Some(PllRDiv::DIV2), // Main system clock at 144 MHz
37 });
38 config.rcc.sys = Sysclk::PLL1_R;
39 config.rcc.boost = true; // BOOST!
40 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
41 //config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; // uncomment to use PLL1_Q instead.
47 } 42 }
48
49 let p = embassy_stm32::init(config); 43 let p = embassy_stm32::init(config);
50 44
51 info!("Hello World!"); 45 info!("Hello World!");
@@ -62,7 +56,6 @@ async fn main(_spawner: Spawner) {
62 config.device_protocol = 0x01; 56 config.device_protocol = 0x01;
63 config.composite_with_iads = true; 57 config.composite_with_iads = true;
64 58
65 let mut device_descriptor = [0; 256];
66 let mut config_descriptor = [0; 256]; 59 let mut config_descriptor = [0; 256];
67 let mut bos_descriptor = [0; 256]; 60 let mut bos_descriptor = [0; 256];
68 let mut control_buf = [0; 64]; 61 let mut control_buf = [0; 64];
@@ -72,7 +65,6 @@ async fn main(_spawner: Spawner) {
72 let mut builder = Builder::new( 65 let mut builder = Builder::new(
73 driver, 66 driver,
74 config, 67 config,
75 &mut device_descriptor,
76 &mut config_descriptor, 68 &mut config_descriptor,
77 &mut bos_descriptor, 69 &mut bos_descriptor,
78 &mut [], // no msos descriptors 70 &mut [], // no msos descriptors
diff --git a/examples/stm32h5/Cargo.toml b/examples/stm32h5/Cargo.toml
index 0ed0ce3c0..c9f08d24e 100644
--- a/examples/stm32h5/Cargo.toml
+++ b/examples/stm32h5/Cargo.toml
@@ -6,11 +6,11 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32h563zi to your chip name, if necessary. 8# Change stm32h563zi to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h563zi", "memory-x", "time-driver-any", "exti", "unstable-pac"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] } 13embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15 15
16defmt = "0.3" 16defmt = "0.3"
@@ -19,8 +19,8 @@ defmt-rtt = "0.4"
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } 22embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
23embedded-hal-async = { version = "=1.0.0-rc.2" } 23embedded-hal-async = { version = "1.0" }
24embedded-io-async = { version = "0.6.1" } 24embedded-io-async = { version = "0.6.1" }
25embedded-nal-async = { version = "0.7.1" } 25embedded-nal-async = { version = "0.7.1" }
26panic-probe = { version = "0.3", features = ["print-defmt"] } 26panic-probe = { version = "0.3", features = ["print-defmt"] }
@@ -31,7 +31,7 @@ critical-section = "1.1"
31micromath = "2.0.0" 31micromath = "2.0.0"
32stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
33embedded-storage = "0.3.1" 33embedded-storage = "0.3.1"
34static_cell = { version = "2", features = ["nightly"]} 34static_cell = "2"
35 35
36# cargo build/run 36# cargo build/run
37[profile.dev] 37[profile.dev]
diff --git a/examples/stm32h5/src/bin/blinky.rs b/examples/stm32h5/src/bin/blinky.rs
index 1394f03fa..f37e8b1d8 100644
--- a/examples/stm32h5/src/bin/blinky.rs
+++ b/examples/stm32h5/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h5/src/bin/button_exti.rs b/examples/stm32h5/src/bin/button_exti.rs
index dfe587d41..2a546dac5 100644
--- a/examples/stm32h5/src/bin/button_exti.rs
+++ b/examples/stm32h5/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs
new file mode 100644
index 000000000..dd625c90a
--- /dev/null
+++ b/examples/stm32h5/src/bin/can.rs
@@ -0,0 +1,98 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::peripherals::*;
7use embassy_stm32::{bind_interrupts, can, rcc, Config};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
13 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let mut config = Config::default();
19 config.rcc.hse = Some(rcc::Hse {
20 freq: embassy_stm32::time::Hertz(25_000_000),
21 mode: rcc::HseMode::Oscillator,
22 });
23 config.rcc.mux.fdcan12sel = rcc::mux::Fdcansel::HSE;
24
25 let peripherals = embassy_stm32::init(config);
26
27 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
28
29 // 250k bps
30 can.set_bitrate(250_000);
31
32 //let mut can = can.into_internal_loopback_mode();
33 let mut can = can.into_normal_mode();
34
35 info!("CAN Configured");
36
37 let mut i = 0;
38 let mut last_read_ts = embassy_time::Instant::now();
39
40 loop {
41 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
42 info!("Writing frame");
43 _ = can.write(&frame).await;
44
45 match can.read().await {
46 Ok(envelope) => {
47 let (rx_frame, ts) = envelope.parts();
48 let delta = (ts - last_read_ts).as_millis();
49 last_read_ts = ts;
50 info!(
51 "Rx: {:x} {:x} {:x} {:x} --- NEW {}",
52 rx_frame.data()[0],
53 rx_frame.data()[1],
54 rx_frame.data()[2],
55 rx_frame.data()[3],
56 delta,
57 )
58 }
59 Err(_err) => error!("Error in frame"),
60 }
61
62 Timer::after_millis(250).await;
63
64 i += 1;
65 if i > 3 {
66 break;
67 }
68 }
69
70 let (mut tx, mut rx) = can.split();
71 // With split
72 loop {
73 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
74 info!("Writing frame");
75 _ = tx.write(&frame).await;
76
77 match rx.read().await {
78 Ok(envelope) => {
79 let (rx_frame, ts) = envelope.parts();
80 let delta = (ts - last_read_ts).as_millis();
81 last_read_ts = ts;
82 info!(
83 "Rx: {:x} {:x} {:x} {:x} --- NEW {}",
84 rx_frame.data()[0],
85 rx_frame.data()[1],
86 rx_frame.data()[2],
87 rx_frame.data()[3],
88 delta,
89 )
90 }
91 Err(_err) => error!("Error in frame"),
92 }
93
94 Timer::after_millis(250).await;
95
96 i += 1;
97 }
98}
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index b2758cba0..2370656e6 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -18,7 +17,7 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
18use embassy_time::Timer; 17use embassy_time::Timer;
19use embedded_io_async::Write; 18use embedded_io_async::Write;
20use rand_core::RngCore; 19use rand_core::RngCore;
21use static_cell::make_static; 20use static_cell::StaticCell;
22use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
23 22
24bind_interrupts!(struct Irqs { 23bind_interrupts!(struct Irqs {
@@ -67,8 +66,9 @@ async fn main(spawner: Spawner) -> ! {
67 66
68 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 67 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
69 68
69 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new();
70 let device = Ethernet::new( 70 let device = Ethernet::new(
71 make_static!(PacketQueue::<4, 4>::new()), 71 PACKETS.init(PacketQueue::<4, 4>::new()),
72 p.ETH, 72 p.ETH,
73 Irqs, 73 Irqs,
74 p.PA1, 74 p.PA1,
@@ -92,11 +92,13 @@ async fn main(spawner: Spawner) -> ! {
92 //}); 92 //});
93 93
94 // Init network stack 94 // Init network stack
95 let stack = &*make_static!(Stack::new( 95 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
96 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
97 let stack = &*STACK.init(Stack::new(
96 device, 98 device,
97 config, 99 config,
98 make_static!(StackResources::<2>::new()), 100 RESOURCES.init(StackResources::<2>::new()),
99 seed 101 seed,
100 )); 102 ));
101 103
102 // Launch network task 104 // Launch network task
diff --git a/examples/stm32h5/src/bin/i2c.rs b/examples/stm32h5/src/bin/i2c.rs
index 31783a2bf..31e83cbb5 100644
--- a/examples/stm32h5/src/bin/i2c.rs
+++ b/examples/stm32h5/src/bin/i2c.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h5/src/bin/rng.rs b/examples/stm32h5/src/bin/rng.rs
index 7c8c50eca..9c0d704b5 100644
--- a/examples/stm32h5/src/bin/rng.rs
+++ b/examples/stm32h5/src/bin/rng.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h5/src/bin/usart.rs b/examples/stm32h5/src/bin/usart.rs
index db04d4e55..f9cbad6af 100644
--- a/examples/stm32h5/src/bin/usart.rs
+++ b/examples/stm32h5/src/bin/usart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32h5/src/bin/usart_dma.rs b/examples/stm32h5/src/bin/usart_dma.rs
index bafe50839..caae0dd18 100644
--- a/examples/stm32h5/src/bin/usart_dma.rs
+++ b/examples/stm32h5/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32h5/src/bin/usart_split.rs b/examples/stm32h5/src/bin/usart_split.rs
index d9037c014..92047de8d 100644
--- a/examples/stm32h5/src/bin/usart_split.rs
+++ b/examples/stm32h5/src/bin/usart_split.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs
index 7d45818af..4f86bb342 100644
--- a/examples/stm32h5/src/bin/usb_serial.rs
+++ b/examples/stm32h5/src/bin/usb_serial.rs
@@ -1,12 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::time::Hertz; 6use embassy_stm32::time::Hertz;
8use embassy_stm32::usb::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -42,15 +41,12 @@ async fn main(_spawner: Spawner) {
42 config.rcc.apb3_pre = APBPrescaler::DIV4; 41 config.rcc.apb3_pre = APBPrescaler::DIV4;
43 config.rcc.sys = Sysclk::PLL1_P; 42 config.rcc.sys = Sysclk::PLL1_P;
44 config.rcc.voltage_scale = VoltageScale::Scale0; 43 config.rcc.voltage_scale = VoltageScale::Scale0;
44 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
45 } 45 }
46 let p = embassy_stm32::init(config); 46 let p = embassy_stm32::init(config);
47 47
48 info!("Hello World!"); 48 info!("Hello World!");
49 49
50 pac::RCC.ccipr4().write(|w| {
51 w.set_usbsel(pac::rcc::vals::Usbsel::HSI48);
52 });
53
54 // Create the driver, from the HAL. 50 // Create the driver, from the HAL.
55 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); 51 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
56 52
@@ -69,7 +65,6 @@ async fn main(_spawner: Spawner) {
69 65
70 // Create embassy-usb DeviceBuilder using the driver and config. 66 // Create embassy-usb DeviceBuilder using the driver and config.
71 // It needs some buffers for building the descriptors. 67 // It needs some buffers for building the descriptors.
72 let mut device_descriptor = [0; 256];
73 let mut config_descriptor = [0; 256]; 68 let mut config_descriptor = [0; 256];
74 let mut bos_descriptor = [0; 256]; 69 let mut bos_descriptor = [0; 256];
75 let mut control_buf = [0; 64]; 70 let mut control_buf = [0; 64];
@@ -79,7 +74,6 @@ async fn main(_spawner: Spawner) {
79 let mut builder = Builder::new( 74 let mut builder = Builder::new(
80 driver, 75 driver,
81 config, 76 config,
82 &mut device_descriptor,
83 &mut config_descriptor, 77 &mut config_descriptor,
84 &mut bos_descriptor, 78 &mut bos_descriptor,
85 &mut [], // no msos descriptors 79 &mut [], // no msos descriptors
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index baa530cf6..d9ea2626d 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -8,9 +8,9 @@ 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.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "chrono"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "time-driver-any", "exti", "memory-x", "unstable-pac", "chrono"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] } 13embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6", "dns"] }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15 15
16defmt = "0.3" 16defmt = "0.3"
@@ -19,8 +19,8 @@ defmt-rtt = "0.4"
19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 19cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6" 21embedded-hal = "0.2.6"
22embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } 22embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
23embedded-hal-async = { version = "=1.0.0-rc.2" } 23embedded-hal-async = { version = "1.0" }
24embedded-nal-async = { version = "0.7.1" } 24embedded-nal-async = { version = "0.7.1" }
25embedded-io-async = { version = "0.6.1" } 25embedded-io-async = { version = "0.6.1" }
26panic-probe = { version = "0.3", features = ["print-defmt"] } 26panic-probe = { version = "0.3", features = ["print-defmt"] }
@@ -31,7 +31,7 @@ critical-section = "1.1"
31micromath = "2.0.0" 31micromath = "2.0.0"
32stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
33embedded-storage = "0.3.1" 33embedded-storage = "0.3.1"
34static_cell = { version = "2", features = ["nightly"]} 34static_cell = "2"
35chrono = { version = "^0.4", default-features = false } 35chrono = { version = "^0.4", default-features = false }
36 36
37# cargo build/run 37# cargo build/run
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index e367827e9..a5594d10c 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -39,7 +38,7 @@ async fn main(_spawner: Spawner) {
39 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 38 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
40 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 39 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
41 config.rcc.voltage_scale = VoltageScale::Scale1; 40 config.rcc.voltage_scale = VoltageScale::Scale1;
42 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 41 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
43 } 42 }
44 let mut p = embassy_stm32::init(config); 43 let mut p = embassy_stm32::init(config);
45 44
@@ -47,7 +46,7 @@ async fn main(_spawner: Spawner) {
47 46
48 let mut adc = Adc::new(p.ADC3, &mut Delay); 47 let mut adc = Adc::new(p.ADC3, &mut Delay);
49 48
50 adc.set_sample_time(SampleTime::Cycles32_5); 49 adc.set_sample_time(SampleTime::CYCLES32_5);
51 50
52 let mut vrefint_channel = adc.enable_vrefint(); 51 let mut vrefint_channel = adc.enable_vrefint();
53 52
diff --git a/examples/stm32h7/src/bin/blinky.rs b/examples/stm32h7/src/bin/blinky.rs
index a9cab1ff4..1ee90a870 100644
--- a/examples/stm32h7/src/bin/blinky.rs
+++ b/examples/stm32h7/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs
index dfe587d41..2a546dac5 100644
--- a/examples/stm32h7/src/bin/button_exti.rs
+++ b/examples/stm32h7/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs
index 489fb03dd..170a5aa28 100644
--- a/examples/stm32h7/src/bin/camera.rs
+++ b/examples/stm32h7/src/bin/camera.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use embassy_executor::Spawner; 4use embassy_executor::Spawner;
6use embassy_stm32::dcmi::{self, *}; 5use embassy_stm32::dcmi::{self, *};
@@ -79,9 +78,9 @@ async fn main(_spawner: Spawner) {
79 ); 78 );
80 79
81 defmt::info!("attempting capture"); 80 defmt::info!("attempting capture");
82 defmt::unwrap!(dcmi.capture(unsafe { &mut FRAME }).await); 81 defmt::unwrap!(dcmi.capture(unsafe { &mut *core::ptr::addr_of_mut!(FRAME) }).await);
83 82
84 defmt::info!("captured frame: {:x}", unsafe { &FRAME }); 83 defmt::info!("captured frame: {:x}", unsafe { &*core::ptr::addr_of!(FRAME) });
85 84
86 defmt::info!("main loop running"); 85 defmt::info!("main loop running");
87 loop { 86 loop {
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs
new file mode 100644
index 000000000..22cb27481
--- /dev/null
+++ b/examples/stm32h7/src/bin/can.rs
@@ -0,0 +1,98 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::peripherals::*;
7use embassy_stm32::{bind_interrupts, can, rcc, Config};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
13 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let mut config = Config::default();
19 config.rcc.hse = Some(rcc::Hse {
20 freq: embassy_stm32::time::Hertz(25_000_000),
21 mode: rcc::HseMode::Oscillator,
22 });
23 config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
24
25 let peripherals = embassy_stm32::init(config);
26
27 let mut can = can::CanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
28
29 // 250k bps
30 can.set_bitrate(250_000);
31
32 //let mut can = can.into_internal_loopback_mode();
33 let mut can = can.into_normal_mode();
34
35 info!("CAN Configured");
36
37 let mut i = 0;
38 let mut last_read_ts = embassy_time::Instant::now();
39
40 loop {
41 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
42 info!("Writing frame");
43 _ = can.write(&frame).await;
44
45 match can.read().await {
46 Ok(envelope) => {
47 let (rx_frame, ts) = envelope.parts();
48 let delta = (ts - last_read_ts).as_millis();
49 last_read_ts = ts;
50 info!(
51 "Rx: {:x} {:x} {:x} {:x} --- NEW {}",
52 rx_frame.data()[0],
53 rx_frame.data()[1],
54 rx_frame.data()[2],
55 rx_frame.data()[3],
56 delta,
57 )
58 }
59 Err(_err) => error!("Error in frame"),
60 }
61
62 Timer::after_millis(250).await;
63
64 i += 1;
65 if i > 3 {
66 break;
67 }
68 }
69
70 let (mut tx, mut rx) = can.split();
71 // With split
72 loop {
73 let frame = can::frame::Frame::new_extended(0x123456F, &[i; 8]).unwrap();
74 info!("Writing frame");
75 _ = tx.write(&frame).await;
76
77 match rx.read().await {
78 Ok(envelope) => {
79 let (rx_frame, ts) = envelope.parts();
80 let delta = (ts - last_read_ts).as_millis();
81 last_read_ts = ts;
82 info!(
83 "Rx: {:x} {:x} {:x} {:x} --- NEW {}",
84 rx_frame.data()[0],
85 rx_frame.data()[1],
86 rx_frame.data()[2],
87 rx_frame.data()[3],
88 delta,
89 )
90 }
91 Err(_err) => error!("Error in frame"),
92 }
93
94 Timer::after_millis(250).await;
95
96 i += 1;
97 }
98}
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs
index f66268151..a6f969aba 100644
--- a/examples/stm32h7/src/bin/dac.rs
+++ b/examples/stm32h7/src/bin/dac.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
@@ -41,7 +40,7 @@ fn main() -> ! {
41 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
42 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
43 config.rcc.voltage_scale = VoltageScale::Scale1; 42 config.rcc.voltage_scale = VoltageScale::Scale1;
44 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 43 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
45 } 44 }
46 let p = embassy_stm32::init(config); 45 let p = embassy_stm32::init(config);
47 46
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs
index c19fdd623..3a9887e3c 100644
--- a/examples/stm32h7/src/bin/dac_dma.rs
+++ b/examples/stm32h7/src/bin/dac_dma.rs
@@ -1,15 +1,14 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
8use embassy_stm32::pac::timer::vals::{Mms, Opm}; 7use embassy_stm32::pac::timer::vals::Mms;
9use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
10use embassy_stm32::rcc::low_level::RccPeripheral; 9use embassy_stm32::rcc::frequency;
11use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
12use embassy_stm32::timer::low_level::Basic16bitInstance; 11use embassy_stm32::timer::low_level::Timer;
13use micromath::F32Ext; 12use micromath::F32Ext;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
@@ -43,7 +42,7 @@ async fn main(spawner: Spawner) {
43 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 42 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
44 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 43 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
45 config.rcc.voltage_scale = VoltageScale::Scale1; 44 config.rcc.voltage_scale = VoltageScale::Scale1;
46 config.rcc.adc_clock_source = AdcClockSource::PLL2_P; 45 config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
47 } 46 }
48 47
49 // Initialize the board and obtain a Peripherals instance 48 // Initialize the board and obtain a Peripherals instance
@@ -52,19 +51,19 @@ async fn main(spawner: Spawner) {
52 // Obtain two independent channels (p.DAC1 can only be consumed once, though!) 51 // Obtain two independent channels (p.DAC1 can only be consumed once, though!)
53 let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); 52 let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split();
54 53
55 spawner.spawn(dac_task1(dac_ch1)).ok(); 54 spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok();
56 spawner.spawn(dac_task2(dac_ch2)).ok(); 55 spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok();
57} 56}
58 57
59#[embassy_executor::task] 58#[embassy_executor::task]
60async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 59async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
61 let data: &[u8; 256] = &calculate_array::<256>(); 60 let data: &[u8; 256] = &calculate_array::<256>();
62 61
63 info!("TIM6 frequency is {}", TIM6::frequency()); 62 info!("TIM6 frequency is {}", frequency::<TIM6>());
64 const FREQUENCY: Hertz = Hertz::hz(200); 63 const FREQUENCY: Hertz = Hertz::hz(200);
65 64
66 // Compute the reload value such that we obtain the FREQUENCY for the sine 65 // Compute the reload value such that we obtain the FREQUENCY for the sine
67 let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; 66 let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
68 67
69 // Depends on your clock and on the specific chip used, you may need higher or lower values here 68 // Depends on your clock and on the specific chip used, you may need higher or lower values here
70 if reload < 10 { 69 if reload < 10 {
@@ -75,17 +74,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
75 dac.set_triggering(true); 74 dac.set_triggering(true);
76 dac.enable(); 75 dac.enable();
77 76
78 TIM6::enable_and_reset(); 77 let tim = Timer::new(tim);
79 TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); 78 tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
80 TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); 79 tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
81 TIM6::regs().cr1().modify(|w| { 80 tim.regs_basic().cr1().modify(|w| {
82 w.set_opm(Opm::DISABLED); 81 w.set_opm(false);
83 w.set_cen(true); 82 w.set_cen(true);
84 }); 83 });
85 84
86 debug!( 85 debug!(
87 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 86 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
88 TIM6::frequency(), 87 frequency::<TIM6>(),
89 FREQUENCY, 88 FREQUENCY,
90 reload, 89 reload,
91 reload as u16, 90 reload as u16,
@@ -100,23 +99,23 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
100} 99}
101 100
102#[embassy_executor::task] 101#[embassy_executor::task]
103async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 102async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
104 let data: &[u8; 256] = &calculate_array::<256>(); 103 let data: &[u8; 256] = &calculate_array::<256>();
105 104
106 info!("TIM7 frequency is {}", TIM7::frequency()); 105 info!("TIM7 frequency is {}", frequency::<TIM6>());
107 106
108 const FREQUENCY: Hertz = Hertz::hz(600); 107 const FREQUENCY: Hertz = Hertz::hz(600);
109 let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; 108 let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
110 109
111 if reload < 10 { 110 if reload < 10 {
112 error!("Reload value {} below threshold!", reload); 111 error!("Reload value {} below threshold!", reload);
113 } 112 }
114 113
115 TIM7::enable_and_reset(); 114 let tim = Timer::new(tim);
116 TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); 115 tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
117 TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); 116 tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
118 TIM7::regs().cr1().modify(|w| { 117 tim.regs_basic().cr1().modify(|w| {
119 w.set_opm(Opm::DISABLED); 118 w.set_opm(false);
120 w.set_cen(true); 119 w.set_cen(true);
121 }); 120 });
122 121
@@ -126,7 +125,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
126 125
127 debug!( 126 debug!(
128 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 127 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
129 TIM7::frequency(), 128 frequency::<TIM7>(),
130 FREQUENCY, 129 FREQUENCY,
131 reload, 130 reload,
132 reload as u16, 131 reload as u16,
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index dbddfc22f..7c7964ecd 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -14,7 +13,7 @@ use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
14use embassy_time::Timer; 13use embassy_time::Timer;
15use embedded_io_async::Write; 14use embedded_io_async::Write;
16use rand_core::RngCore; 15use rand_core::RngCore;
17use static_cell::make_static; 16use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
19 18
20bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -64,19 +63,22 @@ async fn main(spawner: Spawner) -> ! {
64 63
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66 65
66 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new();
67 // warning: Not all STM32H7 devices have the exact same pins here
68 // for STM32H747XIH, replace p.PB13 for PG12
67 let device = Ethernet::new( 69 let device = Ethernet::new(
68 make_static!(PacketQueue::<16, 16>::new()), 70 PACKETS.init(PacketQueue::<4, 4>::new()),
69 p.ETH, 71 p.ETH,
70 Irqs, 72 Irqs,
71 p.PA1, 73 p.PA1, // ref_clk
72 p.PA2, 74 p.PA2, // mdio
73 p.PC1, 75 p.PC1, // eth_mdc
74 p.PA7, 76 p.PA7, // CRS_DV: Carrier Sense
75 p.PC4, 77 p.PC4, // RX_D0: Received Bit 0
76 p.PC5, 78 p.PC5, // RX_D1: Received Bit 1
77 p.PG13, 79 p.PG13, // TX_D0: Transmit Bit 0
78 p.PB13, 80 p.PB13, // TX_D1: Transmit Bit 1
79 p.PG11, 81 p.PG11, // TX_EN: Transmit Enable
80 GenericSMI::new(0), 82 GenericSMI::new(0),
81 mac_addr, 83 mac_addr,
82 ); 84 );
@@ -89,11 +91,13 @@ async fn main(spawner: Spawner) -> ! {
89 //}); 91 //});
90 92
91 // Init network stack 93 // Init network stack
92 let stack = &*make_static!(Stack::new( 94 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
95 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
96 let stack = &*STACK.init(Stack::new(
93 device, 97 device,
94 config, 98 config,
95 make_static!(StackResources::<3>::new()), 99 RESOURCES.init(StackResources::<3>::new()),
96 seed 100 seed,
97 )); 101 ));
98 102
99 // Launch network task 103 // Launch network task
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index 17e1d9fb7..aeb169e19 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -15,7 +14,7 @@ use embassy_time::Timer;
15use embedded_io_async::Write; 14use embedded_io_async::Write;
16use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; 15use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
17use rand_core::RngCore; 16use rand_core::RngCore;
18use static_cell::make_static; 17use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
20 19
21bind_interrupts!(struct Irqs { 20bind_interrupts!(struct Irqs {
@@ -65,8 +64,10 @@ async fn main(spawner: Spawner) -> ! {
65 64
66 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
67 66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68
68 let device = Ethernet::new( 69 let device = Ethernet::new(
69 make_static!(PacketQueue::<16, 16>::new()), 70 PACKETS.init(PacketQueue::<16, 16>::new()),
70 p.ETH, 71 p.ETH,
71 Irqs, 72 Irqs,
72 p.PA1, 73 p.PA1,
@@ -90,11 +91,13 @@ async fn main(spawner: Spawner) -> ! {
90 //}); 91 //});
91 92
92 // Init network stack 93 // Init network stack
93 let stack = &*make_static!(Stack::new( 94 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
95 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
96 let stack = &*STACK.init(Stack::new(
94 device, 97 device,
95 config, 98 config,
96 make_static!(StackResources::<3>::new()), 99 RESOURCES.init(StackResources::<3>::new()),
97 seed 100 seed,
98 )); 101 ));
99 102
100 // Launch network task 103 // Launch network task
diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs
new file mode 100644
index 000000000..de6ea522a
--- /dev/null
+++ b/examples/stm32h7/src/bin/eth_client_mii.rs
@@ -0,0 +1,142 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_net::tcp::client::{TcpClient, TcpClientState};
7use embassy_net::{Stack, StackResources};
8use embassy_stm32::eth::generic_smi::GenericSMI;
9use embassy_stm32::eth::{Ethernet, PacketQueue};
10use embassy_stm32::peripherals::ETH;
11use embassy_stm32::rng::Rng;
12use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
13use embassy_time::Timer;
14use embedded_io_async::Write;
15use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
16use rand_core::RngCore;
17use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _};
19
20bind_interrupts!(struct Irqs {
21 ETH => eth::InterruptHandler;
22 RNG => rng::InterruptHandler<peripherals::RNG>;
23});
24
25type Device = Ethernet<'static, ETH, GenericSMI>;
26
27#[embassy_executor::task]
28async fn net_task(stack: &'static Stack<Device>) -> ! {
29 stack.run().await
30}
31
32#[embassy_executor::main]
33async fn main(spawner: Spawner) -> ! {
34 let mut config = Config::default();
35 {
36 use embassy_stm32::rcc::*;
37 config.rcc.hsi = Some(HSIPrescaler::DIV1);
38 config.rcc.csi = true;
39 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
40 config.rcc.pll1 = Some(Pll {
41 source: PllSource::HSI,
42 prediv: PllPreDiv::DIV4,
43 mul: PllMul::MUL50,
44 divp: Some(PllDiv::DIV2),
45 divq: None,
46 divr: None,
47 });
48 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
49 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
50 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
51 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
52 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
53 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
54 config.rcc.voltage_scale = VoltageScale::Scale1;
55 }
56 let p = embassy_stm32::init(config);
57 info!("Hello World!");
58
59 // Generate random seed.
60 let mut rng = Rng::new(p.RNG, Irqs);
61 let mut seed = [0; 8];
62 rng.fill_bytes(&mut seed);
63 let seed = u64::from_le_bytes(seed);
64
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68
69 let device = Ethernet::new_mii(
70 PACKETS.init(PacketQueue::<16, 16>::new()),
71 p.ETH,
72 Irqs,
73 p.PA1,
74 p.PC3,
75 p.PA2,
76 p.PC1,
77 p.PA7,
78 p.PC4,
79 p.PC5,
80 p.PB0,
81 p.PB1,
82 p.PG13,
83 p.PG12,
84 p.PC2,
85 p.PE2,
86 p.PG11,
87 GenericSMI::new(1),
88 mac_addr,
89 );
90 info!("Device created");
91
92 let config = embassy_net::Config::dhcpv4(Default::default());
93 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
94 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
95 // dns_servers: Vec::new(),
96 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
97 //});
98
99 // Init network stack
100 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
101 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
102 let stack = &*STACK.init(Stack::new(
103 device,
104 config,
105 RESOURCES.init(StackResources::<3>::new()),
106 seed,
107 ));
108
109 // Launch network task
110 unwrap!(spawner.spawn(net_task(stack)));
111
112 // Ensure DHCP configuration is up before trying connect
113 stack.wait_config_up().await;
114
115 info!("Network task initialized");
116
117 let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
118 let client = TcpClient::new(&stack, &state);
119
120 loop {
121 // You need to start a server on the host machine, for example: `nc -l 8000`
122 let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000));
123
124 info!("connecting...");
125 let r = client.connect(addr).await;
126 if let Err(e) = r {
127 info!("connect error: {:?}", e);
128 Timer::after_secs(1).await;
129 continue;
130 }
131 let mut connection = r.unwrap();
132 info!("connected!");
133 loop {
134 let r = connection.write_all(b"Hello\n").await;
135 if let Err(e) = r {
136 info!("write error: {:?}", e);
137 break;
138 }
139 Timer::after_secs(1).await;
140 }
141 }
142}
diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs
index 89c0c8a66..4f9f6bb0a 100644
--- a/examples/stm32h7/src/bin/flash.rs
+++ b/examples/stm32h7/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
index 54e2c3629..5e5e6ccc8 100644
--- a/examples/stm32h7/src/bin/fmc.rs
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs
index aea21ec6f..3bf39eb44 100644
--- a/examples/stm32h7/src/bin/i2c.rs
+++ b/examples/stm32h7/src/bin/i2c.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index e0be495d1..a95b44b74 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -1,14 +1,13 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::gpio::low_level::AFType; 6use embassy_stm32::gpio::{AFType, Flex, Pull, Speed};
8use embassy_stm32::gpio::Speed;
9use embassy_stm32::time::{khz, Hertz}; 7use embassy_stm32::time::{khz, Hertz};
10use embassy_stm32::timer::*; 8use embassy_stm32::timer::low_level::{OutputCompareMode, Timer as LLTimer};
11use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef}; 9use embassy_stm32::timer::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance32bit4Channel};
10use embassy_stm32::{into_ref, Config, Peripheral};
12use embassy_time::Timer; 11use embassy_time::Timer;
13use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
14 13
@@ -57,11 +56,15 @@ async fn main(_spawner: Spawner) {
57 Timer::after_millis(300).await; 56 Timer::after_millis(300).await;
58 } 57 }
59} 58}
60pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { 59pub struct SimplePwm32<'d, T: GeneralInstance32bit4Channel> {
61 inner: PeripheralRef<'d, T>, 60 tim: LLTimer<'d, T>,
61 _ch1: Flex<'d>,
62 _ch2: Flex<'d>,
63 _ch3: Flex<'d>,
64 _ch4: Flex<'d>,
62} 65}
63 66
64impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { 67impl<'d, T: GeneralInstance32bit4Channel> SimplePwm32<'d, T> {
65 pub fn new( 68 pub fn new(
66 tim: impl Peripheral<P = T> + 'd, 69 tim: impl Peripheral<P = T> + 'd,
67 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, 70 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
@@ -70,25 +73,33 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
70 ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, 73 ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
71 freq: Hertz, 74 freq: Hertz,
72 ) -> Self { 75 ) -> Self {
73 into_ref!(tim, ch1, ch2, ch3, ch4); 76 into_ref!(ch1, ch2, ch3, ch4);
74 77
75 T::enable_and_reset(); 78 let af1 = ch1.af_num();
76 79 let af2 = ch2.af_num();
77 ch1.set_speed(Speed::VeryHigh); 80 let af3 = ch3.af_num();
78 ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); 81 let af4 = ch4.af_num();
79 ch2.set_speed(Speed::VeryHigh); 82 let mut ch1 = Flex::new(ch1);
80 ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); 83 let mut ch2 = Flex::new(ch2);
81 ch3.set_speed(Speed::VeryHigh); 84 let mut ch3 = Flex::new(ch3);
82 ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); 85 let mut ch4 = Flex::new(ch4);
83 ch4.set_speed(Speed::VeryHigh); 86 ch1.set_as_af_unchecked(af1, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
84 ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); 87 ch2.set_as_af_unchecked(af2, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
85 88 ch3.set_as_af_unchecked(af3, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
86 let mut this = Self { inner: tim }; 89 ch4.set_as_af_unchecked(af4, AFType::OutputPushPull, Pull::None, Speed::VeryHigh);
87 90
88 this.set_freq(freq); 91 let mut this = Self {
89 this.inner.start(); 92 tim: LLTimer::new(tim),
90 93 _ch1: ch1,
91 let r = T::regs_gp32(); 94 _ch2: ch2,
95 _ch3: ch3,
96 _ch4: ch4,
97 };
98
99 this.set_frequency(freq);
100 this.tim.start();
101
102 let r = this.tim.regs_gp32();
92 r.ccmr_output(0) 103 r.ccmr_output(0)
93 .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); 104 .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into()));
94 r.ccmr_output(0) 105 r.ccmr_output(0)
@@ -102,23 +113,26 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
102 } 113 }
103 114
104 pub fn enable(&mut self, channel: Channel) { 115 pub fn enable(&mut self, channel: Channel) {
105 T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), true)); 116 self.tim.regs_gp32().ccer().modify(|w| w.set_cce(channel.index(), true));
106 } 117 }
107 118
108 pub fn disable(&mut self, channel: Channel) { 119 pub fn disable(&mut self, channel: Channel) {
109 T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), false)); 120 self.tim
121 .regs_gp32()
122 .ccer()
123 .modify(|w| w.set_cce(channel.index(), false));
110 } 124 }
111 125
112 pub fn set_freq(&mut self, freq: Hertz) { 126 pub fn set_frequency(&mut self, freq: Hertz) {
113 <T as embassy_stm32::timer::low_level::GeneralPurpose32bitInstance>::set_frequency(&mut self.inner, freq); 127 self.tim.set_frequency(freq);
114 } 128 }
115 129
116 pub fn get_max_duty(&self) -> u32 { 130 pub fn get_max_duty(&self) -> u32 {
117 T::regs_gp32().arr().read().arr() 131 self.tim.regs_gp32().arr().read()
118 } 132 }
119 133
120 pub fn set_duty(&mut self, channel: Channel, duty: u32) { 134 pub fn set_duty(&mut self, channel: Channel, duty: u32) {
121 defmt::assert!(duty < self.get_max_duty()); 135 defmt::assert!(duty < self.get_max_duty());
122 T::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(duty)) 136 self.tim.regs_gp32().ccr(channel.index()).write_value(duty)
123 } 137 }
124} 138}
diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs
index c023f4584..a6ee27625 100644
--- a/examples/stm32h7/src/bin/mco.rs
+++ b/examples/stm32h7/src/bin/mco.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs
index c55d780a0..1e48ba67b 100644
--- a/examples/stm32h7/src/bin/pwm.rs
+++ b/examples/stm32h7/src/bin/pwm.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs
index 1fb4cfec0..a9ef7200d 100644
--- a/examples/stm32h7/src/bin/rng.rs
+++ b/examples/stm32h7/src/bin/rng.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs
index 78cea9c89..0adb48877 100644
--- a/examples/stm32h7/src/bin/rtc.rs
+++ b/examples/stm32h7/src/bin/rtc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use chrono::{NaiveDate, NaiveDateTime}; 4use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 5use defmt::*;
@@ -25,7 +24,7 @@ async fn main(_spawner: Spawner) {
25 .unwrap(); 24 .unwrap();
26 25
27 let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 26 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
28 info!("Got RTC! {:?}", now.timestamp()); 27 info!("Got RTC! {:?}", now.and_utc().timestamp());
29 28
30 rtc.set_datetime(now.into()).expect("datetime not set"); 29 rtc.set_datetime(now.into()).expect("datetime not set");
31 30
@@ -33,5 +32,5 @@ async fn main(_spawner: Spawner) {
33 Timer::after_millis(20000).await; 32 Timer::after_millis(20000).await;
34 33
35 let then: NaiveDateTime = rtc.now().unwrap().into(); 34 let then: NaiveDateTime = rtc.now().unwrap().into();
36 info!("Got RTC! {:?}", then.timestamp()); 35 info!("Got RTC! {:?}", then.and_utc().timestamp());
37} 36}
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index be968ff77..abe2d4ba7 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs
index b5f583289..b73360f32 100644
--- a/examples/stm32h7/src/bin/signal.rs
+++ b/examples/stm32h7/src/bin/signal.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs
index a8db0ff77..aed27723a 100644
--- a/examples/stm32h7/src/bin/spi.rs
+++ b/examples/stm32h7/src/bin/spi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6use core::str::from_utf8; 5use core::str::from_utf8;
diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs
index 561052e48..54d4d7656 100644
--- a/examples/stm32h7/src/bin/spi_dma.rs
+++ b/examples/stm32h7/src/bin/spi_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6use core::str::from_utf8; 5use core::str::from_utf8;
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs
index db04d4e55..f9cbad6af 100644
--- a/examples/stm32h7/src/bin/usart.rs
+++ b/examples/stm32h7/src/bin/usart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index 249050fd1..ae1f3a2e9 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs
index 61c9f1954..b98c40877 100644
--- a/examples/stm32h7/src/bin/usart_split.rs
+++ b/examples/stm32h7/src/bin/usart_split.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs
index f80cf63ec..576506ad3 100644
--- a/examples/stm32h7/src/bin/usb_serial.rs
+++ b/examples/stm32h7/src/bin/usb_serial.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::usb_otg::{Driver, Instance}; 6use embassy_stm32::usb::{Driver, Instance};
8use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; 7use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
9use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 8use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
10use embassy_usb::driver::EndpointError; 9use embassy_usb::driver::EndpointError;
11use embassy_usb::Builder; 10use embassy_usb::Builder;
@@ -13,7 +12,7 @@ use futures::future::join;
13use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
14 13
15bind_interrupts!(struct Irqs { 14bind_interrupts!(struct Irqs {
16 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 15 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
17}); 16});
18 17
19#[embassy_executor::main] 18#[embassy_executor::main]
@@ -41,12 +40,13 @@ async fn main(_spawner: Spawner) {
41 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz 40 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
42 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz 41 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
43 config.rcc.voltage_scale = VoltageScale::Scale1; 42 config.rcc.voltage_scale = VoltageScale::Scale1;
43 config.rcc.mux.usbsel = mux::Usbsel::HSI48;
44 } 44 }
45 let p = embassy_stm32::init(config); 45 let p = embassy_stm32::init(config);
46 46
47 // Create the driver, from the HAL. 47 // Create the driver, from the HAL.
48 let mut ep_out_buffer = [0u8; 256]; 48 let mut ep_out_buffer = [0u8; 256];
49 let mut config = embassy_stm32::usb_otg::Config::default(); 49 let mut config = embassy_stm32::usb::Config::default();
50 config.vbus_detection = true; 50 config.vbus_detection = true;
51 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 51 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
52 52
@@ -65,7 +65,6 @@ async fn main(_spawner: Spawner) {
65 65
66 // Create embassy-usb DeviceBuilder using the driver and config. 66 // Create embassy-usb DeviceBuilder using the driver and config.
67 // It needs some buffers for building the descriptors. 67 // It needs some buffers for building the descriptors.
68 let mut device_descriptor = [0; 256];
69 let mut config_descriptor = [0; 256]; 68 let mut config_descriptor = [0; 256];
70 let mut bos_descriptor = [0; 256]; 69 let mut bos_descriptor = [0; 256];
71 let mut control_buf = [0; 64]; 70 let mut control_buf = [0; 64];
@@ -75,7 +74,6 @@ async fn main(_spawner: Spawner) {
75 let mut builder = Builder::new( 74 let mut builder = Builder::new(
76 driver, 75 driver,
77 config, 76 config,
78 &mut device_descriptor,
79 &mut config_descriptor, 77 &mut config_descriptor,
80 &mut bos_descriptor, 78 &mut bos_descriptor,
81 &mut [], // no msos descriptors 79 &mut [], // no msos descriptors
diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs
index 76fd9dfc0..a4184aa96 100644
--- a/examples/stm32h7/src/bin/wdg.rs
+++ b/examples/stm32h7/src/bin/wdg.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 7c8264739..dd9097c9b 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -4,16 +4,12 @@ name = "embassy-stm32l0-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[features]
8default = ["nightly"]
9nightly = ["embassy-executor/nightly"]
10
11[dependencies] 7[dependencies]
12# Change stm32l072cz to your chip name, if necessary. 8# Change stm32l072cz to your chip name, if necessary.
13embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] }
14embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
15embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
16embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
17 13
18defmt = "0.3" 14defmt = "0.3"
19defmt-rtt = "0.4" 15defmt-rtt = "0.4"
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs
new file mode 100644
index 000000000..97d41ca4b
--- /dev/null
+++ b/examples/stm32l0/src/bin/adc.rs
@@ -0,0 +1,40 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::peripherals::ADC;
8use embassy_stm32::{adc, bind_interrupts};
9use embassy_time::{Delay, Timer};
10use {defmt_rtt as _, panic_probe as _};
11
12bind_interrupts!(struct Irqs {
13 ADC1_COMP => adc::InterruptHandler<ADC>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let p = embassy_stm32::init(Default::default());
19 info!("Hello World!");
20
21 let mut adc = Adc::new(p.ADC, Irqs, &mut Delay);
22 adc.set_sample_time(SampleTime::CYCLES79_5);
23 let mut pin = p.PA1;
24
25 let mut vrefint = adc.enable_vref(&mut Delay);
26 let vrefint_sample = adc.read(&mut vrefint).await;
27 let convert_to_millivolts = |sample| {
28 // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf
29 // 6.3.3 Embedded internal reference voltage
30 const VREFINT_MV: u32 = 1224; // mV
31
32 (u32::from(sample) * VREFINT_MV / u32::from(vrefint_sample)) as u16
33 };
34
35 loop {
36 let v = adc.read(&mut pin).await;
37 info!("--> {} - {} mV", v, convert_to_millivolts(v));
38 Timer::after_millis(100).await;
39 }
40}
diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs
index ea40bfc48..caca5759f 100644
--- a/examples/stm32l0/src/bin/blinky.rs
+++ b/examples/stm32l0/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/src/bin/button.rs b/examples/stm32l0/src/bin/button.rs
index 9d194471e..707486cdc 100644
--- a/examples/stm32l0/src/bin/button.rs
+++ b/examples/stm32l0/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs
index ffede253e..4945da7ce 100644
--- a/examples/stm32l0/src/bin/button_exti.rs
+++ b/examples/stm32l0/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use embassy_stm32::Config; 8use embassy_stm32::Config;
10use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
11 10
@@ -14,8 +13,7 @@ async fn main(_spawner: Spawner) {
14 let config = Config::default(); 13 let config = Config::default();
15 let p = embassy_stm32::init(config); 14 let p = embassy_stm32::init(config);
16 15
17 let button = Input::new(p.PB2, Pull::Up); 16 let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up);
18 let mut button = ExtiInput::new(button, p.EXTI2);
19 17
20 info!("Press the USER button..."); 18 info!("Press the USER button...");
21 19
diff --git a/examples/stm32l0/src/bin/flash.rs b/examples/stm32l0/src/bin/flash.rs
index 86f6c70b9..1865748fd 100644
--- a/examples/stm32l0/src/bin/flash.rs
+++ b/examples/stm32l0/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs
index 583e3d127..f23a537b8 100644
--- a/examples/stm32l0/src/bin/spi.rs
+++ b/examples/stm32l0/src/bin/spi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/src/bin/usart_dma.rs b/examples/stm32l0/src/bin/usart_dma.rs
index 62c9b5595..74889c838 100644
--- a/examples/stm32l0/src/bin/usart_dma.rs
+++ b/examples/stm32l0/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index 5107a1a0a..2c96a8bc2 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml
index 23dd0ef87..322c41262 100644
--- a/examples/stm32l1/Cargo.toml
+++ b/examples/stm32l1/Cargo.toml
@@ -6,9 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
9embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 9embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
10embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 10embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] }
12embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
12 13
13defmt = "0.3" 14defmt = "0.3"
14defmt-rtt = "0.4" 15defmt-rtt = "0.4"
diff --git a/examples/stm32l1/src/bin/blinky.rs b/examples/stm32l1/src/bin/blinky.rs
index 06f732eb7..da6777b2d 100644
--- a/examples/stm32l1/src/bin/blinky.rs
+++ b/examples/stm32l1/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l1/src/bin/flash.rs b/examples/stm32l1/src/bin/flash.rs
index aeb535cca..e9ce4eae8 100644
--- a/examples/stm32l1/src/bin/flash.rs
+++ b/examples/stm32l1/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l1/src/bin/spi.rs b/examples/stm32l1/src/bin/spi.rs
index 905b4d75c..8be686c5a 100644
--- a/examples/stm32l1/src/bin/spi.rs
+++ b/examples/stm32l1/src/bin/spi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs
new file mode 100644
index 000000000..653bbd6d2
--- /dev/null
+++ b/examples/stm32l1/src/bin/usb_serial.rs
@@ -0,0 +1,101 @@
1#![no_std]
2#![no_main]
3
4use defmt::{panic, *};
5use embassy_executor::Spawner;
6use embassy_stm32::usb::{self, Driver, Instance};
7use embassy_stm32::{bind_interrupts, peripherals};
8use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
9use embassy_usb::driver::EndpointError;
10use embassy_usb::Builder;
11use futures::future::join;
12use {defmt_rtt as _, panic_probe as _};
13
14bind_interrupts!(struct Irqs {
15 USB_LP => usb::InterruptHandler<peripherals::USB>;
16
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 let mut config = embassy_stm32::Config::default();
22 {
23 use embassy_stm32::rcc::*;
24 config.rcc.hsi = true;
25 config.rcc.pll = Some(Pll {
26 source: PllSource::HSI,
27 mul: PllMul::MUL6, // PLLVCO = 16*6 = 96Mhz
28 div: PllDiv::DIV3, // 32Mhz clock (16 * 6 / 3)
29 });
30 config.rcc.sys = Sysclk::PLL1_R;
31 }
32
33 let p = embassy_stm32::init(config);
34
35 info!("Hello World!");
36
37 let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
38
39 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
40 config.manufacturer = Some("Embassy");
41 config.product = Some("USB-Serial Example");
42 config.serial_number = Some("123456");
43
44 config.device_class = 0xEF;
45 config.device_sub_class = 0x02;
46 config.device_protocol = 0x01;
47 config.composite_with_iads = true;
48
49 let mut config_descriptor = [0; 256];
50 let mut bos_descriptor = [0; 256];
51 let mut control_buf = [0; 64];
52
53 let mut state = State::new();
54
55 let mut builder = Builder::new(
56 driver,
57 config,
58 &mut config_descriptor,
59 &mut bos_descriptor,
60 &mut [], // no msos descriptors
61 &mut control_buf,
62 );
63
64 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
65
66 let mut usb = builder.build();
67
68 let usb_fut = usb.run();
69
70 let echo_fut = async {
71 loop {
72 class.wait_connection().await;
73 info!("Connected");
74 let _ = echo(&mut class).await;
75 info!("Disconnected");
76 }
77 };
78
79 join(usb_fut, echo_fut).await;
80}
81
82struct Disconnected {}
83
84impl From<EndpointError> for Disconnected {
85 fn from(val: EndpointError) -> Self {
86 match val {
87 EndpointError::BufferOverflow => panic!("Buffer overflow"),
88 EndpointError::Disabled => Disconnected {},
89 }
90 }
91}
92
93async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> {
94 let mut buf = [0; 64];
95 loop {
96 let n = class.read_packet(&mut buf).await?;
97 let data = &buf[..n];
98 info!("data: {:x}", data);
99 class.write_packet(data).await?;
100 }
101}
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml
index a936d27c3..d42e69578 100644
--- a/examples/stm32l4/Cargo.toml
+++ b/examples/stm32l4/Cargo.toml
@@ -8,12 +8,12 @@ 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.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "chrono"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l4s5qi", "memory-x", "time-driver-any", "exti", "chrono"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768", ] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 14embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
15embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" } 15embassy-net-adin1110 = { version = "0.2.0", path = "../../embassy-net-adin1110" }
16embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] } 16embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "tcp", "dhcpv4", "medium-ethernet"] }
17embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 17embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
18embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } 18embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
19embedded-io = { version = "0.6.0", features = ["defmt-03"] } 19embedded-io = { version = "0.6.0", features = ["defmt-03"] }
@@ -24,15 +24,15 @@ defmt-rtt = "0.4"
24cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 24cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
25cortex-m-rt = "0.7.0" 25cortex-m-rt = "0.7.0"
26embedded-hal = "0.2.6" 26embedded-hal = "0.2.6"
27embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } 27embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
28embedded-hal-async = { version = "=1.0.0-rc.2" } 28embedded-hal-async = { version = "1.0" }
29embedded-hal-bus = { version = "=0.1.0-rc.2", features = ["async"] } 29embedded-hal-bus = { version = "0.1", features = ["async"] }
30panic-probe = { version = "0.3", features = ["print-defmt"] } 30panic-probe = { version = "0.3", features = ["print-defmt"] }
31futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 31futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
32heapless = { version = "0.8", default-features = false } 32heapless = { version = "0.8", default-features = false }
33chrono = { version = "^0.4", default-features = false } 33chrono = { version = "^0.4", default-features = false }
34rand = { version = "0.8.5", default-features = false } 34rand = { version = "0.8.5", default-features = false }
35static_cell = { version = "2", features = ["nightly"]} 35static_cell = "2"
36 36
37micromath = "2.0.0" 37micromath = "2.0.0"
38 38
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index a0ec5c33e..a9f4604aa 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -1,10 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_stm32::adc::{Adc, Resolution}; 5use embassy_stm32::adc::{Adc, Resolution};
7use embassy_stm32::pac; 6use embassy_stm32::Config;
8use embassy_time::Delay; 7use embassy_time::Delay;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
@@ -12,16 +11,16 @@ use {defmt_rtt as _, panic_probe as _};
12fn main() -> ! { 11fn main() -> ! {
13 info!("Hello World!"); 12 info!("Hello World!");
14 13
15 pac::RCC.ccipr().modify(|w| { 14 let mut config = Config::default();
16 w.set_adcsel(pac::rcc::vals::Adcsel::SYS); 15 {
17 }); 16 use embassy_stm32::rcc::*;
18 pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); 17 config.rcc.mux.adcsel = mux::Adcsel::SYS;
19 18 }
20 let p = embassy_stm32::init(Default::default()); 19 let p = embassy_stm32::init(config);
21 20
22 let mut adc = Adc::new(p.ADC1, &mut Delay); 21 let mut adc = Adc::new(p.ADC1, &mut Delay);
23 //adc.enable_vref(); 22 //adc.enable_vref();
24 adc.set_resolution(Resolution::EightBit); 23 adc.set_resolution(Resolution::BITS8);
25 let mut channel = p.PC0; 24 let mut channel = p.PC0;
26 25
27 loop { 26 loop {
diff --git a/examples/stm32l4/src/bin/blinky.rs b/examples/stm32l4/src/bin/blinky.rs
index 6202fe2f7..b55dfd35e 100644
--- a/examples/stm32l4/src/bin/blinky.rs
+++ b/examples/stm32l4/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l4/src/bin/button.rs b/examples/stm32l4/src/bin/button.rs
index 73b1962e8..1f3270214 100644
--- a/examples/stm32l4/src/bin/button.rs
+++ b/examples/stm32l4/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_stm32::gpio::{Input, Pull}; 5use embassy_stm32::gpio::{Input, Pull};
diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs
index ef32d4c4a..34a08bbc6 100644
--- a/examples/stm32l4/src/bin/button_exti.rs
+++ b/examples/stm32l4/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Up); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32l4/src/bin/dac.rs b/examples/stm32l4/src/bin/dac.rs
index d6a7ff624..fdbf1d374 100644
--- a/examples/stm32l4/src/bin/dac.rs
+++ b/examples/stm32l4/src/bin/dac.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_stm32::dac::{DacCh1, Value}; 5use embassy_stm32::dac::{DacCh1, Value};
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs
index dc86dbf43..d01b016c0 100644
--- a/examples/stm32l4/src/bin/dac_dma.rs
+++ b/examples/stm32l4/src/bin/dac_dma.rs
@@ -1,15 +1,14 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray}; 6use embassy_stm32::dac::{DacCh1, DacCh2, ValueArray};
8use embassy_stm32::pac::timer::vals::{Mms, Opm}; 7use embassy_stm32::pac::timer::vals::Mms;
9use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; 8use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7};
10use embassy_stm32::rcc::low_level::RccPeripheral; 9use embassy_stm32::rcc::frequency;
11use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
12use embassy_stm32::timer::low_level::Basic16bitInstance; 11use embassy_stm32::timer::low_level::Timer;
13use micromath::F32Ext; 12use micromath::F32Ext;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
@@ -23,19 +22,19 @@ async fn main(spawner: Spawner) {
23 // Obtain two independent channels (p.DAC1 can only be consumed once, though!) 22 // Obtain two independent channels (p.DAC1 can only be consumed once, though!)
24 let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split(); 23 let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, p.DMA1_CH3, p.DMA1_CH4, p.PA4, p.PA5).split();
25 24
26 spawner.spawn(dac_task1(dac_ch1)).ok(); 25 spawner.spawn(dac_task1(p.TIM6, dac_ch1)).ok();
27 spawner.spawn(dac_task2(dac_ch2)).ok(); 26 spawner.spawn(dac_task2(p.TIM7, dac_ch2)).ok();
28} 27}
29 28
30#[embassy_executor::task] 29#[embassy_executor::task]
31async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { 30async fn dac_task1(tim: TIM6, mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
32 let data: &[u8; 256] = &calculate_array::<256>(); 31 let data: &[u8; 256] = &calculate_array::<256>();
33 32
34 info!("TIM6 frequency is {}", TIM6::frequency()); 33 info!("TIM6 frequency is {}", frequency::<TIM6>());
35 const FREQUENCY: Hertz = Hertz::hz(200); 34 const FREQUENCY: Hertz = Hertz::hz(200);
36 35
37 // Compute the reload value such that we obtain the FREQUENCY for the sine 36 // Compute the reload value such that we obtain the FREQUENCY for the sine
38 let reload: u32 = (TIM6::frequency().0 / FREQUENCY.0) / data.len() as u32; 37 let reload: u32 = (frequency::<TIM6>().0 / FREQUENCY.0) / data.len() as u32;
39 38
40 // Depends on your clock and on the specific chip used, you may need higher or lower values here 39 // Depends on your clock and on the specific chip used, you may need higher or lower values here
41 if reload < 10 { 40 if reload < 10 {
@@ -46,17 +45,17 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
46 dac.set_triggering(true); 45 dac.set_triggering(true);
47 dac.enable(); 46 dac.enable();
48 47
49 TIM6::enable_and_reset(); 48 let tim = Timer::new(tim);
50 TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); 49 tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
51 TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); 50 tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
52 TIM6::regs().cr1().modify(|w| { 51 tim.regs_basic().cr1().modify(|w| {
53 w.set_opm(Opm::DISABLED); 52 w.set_opm(false);
54 w.set_cen(true); 53 w.set_cen(true);
55 }); 54 });
56 55
57 debug!( 56 debug!(
58 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 57 "TIM6 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
59 TIM6::frequency(), 58 frequency::<TIM6>(),
60 FREQUENCY, 59 FREQUENCY,
61 reload, 60 reload,
62 reload as u16, 61 reload as u16,
@@ -71,23 +70,23 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) {
71} 70}
72 71
73#[embassy_executor::task] 72#[embassy_executor::task]
74async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { 73async fn dac_task2(tim: TIM7, mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
75 let data: &[u8; 256] = &calculate_array::<256>(); 74 let data: &[u8; 256] = &calculate_array::<256>();
76 75
77 info!("TIM7 frequency is {}", TIM7::frequency()); 76 info!("TIM7 frequency is {}", frequency::<TIM7>());
78 77
79 const FREQUENCY: Hertz = Hertz::hz(600); 78 const FREQUENCY: Hertz = Hertz::hz(600);
80 let reload: u32 = (TIM7::frequency().0 / FREQUENCY.0) / data.len() as u32; 79 let reload: u32 = (frequency::<TIM7>().0 / FREQUENCY.0) / data.len() as u32;
81 80
82 if reload < 10 { 81 if reload < 10 {
83 error!("Reload value {} below threshold!", reload); 82 error!("Reload value {} below threshold!", reload);
84 } 83 }
85 84
86 TIM7::enable_and_reset(); 85 let tim = Timer::new(tim);
87 TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); 86 tim.regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1));
88 TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); 87 tim.regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE));
89 TIM7::regs().cr1().modify(|w| { 88 tim.regs_basic().cr1().modify(|w| {
90 w.set_opm(Opm::DISABLED); 89 w.set_opm(false);
91 w.set_cen(true); 90 w.set_cen(true);
92 }); 91 });
93 92
@@ -97,7 +96,7 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) {
97 96
98 debug!( 97 debug!(
99 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}", 98 "TIM7 Frequency {}, Target Frequency {}, Reload {}, Reload as u16 {}, Samples {}",
100 TIM7::frequency(), 99 frequency::<TIM7>(),
101 FREQUENCY, 100 FREQUENCY,
102 reload, 101 reload,
103 reload as u16, 102 reload as u16,
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs
index 07dc12e8c..f553deb82 100644
--- a/examples/stm32l4/src/bin/i2c.rs
+++ b/examples/stm32l4/src/bin/i2c.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs
index 60a4e2eb3..1b8652bcc 100644
--- a/examples/stm32l4/src/bin/i2c_blocking_async.rs
+++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_embedded_hal::adapter::BlockingAsync; 5use embassy_embedded_hal::adapter::BlockingAsync;
diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs
index 4c2c224a6..794972a33 100644
--- a/examples/stm32l4/src/bin/i2c_dma.rs
+++ b/examples/stm32l4/src/bin/i2c_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs
index 504879887..36c002952 100644
--- a/examples/stm32l4/src/bin/mco.rs
+++ b/examples/stm32l4/src/bin/mco.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs
index e5ad56fb9..14d0e3c1e 100644
--- a/examples/stm32l4/src/bin/rng.rs
+++ b/examples/stm32l4/src/bin/rng.rs
@@ -1,10 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource}; 6use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk};
8use embassy_stm32::rng::Rng; 7use embassy_stm32::rng::Rng;
9use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
10use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -16,7 +15,7 @@ bind_interrupts!(struct Irqs {
16#[embassy_executor::main] 15#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
18 let mut config = Config::default(); 17 let mut config = Config::default();
19 config.rcc.mux = ClockSrc::PLL1_R; 18 config.rcc.sys = Sysclk::PLL1_R;
20 config.rcc.hsi = true; 19 config.rcc.hsi = true;
21 config.rcc.pll = Some(Pll { 20 config.rcc.pll = Some(Pll {
22 source: PllSource::HSI, 21 source: PllSource::HSI,
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs
index d2a2aa1f2..f554f0f78 100644
--- a/examples/stm32l4/src/bin/rtc.rs
+++ b/examples/stm32l4/src/bin/rtc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use chrono::{NaiveDate, NaiveDateTime}; 4use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 5use defmt::*;
@@ -16,7 +15,7 @@ async fn main(_spawner: Spawner) {
16 let mut config = Config::default(); 15 let mut config = Config::default();
17 { 16 {
18 use embassy_stm32::rcc::*; 17 use embassy_stm32::rcc::*;
19 config.rcc.mux = ClockSrc::PLL1_R; 18 config.rcc.sys = Sysclk::PLL1_R;
20 config.rcc.hse = Some(Hse { 19 config.rcc.hse = Some(Hse {
21 freq: Hertz::mhz(8), 20 freq: Hertz::mhz(8),
22 mode: HseMode::Oscillator, 21 mode: HseMode::Oscillator,
@@ -41,7 +40,7 @@ async fn main(_spawner: Spawner) {
41 .unwrap(); 40 .unwrap();
42 41
43 let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 42 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
44 info!("Got RTC! {:?}", now.timestamp()); 43 info!("Got RTC! {:?}", now.and_utc().timestamp());
45 44
46 rtc.set_datetime(now.into()).expect("datetime not set"); 45 rtc.set_datetime(now.into()).expect("datetime not set");
47 46
@@ -49,5 +48,5 @@ async fn main(_spawner: Spawner) {
49 Timer::after_millis(20000).await; 48 Timer::after_millis(20000).await;
50 49
51 let then: NaiveDateTime = rtc.now().unwrap().into(); 50 let then: NaiveDateTime = rtc.now().unwrap().into();
52 info!("Got RTC! {:?}", then.timestamp()); 51 info!("Got RTC! {:?}", then.and_utc().timestamp());
53} 52}
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index 4826e0bed..77aa929ab 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -1,10 +1,7 @@
1#![deny(clippy::pedantic)]
2#![allow(clippy::doc_markdown)]
3#![no_main] 1#![no_main]
4#![no_std] 2#![no_std]
5// Needed unitl https://github.com/rust-lang/rust/issues/63063 is stablised. 3#![deny(clippy::pedantic)]
6#![feature(type_alias_impl_trait)] 4#![allow(clippy::doc_markdown)]
7#![feature(associated_type_bounds)]
8#![allow(clippy::missing_errors_doc)] 5#![allow(clippy::missing_errors_doc)]
9 6
10// This example works on a ANALOG DEVICE EVAL-ADIN110EBZ board. 7// This example works on a ANALOG DEVICE EVAL-ADIN110EBZ board.
@@ -36,7 +33,7 @@ use hal::rng::{self, Rng};
36use hal::{bind_interrupts, exti, pac, peripherals}; 33use hal::{bind_interrupts, exti, pac, peripherals};
37use heapless::Vec; 34use heapless::Vec;
38use rand::RngCore; 35use rand::RngCore;
39use static_cell::make_static; 36use static_cell::StaticCell;
40use {embassy_stm32 as hal, panic_probe as _}; 37use {embassy_stm32 as hal, panic_probe as _};
41 38
42bind_interrupts!(struct Irqs { 39bind_interrupts!(struct Irqs {
@@ -45,7 +42,7 @@ bind_interrupts!(struct Irqs {
45 RNG => rng::InterruptHandler<peripherals::RNG>; 42 RNG => rng::InterruptHandler<peripherals::RNG>;
46}); 43});
47 44
48use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; 45use embassy_net_adin1110::{Device, Runner, ADIN1110};
49use embedded_hal_bus::spi::ExclusiveDevice; 46use embedded_hal_bus::spi::ExclusiveDevice;
50use hal::gpio::Pull; 47use hal::gpio::Pull;
51use hal::i2c::Config as I2C_Config; 48use hal::i2c::Config as I2C_Config;
@@ -61,9 +58,9 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address([192, 168, 1, 5]), 24);
61const HTTP_LISTEN_PORT: u16 = 80; 58const HTTP_LISTEN_PORT: u16 = 80;
62 59
63pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>; 60pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>;
64pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static, peripherals::PB12>, Delay>; 61pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>;
65pub type SpeInt = exti::ExtiInput<'static, peripherals::PB11>; 62pub type SpeInt = exti::ExtiInput<'static>;
66pub type SpeRst = Output<'static, peripherals::PC7>; 63pub type SpeRst = Output<'static>;
67pub type Adin1110T = ADIN1110<SpeSpiCs>; 64pub type Adin1110T = ADIN1110<SpeSpiCs>;
68pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; 65pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>;
69 66
@@ -78,7 +75,7 @@ async fn main(spawner: Spawner) {
78 use embassy_stm32::rcc::*; 75 use embassy_stm32::rcc::*;
79 // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2) 76 // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2)
80 // 80MHz highest frequency for flash 0 wait. 77 // 80MHz highest frequency for flash 0 wait.
81 config.rcc.mux = ClockSrc::PLL1_R; 78 config.rcc.sys = Sysclk::PLL1_R;
82 config.rcc.hse = Some(Hse { 79 config.rcc.hse = Some(Hse {
83 freq: Hertz::mhz(8), 80 freq: Hertz::mhz(8),
84 mode: HseMode::Oscillator, 81 mode: HseMode::Oscillator,
@@ -96,12 +93,6 @@ async fn main(spawner: Spawner) {
96 93
97 let dp = embassy_stm32::init(config); 94 let dp = embassy_stm32::init(config);
98 95
99 // RM0432rev9, 5.1.2: Independent I/O supply rail
100 // After reset, the I/Os supplied by VDDIO2 are logically and electrically isolated and
101 // therefore are not available. The isolation must be removed before using any I/O from
102 // PG[15:2], by setting the IOSV bit in the PWR_CR2 register, once the VDDIO2 supply is present
103 pac::PWR.cr2().modify(|w| w.set_iosv(true));
104
105 let reset_status = pac::RCC.bdcr().read().0; 96 let reset_status = pac::RCC.bdcr().read().0;
106 defmt::println!("bdcr before: 0x{:X}", reset_status); 97 defmt::println!("bdcr before: 0x{:X}", reset_status);
107 98
@@ -137,8 +128,7 @@ async fn main(spawner: Spawner) {
137 let spe_cfg1 = Input::new(dp.PC9, Pull::None); 128 let spe_cfg1 = Input::new(dp.PC9, Pull::None);
138 let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low); 129 let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low);
139 130
140 let spe_int = Input::new(dp.PB11, Pull::None); 131 let spe_int = exti::ExtiInput::new(dp.PB11, dp.EXTI11, Pull::None);
141 let spe_int = exti::ExtiInput::new(spe_int, dp.EXTI11);
142 132
143 let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High); 133 let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High);
144 let spe_spi_sclk = dp.PB13; 134 let spe_spi_sclk = dp.PB13;
@@ -180,7 +170,8 @@ async fn main(spawner: Spawner) {
180 } 170 }
181 }; 171 };
182 172
183 let state = make_static!(embassy_net_adin1110::State::<8, 8>::new()); 173 static STATE: StaticCell<embassy_net_adin1110::State<8, 8>> = StaticCell::new();
174 let state = STATE.init(embassy_net_adin1110::State::<8, 8>::new());
184 175
185 let (device, runner) = embassy_net_adin1110::new( 176 let (device, runner) = embassy_net_adin1110::new(
186 MAC, 177 MAC,
@@ -217,11 +208,13 @@ async fn main(spawner: Spawner) {
217 }; 208 };
218 209
219 // Init network stack 210 // Init network stack
220 let stack = &*make_static!(Stack::new( 211 static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new();
212 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
213 let stack = &*STACK.init(Stack::new(
221 device, 214 device,
222 ip_cfg, 215 ip_cfg,
223 make_static!(StackResources::<2>::new()), 216 RESOURCES.init(StackResources::<2>::new()),
224 seed 217 seed,
225 )); 218 ));
226 219
227 // Launch network task 220 // Launch network task
@@ -298,7 +291,7 @@ async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net:
298} 291}
299 292
300#[embassy_executor::task] 293#[embassy_executor::task]
301async fn heartbeat_led(mut led: Output<'static, peripherals::PE6>) { 294async fn heartbeat_led(mut led: Output<'static>) {
302 let mut tmr = Ticker::every(Duration::from_hz(3)); 295 let mut tmr = Ticker::every(Duration::from_hz(3));
303 loop { 296 loop {
304 led.toggle(); 297 led.toggle();
@@ -308,7 +301,7 @@ async fn heartbeat_led(mut led: Output<'static, peripherals::PE6>) {
308 301
309// ADT7422 302// ADT7422
310#[embassy_executor::task] 303#[embassy_executor::task]
311async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static, peripherals::PG15>) -> ! { 304async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static>) -> ! {
312 let mut tmr = Ticker::every(Duration::from_hz(1)); 305 let mut tmr = Ticker::every(Duration::from_hz(1));
313 let mut temp_sens = ADT7422::new(temp_dev_i2c, 0x48).unwrap(); 306 let mut temp_sens = ADT7422::new(temp_dev_i2c, 0x48).unwrap();
314 307
diff --git a/examples/stm32l4/src/bin/spi.rs b/examples/stm32l4/src/bin/spi.rs
index 54cf68f7b..6653e4516 100644
--- a/examples/stm32l4/src/bin/spi.rs
+++ b/examples/stm32l4/src/bin/spi.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_stm32::dma::NoDma; 5use embassy_stm32::dma::NoDma;
diff --git a/examples/stm32l4/src/bin/spi_blocking_async.rs b/examples/stm32l4/src/bin/spi_blocking_async.rs
index f1b80087c..68dbb70ad 100644
--- a/examples/stm32l4/src/bin/spi_blocking_async.rs
+++ b/examples/stm32l4/src/bin/spi_blocking_async.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_embedded_hal::adapter::BlockingAsync; 5use embassy_embedded_hal::adapter::BlockingAsync;
diff --git a/examples/stm32l4/src/bin/spi_dma.rs b/examples/stm32l4/src/bin/spi_dma.rs
index ff9b5b43b..946a759b1 100644
--- a/examples/stm32l4/src/bin/spi_dma.rs
+++ b/examples/stm32l4/src/bin/spi_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32l4/src/bin/usart.rs b/examples/stm32l4/src/bin/usart.rs
index f4da6b5ae..7bab23950 100644
--- a/examples/stm32l4/src/bin/usart.rs
+++ b/examples/stm32l4/src/bin/usart.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_stm32::dma::NoDma; 5use embassy_stm32::dma::NoDma;
diff --git a/examples/stm32l4/src/bin/usart_dma.rs b/examples/stm32l4/src/bin/usart_dma.rs
index 2f3b2a0f0..031888f70 100644
--- a/examples/stm32l4/src/bin/usart_dma.rs
+++ b/examples/stm32l4/src/bin/usart_dma.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::fmt::Write; 4use core::fmt::Write;
6 5
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs
index 4baf5f05d..198504b59 100644
--- a/examples/stm32l4/src/bin/usb_serial.rs
+++ b/examples/stm32l4/src/bin/usb_serial.rs
@@ -1,13 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use defmt_rtt as _; // global logger 5use defmt_rtt as _; // global logger
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
8use embassy_stm32::rcc::*; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::usb_otg::{Driver, Instance}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config};
11use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
12use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
13use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -15,7 +13,7 @@ use futures::future::join;
15use panic_probe as _; 13use panic_probe as _;
16 14
17bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
18 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19}); 17});
20 18
21#[embassy_executor::main] 19#[embassy_executor::main]
@@ -23,23 +21,26 @@ async fn main(_spawner: Spawner) {
23 info!("Hello World!"); 21 info!("Hello World!");
24 22
25 let mut config = Config::default(); 23 let mut config = Config::default();
26 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB 24 {
27 config.rcc.mux = ClockSrc::PLL1_R; 25 use embassy_stm32::rcc::*;
28 config.rcc.hsi = true; 26 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
29 config.rcc.pll = Some(Pll { 27 config.rcc.sys = Sysclk::PLL1_R;
30 source: PllSource::HSI, 28 config.rcc.hsi = true;
31 prediv: PllPreDiv::DIV1, 29 config.rcc.pll = Some(Pll {
32 mul: PllMul::MUL10, 30 source: PllSource::HSI,
33 divp: None, 31 prediv: PllPreDiv::DIV1,
34 divq: None, 32 mul: PllMul::MUL10,
35 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2) 33 divp: None,
36 }); 34 divq: None,
37 35 divr: Some(PllRDiv::DIV2), // sysclk 80Mhz (16 / 1 * 10 / 2)
36 });
37 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
38 }
38 let p = embassy_stm32::init(config); 39 let p = embassy_stm32::init(config);
39 40
40 // Create the driver, from the HAL. 41 // Create the driver, from the HAL.
41 let mut ep_out_buffer = [0u8; 256]; 42 let mut ep_out_buffer = [0u8; 256];
42 let mut config = embassy_stm32::usb_otg::Config::default(); 43 let mut config = embassy_stm32::usb::Config::default();
43 config.vbus_detection = true; 44 config.vbus_detection = true;
44 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 45 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
45 46
@@ -59,7 +60,6 @@ async fn main(_spawner: Spawner) {
59 60
60 // Create embassy-usb DeviceBuilder using the driver and config. 61 // Create embassy-usb DeviceBuilder using the driver and config.
61 // It needs some buffers for building the descriptors. 62 // It needs some buffers for building the descriptors.
62 let mut device_descriptor = [0; 256];
63 let mut config_descriptor = [0; 256]; 63 let mut config_descriptor = [0; 256];
64 let mut bos_descriptor = [0; 256]; 64 let mut bos_descriptor = [0; 256];
65 let mut control_buf = [0; 64]; 65 let mut control_buf = [0; 64];
@@ -69,7 +69,6 @@ async fn main(_spawner: Spawner) {
69 let mut builder = Builder::new( 69 let mut builder = Builder::new(
70 driver, 70 driver,
71 config, 71 config,
72 &mut device_descriptor,
73 &mut config_descriptor, 72 &mut config_descriptor,
74 &mut bos_descriptor, 73 &mut bos_descriptor,
75 &mut [], // no msos descriptors 74 &mut [], // no msos descriptors
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml
index 2557ef42d..5bcee178f 100644
--- a/examples/stm32l5/Cargo.toml
+++ b/examples/stm32l5/Cargo.toml
@@ -6,14 +6,14 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32l552ze to your chip name, if necessary. 8# Change stm32l552ze to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "memory-x", "low-power"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } 14embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16usbd-hid = "0.6.0" 16usbd-hid = "0.7.0"
17 17
18defmt = "0.3" 18defmt = "0.3"
19defmt-rtt = "0.4" 19defmt-rtt = "0.4"
@@ -26,7 +26,11 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
26heapless = { version = "0.8", default-features = false } 26heapless = { version = "0.8", default-features = false }
27rand_core = { version = "0.6.3", default-features = false } 27rand_core = { version = "0.6.3", default-features = false }
28embedded-io-async = { version = "0.6.1" } 28embedded-io-async = { version = "0.6.1" }
29static_cell = { version = "2", features = ["nightly"]} 29static_cell = "2"
30 30
31[profile.release] 31[profile.release]
32debug = 2 32debug = 2
33
34[[bin]]
35name = "stop"
36default-features = ["embassy-stm32/low-power"]
diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs
index e80ad2b3a..e6639d22b 100644
--- a/examples/stm32l5/src/bin/button_exti.rs
+++ b/examples/stm32l5/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Down); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs
index 279f4f65d..0a644e73d 100644
--- a/examples/stm32l5/src/bin/rng.rs
+++ b/examples/stm32l5/src/bin/rng.rs
@@ -1,10 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllRDiv, PllSource}; 6use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllRDiv, PllSource, Sysclk};
8use embassy_stm32::rng::Rng; 7use embassy_stm32::rng::Rng;
9use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, rng, Config};
10use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -17,7 +16,7 @@ bind_interrupts!(struct Irqs {
17async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
18 let mut config = Config::default(); 17 let mut config = Config::default();
19 config.rcc.hsi = true; 18 config.rcc.hsi = true;
20 config.rcc.mux = ClockSrc::PLL1_R; 19 config.rcc.sys = Sysclk::PLL1_R;
21 config.rcc.pll = Some(Pll { 20 config.rcc.pll = Some(Pll {
22 // 64Mhz clock (16 / 1 * 8 / 2) 21 // 64Mhz clock (16 / 1 * 8 / 2)
23 source: PllSource::HSI, 22 source: PllSource::HSI,
diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs
new file mode 100644
index 000000000..32a736de8
--- /dev/null
+++ b/examples/stm32l5/src/bin/stop.rs
@@ -0,0 +1,61 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
7use embassy_stm32::low_power::Executor;
8use embassy_stm32::rcc::LsConfig;
9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::Config;
11use embassy_time::Timer;
12use static_cell::StaticCell;
13use {defmt_rtt as _, panic_probe as _};
14
15#[cortex_m_rt::entry]
16fn main() -> ! {
17 Executor::take().run(|spawner| {
18 unwrap!(spawner.spawn(async_main(spawner)));
19 })
20}
21
22#[embassy_executor::task]
23async fn async_main(spawner: Spawner) {
24 let mut config = Config::default();
25 config.rcc.ls = LsConfig::default_lsi();
26 // when enabled the power-consumption is much higher during stop, but debugging and RTT is working
27 // if you wan't to measure the power-consumption, or for production: uncomment this line
28 // config.enable_debug_during_sleep = false;
29 let p = embassy_stm32::init(config);
30
31 // give the RTC to the executor...
32 let rtc = Rtc::new(p.RTC, RtcConfig::default());
33 static RTC: StaticCell<Rtc> = StaticCell::new();
34 let rtc = RTC.init(rtc);
35 embassy_stm32::low_power::stop_with_rtc(rtc);
36
37 unwrap!(spawner.spawn(blinky(p.PC7.into())));
38 unwrap!(spawner.spawn(timeout()));
39}
40
41#[embassy_executor::task]
42async fn blinky(led: AnyPin) -> ! {
43 let mut led = Output::new(led, Level::Low, Speed::Low);
44 loop {
45 info!("high");
46 led.set_high();
47 Timer::after_millis(300).await;
48
49 info!("low");
50 led.set_low();
51 Timer::after_millis(300).await;
52 }
53}
54
55// when enable_debug_during_sleep is false, it is more difficult to reprogram the MCU
56// therefore we block the MCU after 30s to be able to reprogram it easily
57#[embassy_executor::task]
58async fn timeout() -> ! {
59 Timer::after_secs(30).await;
60 loop {}
61}
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs
index 0b0a0e2db..7f73fd677 100644
--- a/examples/stm32l5/src/bin/usb_ethernet.rs
+++ b/examples/stm32l5/src/bin/usb_ethernet.rs
@@ -1,12 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_net::tcp::TcpSocket; 6use embassy_net::tcp::TcpSocket;
8use embassy_net::{Stack, StackResources}; 7use embassy_net::{Stack, StackResources};
9use embassy_stm32::rcc::*;
10use embassy_stm32::rng::Rng; 8use embassy_stm32::rng::Rng;
11use embassy_stm32::usb::Driver; 9use embassy_stm32::usb::Driver;
12use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; 10use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config};
@@ -15,7 +13,7 @@ use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
15use embassy_usb::{Builder, UsbDevice}; 13use embassy_usb::{Builder, UsbDevice};
16use embedded_io_async::Write; 14use embedded_io_async::Write;
17use rand_core::RngCore; 15use rand_core::RngCore;
18use static_cell::make_static; 16use static_cell::StaticCell;
19use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
20 18
21type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>; 19type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>;
@@ -45,17 +43,22 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! {
45#[embassy_executor::main] 43#[embassy_executor::main]
46async fn main(spawner: Spawner) { 44async fn main(spawner: Spawner) {
47 let mut config = Config::default(); 45 let mut config = Config::default();
48 config.rcc.hsi = true; 46 {
49 config.rcc.mux = ClockSrc::PLL1_R; 47 use embassy_stm32::rcc::*;
50 config.rcc.pll = Some(Pll { 48 config.rcc.hsi = true;
51 // 80Mhz clock (16 / 1 * 10 / 2) 49 config.rcc.sys = Sysclk::PLL1_R;
52 source: PllSource::HSI, 50 config.rcc.pll = Some(Pll {
53 prediv: PllPreDiv::DIV1, 51 // 80Mhz clock (16 / 1 * 10 / 2)
54 mul: PllMul::MUL10, 52 source: PllSource::HSI,
55 divp: None, 53 prediv: PllPreDiv::DIV1,
56 divq: None, 54 mul: PllMul::MUL10,
57 divr: Some(PllRDiv::DIV2), 55 divp: None,
58 }); 56 divq: None,
57 divr: Some(PllRDiv::DIV2),
58 });
59 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
60 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
61 }
59 let p = embassy_stm32::init(config); 62 let p = embassy_stm32::init(config);
60 63
61 // Create the driver, from the HAL. 64 // Create the driver, from the HAL.
@@ -76,14 +79,16 @@ async fn main(spawner: Spawner) {
76 config.device_protocol = 0x01; 79 config.device_protocol = 0x01;
77 80
78 // Create embassy-usb DeviceBuilder using the driver and config. 81 // Create embassy-usb DeviceBuilder using the driver and config.
82 static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
83 static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
84 static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
79 let mut builder = Builder::new( 85 let mut builder = Builder::new(
80 driver, 86 driver,
81 config, 87 config,
82 &mut make_static!([0; 256])[..], 88 &mut CONFIG_DESC.init([0; 256])[..],
83 &mut make_static!([0; 256])[..], 89 &mut BOS_DESC.init([0; 256])[..],
84 &mut make_static!([0; 256])[..],
85 &mut [], // no msos descriptors 90 &mut [], // no msos descriptors
86 &mut make_static!([0; 128])[..], 91 &mut CONTROL_BUF.init([0; 128])[..],
87 ); 92 );
88 93
89 // Our MAC addr. 94 // Our MAC addr.
@@ -92,14 +97,16 @@ async fn main(spawner: Spawner) {
92 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; 97 let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88];
93 98
94 // Create classes on the builder. 99 // Create classes on the builder.
95 let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); 100 static STATE: StaticCell<State> = StaticCell::new();
101 let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64);
96 102
97 // Build the builder. 103 // Build the builder.
98 let usb = builder.build(); 104 let usb = builder.build();
99 105
100 unwrap!(spawner.spawn(usb_task(usb))); 106 unwrap!(spawner.spawn(usb_task(usb)));
101 107
102 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); 108 static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new();
109 let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr);
103 unwrap!(spawner.spawn(usb_ncm_task(runner))); 110 unwrap!(spawner.spawn(usb_ncm_task(runner)));
104 111
105 let config = embassy_net::Config::dhcpv4(Default::default()); 112 let config = embassy_net::Config::dhcpv4(Default::default());
@@ -114,11 +121,13 @@ async fn main(spawner: Spawner) {
114 let seed = rng.next_u64(); 121 let seed = rng.next_u64();
115 122
116 // Init network stack 123 // Init network stack
117 let stack = &*make_static!(Stack::new( 124 static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new();
125 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
126 let stack = &*STACK.init(Stack::new(
118 device, 127 device,
119 config, 128 config,
120 make_static!(StackResources::<2>::new()), 129 RESOURCES.init(StackResources::<2>::new()),
121 seed 130 seed,
122 )); 131 ));
123 132
124 unwrap!(spawner.spawn(net_task(stack))); 133 unwrap!(spawner.spawn(net_task(stack)));
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index 3614a8e0a..9d30205bb 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -1,11 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_futures::join::join; 6use embassy_futures::join::join;
8use embassy_stm32::rcc::*;
9use embassy_stm32::usb::Driver; 7use embassy_stm32::usb::Driver;
10use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
11use embassy_time::Timer; 9use embassy_time::Timer;
@@ -22,17 +20,22 @@ bind_interrupts!(struct Irqs {
22#[embassy_executor::main] 20#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
24 let mut config = Config::default(); 22 let mut config = Config::default();
25 config.rcc.hsi = true; 23 {
26 config.rcc.mux = ClockSrc::PLL1_R; 24 use embassy_stm32::rcc::*;
27 config.rcc.pll = Some(Pll { 25 config.rcc.hsi = true;
28 // 80Mhz clock (16 / 1 * 10 / 2) 26 config.rcc.sys = Sysclk::PLL1_R;
29 source: PllSource::HSI, 27 config.rcc.pll = Some(Pll {
30 prediv: PllPreDiv::DIV1, 28 // 80Mhz clock (16 / 1 * 10 / 2)
31 mul: PllMul::MUL10, 29 source: PllSource::HSI,
32 divp: None, 30 prediv: PllPreDiv::DIV1,
33 divq: None, 31 mul: PllMul::MUL10,
34 divr: Some(PllRDiv::DIV2), 32 divp: None,
35 }); 33 divq: None,
34 divr: Some(PllRDiv::DIV2),
35 });
36 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
37 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
38 }
36 let p = embassy_stm32::init(config); 39 let p = embassy_stm32::init(config);
37 40
38 // Create the driver, from the HAL. 41 // Create the driver, from the HAL.
@@ -48,7 +51,6 @@ async fn main(_spawner: Spawner) {
48 51
49 // Create embassy-usb DeviceBuilder using the driver and config. 52 // Create embassy-usb DeviceBuilder using the driver and config.
50 // It needs some buffers for building the descriptors. 53 // It needs some buffers for building the descriptors.
51 let mut device_descriptor = [0; 256];
52 let mut config_descriptor = [0; 256]; 54 let mut config_descriptor = [0; 256];
53 let mut bos_descriptor = [0; 256]; 55 let mut bos_descriptor = [0; 256];
54 let mut control_buf = [0; 64]; 56 let mut control_buf = [0; 64];
@@ -59,7 +61,6 @@ async fn main(_spawner: Spawner) {
59 let mut builder = Builder::new( 61 let mut builder = Builder::new(
60 driver, 62 driver,
61 config, 63 config,
62 &mut device_descriptor,
63 &mut config_descriptor, 64 &mut config_descriptor,
64 &mut bos_descriptor, 65 &mut bos_descriptor,
65 &mut [], // no msos descriptors 66 &mut [], // no msos descriptors
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs
index f2b894b68..a64bda31b 100644
--- a/examples/stm32l5/src/bin/usb_serial.rs
+++ b/examples/stm32l5/src/bin/usb_serial.rs
@@ -1,11 +1,9 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_futures::join::join; 6use embassy_futures::join::join;
8use embassy_stm32::rcc::*;
9use embassy_stm32::usb::{Driver, Instance}; 7use embassy_stm32::usb::{Driver, Instance};
10use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
11use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
@@ -20,17 +18,22 @@ bind_interrupts!(struct Irqs {
20#[embassy_executor::main] 18#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
22 let mut config = Config::default(); 20 let mut config = Config::default();
23 config.rcc.hsi = true; 21 {
24 config.rcc.mux = ClockSrc::PLL1_R; 22 use embassy_stm32::rcc::*;
25 config.rcc.pll = Some(Pll { 23 config.rcc.hsi = true;
26 // 80Mhz clock (16 / 1 * 10 / 2) 24 config.rcc.sys = Sysclk::PLL1_R;
27 source: PllSource::HSI, 25 config.rcc.pll = Some(Pll {
28 prediv: PllPreDiv::DIV1, 26 // 80Mhz clock (16 / 1 * 10 / 2)
29 mul: PllMul::MUL10, 27 source: PllSource::HSI,
30 divp: None, 28 prediv: PllPreDiv::DIV1,
31 divq: None, 29 mul: PllMul::MUL10,
32 divr: Some(PllRDiv::DIV2), 30 divp: None,
33 }); 31 divq: None,
32 divr: Some(PllRDiv::DIV2),
33 });
34 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
35 config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
36 }
34 let p = embassy_stm32::init(config); 37 let p = embassy_stm32::init(config);
35 38
36 info!("Hello World!"); 39 info!("Hello World!");
@@ -44,7 +47,6 @@ async fn main(_spawner: Spawner) {
44 47
45 // Create embassy-usb DeviceBuilder using the driver and config. 48 // Create embassy-usb DeviceBuilder using the driver and config.
46 // It needs some buffers for building the descriptors. 49 // It needs some buffers for building the descriptors.
47 let mut device_descriptor = [0; 256];
48 let mut config_descriptor = [0; 256]; 50 let mut config_descriptor = [0; 256];
49 let mut bos_descriptor = [0; 256]; 51 let mut bos_descriptor = [0; 256];
50 let mut control_buf = [0; 7]; 52 let mut control_buf = [0; 7];
@@ -54,7 +56,6 @@ async fn main(_spawner: Spawner) {
54 let mut builder = Builder::new( 56 let mut builder = Builder::new(
55 driver, 57 driver,
56 config, 58 config,
57 &mut device_descriptor,
58 &mut config_descriptor, 59 &mut config_descriptor,
59 &mut bos_descriptor, 60 &mut bos_descriptor,
60 &mut [], // no msos descriptors 61 &mut [], // no msos descriptors
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml
index 1afbd8db4..03294339d 100644
--- a/examples/stm32u5/Cargo.toml
+++ b/examples/stm32u5/Cargo.toml
@@ -6,10 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8# Change stm32u585ai to your chip name, if necessary. 8# Change stm32u585ai to your chip name, if necessary.
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 13embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
14 14
15defmt = "0.3" 15defmt = "0.3"
diff --git a/examples/stm32u5/src/bin/blinky.rs b/examples/stm32u5/src/bin/blinky.rs
index 4b44cb12b..7fe88c183 100644
--- a/examples/stm32u5/src/bin/blinky.rs
+++ b/examples/stm32u5/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32u5/src/bin/boot.rs b/examples/stm32u5/src/bin/boot.rs
index e2112ce5c..23c7f8b22 100644
--- a/examples/stm32u5/src/bin/boot.rs
+++ b/examples/stm32u5/src/bin/boot.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use {defmt_rtt as _, embassy_stm32 as _, panic_probe as _}; 5use {defmt_rtt as _, embassy_stm32 as _, panic_probe as _};
diff --git a/examples/stm32u5/src/bin/flash.rs b/examples/stm32u5/src/bin/flash.rs
new file mode 100644
index 000000000..e4fd6bb9c
--- /dev/null
+++ b/examples/stm32u5/src/bin/flash.rs
@@ -0,0 +1,55 @@
1#![no_std]
2#![no_main]
3
4use defmt::{info, unwrap};
5use embassy_executor::Spawner;
6use embassy_stm32::flash::Flash;
7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default());
13 info!("Hello Flash!");
14
15 const ADDR: u32 = 0x8_0000; // This is the offset into the third region, the absolute address is 4x32K + 128K + 0x8_0000.
16
17 // wait a bit before accessing the flash
18 Timer::after_millis(300).await;
19
20 let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region;
21
22 info!("Reading...");
23 let mut buf = [0u8; 32];
24 unwrap!(f.blocking_read(ADDR, &mut buf));
25 info!("Read: {=[u8]:x}", buf);
26
27 info!("Erasing...");
28 unwrap!(f.blocking_erase(ADDR, ADDR + 256 * 1024));
29
30 info!("Reading...");
31 let mut buf = [0u8; 32];
32 unwrap!(f.blocking_read(ADDR, &mut buf));
33 info!("Read after erase: {=[u8]:x}", buf);
34
35 info!("Writing...");
36 unwrap!(f.blocking_write(
37 ADDR,
38 &[
39 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,
40 30, 31, 32
41 ]
42 ));
43
44 info!("Reading...");
45 let mut buf = [0u8; 32];
46 unwrap!(f.blocking_read(ADDR, &mut buf));
47 info!("Read: {=[u8]:x}", buf);
48 assert_eq!(
49 &buf[..],
50 &[
51 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,
52 30, 31, 32
53 ]
54 );
55}
diff --git a/examples/stm32u5/src/bin/i2c.rs b/examples/stm32u5/src/bin/i2c.rs
new file mode 100644
index 000000000..e376c6bc8
--- /dev/null
+++ b/examples/stm32u5/src/bin/i2c.rs
@@ -0,0 +1,41 @@
1#![no_std]
2#![no_main]
3
4use defmt::{info, unwrap};
5use embassy_executor::Spawner;
6use embassy_stm32::dma::NoDma;
7use embassy_stm32::i2c::I2c;
8use embassy_stm32::time::Hertz;
9use embassy_stm32::{bind_interrupts, i2c, peripherals};
10use {defmt_rtt as _, panic_probe as _};
11
12const HTS221_ADDRESS: u8 = 0x5F;
13const WHOAMI: u8 = 0x0F;
14
15bind_interrupts!(struct Irqs {
16 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main]
21async fn main(_spawner: Spawner) {
22 let p = embassy_stm32::init(Default::default());
23 let mut i2c = I2c::new(
24 p.I2C2,
25 p.PH4,
26 p.PH5,
27 Irqs,
28 NoDma,
29 NoDma,
30 Hertz(100_000),
31 Default::default(),
32 );
33
34 let mut data = [0u8; 1];
35 unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data));
36
37 // HTS221 data sheet is here: https://www.st.com/resource/en/datasheet/hts221.pdf
38 // 7.1 WHO_AM_I command is x0F which expected response xBC.
39 info!("Whoami: 0x{:02x}", data[0]);
40 assert_eq!(0xBC, data[0]);
41}
diff --git a/examples/stm32u5/src/bin/rng.rs b/examples/stm32u5/src/bin/rng.rs
new file mode 100644
index 000000000..3a5bce097
--- /dev/null
+++ b/examples/stm32u5/src/bin/rng.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::rng::Rng;
7use embassy_stm32::{bind_interrupts, peripherals, rng};
8use {defmt_rtt as _, panic_probe as _};
9
10bind_interrupts!(struct Irqs {
11 RNG => rng::InterruptHandler<peripherals::RNG>;
12});
13
14#[embassy_executor::main]
15async fn main(_spawner: Spawner) {
16 let p = embassy_stm32::init(Default::default());
17
18 info!("Hello World!");
19
20 let mut rng = Rng::new(p.RNG, Irqs);
21
22 let mut buf = [0u8; 16];
23 unwrap!(rng.async_fill_bytes(&mut buf).await);
24 info!("random bytes: {:02x}", buf);
25}
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs
index 839d6472f..6a313efb0 100644
--- a/examples/stm32u5/src/bin/usb_serial.rs
+++ b/examples/stm32u5/src/bin/usb_serial.rs
@@ -1,13 +1,11 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{panic, *}; 4use defmt::{panic, *};
6use defmt_rtt as _; // global logger 5use defmt_rtt as _; // global logger
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
8use embassy_stm32::rcc::*; 7use embassy_stm32::usb::{Driver, Instance};
9use embassy_stm32::usb_otg::{Driver, Instance}; 8use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
10use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config};
11use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 9use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
12use embassy_usb::driver::EndpointError; 10use embassy_usb::driver::EndpointError;
13use embassy_usb::Builder; 11use embassy_usb::Builder;
@@ -15,7 +13,7 @@ use futures::future::join;
15use panic_probe as _; 13use panic_probe as _;
16 14
17bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
18 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; 16 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19}); 17});
20 18
21#[embassy_executor::main] 19#[embassy_executor::main]
@@ -23,20 +21,29 @@ async fn main(_spawner: Spawner) {
23 info!("Hello World!"); 21 info!("Hello World!");
24 22
25 let mut config = Config::default(); 23 let mut config = Config::default();
26 config.rcc.mux = ClockSrc::PLL1_R(PllConfig { 24 {
27 source: PllSource::HSI, 25 use embassy_stm32::rcc::*;
28 m: Pllm::DIV2, 26 config.rcc.hsi = true;
29 n: Plln::MUL10, 27 config.rcc.pll1 = Some(Pll {
30 r: Plldiv::DIV1, 28 source: PllSource::HSI, // 16 MHz
31 }); 29 prediv: PllPreDiv::DIV1,
32 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB 30 mul: PllMul::MUL10,
31 divp: None,
32 divq: None,
33 divr: Some(PllDiv::DIV1), // 160 MHz
34 });
35 config.rcc.sys = Sysclk::PLL1_R;
36 config.rcc.voltage_range = VoltageScale::RANGE1;
37 config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB
38 config.rcc.mux.iclksel = mux::Iclksel::HSI48; // USB uses ICLK
39 }
33 40
34 let p = embassy_stm32::init(config); 41 let p = embassy_stm32::init(config);
35 42
36 // Create the driver, from the HAL. 43 // Create the driver, from the HAL.
37 let mut ep_out_buffer = [0u8; 256]; 44 let mut ep_out_buffer = [0u8; 256];
38 let mut config = embassy_stm32::usb_otg::Config::default(); 45 let mut config = embassy_stm32::usb::Config::default();
39 config.vbus_detection = true; 46 config.vbus_detection = false;
40 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); 47 let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config);
41 48
42 // Create embassy-usb Config 49 // Create embassy-usb Config
@@ -54,7 +61,6 @@ async fn main(_spawner: Spawner) {
54 61
55 // Create embassy-usb DeviceBuilder using the driver and config. 62 // Create embassy-usb DeviceBuilder using the driver and config.
56 // It needs some buffers for building the descriptors. 63 // It needs some buffers for building the descriptors.
57 let mut device_descriptor = [0; 256];
58 let mut config_descriptor = [0; 256]; 64 let mut config_descriptor = [0; 256];
59 let mut bos_descriptor = [0; 256]; 65 let mut bos_descriptor = [0; 256];
60 let mut control_buf = [0; 64]; 66 let mut control_buf = [0; 64];
@@ -64,7 +70,6 @@ async fn main(_spawner: Spawner) {
64 let mut builder = Builder::new( 70 let mut builder = Builder::new(
65 driver, 71 driver,
66 config, 72 config,
67 &mut device_descriptor,
68 &mut config_descriptor, 73 &mut config_descriptor,
69 &mut bos_descriptor, 74 &mut bos_descriptor,
70 &mut [], // no msos descriptors 75 &mut [], // no msos descriptors
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index ada1f32e9..94a5141f5 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -9,9 +9,9 @@ license = "MIT OR Apache-2.0"
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wb55rg", "time-driver-any", "memory-x", "exti"] } 9embassy-stm32 = { version = "0.1.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.5.0", path = "../../embassy-sync", features = ["defmt"] } 11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 12embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
13embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 13embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 14embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true }
15 15
16defmt = "0.3" 16defmt = "0.3"
17defmt-rtt = "0.4" 17defmt-rtt = "0.4"
@@ -22,7 +22,7 @@ embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] } 22panic-probe = { version = "0.3", features = ["print-defmt"] }
23futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 23futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
24heapless = { version = "0.8", default-features = false } 24heapless = { version = "0.8", default-features = false }
25static_cell = { version = "2", features = ["nightly"]} 25static_cell = "2"
26 26
27[features] 27[features]
28default = ["ble", "mac"] 28default = ["ble", "mac"]
diff --git a/examples/stm32wb/src/bin/blinky.rs b/examples/stm32wb/src/bin/blinky.rs
index 1394f03fa..f37e8b1d8 100644
--- a/examples/stm32wb/src/bin/blinky.rs
+++ b/examples/stm32wb/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs
index 3648db6ff..2871fd55f 100644
--- a/examples/stm32wb/src/bin/button_exti.rs
+++ b/examples/stm32wb/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC4, Pull::Up); 15 let mut button = ExtiInput::new(p.PC4, p.EXTI4, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI4);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs
index e58da8e35..d3b3c15ca 100644
--- a/examples/stm32wb/src/bin/eddystone_beacon.rs
+++ b/examples/stm32wb/src/bin/eddystone_beacon.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::time::Duration; 4use core::time::Duration;
6 5
@@ -12,11 +11,9 @@ use embassy_stm32::rcc::WPAN_DEFAULT;
12use embassy_stm32_wpan::hci::host::uart::UartHci; 11use embassy_stm32_wpan::hci::host::uart::UartHci;
13use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; 12use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
14use embassy_stm32_wpan::hci::types::AdvertisingType; 13use embassy_stm32_wpan::hci::types::AdvertisingType;
15use embassy_stm32_wpan::hci::vendor::stm32wb::command::gap::{ 14use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role};
16 AdvertisingDataType, DiscoverableParameters, GapCommands, Role, 15use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands;
17}; 16use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel};
18use embassy_stm32_wpan::hci::vendor::stm32wb::command::gatt::GattCommands;
19use embassy_stm32_wpan::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel};
20use embassy_stm32_wpan::hci::BdAddr; 17use embassy_stm32_wpan::hci::BdAddr;
21use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; 18use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp;
22use embassy_stm32_wpan::TlMbox; 19use embassy_stm32_wpan::TlMbox;
diff --git a/examples/stm32wb/src/bin/gatt_server.rs b/examples/stm32wb/src/bin/gatt_server.rs
index 80e835c1d..3b50d6c31 100644
--- a/examples/stm32wb/src/bin/gatt_server.rs
+++ b/examples/stm32wb/src/bin/gatt_server.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use core::time::Duration; 4use core::time::Duration;
6 5
@@ -13,17 +12,18 @@ use embassy_stm32_wpan::hci::event::command::{CommandComplete, ReturnParameters}
13use embassy_stm32_wpan::hci::host::uart::{Packet, UartHci}; 12use embassy_stm32_wpan::hci::host::uart::{Packet, UartHci};
14use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; 13use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
15use embassy_stm32_wpan::hci::types::AdvertisingType; 14use embassy_stm32_wpan::hci::types::AdvertisingType;
16use embassy_stm32_wpan::hci::vendor::stm32wb::command::gap::{ 15use embassy_stm32_wpan::hci::vendor::command::gap::{
17 AddressType, AuthenticationRequirements, DiscoverableParameters, GapCommands, IoCapability, LocalName, Pin, Role, 16 AddressType, AuthenticationRequirements, DiscoverableParameters, GapCommands, IoCapability, LocalName, Pin, Role,
18 SecureConnectionSupport, 17 SecureConnectionSupport,
19}; 18};
20use embassy_stm32_wpan::hci::vendor::stm32wb::command::gatt::{ 19use embassy_stm32_wpan::hci::vendor::command::gatt::{
21 AddCharacteristicParameters, AddServiceParameters, CharacteristicEvent, CharacteristicPermission, 20 AddCharacteristicParameters, AddServiceParameters, CharacteristicEvent, CharacteristicPermission,
22 CharacteristicProperty, EncryptionKeySize, GattCommands, ServiceType, UpdateCharacteristicValueParameters, Uuid, 21 CharacteristicProperty, EncryptionKeySize, GattCommands, ServiceType, UpdateCharacteristicValueParameters, Uuid,
23 WriteResponseParameters, 22 WriteResponseParameters,
24}; 23};
25use embassy_stm32_wpan::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; 24use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel};
26use embassy_stm32_wpan::hci::vendor::stm32wb::event::{self, AttributeHandle, Stm32Wb5xEvent}; 25use embassy_stm32_wpan::hci::vendor::event::command::VendorReturnParameters;
26use embassy_stm32_wpan::hci::vendor::event::{self, AttributeHandle, VendorEvent};
27use embassy_stm32_wpan::hci::{BdAddr, Event}; 27use embassy_stm32_wpan::hci::{BdAddr, Event};
28use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; 28use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp;
29use embassy_stm32_wpan::sub::ble::Ble; 29use embassy_stm32_wpan::sub::ble::Ble;
@@ -191,11 +191,11 @@ async fn main(_spawner: Spawner) {
191 mbox.ble_subsystem.set_discoverable(&discovery_params).await.unwrap(); 191 mbox.ble_subsystem.set_discoverable(&discovery_params).await.unwrap();
192 } 192 }
193 Event::Vendor(vendor_event) => match vendor_event { 193 Event::Vendor(vendor_event) => match vendor_event {
194 Stm32Wb5xEvent::AttReadPermitRequest(read_req) => { 194 VendorEvent::AttReadPermitRequest(read_req) => {
195 defmt::info!("read request received {}, allowing", read_req); 195 defmt::info!("read request received {}, allowing", read_req);
196 mbox.ble_subsystem.allow_read(read_req.conn_handle).await 196 mbox.ble_subsystem.allow_read(read_req.conn_handle).await
197 } 197 }
198 Stm32Wb5xEvent::AttWritePermitRequest(write_req) => { 198 VendorEvent::AttWritePermitRequest(write_req) => {
199 defmt::info!("write request received {}, allowing", write_req); 199 defmt::info!("write request received {}, allowing", write_req);
200 mbox.ble_subsystem 200 mbox.ble_subsystem
201 .write_response(&WriteResponseParameters { 201 .write_response(&WriteResponseParameters {
@@ -207,7 +207,7 @@ async fn main(_spawner: Spawner) {
207 .await 207 .await
208 .unwrap() 208 .unwrap()
209 } 209 }
210 Stm32Wb5xEvent::GattAttributeModified(attribute) => { 210 VendorEvent::GattAttributeModified(attribute) => {
211 defmt::info!("{}", ble_context); 211 defmt::info!("{}", ble_context);
212 if attribute.attr_handle.0 == ble_context.chars.notify.0 + 2 { 212 if attribute.attr_handle.0 == ble_context.chars.notify.0 + 2 {
213 if attribute.data()[0] == 0x01 { 213 if attribute.data()[0] == 0x01 {
@@ -334,7 +334,7 @@ async fn gatt_add_service(ble_subsystem: &mut Ble, uuid: Uuid) -> Result<Attribu
334 334
335 if let Ok(Packet::Event(Event::CommandComplete(CommandComplete { 335 if let Ok(Packet::Event(Event::CommandComplete(CommandComplete {
336 return_params: 336 return_params:
337 ReturnParameters::Vendor(event::command::ReturnParameters::GattAddService(event::command::GattService { 337 ReturnParameters::Vendor(VendorReturnParameters::GattAddService(event::command::GattService {
338 service_handle, 338 service_handle,
339 .. 339 ..
340 })), 340 })),
@@ -371,11 +371,10 @@ async fn gatt_add_char(
371 371
372 if let Ok(Packet::Event(Event::CommandComplete(CommandComplete { 372 if let Ok(Packet::Event(Event::CommandComplete(CommandComplete {
373 return_params: 373 return_params:
374 ReturnParameters::Vendor(event::command::ReturnParameters::GattAddCharacteristic( 374 ReturnParameters::Vendor(VendorReturnParameters::GattAddCharacteristic(event::command::GattCharacteristic {
375 event::command::GattCharacteristic { 375 characteristic_handle,
376 characteristic_handle, .. 376 ..
377 }, 377 })),
378 )),
379 .. 378 ..
380 }))) = response 379 }))) = response
381 { 380 {
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs
index 881dc488d..5cd660543 100644
--- a/examples/stm32wb/src/bin/mac_ffd.rs
+++ b/examples/stm32wb/src/bin/mac_ffd.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs
index f8c76b5a4..7a42bf577 100644
--- a/examples/stm32wb/src/bin/mac_ffd_net.rs
+++ b/examples/stm32wb/src/bin/mac_ffd_net.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -12,7 +11,7 @@ use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId};
12use embassy_stm32_wpan::mac::{self, Runner}; 11use embassy_stm32_wpan::mac::{self, Runner};
13use embassy_stm32_wpan::sub::mm; 12use embassy_stm32_wpan::sub::mm;
14use embassy_stm32_wpan::TlMbox; 13use embassy_stm32_wpan::TlMbox;
15use static_cell::make_static; 14use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
17 16
18bind_interrupts!(struct Irqs{ 17bind_interrupts!(struct Irqs{
@@ -154,15 +153,21 @@ async fn main(spawner: Spawner) {
154 .unwrap(); 153 .unwrap();
155 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 154 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
156 155
156 static TX1: StaticCell<[u8; 127]> = StaticCell::new();
157 static TX2: StaticCell<[u8; 127]> = StaticCell::new();
158 static TX3: StaticCell<[u8; 127]> = StaticCell::new();
159 static TX4: StaticCell<[u8; 127]> = StaticCell::new();
160 static TX5: StaticCell<[u8; 127]> = StaticCell::new();
157 let tx_queue = [ 161 let tx_queue = [
158 make_static!([0u8; 127]), 162 TX1.init([0u8; 127]),
159 make_static!([0u8; 127]), 163 TX2.init([0u8; 127]),
160 make_static!([0u8; 127]), 164 TX3.init([0u8; 127]),
161 make_static!([0u8; 127]), 165 TX4.init([0u8; 127]),
162 make_static!([0u8; 127]), 166 TX5.init([0u8; 127]),
163 ]; 167 ];
164 168
165 let runner = make_static!(Runner::new(mbox.mac_subsystem, tx_queue)); 169 static RUNNER: StaticCell<Runner> = StaticCell::new();
170 let runner = RUNNER.init(Runner::new(mbox.mac_subsystem, tx_queue));
166 171
167 spawner.spawn(run_mac(runner)).unwrap(); 172 spawner.spawn(run_mac(runner)).unwrap();
168 173
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs
index 000355de6..7949211fb 100644
--- a/examples/stm32wb/src/bin/mac_rfd.rs
+++ b/examples/stm32wb/src/bin/mac_rfd.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs
index 9d0e0070c..cb92d462d 100644
--- a/examples/stm32wb/src/bin/tl_mbox.rs
+++ b/examples/stm32wb/src/bin/tl_mbox.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs
index 12c6aeebb..2599e1151 100644
--- a/examples/stm32wb/src/bin/tl_mbox_ble.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs
index f32e07d96..5d868412a 100644
--- a/examples/stm32wb/src/bin/tl_mbox_mac.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wba/Cargo.toml b/examples/stm32wba/Cargo.toml
index c97605937..47279a012 100644
--- a/examples/stm32wba/Cargo.toml
+++ b/examples/stm32wba/Cargo.toml
@@ -7,9 +7,9 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] } 8embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "stm32wba52cg", "time-driver-any", "memory-x", "exti"] }
9embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 9embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
10embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 10embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
11embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 11embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
12embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true } 12embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "udp", "proto-ipv6", "medium-ieee802154", ], optional=true }
13 13
14defmt = "0.3" 14defmt = "0.3"
15defmt-rtt = "0.4" 15defmt-rtt = "0.4"
@@ -20,7 +20,7 @@ embedded-hal = "0.2.6"
20panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
21futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 21futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
22heapless = { version = "0.8", default-features = false } 22heapless = { version = "0.8", default-features = false }
23static_cell = { version = "2", features = ["nightly"]} 23static_cell = "2"
24 24
25[profile.release] 25[profile.release]
26debug = 2 26debug = 2
diff --git a/examples/stm32wba/src/bin/blinky.rs b/examples/stm32wba/src/bin/blinky.rs
index 6b9635e66..0d803b257 100644
--- a/examples/stm32wba/src/bin/blinky.rs
+++ b/examples/stm32wba/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs
index ef32d4c4a..34a08bbc6 100644
--- a/examples/stm32wba/src/bin/button_exti.rs
+++ b/examples/stm32wba/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PC13, Pull::Up); 15 let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI13);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml
index 070d27cb6..4cb55930b 100644
--- a/examples/stm32wl/Cargo.toml
+++ b/examples/stm32wl/Cargo.toml
@@ -8,8 +8,8 @@ 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.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "unstable-pac", "exti", "chrono"] }
10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
14 14
15defmt = "0.3" 15defmt = "0.3"
diff --git a/examples/stm32wl/src/bin/blinky.rs b/examples/stm32wl/src/bin/blinky.rs
index 5bd5745f0..347bd093f 100644
--- a/examples/stm32wl/src/bin/blinky.rs
+++ b/examples/stm32wl/src/bin/blinky.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wl/src/bin/button.rs b/examples/stm32wl/src/bin/button.rs
index 982a7a112..eccd211e2 100644
--- a/examples/stm32wl/src/bin/button.rs
+++ b/examples/stm32wl/src/bin/button.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use cortex_m_rt::entry; 4use cortex_m_rt::entry;
6use defmt::*; 5use defmt::*;
diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs
index 1f02db5cf..27d5330bd 100644
--- a/examples/stm32wl/src/bin/button_exti.rs
+++ b/examples/stm32wl/src/bin/button_exti.rs
@@ -1,11 +1,10 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
7use embassy_stm32::exti::ExtiInput; 6use embassy_stm32::exti::ExtiInput;
8use embassy_stm32::gpio::{Input, Pull}; 7use embassy_stm32::gpio::Pull;
9use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
10 9
11#[embassy_executor::main] 10#[embassy_executor::main]
@@ -13,8 +12,7 @@ async fn main(_spawner: Spawner) {
13 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
14 info!("Hello World!"); 13 info!("Hello World!");
15 14
16 let button = Input::new(p.PA0, Pull::Up); 15 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up);
17 let mut button = ExtiInput::new(button, p.EXTI0);
18 16
19 info!("Press the USER button..."); 17 info!("Press the USER button...");
20 18
diff --git a/examples/stm32wl/src/bin/flash.rs b/examples/stm32wl/src/bin/flash.rs
index 5e52d49ec..0b7417c01 100644
--- a/examples/stm32wl/src/bin/flash.rs
+++ b/examples/stm32wl/src/bin/flash.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::{info, unwrap}; 4use defmt::{info, unwrap};
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs
index 2fd234966..8e9fe02b2 100644
--- a/examples/stm32wl/src/bin/random.rs
+++ b/examples/stm32wl/src/bin/random.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -23,7 +22,7 @@ async fn main(_spawner: Spawner) {
23 mode: HseMode::Bypass, 22 mode: HseMode::Bypass,
24 prescaler: HsePrescaler::DIV1, 23 prescaler: HsePrescaler::DIV1,
25 }); 24 });
26 config.rcc.mux = ClockSrc::PLL1_R; 25 config.rcc.sys = Sysclk::PLL1_R;
27 config.rcc.pll = Some(Pll { 26 config.rcc.pll = Some(Pll {
28 source: PllSource::HSE, 27 source: PllSource::HSE,
29 prediv: PllPreDiv::DIV2, 28 prediv: PllPreDiv::DIV2,
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs
index 4ffb0bb58..cf7d6d220 100644
--- a/examples/stm32wl/src/bin/rtc.rs
+++ b/examples/stm32wl/src/bin/rtc.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use chrono::{NaiveDate, NaiveDateTime}; 4use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 5use defmt::*;
@@ -22,7 +21,7 @@ async fn main(_spawner: Spawner) {
22 mode: HseMode::Bypass, 21 mode: HseMode::Bypass,
23 prescaler: HsePrescaler::DIV1, 22 prescaler: HsePrescaler::DIV1,
24 }); 23 });
25 config.rcc.mux = ClockSrc::PLL1_R; 24 config.rcc.sys = Sysclk::PLL1_R;
26 config.rcc.pll = Some(Pll { 25 config.rcc.pll = Some(Pll {
27 source: PllSource::HSE, 26 source: PllSource::HSE,
28 prediv: PllPreDiv::DIV2, 27 prediv: PllPreDiv::DIV2,
@@ -41,7 +40,7 @@ async fn main(_spawner: Spawner) {
41 .unwrap(); 40 .unwrap();
42 41
43 let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 42 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
44 info!("Got RTC! {:?}", now.timestamp()); 43 info!("Got RTC! {:?}", now.and_utc().timestamp());
45 44
46 rtc.set_datetime(now.into()).expect("datetime not set"); 45 rtc.set_datetime(now.into()).expect("datetime not set");
47 46
@@ -49,5 +48,5 @@ async fn main(_spawner: Spawner) {
49 Timer::after_millis(20000).await; 48 Timer::after_millis(20000).await;
50 49
51 let then: NaiveDateTime = rtc.now().unwrap().into(); 50 let then: NaiveDateTime = rtc.now().unwrap().into();
52 info!("Got RTC! {:?}", then.timestamp()); 51 info!("Got RTC! {:?}", then.and_utc().timestamp());
53} 52}
diff --git a/examples/stm32wl/src/bin/uart_async.rs b/examples/stm32wl/src/bin/uart_async.rs
index 44e8f83a2..3637243a0 100644
--- a/examples/stm32wl/src/bin/uart_async.rs
+++ b/examples/stm32wl/src/bin/uart_async.rs
@@ -1,6 +1,5 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)]
4 3
5use defmt::*; 4use defmt::*;
6use embassy_executor::Spawner; 5use embassy_executor::Spawner;
@@ -21,7 +20,7 @@ but can be surely changed for your needs.
21#[embassy_executor::main] 20#[embassy_executor::main]
22async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
23 let mut config = embassy_stm32::Config::default(); 22 let mut config = embassy_stm32::Config::default();
24 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; 23 config.rcc.sys = embassy_stm32::rcc::Sysclk::HSE;
25 let p = embassy_stm32::init(config); 24 let p = embassy_stm32::init(config);
26 25
27 defmt::info!("Starting system"); 26 defmt::info!("Starting system");
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index c96a428b9..3d2300b59 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -9,8 +9,8 @@ crate-type = ["cdylib"]
9 9
10[dependencies] 10[dependencies]
11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] } 11embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["log"] }
12embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } 12embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "integrated-timers"] }
13embassy-time = { version = "0.2", path = "../../embassy-time", features = ["log", "wasm", ] } 13embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["log", "wasm", ] }
14 14
15wasm-logger = "0.2.0" 15wasm-logger = "0.2.0"
16wasm-bindgen = "0.2" 16wasm-bindgen = "0.2"
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index 1141096fb..71cf980dd 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -1,5 +1,3 @@
1#![feature(type_alias_impl_trait)]
2
3use embassy_executor::Spawner; 1use embassy_executor::Spawner;
4use embassy_time::Timer; 2use embassy_time::Timer;
5 3