Skip to content
Merged
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
2 changes: 2 additions & 0 deletions src/chips/mimxrt633s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ embassy_hal_internal::peripherals!(
PIO7_29,
PIO7_30,
PIO7_31,
PIOFC15_SCL,
PIOFC15_SDA,
PMC_PMIC,
PIMCTL,
POWERQUAD,
Expand Down
2 changes: 2 additions & 0 deletions src/chips/mimxrt685s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ embassy_hal_internal::peripherals!(
PIO7_29,
PIO7_30,
PIO7_31,
PIOFC15_SCL,
PIOFC15_SDA,
PMC_PMIC,
PIMCTL,
POWERQUAD,
Expand Down
135 changes: 115 additions & 20 deletions src/flexcomm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use paste::paste;

use crate::clocks::{enable_and_reset, SysconPeripheral};
use crate::pac;
use crate::peripherals::{FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7};
use crate::peripherals::{
FLEXCOMM0, FLEXCOMM1, FLEXCOMM14, FLEXCOMM15, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7,
};

/// clock selection option
#[derive(Copy, Clone, Debug)]
Expand All @@ -22,8 +24,17 @@ pub enum Clock {
/// MASTER
Master,

/// `FCn_FRG`
FcnFrg,
/// FCn_FRG with Main clock source
FcnFrgMain,

/// FCn_FRG with Pll clock source
FcnFrgPll,

/// FCn_FRG with Sfro clock source
FcnFrgSfro,

/// FCn_FRG with Ffro clock source
FcnFrgFfro,

/// disabled
None,
Expand Down Expand Up @@ -70,17 +81,20 @@ macro_rules! impl_flexcomm {
Clock::Ffro => w.sel().ffro_clk(),
Clock::AudioPll => w.sel().audio_pll_clk(),
Clock::Master => w.sel().master_clk(),
Clock::FcnFrg => w.sel().fcn_frg_clk(),
Clock::None => w.sel().none(),
});
Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
Clock::None => w.sel().none(), // no clock? throw an error?
});
clkctl1.flexcomm($idx).frgclksel().write(|w| match clk {
Clock::Sfro => w.sel().sfro_clk(),
Clock::Ffro => w.sel().ffro_clk(),
Clock::AudioPll => w.sel().frg_pll_clk(),
Clock::Master => w.sel().main_clk(),
Clock::FcnFrg => w.sel().frg_pll_clk(),
Clock::None => w.sel().none(),
Clock::FcnFrgMain => w.sel().main_clk(),
Clock::FcnFrgPll => w.sel().frg_pll_clk(),
Clock::FcnFrgSfro => w.sel().sfro_clk(),
Clock::FcnFrgFfro => w.sel().ffro_clk(),
_ => w.sel().none(), // not using frg ...
});
// todo: add support for frg div/mult
clkctl1
.flexcomm($idx)
.frgctl()
Expand All @@ -98,6 +112,89 @@ macro_rules! impl_flexcomm {

impl_flexcomm!(0, 1, 2, 3, 4, 5, 6, 7);

// TODO: FLEXCOMM 14 is untested. Enable SPI support on FLEXCOMM14
// Add special case FLEXCOMM14
impl sealed::Sealed for crate::peripherals::FLEXCOMM14 {}
Comment thread
sukomath marked this conversation as resolved.

impl FlexcommLowLevel for crate::peripherals::FLEXCOMM14 {
fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock {
// SAFETY: safe from single executor, enforce
// via peripheral reference lifetime tracking
unsafe { &*crate::pac::Flexcomm14::ptr() }
}

fn enable(clk: Clock) {
// SAFETY: safe from single executor
let clkctl1 = unsafe { crate::pac::Clkctl1::steal() };

clkctl1.fc14fclksel().write(|w| match clk {
Clock::Sfro => w.sel().sfro_clk(),
Clock::Ffro => w.sel().ffro_clk(),
Clock::AudioPll => w.sel().audio_pll_clk(),
Clock::Master => w.sel().master_clk(),
Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
Clock::None => w.sel().none(), // no clock? throw an error?
});
clkctl1.frg14clksel().write(|w| match clk {
Clock::FcnFrgMain => w.sel().main_clk(),
Clock::FcnFrgPll => w.sel().frg_pll_clk(),
Clock::FcnFrgSfro => w.sel().sfro_clk(),
Clock::FcnFrgFfro => w.sel().ffro_clk(),
_ => w.sel().none(), // not using frg ...
});
// todo: add support for frg div/mult
clkctl1.frg14ctl().write(|w|
// SAFETY: unsafe only used for .bits() call
unsafe { w.mult().bits(0) });

enable_and_reset::<FLEXCOMM14>();
}
}

// Add special case FLEXCOMM15
impl sealed::Sealed for crate::peripherals::FLEXCOMM15 {}

impl FlexcommLowLevel for crate::peripherals::FLEXCOMM15 {
fn reg() -> &'static crate::pac::flexcomm0::RegisterBlock {
// SAFETY: safe from single executor, enforce
// via peripheral reference lifetime tracking
unsafe { &*crate::pac::Flexcomm15::ptr() }
}

fn enable(clk: Clock) {
// SAFETY: safe from single executor
let clkctl1 = unsafe { crate::pac::Clkctl1::steal() };

clkctl1.fc15fclksel().write(|w| match clk {
Clock::Sfro => w.sel().sfro_clk(),
Clock::Ffro => w.sel().ffro_clk(),
Clock::AudioPll => w.sel().audio_pll_clk(),
Clock::Master => w.sel().master_clk(),
Clock::FcnFrgMain => w.sel().fcn_frg_clk(),
Clock::FcnFrgPll => w.sel().fcn_frg_clk(),
Clock::FcnFrgSfro => w.sel().fcn_frg_clk(),
Clock::FcnFrgFfro => w.sel().fcn_frg_clk(),
Clock::None => w.sel().none(), // no clock? throw an error?
});
clkctl1.frg15clksel().write(|w| match clk {
Clock::FcnFrgMain => w.sel().main_clk(),
Clock::FcnFrgPll => w.sel().frg_pll_clk(),
Clock::FcnFrgSfro => w.sel().sfro_clk(),
Clock::FcnFrgFfro => w.sel().ffro_clk(),
_ => w.sel().none(), // not using frg ...
});
// todo: add support for frg div/mult
clkctl1.frg15ctl().write(|w|
// SAFETY: unsafe only used for .bits() call
unsafe { w.mult().bits(0) });

enable_and_reset::<FLEXCOMM15>();
}
}

