ESP
This commit is contained in:
parent
a4884bd189
commit
865599e059
64 changed files with 6448 additions and 1221 deletions
17
samd/.cargo/config.toml
Normal file
17
samd/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# samd21 is a Cortex-M0 and thus thumbv6m
|
||||
|
||||
[build]
|
||||
target = "thumbv6m-none-eabi"
|
||||
|
||||
[target.thumbv6m-none-eabi]
|
||||
runner = 'arm-none-eabi-gdb'
|
||||
#runner = 'probe-run --chip ATSAMD21G18A'
|
||||
|
||||
rustflags = [
|
||||
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
]
|
||||
1
samd/.gitignore
vendored
Normal file
1
samd/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
target
|
||||
768
samd/Cargo.lock
generated
Normal file
768
samd/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,768 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atsamd-hal"
|
||||
version = "0.17.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"atsamd-hal-macros",
|
||||
"atsamd21g",
|
||||
"bitfield",
|
||||
"bitflags",
|
||||
"cipher",
|
||||
"cortex-m",
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-hal 1.0.0",
|
||||
"embedded-hal-nb",
|
||||
"embedded-io",
|
||||
"embedded-sdmmc",
|
||||
"fugit",
|
||||
"modular-bitfield",
|
||||
"nb 1.1.0",
|
||||
"num-traits",
|
||||
"opaque-debug",
|
||||
"paste",
|
||||
"rand_core",
|
||||
"seq-macro",
|
||||
"typenum",
|
||||
"usb-device",
|
||||
"vcell",
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atsamd-hal-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atsamd21g"
|
||||
version = "0.13.0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"critical-section",
|
||||
"vcell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[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 = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"bitfield",
|
||||
"critical-section",
|
||||
"embedded-hal 0.2.7",
|
||||
"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 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242"
|
||||
|
||||
[[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-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 = "embedded-sdmmc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d3bf0a2b5becb87e9a329d9290f131e4d10fec39b56d129926826a7cbea1e7a"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"embedded-hal 0.2.7",
|
||||
"log",
|
||||
"nb 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "fugit"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
|
||||
dependencies = [
|
||||
"gcd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcd"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[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 = "indexmap"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "lilos"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090b27a32adb71568314e1c256f3f79b917e74194f0aba4d0e7493537e2820e9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"lilos-list",
|
||||
"pin-project",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lilos-list"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a0f878c972c8b8c28a03b0b433c7f4b0861de43de55fe04546fe44ff7fa32b8"
|
||||
dependencies = [
|
||||
"pin-project",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "maduino_zero_4g"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"atsamd-hal",
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"embedded-sdmmc",
|
||||
"usb-device",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "modular-bitfield"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74"
|
||||
dependencies = [
|
||||
"modular-bitfield-impl",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "modular-bitfield-impl"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[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-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "panic-halt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustphone"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"atsamd-hal",
|
||||
"cortex-m",
|
||||
"futures",
|
||||
"lilos",
|
||||
"maduino_zero_4g",
|
||||
"nb 1.1.0",
|
||||
"panic-halt",
|
||||
"usb-device",
|
||||
"usbd-serial",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[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 = "seq-macro"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.209"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[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.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[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 = "usbd-serial"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "065e4eaf93db81d5adac82d9cef8f8da314cb640fa7f89534b972383f1cf80fc"
|
||||
dependencies = [
|
||||
"embedded-hal 0.2.7",
|
||||
"embedded-io",
|
||||
"nb 1.1.0",
|
||||
"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.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[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",
|
||||
]
|
||||
48
samd/Cargo.toml
Normal file
48
samd/Cargo.toml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
[package]
|
||||
name = "rustphone"
|
||||
version = "0.1.0"
|
||||
authors = ["tuxmain <tuxmain@zettascript.org>"]
|
||||
repository = "https://git.txmn.tk/tuxmain/rustphone"
|
||||
license = "AGPL-3.0-only"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
#arrayvec = { version = "0.7.4", default_features = false }
|
||||
atsamd-hal = { git = "https://github.com/ZettaScript/atsamd", branch = "maduino-zero-4g", default_features = false, features = ["dma", "samd21g", "samd21g-rt", "usb"] }
|
||||
#cfg-if = "1.0.0"
|
||||
cortex-m = "0.7.7"
|
||||
#embedded-graphics = "0.8.1"
|
||||
#embedded-layout = "0.4.1"
|
||||
#embedded-text = "0.7.0"
|
||||
#embedded-sdmmc = { version = "0.3.0", default_features = false }
|
||||
#epd-waveshare = "0.5.0"
|
||||
#epd-waveshare = { git = "https://github.com/caemor/epd-waveshare.git" }
|
||||
#epd-waveshare = { path = "../../epd-waveshare" }
|
||||
futures = { version = "0.3.30", default-features = false, features = ["async-await"] }
|
||||
lilos = { version = "1.2.0" }
|
||||
maduino_zero_4g = { git = "https://github.com/ZettaScript/atsamd", branch = "maduino-zero-4g", features = ["dma", "usb"] }
|
||||
nb = "1.1.0"
|
||||
panic-halt = "0.2.0"
|
||||
#static_assertions = "1.1.0"
|
||||
#tz-rs = { version = "0.6.14", default_features = false, features = ["const"] }
|
||||
#tzdb = { version = "0.6.1", optional = true }
|
||||
usbd-serial = "0.2"
|
||||
usb-device = "0.3.1"
|
||||
|
||||
# simulator
|
||||
#embedded-graphics-simulator = { version = "0.6.0", optional = true }
|
||||
|
||||
[features]
|
||||
#default = ["simulator"]
|
||||
|
||||
#simulator = ["embedded-graphics-simulator", "tzdb"]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
lto = "fat"
|
||||
opt-level = 3
|
||||
debug = 0
|
||||
|
||||
[patch."https://github.com/ZettaScript/atsamd"]
|
||||
atsamd-hal = { path = "../../atsamd/hal" }
|
||||
maduino_zero_4g = { path = "../../atsamd/boards/maduino_zero_4g" }
|
||||
2
samd/flash.sh
Normal file
2
samd/flash.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
cargo flash --release --target thumbv6m-none-eabi --chip ATSAMD21G18A --protocol swd || exit 1
|
||||
probe-run -v --no-flash --chip ATSAMD21G18A target/thumbv6m-none-eabi/release/rustphone
|
||||
6
samd/memory.x
Normal file
6
samd/memory.x
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
|
||||
}
|
||||
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
||||
3
samd/openocd.sh
Normal file
3
samd/openocd.sh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
cargo build --release --target thumbv6m-none-eabi || exit 1
|
||||
cp target/thumbv6m-none-eabi/release/rustphone /tmp/rustphone.elf || exit 1
|
||||
openocd -f /usr/share/openocd/scripts/board/atmel_samd21_xplained_pro.cfg -c "program /tmp/rustphone.elf verify reset exit"
|
||||
9
samd/rustfmt.toml
Normal file
9
samd/rustfmt.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
hard_tabs = true
|
||||
newline_style = "unix"
|
||||
imports_granularity = "Crate"
|
||||
|
||||
unstable_features = true
|
||||
format_code_in_doc_comments = true
|
||||
format_macro_bodies = true
|
||||
format_macro_matchers = true
|
||||
format_strings = true
|
||||
17
samd/src/bak/apps.rs
Normal file
17
samd/src/bak/apps.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use crate::{display::Display, keypad::KeyEvents, state::ModeState, Context};
|
||||
|
||||
pub mod clock;
|
||||
pub mod dial;
|
||||
|
||||
pub trait App {
|
||||
type AppModeState;
|
||||
|
||||
/// Called when the state is entered, before update
|
||||
fn on_enter(context: &mut Context, mode_state: &mut Self::AppModeState);
|
||||
|
||||
/// Return Some if the mode should be changed
|
||||
fn update(context: &mut Context, mode_state: &mut Self::AppModeState) -> Option<ModeState>;
|
||||
|
||||
/// Called when the state is left, after update
|
||||
fn on_leave(context: &mut Context, mode_state: &mut Self::AppModeState);
|
||||
}
|
||||
126
samd/src/bak/apps/clock.rs
Normal file
126
samd/src/bak/apps/clock.rs
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
use crate::{
|
||||
apps::{self, App},
|
||||
display::*,
|
||||
keypad::*,
|
||||
state::{self, ModeState},
|
||||
strf, Context,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
use embedded_graphics::{
|
||||
mono_font::{ascii::FONT_10X20, MonoTextStyleBuilder},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
text::{Alignment, Text},
|
||||
geometry::Dimensions
|
||||
};
|
||||
|
||||
pub struct Clock;
|
||||
|
||||
pub struct ClockState {
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
week_day: u8,
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for ClockState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
year: 0,
|
||||
month: 0,
|
||||
day: 0,
|
||||
week_day: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App for Clock {
|
||||
type AppModeState = ClockState;
|
||||
|
||||
fn on_enter(ctx: &mut Context, mode_state: &mut ClockState) {
|
||||
ctx.state.key_label_left.clear();
|
||||
ctx.state.key_label_left.push_str("Journal");
|
||||
ctx.state.key_label_enter.clear();
|
||||
ctx.state.key_label_enter.push_str("Menu");
|
||||
ctx.state.key_label_right.clear();
|
||||
ctx.state.key_label_right.push_str("Contacts");
|
||||
ctx.key_labels_change = true;
|
||||
}
|
||||
|
||||
fn update(ctx: &mut Context, mode_state: &mut ClockState) -> Option<ModeState> {
|
||||
// TODO move at init
|
||||
let clock_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_10X20)
|
||||
.text_color(WHITE)
|
||||
.background_color(BLACK)
|
||||
.build();
|
||||
|
||||
for key_event in &ctx.key_events {
|
||||
if key_event.event_type != KeyEventType::Pressed {
|
||||
continue;
|
||||
}
|
||||
match key_event.key {
|
||||
_ => {
|
||||
if let Some(ch) = key_event.get_char(KeyInputMode::Digit) {
|
||||
let mut buf = [0; 4];
|
||||
return Some(ModeState::Dial(apps::dial::DialState {
|
||||
line: ArrayString::from(&*ch.encode_utf8(&mut buf)).unwrap(),
|
||||
line_changed: true,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.hm_change {
|
||||
Text::with_alignment(
|
||||
unsafe {
|
||||
core::str::from_utf8_unchecked(&strf::fmt_time_hm(
|
||||
ctx.state.hour,
|
||||
ctx.state.minute,
|
||||
))
|
||||
},
|
||||
ctx.display.inner().bounding_box().center() + Point::new(0, 10),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
let year_ = ctx.now.year();
|
||||
let month_ = ctx.now.month();
|
||||
let day_ = ctx.now.month_day();
|
||||
let week_day_ = ctx.now.week_day();
|
||||
if (year_, month_, day_, week_day_)
|
||||
!= (
|
||||
mode_state.year,
|
||||
mode_state.month,
|
||||
mode_state.day,
|
||||
mode_state.week_day,
|
||||
) {
|
||||
mode_state.year = year_;
|
||||
mode_state.month = month_;
|
||||
mode_state.day = day_;
|
||||
mode_state.week_day = week_day_;
|
||||
Text::with_alignment(
|
||||
unsafe {
|
||||
core::str::from_utf8_unchecked(&strf::fmt_time_ymdw(
|
||||
year_, month_, day_, week_day_,
|
||||
))
|
||||
},
|
||||
ctx.display.inner().bounding_box().center() + Point::new(0, -20),
|
||||
clock_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn on_leave(ctx: &mut Context, mode_state: &mut ClockState) {}
|
||||
}
|
||||
105
samd/src/bak/apps/dial.rs
Normal file
105
samd/src/bak/apps/dial.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use crate::{
|
||||
apps::App,
|
||||
display::*,
|
||||
keypad::{Key, KeyEvent, KeyEventType, KeyEvents, KeyInputMode},
|
||||
state::{ModeState, State},
|
||||
Context,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
use embedded_graphics::{
|
||||
mono_font::{
|
||||
ascii::{FONT_10X20, FONT_6X10, FONT_9X15},
|
||||
MonoTextStyleBuilder,
|
||||
},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
primitives::{Line, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment},
|
||||
text::{Alignment, Text},
|
||||
};
|
||||
use embedded_text::{
|
||||
alignment::*,
|
||||
style::{HeightMode, TextBoxStyleBuilder},
|
||||
TextBox,
|
||||
};
|
||||
|
||||
pub struct Dial;
|
||||
|
||||
pub struct DialState {
|
||||
pub line: ArrayString<40>,
|
||||
pub line_changed: bool,
|
||||
}
|
||||
|
||||
impl App for Dial {
|
||||
type AppModeState = DialState;
|
||||
|
||||
fn on_enter(ctx: &mut Context, mode_state: &mut DialState) {
|
||||
ctx.state.key_label_left.clear();
|
||||
ctx.state.key_label_left.push_str("Message");
|
||||
ctx.state.key_label_enter.clear();
|
||||
ctx.state.key_label_enter.push_str("Save");
|
||||
ctx.state.key_label_right.clear();
|
||||
ctx.state.key_label_right.push_str("Delete");
|
||||
ctx.key_labels_change = true;
|
||||
}
|
||||
|
||||
fn update(ctx: &mut Context, mode_state: &mut DialState) -> Option<ModeState> {
|
||||
// TODO move to init
|
||||
let dial_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_10X20)
|
||||
.text_color(WHITE)
|
||||
.background_color(BLACK)
|
||||
.build();
|
||||
let textbox_style = TextBoxStyleBuilder::new()
|
||||
.height_mode(HeightMode::FitToText)
|
||||
.alignment(HorizontalAlignment::Left)
|
||||
.paragraph_spacing(6)
|
||||
.build();
|
||||
|
||||
for key_event in &ctx.key_events {
|
||||
if key_event.event_type != KeyEventType::Pressed {
|
||||
continue;
|
||||
}
|
||||
match key_event.key {
|
||||
Key::HangUp => {
|
||||
return Some(ModeState::Clock(Default::default()));
|
||||
}
|
||||
Key::PickUp => {
|
||||
// TODO
|
||||
}
|
||||
Key::OptionRight => {
|
||||
if mode_state.line.pop().is_some() {
|
||||
// TODO redraw background over the erased character
|
||||
mode_state.line_changed = true;
|
||||
} else {
|
||||
return Some(ModeState::Clock(Default::default()));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(ch) = key_event.get_char(KeyInputMode::Digit) {
|
||||
if mode_state.line.try_push(ch).is_err() {
|
||||
// TODO
|
||||
} else {
|
||||
mode_state.line_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mode_state.line_changed {
|
||||
let bounds = Rectangle::new(Point::new(0, 16), Size::new(200, 0));
|
||||
let text_box = TextBox::with_textbox_style(
|
||||
&mode_state.line,
|
||||
bounds,
|
||||
dial_text_style,
|
||||
textbox_style,
|
||||
);
|
||||
text_box.draw(ctx.display.inner_mut()).unwrap();
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn on_leave(ctx: &mut Context, mode_state: &mut DialState) {}
|
||||
}
|
||||
1
samd/src/bak/config.rs
Normal file
1
samd/src/bak/config.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub struct Config {}
|
||||
9
samd/src/bak/display.rs
Normal file
9
samd/src/bak/display.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "simulator")] {
|
||||
mod simulator;
|
||||
pub use simulator::*;
|
||||
} else {
|
||||
mod epd;
|
||||
pub use epd::*;
|
||||
}
|
||||
}
|
||||
32
samd/src/bak/display/epd.rs
Normal file
32
samd/src/bak/display/epd.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use embedded_graphics::{prelude::*};
|
||||
use epd_waveshare::epd1in54::{Display1in54, Epd1in54};
|
||||
|
||||
pub type Color = epd_waveshare::color::Color;
|
||||
pub const BLACK: Color = epd_waveshare::color::Color::Black;
|
||||
pub const WHITE: Color = epd_waveshare::color::Color::White;
|
||||
|
||||
pub struct Display {
|
||||
//epd: Epd1in54,
|
||||
display: Display1in54,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
//epd: Epd1in54::new(&mut spi, cs, busy, dc, rst, &mut delay),
|
||||
display: Display1in54::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self) {
|
||||
//self.epd.update_and_display_frame( & mut spi, & self.display.buffer());
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &Display1in54 {
|
||||
&self.display
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> &mut Display1in54 {
|
||||
&mut self.display
|
||||
}
|
||||
}
|
||||
51
samd/src/bak/display/simulator.rs
Normal file
51
samd/src/bak/display/simulator.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
|
||||
use embedded_graphics_simulator::{
|
||||
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
|
||||
};
|
||||
|
||||
pub type Color = BinaryColor;
|
||||
pub const BLACK: Color = BinaryColor::Off;
|
||||
pub const WHITE: Color = BinaryColor::On;
|
||||
|
||||
static mut WINDOW: core::mem::MaybeUninit<Window> = core::mem::MaybeUninit::uninit();
|
||||
|
||||
pub fn window() -> &'static Window {
|
||||
unsafe { WINDOW.assume_init_ref() }
|
||||
}
|
||||
|
||||
pub fn window_mut() -> &'static mut Window {
|
||||
unsafe { WINDOW.assume_init_mut() }
|
||||
}
|
||||
|
||||
pub struct Display {
|
||||
display: SimulatorDisplay<BinaryColor>,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new() -> Self {
|
||||
let output_settings = OutputSettingsBuilder::new()
|
||||
.theme(BinaryColorTheme::Default)
|
||||
.build();
|
||||
|
||||
unsafe { WINDOW.write(Window::new("Rustphone", &output_settings)) };
|
||||
|
||||
Self {
|
||||
display: SimulatorDisplay::new(Size::new(200, 200)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
window_mut().update(&self.display);
|
||||
if window_mut().events().any(|e| e == SimulatorEvent::Quit) {
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &SimulatorDisplay<BinaryColor> {
|
||||
&self.display
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> &mut SimulatorDisplay<BinaryColor> {
|
||||
&mut self.display
|
||||
}
|
||||
}
|
||||
13
samd/src/bak/energy.rs
Normal file
13
samd/src/bak/energy.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#[derive(Eq, PartialEq)]
|
||||
pub struct EnergyStatus {
|
||||
/// Battery percentage
|
||||
pub battery: u8,
|
||||
pub charging: bool,
|
||||
}
|
||||
|
||||
pub fn get_energy_status() -> EnergyStatus {
|
||||
EnergyStatus {
|
||||
battery: 100,
|
||||
charging: true,
|
||||
}
|
||||
}
|
||||
29
samd/src/bak/fs.rs
Normal file
29
samd/src/bak/fs.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use atsamd_hal::{delay::Delay, pac::Peripherals, prelude::*, sercom::spi::EightBit};
|
||||
use embedded_sdmmc::{Controller, SdMmcSpi, VolumeIdx};
|
||||
|
||||
pub struct Fs {
|
||||
controller: Controller<SdMmcSpi<maduino_zero_4g::SdSpi, maduino_zero_4g::SdCs>, ClockMock>,
|
||||
}
|
||||
|
||||
impl Fs {
|
||||
pub fn new(spi: maduino_zero_4g::SdSpi, cs: maduino_zero_4g::SdCs) -> Self {
|
||||
let controller = Controller::new(SdMmcSpi::new(spi, cs), ClockMock);
|
||||
Self { controller }
|
||||
}
|
||||
}
|
||||
|
||||
struct ClockMock;
|
||||
|
||||
// TODO
|
||||
impl embedded_sdmmc::TimeSource for ClockMock {
|
||||
fn get_timestamp(&self) -> embedded_sdmmc::Timestamp {
|
||||
embedded_sdmmc::Timestamp {
|
||||
year_since_1970: 0,
|
||||
zero_indexed_month: 0,
|
||||
zero_indexed_day: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
1
samd/src/bak/gui.rs
Normal file
1
samd/src/bak/gui.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub trait Widget {}
|
||||
188
samd/src/bak/keypad.rs
Normal file
188
samd/src/bak/keypad.rs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
use arrayvec::ArrayVec;
|
||||
|
||||
const NB_KEYS: usize = 21;
|
||||
/// Key repeat max delay (ms)
|
||||
const REPEAT_DELAY: u64 = 500;
|
||||
|
||||
pub type KeyEvents = ArrayVec<KeyEvent, 4>;
|
||||
|
||||
pub struct Keypad {
|
||||
last_key: Option<(Key, u64, u8)>,
|
||||
pressed: [bool; NB_KEYS],
|
||||
}
|
||||
|
||||
impl Default for Keypad {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
last_key: None,
|
||||
pressed: [false; NB_KEYS],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Keypad {
|
||||
pub fn update(&mut self) -> KeyEvents {
|
||||
self.get_keys()
|
||||
.into_iter()
|
||||
.zip(self.pressed.iter_mut())
|
||||
.zip(0u8..)
|
||||
.filter_map(|((new_pressed, old_pressed), key)| {
|
||||
let mut repeats = 0;
|
||||
let event_type = match (*old_pressed, new_pressed) {
|
||||
(true, true) => KeyEventType::Down,
|
||||
(true, false) => {
|
||||
*old_pressed = new_pressed;
|
||||
KeyEventType::Released
|
||||
}
|
||||
(false, true) => {
|
||||
*old_pressed = new_pressed;
|
||||
'count_repeats: {
|
||||
if let Some((last_key, last_when, last_repeats)) = &mut self.last_key {
|
||||
if *last_key as u8 == key {
|
||||
let now = crate::time::millis();
|
||||
if now.wrapping_sub(*last_when) < REPEAT_DELAY {
|
||||
*last_repeats = last_repeats.saturating_add(1);
|
||||
} else {
|
||||
*last_repeats = 1;
|
||||
}
|
||||
repeats = *last_repeats;
|
||||
*last_when = now;
|
||||
break 'count_repeats;
|
||||
}
|
||||
}
|
||||
self.last_key =
|
||||
Some((Key::from_u8_unchecked(key), crate::time::millis(), 1));
|
||||
}
|
||||
KeyEventType::Pressed
|
||||
}
|
||||
(false, false) => return None,
|
||||
};
|
||||
|
||||
Some(KeyEvent {
|
||||
key: Key::from_u8_unchecked(key),
|
||||
event_type,
|
||||
repeats,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
fn get_keys(&self) -> [bool; NB_KEYS] {
|
||||
use embedded_graphics_simulator::{sdl2::Keycode, SimulatorEvent};
|
||||
|
||||
let mut keys = [false; NB_KEYS];
|
||||
crate::display::window_mut()
|
||||
.events()
|
||||
.filter_map(|event| match event {
|
||||
SimulatorEvent::KeyDown { keycode, .. } => match keycode {
|
||||
Keycode::Num0 | Keycode::Kp0 => Some(Key::D0),
|
||||
Keycode::Num1 | Keycode::Kp1 => Some(Key::D1),
|
||||
Keycode::Num2 | Keycode::Kp2 => Some(Key::D2),
|
||||
Keycode::Num3 | Keycode::Kp3 => Some(Key::D3),
|
||||
Keycode::Num4 | Keycode::Kp4 => Some(Key::D4),
|
||||
Keycode::Num5 | Keycode::Kp5 => Some(Key::D5),
|
||||
Keycode::Num6 | Keycode::Kp6 => Some(Key::D6),
|
||||
Keycode::Num7 | Keycode::Kp7 => Some(Key::D7),
|
||||
Keycode::Num8 | Keycode::Kp8 => Some(Key::D8),
|
||||
Keycode::Num9 | Keycode::Kp9 => Some(Key::D9),
|
||||
Keycode::KpEnter | Keycode::Return => Some(Key::Enter),
|
||||
Keycode::Asterisk | Keycode::KpMultiply => Some(Key::Asterisk),
|
||||
Keycode::Hash | Keycode::KpHash => Some(Key::Hash),
|
||||
// TODO more
|
||||
_ => None,
|
||||
},
|
||||
SimulatorEvent::Quit => std::process::exit(0),
|
||||
_ => None,
|
||||
})
|
||||
.for_each(|key| keys[key as usize] = true);
|
||||
keys
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
fn get_keys(&self) -> [bool; NB_KEYS] {
|
||||
[false; NB_KEYS]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum Key {
|
||||
D0 = 0,
|
||||
D1 = 1,
|
||||
D2 = 2,
|
||||
D3 = 3,
|
||||
D4 = 4,
|
||||
D5 = 5,
|
||||
D6 = 6,
|
||||
D7 = 7,
|
||||
D8 = 8,
|
||||
D9 = 9,
|
||||
Enter = 10,
|
||||
OptionRight = 11,
|
||||
OptionLeft = 12,
|
||||
Left = 13,
|
||||
Right = 14,
|
||||
Top = 15,
|
||||
Down = 16,
|
||||
Asterisk = 17,
|
||||
Hash = 18,
|
||||
PickUp = 19,
|
||||
HangUp = 20,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
fn from_u8_unchecked(key: u8) -> Self {
|
||||
unsafe { core::mem::transmute(key) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KeyEvent {
|
||||
pub event_type: KeyEventType,
|
||||
pub key: Key,
|
||||
pub repeats: u8,
|
||||
}
|
||||
|
||||
impl KeyEvent {
|
||||
pub fn get_char(&self, key_input_mode: KeyInputMode) -> Option<char> {
|
||||
use Key::*;
|
||||
match key_input_mode {
|
||||
KeyInputMode::Digit => match (self.key, self.repeats) {
|
||||
(D0, _) => Some('0'),
|
||||
(D1, _) => Some('1'),
|
||||
(D2, _) => Some('2'),
|
||||
(D3, _) => Some('3'),
|
||||
(D4, _) => Some('4'),
|
||||
(D5, _) => Some('5'),
|
||||
(D6, _) => Some('6'),
|
||||
(D7, _) => Some('7'),
|
||||
(D8, _) => Some('8'),
|
||||
(D9, _) => Some('9'),
|
||||
(Asterisk, 1) => Some('*'),
|
||||
(Asterisk, 2) => Some('+'),
|
||||
(Asterisk, 3) => Some('p'),
|
||||
(Asterisk, 4) => Some('W'),
|
||||
(Hash, _) => Some('#'),
|
||||
_ => None,
|
||||
},
|
||||
_ => {
|
||||
None /* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//ncb1 upz2 tdk3
|
||||
//eow4 lqh5 age6
|
||||
//sfx7 rmj8 ivy9
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum KeyEventType {
|
||||
Pressed,
|
||||
Down,
|
||||
Released,
|
||||
}
|
||||
|
||||
pub enum KeyInputMode {
|
||||
Digit,
|
||||
Alpha,
|
||||
}
|
||||
351
samd/src/bak/main.bak.rs
Normal file
351
samd/src/bak/main.bak.rs
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
#![cfg_attr(not(feature = "simulator"), no_std)]
|
||||
#![cfg_attr(not(feature = "simulator"), no_main)]
|
||||
|
||||
mod apps;
|
||||
mod config;
|
||||
mod display;
|
||||
mod energy;
|
||||
mod fs;
|
||||
mod gui;
|
||||
mod keypad;
|
||||
mod state;
|
||||
mod strf;
|
||||
mod text_input;
|
||||
mod time;
|
||||
|
||||
use apps::App;
|
||||
use display::*;
|
||||
use energy::EnergyStatus;
|
||||
use keypad::KeyEvents;
|
||||
use state::*;
|
||||
|
||||
use arrayvec::ArrayString;
|
||||
use core::fmt::Write;
|
||||
use core::sync::atomic;
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embedded_graphics::{
|
||||
mono_font::{
|
||||
ascii::{FONT_10X20, FONT_6X10, FONT_9X15},
|
||||
MonoTextStyleBuilder,
|
||||
},
|
||||
pixelcolor::BinaryColor,
|
||||
prelude::*,
|
||||
primitives::{Line, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment},
|
||||
text::{Alignment, Text},
|
||||
};
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
use maduino_zero_4g::{
|
||||
self as bsp,
|
||||
hal::{rtc::Rtc,
|
||||
clock::{enable_external_32kosc, enable_internal_32kosc, ClockGenId, ClockSource, GenericClockController},
|
||||
delay::Delay,
|
||||
pac::{CorePeripherals, Peripherals, interrupt, RTC},
|
||||
prelude::*,sleeping_delay::SleepingDelay
|
||||
},
|
||||
};
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
use panic_halt as _;
|
||||
use tz::DateTime;
|
||||
|
||||
// Check that stack overflow is unlikely
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
static_assertions::const_assert!(
|
||||
core::mem::size_of::<(
|
||||
State,
|
||||
ModeState,
|
||||
Peripherals,
|
||||
maduino_zero_4g::Pins,
|
||||
CorePeripherals,
|
||||
keypad::Keypad,
|
||||
Display,
|
||||
Context,
|
||||
fs::Fs,
|
||||
)>() < 16 * 1024
|
||||
);
|
||||
|
||||
static INTERRUPT_FIRED: atomic::AtomicBool = atomic::AtomicBool::new(false);
|
||||
|
||||
#[cfg_attr(not(feature = "simulator"), bsp::entry)]
|
||||
fn main() -> ! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "simulator"))] {
|
||||
let mut peripherals = Peripherals::take().unwrap();
|
||||
let mut pins = maduino_zero_4g::Pins::new(peripherals.PORT);
|
||||
let mut core = CorePeripherals::take().unwrap();
|
||||
let mut clocks = GenericClockController::with_external_32kosc(
|
||||
peripherals.GCLK,
|
||||
&mut peripherals.PM,
|
||||
&mut peripherals.SYSCTRL,
|
||||
&mut peripherals.NVMCTRL,
|
||||
);
|
||||
|
||||
enable_external_32kosc(&mut peripherals.SYSCTRL);
|
||||
let timer_clock = clocks
|
||||
.configure_gclk_divider_and_source(ClockGenId::GCLK2, 1, ClockSource::XOSC32K, false)
|
||||
.unwrap();
|
||||
|
||||
/*let mut clocks = GenericClockController::with_internal_8mhz(
|
||||
peripherals.GCLK,
|
||||
&mut peripherals.PM,
|
||||
&mut peripherals.SYSCTRL,
|
||||
&mut peripherals.NVMCTRL,
|
||||
);
|
||||
|
||||
// Get a clock & make a sleeping delay object. use internal 32k clock that runs
|
||||
// in standby
|
||||
enable_internal_32kosc(&mut peripherals.SYSCTRL);
|
||||
let timer_clock = clocks
|
||||
.configure_gclk_divider_and_source(ClockGenId::GCLK1, 1, ClockSource::OSC32K, false)
|
||||
.unwrap();*/
|
||||
|
||||
clocks.configure_standby(ClockGenId::GCLK2, true);
|
||||
let rtc_clock = clocks.rtc(&timer_clock).unwrap();
|
||||
let timer = Rtc::count32_mode(peripherals.RTC, rtc_clock.freq(), &mut peripherals.PM);
|
||||
let mut sleeping_delay = SleepingDelay::new(timer, &INTERRUPT_FIRED);
|
||||
|
||||
//let mut delay = Delay::new(core.SYST, &mut clocks);
|
||||
|
||||
/* let mut fs = fs::Fs::new(atsamd_hal::sercom::spi::Config::new(
|
||||
&peripherals.PM,
|
||||
peripherals.SERCOM4,
|
||||
atsamd_hal::sercom::spi::Pads::default().data_in(pins.sd_miso).data_out(pins.sd_mosi).sclk(pins.sd_sck),
|
||||
10_u32.MHz(),
|
||||
).enable(), pins.d4.into_push_pull_output());
|
||||
*/
|
||||
|
||||
// We can use the RTC in standby for maximum power savings
|
||||
core.SCB.set_sleepdeep();
|
||||
|
||||
// enable interrupts
|
||||
unsafe {
|
||||
core.NVIC.set_priority(interrupt::RTC, 2);
|
||||
NVIC::unmask(interrupt::RTC);
|
||||
}
|
||||
|
||||
// Turn off unnecessary peripherals
|
||||
peripherals.PM.ahbmask.modify(|_, w| {
|
||||
w.usb_().clear_bit();
|
||||
w.dmac_().clear_bit()
|
||||
});
|
||||
peripherals.PM.apbamask.modify(|_, w| {
|
||||
w.eic_().clear_bit();
|
||||
w.wdt_().clear_bit();
|
||||
w.sysctrl_().clear_bit();
|
||||
w.pac0_().clear_bit()
|
||||
});
|
||||
peripherals.PM.apbbmask.modify(|_, w| {
|
||||
w.usb_().clear_bit();
|
||||
w.dmac_().clear_bit();
|
||||
w.nvmctrl_().clear_bit();
|
||||
w.dsu_().clear_bit();
|
||||
w.pac1_().clear_bit()
|
||||
});
|
||||
// Thankfully the only one default on here is ADC
|
||||
peripherals.PM.apbcmask.modify(|_, w| w.adc_().clear_bit());
|
||||
|
||||
let mut led = pins.d9.into_push_pull_output();
|
||||
|
||||
loop {
|
||||
sleeping_delay.delay_ms(1000u16);
|
||||
led.set_high().unwrap();
|
||||
sleeping_delay.delay_ms(1000u16);
|
||||
led.set_low().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = State {
|
||||
energy: EnergyStatus {
|
||||
battery: 255,
|
||||
charging: false,
|
||||
},
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
key_label_left: ArrayString::new_const(),
|
||||
key_label_enter: ArrayString::new_const(),
|
||||
key_label_right: ArrayString::new_const(),
|
||||
};
|
||||
let mut mode_state = ModeState::default();
|
||||
|
||||
let mut display = Display::new();
|
||||
let mut keypad = keypad::Keypad::default();
|
||||
|
||||
let thin_stroke = PrimitiveStyle::with_stroke(WHITE, 1);
|
||||
let thick_stroke = PrimitiveStyle::with_stroke(WHITE, 3);
|
||||
let fill = PrimitiveStyle::with_fill(WHITE);
|
||||
let statusbar_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_9X15)
|
||||
.text_color(WHITE)
|
||||
.background_color(BLACK)
|
||||
.build();
|
||||
let key_label_text_style = MonoTextStyleBuilder::new()
|
||||
.font(&FONT_6X10)
|
||||
.text_color(WHITE)
|
||||
.build();
|
||||
|
||||
Line::new(Point::new(0, 13), Point::new(199, 13))
|
||||
.into_styled(thin_stroke)
|
||||
.draw(display.inner_mut())
|
||||
.unwrap();
|
||||
Line::new(Point::new(0, 189), Point::new(199, 189))
|
||||
.into_styled(thin_stroke)
|
||||
.draw(display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
display.update();
|
||||
|
||||
let mut ctx = Context {
|
||||
display: &mut display,
|
||||
hm_change: true,
|
||||
key_labels_change: false,
|
||||
key_events: Default::default(),
|
||||
now: DateTime::from_timespec(0, 0, tz::TimeZoneRef::utc()).unwrap(),
|
||||
update: true,
|
||||
state: &mut state,
|
||||
};
|
||||
loop {
|
||||
let energy_status = energy::get_energy_status();
|
||||
|
||||
if energy_status != ctx.state.energy {
|
||||
ctx.update = true;
|
||||
|
||||
/*Text::with_alignment(
|
||||
unsafe { core::str::from_utf8_unchecked(&strf::fmt_energy(&energy_status)) },
|
||||
Point::new(0, 9),
|
||||
statusbar_text_style,
|
||||
Alignment::Left,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();*/
|
||||
|
||||
ctx.state.energy = energy_status;
|
||||
}
|
||||
|
||||
//ctx.now = time::now();
|
||||
//ctx.now = tz::DateTime::from_timespec(rtc.count32() as i64, 0, tz::TimeZoneRef::utc()).unwrap();
|
||||
|
||||
if ctx.now.second() % 2 == 0 {
|
||||
led.set_high().unwrap();
|
||||
} else {
|
||||
led.set_low().unwrap();
|
||||
}
|
||||
|
||||
let hour = ctx.now.hour();
|
||||
let minute = ctx.now.minute();
|
||||
if (hour, minute) != (ctx.state.hour, ctx.state.minute) {
|
||||
ctx.update = true;
|
||||
ctx.hm_change = true;
|
||||
ctx.state.hour = hour;
|
||||
ctx.state.minute = minute;
|
||||
|
||||
/*Text::with_alignment(
|
||||
unsafe { core::str::from_utf8_unchecked(&strf::fmt_time_hm(hour, minute)) },
|
||||
Point::new(199, 9),
|
||||
statusbar_text_style,
|
||||
Alignment::Right,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();*/
|
||||
}
|
||||
|
||||
ctx.key_events = keypad.update();
|
||||
|
||||
/*if let Some(new_mode_state) = match &mut mode_state {
|
||||
ModeState::Nothing => Some(ModeState::Clock(Default::default())),
|
||||
ModeState::Clock(clock_state) => apps::clock::Clock::update(&mut ctx, clock_state),
|
||||
ModeState::Dial(dial_state) => apps::dial::Dial::update(&mut ctx, dial_state),
|
||||
} {
|
||||
match &mut mode_state {
|
||||
ModeState::Nothing => {}
|
||||
ModeState::Clock(clock_state) => {
|
||||
apps::clock::Clock::on_leave(&mut ctx, clock_state)
|
||||
}
|
||||
ModeState::Dial(dial_state) => apps::dial::Dial::on_leave(&mut ctx, dial_state),
|
||||
}
|
||||
mode_state = new_mode_state;
|
||||
match &mut mode_state {
|
||||
ModeState::Nothing => {}
|
||||
ModeState::Clock(clock_state) => {
|
||||
apps::clock::Clock::on_enter(&mut ctx, clock_state)
|
||||
}
|
||||
ModeState::Dial(dial_state) => apps::dial::Dial::on_enter(&mut ctx, dial_state),
|
||||
}
|
||||
}*/
|
||||
|
||||
/*if ctx.key_labels_change {
|
||||
let bg_style = PrimitiveStyleBuilder::new()
|
||||
.fill_color(BLACK)
|
||||
.build();
|
||||
Rectangle::new(Point::new(0, 190), Size::new(200, 12))
|
||||
.into_styled(bg_style)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
|
||||
Text::with_alignment(
|
||||
&ctx.state.key_label_left,
|
||||
Point::new(0, 197),
|
||||
key_label_text_style,
|
||||
Alignment::Left,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
Text::with_alignment(
|
||||
&ctx.state.key_label_right,
|
||||
Point::new(200, 197),
|
||||
key_label_text_style,
|
||||
Alignment::Right,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
Text::with_alignment(
|
||||
&ctx.state.key_label_enter,
|
||||
Point::new(100, 197),
|
||||
key_label_text_style,
|
||||
Alignment::Center,
|
||||
)
|
||||
.draw(ctx.display.inner_mut())
|
||||
.unwrap();
|
||||
ctx.key_labels_change = false;
|
||||
}*/
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
{
|
||||
ctx.display.update();
|
||||
std::thread::sleep(core::time::Duration::from_millis(50));
|
||||
}
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
if ctx.update {
|
||||
ctx.display.update();
|
||||
}
|
||||
//#[cfg(not(feature = "simulator"))]
|
||||
//delay.delay_ms(50_u8);
|
||||
|
||||
ctx.update = false;
|
||||
ctx.hm_change = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context<'a> {
|
||||
pub state: &'a mut State,
|
||||
pub display: &'a mut Display,
|
||||
pub hm_change: bool,
|
||||
pub key_labels_change: bool,
|
||||
pub now: DateTime,
|
||||
pub update: bool,
|
||||
pub key_events: KeyEvents,
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn RTC() {
|
||||
// Let the sleepingtimer know that the interrupt fired, and clear it
|
||||
INTERRUPT_FIRED.store(true, atomic::Ordering::Relaxed);
|
||||
unsafe {
|
||||
RTC::ptr()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.mode0()
|
||||
.intflag
|
||||
.modify(|_, w| w.cmp0().set_bit());
|
||||
}
|
||||
}
|
||||
30
samd/src/bak/state.rs
Normal file
30
samd/src/bak/state.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use arrayvec::ArrayString;
|
||||
|
||||
use crate::{apps, energy::EnergyStatus};
|
||||
|
||||
/*pub struct State {
|
||||
pub global: GlobalState,
|
||||
pub mode: ModeState,
|
||||
}*/
|
||||
|
||||
pub struct State {
|
||||
pub energy: EnergyStatus,
|
||||
pub hour: u8,
|
||||
pub minute: u8,
|
||||
pub key_label_left: ArrayString<8>,
|
||||
pub key_label_enter: ArrayString<8>,
|
||||
pub key_label_right: ArrayString<8>,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum ModeState {
|
||||
Nothing,
|
||||
Clock(apps::clock::ClockState),
|
||||
Dial(apps::dial::DialState),
|
||||
}
|
||||
|
||||
impl Default for ModeState {
|
||||
fn default() -> Self {
|
||||
Self::Nothing
|
||||
}
|
||||
}
|
||||
55
samd/src/bak/strf.rs
Normal file
55
samd/src/bak/strf.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use crate::energy::EnergyStatus;
|
||||
|
||||
static WEEK_DAYS: [[u8; 3]; 7] = [
|
||||
*b"Sun", *b"Mon", *b"Tue", *b"Wed", *b"Thu", *b"Fri", *b"Sat",
|
||||
];
|
||||
|
||||
/// hh:mm
|
||||
pub fn fmt_time_hm(hour: u8, minute: u8) -> [u8; 5] {
|
||||
let mut buf = *b"00:00";
|
||||
buf[0] += hour / 10;
|
||||
buf[1] += hour % 10;
|
||||
buf[3] += minute / 10;
|
||||
buf[4] += minute % 10;
|
||||
buf
|
||||
}
|
||||
|
||||
/// yyyy-mm-dd Www
|
||||
pub fn fmt_time_ymdw(year: i32, month: u8, day: u8, week_day: u8) -> [u8; 14] {
|
||||
let mut buf = *b"0000-00-00 \x00\x00\x00";
|
||||
|
||||
let mut year = year as u16 % 10_000;
|
||||
buf[3] += (year % 10) as u8;
|
||||
year /= 10;
|
||||
buf[2] += (year % 10) as u8;
|
||||
year /= 10;
|
||||
buf[1] += (year % 10) as u8;
|
||||
year /= 10;
|
||||
buf[0] += year as u8;
|
||||
|
||||
buf[5] += month / 10;
|
||||
buf[6] += month % 10;
|
||||
|
||||
buf[8] += day / 10;
|
||||
buf[9] += day % 10;
|
||||
|
||||
buf[11..14].copy_from_slice(&WEEK_DAYS[week_day as usize]);
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
pub fn fmt_energy(energy_status: &EnergyStatus) -> [u8; 4] {
|
||||
let mut buf = *b" 0 ";
|
||||
|
||||
buf[3] |= energy_status.charging as u8 * b'+';
|
||||
|
||||
let mut battery = energy_status.battery;
|
||||
buf[2] += energy_status.battery % 10;
|
||||
battery /= 10;
|
||||
buf[1] |= (battery > 9) as u8 * (b'0' + battery % 10);
|
||||
battery /= 10;
|
||||
let d = battery % 10;
|
||||
buf[0] |= d * (b'0' + d);
|
||||
|
||||
buf
|
||||
}
|
||||
6
samd/src/bak/text_input.rs
Normal file
6
samd/src/bak/text_input.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use arrayvec::ArrayString;
|
||||
|
||||
pub struct TextInput<const N: usize> {
|
||||
cursor: usize,
|
||||
value: ArrayString<N>,
|
||||
}
|
||||
31
samd/src/bak/time.rs
Normal file
31
samd/src/bak/time.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
pub fn now() -> tz::DateTime {
|
||||
tz::DateTime::from_timespec(timestamp() as i64, 0, tz::TimeZoneRef::utc()).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
pub fn timestamp() -> u64 {
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
// TODO
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
pub fn timestamp() -> u64 {
|
||||
1692450980
|
||||
}
|
||||
|
||||
#[cfg(feature = "simulator")]
|
||||
pub fn millis() -> u64 {
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as u64
|
||||
}
|
||||
|
||||
// TODO
|
||||
#[cfg(not(feature = "simulator"))]
|
||||
pub fn millis() -> u64 {
|
||||
1692450980000
|
||||
}
|
||||
113
samd/src/main.rs
Normal file
113
samd/src/main.rs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
mod usb;
|
||||
|
||||
use core::{convert::Infallible, mem::MaybeUninit, pin::pin, time::Duration};
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use lilos::time::sleep_for;
|
||||
use maduino_zero_4g::{
|
||||
self as bsp,
|
||||
hal::{
|
||||
clock::GenericClockController,
|
||||
ehal::digital::OutputPin,
|
||||
pac::{interrupt, CorePeripherals, Peripherals},
|
||||
prelude::*,
|
||||
usb::UsbBus,dmac::{DmaController, PriorityLevel}
|
||||
},
|
||||
};
|
||||
use usb_device::{bus::UsbBusAllocator, prelude::*};
|
||||
use usbd_serial::{SerialPort, USB_CLASS_CDC};
|
||||
use panic_halt as _;
|
||||
|
||||
#[bsp::entry]
|
||||
fn main() -> ! {
|
||||
let mut peripherals = Peripherals::take().unwrap();
|
||||
let mut pins = maduino_zero_4g::Pins::new(peripherals.PORT);
|
||||
let mut core = CorePeripherals::take().unwrap();
|
||||
let mut clocks = GenericClockController::with_external_32kosc(
|
||||
peripherals.GCLK,
|
||||
&mut peripherals.PM,
|
||||
&mut peripherals.SYSCTRL,
|
||||
&mut peripherals.NVMCTRL,
|
||||
);
|
||||
let mut dmac = DmaController::init(peripherals.DMAC, &mut peripherals.PM);
|
||||
|
||||
let mut led1 = pins.d9.into_push_pull_output();
|
||||
let mut led2 = pins.d8.into_push_pull_output();
|
||||
|
||||
let mut modem_uart = bsp::setup_modem(
|
||||
&mut clocks,
|
||||
(115200).Hz(),
|
||||
peripherals.SERCOM0,
|
||||
&mut peripherals.PM,
|
||||
pins.d0,
|
||||
pins.d1,
|
||||
);
|
||||
|
||||
let bus_allocator = unsafe {
|
||||
usb::USB_ALLOCATOR = Some(bsp::usb_allocator(
|
||||
peripherals.USB,
|
||||
&mut clocks,
|
||||
&mut peripherals.PM,
|
||||
pins.usb_dm,
|
||||
pins.usb_dp,
|
||||
));
|
||||
usb::USB_ALLOCATOR.as_ref().unwrap()
|
||||
};
|
||||
unsafe {
|
||||
usb::USB_SERIAL = Some(SerialPort::new(bus_allocator));
|
||||
usb::USB_BUS = Some(
|
||||
UsbDeviceBuilder::new(bus_allocator, UsbVidPid(0x2222, 0x3333))
|
||||
.device_class(USB_CLASS_CDC)
|
||||
.build(),
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
core.NVIC.set_priority(interrupt::USB, 1);
|
||||
NVIC::unmask(interrupt::USB);
|
||||
}
|
||||
|
||||
let mut delay = atsamd_hal::delay::Delay::new(core.SYST, &mut clocks);
|
||||
delay.delay_ms(1000u16);
|
||||
let mut syst = delay.free();
|
||||
|
||||
lilos::time::initialize_sys_tick(&mut syst, 32_000_000);
|
||||
/*let (mut rx, mut tx) = modem_uart.split();
|
||||
const LENGTH: usize = 256;
|
||||
let tx_buffer: &'static mut [u8; LENGTH] =
|
||||
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
|
||||
let rx_buffer: &'static mut [u8; LENGTH] =
|
||||
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
|
||||
for (c_buf, c_str) in tx_buffer.iter_mut().zip(b"AT+CGMM\r\n") {
|
||||
*c_buf = *c_str;
|
||||
}
|
||||
let channels = dmac.split();
|
||||
let chan0 = channels.0.init(PriorityLevel::LVL0);
|
||||
let chan1 = channels.1.init(PriorityLevel::LVL0);
|
||||
let tx_dma = tx.send_with_dma(&mut tx_buffer[..9], chan0, |_| {});
|
||||
let (_chan0, _tx, _tx_buffer) = tx_dma.wait();
|
||||
let rx_dma = rx.receive_with_dma(rx_buffer, chan1, |_| {});
|
||||
let (_chan1, _rx, rx_buffer) = rx_dma.wait();
|
||||
cortex_m::interrupt::free(|_| unsafe {
|
||||
if let Some(serial) = usb::USB_SERIAL.as_mut() {
|
||||
let _ = serial.write(rx_buffer);
|
||||
}
|
||||
});*/
|
||||
|
||||
let fut1 = pin!(blinky(Duration::from_millis(1000), led1));
|
||||
let fut2 = pin!(blinky(Duration::from_millis(333), led2));
|
||||
let fut3 = pin!(usb::log_usb(Duration::from_millis(2000)));
|
||||
//let fut3 = pin!(usb::usb_echo());
|
||||
|
||||
lilos::exec::run_tasks(&mut [fut1, fut2, fut3], lilos::exec::ALL_TASKS)
|
||||
}
|
||||
|
||||
async fn blinky<P: OutputPin>(interval: Duration, mut led: P) -> Infallible {
|
||||
loop {
|
||||
led.set_high().ok();
|
||||
sleep_for(interval).await;
|
||||
led.set_low().ok();
|
||||
sleep_for(interval).await;
|
||||
}
|
||||
}
|
||||
100
samd/src/usb.rs
Normal file
100
samd/src/usb.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
use core::{convert::Infallible, mem::MaybeUninit, time::Duration};
|
||||
use usb_device::{bus::UsbBusAllocator, prelude::*};
|
||||
use usbd_serial::{embedded_io::{ReadReady, WriteReady}, SerialPort, USB_CLASS_CDC};
|
||||
use maduino_zero_4g::{
|
||||
self as bsp,
|
||||
hal::{
|
||||
clock::GenericClockController,
|
||||
ehal::digital::OutputPin,
|
||||
pac::{interrupt, CorePeripherals, Peripherals},
|
||||
prelude::*,
|
||||
usb::UsbBus,
|
||||
},pac::USB,
|
||||
};
|
||||
use cortex_m::peripheral::NVIC;
|
||||
|
||||
pub static mut USB_ALLOCATOR: Option<UsbBusAllocator<UsbBus>> = None;
|
||||
pub static mut USB_BUS: Option<UsbDevice<UsbBus>> = None;
|
||||
pub static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None;
|
||||
|
||||
pub async fn usb_echo() -> Infallible {
|
||||
let mut q_storage: [MaybeUninit<u8>; 256] = [MaybeUninit::uninit(); 256];
|
||||
let mut q = lilos::spsc::Queue::new(&mut q_storage);
|
||||
let (q_push, q_pop) = q.split();
|
||||
futures::future::join(usb_echo_rx(q_push), usb_echo_tx(q_pop)).await.0
|
||||
}
|
||||
|
||||
async fn usb_echo_rx(
|
||||
mut q: lilos::spsc::Pusher<'_, u8>,
|
||||
) -> Infallible {
|
||||
loop {
|
||||
q.reserve().await.push(usb_recv().await);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/cbiffle/lilos/blob/main/examples/stm32f4/uart-echo/src/main.rs
|
||||
async fn usb_echo_tx(
|
||||
mut q: lilos::spsc::Popper<'_, u8>,
|
||||
) -> Infallible {
|
||||
loop {
|
||||
usb_send(q.pop().await).await;
|
||||
}
|
||||
}
|
||||
|
||||
static TXE: lilos::exec::Notify = lilos::exec::Notify::new();
|
||||
|
||||
async fn usb_send(c: u8) {
|
||||
unsafe {
|
||||
if let Some(serial) = USB_SERIAL.as_mut() {
|
||||
RXE.until(|| serial.write_ready().unwrap_or(false)).await;
|
||||
//serial.write(&[c]).ok();
|
||||
lilos::time::sleep_for(Duration::from_millis(100)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static RXE: lilos::exec::Notify = lilos::exec::Notify::new();
|
||||
|
||||
async fn usb_recv() -> u8 {
|
||||
unsafe {
|
||||
if let Some(serial) = USB_SERIAL.as_mut() {
|
||||
RXE.until(|| serial.read_ready().unwrap_or(false)).await;
|
||||
let mut buf = [0];
|
||||
//serial.read(&mut buf).ok();
|
||||
lilos::time::sleep_for(Duration::from_millis(100)).await;
|
||||
return buf[0];
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub async fn log_usb(interval: Duration) -> Infallible {
|
||||
loop {
|
||||
lilos::time::sleep_for(interval).await;
|
||||
cortex_m::interrupt::free(|_| unsafe {
|
||||
if let Some(serial) = USB_SERIAL.as_mut() {
|
||||
let _ = serial.write(b"log line\r\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_usb() {
|
||||
unsafe {
|
||||
if let Some(usb_dev) = USB_BUS.as_mut() {
|
||||
if let Some(serial) = USB_SERIAL.as_mut() {
|
||||
usb_dev.poll(&mut [serial]);
|
||||
// Make the other side happy
|
||||
let mut buf = [0u8; 16];
|
||||
let _ = serial.read(&mut buf);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn USB() {
|
||||
poll_usb();
|
||||
//RXE.notify();
|
||||
//TXE.notify();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue