Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: stm32-rs/stm32l4xx-hal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: TwoStoryRobot/stm32l4xx-hal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 8 commits
  • 5 files changed
  • 2 contributors

Commits on Jun 23, 2021

  1. Implement LPUART1 for STM32L476.

    (cherry picked from commit 1cf3332)
    romixlab committed Jun 23, 2021
    Copy the full SHA
    51218a6 View commit details
  2. Fix LPUART1 baud rate calculation.

    (cherry picked from commit 3a1b7be)
    romixlab committed Jun 23, 2021
    Copy the full SHA
    80a83bc View commit details
  3. Copy the full SHA
    f655a95 View commit details

Commits on Aug 9, 2022

  1. Copy the full SHA
    0273aed View commit details
  2. Copy the full SHA
    ef432ab View commit details

Commits on Aug 20, 2022

  1. Copy the full SHA
    920778a View commit details

Commits on Jan 13, 2023

  1. Make sure LPUART1 works on stm32l431/3

    Also implements LSE as clock source
    calebissharp committed Jan 13, 2023

    Verified

    This commit was signed with the committer’s verified signature.
    calebissharp Caleb Sharp
    Copy the full SHA
    fc95b7e View commit details

Commits on Jan 20, 2023

  1. Verified

    This commit was signed with the committer’s verified signature.
    calebissharp Caleb Sharp
    Copy the full SHA
    3f6c41e View commit details
Showing with 276 additions and 47 deletions.
  1. +4 −0 Cargo.toml
  2. +110 −0 examples/serial_lpuart1_rtic.rs
  3. +40 −2 src/rcc.rs
  4. +121 −44 src/serial.rs
  5. +1 −1 src/spi.rs
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -203,3 +203,7 @@ required-features = ["rt"]
[[example]]
name = "adc_dma"
required-features = ["rt"]

[[example]]
name = "serial_lpuart1_rtic"
required-features = ["rt", "stm32l476"]
110 changes: 110 additions & 0 deletions examples/serial_lpuart1_rtic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![no_main]
#![no_std]

extern crate panic_rtt_target;

use heapless::{consts::U8, spsc};
use nb::block;
use rtt_target::{rprint, rprintln};
use stm32l4xx_hal::{
pac::{self, LPUART1},
prelude::*,
serial::{self, Config, Serial},
};

#[rtic::app(device = stm32l4xx_hal::pac)]
const APP: () = {
struct Resources {
rx: serial::Rx<LPUART1>,
tx: serial::Tx<LPUART1>,
//
// rx_prod: spsc::Producer<'static, u8, U8>,
// rx_cons: spsc::Consumer<'static, u8, U8>,
}

#[init]
fn init(_: init::Context) -> init::LateResources {
static mut RX_QUEUE: spsc::Queue<u8, U8> = spsc::Queue(heapless::i::Queue::new());

rtt_target::rtt_init_print!();
rprint!("Initializing... ");

let p = pac::Peripherals::take().unwrap();

let mut rcc = p.RCC.constrain();
let mut flash = p.FLASH.constrain();
let mut pwr = p.PWR.constrain(&mut rcc.apb1r1);

let clocks = rcc.cfgr.freeze(&mut flash.acr, &mut pwr);

let mut gpioa = p.GPIOA.split(&mut rcc.ahb2);
let mut gpioc = p.GPIOC.split(&mut rcc.ahb2);

let tx_pin = gpioc
.pc1
.into_alternate(&mut gpioc.moder, &mut gpioc.otyper, &mut gpioc.afrl);
let rx_pin = gpioc
.pc0
.into_alternate(&mut gpioc.moder, &mut gpioc.otyper, &mut gpioc.afrl);

let mut serial = Serial::lpuart1(
p.LPUART1,
(tx_pin, rx_pin),
Config::default().baudrate(115_200.bps()),
clocks,
&mut rcc.apb1r2,
);
serial.listen(serial::Event::Rxne);

let (tx, rx) = serial.split();
let (rx_prod, rx_cons) = RX_QUEUE.split();

rprintln!("done.");

init::LateResources {
rx,
tx,
//
// rx_prod,
// rx_cons,
}
}

#[idle(resources = [tx])]
fn idle(cx: idle::Context) -> ! {
// let rx = cx.resources.rx_cons;
let tx = cx.resources.tx;

loop {
// if let Some(b) = rx.dequeue() {
// rprintln!("Echoing '{}'", b as char);
// block!(tx.write(b)).unwrap();
// }
block!(tx.write('x' as u8)).unwrap();
cortex_m::asm::delay(1_000_000);
}
}

#[task(binds = LPUART1, resources = [rx])]
fn usart2(cx: usart2::Context) {
let rx = cx.resources.rx;
// let queue = cx.resources.rx_prod;

let b = match rx.read() {
Ok(b) => {
rprintln!("Read: {}", b);
},
Err(err) => {
rprintln!("Error reading from USART: {:?}", err);
return;
}
};
// match queue.enqueue(b) {
// Ok(()) => (),
// Err(err) => {
// rprintln!("Error adding received byte to queue: {:?}", err);
// return;
// }
// }
}
};
42 changes: 40 additions & 2 deletions src/rcc.rs
Original file line number Diff line number Diff line change
@@ -89,6 +89,7 @@ impl RccExt for RCC {
sysclk: None,
pll_source: None,
pll_config: None,
lpuart1_src: LpUart1ClockSource::Pclk,
},
}
}
@@ -158,6 +159,14 @@ impl CRRCR {
}
}

