1
0
Fork 0

Init project

This commit is contained in:
Anton Pöhl 2023-12-01 15:12:35 +01:00
commit 30052f54ab
11 changed files with 1058 additions and 0 deletions

6
.cargo/config Normal file
View File

@ -0,0 +1,6 @@
[target.thumbv7m-none-eabi]
runner = "gdb -q -x openocd.gdb"
rustflags = [ "-C", "link-arg=-Tlink.x" ]
[build]
target = "thumbv7m-none-eabi"

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
/result
/result-lib

516
Cargo.lock generated Normal file
View File

@ -0,0 +1,516 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "atomic-polyfill"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
dependencies = [
"critical-section",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version 0.2.3",
]
[[package]]
name = "bare-metal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
name = "bitfield"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "blackknobs"
version = "0.1.0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"cortex-m-rtic",
"cortex-m-semihosting",
"embedded-hal",
"embedded-midi",
"fugit",
"panic-semihosting",
"stm32f1xx-hal",
"systick-monotonic",
]
[[package]]
name = "bxcan"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80"
dependencies = [
"bitflags",
"embedded-hal",
"nb 1.1.0",
"vcell",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cortex-m"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [
"bare-metal 0.2.5",
"bitfield",
"embedded-hal",
"volatile-register",
]
[[package]]
name = "cortex-m-rt"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
dependencies = [
"cortex-m-rt-macros",
]
[[package]]
name = "cortex-m-rt-macros"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cortex-m-rtic"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d696ae7390bdb9f7978f71ca7144256a2c4616240a6df9002da3c451f9fc8f02"
dependencies = [
"bare-metal 1.0.0",
"cortex-m",
"cortex-m-rtic-macros",
"heapless",
"rtic-core",
"rtic-monotonic",
"version_check",
]
[[package]]
name = "cortex-m-rtic-macros"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eefb40b1ca901c759d29526e5c8a0a1b246c20caaa5b4cc5d0f0b94debecd4c7"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"rtic-syntax",
"syn",
]
[[package]]
name = "cortex-m-semihosting"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
dependencies = [
"cortex-m",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "embedded-dma"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446"
dependencies = [
"stable_deref_trait",
]
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]]
name = "embedded-midi"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26119337828c4c6a29d9c1661962eeec2a3f884b859d5713a70c6c4143988497"
dependencies = [
"embedded-hal",
"midi-types",
"nb 1.1.0",
]
[[package]]
name = "fugit"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
dependencies = [
"gcd",
]
[[package]]
name = "fugit-timer"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a"
dependencies = [
"fugit",
"nb 1.1.0",
]
[[package]]
name = "gcd"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heapless"
version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [
"atomic-polyfill",
"hash32",
"rustc_version 0.4.0",
"spin",
"stable_deref_trait",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "midi-types"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef0bbe5256e5c434947d790788426bb65773502784aed7b23408f7e7fb4d8eb5"
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "panic-semihosting"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab"
dependencies = [
"cortex-m",
"cortex-m-semihosting",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rtic-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
[[package]]
name = "rtic-monotonic"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb8b0b822d1a366470b9cea83a1d4e788392db763539dc4ba022bcc787fece82"
[[package]]
name = "rtic-syntax"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5e215601dc467752c2bddc6284a622c6f3d2bab569d992adcd5ab7e4cb9478"
dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver 1.0.20",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stm32-usbd"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1"
dependencies = [
"cortex-m",
"usb-device",
"vcell",
]
[[package]]
name = "stm32f1"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dc80735831c28fe85384e1e28428fb6d201f67c696e369a239ed9c5eba369d"
dependencies = [
"bare-metal 1.0.0",
"cortex-m",
"cortex-m-rt",
"vcell",
]
[[package]]
name = "stm32f1xx-hal"
version = "0.10.0"
dependencies = [
"bitflags",
"bxcan",
"cortex-m",
"cortex-m-rt",
"embedded-dma",
"embedded-hal",
"fugit",
"fugit-timer",
"nb 1.1.0",
"stm32-usbd",
"stm32f1",
"void",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "systick-monotonic"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fb822d5c615a0ae3a4795ee5b1d06381c7faf488d861c0a4fa8e6a88d5ff84"
dependencies = [
"cortex-m",
"fugit",
"rtic-monotonic",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "usb-device"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508"
[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
dependencies = [
"vcell",
]

25
Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "blackknobs"
version = "0.1.0"
authors = ["toon <toon@c3d2.de>"]
edition = "2021"
[dependencies]
# core
cortex-m = "0.7.7"
cortex-m-rt = "0.7.3"
# panic handler
cortex-m-semihosting = "0.5.0"
panic-semihosting = "0.6.0"
# real time for the masses
cortex-m-rtic = "1.1.4"
fugit = "0.3.7"
systick-monotonic = "1.0.1"
embedded-hal = "0.2.7"
embedded-midi = "0.1.2"
# hardware abstraction layer
[dependencies.stm32f1xx-hal]
path = "../stm32f1xx-hal"
#version = "0.10.0"
features = [ "rt", "stm32f103", "medium" ]

130
flake.lock Normal file
View File

@ -0,0 +1,130 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1699099776,
"narHash": "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "85f1ba3e51676fa8cc604a3d863d729026a6b8eb",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1681358109,
"narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay",
"utils": "utils"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1699323235,
"narHash": "sha256-ZFRItRv0dDSzsfpqSjj9qWM/SA1kRrOk6R04qhBZuxM=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "8a9d6f544c08ee898c7f3761cc9587be7565db5e",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

60
flake.nix Normal file
View File

@ -0,0 +1,60 @@
# Env to develop code for stm32fxxx devices
{
description = "Stm32 rust nixos template";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, utils, rust-overlay }:
let
name = "stm32-rust-nixos-template";
in
utils.lib.eachDefaultSystem
(system:
let
# Imports
pkgs = import nixpkgs {
inherit system;
# Custom rust toolchain
overlays = [ rust-overlay.overlays.default ];
};
openocd-f1 = pkgs.stdenv.mkDerivation {
name = "openocd-f1-stlink";
buildInputs = [
pkgs.openocd
pkgs.makeWrapper
];
src = ./src;
noBuild = true;
installPhase =
let
openOcdFlags = [
# change this for a newer programmer
"-f" "${pkgs.openocd}/share/openocd/scripts/interface/stlink.cfg"
"-f" "${pkgs.openocd}/share/openocd/scripts/target/stm32f1x.cfg"
"-c" "init"
];
in ''
mkdir -p $out/bin
makeWrapper ${pkgs.openocd}/bin/openocd $out/bin/openocd-stlink-blackpill \
--add-flags "${pkgs.lib.escapeShellArgs openOcdFlags}"
'';
};
in
rec {
devShells.default = with pkgs; mkShell {
nativeBuildInputs = [
(rust-bin.fromRustupToolchainFile ./rust-toolchain.toml)
cargo-binutils
gdb
openocd
openocd-f1
];
};
}
);
}

5
memory.x Normal file
View File

@ -0,0 +1,5 @@
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

40
openocd.gdb Normal file
View File

@ -0,0 +1,40 @@
target extended-remote :3333
# print demangled symbols
set print asm-demangle on
# set backtrace limit to not have infinite backtrace loops
set backtrace limit 32
# detect unhandled exceptions, hard faults and panics
break DefaultHandler
break HardFault
break rust_begin_unwind
# # run the next few lines so the panic message is printed immediately
# # the number needs to be adjusted for your panic handler
# commands $bpnum
# next 4
# end
# *try* to stop at the user entry point (it might be gone due to inlining)
break main
monitor arm semihosting enable
# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
# monitor tpiu config internal itm.txt uart off 8000000
# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 8000000 must match the core clock frequency
# # 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 8000000 2000000
# # enable ITM port 0
# monitor itm port 0 on
load
# start the process but immediately halt the processor
stepi

5
rust-toolchain.toml Normal file
View File

@ -0,0 +1,5 @@
# rust-toolchain.toml
[toolchain]
channel = "stable"
components = [ "rust-src", "llvm-tools-preview" ]
targets = [ "thumbv7m-none-eabi" ]

210
src/main.rs Normal file
View File

@ -0,0 +1,210 @@
#![no_std]
#![no_main]
use panic_semihosting as _;
use rtic::app;
use systick_monotonic::*;
use stm32f1xx_hal::{
adc,
dma,
pac::ADC1,
prelude::*,
gpio::{self, Analog},
serial::{Config, Serial},
};
use embedded_midi::{self, MidiMessage};
const CONTROL_CNT: usize = 9;
// Concrete midi out type alias
type MidiOut = embedded_midi::MidiOut<
stm32f1xx_hal::serial::Tx<
stm32f1xx_hal::pac::USART1
>
>;
// Adc channels to scan
pub struct AdcPins(
gpio::gpioa::PA0<Analog>,
gpio::gpioa::PA1<Analog>,
gpio::gpioa::PA2<Analog>,
gpio::gpioa::PA3<Analog>,
gpio::gpioa::PA4<Analog>,
gpio::gpioa::PA5<Analog>,
gpio::gpioa::PA6<Analog>,
gpio::gpioa::PA7<Analog>,
gpio::gpiob::PB0<Analog>,
);
impl adc::SetChannels<AdcPins> for adc::Adc<ADC1>
{
fn set_samples(&mut self) {
for ch in 0..(CONTROL_CNT + 1) as u8 {
self.set_channel_sample_time(ch, adc::SampleTime::T_28);
}
}
fn set_sequence(&mut self) {
self.set_regular_sequence(&[0, 1, 2, 3, 4, 5, 6, 7, 8]);
//self.set_continuous_mode(true);
}
}
// San DMA recources, cunsumed by the DMA controller
pub struct ScanDmaResources(
adc::Adc<ADC1>,
AdcPins,
dma::dma1::C1,
);
#[derive(Copy, Clone)]
pub struct MidiControl{
value: u8, // Actually a 7 bit value
update: bool,
}
#[app(
device = stm32f1xx_hal::pac,
peripherals = true,
dispatchers = [SPI1]
)]
mod app {
use super::*;
#[shared]
struct Shared {
controls: [MidiControl; 9],
}
#[local]
struct Local {
dma_buffer: Option<&'static mut [u16; CONTROL_CNT]>,
scan_dma_rescources: Option<ScanDmaResources>,
midi_out: MidiOut,
}
#[monotonic(priority = 1, binds = SysTick, default = true)]
type MonoTimer = Systick<1000>;
#[init(local = [buffer: [u16; CONTROL_CNT] = [0u16; CONTROL_CNT]])]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
let mut flash = cx.device.FLASH.constrain();
let rcc = cx.device.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(8.MHz())
.sysclk(48.MHz())
.adcclk(2.MHz())
.freeze(&mut flash.acr);
let mono = Systick::new(cx.core.SYST, 48_000_000);
let mut afio = cx.device.AFIO.constrain();
let mut gpioa = cx.device.GPIOA.split();
let tx = gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh);
let rx = gpioa.pa10;
let usart = Serial::new(
cx.device.USART1,
(tx, rx),
&mut afio.mapr,
Config::default().baudrate(31250.bps()).parity_none(),
&clocks,
);
let mut gpiob = cx.device.GPIOB.split();
// SPI 2, PB13, PB15
let adc_pins = AdcPins(
gpioa.pa0.into_analog(&mut gpioa.crl),
gpioa.pa1.into_analog(&mut gpioa.crl),
gpioa.pa2.into_analog(&mut gpioa.crl),
gpioa.pa3.into_analog(&mut gpioa.crl),
gpioa.pa4.into_analog(&mut gpioa.crl),
gpioa.pa5.into_analog(&mut gpioa.crl),
gpioa.pa6.into_analog(&mut gpioa.crl),
gpioa.pa7.into_analog(&mut gpioa.crl),
gpiob.pb0.into_analog(&mut gpiob.crl),
);
let adc1 = adc::Adc::adc1(cx.device.ADC1, clocks);
let dma_ch1 = cx.device.DMA1.split().1;
let scan_dma_rescources = ScanDmaResources(adc1, adc_pins, dma_ch1);
let (tx, _rx) = usart.split();
let midi_out = MidiOut::new(tx);
read_adc::spawn().unwrap();
(
Shared {
controls: [
MidiControl { value: 0, update: false };
CONTROL_CNT
],
},
Local {
dma_buffer: Some(cx.local.buffer),
scan_dma_rescources: Some(scan_dma_rescources),
midi_out,
},
init::Monotonics(mono)
)
}
// This can be implemented non-blocking (use the DMA1 interrupt)
// Is it worth the effort?
#[task(local = [scan_dma_rescources, dma_buffer], shared = [controls])]
fn read_adc(mut cx: read_adc::Context) {
let resources = cx.local.scan_dma_rescources;
let ScanDmaResources(adc, pins, dma) = resources.take().unwrap();
let adc_scan = adc.with_scan_dma(pins, dma);
// Get DMA buffer
let buffer = cx.local.dma_buffer.take().unwrap();
// Perform read
let (buffer, adc_scan) = adc_scan.read(buffer).wait();
// Put the recources back in place
let (adc, pins, dma) = adc_scan.split();
resources.replace(ScanDmaResources(adc, pins, dma));
// Convert adc values to midi control values and check if they changed
cx.shared.controls.lock(|controls| {
for i in 0..controls.len() {
let value = adc_to_midi(&buffer[i]);
if controls[i].value != value {
controls[i].value = value;
controls[i].update = true;
}
}
});
// Put the buffer back in place
cx.local.dma_buffer.replace(buffer);
send_control_changes::spawn().unwrap();
}
#[task(local = [midi_out], shared = [controls])]
fn send_control_changes(mut cx: send_control_changes::Context) {
cx.shared.controls.lock(|controls| {
for i in 0..controls.len() {
if controls[i].update {
let event = MidiMessage::ControlChange(
0u8.into(),
(i as u8).into(),
controls[i].value.into()
);
cx.local.midi_out.write(&event).unwrap();
controls[i].update = false;
}
}
});
read_adc::spawn_after(systick_monotonic::ExtU64::millis(100)).unwrap();
}
}
// Converts a 12 bit adc value to a 7 bit midi control value
fn adc_to_midi(adc_val: &u16) -> u8{
((adc_val & 0x0FFF) >> 5) as u8
}

