Compare commits

...

10 Commits

Author SHA1 Message Date
e1cb93e8d0
update 2024-05-01 23:14:31 -04:00
cc1c3facf3
update 2024-05-01 17:17:53 -04:00
5567293f0c
update 2024-05-01 16:44:51 -04:00
2aad8b9f01
update 2024-04-28 14:22:26 -04:00
194b15fc39
update 2024-04-27 18:16:47 -04:00
2b7098f3fc
update main 2024-04-26 16:46:38 -04:00
50dc033fa7
update 2024-04-25 18:49:55 -04:00
aba4e78514
clean code 2024-04-24 09:23:58 -04:00
9f32a4ec9b
clean code 2024-04-23 16:18:41 -04:00
321983b9e3
write success? 2024-04-23 12:16:31 -04:00
11 changed files with 459 additions and 901 deletions

View File

@ -1,12 +1,6 @@
[target.thumbv8m.main-none-eabihf]
runner = "probe-rs run --chip STM32U575ZITxQ"
[build] [build]
target = "thumbv8m.main-none-eabihf" target = "thumbv8m.main-none-eabihf"
#rustflags = ["-C", "link-arg=-Tlink.x"]
[target.thumbv8m.main-none-eabihf]
runner = "probe-rs run --chip STM32U5A5ZJTx"
# runner = "probe-rs run --chip STM32U575ZITx"
# rustflags = ["-C", "link-arg=-Tlink.x"]
[env] [env]
DEFMT_LOG = "trace" DEFMT_LOG = "info"

6
.vscode/launch.json vendored
View File

@ -2,7 +2,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"preLaunchTask": "rust: cargo build", // "preLaunchTask": "rust: cargo build",
"type": "probe-rs-debug", "type": "probe-rs-debug",
"request": "launch", "request": "launch",
"name": "probe_rs sd_cam launch example", "name": "probe_rs sd_cam launch example",
@ -14,7 +14,7 @@
"runtimeExecutable": "probe-rs", "runtimeExecutable": "probe-rs",
"runtimeArgs": ["dap-server"], "runtimeArgs": ["dap-server"],
//!MODIFY //!MODIFY
"chip": "STM32U5A5ZJTx", "chip": "STM32U575ZITxQ",
"flashingConfig": { "flashingConfig": {
"flashingEnabled": true, "flashingEnabled": true,
"haltAfterReset": false, "haltAfterReset": false,
@ -27,7 +27,7 @@
{ {
"coreIndex": 0, "coreIndex": 0,
//!MODIFY //!MODIFY
"programBinary": "/home/zong/Code/u5_example/target/thumbv8m.main-none-eabihf/debug/usb_hs", "programBinary": "/home/zong/Code/u5_example/target/thumbv8m.main-none-eabihf/debug/u5_example",
//!MODIFY //!MODIFY
"svdFile": "stm32u5a5.svd", "svdFile": "stm32u5a5.svd",
"rttEnabled": true "rttEnabled": true

6
.vscode/taks.json vendored
View File

@ -6,13 +6,15 @@
"command": "build", "command": "build",
"args": [ "args": [
"--bin", "--bin",
"usb_hs" "u5_example",
"--features",
"stm32u575zi"
], ],
"problemMatcher": [ "problemMatcher": [
"$rustc" "$rustc"
], ],
"group": "build", "group": "build",
"label": "rust: cargo build", "label": "rust: cargo build with feature",
"options": { "options": {
"env": { "env": {
"DEFMT_LOG": "info" "DEFMT_LOG": "info"

63
Cargo.lock generated
View File

@ -2,6 +2,24 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aligned"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923"
dependencies = [
"as-slice",
]
[[package]]
name = "as-slice"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
dependencies = [
"stable_deref_trait",
]
[[package]] [[package]]
name = "bare-metal" name = "bare-metal"
version = "0.2.5" version = "0.2.5"
@ -50,9 +68,9 @@ dependencies = [
[[package]] [[package]]
name = "cortex-m-rt" name = "cortex-m-rt"
version = "0.7.3" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d"
dependencies = [ dependencies = [
"cortex-m-rt-macros", "cortex-m-rt-macros",
] ]
@ -95,7 +113,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
@ -106,7 +124,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
@ -139,7 +157,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
@ -173,7 +191,7 @@ dependencies = [
[[package]] [[package]]
name = "eb_cmds" name = "eb_cmds"
version = "0.1.0" version = "0.1.0"
source = "git+ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git#49d7eaf9ecdfa207a1afb23abf73e6a8c8459ea7" source = "git+ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git#3890db9dd1399d1ccf78dedcfdd4efa9e0b91c35"
[[package]] [[package]]
name = "embassy-executor" name = "embassy-executor"
@ -194,7 +212,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
@ -445,9 +463,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.80" version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -493,22 +511,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.197" version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
@ -555,9 +573,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.59" version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -566,28 +584,30 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.58" version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.58" version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.59", "syn 2.0.60",
] ]
[[package]] [[package]]
name = "u5-lib" name = "u5-lib"
version = "0.1.0" version = "0.1.0"
source = "git+ssh://gitea@git.ggeta.com:2002/guangzong/u5_new.git?rev=36dfec969e#36dfec969e0b2a455fbfa29b3b4d0194ac864b63"
dependencies = [ dependencies = [
"aligned",
"cortex-m", "cortex-m",
"cortex-m-rt", "cortex-m-rt",
"critical-section", "critical-section",
@ -611,6 +631,7 @@ dependencies = [
name = "u5_example" name = "u5_example"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aligned",
"cortex-m", "cortex-m",
"cortex-m-rt", "cortex-m-rt",
"defmt", "defmt",

View File

@ -8,29 +8,19 @@ edition = "2021"
# name = "i2c" # name = "i2c"
# path = "src/bin/i2c.rs" # path = "src/bin/i2c.rs"
# [net]
# git-fetch-with-cli = true
[dependencies] [dependencies]
# cortex-m = "0.7.0"
cortex-m = { version = "0.7.7" } cortex-m = { version = "0.7.7" }
#u5-lib = { git = "ssh://gitea@git.ggeta.com:2002/guangzong/u5_new.git", features = [ aligned = "0.4.2"
# "stm32u5a5qj", #u5-lib = { path = "../u5_new", features = ["utils"] }
#], default-features = false, branch = "dev" } u5-lib = {git = "ssh://gitea@git.ggeta.com:2002/guangzong/u5_new.git", features = ["utils"], rev= "36dfec969e"}
u5-lib = { path="../u5_new", features = [
"stm32u5a5qj",
], default-features = false }
eb_cmds = { git = "ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git" } eb_cmds = { git = "ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git" }
#critical-section = "1.1.2"
defmt = "0.3.6" defmt = "0.3.6"
defmt-rtt = { version = "0.4.0" } defmt-rtt = { version = "0.4.0" }
#defmt-itm = { version = "0.3.0" }
futures = { version = "0.3.17", default-features = false, fetures = [ futures = { version = "0.3.17", default-features = false, fetures = [
"async-await", "async-await",
] } ] }
cortex-m-rt = { version = "0.7.3" } cortex-m-rt = { version = "0.7.3", default-features = false }
[dependencies.embassy-usb] [dependencies.embassy-usb]
@ -51,3 +41,8 @@ rev = "35f284e"
[profile.dev] [profile.dev]
opt-level = 1 opt-level = 1
debug = true debug = true
[features]
stm32u575zi = ["u5-lib/stm32u575zi"]
stm32u5a5zj = ["u5-lib/stm32u5a5zj"]
#default = ["stm32u5a5zj"]

View File

@ -1,21 +1,34 @@
use std::path::Path;
use std::env;
use std::fs::File;
use std::io::Write;
fn main() { fn main() {
// println!("cargo:rustc-link-arg-bins=-Tmemory.x"); // println!("cargo:rustc-link-arg-bins=-Tmemory.x"); // feagure in cortex-m-rt
println!("cargo:rustc-link-arg-bins=--nmagic"); println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
// enable cfg sdmmc let runner = if cfg!(feature = "stm32u5a5zj") {
// println!("cargo:rustc-cfg=sdmmc"); "probe-rs run --chip STM32U5A5ZJTx"
// for (key, _value) in std::env::vars() { } else if cfg!(feature = "stm32u575zi") {
// // Check if the current environment variable is a feature that starts with "STM32U5" "probe-rs run --chip STM32U575ZITxQ"
// if key.starts_with("CARGO_FEATURE_STM32U575") { } else {
// // If found, print the cargo directive to set the `stm32u5` cfg flag panic!("No target specified")
// println!("cargo:rustc-cfg=stm32u575"); };
// break; // Exit the loop once the first matching feature is found let config_path = Path::new(".cargo").join("config.toml");
// } let mut config_file = File::create(&config_path).expect("Failed to create config file");
// if key.starts_with("CARGO_FEATURE_STM32U5A5") {
// // If found, print the cargo directive to set the `stm32u5` cfg flag writeln!(config_file, "[target.thumbv8m.main-none-eabihf]").expect("Failed to write to config file");
// println!("cargo:rustc-cfg=stm32u5a5"); writeln!(config_file, "runner = \"{}\"", runner).expect("Failed to write to config file");
// break; // Exit the loop once the first matching feature is found
// } writeln!(config_file, "[build]").expect("Failed to write to config file");
// } writeln!(config_file, "target = \"thumbv8m.main-none-eabihf\"").expect("Failed to write to config file");
writeln!(config_file, "[env]").expect("Failed to write to config file");
writeln!(config_file, "DEFMT_LOG = \"info\"").expect("Failed to write to config file");
// writeln!(config_file, "DEFMT_TIMESTAMP = \"1\"").expect("Failed to write to config file");
env::set_var("CARGO_RUNNER", runner);
} }

View File

@ -1,6 +1,6 @@
MEMORY MEMORY
{ {
FLASH : ORIGIN = 0x08000000, LENGTH = 4096K FLASH : ORIGIN = 0x08000000, LENGTH = 4096K
RAM : ORIGIN = 0x20000000, LENGTH = 2496K /* 2514K? */ RAM : ORIGIN = 0x20000000, LENGTH = 768K /* 2514K?, 2496K for u5a5 */
OTP : ORIGIN = 0x0bfa0000, LENGTH = 512 OTP : ORIGIN = 0x0bfa0000, LENGTH = 512
} }

315
src/bin/ebutton_cam.rs Normal file
View File

@ -0,0 +1,315 @@
#![feature(noop_waker)]
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use core::panic::PanicInfo;
use aligned::Aligned;
use defmt::println;
use defmt_rtt as _;
use eb_cmds::Command;
use embassy_executor::Spawner;
use u5_lib::{
*,
usb_otg_hs::{ control_pipe::setup_process, mod_new::{cdc_acm_ep2_read, cdc_acm_ep2_write} },
gpio::{SDMMC2_CMD_PD7, SDMMC2_D0_PB14},
clock::delay_ms,
com_interface::ComInterface,
};
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
defmt::info!("panic");
defmt::error!(
"Location file name: {:?}, line: {:?}, col: {:?}",
_info.location().unwrap().file(),
_info.location().unwrap().line(),
_info.location().unwrap().column()
);
loop {}
}
fn setup_camera() -> (gpio::GpioPort, i2c::I2c) {
let cam_down = gpio::PD13;
let rst = gpio::PD12;
cam_down.setup();
rst.setup();
clock::set_mco(
gpio::GPIO_MCO_PA8,
clock::Mcosel::HSI48,
clock::Mcopre::DIV2,
); // clock. which use PA8 as clock output
let mut i2c = i2c::I2c::new(i2c::I2cConfig::new(
2,
100_000,
gpio::I2C2_SDA_PF0,
gpio::I2C2_SCL_PF1,
)).unwrap();
delay_ms(1);
cam_down.set_low();
rst.set_high();
delay_ms(10);
// camera::setup_camera(&mut i2c);
defmt::info!("start setup camera");
u5_lib::drivers::ov5640::setup_camera(&mut i2c, &cam_down, &rst);
// cam_down.set_high();
(cam_down, i2c)
}
fn setup_leds() -> (gpio::GpioPort, gpio::GpioPort, gpio::GpioPort) {
let green: gpio::GpioPort = gpio::PD14;
let orange: gpio::GpioPort = gpio::PD15;
let blue: gpio::GpioPort = gpio::PD10;
green.setup();
orange.setup();
blue.setup();
(green, orange, blue)
}
fn setup_sd() -> sdmmc::SdInstance {
let mut sd = sdmmc::SdInstance::new(sdmmc::SDMMC2);
sd.init(
gpio::SDMMC2_CK_PD6,
SDMMC2_CMD_PD7,
SDMMC2_D0_PB14,
SDMMC2_D1_PB15,
SDMMC2_D2_PB3,
SDMMC2_D3_PB4,
SDMMC2_D4_PB8,
SDMMC2_D5_PB9,
SDMMC2_D6_PC6,
SDMMC2_D7_PC7,
);
sd
}
fn set_dcmi() -> dcmi::DcmiPort {
let dcmi = dcmi::DCMI;
dcmi.init(
gpio::DCMI_D0_PA9, // todo: update the pin
gpio::DCMI_D1_PA10,
gpio::DCMI_D2_PE0,
gpio::DCMI_D3_PE1,
gpio::DCMI_D4_PE4,
gpio::DCMI_D5_PB6,
gpio::DCMI_D6_PE5,
gpio::DCMI_D7_PE6,
gpio::DCMI_HSYNC_PA4,
gpio::DCMI_VSYNC_PB7,
gpio::DCMI_PIXCLK_PD9,
);
dcmi
}
static mut PIC_BUF: Aligned<aligned::A4,[u8; 1_600_000]> = Aligned([0u8; 1_600_000]);
// static mut pic_buf: Aligned<[u8; 300_000_000]> = Aligned([0; 300_000_000]);
// #[embassy_executor::main]
#[task]
async fn async_main(spawner: Spawner) {
clock::init_clock(false, true, 26_000_000, true, clock::ClockFreqs::KernelFreq4Mhz);
// low_power::no_deep_sleep_request();
// let (green, blue, blue) = setup_leds();
let (green, orange, _blue) = setup_leds();
//
let (cam_down, mut i2c, sd, dcmi) =
// // todo: check functions, one of them may take too much time.
clock::hclk_request(clock::ClockFreqs::KernelFreq160Mhz, || {
let sd = setup_sd();
defmt::info!("sd init finished!");
let (cam_down, i2c) = setup_camera();
defmt::info!("camera init finished!");
let dcmi = set_dcmi();
// cam_down.set_high();
(cam_down, i2c, sd, dcmi)
});
spawner.spawn(pwr::vddusb_monitor_up()).unwrap();
spawner.spawn(setup_process()).unwrap();
spawner.spawn(usb_task()).unwrap();
spawner.spawn(btn()).unwrap();
// green.set_high();
// blue.set_high();
// orange.set_high();
// loop {
// exti::EXTI2_PB2.wait_for_raising().await;
// green.toggle();
// }
let mut power_on = false;
loop {
if !power_on {
let val = POWER_SIGNAL.wait().await;
if val {
defmt::info!("power on");
power_on = true;
}
} else {
if POWER_SIGNAL.signaled() {
let val = POWER_SIGNAL.wait().await;
power_on = val;
}
}
if !power_on {
continue;
}
green.toggle();
// deep sleep is not allowed
clock::hclk_request_async(clock::ClockFreqs::KernelFreq160Mhz, || async {
low_power::run_no_deep_sleep_async(|| async {
unsafe {
defmt::info!("start capture, ########################");
camera::capture(&cam_down, &mut i2c, &dcmi, &mut PIC_BUF[..]).await;
defmt::info!("finish capture, ########################");
camera::save_picture(&mut PIC_BUF[..], &sd).await;
defmt::debug!("finish save picture, ##################");
orange.toggle();
}
})
.await;
})
.await;
}
}
use low_power::Executor;
#[cortex_m_rt::entry]
fn main() -> ! {
Executor::take().run(|spawner| {
spawner.spawn(async_main(spawner)).unwrap();
});
}
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::signal::Signal;
use u5_lib::gpio::{SDMMC2_D1_PB15, SDMMC2_D2_PB3, SDMMC2_D3_PB4, SDMMC2_D4_PB8, SDMMC2_D5_PB9, SDMMC2_D6_PC6, SDMMC2_D7_PC7};
// static mut POWER_STATE: bool = false;
static POWER_SIGNAL: Signal<CriticalSectionRawMutex, bool> = Signal::new();
#[embassy_executor::task]
async fn btn() {
let _last_time: (u8, u8, u8) = (0, 0, 0);
defmt::info!("waiting for btn");
unsafe {
static mut POWER_STATE: bool = false;
loop {
exti::EXTI2_PB2.wait_for_raising().await;
defmt::info!("btn pressed");
let green: gpio::GpioPort = gpio::PD14;
green.toggle();
POWER_STATE = !POWER_STATE;
POWER_SIGNAL.signal(POWER_STATE);
}
}
}
// todo: these should be rewrite
const IMG_START_BLOCK: u32 = 10;
const IMG_SIZE: u32 = 2000;
// 2000 block = 2000 * 512 = 1M
const SIZE_BLOCK: u32 = 1; // first block store the number of image files
#[embassy_executor::task]
async unsafe fn usb_task() {
defmt::info!("start usb handler");
let sd = setup_sd();
loop {
// todo: in read function, we need to wait for usbepen to be set.
let (ret, len) = cdc_acm_ep2_read().await;
// cdc_acm_ep2_write(&ret[0..len]).await;
// continue;
let command = eb_cmds::Command::from_array(&ret[..]);
if command.is_err() {
continue;
}
let command = command.unwrap();
match command {
Command::SetTim(year, month, day, hour, minute, second, period) => {
// rtc::set_time(year, month, day, hour, minute, second, period);
rtc::setup(
year,
month,
day,
hour,
minute,
second,
period,
rtc::RtcSource::LSE,
);
let response = eb_cmds::Response::SetTim(0);
let (buf, len) = response.to_array();
// class.write_packet(&buf[..len]).await.unwrap();
cdc_acm_ep2_write(&buf[0..len]).await;
}
Command::GetTim => {
let date = rtc::get_date();
let time = rtc::get_time();
let response =
eb_cmds::Response::GetTim(date.0, date.1, date.2, time.0, time.1, time.2);
let (buf, len) = response.to_array();
// class.write_packet(&buf[..len]).await.unwrap();
cdc_acm_ep2_write(&buf[0..len]).await;
}
Command::GetPic(id) => {
let start_block = (id + IMG_START_BLOCK) * IMG_SIZE;
let _ = sd.read_single_block_async(&mut PIC_BUF[..], start_block).await.unwrap();
// pic_buf[0] = (pic_end >> 24) as u8;
// pic_buf[1] = ((pic_end >> 16) & 0xff) as u8;
// pic_buf[2] = ((pic_end >> 8) & 0xff) as u8;
// pic_buf[3] = (pic_end & 0xff) as u8;
// get the picture length from the first 4 bytes
let pic_end = ((PIC_BUF[0] as u32) << 24)
| ((PIC_BUF[1] as u32) << 16)
| ((PIC_BUF[2] as u32) << 8)
| (PIC_BUF[3] as u32);
let _ = sd.read_multiple_blocks_async(&mut PIC_BUF[..], start_block, IMG_SIZE).await;
// only allow to send 30k data each time
for i in 0..50 {
let begin = i * 30_000;
let begin = core::cmp::max(16, begin);
let mut end = (i + 1) * 30_000;
if end > pic_end as usize {
end = pic_end as usize;
}
cdc_acm_ep2_write(&PIC_BUF[begin..end]).await;
if end == pic_end as usize {
break;
}
}
}
Command::GetPicNum => {
let mut buf:Aligned<aligned::A4, [u8; 512]> = Aligned([0u8; 512]);
sd.read_single_block_async(&mut buf[..], SIZE_BLOCK).await.unwrap();
let num = ((buf[0] as u32) << 24)
| ((buf[1] as u32) << 16)
| ((buf[2] as u32) << 8)
| (buf[3] as u32);
// ebcmd::Response::GetPicNum(num)
let res = eb_cmds::Response::GetPicNum(num);
let (buf, len) = res.to_array();
let mut buf_align:Aligned<aligned::A4, [u8; 64]> = Aligned([0u8; 64]);
for i in 0..len {
buf_align[i] = buf[i];
}
// cdc_acm_ep2_write(&buf[0..len]).await;
cdc_acm_ep2_write(&buf_align[..len]).await;
}
Command::ClearPic => {
let mut buf:Aligned<aligned::A4, [u8; 512]> = Aligned([0u8; 512]);
sd.write_single_block_async(&mut buf[..], SIZE_BLOCK).await;
}
}
}
}

View File

@ -2,34 +2,22 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
use core::default::Default;
use core::panic::PanicInfo; use core::panic::PanicInfo;
use defmt_rtt as _; use defmt_rtt as _;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_usb::{
class::cdc_acm::{CdcAcmClass, State}, use u5_lib::{
driver::EndpointError, usb_otg_hs::mod_new::{cdc_acm_ep2_read },
Builder, *,
}; };
use futures::future::join; use u5_lib::usb_otg_hs::control_pipe::setup_process;
// use stm32_metapac; use u5_lib::usb_otg_hs::power::power_up_init;
use u5_lib::{pwr::vddusb_monitor_up, usb_otg_hs::mod_new::{power_up_init, setup_process}, *};
// define defmt format
#[derive(defmt::Format)]
pub enum UsbError {
BufferOverflow,
Disabled,
}
const GREEN: gpio::GpioPort = gpio::PB7; const GREEN: gpio::GpioPort = gpio::PB7;
#[embassy_executor::main] #[embassy_executor::main]
async fn main(spawner: Spawner) { async fn main(spawner: Spawner) {
clock::init_clock(false, true, true, clock::ClockFreqs::KernelFreq160Mhz); clock::init_clock(false, true, true, clock::ClockFreqs::KernelFreq4Mhz);
low_power::no_deep_sleep_request(); low_power::no_deep_sleep_request();
GREEN.setup(); GREEN.setup();
// low_power::no_deep_sleep_request(); // low_power::no_deep_sleep_request();
@ -37,23 +25,35 @@ async fn main(spawner: Spawner) {
defmt::info!("setup led finished!"); defmt::info!("setup led finished!");
// spawner.spawn(btn()).unwrap(); // spawner.spawn(btn()).unwrap();
// spawner.spawn(pwr::vddusb_monitor_up()).unwrap(); // spawner.spawn(pwr::vddusb_monitor_up()).unwrap();
// spawner.spawn(usb_task()).unwrap();
// use some delay to wait for usb power up // use some delay to wait for usb power up
pwr::vddusb_monitor_up_tmp(); pwr::vddusb_monitor_up_tmp();
power_up_init(); power_up_init();
defmt::info!("vddusb monitor finished!"); defmt::info!("vddusb monitor finished!");
//
spawner.spawn( setup_process()).unwrap();
spawner.spawn(setup_process()).unwrap();
defmt::info!("usb init finished!"); defmt::info!("usb init finished!");
spawner.spawn(usb_task()).unwrap();
loop { loop {
exti::EXTI13_PC13.wait_for_raising().await; exti::EXTI13_PC13.wait_for_raising().await;
GREEN.toggle(); GREEN.toggle();
} }
} }
#[embassy_executor::task]
async fn usb_task() {
// the maximum size of the command is 64 bytes
defmt::info!("start usb handler");
// wait for end of suspend here
loop {
// todo: in read function, we need to wait for usbepen to be set.
let (ret, len) = cdc_acm_ep2_read().await;
defmt::info!("read ret: {:?}", &ret[0..len]);
}
}
#[panic_handler] #[panic_handler]
fn panic(_info: &PanicInfo) -> ! { fn panic(_info: &PanicInfo) -> ! {
defmt::info!("panic"); defmt::info!("panic");
@ -66,92 +66,3 @@ fn panic(_info: &PanicInfo) -> ! {
loop {} loop {}
} }
#[embassy_executor::task]
pub async fn usb_task() {
let _ep_out_buffer = [0u8; 256];
let mut config = usb_otg_hs::Config::default();
config.vbus_detection = false;
let driver = usb_otg_hs::Driver::new(config, gpio::USB_DM_PA11, gpio::USB_DP_PA12);
// // Create embassy-usb Config
let mut config = embassy_usb::Config::new(0xaaaa, 0xefba);
config.manufacturer = Some("ggeta");
config.product = Some("USB-serial example");
config.serial_number = Some("12345678");
config.device_class = 0xEF;
config.device_sub_class = 0x02;
config.device_protocol = 0x01;
config.composite_with_iads = true;
let mut device_descriptor = [0; 512];
let mut config_descriptor = [0; 512];
let mut bos_descriptor = [0; 512];
let mut control_buf = [0; 64];
let mut msos_descriptor = [0; 512];
let mut state = State::new();
// USART1.send("starting usb task new!\n\n".as_bytes());
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,
&mut control_buf,
);
let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
// USART1.send("declare class success!\n".as_bytes());
// Build the builder.
let mut usb = builder.build();
// USART1.send("success!\n".as_bytes());
let usb_fut = usb.run(); // Run the USB device.
let handler_fut = async {
loop {
class.wait_connection().await;
defmt::info!("connected");
let _ = usb_handler(&mut class).await;
defmt::info!("disconnected");
}
};
// USART1.send("start usb task success!\n".as_bytes());
join(usb_fut, handler_fut).await; // Run everything concurrently.
}
struct Disconnected {}
impl From<EndpointError> for Disconnected {
fn from(val: EndpointError) -> Self {
match val {
EndpointError::BufferOverflow => panic!("Buffer overflow"),
EndpointError::Disabled => Disconnected {},
}
}
}
async fn usb_handler<'d>(
class: &mut CdcAcmClass<'d, usb_otg_hs::Driver>,
) -> Result<(), Disconnected> {
let mut buf: [u8; 128] = [0; 128];
// the maximum size of the command is 64 bytes
defmt::info!("start usb handler");
loop {
// select(future1, future2)
let ret = class.read_packet(&mut buf).await;
match ret {
Ok(n) => {
defmt::info!("read {} bytes", n);
class.write_packet(&buf[0..n]).await.unwrap();
}
Err(e) => {
defmt::info!("error: {:?}", e);
return Err(e.into());
}
}
// class.write_packet(&buf[0..n]).await.unwrap();
}
}

View File

@ -3,297 +3,51 @@
#![no_main] #![no_main]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
use core::default::Default;
use core::panic::PanicInfo;
use cortex_m::asm::delay;
use defmt_rtt as _; use defmt_rtt as _;
use eb_cmds::Command;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_usb::{
class::cdc_acm::{CdcAcmClass, State},
driver::EndpointError,
Builder,
};
use futures::future::join;
use u5_lib::com_interface::ComInterface;
use u5_lib::{clock::delay_ms, i2c::I2cMessage};
use u5_lib::{ use u5_lib::{
gpio::{SDMMC2_CMD_PD7, SDMMC2_D0_PB14},
*, *,
low_power::{Executor, no_deep_sleep_request},
clock, clock::delay_ms, com_interface::ComInterface, exti, gpio, task,
i2c, i2c::I2c,
}; };
#[panic_handler] fn i2c_init() -> (I2c, I2c) {
fn panic(_info: &PanicInfo) -> ! { let i2c_config_plus = i2c::I2cConfig::new(1, 100_000, gpio::I2C1_SCL_PB6, gpio::I2C1_SDA_PB3);
defmt::info!("panic"); let i2c_plus = I2c::new(i2c_config_plus).unwrap();
defmt::error!( let i2c_config_minus = i2c::I2cConfig::new(2, 100_000, gpio::I2C2_SCL_PB13, gpio::I2C2_SDA_PB14);
"Location file name: {:?}, line: {:?}, col: {:?}", let i2c_minus = I2c::new(i2c_config_minus).unwrap();
_info.location().unwrap().file(), (i2c_plus, i2c_minus)
_info.location().unwrap().line(),
_info.location().unwrap().column()
);
loop {}
} }
fn setup_camera() -> (gpio::GpioPort, i2c::I2c) {
let cam_down = gpio::PD13;
cam_down.setup();
let rst = gpio::PD12;
rst.setup();
cam_down.set_high();
rst.set_low();
clock::set_mco(
gpio::GPIO_MCO_PA8,
clock::Mcosel::HSI48,
clock::Mcopre::DIV2,
); // clock. which use PA8 as clock output
// cam_down.set_high();
delay_ms(5);
cam_down.set_low();
delay_ms(5);
rst.set_high();
// wait for short time
delay_ms(50);
let mut i2c = i2c::I2c::new(i2c::I2cConfig::new(
2,
100_000,
gpio::I2C2_SDA_PF0,
gpio::I2C2_SCL_PF1,
))
.unwrap();
delay_ms(1);
camera::setup_camera(&mut i2c);
delay_ms(500);
cam_down.set_high();
(cam_down, i2c)
}
const ICM20948_ADDR: u16 = 0x68 << 1;
const ICM20948_WHO_AM_I: u8 = 0x00;
const ICM20948_GYRO_CONFIG_1: u8 = 0x01;
const ICM20948_GYRO_CONFIG_2: u8 = 0x02;
const ICM20948_USER_CTRL: u8 = 0x03;
const ICM20948_LP_CONFIG: u8 = 0x05;
const ICM20948_PWR_MGMT_1: u8 = 0x06;
const ICM20948_PWR_MGMT_2: u8 = 0x07;
const ICM20948_ACCEL_CONFIG: u8 = 0x14;
const ICM20948_ACCEL_CONFIG2: u8 = 0x15;
const ICM20948_ACC_XOUT_H: u8 = 0x2d;
const ICM20948_ACC_XOUT_L: u8 = 0x2e;
const ICM20948_ACC_YOUT_H: u8 = 0x2f;
const ICM20948_ACC_YOUT_L: u8 = 0x30;
const ICM20948_ACC_ZOUT_H: u8 = 0x31;
const ICM20948_ACC_ZOUT_L: u8 = 0x32;
const ICM20948_BANK_SEL: u8 = 0x7f;
fn read_imu(i2c: &mut i2c::I2c) {
let mut buf = [0u8; 6];
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_ACC_XOUT_H],
};
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_XOUT_H], &mut buf[0..1])
.unwrap();
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_XOUT_L], &mut buf[1..2])
.unwrap();
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_YOUT_H], &mut buf[2..3])
.unwrap();
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_YOUT_L], &mut buf[3..4])
.unwrap();
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_ZOUT_H], &mut buf[4..5])
.unwrap();
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_ACC_ZOUT_L], &mut buf[5..6])
.unwrap();
}
fn setup_imu(i2c: &mut i2c::I2c) {
// pa3 to ground
let fsync = gpio::PA3;
fsync.setup();
fsync.set_low();
defmt::info!("start setup imu");
// icm-20948
let mut buf = [0u8; 1];
i2c.write_read(ICM20948_ADDR, &mut [ICM20948_WHO_AM_I], &mut buf)
.unwrap(); // read who am i
defmt::info!("imu who am i: {:?}", buf[0]);
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_PWR_MGMT_1, 0x00],
};
i2c.send(&message).unwrap();
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_PWR_MGMT_1, 0x80], // reset the device
};
// config the accelerometer
i2c.send(&message).unwrap();
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_ACCEL_CONFIG, 0x18], // cofig accelerometer full scale range to 16g
};
i2c.send(&message).unwrap();
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_ACCEL_CONFIG2, 0x00], // disable accelerometer low pass filter
};
i2c.send(&message).unwrap();
// config the gyroscope
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_GYRO_CONFIG_1, 0x18], // config gyroscope full scale range to 2000dps
};
i2c.send(&message).unwrap();
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_GYRO_CONFIG_2, 0x00], // disable gyroscope low pass filter
};
i2c.send(&message).unwrap();
// config magnetometer
// todo: add magnetometer config
//
// todo: configure samle rate (all sensors at 100Hz)
//
// Enable sensor
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_PWR_MGMT_2, 0x00], // enable the device
};
i2c.send(&message).unwrap();
let message = I2cMessage {
addr: ICM20948_ADDR,
data: &mut [ICM20948_PWR_MGMT_1, 0x09], // enable the i2c master
};
i2c.send(&message).unwrap();
}
fn setup_led() -> gpio::GpioPort {
let green: gpio::GpioPort = gpio::PD15;
green.setup();
green
}
fn setup_sd() -> sdmmc::SdInstance {
let mut sd = sdmmc::SdInstance::new(sdmmc::SDMMC2);
sd.init(
gpio::SDMMC2_CK_PD6,
SDMMC2_CMD_PD7,
SDMMC2_D0_PB14,
SDMMC2_D1_PB15,
SDMMC2_D2_PB3,
SDMMC2_D3_PB4,
SDMMC2_D4_PB8,
SDMMC2_D5_PB9,
SDMMC2_D6_PC6,
SDMMC2_D7_PC7,
);
sd
}
fn set_dcmi() -> dcmi::DcmiPort {
let dcmi = dcmi::DCMI;
dcmi.init(
gpio::DCMI_D0_PA9, // todo: updat the pin
gpio::DCMI_D1_PA10,
gpio::DCMI_D2_PE0,
gpio::DCMI_D3_PE1,
gpio::DCMI_D4_PE4,
gpio::DCMI_D5_PB6,
gpio::DCMI_D6_PE5,
gpio::DCMI_D7_PE6,
gpio::DCMI_HSYNC_PA4,
gpio::DCMI_VSYNC_PB7,
gpio::DCMI_PIXCLK_PD9,
);
dcmi
}
// #[embassy_executor::main]
#[task] #[task]
async fn async_main(spawner: Spawner) { async fn async_main(spawner: Spawner) {
// clock::init_clock(true, false, clock::ClockFreqs::KernelFreq4Mhz); // be careful, if the dbg is not enabled, but using deep sleep. This framework will not able to connect to chip.
// clock::init_clock(false, true, true, clock::ClockFreqs::KernelFreq160Mhz); // stm32cube programmer, stmcubeide can be used to program the chip, then this framework can be used to debug.
// cam_down.set_high(); clock::init_clock(false, true, 16_000_000, true, clock::ClockFreqs::KernelFreq4Mhz);
delay_ms(200); no_deep_sleep_request();
let green = setup_led(); defmt::info!("setup led finished!");
spawner.spawn(btn()).unwrap(); let red: gpio::GpioPort = gpio::PB7;
spawner.spawn(pwr::vddusb_monitor_up()).unwrap(); let green: gpio::GpioPort = gpio::PB8;
spawner.spawn(usb_task()).unwrap(); green.setup();
// init dcmi red.setup();
let (mut i2c_plus, mut i2c_minus) = i2c_init();
let (cam_down, mut i2c, sd, dcmi) = // let i2c_message = i2c::I2cMessage {
clock::hclk_request(clock::ClockFreqs::KernelFreq160Mhz, || { // addr: 0x68,
let sd = setup_sd(); // data: &mut [0x75],
defmt::info!("sd init finished!"); // };
let (cam_down, i2c) = setup_camera(); // i2c_plus.send(&i2c_message).unwrap();
defmt::info!("camera init finished!"); defmt::info!("i2c init finished!");
let dcmi = set_dcmi();
(cam_down, i2c, sd, dcmi)
});
setup_imu(&mut i2c);
defmt::info!("usb init finished!");
let mut power_on = false;
// let mut green = gpio::PD10;
gpio::PD10.setup();
gpio::PD14.setup();
gpio::PD15.setup();
// set high
gpio::PD10.set_high();
gpio::PD14.set_high();
gpio::PD15.set_high();
delay_ms(500);
gpio::PD10.set_low();
gpio::PD14.set_low();
gpio::PD15.set_low();
loop { loop {
if !power_on { // exti::EXTI13_PC13.wait_for_raising().await;
let val = POWER_SIGNAL.wait().await;
if val {
defmt::info!("power on");
power_on = true;
}
} else {
if POWER_SIGNAL.signaled() {
let val = POWER_SIGNAL.wait().await;
power_on = val;
}
}
if !power_on {
continue;
}
// exti::EXTI2_PB2.wait_for_raising().await;
// clock::init_clock(false, true, clock::ClockFreqs::KernelFreq160Mhz);
// delay_ms(1);
// rtc::rtc_interrupt().await;
green.toggle(); green.toggle();
let mut pic_buf = [0u8; 1_600_000]; red.toggle();
// deep sleep is not allowed delay_ms(500);
clock::hclk_request_async(clock::ClockFreqs::KernelFreq160Mhz, || async { defmt::info!("toggle leds");
low_power::run_no_deep_sleep_async(|| async {
defmt::info!("start capture, ########################");
camera::capture(&cam_down, &mut i2c, &dcmi, &mut pic_buf).await;
defmt::info!("finish capture, ########################");
camera::save_picture(&mut pic_buf, &sd).await;
defmt::info!("finish save picture, ########################");
})
.await;
})
.await;
} }
} }
use low_power::Executor;
#[cortex_m_rt::entry] #[cortex_m_rt::entry]
fn main() -> ! { fn main() -> ! {
@ -302,219 +56,3 @@ fn main() -> ! {
}); });
} }
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::signal::Signal;
use u5_lib::gpio::{
SDMMC2_D1_PB15, SDMMC2_D2_PB3, SDMMC2_D3_PB4, SDMMC2_D4_PB8, SDMMC2_D5_PB9, SDMMC2_D6_PC6,
SDMMC2_D7_PC7,
};
// static mut POWER_STATE: bool = false;
static POWER_SIGNAL: Signal<CriticalSectionRawMutex, bool> = Signal::new();
#[embassy_executor::task]
async fn btn() {
let _last_time: (u8, u8, u8) = (0, 0, 0);
defmt::info!("waiting for btn");
unsafe {
static mut POWER_STATE: bool = false;
loop {
exti::EXTI2_PB2.wait_for_raising().await;
defmt::info!("btn pressed");
let green: gpio::GpioPort = gpio::PD14;
green.toggle();
POWER_STATE = !POWER_STATE;
POWER_SIGNAL.signal(POWER_STATE);
}
}
}
#[embassy_executor::task]
pub async fn usb_task() {
let _ep_out_buffer = [0u8; 256];
let mut config = usb_otg_hs::Config::default();
config.vbus_detection = false;
let driver = usb_otg_hs::Driver::new(config, gpio::USB_DM_PA11, gpio::USB_DP_PA12);
// // Create embassy-usb Config
let mut config = embassy_usb::Config::new(0xaaaa, 0xefba);
config.manufacturer = Some("ggeta");
config.product = Some("USB-serial example");
config.serial_number = Some("12345678");
config.device_class = 0xEF;
config.device_sub_class = 0x02;
config.device_protocol = 0x01;
config.composite_with_iads = true;
let mut device_descriptor = [0; 512];
let mut config_descriptor = [0; 512];
let mut bos_descriptor = [0; 512];
let mut control_buf = [0; 64];
let mut msos_descriptor = [0; 512];
let mut state = State::new();
// USART1.send("starting usb task new!\n\n".as_bytes());
let mut builder = Builder::new(
driver,
config,
&mut device_descriptor,
&mut config_descriptor,
&mut bos_descriptor,
&mut msos_descriptor,
&mut control_buf,
);
let mut class = CdcAcmClass::new(&mut builder, &mut state, 64);
// Build the builder.
let mut usb = builder.build();
let usb_fut = usb.run(); // Run the USB device.
let handler_fut = async {
loop {
class.wait_connection().await;
defmt::info!("connected");
let _ = usb_handler(&mut class).await;
defmt::info!("disconnected");
}
};
// USART1.send("start usb task success!\n".as_bytes());
join(usb_fut, handler_fut).await; // Run everything concurrently.
}
struct Disconnected {}
impl From<EndpointError> for Disconnected {
fn from(val: EndpointError) -> Self {
match val {
EndpointError::BufferOverflow => panic!("Buffer overflow"),
EndpointError::Disabled => Disconnected {},
}
}
}
// todo: these should be rewrite
const IMG_START_BLOCK: u32 = 10;
const IMG_SIZE: u32 = 2000;
// 2000 block = 2000 * 512 = 1M
const SIZE_BLOCK: u32 = 1; // first block store the number of image files
async fn usb_handler<'d>(class: &mut CdcAcmClass<'d, usb_otg_hs::Driver>) -> Result<(), Disconnected> {
let mut in_buf: [u8; 128] = [0; 128];
// the maximum size of the command is 64 bytes
let sd = setup_sd();
defmt::info!("start usb handler");
loop {
// select(future1, future2)
let ret = class.read_packet(&mut in_buf).await;
let n = match ret {
Ok(n) => n,
Err(EndpointError::Disabled) => return Err(Disconnected {}),
Err(EndpointError::BufferOverflow) => panic!("Buffer overflow"),
};
let command = eb_cmds::Command::from_array(&in_buf[..n]);
match command {
Command::SetTim(year, month, day, hour, minute, second, period) => {
// rtc::set_time(year, month, day, hour, minute, second, period);
rtc::setup(
year,
month,
day,
hour,
minute,
second,
period,
rtc::RtcSource::LSE,
);
let response = eb_cmds::Response::SetTim(0);
let (buf, len) = response.to_array();
class.write_packet(&buf[..len]).await.unwrap();
}
Command::GetTim => {
let date = rtc::get_date();
let time = rtc::get_time();
let response =
eb_cmds::Response::GetTim(date.0, date.1, date.2, time.0, time.1, time.2);
let (buf, len) = response.to_array();
class.write_packet(&buf[..len]).await.unwrap();
}
Command::GetPic(id) => {
let mut buf = [0; 64];
buf[0] = 0x02;
let mut pic_buf = [0; 512];
let start_block = (id + IMG_START_BLOCK) * IMG_SIZE;
sd.read_single_block_async(&mut pic_buf, start_block)
.await
.unwrap();
// get the end of picture
let pic_end = ((pic_buf[0] as u32) << 24)
| ((pic_buf[1] as u32) << 16)
| ((pic_buf[2] as u32) << 8)
| (pic_buf[3] as u32);
let block_count: u32 = ((pic_end + 512 - 1) / 512) as u32;
let mut ordinal = 0;
let mut send_len: usize;
let mut res: eb_cmds::Response;
let mut start = 16;
loop {
if start >= pic_buf.len() {
break;
}
(ordinal, send_len, res) =
eb_cmds::Response::pic_res_from_data(id, ordinal, &pic_buf[start..]);
if send_len == 0 {
break;
}
start += send_len;
let (buf_tmp, len) = res.to_array();
class.write_packet(&buf_tmp[0..len]).await.unwrap();
// Timer::after(Duration::from_millis(100)).await;
// LED_BLUE.toggle();
}
// LED_GREEN.toggle();
for block in 1..block_count {
// sd.read_single_block(&mut buf, start_block + block).unwrap();
// let mut pic_buf = [0; 512]; // why without this line, the program not work?
sd.read_single_block_async(&mut pic_buf, start_block + block)
.await
.unwrap();
start = 0;
loop {
if start >= pic_buf.len() {
break;
}
(ordinal, send_len, res) =
eb_cmds::Response::pic_res_from_data(id, ordinal, &pic_buf[start..]);
if send_len == 0 {
break;
}
start += send_len;
let (buf_tmp, len) = res.to_array();
class.write_packet(&buf_tmp[0..len]).await.unwrap();
}
}
}
Command::GetPicNum => {
let mut buf = [0u8; 512];
sd.read_single_block_async(&mut buf, SIZE_BLOCK)
.await
.unwrap();
let num = ((buf[0] as u32) << 24)
| ((buf[1] as u32) << 16)
| ((buf[2] as u32) << 8)
| (buf[3] as u32);
// ebcmd::Response::GetPicNum(num)
let res = eb_cmds::Response::GetPicNum(num);
let (buf, len) = res.to_array();
class.write_packet(&buf[0..len]).await.unwrap();
}
Command::ClearPic => {}
}
// let ret = select(class.read_packet(&mut buf), class.write_packet(&buf)).await;
// class.write_packet(&buf[0..n]).await.unwrap();
}
}