#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum LpUart1ClockSource {
Pclk = 0b00,
Sysclk = 0b01,
Hsi16 = 0b10,
Lse = 0b11,
}

/// Peripherals independent clock configuration register
pub struct CCIPR {
_0: (),
@@ -355,6 +364,7 @@ pub struct CFGR {
sysclk: Option<u32>,
pll_source: Option<PllSource>,
pll_config: Option<PllConfig>,
lpuart1_src: LpUart1ClockSource,
}

impl CFGR {
@@ -431,6 +441,12 @@ impl CFGR {
self
}

/// Sets LPUART1 clock source
pub fn lpuart1_clk_src(mut self, source: LpUart1ClockSource) -> Self {
self.lpuart1_src = source;
self
}

/// Freezes the clock configuration, making it effective
pub fn freeze(&self, acr: &mut ACR, pwr: &mut Pwr) -> Clocks {
let rcc = unsafe { &*RCC::ptr() };
@@ -608,8 +624,24 @@ impl CFGR {
};

// Check if HSI should be started
if pll_source == PllSource::HSI16 || (self.msi.is_none() && self.hse.is_none()) {
rcc.cr.write(|w| w.hsion().set_bit());
let lpuart1_clk_from_hsi = match self.lpuart1_src {
LpUart1ClockSource::Hsi16 => {
rcc.ccipr
.modify(|_, w| unsafe { w.lpuart1sel().bits(self.lpuart1_src as u8) });
true
}
LpUart1ClockSource::Lse => {
rcc.ccipr
.modify(|_, w| unsafe { w.lpuart1sel().bits(self.lpuart1_src as u8) });
false
}
_ => false,
};
if pll_source == PllSource::HSI16
|| (self.msi.is_none() && self.hse.is_none())
|| lpuart1_clk_from_hsi
{
rcc.cr.modify(|_, w| w.hsion().set_bit());
while rcc.cr.read().hsirdy().bit_is_clear() {}
}

@@ -819,6 +851,7 @@ impl CFGR {
timclk1: timclk1.Hz(),
timclk2: timclk2.Hz(),
pll_source: pllconf.map(|_| pll_source),
lpuart1_src: self.lpuart1_src,
}
}
}
@@ -918,6 +951,7 @@ pub struct Clocks {
timclk1: Hertz,
timclk2: Hertz,
pll_source: Option<PllSource>,
lpuart1_src: LpUart1ClockSource,
}

impl Clocks {
@@ -986,4 +1020,8 @@ impl Clocks {
pub fn timclk2(&self) -> Hertz {
self.timclk2
}

pub fn lpuart1_src(&self) -> LpUart1ClockSource {
self.lpuart1_src
}
}
Loading