58
src/tim2_mono.rs Normal file
View File

@ -0,0 +1,58 @@
use rtic::Monotonic;
use stm32f1xx_hal::{
time::U32Ext,
pac::{RCC, TIM2},
rcc::Clocks,
};
pub struct MonoTimer<T, const FREQ: u32>(T);
impl<const FREQ: u32> MonoTimer<TIM2, FREQ> {
pub fn new(timer: TIM2, clocks: &Clocks) -> Self {
let rcc = unsafe { &(*RCC::ptr()) };
rcc.apb1enr.modify(|_, w| w.tim2en().set_bit());
rcc.apb1rstr.modify(|_, w| w.tim2rst().set_bit());
rcc.apb1rstr.modify(|_, w| w.tim2rst().clear_bit());
let prescaler: u32 = clocks.pclk1_tim().to_Hz() / FREQ - 1;
timer.psc.write(|w| w.psc().bits(prescaler as u16));
// set reload value to max
timer.arr.write(|w| unsafe { w.bits(u32::MAX) });
// set upcounting mode
timer.egr.write(|w| w.ug().set_bit());
// clear update interrupt flag
timer.sr.modify(|_, w| w.uif().clear_bit());
timer.cr1.modify(|_, w| w.cen().set_bit().udis().set_bit());
MonoTimer(timer)
}
}
impl<const FREQ: u32> Monotonic for MonoTimer<TIM2, FREQ> {
type Instant = fugit::TimerInstantU32<FREQ>;
type Duration = fugit::TimerDurationU32<FREQ>;
unsafe fn reset(&mut self) {
self.0.dier.modify(|_, w| w.cc1ie().set_bit());
}
#[inline(always)]
fn now(&mut self) -> Self::Instant {
Self::Instant::from_ticks(self.0.cnt.read().cnt().bits().into())
}
fn set_compare(&mut self, instant: Self::Instant) {
self.0
.ccr1()
.write(|w| w.ccr().bits(instant.duration_since_epoch().ticks()));
}
fn clear_compare_flag(&mut self) {
self.0.sr.modify(|_, w| w.cc1if().clear_bit());
}
#[inline(always)]
fn zero() -> Self::Instant {
Self::Instant::from_ticks(0)
}
}