mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-02-16 17:02:30 +00:00
Merge pull request #2889 from embassy-rs/update-metapac-42
stm32: update metapac. Adds U5 LPDMA, fixes ADC_COMMONs.
This commit is contained in:
commit
e6d90b18c0
@ -72,7 +72,7 @@ rand_core = "0.6.3"
|
|||||||
sdio-host = "0.5.0"
|
sdio-host = "0.5.0"
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
#stm32-metapac = { version = "15" }
|
#stm32-metapac = { version = "15" }
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c" }
|
||||||
|
|
||||||
vcell = "0.1.3"
|
vcell = "0.1.3"
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
@ -98,7 +98,7 @@ proc-macro2 = "1.0.36"
|
|||||||
quote = "1.0.15"
|
quote = "1.0.15"
|
||||||
|
|
||||||
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0", default-features = false, features = ["metadata"]}
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c", default-features = false, features = ["metadata"]}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rt"]
|
default = ["rt"]
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::path::PathBuf;
|
use std::io::Write;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
@ -49,6 +51,8 @@ fn main() {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_ascii_lowercase();
|
.to_ascii_lowercase();
|
||||||
|
|
||||||
|
eprintln!("chip: {chip_name}");
|
||||||
|
|
||||||
for p in METADATA.peripherals {
|
for p in METADATA.peripherals {
|
||||||
if let Some(r) = &p.registers {
|
if let Some(r) = &p.registers {
|
||||||
println!("cargo:rustc-cfg={}", r.kind);
|
println!("cargo:rustc-cfg={}", r.kind);
|
||||||
@ -1165,42 +1169,52 @@ fn main() {
|
|||||||
|
|
||||||
let mut dupe = HashSet::new();
|
let mut dupe = HashSet::new();
|
||||||
for ch in p.dma_channels {
|
for ch in p.dma_channels {
|
||||||
// Some chips have multiple request numbers for the same (peri, signal, channel) combos.
|
|
||||||
// Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
|
|
||||||
let key = (ch.signal, ch.channel);
|
|
||||||
if !dupe.insert(key) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
|
if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
|
||||||
let peri = format_ident!("{}", p.name);
|
let peri = format_ident!("{}", p.name);
|
||||||
|
|
||||||
let channel = if let Some(channel) = &ch.channel {
|
let channels = if let Some(channel) = &ch.channel {
|
||||||
// Chip with DMA/BDMA, without DMAMUX
|
// Chip with DMA/BDMA, without DMAMUX
|
||||||
let channel = format_ident!("{}", channel);
|
vec![*channel]
|
||||||
quote!({channel: #channel})
|
|
||||||
} else if let Some(dmamux) = &ch.dmamux {
|
} else if let Some(dmamux) = &ch.dmamux {
|
||||||
// Chip with DMAMUX
|
// Chip with DMAMUX
|
||||||
let dmamux = format_ident!("{}", dmamux);
|
METADATA
|
||||||
quote!({dmamux: #dmamux})
|
.dma_channels
|
||||||
|
.iter()
|
||||||
|
.filter(|ch| ch.dmamux == Some(*dmamux))
|
||||||
|
.map(|ch| ch.name)
|
||||||
|
.collect()
|
||||||
} else if let Some(dma) = &ch.dma {
|
} else if let Some(dma) = &ch.dma {
|
||||||
// Chip with GPDMA
|
// Chip with GPDMA
|
||||||
let dma = format_ident!("{}", dma);
|
METADATA
|
||||||
quote!({dma: #dma})
|
.dma_channels
|
||||||
|
.iter()
|
||||||
|
.filter(|ch| ch.dma == *dma)
|
||||||
|
.map(|ch| ch.name)
|
||||||
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let request = if let Some(request) = ch.request {
|
for channel in channels {
|
||||||
let request = request as u8;
|
// Some chips have multiple request numbers for the same (peri, signal, channel) combos.
|
||||||
quote!(#request)
|
// Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
|
||||||
} else {
|
let key = (ch.signal, channel.to_string());
|
||||||
quote!(())
|
if !dupe.insert(key) {
|
||||||
};
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
g.extend(quote! {
|
let request = if let Some(request) = ch.request {
|
||||||
dma_trait_impl!(#tr, #peri, #channel, #request);
|
let request = request as u8;
|
||||||
});
|
quote!(#request)
|
||||||
|
} else {
|
||||||
|
quote!(())
|
||||||
|
};
|
||||||
|
|
||||||
|
let channel = format_ident!("{}", channel);
|
||||||
|
g.extend(quote! {
|
||||||
|
dma_trait_impl!(#tr, #peri, #channel, #request);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1321,17 +1335,7 @@ fn main() {
|
|||||||
let mut interrupts_table: Vec<Vec<String>> = Vec::new();
|
let mut interrupts_table: Vec<Vec<String>> = Vec::new();
|
||||||
let mut peripherals_table: Vec<Vec<String>> = Vec::new();
|
let mut peripherals_table: Vec<Vec<String>> = Vec::new();
|
||||||
let mut pins_table: Vec<Vec<String>> = Vec::new();
|
let mut pins_table: Vec<Vec<String>> = Vec::new();
|
||||||
let mut adc_common_table: Vec<Vec<String>> = Vec::new();
|
let mut adc_table: Vec<Vec<String>> = Vec::new();
|
||||||
|
|
||||||
/*
|
|
||||||
If ADC3_COMMON exists, ADC3 and higher are assigned to it
|
|
||||||
All other ADCs are assigned to ADC_COMMON
|
|
||||||
|
|
||||||
ADC3 and higher are assigned to the adc34 clock in the table
|
|
||||||
The adc3_common cfg directive is added if ADC3_COMMON exists
|
|
||||||
*/
|
|
||||||
let has_adc3 = METADATA.peripherals.iter().any(|p| p.name == "ADC3_COMMON");
|
|
||||||
let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]);
|
|
||||||
|
|
||||||
for m in METADATA
|
for m in METADATA
|
||||||
.memory
|
.memory
|
||||||
@ -1388,14 +1392,18 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if regs.kind == "adc" {
|
if regs.kind == "adc" {
|
||||||
let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 {
|
let adc_num = p.name.strip_prefix("ADC").unwrap();
|
||||||
("ADC3_COMMON", "adc34")
|
let mut adc_common = None;
|
||||||
} else {
|
for p2 in METADATA.peripherals {
|
||||||
("ADC_COMMON", "adc")
|
if let Some(common_nums) = p2.name.strip_prefix("ADC").and_then(|s| s.strip_suffix("_COMMON")) {
|
||||||
};
|
if common_nums.contains(adc_num) {
|
||||||
|
adc_common = Some(p2);
|
||||||
let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()];
|
}
|
||||||
adc_common_table.push(row);
|
}
|
||||||
|
}
|
||||||
|
let adc_common = adc_common.map(|p| p.name).unwrap_or("none");
|
||||||
|
let row = vec![p.name.to_string(), adc_common.to_string(), "adc".to_string()];
|
||||||
|
adc_table.push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
for irq in p.interrupts {
|
for irq in p.interrupts {
|
||||||
@ -1441,6 +1449,7 @@ fn main() {
|
|||||||
"dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)),
|
"dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)),
|
||||||
"bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)),
|
"bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)),
|
||||||
"gpdma" => quote!(crate::pac::#dma),
|
"gpdma" => quote!(crate::pac::#dma),
|
||||||
|
"lpdma" => quote!(unsafe { crate::pac::gpdma::Gpdma::from_ptr(crate::pac::#dma.as_ptr())}),
|
||||||
_ => panic!("bad dma channel kind {}", bi.kind),
|
_ => panic!("bad dma channel kind {}", bi.kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1448,9 +1457,6 @@ fn main() {
|
|||||||
Some(dmamux) => {
|
Some(dmamux) => {
|
||||||
let dmamux = format_ident!("{}", dmamux);
|
let dmamux = format_ident!("{}", dmamux);
|
||||||
let num = ch.dmamux_channel.unwrap() as usize;
|
let num = ch.dmamux_channel.unwrap() as usize;
|
||||||
|
|
||||||
g.extend(quote!(dmamux_channel_impl!(#name, #dmamux);));
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
dmamux: crate::dma::DmamuxInfo {
|
dmamux: crate::dma::DmamuxInfo {
|
||||||
mux: crate::pac::#dmamux,
|
mux: crate::pac::#dmamux,
|
||||||
@ -1535,17 +1541,19 @@ fn main() {
|
|||||||
make_table(&mut m, "foreach_interrupt", &interrupts_table);
|
make_table(&mut m, "foreach_interrupt", &interrupts_table);
|
||||||
make_table(&mut m, "foreach_peripheral", &peripherals_table);
|
make_table(&mut m, "foreach_peripheral", &peripherals_table);
|
||||||
make_table(&mut m, "foreach_pin", &pins_table);
|
make_table(&mut m, "foreach_pin", &pins_table);
|
||||||
make_table(&mut m, "foreach_adc", &adc_common_table);
|
make_table(&mut m, "foreach_adc", &adc_table);
|
||||||
|
|
||||||
let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string();
|
let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string();
|
||||||
fs::write(out_file, m).unwrap();
|
fs::write(&out_file, m).unwrap();
|
||||||
|
rustfmt(&out_file);
|
||||||
|
|
||||||
// ========
|
// ========
|
||||||
// Write generated.rs
|
// Write generated.rs
|
||||||
|
|
||||||
let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
|
let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
|
||||||
fs::write(out_file, g.to_string()).unwrap();
|
fs::write(&out_file, g.to_string()).unwrap();
|
||||||
|
rustfmt(&out_file);
|
||||||
|
|
||||||
// ========
|
// ========
|
||||||
// Multicore
|
// Multicore
|
||||||
@ -1568,13 +1576,6 @@ fn main() {
|
|||||||
println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core);
|
println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======
|
|
||||||
// ADC3_COMMON is present
|
|
||||||
#[allow(clippy::print_literal)]
|
|
||||||
if has_adc3 {
|
|
||||||
println!("cargo:rustc-cfg={}", "adc3_common");
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======
|
// =======
|
||||||
// Features for targeting groups of chips
|
// Features for targeting groups of chips
|
||||||
|
|
||||||
@ -1667,3 +1668,23 @@ fn get_flash_region_type_name(name: &str) -> String {
|
|||||||
.replace("REGION", "Region")
|
.replace("REGION", "Region")
|
||||||
.replace('_', "")
|
.replace('_', "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// rustfmt a given path.
|
||||||
|
/// Failures are logged to stderr and ignored.
|
||||||
|
fn rustfmt(path: impl AsRef<Path>) {
|
||||||
|
let path = path.as_ref();
|
||||||
|
match Command::new("rustfmt").args([path]).output() {
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("failed to exec rustfmt {:?}: {:?}", path, e);
|
||||||
|
}
|
||||||
|
Ok(out) => {
|
||||||
|
if !out.status.success() {
|
||||||
|
eprintln!("rustfmt {:?} failed:", path);
|
||||||
|
eprintln!("=== STDOUT:");
|
||||||
|
std::io::stderr().write_all(&out.stdout).unwrap();
|
||||||
|
eprintln!("=== STDERR:");
|
||||||
|
std::io::stderr().write_all(&out.stderr).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@ use stm32_metapac::adc::vals::Ckmode;
|
|||||||
use super::blocking_delay_us;
|
use super::blocking_delay_us;
|
||||||
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::peripherals::ADC;
|
use crate::peripherals::ADC1;
|
||||||
use crate::{interrupt, Peripheral};
|
use crate::{interrupt, Peripheral};
|
||||||
|
|
||||||
pub const VDDA_CALIB_MV: u32 = 3300;
|
pub const VDDA_CALIB_MV: u32 = 3300;
|
||||||
@ -36,26 +36,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
|||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
|
|
||||||
#[cfg(not(adc_l0))]
|
#[cfg(not(adc_l0))]
|
||||||
impl AdcPin<ADC> for Vbat {}
|
impl AdcPin<ADC1> for Vbat {}
|
||||||
|
|
||||||
#[cfg(not(adc_l0))]
|
#[cfg(not(adc_l0))]
|
||||||
impl super::SealedAdcPin<ADC> for Vbat {
|
impl super::SealedAdcPin<ADC1> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl AdcPin<ADC> for Vref {}
|
impl AdcPin<ADC1> for Vref {}
|
||||||
impl super::SealedAdcPin<ADC> for Vref {
|
impl super::SealedAdcPin<ADC1> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl AdcPin<ADC> for Temperature {}
|
impl AdcPin<ADC1> for Temperature {}
|
||||||
impl super::SealedAdcPin<ADC> for Temperature {
|
impl super::SealedAdcPin<ADC1> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> {
|
|||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// // Pins may need to be changed for your specific device.
|
/// // Pins may need to be changed for your specific device.
|
||||||
/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC, NoDma, NoDma, p.PA4, p.PA5).split();
|
/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split();
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> {
|
pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> {
|
||||||
ch1: DacChannel<'d, T, 1, DMACh1>,
|
ch1: DacChannel<'d, T, 1, DMACh1>,
|
||||||
|
@ -19,30 +19,6 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait SealedMuxChannel {}
|
|
||||||
|
|
||||||
/// DMAMUX1 instance.
|
|
||||||
pub struct DMAMUX1;
|
|
||||||
/// DMAMUX2 instance.
|
|
||||||
#[cfg(stm32h7)]
|
|
||||||
pub struct DMAMUX2;
|
|
||||||
|
|
||||||
/// DMAMUX channel trait.
|
|
||||||
#[allow(private_bounds)]
|
|
||||||
pub trait MuxChannel: SealedMuxChannel {
|
|
||||||
/// DMAMUX instance this channel is on.
|
|
||||||
type Mux;
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dmamux_channel_impl {
|
|
||||||
($channel_peri:ident, $dmamux:ident) => {
|
|
||||||
impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
|
|
||||||
impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
|
|
||||||
type Mux = crate::dma::$dmamux;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// safety: must be called only once
|
/// safety: must be called only once
|
||||||
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) {
|
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) {
|
||||||
crate::_generated::init_dmamux();
|
crate::_generated::init_dmamux();
|
||||||
|
@ -32,7 +32,7 @@ impl Default for TransferOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WordSize> for vals::ChTr1Dw {
|
impl From<WordSize> for vals::Dw {
|
||||||
fn from(raw: WordSize) -> Self {
|
fn from(raw: WordSize) -> Self {
|
||||||
match raw {
|
match raw {
|
||||||
WordSize::OneByte => Self::BYTE,
|
WordSize::OneByte => Self::BYTE,
|
||||||
@ -235,8 +235,8 @@ impl<'a> Transfer<'a> {
|
|||||||
});
|
});
|
||||||
ch.tr2().write(|w| {
|
ch.tr2().write(|w| {
|
||||||
w.set_dreq(match dir {
|
w.set_dreq(match dir {
|
||||||
Dir::MemoryToPeripheral => vals::ChTr2Dreq::DESTINATIONPERIPHERAL,
|
Dir::MemoryToPeripheral => vals::Dreq::DESTINATIONPERIPHERAL,
|
||||||
Dir::PeripheralToMemory => vals::ChTr2Dreq::SOURCEPERIPHERAL,
|
Dir::PeripheralToMemory => vals::Dreq::SOURCEPERIPHERAL,
|
||||||
});
|
});
|
||||||
w.set_reqsel(request);
|
w.set_reqsel(request);
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ pub use gpdma::*;
|
|||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
mod dmamux;
|
mod dmamux;
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
pub use dmamux::*;
|
pub(crate) use dmamux::*;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
pub(crate) use util::*;
|
pub(crate) use util::*;
|
||||||
|
@ -94,8 +94,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
|
|
||||||
#[cfg(rcc_h5)]
|
#[cfg(rcc_h5)]
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.ahb1enr().modify(|w| {
|
crate::pac::RCC.ahb1enr().modify(|w| {
|
||||||
w.set_ethen(true);
|
w.set_ethen(true);
|
||||||
w.set_ethtxen(true);
|
w.set_ethtxen(true);
|
||||||
@ -161,8 +159,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
|
|
||||||
#[cfg(rcc_h5)]
|
#[cfg(rcc_h5)]
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.ahb1enr().modify(|w| {
|
crate::pac::RCC.ahb1enr().modify(|w| {
|
||||||
w.set_ethen(true);
|
w.set_ethen(true);
|
||||||
w.set_ethtxen(true);
|
w.set_ethtxen(true);
|
||||||
|
@ -36,32 +36,7 @@ macro_rules! dma_trait {
|
|||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! dma_trait_impl {
|
macro_rules! dma_trait_impl {
|
||||||
// DMAMUX
|
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $channel:ident, $request:expr) => {
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
|
|
||||||
impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
|
|
||||||
where
|
|
||||||
T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
|
|
||||||
{
|
|
||||||
fn request(&self) -> crate::dma::Request {
|
|
||||||
$request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// DMAMUX
|
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dma: $dma:ident}, $request:expr) => {
|
|
||||||
impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
|
|
||||||
where
|
|
||||||
T: crate::dma::Channel,
|
|
||||||
{
|
|
||||||
fn request(&self) -> crate::dma::Request {
|
|
||||||
$request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// DMA/GPDMA, without DMAMUX
|
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {channel: $channel:ident}, $request:expr) => {
|
|
||||||
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
|
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
|
||||||
fn request(&self) -> crate::dma::Request {
|
fn request(&self) -> crate::dma::Request {
|
||||||
$request
|
$request
|
||||||
|
@ -299,54 +299,66 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
|
|
||||||
let rtc = config.ls.init();
|
let rtc = config.ls.init();
|
||||||
|
|
||||||
|
// TODO: all this ADC stuff should probably go into the ADC module, not here.
|
||||||
|
// Most STM32s manage ADC clocks in a similar way with ADCx_COMMON.
|
||||||
#[cfg(all(stm32f3, not(rcc_f37)))]
|
#[cfg(all(stm32f3, not(rcc_f37)))]
|
||||||
use crate::pac::adccommon::vals::Ckmode;
|
use crate::pac::adccommon::vals::Ckmode;
|
||||||
|
|
||||||
#[cfg(all(stm32f3, not(rcc_f37)))]
|
#[cfg(all(stm32f3, not(rcc_f37)))]
|
||||||
let adc = match config.adc {
|
let adc = {
|
||||||
AdcClockSource::Pll(adcpres) => {
|
#[cfg(peri_adc1_common)]
|
||||||
RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres));
|
let common = crate::pac::ADC1_COMMON;
|
||||||
crate::pac::ADC_COMMON
|
#[cfg(peri_adc12_common)]
|
||||||
.ccr()
|
let common = crate::pac::ADC12_COMMON;
|
||||||
.modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
|
|
||||||
|
|
||||||
unwrap!(pll) / adcpres
|
match config.adc {
|
||||||
}
|
AdcClockSource::Pll(adcpres) => {
|
||||||
AdcClockSource::Hclk(adcpres) => {
|
RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres));
|
||||||
assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
|
common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
|
||||||
|
|
||||||
let (div, ckmode) = match adcpres {
|
unwrap!(pll) / adcpres
|
||||||
AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
|
}
|
||||||
AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
|
AdcClockSource::Hclk(adcpres) => {
|
||||||
AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
|
assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
|
||||||
};
|
|
||||||
crate::pac::ADC_COMMON.ccr().modify(|w| w.set_ckmode(ckmode));
|
|
||||||
|
|
||||||
hclk / div
|
let (div, ckmode) = match adcpres {
|
||||||
|
AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
|
||||||
|
AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
|
||||||
|
AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
|
||||||
|
};
|
||||||
|
common.ccr().modify(|w| w.set_ckmode(ckmode));
|
||||||
|
|
||||||
|
hclk / div
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
|
#[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
|
||||||
let adc34 = match config.adc34 {
|
let adc34 = {
|
||||||
AdcClockSource::Pll(adcpres) => {
|
#[cfg(peri_adc3_common)]
|
||||||
RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres));
|
let common = crate::pac::ADC3_COMMON;
|
||||||
crate::pac::ADC3_COMMON
|
#[cfg(peri_adc34_common)]
|
||||||
.ccr()
|
let common = crate::pac::ADC34_COMMON;
|
||||||
.modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
|
|
||||||
|
|
||||||
unwrap!(pll) / adcpres
|
match config.adc34 {
|
||||||
}
|
AdcClockSource::Pll(adcpres) => {
|
||||||
AdcClockSource::Hclk(adcpres) => {
|
RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres));
|
||||||
assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
|
common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
|
||||||
|
|
||||||
let (div, ckmode) = match adcpres {
|
unwrap!(pll) / adcpres
|
||||||
AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
|
}
|
||||||
AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
|
AdcClockSource::Hclk(adcpres) => {
|
||||||
AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
|
assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
|
||||||
};
|
|
||||||
crate::pac::ADC3_COMMON.ccr().modify(|w| w.set_ckmode(ckmode));
|
|
||||||
|
|
||||||
hclk / div
|
let (div, ckmode) = match adcpres {
|
||||||
|
AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
|
||||||
|
AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
|
||||||
|
AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
|
||||||
|
};
|
||||||
|
common.ccr().modify(|w| w.set_ckmode(ckmode));
|
||||||
|
|
||||||
|
hclk / div
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::adc::{Adc, SampleTime};
|
use embassy_stm32::adc::{Adc, SampleTime};
|
||||||
use embassy_stm32::peripherals::ADC;
|
use embassy_stm32::peripherals::ADC1;
|
||||||
use embassy_stm32::{adc, bind_interrupts};
|
use embassy_stm32::{adc, bind_interrupts};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
ADC1_COMP => adc::InterruptHandler<ADC>;
|
ADC1_COMP => adc::InterruptHandler<ADC1>;
|
||||||
});
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let mut adc = Adc::new(p.ADC, Irqs);
|
let mut adc = Adc::new(p.ADC1, Irqs);
|
||||||
adc.set_sample_time(SampleTime::CYCLES71_5);
|
adc.set_sample_time(SampleTime::CYCLES71_5);
|
||||||
let mut pin = p.PA1;
|
let mut pin = p.PA1;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
info!("Hello World, dude!");
|
info!("Hello World, dude!");
|
||||||
|
|
||||||
let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4);
|
let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for v in 0..=255 {
|
for v in 0..=255 {
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::adc::{Adc, SampleTime};
|
use embassy_stm32::adc::{Adc, SampleTime};
|
||||||
use embassy_stm32::peripherals::ADC;
|
use embassy_stm32::peripherals::ADC1;
|
||||||
use embassy_stm32::{adc, bind_interrupts};
|
use embassy_stm32::{adc, bind_interrupts};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
ADC1_COMP => adc::InterruptHandler<ADC>;
|
ADC1_COMP => adc::InterruptHandler<ADC1>;
|
||||||
});
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let p = embassy_stm32::init(Default::default());
|
let p = embassy_stm32::init(Default::default());
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let mut adc = Adc::new(p.ADC, Irqs);
|
let mut adc = Adc::new(p.ADC1, Irqs);
|
||||||
adc.set_sample_time(SampleTime::CYCLES79_5);
|
adc.set_sample_time(SampleTime::CYCLES79_5);
|
||||||
let mut pin = p.PA1;
|
let mut pin = p.PA1;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ use micromath::F32Ext;
|
|||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC>;
|
ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC1>;
|
||||||
});
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
|
@ -120,7 +120,7 @@ define_peris!(
|
|||||||
define_peris!(
|
define_peris!(
|
||||||
UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1,
|
UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1,
|
||||||
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
|
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
|
||||||
ADC = ADC1, DAC = DAC, DAC_PIN = PA4,
|
ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
|
||||||
CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1,
|
CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1,
|
||||||
@irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;},
|
@irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;},
|
||||||
);
|
);
|
||||||
@ -128,7 +128,7 @@ define_peris!(
|
|||||||
define_peris!(
|
define_peris!(
|
||||||
UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5,
|
UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5,
|
||||||
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
|
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
|
||||||
ADC = ADC1, DAC = DAC, DAC_PIN = PA4,
|
ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
|
||||||
CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12,
|
CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12,
|
||||||
@irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
|
@irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
|
||||||
);
|
);
|
||||||
@ -210,7 +210,7 @@ define_peris!(
|
|||||||
define_peris!(
|
define_peris!(
|
||||||
UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
|
UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
|
||||||
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
||||||
ADC = ADC, DAC = DAC, DAC_PIN = PA4,
|
ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
|
||||||
@irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
|
@irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
|
||||||
);
|
);
|
||||||
#[cfg(feature = "stm32l552ze")]
|
#[cfg(feature = "stm32l552ze")]
|
||||||
|
Loading…
Reference in New Issue
Block a user