From 52da592ec11c0e3b0404988c81f879e24ed09769 Mon Sep 17 00:00:00 2001 From: Levi Pearson Date: Tue, 7 Jul 2020 22:55:16 -0600 Subject: [PATCH] Initial commit --- .cargo/config | 25 +++++++++++++++++++++++ .gdbinit | 6 ++++++ .gitignore | 1 + Cargo.toml | 39 +++++++++++++++++++++++++++++++++++ memory.x | 32 +++++++++++++++++++++++++++++ openocd.cfg | 12 +++++++++++ src/main.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 171 insertions(+) create mode 100644 .cargo/config create mode 100644 .gdbinit create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 memory.x create mode 100644 openocd.cfg create mode 100644 src/main.rs diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..c77c017 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,25 @@ +[target.thumbv7m-none-eabi] +# 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" +# 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 = "thumbv7m-none-eabi" # Cortex-M3 diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..7c72d4f --- /dev/null +++ b/.gdbinit @@ -0,0 +1,6 @@ +target remote :3333 + +monitor arm semihosting enable + +load +step diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a551fd4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "blue_pill_base" +version = "0.1.0" +authors = ["Levi Pearson "] +description = "Base binary crate for STM32F103 Blue Pill boards" +categories = ["embedded", "no-std"] +edition = "2018" + +[dependencies] +cortex-m = "0.6.2" +cortex-m-rt = "0.6.12" +#cortex-m-semihosting = "0.3.5" +# alternate panic impls, choose only one! +panic-halt = "0.2.0" +#panic-semihosting = "0.5.3" # requires cortex-m-semihosting +#panic-itm = "0.4.1" +#panic-abort = "0.3.2" +#panic-ramdump = "0.1.1" +#panic-persist = "0.2.1" +embedded-hal = "0.2.3" +nb = "0.1.2" + +[dependencies.stm32f1] +version = "0.10.0" +features = ["stm32f103", "rt"] + +[dependencies.stm32f1xx-hal] +version = "0.5.3" +features = ["rt", "stm32f103", "medium"] + +[[bin]] +name = "blue_pill_base" +test = false +bench = false + +[profile.release] +lto = true +codegen-units = 1 +debug = true diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..6a7b3b2 --- /dev/null +++ b/memory.x @@ -0,0 +1,32 @@ +MEMORY +{ + /* NOTE 1 K = 1 KiBi = 1024 bytes */ + FLASH : ORIGIN = 0x08000000, LENGTH = 64K + RAM : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* 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; */ + +/* Example of putting non-initialized variables into custom RAM locations. */ +/* This assumes you have defined a region RAM2 above, and in the Rust + sources added the attribute `#[link_section = ".ram2bss"]` to the data + you want to place there. */ +/* Note that the section will not be zero-initialized by the runtime! */ +/* SECTIONS { + .ram2bss (NOLOAD) : ALIGN(4) { + *(.ram2bss); + . = ALIGN(4); + } > RAM2 + } INSERT AFTER .bss; +*/ diff --git a/openocd.cfg b/openocd.cfg new file mode 100644 index 0000000..88b2e9c --- /dev/null +++ b/openocd.cfg @@ -0,0 +1,12 @@ +# Sample OpenOCD configuration for the blue pill board + +# Depending on the hardware revision you got you'll have to pick ONE of these +# interfaces. At any time only one interface should be commented out. + +# Revision C (newer revision) +# source [find interface/stlink-v2-1.cfg] + +# Revision A and B (older revisions) +source [find interface/stlink-v2.cfg] + +source [find target/stm32f1x.cfg] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..7b224e7 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,56 @@ +//! Blinks an LED +//! +//! This assumes that a LED is connected to pc13 as is the case on the blue pill board. +//! +//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of +//! the reference manual for an explanation. This is not an issue on the blue pill. + +#![deny(unsafe_code)] +#![no_std] +#![no_main] + +use panic_halt as _; + +use nb::block; + +use stm32f1xx_hal::{ + prelude::*, + pac, + timer::Timer, +}; +use cortex_m_rt::entry; +use embedded_hal::digital::v2::OutputPin; + +#[entry] +fn main() -> ! { + // Get access to the core peripherals from the cortex-m crate + let cp = cortex_m::Peripherals::take().unwrap(); + // Get access to the device specific peripherals from the peripheral access crate + let dp = pac::Peripherals::take().unwrap(); + + // Take ownership over the raw flash and rcc devices and convert them into the corresponding + // HAL structs + let mut flash = dp.FLASH.constrain(); + let mut rcc = dp.RCC.constrain(); + + // Freeze the configuration of all the clocks in the system and store the frozen frequencies in + // `clocks` + let clocks = rcc.cfgr.freeze(&mut flash.acr); + + // Acquire the GPIOC peripheral + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + + // Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function + // in order to configure the port. For pins 0-7, crl should be passed instead. + let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); + // Configure the syst timer to trigger an update every second + let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); + + // Wait for the timer to trigger an update and change the state of the LED + loop { + block!(timer.wait()).unwrap(); + led.set_high().unwrap(); + block!(timer.wait()).unwrap(); + led.set_low().unwrap(); + } +}