diff options
| author | Quentin Smith <[email protected]> | 2023-07-17 21:31:43 -0400 |
|---|---|---|
| committer | Quentin Smith <[email protected]> | 2023-07-17 21:31:43 -0400 |
| commit | 6f02403184eb7fb7990fb88fc9df9c4328a690a3 (patch) | |
| tree | 748f510e190bb2724750507a6e69ed1a8e08cb20 /examples/stm32h7/src/bin | |
| parent | d896f80405aa8963877049ed999e4aba25d6e2bb (diff) | |
| parent | 6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff) | |
Merge remote-tracking branch 'origin/main' into nrf-pdm
Diffstat (limited to 'examples/stm32h7/src/bin')
| -rw-r--r-- | examples/stm32h7/src/bin/camera.rs | 14 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/dac.rs | 9 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth.rs | 70 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth_client.rs | 68 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/flash.rs | 15 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/i2c.rs | 47 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/low_level_timer_api.rs | 54 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/sdmmc.rs | 10 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/signal.rs | 3 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/usart.rs | 7 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/usart_dma.rs | 7 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/usart_split.rs | 7 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/usb_serial.rs | 110 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/wdg.rs | 24 |
14 files changed, 310 insertions, 135 deletions
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 9c443b83a..6f75a0630 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::gpio::{Level, Output, Speed}; | |||
| 8 | use embassy_stm32::i2c::I2c; | 8 | use embassy_stm32::i2c::I2c; |
| 9 | use embassy_stm32::rcc::{Mco, Mco1Source, McoClock}; | 9 | use embassy_stm32::rcc::{Mco, Mco1Source, McoClock}; |
| 10 | use embassy_stm32::time::{khz, mhz}; | 10 | use embassy_stm32::time::{khz, mhz}; |
| 11 | use embassy_stm32::{interrupt, Config}; | 11 | use embassy_stm32::{bind_interrupts, i2c, peripherals, Config}; |
| 12 | use embassy_time::{Duration, Timer}; | 12 | use embassy_time::{Duration, Timer}; |
| 13 | use ov7725::*; | 13 | use ov7725::*; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -18,6 +18,11 @@ const HEIGHT: usize = 100; | |||
| 18 | 18 | ||
| 19 | static mut FRAME: [u32; WIDTH * HEIGHT / 2] = [0u32; WIDTH * HEIGHT / 2]; | 19 | static mut FRAME: [u32; WIDTH * HEIGHT / 2] = [0u32; WIDTH * HEIGHT / 2]; |
| 20 | 20 | ||
| 21 | bind_interrupts!(struct Irqs { | ||
| 22 | I2C1_EV => i2c::InterruptHandler<peripherals::I2C1>; | ||
| 23 | DCMI => dcmi::InterruptHandler<peripherals::DCMI>; | ||
| 24 | }); | ||
| 25 | |||
| 21 | #[embassy_executor::main] | 26 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 27 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 28 | let mut config = Config::default(); |
| @@ -34,12 +39,11 @@ async fn main(_spawner: Spawner) { | |||
| 34 | let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::Hsi, McoClock::Divided(3)); | 39 | let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::Hsi, McoClock::Divided(3)); |
| 35 | 40 | ||
| 36 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); | 41 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); |
| 37 | let i2c_irq = interrupt::take!(I2C1_EV); | ||
| 38 | let cam_i2c = I2c::new( | 42 | let cam_i2c = I2c::new( |
| 39 | p.I2C1, | 43 | p.I2C1, |
| 40 | p.PB8, | 44 | p.PB8, |
| 41 | p.PB9, | 45 | p.PB9, |
| 42 | i2c_irq, | 46 | Irqs, |
| 43 | p.DMA1_CH1, | 47 | p.DMA1_CH1, |
| 44 | p.DMA1_CH2, | 48 | p.DMA1_CH2, |
| 45 | khz(100), | 49 | khz(100), |
| @@ -55,11 +59,9 @@ async fn main(_spawner: Spawner) { | |||
| 55 | 59 | ||
| 56 | defmt::info!("manufacturer: 0x{:x}, pid: 0x{:x}", manufacturer_id, camera_id); | 60 | defmt::info!("manufacturer: 0x{:x}, pid: 0x{:x}", manufacturer_id, camera_id); |
| 57 | 61 | ||
| 58 | let dcmi_irq = interrupt::take!(DCMI); | ||
| 59 | let config = dcmi::Config::default(); | 62 | let config = dcmi::Config::default(); |
| 60 | let mut dcmi = Dcmi::new_8bit( | 63 | let mut dcmi = Dcmi::new_8bit( |
| 61 | p.DCMI, p.DMA1_CH0, dcmi_irq, p.PC6, p.PC7, p.PE0, p.PE1, p.PE4, p.PD3, p.PE5, p.PE6, p.PB7, p.PA4, p.PA6, | 64 | p.DCMI, p.DMA1_CH0, Irqs, p.PC6, p.PC7, p.PE0, p.PE1, p.PE4, p.PD3, p.PE5, p.PE6, p.PB7, p.PA4, p.PA6, config, |
| 62 | config, | ||
| 63 | ); | 65 | ); |
| 64 | 66 | ||
| 65 | defmt::info!("attempting capture"); | 67 | defmt::info!("attempting capture"); |
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index f12716370..586b4154b 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs | |||
| @@ -4,7 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | use cortex_m_rt::entry; | 5 | use cortex_m_rt::entry; |
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_stm32::dac::{Channel, Dac, Value}; | 7 | use embassy_stm32::dac::{DacCh1, DacChannel, Value}; |
| 8 | use embassy_stm32::dma::NoDma; | ||
| 8 | use embassy_stm32::time::mhz; | 9 | use embassy_stm32::time::mhz; |
| 9 | use embassy_stm32::Config; | 10 | use embassy_stm32::Config; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -19,12 +20,12 @@ fn main() -> ! { | |||
| 19 | config.rcc.pll1.q_ck = Some(mhz(100)); | 20 | config.rcc.pll1.q_ck = Some(mhz(100)); |
| 20 | let p = embassy_stm32::init(config); | 21 | let p = embassy_stm32::init(config); |
| 21 | 22 | ||
| 22 | let mut dac = Dac::new_1ch(p.DAC1, p.PA4); | 23 | let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4); |
| 23 | 24 | ||
| 24 | loop { | 25 | loop { |
| 25 | for v in 0..=255 { | 26 | for v in 0..=255 { |
| 26 | unwrap!(dac.set(Channel::Ch1, Value::Bit8(to_sine_wave(v)))); | 27 | unwrap!(dac.set(Value::Bit8(to_sine_wave(v)))); |
| 27 | unwrap!(dac.trigger(Channel::Ch1)); | 28 | dac.trigger(); |
| 28 | } | 29 | } |
| 29 | } | 30 | } |
| 30 | } | 31 | } |
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 4ccc0b5ef..cfafcaed1 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs | |||
| @@ -7,26 +7,21 @@ use embassy_executor::Spawner; | |||
| 7 | use embassy_net::tcp::TcpSocket; | 7 | use embassy_net::tcp::TcpSocket; |
| 8 | use embassy_net::{Ipv4Address, Stack, StackResources}; | 8 | use embassy_net::{Ipv4Address, Stack, StackResources}; |
| 9 | use embassy_stm32::eth::generic_smi::GenericSMI; | 9 | use embassy_stm32::eth::generic_smi::GenericSMI; |
| 10 | use embassy_stm32::eth::{Ethernet, State}; | 10 | use embassy_stm32::eth::{Ethernet, PacketQueue}; |
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{interrupt, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use rand_core::RngCore; | 17 | use rand_core::RngCore; |
| 18 | use static_cell::StaticCell; | 18 | use static_cell::make_static; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | bind_interrupts!(struct Irqs { | ||
| 21 | ETH => eth::InterruptHandler; | ||
| 22 | }); | ||
| 20 | 23 | ||
| 21 | macro_rules! singleton { | 24 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| 22 | ($val:expr) => {{ | ||
| 23 | type T = impl Sized; | ||
| 24 | static STATIC_CELL: StaticCell<T> = StaticCell::new(); | ||
| 25 | STATIC_CELL.init_with(move || $val) | ||
| 26 | }}; | ||
| 27 | } | ||
| 28 | |||
| 29 | type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>; | ||
| 30 | 25 | ||
| 31 | #[embassy_executor::task] | 26 | #[embassy_executor::task] |
| 32 | async fn net_task(stack: &'static Stack<Device>) -> ! { | 27 | async fn net_task(stack: &'static Stack<Device>) -> ! { |
| @@ -48,41 +43,38 @@ async fn main(spawner: Spawner) -> ! { | |||
| 48 | rng.fill_bytes(&mut seed); | 43 | rng.fill_bytes(&mut seed); |
| 49 | let seed = u64::from_le_bytes(seed); | 44 | let seed = u64::from_le_bytes(seed); |
| 50 | 45 | ||
| 51 | let eth_int = interrupt::take!(ETH); | ||
| 52 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 46 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 53 | 47 | ||
| 54 | let device = unsafe { | 48 | let device = Ethernet::new( |
| 55 | Ethernet::new( | 49 | make_static!(PacketQueue::<16, 16>::new()), |
| 56 | singleton!(State::new()), | 50 | p.ETH, |
| 57 | p.ETH, | 51 | Irqs, |
| 58 | eth_int, | 52 | p.PA1, |
| 59 | p.PA1, | 53 | p.PA2, |
| 60 | p.PA2, | 54 | p.PC1, |
| 61 | p.PC1, | 55 | p.PA7, |
| 62 | p.PA7, | 56 | p.PC4, |
| 63 | p.PC4, | 57 | p.PC5, |
| 64 | p.PC5, | 58 | p.PG13, |
| 65 | p.PG13, | 59 | p.PB13, |
| 66 | p.PB13, | 60 | p.PG11, |
| 67 | p.PG11, | 61 | GenericSMI::new(), |
| 68 | GenericSMI, | 62 | mac_addr, |
| 69 | mac_addr, | 63 | 0, |
| 70 | 0, | 64 | ); |
| 71 | ) | 65 | |
| 72 | }; | 66 | let config = embassy_net::Config::dhcpv4(Default::default()); |
| 73 | 67 | //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { | |
| 74 | let config = embassy_net::ConfigStrategy::Dhcp; | ||
| 75 | //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { | ||
| 76 | // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), | 68 | // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), |
| 77 | // dns_servers: Vec::new(), | 69 | // dns_servers: Vec::new(), |
| 78 | // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), | 70 | // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), |
| 79 | //}); | 71 | //}); |
| 80 | 72 | ||
| 81 | // Init network stack | 73 | // Init network stack |
| 82 | let stack = &*singleton!(Stack::new( | 74 | let stack = &*make_static!(Stack::new( |
| 83 | device, | 75 | device, |
| 84 | config, | 76 | config, |
| 85 | singleton!(StackResources::<1, 2, 8>::new()), | 77 | make_static!(StackResources::<2>::new()), |
| 86 | seed | 78 | seed |
| 87 | )); | 79 | )); |
| 88 | 80 | ||
| @@ -98,7 +90,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 98 | loop { | 90 | loop { |
| 99 | let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer); | 91 | let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer); |
| 100 | 92 | ||
| 101 | socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); | 93 | socket.set_timeout(Some(embassy_time::Duration::from_secs(10))); |
| 102 | 94 | ||
| 103 | let remote_endpoint = (Ipv4Address::new(10, 42, 0, 1), 8000); | 95 | let remote_endpoint = (Ipv4Address::new(10, 42, 0, 1), 8000); |
| 104 | info!("connecting..."); | 96 | info!("connecting..."); |
| @@ -112,7 +104,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 112 | let r = socket.write_all(b"Hello\n").await; | 104 | let r = socket.write_all(b"Hello\n").await; |
| 113 | if let Err(e) = r { | 105 | if let Err(e) = r { |
| 114 | info!("write error: {:?}", e); | 106 | info!("write error: {:?}", e); |
| 115 | return; | 107 | continue; |
| 116 | } | 108 | } |
| 117 | Timer::after(Duration::from_secs(1)).await; | 109 | Timer::after(Duration::from_secs(1)).await; |
| 118 | } | 110 | } |
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 64fd84141..4ed737578 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs | |||
| @@ -7,27 +7,22 @@ use embassy_executor::Spawner; | |||
| 7 | use embassy_net::tcp::client::{TcpClient, TcpClientState}; | 7 | use embassy_net::tcp::client::{TcpClient, TcpClientState}; |
| 8 | use embassy_net::{Stack, StackResources}; | 8 | use embassy_net::{Stack, StackResources}; |
| 9 | use embassy_stm32::eth::generic_smi::GenericSMI; | 9 | use embassy_stm32::eth::generic_smi::GenericSMI; |
| 10 | use embassy_stm32::eth::{Ethernet, State}; | 10 | use embassy_stm32::eth::{Ethernet, PacketQueue}; |
| 11 | use embassy_stm32::peripherals::ETH; | 11 | use embassy_stm32::peripherals::ETH; |
| 12 | use embassy_stm32::rng::Rng; | 12 | use embassy_stm32::rng::Rng; |
| 13 | use embassy_stm32::time::mhz; | 13 | use embassy_stm32::time::mhz; |
| 14 | use embassy_stm32::{interrupt, Config}; | 14 | use embassy_stm32::{bind_interrupts, eth, Config}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use embedded_io::asynch::Write; | 16 | use embedded_io::asynch::Write; |
| 17 | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | 17 | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; |
| 18 | use rand_core::RngCore; | 18 | use rand_core::RngCore; |
| 19 | use static_cell::StaticCell; | 19 | use static_cell::make_static; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | bind_interrupts!(struct Irqs { | ||
| 22 | ETH => eth::InterruptHandler; | ||
| 23 | }); | ||
| 21 | 24 | ||
| 22 | macro_rules! singleton { | 25 | type Device = Ethernet<'static, ETH, GenericSMI>; |
| 23 | ($val:expr) => {{ | ||
| 24 | type T = impl Sized; | ||
| 25 | static STATIC_CELL: StaticCell<T> = StaticCell::new(); | ||
| 26 | STATIC_CELL.init_with(move || $val) | ||
| 27 | }}; | ||
| 28 | } | ||
| 29 | |||
| 30 | type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>; | ||
| 31 | 26 | ||
| 32 | #[embassy_executor::task] | 27 | #[embassy_executor::task] |
| 33 | async fn net_task(stack: &'static Stack<Device>) -> ! { | 28 | async fn net_task(stack: &'static Stack<Device>) -> ! { |
| @@ -49,41 +44,38 @@ async fn main(spawner: Spawner) -> ! { | |||
| 49 | rng.fill_bytes(&mut seed); | 44 | rng.fill_bytes(&mut seed); |
| 50 | let seed = u64::from_le_bytes(seed); | 45 | let seed = u64::from_le_bytes(seed); |
| 51 | 46 | ||
| 52 | let eth_int = interrupt::take!(ETH); | ||
| 53 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 47 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 54 | 48 | ||
| 55 | let device = unsafe { | 49 | let device = Ethernet::new( |
| 56 | Ethernet::new( | 50 | make_static!(PacketQueue::<16, 16>::new()), |
| 57 | singleton!(State::new()), | 51 | p.ETH, |
| 58 | p.ETH, | 52 | Irqs, |
| 59 | eth_int, | 53 | p.PA1, |
| 60 | p.PA1, | 54 | p.PA2, |
| 61 | p.PA2, | 55 | p.PC1, |
| 62 | p.PC1, | 56 | p.PA7, |
| 63 | p.PA7, | 57 | p.PC4, |
| 64 | p.PC4, | 58 | p.PC5, |
| 65 | p.PC5, | 59 | p.PG13, |
| 66 | p.PG13, | 60 | p.PB13, |
| 67 | p.PB13, | 61 | p.PG11, |
| 68 | p.PG11, | 62 | GenericSMI::new(), |
| 69 | GenericSMI, | 63 | mac_addr, |
| 70 | mac_addr, | 64 | 0, |
| 71 | 0, | 65 | ); |
| 72 | ) | 66 | |
| 73 | }; | 67 | let config = embassy_net::Config::dhcpv4(Default::default()); |
| 74 | 68 | //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { | |
| 75 | let config = embassy_net::ConfigStrategy::Dhcp; | ||
| 76 | //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { | ||
| 77 | // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), | 69 | // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), |
| 78 | // dns_servers: Vec::new(), | 70 | // dns_servers: Vec::new(), |
| 79 | // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), | 71 | // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), |
| 80 | //}); | 72 | //}); |
| 81 | 73 | ||
| 82 | // Init network stack | 74 | // Init network stack |
| 83 | let stack = &*singleton!(Stack::new( | 75 | let stack = &*make_static!(Stack::new( |
| 84 | device, | 76 | device, |
| 85 | config, | 77 | config, |
| 86 | singleton!(StackResources::<1, 2, 8>::new()), | 78 | make_static!(StackResources::<2>::new()), |
| 87 | seed | 79 | seed |
| 88 | )); | 80 | )); |
| 89 | 81 | ||
| @@ -114,7 +106,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 114 | let r = connection.write_all(b"Hello\n").await; | 106 | let r = connection.write_all(b"Hello\n").await; |
| 115 | if let Err(e) = r { | 107 | if let Err(e) = r { |
| 116 | info!("write error: {:?}", e); | 108 | info!("write error: {:?}", e); |
| 117 | return; | 109 | continue; |
| 118 | } | 110 | } |
| 119 | Timer::after(Duration::from_secs(1)).await; | 111 | Timer::after(Duration::from_secs(1)).await; |
| 120 | } | 112 | } |
diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs index 6682c64d5..f66df770b 100644 --- a/examples/stm32h7/src/bin/flash.rs +++ b/examples/stm32h7/src/bin/flash.rs | |||
| @@ -6,7 +6,6 @@ use defmt::{info, unwrap}; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::flash::Flash; | 7 | use embassy_stm32::flash::Flash; |
| 8 | use embassy_time::{Duration, Timer}; | 8 | use embassy_time::{Duration, Timer}; |
| 9 | use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 10 | ||
| 12 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| @@ -14,28 +13,28 @@ async fn main(_spawner: Spawner) { | |||
| 14 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 15 | info!("Hello Flash!"); | 14 | info!("Hello Flash!"); |
| 16 | 15 | ||
| 17 | const ADDR: u32 = 0x08_0000; | 16 | const ADDR: u32 = 0; // This is the offset into bank 2, the absolute address is 0x8_0000 |
| 18 | 17 | ||
| 19 | // wait a bit before accessing the flash | 18 | // wait a bit before accessing the flash |
| 20 | Timer::after(Duration::from_millis(300)).await; | 19 | Timer::after(Duration::from_millis(300)).await; |
| 21 | 20 | ||
| 22 | let mut f = Flash::unlock(p.FLASH); | 21 | let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank2_region; |
| 23 | 22 | ||
| 24 | info!("Reading..."); | 23 | info!("Reading..."); |
| 25 | let mut buf = [0u8; 32]; | 24 | let mut buf = [0u8; 32]; |
| 26 | unwrap!(f.read(ADDR, &mut buf)); | 25 | unwrap!(f.blocking_read(ADDR, &mut buf)); |
| 27 | info!("Read: {=[u8]:x}", buf); | 26 | info!("Read: {=[u8]:x}", buf); |
| 28 | 27 | ||
| 29 | info!("Erasing..."); | 28 | info!("Erasing..."); |
| 30 | unwrap!(f.erase(ADDR, ADDR + 128 * 1024)); | 29 | unwrap!(f.blocking_erase(ADDR, ADDR + 128 * 1024)); |
| 31 | 30 | ||
| 32 | info!("Reading..."); | 31 | info!("Reading..."); |
| 33 | let mut buf = [0u8; 32]; | 32 | let mut buf = [0u8; 32]; |
| 34 | unwrap!(f.read(ADDR, &mut buf)); | 33 | unwrap!(f.blocking_read(ADDR, &mut buf)); |
| 35 | info!("Read after erase: {=[u8]:x}", buf); | 34 | info!("Read after erase: {=[u8]:x}", buf); |
| 36 | 35 | ||
| 37 | info!("Writing..."); | 36 | info!("Writing..."); |
| 38 | unwrap!(f.write( | 37 | unwrap!(f.blocking_write( |
| 39 | ADDR, | 38 | ADDR, |
| 40 | &[ | 39 | &[ |
| 41 | 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 | 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, |
| @@ -45,7 +44,7 @@ async fn main(_spawner: Spawner) { | |||
| 45 | 44 | ||
| 46 | info!("Reading..."); | 45 | info!("Reading..."); |
| 47 | let mut buf = [0u8; 32]; | 46 | let mut buf = [0u8; 32]; |
| 48 | unwrap!(f.read(ADDR, &mut buf)); | 47 | unwrap!(f.blocking_read(ADDR, &mut buf)); |
| 49 | info!("Read: {=[u8]:x}", buf); | 48 | info!("Read: {=[u8]:x}", buf); |
| 50 | assert_eq!( | 49 | assert_eq!( |
| 51 | &buf[..], | 50 | &buf[..], |
diff --git a/examples/stm32h7/src/bin/i2c.rs b/examples/stm32h7/src/bin/i2c.rs new file mode 100644 index 000000000..c2979c59b --- /dev/null +++ b/examples/stm32h7/src/bin/i2c.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::i2c::{Error, I2c, TimeoutI2c}; | ||
| 8 | use embassy_stm32::time::Hertz; | ||
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 10 | use embassy_time::Duration; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | const ADDRESS: u8 = 0x5F; | ||
| 14 | const WHOAMI: u8 = 0x0F; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs { | ||
| 17 | I2C2_EV => i2c::InterruptHandler<peripherals::I2C2>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) { | ||
| 22 | info!("Hello world!"); | ||
| 23 | let p = embassy_stm32::init(Default::default()); | ||
| 24 | |||
| 25 | let mut i2c = I2c::new( | ||
| 26 | p.I2C2, | ||
| 27 | p.PB10, | ||
| 28 | p.PB11, | ||
| 29 | Irqs, | ||
| 30 | p.DMA1_CH4, | ||
| 31 | p.DMA1_CH5, | ||
| 32 | Hertz(100_000), | ||
| 33 | Default::default(), | ||
| 34 | ); | ||
| 35 | |||
| 36 | // I2C bus can freeze if SCL line is shorted or due to a broken device that clock stretches for too long. | ||
| 37 | // TimeoutI2c allows recovering from such errors by throwing `Error::Timeout` after a given delay. | ||
| 38 | let mut timeout_i2c = TimeoutI2c::new(&mut i2c, Duration::from_millis(1000)); | ||
| 39 | |||
| 40 | let mut data = [0u8; 1]; | ||
| 41 | |||
| 42 | match timeout_i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data) { | ||
| 43 | Ok(()) => info!("Whoami: {}", data[0]), | ||
| 44 | Err(Error::Timeout) => error!("Operation timed out"), | ||
| 45 | Err(e) => error!("I2c Error: {:?}", e), | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index 1972f8ff2..d360df085 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs | |||
| @@ -62,49 +62,39 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 62 | T::enable(); | 62 | T::enable(); |
| 63 | <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset(); | 63 | <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset(); |
| 64 | 64 | ||
| 65 | unsafe { | 65 | ch1.set_speed(Speed::VeryHigh); |
| 66 | ch1.set_speed(Speed::VeryHigh); | 66 | ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); |
| 67 | ch1.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 67 | ch2.set_speed(Speed::VeryHigh); |
| 68 | ch2.set_speed(Speed::VeryHigh); | 68 | ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); |
| 69 | ch2.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 69 | ch3.set_speed(Speed::VeryHigh); |
| 70 | ch3.set_speed(Speed::VeryHigh); | 70 | ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); |
| 71 | ch3.set_as_af(ch1.af_num(), AFType::OutputPushPull); | 71 | ch4.set_speed(Speed::VeryHigh); |
| 72 | ch4.set_speed(Speed::VeryHigh); | 72 | ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); |
| 73 | ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); | ||
| 74 | } | ||
| 75 | 73 | ||
| 76 | let mut this = Self { inner: tim }; | 74 | let mut this = Self { inner: tim }; |
| 77 | 75 | ||
| 78 | this.set_freq(freq); | 76 | this.set_freq(freq); |
| 79 | this.inner.start(); | 77 | this.inner.start(); |
| 80 | 78 | ||
| 81 | unsafe { | 79 | let r = T::regs_gp32(); |
| 82 | T::regs_gp32() | 80 | r.ccmr_output(0) |
| 83 | .ccmr_output(0) | 81 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); |
| 84 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | 82 | r.ccmr_output(0) |
| 85 | T::regs_gp32() | 83 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); |
| 86 | .ccmr_output(0) | 84 | r.ccmr_output(1) |
| 87 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); | 85 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); |
| 88 | T::regs_gp32() | 86 | r.ccmr_output(1) |
| 89 | .ccmr_output(1) | 87 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); |
| 90 | .modify(|w| w.set_ocm(0, OutputCompareMode::PwmMode1.into())); | 88 | |
| 91 | T::regs_gp32() | ||
| 92 | .ccmr_output(1) | ||
| 93 | .modify(|w| w.set_ocm(1, OutputCompareMode::PwmMode1.into())); | ||
| 94 | } | ||
| 95 | this | 89 | this |
| 96 | } | 90 | } |
| 97 | 91 | ||
| 98 | pub fn enable(&mut self, channel: Channel) { | 92 | pub fn enable(&mut self, channel: Channel) { |
| 99 | unsafe { | 93 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), true)); |
| 100 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), true)); | ||
| 101 | } | ||
| 102 | } | 94 | } |
| 103 | 95 | ||
| 104 | pub fn disable(&mut self, channel: Channel) { | 96 | pub fn disable(&mut self, channel: Channel) { |
| 105 | unsafe { | 97 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), false)); |
| 106 | T::regs_gp32().ccer().modify(|w| w.set_cce(channel.raw(), false)); | ||
| 107 | } | ||
| 108 | } | 98 | } |
| 109 | 99 | ||
| 110 | pub fn set_freq(&mut self, freq: Hertz) { | 100 | pub fn set_freq(&mut self, freq: Hertz) { |
| @@ -112,11 +102,11 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 112 | } | 102 | } |
| 113 | 103 | ||
| 114 | pub fn get_max_duty(&self) -> u32 { | 104 | pub fn get_max_duty(&self) -> u32 { |
| 115 | unsafe { T::regs_gp32().arr().read().arr() } | 105 | T::regs_gp32().arr().read().arr() |
| 116 | } | 106 | } |
| 117 | 107 | ||
| 118 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | 108 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { |
| 119 | defmt::assert!(duty < self.get_max_duty()); | 109 | defmt::assert!(duty < self.get_max_duty()); |
| 120 | unsafe { T::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(duty)) } | 110 | T::regs_gp32().ccr(channel.raw()).modify(|w| w.set_ccr(duty)) |
| 121 | } | 111 | } |
| 122 | } | 112 | } |
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs index 26d1db01e..ce91b6b1c 100644 --- a/examples/stm32h7/src/bin/sdmmc.rs +++ b/examples/stm32h7/src/bin/sdmmc.rs | |||
| @@ -6,9 +6,13 @@ use defmt::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::sdmmc::Sdmmc; | 7 | use embassy_stm32::sdmmc::Sdmmc; |
| 8 | use embassy_stm32::time::mhz; | 8 | use embassy_stm32::time::mhz; |
| 9 | use embassy_stm32::{interrupt, Config}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | SDMMC1 => sdmmc::InterruptHandler<peripherals::SDMMC1>; | ||
| 14 | }); | ||
| 15 | |||
| 12 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) -> ! { | 17 | async fn main(_spawner: Spawner) -> ! { |
| 14 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| @@ -16,11 +20,9 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 16 | let p = embassy_stm32::init(config); | 20 | let p = embassy_stm32::init(config); |
| 17 | info!("Hello World!"); | 21 | info!("Hello World!"); |
| 18 | 22 | ||
| 19 | let irq = interrupt::take!(SDMMC1); | ||
| 20 | |||
| 21 | let mut sdmmc = Sdmmc::new_4bit( | 23 | let mut sdmmc = Sdmmc::new_4bit( |
| 22 | p.SDMMC1, | 24 | p.SDMMC1, |
| 23 | irq, | 25 | Irqs, |
| 24 | p.PC12, | 26 | p.PC12, |
| 25 | p.PD2, | 27 | p.PD2, |
| 26 | p.PC8, | 28 | p.PC8, |
diff --git a/examples/stm32h7/src/bin/signal.rs b/examples/stm32h7/src/bin/signal.rs index cc3e4e3ca..6d7c168d5 100644 --- a/examples/stm32h7/src/bin/signal.rs +++ b/examples/stm32h7/src/bin/signal.rs | |||
| @@ -4,11 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::{info, unwrap}; | 5 | use defmt::{info, unwrap}; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 7 | use embassy_sync::signal::Signal; | 8 | use embassy_sync::signal::Signal; |
| 8 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 11 | ||
| 11 | static SIGNAL: Signal<u32> = Signal::new(); | 12 | static SIGNAL: Signal<CriticalSectionRawMutex, u32> = Signal::new(); |
| 12 | 13 | ||
| 13 | #[embassy_executor::task] | 14 | #[embassy_executor::task] |
| 14 | async fn my_sending_task() { | 15 | async fn my_sending_task() { |
diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index 87c2b1253..0abb94abb 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs | |||
| @@ -7,15 +7,20 @@ use defmt::*; | |||
| 7 | use embassy_executor::Executor; | 7 | use embassy_executor::Executor; |
| 8 | use embassy_stm32::dma::NoDma; | 8 | use embassy_stm32::dma::NoDma; |
| 9 | use embassy_stm32::usart::{Config, Uart}; | 9 | use embassy_stm32::usart::{Config, Uart}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 10 | use static_cell::StaticCell; | 11 | use static_cell::StaticCell; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 13 | ||
| 14 | bind_interrupts!(struct Irqs { | ||
| 15 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 16 | }); | ||
| 17 | |||
| 13 | #[embassy_executor::task] | 18 | #[embassy_executor::task] |
| 14 | async fn main_task() { | 19 | async fn main_task() { |
| 15 | let p = embassy_stm32::init(Default::default()); | 20 | let p = embassy_stm32::init(Default::default()); |
| 16 | 21 | ||
| 17 | let config = Config::default(); | 22 | let config = Config::default(); |
| 18 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, NoDma, NoDma, config); | 23 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, NoDma, NoDma, config); |
| 19 | 24 | ||
| 20 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 25 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| 21 | info!("wrote Hello, starting echo"); | 26 | info!("wrote Hello, starting echo"); |
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs index 3adffcbeb..f1fe7fce6 100644 --- a/examples/stm32h7/src/bin/usart_dma.rs +++ b/examples/stm32h7/src/bin/usart_dma.rs | |||
| @@ -9,16 +9,21 @@ use defmt::*; | |||
| 9 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 10 | use embassy_stm32::dma::NoDma; | 10 | use embassy_stm32::dma::NoDma; |
| 11 | use embassy_stm32::usart::{Config, Uart}; | 11 | use embassy_stm32::usart::{Config, Uart}; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 12 | use heapless::String; | 13 | use heapless::String; |
| 13 | use static_cell::StaticCell; | 14 | use static_cell::StaticCell; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 15 | 16 | ||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 19 | }); | ||
| 20 | |||
| 16 | #[embassy_executor::task] | 21 | #[embassy_executor::task] |
| 17 | async fn main_task() { | 22 | async fn main_task() { |
| 18 | let p = embassy_stm32::init(Default::default()); | 23 | let p = embassy_stm32::init(Default::default()); |
| 19 | 24 | ||
| 20 | let config = Config::default(); | 25 | let config = Config::default(); |
| 21 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, p.DMA1_CH0, NoDma, config); | 26 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, NoDma, config); |
| 22 | 27 | ||
| 23 | for n in 0u32.. { | 28 | for n in 0u32.. { |
| 24 | let mut s: String<128> = String::new(); | 29 | let mut s: String<128> = String::new(); |
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs index df2b600f8..330d1ce09 100644 --- a/examples/stm32h7/src/bin/usart_split.rs +++ b/examples/stm32h7/src/bin/usart_split.rs | |||
| @@ -7,10 +7,15 @@ use embassy_executor::Spawner; | |||
| 7 | use embassy_stm32::dma::NoDma; | 7 | use embassy_stm32::dma::NoDma; |
| 8 | use embassy_stm32::peripherals::{DMA1_CH1, UART7}; | 8 | use embassy_stm32::peripherals::{DMA1_CH1, UART7}; |
| 9 | use embassy_stm32::usart::{Config, Uart, UartRx}; | 9 | use embassy_stm32::usart::{Config, Uart, UartRx}; |
| 10 | use embassy_stm32::{bind_interrupts, peripherals, usart}; | ||
| 10 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | 11 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; |
| 11 | use embassy_sync::channel::Channel; | 12 | use embassy_sync::channel::Channel; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | UART7 => usart::InterruptHandler<peripherals::UART7>; | ||
| 17 | }); | ||
| 18 | |||
| 14 | #[embassy_executor::task] | 19 | #[embassy_executor::task] |
| 15 | async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { | 20 | async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { |
| 16 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); | 21 | unwrap!(usart.blocking_write(b"Hello Embassy World!\r\n")); |
| @@ -31,7 +36,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 31 | info!("Hello World!"); | 36 | info!("Hello World!"); |
| 32 | 37 | ||
| 33 | let config = Config::default(); | 38 | let config = Config::default(); |
| 34 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, p.DMA1_CH0, p.DMA1_CH1, config); | 39 | let mut usart = Uart::new(p.UART7, p.PF6, p.PF7, Irqs, p.DMA1_CH0, p.DMA1_CH1, config); |
| 35 | unwrap!(usart.blocking_write(b"Type 8 chars to echo!\r\n")); | 40 | unwrap!(usart.blocking_write(b"Type 8 chars to echo!\r\n")); |
| 36 | 41 | ||
| 37 | let (mut tx, rx) = usart.split(); | 42 | let (mut tx, rx) = usart.split(); |
diff --git a/examples/stm32h7/src/bin/usb_serial.rs b/examples/stm32h7/src/bin/usb_serial.rs new file mode 100644 index 000000000..97291f60c --- /dev/null +++ b/examples/stm32h7/src/bin/usb_serial.rs | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::{panic, *}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::time::mhz; | ||
| 8 | use embassy_stm32::usb_otg::{Driver, Instance}; | ||
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | ||
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | ||
| 11 | use embassy_usb::driver::EndpointError; | ||
| 12 | use embassy_usb::Builder; | ||
| 13 | use futures::future::join; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs { | ||
| 17 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) { | ||
| 22 | info!("Hello World!"); | ||
| 23 | |||
| 24 | let mut config = Config::default(); | ||
| 25 | config.rcc.sys_ck = Some(mhz(400)); | ||
| 26 | config.rcc.hclk = Some(mhz(200)); | ||
| 27 | config.rcc.pll1.q_ck = Some(mhz(100)); | ||
| 28 | let p = embassy_stm32::init(config); | ||
| 29 | |||
| 30 | // Create the driver, from the HAL. | ||
| 31 | let mut ep_out_buffer = [0u8; 256]; | ||
| 32 | let mut config = embassy_stm32::usb_otg::Config::default(); | ||
| 33 | config.vbus_detection = true; | ||
| 34 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | ||
| 35 | |||
| 36 | // Create embassy-usb Config | ||
| 37 | let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); | ||
| 38 | config.manufacturer = Some("Embassy"); | ||
| 39 | config.product = Some("USB-serial example"); | ||
| 40 | config.serial_number = Some("12345678"); | ||
| 41 | |||
| 42 | // Required for windows compatibility. | ||
| 43 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
| 44 | config.device_class = 0xEF; | ||
| 45 | config.device_sub_class = 0x02; | ||
| 46 | config.device_protocol = 0x01; | ||
| 47 | config.composite_with_iads = true; | ||
| 48 | |||
| 49 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 50 | // It needs some buffers for building the descriptors. | ||
| 51 | let mut device_descriptor = [0; 256]; | ||
| 52 | let mut config_descriptor = [0; 256]; | ||
| 53 | let mut bos_descriptor = [0; 256]; | ||
| 54 | let mut control_buf = [0; 64]; | ||
| 55 | |||
| 56 | let mut state = State::new(); | ||
| 57 | |||
| 58 | let mut builder = Builder::new( | ||
| 59 | driver, | ||
| 60 | config, | ||
| 61 | &mut device_descriptor, | ||
| 62 | &mut config_descriptor, | ||
| 63 | &mut bos_descriptor, | ||
| 64 | &mut control_buf, | ||
| 65 | ); | ||
| 66 | |||
| 67 | // Create classes on the builder. | ||
| 68 | let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); | ||
| 69 | |||
| 70 | // Build the builder. | ||
| 71 | let mut usb = builder.build(); | ||
| 72 | |||
| 73 | // Run the USB device. | ||
| 74 | let usb_fut = usb.run(); | ||
| 75 | |||
| 76 | // Do stuff with the class! | ||
| 77 | let echo_fut = async { | ||
| 78 | loop { | ||
| 79 | class.wait_connection().await; | ||
| 80 | info!("Connected"); | ||
| 81 | let _ = echo(&mut class).await; | ||
| 82 | info!("Disconnected"); | ||
| 83 | } | ||
| 84 | }; | ||
| 85 | |||
| 86 | // Run everything concurrently. | ||
| 87 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 88 | join(usb_fut, echo_fut).await; | ||
| 89 | } | ||
| 90 | |||
| 91 | struct Disconnected {} | ||
| 92 | |||
| 93 | impl From<EndpointError> for Disconnected { | ||
| 94 | fn from(val: EndpointError) -> Self { | ||
| 95 | match val { | ||
| 96 | EndpointError::BufferOverflow => panic!("Buffer overflow"), | ||
| 97 | EndpointError::Disabled => Disconnected {}, | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { | ||
| 103 | let mut buf = [0; 64]; | ||
| 104 | loop { | ||
| 105 | let n = class.read_packet(&mut buf).await?; | ||
| 106 | let data = &buf[..n]; | ||
| 107 | info!("data: {:x}", data); | ||
| 108 | class.write_packet(data).await?; | ||
| 109 | } | ||
| 110 | } | ||
diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs new file mode 100644 index 000000000..9181dfd67 --- /dev/null +++ b/examples/stm32h7/src/bin/wdg.rs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_stm32::wdg::IndependentWatchdog; | ||
| 8 | use embassy_time::{Duration, Timer}; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | let p = embassy_stm32::init(Default::default()); | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let mut wdg = IndependentWatchdog::new(p.IWDG1, 20_000_000); | ||
| 17 | |||
| 18 | wdg.unleash(); | ||
| 19 | |||
| 20 | loop { | ||
| 21 | Timer::after(Duration::from_secs(1)).await; | ||
| 22 | wdg.pet(); | ||
| 23 | } | ||
| 24 | } | ||
