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: global serial number

+29 -16
+28 -16
fw16-epd-main/src/main.rs
··· 9 9 #[allow(unused_imports)] 10 10 use defmt_rtt as _; 11 11 12 - use core::cell::RefCell; 12 + use core::cell::{RefCell, UnsafeCell}; 13 13 use critical_section::Mutex; 14 14 use defmt::{debug, info, trace, warn}; 15 15 use embedded_hal::digital::{InputPin, OutputPin, PinState}; ··· 18 18 use mcp9808::reg_conf::{Configuration, ShutdownMode}; 19 19 use mcp9808::reg_res::ResolutionVal; 20 20 use mcp9808::reg_temp_generic::ReadableTempRegister; 21 - use portable_atomic::{AtomicBool, AtomicU8}; 21 + use portable_atomic::{AtomicBool, AtomicU128, AtomicU8}; 22 22 use portable_atomic::Ordering; 23 23 use usb_device::bus::UsbBusAllocator; 24 24 use usb_device::prelude::*; ··· 30 30 use fw16_epd_bsp::hal::gpio::Interrupt::{EdgeHigh, EdgeLow}; 31 31 use fw16_epd_bsp::hal::multicore::{Multicore, Stack}; 32 32 use fw16_epd_bsp::hal::timer::{Alarm, Alarm0}; 33 - use fw16_epd_bsp::pac::{CorePeripherals, I2C0}; 33 + use fw16_epd_bsp::pac::I2C0; 34 34 use fw16_epd_bsp::pac::interrupt; 35 35 use fw16_epd_gui::draw_target::EpdDrawTarget; 36 36 use fw16_epd_program_interface::{SafeOption, TouchEvent, TouchEventType}; ··· 59 59 static mut GLOBAL_USB_BUS: Option<UsbBusAllocator<hal::usb::UsbBus>> = None; 60 60 static mut GLOBAL_USB_SERIAL: Option<SerialPort<hal::usb::UsbBus>> = None; 61 61 62 + static mut SERIAL_NUMBER: [u8; 16] = [b'X'; 16]; 63 + 62 64 static TOUCH_EVENT_BUFFER: Mutex<RefCell<TouchEventBuffer>> = Mutex::new(RefCell::new(TouchEventBuffer::new())); 63 65 static TOUCH_ENABLED: AtomicBool = AtomicBool::new(false); 64 66 ··· 87 89 } 88 90 } 89 91 92 + // Safety: The only time a mutable reference to SERIAL_NUMBER is created is right 93 + // at the start of the program when the serial number is read from the flash. This 94 + // function must never be called before then. 95 + #[allow(static_mut_refs)] 96 + extern "C" fn serial_number() -> &'static [u8; 16] { 97 + unsafe { &SERIAL_NUMBER } 98 + } 99 + 90 100 struct TouchEventBuffer<const SIZE: usize = 32> { 91 101 inner: [TouchEvent; SIZE], 92 102 read_index: usize, ··· 167 177 let mut id = [0u8; 8]; 168 178 unsafe { rp2040_flash::flash::flash_unique_id(&mut id, true) }; 169 179 let mut id = u64::from_be_bytes(id); 170 - let mut serial_no = [0u8; 16]; 171 - for c in serial_no.iter_mut().rev() { 172 - let nibble = (id & 0x0f) as u8; 173 - *c = match nibble { 174 - 0x0..=0x9 => b'0' + nibble, 175 - 0xa..=0xf => b'A' + nibble - 0xa, 176 - _ => unreachable!(), 177 - }; 178 - id >>= 4; 180 + unsafe { 181 + // Safety: This is the only place we modify SERIAL_NUMBER, and this is before any 182 + // shared references are created 183 + #[allow(static_mut_refs)] 184 + for c in SERIAL_NUMBER.iter_mut().rev() { 185 + let nibble = (id & 0x0f) as u8; 186 + *c = match nibble { 187 + 0x0..=0x9 => b'0' + nibble, 188 + 0xa..=0xf => b'A' + nibble - 0xa, 189 + _ => unreachable!(), 190 + }; 191 + id >>= 4; 192 + } 179 193 } 180 - // Safety: this function never returns, so we should be fine right? 181 - let serial_no: &'static str = unsafe { &*&raw const *core::str::from_utf8(&serial_no).unwrap() }; 182 194 unsafe { cortex_m::interrupt::enable() }; 183 195 184 - info!("Framework 16 EPD firmware version {}, serial no. {}", env!("CARGO_PKG_VERSION"), serial_no); 196 + info!("Framework 16 EPD firmware version {}, serial no. {}", env!("CARGO_PKG_VERSION"), unsafe { core::str::from_utf8_unchecked(serial_number()) }); 185 197 186 198 let mut sio = Sio::new(pac.SIO); 187 199 let pins = Pins::new( ··· 256 268 .strings(&[StringDescriptors::default() 257 269 .manufacturer("arthomnix") 258 270 .product("Touchscreen EPD Input Module for Framework 16") 259 - .serial_number(serial_no) 271 + .serial_number(unsafe { core::str::from_utf8_unchecked(serial_number()) }) 260 272 ]) 261 273 .unwrap() 262 274 .device_class(usbd_serial::USB_CLASS_CDC)
+1
fw16-epd-program-interface/src/lib.rs
··· 35 35 pub refresh: extern "C" fn(bool, bool), 36 36 pub next_touch_event: extern "C" fn() -> SafeOption<TouchEvent>, 37 37 pub set_touch_enabled: unsafe extern "C" fn(bool), 38 + pub serial_number: extern "C" fn() -> &'static [u8; 16] 38 39 } 39 40 40 41 #[repr(u8)]