231
tmp.log
View File

@ -1,231 +0,0 @@
ffff9f802a787a40 690792870 S Ci:3:067:0 s 80 06 0100 0000 0012 18 <
ffff9f802a787a40 690795417 C Ci:3:067:0 0 18 = 12011001 02000040 34127856 00020102 0301
ffff9f802a787a40 690795431 S Ci:3:067:0 s 80 06 0200 0000 0009 9 <
ffff9f802a787a40 690799416 C Ci:3:067:0 0 9 = 09024b00 02010080 32
ffff9f802a787a40 690799424 S Ci:3:067:0 s 80 06 0200 0000 004b 75 <
ffff9f802a787a40 690803415 C Ci:3:067:0 0 75 = 09024b00 02010080 32080b00 02020201 00090400 00010202 01000524 00100105
ffff9f802a787e00 690803427 S Ci:3:067:0 s 80 06 0300 0000 00ff 255 <
ffff9f802a787e00 690807416 C Ci:3:067:0 0 4 = 04030904
ffff9f802a787e00 690807422 S Ci:3:067:0 s 80 06 0302 0409 00ff 255 <
ffff9f802a787e00 690811416 C Ci:3:067:0 0 38 = 26035500 53004200 20004500 78006100 6d007000 6c006500 20004400 65007600
ffff9f802a787e00 690811425 S Ci:3:067:0 s 80 06 0301 0409 00ff 255 <
ffff9f802a787e00 690815416 C Ci:3:067:0 0 12 = 0c034700 47004500 54004100
ffff9f802a787e00 690815425 S Ci:3:067:0 s 80 06 0303 0409 00ff 255 <
ffff9f802a787e00 690819415 C Ci:3:067:0 0 14 = 0e033100 32003300 34003500 3600
ffff9f802a787e00 690855564 S Co:3:067:0 s 00 09 0001 0000 0000 0
ffff9f802a787e00 690856537 C Co:3:067:0 0 0
ffff9f802a7866c0 690856587 S Co:3:067:0 s 21 20 0000 0000 0007 7 = 80250000 000008
ffff9f802a7866c0 690860412 C Co:3:067:0 0 7 >
ffff9f802a787e00 691476571 S Ii:3:067:1 -115:8 64 <
ffff9f802a7863c0 691476585 S Bi:3:067:2 -115 128 <
ffff9f802a786000 691476587 S Bi:3:067:2 -115 128 <
ffff9f802a787680 691476589 S Bi:3:067:2 -115 128 <
ffff9f802a786d80 691476591 S Bi:3:067:2 -115 128 <
ffff9f802a787c80 691476593 S Bi:3:067:2 -115 128 <
ffff9f802a786240 691476595 S Bi:3:067:2 -115 128 <
ffff9f802a787080 691476597 S Bi:3:067:2 -115 128 <
ffff9f802a787800 691476599 S Bi:3:067:2 -115 128 <
ffff9f802a786780 691476601 S Bi:3:067:2 -115 128 <
ffff9f802a786fc0 691476603 S Bi:3:067:2 -115 128 <
ffff9f802a786b40 691476605 S Bi:3:067:2 -115 128 <
ffff9f802a786480 691476608 S Bi:3:067:2 -115 128 <
ffff9f802a786c00 691476610 S Bi:3:067:2 -115 128 <
ffff9f802a787500 691476612 S Bi:3:067:2 -115 128 <
ffff9f802a786300 691476614 S Bi:3:067:2 -115 128 <
ffff9f802a787bc0 691476616 S Bi:3:067:2 -115 128 <
ffff9f7e7e7eb680 691476621 S Co:3:067:0 s 21 22 0003 0000 0000 0
ffff9f802a7863c0 695583608 C Bi:3:067:2 -32 0
ffff9f7e7e7eb680 695583644 C Co:3:067:0 -32 0
ffff9f7e7e7eb680 695583681 S Co:3:067:0 s 21 20 0000 0000 0007 7 = 00c20100 000008
ffff9f802a786000 695583683 C Bi:3:067:2 -2 0
ffff9f802a787e00 695583725 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695583726 S Ii:3:067:1 -115:8 64 <
ffff9f802a787680 695583759 C Bi:3:067:2 -2 0
ffff9f802a786d80 695583877 C Bi:3:067:2 -2 0
ffff9f802a787c80 695583926 C Bi:3:067:2 -2 0
ffff9f7e7e7eb680 695583967 C Co:3:067:0 -71 0
ffff9f7e7e7eb680 695583997 S Co:3:067:0 s 21 20 0000 0000 0007 7 = 00093d00 000008
ffff9f802a786240 695584037 C Bi:3:067:2 -2 0
ffff9f802a787080 695584115 C Bi:3:067:2 -2 0
ffff9f802a787800 695584194 C Bi:3:067:2 -2 0
ffff9f802a786780 695584274 C Bi:3:067:2 -2 0
ffff9f802a786fc0 695584352 C Bi:3:067:2 -2 0
ffff9f802a786b40 695584432 C Bi:3:067:2 -2 0
ffff9f802a786480 695584511 C Bi:3:067:2 -2 0
ffff9f802a786c00 695584594 C Bi:3:067:2 -2 0
ffff9f7e7e7eb680 695584633 C Co:3:067:0 -71 0
ffff9f7e7e7eb680 695584646 S Co:3:067:0 s 21 20 0000 0000 0007 7 = 00c20100 000008
ffff9f802a787500 695584710 C Bi:3:067:2 -2 0
ffff9f802a786300 695584790 C Bi:3:067:2 -2 0
ffff9f802a787bc0 695584869 C Bi:3:067:2 -2 0
ffff9f802a786e40 695584872 S Co:3:067:0 s 02 01 0000 0082 0000 0
ffff9f7e7e7eb680 695585029 C Co:3:067:0 -71 0
ffff9f7e7e7eb680 695585052 S Co:3:067:0 s 21 22 0002 0000 0000 0
ffff9f802a786e40 695587486 C Co:3:067:0 -71 0
ffff9f802a7863c0 695587489 S Bi:3:067:2 -115 128 <
ffff9f802a786000 695587491 S Bi:3:067:2 -115 128 <
ffff9f802a787680 695587492 S Bi:3:067:2 -115 128 <
ffff9f802a786d80 695587494 S Bi:3:067:2 -115 128 <
ffff9f802a787c80 695587496 S Bi:3:067:2 -115 128 <
ffff9f802a786240 695587498 S Bi:3:067:2 -115 128 <
ffff9f802a787080 695587500 S Bi:3:067:2 -115 128 <
ffff9f802a787800 695587501 S Bi:3:067:2 -115 128 <
ffff9f802a786780 695587503 S Bi:3:067:2 -115 128 <
ffff9f802a786fc0 695587505 S Bi:3:067:2 -115 128 <
ffff9f802a786b40 695587506 S Bi:3:067:2 -115 128 <
ffff9f802a786480 695587508 S Bi:3:067:2 -115 128 <
ffff9f802a786c00 695587509 S Bi:3:067:2 -115 128 <
ffff9f802a787500 695587512 S Bi:3:067:2 -115 128 <
ffff9f802a786300 695587513 S Bi:3:067:2 -115 128 <
ffff9f802a787bc0 695587515 S Bi:3:067:2 -115 128 <
ffff9f802a7863c0 695587605 C Bi:3:067:2 -71 0
ffff9f7e7e7eb680 695588155 C Co:3:067:0 -71 0
ffff9f802a786000 695588156 C Bi:3:067:2 -71 0
ffff9f802a787680 695588900 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695589030 C Co:3:004:0 0 0
ffff9f802a7866c0 695589072 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786d80 695589149 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695589280 C Co:3:004:0 0 0
ffff9f802a7866c0 695589322 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a787c80 695589400 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695589530 C Co:3:004:0 0 0
ffff9f802a7866c0 695589575 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786240 695589649 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695589781 C Co:3:004:0 0 0
ffff9f802a7866c0 695589823 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a787080 695589899 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695590030 C Co:3:004:0 0 0
ffff9f802a7866c0 695590073 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a787800 695590150 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695590280 C Co:3:004:0 0 0
ffff9f802a7866c0 695590323 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786780 695590401 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695590530 C Co:3:004:0 0 0
ffff9f802a7866c0 695590573 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786fc0 695590650 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695590780 C Co:3:004:0 0 0
ffff9f802a7866c0 695590822 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786b40 695590900 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695591030 C Co:3:004:0 0 0
ffff9f802a7866c0 695591072 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786480 695591150 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695591280 C Co:3:004:0 0 0
ffff9f802a7866c0 695591322 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786c00 695591400 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695591439 C Co:3:004:0 0 0
ffff9f802a7866c0 695591481 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a787500 695591559 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695591560 C Co:3:004:0 0 0
ffff9f802a7866c0 695591601 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a786300 695591680 C Bi:3:067:2 -71 0
ffff9f802a7866c0 695591681 C Co:3:004:0 0 0
ffff9f802a787e00 695591760 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695591761 S Ii:3:067:1 -115:8 64 <
ffff9f802a7866c0 695591765 S Co:3:004:0 s 23 08 9052 0001 0000 0
ffff9f802a7866c0 695591799 C Co:3:004:0 0 0
ffff9f802a787bc0 695591838 C Bi:3:067:2 -71 0
ffff9f802a787e00 695599736 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695599738 S Ii:3:067:1 -115:8 64 <
ffff9f802a787e00 695607736 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695607737 S Ii:3:067:1 -115:8 64 <
ffff9f802a787e00 695615736 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695615737 S Ii:3:067:1 -115:8 64 <
ffff9f802a787e00 695623736 C Ii:3:067:1 -32:8 0
ffff9f802a787e00 695623737 S Ii:3:067:1 -115:8 64 <
ffff9f7e456ea0c0 695623911 C Ii:3:004:1 0:2048 1 = 04
ffff9f7e456ea0c0 695623915 S Ii:3:004:1 -115:2048 1 <
ffff9f802a7866c0 695623923 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a7866c0 695624156 C Ci:3:004:0 0 4 = 00010100
ffff9f802a7866c0 695624159 S Co:3:004:0 s 23 01 0010 0002 0000 0
ffff9f802a7866c0 695624405 C Co:3:004:0 0 0
ffff9f802a787e00 695624512 C Ii:3:067:1 -108:8 0
ffff9f802a787bc0 695655522 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695655783 C Ci:3:004:0 0 4 = 00010000
ffff9f802a787bc0 695689530 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695689783 C Ci:3:004:0 0 4 = 00010000
ffff9f802a787bc0 695726198 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695726410 C Ci:3:004:0 0 4 = 01010100
ffff9f802a787bc0 695726416 S Co:3:004:0 s 23 01 0010 0002 0000 0
ffff9f802a787bc0 695726656 C Co:3:004:0 0 0
ffff9f802a787bc0 695759536 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695759785 C Ci:3:004:0 0 4 = 01010000
ffff9f802a787bc0 695792872 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695793035 C Ci:3:004:0 0 4 = 01010000
ffff9f802a787bc0 695826195 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695826408 C Ci:3:004:0 0 4 = 01010000
ffff9f802a787bc0 695859527 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695859783 C Ci:3:004:0 0 4 = 01010000
ffff9f802a787bc0 695859846 S Co:3:004:0 s 23 03 0004 0002 0000 0
ffff9f802a787bc0 695860031 C Co:3:004:0 0 0
ffff9f802a787bc0 695876196 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695876408 C Ci:3:004:0 0 4 = 11010000
ffff9f7e456ea0c0 695879908 C Ii:3:004:1 0:2048 1 = 04
ffff9f7e456ea0c0 695879911 S Ii:3:004:1 -115:2048 1 <
ffff9f802a787bc0 695892862 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 695893033 C Ci:3:004:0 0 4 = 03011000
ffff9f802a787bc0 695893037 S Co:3:004:0 s 23 01 0014 0002 0000 0
ffff9f802a787bc0 695893281 C Co:3:004:0 0 0
ffff9f802a787bc0 696049558 S Ci:3:000:0 s 80 06 0100 0000 0040 64 <
ffff9f802a787bc0 696052417 C Ci:3:000:0 0 18 = 12011001 02000040 34127856 00020102 0301
ffff9f802a787bc0 696052421 S Co:3:004:0 s 23 03 0004 0002 0000 0
ffff9f802a787bc0 696052656 C Co:3:004:0 0 0
ffff9f802a787bc0 696066192 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696066408 C Ci:3:004:0 0 4 = 11010000
ffff9f802a787bc0 696082860 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696083032 C Ci:3:004:0 0 4 = 03011000
ffff9f802a787bc0 696083036 S Co:3:004:0 s 23 01 0014 0002 0000 0
ffff9f802a787bc0 696083281 C Co:3:004:0 0 0
ffff9f802a787bc0 696259527 S Ci:3:068:0 s 80 06 0100 0000 0012 18 <
ffff9f802a787bc0 696259666 C Ci:3:068:0 -32 0
ffff9f802a787bc0 696259670 S Ci:3:068:0 s 80 06 0100 0000 0012 18 <
ffff9f802a787bc0 696259805 C Ci:3:068:0 -32 0
ffff9f802a787bc0 696259809 S Ci:3:068:0 s 80 06 0100 0000 0012 18 <
ffff9f802a787bc0 696259945 C Ci:3:068:0 -32 0
ffff9f802a787bc0 696259953 S Co:3:004:0 s 23 01 0001 0002 0000 0
ffff9f802a787bc0 696260031 C Co:3:004:0 0 0
ffff9f802a787bc0 696260133 S Co:3:004:0 s 23 03 0004 0002 0000 0
ffff9f802a787bc0 696260281 C Co:3:004:0 0 0
ffff9f802a787bc0 696276192 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696276408 C Ci:3:004:0 0 4 = 11010000
ffff9f802a787bc0 696292862 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696293033 C Ci:3:004:0 0 4 = 03011000
ffff9f802a787bc0 696293036 S Co:3:004:0 s 23 01 0014 0002 0000 0
ffff9f802a787bc0 696293280 C Co:3:004:0 0 0
ffff9f802a787bc0 696449565 S Ci:3:000:0 s 80 06 0100 0000 0040 64 <
ffff9f802a787bc0 696452419 C Ci:3:000:0 0 18 = 12011001 02000040 34127856 00020102 0301
ffff9f802a787bc0 696452425 S Co:3:004:0 s 23 03 0004 0002 0000 0
ffff9f802a787bc0 696452657 C Co:3:004:0 0 0
ffff9f802a787bc0 696466197 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696466410 C Ci:3:004:0 0 4 = 11010000
ffff9f802a787bc0 696482862 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a787bc0 696483034 C Ci:3:004:0 0 4 = 03011000
ffff9f802a787bc0 696483040 S Co:3:004:0 s 23 01 0014 0002 0000 0
ffff9f802a787bc0 696483282 C Co:3:004:0 0 0
ffff9f7e455f09c0 696529582 S Bo:3:005:3 -115 31 = 55534243 01090000 00000000 00000600 00000000 00000000 00000000 000000
ffff9f7e455f09c0 696529602 C Bo:3:005:3 0 31 >
ffff9f7e455f09c0 696529611 S Bi:3:005:3 -115 13 <
ffff9f7e455f09c0 696529640 C Bi:3:005:3 0 13 = 55534253 01090000 00000000 00
ffff9f802a787bc0 696656208 S Ci:3:069:0 s 80 06 0100 0000 0012 18 <
ffff9f802a787bc0 696658422 C Ci:3:069:0 0 18 = 12011001 02000040 34127856 00020102 0301
ffff9f802a787bc0 696658436 S Ci:3:069:0 s 80 06 0200 0000 0009 9 <
ffff9f802a787bc0 696662418 C Ci:3:069:0 0 9 = 09024b00 02010080 32
ffff9f802a787bc0 696662425 S Ci:3:069:0 s 80 06 0200 0000 004b 75 <
ffff9f802a787bc0 696665420 C Ci:3:069:0 0 75 = 09024b00 02010080 32080b00 02020201 00090400 00010202 01000524 00100105
ffff9f802a786300 696665433 S Ci:3:069:0 s 80 06 0300 0000 00ff 255 <
ffff9f802a786300 696669418 C Ci:3:069:0 0 4 = 04030904
ffff9f802a786300 696669425 S Ci:3:069:0 s 80 06 0302 0409 00ff 255 <
ffff9f802a786300 696672420 C Ci:3:069:0 0 38 = 26035500 53004200 20004500 78006100 6d007000 6c006500 20004400 65007600
ffff9f802a786300 696672431 S Ci:3:069:0 s 80 06 0301 0409 00ff 255 <
ffff9f802a786300 696676418 C Ci:3:069:0 0 12 = 0c034700 47004500 54004100
ffff9f802a786300 696676426 S Ci:3:069:0 s 80 06 0303 0409 00ff 255 <
ffff9f802a786300 696680422 C Ci:3:069:0 0 14 = 0e033100 32003300 34003500 3600
ffff9f802a786300 696743567 S Co:3:069:0 s 00 09 0001 0000 0000 0
ffff9f802a786300 696744541 C Co:3:069:0 0 0
ffff9f802a786e40 696744602 S Co:3:069:0 s 21 20 0000 0000 0007 7 = 80250000 000008
ffff9f802a786e40 696748416 C Co:3:069:0 0 7 >
ffff9f802a786e40 696748604 S Ci:3:004:0 s a3 00 0000 0002 0004 4 <
ffff9f802a786e40 696748783 C Ci:3:004:0 0 4 = 03010000
ffff9f7e455f09c0 698662926 S Bo:3:005:3 -115 31 = 55534243 02090000 00000000 00000600 00000000 00000000 00000000 000000
ffff9f7e455f09c0 698662953 C Bo:3:005:3 0 31 >
ffff9f7e455f09c0 698662963 S Bi:3:005:3 -115 13 <
ffff9f7e455f09c0 698662988 C Bi:3:005:3 0 13 = 55534253 02090000 00000000 00