alpha
Login
or
Join now
arthomnix.dev
/
eepy
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
fw16-epd-main: global serial number
author
arthomnix
date
1 year ago
(Jan 12, 2025, 6:15 PM UTC)
commit
de04cc65
de04cc65d0c6f80dfcec3d6358f15df4e218ce00
parent
23b73e75
23b73e75863b0d908927676479754469a356786e
+29
-16
2 changed files
Expand all
Collapse all
Unified
Split
fw16-epd-main
src
main.rs
fw16-epd-program-interface
src
lib.rs
+28
-16
fw16-epd-main/src/main.rs
Reviewed
···
9
9
#[allow(unused_imports)]
10
10
use defmt_rtt as _;
11
11
12
12
-
use core::cell::RefCell;
12
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
21
-
use portable_atomic::{AtomicBool, AtomicU8};
21
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
33
-
use fw16_epd_bsp::pac::{CorePeripherals, I2C0};
33
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
62
+
static mut SERIAL_NUMBER: [u8; 16] = [b'X'; 16];
63
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
92
+
// Safety: The only time a mutable reference to SERIAL_NUMBER is created is right
93
93
+
// at the start of the program when the serial number is read from the flash. This
94
94
+
// function must never be called before then.
95
95
+
#[allow(static_mut_refs)]
96
96
+
extern "C" fn serial_number() -> &'static [u8; 16] {
97
97
+
unsafe { &SERIAL_NUMBER }
98
98
+
}
99
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
170
-
let mut serial_no = [0u8; 16];
171
171
-
for c in serial_no.iter_mut().rev() {
172
172
-
let nibble = (id & 0x0f) as u8;
173
173
-
*c = match nibble {
174
174
-
0x0..=0x9 => b'0' + nibble,
175
175
-
0xa..=0xf => b'A' + nibble - 0xa,
176
176
-
_ => unreachable!(),
177
177
-
};
178
178
-
id >>= 4;
180
180
+
unsafe {
181
181
+
// Safety: This is the only place we modify SERIAL_NUMBER, and this is before any
182
182
+
// shared references are created
183
183
+
#[allow(static_mut_refs)]
184
184
+
for c in SERIAL_NUMBER.iter_mut().rev() {
185
185
+
let nibble = (id & 0x0f) as u8;
186
186
+
*c = match nibble {
187
187
+
0x0..=0x9 => b'0' + nibble,
188
188
+
0xa..=0xf => b'A' + nibble - 0xa,
189
189
+
_ => unreachable!(),
190
190
+
};
191
191
+
id >>= 4;
192
192
+
}
179
193
}
180
180
-
// Safety: this function never returns, so we should be fine right?
181
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
184
-
info!("Framework 16 EPD firmware version {}, serial no. {}", env!("CARGO_PKG_VERSION"), serial_no);
196
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
259
-
.serial_number(serial_no)
271
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
Reviewed
···
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
38
+
pub serial_number: extern "C" fn() -> &'static [u8; 16]
38
39
}
39
40
40
41
#[repr(u8)]