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.

at a3ff1f4e4e2aaec4a4c1ec5def91c21d36dc12f7 92 lines 3.1 kB view raw
1#![no_std] 2#![no_main] 3 4mod serial; 5mod ui; 6 7extern crate panic_halt; 8 9use core::arch::asm; 10use core::mem::offset_of; 11use core::sync::atomic::Ordering; 12use usb_device::bus::UsbBusAllocator; 13use eepy_gui::draw_target::EpdDrawTarget; 14use eepy_gui::element::Gui; 15use eepy_sys::input::{has_event, next_event, set_touch_enabled}; 16use eepy_sys::misc::get_serial; 17use eepy_sys::usb::{self, UsbBus}; 18use usb_device::prelude::*; 19use usbd_serial::SerialPort; 20use eepy_sys::{eepy_app, flash}; 21use eepy_sys::header::{slot_ptr, ProgramSlotHeader}; 22use crate::serial::{HOST_APP, NEEDS_REFRESH, NEEDS_REFRESH_PROGRAMS}; 23use crate::ui::MainGui; 24 25static mut USB: Option<UsbBusAllocator<UsbBus>> = None; 26static mut USB_DEVICE: Option<UsbDevice<UsbBus>> = None; 27static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None; 28 29pub(crate) unsafe fn delete_program(slot: u8) { 30 let ptr = unsafe { slot_ptr(slot) }; 31 let mut buf = [0u8; 256]; 32 unsafe { buf.copy_from_slice(core::slice::from_raw_parts(ptr, 256)) }; 33 let offset = offset_of!(ProgramSlotHeader, len); 34 buf[offset..offset + 4].copy_from_slice(&0usize.to_ne_bytes()); 35 36 unsafe { flash::program(slot as u32 * 512 * 1024, &buf) }; 37} 38 39#[eepy_app(name = "Launcher")] 40fn main() { 41 #[allow(static_mut_refs)] 42 unsafe { 43 let bus = UsbBusAllocator::new(UsbBus::init()); 44 USB = Some(bus); 45 let bus_ref = USB.as_ref().unwrap(); 46 47 let serial = SerialPort::new(bus_ref); 48 USB_SERIAL = Some(serial); 49 50 let usb_dev = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x2e8a, 0x000a)) 51 .strings(&[StringDescriptors::default() 52 .manufacturer("arthomnix") 53 .product("Touchscreen EPD for FW16 [eepyOS Launcher]") 54 .serial_number(get_serial()) 55 ]) 56 .unwrap() 57 .device_class(usbd_serial::USB_CLASS_CDC) 58 .build(); 59 USB_DEVICE = Some(usb_dev); 60 } 61 62 usb::set_handler(serial::usb_handler); 63 64 let mut draw_target = EpdDrawTarget::default(); 65 set_touch_enabled(true); 66 let mut gui = MainGui::new(); 67 gui.draw_init(&mut draw_target); 68 draw_target.refresh(false); 69 70 loop { 71 if !HOST_APP.load(Ordering::Relaxed) { 72 while let Some(ev) = next_event() { 73 gui.tick(&mut draw_target, ev); 74 } 75 76 if NEEDS_REFRESH_PROGRAMS.swap(false, Ordering::Relaxed) { 77 if let MainGui::MainPage(page) = &mut gui { 78 page.refresh_buttons(); 79 page.draw_init(&mut draw_target); 80 } 81 draw_target.refresh(false); 82 } else if NEEDS_REFRESH.swap(false, Ordering::Relaxed) { 83 gui.draw_init(&mut draw_target); 84 draw_target.refresh(false); 85 } else if !has_event() { 86 // has_event() is a syscall. The SVCall exception is a WFE wakeup event, so we need two 87 // WFEs so we don't immediately wake up. 88 unsafe { asm!("wfe", "wfe") }; 89 } 90 } 91 } 92}