This commit is contained in:
guangzong 2024-04-27 18:16:47 -04:00
parent 2b7098f3fc
commit 194b15fc39
Signed by: guangzong
GPG Key ID: 095389BACAE97D19
4 changed files with 124 additions and 259 deletions

62
Cargo.lock generated
View File

@ -2,6 +2,24 @@
# It is not intended for manual editing.
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]]
name = "bare-metal"
version = "0.2.5"
@ -50,9 +68,9 @@ dependencies = [
[[package]]
name = "cortex-m-rt"
version = "0.7.3"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d"
dependencies = [
"cortex-m-rt-macros",
]
@ -95,7 +113,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -106,7 +124,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [
"darling_core",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -139,7 +157,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -173,7 +191,7 @@ dependencies = [
[[package]]
name = "eb_cmds"
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]]
name = "embassy-executor"
@ -194,7 +212,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -445,9 +463,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.80"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
@ -493,22 +511,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
@ -555,9 +573,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.59"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
@ -566,28 +584,29 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.59",
"syn 2.0.60",
]
[[package]]
name = "u5-lib"
version = "0.1.0"
dependencies = [
"aligned",
"cortex-m",
"cortex-m-rt",
"critical-section",
@ -611,6 +630,7 @@ dependencies = [
name = "u5_example"
version = "0.1.0"
dependencies = [
"aligned",
"cortex-m",
"cortex-m-rt",
"defmt",

View File

@ -13,6 +13,7 @@ edition = "2021"
[dependencies]
# cortex-m = "0.7.0"
cortex-m = { version = "0.7.7" }
aligned = "0.4.2"
#u5-lib = { git = "ssh://gitea@git.ggeta.com:2002/guangzong/u5_new.git", features = [
# "stm32u5a5qj",
#], default-features = false, branch = "dev" }

View File

@ -29,11 +29,11 @@ async fn main(spawner: Spawner) {
pwr::vddusb_monitor_up_tmp();
power_up_init();
defmt::info!("vddusb monitor finished!");
spawner.spawn(usb_task()).unwrap();
spawner.spawn(setup_process()).unwrap();
defmt::info!("usb init finished!");
spawner.spawn(usb_task()).unwrap();
loop {
exti::EXTI13_PC13.wait_for_raising().await;
GREEN.toggle();
@ -48,8 +48,8 @@ async fn usb_task() {
loop {
// todo: in read function, we need to wait for usbepen to be set.
let ret = cdc_acm_ep2_read().await;
defmt::info!("read ret: {:?}", ret);
let (ret, len) = cdc_acm_ep2_read().await;
defmt::info!("read ret: {:?}", &ret[0..len]);
}
}

View File

@ -4,18 +4,18 @@
#![feature(type_alias_impl_trait)]
use core::panic::PanicInfo;
use aligned::Aligned;
use defmt_rtt as _;
use eb_cmds::Command;
use embassy_executor::Spawner;
use u5_lib::com_interface::ComInterface;
use u5_lib::usb_otg_hs::control_pipe::setup_process;
use u5_lib::usb_otg_hs::mod_new::cdc_acm_ep2_read;
use u5_lib::{clock::delay_ms, i2c::I2cMessage};
use u5_lib::{
gpio::{SDMMC2_CMD_PD7, SDMMC2_D0_PB14},
*,
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]
@ -32,146 +32,40 @@ fn panic(_info: &PanicInfo) -> ! {
fn setup_camera() -> (gpio::GpioPort, i2c::I2c) {
let cam_down = gpio::PD13;
cam_down.setup();
let rst = gpio::PD12;
cam_down.setup();
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();
)).unwrap();
delay_ms(1);
camera::setup_camera(&mut i2c);
delay_ms(500);
cam_down.set_high();
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)
}
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;
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();
green
orange.setup();
blue.setup();
(green, orange, blue)
}
fn setup_sd() -> sdmmc::SdInstance {
@ -210,21 +104,20 @@ fn set_dcmi() -> dcmi::DcmiPort {
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(true, false, clock::ClockFreqs::KernelFreq4Mhz);
// clock::init_clock(false, true, true, clock::ClockFreqs::KernelFreq160Mhz);
// cam_down.set_high();
delay_ms(200);
let green = setup_led();
spawner.spawn(btn()).unwrap();
spawner.spawn(pwr::vddusb_monitor_up()).unwrap();
// spawner.spawn(setup_process() ).unwrap();
spawner.spawn(usb_task()).unwrap();
// init dcmi
clock::init_clock(false, true, 26_000_000, true, clock::ClockFreqs::KernelFreq160Mhz);
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!");
@ -233,23 +126,19 @@ async fn async_main(spawner: Spawner) {
let dcmi = set_dcmi();
(cam_down, i2c, sd, dcmi)
});
setup_imu(&mut i2c);
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();
// }
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 {
if !power_on {
let val = POWER_SIGNAL.wait().await;
@ -266,25 +155,28 @@ async fn async_main(spawner: Spawner) {
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();
let mut pic_buf = [0u8; 1_600_000];
// deep sleep is not allowed
clock::hclk_request_async(clock::ClockFreqs::KernelFreq160Mhz, || async {
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, ########################");
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, ##################");
for i in 0..20 {
let begin = i * 30_000;
let end = (i + 1) * 30_000;
cdc_acm_ep2_write(&PIC_BUF[begin..end]).await;
}
defmt::debug!("finish send picture, ##################");
orange.toggle();
}
})
.await;
.await;
})
.await;
.await;
}
}
@ -299,10 +191,7 @@ 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,
};
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();
@ -332,17 +221,21 @@ const IMG_SIZE: u32 = 2000;
const SIZE_BLOCK: u32 = 1; // first block store the number of image files
#[embassy_executor::task]
async fn usb_task() {
let mut in_buf: [u8; 128] = [0; 128];
// the maximum size of the command is 64 bytes
let sd = setup_sd();
async unsafe fn usb_task() {
defmt::info!("start usb handler");
let sd = setup_sd();
loop {
// select(future1, future2)
// 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();
let ret = cdc_acm_ep2_read().await;
let command = eb_cmds::Command::from_array(&ret);
match command {
Command::SetTim(year, month, day, hour, minute, second, period) => {
// rtc::set_time(year, month, day, hour, minute, second, period);
@ -359,6 +252,7 @@ async fn usb_task() {
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();
@ -367,69 +261,18 @@ async fn usb_task() {
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 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();
}
}
// sd.read_single_block_async(&mut pic_buf[..], start_block).await.unwrap();
let _ = sd.read_multiple_blocks_async(&mut PIC_BUF[..], start_block, IMG_SIZE).await;
cdc_acm_ep2_write(&PIC_BUF[..]).await;
}
Command::GetPicNum => {
let mut buf = [0u8; 512];
sd.read_single_block_async(&mut buf, SIZE_BLOCK)
.await
.unwrap();
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)
@ -438,6 +281,7 @@ async fn usb_task() {
let res = eb_cmds::Response::GetPicNum(num);
let (buf, len) = res.to_array();
// class.write_packet(&buf[0..len]).await.unwrap();
cdc_acm_ep2_write(&buf[0..len]).await;
}
Command::ClearPic => {}
}