Initial commit

This commit is contained in:
JP Stringham
2026-03-22 19:25:04 -04:00
commit d1f2bbd25e
8 changed files with 1150 additions and 0 deletions

39
.cargo/config.toml Normal file
View File

@@ -0,0 +1,39 @@
[build]
target = "thumbv6m-none-eabi"
# Target specific options
[target.thumbv6m-none-eabi]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Tlink.x tells the linker to use link.x as the linker
# script. This is usually provided by the cortex-m-rt crate, and by default
# the version in that crate will include a file called `memory.x` which
# describes the particular memory layout for your specific chip.
# * no-vectorize-loops turns off the loop vectorizer (seeing as the M0+ doesn't
# have SIMD)
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
# Code-size optimizations.
# trap unreachable can save a lot of space, but requires nightly compiler.
# uncomment the next line if you wish to enable it
# "-Z", "trap-unreachable=no",
"-C", "no-vectorize-loops",
]
# This runner will make a UF2 file and then copy it to a mounted RP2040 in USB
# Bootloader mode:
runner = "elf2uf2-rs -d"
# This runner will find a supported SWD debug probe and flash your RP2040 over
# SWD:
# runner = "probe-rs run --chip RP2040 --protocol swd --speed 150"
[env]
DEFMT_RTT_BUFFER_SIZE = { value = "4096", force = true }
DEFMT_LOG = { value = "info", force = true }

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"rust-analyzer.cargo.target": "thumbv6m-none-eabi",
"rust-analyzer.check.allTargets": false,
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true,
}

622
Cargo.lock generated Normal file
View File

