initial commit
This commit is contained in:
commit
55ed793c12
BIN
.assets/ferris.webp
Normal file
BIN
.assets/ferris.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
15
.cargo/config.toml
Normal file
15
.cargo/config.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[build]
|
||||
target = "thumbv7em-none-eabihf"
|
||||
|
||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
rustflags = [
|
||||
"-C",
|
||||
"link-arg=-Tlink.x",
|
||||
"-C",
|
||||
"link-arg=-Tdefmt.x",
|
||||
"-C",
|
||||
"link-arg=--nmagic",
|
||||
]
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "trace"
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
1676
Cargo.lock
generated
Normal file
1676
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
78
Cargo.toml
Normal file
78
Cargo.toml
Normal file
@ -0,0 +1,78 @@
|
||||
[workspace]
|
||||
members = ["tflite_demo", "lsm6ds3tr_demo"]
|
||||
|
||||
[workspace.features]
|
||||
default = ["ble-l2cap", "ble-gatt-server", "ble-gatt-client", "ble-sec"]
|
||||
|
||||
ble-l2cap = ["nrf-softdevice/ble-l2cap"]
|
||||
ble-gatt-server = ["nrf-softdevice/ble-gatt-server"]
|
||||
ble-gatt-client = ["nrf-softdevice/ble-gatt-client"]
|
||||
ble-sec = ["nrf-softdevice/ble-sec"]
|
||||
|
||||
nrf52840 = [
|
||||
"embassy-nrf/nrf52840",
|
||||
"nrf-softdevice/nrf52840",
|
||||
"nrf-softdevice/s140",
|
||||
"dep:nrf-softdevice-s140",
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
assign-resources = "0.4.1"
|
||||
embassy-futures = { version = "0.1.0" }
|
||||
embassy-usb = { version = "0.3.0", features = ["defmt"] }
|
||||
embassy-executor = { version = "0.7.0", features = [
|
||||
"task-arena-size-32768",
|
||||
"arch-cortex-m",
|
||||
"executor-thread",
|
||||
"executor-interrupt",
|
||||
"defmt",
|
||||
] }
|
||||
embassy-time = { version = "0.4.0", features = [
|
||||
"defmt",
|
||||
"defmt-timestamp-uptime",
|
||||
] }
|
||||
embassy-nrf = { version = "0.3.1", features = [
|
||||
"defmt",
|
||||
"nrf52840",
|
||||
"time-driver-rtc1",
|
||||
"gpiote",
|
||||
"unstable-pac",
|
||||
"time",
|
||||
"reset-pin-as-gpio",
|
||||
] }
|
||||
embassy-embedded-hal = "0.3.0"
|
||||
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7.0"
|
||||
defmt = "0.3"
|
||||
defmt-rtt = "0.4"
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
nrf52840-hal = "0.16.0"
|
||||
usb-device = "0.2.7"
|
||||
usbd-serial = "0.1.0"
|
||||
microflow = { path = "../microflow-rs" }
|
||||
nalgebra = { version = "0.33.2", default-features = false, features = [
|
||||
"macros",
|
||||
] }
|
||||
libm = "0.2"
|
||||
panic-halt = "1.0.0"
|
||||
heapless = "0.8.0"
|
||||
lsm6ds3tr = { git = "https://avoid.sh/PetActivityMonitor/lsm6ds3tr.git", rev = "b368f6200c3ec9a84114e8ca137eb5fe0aa08e29", features = [
|
||||
"defmt",
|
||||
] }
|
||||
embassy-sync = { version = "0.5.0" }
|
||||
embedded-storage = "0.3.0"
|
||||
embedded-hal = "1.0.0"
|
||||
embedded-hal-async = { version = "1.0.0" }
|
||||
embedded-alloc = "0.6.0"
|
||||
nrf-softdevice = { version = "0.1.0", features = [
|
||||
"defmt",
|
||||
"ble-peripheral",
|
||||
"ble-central",
|
||||
"critical-section-impl",
|
||||
"nrf52840",
|
||||
"s140",
|
||||
] }
|
||||
nrf-softdevice-s140 = { version = "0.1.1" }
|
||||
fixed = "1.24.0"
|
||||
atomic-pool = "1.0.1"
|
||||
static_cell = "2.0.0"
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# xiao_pet_activity_analyser
|
||||
|
||||
<img src="./.assets/ferris.webp" width="300" />
|
||||
|
||||
Blazingly fast and efficient pet activity analyser!
|
||||
|
||||
## Supported Microcontrollers
|
||||
|
||||
- Seeed XIAO BLE
|
||||
|
||||
## Mac Tooling
|
||||
|
||||
List connected devices:
|
||||
|
||||
```bash
|
||||
ioreg -p IOUSB
|
||||
```
|
||||
|
||||
Screen the controller:
|
||||
|
||||
```bash
|
||||
screen /dev/tty./dev/tty.usbmodempet11
|
||||
```
|
6
build.rs
Normal file
6
build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
// Rebuild if memory.x file was rebuild.
|
||||
// Linker seems to pick it up automatically.
|
||||
// (via the include in link.x which is added with a linker argument!)
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
}
|
28
build_and_flash.sh
Executable file
28
build_and_flash.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
COM_PORT=/dev/cu.usbmodem2101
|
||||
|
||||
echo -e "bootloader" > $COM_PORT
|
||||
|
||||
sleep 1s
|
||||
|
||||
while getopts 'abc:h' opt; do
|
||||
case "$opt" in
|
||||
?|h)
|
||||
echo "Usage: $(basename $0) crate_name"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift "$(($OPTIND -1))"
|
||||
CRATE=$1
|
||||
|
||||
cargo build -p $CRATE --release
|
||||
arm-none-eabi-objcopy -O ihex target/thumbv7em-none-eabihf/release/$CRATE target/$CRATE.hex
|
||||
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0x0123 --application target/$CRATE.hex target/$CRATE.zip
|
||||
# Use our custom reboot system to boot the controller into serial-only DFU mode.
|
||||
# echo -e "bootloader" > $COM_PORT
|
||||
# Wait for the reboot.
|
||||
# sleep 1s
|
||||
adafruit-nrfutil --verbose dfu serial -pkg target/$CRATE.zip -p $COM_PORT -b 115200 --singlebank
|
15
flashing_time.py
Executable file
15
flashing_time.py
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from subprocess import run
|
||||
|
||||
# requires pySerial:
|
||||
# python -m pip install pyserial
|
||||
import serial
|
||||
|
||||
# grab the port for the seeed nrf52 (only connect one at a time)
|
||||
data = run("ls /dev/ | grep 'cu.usbmodem'", capture_output=True, shell=True, text=True)
|
||||
|
||||
ser = serial.Serial("/dev/" + data.stdout.strip(), 1200)
|
||||
# send 16 null characters as reset signal to enter the bootloader
|
||||
ser.write(b"\x00" * 16)
|
||||
ser.close()
|
BIN
lsm6ds3tr_demo/.DS_Store
vendored
Normal file
BIN
lsm6ds3tr_demo/.DS_Store
vendored
Normal file
Binary file not shown.
36
lsm6ds3tr_demo/Cargo.toml
Normal file
36
lsm6ds3tr_demo/Cargo.toml
Normal file
@ -0,0 +1,36 @@
|
||||
[package]
|
||||
name = "lsm6ds3tr_demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
cortex-m.workspace = true
|
||||
cortex-m-rt.workspace = true
|
||||
nrf52840-hal.workspace = true
|
||||
usb-device.workspace = true
|
||||
usbd-serial.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-time.workspace = true
|
||||
embassy-executor.workspace = true
|
||||
embassy-sync.workspace = true
|
||||
embassy-embedded-hal.workspace = true
|
||||
fixed.workspace = true
|
||||
atomic-pool.workspace = true
|
||||
static_cell.workspace = true
|
||||
embassy-usb.workspace = true
|
||||
embassy-futures.workspace = true
|
||||
panic-probe.workspace = true
|
||||
assign-resources.workspace = true
|
4
lsm6ds3tr_demo/src/common.rs
Normal file
4
lsm6ds3tr_demo/src/common.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#![macro_use]
|
||||
|
||||
use defmt_rtt as _; // global logger
|
||||
use embassy_nrf as _; // time driver
|
284
lsm6ds3tr_demo/src/main.rs
Normal file
284
lsm6ds3tr_demo/src/main.rs
Normal file
@ -0,0 +1,284 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use assign_resources::assign_resources;
|
||||
use core::fmt::Write;
|
||||
use defmt::{dbg, info, unwrap};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||
use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
|
||||
use embassy_nrf::usb::Driver;
|
||||
use embassy_nrf::{bind_interrupts, peripherals, twim, usb, Peripherals};
|
||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
use embassy_usb::driver::EndpointError;
|
||||
use embassy_usb::{Builder, Config, UsbDevice};
|
||||
use heapless::String;
|
||||
use lsm6ds3tr::interface::I2cInterface;
|
||||
use lsm6ds3tr::{
|
||||
registers::{GyroSampleRate, GyroScale},
|
||||
AccelSampleRate, AccelScale, AccelSettings, GyroSettings, LsmSettings, LSM6DS3TR,
|
||||
};
|
||||
use static_cell::StaticCell;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
mod usb_dfu;
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
USBD => usb::InterruptHandler<peripherals::USBD>;
|
||||
CLOCK_POWER => usb::vbus_detect::InterruptHandler;
|
||||
});
|
||||
|
||||
assign_resources! {
|
||||
imu: ImuResources {
|
||||
spi: SPI2,
|
||||
}
|
||||
}
|
||||
|
||||
bind_interrupts!(struct IrqsTest {
|
||||
// SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<TWISPI0>;
|
||||
TWISPI0 => twim::InterruptHandler<peripherals::TWISPI0>;
|
||||
});
|
||||
|
||||
static I2C_BUS: StaticCell<Mutex<ThreadModeRawMutex, twim::Twim<peripherals::TWISPI0>>> =
|
||||
StaticCell::new();
|
||||
|
||||
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
let p = embassy_nrf::init(Default::default());
|
||||
// let resources = split_resources!(p);
|
||||
|
||||
// setup_dfu_over_usb(&spawner, p.USBD);
|
||||
|
||||
// Create the driver, from the HAL.
|
||||
let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs));
|
||||
|
||||
let mut config = Config::new(0xc0de, 0xcafe);
|
||||
config.manufacturer = Some("Umbrella Corporation");
|
||||
config.product = Some("Secret Project");
|
||||
config.serial_number = Some("11880");
|
||||
config.max_power = 100;
|
||||
config.max_packet_size_0 = 64;
|
||||
|
||||
static STATE: StaticCell<State> = StaticCell::new();
|
||||
let state = STATE.init(State::new());
|
||||
|
||||
// Create embassy-usb DeviceBuilder using the driver and config.
|
||||
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
|
||||
static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
|
||||
let mut builder = Builder::new(
|
||||
driver,
|
||||
config,
|
||||
&mut CONFIG_DESC.init([0; 256])[..],
|
||||
&mut BOS_DESC.init([0; 256])[..],
|
||||
&mut MSOS_DESC.init([0; 128])[..],
|
||||
&mut CONTROL_BUF.init([0; 128])[..],
|
||||
);
|
||||
|
||||
// Create classes on the builder.
|
||||
let mut class = CdcAcmClass::new(&mut builder, state, 64);
|
||||
|
||||
// Build the builder.
|
||||
let usb = builder.build();
|
||||
|
||||
unwrap!(spawner.spawn(usb_task(usb)));
|
||||
|
||||
let mut led_red = Output::new(p.P0_06, Level::Low, OutputDrive::Standard);
|
||||
|
||||
let mut pin = Output::new(p.P1_08, Level::High, OutputDrive::HighDrive);
|
||||
pin.set_high();
|
||||
|
||||
Timer::after_millis(100).await;
|
||||
|
||||
let sda_pin = p.P0_07;
|
||||
let scl_pin = p.P0_27;
|
||||
|
||||
let mut imuConfig = twim::Config::default();
|
||||
// This limits the ADXL355 ODR to 200Hz max.
|
||||
imuConfig.frequency = twim::Frequency::K400;
|
||||
// Internal pullups for SCL and SDA must be enabled.
|
||||
imuConfig.scl_pullup = true;
|
||||
imuConfig.sda_pullup = true;
|
||||
|
||||
let i2c = twim::Twim::new(p.TWISPI0, IrqsTest, sda_pin, scl_pin, imuConfig);
|
||||
|
||||
let settings = LsmSettings::basic()
|
||||
.with_gyro(
|
||||
GyroSettings::new()
|
||||
.with_sample_rate(GyroSampleRate::_104Hz)
|
||||
.with_scale(GyroScale::_2000DPS),
|
||||
)
|
||||
.with_accel(
|
||||
AccelSettings::new()
|
||||
.with_sample_rate(AccelSampleRate::_104Hz)
|
||||
.with_scale(AccelScale::_4G),
|
||||
);
|
||||
|
||||
let mut imu = LSM6DS3TR::new(I2cInterface::new(i2c)).with_settings(settings);
|
||||
imu.init().expect("LSM6DS3TR-C initialization failure!");
|
||||
|
||||
let blink_fut = async {
|
||||
loop {
|
||||
Timer::after_millis(500).await;
|
||||
|
||||
if let (Ok(xyz_a), Ok(xyz_g)) = (imu.read_accel_raw(), imu.read_gyro()) {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let temp = imu.read_temp().expect("Error reading temperature data.");
|
||||
|
||||
let mut accel_data = String::<32>::new();
|
||||
if write!(
|
||||
accel_data,
|
||||
"Accel: x:{} y:{} z:{}\r\n",
|
||||
xyz_a.x, xyz_a.y, xyz_a.z
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
if let Err(e) = class.write_packet(accel_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
let mut gyro_data = String::<32>::new();
|
||||
if write!(
|
||||
gyro_data,
|
||||
"Gyro: x:{} y:{} z:{}\r\n",
|
||||
xyz_g.x, xyz_g.y, xyz_g.z
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
if let Err(e) = class.write_packet(gyro_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
let mut temp_data = String::<32>::new();
|
||||
if write!(temp_data, "Degrees C1 = {}\r\n", temp).is_ok() {
|
||||
if let Err(e) = class.write_packet(temp_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Error: Could not read imu data. \r\n").is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
blink_fut.await;
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn led_blinking_task(resources: ImuResources) {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn usb_task(mut device: UsbDevice<'static, MyDriver>) {
|
||||
device.run().await;
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn gyro_task(mut class: CdcAcmClass<'static, MyDriver>, p: &'static Peripherals) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn print_task(mut class: CdcAcmClass<'static, MyDriver>, text: &'static str) {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", text).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
info!("Disconnected");
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected :)");
|
||||
let _ = echo(&mut class).await;
|
||||
info!("Disconnected :(");
|
||||
}
|
||||
}
|
||||
|
||||
struct Disconnected {}
|
||||
|
||||
impl From<EndpointError> for Disconnected {
|
||||
fn from(val: EndpointError) -> Self {
|
||||
match val {
|
||||
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||
EndpointError::Disabled => Disconnected {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn echo(class: &mut CdcAcmClass<'static, MyDriver>) -> 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?;
|
||||
}
|
||||
}
|
157
lsm6ds3tr_demo/src/usb_dfu.rs
Normal file
157
lsm6ds3tr_demo/src/usb_dfu.rs
Normal file
@ -0,0 +1,157 @@
|
||||
use crate::Irqs;
|
||||
use core::fmt::Write;
|
||||
use defmt::{info, unwrap};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_nrf::peripherals::USBD;
|
||||
use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect};
|
||||
use embassy_nrf::usb::{Driver, Instance};
|
||||
use embassy_nrf::{pac, peripherals};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
use embassy_usb::driver::EndpointError;
|
||||
use embassy_usb::{Builder, Config};
|
||||
use heapless::String;
|
||||
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
const MAGIC_REBOOT_MESSAGE: &str = "bootloader";
|
||||
|
||||
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
|
||||
|
||||
/// Creates a usb serial device.
|
||||
/// Sending it [MAGIC_REBOOT_MESSAGE] will reboot the device
|
||||
/// into serial-only-dfu mode.
|
||||
pub fn setup_dfu_over_usb(spawner: &Spawner, usbd: USBD) {
|
||||
spawner.spawn(dfu_over_usb(usbd, *spawner)).unwrap();
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn dfu_over_usb(usbd: USBD, spawner: Spawner) {
|
||||
pac::CLOCK.tasks_hfclkstart().write_value(1);
|
||||
while pac::CLOCK.events_hfclkstarted().read() != 1 {}
|
||||
|
||||
// Create the driver, from the HAL.
|
||||
let driver = Driver::new(usbd, Irqs, HardwareVbusDetect::new(Irqs));
|
||||
|
||||
// Create embassy-usb Config
|
||||
let mut config = Config::new(0xc0de, 0xcafe);
|
||||
config.manufacturer = Some("Embassy");
|
||||
config.product = Some("USB-serial example");
|
||||
config.serial_number = Some("12345678");
|
||||
config.max_power = 100;
|
||||
config.max_packet_size_0 = 64;
|
||||
|
||||
// Create embassy-usb DeviceBuilder using the driver and config.
|
||||
// It needs some buffers for building the descriptors.
|
||||
let mut config_descriptor = [0; 256];
|
||||
let mut bos_descriptor = [0; 256];
|
||||
let mut msos_descriptor = [0; 256];
|
||||
let mut control_buf = [0; 64];
|
||||
|
||||
let mut state = State::new();
|
||||
|
||||
let mut builder = Builder::new(
|
||||
driver,
|
||||
config,
|
||||
&mut config_descriptor,
|
||||
&mut bos_descriptor,
|
||||
&mut msos_descriptor,
|
||||
&mut control_buf,
|
||||
);
|
||||
|
||||
// Create classes on the builder.
|
||||
let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
|
||||
|
||||
// Build the builder.
|
||||
let mut usb = builder.build();
|
||||
|
||||
// Run the USB device.
|
||||
let usb_fut = usb.run();
|
||||
|
||||
// Do stuff with the class!
|
||||
// let reboot_fut = async {
|
||||
// loop {
|
||||
// class.wait_connection().await;
|
||||
// let _ = reboot_on_magic_message(&mut class).await;
|
||||
// }
|
||||
// };
|
||||
|
||||
let print_fut = async {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
};
|
||||
|
||||
join(usb_fut, print_fut).await;
|
||||
}
|
||||
|
||||
struct Disconnected {}
|
||||
|
||||
impl From<EndpointError> for Disconnected {
|
||||
fn from(val: EndpointError) -> Self {
|
||||
match val {
|
||||
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||
EndpointError::Disabled => Disconnected {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn reboot_on_magic_message<'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];
|
||||
|
||||
if data == MAGIC_REBOOT_MESSAGE.as_bytes() {
|
||||
// Reboot the controller in DFU mode.
|
||||
// The magic number has been taken from the arduino bootloader:
|
||||
// https://github.com/mike1808/PIO_SEEED_Adafruit_nRF52_Arduino/blob/master/cores/nRF5/wiring.c#L26
|
||||
let dfu_magic_serial_only_reset = 0x4E;
|
||||
pac::POWER
|
||||
.gpregret()
|
||||
.write(|w| w.0 = dfu_magic_serial_only_reset);
|
||||
cortex_m::peripheral::SCB::sys_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
20
memory.x
Normal file
20
memory.x
Normal file
@ -0,0 +1,20 @@
|
||||
MEMORY
|
||||
{
|
||||
/* https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsds_s140%2FSDS%2Fs1xx%2Fmem_usage%2Fmem_resource_reqs.html&cp=5_7_4_0_13_0_0 */
|
||||
|
||||
/* Need to leave space for the SoftDevice
|
||||
These values are confirmed working for S140 7.3.0
|
||||
|
||||
They were extracted from the Arduino IDE plugin linked indirectly at https://wiki.seeedstudio.com/XIAO_BLE/
|
||||
*/
|
||||
FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xED000 - 0x27000
|
||||
|
||||
/* SRAM required by Softdevice depend on
|
||||
* - Attribute Table Size (Number of Services and Characteristics)
|
||||
* - Vendor UUID count
|
||||
* - Max ATT MTU
|
||||
* - Concurrent connection peripheral + central + secure links
|
||||
* - Event Len, HVN queue, Write CMD queue
|
||||
*/
|
||||
RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
|
||||
}
|
BIN
tflite_demo/.DS_Store
vendored
Normal file
BIN
tflite_demo/.DS_Store
vendored
Normal file
Binary file not shown.
37
tflite_demo/Cargo.toml
Normal file
37
tflite_demo/Cargo.toml
Normal file
@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "tflite_demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[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-time.workspace = true
|
||||
embassy-executor.workspace = true
|
||||
embassy-sync.workspace = true
|
||||
embassy-embedded-hal.workspace = true
|
||||
fixed.workspace = true
|
||||
atomic-pool.workspace = true
|
||||
static_cell.workspace = true
|
||||
embassy-usb.workspace = true
|
||||
embassy-futures.workspace = true
|
||||
panic-probe.workspace = true
|
||||
assign-resources.workspace = true
|
219
tflite_demo/features/speech.rs
Normal file
219
tflite_demo/features/speech.rs
Normal file
@ -0,0 +1,219 @@
|
||||
use nalgebra::matrix;
|
||||
|
||||
use microflow::buffer::Buffer2D;
|
||||
|
||||
pub const YES: Buffer2D<i8, 1, 1960> = matrix![
|
||||
116, 98, 118, 95, 106, 85, 101, 81, 67, -18, -33, -12, -26, -128, 9, 34, 56, 45, 9, -12, 5, 30,
|
||||
23, 28, 0, -18, 0, -128, -60, -50, -50, -37, -60, -60, -50, -26, -33, -50, -33, -50, 83, 61,
|
||||
81, 55, 76, 61, 73, 64, 38, -8, -37, -20, -18, -20, 48, 29, 52, 41, 55, 18, 25, 37, 44, 37, 8,
|
||||
15, -6, -60, -128, -50, -37, -37, -18, -37, -26, -29, -37, -60, -50, -60, 95, 59, 52, -4, 54,
|
||||
-18, 68, 43, 31, -18, -26, -33, -37, -29, 33, 7, -3, 8, 26, 24, 36, 6, 36, 23, 14, 8, -29, -37,
|
||||
-37, -37, -50, -50, -26, -8, -26, -37, -18, -37, -60, -77, 50, 48, 83, 44, 56, -128, -33, -60,
|
||||
1, -26, -60, -43, -14, -23, -18, -43, -26, -33, 13, -77, -43, -77, -33, -37, 16, -12, -37, -50,
|
||||
-50, -77, -20, -43, -60, -128, -60, -77, -37, -77, -60, -128, 37, -10, 65, -7, 28, -128, 10,
|
||||
-77, -37, -128, -77, -128, -77, -43, -128, -128, -77, -128, -128, -128, -128, -128, -14, -128,
|
||||
-43, -50, -37, -77, -128, -128, -77, -43, -29, -43, -20, -60, -37, -43, -50, -128, -77, -128,
|
||||
-18, -128, -60, -128, -128, -128, -77, -128, -77, -128, -128, -128, -60, -37, -20, -128, -60,
|
||||
-128, -128, -128, -60, -128, -77, -60, -128, -50, -60, -128, -77, -128, -50, -60, -37, -60,
|
||||
-50, -77, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -37, -128,
|
||||
-128, -128, -128, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-77, -60, -128, -128, -50, -128, -50, -128, -50, -128, -77, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -77, -128, -77,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128, -128, -128,
|
||||
-77, -50, -128, -128, -77, -77, -128, -128, -128, -50, -128, 85, 43, 65, 53, 69, 60, 45, 3, 46,
|
||||
-12, 9, -23, 32, -1, -128, -128, -128, -128, -1, 37, 38, 33, 43, 36, 58, 70, 68, 39, 6, 10, 32,
|
||||
6, 8, -23, -77, -128, -29, -128, -77, -128, 101, 87, 102, 91, 110, 88, 101, 83, 110, 95, 111,
|
||||
83, 81, 84, 106, 90, 93, 82, 98, 91, 108, 95, 118, 97, 118, 97, 116, 96, 113, 90, 110, 96, 107,
|
||||
85, 94, 66, 69, 36, 29, 0, 100, 60, 105, 68, 92, 93, 113, 92, 107, 85, 107, 83, 104, 91, 105,
|
||||
85, 112, 88, 101, 80, 101, 79, 96, 80, 98, 80, 105, 83, 98, 81, 103, 71, 100, 79, 83, 78, 91,
|
||||
47, 50, 13, 108, 81, 93, 78, 98, 76, 105, 76, 98, 40, 77, 72, 81, 62, 93, 77, 96, 80, 98, 61,
|
||||
97, 69, 88, 61, 71, 56, 98, 68, 97, 72, 89, 51, 81, 61, 88, 75, 86, 56, 48, 13, 71, 22, 84, 66,
|
||||
76, -7, 48, 61, 77, 62, 91, 65, 95, 74, 88, 59, 75, 58, 83, 55, 87, 55, 76, 43, 76, -3, 56, 60,
|
||||
79, 57, 71, 54, 82, 33, 74, 71, 91, 45, 18, -7, 61, 56, 77, 41, 73, 42, 82, 49, 59, 63, 82, 65,
|
||||
66, 38, 83, 34, 48, -8, 46, 20, 54, 33, 54, 6, 48, 16, 60, 37, 58, 22, 58, 14, 65, 53, 75, -4,
|
||||
42, 16, 16, -50, 22, -128, 80, 54, 43, -50, 42, -128, -10, -77, 28, -29, 68, 43, 73, 2, 25,
|
||||
-60, 47, 14, 45, 7, 66, 4, 62, 37, 71, 7, 46, -10, 44, 22, 55, 53, 57, -29, 26, -10, -3, -128,
|
||||
38, -128, 46, -10, 16, -128, -10, -26, 60, -7, 65, 38, 70, -60, 35, -8, 42, -29, 6, -128, 34,
|
||||
-128, 36, -60, 44, -12, -2, -128, -7, -60, -60, -128, -23, -128, 31, -33, 22, -77, -37, -43,
|
||||
-128, -128, 3, -128, -23, -128, 17, -77, 43, -77, -7, -128, -20, -128, 17, -43, 32, -128, -43,
|
||||
-128, -128, -77, 21, -128, -50, -128, -128, -128, -128, -128, -128, -128, -37, -128, -16, -128,
|
||||
-50, -26, -6, -128, -128, -128, -128, -128, -23, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -16, -128, 36, -7, 16, -128, -128, -128, -128, -128, -77, -128, -37, -128, -50,
|
||||
-128, -128, -128, -128, -128, -18, -128, 11, -128, -16, -77, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -26, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -20, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -50, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -1, -18, 5, -128, 40, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
4, -128, 63, 66, 75, -128, 70, 60, 34, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
87, 86, 95, 76, 91, 62, 72, -6, -50, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, 64, 83, 104, 70, 98, 90, 111, 89, 109, 80, 71, -128, -128, -128, -128, -128, -20,
|
||||
-6, 27, 33, 86, 88, 108, 75, 108, 76, 98, 64, 75, 61, 71, 66, 85, -1, -77, -128, 46, 61, 92,
|
||||
69, 100, 93, 113, 80, 108, 93, 113, 91, 110, 80, 85, 15, -33, -128, 12, -50, 34, 50, 70, 55,
|
||||
84, 72, 108, 81, 111, 88, 100, 80, 84, 73, 97, 86, 99, 65, 85, 43, 96, 78, 107, 94, 118, 98,
|
||||
115, 92, 118, 94, 111, 93, 111, 86, 99, 52, 32, -16, 48, 31, 81, 74, 85, 64, 78, 64, 98, 70,
|
||||
110, 92, 96, 73, 100, 72, 94, 73, 98, 76, 85, 67, 101, 83, 101, 83, 112, 89, 98, 85, 105, 78,
|
||||
98, 72, 102, 80, 95, 23, 19, -8, 52, 57, 103, 91, 95, 65, 74, 8, 77, 49, 96, 76, 100, 87, 105,
|
||||
81, 94, 62, 94, 78, 81, 72, 99, 82, 101, 78, 108, 65, 82, 70, 100, 63, 79, 58, 80, 59, 87, 48,
|
||||
50, 57, 93, 67, 86, 80, 103, 56, 77, 31, 81, 57, 62, 41, 96, 85, 91, 71, 101, 76, 89, 78, 95,
|
||||
76, 96, 79, 103, 81, 103, 48, 70, 57, 88, 66, 84, 11, 85, 67, 104, 37, 38, 67, 90, 54, 81, 62,
|
||||
90, 52, 78, -60, 54, -8, 68, 40, 55, 8, 77, 52, 66, 31, 55, 13, 60, 26, 69, 42, 63, -29, 57,
|
||||
-128, -3, -128, 3, -128, -29, -60, 52, -43, 63, 56, 86, 75, 95, 75, 85, 63, 82, 10, 50, -128,
|
||||
31, -77, 0, -77, -23, -128, 12, -77, 51, -3, 58, -14, 44, 0, 48, 4, 53, 47, 28, -128, -128,
|
||||
-128, -37, -128, -3, -128, 49, 61, 100, 90, 117, 88, 107, 94, 112, 64, 96, 83, -128, -128, 7,
|
||||
-128, -77, -128, -23, -128, -23, -128, 16, -37, 65, -8, 48, 20, 14, -77, 57, -18, -43, -128,
|
||||
-128, -128, -128, -128, -128, -128, 24, 12, 74, 76, 105, 76, 99, 80, 108, 79, 103, 85, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 42, -128, -8, -128, -50,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -60, -128, -128, 5, 73, 53, 93, 70, 101,
|
||||
73, 94, 57, 86, 66, -18, -128, -128, -128, -128, -128, -128, -128, -128, -128, -50, -128, 36,
|
||||
-128, -128, -128, -128, -128, -20, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, 23, 37, 75, 54, 97, 70, 83, 52, 85, 65, 7, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -43, -128, 23, -128, -43, -128, -33, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -26, -37, 65, 33, 76, 37, 73, 50, 77, 47, -12, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -7, -14, -4, -128, -14, -128, 18, -60, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -26, -60, 71, 42, 68, 53, 81, 49,
|
||||
73, 36, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -18, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
15, -26, 44, -18, 59, 39, 57, 20, 62, 26, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, 49, -128, 30, 8, 69, 27, 62, 38, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -43, -128, 28, -37, 48, -10,
|
||||
48, 11, 74, 37, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -77, -128, 11, -128, -7, -60, -77, -4, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -8, -128, -50, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128
|
||||
];
|
||||
|
||||
pub const NO: Buffer2D<i8, 1, 1960> = matrix![
|
||||
103, 78, 64, 76, 75, 54, 53, 67, 77, 60, 56, 70, 76, 71, 68, 58, 74, 32, 23, -2, -18, 11, 13,
|
||||
15, 9, 20, 5, -7, -18, -2, -10, -18, -10, -12, 9, 7, -33, -12, -4, -18, 57, 17, 55, 62, 70, 45,
|
||||
61, 37, 67, 52, 48, 47, 55, 46, 57, 47, 73, 17, 27, 20, 19, 8, 15, -6, -1, 10, -12, -29, -6,
|
||||
-23, -18, -3, -1, 5, 3, -4, -12, -8, -1, -14, 65, 48, 58, 43, 48, 19, 39, 39, 57, 57, 58, 55,
|
||||
67, 58, 49, 50, 70, 27, 9, 16, 37, 4, 25, 4, 11, 9, 7, -33, -7, -12, 3, -6, -29, -7, -7, -18,
|
||||
-12, -18, -2, -1, 0, 31, 60, -8, 51, 59, 70, 40, 71, 57, 52, 38, 66, 48, 17, 6, 59, 8, 15, 7,
|
||||
18, 4, 18, -23, -8, -4, -3, -12, -3, -26, 1, 10, 2, -29, -29, -37, -7, -4, 6, -33, 67, 44, 59,
|
||||
-4, 64, 51, 68, 55, 74, 9, 40, 15, 57, 33, 60, 18, 40, 25, 27, -20, 25, -16, 6, 17, -10, -12,
|
||||
-23, -43, -23, -23, -29, -37, -4, -16, -16, -60, -20, -23, -10, -29, -12, 15, 12, -37, 27, 15,
|
||||
61, 44, 50, 8, 48, 22, 49, -18, 46, 33, 42, 34, 46, -8, 4, -18, -43, -43, -10, 1, -10, -16,
|
||||
-10, -77, -16, -33, 11, -26, -23, -37, 0, -8, -16, -29, 42, 40, 68, 24, 47, 46, 53, -128, 30,
|
||||
2, 42, 21, 21, -4, 43, 2, 43, 5, 32, -26, 7, -37, -43, -23, -2, -8, 2, -37, -50, -60, -1, -7,
|
||||
-33, -77, -6, -18, -16, -50, -12, -33, 53, 8, 52, 18, 51, 35, 69, 26, 44, 8, 27, -128, 21, -33,
|
||||
17, -14, 38, -128, -14, -18, 17, -20, -14, -37, 8, -60, -33, -33, -33, -43, -12, -29, -12,
|
||||
-128, -33, -60, -26, -77, -26, -50, 57, 29, 11, 30, 53, -10, 45, 15, 18, -10, 42, 2, 31, -29,
|
||||
10, -4, 42, -37, -50, -128, -4, -43, -20, -77, -14, -26, -33, -128, -12, -43, -8, -33, -33,
|
||||
-60, -43, -77, -12, -60, -26, -50, 40, -23, 36, 35, 50, -2, 37, 27, 26, -77, 49, -7, 28, -43,
|
||||
6, 11, 41, -37, 33, -26, -14, -12, -6, -33, -16, -26, -20, -77, -14, -43, -8, -50, -14, -37,
|
||||
-26, -77, -26, -77, -14, -29, 50, -60, 25, -26, 57, 38, 51, 1, 50, 1, 53, -18, 30, -23, 11,
|
||||
-128, 18, -43, 20, -26, -10, -26, -12, -128, -50, -60, -37, -77, -20, -43, -50, -128, -77,
|
||||
-128, -77, -128, -33, -77, -20, -60, 53, -10, -37, -128, 10, -128, 60, 18, -8, 13, 37, -37, 8,
|
||||
-128, 3, -77, 32, -29, 14, 10, -12, -77, -37, -77, -37, -60, -23, -128, -43, -50, -16, -77, -6,
|
||||
-33, 0, -60, -43, -128, -16, -60, 20, -2, 51, 19, 43, 2, 63, 20, 60, -4, 42, -50, 4, -128, 2,
|
||||
-3, 32, -33, -26, -128, -18, -128, -33, -43, -7, -60, -50, -77, -29, -77, -23, -128, -16, -26,
|
||||
-23, -60, -37, -77, -37, -128, -1, -33, 39, 48, 60, 5, 8, -128, 44, 11, 4, 0, 13, -77, -2, -20,
|
||||
33, -128, -33, -77, -8, -128, -14, -128, -33, -18, -12, -77, -16, -128, -37, -128, -12, -77,
|
||||
-60, -128, -23, -60, -23, -128, 36, -50, 46, -128, 66, 39, 18, -14, -12, -77, -20, -6, 24,
|
||||
-128, 28, -26, 21, -77, -6, -33, 1, -128, -43, -128, -1, -50, -37, -128, -50, -128, -33, -128,
|
||||
-18, -128, -60, -8, -7, -60, -60, -128, -6, -29, 20, -1, 73, 40, -43, -14, 33, -43, 33, -3, 15,
|
||||
-29, 29, -43, 20, -60, -29, -128, -20, -26, 4, -77, -16, -60, -33, -50, -29, -128, -60, -128,
|
||||
-77, -128, -37, -50, 0, -77, -33, -128, 39, 8, 47, 10, 62, 16, 2, 1, 10, 7, 4, -7, 6, -128,
|
||||
-77, -50, 19, -77, -77, -128, -77, -128, -50, -128, -60, -60, -33, -50, -37, -128, -128, -128,
|
||||
-60, -128, -37, -60, -18, -128, -33, -77, 37, 23, 29, -128, -128, -128, -16, -128, -16, -33,
|
||||
21, -20, -8, -60, -2, -60, 11, -128, -50, -128, -50, -128, -29, -77, -16, -128, -26, -128, -50,
|
||||
-77, -43, -128, -128, -128, -50, -128, -33, -128, -33, -50, -23, -128, 24, -128, -128, -77, 4,
|
||||
-23, 32, -128, 1, -26, -14, -128, 10, -77, -4, -128, 1, -50, -8, -77, -77, -77, -23, -128, -50,
|
||||
-43, -33, -128, -43, -128, -128, -128, -43, -128, -50, -128, -128, -128, 44, 15, 14, -128, 9,
|
||||
-128, 21, 0, 29, -7, 18, -7, -7, -128, -33, -50, 14, -60, -60, -128, -60, -128, -37, -128, -43,
|
||||
-128, -20, -128, -50, -128, -43, -77, -26, -128, -60, -50, -60, -128, -77, -128, -3, -128, 14,
|
||||
-77, -26, 11, 47, -77, -7, -77, 45, -43, -12, 14, 37, -60, 22, -4, 5, -77, -14, -128, -10, -60,
|
||||
22, -77, -12, -60, -50, -128, -60, -128, -60, -128, -43, -128, -50, -128, -77, -50, 27, -37,
|
||||
33, -128, 4, -29, -4, -50, -20, -128, 6, -37, -33, -128, -50, -128, 34, 15, -43, -128, -20,
|
||||
-50, -3, -37, -37, -77, -77, -128, -43, -128, -128, -128, 4, -26, -26, 27, 0, -128, -29, -60,
|
||||
35, -26, 23, -128, -29, -77, 19, 14, 28, -128, -16, -7, 31, -1, 17, 11, 60, 44, 8, 11, 18,
|
||||
-128, -33, -60, -1, -128, -43, -128, -23, -128, -128, -128, 59, 43, 35, 61, 37, -77, -77, -50,
|
||||
116, 88, 98, 69, 78, 53, 78, 40, 48, 7, 29, -18, -2, -14, 5, 12, 65, 35, 31, -12, 33, -2, -6,
|
||||
-1, 44, -29, -14, -60, -4, -43, -37, -128, 29, 18, 38, 51, 8, -128, -12, -37, 115, 91, 113, 77,
|
||||
89, 36, 60, 44, 49, 36, 27, 31, 63, 30, 62, 14, 55, 49, 42, 0, 45, 17, -23, 1, 30, -37, -50,
|
||||
-77, -8, -60, 9, -60, -12, -50, 13, 4, 23, -6, 28, 13, 107, 78, 101, 73, 89, 46, 63, 17, 34,
|
||||
-43, -6, 30, 67, 40, 77, 21, 53, 39, 38, 12, -6, 5, 28, -2, 18, -43, 0, -128, -29, -77, 18,
|
||||
-128, -2, -77, 39, 35, 38, 35, 50, 29, 100, 70, 94, 69, 86, 50, 45, 38, 45, 12, 58, 64, 74, 36,
|
||||
77, 45, 78, 62, 8, -60, 38, 6, 21, 7, 8, -37, -1, -20, 48, -37, 8, -10, 8, 13, 45, 39, 38, 22,
|
||||
49, 25, 94, 63, 87, 66, 84, -128, 29, 20, 55, 51, 80, 36, 62, 30, 81, 72, 68, 37, 51, 27, 54,
|
||||
22, 16, -29, 4, 9, 57, 15, 35, -43, -77, -20, 4, 6, 37, -1, 40, 31, 47, 14, 89, 68, 96, 83,
|
||||
111, 96, 115, 87, 99, 76, 105, 84, 105, 86, 113, 91, 108, 87, 110, 78, 80, 46, 22, 74, 88, 72,
|
||||
103, 86, 80, 68, 48, 24, 68, 48, 55, 36, 108, 90, 90, 63, 83, 63, 87, 64, 90, 92, 113, 88, 102,
|
||||
79, 109, 83, 100, 89, 109, 60, 56, 21, 75, 62, 81, 45, 63, 73, 93, 65, 94, 80, 89, 81, 73, 3,
|
||||
43, 60, 102, 70, 84, 67, 99, 74, 78, 57, 79, 50, 93, 82, 98, 56, 77, 70, 91, 71, 85, 82, 86,
|
||||
13, 45, -18, 48, 40, 53, 28, 85, 60, 65, 52, 86, 78, 76, 46, 73, 19, 35, 54, 75, 40, 71, 60,
|
||||
82, 37, 69, 42, 62, 40, 96, 70, 85, 77, 70, 68, 103, 84, 94, 69, 81, -128, -128, -128, -43,
|
||||
-37, 40, 2, 48, 45, 76, 37, 65, 16, 43, 18, 58, 20, 27, 12, 71, 31, 53, 44, 88, 47, 50, 33, 39,
|
||||
8, 89, 57, 88, 69, 72, 63, 100, 68, 81, -77, -10, -128, -128, -128, -128, -128, 13, -77, 8, 27,
|
||||
60, 28, 41, -128, -37, -128, 28, -43, -18, -128, 47, -37, 45, 27, 51, -29, 15, 39, 52, 30, 49,
|
||||
-33, 65, 15, 76, 71, 90, 19, 46, -128, -16, -128, -128, -128, -128, -128, -128, -128, -18,
|
||||
-128, -20, -128, 32, -128, 21, -33, 45, -128, -128, -128, -12, -128, -6, -14, 43, -128, -128,
|
||||
-128, -128, -128, 52, -18, 69, -43, 78, 55, 42, -128, -29, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, 14, -128, -16, -128, -128, -128, 7, -128, -128, -128, -128, -128,
|
||||
-128, -128, 12, -128, -128, -128, -128, -16, 59, -50, 35, -128, 42, 0, 47, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -33, -128, -23, -128, -128, -128,
|
||||
-23, -128, -128, -128, -128, -128, -128, -128, -33, -128, -128, -128, -128, -128, -128, -128,
|
||||
-8, -128, 36, -50, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -37, -128, -128, -60, -10, -128, -128, -128, -128, -128, -128, -128,
|
||||
21, -128, -128, -128, -128, -128, -128, -128, -128, -128, -12, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -77, -128, -128, -128, -29, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -29, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-50, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
|
||||
-128, -128
|
||||
];
|
BIN
tflite_demo/models/.DS_Store
vendored
Normal file
BIN
tflite_demo/models/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
tflite_demo/models/gesture_model.tflite
Normal file
BIN
tflite_demo/models/gesture_model.tflite
Normal file
Binary file not shown.
BIN
tflite_demo/models/sine.tflite
Normal file
BIN
tflite_demo/models/sine.tflite
Normal file
Binary file not shown.
BIN
tflite_demo/models/speech.tflite
Normal file
BIN
tflite_demo/models/speech.tflite
Normal file
Binary file not shown.
4
tflite_demo/src/common.rs
Normal file
4
tflite_demo/src/common.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#![macro_use]
|
||||
|
||||
use defmt_rtt as _; // global logger
|
||||
use embassy_nrf as _; // time driver
|
285
tflite_demo/src/main.rs
Normal file
285
tflite_demo/src/main.rs
Normal file
@ -0,0 +1,285 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use assign_resources::assign_resources;
|
||||
use core::fmt::Write;
|
||||
use defmt::{dbg, info, unwrap};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||
use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
|
||||
use embassy_nrf::usb::Driver;
|
||||
use embassy_nrf::{bind_interrupts, peripherals, twim, usb, Peripherals};
|
||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
use embassy_usb::driver::EndpointError;
|
||||
use embassy_usb::{Builder, Config, UsbDevice};
|
||||
use heapless::String;
|
||||
use lsm6ds3tr::interface::I2cInterface;
|
||||
use lsm6ds3tr::{
|
||||
registers::{GyroSampleRate, GyroScale},
|
||||
AccelSampleRate, AccelScale, AccelSettings, GyroSettings, LsmSettings, LSM6DS3TR,
|
||||
};
|
||||
use static_cell::StaticCell;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
mod usb_dfu;
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
USBD => usb::InterruptHandler<peripherals::USBD>;
|
||||
CLOCK_POWER => usb::vbus_detect::InterruptHandler;
|
||||
});
|
||||
|
||||
assign_resources! {
|
||||
imu: ImuResources {
|
||||
spi: SPI2,
|
||||
}
|
||||
}
|
||||
|
||||
bind_interrupts!(struct IrqsTest {
|
||||
// SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<TWISPI0>;
|
||||
TWISPI0 => twim::InterruptHandler<peripherals::TWISPI0>;
|
||||
});
|
||||
|
||||
static I2C_BUS: StaticCell<Mutex<ThreadModeRawMutex, twim::Twim<peripherals::TWISPI0>>> =
|
||||
StaticCell::new();
|
||||
|
||||
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
let p = embassy_nrf::init(Default::default());
|
||||
// let resources = split_resources!(p);
|
||||
|
||||
// setup_dfu_over_usb(&spawner, p.USBD);
|
||||
|
||||
// Create the driver, from the HAL.
|
||||
let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs));
|
||||
|
||||
let mut config = Config::new(0xc0de, 0xcafe);
|
||||
config.manufacturer = Some("Umbrella Corporation");
|
||||
config.product = Some("Secret Project");
|
||||
config.serial_number = Some("11880");
|
||||
config.max_power = 100;
|
||||
config.max_packet_size_0 = 64;
|
||||
|
||||
static STATE: StaticCell<State> = StaticCell::new();
|
||||
let state = STATE.init(State::new());
|
||||
|
||||
// Create embassy-usb DeviceBuilder using the driver and config.
|
||||
static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new();
|
||||
static MSOS_DESC: StaticCell<[u8; 128]> = StaticCell::new();
|
||||
static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new();
|
||||
let mut builder = Builder::new(
|
||||
driver,
|
||||
config,
|
||||
&mut CONFIG_DESC.init([0; 256])[..],
|
||||
&mut BOS_DESC.init([0; 256])[..],
|
||||
&mut MSOS_DESC.init([0; 128])[..],
|
||||
&mut CONTROL_BUF.init([0; 128])[..],
|
||||
);
|
||||
|
||||
// Create classes on the builder.
|
||||
let mut class = CdcAcmClass::new(&mut builder, state, 64);
|
||||
|
||||
// Build the builder.
|
||||
let usb = builder.build();
|
||||
|
||||
unwrap!(spawner.spawn(usb_task(usb)));
|
||||
|
||||
let mut led_red = Output::new(p.P0_06, Level::Low, OutputDrive::Standard);
|
||||
|
||||
let mut pin = Output::new(p.P1_08, Level::High, OutputDrive::HighDrive);
|
||||
pin.set_high();
|
||||
|
||||
Timer::after_millis(100).await;
|
||||
|
||||
let sda_pin = p.P0_07;
|
||||
let scl_pin = p.P0_27;
|
||||
|
||||
let mut imuConfig = twim::Config::default();
|
||||
// This limits the ADXL355 ODR to 200Hz max.
|
||||
imuConfig.frequency = twim::Frequency::K400;
|
||||
// Internal pullups for SCL and SDA must be enabled.
|
||||
imuConfig.scl_pullup = true;
|
||||
imuConfig.sda_pullup = true;
|
||||
|
||||
let i2c = twim::Twim::new(p.TWISPI0, IrqsTest, sda_pin, scl_pin, imuConfig);
|
||||
|
||||
let settings = LsmSettings::basic()
|
||||
.with_gyro(
|
||||
GyroSettings::new()
|
||||
.with_sample_rate(GyroSampleRate::_104Hz)
|
||||
.with_scale(GyroScale::_2000DPS),
|
||||
)
|
||||
.with_accel(
|
||||
AccelSettings::new()
|
||||
.with_sample_rate(AccelSampleRate::_104Hz)
|
||||
.with_scale(AccelScale::_4G),
|
||||
);
|
||||
|
||||
let mut imu = LSM6DS3TR::new(I2cInterface::new(i2c)).with_settings(settings);
|
||||
imu.init().expect("LSM6DS3TR-C initialization failure!");
|
||||
|
||||
let blink_fut = async {
|
||||
loop {
|
||||
Timer::after_millis(500).await;
|
||||
|
||||
if let (Ok(xyz_a), Ok(xyz_g)) = (imu.read_accel_raw(), imu.read_gyro()) {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let temp = imu.read_temp().expect("Error reading temperature data.");
|
||||
// imu.read_temp()
|
||||
|
||||
let mut accel_data = String::<32>::new();
|
||||
if write!(
|
||||
accel_data,
|
||||
"Accel: x:{} y:{} z:{}\r\n",
|
||||
xyz_a.x, xyz_a.y, xyz_a.z
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
if let Err(e) = class.write_packet(accel_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
let mut gyro_data = String::<32>::new();
|
||||
if write!(
|
||||
gyro_data,
|
||||
"Gyro: x:{} y:{} z:{}\r\n",
|
||||
xyz_g.x, xyz_g.y, xyz_g.z
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
if let Err(e) = class.write_packet(gyro_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
let mut temp_data = String::<32>::new();
|
||||
if write!(temp_data, "Degrees C1 = {}\r\n", temp).is_ok() {
|
||||
if let Err(e) = class.write_packet(temp_data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Error: Could not read imu data. \r\n").is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
blink_fut.await;
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn led_blinking_task(resources: ImuResources) {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn usb_task(mut device: UsbDevice<'static, MyDriver>) {
|
||||
device.run().await;
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn gyro_task(mut class: CdcAcmClass<'static, MyDriver>, p: &'static Peripherals) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn print_task(mut class: CdcAcmClass<'static, MyDriver>, text: &'static str) {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", text).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
info!("Disconnected");
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected :)");
|
||||
let _ = echo(&mut class).await;
|
||||
info!("Disconnected :(");
|
||||
}
|
||||
}
|
||||
|
||||
struct Disconnected {}
|
||||
|
||||
impl From<EndpointError> for Disconnected {
|
||||
fn from(val: EndpointError) -> Self {
|
||||
match val {
|
||||
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||
EndpointError::Disabled => Disconnected {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn echo(class: &mut CdcAcmClass<'static, MyDriver>) -> 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?;
|
||||
}
|
||||
}
|
157
tflite_demo/src/usb_dfu.rs
Normal file
157
tflite_demo/src/usb_dfu.rs
Normal file
@ -0,0 +1,157 @@
|
||||
use crate::Irqs;
|
||||
use core::fmt::Write;
|
||||
use defmt::{info, unwrap};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_nrf::peripherals::USBD;
|
||||
use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect};
|
||||
use embassy_nrf::usb::{Driver, Instance};
|
||||
use embassy_nrf::{pac, peripherals};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
use embassy_usb::driver::EndpointError;
|
||||
use embassy_usb::{Builder, Config};
|
||||
use heapless::String;
|
||||
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
const MAGIC_REBOOT_MESSAGE: &str = "bootloader";
|
||||
|
||||
type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>;
|
||||
|
||||
/// Creates a usb serial device.
|
||||
/// Sending it [MAGIC_REBOOT_MESSAGE] will reboot the device
|
||||
/// into serial-only-dfu mode.
|
||||
pub fn setup_dfu_over_usb(spawner: &Spawner, usbd: USBD) {
|
||||
spawner.spawn(dfu_over_usb(usbd, *spawner)).unwrap();
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn dfu_over_usb(usbd: USBD, spawner: Spawner) {
|
||||
pac::CLOCK.tasks_hfclkstart().write_value(1);
|
||||
while pac::CLOCK.events_hfclkstarted().read() != 1 {}
|
||||
|
||||
// Create the driver, from the HAL.
|
||||
let driver = Driver::new(usbd, Irqs, HardwareVbusDetect::new(Irqs));
|
||||
|
||||
// Create embassy-usb Config
|
||||
let mut config = Config::new(0xc0de, 0xcafe);
|
||||
config.manufacturer = Some("Embassy");
|
||||
config.product = Some("USB-serial example");
|
||||
config.serial_number = Some("12345678");
|
||||
config.max_power = 100;
|
||||
config.max_packet_size_0 = 64;
|
||||
|
||||
// Create embassy-usb DeviceBuilder using the driver and config.
|
||||
// It needs some buffers for building the descriptors.
|
||||
let mut config_descriptor = [0; 256];
|
||||
let mut bos_descriptor = [0; 256];
|
||||
let mut msos_descriptor = [0; 256];
|
||||
let mut control_buf = [0; 64];
|
||||
|
||||
let mut state = State::new();
|
||||
|
||||
let mut builder = Builder::new(
|
||||
driver,
|
||||
config,
|
||||
&mut config_descriptor,
|
||||
&mut bos_descriptor,
|
||||
&mut msos_descriptor,
|
||||
&mut control_buf,
|
||||
);
|
||||
|
||||
// Create classes on the builder.
|
||||
let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
|
||||
|
||||
// Build the builder.
|
||||
let mut usb = builder.build();
|
||||
|
||||
// Run the USB device.
|
||||
let usb_fut = usb.run();
|
||||
|
||||
// Do stuff with the class!
|
||||
// let reboot_fut = async {
|
||||
// loop {
|
||||
// class.wait_connection().await;
|
||||
// let _ = reboot_on_magic_message(&mut class).await;
|
||||
// }
|
||||
// };
|
||||
|
||||
let print_fut = async {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
};
|
||||
|
||||
join(usb_fut, print_fut).await;
|
||||
}
|
||||
|
||||
struct Disconnected {}
|
||||
|
||||
impl From<EndpointError> for Disconnected {
|
||||
fn from(val: EndpointError) -> Self {
|
||||
match val {
|
||||
EndpointError::BufferOverflow => panic!("Buffer overflow"),
|
||||
EndpointError::Disabled => Disconnected {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn reboot_on_magic_message<'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];
|
||||
|
||||
if data == MAGIC_REBOOT_MESSAGE.as_bytes() {
|
||||
// Reboot the controller in DFU mode.
|
||||
// The magic number has been taken from the arduino bootloader:
|
||||
// https://github.com/mike1808/PIO_SEEED_Adafruit_nRF52_Arduino/blob/master/cores/nRF5/wiring.c#L26
|
||||
let dfu_magic_serial_only_reset = 0x4E;
|
||||
pac::POWER
|
||||
.gpregret()
|
||||
.write(|w| w.0 = dfu_magic_serial_only_reset);
|
||||
cortex_m::peripheral::SCB::sys_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn write_task(mut class: CdcAcmClass<'static, MyDriver>) {
|
||||
let mut count = 1;
|
||||
loop {
|
||||
class.wait_connection().await;
|
||||
info!("Connected");
|
||||
|
||||
let mut data = String::<32>::new();
|
||||
if write!(data, "Count: {}\r\n", count).is_ok() {
|
||||
if let Err(e) = class.write_packet(data.as_bytes()).await {
|
||||
info!("Failed to write to serial console: {:?}", e);
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
|
||||
// Add a delay of 1 second
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
info!("Disconnected");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user