aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf52840/src/bin/gpiote_channel.rs8
-rw-r--r--examples/nrf52840/src/bin/usb_hid_keyboard.rs58
-rw-r--r--examples/nrf52840/src/bin/usb_hid_mouse.rs56
-rw-r--r--examples/nrf5340/src/bin/gpiote_channel.rs8
-rw-r--r--examples/nrf54l15/memory.x2
-rw-r--r--examples/nrf54l15/src/bin/gpiote_channel.rs8
-rw-r--r--examples/rp/src/bin/usb_hid_keyboard.rs86
-rwxr-xr-xexamples/rp/src/bin/usb_hid_mouse.rs60
-rw-r--r--examples/rp235x/src/bin/usb_hid_keyboard.rs85
-rw-r--r--examples/stm32c0/src/bin/adc.rs26
-rw-r--r--examples/stm32f0/Cargo.toml1
-rw-r--r--examples/stm32f0/src/bin/adc-watchdog.rs6
-rw-r--r--examples/stm32f0/src/bin/adc.rs5
-rw-r--r--examples/stm32f0/src/bin/i2c_master.rs609
-rw-r--r--examples/stm32f1/src/bin/adc.rs6
-rw-r--r--examples/stm32f334/src/bin/adc.rs12
-rw-r--r--examples/stm32f334/src/bin/opamp.rs12
-rw-r--r--examples/stm32f4/src/bin/adc.rs12
-rw-r--r--examples/stm32f4/src/bin/adc_dma.rs16
-rw-r--r--examples/stm32f4/src/bin/usb_hid_keyboard.rs84
-rw-r--r--examples/stm32f4/src/bin/usb_hid_mouse.rs56
-rw-r--r--examples/stm32f469/src/bin/dsi_bsp.rs14
-rw-r--r--examples/stm32f7/src/bin/adc.rs6
-rw-r--r--examples/stm32g0/src/bin/adc.rs5
-rw-r--r--examples/stm32g0/src/bin/adc_oversampling.rs17
-rw-r--r--examples/stm32g4/src/bin/adc.rs10
-rw-r--r--examples/stm32g4/src/bin/adc_differential.rs9
-rw-r--r--examples/stm32g4/src/bin/adc_dma.rs2
-rw-r--r--examples/stm32g4/src/bin/adc_injected_and_regular.rs2
-rw-r--r--examples/stm32g4/src/bin/adc_oversampling.rs16
-rw-r--r--examples/stm32h5/src/bin/adc.rs6
-rw-r--r--examples/stm32h5/src/bin/adc_dma.rs9
-rw-r--r--examples/stm32h7/src/bin/adc.rs6
-rw-r--r--examples/stm32l0/src/bin/adc.rs5
-rw-r--r--examples/stm32l4/src/bin/adc.rs11
-rw-r--r--examples/stm32l4/src/bin/adc_dma.rs15
-rw-r--r--examples/stm32l5/src/bin/usb_hid_mouse.rs56
-rw-r--r--examples/stm32n6/.cargo/config.toml8
-rw-r--r--examples/stm32n6/Cargo.toml78
-rw-r--r--examples/stm32n6/build.rs5
-rw-r--r--examples/stm32n6/memory.x5
-rw-r--r--examples/stm32n6/src/bin/blinky.rs36
-rw-r--r--examples/stm32u0/src/bin/adc.rs9
-rw-r--r--examples/stm32u5/src/bin/adc.rs47
-rw-r--r--examples/stm32wba/src/bin/adc.rs23
-rw-r--r--examples/stm32wba6/src/bin/adc.rs22
-rw-r--r--examples/stm32wl/src/bin/adc.rs6
-rw-r--r--examples/stm32wle5/src/bin/adc.rs5
48 files changed, 1337 insertions, 312 deletions
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs
index c7ddc1d8d..e358779b2 100644
--- a/examples/nrf52840/src/bin/gpiote_channel.rs
+++ b/examples/nrf52840/src/bin/gpiote_channel.rs
@@ -12,10 +12,10 @@ async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!"); 13 info!("Starting!");
14 14
15 let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi); 16 let mut ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle); 17 let mut ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle); 18 let mut ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
index 1cd730503..7b7303526 100644
--- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -13,7 +13,9 @@ use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
13use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; 13use embassy_nrf::{bind_interrupts, pac, peripherals, usb};
14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
15use embassy_sync::signal::Signal; 15use embassy_sync::signal::Signal;
16use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; 16use embassy_usb::class::hid::{
17 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
18};
17use embassy_usb::control::OutResponse; 19use embassy_usb::control::OutResponse;
18use embassy_usb::{Builder, Config, Handler}; 20use embassy_usb::{Builder, Config, Handler};
19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 21use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -26,6 +28,8 @@ bind_interrupts!(struct Irqs {
26 28
27static SUSPENDED: AtomicBool = AtomicBool::new(false); 29static SUSPENDED: AtomicBool = AtomicBool::new(false);
28 30
31static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
32
29#[embassy_executor::main] 33#[embassy_executor::main]
30async fn main(_spawner: Spawner) { 34async fn main(_spawner: Spawner) {
31 let p = embassy_nrf::init(Default::default()); 35 let p = embassy_nrf::init(Default::default());
@@ -45,6 +49,10 @@ async fn main(_spawner: Spawner) {
45 config.max_power = 100; 49 config.max_power = 100;
46 config.max_packet_size_0 = 64; 50 config.max_packet_size_0 = 64;
47 config.supports_remote_wakeup = true; 51 config.supports_remote_wakeup = true;
52 config.composite_with_iads = false;
53 config.device_class = 0;
54 config.device_sub_class = 0;
55 config.device_protocol = 0;
48 56
49 // Create embassy-usb DeviceBuilder using the driver and config. 57 // Create embassy-usb DeviceBuilder using the driver and config.
50 // It needs some buffers for building the descriptors. 58 // It needs some buffers for building the descriptors.
@@ -74,6 +82,8 @@ async fn main(_spawner: Spawner) {
74 request_handler: None, 82 request_handler: None,
75 poll_ms: 60, 83 poll_ms: 60,
76 max_packet_size: 64, 84 max_packet_size: 64,
85 hid_subclass: HidSubclass::Boot,
86 hid_boot_protocol: HidBootProtocol::Keyboard,
77 }; 87 };
78 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); 88 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
79 89
@@ -106,6 +116,11 @@ async fn main(_spawner: Spawner) {
106 if SUSPENDED.load(Ordering::Acquire) { 116 if SUSPENDED.load(Ordering::Acquire) {
107 info!("Triggering remote wakeup"); 117 info!("Triggering remote wakeup");
108 remote_wakeup.signal(()); 118 remote_wakeup.signal(());
119 } else if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
120 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
121 Ok(()) => {}
122 Err(e) => warn!("Failed to send boot report: {:?}", e),
123 };
109 } else { 124 } else {
110 let report = KeyboardReport { 125 let report = KeyboardReport {
111 keycodes: [4, 0, 0, 0, 0, 0], 126 keycodes: [4, 0, 0, 0, 0, 0],
@@ -121,16 +136,23 @@ async fn main(_spawner: Spawner) {
121 136
122 button.wait_for_high().await; 137 button.wait_for_high().await;
123 info!("RELEASED"); 138 info!("RELEASED");
124 let report = KeyboardReport { 139 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
125 keycodes: [0, 0, 0, 0, 0, 0], 140 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
126 leds: 0, 141 Ok(()) => {}
127 modifier: 0, 142 Err(e) => warn!("Failed to send boot report: {:?}", e),
128 reserved: 0, 143 };
129 }; 144 } else {
130 match writer.write_serialize(&report).await { 145 let report = KeyboardReport {
131 Ok(()) => {} 146 keycodes: [0, 0, 0, 0, 0, 0],
132 Err(e) => warn!("Failed to send report: {:?}", e), 147 leds: 0,
133 }; 148 modifier: 0,
149 reserved: 0,
150 };
151 match writer.write_serialize(&report).await {
152 Ok(()) => {}
153 Err(e) => warn!("Failed to send report: {:?}", e),
154 };
155 }
134 } 156 }
135 }; 157 };
136 158
@@ -156,6 +178,18 @@ impl RequestHandler for MyRequestHandler {
156 OutResponse::Accepted 178 OutResponse::Accepted
157 } 179 }
158 180
181 fn get_protocol(&self) -> HidProtocolMode {
182 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
183 info!("The current HID protocol mode is: {}", protocol);
184 protocol
185 }
186
187 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
188 info!("Switching to HID protocol mode: {}", protocol);
189 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
190 OutResponse::Accepted
191 }
192
159 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 193 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
160 info!("Set idle rate for {:?} to {:?}", id, dur); 194 info!("Set idle rate for {:?} to {:?}", id, dur);
161 } 195 }
diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs
index 3c0fc04e8..6bee4546b 100644
--- a/examples/nrf52840/src/bin/usb_hid_mouse.rs
+++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs
@@ -1,6 +1,8 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicU8, Ordering};
5
4use defmt::*; 6use defmt::*;
5use embassy_executor::Spawner; 7use embassy_executor::Spawner;
6use embassy_futures::join::join; 8use embassy_futures::join::join;
@@ -8,7 +10,9 @@ use embassy_nrf::usb::Driver;
8use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; 10use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
9use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; 11use embassy_nrf::{bind_interrupts, pac, peripherals, usb};
10use embassy_time::Timer; 12use embassy_time::Timer;
11use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidSubclass, HidWriter, ReportId, RequestHandler, State,
15};
12use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
13use embassy_usb::{Builder, Config}; 17use embassy_usb::{Builder, Config};
14use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
@@ -19,6 +23,8 @@ bind_interrupts!(struct Irqs {
19 CLOCK_POWER => usb::vbus_detect::InterruptHandler; 23 CLOCK_POWER => usb::vbus_detect::InterruptHandler;
20}); 24});
21 25
26static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
27
22#[embassy_executor::main] 28#[embassy_executor::main]
23async fn main(_spawner: Spawner) { 29async fn main(_spawner: Spawner) {
24 let p = embassy_nrf::init(Default::default()); 30 let p = embassy_nrf::init(Default::default());
@@ -37,6 +43,10 @@ async fn main(_spawner: Spawner) {
37 config.serial_number = Some("12345678"); 43 config.serial_number = Some("12345678");
38 config.max_power = 100; 44 config.max_power = 100;
39 config.max_packet_size_0 = 64; 45 config.max_packet_size_0 = 64;
46 config.composite_with_iads = false;
47 config.device_class = 0;
48 config.device_sub_class = 0;
49 config.device_protocol = 0;
40 50
41 // Create embassy-usb DeviceBuilder using the driver and config. 51 // Create embassy-usb DeviceBuilder using the driver and config.
42 // It needs some buffers for building the descriptors. 52 // It needs some buffers for building the descriptors.
@@ -63,6 +73,8 @@ async fn main(_spawner: Spawner) {
63 request_handler: Some(&mut request_handler), 73 request_handler: Some(&mut request_handler),
64 poll_ms: 60, 74 poll_ms: 60,
65 max_packet_size: 8, 75 max_packet_size: 8,
76 hid_subclass: HidSubclass::Boot,
77 hid_boot_protocol: HidBootProtocol::Mouse,
66 }; 78 };
67 79
68 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config); 80 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
@@ -80,16 +92,26 @@ async fn main(_spawner: Spawner) {
80 Timer::after_millis(500).await; 92 Timer::after_millis(500).await;
81 93
82 y = -y; 94 y = -y;
83 let report = MouseReport { 95
84 buttons: 0, 96 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
85 x: 0, 97 let buttons = 0u8;
86 y, 98 let x = 0i8;
87 wheel: 0, 99 match writer.write(&[buttons, x as u8, y as u8]).await {
88 pan: 0, 100 Ok(()) => {}
89 }; 101 Err(e) => warn!("Failed to send boot report: {:?}", e),
90 match writer.write_serialize(&report).await { 102 }
91 Ok(()) => {} 103 } else {
92 Err(e) => warn!("Failed to send report: {:?}", e), 104 let report = MouseReport {
105 buttons: 0,
106 x: 0,
107 y,
108 wheel: 0,
109 pan: 0,
110 };
111 match writer.write_serialize(&report).await {
112 Ok(()) => {}
113 Err(e) => warn!("Failed to send report: {:?}", e),
114 }
93 } 115 }
94 } 116 }
95 }; 117 };
@@ -112,6 +134,18 @@ impl RequestHandler for MyRequestHandler {
112 OutResponse::Accepted 134 OutResponse::Accepted
113 } 135 }
114 136
137 fn get_protocol(&self) -> HidProtocolMode {
138 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
139 info!("The current HID protocol mode is: {}", protocol);
140 protocol
141 }
142
143 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
144 info!("Switching to HID protocol mode: {}", protocol);
145 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
146 OutResponse::Accepted
147 }
148
115 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 149 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
116 info!("Set idle rate for {:?} to {:?}", id, dur); 150 info!("Set idle rate for {:?} to {:?}", id, dur);
117 } 151 }
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs
index a085310ce..41ee732c3 100644
--- a/examples/nrf5340/src/bin/gpiote_channel.rs
+++ b/examples/nrf5340/src/bin/gpiote_channel.rs
@@ -12,10 +12,10 @@ async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!"); 13 info!("Starting!");
14 14
15 let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi); 16 let mut ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle); 17 let mut ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle); 18 let mut ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/nrf54l15/memory.x b/examples/nrf54l15/memory.x
index 1064c8a5c..332200828 100644
--- a/examples/nrf54l15/memory.x
+++ b/examples/nrf54l15/memory.x
@@ -1,5 +1,5 @@
1MEMORY 1MEMORY
2{ 2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 1536K 3 FLASH : ORIGIN = 0x00000000, LENGTH = 1524K
4 RAM : ORIGIN = 0x20000000, LENGTH = 256K 4 RAM : ORIGIN = 0x20000000, LENGTH = 256K
5} 5}
diff --git a/examples/nrf54l15/src/bin/gpiote_channel.rs b/examples/nrf54l15/src/bin/gpiote_channel.rs
index 6333250ba..cac8823f8 100644
--- a/examples/nrf54l15/src/bin/gpiote_channel.rs
+++ b/examples/nrf54l15/src/bin/gpiote_channel.rs
@@ -12,10 +12,10 @@ async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!"); 13 info!("Starting!");
14 14
15 let ch1 = InputChannel::new(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut ch1 = InputChannel::new(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE20_CH1, p.P1_09, Pull::Up, InputChannelPolarity::LoToHi); 16 let mut ch2 = InputChannel::new(p.GPIOTE20_CH1, p.P1_09, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE20_CH2, p.P1_08, Pull::Up, InputChannelPolarity::Toggle); 17 let mut ch3 = InputChannel::new(p.GPIOTE20_CH2, p.P1_08, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle); 18 let mut ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs
index a7cb322d8..2f6d169bf 100644
--- a/examples/rp/src/bin/usb_hid_keyboard.rs
+++ b/examples/rp/src/bin/usb_hid_keyboard.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -10,7 +10,9 @@ use embassy_rp::bind_interrupts;
10use embassy_rp::gpio::{Input, Pull}; 10use embassy_rp::gpio::{Input, Pull};
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver, InterruptHandler}; 12use embassy_rp::usb::{Driver, InterruptHandler};
13use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
15};
14use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Config, Handler}; 17use embassy_usb::{Builder, Config, Handler};
16use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -20,6 +22,8 @@ bind_interrupts!(struct Irqs {
20 USBCTRL_IRQ => InterruptHandler<USB>; 22 USBCTRL_IRQ => InterruptHandler<USB>;
21}); 23});
22 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
23#[embassy_executor::main] 27#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
25 let p = embassy_rp::init(Default::default()); 29 let p = embassy_rp::init(Default::default());
@@ -33,6 +37,10 @@ async fn main(_spawner: Spawner) {
33 config.serial_number = Some("12345678"); 37 config.serial_number = Some("12345678");
34 config.max_power = 100; 38 config.max_power = 100;
35 config.max_packet_size_0 = 64; 39 config.max_packet_size_0 = 64;
40 config.composite_with_iads = false;
41 config.device_class = 0;
42 config.device_sub_class = 0;
43 config.device_protocol = 0;
36 44
37 // Create embassy-usb DeviceBuilder using the driver and config. 45 // Create embassy-usb DeviceBuilder using the driver and config.
38 // It needs some buffers for building the descriptors. 46 // It needs some buffers for building the descriptors.
@@ -63,6 +71,8 @@ async fn main(_spawner: Spawner) {
63 request_handler: None, 71 request_handler: None,
64 poll_ms: 60, 72 poll_ms: 60,
65 max_packet_size: 64, 73 max_packet_size: 64,
74 hid_subclass: HidSubclass::Boot,
75 hid_boot_protocol: HidBootProtocol::Keyboard,
66 }; 76 };
67 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); 77 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
68 78
@@ -86,30 +96,46 @@ async fn main(_spawner: Spawner) {
86 info!("Waiting for HIGH on pin 16"); 96 info!("Waiting for HIGH on pin 16");
87 signal_pin.wait_for_high().await; 97 signal_pin.wait_for_high().await;
88 info!("HIGH DETECTED"); 98 info!("HIGH DETECTED");
89 // Create a report with the A key pressed. (no shift modifier) 99
90 let report = KeyboardReport { 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
91 keycodes: [4, 0, 0, 0, 0, 0], 101 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
92 leds: 0, 102 Ok(()) => {}
93 modifier: 0, 103 Err(e) => warn!("Failed to send boot report: {:?}", e),
94 reserved: 0, 104 };
95 }; 105 } else {
96 // Send the report. 106 // Create a report with the A key pressed. (no shift modifier)
97 match writer.write_serialize(&report).await { 107 let report = KeyboardReport {
98 Ok(()) => {} 108 keycodes: [4, 0, 0, 0, 0, 0],
99 Err(e) => warn!("Failed to send report: {:?}", e), 109 leds: 0,
100 }; 110 modifier: 0,
111 reserved: 0,
112 };
113 // Send the report.
114 match writer.write_serialize(&report).await {
115 Ok(()) => {}
116 Err(e) => warn!("Failed to send report: {:?}", e),
117 };
118 }
119
101 signal_pin.wait_for_low().await; 120 signal_pin.wait_for_low().await;
102 info!("LOW DETECTED"); 121 info!("LOW DETECTED");
103 let report = KeyboardReport { 122 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
104 keycodes: [0, 0, 0, 0, 0, 0], 123 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
105 leds: 0, 124 Ok(()) => {}
106 modifier: 0, 125 Err(e) => warn!("Failed to send boot report: {:?}", e),
107 reserved: 0, 126 };
108 }; 127 } else {
109 match writer.write_serialize(&report).await { 128 let report = KeyboardReport {
110 Ok(()) => {} 129 keycodes: [0, 0, 0, 0, 0, 0],
111 Err(e) => warn!("Failed to send report: {:?}", e), 130 leds: 0,
112 }; 131 modifier: 0,
132 reserved: 0,
133 };
134 match writer.write_serialize(&report).await {
135 Ok(()) => {}
136 Err(e) => warn!("Failed to send report: {:?}", e),
137 };
138 }
113 } 139 }
114 }; 140 };
115 141
@@ -135,6 +161,18 @@ impl RequestHandler for MyRequestHandler {
135 OutResponse::Accepted 161 OutResponse::Accepted
136 } 162 }
137 163
164 fn get_protocol(&self) -> HidProtocolMode {
165 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
166 info!("The current HID protocol mode is: {}", protocol);
167 protocol
168 }
169
170 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
171 info!("Switching to HID protocol mode: {}", protocol);
172 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
173 OutResponse::Accepted
174 }
175
138 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 176 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
139 info!("Set idle rate for {:?} to {:?}", id, dur); 177 info!("Set idle rate for {:?} to {:?}", id, dur);
140 } 178 }
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs
index 4454c593c..dc331cbdd 100755
--- a/examples/rp/src/bin/usb_hid_mouse.rs
+++ b/examples/rp/src/bin/usb_hid_mouse.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -11,7 +11,9 @@ use embassy_rp::clocks::RoscRng;
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver, InterruptHandler}; 12use embassy_rp::usb::{Driver, InterruptHandler};
13use embassy_time::Timer; 13use embassy_time::Timer;
14use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; 14use embassy_usb::class::hid::{
15 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
16};
15use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
16use embassy_usb::{Builder, Config, Handler}; 18use embassy_usb::{Builder, Config, Handler};
17use rand::Rng; 19use rand::Rng;
@@ -22,6 +24,8 @@ bind_interrupts!(struct Irqs {
22 USBCTRL_IRQ => InterruptHandler<USB>; 24 USBCTRL_IRQ => InterruptHandler<USB>;
23}); 25});
24 26
27static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
28
25#[embassy_executor::main] 29#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 30async fn main(_spawner: Spawner) {
27 let p = embassy_rp::init(Default::default()); 31 let p = embassy_rp::init(Default::default());
@@ -35,6 +39,10 @@ async fn main(_spawner: Spawner) {
35 config.serial_number = Some("12345678"); 39 config.serial_number = Some("12345678");
36 config.max_power = 100; 40 config.max_power = 100;
37 config.max_packet_size_0 = 64; 41 config.max_packet_size_0 = 64;
42 config.composite_with_iads = false;
43 config.device_class = 0;
44 config.device_sub_class = 0;
45 config.device_protocol = 0;
38 46
39 // Create embassy-usb DeviceBuilder using the driver and config. 47 // Create embassy-usb DeviceBuilder using the driver and config.
40 // It needs some buffers for building the descriptors. 48 // It needs some buffers for building the descriptors.
@@ -65,6 +73,8 @@ async fn main(_spawner: Spawner) {
65 request_handler: None, 73 request_handler: None,
66 poll_ms: 60, 74 poll_ms: 60,
67 max_packet_size: 64, 75 max_packet_size: 64,
76 hid_subclass: HidSubclass::Boot,
77 hid_boot_protocol: HidBootProtocol::Mouse,
68 }; 78 };
69 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); 79 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
70 80
@@ -83,17 +93,29 @@ async fn main(_spawner: Spawner) {
83 loop { 93 loop {
84 // every 1 second 94 // every 1 second
85 _ = Timer::after_secs(1).await; 95 _ = Timer::after_secs(1).await;
86 let report = MouseReport { 96
87 buttons: 0, 97 let x = rng.random_range(-100..100); // random small x movement
88 x: rng.random_range(-100..100), // random small x movement 98 let y = rng.random_range(-100..100); // random small y movement
89 y: rng.random_range(-100..100), // random small y movement 99
90 wheel: 0, 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
91 pan: 0, 101 let buttons = 0u8;
92 }; 102 match writer.write(&[buttons, x as u8, y as u8]).await {
93 // Send the report. 103 Ok(()) => {}
94 match writer.write_serialize(&report).await { 104 Err(e) => warn!("Failed to send boot report: {:?}", e),
95 Ok(()) => {} 105 }
96 Err(e) => warn!("Failed to send report: {:?}", e), 106 } else {
107 let report = MouseReport {
108 buttons: 0,
109 x,
110 y,
111 wheel: 0,
112 pan: 0,
113 };
114 // Send the report.
115 match writer.write_serialize(&report).await {
116 Ok(()) => {}
117 Err(e) => warn!("Failed to send report: {:?}", e),
118 }
97 } 119 }
98 } 120 }
99 }; 121 };
@@ -120,6 +142,18 @@ impl RequestHandler for MyRequestHandler {
120 OutResponse::Accepted 142 OutResponse::Accepted
121 } 143 }
122 144
145 fn get_protocol(&self) -> HidProtocolMode {
146 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
147 info!("The current HID protocol mode is: {}", protocol);
148 protocol
149 }
150
151 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
152 info!("Switching to HID protocol mode: {}", protocol);
153 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
154 OutResponse::Accepted
155 }
156
123 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 157 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
124 info!("Set idle rate for {:?} to {:?}", id, dur); 158 info!("Set idle rate for {:?} to {:?}", id, dur);
125 } 159 }
diff --git a/examples/rp235x/src/bin/usb_hid_keyboard.rs b/examples/rp235x/src/bin/usb_hid_keyboard.rs
index 6f496e23a..d8f64c470 100644
--- a/examples/rp235x/src/bin/usb_hid_keyboard.rs
+++ b/examples/rp235x/src/bin/usb_hid_keyboard.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -10,7 +10,9 @@ use embassy_rp::bind_interrupts;
10use embassy_rp::gpio::{Input, Pull}; 10use embassy_rp::gpio::{Input, Pull};
11use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
12use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler}; 12use embassy_rp::usb::{Driver as UsbDriver, InterruptHandler};
13use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State as HidState}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State as HidState,
15};
14use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
15use embassy_usb::{Builder, Config, Handler}; 17use embassy_usb::{Builder, Config, Handler};
16use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -20,6 +22,8 @@ bind_interrupts!(struct Irqs {
20 USBCTRL_IRQ => InterruptHandler<USB>; 22 USBCTRL_IRQ => InterruptHandler<USB>;
21}); 23});
22 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
23#[embassy_executor::main] 27#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 28async fn main(_spawner: Spawner) {
25 let p = embassy_rp::init(Default::default()); 29 let p = embassy_rp::init(Default::default());
@@ -33,6 +37,10 @@ async fn main(_spawner: Spawner) {
33 config.serial_number = Some("12345678"); 37 config.serial_number = Some("12345678");
34 config.max_power = 100; 38 config.max_power = 100;
35 config.max_packet_size_0 = 64; 39 config.max_packet_size_0 = 64;
40 config.composite_with_iads = false;
41 config.device_class = 0;
42 config.device_sub_class = 0;
43 config.device_protocol = 0;
36 44
37 // Create embassy-usb DeviceBuilder using the driver and config. 45 // Create embassy-usb DeviceBuilder using the driver and config.
38 // It needs some buffers for building the descriptors. 46 // It needs some buffers for building the descriptors.
@@ -63,6 +71,8 @@ async fn main(_spawner: Spawner) {
63 request_handler: None, 71 request_handler: None,
64 poll_ms: 60, 72 poll_ms: 60,
65 max_packet_size: 64, 73 max_packet_size: 64,
74 hid_subclass: HidSubclass::Boot,
75 hid_boot_protocol: HidBootProtocol::Keyboard,
66 }; 76 };
67 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); 77 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
68 78
@@ -86,30 +96,45 @@ async fn main(_spawner: Spawner) {
86 info!("Waiting for HIGH on pin 16"); 96 info!("Waiting for HIGH on pin 16");
87 signal_pin.wait_for_high().await; 97 signal_pin.wait_for_high().await;
88 info!("HIGH DETECTED"); 98 info!("HIGH DETECTED");
89 // Create a report with the A key pressed. (no shift modifier) 99
90 let report = KeyboardReport { 100 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
91 keycodes: [4, 0, 0, 0, 0, 0], 101 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
92 leds: 0, 102 Ok(()) => {}
93 modifier: 0, 103 Err(e) => warn!("Failed to send boot report: {:?}", e),
94 reserved: 0, 104 };
95 }; 105 } else {
96 // Send the report. 106 // Create a report with the A key pressed. (no shift modifier)
97 match writer.write_serialize(&report).await { 107 let report = KeyboardReport {
98 Ok(()) => {} 108 keycodes: [4, 0, 0, 0, 0, 0],
99 Err(e) => warn!("Failed to send report: {:?}", e), 109 leds: 0,
100 }; 110 modifier: 0,
111 reserved: 0,
112 };
113 // Send the report.
114 match writer.write_serialize(&report).await {
115 Ok(()) => {}
116 Err(e) => warn!("Failed to send report: {:?}", e),
117 };
118 }
101 signal_pin.wait_for_low().await; 119 signal_pin.wait_for_low().await;
102 info!("LOW DETECTED"); 120 info!("LOW DETECTED");
103 let report = KeyboardReport { 121 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
104 keycodes: [0, 0, 0, 0, 0, 0], 122 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
105 leds: 0, 123 Ok(()) => {}
106 modifier: 0, 124 Err(e) => warn!("Failed to send boot report: {:?}", e),
107 reserved: 0, 125 };
108 }; 126 } else {
109 match writer.write_serialize(&report).await { 127 let report = KeyboardReport {
110 Ok(()) => {} 128 keycodes: [0, 0, 0, 0, 0, 0],
111 Err(e) => warn!("Failed to send report: {:?}", e), 129 leds: 0,
112 }; 130 modifier: 0,
131 reserved: 0,
132 };
133 match writer.write_serialize(&report).await {
134 Ok(()) => {}
135 Err(e) => warn!("Failed to send report: {:?}", e),
136 };
137 }
113 } 138 }
114 }; 139 };
115 140
@@ -135,6 +160,18 @@ impl RequestHandler for MyRequestHandler {
135 OutResponse::Accepted 160 OutResponse::Accepted
136 } 161 }
137 162
163 fn get_protocol(&self) -> HidProtocolMode {
164 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
165 info!("The current HID protocol mode is: {}", protocol);
166 protocol
167 }
168
169 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
170 info!("Switching to HID protocol mode: {}", protocol);
171 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
172 OutResponse::Accepted
173 }
174
138 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 175 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
139 info!("Set idle rate for {:?} to {:?}", id, dur); 176 info!("Set idle rate for {:?} to {:?}", id, dur);
140 } 177 }
diff --git a/examples/stm32c0/src/bin/adc.rs b/examples/stm32c0/src/bin/adc.rs
index 1f54b0b18..ad597b63c 100644
--- a/examples/stm32c0/src/bin/adc.rs
+++ b/examples/stm32c0/src/bin/adc.rs
@@ -3,7 +3,6 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::vals::Scandir;
7use embassy_stm32::adc::{Adc, AdcChannel, AnyAdcChannel, Resolution, SampleTime}; 6use embassy_stm32::adc::{Adc, AdcChannel, AnyAdcChannel, Resolution, SampleTime};
8use embassy_stm32::peripherals::ADC1; 7use embassy_stm32::peripherals::ADC1;
9use embassy_time::Timer; 8use embassy_time::Timer;
@@ -17,7 +16,7 @@ async fn main(_spawner: Spawner) {
17 info!("ADC STM32C0 example."); 16 info!("ADC STM32C0 example.");
18 17
19 // We need to set certain sample time to be able to read temp sensor. 18 // We need to set certain sample time to be able to read temp sensor.
20 let mut adc = Adc::new(p.ADC1, SampleTime::CYCLES12_5, Resolution::BITS12); 19 let mut adc = Adc::new(p.ADC1, Resolution::BITS12);
21 let mut temp = adc.enable_temperature().degrade_adc(); 20 let mut temp = adc.enable_temperature().degrade_adc();
22 let mut vref = adc.enable_vrefint().degrade_adc(); 21 let mut vref = adc.enable_vrefint().degrade_adc();
23 let mut pin0 = p.PA0.degrade_adc(); 22 let mut pin0 = p.PA0.degrade_adc();
@@ -27,16 +26,20 @@ async fn main(_spawner: Spawner) {
27 26
28 loop { 27 loop {
29 info!("============================"); 28 info!("============================");
30 let blocking_temp = adc.blocking_read(&mut temp); 29 let blocking_temp = adc.blocking_read(&mut temp, SampleTime::CYCLES12_5);
31 let blocking_vref = adc.blocking_read(&mut vref); 30 let blocking_vref = adc.blocking_read(&mut vref, SampleTime::CYCLES12_5);
32 let blocing_pin0 = adc.blocking_read(&mut pin0); 31 let blocing_pin0 = adc.blocking_read(&mut pin0, SampleTime::CYCLES12_5);
33 info!( 32 info!(
34 "Blocking ADC read: vref = {}, temp = {}, pin0 = {}.", 33 "Blocking ADC read: vref = {}, temp = {}, pin0 = {}.",
35 blocking_vref, blocking_temp, blocing_pin0 34 blocking_vref, blocking_temp, blocing_pin0
36 ); 35 );
37 36
38 let channels_seqence: [&mut AnyAdcChannel<ADC1>; 3] = [&mut vref, &mut temp, &mut pin0]; 37 let channels_sequence: [(&mut AnyAdcChannel<ADC1>, SampleTime); 3] = [
39 adc.read(dma.reborrow(), channels_seqence.into_iter(), &mut read_buffer) 38 (&mut vref, SampleTime::CYCLES12_5),
39 (&mut temp, SampleTime::CYCLES12_5),
40 (&mut pin0, SampleTime::CYCLES12_5),
41 ];
42 adc.read(dma.reborrow(), channels_sequence.into_iter(), &mut read_buffer)
40 .await; 43 .await;
41 // Values are ordered according to hardware ADC channel number! 44 // Values are ordered according to hardware ADC channel number!
42 info!( 45 info!(
@@ -44,15 +47,6 @@ async fn main(_spawner: Spawner) {
44 read_buffer[0], read_buffer[1], read_buffer[2] 47 read_buffer[0], read_buffer[1], read_buffer[2]
45 ); 48 );
46 49
47 let hw_channel_selection: u32 =
48 (1 << temp.get_hw_channel()) + (1 << vref.get_hw_channel()) + (1 << pin0.get_hw_channel());
49 adc.read_in_hw_order(dma.reborrow(), hw_channel_selection, Scandir::UP, &mut read_buffer)
50 .await;
51 info!(
52 "DMA ADC read in hardware order: vref = {}, temp = {}, pin0 = {}.",
53 read_buffer[2], read_buffer[1], read_buffer[0]
54 );
55
56 Timer::after_millis(2000).await; 50 Timer::after_millis(2000).await;
57 } 51 }
58} 52}
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml
index a78873d21..177dd0ac2 100644
--- a/examples/stm32f0/Cargo.toml
+++ b/examples/stm32f0/Cargo.toml
@@ -16,6 +16,7 @@ panic-probe = { version = "1.0.0", features = ["print-defmt"] }
16embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } 16embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
17embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 17embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
18embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 18embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
19embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
19static_cell = "2" 20static_cell = "2"
20portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] } 21portable-atomic = { version = "1.5", features = ["unsafe-assume-single-core"] }
21 22
diff --git a/examples/stm32f0/src/bin/adc-watchdog.rs b/examples/stm32f0/src/bin/adc-watchdog.rs
index ff98aac8e..6879dd10a 100644
--- a/examples/stm32f0/src/bin/adc-watchdog.rs
+++ b/examples/stm32f0/src/bin/adc-watchdog.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{self, Adc, WatchdogChannels}; 6use embassy_stm32::adc::{self, Adc, SampleTime, WatchdogChannels};
7use embassy_stm32::bind_interrupts; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::peripherals::ADC1; 8use embassy_stm32::peripherals::ADC1;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
@@ -23,12 +23,12 @@ async fn main(_spawner: Spawner) {
23 loop { 23 loop {
24 // Wait for pin to go high 24 // Wait for pin to go high
25 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0, 0x07F); 25 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0, 0x07F);
26 let v_high = adc.monitor_watchdog().await; 26 let v_high = adc.monitor_watchdog(SampleTime::CYCLES13_5).await;
27 info!("ADC sample is high {}", v_high); 27 info!("ADC sample is high {}", v_high);
28 28
29 // Wait for pin to go low 29 // Wait for pin to go low
30 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0x01f, 0xFFF); 30 adc.init_watchdog(WatchdogChannels::from_channel(&pin), 0x01f, 0xFFF);
31 let v_low = adc.monitor_watchdog().await; 31 let v_low = adc.monitor_watchdog(SampleTime::CYCLES13_5).await;
32 info!("ADC sample is low {}", v_low); 32 info!("ADC sample is low {}", v_low);
33 } 33 }
34} 34}
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs
index 8825e2687..fafeeffaf 100644
--- a/examples/stm32f0/src/bin/adc.rs
+++ b/examples/stm32f0/src/bin/adc.rs
@@ -19,11 +19,10 @@ async fn main(_spawner: Spawner) {
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC1, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES71_5);
23 let mut pin = p.PA1; 22 let mut pin = p.PA1;
24 23
25 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
26 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES13_5).await;
27 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
28 // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32f031c6.pdf
29 // 6.3.4 Embedded reference voltage 28 // 6.3.4 Embedded reference voltage
@@ -33,7 +32,7 @@ async fn main(_spawner: Spawner) {
33 }; 32 };
34 33
35 loop { 34 loop {
36 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES13_5).await;
37 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
38 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
39 } 38 }
diff --git a/examples/stm32f0/src/bin/i2c_master.rs b/examples/stm32f0/src/bin/i2c_master.rs
new file mode 100644
index 000000000..2e61ecdf7
--- /dev/null
+++ b/examples/stm32f0/src/bin/i2c_master.rs
@@ -0,0 +1,609 @@
1#![no_std]
2#![no_main]
3
4// Hardware Setup for NUCLEO-F072RB:
5// - I2C1 pins: PB8 (SCL), PB9 (SDA) on CN5 connector
6// - Connect to I2C slave device (e.g., Digilent Analog Discovery I2C slave, or EEPROM)
7// - Default slave address: 0x50
8// - Pull-up resistors: 4.7kΩ on both SCL and SDA
9// - CN5 Pin 10 (PB8/SCL) and CN5 Pin 9 (PB9/SDA)
10//
11// Analog Discovery - Waveforms Setup:
12// - Increase buffer size: Settings -> Device Manager -> Option 4
13// - Run Protocol Analyzer
14// - Configure as I2C Slave at address 0x50
15// - Connect and configure DIO pins for SCL and SDA
16// - Frequency: 100kHz - [✓] Clock Stretching
17
18use defmt::*;
19use embassy_executor::Spawner;
20use embassy_stm32::i2c::{Config, I2c, Master};
21use embassy_stm32::mode::{Async, Blocking};
22use embassy_stm32::time::Hertz;
23use embassy_stm32::{bind_interrupts, i2c, peripherals};
24use embassy_time::Timer;
25use embedded_hal_1::i2c::Operation;
26use {defmt_rtt as _, panic_probe as _};
27
28bind_interrupts!(struct Irqs {
29 I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>;
30});
31
32#[embassy_executor::main]
33async fn main(_spawner: Spawner) {
34 let p = embassy_stm32::init(Default::default());
35 info!("Run stm32 I2C v2 Master Tests...");
36
37 let mut i2c_peri = p.I2C1;
38 let mut scl = p.PB8;
39 let mut sda = p.PB9;
40
41 let mut config = Config::default();
42 config.frequency = Hertz(100_000);
43
44 // I2C slave address for Analog Discovery or test EEPROM
45 let slave_addr = 0x50u8;
46
47 // Wait for slave device to be ready
48 Timer::after_millis(100).await;
49
50 // ========== BLOCKING DIRECT API TESTS ==========
51 info!("========== BLOCKING DIRECT API TESTS ==========");
52 {
53 let mut i2c = I2c::new_blocking(i2c_peri.reborrow(), scl.reborrow(), sda.reborrow(), config);
54
55 info!("=== Test 1: Direct blocking_write ===");
56 test_blocking_write(&mut i2c, slave_addr);
57
58 info!("=== Test 2: Direct blocking_read ===");
59 test_blocking_read(&mut i2c, slave_addr);
60
61 info!("=== Test 3: Direct blocking_write_read ===");
62 test_blocking_write_read(&mut i2c, slave_addr);
63
64 info!("=== Test 4: Direct blocking_write_vectored ===");
65 test_blocking_write_vectored(&mut i2c, slave_addr);
66
67 info!("=== Test 5: Large buffer (>255 bytes) ===");
68 test_blocking_large_buffer(&mut i2c, slave_addr);
69
70 info!("Blocking direct API tests OK");
71 }
72
73 Timer::after_millis(100).await;
74
75 // ========== BLOCKING TRANSACTION TESTS ==========
76 info!("========== BLOCKING TRANSACTION TESTS ==========");
77 {
78 let mut i2c = I2c::new_blocking(i2c_peri.reborrow(), scl.reborrow(), sda.reborrow(), config);
79
80 info!("=== Test 6: Consecutive Writes (Should Merge) ===");
81 test_consecutive_writes_blocking(&mut i2c, slave_addr);
82
83 info!("=== Test 7: Consecutive Reads (Should Merge) ===");
84 test_consecutive_reads_blocking(&mut i2c, slave_addr);
85
86 info!("=== Test 8: Write then Read (RESTART) ===");
87 test_write_then_read_blocking(&mut i2c, slave_addr);
88
89 info!("=== Test 9: Read then Write (RESTART) ===");
90 test_read_then_write_blocking(&mut i2c, slave_addr);
91
92 info!("=== Test 10: Complex Mixed Sequence ===");
93 test_mixed_sequence_blocking(&mut i2c, slave_addr);
94
95 info!("=== Test 11: Single Operations ===");
96 test_single_operations_blocking(&mut i2c, slave_addr);
97
98 info!("Blocking transaction tests OK");
99 }
100
101 Timer::after_millis(100).await;
102
103 // ========== ASYNC TESTS (DMA) ==========
104 info!("========== ASYNC TESTS (DMA) ==========");
105 {
106 let tx_dma = p.DMA1_CH2;
107 let rx_dma = p.DMA1_CH3;
108
109 let mut i2c = I2c::new(i2c_peri, scl, sda, Irqs, tx_dma, rx_dma, config);
110
111 // Direct API tests (reusing same I2C instance)
112 info!("=== Direct API Test 1: write() ===");
113 test_async_write(&mut i2c, slave_addr).await;
114
115 info!("=== Direct API Test 2: read() ===");
116 test_async_read(&mut i2c, slave_addr).await;
117
118 info!("=== Direct API Test 3: write_read() ===");
119 test_async_write_read(&mut i2c, slave_addr).await;
120
121 info!("=== Direct API Test 4: write_vectored() ===");
122 test_async_write_vectored(&mut i2c, slave_addr).await;
123
124 info!("=== Direct API Test 5: Large buffer (>255 bytes) ===");
125 test_async_large_buffer(&mut i2c, slave_addr).await;
126
127 info!("Async Direct API tests OK");
128
129 // Transaction tests
130 info!("=== Transaction Test 6: Consecutive Writes (Should Merge) ===");
131 test_consecutive_writes_async(&mut i2c, slave_addr).await;
132
133 info!("=== Transaction Test 7: Consecutive Reads (Should Merge) ===");
134 test_consecutive_reads_async(&mut i2c, slave_addr).await;
135
136 info!("=== Transaction Test 8: Write then Read (RESTART) ===");
137 test_write_then_read_async(&mut i2c, slave_addr).await;
138
139 info!("=== Transaction Test 9: Read then Write (RESTART) ===");
140 test_read_then_write_async(&mut i2c, slave_addr).await;
141
142 info!("=== Transaction Test 10: Complex Mixed Sequence ===");
143 test_mixed_sequence_async(&mut i2c, slave_addr).await;
144
145 info!("=== Transaction Test 11: Single Operations ===");
146 test_single_operations_async(&mut i2c, slave_addr).await;
147
148 info!("Async transaction tests OK");
149 }
150
151 info!("All tests OK");
152 cortex_m::asm::bkpt();
153}
154
155// ==================== BLOCKING DIRECT API TEST FUNCTIONS ====================
156
157fn test_blocking_write(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
158 let write_data = [0x42, 0x43, 0x44, 0x45];
159
160 match i2c.blocking_write(addr, &write_data) {
161 Ok(_) => info!("✓ blocking_write succeeded: {:02x}", write_data),
162 Err(e) => {
163 error!("✗ blocking_write failed: {:?}", e);
164 defmt::panic!("Test failed: blocking_write");
165 }
166 }
167}
168
169fn test_blocking_read(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
170 let mut read_buf = [0u8; 8];
171
172 match i2c.blocking_read(addr, &mut read_buf) {
173 Ok(_) => info!("✓ blocking_read succeeded: {:02x}", read_buf),
174 Err(e) => {
175 error!("✗ blocking_read failed: {:?}", e);
176 defmt::panic!("Test failed: blocking_read");
177 }
178 }
179}
180
181fn test_blocking_write_read(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
182 let write_data = [0x50, 0x51];
183 let mut read_buf = [0u8; 6];
184
185 match i2c.blocking_write_read(addr, &write_data, &mut read_buf) {
186 Ok(_) => {
187 info!("✓ blocking_write_read succeeded");
188 info!(" Written: {:02x}", write_data);
189 info!(" Read: {:02x}", read_buf);
190 }
191 Err(e) => {
192 error!("✗ blocking_write_read failed: {:?}", e);
193 defmt::panic!("Test failed: blocking_write_read");
194 }
195 }
196}
197
198fn test_blocking_write_vectored(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
199 let buf1 = [0x60, 0x61, 0x62];
200 let buf2 = [0x70, 0x71];
201 let buf3 = [0x80, 0x81, 0x82, 0x83];
202 let bufs = [&buf1[..], &buf2[..], &buf3[..]];
203
204 match i2c.blocking_write_vectored(addr, &bufs) {
205 Ok(_) => info!("✓ blocking_write_vectored succeeded (9 bytes total)"),
206 Err(e) => {
207 error!("✗ blocking_write_vectored failed: {:?}", e);
208 defmt::panic!("Test failed: blocking_write_vectored");
209 }
210 }
211}
212
213fn test_blocking_large_buffer(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
214 // Test with 300 bytes to verify RELOAD mechanism works (needs chunking at 255 bytes)
215 let mut write_buf = [0u8; 300];
216 for (i, byte) in write_buf.iter_mut().enumerate() {
217 *byte = (i & 0xFF) as u8;
218 }
219
220 match i2c.blocking_write(addr, &write_buf) {
221 Ok(_) => info!("✓ Large buffer write succeeded (300 bytes, tests RELOAD)"),
222 Err(e) => {
223 error!("✗ Large buffer write failed: {:?}", e);
224 defmt::panic!("Test failed: large buffer write");
225 }
226 }
227
228 // Test large read
229 let mut read_buf = [0u8; 300];
230 match i2c.blocking_read(addr, &mut read_buf) {
231 Ok(_) => info!("✓ Large buffer read succeeded (300 bytes, tests RELOAD)"),
232 Err(e) => {
233 error!("✗ Large buffer read failed: {:?}", e);
234 defmt::panic!("Test failed: large buffer read");
235 }
236 }
237}
238
239// ==================== BLOCKING TRANSACTION TEST FUNCTIONS ====================
240
241fn test_consecutive_writes_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
242 // Expected on bus: START, ADDR+W, data1, data2, data3, STOP
243 // NO intermediate RESTART/STOP between writes - they should be merged
244 let data1 = [0x10, 0x11, 0x12];
245 let data2 = [0x20, 0x21];
246 let data3 = [0x30, 0x31, 0x32, 0x33];
247
248 let mut ops = [
249 Operation::Write(&data1),
250 Operation::Write(&data2),
251 Operation::Write(&data3),
252 ];
253
254 match i2c.blocking_transaction(addr, &mut ops) {
255 Ok(_) => info!("✓ Consecutive writes succeeded (merged 9 bytes)"),
256 Err(e) => {
257 error!("✗ Consecutive writes failed: {:?}", e);
258 defmt::panic!("Test failed: consecutive writes");
259 }
260 }
261}
262
263fn test_consecutive_reads_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
264 // Expected on bus: START, ADDR+R, data1, data2, data3, NACK, STOP
265 // NO intermediate RESTART/STOP between reads - they should be merged
266 let mut buf1 = [0u8; 4];
267 let mut buf2 = [0u8; 3];
268 let mut buf3 = [0u8; 2];
269
270 let mut ops = [
271 Operation::Read(&mut buf1),
272 Operation::Read(&mut buf2),
273 Operation::Read(&mut buf3),
274 ];
275
276 match i2c.blocking_transaction(addr, &mut ops) {
277 Ok(_) => {
278 info!("✓ Consecutive reads succeeded (merged 9 bytes)");
279 info!(" buf1: {:02x}", buf1);
280 info!(" buf2: {:02x}", buf2);
281 info!(" buf3: {:02x}", buf3);
282 }
283 Err(e) => {
284 error!("✗ Consecutive reads failed: {:?}", e);
285 defmt::panic!("Test failed: consecutive reads");
286 }
287 }
288}
289
290fn test_write_then_read_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
291 // Expected: START, ADDR+W, data, RESTART, ADDR+R, data, NACK, STOP
292 let write_data = [0xAA, 0xBB];
293 let mut read_buf = [0u8; 4];
294
295 let mut ops = [Operation::Write(&write_data), Operation::Read(&mut read_buf)];
296
297 match i2c.blocking_transaction(addr, &mut ops) {
298 Ok(_) => {
299 info!("✓ Write-then-read succeeded with RESTART");
300 info!(" Written: {:02x}", write_data);
301 info!(" Read: {:02x}", read_buf);
302 }
303 Err(e) => {
304 error!("✗ Write-then-read failed: {:?}", e);
305 defmt::panic!("Test failed: write-then-read");
306 }
307 }
308}
309
310fn test_read_then_write_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
311 // Expected: START, ADDR+R, data, NACK, RESTART, ADDR+W, data, STOP
312 let mut read_buf = [0u8; 3];
313 let write_data = [0xCC, 0xDD, 0xEE];
314
315 let mut ops = [Operation::Read(&mut read_buf), Operation::Write(&write_data)];
316
317 match i2c.blocking_transaction(addr, &mut ops) {
318 Ok(_) => {
319 info!("✓ Read-then-write succeeded with RESTART");
320 info!(" Read: {:02x}", read_buf);
321 info!(" Written: {:02x}", write_data);
322 }
323 Err(e) => {
324 error!("✗ Read-then-write failed: {:?}", e);
325 defmt::panic!("Test failed: read-then-write");
326 }
327 }
328}
329
330fn test_mixed_sequence_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
331 // Complex: W, W, R, R, W, R
332 // Groups: [W,W] RESTART [R,R] RESTART [W] RESTART [R]
333 let w1 = [0x01, 0x02];
334 let w2 = [0x03, 0x04];
335 let mut r1 = [0u8; 2];
336 let mut r2 = [0u8; 2];
337 let w3 = [0x05];
338 let mut r3 = [0u8; 1];
339
340 let mut ops = [
341 Operation::Write(&w1),
342 Operation::Write(&w2),
343 Operation::Read(&mut r1),
344 Operation::Read(&mut r2),
345 Operation::Write(&w3),
346 Operation::Read(&mut r3),
347 ];
348
349 match i2c.blocking_transaction(addr, &mut ops) {
350 Ok(_) => {
351 info!("✓ Mixed sequence succeeded");
352 info!(" Groups: [W4] RESTART [R4] RESTART [W1] RESTART [R1]");
353 }
354 Err(e) => {
355 error!("✗ Mixed sequence failed: {:?}", e);
356 defmt::panic!("Test failed: mixed sequence");
357 }
358 }
359}
360
361fn test_single_operations_blocking(i2c: &mut I2c<'_, Blocking, Master>, addr: u8) {
362 // Test single write
363 let write_data = [0xFF];
364 let mut ops = [Operation::Write(&write_data)];
365
366 match i2c.blocking_transaction(addr, &mut ops) {
367 Ok(_) => info!("✓ Single write succeeded"),
368 Err(e) => {
369 error!("✗ Single write failed: {:?}", e);
370 defmt::panic!("Test failed: single write");
371 }
372 }
373
374 // Test single read
375 let mut read_buf = [0u8; 1];
376 let mut ops = [Operation::Read(&mut read_buf)];
377
378 match i2c.blocking_transaction(addr, &mut ops) {
379 Ok(_) => info!("✓ Single read succeeded, data: 0x{:02x}", read_buf[0]),
380 Err(e) => {
381 error!("✗ Single read failed: {:?}", e);
382 defmt::panic!("Test failed: single read");
383 }
384 }
385}
386
387// ==================== ASYNC DIRECT API TEST FUNCTIONS ====================
388
389async fn test_async_write(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
390 let write_data = [0x42, 0x43, 0x44, 0x45];
391
392 match i2c.write(addr, &write_data).await {
393 Ok(_) => info!("✓ async write succeeded: {:02x}", write_data),
394 Err(e) => {
395 error!("✗ async write failed: {:?}", e);
396 defmt::panic!("Test failed: async write");
397 }
398 }
399}
400
401async fn test_async_read(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
402 let mut read_buf = [0u8; 8];
403
404 match i2c.read(addr, &mut read_buf).await {
405 Ok(_) => info!("✓ async read succeeded: {:02x}", read_buf),
406 Err(e) => {
407 error!("✗ async read failed: {:?}", e);
408 defmt::panic!("Test failed: async read");
409 }
410 }
411}
412
413async fn test_async_write_read(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
414 let write_data = [0x50, 0x51];
415 let mut read_buf = [0u8; 6];
416
417 match i2c.write_read(addr, &write_data, &mut read_buf).await {
418 Ok(_) => {
419 info!("✓ async write_read succeeded");
420 info!(" Written: {:02x}", write_data);
421 info!(" Read: {:02x}", read_buf);
422 }
423 Err(e) => {
424 error!("✗ async write_read failed: {:?}", e);
425 defmt::panic!("Test failed: async write_read");
426 }
427 }
428}
429
430async fn test_async_write_vectored(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
431 let buf1 = [0x60, 0x61, 0x62];
432 let buf2 = [0x70, 0x71];
433 let buf3 = [0x80, 0x81, 0x82, 0x83];
434 let bufs = [&buf1[..], &buf2[..], &buf3[..]];
435
436 match i2c.write_vectored(addr.into(), &bufs).await {
437 Ok(_) => info!("✓ async write_vectored succeeded (9 bytes total)"),
438 Err(e) => {
439 error!("✗ async write_vectored failed: {:?}", e);
440 defmt::panic!("Test failed: async write_vectored");
441 }
442 }
443}
444
445async fn test_async_large_buffer(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
446 // Test with 300 bytes to verify RELOAD mechanism works with DMA (needs chunking at 255 bytes)
447 let mut write_buf = [0u8; 300];
448 for (i, byte) in write_buf.iter_mut().enumerate() {
449 *byte = (i & 0xFF) as u8;
450 }
451
452 match i2c.write(addr, &write_buf).await {
453 Ok(_) => info!("✓ Large buffer async write succeeded (300 bytes, tests RELOAD with DMA)"),
454 Err(e) => {
455 error!("✗ Large buffer async write failed: {:?}", e);
456 defmt::panic!("Test failed: large buffer async write");
457 }
458 }
459
460 // Test large read
461 let mut read_buf = [0u8; 300];
462 match i2c.read(addr, &mut read_buf).await {
463 Ok(_) => info!("✓ Large buffer async read succeeded (300 bytes, tests RELOAD with DMA)"),
464 Err(e) => {
465 error!("✗ Large buffer async read failed: {:?}", e);
466 defmt::panic!("Test failed: large buffer async read");
467 }
468 }
469}
470
471// ==================== ASYNC TRANSACTION TEST FUNCTIONS ====================
472
473async fn test_consecutive_writes_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
474 let data1 = [0x10, 0x11, 0x12];
475 let data2 = [0x20, 0x21];
476 let data3 = [0x30, 0x31, 0x32, 0x33];
477
478 let mut ops = [
479 Operation::Write(&data1),
480 Operation::Write(&data2),
481 Operation::Write(&data3),
482 ];
483
484 match i2c.transaction(addr, &mut ops).await {
485 Ok(_) => info!("✓ Consecutive writes succeeded (merged 9 bytes)"),
486 Err(e) => {
487 error!("✗ Consecutive writes failed: {:?}", e);
488 defmt::panic!("Test failed: consecutive writes");
489 }
490 }
491}
492
493async fn test_consecutive_reads_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
494 let mut buf1 = [0u8; 4];
495 let mut buf2 = [0u8; 3];
496 let mut buf3 = [0u8; 2];
497
498 let mut ops = [
499 Operation::Read(&mut buf1),
500 Operation::Read(&mut buf2),
501 Operation::Read(&mut buf3),
502 ];
503
504 match i2c.transaction(addr, &mut ops).await {
505 Ok(_) => {
506 info!("✓ Consecutive reads succeeded (merged 9 bytes)");
507 info!(" buf1: {:02x}", buf1);
508 info!(" buf2: {:02x}", buf2);
509 info!(" buf3: {:02x}", buf3);
510 }
511 Err(e) => {
512 error!("✗ Consecutive reads failed: {:?}", e);
513 defmt::panic!("Test failed: consecutive reads");
514 }
515 }
516}
517
518async fn test_write_then_read_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
519 let write_data = [0xAA, 0xBB];
520 let mut read_buf = [0u8; 4];
521
522 let mut ops = [Operation::Write(&write_data), Operation::Read(&mut read_buf)];
523
524 match i2c.transaction(addr, &mut ops).await {
525 Ok(_) => {
526 info!("✓ Write-then-read succeeded with RESTART");
527 info!(" Written: {:02x}", write_data);
528 info!(" Read: {:02x}", read_buf);
529 }
530 Err(e) => {
531 error!("✗ Write-then-read failed: {:?}", e);
532 defmt::panic!("Test failed: write-then-read");
533 }
534 }
535}
536
537async fn test_read_then_write_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
538 let mut read_buf = [0u8; 3];
539 let write_data = [0xCC, 0xDD, 0xEE];
540
541 let mut ops = [Operation::Read(&mut read_buf), Operation::Write(&write_data)];
542
543 match i2c.transaction(addr, &mut ops).await {
544 Ok(_) => {
545 info!("✓ Read-then-write succeeded with RESTART");
546 info!(" Read: {:02x}", read_buf);
547 info!(" Written: {:02x}", write_data);
548 }
549 Err(e) => {
550 error!("✗ Read-then-write failed: {:?}", e);
551 defmt::panic!("Test failed: read-then-write");
552 }
553 }
554}
555
556async fn test_mixed_sequence_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
557 let w1 = [0x01, 0x02];
558 let w2 = [0x03, 0x04];
559 let mut r1 = [0u8; 2];
560 let mut r2 = [0u8; 2];
561 let w3 = [0x05];
562 let mut r3 = [0u8; 1];
563
564 let mut ops = [
565 Operation::Write(&w1),
566 Operation::Write(&w2),
567 Operation::Read(&mut r1),
568 Operation::Read(&mut r2),
569 Operation::Write(&w3),
570 Operation::Read(&mut r3),
571 ];
572
573 match i2c.transaction(addr, &mut ops).await {
574 Ok(_) => {
575 info!("✓ Mixed sequence succeeded");
576 info!(" Groups: [W4] RESTART [R4] RESTART [W1] RESTART [R1]");
577 }
578 Err(e) => {
579 error!("✗ Mixed sequence failed: {:?}", e);
580 defmt::panic!("Test failed: mixed sequence");
581 }
582 }
583}
584
585async fn test_single_operations_async(i2c: &mut I2c<'_, Async, Master>, addr: u8) {
586 // Test single write
587 let write_data = [0xFF];
588 let mut ops = [Operation::Write(&write_data)];
589
590 match i2c.transaction(addr, &mut ops).await {
591 Ok(_) => info!("✓ Single write succeeded"),
592 Err(e) => {
593 error!("✗ Single write failed: {:?}", e);
594 defmt::panic!("Test failed: single write");
595 }
596 }
597
598 // Test single read
599 let mut read_buf = [0u8; 1];
600 let mut ops = [Operation::Read(&mut read_buf)];
601
602 match i2c.transaction(addr, &mut ops).await {
603 Ok(_) => info!("✓ Single read succeeded, data: 0x{:02x}", read_buf[0]),
604 Err(e) => {
605 error!("✗ Single read failed: {:?}", e);
606 defmt::panic!("Test failed: single read");
607 }
608 }
609}
diff --git a/examples/stm32f1/src/bin/adc.rs b/examples/stm32f1/src/bin/adc.rs
index 541ff159e..2451aee3d 100644
--- a/examples/stm32f1/src/bin/adc.rs
+++ b/examples/stm32f1/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::Adc; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::peripherals::ADC1; 7use embassy_stm32::peripherals::ADC1;
8use embassy_stm32::{adc, bind_interrupts}; 8use embassy_stm32::{adc, bind_interrupts};
9use embassy_time::Timer; 9use embassy_time::Timer;
@@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) {
22 let mut pin = p.PB1; 22 let mut pin = p.PB1;
23 23
24 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
25 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES13_5).await;
26 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
27 // From http://www.st.com/resource/en/datasheet/CD00161566.pdf 27 // From http://www.st.com/resource/en/datasheet/CD00161566.pdf
28 // 5.3.4 Embedded reference voltage 28 // 5.3.4 Embedded reference voltage
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
32 }; 32 };
33 33
34 loop { 34 loop {
35 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES13_5).await;
36 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
37 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
38 } 38 }
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs
index a993b00ca..486f160ec 100644
--- a/examples/stm32f334/src/bin/adc.rs
+++ b/examples/stm32f334/src/bin/adc.rs
@@ -40,24 +40,22 @@ async fn main(_spawner: Spawner) -> ! {
40 40
41 let mut adc = Adc::new(p.ADC1, Irqs); 41 let mut adc = Adc::new(p.ADC1, Irqs);
42 42
43 adc.set_sample_time(SampleTime::CYCLES601_5);
44
45 info!("enable vrefint..."); 43 info!("enable vrefint...");
46 44
47 let mut vrefint = adc.enable_vref(); 45 let mut vrefint = adc.enable_vref();
48 let mut temperature = adc.enable_temperature(); 46 let mut temperature = adc.enable_temperature();
49 47
50 loop { 48 loop {
51 let vref = adc.read(&mut vrefint).await; 49 let vref = adc.read(&mut vrefint, SampleTime::CYCLES601_5).await;
52 info!("read vref: {} (should be {})", vref, vrefint.value()); 50 info!("read vref: {} (should be {})", vref, vrefint.calibrated_value());
53 51
54 let temp = adc.read(&mut temperature).await; 52 let temp = adc.read(&mut temperature, SampleTime::CYCLES601_5).await;
55 info!("read temperature: {}", temp); 53 info!("read temperature: {}", temp);
56 54
57 let pin = adc.read(&mut p.PA0).await; 55 let pin = adc.read(&mut p.PA0, SampleTime::CYCLES601_5).await;
58 info!("read pin: {}", pin); 56 info!("read pin: {}", pin);
59 57
60 let pin_mv = (pin as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; 58 let pin_mv = (pin as u32 * vrefint.calibrated_value() as u32 / vref as u32) * 3300 / 4095;
61 info!("computed pin mv: {}", pin_mv); 59 info!("computed pin mv: {}", pin_mv);
62 60
63 Timer::after_millis(500).await; 61 Timer::after_millis(500).await;
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs
index 3e621f2a1..9555fd35d 100644
--- a/examples/stm32f334/src/bin/opamp.rs
+++ b/examples/stm32f334/src/bin/opamp.rs
@@ -42,8 +42,6 @@ async fn main(_spawner: Spawner) -> ! {
42 let mut adc = Adc::new(p.ADC2, Irqs); 42 let mut adc = Adc::new(p.ADC2, Irqs);
43 let mut opamp = OpAmp::new(p.OPAMP2); 43 let mut opamp = OpAmp::new(p.OPAMP2);
44 44
45 adc.set_sample_time(SampleTime::CYCLES601_5);
46
47 info!("enable vrefint..."); 45 info!("enable vrefint...");
48 46
49 let mut vrefint = adc.enable_vref(); 47 let mut vrefint = adc.enable_vref();
@@ -51,16 +49,16 @@ async fn main(_spawner: Spawner) -> ! {
51 let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow()); 49 let mut buffer = opamp.buffer_ext(p.PA7.reborrow(), p.PA6.reborrow());
52 50
53 loop { 51 loop {
54 let vref = adc.read(&mut vrefint).await; 52 let vref = adc.read(&mut vrefint, SampleTime::CYCLES601_5).await;
55 info!("read vref: {} (should be {})", vref, vrefint.value()); 53 info!("read vref: {} (should be {})", vref, vrefint.calibrated_value());
56 54
57 let temp = adc.read(&mut temperature).await; 55 let temp = adc.read(&mut temperature, SampleTime::CYCLES601_5).await;
58 info!("read temperature: {}", temp); 56 info!("read temperature: {}", temp);
59 57
60 let buffer = adc.read(&mut buffer).await; 58 let buffer = adc.read(&mut buffer, SampleTime::CYCLES601_5).await;
61 info!("read buffer: {}", buffer); 59 info!("read buffer: {}", buffer);
62 60
63 let pin_mv = (buffer as u32 * vrefint.value() as u32 / vref as u32) * 3300 / 4095; 61 let pin_mv = (buffer as u32 * vrefint.calibrated_value() as u32 / vref as u32) * 3300 / 4095;
64 info!("computed pin mv: {}", pin_mv); 62 info!("computed pin mv: {}", pin_mv);
65 63
66 Timer::after_millis(500).await; 64 Timer::after_millis(500).await;
diff --git a/examples/stm32f4/src/bin/adc.rs b/examples/stm32f4/src/bin/adc.rs
index 423d29225..694e85657 100644
--- a/examples/stm32f4/src/bin/adc.rs
+++ b/examples/stm32f4/src/bin/adc.rs
@@ -4,7 +4,7 @@
4use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs; 4use cortex_m::prelude::_embedded_hal_blocking_delay_DelayUs;
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::adc::{Adc, Temperature, VrefInt}; 7use embassy_stm32::adc::{Adc, SampleTime, Temperature, VrefInt};
8use embassy_time::{Delay, Timer}; 8use embassy_time::{Delay, Timer};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
@@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) {
14 info!("Hello World!"); 14 info!("Hello World!");
15 15
16 let mut delay = Delay; 16 let mut delay = Delay;
17 let mut adc = Adc::new(p.ADC1); 17 let mut adc = Adc::new_with_config(p.ADC1, Default::default());
18 let mut pin = p.PC1; 18 let mut pin = p.PC1;
19 19
20 let mut vrefint = adc.enable_vrefint(); 20 let mut vrefint = adc.enable_vrefint();
@@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) {
23 // Startup delay can be combined to the maximum of either 23 // Startup delay can be combined to the maximum of either
24 delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us())); 24 delay.delay_us(Temperature::start_time_us().max(VrefInt::start_time_us()));
25 25
26 let vrefint_sample = adc.blocking_read(&mut vrefint); 26 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
27 27
28 let convert_to_millivolts = |sample| { 28 let convert_to_millivolts = |sample| {
29 // From http://www.st.com/resource/en/datasheet/DM00071990.pdf 29 // From http://www.st.com/resource/en/datasheet/DM00071990.pdf
@@ -50,16 +50,16 @@ async fn main(_spawner: Spawner) {
50 50
51 loop { 51 loop {
52 // Read pin 52 // Read pin
53 let v = adc.blocking_read(&mut pin); 53 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES112);
54 info!("PC1: {} ({} mV)", v, convert_to_millivolts(v)); 54 info!("PC1: {} ({} mV)", v, convert_to_millivolts(v));
55 55
56 // Read internal temperature 56 // Read internal temperature
57 let v = adc.blocking_read(&mut temp); 57 let v = adc.blocking_read(&mut temp, SampleTime::CYCLES112);
58 let celcius = convert_to_celcius(v); 58 let celcius = convert_to_celcius(v);
59 info!("Internal temp: {} ({} C)", v, celcius); 59 info!("Internal temp: {} ({} C)", v, celcius);
60 60
61 // Read internal voltage reference 61 // Read internal voltage reference
62 let v = adc.blocking_read(&mut vrefint); 62 let v = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
63 info!("VrefInt: {}", v); 63 info!("VrefInt: {}", v);
64 64
65 Timer::after_millis(100).await; 65 Timer::after_millis(100).await;
diff --git a/examples/stm32f4/src/bin/adc_dma.rs b/examples/stm32f4/src/bin/adc_dma.rs
index f8da91336..d61b1b2eb 100644
--- a/examples/stm32f4/src/bin/adc_dma.rs
+++ b/examples/stm32f4/src/bin/adc_dma.rs
@@ -4,7 +4,7 @@ use cortex_m::singleton;
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::Peripherals; 6use embassy_stm32::Peripherals;
7use embassy_stm32::adc::{Adc, AdcChannel, RingBufferedAdc, SampleTime}; 7use embassy_stm32::adc::{Adc, AdcChannel, RegularConversionMode, RingBufferedAdc, SampleTime};
8use embassy_time::Instant; 8use embassy_time::Instant;
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
@@ -20,26 +20,28 @@ async fn adc_task(p: Peripherals) {
20 let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); 20 let adc_data: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap();
21 let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap(); 21 let adc_data2: &mut [u16; ADC_BUF_SIZE] = singleton!(ADCDAT2 : [u16; ADC_BUF_SIZE] = [0u16; ADC_BUF_SIZE]).unwrap();
22 22
23 let adc = Adc::new(p.ADC1); 23 let adc = Adc::new_with_config(p.ADC1, Default::default());
24 let adc2 = Adc::new(p.ADC2); 24 let adc2 = Adc::new_with_config(p.ADC2, Default::default());
25 25
26 let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered( 26 let mut adc: RingBufferedAdc<embassy_stm32::peripherals::ADC1> = adc.into_ring_buffered(
27 p.DMA2_CH0, 27 p.DMA2_CH0,
28 adc_data, 28 adc_data,
29 [ 29 [
30 (&mut p.PA0.degrade_adc(), SampleTime::CYCLES112), 30 (p.PA0.degrade_adc(), SampleTime::CYCLES112),
31 (&mut p.PA2.degrade_adc(), SampleTime::CYCLES112), 31 (p.PA2.degrade_adc(), SampleTime::CYCLES112),
32 ] 32 ]
33 .into_iter(), 33 .into_iter(),
34 RegularConversionMode::Continuous,
34 ); 35 );
35 let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered( 36 let mut adc2: RingBufferedAdc<embassy_stm32::peripherals::ADC2> = adc2.into_ring_buffered(
36 p.DMA2_CH2, 37 p.DMA2_CH2,
37 adc_data2, 38 adc_data2,
38 [ 39 [
39 (&mut p.PA1.degrade_adc(), SampleTime::CYCLES112), 40 (p.PA1.degrade_adc(), SampleTime::CYCLES112),
40 (&mut p.PA3.degrade_adc(), SampleTime::CYCLES112), 41 (p.PA3.degrade_adc(), SampleTime::CYCLES112),
41 ] 42 ]
42 .into_iter(), 43 .into_iter(),
44 RegularConversionMode::Continuous,
43 ); 45 );
44 46
45 // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around 47 // Note that overrun is a big consideration in this implementation. Whatever task is running the adc.read() calls absolutely must circle back around
diff --git a/examples/stm32f4/src/bin/usb_hid_keyboard.rs b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
index a3afb887c..9971e43f5 100644
--- a/examples/stm32f4/src/bin/usb_hid_keyboard.rs
+++ b/examples/stm32f4/src/bin/usb_hid_keyboard.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
@@ -11,7 +11,9 @@ use embassy_stm32::gpio::Pull;
11use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
12use embassy_stm32::usb::Driver; 12use embassy_stm32::usb::Driver;
13use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; 13use embassy_stm32::{Config, bind_interrupts, peripherals, usb};
14use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; 14use embassy_usb::class::hid::{
15 HidBootProtocol, HidProtocolMode, HidReaderWriter, HidSubclass, ReportId, RequestHandler, State,
16};
15use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
16use embassy_usb::{Builder, Handler}; 18use embassy_usb::{Builder, Handler};
17use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; 19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
@@ -21,6 +23,8 @@ bind_interrupts!(struct Irqs {
21 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; 23 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
22}); 24});
23 25
26static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
27
24// If you are trying this and your USB device doesn't connect, the most 28// If you are trying this and your USB device doesn't connect, the most
25// common issues are the RCC config and vbus_detection 29// common issues are the RCC config and vbus_detection
26// 30//
@@ -70,6 +74,10 @@ async fn main(_spawner: Spawner) {
70 config.serial_number = Some("12345678"); 74 config.serial_number = Some("12345678");
71 config.max_power = 100; 75 config.max_power = 100;
72 config.max_packet_size_0 = 64; 76 config.max_packet_size_0 = 64;
77 config.composite_with_iads = false;
78 config.device_class = 0;
79 config.device_sub_class = 0;
80 config.device_protocol = 0;
73 81
74 // Create embassy-usb DeviceBuilder using the driver and config. 82 // Create embassy-usb DeviceBuilder using the driver and config.
75 // It needs some buffers for building the descriptors. 83 // It needs some buffers for building the descriptors.
@@ -101,6 +109,8 @@ async fn main(_spawner: Spawner) {
101 request_handler: None, 109 request_handler: None,
102 poll_ms: 60, 110 poll_ms: 60,
103 max_packet_size: 8, 111 max_packet_size: 8,
112 hid_subclass: HidSubclass::Boot,
113 hid_boot_protocol: HidBootProtocol::Keyboard,
104 }; 114 };
105 115
106 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); 116 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
@@ -121,32 +131,46 @@ async fn main(_spawner: Spawner) {
121 button.wait_for_rising_edge().await; 131 button.wait_for_rising_edge().await;
122 // signal_pin.wait_for_high().await; 132 // signal_pin.wait_for_high().await;
123 info!("Button pressed!"); 133 info!("Button pressed!");
124 // Create a report with the A key pressed. (no shift modifier) 134 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
125 let report = KeyboardReport { 135 match writer.write(&[0, 0, 4, 0, 0, 0, 0, 0]).await {
126 keycodes: [4, 0, 0, 0, 0, 0], 136 Ok(()) => {}
127 leds: 0, 137 Err(e) => warn!("Failed to send boot report: {:?}", e),
128 modifier: 0, 138 };
129 reserved: 0, 139 } else {
130 }; 140 // Create a report with the A key pressed. (no shift modifier)
131 // Send the report. 141 let report = KeyboardReport {
132 match writer.write_serialize(&report).await { 142 keycodes: [4, 0, 0, 0, 0, 0],
133 Ok(()) => {} 143 leds: 0,
134 Err(e) => warn!("Failed to send report: {:?}", e), 144 modifier: 0,
135 }; 145 reserved: 0,
146 };
147 // Send the report.
148 match writer.write_serialize(&report).await {
149 Ok(()) => {}
150 Err(e) => warn!("Failed to send report: {:?}", e),
151 };
152 }
136 153
137 button.wait_for_falling_edge().await; 154 button.wait_for_falling_edge().await;
138 // signal_pin.wait_for_low().await; 155 // signal_pin.wait_for_low().await;
139 info!("Button released!"); 156 info!("Button released!");
140 let report = KeyboardReport { 157 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
141 keycodes: [0, 0, 0, 0, 0, 0], 158 match writer.write(&[0, 0, 0, 0, 0, 0, 0, 0]).await {
142 leds: 0, 159 Ok(()) => {}
143 modifier: 0, 160 Err(e) => warn!("Failed to send boot report: {:?}", e),
144 reserved: 0, 161 };
145 }; 162 } else {
146 match writer.write_serialize(&report).await { 163 let report = KeyboardReport {
147 Ok(()) => {} 164 keycodes: [0, 0, 0, 0, 0, 0],
148 Err(e) => warn!("Failed to send report: {:?}", e), 165 leds: 0,
149 }; 166 modifier: 0,
167 reserved: 0,
168 };
169 match writer.write_serialize(&report).await {
170 Ok(()) => {}
171 Err(e) => warn!("Failed to send report: {:?}", e),
172 };
173 }
150 } 174 }
151 }; 175 };
152 176
@@ -172,6 +196,18 @@ impl RequestHandler for MyRequestHandler {
172 OutResponse::Accepted 196 OutResponse::Accepted
173 } 197 }
174 198
199 fn get_protocol(&self) -> HidProtocolMode {
200 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
201 info!("The current HID protocol mode is: {}", protocol);
202 protocol
203 }
204
205 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
206 info!("Switching to HID protocol mode: {}", protocol);
207 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
208 OutResponse::Accepted
209 }
210
175 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 211 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
176 info!("Set idle rate for {:?} to {:?}", id, dur); 212 info!("Set idle rate for {:?} to {:?}", id, dur);
177 } 213 }
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs
index 162a035f2..e83d01f88 100644
--- a/examples/stm32f4/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs
@@ -1,6 +1,8 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicU8, Ordering};
5
4use defmt::*; 6use defmt::*;
5use embassy_executor::Spawner; 7use embassy_executor::Spawner;
6use embassy_futures::join::join; 8use embassy_futures::join::join;
@@ -9,7 +11,9 @@ use embassy_stm32::usb::Driver;
9use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; 11use embassy_stm32::{Config, bind_interrupts, peripherals, usb};
10use embassy_time::Timer; 12use embassy_time::Timer;
11use embassy_usb::Builder; 13use embassy_usb::Builder;
12use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; 14use embassy_usb::class::hid::{
15 HidBootProtocol, HidProtocolMode, HidSubclass, HidWriter, ReportId, RequestHandler, State,
16};
13use embassy_usb::control::OutResponse; 17use embassy_usb::control::OutResponse;
14use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 18use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
15use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
@@ -18,6 +22,8 @@ bind_interrupts!(struct Irqs {
18 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>; 22 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
19}); 23});
20 24
25static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
26
21// If you are trying this and your USB device doesn't connect, the most 27// If you are trying this and your USB device doesn't connect, the most
22// common issues are the RCC config and vbus_detection 28// common issues are the RCC config and vbus_detection
23// 29//
@@ -65,6 +71,10 @@ async fn main(_spawner: Spawner) {
65 config.manufacturer = Some("Embassy"); 71 config.manufacturer = Some("Embassy");
66 config.product = Some("HID mouse example"); 72 config.product = Some("HID mouse example");
67 config.serial_number = Some("12345678"); 73 config.serial_number = Some("12345678");
74 config.composite_with_iads = false;
75 config.device_class = 0;
76 config.device_sub_class = 0;
77 config.device_protocol = 0;
68 78
69 // Create embassy-usb DeviceBuilder using the driver and config. 79 // Create embassy-usb DeviceBuilder using the driver and config.
70 // It needs some buffers for building the descriptors. 80 // It needs some buffers for building the descriptors.
@@ -91,6 +101,8 @@ async fn main(_spawner: Spawner) {
91 request_handler: Some(&mut request_handler), 101 request_handler: Some(&mut request_handler),
92 poll_ms: 60, 102 poll_ms: 60,
93 max_packet_size: 8, 103 max_packet_size: 8,
104 hid_subclass: HidSubclass::Boot,
105 hid_boot_protocol: HidBootProtocol::Mouse,
94 }; 106 };
95 107
96 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config); 108 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
@@ -108,16 +120,26 @@ async fn main(_spawner: Spawner) {
108 Timer::after_millis(500).await; 120 Timer::after_millis(500).await;
109 121
110 y = -y; 122 y = -y;
111 let report = MouseReport { 123
112 buttons: 0, 124 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
113 x: 0, 125 let buttons = 0u8;
114 y, 126 let x = 0i8;
115 wheel: 0, 127 match writer.write(&[buttons, x as u8, y as u8]).await {
116 pan: 0, 128 Ok(()) => {}
117 }; 129 Err(e) => warn!("Failed to send boot report: {:?}", e),
118 match writer.write_serialize(&report).await { 130 }
119 Ok(()) => {} 131 } else {
120 Err(e) => warn!("Failed to send report: {:?}", e), 132 let report = MouseReport {
133 buttons: 0,
134 x: 0,
135 y,
136 wheel: 0,
137 pan: 0,
138 };
139 match writer.write_serialize(&report).await {
140 Ok(()) => {}
141 Err(e) => warn!("Failed to send report: {:?}", e),
142 }
121 } 143 }
122 } 144 }
123 }; 145 };
@@ -140,6 +162,18 @@ impl RequestHandler for MyRequestHandler {
140 OutResponse::Accepted 162 OutResponse::Accepted
141 } 163 }
142 164
165 fn get_protocol(&self) -> HidProtocolMode {
166 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
167 info!("The current HID protocol mode is: {}", protocol);
168 protocol
169 }
170
171 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
172 info!("Switching to HID protocol mode: {}", protocol);
173 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
174 OutResponse::Accepted
175 }
176
143 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 177 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
144 info!("Set idle rate for {:?} to {:?}", id, dur); 178 info!("Set idle rate for {:?} to {:?}", id, dur);
145 } 179 }
diff --git a/examples/stm32f469/src/bin/dsi_bsp.rs b/examples/stm32f469/src/bin/dsi_bsp.rs
index d659291ff..7ba4da72b 100644
--- a/examples/stm32f469/src/bin/dsi_bsp.rs
+++ b/examples/stm32f469/src/bin/dsi_bsp.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dsihost::{DsiHost, PacketType, blocking_delay_ms}; 6use embassy_stm32::dsihost::{DsiHost, PacketType};
7use embassy_stm32::gpio::{Level, Output, Speed}; 7use embassy_stm32::gpio::{Level, Output, Speed};
8use embassy_stm32::ltdc::Ltdc; 8use embassy_stm32::ltdc::Ltdc;
9use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1}; 9use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1};
@@ -13,7 +13,7 @@ use embassy_stm32::rcc::{
13 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk, 13 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk,
14}; 14};
15use embassy_stm32::time::mhz; 15use embassy_stm32::time::mhz;
16use embassy_time::Timer; 16use embassy_time::{Duration, Timer, block_for};
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19enum _Orientation { 19enum _Orientation {
@@ -444,7 +444,7 @@ async fn main(_spawner: Spawner) {
444 dsi.enable_wrapper_dsi(); 444 dsi.enable_wrapper_dsi();
445 445
446 // First, delay 120 ms (reason unknown, STM32 Cube Example does it) 446 // First, delay 120 ms (reason unknown, STM32 Cube Example does it)
447 blocking_delay_ms(120); 447 block_for(Duration::from_millis(120));
448 448
449 // 1 to 26 449 // 1 to 26
450 dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap(); 450 dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap();
@@ -480,7 +480,7 @@ async fn main(_spawner: Spawner) {
480 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); 480 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap();
481 481
482 // Add a delay, otherwise MADCTL not taken 482 // Add a delay, otherwise MADCTL not taken
483 blocking_delay_ms(200); 483 block_for(Duration::from_millis(200));
484 484
485 // Configure orientation as landscape 485 // Configure orientation as landscape
486 dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..]) 486 dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..])
@@ -494,7 +494,7 @@ async fn main(_spawner: Spawner) {
494 dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap(); 494 dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap();
495 495
496 // Wait for sleep out exit 496 // Wait for sleep out exit
497 blocking_delay_ms(120); 497 block_for(Duration::from_millis(120));
498 498
499 // Configure COLOR_CODING 499 // Configure COLOR_CODING
500 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); 500 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap();
@@ -590,7 +590,7 @@ async fn main(_spawner: Spawner) {
590 //LTDC->SRCR = LTDC_SRCR_IMR; 590 //LTDC->SRCR = LTDC_SRCR_IMR;
591 LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD)); 591 LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD));
592 592
593 blocking_delay_ms(5000); 593 block_for(Duration::from_millis(5000));
594 594
595 const READ_SIZE: u16 = 1; 595 const READ_SIZE: u16 = 1;
596 let mut data = [1u8; READ_SIZE as usize]; 596 let mut data = [1u8; READ_SIZE as usize];
@@ -606,7 +606,7 @@ async fn main(_spawner: Spawner) {
606 .unwrap(); 606 .unwrap();
607 info!("Display ID3: {:#04x}", data); 607 info!("Display ID3: {:#04x}", data);
608 608
609 blocking_delay_ms(500); 609 block_for(Duration::from_millis(500));
610 610
611 info!("Config done, start blinking LED"); 611 info!("Config done, start blinking LED");
612 loop { 612 loop {
diff --git a/examples/stm32f7/src/bin/adc.rs b/examples/stm32f7/src/bin/adc.rs
index 6689e3b5d..0f226d34e 100644
--- a/examples/stm32f7/src/bin/adc.rs
+++ b/examples/stm32f7/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::Adc; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_time::Timer; 7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) {
16 let mut pin = p.PA3; 16 let mut pin = p.PA3;
17 17
18 let mut vrefint = adc.enable_vrefint(); 18 let mut vrefint = adc.enable_vrefint();
19 let vrefint_sample = adc.blocking_read(&mut vrefint); 19 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES112);
20 let convert_to_millivolts = |sample| { 20 let convert_to_millivolts = |sample| {
21 // From http://www.st.com/resource/en/datasheet/DM00273119.pdf 21 // From http://www.st.com/resource/en/datasheet/DM00273119.pdf
22 // 6.3.27 Reference voltage 22 // 6.3.27 Reference voltage
@@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) {
26 }; 26 };
27 27
28 loop { 28 loop {
29 let v = adc.blocking_read(&mut pin); 29 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES112);
30 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 30 info!("--> {} - {} mV", v, convert_to_millivolts(v));
31 Timer::after_millis(100).await; 31 Timer::after_millis(100).await;
32 } 32 }
diff --git a/examples/stm32g0/src/bin/adc.rs b/examples/stm32g0/src/bin/adc.rs
index 7d8653ef2..972e43b55 100644
--- a/examples/stm32g0/src/bin/adc.rs
+++ b/examples/stm32g0/src/bin/adc.rs
@@ -13,11 +13,10 @@ async fn main(_spawner: Spawner) {
13 info!("Hello World!"); 13 info!("Hello World!");
14 14
15 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 }); 15 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 });
16 adc.set_sample_time(SampleTime::CYCLES79_5);
17 let mut pin = p.PA1; 16 let mut pin = p.PA1;
18 17
19 let mut vrefint = adc.enable_vrefint(); 18 let mut vrefint = adc.enable_vrefint();
20 let vrefint_sample = adc.blocking_read(&mut vrefint); 19 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
21 let convert_to_millivolts = |sample| { 20 let convert_to_millivolts = |sample| {
22 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 21 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
23 // 6.3.3 Embedded internal reference voltage 22 // 6.3.3 Embedded internal reference voltage
@@ -27,7 +26,7 @@ async fn main(_spawner: Spawner) {
27 }; 26 };
28 27
29 loop { 28 loop {
30 let v = adc.blocking_read(&mut pin); 29 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
31 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 30 info!("--> {} - {} mV", v, convert_to_millivolts(v));
32 Timer::after_millis(100).await; 31 Timer::after_millis(100).await;
33 } 32 }
diff --git a/examples/stm32g0/src/bin/adc_oversampling.rs b/examples/stm32g0/src/bin/adc_oversampling.rs
index 834d1cd4a..aa8b1771b 100644
--- a/examples/stm32g0/src/bin/adc_oversampling.rs
+++ b/examples/stm32g0/src/bin/adc_oversampling.rs
@@ -7,7 +7,7 @@
7 7
8use defmt::*; 8use defmt::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::adc::{Adc, Clock, Ovsr, Ovss, Presc, SampleTime}; 10use embassy_stm32::adc::{Adc, AdcConfig, Clock, Ovsr, Ovss, Presc, SampleTime};
11use embassy_time::Timer; 11use embassy_time::Timer;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
@@ -16,16 +16,17 @@ async fn main(_spawner: Spawner) {
16 let p = embassy_stm32::init(Default::default()); 16 let p = embassy_stm32::init(Default::default());
17 info!("Adc oversample test"); 17 info!("Adc oversample test");
18 18
19 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Async { div: Presc::DIV1 }); 19 let mut config = AdcConfig::default();
20 adc.set_sample_time(SampleTime::CYCLES1_5); 20 config.clock = Some(Clock::Async { div: Presc::DIV1 });
21 let mut pin = p.PA1; 21 config.oversampling_ratio = Some(Ovsr::MUL16);
22 config.oversampling_shift = Some(Ovss::NO_SHIFT);
23 config.oversampling_enable = Some(true);
22 24
23 adc.set_oversampling_ratio(Ovsr::MUL16); 25 let mut adc = Adc::new_with_config(p.ADC1, config);
24 adc.set_oversampling_shift(Ovss::NO_SHIFT); 26 let mut pin = p.PA1;
25 adc.oversampling_enable(true);
26 27
27 loop { 28 loop {
28 let v = adc.blocking_read(&mut pin); 29 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES1_5);
29 info!("--> {} ", v); //max 65520 = 0xFFF0 30 info!("--> {} ", v); //max 65520 = 0xFFF0
30 Timer::after_millis(100).await; 31 Timer::after_millis(100).await;
31 } 32 }
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs
index 920142a18..2149e0748 100644
--- a/examples/stm32g4/src/bin/adc.rs
+++ b/examples/stm32g4/src/bin/adc.rs
@@ -28,12 +28,16 @@ async fn main(_spawner: Spawner) {
28 let mut p = embassy_stm32::init(config); 28 let mut p = embassy_stm32::init(config);
29 info!("Hello World!"); 29 info!("Hello World!");
30 30
31 let mut adc = Adc::new(p.ADC2); 31 let mut adc = Adc::new(p.ADC2, Default::default());
32 adc.set_sample_time(SampleTime::CYCLES24_5); 32
33 let mut adc_temp = Adc::new(p.ADC1, Default::default());
34 let mut temperature = adc_temp.enable_temperature();
33 35
34 loop { 36 loop {
35 let measured = adc.blocking_read(&mut p.PA7); 37 let measured = adc.blocking_read(&mut p.PA7, SampleTime::CYCLES24_5);
38 let temperature = adc_temp.blocking_read(&mut temperature, SampleTime::CYCLES24_5);
36 info!("measured: {}", measured); 39 info!("measured: {}", measured);
40 info!("temperature: {}", temperature);
37 Timer::after_millis(500).await; 41 Timer::after_millis(500).await;
38 } 42 }
39} 43}
diff --git a/examples/stm32g4/src/bin/adc_differential.rs b/examples/stm32g4/src/bin/adc_differential.rs
index 301f0da84..6dedf88d6 100644
--- a/examples/stm32g4/src/bin/adc_differential.rs
+++ b/examples/stm32g4/src/bin/adc_differential.rs
@@ -30,17 +30,16 @@ async fn main(_spawner: Spawner) {
30 config.rcc.mux.adc12sel = mux::Adcsel::SYS; 30 config.rcc.mux.adc12sel = mux::Adcsel::SYS;
31 config.rcc.sys = Sysclk::PLL1_R; 31 config.rcc.sys = Sysclk::PLL1_R;
32 } 32 }
33 let mut p = embassy_stm32::init(config); 33 let p = embassy_stm32::init(config);
34 34
35 let mut adc = Adc::new(p.ADC1); 35 let mut adc = Adc::new(p.ADC1, Default::default());
36 adc.set_sample_time(SampleTime::CYCLES247_5); 36 let mut differential_channel = (p.PA0, p.PA1);
37 adc.set_differential(&mut p.PA0, true); //p:pa0,n:pa1
38 37
39 // can also use 38 // can also use
40 // adc.set_differential_channel(1, true); 39 // adc.set_differential_channel(1, true);
41 info!("adc initialized"); 40 info!("adc initialized");
42 loop { 41 loop {
43 let measured = adc.blocking_read(&mut p.PA0); 42 let measured = adc.blocking_read(&mut differential_channel, SampleTime::CYCLES247_5);
44 info!("data: {}", measured); 43 info!("data: {}", measured);
45 Timer::after_millis(500).await; 44 Timer::after_millis(500).await;
46 } 45 }
diff --git a/examples/stm32g4/src/bin/adc_dma.rs b/examples/stm32g4/src/bin/adc_dma.rs
index ef8b0c3c2..478b6b2ca 100644
--- a/examples/stm32g4/src/bin/adc_dma.rs
+++ b/examples/stm32g4/src/bin/adc_dma.rs
@@ -33,7 +33,7 @@ async fn main(_spawner: Spawner) {
33 33
34 info!("Hello World!"); 34 info!("Hello World!");
35 35
36 let mut adc = Adc::new(p.ADC1); 36 let mut adc = Adc::new(p.ADC1, Default::default());
37 37
38 let mut dma = p.DMA1_CH1; 38 let mut dma = p.DMA1_CH1;
39 let mut vrefint_channel = adc.enable_vrefint().degrade_adc(); 39 let mut vrefint_channel = adc.enable_vrefint().degrade_adc();
diff --git a/examples/stm32g4/src/bin/adc_injected_and_regular.rs b/examples/stm32g4/src/bin/adc_injected_and_regular.rs
index 3ae2ff064..1e97fa925 100644
--- a/examples/stm32g4/src/bin/adc_injected_and_regular.rs
+++ b/examples/stm32g4/src/bin/adc_injected_and_regular.rs
@@ -77,7 +77,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
77 pwm.set_mms2(Mms2::UPDATE); 77 pwm.set_mms2(Mms2::UPDATE);
78 78
79 // Configure regular conversions with DMA 79 // Configure regular conversions with DMA
80 let adc1 = Adc::new(p.ADC1); 80 let adc1 = Adc::new(p.ADC1, Default::default());
81 81
82 let vrefint_channel = adc1.enable_vrefint().degrade_adc(); 82 let vrefint_channel = adc1.enable_vrefint().degrade_adc();
83 let pa0 = p.PC1.degrade_adc(); 83 let pa0 = p.PC1.degrade_adc();
diff --git a/examples/stm32g4/src/bin/adc_oversampling.rs b/examples/stm32g4/src/bin/adc_oversampling.rs
index 1e464183a..87ffea4be 100644
--- a/examples/stm32g4/src/bin/adc_oversampling.rs
+++ b/examples/stm32g4/src/bin/adc_oversampling.rs
@@ -9,7 +9,7 @@ use defmt::*;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::Config; 10use embassy_stm32::Config;
11use embassy_stm32::adc::vals::{Rovsm, Trovs}; 11use embassy_stm32::adc::vals::{Rovsm, Trovs};
12use embassy_stm32::adc::{Adc, SampleTime}; 12use embassy_stm32::adc::{Adc, AdcConfig, SampleTime};
13use embassy_time::Timer; 13use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
15 15
@@ -32,8 +32,8 @@ async fn main(_spawner: Spawner) {
32 } 32 }
33 let mut p = embassy_stm32::init(config); 33 let mut p = embassy_stm32::init(config);
34 34
35 let mut adc = Adc::new(p.ADC1); 35 let mut config = AdcConfig::default();
36 adc.set_sample_time(SampleTime::CYCLES6_5); 36
37 // From https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf 37 // From https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
38 // page652 Oversampler 38 // page652 Oversampler
39 // Table 172. Maximum output results vs N and M. Grayed values indicates truncation 39 // Table 172. Maximum output results vs N and M. Grayed values indicates truncation
@@ -45,12 +45,14 @@ async fn main(_spawner: Spawner) {
45 // 0x05 oversampling ratio X64 45 // 0x05 oversampling ratio X64
46 // 0x06 oversampling ratio X128 46 // 0x06 oversampling ratio X128
47 // 0x07 oversampling ratio X256 47 // 0x07 oversampling ratio X256
48 adc.set_oversampling_ratio(0x03); // ratio X3 48 config.oversampling_ratio = Some(0x03); // ratio X3
49 adc.set_oversampling_shift(0b0000); // no shift 49 config.oversampling_shift = Some(0b0000); // no shift
50 adc.enable_regular_oversampling_mode(Rovsm::RESUMED, Trovs::AUTOMATIC, true); 50 config.oversampling_mode = Some((Rovsm::RESUMED, Trovs::AUTOMATIC, true));
51
52 let mut adc = Adc::new(p.ADC1, config);
51 53
52 loop { 54 loop {
53 let measured = adc.blocking_read(&mut p.PA0); 55 let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES6_5);
54 info!("data: 0x{:X}", measured); //max 0xFFF0 -> 65520 56 info!("data: 0x{:X}", measured); //max 0xFFF0 -> 65520
55 Timer::after_millis(500).await; 57 Timer::after_millis(500).await;
56 } 58 }
diff --git a/examples/stm32h5/src/bin/adc.rs b/examples/stm32h5/src/bin/adc.rs
index 0566320d4..c919b1a95 100644
--- a/examples/stm32h5/src/bin/adc.rs
+++ b/examples/stm32h5/src/bin/adc.rs
@@ -45,14 +45,12 @@ async fn main(_spawner: Spawner) {
45 45
46 let mut adc = Adc::new(p.ADC1); 46 let mut adc = Adc::new(p.ADC1);
47 47
48 adc.set_sample_time(SampleTime::CYCLES24_5);
49
50 let mut vrefint_channel = adc.enable_vrefint(); 48 let mut vrefint_channel = adc.enable_vrefint();
51 49
52 loop { 50 loop {
53 let vrefint = adc.blocking_read(&mut vrefint_channel); 51 let vrefint = adc.blocking_read(&mut vrefint_channel, SampleTime::CYCLES24_5);
54 info!("vrefint: {}", vrefint); 52 info!("vrefint: {}", vrefint);
55 let measured = adc.blocking_read(&mut p.PA0); 53 let measured = adc.blocking_read(&mut p.PA0, SampleTime::CYCLES24_5);
56 info!("measured: {}", measured); 54 info!("measured: {}", measured);
57 Timer::after_millis(500).await; 55 Timer::after_millis(500).await;
58 } 56 }
diff --git a/examples/stm32h5/src/bin/adc_dma.rs b/examples/stm32h5/src/bin/adc_dma.rs
index fb9fcbc5c..2138257f7 100644
--- a/examples/stm32h5/src/bin/adc_dma.rs
+++ b/examples/stm32h5/src/bin/adc_dma.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
6use embassy_stm32::adc::{self, Adc, AdcChannel, RxDma, SampleTime}; 6use embassy_stm32::adc::{self, Adc, AdcChannel, RxDma, SampleTime};
7use embassy_stm32::peripherals::{ADC1, ADC2, GPDMA1_CH0, GPDMA1_CH1, PA0, PA1, PA2, PA3}; 7use embassy_stm32::peripherals::{ADC1, ADC2, GPDMA1_CH0, GPDMA1_CH1, PA0, PA1, PA2, PA3};
8use embassy_stm32::{Config, Peri}; 8use embassy_stm32::{Config, Peri};
9use embassy_time::Instant; 9use embassy_time::{Duration, Instant, Ticker};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12#[embassy_executor::main] 12#[embassy_executor::main]
@@ -76,6 +76,9 @@ async fn adc_task<'a, T: adc::Instance>(
76 let mut pin1 = pin1.degrade_adc(); 76 let mut pin1 = pin1.degrade_adc();
77 let mut pin2 = pin2.degrade_adc(); 77 let mut pin2 = pin2.degrade_adc();
78 78
79 info!("adc init");
80
81 let mut ticker = Ticker::every(Duration::from_millis(500));
79 let mut tic = Instant::now(); 82 let mut tic = Instant::now();
80 let mut buffer = [0u16; 512]; 83 let mut buffer = [0u16; 512];
81 loop { 84 loop {
@@ -84,11 +87,13 @@ async fn adc_task<'a, T: adc::Instance>(
84 adc.read( 87 adc.read(
85 dma.reborrow(), 88 dma.reborrow(),
86 [(&mut pin1, SampleTime::CYCLES2_5), (&mut pin2, SampleTime::CYCLES2_5)].into_iter(), 89 [(&mut pin1, SampleTime::CYCLES2_5), (&mut pin2, SampleTime::CYCLES2_5)].into_iter(),
87 &mut buffer, 90 &mut buffer[0..2],
88 ) 91 )
89 .await; 92 .await;
90 let toc = Instant::now(); 93 let toc = Instant::now();
91 info!("\n adc1: {} dt = {}", buffer[0..16], (toc - tic).as_micros()); 94 info!("\n adc1: {} dt = {}", buffer[0..16], (toc - tic).as_micros());
92 tic = toc; 95 tic = toc;
96
97 ticker.next().await;
93 } 98 }
94} 99}
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs
index a53c9d8d5..fc45541bf 100644
--- a/examples/stm32h7/src/bin/adc.rs
+++ b/examples/stm32h7/src/bin/adc.rs
@@ -46,14 +46,12 @@ async fn main(_spawner: Spawner) {
46 46
47 let mut adc = Adc::new(p.ADC3); 47 let mut adc = Adc::new(p.ADC3);
48 48
49 adc.set_sample_time(SampleTime::CYCLES32_5);
50
51 let mut vrefint_channel = adc.enable_vrefint(); 49 let mut vrefint_channel = adc.enable_vrefint();
52 50
53 loop { 51 loop {
54 let vrefint = adc.blocking_read(&mut vrefint_channel); 52 let vrefint = adc.blocking_read(&mut vrefint_channel, SampleTime::CYCLES32_5);
55 info!("vrefint: {}", vrefint); 53 info!("vrefint: {}", vrefint);
56 let measured = adc.blocking_read(&mut p.PC0); 54 let measured = adc.blocking_read(&mut p.PC0, SampleTime::CYCLES32_5);
57 info!("measured: {}", measured); 55 info!("measured: {}", measured);
58 Timer::after_millis(500).await; 56 Timer::after_millis(500).await;
59 } 57 }
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs
index 9dd09bc45..83be74ed9 100644
--- a/examples/stm32l0/src/bin/adc.rs
+++ b/examples/stm32l0/src/bin/adc.rs
@@ -19,11 +19,10 @@ async fn main(_spawner: Spawner) {
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC1, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES79_5);
23 let mut pin = p.PA1; 22 let mut pin = p.PA1;
24 23
25 let mut vrefint = adc.enable_vref(); 24 let mut vrefint = adc.enable_vref();
26 let vrefint_sample = adc.read(&mut vrefint).await; 25 let vrefint_sample = adc.read(&mut vrefint, SampleTime::CYCLES79_5).await;
27 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
28 // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf
29 // 6.3.3 Embedded internal reference voltage 28 // 6.3.3 Embedded internal reference voltage
@@ -33,7 +32,7 @@ async fn main(_spawner: Spawner) {
33 }; 32 };
34 33
35 loop { 34 loop {
36 let v = adc.read(&mut pin).await; 35 let v = adc.read(&mut pin, SampleTime::CYCLES79_5).await;
37 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
38 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
39 } 38 }
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs
index 40e907940..42766a5e3 100644
--- a/examples/stm32l4/src/bin/adc.rs
+++ b/examples/stm32l4/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::Config; 5use embassy_stm32::Config;
6use embassy_stm32::adc::{Adc, Resolution}; 6use embassy_stm32::adc::{Adc, AdcConfig, Resolution, SampleTime};
7use {defmt_rtt as _, panic_probe as _}; 7use {defmt_rtt as _, panic_probe as _};
8 8
9#[cortex_m_rt::entry] 9#[cortex_m_rt::entry]
@@ -17,13 +17,16 @@ fn main() -> ! {
17 } 17 }
18 let p = embassy_stm32::init(config); 18 let p = embassy_stm32::init(config);
19 19
20 let mut adc = Adc::new(p.ADC1); 20 let mut config = AdcConfig::default();
21 config.resolution = Some(Resolution::BITS8);
22
23 let mut adc = Adc::new_with_config(p.ADC1, config);
21 //adc.enable_vref(); 24 //adc.enable_vref();
22 adc.set_resolution(Resolution::BITS8); 25
23 let mut channel = p.PC0; 26 let mut channel = p.PC0;
24 27
25 loop { 28 loop {
26 let v = adc.blocking_read(&mut channel); 29 let v = adc.blocking_read(&mut channel, SampleTime::from_bits(0));
27 info!("--> {}", v); 30 info!("--> {}", v);
28 } 31 }
29} 32}
diff --git a/examples/stm32l4/src/bin/adc_dma.rs b/examples/stm32l4/src/bin/adc_dma.rs
index 7a9200edd..550da95a4 100644
--- a/examples/stm32l4/src/bin/adc_dma.rs
+++ b/examples/stm32l4/src/bin/adc_dma.rs
@@ -4,7 +4,7 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::Config; 6use embassy_stm32::Config;
7use embassy_stm32::adc::{Adc, AdcChannel, SampleTime}; 7use embassy_stm32::adc::{Adc, AdcChannel, RegularConversionMode, SampleTime};
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
10const DMA_BUF_LEN: usize = 512; 10const DMA_BUF_LEN: usize = 512;
@@ -20,19 +20,16 @@ async fn main(_spawner: Spawner) {
20 } 20 }
21 let p = embassy_stm32::init(config); 21 let p = embassy_stm32::init(config);
22 22
23 let mut adc = Adc::new(p.ADC1); 23 let adc = Adc::new(p.ADC1);
24 let mut adc_pin0 = p.PA0.degrade_adc(); 24 let adc_pin0 = p.PA0.degrade_adc();
25 let mut adc_pin1 = p.PA1.degrade_adc(); 25 let adc_pin1 = p.PA1.degrade_adc();
26 let mut adc_dma_buf = [0u16; DMA_BUF_LEN]; 26 let mut adc_dma_buf = [0u16; DMA_BUF_LEN];
27 let mut measurements = [0u16; DMA_BUF_LEN / 2]; 27 let mut measurements = [0u16; DMA_BUF_LEN / 2];
28 let mut ring_buffered_adc = adc.into_ring_buffered( 28 let mut ring_buffered_adc = adc.into_ring_buffered(
29 p.DMA1_CH1, 29 p.DMA1_CH1,
30 &mut adc_dma_buf, 30 &mut adc_dma_buf,
31 [ 31 [(adc_pin0, SampleTime::CYCLES640_5), (adc_pin1, SampleTime::CYCLES640_5)].into_iter(),
32 (&mut adc_pin0, SampleTime::CYCLES640_5), 32 RegularConversionMode::Continuous,
33 (&mut adc_pin1, SampleTime::CYCLES640_5),
34 ]
35 .into_iter(),
36 ); 33 );
37 34
38 info!("starting measurement loop"); 35 info!("starting measurement loop");
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs
index b721f5b2e..d8f2de941 100644
--- a/examples/stm32l5/src/bin/usb_hid_mouse.rs
+++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs
@@ -1,6 +1,8 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::sync::atomic::{AtomicU8, Ordering};
5
4use defmt::*; 6use defmt::*;
5use embassy_executor::Spawner; 7use embassy_executor::Spawner;
6use embassy_futures::join::join; 8use embassy_futures::join::join;
@@ -8,7 +10,9 @@ use embassy_stm32::usb::Driver;
8use embassy_stm32::{Config, bind_interrupts, peripherals, usb}; 10use embassy_stm32::{Config, bind_interrupts, peripherals, usb};
9use embassy_time::Timer; 11use embassy_time::Timer;
10use embassy_usb::Builder; 12use embassy_usb::Builder;
11use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; 13use embassy_usb::class::hid::{
14 HidBootProtocol, HidProtocolMode, HidSubclass, HidWriter, ReportId, RequestHandler, State,
15};
12use embassy_usb::control::OutResponse; 16use embassy_usb::control::OutResponse;
13use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; 17use usbd_hid::descriptor::{MouseReport, SerializedDescriptor};
14use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
@@ -17,6 +21,8 @@ bind_interrupts!(struct Irqs {
17 USB_FS => usb::InterruptHandler<peripherals::USB>; 21 USB_FS => usb::InterruptHandler<peripherals::USB>;
18}); 22});
19 23
24static HID_PROTOCOL_MODE: AtomicU8 = AtomicU8::new(HidProtocolMode::Boot as u8);
25
20#[embassy_executor::main] 26#[embassy_executor::main]
21async fn main(_spawner: Spawner) { 27async fn main(_spawner: Spawner) {
22 let mut config = Config::default(); 28 let mut config = Config::default();
@@ -48,6 +54,10 @@ async fn main(_spawner: Spawner) {
48 config.serial_number = Some("12345678"); 54 config.serial_number = Some("12345678");
49 config.max_power = 100; 55 config.max_power = 100;
50 config.max_packet_size_0 = 64; 56 config.max_packet_size_0 = 64;
57 config.composite_with_iads = false;
58 config.device_class = 0;
59 config.device_sub_class = 0;
60 config.device_protocol = 0;
51 61
52 // Create embassy-usb DeviceBuilder using the driver and config. 62 // Create embassy-usb DeviceBuilder using the driver and config.
53 // It needs some buffers for building the descriptors. 63 // It needs some buffers for building the descriptors.
@@ -73,6 +83,8 @@ async fn main(_spawner: Spawner) {
73 request_handler: Some(&mut request_handler), 83 request_handler: Some(&mut request_handler),
74 poll_ms: 60, 84 poll_ms: 60,
75 max_packet_size: 8, 85 max_packet_size: 8,
86 hid_subclass: HidSubclass::Boot,
87 hid_boot_protocol: HidBootProtocol::Mouse,
76 }; 88 };
77 89
78 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config); 90 let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
@@ -90,16 +102,26 @@ async fn main(_spawner: Spawner) {
90 Timer::after_millis(500).await; 102 Timer::after_millis(500).await;
91 103
92 y = -y; 104 y = -y;
93 let report = MouseReport { 105
94 buttons: 0, 106 if HID_PROTOCOL_MODE.load(Ordering::Relaxed) == HidProtocolMode::Boot as u8 {
95 x: 0, 107 let buttons = 0u8;
96 y, 108 let x = 0i8;
97 wheel: 0, 109 match writer.write(&[buttons, x as u8, y as u8]).await {
98 pan: 0, 110 Ok(()) => {}
99 }; 111 Err(e) => warn!("Failed to send boot report: {:?}", e),
100 match writer.write_serialize(&report).await { 112 }
101 Ok(()) => {} 113 } else {
102 Err(e) => warn!("Failed to send report: {:?}", e), 114 let report = MouseReport {
115 buttons: 0,
116 x: 0,
117 y,
118 wheel: 0,
119 pan: 0,
120 };
121 match writer.write_serialize(&report).await {
122 Ok(()) => {}
123 Err(e) => warn!("Failed to send report: {:?}", e),
124 }
103 } 125 }
104 } 126 }
105 }; 127 };
@@ -122,6 +144,18 @@ impl RequestHandler for MyRequestHandler {
122 OutResponse::Accepted 144 OutResponse::Accepted
123 } 145 }
124 146
147 fn get_protocol(&self) -> HidProtocolMode {
148 let protocol = HidProtocolMode::from(HID_PROTOCOL_MODE.load(Ordering::Relaxed));
149 info!("The current HID protocol mode is: {}", protocol);
150 protocol
151 }
152
153 fn set_protocol(&mut self, protocol: HidProtocolMode) -> OutResponse {
154 info!("Switching to HID protocol mode: {}", protocol);
155 HID_PROTOCOL_MODE.store(protocol as u8, Ordering::Relaxed);
156 OutResponse::Accepted
157 }
158
125 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) { 159 fn set_idle_ms(&mut self, id: Option<ReportId>, dur: u32) {
126 info!("Set idle rate for {:?} to {:?}", id, dur); 160 info!("Set idle rate for {:?} to {:?}", id, dur);
127 } 161 }
diff --git a/examples/stm32n6/.cargo/config.toml b/examples/stm32n6/.cargo/config.toml
new file mode 100644
index 000000000..2fdd70649
--- /dev/null
+++ b/examples/stm32n6/.cargo/config.toml
@@ -0,0 +1,8 @@
1[target.thumbv8m.main-none-eabihf]
2runner = 'probe-rs run --chip STM32N657'
3
4[build]
5target = "thumbv8m.main-none-eabihf"
6
7[env]
8DEFMT_LOG = "trace"
diff --git a/examples/stm32n6/Cargo.toml b/examples/stm32n6/Cargo.toml
new file mode 100644
index 000000000..5ed28eed1
--- /dev/null
+++ b/examples/stm32n6/Cargo.toml
@@ -0,0 +1,78 @@
1[package]
2edition = "2021"
3name = "embassy-stm32n6-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6publish = false
7
8[dependencies]
9# Change stm32h563zi to your chip name, if necessary.
10embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = ["defmt", "stm32n657x0", "time-driver-any", "exti", "unstable-pac"] }
11embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
13embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
14embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "proto-ipv6"] }
15embassy-usb = { version = "0.5.1", path = "../../embassy-usb", features = ["defmt"] }
16embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
17
18defmt = "1.0.1"
19defmt-rtt = "1.0.0"
20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0"
23embedded-hal = "0.2.6"
24embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
25embedded-hal-async = { version = "1.0" }
26embedded-io-async = { version = "0.6.1" }
27embedded-nal-async = "0.8.0"
28panic-probe = { version = "1.0.0", features = ["print-defmt"] }
29heapless = { version = "0.8", default-features = false }
30critical-section = "1.1"
31micromath = "2.0.0"
32stm32-fmc = "0.3.0"
33embedded-storage = "0.3.1"
34static_cell = "2"
35
36
37# cargo build/run
38[profile.dev]
39codegen-units = 1
40debug = 2
41debug-assertions = true # <-
42incremental = false
43opt-level = 3 # <-
44overflow-checks = true # <-
45
46# cargo test
47[profile.test]
48codegen-units = 1
49debug = 2
50debug-assertions = true # <-
51incremental = false
52opt-level = 3 # <-
53overflow-checks = true # <-
54
55# cargo build/run --release
56[profile.release]
57codegen-units = 1
58debug = 2
59debug-assertions = false # <-
60incremental = false
61lto = 'fat'
62opt-level = 3 # <-
63overflow-checks = false # <-
64
65# cargo test --release
66[profile.bench]
67codegen-units = 1
68debug = 2
69debug-assertions = false # <-
70incremental = false
71lto = 'fat'
72opt-level = 3 # <-
73overflow-checks = false # <-
74
75[package.metadata.embassy]
76build = [
77 { target = "thumbv8m.main-none-eabihf", artifact-dir = "out/examples/stm32n6" }
78]
diff --git a/examples/stm32n6/build.rs b/examples/stm32n6/build.rs
new file mode 100644
index 000000000..8cd32d7ed
--- /dev/null
+++ b/examples/stm32n6/build.rs
@@ -0,0 +1,5 @@
1fn main() {
2 println!("cargo:rustc-link-arg-bins=--nmagic");
3 println!("cargo:rustc-link-arg-bins=-Tlink.x");
4 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
5}
diff --git a/examples/stm32n6/memory.x b/examples/stm32n6/memory.x
new file mode 100644
index 000000000..59f127adc
--- /dev/null
+++ b/examples/stm32n6/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x34180400, LENGTH = 255K
4 RAM : ORIGIN = 0x341C0000, LENGTH = 256K
5}
diff --git a/examples/stm32n6/src/bin/blinky.rs b/examples/stm32n6/src/bin/blinky.rs
new file mode 100644
index 000000000..018967f08
--- /dev/null
+++ b/examples/stm32n6/src/bin/blinky.rs
@@ -0,0 +1,36 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::exti::ExtiInput;
7use embassy_stm32::gpio::{Level, Output, Pull, Speed};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::task]
12async fn button_task(mut p: ExtiInput<'static>) {
13 loop {
14 p.wait_for_any_edge().await;
15 info!("button pressed!");
16 }
17}
18
19#[embassy_executor::main]
20async fn main(spawner: Spawner) {
21 let p = embassy_stm32::init(Default::default());
22 info!("Hello World!");
23
24 let mut led = Output::new(p.PG10, Level::High, Speed::Low);
25 let button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up);
26
27 spawner.spawn(button_task(button).unwrap());
28
29 loop {
30 led.set_high();
31 Timer::after_millis(500).await;
32
33 led.set_low();
34 Timer::after_millis(500).await;
35 }
36}
diff --git a/examples/stm32u0/src/bin/adc.rs b/examples/stm32u0/src/bin/adc.rs
index 32a54299d..53bd37303 100644
--- a/examples/stm32u0/src/bin/adc.rs
+++ b/examples/stm32u0/src/bin/adc.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::Config; 5use embassy_stm32::Config;
6use embassy_stm32::adc::{Adc, Resolution}; 6use embassy_stm32::adc::{Adc, AdcConfig, Resolution, SampleTime};
7use embassy_time::Duration; 7use embassy_time::Duration;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -18,12 +18,13 @@ fn main() -> ! {
18 } 18 }
19 let p = embassy_stm32::init(config); 19 let p = embassy_stm32::init(config);
20 20
21 let mut adc = Adc::new(p.ADC1); 21 let mut config = AdcConfig::default();
22 adc.set_resolution(Resolution::BITS8); 22 config.resolution = Some(Resolution::BITS8);
23 let mut adc = Adc::new_with_config(p.ADC1, config);
23 let mut channel = p.PC0; 24 let mut channel = p.PC0;
24 25
25 loop { 26 loop {
26 let v = adc.blocking_read(&mut channel); 27 let v = adc.blocking_read(&mut channel, SampleTime::CYCLES12_5);
27 info!("--> {}", v); 28 info!("--> {}", v);
28 embassy_time::block_for(Duration::from_millis(200)); 29 embassy_time::block_for(Duration::from_millis(200));
29 } 30 }
diff --git a/examples/stm32u5/src/bin/adc.rs b/examples/stm32u5/src/bin/adc.rs
index 91e33053e..ad59c0bea 100644
--- a/examples/stm32u5/src/bin/adc.rs
+++ b/examples/stm32u5/src/bin/adc.rs
@@ -2,8 +2,7 @@
2#![no_main] 2#![no_main]
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::adc; 5use embassy_stm32::adc::{self, Adc, AdcChannel, AdcConfig, SampleTime, adc4};
6use embassy_stm32::adc::{AdcChannel, adc4};
7use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
8 7
9#[embassy_executor::main] 8#[embassy_executor::main]
@@ -13,56 +12,55 @@ async fn main(_spawner: embassy_executor::Spawner) {
13 let mut p = embassy_stm32::init(config); 12 let mut p = embassy_stm32::init(config);
14 13
15 // **** ADC1 init **** 14 // **** ADC1 init ****
16 let mut adc1 = adc::Adc::new(p.ADC1); 15 let mut config = AdcConfig::default();
16 config.averaging = Some(adc::Averaging::Samples1024);
17 config.resolution = Some(adc::Resolution::BITS14);
18 let mut adc1 = Adc::new_with_config(p.ADC1, config);
17 let mut adc1_pin1 = p.PA3; // A0 on nucleo u5a5 19 let mut adc1_pin1 = p.PA3; // A0 on nucleo u5a5
18 let mut adc1_pin2 = p.PA2; // A1 20 let mut adc1_pin2 = p.PA2; // A1
19 adc1.set_resolution(adc::Resolution::BITS14);
20 adc1.set_averaging(adc::Averaging::Samples1024);
21 adc1.set_sample_time(adc::SampleTime::CYCLES160_5);
22 let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14); 21 let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14);
23 22
24 // **** ADC2 init **** 23 // **** ADC2 init ****
25 let mut adc2 = adc::Adc::new(p.ADC2); 24 let mut config = AdcConfig::default();
25 config.averaging = Some(adc::Averaging::Samples1024);
26 config.resolution = Some(adc::Resolution::BITS14);
27 let mut adc2 = Adc::new_with_config(p.ADC2, config);
26 let mut adc2_pin1 = p.PC3; // A2 28 let mut adc2_pin1 = p.PC3; // A2
27 let mut adc2_pin2 = p.PB0; // A3 29 let mut adc2_pin2 = p.PB0; // A3
28 adc2.set_resolution(adc::Resolution::BITS14);
29 adc2.set_averaging(adc::Averaging::Samples1024);
30 adc2.set_sample_time(adc::SampleTime::CYCLES160_5);
31 let max2 = adc::resolution_to_max_count(adc::Resolution::BITS14); 30 let max2 = adc::resolution_to_max_count(adc::Resolution::BITS14);
32 31
33 // **** ADC4 init **** 32 // **** ADC4 init ****
34 let mut adc4 = adc4::Adc4::new(p.ADC4); 33 let mut adc4 = Adc::new_adc4(p.ADC4);
35 let mut adc4_pin1 = p.PC1; // A4 34 let mut adc4_pin1 = p.PC1; // A4
36 let mut adc4_pin2 = p.PC0; // A5 35 let mut adc4_pin2 = p.PC0; // A5
37 adc4.set_resolution(adc4::Resolution::BITS12); 36 adc4.set_resolution_adc4(adc4::Resolution::BITS12);
38 adc4.set_averaging(adc4::Averaging::Samples256); 37 adc4.set_averaging_adc4(adc4::Averaging::Samples256);
39 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
40 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 38 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
41 39
42 // **** ADC1 blocking read **** 40 // **** ADC1 blocking read ****
43 let raw: u16 = adc1.blocking_read(&mut adc1_pin1); 41 let raw: u16 = adc1.blocking_read(&mut adc1_pin1, SampleTime::CYCLES160_5);
44 let volt: f32 = 3.3 * raw as f32 / max1 as f32; 42 let volt: f32 = 3.3 * raw as f32 / max1 as f32;
45 info!("Read adc1 pin 1 {}", volt); 43 info!("Read adc1 pin 1 {}", volt);
46 44
47 let raw: u16 = adc1.blocking_read(&mut adc1_pin2); 45 let raw: u16 = adc1.blocking_read(&mut adc1_pin2, SampleTime::CYCLES160_5);
48 let volt: f32 = 3.3 * raw as f32 / max1 as f32; 46 let volt: f32 = 3.3 * raw as f32 / max1 as f32;
49 info!("Read adc1 pin 2 {}", volt); 47 info!("Read adc1 pin 2 {}", volt);
50 48
51 // **** ADC2 blocking read **** 49 // **** ADC2 blocking read ****
52 let raw: u16 = adc2.blocking_read(&mut adc2_pin1); 50 let raw: u16 = adc2.blocking_read(&mut adc2_pin1, SampleTime::CYCLES160_5);
53 let volt: f32 = 3.3 * raw as f32 / max2 as f32; 51 let volt: f32 = 3.3 * raw as f32 / max2 as f32;
54 info!("Read adc2 pin 1 {}", volt); 52 info!("Read adc2 pin 1 {}", volt);
55 53
56 let raw: u16 = adc2.blocking_read(&mut adc2_pin2); 54 let raw: u16 = adc2.blocking_read(&mut adc2_pin2, SampleTime::CYCLES160_5);
57 let volt: f32 = 3.3 * raw as f32 / max2 as f32; 55 let volt: f32 = 3.3 * raw as f32 / max2 as f32;
58 info!("Read adc2 pin 2 {}", volt); 56 info!("Read adc2 pin 2 {}", volt);
59 57
60 // **** ADC4 blocking read **** 58 // **** ADC4 blocking read ****
61 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 59 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
62 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 60 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
63 info!("Read adc4 pin 1 {}", volt); 61 info!("Read adc4 pin 1 {}", volt);
64 62
65 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 63 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
66 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 64 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
67 info!("Read adc4 pin 2 {}", volt); 65 info!("Read adc4 pin 2 {}", volt);
68 66
@@ -97,11 +95,14 @@ async fn main(_spawner: embassy_executor::Spawner) {
97 // The channels must be in ascending order and can't repeat for ADC4 95 // The channels must be in ascending order and can't repeat for ADC4
98 adc4.read( 96 adc4.read(
99 p.GPDMA1_CH1.reborrow(), 97 p.GPDMA1_CH1.reborrow(),
100 [&mut degraded42, &mut degraded41].into_iter(), 98 [
99 (&mut degraded42, adc4::SampleTime::CYCLES1_5),
100 (&mut degraded41, adc4::SampleTime::CYCLES1_5),
101 ]
102 .into_iter(),
101 &mut measurements, 103 &mut measurements,
102 ) 104 )
103 .await 105 .await;
104 .unwrap();
105 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32; 106 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32;
106 let volt1: f32 = 3.3 * measurements[1] as f32 / max4 as f32; 107 let volt1: f32 = 3.3 * measurements[1] as f32 / max4 as f32;
107 info!("Async read 4 pin 1 {}", volt1); 108 info!("Async read 4 pin 1 {}", volt1);
diff --git a/examples/stm32wba/src/bin/adc.rs b/examples/stm32wba/src/bin/adc.rs
index 8c80470b8..ade3f5d6a 100644
--- a/examples/stm32wba/src/bin/adc.rs
+++ b/examples/stm32wba/src/bin/adc.rs
@@ -2,7 +2,7 @@
2#![no_main] 2#![no_main]
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::adc::{AdcChannel, adc4}; 5use embassy_stm32::adc::{Adc, AdcChannel, SampleTime, adc4};
6use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
7 7
8#[embassy_executor::main] 8#[embassy_executor::main]
@@ -12,20 +12,20 @@ async fn main(_spawner: embassy_executor::Spawner) {
12 let mut p = embassy_stm32::init(config); 12 let mut p = embassy_stm32::init(config);
13 13
14 // **** ADC4 init **** 14 // **** ADC4 init ****
15 let mut adc4 = adc4::Adc4::new(p.ADC4); 15 let mut adc4 = Adc::new_adc4(p.ADC4);
16 let mut adc4_pin1 = p.PA0; // A4 16 let mut adc4_pin1 = p.PA0; // A4
17 let mut adc4_pin2 = p.PA1; // A5 17 let mut adc4_pin2 = p.PA1; // A5
18 adc4.set_resolution(adc4::Resolution::BITS12); 18 adc4.set_resolution_adc4(adc4::Resolution::BITS12);
19 adc4.set_averaging(adc4::Averaging::Samples256); 19 adc4.set_averaging_adc4(adc4::Averaging::Samples256);
20 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5); 20
21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
22 22
23 // **** ADC4 blocking read **** 23 // **** ADC4 blocking read ****
24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
25 let volt: f32 = 3.0 * raw as f32 / max4 as f32; 25 let volt: f32 = 3.0 * raw as f32 / max4 as f32;
26 info!("Read adc4 pin 1 {}", volt); 26 info!("Read adc4 pin 1 {}", volt);
27 27
28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
29 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 29 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
30 info!("Read adc4 pin 2 {}", volt); 30 info!("Read adc4 pin 2 {}", volt);
31 31
@@ -37,11 +37,14 @@ async fn main(_spawner: embassy_executor::Spawner) {
37 // The channels must be in ascending order and can't repeat for ADC4 37 // The channels must be in ascending order and can't repeat for ADC4
38 adc4.read( 38 adc4.read(
39 p.GPDMA1_CH1.reborrow(), 39 p.GPDMA1_CH1.reborrow(),
40 [&mut degraded42, &mut degraded41].into_iter(), 40 [
41 (&mut degraded42, SampleTime::CYCLES12_5),
42 (&mut degraded41, SampleTime::CYCLES12_5),
43 ]
44 .into_iter(),
41 &mut measurements, 45 &mut measurements,
42 ) 46 )
43 .await 47 .await;
44 .unwrap();
45 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32; 48 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32;
46 let volt1: f32 = 3.0 * measurements[1] as f32 / max4 as f32; 49 let volt1: f32 = 3.0 * measurements[1] as f32 / max4 as f32;
47 info!("Async read 4 pin 1 {}", volt1); 50 info!("Async read 4 pin 1 {}", volt1);
diff --git a/examples/stm32wba6/src/bin/adc.rs b/examples/stm32wba6/src/bin/adc.rs
index 8c80470b8..9d1f39419 100644
--- a/examples/stm32wba6/src/bin/adc.rs
+++ b/examples/stm32wba6/src/bin/adc.rs
@@ -2,7 +2,7 @@
2#![no_main] 2#![no_main]
3 3
4use defmt::*; 4use defmt::*;
5use embassy_stm32::adc::{AdcChannel, adc4}; 5use embassy_stm32::adc::{Adc, AdcChannel, SampleTime, adc4};
6use {defmt_rtt as _, panic_probe as _}; 6use {defmt_rtt as _, panic_probe as _};
7 7
8#[embassy_executor::main] 8#[embassy_executor::main]
@@ -12,20 +12,19 @@ async fn main(_spawner: embassy_executor::Spawner) {
12 let mut p = embassy_stm32::init(config); 12 let mut p = embassy_stm32::init(config);
13 13
14 // **** ADC4 init **** 14 // **** ADC4 init ****
15 let mut adc4 = adc4::Adc4::new(p.ADC4); 15 let mut adc4 = Adc::new_adc4(p.ADC4);
16 let mut adc4_pin1 = p.PA0; // A4 16 let mut adc4_pin1 = p.PA0; // A4
17 let mut adc4_pin2 = p.PA1; // A5 17 let mut adc4_pin2 = p.PA1; // A5
18 adc4.set_resolution(adc4::Resolution::BITS12); 18 adc4.set_resolution_adc4(adc4::Resolution::BITS12);
19 adc4.set_averaging(adc4::Averaging::Samples256); 19 adc4.set_averaging_adc4(adc4::Averaging::Samples256);
20 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12); 20 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
22 21
23 // **** ADC4 blocking read **** 22 // **** ADC4 blocking read ****
24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1); 23 let raw: u16 = adc4.blocking_read(&mut adc4_pin1, adc4::SampleTime::CYCLES1_5);
25 let volt: f32 = 3.0 * raw as f32 / max4 as f32; 24 let volt: f32 = 3.0 * raw as f32 / max4 as f32;
26 info!("Read adc4 pin 1 {}", volt); 25 info!("Read adc4 pin 1 {}", volt);
27 26
28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2); 27 let raw: u16 = adc4.blocking_read(&mut adc4_pin2, adc4::SampleTime::CYCLES1_5);
29 let volt: f32 = 3.3 * raw as f32 / max4 as f32; 28 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
30 info!("Read adc4 pin 2 {}", volt); 29 info!("Read adc4 pin 2 {}", volt);
31 30
@@ -37,11 +36,14 @@ async fn main(_spawner: embassy_executor::Spawner) {
37 // The channels must be in ascending order and can't repeat for ADC4 36 // The channels must be in ascending order and can't repeat for ADC4
38 adc4.read( 37 adc4.read(
39 p.GPDMA1_CH1.reborrow(), 38 p.GPDMA1_CH1.reborrow(),
40 [&mut degraded42, &mut degraded41].into_iter(), 39 [
40 (&mut degraded42, SampleTime::CYCLES12_5),
41 (&mut degraded41, SampleTime::CYCLES12_5),
42 ]
43 .into_iter(),
41 &mut measurements, 44 &mut measurements,
42 ) 45 )
43 .await 46 .await;
44 .unwrap();
45 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32; 47 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32;
46 let volt1: f32 = 3.0 * measurements[1] as f32 / max4 as f32; 48 let volt1: f32 = 3.0 * measurements[1] as f32 / max4 as f32;
47 info!("Async read 4 pin 1 {}", volt1); 49 info!("Async read 4 pin 1 {}", volt1);
diff --git a/examples/stm32wl/src/bin/adc.rs b/examples/stm32wl/src/bin/adc.rs
index 6b21b086b..adabe0df8 100644
--- a/examples/stm32wl/src/bin/adc.rs
+++ b/examples/stm32wl/src/bin/adc.rs
@@ -18,11 +18,11 @@ async fn main(_spawner: Spawner) {
18 info!("Hello World!"); 18 info!("Hello World!");
19 19
20 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Sync { div: CkModePclk::DIV1 }); 20 let mut adc = Adc::new_with_clock(p.ADC1, Clock::Sync { div: CkModePclk::DIV1 });
21 adc.set_sample_time(SampleTime::CYCLES79_5); 21
22 let mut pin = p.PB2; 22 let mut pin = p.PB2;
23 23
24 let mut vrefint = adc.enable_vrefint(); 24 let mut vrefint = adc.enable_vrefint();
25 let vrefint_sample = adc.blocking_read(&mut vrefint); 25 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
26 let convert_to_millivolts = |sample| { 26 let convert_to_millivolts = |sample| {
27 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 27 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
28 // 6.3.3 Embedded internal reference voltage 28 // 6.3.3 Embedded internal reference voltage
@@ -32,7 +32,7 @@ async fn main(_spawner: Spawner) {
32 }; 32 };
33 33
34 loop { 34 loop {
35 let v = adc.blocking_read(&mut pin); 35 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
36 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 36 info!("--> {} - {} mV", v, convert_to_millivolts(v));
37 Timer::after_millis(100).await; 37 Timer::after_millis(100).await;
38 } 38 }
diff --git a/examples/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs
index 8b830a1e6..4e0574d97 100644
--- a/examples/stm32wle5/src/bin/adc.rs
+++ b/examples/stm32wle5/src/bin/adc.rs
@@ -73,11 +73,10 @@ async fn async_main(_spawner: Spawner) {
73 info!("Hello World!"); 73 info!("Hello World!");
74 74
75 let mut adc = Adc::new(p.ADC1); 75 let mut adc = Adc::new(p.ADC1);
76 adc.set_sample_time(SampleTime::CYCLES79_5);
77 let mut pin = p.PA10; 76 let mut pin = p.PA10;
78 77
79 let mut vrefint = adc.enable_vrefint(); 78 let mut vrefint = adc.enable_vrefint();
80 let vrefint_sample = adc.blocking_read(&mut vrefint); 79 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
81 let convert_to_millivolts = |sample| { 80 let convert_to_millivolts = |sample| {
82 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf 81 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
83 // 6.3.3 Embedded internal reference voltage 82 // 6.3.3 Embedded internal reference voltage
@@ -87,7 +86,7 @@ async fn async_main(_spawner: Spawner) {
87 }; 86 };
88 87
89 loop { 88 loop {
90 let v = adc.blocking_read(&mut pin); 89 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
91 info!("--> {} - {} mV", v, convert_to_millivolts(v)); 90 info!("--> {} - {} mV", v, convert_to_millivolts(v));
92 Timer::after_secs(1).await; 91 Timer::after_secs(1).await;
93 } 92 }