~pcein/max7219-pico-rust

48dad1553a10e3024086ddbe84541f7fdfa8ebd1 — Pramode 1 year, 2 months ago
First commit
9 files changed, 1197 insertions(+), 0 deletions(-)

A .cargo/config.toml
A .gitignore
A Cargo.lock
A Cargo.toml
A README.md
A build.rs
A memory.x
A src/cp437.rs
A src/main.rs
A  => .cargo/config.toml +23 -0
@@ 1,23 @@
# Choose a default "cargo run" tool.
# probe-run is recommended if you have a debugger
# elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# runner = "probe-run --chip RP2040"
runner = "elf2uf2-rs -d"

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", "inline-threshold=5",
  "-C", "no-vectorize-loops",
]

[build]
target = "thumbv6m-none-eabi"

A  => .gitignore +1 -0
@@ 1,1 @@
target/

A  => Cargo.lock +637 -0
@@ 1,637 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
 "memchr",
]

[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"

[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"

[[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 = "bare-metal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"

[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"

[[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 = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "cortex-m"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ac919ef424449ec8c08d515590ce15d9262c0ca5f0da5b0c901e971a3b783b3"
dependencies = [
 "bare-metal 0.2.5",
 "bitfield",
 "embedded-hal",
 "volatile-register",
]

[[package]]
name = "cortex-m-rt"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c433da385b720d5bb9f52362fa2782420798e68d40d67bfe4b0d992aba5dfe7"
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 = "crc-any"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "073375684a58dece169afbdc9879a027f3698118ad3814938316c6002b7aa921"
dependencies = [
 "debug-helper",
]

[[package]]
name = "critical-section"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01e191a5a6f6edad9b679777ef6b6c0f2bdd4a333f2ecb8f61c3e28109a03d70"
dependencies = [
 "bare-metal 1.0.0",
 "cfg-if",
 "cortex-m",
 "riscv",
]

[[package]]
name = "debug-helper"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76fbd10dce159c002b9c688ae8ab7cd531151e185e0ad360f4bfea3b0eede3a8"

[[package]]
name = "defmt"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62fb5df4d2b06a2dbf6ba26b49031f5f45f1aafdfca4b9259719466d362f34a0"
dependencies = [
 "bitflags",
 "defmt-macros",
]

[[package]]
name = "defmt-macros"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "098396b763a1786b329405f69bc3677e00d45eb4534bc9f31cd23011ee2ba267"
dependencies = [
 "defmt-parser",
 "proc-macro-error",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "defmt-parser"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d1ce010e1a51aef925c98f12ed81a4e0e96ce0185a87c33f1b3b9c8f20749c7"

[[package]]
name = "defmt-rtt"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "757110fd3748162dddbea88854529888a7e9e36929058118efe06f9f88d93b64"
dependencies = [
 "cortex-m",
 "defmt",
]

[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"

[[package]]
name = "embedded-hal"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9"
dependencies = [
 "nb 0.1.3",
 "void",
]

[[package]]
name = "embedded-time"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58"
dependencies = [
 "num",
]

[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"

[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
 "either",
]

[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"

[[package]]
name = "max7219-pico-rust"
version = "0.1.0"
dependencies = [
 "cortex-m",
 "cortex-m-rt",
 "defmt",
 "defmt-rtt",
 "embedded-hal",
 "embedded-time",
 "panic-probe",
 "rp-pico",
]

[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"

[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
 "nb 1.0.0",
]

[[package]]
name = "nb"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"

[[package]]
name = "num"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
dependencies = [
 "num-complex",
 "num-integer",
 "num-iter",
 "num-rational",
 "num-traits",
]

[[package]]
name = "num-complex"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
dependencies = [
 "num-traits",
]

[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
 "autocfg",
 "num-traits",
]

[[package]]
name = "num-iter"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
dependencies = [
 "autocfg",
 "num-integer",
 "num-traits",
]

[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
 "autocfg",
 "num-integer",
 "num-traits",
]

[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
 "autocfg",
]

[[package]]
name = "num_enum"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad"
dependencies = [
 "num_enum_derive",
]

[[package]]
name = "num_enum_derive"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "panic-probe"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab1f00eac22bd18f8e5cae9555f2820b3a0c166b5b556ee3e203746ea6dcf3a"
dependencies = [
 "cortex-m",
 "defmt",
]

[[package]]
name = "paste"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"

[[package]]
name = "pio"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "593b4978951e32f8dd5b76203503a9dd8dc4665e4bcb4f7fe8e03e33b9f7abc0"
dependencies = [
 "arrayvec",
 "num_enum",
 "paste",
]

[[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.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
 "unicode-xid",
]

[[package]]
name = "quote"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"

[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
 "aho-corasick",
 "memchr",
 "regex-syntax",
]

[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"

[[package]]
name = "riscv"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba"
dependencies = [
 "bare-metal 1.0.0",
 "bit_field",
 "riscv-target",
]

[[package]]
name = "riscv-target"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
dependencies = [
 "lazy_static",
 "regex",
]

[[package]]
name = "rp-pico"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99fc2d1b3bf764c02ee395e520dad1953377e7d68af56713620365e43f27cf29"
dependencies = [
 "cortex-m",
 "cortex-m-rt",
 "embedded-time",
 "rp2040-boot2",
 "rp2040-hal",
 "usb-device",
 "usbd-hid",
 "usbd-serial",
]

[[package]]
name = "rp2040-boot2"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b480fe63133f0d639f82ce5a027fee7cac7ac92f67ef1896ee036a6f9737128"
dependencies = [
 "crc-any",
]

[[package]]
name = "rp2040-hal"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4cc5eed93ae7e2432580923fc5d5797c14b2bf215e1ab84e828f211881393b9"
dependencies = [
 "cortex-m",
 "critical-section",
 "embedded-hal",
 "embedded-time",
 "itertools",
 "nb 1.0.0",
 "paste",
 "pio",
 "rand_core",
 "rp2040-pac",
 "usb-device",
 "vcell",
 "void",
]

[[package]]
name = "rp2040-pac"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04fc92670038074acf20ad422130b735897937812a1761b17cfc26d56c253f"
dependencies = [
 "cortex-m",
 "cortex-m-rt",
 "vcell",
]

[[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 = "serde"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"

[[package]]
name = "ssmarshal"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850"
dependencies = [
 "encode_unicode",
 "serde",
]

[[package]]
name = "syn"
version = "1.0.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-xid",
]

[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

[[package]]
name = "usb-device"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6be90410d4772074ea49525e2e753b65920b94b57eee21a6ef7b6a6fe6296245"

[[package]]
name = "usbd-hid"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "183b7e65bbd75512aedf250deda89394c74ae3118b79fe41f159e8503e1d5d7f"
dependencies = [
 "serde",
 "ssmarshal",
 "usb-device",
 "usbd-hid-macros",
]

[[package]]
name = "usbd-hid-descriptors"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e00430c0b39caf3957aba6c2b2824f8e70e1ac0278941418bf1fe35f9566d64"
dependencies = [
 "bitfield",
]

[[package]]
name = "usbd-hid-macros"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78bd005b3aa54e62905d99df49a75d11888bb958eb780adb5e8f2029733077df"
dependencies = [
 "byteorder",
 "proc-macro2",
 "quote",
 "serde",
 "syn",
 "usbd-hid-descriptors",
]

[[package]]
name = "usbd-serial"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe"
dependencies = [
 "embedded-hal",
 "nb 0.1.3",
 "usb-device",
]

[[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",
]

A  => Cargo.toml +79 -0
@@ 1,79 @@
[package]
authors = ["Pramode C.E"]
edition = "2018"
readme = "README.md"
name = "max7219-pico-rust"
version = "0.1.0"
resolver = "2"

[dependencies]
cortex-m = "0.7.3"
cortex-m-rt = "0.7.0"
embedded-hal = { version = "0.2.5", features=["unproven"] }
embedded-time = "0.12.0"

defmt = "0.3.0"
defmt-rtt = "0.3.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

# We're using a Pico by default on this template
rp-pico = "0.2.0"

# but you can use any BSP. Uncomment this to use the pro_micro_rp2040 BSP instead
# sparkfun-pro-micro-rp2040 = "0.1.0"

# If you're not going to use a Board Support Package you'll need these:
# rp2040-hal = { version="0.3.0", features=["rt"] }
# rp2040-boot2 = "0.2.0"

# cargo build/run
[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo build/run --release
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3
overflow-checks = false

# do not optimize proc-macro crates = faster builds from scratch
[profile.dev.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

[profile.release.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false

# cargo test
[profile.test]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

# cargo test --release
[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3

A  => README.md +5 -0
@@ 1,5 @@
# Use MAX7219 to interface a Raspberry Pico with 8x8 LED display

Rust translation of: https://github.com/riyas-org/max7219/tree/master/max7219-rpi,
running on a Raspberry Pi Pico board.


A  => build.rs +31 -0
@@ 1,31 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

fn main() {
    // Put `memory.x` in our output directory and ensure it's
    // on the linker search path.
    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
    File::create(out.join("memory.x"))
        .unwrap()
        .write_all(include_bytes!("memory.x"))
        .unwrap();
    println!("cargo:rustc-link-search={}", out.display());

    // By default, Cargo will re-run a build script whenever
    // any file in the project changes. By specifying `memory.x`
    // here, we ensure the build script is only re-run when
    // `memory.x` is changed.
    println!("cargo:rerun-if-changed=memory.x");
}

A  => memory.x +15 -0
@@ 1,15 @@
MEMORY {
    BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
    FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
    RAM   : ORIGIN = 0x20000000, LENGTH = 256K
}

EXTERN(BOOT2_FIRMWARE)

SECTIONS {
    /* ### Boot loader */
    .boot2 ORIGIN(BOOT2) :
    {
        KEEP(*(.boot2));
    } > BOOT2
} INSERT BEFORE .text;
\ No newline at end of file

A  => src/cp437.rs +263 -0
@@ 1,263 @@
// Bit patterns for the CP437 font
// see https://en.wikipedia.org/wiki/Code_page_437 for details

// Also see: https://github.com/riyas-org/max7219/blob/master/max7219-rpi/src/transitions.py

pub(crate) static cp437_FONT: [[u8; 8]; 256] = [
    [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // 0x00
    [0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E], // 0x01
    [0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E], // 0x02
    [0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00], // 0x03
    [0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00], // 0x04
    [0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00], // 0x05
    [0x10, 0xB8, 0xFC, 0xFF, 0xFC, 0xB8, 0x10, 0x00], // 0x06
    [0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00], // 0x07
    [0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF], // 0x08
    [0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00], // 0x09
    [0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF], // 0x0A
    [0x70, 0xF8, 0x88, 0x88, 0xFD, 0x7F, 0x07, 0x0F], // 0x0B
    [0x00, 0x4E, 0x5F, 0xF1, 0xF1, 0x5F, 0x4E, 0x00], // 0x0C
    [0xC0, 0xE0, 0xFF, 0x7F, 0x05, 0x05, 0x07, 0x07], // 0x0D
    [0xC0, 0xFF, 0x7F, 0x05, 0x05, 0x65, 0x7F, 0x3F], // 0x0E
    [0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99], // 0x0F
    [0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x00], // 0x10
    [0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x3E, 0x7F, 0x00], // 0x11
    [0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00], // 0x12
    [0x00, 0x5F, 0x5F, 0x00, 0x00, 0x5F, 0x5F, 0x00], // 0x13
    [0x06, 0x0F, 0x09, 0x7F, 0x7F, 0x01, 0x7F, 0x7F], // 0x14
    [0x40, 0xDA, 0xBF, 0xA5, 0xFD, 0x59, 0x03, 0x02], // 0x15
    [0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00], // 0x16
    [0x80, 0x94, 0xB6, 0xFF, 0xFF, 0xB6, 0x94, 0x80], // 0x17
    [0x00, 0x04, 0x06, 0x7F, 0x7F, 0x06, 0x04, 0x00], // 0x18
    [0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00], // 0x19
    [0x08, 0x08, 0x08, 0x2A, 0x3E, 0x1C, 0x08, 0x00], // 0x1A
    [0x08, 0x1C, 0x3E, 0x2A, 0x08, 0x08, 0x08, 0x00], // 0x1B
    [0x3C, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00], // 0x1C
    [0x08, 0x1C, 0x3E, 0x08, 0x08, 0x3E, 0x1C, 0x08], // 0x1D
    [0x30, 0x38, 0x3C, 0x3E, 0x3E, 0x3C, 0x38, 0x30], // 0x1E
    [0x06, 0x0E, 0x1E, 0x3E, 0x3E, 0x1E, 0x0E, 0x06], // 0x1F
    [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // ' '
    [0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00], // '!'
    [0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00], // '"'
    [0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00], // '//'
    [0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00], // '$'
    [0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00], // '%'
    [0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00], // '&'
    [0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00], // '''
    [0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00], // '('
    [0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00], // ')'
    [0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08], // '*'
    [0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00], // '+'
    [0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00], // ','
    [0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00], // '-'
    [0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00], // '.'
    [0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00], // '/'
    [0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00], // '0'
    [0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00], // '1'
    [0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00], // '2'
    [0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00], // '3'
    [0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00], // '4'
    [0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00], // '5'
    [0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00], // '6'
    [0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00], // '7'
    [0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00], // '8'
    [0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00], // '9'
    [0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00], // ':'
    [0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00], // ';'
    [0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00], // '<'
    [0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00], // '='
    [0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00], // '>'
    [0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00], // '?'
    [0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00], // '@'
    [0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00], // 'A'
    [0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00], // 'B'
    [0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00], // 'C'
    [0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00], // 'D'
    [0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00], // 'E'
    [0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00], // 'F'
    [0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00], // 'G'
    [0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00], // 'H'
    [0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00], // 'I'
    [0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00], // 'J'
    [0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00], // 'K'
    [0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00], // 'L'
    [0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00], // 'M'
    [0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00], // 'N'
    [0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00], // 'O'
    [0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00], // 'P'
    [0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00], // 'Q'
    [0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00], // 'R'
    [0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00], // 'S'
    [0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00], // 'T'
    [0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00], // 'U'
    [0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00], // 'V'
    [0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00], // 'W'
    [0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00], // 'X'
    [0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00], // 'Y'
    [0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00], // 'Z'
    [0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00], // '['
    [0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00], // backslash
    [0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00], // ']'
    [0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00], // '^'
    [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80], // '_'
    [0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00], // '`'
    [0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00], // 'a'
    [0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00], // 'b'
    [0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00], // 'c'
    [0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00], // 'd'
    [0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00], // 'e'
    [0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00], // 'f'
    [0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00], // 'g'
    [0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00], // 'h'
    [0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00], // 'i'
    [0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00], // 'j'
    [0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00], // 'k'
    [0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00], // 'l'
    [0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00], // 'm'
    [0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00], // 'n'
    [0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00], // 'o'
    [0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00], // 'p'
    [0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00], // 'q'
    [0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00], // 'r'
    [0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00], // 's'
    [0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00], // 't'
    [0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00], // 'u'
    [0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00], // 'v'
    [0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00], // 'w'
    [0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00], // 'x'
    [0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00], // 'y'
    [0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00], // 'z'
    [0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00], // '{'
    [0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00], // '|'
    [0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00], // '}'
    [0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00], // '~'
    [0x70, 0x78, 0x4C, 0x46, 0x4C, 0x78, 0x70, 0x00], // 0x7F
    [0x0E, 0x9F, 0x91, 0xB1, 0xFB, 0x4A, 0x00, 0x00], // 0x80
    [0x3A, 0x7A, 0x40, 0x40, 0x7A, 0x7A, 0x40, 0x00], // 0x81
    [0x38, 0x7C, 0x54, 0x55, 0x5D, 0x19, 0x00, 0x00], // 0x82
    [0x02, 0x23, 0x75, 0x55, 0x55, 0x7D, 0x7B, 0x42], // 0x83
    [0x21, 0x75, 0x54, 0x54, 0x7D, 0x79, 0x40, 0x00], // 0x84
    [0x21, 0x75, 0x55, 0x54, 0x7C, 0x78, 0x40, 0x00], // 0x85
    [0x20, 0x74, 0x57, 0x57, 0x7C, 0x78, 0x40, 0x00], // 0x86
    [0x18, 0x3C, 0xA4, 0xA4, 0xE4, 0x40, 0x00, 0x00], // 0x87
    [0x02, 0x3B, 0x7D, 0x55, 0x55, 0x5D, 0x1B, 0x02], // 0x88
    [0x39, 0x7D, 0x54, 0x54, 0x5D, 0x19, 0x00, 0x00], // 0x89
    [0x39, 0x7D, 0x55, 0x54, 0x5C, 0x18, 0x00, 0x00], // 0x8A
    [0x01, 0x45, 0x7C, 0x7C, 0x41, 0x01, 0x00, 0x00], // 0x8B
    [0x02, 0x03, 0x45, 0x7D, 0x7D, 0x43, 0x02, 0x00], // 0x8C
    [0x01, 0x45, 0x7D, 0x7C, 0x40, 0x00, 0x00, 0x00], // 0x8D
    [0x79, 0x7D, 0x16, 0x12, 0x16, 0x7D, 0x79, 0x00], // 0x8E
    [0x70, 0x78, 0x2B, 0x2B, 0x78, 0x70, 0x00, 0x00], // 0x8F
    [0x44, 0x7C, 0x7C, 0x55, 0x55, 0x45, 0x00, 0x00], // 0x90
    [0x20, 0x74, 0x54, 0x54, 0x7C, 0x7C, 0x54, 0x54], // 0x91
    [0x7C, 0x7E, 0x0B, 0x09, 0x7F, 0x7F, 0x49, 0x00], // 0x92
    [0x32, 0x7B, 0x49, 0x49, 0x7B, 0x32, 0x00, 0x00], // 0x93
    [0x32, 0x7A, 0x48, 0x48, 0x7A, 0x32, 0x00, 0x00], // 0x94
    [0x32, 0x7A, 0x4A, 0x48, 0x78, 0x30, 0x00, 0x00], // 0x95
    [0x3A, 0x7B, 0x41, 0x41, 0x7B, 0x7A, 0x40, 0x00], // 0x96
    [0x3A, 0x7A, 0x42, 0x40, 0x78, 0x78, 0x40, 0x00], // 0x97
    [0x9A, 0xBA, 0xA0, 0xA0, 0xFA, 0x7A, 0x00, 0x00], // 0x98
    [0x01, 0x19, 0x3C, 0x66, 0x66, 0x3C, 0x19, 0x01], // 0x99
    [0x3D, 0x7D, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00], // 0x9A
    [0x18, 0x3C, 0x24, 0xE7, 0xE7, 0x24, 0x24, 0x00], // 0x9B
    [0x68, 0x7E, 0x7F, 0x49, 0x43, 0x66, 0x20, 0x00], // 0x9C
    [0x2B, 0x2F, 0xFC, 0xFC, 0x2F, 0x2B, 0x00, 0x00], // 0x9D
    [0xFF, 0xFF, 0x09, 0x09, 0x2F, 0xF6, 0xF8, 0xA0], // 0x9E
    [0x40, 0xC0, 0x88, 0xFE, 0x7F, 0x09, 0x03, 0x02], // 0x9F
    [0x20, 0x74, 0x54, 0x55, 0x7D, 0x79, 0x40, 0x00], // 0xA0
    [0x00, 0x44, 0x7D, 0x7D, 0x41, 0x00, 0x00, 0x00], // 0xA1
    [0x30, 0x78, 0x48, 0x4A, 0x7A, 0x32, 0x00, 0x00], // 0xA2
    [0x38, 0x78, 0x40, 0x42, 0x7A, 0x7A, 0x40, 0x00], // 0xA3
    [0x7A, 0x7A, 0x0A, 0x0A, 0x7A, 0x70, 0x00, 0x00], // 0xA4
    [0x7D, 0x7D, 0x19, 0x31, 0x7D, 0x7D, 0x00, 0x00], // 0xA5
    [0x00, 0x26, 0x2F, 0x29, 0x2F, 0x2F, 0x28, 0x00], // 0xA6
    [0x00, 0x26, 0x2F, 0x29, 0x2F, 0x26, 0x00, 0x00], // 0xA7
    [0x30, 0x78, 0x4D, 0x45, 0x60, 0x20, 0x00, 0x00], // 0xA8
    [0x38, 0x38, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00], // 0xA9
    [0x08, 0x08, 0x08, 0x08, 0x38, 0x38, 0x00, 0x00], // 0xAA
    [0x4F, 0x6F, 0x30, 0x18, 0xCC, 0xEE, 0xBB, 0x91], // 0xAB
    [0x4F, 0x6F, 0x30, 0x18, 0x6C, 0x76, 0xFB, 0xF9], // 0xAC
    [0x00, 0x00, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x00], // 0xAD
    [0x08, 0x1C, 0x36, 0x22, 0x08, 0x1C, 0x36, 0x22], // 0xAE
    [0x22, 0x36, 0x1C, 0x08, 0x22, 0x36, 0x1C, 0x08], // 0xAF
    [0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00], // 0xB0
    [0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55], // 0xB1
    [0xDD, 0xFF, 0xAA, 0x77, 0xDD, 0xAA, 0xFF, 0x77], // 0xB2
    [0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00], // 0xB3
    [0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00], // 0xB4
    [0x14, 0x14, 0x14, 0xFF, 0xFF, 0x00, 0x00, 0x00], // 0xB5
    [0x10, 0x10, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00], // 0xB6
    [0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x00], // 0xB7
    [0x14, 0x14, 0x14, 0xFC, 0xFC, 0x00, 0x00, 0x00], // 0xB8
    [0x14, 0x14, 0xF7, 0xF7, 0x00, 0xFF, 0xFF, 0x00], // 0xB9
    [0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00], // 0xBA
    [0x14, 0x14, 0xF4, 0xF4, 0x04, 0xFC, 0xFC, 0x00], // 0xBB
    [0x14, 0x14, 0x17, 0x17, 0x10, 0x1F, 0x1F, 0x00], // 0xBC
    [0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x00], // 0xBD
    [0x14, 0x14, 0x14, 0x1F, 0x1F, 0x00, 0x00, 0x00], // 0xBE
    [0x10, 0x10, 0x10, 0xF0, 0xF0, 0x00, 0x00, 0x00], // 0xBF
    [0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x10], // 0xC0
    [0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10], // 0xC1
    [0x10, 0x10, 0x10, 0xF0, 0xF0, 0x10, 0x10, 0x10], // 0xC2
    [0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10], // 0xC3
    [0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10], // 0xC4
    [0x10, 0x10, 0x10, 0xFF, 0xFF, 0x10, 0x10, 0x10], // 0xC5
    [0x00, 0x00, 0x00, 0xFF, 0xFF, 0x14, 0x14, 0x14], // 0xC6
    [0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x10], // 0xC7
    [0x00, 0x00, 0x1F, 0x1F, 0x10, 0x17, 0x17, 0x14], // 0xC8
    [0x00, 0x00, 0xFC, 0xFC, 0x04, 0xF4, 0xF4, 0x14], // 0xC9
    [0x14, 0x14, 0x17, 0x17, 0x10, 0x17, 0x17, 0x14], // 0xCA
    [0x14, 0x14, 0xF4, 0xF4, 0x04, 0xF4, 0xF4, 0x14], // 0xCB
    [0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF7, 0xF7, 0x14], // 0xCC
    [0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14], // 0xCD
    [0x14, 0x14, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0x14], // 0xCE
    [0x14, 0x14, 0x14, 0x17, 0x17, 0x14, 0x14, 0x14], // 0xCF
    [0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10], // 0xD0
    [0x14, 0x14, 0x14, 0xF4, 0xF4, 0x14, 0x14, 0x14], // 0xD1
    [0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10], // 0xD2
    [0x00, 0x00, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10], // 0xD3
    [0x00, 0x00, 0x00, 0x1F, 0x1F, 0x14, 0x14, 0x14], // 0xD4
    [0x00, 0x00, 0x00, 0xFC, 0xFC, 0x14, 0x14, 0x14], // 0xD5
    [0x00, 0x00, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10], // 0xD6
    [0x10, 0x10, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0x10], // 0xD7
    [0x14, 0x14, 0x14, 0xFF, 0xFF, 0x14, 0x14, 0x14], // 0xD8
    [0x10, 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00], // 0xD9
    [0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10], // 0xDA
    [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], // 0xDB
    [0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0], // 0xDC
    [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00], // 0xDD
    [0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF], // 0xDE
    [0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F], // 0xDF
    [0x38, 0x7C, 0x44, 0x6C, 0x38, 0x6C, 0x44, 0x00], // 0xE0
    [0xFC, 0xFE, 0x2A, 0x2A, 0x3E, 0x14, 0x00, 0x00], // 0xE1
    [0x7E, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x00, 0x00], // 0xE2
    [0x02, 0x7E, 0x7E, 0x02, 0x7E, 0x7E, 0x02, 0x00], // 0xE3
    [0x63, 0x77, 0x5D, 0x49, 0x63, 0x63, 0x00, 0x00], // 0xE4
    [0x38, 0x7C, 0x44, 0x7C, 0x3C, 0x04, 0x04, 0x00], // 0xE5
    [0x80, 0xFE, 0x7E, 0x20, 0x20, 0x3E, 0x1E, 0x00], // 0xE6
    [0x04, 0x06, 0x02, 0x7E, 0x7C, 0x06, 0x02, 0x00], // 0xE7
    [0x99, 0xBD, 0xE7, 0xE7, 0xBD, 0x99, 0x00, 0x00], // 0xE8
    [0x1C, 0x3E, 0x6B, 0x49, 0x6B, 0x3E, 0x1C, 0x00], // 0xE9
    [0x4C, 0x7E, 0x73, 0x01, 0x73, 0x7E, 0x4C, 0x00], // 0xEA
    [0x30, 0x78, 0x4A, 0x4F, 0x7D, 0x39, 0x00, 0x00], // 0xEB
    [0x18, 0x3C, 0x24, 0x3C, 0x3C, 0x24, 0x3C, 0x18], // 0xEC
    [0x98, 0xFC, 0x64, 0x3C, 0x3E, 0x27, 0x3D, 0x18], // 0xED
    [0x1C, 0x3E, 0x6B, 0x49, 0x49, 0x00, 0x00, 0x00], // 0xEE
    [0x7E, 0x7F, 0x01, 0x01, 0x7F, 0x7E, 0x00, 0x00], // 0xEF
    [0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, 0x00], // 0xF0
    [0x44, 0x44, 0x5F, 0x5F, 0x44, 0x44, 0x00, 0x00], // 0xF1
    [0x40, 0x51, 0x5B, 0x4E, 0x44, 0x40, 0x00, 0x00], // 0xF2
    [0x40, 0x44, 0x4E, 0x5B, 0x51, 0x40, 0x00, 0x00], // 0xF3
    [0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x07, 0x06], // 0xF4
    [0x60, 0xE0, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00], // 0xF5
    [0x08, 0x08, 0x6B, 0x6B, 0x08, 0x08, 0x00, 0x00], // 0xF6
    [0x24, 0x36, 0x12, 0x36, 0x24, 0x36, 0x12, 0x00], // 0xF7
    [0x00, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00], // 0xF8
    [0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00], // 0xF9
    [0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00], // 0xFA
    [0x10, 0x30, 0x70, 0xC0, 0xFF, 0xFF, 0x01, 0x01], // 0xFB
    [0x00, 0x1F, 0x1F, 0x01, 0x1F, 0x1E, 0x00, 0x00], // 0xFC
    [0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x00, 0x00], // 0xFD
    [0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00], // 0xFE
    [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // 0xFF
]; //  end of cp437_FONT

A  => src/main.rs +143 -0
@@ 1,143 @@
//! Blinks the LED on a Pico board
//!
//! This will blink an LED attached to GP25, which is the pin the Pico uses for the on-board LED.
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use defmt::*;
use defmt_rtt as _;
use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex;
use embedded_time::fixed_point::FixedPoint;
use embedded_time::rate::Extensions;
use panic_probe as _;

// Provide an alias for our BSP so we can switch targets quickly.
// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change.
use rp_pico as bsp;
// use sparkfun_pro_micro_rp2040 as bsp;

use bsp::hal::{
    clocks::{init_clocks_and_plls, Clock},
    pac,
    sio::Sio,
    spi::{Enabled, Spi, SpiDevice},
    watchdog::Watchdog,
};

mod cp437;
use cp437::cp437_FONT;

struct Max7219<D>
where
    D: SpiDevice,
{
    spi: Spi<Enabled, D, 16>,
    delay: cortex_m::delay::Delay,
}

impl<D> Max7219<D>
where
    D: SpiDevice,
{
    fn new(s: Spi<Enabled, D, 16>, d: cortex_m::delay::Delay) -> Self {
        Max7219 { spi: s, delay: d }
    }

    fn init(&mut self) {
        self.spi.send(0x0b07);
        self.spi.send(0x0900);
        self.spi.send(0x0f00);
        // intensity = 10
        self.spi.send(0x0a0a);
        // not in shutdown mode
        self.spi.send(0x0c01);
    }

    fn clear(&mut self) {
        for col in 1..9 {
            self.spi.send((col as u16) << 8);
            self.delay.delay_ms(1);
        }
    }

    fn scroll_left(&mut self, from_char: u8, to_char: u8, font: &[[u8; 8]]) {
        let mut data = 0u16;
        for i in 0..8 {
            self.delay.delay_ms(90);
            for col in 0..8 {
                if (col + i) < 8 {
                    data = font[from_char as usize][col + i] as u16;
                } else {
                    data = font[to_char as usize][col + i - 8] as u16;
                }
                self.spi.send(((col as u16 + 1) << 8) + data);
                self.delay.delay_ms(1);
            }
        }
    }

    fn show_message(&mut self, msg: &str, font: &[[u8; 8]]) {
        let mut prev = ' ';
        for curr in msg.chars() {
            self.scroll_left(prev as u8, curr as u8, font);
            prev = curr;
        }
        self.scroll_left(prev as u8, ' ' as u8, font);
    }
}

#[entry]
fn main() -> ! {
    let mut pac = pac::Peripherals::take().unwrap();
    let core = pac::CorePeripherals::take().unwrap();
    let mut watchdog = Watchdog::new(pac.WATCHDOG);
    let sio = Sio::new(pac.SIO);

    // External high-speed crystal on the pico board is 12Mhz
    let external_xtal_freq_hz = 12_000_000u32;
    let clocks = init_clocks_and_plls(
        external_xtal_freq_hz,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    let pins = bsp::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );

    let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer());

    let _spi1_sck = pins.gpio14.into_mode::<bsp::hal::gpio::FunctionSpi>();
    let _spi1_tx = pins.gpio15.into_mode::<bsp::hal::gpio::FunctionSpi>();
    let _spi1_cs = pins.gpio13.into_mode::<bsp::hal::gpio::FunctionSpi>();

    let spi = bsp::hal::Spi::<_, _, 16>::new(pac.SPI1);
    // Exchange the uninitialised SPI driver for an initialised one
    let mut spi = spi.init(
        &mut pac.RESETS,
        clocks.peripheral_clock.freq(),
        1_000_000u32.Hz(),
        &embedded_hal::spi::MODE_0,
    );

    let mut max7219 = Max7219::new(spi, delay);

    max7219.init();
    max7219.clear();
    loop {
        max7219.show_message("Happy New Year @rustembedded !!", &cp437_FONT);
    }

    loop {}
}