start to switch to embassy

This commit is contained in:
baldeau 2025-01-12 19:39:49 +01:00
parent f95f4b3f32
commit 45affbb325
36 changed files with 539 additions and 1293 deletions

View File

@ -1,8 +1,15 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
rustflags = [
"-C",
"link-arg=-Tlink.x",
"-C",
"link-arg=-Tdefmt.x",
"-C",
"link-arg=--nmagic",
]
[build] [build]
target = "thumbv7em-none-eabihf" target = "thumbv7em-none-eabihf"
[target.'cfg(all(target_arch = "arm", target_os = "none"))'] [env]
rustflags = [ DEFMT_LOG = "debug"
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=--nmagic",
]

987
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +1,108 @@
[workspace] [workspace]
members = ["tflite_demo"] members = ["tflite_demo"]
[workspace.features] # [workspace.features]
default = ["ble-l2cap", "ble-gatt-server", "ble-gatt-client", "ble-sec"] # default = ["ble-l2cap", "ble-gatt-server", "ble-gatt-client", "ble-sec"]
ble-l2cap = ["nrf-softdevice/ble-l2cap"] # ble-l2cap = ["nrf-softdevice/ble-l2cap"]
ble-gatt-server = ["nrf-softdevice/ble-gatt-server"] # ble-gatt-server = ["nrf-softdevice/ble-gatt-server"]
ble-gatt-client = ["nrf-softdevice/ble-gatt-client"] # ble-gatt-client = ["nrf-softdevice/ble-gatt-client"]
ble-sec = ["nrf-softdevice/ble-sec"] # ble-sec = ["nrf-softdevice/ble-sec"]
nrf52840 = [ # nrf52840 = [
"embassy-nrf/nrf52840", # "embassy-nrf/nrf52840",
"nrf-softdevice/nrf52840", # "nrf-softdevice/nrf52840",
"nrf-softdevice/s140", # "nrf-softdevice/s140",
"dep:nrf-softdevice-s140", # "dep:nrf-softdevice-s140",
] # ]
[workspace.dependencies] [workspace.dependencies]
cortex-m = { version = "0.7.7", features = [ cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
"critical-section-single-core", cortex-m-rt = "0.7.5"
"inline-asm", defmt = "0.3.10"
] } defmt-rtt = "0.4.1"
cortex-m-rt = "0.7.2" defmt-serial = "0.10.0"
nrf52840-hal = "0.16.0" embassy-executor = { version = "0.7.0", features = [
usb-device = "0.2.7"
usbd-serial = "0.1.0"
microflow = { path = "../microflow-rs" }
# microflow = "0.1.3"
nalgebra = { version = "0.33.2", default-features = false, features = [
"macros",
] }
libm = "0.2"
panic-halt = "1.0.0"
panic-probe = { version = "0.3.1", features = ["print-defmt"] }
heapless = "0.8.0"
lsm6ds3tr = { path = "../lsm6ds3tr-rs" }
embassy-sync = { version = "0.5.0" }
embassy-executor = { version = "0.5.0", features = [
"arch-cortex-m", "arch-cortex-m",
"defmt",
"executor-thread", "executor-thread",
"executor-interrupt", "executor-interrupt",
"defmt",
"integrated-timers",
] } ] }
embassy-time = { version = "0.3.0", features = [ embassy-futures = { version = "0.1.1", features = ["defmt"] }
embassy-nrf = { version = "0.3.1", features = [
"defmt",
"gpiote",
"nrf52840",
"time",
"time-driver-rtc1",
"unstable-pac",
] }
embassy-sync = { version = "0.6.1", features = ["defmt"] }
embassy-time = { version = "0.4.0", features = [
"defmt", "defmt",
"defmt-timestamp-uptime", "defmt-timestamp-uptime",
] } ] }
embassy-nrf = { version = "0.1.0", features = [ embassy-embedded-hal = "0.3.0"
"defmt", embassy-usb = "0.2.0"
"nrf52840", embassy-usb-logger = "0.2.0"
"time-driver-rtc1", panic-probe = { version = "0.3.2", features = ["print-defmt"] }
"gpiote", # cortex-m = { version = "0.7.7", features = [
"time", # "critical-section-single-core",
] } # "inline-asm",
defmt = "0.3.0" # ] }
defmt-rtt = "0.4.0" # cortex-m-rt = "0.7.5"
embedded-storage = "0.3.0" # nrf52840-hal = "0.16.0"
# usb-device = "0.3.2"
# usbd-serial = "0.2.2"
# microflow = { path = "../microflow-rs" }
# # microflow = "0.1.3"
# nalgebra = { version = "0.33.2", default-features = false, features = [
# "macros",
# ] }
# libm = "0.2"
# panic-halt = "1.0.0"
# panic-probe = { version = "0.3.2", features = ["print-defmt"] }
# heapless = "0.8.0"
# lsm6ds3tr = { path = "../lsm6ds3tr-rs" }
# embassy-sync = { version = "0.5.0" }
# # embassy-embedded-hal = "0.3.0"
# embassy-executor = { version = "0.5.0", features = [
# "arch-cortex-m",
# "executor-thread",
# "executor-interrupt",
# "defmt",
# "integrated-timers",
# ] }
# embassy-time = { version = "0.3.0", features = [
# "defmt",
# "defmt-timestamp-uptime",
# ] }
# embassy-nrf = { version = "0.1.0", features = [
# "defmt",
# "nrf52840",
# "time-driver-rtc1",
# "gpiote",
# "time",
# ] }
# defmt = "0.3.10"
# defmt-rtt = "0.4.1"
# embedded-storage = "0.3.0"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
embedded-hal-async = { version = "1.0.0" } embedded-hal-async = { version = "1.0.0" }
embedded-alloc = "0.6.0" # embedded-hal-bus = { version = "0.2.0", features = ["async"] }
nrf-softdevice = { version = "0.1.0", features = [ # embedded-alloc = "0.6.0"
"defmt", # nrf-softdevice = { version = "0.1.0", features = [
"ble-peripheral", # "defmt",
"ble-central", # "ble-peripheral",
"critical-section-impl", # "ble-central",
"nrf52840", # "critical-section-impl",
"s140", # "nrf52840",
] } # "s140",
nrf-softdevice-s140 = { version = "0.1.1" } # ] }
# nrf-softdevice-s140 = { version = "0.1.1" }
fixed = "1.24.0" fixed = "1.24.0"
atomic-pool = "1.0.1" atomic-pool = "1.0.1"
static_cell = "2.0.0" static_cell = "2.0.0"
assign-resources = "0.4.1"

