diff --git a/.cargo/config.toml b/.cargo/config.toml index d4a01da..07574cf 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,33 +1,10 @@ -[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" +[build] +target = "thumbv7em-none-eabihf" -[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" +[target.thumbv7em-none-eabihf] +# Using probe-rs for flashing +runner = "probe-rs run --chip STM32F469NIx" 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", + "-C", "link-arg=-Tlink.x", ] - -[build] -# Pick ONE of these compilation targets -# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ -# target = "thumbv7m-none-eabi" # Cortex-M3 -target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) -# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) diff --git a/Cargo.lock b/Cargo.lock index e9cc5fa..ac813e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +[[package]] +name = "panic-halt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11" + [[package]] name = "panic-probe" version = "1.0.0" @@ -385,6 +391,7 @@ dependencies = [ "defmt", "defmt-rtt", "embedded-hal 1.0.0", + "panic-halt", "panic-probe", "stm32f4xx-hal", ] diff --git a/Cargo.toml b/Cargo.toml index e8740b6..b844ebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,16 @@ embedded-hal = "1.0.0" defmt-rtt = "1.1.0" defmt = "1.0.1" panic-probe = {version = "1.0.0", features = ["print-defmt"]} +panic-halt = "1.0.0" [dependencies.stm32f4xx-hal] version = "0.23.0" features = ["stm32f469"] +[features] +default = [] +ccmram = [] + [[bin]] name = "stm32f469ni" test = false diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..b7f5305 --- /dev/null +++ b/build.rs @@ -0,0 +1,19 @@ +// I totally understand this and it's not copied from +// https://github.com/cyang812/rust_stm32f469i/blob/main/led_blinky/ +// hehe +use std::env; +use std::fs; +use std::path::PathBuf; + +fn main() { + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + fs::write(out.join("memory.x"), include_bytes!("memory.x")).unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // Only link CCM script when the feature is enabled. + // Enable with: cargo build --features ccmram + if env::var_os("CARGO_FEATURE_CCMRAM").is_some() { + fs::write(out.join("ccmram.x"), include_bytes!("ccmram.x")).unwrap(); + println!("cargo:rustc-link-arg=-Tccmram.x"); + } +} diff --git a/ccmram.x b/ccmram.x new file mode 100644 index 0000000..3bafd68 --- /dev/null +++ b/ccmram.x @@ -0,0 +1,10 @@ +/* Extra linker script to place data into CCM SRAM */ +SECTIONS +{ + .ccmram (NOLOAD) : + { + . = ALIGN(4); + *(.ccmram .ccmram.*) + . = ALIGN(4); + } > CCMRAM +} INSERT AFTER .rodata; diff --git a/memory.x b/memory.x index 10fc16b..40e7dd0 100644 --- a/memory.x +++ b/memory.x @@ -1,37 +1,12 @@ +/* Memory layout of the STM32F469NI */ MEMORY { - /* NOTE 1 K = 1 KiBi = 1024 bytes */ - - /* STM32F302R8T6 from STM32F302R8Tx_FLASH.ld in the STM32Cube archive */ - /* or the reference doc at */ - /* https://www.st.com/en/microcontrollers-microprocessors/stm32f302.html#resource */ - - FLASH : ORIGIN = 0x08000000, LENGTH = 2M - RAM : ORIGIN = 0x20000000, LENGTH = 320k + FLASH : ORIGIN = 0x08000000, LENGTH = 2048K + RAM : ORIGIN = 0x20000000, LENGTH = 256K + /* Core Coupled Memory (CCM) SRAM: 128KB at 0x10000000 */ + CCMRAM : ORIGIN = 0x10000000, LENGTH = 128K } /* 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; -*/ +/* The stack is of the full size of the RAM, minus the size of the .data section */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/src/main.rs b/src/main.rs index 0c027a4..d519383 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use cortex_m_rt::entry; use defmt_rtt as _; use hal::prelude::*; use panic_probe as _; -use stm32f4xx_hal as hal; +use stm32f4xx_hal::{self as hal, ltdc::DisplayController}; defmt::timestamp!("{=u32}", 0u32); @@ -14,6 +14,7 @@ fn main() -> ! { let mut rcc = peripherals.RCC.constrain(); let ltdc = peripherals.LTDC; let dma2d = peripherals.DMA2D; + let display_config = hal::ltdc::DisplayConfig { active_width: 480, active_height: 800, @@ -30,7 +31,7 @@ fn main() -> ! { pixel_clock_pol: false, }; - let display = hal::ltdc::DisplayController::new( + let mut display: DisplayController = hal::ltdc::DisplayController::new( ltdc, dma2d, None, @@ -39,11 +40,26 @@ fn main() -> ! { None, ); + display.draw_pixel(hal::ltdc::Layer::L1, 50, 50, 1); + let gpiog = peripherals.GPIOG.split(&mut rcc); + let gpiod = peripherals.GPIOD.split(&mut rcc); let mut led1 = gpiog.pg6.into_push_pull_output(); + let mut led2 = gpiod.pd4.into_push_pull_output(); - led1.set_high(); + led1.set_low(); + led2.set_low(); - loop {} + loop { + for _ in 0..100000 { + led1.set_low(); + led2.set_high(); + } + + for _ in 0..100000 { + led1.set_high(); + led2.set_low(); + } + } }