aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32h7/src
diff options
context:
space:
mode:
authorQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
committerQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
commit6f02403184eb7fb7990fb88fc9df9c4328a690a3 (patch)
tree748f510e190bb2724750507a6e69ed1a8e08cb20 /examples/stm32h7/src
parentd896f80405aa8963877049ed999e4aba25d6e2bb (diff)
parent6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff)
Merge remote-tracking branch 'origin/main' into nrf-pdm
Diffstat (limited to 'examples/stm32h7/src')
-rw-r--r--examples/stm32h7/src/bin/camera.rs14
-rw-r--r--examples/stm32h7/src/bin/dac.rs9
-rw-r--r--examples/stm32h7/src/bin/eth.rs70
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs68
-rw-r--r--examples/stm32h7/src/bin/flash.rs15
-rw-r--r--examples/stm32h7/src/bin/i2c.rs47
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs54
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs10
-rw-r--r--examples/stm32h7/src/bin/signal.rs3
-rw-r--r--examples/stm32h7/src/bin/usart.rs7
-rw-r--r--examples/stm32h7/src/bin/usart_dma.rs7
-rw-r--r--examples/stm32h7/src/bin/usart_split.rs7
-rw-r--r--examples/stm32h7/src/bin/usb_serial.rs110
-rw-r--r--examples/stm32h7/src/bin/wdg.rs24
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};
8use embassy_stm32::i2c::I2c; 8use embassy_stm32::i2c::I2c;
9use embassy_stm32::rcc::{Mco, Mco1Source, McoClock}; 9use embassy_stm32::rcc::{Mco, Mco1Source, McoClock};
10use embassy_stm32::time::{khz, mhz}; 10use embassy_stm32::time::{khz, mhz};
11use embassy_stm32::{interrupt, Config}; 11use embassy_stm32::{bind_interrupts, i2c, peripherals, Config};
12use embassy_time::{Duration, Timer}; 12use embassy_time::{Duration, Timer};
13use ov7725::*; 13use ov7725::*;
14use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
@@ -18,6 +18,11 @@ const HEIGHT: usize = 100;
18 18
19static mut FRAME: [u32; WIDTH * HEIGHT / 2] = [0u32; WIDTH * HEIGHT / 2]; 19static mut FRAME: [u32; WIDTH * HEIGHT / 2] = [0u32; WIDTH * HEIGHT / 2];
20 20
21bind_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]
22async fn main(_spawner: Spawner) { 27async 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
5use cortex_m_rt::entry; 5use cortex_m_rt::entry;
6use defmt::*; 6use defmt::*;
7use embassy_stm32::dac::{Channel, Dac, Value}; 7use embassy_stm32::dac::{DacCh1, DacChannel, Value};
8use embassy_stm32::dma::NoDma;
8use embassy_stm32::time::mhz; 9use embassy_stm32::time::mhz;
9use embassy_stm32::Config; 10use embassy_stm32::Config;
10use {defmt_rtt as _, panic_probe as _}; 11use {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;
7use embassy_net::tcp::TcpSocket; 7use embassy_net::tcp::TcpSocket;
8use embassy_net::{Ipv4Address, Stack, StackResources}; 8use embassy_net::{Ipv4Address, Stack, StackResources};
9use embassy_stm32::eth::generic_smi::GenericSMI; 9use embassy_stm32::eth::generic_smi::GenericSMI;
10use embassy_stm32::eth::{Ethernet, State}; 10use embassy_stm32::eth::{Ethernet, PacketQueue};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::ETH;
12use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{interrupt, Config}; 14use embassy_stm32::{bind_interrupts, eth, Config};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use embedded_io::asynch::Write; 16use embedded_io::asynch::Write;
17use rand_core::RngCore; 17use rand_core::RngCore;
18use static_cell::StaticCell; 18use static_cell::make_static;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20bind_interrupts!(struct Irqs {
21 ETH => eth::InterruptHandler;
22});
20 23
21macro_rules! singleton { 24type 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
29type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>;
30 25
31#[embassy_executor::task] 26#[embassy_executor::task]
32async fn net_task(stack: &'static Stack<Device>) -> ! { 27async 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;
7use embassy_net::tcp::client::{TcpClient, TcpClientState}; 7use embassy_net::tcp::client::{TcpClient, TcpClientState};
8use embassy_net::{Stack, StackResources}; 8use embassy_net::{Stack, StackResources};
9use embassy_stm32::eth::generic_smi::GenericSMI; 9use embassy_stm32::eth::generic_smi::GenericSMI;
10use embassy_stm32::eth::{Ethernet, State}; 10use embassy_stm32::eth::{Ethernet, PacketQueue};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::ETH;
12use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
13use embassy_stm32::time::mhz; 13use embassy_stm32::time::mhz;
14use embassy_stm32::{interrupt, Config}; 14use embassy_stm32::{bind_interrupts, eth, Config};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16use embedded_io::asynch::Write; 16use embedded_io::asynch::Write;
17use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; 17use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
18use rand_core::RngCore; 18use rand_core::RngCore;
19use static_cell::StaticCell; 19use static_cell::make_static;
20use {defmt_rtt as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _};
21bind_interrupts!(struct Irqs {
22 ETH => eth::InterruptHandler;
23});
21 24
22macro_rules! singleton { 25type 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
30type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>;
31 26
32#[embassy_executor::task] 27#[embassy_executor::task]
33async fn net_task(stack: &'static Stack<Device>) -> ! { 28async 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};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::flash::Flash; 7use embassy_stm32::flash::Flash;
8use embassy_time::{Duration, Timer}; 8use embassy_time::{Duration, Timer};
9use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
10use {defmt_rtt as _, panic_probe as _}; 9use {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
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::i2c::{Error, I2c, TimeoutI2c};
8use embassy_stm32::time::Hertz;
9use embassy_stm32::{bind_interrupts, i2c, peripherals};
10use embassy_time::Duration;
11use {defmt_rtt as _, panic_probe as _};
12
13const ADDRESS: u8 = 0x5F;
14const WHOAMI: u8 = 0x0F;
15
16bind_interrupts!(struct Irqs {
17 I2C2_EV => i2c::InterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main]
21async 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::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::sdmmc::Sdmmc; 7use embassy_stm32::sdmmc::Sdmmc;
8use embassy_stm32::time::mhz; 8use embassy_stm32::time::mhz;
9use embassy_stm32::{interrupt, Config}; 9use embassy_stm32::{bind_interrupts, peripherals, sdmmc, Config};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs {
13 SDMMC1 => sdmmc::InterruptHandler<peripherals::SDMMC1>;
14});
15
12#[embassy_executor::main] 16#[embassy_executor::main]
13async fn main(_spawner: Spawner) -> ! { 17async 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
5use defmt::{info, unwrap}; 5use defmt::{info, unwrap};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_sync::signal::Signal; 8use embassy_sync::signal::Signal;
8use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
9use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
10 11
11static SIGNAL: Signal<u32> = Signal::new(); 12static SIGNAL: Signal<CriticalSectionRawMutex, u32> = Signal::new();
12 13
13#[embassy_executor::task] 14#[embassy_executor::task]
14async fn my_sending_task() { 15async 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::*;
7use embassy_executor::Executor; 7use embassy_executor::Executor;
8use embassy_stm32::dma::NoDma; 8use embassy_stm32::dma::NoDma;
9use embassy_stm32::usart::{Config, Uart}; 9use embassy_stm32::usart::{Config, Uart};
10use embassy_stm32::{bind_interrupts, peripherals, usart};
10use static_cell::StaticCell; 11use static_cell::StaticCell;
11use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
12 13
14bind_interrupts!(struct Irqs {
15 UART7 => usart::InterruptHandler<peripherals::UART7>;
16});
17
13#[embassy_executor::task] 18#[embassy_executor::task]
14async fn main_task() { 19async 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::*;
9use embassy_executor::Executor; 9use embassy_executor::Executor;
10use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
11use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
12use embassy_stm32::{bind_interrupts, peripherals, usart};
12use heapless::String; 13use heapless::String;
13use static_cell::StaticCell; 14use static_cell::StaticCell;
14use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
15 16
17bind_interrupts!(struct Irqs {
18 UART7 => usart::InterruptHandler<peripherals::UART7>;
19});
20
16#[embassy_executor::task] 21#[embassy_executor::task]
17async fn main_task() { 22async 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;
7use embassy_stm32::dma::NoDma; 7use embassy_stm32::dma::NoDma;
8use embassy_stm32::peripherals::{DMA1_CH1, UART7}; 8use embassy_stm32::peripherals::{DMA1_CH1, UART7};
9use embassy_stm32::usart::{Config, Uart, UartRx}; 9use embassy_stm32::usart::{Config, Uart, UartRx};
10use embassy_stm32::{bind_interrupts, peripherals, usart};
10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
11use embassy_sync::channel::Channel; 12use embassy_sync::channel::Channel;
12use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
13 14
15bind_interrupts!(struct Irqs {
16 UART7 => usart::InterruptHandler<peripherals::UART7>;
17});
18
14#[embassy_executor::task] 19#[embassy_executor::task]
15async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) { 20async 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
5use defmt::{panic, *};
6use embassy_executor::Spawner;
7use embassy_stm32::time::mhz;
8use embassy_stm32::usb_otg::{Driver, Instance};
9use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config};
10use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
11use embassy_usb::driver::EndpointError;
12use embassy_usb::Builder;
13use futures::future::join;
14use {defmt_rtt as _, panic_probe as _};
15
16bind_interrupts!(struct Irqs {
17 OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>;
18});
19
20#[embassy_executor::main]
21async 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
91struct Disconnected {}
92
93impl 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
102async 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
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::wdg::IndependentWatchdog;
8use embassy_time::{Duration, Timer};
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::main]
12async 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}