Compare commits
2 Commits
1ca2aeb3f5
...
6c5abf43a7
| Author | SHA1 | Date |
|---|---|---|
|
|
6c5abf43a7 | |
|
|
4c8dbfe92f |
|
|
@ -7,6 +7,19 @@ name = "Inflector"
|
||||||
version = "0.11.4"
|
version = "0.11.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
|
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
|
|
@ -352,14 +365,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embassy-sync"
|
name = "embassy-sync"
|
||||||
version = "0.6.2"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049"
|
checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
"embedded-io-async",
|
"embedded-io-async",
|
||||||
"futures-sink",
|
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"heapless",
|
"heapless",
|
||||||
]
|
]
|
||||||
|
|
@ -605,12 +617,24 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litrs"
|
name = "litrs"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
|
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nb"
|
name = "nb"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
@ -639,13 +663,15 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nrf-softdevice"
|
name = "nrf-softdevice"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "225a21d963b2382617dbbff5953dc8c6c43fe56db5c5155f4d20a30c50c2766d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
|
"cortex-m-rt",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
"defmt 0.3.100",
|
"defmt 0.3.100",
|
||||||
"embassy-futures",
|
"embassy-futures",
|
||||||
"embassy-sync 0.6.2",
|
"embassy-sync 0.5.0",
|
||||||
"embedded-storage",
|
"embedded-storage",
|
||||||
"embedded-storage-async",
|
"embedded-storage-async",
|
||||||
"fixed",
|
"fixed",
|
||||||
|
|
@ -653,13 +679,15 @@ dependencies = [
|
||||||
"heapless",
|
"heapless",
|
||||||
"nrf-softdevice-macro",
|
"nrf-softdevice-macro",
|
||||||
"nrf-softdevice-s140",
|
"nrf-softdevice-s140",
|
||||||
|
"nrf52840-pac",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nrf-softdevice-macro"
|
name = "nrf-softdevice-macro"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3af0752f2f12e202fa29f5a8d2f6dcc8a421c7a7e368d9dab7feb6bfe24ff0e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"darling 0.13.4",
|
"darling 0.13.4",
|
||||||
|
|
@ -672,7 +700,19 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nrf-softdevice-s140"
|
name = "nrf-softdevice-s140"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "git+https://github.com/embassy-rs/nrf-softdevice#5949a5b1445cc907745c6449a35577e4544cd255"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ea93a1e11efdafcf914ed6b81b5be0cd99ee8ff6c3060102265ea863a355393"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nrf52840-pac"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m",
|
||||||
|
"cortex-m-rt",
|
||||||
|
"vcell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
|
|
@ -719,11 +759,9 @@ dependencies = [
|
||||||
"embassy-time",
|
"embassy-time",
|
||||||
"embedded-storage-async",
|
"embedded-storage-async",
|
||||||
"futures",
|
"futures",
|
||||||
"heapless",
|
|
||||||
"nrf-softdevice",
|
"nrf-softdevice",
|
||||||
"panic-halt",
|
"panic-halt",
|
||||||
"panic-probe",
|
"panic-probe",
|
||||||
"static_cell",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -760,12 +798,6 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "portable-atomic"
|
|
||||||
version = "1.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error-attr2"
|
name = "proc-macro-error-attr2"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
|
@ -818,6 +850,35 @@ version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
|
@ -854,15 +915,6 @@ version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_cell"
|
|
||||||
version = "2.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23"
|
|
||||||
dependencies = [
|
|
||||||
"portable-atomic",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,9 @@ embassy-sync = { version = "0.7.2", features = ["defmt"] }
|
||||||
embassy-time = { version = "0.5.0", features = ["tick-hz-32_768", "defmt", "defmt-timestamp-uptime"] }
|
embassy-time = { version = "0.5.0", features = ["tick-hz-32_768", "defmt", "defmt-timestamp-uptime"] }
|
||||||
panic-halt = "1.0.0"
|
panic-halt = "1.0.0"
|
||||||
panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true }
|
panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true }
|
||||||
nrf-softdevice = { git = "https://github.com/embassy-rs/nrf-softdevice", features = ["s140", "ble-peripheral", "nrf52840", "nrf-softdevice-s140", "critical-section-impl", "defmt", "critical-section", "ble-gatt-server", "ble-sec"] }
|
nrf-softdevice = { version = "0.1.0", features = ["s140", "ble-peripheral", "nrf52840", "nrf-softdevice-s140", "critical-section-impl", "defmt", "nrf52840-pac", "critical-section", "ble-gatt-server"] }
|
||||||
futures = { version = "0.3", default-features = false, features = [] }
|
futures = { version = "0.3", default-features = false, features = [] }
|
||||||
embedded-storage-async = "0.4.1"
|
embedded-storage-async = "0.4.1"
|
||||||
heapless = "0.8.0"
|
|
||||||
static_cell = "2.1.1"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "odesa"
|
name = "odesa"
|
||||||
|
|
|
||||||
203
src/main.rs
203
src/main.rs
|
|
@ -3,11 +3,9 @@
|
||||||
|
|
||||||
mod fmt;
|
mod fmt;
|
||||||
|
|
||||||
use core::cell::{Cell, RefCell};
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ops::{AddAssign, SubAssign};
|
use core::ops::{AddAssign, SubAssign};
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::sync::atomic::{AtomicU32, AtomicU8, Ordering};
|
|
||||||
use defmt::{error, Format};
|
use defmt::{error, Format};
|
||||||
#[cfg(not(feature = "defmt"))]
|
#[cfg(not(feature = "defmt"))]
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
@ -18,11 +16,10 @@ use defmt::info;
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::{join3, join4};
|
use embassy_futures::join::{join3, join4};
|
||||||
use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pull};
|
use embassy_nrf::gpio::{AnyPin, Input, OutputDrive, Pull};
|
||||||
use embassy_nrf::interrupt::{InterruptExt, Priority};
|
use embassy_nrf::interrupt::{InterruptExt, Priority};
|
||||||
use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
|
use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
|
||||||
use embassy_nrf::{bind_interrupts, interrupt, saadc, Peri};
|
use embassy_nrf::{bind_interrupts, interrupt, saadc, Peri};
|
||||||
use embassy_nrf::gpio::OutputDrive::Standard;
|
|
||||||
use embassy_nrf::peripherals::SAADC;
|
use embassy_nrf::peripherals::SAADC;
|
||||||
use embassy_nrf::saadc::{ChannelConfig, Gain, Reference, Saadc};
|
use embassy_nrf::saadc::{ChannelConfig, Gain, Reference, Saadc};
|
||||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
|
|
@ -33,11 +30,8 @@ use futures::future::{select, Either};
|
||||||
use futures::pin_mut;
|
use futures::pin_mut;
|
||||||
use nrf_softdevice::{raw, Flash, Softdevice};
|
use nrf_softdevice::{raw, Flash, Softdevice};
|
||||||
use nrf_softdevice::ble::advertisement_builder::{Flag, LegacyAdvertisementBuilder, LegacyAdvertisementPayload, ServiceList, ServiceUuid16};
|
use nrf_softdevice::ble::advertisement_builder::{Flag, LegacyAdvertisementBuilder, LegacyAdvertisementPayload, ServiceList, ServiceUuid16};
|
||||||
use nrf_softdevice::ble::{peripheral, gatt_server, Connection, MasterId, EncryptionInfo, IdentityKey, PasskeyReply};
|
use nrf_softdevice::ble::{peripheral, gatt_server, Connection};
|
||||||
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
use embedded_storage_async::nor_flash::{NorFlash, ReadNorFlash};
|
||||||
use nrf_softdevice::ble::gatt_server::set_sys_attrs;
|
|
||||||
use nrf_softdevice::ble::security::{IoCapabilities, SecurityHandler};
|
|
||||||
use static_cell::StaticCell;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Format)]
|
#[derive(Copy, Clone, Eq, PartialEq, Format)]
|
||||||
enum SysAction {
|
enum SysAction {
|
||||||
|
|
@ -133,24 +127,23 @@ static TEXT_ANIMATION_SIGNAL: Signal<ThreadModeRawMutex, AnimationSignal<TextLig
|
||||||
static HEART_ANIMATION_SIGNAL: Signal<ThreadModeRawMutex, AnimationSignal<HeartLightType>> = Signal::new();
|
static HEART_ANIMATION_SIGNAL: Signal<ThreadModeRawMutex, AnimationSignal<HeartLightType>> = Signal::new();
|
||||||
static SYS_ACTION: Mutex<ThreadModeRawMutex, SysAction> = Mutex::new(SysAction::PresentenceOn);
|
static SYS_ACTION: Mutex<ThreadModeRawMutex, SysAction> = Mutex::new(SysAction::PresentenceOn);
|
||||||
static SAVE_SIGNAL: Signal<ThreadModeRawMutex, StoreType> = Signal::new();
|
static SAVE_SIGNAL: Signal<ThreadModeRawMutex, StoreType> = Signal::new();
|
||||||
static BOND_COUNTER: AtomicU8 = AtomicU8::new(0);
|
|
||||||
|
|
||||||
#[nrf_softdevice::gatt_service(uuid = "9e7312e0-2354-11eb-9f10-fbc30a62cf38")]
|
#[nrf_softdevice::gatt_service(uuid = "9e7312e0-2354-11eb-9f10-fbc30a62cf38")]
|
||||||
struct AnimationService {
|
struct AnimationService {
|
||||||
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a63cf38", read, write, notify, indicate, security = "JustWorks")]
|
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a63cf38", read, write, notify, indicate)]
|
||||||
text_mode: u16,
|
text_mode: u16,
|
||||||
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a64cf38", read, write, notify, indicate, security = "JustWorks")]
|
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a64cf38", read, write, notify, indicate)]
|
||||||
text_color: u16,
|
text_color: u16,
|
||||||
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a65cf38", read, write, notify, indicate, security = "JustWorks")]
|
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a65cf38", read, write, notify, indicate)]
|
||||||
heart_mode: u16,
|
heart_mode: u16,
|
||||||
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a66cf38", read, write, notify, indicate, security = "JustWorks")]
|
#[characteristic(uuid = "9e7312e0-2354-11eb-9f10-fbc30a66cf38", read, write, notify, indicate)]
|
||||||
heart_color: u16,
|
heart_color: u16,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[nrf_softdevice::gatt_service(uuid = "180f")]
|
#[nrf_softdevice::gatt_service(uuid = "180f")]
|
||||||
struct BatteryService {
|
struct BatteryService {
|
||||||
#[characteristic(uuid = "2a19", read, notify, security = "JustWorks")]
|
#[characteristic(uuid = "2a19", read, notify)]
|
||||||
battery_level: u8,
|
battery_level: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,100 +157,7 @@ bind_interrupts!(struct AdcIrqs {
|
||||||
SAADC => saadc::InterruptHandler;
|
SAADC => saadc::InterruptHandler;
|
||||||
});
|
});
|
||||||
|
|
||||||
const DATA_POINT: u32 = 0x000F9800 - 4096;
|
const DATA_POINT: u32 = 0xf8000;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct Peer {
|
|
||||||
master_id: MasterId,
|
|
||||||
key: EncryptionInfo,
|
|
||||||
peer_id: IdentityKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Bonder {
|
|
||||||
peer: Cell<Option<Peer>>,
|
|
||||||
sys_attrs: RefCell<heapless::Vec<u8, 62>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Bonder {
|
|
||||||
fn default() -> Self {
|
|
||||||
Bonder {
|
|
||||||
peer: Cell::new(None),
|
|
||||||
sys_attrs: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SecurityHandler for Bonder {
|
|
||||||
fn io_capabilities(&self) -> IoCapabilities {
|
|
||||||
let val = BOND_COUNTER.load(Ordering::Relaxed);
|
|
||||||
if val > 0 {
|
|
||||||
IoCapabilities::None
|
|
||||||
} else {
|
|
||||||
IoCapabilities::DisplayYesNo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_bond(&self, _conn: &Connection) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn display_passkey(&self, passkey: &[u8; 6]) {
|
|
||||||
info!("The passkey is \"{:a}\"", passkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enter_passkey(&self, _reply: PasskeyReply) {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_bonded(&self, _conn: &Connection, master_id: MasterId, key: EncryptionInfo, peer_id: IdentityKey) {
|
|
||||||
info!("storing bond for: id: {}, key: {}", master_id, key);
|
|
||||||
|
|
||||||
// In a real application you would want to signal another task to permanently store the keys in non-volatile memory here.
|
|
||||||
self.sys_attrs.borrow_mut().clear();
|
|
||||||
self.peer.set(Some(Peer {
|
|
||||||
master_id,
|
|
||||||
key,
|
|
||||||
peer_id,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_key(&self, _conn: &Connection, master_id: MasterId) -> Option<EncryptionInfo> {
|
|
||||||
info!("getting bond for: id: {}", master_id);
|
|
||||||
|
|
||||||
self.peer
|
|
||||||
.get()
|
|
||||||
.and_then(|peer| (master_id == peer.master_id).then_some(peer.key))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_sys_attrs(&self, conn: &Connection) {
|
|
||||||
info!("saving system attributes for: {}", conn.peer_address());
|
|
||||||
|
|
||||||
if let Some(peer) = self.peer.get() {
|
|
||||||
if peer.peer_id.is_match(conn.peer_address()) {
|
|
||||||
let mut sys_attrs = self.sys_attrs.borrow_mut();
|
|
||||||
let capacity = sys_attrs.capacity();
|
|
||||||
sys_attrs.resize(capacity, 0).expect("failed to resize sys attributes");
|
|
||||||
let len = gatt_server::get_sys_attrs(conn, &mut sys_attrs).expect("failed to get sys attributes") as u16;
|
|
||||||
sys_attrs.truncate(usize::from(len));
|
|
||||||
// In a real application you would want to signal another task to permanently store sys_attrs for this connection's peer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_sys_attrs(&self, conn: &Connection) {
|
|
||||||
let addr = conn.peer_address();
|
|
||||||
info!("loading system attributes for: {}", addr);
|
|
||||||
|
|
||||||
let attrs = self.sys_attrs.borrow();
|
|
||||||
// In a real application you would search all stored peers to find a match
|
|
||||||
let attrs = if self.peer.get().map(|peer| peer.peer_id.is_match(addr)).unwrap_or(false) {
|
|
||||||
(!attrs.is_empty()).then_some(attrs.as_slice())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
set_sys_attrs(conn, attrs).expect("failed to set sys attributes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
|
|
@ -325,7 +225,7 @@ async fn main(spawner: Spawner) {
|
||||||
let pwm_heart = SimplePwm::new_3ch(p.PWM2, p.P0_17, p.P0_20, p.P0_22, &Default::default());
|
let pwm_heart = SimplePwm::new_3ch(p.PWM2, p.P0_17, p.P0_20, p.P0_22, &Default::default());
|
||||||
spawner.spawn(radar_task()).expect("failed to spawn radar task");
|
spawner.spawn(radar_task()).expect("failed to spawn radar task");
|
||||||
spawner.spawn(touch_button(p.P0_08.into())).expect("failed to spawn touch task");
|
spawner.spawn(touch_button(p.P0_08.into())).expect("failed to spawn touch task");
|
||||||
spawner.spawn(actions_task(p.P0_15.into())).expect("failed to spawn actions task");
|
spawner.spawn(actions_task()).expect("failed to spawn actions task");
|
||||||
spawner.spawn(softdevice_task(sd)).expect("failed to spawn softdevice task");
|
spawner.spawn(softdevice_task(sd)).expect("failed to spawn softdevice task");
|
||||||
spawner.spawn(storage_task(flash, initial_data.0, initial_data.1, initial_data.2, initial_data.3)).expect("failed to spawn softdevice task");
|
spawner.spawn(storage_task(flash, initial_data.0, initial_data.1, initial_data.2, initial_data.3)).expect("failed to spawn softdevice task");
|
||||||
|
|
||||||
|
|
@ -393,6 +293,9 @@ async fn storage_task(flash: Flash, initial_text_type: TextLightType, initial_te
|
||||||
let h_color: [u8; 2] = heart_color.to_le_bytes();
|
let h_color: [u8; 2] = heart_color.to_le_bytes();
|
||||||
let data = [0b01010101u8, 0b10101010u8, text_type.into(), heart_type.into(), t_color[0], t_color[1], h_color[0], h_color[1], 0xFF, 0xFF, 0xFF, 0xFF];
|
let data = [0b01010101u8, 0b10101010u8, text_type.into(), heart_type.into(), t_color[0], t_color[1], h_color[0], h_color[1], 0xFF, 0xFF, 0xFF, 0xFF];
|
||||||
info!("Saving data: {:?}", data);
|
info!("Saving data: {:?}", data);
|
||||||
|
if let Err(e) = flash.as_mut().erase(DATA_POINT, DATA_POINT + 4096).await {
|
||||||
|
error!("Error erasing flash page: {}", e);
|
||||||
|
}
|
||||||
if let Err(e) = flash.as_mut().write(DATA_POINT, &data).await {
|
if let Err(e) = flash.as_mut().write(DATA_POINT, &data).await {
|
||||||
error!("Error writing to flash: {}", e);
|
error!("Error writing to flash: {}", e);
|
||||||
}
|
}
|
||||||
|
|
@ -418,21 +321,13 @@ async fn gatt_task(server: Server, mut saadc: Saadc<'static, 1>, sd: &'static So
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
static BONDER: StaticCell<Bonder> = StaticCell::new();
|
|
||||||
let bonder = BONDER.init(Bonder::default());
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let config = peripheral::Config::default();
|
let config = peripheral::Config::default();
|
||||||
let adv = peripheral::ConnectableAdvertisement::ScannableUndirected {
|
let adv = peripheral::ConnectableAdvertisement::ScannableUndirected {
|
||||||
adv_data: &ADV_DATA,
|
adv_data: &ADV_DATA,
|
||||||
scan_data: &SCAN_DATA,
|
scan_data: &SCAN_DATA,
|
||||||
};
|
};
|
||||||
let conn = peripheral::advertise_pairable(sd, adv, &config, bonder).await.expect("failed to advertise");
|
let conn = peripheral::advertise_connectable(sd, adv, &config).await.expect("failed to advertise");
|
||||||
|
|
||||||
if let Err(e) = conn.request_security() {
|
|
||||||
info!("Failed to request security: {}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
info!("advertising done!");
|
info!("advertising done!");
|
||||||
|
|
||||||
|
|
@ -625,55 +520,38 @@ fn battery_mv_to_percent(mv: u16) -> u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn actions_task(pin: Peri<'static, AnyPin>) {
|
async fn actions_task() {
|
||||||
let mut led_pin = Output::new(pin, Level::High, Standard);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(signal) = with_timeout(Duration::from_secs(60), TOUCH_SIGNAL.wait()).await {
|
let signal = TOUCH_SIGNAL.wait().await;
|
||||||
info!("Action: {:?}", signal);
|
info!("Action: {:?}", signal);
|
||||||
match signal {
|
match signal {
|
||||||
// constant on vs presentence
|
// constant on vs presentence
|
||||||
TouchAction::Tap => {
|
TouchAction::Tap => {
|
||||||
let mut action = SYS_ACTION.lock().await;
|
let mut action = SYS_ACTION.lock().await;
|
||||||
match *action {
|
match *action {
|
||||||
SysAction::PresentenceOn |
|
SysAction::PresentenceOn |
|
||||||
SysAction::PresentenceOff => {
|
SysAction::PresentenceOff => {
|
||||||
*action = SysAction::ConstantOn;
|
*action = SysAction::ConstantOn;
|
||||||
info!("Constant light");
|
info!("Constant light");
|
||||||
}
|
|
||||||
SysAction::ConstantOn => {
|
|
||||||
*action = SysAction::PresentenceOn;
|
|
||||||
info!("Light by presentence");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
info!("Light mode {:?}", *action);
|
SysAction::ConstantOn => {
|
||||||
}
|
*action = SysAction::PresentenceOn;
|
||||||
// change text animation
|
info!("Light by presentence");
|
||||||
TouchAction::DoubleTap => {
|
|
||||||
TEXT_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation);
|
|
||||||
}
|
|
||||||
// change anchor animation
|
|
||||||
TouchAction::TripleTap => {
|
|
||||||
HEART_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation);
|
|
||||||
}
|
|
||||||
// enter pairing mode
|
|
||||||
TouchAction::Hold => {
|
|
||||||
let current = BOND_COUNTER.load(Ordering::Relaxed);
|
|
||||||
let next = if current > 0 { 0 } else { 1 };
|
|
||||||
BOND_COUNTER.store(next, Ordering::Relaxed);
|
|
||||||
info!("Set bond: {}", next);
|
|
||||||
if next > 0 {
|
|
||||||
led_pin.set_low();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info!("Light mode {:?}", *action);
|
||||||
}
|
}
|
||||||
} else {
|
// change text animation
|
||||||
let current = BOND_COUNTER.load(Ordering::Relaxed);
|
TouchAction::DoubleTap => {
|
||||||
if current > 0 {
|
TEXT_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation);
|
||||||
BOND_COUNTER.store(0, Ordering::Relaxed);
|
}
|
||||||
led_pin.set_high();
|
// change anchor animation
|
||||||
|
TouchAction::TripleTap => {
|
||||||
|
HEART_ANIMATION_SIGNAL.signal(AnimationSignal::NextAnimation);
|
||||||
|
}
|
||||||
|
// enter pairing mode
|
||||||
|
TouchAction::Hold => {
|
||||||
}
|
}
|
||||||
info!("Timeout bond");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -720,11 +598,10 @@ async fn moving_radar(pin: Peri<'static, AnyPin>) {
|
||||||
info!("Waiting for radar");
|
info!("Waiting for radar");
|
||||||
radar.wait_for_high().await;
|
radar.wait_for_high().await;
|
||||||
RADAR_SIGNAL.signal(0);
|
RADAR_SIGNAL.signal(0);
|
||||||
info!("Moving!!");
|
|
||||||
while let Err(_) = with_timeout(Duration::from_secs(1), radar.wait_for_low()).await {
|
while let Err(_) = with_timeout(Duration::from_secs(1), radar.wait_for_low()).await {
|
||||||
|
info!("Moving!!");
|
||||||
RADAR_SIGNAL.signal(0);
|
RADAR_SIGNAL.signal(0);
|
||||||
}
|
}
|
||||||
info!("Stopped");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue