Skip to content

Commit

Permalink
enhance(spi): impl half-duplex spi
Browse files Browse the repository at this point in the history
  • Loading branch information
andelf committed Dec 20, 2024
1 parent ce135a4 commit d9e693d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
14 changes: 6 additions & 8 deletions examples/hpm5300evk/src/bin/qspi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,14 +282,12 @@ fn main() -> ! {
// PA10
let mut led = Output::new(p.PA10, Level::Low, Speed::Fast);

let spi_config = Config {
frequency: Hertz(40_000_000),
mode: MODE_0,
timing: Timings {
cs2sclk: hpm_hal::spi::Cs2Sclk::_1HalfSclk,
csht: hpm_hal::spi::CsHighTime::_8HalfSclk,
},
..Default::default()
let mut spi_config = Config::default();
spi_config.frequency = Hertz(40_000_000);
spi_config.mode = MODE_0;
spi_config.timing = Timings {
cs2sclk: hpm_hal::spi::Cs2Sclk::_1HalfSclk,
csht: hpm_hal::spi::CsHighTime::_8HalfSclk,
};

let spi: hal::spi::Spi<'_, Blocking> =
Expand Down
72 changes: 71 additions & 1 deletion src/spi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ pub struct Config {
pub frequency: Hertz,
/// Timings
pub timing: Timings,
/// Half duplex mode, only MOSI is used.
pub half_duplex: bool,
}

impl Default for Config {
Expand All @@ -151,6 +153,7 @@ impl Default for Config {
mode: MODE_0,
frequency: Hertz(10_000_000),
timing: Timings::default(),
half_duplex: false,
}
}
}
Expand Down Expand Up @@ -253,6 +256,36 @@ impl<'d> Spi<'d, Blocking> {
)
}

pub fn new_blocking_half_duplex<T: Instance>(
peri: impl Peripheral<P = T> + 'd,
sclk: impl Peripheral<P = impl SclkPin<T>> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
mut config: Config,
) -> Self {
into_ref!(sclk, mosi);

T::add_resource_group(0);

mosi.set_as_alt(mosi.alt_num());
sclk.ioc_pad().func_ctl().modify(|w| {
w.set_alt_select(sclk.alt_num());
w.set_loop_back(true);
});
config.half_duplex = true;

Self::new_inner(
peri,
Some(sclk.map_into()),
Some(mosi.map_into()),
None,
None,
None,
None,
None,
config,
)
}

pub fn new_blocking_rxonly<T: Instance>(
peri: impl Peripheral<P = T> + 'd,
sclk: impl Peripheral<P = impl SclkPin<T>> + 'd,
Expand Down Expand Up @@ -406,6 +439,39 @@ impl<'d> Spi<'d, Async> {
)
}

pub fn new_half_duplex<T: Instance>(
peri: impl Peripheral<P = T> + 'd,
sclk: impl Peripheral<P = impl SclkPin<T>> + 'd,
mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
mut config: Config,
) -> Self {
into_ref!(sclk, mosi);

T::add_resource_group(0);

mosi.set_as_alt(mosi.alt_num());
sclk.ioc_pad().func_ctl().modify(|w| {
w.set_alt_select(sclk.alt_num());
w.set_loop_back(true);
});

config.half_duplex = true;

Self::new_inner(
peri,
Some(sclk.map_into()),
Some(mosi.map_into()),
None,
None,
None,
new_dma!(tx_dma),
new_dma!(rx_dma),
config,
)
}

pub fn new_rxonly<T: Instance>(
peri: impl Peripheral<P = T> + 'd,
sclk: impl Peripheral<P = impl SclkPin<T>> + 'd,
Expand Down Expand Up @@ -690,7 +756,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
// 32 bit data length only works when the data is 32bit aligned
w.set_datalen(<u8 as SealedWord>::CONFIG);
w.set_datamerge(false);
w.set_mosibidir(false);
if config.half_duplex {
w.set_mosibidir(true);
} else {
w.set_mosibidir(false);
}
w.set_lsb(config.bit_order == BitOrder::LsbFirst);
w.set_slvmode(false); // default master mode
w.set_cpha(cpha);
Expand Down

0 comments on commit d9e693d

Please sign in to comment.