Skip to content

Commit

Permalink
Add stm32l4r9 support (#270)
Browse files Browse the repository at this point in the history
* src/dma.rs: disable `cselr` for stm32l4+

The stm32l4+ devices do not have this register,
but use a separate peripheral (DMAMUX) for routing between
peripherals and DMA controllers.

* src/rcc/enable.rs: fix some issues for stm32l4+

* src/i2c.rs: define stm32l4+ pins

* src/spi.rs: add `unsafe` where required by stm32l4r9 PAC.

To make this implementation also usable by stm32l4+ devices,
some additional use of `unsafe` is necessary because of PAC differences.

* src/timer.rs: disable creation of TIM4 for stm32l4+ because of PAC error.

In the current release of the stm32l4 PAC,
the `cnt` register of TIM3 and tim4 have an incorrect width.
This was fixed in stm32-rs#669, once this is included in the next
release, we will be able to start using TIM3 and TIM4.

* Create module dmamux.rs as common interface for DMA request mapping.

The new stm32l4+ devices use a separate peripheral (DMAMUX) for routing
a DMA request line between peripherals and DMA controllers, whereas the
"old" stm32l4 devices use the `CSELR` register for request mapping.
This module tries to abstract this difference, and provides a common
interface for all L4 devices.
This commit also enable the DMAMUX clock when required.

* Use new dmamux interface in adc.rs, serial.rs and spi.rs

* src/lib.rs: enable most modules for stm32l4+ devices as well
  • Loading branch information
jspngh authored Mar 1, 2022
1 parent c3b68e8 commit f93b505
Show file tree
Hide file tree
Showing 9 changed files with 794 additions and 59 deletions.
3 changes: 2 additions & 1 deletion src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::{

use crate::{
dma::{dma1, Event as DMAEvent, RxDma, Transfer, TransferPayload, W},
dmamux::{DmaInput, DmaMux},
gpio::{self, Analog},
hal::{
adc::{Channel as EmbeddedHalChannel, OneShot},
Expand Down Expand Up @@ -526,7 +527,7 @@ where
channel.set_memory_address(buffer.as_ptr() as u32, true);
channel.set_transfer_length(N as u16);

channel.cselr().modify(|_, w| w.c1s().bits(0b0000));
channel.set_request_line(DmaInput::Adc1).unwrap();

channel.ccr().modify(|_, w| unsafe {
w.mem2mem()
Expand Down
22 changes: 22 additions & 0 deletions src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,16 @@ macro_rules! dma {
unsafe { &(*$DMAX::ptr()).$cmarX }
}

#[cfg(not(any(
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9"
)))]
#[inline]
pub(crate) fn cselr(&mut self) -> &dma1::CSELR {
unsafe { &(*$DMAX::ptr()).cselr }
Expand Down Expand Up @@ -1072,6 +1082,18 @@ macro_rules! dma {
fn split(self, ahb: &mut AHB1) -> Channels {
<$DMAX>::enable(ahb);

#[cfg(any(
// feature = "stm32l4p5",
// feature = "stm32l4q5",
// feature = "stm32l4r5",
// feature = "stm32l4s5",
// feature = "stm32l4r7",
// feature = "stm32l4s7",
feature = "stm32l4r9",
feature = "stm32l4s9"
))]
ahb.enr().modify(|_, w| w.dmamux1en().set_bit());

// reset the DMA control registers (stops all on-going transfers)
$(
self.$ccrX.reset();
Expand Down
Loading

0 comments on commit f93b505

Please sign in to comment.