Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions embassy-mspm0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ build = [
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1345dgs28", "time-driver-any"]},
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1106dgs28", "time-driver-any"]},
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1228pt", "time-driver-any"]},
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1306rhb", "time-driver-any", "executor-thread"]},
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1306rhb", "time-driver-any", "executor-interrupt"]},
{target = "thumbv6m-none-eabi", features = ["defmt", "mspm0l1306rhb", "time-driver-any", "executor-thread", "executor-interrupt"]},
]

[package.metadata.embassy_docs]
Expand All @@ -47,6 +50,7 @@ rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
embassy-sync = { version = "0.8.0", path = "../embassy-sync" }
embassy-executor = { version = "0.10.0", path = "../embassy-executor", optional = true }
# TODO: Support other tick rates
embassy-time-driver = { version = "0.2.2", path = "../embassy-time-driver", optional = true, features = ["tick-hz-32_768"] }
embassy-time-queue-utils = { version = "0.3.2", path = "../embassy-time-queue-utils", optional = true }
Expand All @@ -70,7 +74,7 @@ critical-section = "1.2.0"
micromath = "2.0.0"

# mspm0-metapac = { version = "" }
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-1da5eda11bf1ae69a604ba62df6242884df15d68" }
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-f78bc71fcc6d74b25c2cae58220d8bf443fb12df" }
rand_core = "0.9"
# Force no cache padding or the types are too large.
maitake-sync = { version = "0.3.0", default-features = false, features = ["critical-section", "no-cache-pad"]}
Expand All @@ -84,7 +88,7 @@ quote = "1.0.40"
cfg_aliases = "0.2.1"

# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-1da5eda11bf1ae69a604ba62df6242884df15d68", default-features = false, features = ["metadata"] }
mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-f78bc71fcc6d74b25c2cae58220d8bf443fb12df", default-features = false, features = ["metadata"] }

[features]
default = ["rt"]
Expand Down Expand Up @@ -116,6 +120,14 @@ nrst-pin-as-gpio = []
## Allow using the SWD pins as regular GPIO pins.
swd-pins-as-gpio = []

low-power = []

executor-thread = ["_executor"]

executor-interrupt = ["_executor"]

_executor = ["dep:embassy-executor", "low-power"]

#! ## Time

# Features starting with `_` are for internal use only. They're not intended
Expand Down
60 changes: 55 additions & 5 deletions embassy-mspm0/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::sync::LazyLock;
use std::{env, fs};

use common::CfgSet;
use mspm0_metapac::metadata::{ALL_CHIPS, METADATA};
use mspm0_metapac::metadata::{ALL_CHIPS, METADATA, PowerDomain};
use proc_macro2::{Ident, Literal, Span, TokenStream};
use quote::{format_ident, quote};