macro_rules! declare_into_mode {
($mode:ident) => {
paste! {
Expand Down Expand Up @@ -130,13 +227,15 @@ macro_rules! impl_into_mode {
declare_into_mode!(usart);
impl_into_mode!(usart, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7);

// REVISIT: Add support for FLEXCOMM14
declare_into_mode!(spi);
impl_into_mode!(spi, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7);
impl_into_mode!(
spi, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM14
);

// REVISIT: Add support for FLEXCOMM15
declare_into_mode!(i2c);
impl_into_mode!(i2c, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7);
impl_into_mode!(
i2c, FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7, FLEXCOMM15
);

declare_into_mode!(i2s_transmit);
impl_into_mode!(
Expand All @@ -163,7 +262,3 @@ impl_into_mode!(
FLEXCOMM6,
FLEXCOMM7
);

// TODO: in follow up flexcomm PR, implement special FC14 + FC15 support
//impl_flexcomm!(14, FLEXCOMM14, Flexcomm14, I2c14, Spi14, I2s14);
//impl_flexcomm!(15, FLEXCOMM15, Flexcomm15, I2c15, Sp157, I2s15);
62 changes: 38 additions & 24 deletions src/i2c/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,34 +97,42 @@ pub trait Instance: crate::flexcomm::IntoI2c + SealedInstance + Peripheral<P = S

macro_rules! impl_instance {
($($n:expr),*) => {
$(
paste!{
impl SealedInstance for crate::peripherals::[<FLEXCOMM $n>] {
fn info() -> Info {
Info {
regs: unsafe { &*crate::pac::[<I2c $n>]::ptr() },
index: $n,
}
}


#[inline]
fn index() -> usize {
$n
}
}

impl Instance for crate::peripherals::[<FLEXCOMM $n>] {
type Interrupt = crate::interrupt::typelevel::[<FLEXCOMM $n>];
}
}
)*
$(
paste!{
impl SealedInstance for crate::peripherals::[<FLEXCOMM $n>] {
fn info() -> Info {
let mut info_index = $n;
if $n == 15 {
info_index = 8;
}

Info {
regs: unsafe { &*crate::pac::[<I2c $n>]::ptr() },
index: info_index,
}
}


#[inline]
fn index() -> usize {
if $n == 15 {
return 8
}
$n
}
}

impl Instance for crate::peripherals::[<FLEXCOMM $n>] {
type Interrupt = crate::interrupt::typelevel::[<FLEXCOMM $n>];
}
}
)*
};
}

impl_instance!(0, 1, 2, 3, 4, 5, 6, 7);
impl_instance!(0, 1, 2, 3, 4, 5, 6, 7, 15);

const I2C_COUNT: usize = 8;
const I2C_COUNT: usize = 9;
static I2C_WAKERS: [AtomicWaker; I2C_COUNT] = [const { AtomicWaker::new() }; I2C_COUNT];

/// Ten bit addresses start with first byte 0b11110XXX
Expand Down Expand Up @@ -293,6 +301,12 @@ impl_sda!(PIO4_2, F1, FLEXCOMM7);
impl_sda!(PIO4_3, F1, FLEXCOMM7);
impl_scl!(PIO4_4, F1, FLEXCOMM7);

// Flexcomm15 GPIOs
// Function configuration is not needed for FC15
// Implementing SCL/SDA traits to use the I2C APIs
impl_scl!(PIOFC15_SCL, F1, FLEXCOMM15);
impl_sda!(PIOFC15_SDA, F1, FLEXCOMM15);

/// I2C Master DMA trait.
#[allow(private_bounds)]
pub trait MasterDma<T: Instance>: dma::Instance {}
Expand Down
Loading