firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

fw16-epd-main: use timer to read temperature

+75 -27
+4 -1
fw16-epd-main/.cargo/config.toml
··· 4 4 "-C", "link-arg=-Tlink.x", 5 5 "-C", "link-arg=-Tdefmt.x", 6 6 ] 7 - runner = "probe-rs run --chip RP2040" 7 + runner = "probe-rs run --chip RP2040" 8 + 9 + [profile.release] 10 + debug = 2
+71 -26
fw16-epd-main/src/main.rs
··· 8 8 #[allow(unused_imports)] 9 9 use defmt_rtt as _; 10 10 11 - use core::cell::{RefCell, RefMut}; 11 + use core::cell::RefCell; 12 12 use critical_section::Mutex; 13 13 use defmt::{debug, error, info, trace}; 14 14 use embedded_graphics::mono_font::ascii::FONT_10X20; 15 15 use embedded_graphics::mono_font::MonoTextStyle; 16 16 use embedded_graphics::pixelcolor::BinaryColor; 17 17 use embedded_graphics::prelude::*; 18 - use embedded_graphics::primitives::{Line, PrimitiveStyle, PrimitiveStyleBuilder}; 18 + use embedded_graphics::primitives::{Line, PrimitiveStyle}; 19 19 use embedded_graphics::text::Text; 20 20 use embedded_hal::digital::{OutputPin, PinState}; 21 21 use embedded_hal::i2c::I2c; ··· 31 31 use fw16_epd_bsp::{entry, hal, pac, EpdBusy, EpdCs, EpdDc, EpdReset, EpdSck, EpdSdaWrite, EpdTouchInt, I2CScl, I2CSda, Pins}; 32 32 use fw16_epd_bsp::hal::{Sio, Timer, I2C}; 33 33 use fw16_epd_bsp::hal::clocks::ClockSource; 34 - use fw16_epd_bsp::hal::fugit::RateExtU32; 34 + use fw16_epd_bsp::hal::fugit::{RateExtU32, ExtU32}; 35 35 use fw16_epd_bsp::hal::gpio::Interrupt::EdgeLow; 36 36 use fw16_epd_bsp::hal::multicore::{Multicore, Stack}; 37 + use fw16_epd_bsp::hal::timer::{Alarm, Alarm0}; 37 38 use fw16_epd_bsp::pac::I2C0; 38 39 use fw16_epd_bsp::pac::interrupt; 39 40 use fw16_epd_program_interface::eg::EpdDrawTarget; ··· 47 48 static GLOBAL_TOUCH_INT_PIN: Mutex<RefCell<Option<EpdTouchInt>>> = Mutex::new(RefCell::new(None)); 48 49 static GLOBAL_I2C: Mutex<RefCell<Option<I2C<I2C0, (I2CSda, I2CScl)>>>> = Mutex::new(RefCell::new(None)); 49 50 50 - static IMAGE_BUFFER: Mutex<RefCell<[u8; IMAGE_BYTES]>> = Mutex::new(RefCell::new([0; tp370pgh01::IMAGE_BYTES])); 51 + static GLOBAL_ALARM0: Mutex<RefCell<Option<Alarm0>>> = Mutex::new(RefCell::new(None)); 52 + 53 + static IMAGE_BUFFER: Mutex<RefCell<[u8; IMAGE_BYTES]>> = Mutex::new(RefCell::new([0; IMAGE_BYTES])); 51 54 static DO_REFRESH: AtomicBool = AtomicBool::new(false); 52 55 static FAST_REFRESH: AtomicBool = AtomicBool::new(false); 53 56 static TEMP: AtomicU8 = AtomicU8::new(20); ··· 75 78 #[entry] 76 79 fn main() -> ! { 77 80 let mut pac = pac::Peripherals::take().unwrap(); 78 - let core = pac::CorePeripherals::take().unwrap(); 79 81 let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); 80 82 81 83 let clocks = hal::clocks::init_clocks_and_plls( ··· 104 106 touch_reset.set_low().unwrap(); 105 107 cortex_m::asm::delay(120000); 106 108 touch_reset.set_high().unwrap(); 107 - cortex_m::asm::delay(1200000); 109 + cortex_m::asm::delay(12000000); 108 110 109 111 110 112 let cs: EpdCs = pins.spi3_epd_cs.reconfigure(); ··· 118 120 let i2c_scl: I2CScl = pins.i2c_scl.reconfigure(); 119 121 let int: EpdTouchInt = pins.epd_touch_int.reconfigure(); 120 122 121 - let timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); 123 + let mut timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); 124 + let mut alarm = timer.alarm_0().unwrap(); 125 + alarm.enable_interrupt(); 126 + critical_section::with(|cs| GLOBAL_ALARM0.borrow_ref_mut(cs).replace(alarm)); 127 + unsafe { pac::NVIC::unmask(interrupt::TIMER_IRQ_0); } 128 + pac::NVIC::pend(interrupt::TIMER_IRQ_0); 122 129 123 130 let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( 124 131 pac.USBCTRL_REGS, ··· 132 139 GLOBAL_USB_BUS = Some(usb_bus); 133 140 } 134 141 142 + #[allow(static_mut_refs)] 135 143 let bus_ref = unsafe { GLOBAL_USB_BUS.as_ref().unwrap() }; 136 144 137 145 let serial = SerialPort::new(bus_ref); ··· 152 160 let mut mc = Multicore::new(&mut pac.PSM, &mut pac.PPB, &mut sio.fifo); 153 161 let core1 = &mut mc.cores()[1]; 154 162 core1.spawn(CORE1_STACK.take().unwrap(), move || { 163 + info!("core1 init"); 164 + 155 165 int.set_interrupt_enabled(EdgeLow, true); 156 166 157 167 let i2c = hal::i2c::I2C::i2c0(pac.I2C0, i2c_sda, i2c_scl, 400.kHz(), &mut pac.RESETS, clocks.system_clock.get_freq()); ··· 213 223 } 214 224 215 225 #[interrupt] 226 + fn TIMER_IRQ_0() { 227 + static mut ALARM0: Option<Alarm0> = None; 228 + 229 + trace!("TIMER_IRQ_0"); 230 + 231 + if ALARM0.is_none() { 232 + critical_section::with(|cs| *ALARM0 = GLOBAL_ALARM0.borrow(cs).take()); 233 + } 234 + 235 + let mut i2c = critical_section::with(|cs| GLOBAL_I2C.borrow(cs).take()); 236 + 237 + if let Some(alarm) = ALARM0 { 238 + if let Some(i2c) = &mut i2c { 239 + let mut mcp9808 = MCP9808::new(i2c); 240 + 241 + let temp = mcp9808.read_temperature().unwrap().get_celsius(ResolutionVal::Deg_0_0625C); 242 + let clamped = match temp { 243 + ..=0.0 => 0u8, 244 + 60.0.. => 60u8, 245 + t => t as u8, 246 + }; 247 + 248 + debug!("read temperature {}C (using {}C)", temp, clamped); 249 + 250 + TEMP.store(clamped, Ordering::Relaxed); 251 + 252 + alarm.clear_interrupt(); 253 + alarm.schedule(1.minutes()).unwrap(); 254 + } else { 255 + // I2C bus was in use, so try again in a short time 256 + alarm.clear_interrupt(); 257 + alarm.schedule(10.millis()).unwrap(); 258 + } 259 + } 260 + 261 + critical_section::with(|cs| GLOBAL_I2C.borrow(cs).replace(i2c)); 262 + } 263 + 264 + #[interrupt] 216 265 fn USBCTRL_IRQ() { 217 266 static mut INDEX: usize = 0; 218 267 219 268 trace!("USBCTRL_IRQ"); 220 269 270 + #[allow(static_mut_refs)] 221 271 let usb_dev = unsafe { GLOBAL_USB_DEVICE.as_mut().unwrap() }; 272 + #[allow(static_mut_refs)] 222 273 let serial = unsafe { GLOBAL_USB_SERIAL.as_mut().unwrap() }; 223 274 224 275 if usb_dev.poll(&mut [serial]) { ··· 245 296 fn IO_IRQ_BANK0() { 246 297 static mut FIRST_EVENT: bool = true; 247 298 static mut TOUCH_INT_PIN: Option<EpdTouchInt> = None; 248 - static mut I2C: Option<I2C<I2C0, (I2CSda, I2CScl)>> = None; 249 - static mut PREV_POS: Point = Point::new(0, 0); 299 + static mut PREV_POS: Option<Point> = None; 250 300 static mut DRAW_TARGET: EpdDrawTarget = EpdDrawTarget::new(ProgramFunctionTable { 251 301 write_image, 252 302 refresh, ··· 259 309 critical_section::with(|cs| *TOUCH_INT_PIN = GLOBAL_TOUCH_INT_PIN.borrow(cs).take()); 260 310 } 261 311 262 - if I2C.is_none() { 263 - critical_section::with(|cs| *I2C = GLOBAL_I2C.borrow(cs).take()); 264 - } 312 + let mut i2c = critical_section::with(|cs| GLOBAL_I2C.borrow(cs).take()); 265 313 266 - if let Some(i2c) = I2C { 314 + if let Some(i2c) = &mut i2c { 267 315 let rc = RefCell::new(i2c); 268 316 let mut i2c = RefCellDevice::new(&rc); 269 - let mut mcp9808 = MCP9808::new(RefCellDevice::new(&rc)); 270 317 271 - let temp = match mcp9808.read_temperature().unwrap().get_celsius(ResolutionVal::Deg_0_0625C) { 272 - ..=0.0 => 0u8, 273 - 60.0.. => 60u8, 274 - t => t as u8, 275 - }; 276 - TEMP.store(temp, Ordering::Relaxed); 277 318 278 319 if *FIRST_EVENT == true { 279 320 *FIRST_EVENT = false; ··· 295 336 hal::rom_data::reset_to_usb_boot(0, 0); 296 337 } else { 297 338 if state == 1 || state == 2 { 298 - Line::new(PREV_POS.clone(), pos) 299 - .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 5)) 300 - .draw(DRAW_TARGET) 301 - .unwrap(); 302 - DRAW_TARGET.refresh_fast(); 339 + if let Some(prev) = *PREV_POS { 340 + Line::new(prev, pos) 341 + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 5)) 342 + .draw(DRAW_TARGET) 343 + .unwrap(); 344 + DRAW_TARGET.refresh_fast(); 345 + } 303 346 } 304 347 305 348 if state == 0 || state == 2 { 306 - *PREV_POS = Point::new(x, y); 349 + *PREV_POS = Some(Point::new(x, y)); 307 350 } 308 351 } 309 352 int.clear_interrupt(EdgeLow); ··· 314 357 } else { 315 358 error!("i2c is None"); 316 359 } 360 + 361 + critical_section::with(|cs| GLOBAL_I2C.borrow(cs).replace(i2c)); 317 362 }