Skip to content
Snippets Groups Projects
Commit dcd5d69d authored by zdmx's avatar zdmx :crab:
Browse files

Work on captouch, clean up a bit

parent b4933d91
No related branches found
No related tags found
No related merge requests found
......@@ -9,14 +9,13 @@ use embedded_graphics::{
primitives::{PrimitiveStyle, Rectangle, StyledDrawable},
text::Text,
};
use embedded_hal_async::digital::Wait;
use esp_backtrace as _;
use esp_println::println;
use tinybmp::Bmp;
use smart_leds::SmartLedsWrite;
use crate::flow3r::input::{FlowerInputEventSource, InputHandler};
use crate::flow3r::input::InputHandler;
#[embassy_executor::task]
pub async fn leds_fade(mut leds: crate::flow3r::leds::Leds) -> ! {
......
use hal::{i2c::I2C, peripherals::I2C0};
use port_expander::{Max7321, dev::max7321::Driver};
use shared_bus::{I2cProxy, XtensaMutex, NullMutex};
use port_expander::{dev::max7321::Driver, Max7321};
use shared_bus::{I2cProxy, NullMutex, XtensaMutex};
pub mod badgenet;
pub struct BadgeLink {
port_expander: Max7321<NullMutex<Driver<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>>
port_expander: Max7321<NullMutex<Driver<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>>,
}
impl BadgeLink {
pub fn new(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> Self {
let mut port_expander = port_expander::Max7321::new(i2c, true, true, true, false);
Self {
port_expander
}
let port_expander = port_expander::Max7321::new(i2c, true, true, true, false);
Self { port_expander }
}
pub fn left_audio(&mut self) -> Result<(), hal::i2c::Error> {
......
......@@ -3,64 +3,317 @@ use ad7147::{
stage::{CapInput, CdcInput, InputConnection},
Ad7147, DeviceConfiguration, Initialized, StageConfiguration,
};
use embassy_futures::select::select;
use embassy_time::{Delay, Duration, Timer};
use embedded_hal_async::digital::Wait;
use esp_println::println;
use hal::{
gpio::{Gpio16, Unknown},
gpio::{Gpio15, Gpio16, Unknown},
i2c::I2C,
peripherals::I2C0, prelude::_esp_hal_gpio_InputPin,
peripherals::I2C0,
};
use shared_bus::{I2cProxy, XtensaMutex};
pub struct CapTouchHandler;
fn init_captouch(
i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
i2c_bot: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
i2c_top: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
) -> Result<
Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 1>,
(
Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 12>,
Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 12>,
),
hal::i2c::Error,
> {
let ad7147 = Ad7147::new(i2c, 0b00101100);
let config = DeviceConfiguration::builder()
let ad7147_bot = Ad7147::new(i2c_bot, 0b00101101);
let config_bot = DeviceConfiguration::builder()
.decimation(DecimationFactor::Factor64)
.stages([StageConfiguration::builder()
.stages([
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN0,
cdc: CdcInput::Positive,
})
.build()])
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN1,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN2,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN3,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN4,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN5,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN6,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN7,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN8,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(2)
.add_input_connection(InputConnection {
cin: CapInput::CIN9,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(30)
.add_input_connection(InputConnection {
cin: CapInput::CIN10,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(26)
.add_input_connection(InputConnection {
cin: CapInput::CIN11,
cdc: CdcInput::Positive,
})
.build(),
])
.build();
let ad7147_top = Ad7147::new(i2c_top, 0b00101100);
let config_top = DeviceConfiguration::builder()
.decimation(DecimationFactor::Factor64)
.stages([
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(30)
.add_input_connection(InputConnection {
cin: CapInput::CIN0,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(30)
.add_input_connection(InputConnection {
cin: CapInput::CIN1,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(28)
.add_input_connection(InputConnection {
cin: CapInput::CIN2,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(28)
.add_input_connection(InputConnection {
cin: CapInput::CIN3,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(28)
.add_input_connection(InputConnection {
cin: CapInput::CIN4,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(28)
.add_input_connection(InputConnection {
cin: CapInput::CIN5,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(28)
.add_input_connection(InputConnection {
cin: CapInput::CIN6,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(10)
.add_input_connection(InputConnection {
cin: CapInput::CIN7,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(20)
.add_input_connection(InputConnection {
cin: CapInput::CIN8,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(20)
.add_input_connection(InputConnection {
cin: CapInput::CIN9,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(8)
.add_input_connection(InputConnection {
cin: CapInput::CIN10,
cdc: CdcInput::Positive,
})
.build(),
StageConfiguration::builder()
.calibration_enabled(true)
.conversion_complete_interrupt_enabled(true)
.pos_afe_offset(20)
.add_input_connection(InputConnection {
cin: CapInput::CIN11,
cdc: CdcInput::Positive,
})
.build(),
])
.build();
println!("device config: {:x?}", config.0.to_reg_value_for_init());
ad7147.init(config, &mut Delay)
Ok((
ad7147_bot.init(config_bot, &mut Delay)?,
ad7147_top.init(config_top, &mut Delay)?,
))
}
#[embassy_executor::task]
pub async fn captouch_controller(
i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
cap_b_int: Gpio16<Unknown>,
i2c_bot: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
i2c_top: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
cap_bot_int: Gpio16<Unknown>,
cap_top_int: Gpio15<Unknown>,
) -> ! {
let mut cap_b_int = cap_b_int.into_pull_up_input();
let mut ad7147 = init_captouch(i2c).unwrap();
let device_id = ad7147.read_device_id().unwrap();
println!("captouch device id: {:016b}", device_id);
let ints = ad7147.read_interrupt_registers().unwrap();
println!("ints: {:?}", ints);
let mut cap_bot_int = cap_bot_int.into_pull_up_input();
let mut cap_top_int = cap_top_int.into_pull_up_input();
let (mut ad7147_bot, mut ad7147_top) = init_captouch(i2c_bot, i2c_top).unwrap();
println!("int pin: {}", cap_b_int.is_input_high());
let device_id = ad7147_bot.read_device_id().unwrap();
println!("captouch bot device id: {:016b}", device_id);
let device_id = ad7147_top.read_device_id().unwrap();
println!("captouch top device id: {:016b}", device_id);
println!("initialized captouch");
loop {
println!("int pin: {}", cap_b_int.is_input_high());
// cap_b_int.wait_for_low().await.unwrap();
println!("captouch interrupt");
let ints = ad7147.read_interrupt_registers().unwrap();
println!("ints: {:?}", ints);
let measurement = ad7147.read_all_stages().unwrap();
println!("{}", measurement[0]);
Timer::after(Duration::from_secs(10)).await;
//println!("int pin: {}", cap_b_int.is_input_high());
select(cap_bot_int.wait_for_low(), cap_top_int.wait_for_low());
let _ = ad7147_bot.read_interrupt_registers().unwrap();
let _ = ad7147_top.read_interrupt_registers().unwrap();
//println!("ints: {:?}", ints);
let measurement = ad7147_bot.read_all_stages().unwrap();
println!(
"{} {} {} {} {} {} {} {} {} {} {} {}",
measurement[0],
measurement[1],
measurement[2],
measurement[3],
measurement[4],
measurement[5],
measurement[6],
measurement[7],
measurement[8],
measurement[9],
measurement[10],
measurement[11]
);
let measurement = ad7147_top.read_all_stages().unwrap();
println!(
"{} {} {} {} {} {} {} {} {} {} {} {}",
measurement[0],
measurement[1],
measurement[2],
measurement[3],
measurement[4],
measurement[5],
measurement[6],
measurement[7],
measurement[8],
measurement[9],
measurement[10],
measurement[11]
);
Timer::after(Duration::from_millis(1000)).await;
}
}
use bmi270::{interface::I2cInterface, Bmi270, PwrCtrl};
use bmi270::{interface::I2cInterface, AuxData, AxisData, Bmi270, Error, PwrCtrl};
use embassy_time::{Duration, Timer};
use esp_println::println;
use hal::{i2c::I2C, peripherals::I2C0};
......@@ -8,10 +8,8 @@ pub struct ImuHandler {
imu: Bmi270<I2cInterface<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>,
}
impl ImuHandler {}
#[embassy_executor::task]
pub async fn imu_manager(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> ! {
impl ImuHandler {
pub fn new(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> Self {
let mut bmi270 = Bmi270::new_i2c(i2c, bmi270::I2cAddr::Default, bmi270::Burst::Max);
let chip_id = bmi270.get_chip_id().unwrap();
......@@ -26,12 +24,18 @@ pub async fn imu_manager(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>
temp_en: false,
};
bmi270.set_pwr_ctrl(pwr_ctrl).unwrap();
Self { imu: bmi270 }
}
let data = bmi270.get_data().unwrap();
pub fn acceleration(&mut self) -> Result<AxisData, Error<hal::i2c::Error, ()>> {
self.imu.get_acc_data()
}
println!("imu data: {:?}", data);
pub fn rotation(&mut self) -> Result<AxisData, Error<hal::i2c::Error, ()>> {
self.imu.get_gyr_data()
}
loop {
Timer::after(Duration::from_secs(10)).await;
pub fn atmospheric_pressure(&mut self) -> Result<AuxData, Error<hal::i2c::Error, ()>> {
todo!()
}
}
......@@ -70,13 +70,11 @@ pub struct Flow3rInput(FlowerInputEventSource);
impl Flow3rInput {
pub async fn wait_for_release(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
wait_for_event(self.0, Flow3rInputEventType::Press)
.await
wait_for_event(self.0, Flow3rInputEventType::Press).await
}
pub async fn wait_for_press(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
wait_for_event(self.0, Flow3rInputEventType::Press)
.await
wait_for_event(self.0, Flow3rInputEventType::Press).await
}
pub async fn wait_for_any(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
......
use self::badgelink::BadgeLink;
use self::captouch::CapTouchHandler;
use self::display::Display;
use self::imu::ImuHandler;
use self::input::InputHandler;
use self::leds::Leds;
pub mod badgelink;
......@@ -11,13 +14,30 @@ pub mod leds;
pub mod sdcard;
pub struct Flow3r {
pub badgelink: BadgeLink,
pub captouch: CapTouchHandler,
pub display: Display,
pub imu: ImuHandler,
pub inputs: InputHandler,
pub leds: Leds,
pub badgelink: BadgeLink,
}
impl Flow3r {
pub fn new(display: Display, leds: Leds, badgelink: BadgeLink) -> Self {
Self { display, leds, badgelink }
pub fn new(
badgelink: BadgeLink,
captouch: CapTouchHandler,
display: Display,
imu: ImuHandler,
inputs: InputHandler,
leds: Leds,
) -> Self {
Self {
badgelink,
captouch,
display,
imu,
inputs,
leds,
}
}
}
......@@ -2,7 +2,7 @@ use embassy_executor::{Executor, Spawner};
use embassy_time::{Duration, Timer};
use hal::{
clock::{ClockControl, Clocks},
cpu_control::{self, AppCoreGuard, CpuControl},
cpu_control::CpuControl,
embassy,
gdma::Gdma,
i2c::I2C,
......@@ -17,11 +17,13 @@ use hal::{
use static_cell::StaticCell;
use crate::flow3r::{
captouch::captouch_controller,
badgelink::BadgeLink,
captouch::{captouch_controller, CapTouchHandler},
display::{display_refresh, Display},
input::input_controller,
imu::ImuHandler,
input::{input_controller, InputHandler},
leds::init_leds,
Flow3r, badgelink::BadgeLink,
Flow3r,
};
use crate::main;
......@@ -82,7 +84,7 @@ async fn init_runtime() {
embassy::init(&clocks, SystemTimer::new(peripherals.SYSTIMER));
let cpu_control = CpuControl::new(system.cpu_control);
let _cpu_control = CpuControl::new(system.cpu_control);
// Async requires the GPIO interrupt to wake futures
hal::interrupt::enable(
......@@ -101,7 +103,8 @@ async fn init_runtime() {
0,
)
.unwrap();
let leds = init_leds(pulse.channel0, io.pins.gpio14);
// Init I2C
let sda = io.pins.gpio2;
let scl = io.pins.gpio1;
......@@ -115,8 +118,12 @@ async fn init_runtime() {
&clocks,
);
// Create shared I2C Bus
let i2c_busmanager = shared_bus::new_xtensa!(I2C<'static, I2C0> = i2c).unwrap();
// Init SPI + DMA
let sck = io.pins.gpio41;
let mosi = io.pins.gpio42;
let spi = Spi::new_no_cs_no_miso(
......@@ -132,13 +139,16 @@ async fn init_runtime() {
let dma = Gdma::new(peripherals.DMA, &mut system.peripheral_clock_control);
let dma_channel = dma.channel0;
// Display backlight control
// Init Display backlight control
let ledc = LEDC::new(
peripherals.LEDC,
clocks,
&mut system.peripheral_clock_control,
);
// Init display early to clear pixel mash from screen
let mut display = Display::new(
spi,
dma_channel,
......@@ -150,6 +160,8 @@ async fn init_runtime() {
.await;
display.clear().await.unwrap();
// Init uart
let mut uart0 = Uart::new(peripherals.UART0, &mut system.peripheral_clock_control);
uart0.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16);
......@@ -159,11 +171,19 @@ async fn init_runtime() {
)
.unwrap();
let rng = RNG.init(Rng::new(peripherals.RNG));
let _rng = RNG.init(Rng::new(peripherals.RNG));
// Init Flow3r components
let badgelink = BadgeLink::new(i2c_busmanager.acquire_i2c());
let imu = ImuHandler::new(i2c_busmanager.acquire_i2c());
let inputs = InputHandler;
let captouch = CapTouchHandler;
let leds = init_leds(pulse.channel0, io.pins.gpio14);
let flow3r = Flow3r::new(display, leds, badgelink);
let flow3r = Flow3r::new(badgelink, captouch, display, imu, inputs, leds);
// Spawn background tasks
let spawner = Spawner::for_current_executor().await;
spawner
......@@ -176,9 +196,13 @@ async fn init_runtime() {
.ok();
spawner
.spawn(captouch_controller(
i2c_busmanager.acquire_i2c(),
i2c_busmanager.acquire_i2c(),
io.pins.gpio16,
io.pins.gpio15,
))
.ok();
// Hand over to main task
spawner.spawn(main(flow3r)).ok();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment