From 154b04767943c5053526c13050ef4b45faee5cb6 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Sun, 29 May 2022 12:42:20 +0800 Subject: [PATCH] add uart example --- .gitignore | 11 +++++++ uart/.cargo/config | 29 ++++++++++++++++ uart/Cargo.toml | 25 ++++++++++++++ uart/memory.x | 23 +++++++++++++ uart/src/main.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 .gitignore create mode 100644 uart/.cargo/config create mode 100644 uart/Cargo.toml create mode 100644 uart/memory.x create mode 100644 uart/src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..054b607 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Generated by Cargo +# will have compiled files and executables +**/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk +**/*.bin \ No newline at end of file diff --git a/uart/.cargo/config b/uart/.cargo/config new file mode 100644 index 0000000..c7a89e4 --- /dev/null +++ b/uart/.cargo/config @@ -0,0 +1,29 @@ +[target.thumbv7m-none-eabi] +# uncomment this to make `cargo run` execute programs on QEMU +# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x openocd.gdb" +# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "gdb -q -x openocd.gdb" + +rustflags = [ + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # if you run into problems with LLD switch to the GNU linker by commenting out + # this line + # "-C", "linker=arm-none-eabi-ld", + + # if you need to link to pre-compiled C libraries provided by a C toolchain + # use GCC as the linker by commenting out both lines above and then + # uncommenting the three lines below + # "-C", "linker=arm-none-eabi-gcc", + # "-C", "link-arg=-Wl,-Tlink.x", + # "-C", "link-arg=-nostartfiles", +] + +[build] +target = "thumbv7em-none-eabihf" \ No newline at end of file diff --git a/uart/Cargo.toml b/uart/Cargo.toml new file mode 100644 index 0000000..80ae096 --- /dev/null +++ b/uart/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "uart" +version = "0.1.0" +edition = "2021" +readme = "README.md" +authors = ["guozhanxin "] + +[dependencies] +cortex-m = "0.7" +cortex-m-rt = "0.6.5" +panic-halt = "0.2.0" +panic-semihosting = "0.6.0" +cortex-m-semihosting = "0.5.0" +stm32l4xx-hal = { version = "0.6.0", features = ["rt", "stm32l4x2"] } +nb = "1.0.0" + +[profile.dev] +opt-level = 1 +debug = true +lto = false + +[profile.release] +opt-level = "s" # optimize for size +debug = true # symbols are nice and they don't increase the size on Flash +lto = true # better optimizations \ No newline at end of file diff --git a/uart/memory.x b/uart/memory.x new file mode 100644 index 0000000..092bcea --- /dev/null +++ b/uart/memory.x @@ -0,0 +1,23 @@ +MEMORY +{ + /* NOTE K = KiBi = 1024 bytes */ + /* TODO Adjust these memory regions to match your device memory layout */ + FLASH : ORIGIN = 0x8000000, LENGTH = 128K + RAM : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* You may want to use this variable to locate the call stack and static + variables in different memory regions. Below is shown the default value */ +/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ + +/* You can use this symbol to customize the location of the .text section */ +/* If omitted the .text section will be placed right after the .vector_table + section */ +/* This is required only on microcontrollers that store some configuration right + after the vector table */ +/* _stext = ORIGIN(FLASH) + 0x400; */ + +/* Size of the heap (in bytes) */ +/* _heap_size = 1024; */ \ No newline at end of file diff --git a/uart/src/main.rs b/uart/src/main.rs new file mode 100644 index 0000000..d9d6052 --- /dev/null +++ b/uart/src/main.rs @@ -0,0 +1,82 @@ +//! Test the serial interface +//! +//! This example requires you to short (connect) the TX and RX pins. +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +extern crate cortex_m; +#[macro_use(entry, exception)] +extern crate cortex_m_rt as rt; +#[macro_use(block)] +extern crate nb; +extern crate panic_semihosting; + +extern crate stm32l4xx_hal as hal; +// #[macro_use(block)] +// extern crate nb; + +use crate::hal::prelude::*; +use crate::hal::serial::{Config, Serial}; +use crate::rt::ExceptionFrame; +// use cortex_m::asm; + +#[entry] +fn main() -> ! { + let p = hal::stm32::Peripherals::take().unwrap(); + + let mut flash = p.FLASH.constrain(); + let mut rcc = p.RCC.constrain(); + let mut pwr = p.PWR.constrain(&mut rcc.apb1r1); + + let mut gpioa = p.GPIOA.split(&mut rcc.ahb2); + // let mut gpiob = p.GPIOB.split(&mut rcc.ahb2); + + // clock configuration using the default settings (all clocks run at 8 MHz) + // let clocks = rcc.cfgr.freeze(&mut flash.acr); + // TRY this alternate clock configuration (clocks run at nearly the maximum frequency) + let clocks = rcc + .cfgr + .sysclk(80.mhz()) + .pclk1(80.mhz()) + .pclk2(80.mhz()) + .freeze(&mut flash.acr, &mut pwr); + + // The Serial API is highly generic + // TRY the commented out, different pin configurations + // let tx = gpioa.pa9.into_af7(&mut gpioa.moder, &mut gpioa.afrh); + let tx = gpioa.pa2.into_af7(&mut gpioa.moder, &mut gpioa.afrl); + // let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl); + + // let rx = gpioa.pa10.into_af7(&mut gpioa.moder, &mut gpioa.afrh); + let rx = gpioa.pa3.into_af7(&mut gpioa.moder, &mut gpioa.afrl); + // let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl); + + // TRY using a different USART peripheral here + let serial = Serial::usart2( + p.USART2, + (tx, rx), + Config::default().baudrate(115_200.bps()), + clocks, + &mut rcc.apb1r1, + ); + + // serial.listen(serial::Event::Rxne); + let (mut tx, mut rx) = serial.split(); + + // core::fmt::Write is implemented for tx. + // writeln!(tx, "Hello, world!").unwrap(); + + loop { + // Echo what is received on the serial link. + let received = block!(rx.read()).unwrap(); + block!(tx.write(received)).ok(); + } + +} + +#[exception] +fn HardFault(ef: &ExceptionFrame) -> ! { + panic!("{:#?}", ef); +} \ No newline at end of file