@@ -106,6 +106,29 @@ use patterns::*;
106
106
mod control;
107
107
use control:: * ;
108
108
109
+ // FRA - Framwork
110
+ // KDE - Lotus C2 LED Matrix
111
+ // AM - Atemitech
112
+ // 00 - Default Configuration
113
+ // 00000000 - Device Identifier
114
+ const DEFAULT_SERIAL : & str = "FRAKDEAM0000000000" ;
115
+ // Get serial number from last 4K block of the first 1M
116
+ const FLASH_OFFSET : usize = 0x10000000 ;
117
+ const LAST_4K_BLOCK : usize = 0xff000 ;
118
+ const SERIALNUM_LEN : usize = 18 ;
119
+
120
+ fn get_serialnum ( ) -> Option < & ' static str > {
121
+ // Flash is mapped into memory, just read it from there
122
+ let ptr: * const u8 = ( FLASH_OFFSET + LAST_4K_BLOCK ) as * const u8 ;
123
+ unsafe {
124
+ let slice: & [ u8 ] = core:: slice:: from_raw_parts ( ptr, SERIALNUM_LEN ) ;
125
+ if slice[ 0 ] == 0xFF || slice[ 0 ] == 0x00 {
126
+ return None ;
127
+ }
128
+ core:: str:: from_utf8 ( slice) . ok ( )
129
+ }
130
+ }
131
+
109
132
pub type Grid = [ [ u8 ; 34 ] ; 9 ] ;
110
133
111
134
#[ derive( Clone ) ]
@@ -161,10 +184,16 @@ fn main() -> ! {
161
184
// Set up the USB Communications Class Device driver
162
185
let mut serial = SerialPort :: new ( & usb_bus) ;
163
186
187
+ let serialnum = if let Some ( serialnum) = get_serialnum ( ) {
188
+ serialnum
189
+ } else {
190
+ DEFAULT_SERIAL
191
+ } ;
192
+
164
193
let mut usb_dev = UsbDeviceBuilder :: new ( & usb_bus, UsbVidPid ( 0x32ac , 0x0020 ) )
165
194
. manufacturer ( "Framework" )
166
195
. product ( "Lotus LED Matrix" )
167
- . serial_number ( "FRAKDE??0000000000" )
196
+ . serial_number ( serialnum )
168
197
. device_class ( 2 ) // Communications and CDC Control. From: https://www.usb.org/defined-class-codes
169
198
. build ( ) ;
170
199
0 commit comments