This commit is contained in:
Pascal Engélibert 2023-10-07 13:33:14 +02:00
commit 865599e059
64 changed files with 6448 additions and 1221 deletions

17
samd/.cargo/config.toml Normal file
View 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
View file

@ -0,0 +1 @@
target

768
samd/Cargo.lock generated Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View file

@ -0,0 +1 @@
pub struct Config {}

9
samd/src/bak/display.rs Normal file
View file

@ -0,0 +1,9 @@
cfg_if::cfg_if! {
if #[cfg(feature = "simulator")] {
mod simulator;
pub use simulator::*;
} else {
mod epd;
pub use epd::*;
}
}

View 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
}
}

View 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
View 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
View 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
View file

@ -0,0 +1 @@
pub trait Widget {}

188
samd/src/bak/keypad.rs Normal file
View 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
View 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
View 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
View 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
}

View 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
View 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
View 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
View 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();
}