View File

@ -6,27 +6,42 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
cortex-m.workspace = true
cortex-m-rt.workspace = true
nrf52840-hal.workspace = true
usb-device.workspace = true
usbd-serial.workspace = true
microflow.workspace = true
libm.workspace = true
nalgebra.workspace = true
heapless.workspace = true
lsm6ds3tr.workspace = true
defmt.workspace = true
defmt-rtt.workspace = true
embedded-alloc.workspace = true
embedded-hal.workspace = true
embedded-hal-async.workspace = true
nrf-softdevice.workspace = true
nrf-softdevice-s140.workspace = true
embassy-nrf.workspace = true embassy-nrf.workspace = true
embassy-time.workspace = true # embassy-time.workspace = true
embassy-executor.workspace = true embassy-executor.workspace = true
embassy-sync.workspace = true embassy-sync.workspace = true
embassy-embedded-hal.workspace = true
embassy-futures.workspace = true
embassy-usb.workspace = true
embassy-usb-logger.workspace = true
# embedded-alloc.workspace = true
embedded-hal.workspace = true
embedded-hal-async.workspace = true
cortex-m.workspace = true
cortex-m-rt.workspace = true
defmt.workspace = true
defmt-rtt.workspace = true
# nrf52840-hal.workspace = true
# usb-device.workspace = true
# usbd-serial.workspace = true
# microflow.workspace = true
# libm.workspace = true
# nalgebra.workspace = true
# heapless.workspace = true
# lsm6ds3tr.workspace = true
# nrf-softdevice.workspace = true
# nrf-softdevice-s140.workspace = true
fixed.workspace = true fixed.workspace = true
atomic-pool.workspace = true atomic-pool.workspace = true
panic-probe.workspace = true
defmt-serial.workspace = true
static_cell.workspace = true static_cell.workspace = true
assign-resources.workspace = true
# embassy-embedded-hal.workspace = true

View File

@ -1,4 +0,0 @@
#![macro_use]
use defmt_rtt as _; // global logger
use embassy_nrf as _; // time driver

View File