Expand Down Expand Up @@ -67,6 +67,7 @@ fn generate_code(cfgs: &mut CfgSet) {
g.extend(generate_timers());
g.extend(generate_interrupts());
g.extend(generate_peripheral_instances());
g.extend(generate_power_domains(&singletons));
g.extend(generate_pin_trait_impls());
g.extend(generate_groups());
g.extend(generate_dma_channel_count());
Expand Down Expand Up @@ -202,11 +203,11 @@ fn generate_groups() -> TokenStream {
let stat = group.iidx().read().stat();

// check for spurious interrupts
if stat == crate::pac::cpuss::vals::Iidx::NO_INTR {
if stat == crate::pac::cpuss::vals::Iidx::NoIntr {
return;
}

// MUST subtract by 1 because NO_INTR offsets IIDX values.
// MUST subtract by 1 because NoIntr offsets IIDX values.
let iidx = stat.to_bits() - 1;

let Ok(group) = #group_enum::try_from(iidx as u8) else {
Expand Down Expand Up @@ -672,16 +673,65 @@ fn generate_interrupts() -> TokenStream {
}
}

fn power_domain_ident(domain: &PowerDomain) -> Ident {
format_ident!(
"{}",
match domain {
PowerDomain::Pd0 => "Pd0",
PowerDomain::Pd1 => "Pd1",
PowerDomain::Backup => "Backup",
}
)
}

/// Implement `PowerDomainInstance` for every peripheral singleton.
///
/// Driven off the singleton list rather than the metadata so it cannot emit an impl for a type
/// `get_singletons` decided not to create.
fn generate_power_domains(singletons: &[Singleton]) -> TokenStream {
let impls = singletons.iter().filter_map(|singleton| {
let name = singleton.name.as_str();

// A pin's domain says nothing useful: GPIO logic is in PD0 on every chip.
if METADATA.pins.iter().any(|pin| pin.pin == name) {
return None;
}

// Singletons without a metadata entry of their own inherit from the peripheral they belong to.
let owner = match name {
"CLK_OUT" => "SYSCTL",
_ if name.starts_with("DMA_CH") => "DMA",
_ => name,
};

let domain = METADATA
.peripherals
.iter()
.find(|peripheral| peripheral.name == owner)
.map(|peripheral| power_domain_ident(&peripheral.power_domain))
.unwrap_or_else(|| panic!("no power domain for singleton {name} (looked for peripheral {owner})"));

let peri = format_ident!("{}", name);

Some(quote! { impl_power_domain!(#peri, #domain); })
});

quote! {
#(#impls)*
}
}

fn generate_peripheral_instances() -> TokenStream {
let mut impls = Vec::<TokenStream>::new();

for peripheral in METADATA.peripherals {
let peri = format_ident!("{}", peripheral.name);
let fifo_size = peripheral.sys_fentries;
let power_domain = power_domain_ident(&peripheral.power_domain);

let tokens = match peripheral.kind {
"uart" => Some(quote! { impl_uart_instance!(#peri); }),
"i2c" => Some(quote! { impl_i2c_instance!(#peri, #fifo_size); }),
"uart" => Some(quote! { impl_uart_instance!(#peri, #power_domain); }),
"i2c" => Some(quote! { impl_i2c_instance!(#peri, #fifo_size, #power_domain); }),
"wwdt" => Some(quote! { impl_wwdt_instance!(#peri); }),
"adc" => Some(quote! { impl_adc_instance!(#peri); }),
"mathacl" => Some(quote! { impl_mathacl_instance!(#peri); }),
Expand Down
60 changes: 29 additions & 31 deletions embassy-mspm0/src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
});

r.ctl1().modify(|w| {
w.set_sc(vals::Sc::START);
w.set_sc(vals::Sc::Start);
});

// Wait for conversion
Expand Down Expand Up @@ -297,7 +297,7 @@ impl<'d, T: Instance> Adc<'d, T, Async> {
});

r.ctl1().modify(|w| {
w.set_sc(vals::Sc::START);
w.set_sc(vals::Sc::Start);
});

Self::wait_for_conversion().await;
Expand Down Expand Up @@ -344,7 +344,7 @@ impl<'d, T: Instance> Adc<'d, T, Async> {
});

r.ctl1().modify(|w| {
w.set_sc(vals::Sc::START);
w.set_sc(vals::Sc::Start);
});

Self::wait_for_conversion().await;
Expand Down Expand Up @@ -432,41 +432,41 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
r.gprcm(0).rstctl().write(|w| {
w.set_resetstkyclr(true);
w.set_resetassert(true);
w.set_key(vals::ResetKey::KEY);
w.set_key(vals::ResetKey::Key);
});

r.gprcm(0).pwren().modify(|reg| {
reg.set_enable(true);
reg.set_key(vals::PwrenKey::KEY);
reg.set_key(vals::PwrenKey::Key);
});

// Wait for power up
cortex_m::asm::delay(16);

r.gprcm(0).clkcfg().write(|w| {
w.set_key(vals::ClkcfgKey::KEY);
w.set_sampclk(vals::Sampclk::SYSOSC);
w.set_key(vals::ClkcfgKey::Key);
w.set_sampclk(vals::Sampclk::Sysosc);
});

// FIXME: Consider clock config
// This code assumes the 24/32 MHz boot frequency
r.ctl0().write(|w| {
w.set_enc(false);
// TODO: power down config
w.set_pwrdn(vals::Pwrdn::MANUAL);
w.set_sclkdiv(vals::Sclkdiv::DIV_BY_4);
w.set_pwrdn(vals::Pwrdn::Manual);
w.set_sclkdiv(vals::Sclkdiv::DivBy4);
});

r.clkfreq().write(|w| {
w.set_frange(vals::Frange::RANGE24TO32);
w.set_frange(vals::Frange::Range24to32);
});

r.ctl1().write(|w| {
w.set_trigsrc(vals::Trigsrc::SOFTWARE);
w.set_sc(vals::Sc::STOP);
w.set_conseq(vals::Conseq::SEQUENCE);
w.set_sampmode(vals::Sampmode::AUTO);
w.set_avgn(vals::Avgn::DISABLE);
w.set_trigsrc(vals::Trigsrc::Software);
w.set_sc(vals::Sc::Stop);
w.set_conseq(vals::Conseq::Sequence);
w.set_sampmode(vals::Sampmode::Auto);
w.set_avgn(vals::Avgn::Disable);
w.set_avgd(0);
});

Expand All @@ -477,7 +477,7 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
w.set_rstsampcapen(false);
w.set_dmaen(false);
w.set_fifoen(false);
w.set_sampcnt(vals::Sampcnt::MIN);
w.set_sampcnt(vals::Sampcnt::Min);
w.set_startadd(0);
w.set_endadd(0);
});
Expand Down Expand Up @@ -510,7 +510,7 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
// TODO: More parameters
w.set_avgen(false);
w.set_bcsen(false);
w.set_trig(vals::Trig::AUTO_NEXT);
w.set_trig(vals::Trig::AutoNext);
w.set_wincomp(false);
});
}
Expand All @@ -525,15 +525,13 @@ impl<'d, T: Instance, M: Mode> Adc<'d, T, M> {
#[inline]
fn wait_for_conversion() -> impl Future<Output = ()> {
let r = T::info().regs;
let state = T::state();

poll_fn(move |cx| {
state.waker.register(cx.waker());

if !r.ctl0().read().enc() {
Poll::Ready(())
} else {
if r.ctl0().read().enc() {
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
})
}
Expand Down Expand Up @@ -576,26 +574,26 @@ trait SealedBorrowedChannel<'a, T> {

const fn to_res(resolution: Resolution) -> vals::Res {
match resolution {
Resolution::Bits12 => vals::Res::BIT_12,
Resolution::Bits10 => vals::Res::BIT_10,
Resolution::Bits8 => vals::Res::BIT_8,
Resolution::Bits12 => vals::Res::Bit12,
Resolution::Bits10 => vals::Res::Bit10,
Resolution::Bits8 => vals::Res::Bit8,
}
}

const fn from_res(res: vals::Res) -> Resolution {
match res {
vals::Res::BIT_12 => Resolution::Bits12,
vals::Res::BIT_10 => Resolution::Bits10,
vals::Res::BIT_8 => Resolution::Bits8,
vals::Res::Bit12 => Resolution::Bits12,
vals::Res::Bit10 => Resolution::Bits10,
vals::Res::Bit8 => Resolution::Bits8,
// SAFETY: The HAL will never program an invalid valid.
vals::Res::_RESERVED_3 => unsafe { unreachable_unchecked() },
}
}

const fn convert_stime(stime: SampleTimeComparator) -> vals::Stime {
match stime {
SampleTimeComparator::Scomp0 => vals::Stime::SEL_SCOMP0,
SampleTimeComparator::Scomp1 => vals::Stime::SEL_SCOMP1,
SampleTimeComparator::Scomp0 => vals::Stime::SelScomp0,
SampleTimeComparator::Scomp1 => vals::Stime::SelScomp1,
}
}

Expand Down
Loading