Compare commits
14 Commits
6b2fd0e61b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a76ebdbeb | |||
| 53c97dcb32 | |||
| 1f3162dc6f | |||
| 6e1c5370ba | |||
| 34b11fb262 | |||
| 7ad309d78d | |||
| 711ec0f93f | |||
|
|
ac02415275 | ||
|
|
6aa25500e6 | ||
|
|
0f9748a5e1 | ||
|
|
a34dd4f1c5 | ||
|
|
6929b56b4a | ||
|
|
cf52e9e29e | ||
|
|
54e1059ae5 |
@@ -1,13 +1,13 @@
|
||||
[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"
|
||||
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"
|
||||
runner = "gdb -q -x openocd.gdb"
|
||||
|
||||
rustflags = [
|
||||
# Previously, the linker arguments --nmagic and -Tlink.x were set here.
|
||||
@@ -29,9 +29,9 @@ rustflags = [
|
||||
[build]
|
||||
# Pick ONE of these default compilation targets
|
||||
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||
target = "thumbv7m-none-eabi" # Cortex-M3
|
||||
# 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)
|
||||
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
||||
# target = "thumbv8m.base-none-eabi" # Cortex-M23
|
||||
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
|
||||
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)
|
||||
|
||||
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
@@ -14,7 +14,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Cargo Build (debug)",
|
||||
"runToEntryPoint": "main",
|
||||
"executable": "./target/thumbv7m-none-eabi/debug/{{project-name}}",
|
||||
"executable": "./target/thumbv7m-none-eabi/debug/embedded-rs",
|
||||
/* Run `cargo build --example hello` and uncomment this line to run semi-hosting example */
|
||||
//"executable": "./target/thumbv7m-none-eabi/debug/examples/hello",
|
||||
"cpu": "cortex-m3",
|
||||
@@ -29,7 +29,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Cargo Build (debug)",
|
||||
"runToEntryPoint": "main",
|
||||
"executable": "./target/thumbv7em-none-eabihf/debug/{{project-name}}",
|
||||
"executable": "./target/thumbv7em-none-eabihf/debug/embedded-rs",
|
||||
/* Run `cargo build --example itm` and uncomment this line to run itm example */
|
||||
// "executable": "./target/thumbv7em-none-eabihf/debug/examples/itm",
|
||||
"device": "STM32F303VCT6",
|
||||
@@ -44,9 +44,17 @@
|
||||
"swoFrequency": 2000000,
|
||||
"source": "probe",
|
||||
"decoders": [
|
||||
{ "type": "console", "label": "ITM", "port": 0 }
|
||||
{
|
||||
"type": "console",
|
||||
"label": "ITM",
|
||||
"port": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"gdbPath": "gdb",
|
||||
"postLaunchCommands": [
|
||||
"monitor arm semihosting enable"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
34
.vscode/tasks.json
vendored
34
.vscode/tasks.json
vendored
@@ -10,9 +10,11 @@
|
||||
* so we can invoke it from the debug launcher.
|
||||
*/
|
||||
"label": "Cargo Build (debug)",
|
||||
"type": "process",
|
||||
"type": "shell",
|
||||
"command": "cargo",
|
||||
"args": ["build"],
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
@@ -23,9 +25,12 @@
|
||||
},
|
||||
{
|
||||
"label": "Cargo Build (release)",
|
||||
"type": "process",
|
||||
"type": "shell",
|
||||
"command": "cargo",
|
||||
"args": ["build", "--release"],
|
||||
"args": [
|
||||
"build",
|
||||
"--release"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
@@ -34,8 +39,11 @@
|
||||
{
|
||||
"label": "Cargo Build Examples (debug)",
|
||||
"type": "process",
|
||||
"command": "cargo",
|
||||
"args": ["build","--examples"],
|
||||
"command": "shell",
|
||||
"args": [
|
||||
"build",
|
||||
"--examples"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
@@ -43,9 +51,13 @@
|
||||
},
|
||||
{
|
||||
"label": "Cargo Build Examples (release)",
|
||||
"type": "process",
|
||||
"type": "shell",
|
||||
"command": "cargo",
|
||||
"args": ["build","--examples", "--release"],
|
||||
"args": [
|
||||
"build",
|
||||
"--examples",
|
||||
"--release"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
@@ -53,9 +65,11 @@
|
||||
},
|
||||
{
|
||||
"label": "Cargo Clean",
|
||||
"type": "process",
|
||||
"type": "shell",
|
||||
"command": "cargo",
|
||||
"args": ["clean"],
|
||||
"args": [
|
||||
"clean"
|
||||
],
|
||||
"problemMatcher": [],
|
||||
"group": "build"
|
||||
},
|
||||
|
||||
28
Cargo.toml
28
Cargo.toml
@@ -1,36 +1,40 @@
|
||||
[package]
|
||||
authors = ["{{authors}}"]
|
||||
authors = ["jasper"]
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
name = "{{project-name}}"
|
||||
name = "embedded-rs"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = "0.6.0"
|
||||
cortex-m-rt = "0.6.10"
|
||||
cortex-m-semihosting = "0.3.3"
|
||||
panic-halt = "0.2.0"
|
||||
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7"
|
||||
cortex-m-semihosting = "0.5"
|
||||
panic-halt = "1.0.0"
|
||||
panic-semihosting = "0.6"
|
||||
stm32f3 = { version = "0.16.0", features = ["stm32f303"] }
|
||||
stm32f3xx-hal = { version = "0.10.0", features = ["stm32f303xc"] }
|
||||
switch-hal = "0.4.0"
|
||||
|
||||
# Uncomment for the panic example.
|
||||
# panic-itm = "0.4.1"
|
||||
|
||||
# Uncomment for the allocator example.
|
||||
# alloc-cortex-m = "0.4.0"
|
||||
# embedded-alloc = "0.6.0"
|
||||
|
||||
# Uncomment for the device example.
|
||||
# Update `memory.x`, set target to `thumbv7em-none-eabihf` in `.cargo/config`,
|
||||
# and then use `cargo build --examples device` to build it.
|
||||
# and then use `cargo build --example device` to build it.
|
||||
# [dependencies.stm32f3]
|
||||
# features = ["stm32f303", "rt"]
|
||||
# version = "0.7.1"
|
||||
# version = "^0.16.0"
|
||||
|
||||
# this lets you use `cargo fix`!
|
||||
[[bin]]
|
||||
name = "{{project-name}}"
|
||||
name = "embedded-rs"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1 # better optimizations
|
||||
debug = true # symbols are nice and they don't increase the size on Flash
|
||||
lto = true # better optimizations
|
||||
debug = true # symbols are nice and they don't increase the size on Flash
|
||||
lto = true # better optimizations
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
//! How to use the heap and a dynamic memory allocator
|
||||
//!
|
||||
//! This example depends on the alloc-cortex-m crate so you'll have to add it to your Cargo.toml:
|
||||
//! This example depends on the embedded-alloc crate so you'll have to add it to your Cargo.toml:
|
||||
//!
|
||||
//! ``` text
|
||||
//! # or edit the Cargo.toml file manually
|
||||
//! $ cargo add alloc-cortex-m
|
||||
//! $ cargo add embedded-alloc
|
||||
//! ```
|
||||
//!
|
||||
//! ---
|
||||
|
||||
#![feature(alloc_error_handler)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
@@ -17,28 +16,33 @@ extern crate alloc;
|
||||
use panic_halt as _;
|
||||
|
||||
use self::alloc::vec;
|
||||
use core::alloc::Layout;
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
use alloc_cortex_m::CortexMHeap;
|
||||
use cortex_m::asm;
|
||||
// Linked-List First Fit Heap allocator (feature = "llff")
|
||||
use embedded_alloc::LlffHeap as Heap;
|
||||
// Two-Level Segregated Fit Heap allocator (feature = "tlsf")
|
||||
// use embedded_alloc::TlsfHeap as Heap;
|
||||
use cortex_m_rt::entry;
|
||||
use cortex_m_semihosting::{hprintln, debug};
|
||||
|
||||
// this is the allocator the application will use
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
|
||||
|
||||
const HEAP_SIZE: usize = 1024; // in bytes
|
||||
static HEAP: Heap = Heap::empty();
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Initialize the allocator BEFORE you use it
|
||||
unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }
|
||||
{
|
||||
use core::mem::MaybeUninit;
|
||||
const HEAP_SIZE: usize = 1024;
|
||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||
unsafe { HEAP.init(addr_of_mut!(HEAP_MEM) as usize, HEAP_SIZE) }
|
||||
}
|
||||
|
||||
// Growable array allocated on the heap
|
||||
let xs = vec![0, 1, 2];
|
||||
|
||||
hprintln!("{:?}", xs).unwrap();
|
||||
hprintln!("{:?}", xs);
|
||||
|
||||
// exit QEMU
|
||||
// NOTE do not run this on hardware; it can corrupt OpenOCD state
|
||||
@@ -46,11 +50,3 @@ fn main() -> ! {
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
// define what happens in an Out Of Memory (OOM) condition
|
||||
#[alloc_error_handler]
|
||||
fn alloc_error(_layout: Layout) -> ! {
|
||||
asm::bkpt();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
@@ -82,8 +82,10 @@
|
||||
use panic_halt as _;
|
||||
|
||||
use core::ptr;
|
||||
use core::fmt::Write;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use cortex_m_rt::{entry, exception, ExceptionFrame};
|
||||
use cortex_m_semihosting::hio;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
@@ -94,3 +96,12 @@ fn main() -> ! {
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[exception(trampoline = true)]
|
||||
unsafe fn HardFault(ef: &ExceptionFrame) -> ! {
|
||||
if let Ok(mut hstdout) = hio::hstdout() {
|
||||
writeln!(hstdout, "{:#?}", ef).ok();
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ fn main() -> ! {
|
||||
let mut syst = p.SYST;
|
||||
let mut nvic = p.NVIC;
|
||||
|
||||
nvic.enable(Interrupt::EXTI0);
|
||||
unsafe {
|
||||
nvic.iser[Interrupt::EXTI0 as usize / 32].write(1 << (Interrupt::EXTI0 as usize % 32));
|
||||
}
|
||||
|
||||
// configure the system timer to wrap around every second
|
||||
syst.set_clock_source(SystClkSource::Core);
|
||||
@@ -58,5 +60,5 @@ fn main() -> ! {
|
||||
|
||||
#[interrupt]
|
||||
fn EXTI0() {
|
||||
hprint!(".").unwrap();
|
||||
hprint!(".");
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@ fn main() -> ! {
|
||||
|
||||
#[exception]
|
||||
fn SysTick() {
|
||||
hprint!(".").unwrap();
|
||||
hprint!(".");
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ use cortex_m_semihosting::{debug, hprintln};
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
hprintln!("Hello, world!").unwrap();
|
||||
hprintln!("Hello, world!");
|
||||
|
||||
// exit QEMU
|
||||
// NOTE do not run this on hardware; it can corrupt OpenOCD state
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
// debug::exit(debug::EXIT_SUCCESS);
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,11 @@ use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch
|
||||
// use panic_itm as _; // logs messages over ITM; requires ITM support
|
||||
// use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
|
||||
|
||||
use cortex_m::asm;
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
asm::nop(); // To not have main optimize to abort in release mode, remove when you add code
|
||||
|
||||
loop {
|
||||
// your code goes here
|
||||
}
|
||||
|
||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1760423683,
|
||||
"narHash": "sha256-Tb+NYuJhWZieDZUxN6PgglB16yuqBYQeMJyYBGCXlt8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a493e93b4a259cd9fea8073f89a7ed9b1c5a1da2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
48
flake.nix
Normal file
48
flake.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
# Adapted from https://wiki.nixos.org/wiki/Rust#Installation_via_rustup
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
outputs =
|
||||
{
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
...
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
in
|
||||
with pkgs;
|
||||
{
|
||||
devShells.default = mkShell {
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = [
|
||||
rustup
|
||||
rustPlatform.bindgenHook
|
||||
rustfmt
|
||||
clippy
|
||||
rust-analyzer
|
||||
pkg-config
|
||||
|
||||
openocd
|
||||
gdb
|
||||
qemu
|
||||
inetutils # telnet for OpenOCD console
|
||||
];
|
||||
buildInputs = [
|
||||
# Libraries here
|
||||
openssl
|
||||
];
|
||||
RUSTC_VERSION = "stable";
|
||||
shellHook = ''
|
||||
export PATH="''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-${stdenv.hostPlatform.rust.rustcTarget}/bin:''${CARGO_HOME:-~/.cargo}/bin:$PATH"
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
4
memory.x
4
memory.x
@@ -3,8 +3,8 @@ MEMORY
|
||||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
||||
/* TODO Adjust these memory regions to match your device memory layout */
|
||||
/* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
|
||||
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 40K
|
||||
}
|
||||
|
||||
/* This is where the call stack will be allocated. */
|
||||
|
||||
@@ -36,5 +36,5 @@ monitor arm semihosting enable
|
||||
|
||||
load
|
||||
|
||||
# start the process but immediately halt the processor
|
||||
stepi
|
||||
# Run to main
|
||||
continue
|
||||
|
||||
183
src/main.rs
183
src/main.rs
@@ -1,20 +1,193 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
use core::slice::Iter;
|
||||
|
||||
use cortex_m_semihosting::hprintln;
|
||||
// pick a panicking behavior
|
||||
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
|
||||
// use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
|
||||
// use panic_abort as _; // requires nightly
|
||||
// use panic_itm as _; // logs messages over ITM; requires ITM support
|
||||
// use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
|
||||
use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
|
||||
|
||||
use cortex_m::asm;
|
||||
use cortex_m::peripheral::{syst, Peripherals};
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
use stm32f3xx_hal::delay;
|
||||
use stm32f3xx_hal::serial::Serial;
|
||||
use stm32f3xx_hal::{
|
||||
gpio::{self, gpioe},
|
||||
pac,
|
||||
prelude::*,
|
||||
};
|
||||
use switch_hal::{ActiveHigh, IntoSwitch, OutputSwitch, Switch};
|
||||
|
||||
enum Direction {
|
||||
North,
|
||||
NorthEast,
|
||||
East,
|
||||
SouthEast,
|
||||
South,
|
||||
SouthWest,
|
||||
West,
|
||||
NorthWest,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn iter() -> Iter<'static, Direction> {
|
||||
static DIRECTIONS: [Direction; 8] = [
|
||||
Direction::North,
|
||||
Direction::NorthEast,
|
||||
Direction::East,
|
||||
Direction::SouthEast,
|
||||
Direction::South,
|
||||
Direction::SouthWest,
|
||||
Direction::West,
|
||||
Direction::NorthWest,
|
||||
];
|
||||
DIRECTIONS.iter()
|
||||
}
|
||||
}
|
||||
|
||||
type Led = Switch<gpioe::PEx<gpio::Output<gpio::PushPull>>, ActiveHigh>;
|
||||
struct Leds {
|
||||
ld3: Led,
|
||||
ld4: Led,
|
||||
ld5: Led,
|
||||
ld6: Led,
|
||||
ld7: Led,
|
||||
ld8: Led,
|
||||
ld9: Led,
|
||||
ld10: Led,
|
||||
}
|
||||
|
||||
impl Leds {
|
||||
fn new<PE8Mode, PE9Mode, PE10Mode, PE11Mode, PE12Mode, PE13Mode, PE14Mode, PE15Mode>(
|
||||
pe8: gpioe::PE8<PE8Mode>,
|
||||
pe9: gpioe::PE9<PE9Mode>,
|
||||
pe10: gpioe::PE10<PE10Mode>,
|
||||
pe11: gpioe::PE11<PE11Mode>,
|
||||
pe12: gpioe::PE12<PE12Mode>,
|
||||
pe13: gpioe::PE13<PE13Mode>,
|
||||
pe14: gpioe::PE14<PE14Mode>,
|
||||
pe15: gpioe::PE15<PE15Mode>,
|
||||
moder: &mut gpioe::MODER,
|
||||
otyper: &mut gpioe::OTYPER,
|
||||
) -> Self {
|
||||
let mut leds = Self {
|
||||
ld3: pe9
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld4: pe8
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld5: pe10
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld6: pe15
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld7: pe11
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld8: pe14
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld9: pe12
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
ld10: pe13
|
||||
.into_push_pull_output(moder, otyper)
|
||||
.downgrade()
|
||||
.into_active_high_switch(),
|
||||
};
|
||||
for dir in Direction::iter() {
|
||||
leds.for_direction(dir).off().ok();
|
||||
}
|
||||
leds
|
||||
}
|
||||
|
||||
pub fn for_direction(&mut self, direction: &Direction) -> &mut Led {
|
||||
match direction {
|
||||
Direction::North => &mut self.ld3,
|
||||
Direction::NorthEast => &mut self.ld5,
|
||||
Direction::East => &mut self.ld7,
|
||||
Direction::SouthEast => &mut self.ld9,
|
||||
Direction::South => &mut self.ld10,
|
||||
Direction::SouthWest => &mut self.ld8,
|
||||
Direction::West => &mut self.ld6,
|
||||
Direction::NorthWest => &mut self.ld4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
asm::nop(); // To not have main optimize to abort in release mode, remove when you add code
|
||||
let cortex_peripherals = Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
let mut rcc = dp.RCC.constrain();
|
||||
let mut flash = dp.FLASH.constrain();
|
||||
let clocks = rcc.cfgr.sysclk(8.MHz()).freeze(&mut flash.acr);
|
||||
|
||||
// The HAL Serial example does this -- but where does Systick come from?
|
||||
// https://github.com/stm32-rs/stm32f3xx-hal/blob/b0cead18208099b94a085fb634d0db4e75ac6e4d/examples/serial_echo_rtic.rs
|
||||
// let mono = Systick::new(systick, 8_000_000);
|
||||
let mut systick = cortex_peripherals.SYST;
|
||||
systick.set_clock_source(syst::SystClkSource::Core);
|
||||
systick.set_reload(8_000_000); // 1s
|
||||
systick.clear_current();
|
||||
|
||||
let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);
|
||||
let mut leds = Leds::new(
|
||||
gpioe.pe8,
|
||||
gpioe.pe9,
|
||||
gpioe.pe10,
|
||||
gpioe.pe11,
|
||||
gpioe.pe12,
|
||||
gpioe.pe13,
|
||||
gpioe.pe14,
|
||||
gpioe.pe15,
|
||||
&mut gpioe.moder,
|
||||
&mut gpioe.otyper,
|
||||
);
|
||||
|
||||
let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
|
||||
let pins = (
|
||||
gpioc
|
||||
.pc4
|
||||
// The specific AF number is fixed by the type arguments for Serial::new():
|
||||
// impl<Otype> TxPin<USART1> for gpioc::PC4<AF7<Otype>> {}
|
||||
.into_af_push_pull(&mut gpioc.moder, &mut gpioc.otyper, &mut gpioc.afrl),
|
||||
gpioc
|
||||
.pc5
|
||||
.into_af_push_pull(&mut gpioc.moder, &mut gpioc.otyper, &mut gpioc.afrl),
|
||||
);
|
||||
|
||||
let mut uart = Serial::new(dp.USART1, pins, 115200.Bd(), clocks, &mut rcc.apb2);
|
||||
|
||||
let mut delay = delay::Delay::new(systick, clocks);
|
||||
|
||||
let mut enabled = true;
|
||||
loop {
|
||||
// your code goes here
|
||||
enabled = !enabled;
|
||||
for dir in Direction::iter() {
|
||||
let led = leds.for_direction(dir);
|
||||
if enabled {
|
||||
led.on().ok();
|
||||
} else {
|
||||
led.off().ok();
|
||||
}
|
||||
delay.delay_ms(50u16);
|
||||
}
|
||||
uart.write_str("Loop\r\n").unwrap();
|
||||
hprintln!("Loop");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user