@ -1,16 +0,0 @@
// Hypothetical I2C implementation (replace with your actual hardware I2C)
// struct MyI2c;
// impl I2c for MyI2c {
// // type Error = I2cError;
// fn read(&mut self, _address: u8, _buffer: &mut [u8]) -> Result<(), Self::Error> {
// // Simulate reading data
// Ok(())
// }
// fn write(&mut self, _address: u8, _bytes: &[u8]) -> Result<(), Self::Error> {
// // Simulate writing data
// Ok(())
// }
// }

View File

@ -277,264 +277,3 @@ impl<const BITS_NUM: u8, const BITS_POS: u8> From<bool> for RegisterBits<BITS_NU
Self::from(value as u8) Self::from(value as u8)
} }
} }
#[cfg(test)]
mod tests {
use super::{RegisterBits, RegisterValue};
#[test]
fn new_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
}
#[test]
fn new_1_1() {
const BITS: u8 = 1;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
}
#[test]
fn new_1_2() {
const BITS: u8 = 1;
const POS: u8 = 2;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
}
#[test]
fn new_2_0() {
const BITS: u8 = 2;
const POS: u8 = 0;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b11);
}
#[test]
fn new_2_1() {
const BITS: u8 = 2;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b11);
}
#[test]
fn new_2_2() {
const BITS: u8 = 2;
const POS: u8 = 2;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b11);
}
#[test]
fn shifted_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b1);
}
#[test]
fn shifted_1_1() {
const BITS: u8 = 1;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b10);
}
#[test]
fn shifted_1_2() {
const BITS: u8 = 1;
const POS: u8 = 2;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b100);
}
#[test]
fn shifted_2_1() {
const BITS: u8 = 2;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b110);
}
#[test]
fn shifted_2_2() {
const BITS: u8 = 2;
const POS: u8 = 2;
let rb = RegisterBits::<BITS, POS>::new(0b11111111);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b1100);
}
#[test]
fn new_from_reg_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
let rb = RegisterBits::<BITS, POS>::from_reg(0b11111111);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b1);
}
#[test]
fn new_from_reg_1_1() {
const BITS: u8 = 1;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::from_reg(0b11111111);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b10);
}
#[test]
fn new_from_reg_2_0() {
const BITS: u8 = 2;
const POS: u8 = 0;
let rb = RegisterBits::<BITS, POS>::from_reg(0b11111111);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b11);
}
#[test]
fn new_from_reg_2_1() {
const BITS: u8 = 2;
const POS: u8 = 1;
let rb = RegisterBits::<BITS, POS>::from_reg(0b11111111);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b110);
}
#[test]
fn new_from_reg_2_2() {
const BITS: u8 = 2;
const POS: u8 = 2;
let rb = RegisterBits::<BITS, POS>::from_reg(0b11111111);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b1100);
}
#[test]
fn from_reg_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
let mut rb = RegisterBits::<BITS, POS>::default();
let reg: u8 = 0b11111111;
rb.set_from_reg(reg);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b1);
}
#[test]
fn from_reg_1_1() {
const BITS: u8 = 1;
const POS: u8 = 1;
let mut rb = RegisterBits::<BITS, POS>::default();
let reg: u8 = 0b11111111;
rb.set_from_reg(reg);
assert_eq!(rb.value, 0b1);
assert_eq!(rb.shifted(), 0b10);
}
#[test]
fn from_reg_2_0() {
const BITS: u8 = 2;
const POS: u8 = 0;
let mut rb = RegisterBits::<BITS, POS>::default();
let reg: u8 = 0b11111111;
rb.set_from_reg(reg);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b11);
}
#[test]
fn from_reg_2_1() {
const BITS: u8 = 2;
const POS: u8 = 1;
let mut rb = RegisterBits::<BITS, POS>::default();
let reg: u8 = 0b11111111;
rb.set_from_reg(reg);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b110);
}
#[test]
fn from_reg_2_2() {
const BITS: u8 = 2;
const POS: u8 = 2;
let mut rb = RegisterBits::<BITS, POS>::default();
let reg: u8 = 0b11111111;
rb.set_from_reg(reg);
assert_eq!(rb.value, 0b11);
assert_eq!(rb.shifted(), 0b1100);
}
#[test]
fn bit_mask_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_mask(), 0b1);
}
#[test]
fn bit_mask_2_0() {
const BITS: u8 = 2;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_mask(), 0b11);
}
#[test]
fn bit_mask_3_0() {
const BITS: u8 = 3;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_mask(), 0b111);
}
#[test]
fn bit_shifted_mask_1_0() {
const BITS: u8 = 1;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b1);
}
#[test]
fn bit_shifted_mask_1_1() {
const BITS: u8 = 1;
const POS: u8 = 1;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b10);
}
#[test]
fn bit_shifted_mask_2_0() {
const BITS: u8 = 2;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b11);
}
#[test]
fn bit_shifted_mask_2_1() {
const BITS: u8 = 2;
const POS: u8 = 1;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b110);
}
#[test]
fn bit_shifted_mask_3_0() {
const BITS: u8 = 3;
const POS: u8 = 0;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b111);
}
#[test]
fn bit_shifted_mask_3_1() {
const BITS: u8 = 3;
const POS: u8 = 1;
assert_eq!(RegisterBits::<BITS, POS>::bit_shifted_mask(), 0b1110);
}
}

