Skip to content
Open
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
1 change: 1 addition & 0 deletions embassy-mspm0/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- fix: feature guard pins used for NRST and SWD (#5257)
- feat: Move from GPIO waker arrays to maitake-sync wait map
- fix: Flush the I2C controller FIFOs on the NACK/error paths, to prevent stale data
- feat: Add `TempSensorChannel` and `read_temp_calibration_constant()` for the internal temperature sensor
4 changes: 2 additions & 2 deletions embassy-mspm0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,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-4be499610ef6e0d40ab18a5d362171e9a07310e1" }
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 @@ -88,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-4be499610ef6e0d40ab18a5d362171e9a07310e1", default-features = false, features = ["metadata"] }

[features]
default = ["rt"]
Expand Down
27 changes: 25 additions & 2 deletions embassy-mspm0/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,29 @@ fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
cfgs.push("mspm0l222x".to_string());
}

// Devices with an internal temperature sensor, see `TEMP_SENSOR_CHANNEL` in `adc.rs`.
const TEMP_SENSOR_FAMILIES: &[&str] = &[
"mspm0c110x",
"mspm0c1105_c1106",
"mspm0g110x",
"mspm0g150x",
"mspm0g151x",
"mspm0g310x",
"mspm0g350x",
"mspm0g351x",
"mspm0g518x",
"mspm0h321x",
"mspm0l110x",
"mspm0l122x",
"mspm0l130x",
"mspm0l134x",
"mspm0l222x",
];

if cfgs.iter().any(|cfg| TEMP_SENSOR_FAMILIES.contains(&cfg.as_str())) {
cfgs.push("temp_sensor".to_string());
}

cfgs
}

Expand Down Expand Up @@ -202,11 +225,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
82 changes: 57 additions & 25 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 Down Expand Up @@ -576,26 +576,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 Expand Up @@ -641,3 +641,35 @@ macro_rules! impl_adc_pin {
}
};
}

/// The ADC0 channel the temperature sensor is connected to.
///
/// See `SYS_TEMP_SENSE_CHANNEL` in the device specific data sheet. ADC1 uses a different
/// channel (12 on the G-series), which is not exposed.
#[cfg(any(
mspm0c110x, mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0l110x, mspm0l130x,
mspm0l134x
))]
const TEMP_SENSOR_CHANNEL: u8 = 11;

#[cfg(any(mspm0c1105_c1106, mspm0h321x))]
const TEMP_SENSOR_CHANNEL: u8 = 28;

#[cfg(any(mspm0g518x, mspm0l122x, mspm0l222x))]
const TEMP_SENSOR_CHANNEL: u8 = 29;

/// Internal temperature sensor channel.
///
/// Uses an internal ADC0 channel, no external pin is required. It can be sampled like a
/// regular [`AdcChannel`].
#[cfg(temp_sensor)]
pub struct TempSensorChannel;

#[cfg(temp_sensor)]
impl crate::adc::AdcChannel<crate::peripherals::ADC0> for TempSensorChannel {}
#[cfg(temp_sensor)]
impl crate::adc::SealedAdcChannel<crate::peripherals::ADC0> for TempSensorChannel {
fn channel(&self) -> u8 {
TEMP_SENSOR_CHANNEL
}
}
36 changes: 18 additions & 18 deletions embassy-mspm0/src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub trait Word: SealedWord + 'static {

