Skip to content

MSPM0: update mspm0-metapac & internal temperature sensor - #6732

Open
bespsm wants to merge 4 commits into
embassy-rs:mainfrom
bespsm:MSPM0-INT-TEMPERATURE
Open

MSPM0: update mspm0-metapac & internal temperature sensor#6732
bespsm wants to merge 4 commits into
embassy-rs:mainfrom
bespsm:MSPM0-INT-TEMPERATURE

Conversation

@bespsm

@bespsm bespsm commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I had to update "mspm0-metapac" because only the latest version has "FACTORYREGION" peripheral.
The typing style changes come with with mspm0-metapac (cherry-picked from @CordlessCoder ).

Changes:

  • Update mspm0-metapac to mspm0-data-f78bc71
  • Update mspm0-metapac to mspm0-data-4be4996
  • mspm0: add internal temperature sensor channel
  • mspm0: add internal temperature sensor example for g3507

Running on g3507 showed following print:

[INFO ] Temperature: 28.652153 C, 83.573875 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 28.652153 C, 83.573875 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 29.101437 C, 84.38258 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)    <--- here I started applying hair dryer :smile: 
[INFO ] Temperature: 29.101437 C, 84.38258 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 29.550718 C, 85.19129 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 30.0 C, 86.0 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 31.339369 C, 88.41086 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 32.237934 C, 90.028275 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 33.5773 C, 92.43914 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 34.925148 C, 94.865265 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
[INFO ] Temperature: 36.26452 C, 97.27613 F (adc_temp_sensor src/bin/adc_temp_sensor.rs:66)
...
```

@bespsm
bespsm force-pushed the MSPM0-INT-TEMPERATURE branch 2 times, most recently from 02d27fc to b1b9c99 Compare August 6, 2026 21:51
@CordlessCoder

Copy link
Copy Markdown
Contributor

Just so we don't end up accidentally duplicating work, I'm currently working on a very large set of low-power improvements in my mspm0-low-power branch
Here's the rough overview of where it's at:

Breaking changes

  • sysctl::clocks() replaces MCLK_HZ / ULPCLK_HZ.
  • tim::ClockSel::frequency takes a Clocks.
  • I2C addresses are an Address enum, so a bare integer literal needs a u8 suffix.
  • atomics-critical-section is a default feature; the alternative needs default-features = false.
  • A time-driver-* feature without rt is now a compile_error! instead of a wait that never completes.

Done

Low power

  • Deep sleep on every chip family — it used to fail to compile on families with no hand-written entry
    sequence.
  • sysctl::SleepLevel, low_power::enter_sleep, per-instance retention metadata, and a WakeGuard
    drivers hold to keep the chip shallower than a given level.
  • Wake from a GPIO edge, from UART receive, and from a wake-capable pin in SHUTDOWN.
  • Config::min_sleep: fall back to a plain WFI when the wake is too soon to pay for a deep sleep.

Clocks

  • Configurable tree via Config::clock, reported by sysctl::clocks(), solved in a const fn — an
    out-of-range tree fails to compile.
  • HFXT and the SYSPLL, so G-series parts reach 80 MHz.

I2C

  • Fault handling rewritten, fixing the root cause of MSPM0(I2C): Add FIFO flush for Sync I2C controller to prevent stale data on NACK/error paths #6633. Superset of the merged fix, and the rebase conflict is already resolved.
  • No unbounded wait anywhere, and a cancelled async transfer no longer locks up I2C.
  • New: Config::clock_low_timeout_us, Error::NackAddress / NackData, Error::BusStuck with
    recover_stuck_bus.
  • 10-bit addressing in controller and target, plus a second target address with a mask.

GPIO

  • The maitake-sync wait map is replaced by a per-port waiter list. A GPIO wake costs half the latency it did, and the dependency is gone.

Timers

  • New low-level, PWM (edge- and centre-aligned), input capture and output compare drivers.
  • The time driver moved onto the shared timer configuration, and supports 32-bit timers.

UART

  • Both flush paths returned before the hardware had drained.
  • Baud dividers solved in a const fn, in 32-bit arithmetic — which also fixes a panic above 67.1 MHz.

Build and metadata

  • Per-device facts — SYSCTL and timer capabilities, errata applicability, flash wait states, ADC and TRNG
    clock ranges — come from the metapac and the errata sheets rather than hand-written chip-family lists.
    An unrecognised peripheral version is a build error, not a silently reduced feature set.
  • rand_core moved to 0.10.
  • unsafe-atomics-single-core, emulating atomic read-modify-writes inline instead of through
    critical-section.

Examples

Around 20 new ones, plus two new low-power example crates.

@bespsm

bespsm commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Just so we don't end up accidentally duplicating work, I'm currently working on a very large set of low-power improvements in my mspm0-low-power branch Here's the rough overview of where it's at:

Breaking changes

* `sysctl::clocks()` replaces `MCLK_HZ` / `ULPCLK_HZ`.

* `tim::ClockSel::frequency` takes a `Clocks`.

* I2C addresses are an `Address` enum, so a bare integer literal needs a `u8` suffix.

* `atomics-critical-section` is a default feature; the alternative needs `default-features = false`.

* A `time-driver-*` feature without `rt` is now a `compile_error!` instead of a wait that never completes.

Done

Low power

* Deep sleep on every chip family — it used to fail to compile on families with no hand-written entry
  sequence.

* `sysctl::SleepLevel`, `low_power::enter_sleep`, per-instance retention metadata, and a `WakeGuard`
  drivers hold to keep the chip shallower than a given level.

* Wake from a GPIO edge, from UART receive, and from a wake-capable pin in SHUTDOWN.

* `Config::min_sleep`: fall back to a plain `WFI` when the wake is too soon to pay for a deep sleep.

Clocks

* Configurable tree via `Config::clock`, reported by `sysctl::clocks()`, solved in a `const fn` — an
  out-of-range tree fails to compile.

* HFXT and the SYSPLL, so G-series parts reach 80 MHz.

I2C

* Fault handling rewritten, fixing the root cause of [MSPM0(I2C): Add FIFO flush for Sync I2C controller to prevent stale data on NACK/error paths #6633](https://github.com/embassy-rs/embassy/pull/6633). Superset of the merged fix, and the rebase conflict is already resolved.

* No unbounded wait anywhere, and a cancelled async transfer no longer locks up I2C.

* New: `Config::clock_low_timeout_us`, `Error::NackAddress` / `NackData`, `Error::BusStuck` with
  `recover_stuck_bus`.

* 10-bit addressing in controller and target, plus a second target address with a mask.

GPIO

* The `maitake-sync` wait map is replaced by a per-port waiter list. **A GPIO wake costs half the latency it did**, and the dependency is gone.

Timers

* New low-level, PWM (edge- and centre-aligned), input capture and output compare drivers.

* The time driver moved onto the shared timer configuration, and supports 32-bit timers.

UART

* Both flush paths returned before the hardware had drained.

* Baud dividers solved in a `const fn`, in 32-bit arithmetic — which also fixes a panic above 67.1 MHz.

Build and metadata

* Per-device facts — SYSCTL and timer capabilities, errata applicability, flash wait states, ADC and TRNG
  clock ranges — come from the metapac and the errata sheets rather than hand-written chip-family lists.
  An unrecognised peripheral version is a build error, not a silently reduced feature set.

* `rand_core` moved to 0.10.

* `unsafe-atomics-single-core`, emulating atomic read-modify-writes inline instead of through
  `critical-section`.

Examples

Around 20 new ones, plus two new low-power example crates.

Thank you for the informing. I don't see any duplicate work so far

@leftger leftger added the e-mspm0 Issues for the MSPM0 family of chips label Aug 6, 2026
CordlessCoder and others added 4 commits August 7, 2026 00:14
chiptool now generates register values in PascalCase rather than
SCREAMING_SNAKE, and emits the key/index fieldsets as newtypes carrying
associated constants instead of enums.

No functional change.
Add `TempSensorChannel`, an `AdcChannel` for the internal temperature
sensor, and `read_temp_calibration_constant()` for the factory trim
constant used to convert its readings to a temperature.

The sensor is present on every supported family, but the ADC0 channel it
is connected to is device specific (11, 28 or 29 per SysConfig's
SYS_TEMP_SENSE_CHANNEL), so gate both on a new `temp_sensor` cfg and
select the channel per family.
Port TI's `adc12_internal_temp_sensor_mathacl` example, converting the
sensor reading to degrees Celsius and Fahrenheit with MATHACL.
@bespsm
bespsm force-pushed the MSPM0-INT-TEMPERATURE branch from b1b9c99 to e3ce638 Compare August 6, 2026 22:14
@bespsm

bespsm commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

@i509VCB @CordlessCoder sorry for bothering you guys, just a kind reminder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e-mspm0 Issues for the MSPM0 family of chips

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants