From 194b15fc39c1dafe5b569055491cddace7f9a64a Mon Sep 17 00:00:00 2001 From: Guangzong Chen Date: Sat, 27 Apr 2024 18:16:47 -0400 Subject: [PATCH] update --- Cargo.lock | 62 +++++---- Cargo.toml | 1 + src/bin/usb_hs.rs | 6 +- src/main.rs | 314 ++++++++++++---------------------------------- 4 files changed, 124 insertions(+), 259 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6108584..6f22ac1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index 03325f0..6dfafe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" } diff --git a/src/bin/usb_hs.rs b/src/bin/usb_hs.rs index eafc614..171b857 100644 --- a/src/bin/usb_hs.rs +++ b/src/bin/usb_hs.rs @@ -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]); } } diff --git a/src/main.rs b/src/main.rs index dee8e3f..fcdacd3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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([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 = 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([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 => {} }