update
This commit is contained in:
parent
e1cb93e8d0
commit
2d8e73fc81
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -188,11 +188,6 @@ dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eb_cmds"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git#3890db9dd1399d1ccf78dedcfdd4efa9e0b91c35"
|
||||
|
||||
[[package]]
|
||||
name = "embassy-executor"
|
||||
version = "0.5.0"
|
||||
@ -631,16 +626,11 @@ dependencies = [
|
||||
name = "u5_example"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aligned",
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"defmt",
|
||||
"defmt-rtt",
|
||||
"eb_cmds",
|
||||
"embassy-executor",
|
||||
"embassy-sync",
|
||||
"embassy-usb",
|
||||
"futures",
|
||||
"u5-lib",
|
||||
]
|
||||
|
||||
|
17
Cargo.toml
17
Cargo.toml
@ -10,33 +10,16 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7.7" }
|
||||
aligned = "0.4.2"
|
||||
#u5-lib = { path = "../u5_new", features = ["utils"] }
|
||||
u5-lib = {git = "ssh://gitea@git.ggeta.com:2002/guangzong/u5_new.git", features = ["utils"], rev= "36dfec969e"}
|
||||
eb_cmds = { git = "ssh://gitea@git.ggeta.com:2002/guangzong/eb_cmds.git" }
|
||||
|
||||
defmt = "0.3.6"
|
||||
defmt-rtt = { version = "0.4.0" }
|
||||
futures = { version = "0.3.17", default-features = false, fetures = [
|
||||
"async-await",
|
||||
] }
|
||||
cortex-m-rt = { version = "0.7.3", default-features = false }
|
||||
|
||||
|
||||
[dependencies.embassy-usb]
|
||||
git = "https://github.com/embassy-rs/embassy"
|
||||
rev = "35f284e"
|
||||
|
||||
[dependencies.embassy-executor]
|
||||
features = ["nightly", "arch-cortex-m", "executor-thread"]
|
||||
git = "https://github.com/embassy-rs/embassy"
|
||||
rev = "35f284e"
|
||||
|
||||
[dependencies.embassy-sync]
|
||||
git = "https://github.com/embassy-rs/embassy"
|
||||
rev = "35f284e"
|
||||
|
||||
|
||||
# disable all optimizations
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
@ -1,315 +0,0 @@
|
||||
#![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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// #[!no_std]
|
||||
#![feature(noop_waker)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use core::default;
|
||||
use core::panic::PanicInfo;
|
||||
use core::default::Default;
|
||||
|
||||
use u5_lib::{*};
|
||||
use u5_lib::com_interface::ComInterface;
|
||||
|
||||
#[derive(defmt::Format)]
|
||||
pub enum UsbError {
|
||||
BufferOverflow,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
const BLUE: gpio::GpioPort = gpio::PB7;
|
||||
// const USART: usart::Usart = usart::USART1;
|
||||
|
||||
use u5_lib::low_power::Executor;
|
||||
|
||||
#[cortex_m_rt::entry]
|
||||
fn main() -> ! {
|
||||
Executor::take().run(|spawner| {
|
||||
spawner.spawn(async_main(spawner)).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[task]
|
||||
async fn async_main(_spawner: Spawner) {
|
||||
clock::init_clock(true, true, false, clock::ClockFreqs::KernelFreq160Mhz);
|
||||
BLUE.setup();
|
||||
defmt::info!("setup led finished!");
|
||||
loop {
|
||||
let mut i2c = i2c::I2c::new(default::Default::default()).unwrap();
|
||||
let mut data = [0x00];
|
||||
// i2c.send(i2c::I2cMessage { addr: 0x68, data: &mut data }).unwrap();
|
||||
clock::delay_ms(1000);
|
||||
}
|
||||
}
|
||||
|
||||
#[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 {}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#![feature(noop_waker)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
use core::panic::PanicInfo;
|
||||
use defmt_rtt as _;
|
||||
use embassy_executor::Spawner;
|
||||
|
||||
use u5_lib::{
|
||||
usb_otg_hs::mod_new::{cdc_acm_ep2_read },
|
||||
*,
|
||||
};
|
||||
use u5_lib::usb_otg_hs::control_pipe::setup_process;
|
||||
use u5_lib::usb_otg_hs::power::power_up_init;
|
||||
|
||||
const GREEN: gpio::GpioPort = gpio::PB7;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
clock::init_clock(false, true, true, clock::ClockFreqs::KernelFreq4Mhz);
|
||||
low_power::no_deep_sleep_request();
|
||||
GREEN.setup();
|
||||
// low_power::no_deep_sleep_request();
|
||||
// mcu_no_deep_sleep();
|
||||
defmt::info!("setup led finished!");
|
||||
// spawner.spawn(btn()).unwrap();
|
||||
// spawner.spawn(pwr::vddusb_monitor_up()).unwrap();
|
||||
// use some delay to wait for usb power up
|
||||
pwr::vddusb_monitor_up_tmp();
|
||||
power_up_init();
|
||||
defmt::info!("vddusb monitor finished!");
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
#[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]
|
||||
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 {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user