aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-12-19 18:03:20 +0100
committerDario Nieuwenhuis <[email protected]>2023-12-19 18:03:20 +0100
commitc8c8b89104acb396476b72ff9192d7b14a46752d (patch)
tree1367fd299022eb91ddbfd01bf73b55ae58a013ec /embassy-stm32/src
parent189b15c426a3a9ef7d4024ba7e5de6a255f88ee7 (diff)
stm32: doc everything else.
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/dma/gpdma.rs18
-rw-r--r--embassy-stm32/src/ipcc.rs8
-rw-r--r--embassy-stm32/src/lib.rs1
-rw-r--r--embassy-stm32/src/low_power.rs106
-rw-r--r--embassy-stm32/src/opamp.rs9
-rw-r--r--embassy-stm32/src/rng.rs1
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs2
-rw-r--r--embassy-stm32/src/usb/mod.rs4
-rw-r--r--embassy-stm32/src/usb/usb.rs7
-rw-r--r--embassy-stm32/src/usb_otg/mod.rs2
-rw-r--r--embassy-stm32/src/usb_otg/usb.rs13
-rw-r--r--embassy-stm32/src/wdg/mod.rs4
12 files changed, 127 insertions, 48 deletions
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index b061415eb..34b2426b9 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -16,6 +16,7 @@ use crate::interrupt::Priority;
16use crate::pac; 16use crate::pac;
17use crate::pac::gpdma::vals; 17use crate::pac::gpdma::vals;
18 18
19/// GPDMA transfer options.
19#[derive(Debug, Copy, Clone, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "defmt", derive(defmt::Format))] 21#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21#[non_exhaustive] 22#[non_exhaustive]
@@ -113,10 +114,13 @@ pub(crate) unsafe fn on_irq_inner(dma: pac::gpdma::Gpdma, channel_num: usize, in
113 } 114 }
114} 115}
115 116
117/// DMA request type alias. (also known as DMA channel number in some chips)
116pub type Request = u8; 118pub type Request = u8;
117 119
120/// DMA channel.
118#[cfg(dmamux)] 121#[cfg(dmamux)]
119pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static + super::dmamux::MuxChannel {} 122pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static + super::dmamux::MuxChannel {}
123/// DMA channel.
120#[cfg(not(dmamux))] 124#[cfg(not(dmamux))]
121pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static {} 125pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static {}
122 126
@@ -131,12 +135,14 @@ pub(crate) mod sealed {
131 } 135 }
132} 136}
133 137
138/// DMA transfer.
134#[must_use = "futures do nothing unless you `.await` or poll them"] 139#[must_use = "futures do nothing unless you `.await` or poll them"]
135pub struct Transfer<'a, C: Channel> { 140pub struct Transfer<'a, C: Channel> {
136 channel: PeripheralRef<'a, C>, 141 channel: PeripheralRef<'a, C>,
137} 142}
138 143
139impl<'a, C: Channel> Transfer<'a, C> { 144impl<'a, C: Channel> Transfer<'a, C> {
145 /// Create a new read DMA transfer (peripheral to memory).
140 pub unsafe fn new_read<W: Word>( 146 pub unsafe fn new_read<W: Word>(
141 channel: impl Peripheral<P = C> + 'a, 147 channel: impl Peripheral<P = C> + 'a,
142 request: Request, 148 request: Request,
@@ -147,6 +153,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
147 Self::new_read_raw(channel, request, peri_addr, buf, options) 153 Self::new_read_raw(channel, request, peri_addr, buf, options)
148 } 154 }
149 155
156 /// Create a new read DMA transfer (peripheral to memory), using raw pointers.
150 pub unsafe fn new_read_raw<W: Word>( 157 pub unsafe fn new_read_raw<W: Word>(
151 channel: impl Peripheral<P = C> + 'a, 158 channel: impl Peripheral<P = C> + 'a,
152 request: Request, 159 request: Request,
@@ -172,6 +179,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
172 ) 179 )
173 } 180 }
174 181
182 /// Create a new write DMA transfer (memory to peripheral).
175 pub unsafe fn new_write<W: Word>( 183 pub unsafe fn new_write<W: Word>(
176 channel: impl Peripheral<P = C> + 'a, 184 channel: impl Peripheral<P = C> + 'a,
177 request: Request, 185 request: Request,
@@ -182,6 +190,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
182 Self::new_write_raw(channel, request, buf, peri_addr, options) 190 Self::new_write_raw(channel, request, buf, peri_addr, options)
183 } 191 }
184 192
193 /// Create a new write DMA transfer (memory to peripheral), using raw pointers.
185 pub unsafe fn new_write_raw<W: Word>( 194 pub unsafe fn new_write_raw<W: Word>(
186 channel: impl Peripheral<P = C> + 'a, 195 channel: impl Peripheral<P = C> + 'a,
187 request: Request, 196 request: Request,
@@ -207,6 +216,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
207 ) 216 )
208 } 217 }
209 218
219 /// Create a new write DMA transfer (memory to peripheral), writing the same value repeatedly.
210 pub unsafe fn new_write_repeated<W: Word>( 220 pub unsafe fn new_write_repeated<W: Word>(
211 channel: impl Peripheral<P = C> + 'a, 221 channel: impl Peripheral<P = C> + 'a,
212 request: Request, 222 request: Request,
@@ -297,6 +307,9 @@ impl<'a, C: Channel> Transfer<'a, C> {
297 this 307 this
298 } 308 }
299 309
310 /// Request the transfer to stop.
311 ///
312 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
300 pub fn request_stop(&mut self) { 313 pub fn request_stop(&mut self) {
301 let ch = self.channel.regs().ch(self.channel.num()); 314 let ch = self.channel.regs().ch(self.channel.num());
302 ch.cr().modify(|w| { 315 ch.cr().modify(|w| {
@@ -304,6 +317,10 @@ impl<'a, C: Channel> Transfer<'a, C> {
304 }) 317 })
305 } 318 }
306 319
320 /// Return whether this transfer is still running.
321 ///
322 /// If this returns `false`, it can be because either the transfer finished, or
323 /// it was requested to stop early with [`request_stop`](Self::request_stop).
307 pub fn is_running(&mut self) -> bool { 324 pub fn is_running(&mut self) -> bool {
308 let ch = self.channel.regs().ch(self.channel.num()); 325 let ch = self.channel.regs().ch(self.channel.num());
309 let sr = ch.sr().read(); 326 let sr = ch.sr().read();
@@ -317,6 +334,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
317 ch.br1().read().bndt() 334 ch.br1().read().bndt()
318 } 335 }
319 336
337 /// Blocking wait until the transfer finishes.
320 pub fn blocking_wait(mut self) { 338 pub fn blocking_wait(mut self) {
321 while self.is_running() {} 339 while self.is_running() {}
322 340
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index 4006dee19..663a7f59d 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -1,3 +1,5 @@
1//! Inter-Process Communication Controller (IPCC)
2
1use core::future::poll_fn; 3use core::future::poll_fn;
2use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
3use core::task::Poll; 5use core::task::Poll;
@@ -41,6 +43,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_RX> for Receive
41 } 43 }
42} 44}
43 45
46/// TX interrupt handler.
44pub struct TransmitInterruptHandler {} 47pub struct TransmitInterruptHandler {}
45 48
46impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_TX> for TransmitInterruptHandler { 49impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_TX> for TransmitInterruptHandler {
@@ -72,6 +75,7 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_TX> for Transmi
72 } 75 }
73} 76}
74 77
78/// IPCC config.
75#[non_exhaustive] 79#[non_exhaustive]
76#[derive(Clone, Copy, Default)] 80#[derive(Clone, Copy, Default)]
77pub struct Config { 81pub struct Config {
@@ -79,6 +83,8 @@ pub struct Config {
79 // reserved for future use 83 // reserved for future use
80} 84}
81 85
86/// Channel.
87#[allow(missing_docs)]
82#[derive(Debug, Clone, Copy)] 88#[derive(Debug, Clone, Copy)]
83#[repr(C)] 89#[repr(C)]
84pub enum IpccChannel { 90pub enum IpccChannel {
@@ -90,9 +96,11 @@ pub enum IpccChannel {
90 Channel6 = 5, 96 Channel6 = 5,
91} 97}
92 98
99/// IPCC driver.
93pub struct Ipcc; 100pub struct Ipcc;
94 101
95impl Ipcc { 102impl Ipcc {
103 /// Enable IPCC.
96 pub fn enable(_config: Config) { 104 pub fn enable(_config: Config) {
97 IPCC::enable_and_reset(); 105 IPCC::enable_and_reset();
98 IPCC::set_cpu2(true); 106 IPCC::set_cpu2(true);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 4952d26eb..207f7ed8f 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -1,5 +1,6 @@
1#![cfg_attr(not(test), no_std)] 1#![cfg_attr(not(test), no_std)]
2#![allow(async_fn_in_trait)] 2#![allow(async_fn_in_trait)]
3#![warn(missing_docs)]
3 4
4//! ## Feature flags 5//! ## Feature flags
5#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)] 6#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs
index 20d8f9045..a41c40eba 100644
--- a/embassy-stm32/src/low_power.rs
+++ b/embassy-stm32/src/low_power.rs
@@ -1,50 +1,53 @@
1/// The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating 1//! Low-power support.
2/// to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which 2//!
3/// can use knowledge of which peripherals are currently blocked upon to transparently and safely 3//! The STM32 line of microcontrollers support various deep-sleep modes which exploit clock-gating
4/// enter such low-power modes (currently, only `STOP2`) when idle. 4//! to reduce power consumption. `embassy-stm32` provides a low-power executor, [`Executor`] which
5/// 5//! can use knowledge of which peripherals are currently blocked upon to transparently and safely
6/// The executor determines which peripherals are active by their RCC state; consequently, 6//! enter such low-power modes (currently, only `STOP2`) when idle.
7/// low-power states can only be entered if all peripherals have been `drop`'d. There are a few 7//!
8/// exceptions to this rule: 8//! The executor determines which peripherals are active by their RCC state; consequently,
9/// 9//! low-power states can only be entered if all peripherals have been `drop`'d. There are a few
10/// * `GPIO` 10//! exceptions to this rule:
11/// * `RCC` 11//!
12/// 12//! * `GPIO`
13/// Since entering and leaving low-power modes typically incurs a significant latency, the 13//! * `RCC`
14/// low-power executor will only attempt to enter when the next timer event is at least 14//!
15/// [`time_driver::MIN_STOP_PAUSE`] in the future. 15//! Since entering and leaving low-power modes typically incurs a significant latency, the
16/// 16//! low-power executor will only attempt to enter when the next timer event is at least
17/// Currently there is no macro analogous to `embassy_executor::main` for this executor; 17//! [`time_driver::MIN_STOP_PAUSE`] in the future.
18/// consequently one must define their entrypoint manually. Moveover, you must relinquish control 18//!
19/// of the `RTC` peripheral to the executor. This will typically look like 19//! Currently there is no macro analogous to `embassy_executor::main` for this executor;
20/// 20//! consequently one must define their entrypoint manually. Moveover, you must relinquish control
21/// ```rust,no_run 21//! of the `RTC` peripheral to the executor. This will typically look like
22/// use embassy_executor::Spawner; 22//!
23/// use embassy_stm32::low_power::Executor; 23//! ```rust,no_run
24/// use embassy_stm32::rtc::{Rtc, RtcConfig}; 24//! use embassy_executor::Spawner;
25/// use static_cell::make_static; 25//! use embassy_stm32::low_power::Executor;
26/// 26//! use embassy_stm32::rtc::{Rtc, RtcConfig};
27/// #[cortex_m_rt::entry] 27//! use static_cell::make_static;
28/// fn main() -> ! { 28//!
29/// Executor::take().run(|spawner| { 29//! #[cortex_m_rt::entry]
30/// unwrap!(spawner.spawn(async_main(spawner))); 30//! fn main() -> ! {
31/// }); 31//! Executor::take().run(|spawner| {
32/// } 32//! unwrap!(spawner.spawn(async_main(spawner)));
33/// 33//! });
34/// #[embassy_executor::task] 34//! }
35/// async fn async_main(spawner: Spawner) { 35//!
36/// // initialize the platform... 36//! #[embassy_executor::task]
37/// let mut config = embassy_stm32::Config::default(); 37//! async fn async_main(spawner: Spawner) {
38/// let p = embassy_stm32::init(config); 38//! // initialize the platform...
39/// 39//! let mut config = embassy_stm32::Config::default();
40/// // give the RTC to the executor... 40//! let p = embassy_stm32::init(config);
41/// let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); 41//!
42/// let rtc = make_static!(rtc); 42//! // give the RTC to the executor...
43/// embassy_stm32::low_power::stop_with_rtc(rtc); 43//! let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
44/// 44//! let rtc = make_static!(rtc);
45/// // your application here... 45//! embassy_stm32::low_power::stop_with_rtc(rtc);
46/// } 46//!
47/// ``` 47//! // your application here...
48//! }
49//! ```
50
48use core::arch::asm; 51use core::arch::asm;
49use core::marker::PhantomData; 52use core::marker::PhantomData;
50use core::sync::atomic::{compiler_fence, Ordering}; 53use core::sync::atomic::{compiler_fence, Ordering};
@@ -64,6 +67,7 @@ static mut EXECUTOR: Option<Executor> = None;
64foreach_interrupt! { 67foreach_interrupt! {
65 (RTC, rtc, $block:ident, WKUP, $irq:ident) => { 68 (RTC, rtc, $block:ident, WKUP, $irq:ident) => {
66 #[interrupt] 69 #[interrupt]
70 #[allow(non_snake_case)]
67 unsafe fn $irq() { 71 unsafe fn $irq() {
68 EXECUTOR.as_mut().unwrap().on_wakeup_irq(); 72 EXECUTOR.as_mut().unwrap().on_wakeup_irq();
69 } 73 }
@@ -75,10 +79,15 @@ pub(crate) unsafe fn on_wakeup_irq() {
75 EXECUTOR.as_mut().unwrap().on_wakeup_irq(); 79 EXECUTOR.as_mut().unwrap().on_wakeup_irq();
76} 80}
77 81
82/// Configure STOP mode with RTC.
78pub fn stop_with_rtc(rtc: &'static Rtc) { 83pub fn stop_with_rtc(rtc: &'static Rtc) {
79 unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc) 84 unsafe { EXECUTOR.as_mut().unwrap() }.stop_with_rtc(rtc)
80} 85}
81 86
87/// Get whether the core is ready to enter the given stop mode.
88///
89/// This will return false if some peripheral driver is in use that
90/// prevents entering the given stop mode.
82pub fn stop_ready(stop_mode: StopMode) -> bool { 91pub fn stop_ready(stop_mode: StopMode) -> bool {
83 match unsafe { EXECUTOR.as_mut().unwrap() }.stop_mode() { 92 match unsafe { EXECUTOR.as_mut().unwrap() }.stop_mode() {
84 Some(StopMode::Stop2) => true, 93 Some(StopMode::Stop2) => true,
@@ -87,10 +96,13 @@ pub fn stop_ready(stop_mode: StopMode) -> bool {
87 } 96 }
88} 97}
89 98
99/// Available stop modes.
90#[non_exhaustive] 100#[non_exhaustive]
91#[derive(PartialEq)] 101#[derive(PartialEq)]
92pub enum StopMode { 102pub enum StopMode {
103 /// STOP 1
93 Stop1, 104 Stop1,
105 /// STOP 2
94 Stop2, 106 Stop2,
95} 107}
96 108
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index e1eb031d1..df8a78bcc 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -1,9 +1,12 @@
1//! Operational Amplifier (OPAMP)
1#![macro_use] 2#![macro_use]
2 3
3use embassy_hal_internal::{into_ref, PeripheralRef}; 4use embassy_hal_internal::{into_ref, PeripheralRef};
4 5
5use crate::Peripheral; 6use crate::Peripheral;
6 7
8/// Gain
9#[allow(missing_docs)]
7#[derive(Clone, Copy)] 10#[derive(Clone, Copy)]
8pub enum OpAmpGain { 11pub enum OpAmpGain {
9 Mul1, 12 Mul1,
@@ -13,6 +16,8 @@ pub enum OpAmpGain {
13 Mul16, 16 Mul16,
14} 17}
15 18
19/// Speed
20#[allow(missing_docs)]
16#[derive(Clone, Copy)] 21#[derive(Clone, Copy)]
17pub enum OpAmpSpeed { 22pub enum OpAmpSpeed {
18 Normal, 23 Normal,
@@ -180,6 +185,7 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
180 } 185 }
181} 186}
182 187
188/// Opamp instance trait.
183pub trait Instance: sealed::Instance + 'static {} 189pub trait Instance: sealed::Instance + 'static {}
184 190
185pub(crate) mod sealed { 191pub(crate) mod sealed {
@@ -198,8 +204,11 @@ pub(crate) mod sealed {
198 pub trait OutputPin<T: Instance> {} 204 pub trait OutputPin<T: Instance> {}
199} 205}
200 206
207/// Non-inverting pin trait.
201pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {} 208pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {}
209/// Inverting pin trait.
202pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {} 210pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {}
211/// Output pin trait.
203pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {} 212pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {}
204 213
205macro_rules! impl_opamp_external_output { 214macro_rules! impl_opamp_external_output {
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 6ee89a922..ca641f352 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -80,6 +80,7 @@ impl<'d, T: Instance> Rng<'d, T> {
80 let _ = self.next_u32(); 80 let _ = self.next_u32();
81 } 81 }
82 82
83 /// Reset the RNG.
83 #[cfg(not(rng_v1))] 84 #[cfg(not(rng_v1))]
84 pub fn reset(&mut self) { 85 pub fn reset(&mut self) {
85 T::regs().cr().write(|reg| { 86 T::regs().cr().write(|reg| {
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index ab142053a..10006baff 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -293,6 +293,7 @@ pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma<T> = NoDma> {
293 293
294#[cfg(sdmmc_v1)] 294#[cfg(sdmmc_v1)]
295impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { 295impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
296 /// Create a new SDMMC driver, with 1 data lane.
296 pub fn new_1bit( 297 pub fn new_1bit(
297 sdmmc: impl Peripheral<P = T> + 'd, 298 sdmmc: impl Peripheral<P = T> + 'd,
298 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 299 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@@ -327,6 +328,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
327 ) 328 )
328 } 329 }
329 330
331 /// Create a new SDMMC driver, with 4 data lanes.
330 pub fn new_4bit( 332 pub fn new_4bit(
331 sdmmc: impl Peripheral<P = T> + 'd, 333 sdmmc: impl Peripheral<P = T> + 'd,
332 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 334 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs
index d0b289462..4debd4e54 100644
--- a/embassy-stm32/src/usb/mod.rs
+++ b/embassy-stm32/src/usb/mod.rs
@@ -1,3 +1,5 @@
1//! Universal Serial Bus (USB)
2
1use crate::interrupt; 3use crate::interrupt;
2use crate::rcc::RccPeripheral; 4use crate::rcc::RccPeripheral;
3 5
@@ -10,7 +12,9 @@ pub(crate) mod sealed {
10 } 12 }
11} 13}
12 14
15/// USB instance trait.
13pub trait Instance: sealed::Instance + RccPeripheral + 'static { 16pub trait Instance: sealed::Instance + RccPeripheral + 'static {
17 /// Interrupt for this USB instance.
14 type Interrupt: interrupt::typelevel::Interrupt; 18 type Interrupt: interrupt::typelevel::Interrupt;
15} 19}
16 20
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 295dc9198..a8aebfe1f 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -244,6 +244,7 @@ struct EndpointData {
244 used_out: bool, 244 used_out: bool,
245} 245}
246 246
247/// USB driver.
247pub struct Driver<'d, T: Instance> { 248pub struct Driver<'d, T: Instance> {
248 phantom: PhantomData<&'d mut T>, 249 phantom: PhantomData<&'d mut T>,
249 alloc: [EndpointData; EP_COUNT], 250 alloc: [EndpointData; EP_COUNT],
@@ -251,6 +252,7 @@ pub struct Driver<'d, T: Instance> {
251} 252}
252 253
253impl<'d, T: Instance> Driver<'d, T> { 254impl<'d, T: Instance> Driver<'d, T> {
255 /// Create a new USB driver.
254 pub fn new( 256 pub fn new(
255 _usb: impl Peripheral<P = T> + 'd, 257 _usb: impl Peripheral<P = T> + 'd,
256 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 258 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@@ -465,6 +467,7 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
465 } 467 }
466} 468}
467 469
470/// USB bus.
468pub struct Bus<'d, T: Instance> { 471pub struct Bus<'d, T: Instance> {
469 phantom: PhantomData<&'d mut T>, 472 phantom: PhantomData<&'d mut T>,
470 ep_types: [EpType; EP_COUNT - 1], 473 ep_types: [EpType; EP_COUNT - 1],
@@ -640,6 +643,7 @@ trait Dir {
640 fn waker(i: usize) -> &'static AtomicWaker; 643 fn waker(i: usize) -> &'static AtomicWaker;
641} 644}
642 645
646/// Marker type for the "IN" direction.
643pub enum In {} 647pub enum In {}
644impl Dir for In { 648impl Dir for In {
645 fn dir() -> Direction { 649 fn dir() -> Direction {
@@ -652,6 +656,7 @@ impl Dir for In {
652 } 656 }
653} 657}
654 658
659/// Marker type for the "OUT" direction.
655pub enum Out {} 660pub enum Out {}
656impl Dir for Out { 661impl Dir for Out {
657 fn dir() -> Direction { 662 fn dir() -> Direction {
@@ -664,6 +669,7 @@ impl Dir for Out {
664 } 669 }
665} 670}
666 671
672/// USB endpoint.
667pub struct Endpoint<'d, T: Instance, D> { 673pub struct Endpoint<'d, T: Instance, D> {
668 _phantom: PhantomData<(&'d mut T, D)>, 674 _phantom: PhantomData<(&'d mut T, D)>,
669 info: EndpointInfo, 675 info: EndpointInfo,
@@ -813,6 +819,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
813 } 819 }
814} 820}
815 821
822/// USB control pipe.
816pub struct ControlPipe<'d, T: Instance> { 823pub struct ControlPipe<'d, T: Instance> {
817 _phantom: PhantomData<&'d mut T>, 824 _phantom: PhantomData<&'d mut T>,
818 max_packet_size: u16, 825 max_packet_size: u16,
diff --git a/embassy-stm32/src/usb_otg/mod.rs b/embassy-stm32/src/usb_otg/mod.rs
index 1abd031dd..0649e684b 100644
--- a/embassy-stm32/src/usb_otg/mod.rs
+++ b/embassy-stm32/src/usb_otg/mod.rs
@@ -20,7 +20,9 @@ pub(crate) mod sealed {
20 } 20 }
21} 21}
22 22
23/// USB OTG instance.
23pub trait Instance: sealed::Instance + RccPeripheral { 24pub trait Instance: sealed::Instance + RccPeripheral {
25 /// Interrupt for this USB OTG instance.
24 type Interrupt: interrupt::typelevel::Interrupt; 26 type Interrupt: interrupt::typelevel::Interrupt;
25} 27}
26 28
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs
index ba77bfb16..190fb274f 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb_otg/usb.rs
@@ -204,6 +204,7 @@ pub enum PhyType {
204} 204}
205 205
206impl PhyType { 206impl PhyType {
207 /// Get whether this PHY is any of the internal types.
207 pub fn internal(&self) -> bool { 208 pub fn internal(&self) -> bool {
208 match self { 209 match self {
209 PhyType::InternalFullSpeed | PhyType::InternalHighSpeed => true, 210 PhyType::InternalFullSpeed | PhyType::InternalHighSpeed => true,
@@ -211,6 +212,7 @@ impl PhyType {
211 } 212 }
212 } 213 }
213 214
215 /// Get whether this PHY is any of the high-speed types.
214 pub fn high_speed(&self) -> bool { 216 pub fn high_speed(&self) -> bool {
215 match self { 217 match self {
216 PhyType::InternalFullSpeed => false, 218 PhyType::InternalFullSpeed => false,
@@ -218,7 +220,7 @@ impl PhyType {
218 } 220 }
219 } 221 }
220 222
221 pub fn to_dspd(&self) -> vals::Dspd { 223 fn to_dspd(&self) -> vals::Dspd {
222 match self { 224 match self {
223 PhyType::InternalFullSpeed => vals::Dspd::FULL_SPEED_INTERNAL, 225 PhyType::InternalFullSpeed => vals::Dspd::FULL_SPEED_INTERNAL,
224 PhyType::InternalHighSpeed => vals::Dspd::HIGH_SPEED, 226 PhyType::InternalHighSpeed => vals::Dspd::HIGH_SPEED,
@@ -230,6 +232,7 @@ impl PhyType {
230/// Indicates that [State::ep_out_buffers] is empty. 232/// Indicates that [State::ep_out_buffers] is empty.
231const EP_OUT_BUFFER_EMPTY: u16 = u16::MAX; 233const EP_OUT_BUFFER_EMPTY: u16 = u16::MAX;
232 234
235/// USB OTG driver state.
233pub struct State<const EP_COUNT: usize> { 236pub struct State<const EP_COUNT: usize> {
234 /// Holds received SETUP packets. Available if [State::ep0_setup_ready] is true. 237 /// Holds received SETUP packets. Available if [State::ep0_setup_ready] is true.
235 ep0_setup_data: UnsafeCell<[u8; 8]>, 238 ep0_setup_data: UnsafeCell<[u8; 8]>,
@@ -247,6 +250,7 @@ unsafe impl<const EP_COUNT: usize> Send for State<EP_COUNT> {}
247unsafe impl<const EP_COUNT: usize> Sync for State<EP_COUNT> {} 250unsafe impl<const EP_COUNT: usize> Sync for State<EP_COUNT> {}
248 251
249impl<const EP_COUNT: usize> State<EP_COUNT> { 252impl<const EP_COUNT: usize> State<EP_COUNT> {
253 /// Create a new State.
250 pub const fn new() -> Self { 254 pub const fn new() -> Self {
251 const NEW_AW: AtomicWaker = AtomicWaker::new(); 255 const NEW_AW: AtomicWaker = AtomicWaker::new();
252 const NEW_BUF: UnsafeCell<*mut u8> = UnsafeCell::new(0 as _); 256 const NEW_BUF: UnsafeCell<*mut u8> = UnsafeCell::new(0 as _);
@@ -271,6 +275,7 @@ struct EndpointData {
271 fifo_size_words: u16, 275 fifo_size_words: u16,
272} 276}
273 277
278/// USB driver config.
274#[non_exhaustive] 279#[non_exhaustive]
275#[derive(Clone, Copy, PartialEq, Eq, Debug)] 280#[derive(Clone, Copy, PartialEq, Eq, Debug)]
276pub struct Config { 281pub struct Config {
@@ -297,6 +302,7 @@ impl Default for Config {
297 } 302 }
298} 303}
299 304
305/// USB driver.
300pub struct Driver<'d, T: Instance> { 306pub struct Driver<'d, T: Instance> {
301 config: Config, 307 config: Config,
302 phantom: PhantomData<&'d mut T>, 308 phantom: PhantomData<&'d mut T>,
@@ -527,6 +533,7 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> {
527 } 533 }
528} 534}
529 535
536/// USB bus.
530pub struct Bus<'d, T: Instance> { 537pub struct Bus<'d, T: Instance> {
531 config: Config, 538 config: Config,
532 phantom: PhantomData<&'d mut T>, 539 phantom: PhantomData<&'d mut T>,
@@ -1092,6 +1099,7 @@ trait Dir {
1092 fn dir() -> Direction; 1099 fn dir() -> Direction;
1093} 1100}
1094 1101
1102/// Marker type for the "IN" direction.
1095pub enum In {} 1103pub enum In {}
1096impl Dir for In { 1104impl Dir for In {
1097 fn dir() -> Direction { 1105 fn dir() -> Direction {
@@ -1099,6 +1107,7 @@ impl Dir for In {
1099 } 1107 }
1100} 1108}
1101 1109
1110/// Marker type for the "OUT" direction.
1102pub enum Out {} 1111pub enum Out {}
1103impl Dir for Out { 1112impl Dir for Out {
1104 fn dir() -> Direction { 1113 fn dir() -> Direction {
@@ -1106,6 +1115,7 @@ impl Dir for Out {
1106 } 1115 }
1107} 1116}
1108 1117
1118/// USB endpoint.
1109pub struct Endpoint<'d, T: Instance, D> { 1119pub struct Endpoint<'d, T: Instance, D> {
1110 _phantom: PhantomData<(&'d mut T, D)>, 1120 _phantom: PhantomData<(&'d mut T, D)>,
1111 info: EndpointInfo, 1121 info: EndpointInfo,
@@ -1299,6 +1309,7 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> {
1299 } 1309 }
1300} 1310}
1301 1311
1312/// USB control pipe.
1302pub struct ControlPipe<'d, T: Instance> { 1313pub struct ControlPipe<'d, T: Instance> {
1303 _phantom: PhantomData<&'d mut T>, 1314 _phantom: PhantomData<&'d mut T>,
1304 max_packet_size: u16, 1315 max_packet_size: u16,
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index 5751a9ff3..dc701ef64 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -6,6 +6,7 @@ use stm32_metapac::iwdg::vals::{Key, Pr};
6 6
7use crate::rcc::LSI_FREQ; 7use crate::rcc::LSI_FREQ;
8 8
9/// Independent watchdog (IWDG) driver.
9pub struct IndependentWatchdog<'d, T: Instance> { 10pub struct IndependentWatchdog<'d, T: Instance> {
10 wdg: PhantomData<&'d mut T>, 11 wdg: PhantomData<&'d mut T>,
11} 12}
@@ -64,10 +65,12 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
64 IndependentWatchdog { wdg: PhantomData } 65 IndependentWatchdog { wdg: PhantomData }
65 } 66 }
66 67
68 /// Unleash (start) the watchdog.
67 pub fn unleash(&mut self) { 69 pub fn unleash(&mut self) {
68 T::regs().kr().write(|w| w.set_key(Key::START)); 70 T::regs().kr().write(|w| w.set_key(Key::START));
69 } 71 }
70 72
73 /// Pet (reload, refresh) the watchdog.
71 pub fn pet(&mut self) { 74 pub fn pet(&mut self) {
72 T::regs().kr().write(|w| w.set_key(Key::RESET)); 75 T::regs().kr().write(|w| w.set_key(Key::RESET));
73 } 76 }
@@ -79,6 +82,7 @@ mod sealed {
79 } 82 }
80} 83}
81 84
85/// IWDG instance trait.
82pub trait Instance: sealed::Instance {} 86pub trait Instance: sealed::Instance {}
83 87
84foreach_peripheral!( 88foreach_peripheral!(