Skip to content

Commit 76a51eb

Browse files
committed
Add USDHC1 SD card support for Teensy 4.1
Configure USDHC1 root clock and expose the peripheral: - Configure USDHC1 root clock (PLL2_PFD2 / 2 = 198 MHz) - Add USDHC1 clock gate to CLOCK_GATES - Add USDHC1_FREQUENCY constant - Add usdhc1 instance to board Resources
1 parent c4f94a5 commit 76a51eb

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Unreleased
44

5+
Add USDHC1 clock configuration and expose the USDHC1 peripheral instance
6+
in board resources. The BSP configures the USDHC1 root clock to 198 MHz
7+
(PLL2_PFD2 / 2) and publishes this as `USDHC1_FREQUENCY`. Pin muxing and
8+
driver initialization are left to the caller.
9+
510
### [0.5.2] 2026-03-10
611

712
Add LPUART5 and LPUART7 aliases, resources, to teensy4-bsp.

src/board.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ pub struct Resources<Pins> {
299299
pub sai3: ral::sai::SAI3,
300300
/// The IOMUXC general purpose register block.
301301
pub iomuxc_gpr: ral::iomuxc_gpr::IOMUXC_GPR,
302+
/// The USDHC1 peripheral instance.
303+
pub usdhc1: ral::usdhc::USDHC1,
302304
}
303305

304306
/// The board's dedicated LED.
@@ -689,6 +691,7 @@ fn prepare_resources<Pins>(
689691
sai2: instances.SAI2,
690692
sai3: instances.SAI3,
691693
iomuxc_gpr: instances.IOMUXC_GPR,
694+
usdhc1: instances.USDHC1,
692695
}
693696
}
694697

src/clock_power.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ const CLOCK_GATES: &[clock_gate::Locator] = &[
267267
clock_gate::sai::<1>(),
268268
clock_gate::sai::<2>(),
269269
clock_gate::sai::<3>(),
270+
clock_gate::usdhc::<1>(),
270271
];
271272

272273
/// Prepare clocks and power for the MCU.
@@ -289,8 +290,29 @@ pub fn prepare_clocks_and_power(
289290
setup_uart_clk(ccm);
290291
setup_audio_pll(ccm_analog);
291292
setup_sai1_clk(ccm);
293+
setup_usdhc1_clk(ccm);
292294

293295
CLOCK_GATES
294296
.iter()
295297
.for_each(|locator| locator.set(ccm, clock_gate::ON));
296298
}
299+
300+
/// USDHC1 root clock frequency (Hz).
301+
///
302+
/// PLL2_PFD2 (396 MHz) / 2 = 198 MHz. The actual SD bus clock is
303+
/// further divided by the USDHC1 peripheral's internal SDCLKFS and
304+
/// DVS dividers during card initialization.
305+
pub const USDHC1_FREQUENCY: u32 = 198_000_000;
306+
307+
/// Configure the USDHC1 clock root for the SD card slot.
308+
///
309+
/// Source: PLL2_PFD2 (396 MHz), divider: /2 → 198 MHz root clock.
310+
///
311+
/// PLL2 (528 MHz) and its PFD2 output (396 MHz) are initialized by the
312+
/// Teensy bootloader before transferring control to user code. This
313+
/// function assumes PLL2_PFD2 is already running and stable.
314+
fn setup_usdhc1_clk(ccm: &mut ral::ccm::CCM) {
315+
clock_gate::usdhc::<1>().set(ccm, clock_gate::OFF);
316+
ral::modify_reg!(ral::ccm, ccm, CSCMR1, USDHC1_CLK_SEL: 0); // PLL2_PFD2
317+
ral::modify_reg!(ral::ccm, ccm, CSCDR1, USDHC1_PODF: 1); // divide by 2
318+
}

0 commit comments

Comments
 (0)