Skip to content

Commit

Permalink
Merge #1983
Browse files Browse the repository at this point in the history
1983: USB: CDC: Allow boards to specify vendor id, product id, and strings. r=ppannuto a=bradjc

### Pull Request Overview

Rather than hardcoding the USB identifying information, this allows the board file to set it for the board.

This adds a get address function for the nRF52, which permits using the hardcoded mac address as the serial number for USB so that USB devices get their own serial numbers.

This also configures the nano33ble to use the arduino vendor/product id that matches the bootloader. I think this makes sense for two reasons:
1. The hardware is the same and it is still an arduino board.
2. arduino udev rules will work.


### Testing Strategy

Running `lsusb` after flashing the kernel.


### TODO or Help Wanted

If someone wants to re-write `address_str()`.


### Documentation Updated

- [x] Updated the relevant files in `/docs`, or no updates are required.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Brad Campbell <bradjc5@gmail.com>
  • Loading branch information
bors[bot] and bradjc committed Jun 26, 2020
2 parents 3b06ee3 + da079b2 commit bf9e9bb
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 17 deletions.
32 changes: 29 additions & 3 deletions boards/components/src/cdc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@
//! Usage
//! -----
//! ```rust
//! static STRINGS: &'static [&str; 3] = &[
//! "XYZ Corp.", // Manufacturer
//! "The Zorpinator", // Product
//! "Serial No. 5", // Serial number
//! ];
//! let cdc_acm = components::cdc::CdcAcmComponent::new(
//! &nrf52::usbd::USBD,
//! capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840)
//! capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
//! 0x2341,
//! 0x005a,
//! STRINGS)
//! .finalize(components::usb_cdc_acm_component_helper!(nrf52::usbd::Usbd));
//! ```

Expand All @@ -32,13 +40,25 @@ macro_rules! usb_cdc_acm_component_helper {
pub struct CdcAcmComponent<U: 'static + hil::usb::UsbController<'static>> {
usb: &'static U,
max_ctrl_packet_size: u8,
vendor_id: u16,
product_id: u16,
strings: &'static [&'static str; 3],
}

impl<U: 'static + hil::usb::UsbController<'static>> CdcAcmComponent<U> {
pub fn new(usb: &'static U, max_ctrl_packet_size: u8) -> CdcAcmComponent<U> {
pub fn new(
usb: &'static U,
max_ctrl_packet_size: u8,
vendor_id: u16,
product_id: u16,
strings: &'static [&'static str; 3],
) -> CdcAcmComponent<U> {
CdcAcmComponent {
usb,
max_ctrl_packet_size,
vendor_id,
product_id,
strings,
}
}
}
Expand All @@ -51,7 +71,13 @@ impl<U: 'static + hil::usb::UsbController<'static>> Component for CdcAcmComponen
let cdc = static_init_half!(
s,
capsules::usb::cdc::CdcAcm<'static, U>,
capsules::usb::cdc::CdcAcm::new(self.usb, self.max_ctrl_packet_size)
capsules::usb::cdc::CdcAcm::new(
self.usb,
self.max_ctrl_packet_size,
self.vendor_id,
self.product_id,
self.strings
)
);
self.usb.set_client(cdc);

Expand Down
19 changes: 19 additions & 0 deletions boards/nano33ble/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,28 @@ pub unsafe fn reset_handler() {
//--------------------------------------------------------------------------

// Setup the CDC-ACM over USB driver that we will use for UART.
// We use the Arduino Vendor ID and Product ID since the device is the same.

// Create the strings we include in the USB descriptor. We use the hardcoded
// DEVICEADDR register on the nRF52 to set the serial number.
let serial_number_buf = static_init!([u8; 17], [0; 17]);
let serial_number_string: &'static str =
nrf52::ficr::FICR_INSTANCE.address_str(serial_number_buf);
let strings = static_init!(
[&str; 3],
[
"Arduino", // Manufacturer
"Nano 33 BLE - TockOS", // Product
serial_number_string, // Serial number
]
);

let cdc = components::cdc::CdcAcmComponent::new(
&nrf52::usbd::USBD,
capsules::usb::cdc::MAX_CTRL_PACKET_SIZE_NRF52840,
0x2341,
0x005a,
strings,
)
.finalize(components::usb_cdc_acm_component_helper!(nrf52::usbd::Usbd));

Expand Down
24 changes: 10 additions & 14 deletions capsules/src/usb/cdc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ use kernel::hil::uart;
use kernel::hil::usb::TransferType;
use kernel::ReturnCode;

const VENDOR_ID: u16 = 0x6668;
const PRODUCT_ID: u16 = 0xabce;

/// Identifying number for the endpoint when transferring data from us to the
/// host.
const ENDPOINT_IN_NUM: usize = 2;
Expand All @@ -35,13 +32,6 @@ const ENDPOINT_OUT_NUM: usize = 3;
static LANGUAGES: &'static [u16; 1] = &[
0x0409, // English (United States)
];

