Skip to content

Commit

Permalink
Report device unique ID as USB serial number
Browse files Browse the repository at this point in the history
  • Loading branch information
adamgreig committed Jun 14, 2019
1 parent b4d7778 commit e989909
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 12 deletions.
4 changes: 2 additions & 2 deletions firmware/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "ffp"
version = "0.1.0"
name = "ffp_firmware"
version = "1.0.0"
authors = ["Adam Greig <adam@adamgreig.com>"]
edition = "2018"

Expand Down
1 change: 1 addition & 0 deletions firmware/src/hal/mod.rs
Expand Up @@ -9,3 +9,4 @@ pub mod dma;
pub mod spi;
pub mod usb;
pub mod bootload;
pub mod unique_id;
37 changes: 37 additions & 0 deletions firmware/src/hal/unique_id.rs
@@ -0,0 +1,37 @@
// Copyright 2019 Adam Greig
// Dual licensed under the Apache 2.0 and MIT licenses.

static HEX_DIGITS: [u8; 16] = [
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
97, 98, 99, 100, 101, 102,
];

/// Returns the 12-byte (96-bit) unique ID
pub fn get_id() -> [u8; 12] {
// UNSAFE: Reads fixed memory address known to contain unqiue ID.
unsafe { read_id() }
}

/// Returns the unique ID as ASCII hex
pub fn get_hex_id() -> [u8; 24] {
let id = get_id();
let mut out = [0u8; 24];
for (idx, v) in id.iter().enumerate() {
let v1 = v & 0x0F;
let v2 = (v & 0xF0) >> 4;
out[idx*2] = HEX_DIGITS[v1 as usize];
out[idx*2+1] = HEX_DIGITS[v2 as usize];
}
out
}

unsafe fn read_id() -> [u8; 12] {
let id1: [u8; 4] = (*(0x1FFF_F7AC as *const u32)).to_le_bytes();
let id2: [u8; 4] = (*(0x1FFF_F7B0 as *const u32)).to_le_bytes();
let id3: [u8; 4] = (*(0x1FFF_F7B4 as *const u32)).to_le_bytes();
[
id1[0], id1[1], id1[2], id1[3],
id2[0], id2[1], id2[2], id2[3],
id3[0], id3[1], id3[2], id3[3],
]
}
3 changes: 2 additions & 1 deletion firmware/src/hal/usb/descriptors.rs
Expand Up @@ -5,7 +5,8 @@ use core::mem::size_of;
use super::packets::*;

pub static STRING_LANGS: [u16; 1] = [0x0409];
pub static STRINGS: [&str; 3] = ["AGG", "FFP r1", "001"];
pub static STRING_MFN: &str = "AGG";
pub static STRING_PRD: &str = "FFP r1";

// Assigned by http://pid.codes/1209/FF50/
const VENDOR_ID: u16 = 0x1209;
Expand Down
28 changes: 21 additions & 7 deletions firmware/src/hal/usb/mod.rs
Expand Up @@ -13,6 +13,7 @@ use buffers::*;
use descriptors::*;

use crate::app::{PinState, Mode, Request};
use crate::hal::unique_id::get_hex_id;

/// USB stack interface
pub struct USB {
Expand Down Expand Up @@ -362,7 +363,7 @@ impl USB {
let mut desc = StringDescriptor {
bLength: 2 + 2 * STRING_LANGS.len() as u8,
bDescriptorType: DescriptorType::String as u8,
bString: [0u8; 32],
bString: [0u8; 48],
};
// Pack the u16 language codes into the u8 array
for (idx, lang) in STRING_LANGS.iter().enumerate() {
Expand All @@ -373,16 +374,29 @@ impl USB {
desc
},

// Handle all other strings
idx if idx as usize <= STRINGS.len() => {
// Handle manufacturer, product, and serial number strings
1 | 2 | 3 => {
let id;
let string = match idx {
1 => Ok(STRING_MFN),
2 => Ok(STRING_PRD),
3 => { id = get_hex_id(); core::str::from_utf8(&id) },
_ => unreachable!(),
};
let string = match string {
Ok(s) => s,
Err(_) => {
self.control_stall();
return;
}
};
let mut desc = StringDescriptor {
bLength: 2 + 2 * STRINGS[idx as usize - 1].len() as u8,
bLength: 2 + 2 * string.len() as u8,
bDescriptorType: DescriptorType::String as u8,
bString: [0u8; 32],
bString: [0u8; 48],
};
// Encode the &str to an iter of u16 and pack them
let string = STRINGS[idx as usize - 1].encode_utf16();
for (idx, cp) in string.enumerate() {
for (idx, cp) in string.encode_utf16().enumerate() {
let [u1, u2] = cp.to_le_bytes();
desc.bString[idx*2 ] = u1;
desc.bString[idx*2+1] = u2;
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/hal/usb/packets.rs
Expand Up @@ -116,7 +116,7 @@ pub struct EndpointDescriptor {
pub struct StringDescriptor {
pub bLength: u8,
pub bDescriptorType: u8,
pub bString: [u8; 32],
pub bString: [u8; 48],
}

#[allow(unused)]
Expand Down
2 changes: 1 addition & 1 deletion software/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e989909

Please sign in to comment.