impl SealedWord for u8 {
fn width() -> vals::Wdth {
vals::Wdth::BYTE
vals::Wdth::Byte
}
}
impl Word for u8 {
Expand All @@ -213,7 +213,7 @@ impl Word for u8 {

impl SealedWord for u16 {
fn width() -> vals::Wdth {
vals::Wdth::HALF
vals::Wdth::Half
}
}
impl Word for u16 {
Expand All @@ -224,7 +224,7 @@ impl Word for u16 {

impl SealedWord for u32 {
fn width() -> vals::Wdth {
vals::Wdth::WORD
vals::Wdth::Word
}
}
impl Word for u32 {
Expand All @@ -235,7 +235,7 @@ impl Word for u32 {

impl SealedWord for u64 {
fn width() -> vals::Wdth {
vals::Wdth::LONG
vals::Wdth::Long
}
}
impl Word for u64 {
Expand Down Expand Up @@ -399,17 +399,17 @@ fn verify_transfer<W: Word>(ptr: *const [W]) -> Result<(), Error> {

fn convert_burst_size(value: BurstSize) -> vals::Burstsz {
match value {
BurstSize::Complete => vals::Burstsz::INFINITI,
BurstSize::_8 => vals::Burstsz::BURST_8,
BurstSize::_16 => vals::Burstsz::BURST_16,
BurstSize::_32 => vals::Burstsz::BURST_32,
BurstSize::Complete => vals::Burstsz::Infiniti,
BurstSize::_8 => vals::Burstsz::Burst8,
BurstSize::_16 => vals::Burstsz::Burst16,
BurstSize::_32 => vals::Burstsz::Burst32,
}
}

fn convert_mode(mode: TransferMode) -> vals::Tm {
match mode {
TransferMode::Single => vals::Tm::SINGLE,
TransferMode::Block => vals::Tm::BLOCK,
TransferMode::Single => vals::Tm::Single,
TransferMode::Block => vals::Tm::Block,
}
}

Expand Down Expand Up @@ -517,30 +517,30 @@ impl<'d> Channel<'d> {
w.set_req(false);

// Not every part supports auto enable, so force its value to 0.
w.set_autoen(Autoen::NONE);
w.set_preirq(Preirq::PREIRQ_DISABLE);
w.set_autoen(Autoen::None);
w.set_preirq(Preirq::PreirqDisable);
w.set_srcwdth(src_wdth);
w.set_dstwdth(dst_wdth);
w.set_srcincr(if increment_src {
Incr::INCREMENT
Incr::Increment
} else {
Incr::UNCHANGED
Incr::Unchanged
});
w.set_dstincr(if increment_dst {
Incr::INCREMENT
Incr::Increment
} else {
Incr::UNCHANGED
Incr::Unchanged
});

w.set_em(Em::NORMAL);
w.set_em(Em::Normal);
// Single and block will clear the enable bit when the transfers finish.
w.set_tm(convert_mode(options.mode));
});

self.tctl().write(|w| {
w.set_tsel(trigger_sel);
// Basic channels do not implement cross triggering.
w.set_tint(vals::Tint::EXTERNAL);
w.set_tint(vals::Tint::External);
});

self.sz().write(|w| {
Expand Down
12 changes: 6 additions & 6 deletions embassy-mspm0/src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,19 +318,19 @@ impl<'d> Flex<'d> {
// Per https://tweedegolf.nl/en/blog/235/debloat-your-async-rust
//
// We match the async pass-through suggestion to reduce async bloat.
self.wait_inner(Polarity::RISE)
self.wait_inner(Polarity::Rise)
}

/// Wait for the pin to undergo a transition from high to low.
#[inline]
pub fn wait_for_falling_edge(&mut self) -> impl Future<Output = ()> {
self.wait_inner(Polarity::FALL)
self.wait_inner(Polarity::Fall)
}

/// Wait for the pin to undergo any transition, i.e low to high OR high to low.
#[inline]
pub fn wait_for_any_edge(&mut self) -> impl Future<Output = ()> {
self.wait_inner(Polarity::RISE_FALL)
self.wait_inner(Polarity::RiseFall)
}

async fn wait_inner(&mut self, polarity: Polarity) {
Expand Down Expand Up @@ -1029,17 +1029,17 @@ pub(crate) fn init(gpio: gpio::Gpio) {
gpio.gprcm().rstctl().write(|w| {
w.set_resetstkyclr(true);
w.set_resetassert(true);
w.set_key(ResetKey::KEY);
w.set_key(ResetKey::Key);
});

gpio.gprcm().pwren().write(|w| {
w.set_enable(true);
w.set_key(PwrenKey::KEY);
w.set_key(PwrenKey::Key);
});

gpio.evt_mode().modify(|w| {
// The CPU will clear it's own interrupts
w.set_cpu_cfg(EvtCfg::SOFTWARE);
w.set_cpu_cfg(EvtCfg::Software);
});
}

Expand Down
Loading