@@ -0,0 +1,622 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version",
]
[[package]]
name = "bitfield"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "bitfield"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[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",
"bitfield 0.13.2",
"critical-section",
"embedded-hal 0.2.7",
"volatile-register",
]
[[package]]
name = "cortex-m-rt"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6"
dependencies = [
"cortex-m-rt-macros",
]
[[package]]
name = "cortex-m-rt-macros"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "crc-any"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73"
dependencies = [
"debug-helper",
]
[[package]]
name = "critical-section"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "debug-helper"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
[[package]]
name = "defmt"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
dependencies = [
"bitflags",
"defmt-macros",
]
[[package]]
name = "defmt-macros"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
dependencies = [
"defmt-parser",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "defmt-parser"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
dependencies = [
"thiserror",
]
[[package]]
name = "defmt-rtt"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e"
dependencies = [
"critical-section",
"defmt",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[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-hal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "embedded-hal-async"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
dependencies = [
"embedded-hal 1.0.0",
]
[[package]]
name = "embedded-hal-nb"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605"
dependencies = [
"embedded-hal 1.0.0",
"nb 1.1.0",
]
[[package]]
name = "embedded-io"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
[[package]]
name = "frunk"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28aef0f9aa070bce60767c12ba9cb41efeaf1a2bc6427f87b7d83f11239a16d7"
dependencies = [
"frunk_core",
"frunk_derives",
]
[[package]]
name = "frunk_core"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "476eeaa382e3462b84da5d6ba3da97b5786823c2d0d3a0d04ef088d073da225c"
[[package]]
name = "frunk_derives"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0b4095fc99e1d858e5b8c7125d2638372ec85aa0fe6c807105cf10b0265ca6c"
dependencies = [
"frunk_proc_macro_helpers",
"quote",
"syn 2.0.117",
]
[[package]]
name = "frunk_proc_macro_helpers"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1952b802269f2db12ab7c0bd328d0ae8feaabf19f352a7b0af7bb0c5693abfce"
dependencies = [
"frunk_core",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "fugit"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e639847d312d9a82d2e75b0edcc1e934efcc64e6cb7aa94f0b1fbec0bc231d6"
dependencies = [
"gcd",
]
[[package]]
name = "gcd"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "hash32"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
dependencies = [
"hash32",
"stable_deref_trait",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[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 = "num_enum"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "panic-probe"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a"
dependencies = [
"cortex-m",
"rtt-target",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pio"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76e09694b50f89f302ed531c1f2a7569f0be5867aee4ab4f8f729bbeec0078e3"
dependencies = [
"arrayvec",
"num_enum",
"paste",
]
[[package]]
name = "portable-atomic"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "proc-macro-error2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rp-binary-info"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f582261945fa215d40e2988b4df595d11c0908c0fff97a0fe23df766d117b790"
[[package]]
name = "rp-hal-common"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8288358786b1458fb2caac8c4b40fb529ef4200d6c46467e2695b7a8ba573ae8"
dependencies = [
"fugit",
]
[[package]]
name = "rp2040-boot2"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21"
dependencies = [
"crc-any",
]
[[package]]
name = "rp2040-hal"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb79a4590775204387f334672e6f79c0d734d0a159da23d60677b3c10fa1245"
dependencies = [
"bitfield 0.14.0",
"cortex-m",
"critical-section",
"embedded-dma",
"embedded-hal 0.2.7",
"embedded-hal 1.0.0",
"embedded-hal-async",
"embedded-hal-nb",
"embedded-io",
"frunk",
"fugit",
"itertools",
"nb 1.1.0",
"paste",
"pio",
"rand_core",
"rp-binary-info",
"rp-hal-common",
"rp2040-hal-macros",
"rp2040-pac",
"usb-device",
"vcell",
"void",
]
[[package]]
name = "rp2040-hal-macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86479063e497efe1ae81995ef9071f54fd1c7427e04d6c5b84cde545ff672a5e"
dependencies = [
"cortex-m-rt",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "rp2040-pac"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83cbcd3f7a0ca7bbe61dc4eb7e202842bee4e27b769a7bf3a4a72fa399d6e404"
dependencies = [
"cortex-m",
"critical-section",
"vcell",
]
[[package]]
name = "rtt-target"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10b34c9e6832388e45f3c01f1bb60a016384a0a4ad80cdd7d34913bed25037f0"
dependencies = [
"critical-section",
"ufmt-write",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[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-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "sh1106-pico-rs"
version = "0.1.0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"defmt",
"defmt-rtt",
"embedded-hal 1.0.0",
"panic-probe",
"rp2040-boot2",
"rp2040-hal",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[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 = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "ufmt-write"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "usb-device"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6"
dependencies = [
"heapless",
"portable-atomic",
]
[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
[[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.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
dependencies = [
"vcell",
]
[[package]]
name = "zero-dev-base"
version = "0.1.0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"defmt",
"defmt-rtt",
"embedded-hal 1.0.0",
"panic-probe",
"rp2040-boot2",
"rp2040-hal",
"sh1106-pico-rs",
]

18
Cargo.toml Normal file
View File

@@ -0,0 +1,18 @@
[package]
name = "zero-dev-base"
version = "0.1.0"
edition = "2024"
[dependencies]
cortex-m = { version = "0.7.7", features = [ "critical-section-single-core" ] }
cortex-m-rt = "0.7.5"
defmt = "1.0.1"
defmt-rtt = "1.1.0"
embedded-hal = "1.0.0"
panic-probe = { version = "1.0.0", features = [ "print-rtt" ]}
rp2040-boot2 = "0.3.0"
rp2040-hal = "0.11.0"
sh1106-pico-rs = { path = "../sh1106-pico-rs" }
[features]
logging = []

13
memory.x Normal file
View File

@@ -0,0 +1,13 @@
MEMORY {
BOOT_LOADER : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
SECTIONS {
/* ### Boot loader */
.boot_loader ORIGIN(BOOT_LOADER) :
{
KEEP(*(.boot_loader));
} > BOOT_LOADER
} INSERT BEFORE .text;

415
src/main.rs Normal file
View File

@@ -0,0 +1,415 @@
#![no_std]
#![no_main]
mod onboard_led;
use core::u16::MIN;
use cortex_m::prelude::_embedded_hal_PwmPin;
use defmt::info;
use defmt::println;
use defmt_rtt as _;
use embedded_hal::digital::StatefulOutputPin;
use panic_probe as _;
use rp2040_hal::clocks::ClockSource;
use rp2040_hal::gpio::DynPinId;
use rp2040_hal::gpio::FunctionNull;
use rp2040_hal::gpio::FunctionSioInput;
use rp2040_hal::gpio::FunctionSioOutput;
use rp2040_hal::gpio::Pin;
use rp2040_hal::gpio::PullDown;
use rp2040_hal::gpio::PullNone;
use rp2040_hal::pll;
use rp2040_hal::pll::PLLConfig;
use rp2040_hal::pll::common_configs::PLL_USB_48MHZ;
// Alias for our HAL crate
use rp2040_hal as hal;
use hal::fugit::RateExtU32;
use hal::pac;
use embedded_hal::digital::InputPin;
use embedded_hal::digital::OutputPin;
use sh1106_pico_rs::graphics::GraphicsBuf;
use sh1106_pico_rs::sh1106::SH1106Dev;
use crate::onboard_led::OnboardLed;
/// NB if OVERCLOCKING
/// you MUST use a BOOT_LOADER which can tolerate the OC
/// the GENERIC_03H one cannot (unsure why) but W25Q080 has been solid for me
#[unsafe(link_section = ".boot_loader")]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
/// if your board has a different frequency
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
const WAVE_TABLE: [u8; 128] = [
128, 134, 140, 146, 152, 159, 165, 171, 176, 182, 188, 193, 199, 204, 209, 213, 218, 222, 226,
230, 234, 237, 240, 243, 246, 248, 250, 252, 253, 254, 255, 255, 255, 255, 255, 254, 253, 252,
250, 248, 246, 243, 240, 237, 234, 230, 227, 222, 218, 214, 209, 204, 199, 193, 188, 182, 177,
171, 165, 159, 153, 146, 140, 134, 128, 121, 115, 109, 103, 97, 91, 85, 79, 73, 67, 62, 57, 51,
46, 42, 37, 33, 29, 25, 21, 18, 15, 12, 9, 7, 5, 3, 2, 1, 0, 0, 0, 0, 0, 1, 2, 3, 5, 7, 9, 12,
14, 18, 21, 24, 28, 32, 37, 41, 46, 51, 56, 61, 67, 72, 78, 84, 90, 96, 102, 108, 115, 121,
];
#[rp2040_hal::entry]
fn main() -> ! {
// Grab our singleton objects
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();
// Set up the watchdog driver - needed by the clock setup code
// let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);
hal::vreg::set_voltage(
&mut pac.VREG_AND_CHIP_RESET,
pac::vreg_and_chip_reset::vreg::VSEL_A::VOLTAGE1_30,
);
// settle
// cortex_m::asm::delay(3_000_000);
let xosc = hal::xosc::setup_xosc_blocking_custom_delay(pac.XOSC, XTAL_FREQ_HZ.Hz(), 128)
.map_err(|_x| false)
.unwrap();
// watchdog.enable_tick_generation((XTAL_FREQ_HZ / 1_000_000) as u8);
// Configure the clocks
let mut clocks = hal::clocks::ClocksManager::new(pac.CLOCKS);
let pll_usb = rp2040_hal::pll::setup_pll_blocking(
pac.PLL_USB,
xosc.operating_frequency(),
PLL_USB_48MHZ,
&mut clocks,
&mut pac.RESETS,
)
.unwrap();
let pll_sys = hal::pll::setup_pll_blocking(
pac.PLL_SYS,
xosc.operating_frequency(),
PLLConfig {
vco_freq: 1500.MHz(),
refdiv: 1,
post_div1: 5,
post_div2: 3,
},
&mut clocks,
&mut pac.RESETS,
)
.unwrap();
clocks.init_default(&xosc, &pll_sys, &pll_usb).unwrap();
// let mut delay = cortex_m::delay::Delay::new(core.SYST, 200_000_000);
// The single-cycle I/O block controls our GPIO pins
let sio = hal::Sio::new(pac.SIO);
// Set the pins to their default state
let pins = hal::gpio::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let pll_freq = pll_sys.get_freq();
// Init PWMs
let mut pwm_slices = hal::pwm::Slices::new(pac.PWM, &mut pac.RESETS);
// Configure PWM0
let pwm = &mut pwm_slices.pwm7;
pwm.set_ph_correct();
pwm.set_div_int(20);
pwm.set_div_frac(0);
pwm.clear_interrupt();
pwm.enable();
// let mut pwm_pin = pins.gpio15;
// pwm_pin.set_drive_strength(rp2040_hal::gpio::OutputDriveStrength::TwelveMilliAmps);
// pwm.channel_b.output_to(pwm_pin);
// let mut duty = 0;
// pwm.set_top(50000);
// pwm.channel_a.set_duty(duty);
// let mut on_off_input = pins.gpio15.into_pull_up_input();
// let mut min_input = pins.gpio12.into_pull_up_input();
let mut left_input = pins.gpio15.into_pull_up_input();
let mut right_input = pins.gpio14.into_pull_up_input();
let mut enter_input = pins.gpio13.into_pull_up_input();
// Create the I²C drive
let mut i2c = hal::I2C::i2c0(
pac.I2C0,
pins.gpio8.reconfigure(),
pins.gpio9.reconfigure(),
400.kHz(),
&mut pac.RESETS,
&clocks.system_clock,
);
let mut delay = cortex_m::delay::Delay::new(core.SYST, pll_freq.to_Hz());
let mut sh1106_dev = SH1106Dev::new(&mut delay, &mut i2c);
sh1106_dev.set_vertical_flip(&mut i2c, true);
let sh1106_dev = sh1106_dev;
let mut gfx_buf = GraphicsBuf::new();
gfx_buf.sprites[0].x = 114;
gfx_buf.clear();
gfx_buf.redraw();
sh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
let mut tick: u32 = 0;
let mut led = OnboardLed::new(pins.gpio16.into_push_pull_output().into_dyn_pin());
println!("Booted at {}MHz", pll_freq.to_MHz());
println!("PWM at {}Hz", pll_freq.to_Hz() / (20 * 2 * 50000));
let mut r = 0u8;
let mut g = 0u8;
let mut b = 0u8;
const ON_VALUE: u8 = 64;
loop {
tick = tick.wrapping_add(1);
let i = (tick % 144) as usize;
// let r = WAVE_TABLE[i] / 2;
// let g = WAVE_TABLE[(i + 48) % 128] / 2;
// let b = WAVE_TABLE[(i + 96) % 128] / 2;
// led.set_color(r, g, b);
// match i {
// ..48 => led.set_color(128, 0, 0),
// 48..96 => led.set_color(0, 128, 0),
// _ => led.set_color(0, 0, 128),
// }
cortex_m::asm::delay(10_000_000);
if left_input.is_low().unwrap() {
r = match r {
ON_VALUE => 0,
_ => ON_VALUE,
}
}
if right_input.is_low().unwrap() {
g = match g {
ON_VALUE => 0,
_ => ON_VALUE,
}
}
if enter_input.is_low().unwrap() {
b = match b {
ON_VALUE => 0,
_ => ON_VALUE,
}
}
led.set_color(r, g, b);
// pwm.channel_a.set_duty(duty);
// gfx_buf.clear();
// gfx_buf.redraw();
// let mut str_buf = [0u8; 12];
// let len = u32_into_str(duty as u32, &mut str_buf);
// let num_str = str::from_utf8(&str_buf[str_buf.len() - len..]).unwrap();
// gfx_buf.draw_string(20, 20, num_str);
// sh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
}
}
// returns the length of the final str removing leading zeroes
fn u32_into_str(mut value: u32, str_buf: &mut [u8]) -> usize {
let mut len = str_buf.len();
// info!("val {}", value);
for i in 0..len {
// info!("val {}, i {}, digit {}", value, i, value % 10);
str_buf[len - i - 1] = b'0' + (value % 10) as u8;
value /= 10;
if value <= 0 {
// info!("Ran out of digits at {}", i);
len = i + 1;
break;
}
}
// info!("utf8 buf {}, len {}", str_buf, len);
len
}
enum MyPinMode {
Input,
Output,
Floating,
}
struct MyPin {
mode: MyPinMode,
i_pin: Option<Pin<DynPinId, FunctionSioInput, PullNone>>,
o_pin: Option<Pin<DynPinId, FunctionSioOutput, PullDown>>,
d_pin: Option<Pin<DynPinId, FunctionNull, PullNone>>,
}
impl MyPin {
/// Expects to be passed a fresh gpio pin
fn new(mode: MyPinMode, pin: Pin<DynPinId, FunctionNull, PullDown>) -> Self {
match mode {
MyPinMode::Input => MyPin {
mode,
i_pin: Some(
pin.try_into_function::<FunctionSioInput>()
.unwrap()
.into_pull_type::<PullNone>(),
),
o_pin: None,
d_pin: None,
},
MyPinMode::Output => MyPin {
mode,
i_pin: None,
o_pin: Some(
pin.try_into_function::<FunctionSioOutput>()
.unwrap()
.into_pull_type::<PullDown>(),
),
d_pin: None,
},
MyPinMode::Floating => MyPin {
mode,
i_pin: None,
o_pin: None,
d_pin: Some(pin.into_pull_type::<PullNone>()),
},
}
}
fn switch_to_floating(&mut self) {
self.d_pin = match self.mode {
MyPinMode::Floating => return,
MyPinMode::Input => {
let pin = self.i_pin.take().unwrap();
Some(
pin.into_pull_type::<PullNone>()
.try_into_function::<FunctionNull>()
.unwrap()
.into_pull_type::<PullNone>(),
)
}
MyPinMode::Output => {
let pin = self.o_pin.take().unwrap();
Some(
pin.into_pull_type::<PullNone>()
.try_into_function::<FunctionNull>()
.unwrap()
.into_pull_type::<PullNone>(),
)
}
};
self.mode = MyPinMode::Floating;
}
fn switch_to_input(&mut self) {
self.i_pin = match self.mode {
MyPinMode::Input => return,
MyPinMode::Output => {
let pin = self.o_pin.take().unwrap();
Some(
pin.into_pull_type::<PullNone>()
.try_into_function::<FunctionSioInput>()
.unwrap()
.into_pull_type::<PullNone>(),
)
}
MyPinMode::Floating => {
let pin = self.d_pin.take().unwrap();
Some(
pin.into_pull_type::<PullNone>()
.try_into_function::<FunctionSioInput>()
.unwrap()
.into_pull_type::<PullNone>(),
)
}
};
self.mode = MyPinMode::Input;
}
fn switch_into_output(&mut self) {
self.o_pin = match self.mode {
MyPinMode::Output => return,
MyPinMode::Input => {
let pin = self.i_pin.take().unwrap();
Some(
pin.into_pull_type::<PullDown>()
.try_into_function::<FunctionSioOutput>()
.unwrap(),
)
}
MyPinMode::Floating => {
let pin = self.d_pin.take().unwrap();
Some(
pin.into_pull_type::<PullDown>()
.try_into_function::<FunctionSioOutput>()
.unwrap(),
)
}
};
self.mode = MyPinMode::Output;
}
fn set_low(&mut self) {
match self.mode {
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_low().unwrap(),
_ => println!("Ignoring set_low for input or floating pin"),
}
}
fn set_high(&mut self) {
match self.mode {
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_high().unwrap(),
_ => println!("Ignoring set_high for input or floating pin"),
}
}
fn is_high(&mut self) -> bool {
match self.mode {
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_high().unwrap(),
_ => {
println!("Warning: read of output or floating pin.");
false
}
}
}
fn is_low(&mut self) -> bool {
match self.mode {
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_low().unwrap(),
_ => {
println!("Warning: read of output or floating pin.");
false
}
}
}
}

36
src/onboard_led.rs Normal file
View File

@@ -0,0 +1,36 @@
use embedded_hal::digital::OutputPin;
use rp2040_hal::gpio::{DynPinId, FunctionSioOutput, Pin, PullDown};
pub struct OnboardLed {
led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>,
}
impl OnboardLed {
pub fn new(led_pin: Pin<DynPinId, FunctionSioOutput, PullDown>) -> Self {
Self { led_pin }
}
pub fn set_color(&mut self, r: u8, g: u8, b: u8) {
// ws2812b bitbang
// at 100mHz 1 cycle is 10ns
let color = ((g as u32) << 16) + ((r as u32) << 8) + b as u32;
cortex_m::asm::delay(1000);
for i in 0..24 {
let bit = color & (0x1 << (23 - i));
self.led_pin.set_high().unwrap();
if bit == 0 {
cortex_m::asm::nop();
cortex_m::asm::nop();
cortex_m::asm::nop();
} else {
cortex_m::asm::delay(60);
}
self.led_pin.set_low().unwrap();
cortex_m::asm::delay(35);
}
}
}