View File

@ -1,265 +1,147 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
mod common; mod lsm6ds3tr;
mod i2c;
mod lsm6ds;
use core::fmt::Write; use defmt::{info, panic};
use embedded_alloc::LlffHeap; use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
use libm::sinf; use embassy_executor::Spawner;
use lsm6ds::Lsm6ds33; use embassy_futures::join::join;
// use lsm6ds3tr::{ use embassy_nrf::peripherals::TWISPI0;
// interface::{I2cInterface, SpiInterface}, use embassy_nrf::twim::Twim;
// LsmSettings, LSM6DS3TR, use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect};
// }; use embassy_nrf::usb::{Driver, Instance};
// use lsm6ds3tr::{interface::SpiInterface, AccelScale, LsmSettings, LSM6DS3TR}; use embassy_nrf::{bind_interrupts, pac, peripherals, twim, usb};
use microflow::model; use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use nalgebra::matrix; use embassy_sync::mutex::Mutex;
use nrf52840_hal::{self as hal, twim, Spim, Twim}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
// use nrf_softdevice::{ use embassy_usb::driver::EndpointError;
// ble::{EncryptionInfo, IdentityKey, MasterId, Uuid}, use embassy_usb::{Builder, Config};
// Softdevice,
// };
use usb_device::class_prelude::UsbBusAllocator;
use nrf52840_hal::{ use lsm6ds3tr::interface::i2c::I2cInterface;
gpio::Level, // use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
prelude::{OutputPin, PinState, _embedded_hal_timer_CountDown}, use static_cell::StaticCell;
uarte::{Baudrate, Parity, Pins, Uarte},
Rtc,
};
use heapless::String; use {defmt_serial as _, panic_probe as _};
// const BATTERY_SERVICE: Uuid = Uuid::new_16(0x180f); static I2C_BUS: StaticCell<Mutex<NoopRawMutex, Twim<TWISPI0>>> = StaticCell::new();
// const BATTERY_LEVEL: Uuid = Uuid::new_16(0x2a19);
// const LED_SERVICE_UUID: Uuid = Uuid::new_16(0x112f); bind_interrupts!(struct Irqs {
// const LED_CONTROL_CHAR_UUID: Uuid = Uuid::new_16(0x321f); USBD => usb::InterruptHandler<peripherals::USBD>;
CLOCK_POWER => usb::vbus_detect::InterruptHandler;
});
const RTC_FREQ_MHZ: f32 = 0.032_768; #[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_nrf::init(Default::default());
#[global_allocator] info!("Enabling ext hfosc...");
static HEAP: LlffHeap = LlffHeap::empty(); pac::CLOCK.tasks_hfclkstart().write_value(1);
while pac::CLOCK.events_hfclkstarted().read() != 1 {}
// #[embassy_executor::task] // Create the driver, from the HAL.
// async fn softdevice_task(sd: &'static Softdevice) { let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs));
// sd.run().await;
// }
// #[derive(Debug, Clone, Copy)] // Create embassy-usb Config
// struct Peer { let mut config = Config::new(0xc0de, 0xcafe);
// master_id: MasterId, config.manufacturer = Some("Embassy");
// key: EncryptionInfo, config.product = Some("USB-serial example");
// peer_id: IdentityKey, config.serial_number = Some("12345678");
// } config.max_power = 100;
config.max_packet_size_0 = 64;
#[panic_handler] // panicking behavior // Create embassy-usb DeviceBuilder using the driver and config.
fn panic(_: &core::panic::PanicInfo) -> ! { // It needs some buffers for building the descriptors.
reset_into_dfu(); let mut config_descriptor = [0; 256];
} let mut bos_descriptor = [0; 256];
let mut msos_descriptor = [0; 256];
let mut control_buf = [0; 64];
#[model("tflite_demo/models/sine.tflite")] let mut state = State::new();
struct Sine;
#[model("tflite_demo/models/speech.tflite")] let mut builder = Builder::new(
struct Speech; driver,
config,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,
&mut control_buf,
);
/// Resets the device into Device Firmware Update mode (DFU). // Create classes on the builder.
fn reset_into_dfu() -> ! { let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
// Via https://devzone.nordicsemi.com/f/nordic-q-a/50839/start-dfu-mode-or-open_bootloader-from-application-by-function-call
unsafe { // Build the builder.
(*hal::pac::POWER::PTR).gpregret.write(|w| w.bits(0xB1)); let mut usb = builder.build();
// Run the USB device.
let usb_fut = usb.run();
// Do stuff with the class!
let echo_fut = async {
loop {
class.wait_connection().await;
info!("Connected");
let _ = echo(&mut class).await;
info!("Disconnected");
}
}; };
hal::pac::SCB::sys_reset() // Run everything concurrently.
} // If we had made everything `'static` above instead, we could do this using separate tasks instead.
join(usb_fut, echo_fut).await;
#[derive(Clone, Copy)] // let config = twim::Config::default();
enum LightState { // let i2c = embassy_nrf::twim::Twim::new(p.TWISPI0, Irqs2, p.P0_07, p.P0_27, config);
Red = 0,
Green = 1,
Blue = 2,
}
#[cortex_m_rt::entry] let i2c_bus = {
fn main() -> ! { use embassy_nrf::{
{ bind_interrupts,
use core::mem::MaybeUninit; peripherals::{self},
const HEAP_SIZE: usize = 1024; };
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; // bind_interrupts!(struct Irqs {
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) } // SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>;
} // });
bind_interrupts!(struct Irqs2 {
TWISPI0 => twim::InterruptHandler<peripherals::TWISPI0>;
});
let config = twim::Config::default();
let i2c = Twim::new(p.TWISPI0, Irqs2, p.P0_07, p.P0_27, config);
let i2c_bus = Mutex::<NoopRawMutex, _>::new(i2c);
I2C_BUS.init(i2c_bus)
};
let p = hal::pac::Peripherals::take().unwrap(); let i2c = I2cDevice::new(i2c_bus);
let port0 = hal::gpio::p0::Parts::new(p.P0);
let mut led_red = port0.p0_26.into_push_pull_output(Level::Low);
let mut led_green = port0.p0_30.into_push_pull_output(Level::Low);
let mut led_blue = port0.p0_06.into_push_pull_output(Level::Low);
let clocks = hal::clocks::Clocks::new(p.CLOCK); let interface = I2cInterface::new(i2c);
let clocks = clocks.enable_ext_hfosc(); let imu = lsm6ds3tr::LSM6DS3TR::new(interface);
let usb_peripheral = hal::usbd::UsbPeripheral::new(p.USBD, &clocks);
let usb_bus = UsbBusAllocator::new(hal::usbd::Usbd::new(usb_peripheral));
let mut serial_port = usbd_serial::SerialPort::new(&usb_bus);
// let spiclk = port0.p0_24.into_push_pull_output(Level::Low).degrade(); // let mut serial_port = usbd_serial::SerialPort::new(&usb);
// let spimosi = port0.p0_23.into_push_pull_output(Level::Low).degrade();
// let spimiso = port0.p0_22.into_floating_input().degrade();
// let pins = nrf52840_hal::spim::Pins {
// sck: Some(spiclk),
// miso: Some(spimiso),
// mosi: Some(spimosi),
// };
// let spim = Spim::new(
// p.SPIM2,
// pins,
// nrf52840_hal::spim::Frequency::K125,
// nrf52840_hal::spim::MODE_0,
// 0,
// );
// let spi_interface = SpiInterface::new(spim);
// let settings = LsmSettings::basic();
// let mut imu = LSM6DS3TR::new(spi_interface);
// imu.init().expect("Couldn't initialize the LSM6 sensor!");
// let scl = port0.p0_27.into_floating_input().degrade();
// let sda = port0.p0_07.into_floating_input().degrade();
// let pins = twim::Pins { scl: scl, sda: sda };
// let i2c = Twim::new(p.TWIM0, pins, twim::Frequency::K100);
// let i2c_interface = I2cInterface::new(i2c);
// let mut imu = LSM6DS3TR::new(I2cInterface::new(""));
// let mut imu = Lsm6ds33::new(i2c, addr);
let rtc = Rtc::new(p.RTC0, 0).unwrap();
rtc.enable_counter();
let mut usb_device = usb_device::device::UsbDeviceBuilder::new(
&usb_bus,
usb_device::device::UsbVidPid(0x16c0, 0x27dd),
)
.manufacturer("HSRW")
.product("HSRW Pet Tracker nRF52840")
.serial_number("pet1")
.device_class(usbd_serial::USB_CLASS_CDC)
.max_packet_size_0(64) // makes control transfers 8x faster says https://github.com/nrf-rs/nrf-hal/blob/master/examples/usb/src/bin/serial.rs
.build();
let x = 0.5;
let start = rtc.get_counter();
let y_predicted = Sine::predict(matrix![x])[0];
let end = rtc.get_counter();
let y_exact = sinf(x);
// TIMER0 is reserved by Softdevice
// https://devzone.nordicsemi.com/f/nordic-q-a/1160/soft-device-and-timers---how-do-they-work-together
let mut timer = hal::Timer::new(p.TIMER1).into_periodic();
timer.start(hal::Timer::<hal::pac::TIMER0>::TICKS_PER_SECOND);
let mut light = LightState::Red;
loop { loop {
light = match light { info!("Hello, world!");
LightState::Red => LightState::Green, }
LightState::Green => LightState::Blue, }
LightState::Blue => LightState::Red,
};
match light {
LightState::Red => {
led_red.set_state(PinState::Low).unwrap();
led_green.set_state(PinState::High).unwrap();
led_blue.set_state(PinState::High).unwrap();
}
LightState::Green => {
led_red.set_state(PinState::High).unwrap();
led_green.set_state(PinState::Low).unwrap();
led_blue.set_state(PinState::High).unwrap();
}
LightState::Blue => {
led_red.set_state(PinState::High).unwrap();
led_green.set_state(PinState::High).unwrap();
led_blue.set_state(PinState::Low).unwrap();
//reset_into_dfu();
}
}
// if !usb_dev.poll(&mut [&mut serial]) { struct Disconnected {}
// continue;
// }
let mut buf = [0u8; 64]; impl From<EndpointError> for Disconnected {
fn from(val: EndpointError) -> Self {
match serial_port.read(&mut buf) { match val {
Ok(count) if count > 0 => { EndpointError::BufferOverflow => panic!("Buffer overflow"),
// Check if received data equals to 'reset' EndpointError::Disabled => Disconnected {},
for i in 0..count - 4 {
if buf[i] == b'r'
&& buf[i + 1] == b'e'
&& buf[i + 2] == b's'
&& buf[i + 3] == b'e'
&& buf[i + 4] == b't'
{
reset_into_dfu();
}
}
if buf[..12].iter().all(|&x| x == 0) {
reset_into_dfu();
}
// Echo back in upper case
for c in buf[0..count].iter_mut() {
if 0x61 <= *c && *c <= 0x7a {
*c &= !0x20;
}
}
let mut write_offset = 0;
while write_offset < count {
match serial_port.write(&buf[write_offset..count]) {
Ok(len) if len > 0 => {
write_offset += len;
}
_ => {}
}
}
}
_ => {}
}
let text = y_predicted.to_bits();
let mut data = String::<32>::new();
let text2 = y_exact.to_bits();
let mut data2 = String::<32>::new();
let _ = serial_port.write("Hello World\n".as_bytes());
let _ = serial_port.write("Predicted Y: ".as_bytes());
let _ = write!(data, "data:{text}");
let _ = serial_port.write(data.as_bytes());
let _ = serial_port.write("\n".as_bytes());
let _ = serial_port.write("Exact Y: ".as_bytes());
let _ = write!(data2, "data:{text2}");
let _ = serial_port.write(data2.as_bytes());
let _ = serial_port.write("\n".as_bytes());
while timer.wait().is_err() {
// TODO: sleep.
// Spec says poll needs to be called at least every 10ms.
usb_device.poll(&mut [&mut serial_port]);
continue;
} }
} }
} }
async fn echo<'d, T: Instance + 'd, P: VbusDetect + 'd>(
class: &mut CdcAcmClass<'d, Driver<'d, T, P>>,
) -> Result<(), Disconnected> {
let mut buf = [0; 64];
loop {
let n = class.read_packet(&mut buf).await?;
let data = &buf[..n];
info!("data: {:x}", data);
class.write_packet(data).await?;
}
}