static STRINGS: &'static [&'static str] = &[
"TockOS", // Manufacturer
"The Zorpinator", // Product
"123456", // Serial number
];

/// Platform-specific packet length for the `SAM4L` USB hardware.
pub const MAX_CTRL_PACKET_SIZE_SAM4L: u8 = 8;
/// Platform-specific packet length for the `nRF52` USB hardware.
Expand Down Expand Up @@ -108,7 +98,13 @@ pub struct CdcAcm<'a, U: 'a> {
}

impl<'a, U: hil::usb::UsbController<'a>> CdcAcm<'a, U> {
pub fn new(controller: &'a U, max_ctrl_packet_size: u8) -> Self {
pub fn new(
controller: &'a U,
max_ctrl_packet_size: u8,
vendor_id: u16,
product_id: u16,
strings: &'static [&'static str; 3],
) -> Self {
let interfaces: &mut [InterfaceDescriptor] = &mut [
InterfaceDescriptor {
interface_number: 0,
Expand Down Expand Up @@ -181,8 +177,8 @@ impl<'a, U: hil::usb::UsbController<'a>> CdcAcm<'a, U> {
let (device_descriptor_buffer, other_descriptor_buffer) =
descriptors::create_descriptor_buffers(
descriptors::DeviceDescriptor {
vendor_id: VENDOR_ID,
product_id: PRODUCT_ID,
vendor_id: vendor_id,
product_id: product_id,
manufacturer_string: 1,
product_string: 2,
serial_number_string: 3,
Expand All @@ -207,7 +203,7 @@ impl<'a, U: hil::usb::UsbController<'a>> CdcAcm<'a, U> {
None, // No HID descriptor
None, // No report descriptor
LANGUAGES,
STRINGS,
strings,
),
buffers: [
Buffer64::default(),
Expand Down
39 changes: 39 additions & 0 deletions chips/nrf52/src/ficr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,45 @@ impl Ficr {
_ => Flash::Unspecified,
}
}

pub fn address(&self) -> u32 {
let regs = self.registers;
regs.deviceaddr0.read(DeviceAddress0::DEVICEADDRESS)
}

/// Return a MAC address string that has been hardcoded on this chip in the
/// format `46:db:52:cd:93:9e`.
pub fn address_str(&self, buf: &'static mut [u8; 17]) -> &'static str {
let regs = self.registers;
let lo = regs.deviceaddr0.read(DeviceAddress0::DEVICEADDRESS);
let hi = regs.deviceaddr1.read(DeviceAddress1::DEVICEADDRESS);

let h: [u8; 16] = [
'0' as u8, '1' as u8, '2' as u8, '3' as u8, '4' as u8, '5' as u8, '6' as u8, '7' as u8,
'8' as u8, '9' as u8, 'a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8, 'f' as u8,
];

buf[0] = h[((hi >> 12) & 0xf) as usize];
buf[1] = h[((hi >> 8) & 0xf) as usize];
buf[2] = ':' as u8;
buf[3] = h[((hi >> 4) & 0xf) as usize];
buf[4] = h[((hi >> 0) & 0xf) as usize];
buf[5] = ':' as u8;
buf[6] = h[((lo >> 28) & 0xf) as usize];
buf[7] = h[((lo >> 24) & 0xf) as usize];
buf[8] = ':' as u8;
buf[9] = h[((lo >> 20) & 0xf) as usize];
buf[10] = h[((lo >> 16) & 0xf) as usize];
buf[11] = ':' as u8;
buf[12] = h[((lo >> 12) & 0xf) as usize];
buf[13] = h[((lo >> 8) & 0xf) as usize];
buf[14] = ':' as u8;
buf[15] = h[((lo >> 4) & 0xf) as usize];
buf[16] = h[((lo >> 0) & 0xf) as usize];

// Safe because we use only ascii characters in this buffer.
unsafe { &*(buf as *const [u8] as *const str) }
}
}

impl fmt::Display for Ficr {
Expand Down

0 comments on commit bf9e9bb

Please sign in to comment.