Skip to content

Commit

Permalink
repo: proof-of-concept for sharing values between host and device code
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinevg committed Sep 29, 2023
1 parent 4300bbf commit c4f1d15
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 58 deletions.
1 change: 1 addition & 0 deletions device/firmware/moondancer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ heapless = { version = "=0.7.16", default-features = false, features = ["mpmc_la
zerocopy = { version = "=0.7.0-alpha.2", default-features = false }

log = { version="=0.4.17", features = ["release_max_level_info"] }
static-toml = { version = "1.0.1" }

# - binaries ------------------------------------------------------------------

Expand Down
5 changes: 5 additions & 0 deletions device/firmware/moondancer/src/bin/moondancer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ impl<'a> Firmware<'a> {
fn new(peripherals: pac::Peripherals) -> Self {
// initialize logging
moondancer::log::init(hal::Serial::new(peripherals.UART));
info!(
"{} {}",
moondancer::shared::usb::bManufacturerString,
moondancer::shared::usb::bProductString
);
info!("Logging initialized");

// usb1: aux (host on r0.4)
Expand Down
36 changes: 36 additions & 0 deletions device/firmware/moondancer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub use libgreat::firmware::BoardInformation;
// - constants ----------------------------------------------------------------

pub const SYSTEM_CLOCK_FREQUENCY: u32 = pac::clock::sysclk();

// TODO these should be sourced at runtime
pub const BOARD_INFORMATION: BoardInformation = BoardInformation {
board_id: 0x10_u32.to_le_bytes(),
version_string: "v2023.0.1\0",
Expand All @@ -40,6 +42,40 @@ pub const BOARD_INFORMATION: BoardInformation = BoardInformation {
pub const EP_MAX_ENDPOINTS: usize = 16;
pub const EP_MAX_PACKET_SIZE: usize = 512;

#[allow(non_upper_case_globals)]
pub mod shared {
/// The values in this module are statically generated at compile
/// time from the corresponding TOML files located in the
/// `cynthion.git/host/cynthion/shared/` directory.
pub mod libgreat {
static_toml::static_toml! {
static CONFIG = include_toml!("../../../host/cynthion/shared/libgreat.toml");
}
pub mod endpoints {
use super::CONFIG;
pub static bulk_in_address: u8 = CONFIG.endpoints.bulk_in_address as u8;
pub static bulk_out_address: u8 = CONFIG.endpoints.bulk_out_address as u8;
}
pub mod vendor {
use super::CONFIG;
pub static command_request: u8 = CONFIG.vendor.command_request as u8;
}
}

pub mod usb {
static_toml::static_toml! {
static CONFIG = include_toml!("../../../host/cynthion/shared/usb.toml");
}
pub static bVendorId: u16 = CONFIG.b_vendor_id.cynthion as u16;
pub static bProductId: u16 = CONFIG.b_product_id.cynthion as u16;
pub static bManufacturerString: &'static str = CONFIG.b_manufacturer_string.cynthion;
pub static bProductString: &'static str = CONFIG.b_product_string.cynthion;
pub static bInterfaceSubClass: u8 = CONFIG.b_interface_sub_class.moondancer as u8;
pub static bInterfaceProtocol: u8 = CONFIG.b_interface_protocol.moondancer as u8;
}
}

// - types --------------------------------------------------------------------

#[derive(Copy, Clone, Debug)]
Expand Down
80 changes: 29 additions & 51 deletions device/firmware/moondancer/src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,9 @@ use smolusb::descriptor::*;

// - constants ----------------------------------------------------------------

pub const VENDOR_ID: u16 = 0x1d50; // OpenMoko, Inc.
pub const PRODUCT_ID: u16 = 0x615b; // Cynthion USB Multitool

pub const DEVICE_VERSION_NUMBER: u16 = 0x0004; // Cynthion r0.4 TODO read from?
pub const DEVICE_SERIAL_STRING: &'static str = "r0.4"; // TODO read from?

/// libgreat backend interface subclass TODO document
///
/// 0x00 - Apollo / Flash Bridge Interface
/// 0x01..0x0f - Reserved
/// 0x10 - Analyzer
/// 0x11 - Moondancer
pub const LIBGREAT_INTERFACE_SUBCLASS: u8 = 0x11;

/// libgreat backend interface protocol version TODO document
///
/// 0x01 -> v0.1
/// 0x10 -> v1.0
pub const LIBGREAT_INTERFACE_PROTOCOL: u8 = 0x01;

pub const LIBGREAT_BULK_OUT_ENDPOINT_ADDRESS: u8 = 0x02;
pub const LIBGREAT_BULK_IN_ENDPOINT_ADDRESS: u8 = 0x81;

pub const LIBGREAT_BULK_OUT_ENDPOINT_NUMBER: u8 = LIBGREAT_BULK_OUT_ENDPOINT_ADDRESS;
pub const LIBGREAT_BULK_IN_ENDPOINT_NUMBER: u8 = LIBGREAT_BULK_IN_ENDPOINT_ADDRESS & 0x7f;

// - vendor request -----------------------------------------------------------

Expand Down Expand Up @@ -87,23 +65,24 @@ pub mod vendor {

// - descriptors --------------------------------------------------------------

pub const DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor {
use crate::shared;

pub static DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor {
descriptor_version: 0x0200,
device_class: 0x00, // Composite
device_subclass: 0x00, // Composite
device_protocol: 0x00, // Composite
max_packet_size: 64,
vendor_id: VENDOR_ID,
product_id: PRODUCT_ID,
vendor_id: shared::usb::bVendorId,
product_id: shared::usb::bProductId,
device_version_number: DEVICE_VERSION_NUMBER,
manufacturer_string_index: 1,
product_string_index: 2,
serial_string_index: 3,
num_configurations: 1,
..DeviceDescriptor::new()
};

pub const DEVICE_QUALIFIER_DESCRIPTOR: DeviceQualifierDescriptor = DeviceQualifierDescriptor {
pub static DEVICE_QUALIFIER_DESCRIPTOR: DeviceQualifierDescriptor = DeviceQualifierDescriptor {
descriptor_version: 0x0200,
device_class: 0x00, // Composite
device_subclass: 0x00, // Composite
Expand All @@ -113,7 +92,7 @@ pub const DEVICE_QUALIFIER_DESCRIPTOR: DeviceQualifierDescriptor = DeviceQualifi
..DeviceQualifierDescriptor::new()
};

pub const CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor = ConfigurationDescriptor::new(
pub static CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor = ConfigurationDescriptor::new(
ConfigurationDescriptorHeader {
descriptor_type: DescriptorType::Configuration as u8,
configuration_value: 1,
Expand All @@ -127,22 +106,22 @@ pub const CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor = ConfigurationDes
interface_number: 0,
alternate_setting: 0,
interface_class: 0xff, // Vendor-specific
interface_subclass: LIBGREAT_INTERFACE_SUBCLASS,
interface_protocol: LIBGREAT_INTERFACE_PROTOCOL,
interface_subclass: shared::usb::bInterfaceSubClass,
interface_protocol: shared::usb::bInterfaceProtocol,
interface_string_index: 5,
..InterfaceDescriptorHeader::new()
},
&[
EndpointDescriptor {
endpoint_address: LIBGREAT_BULK_IN_ENDPOINT_ADDRESS, // IN
attributes: 0x02, // Bulk
endpoint_address: shared::libgreat::endpoints::bulk_in_address, // IN
attributes: 0x02, // Bulk
max_packet_size: 512,
interval: 0,
..EndpointDescriptor::new()
},
EndpointDescriptor {
endpoint_address: LIBGREAT_BULK_OUT_ENDPOINT_ADDRESS, // OUT
attributes: 0x02, // Bulk
endpoint_address: shared::libgreat::endpoints::bulk_out_address, // OUT
attributes: 0x02, // Bulk
max_packet_size: 512,
interval: 0,
..EndpointDescriptor::new()
Expand All @@ -151,7 +130,7 @@ pub const CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor = ConfigurationDes
)],
);

pub const OTHER_SPEED_CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor =
pub static OTHER_SPEED_CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor =
ConfigurationDescriptor::new(
ConfigurationDescriptorHeader {
descriptor_type: DescriptorType::OtherSpeedConfiguration as u8,
Expand All @@ -166,22 +145,22 @@ pub const OTHER_SPEED_CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor =
interface_number: 0,
alternate_setting: 0,
interface_class: 0xff, // Vendor-specific
interface_subclass: LIBGREAT_INTERFACE_SUBCLASS,
interface_protocol: LIBGREAT_INTERFACE_PROTOCOL,
interface_subclass: shared::usb::bInterfaceSubClass,
interface_protocol: shared::usb::bInterfaceProtocol,
interface_string_index: 5,
..InterfaceDescriptorHeader::new()
},
&[
EndpointDescriptor {
endpoint_address: LIBGREAT_BULK_IN_ENDPOINT_ADDRESS, // IN
attributes: 0x02, // Bulk
endpoint_address: shared::libgreat::endpoints::bulk_in_address, // IN
attributes: 0x02, // Bulk
max_packet_size: 512,
interval: 0,
..EndpointDescriptor::new()
},
EndpointDescriptor {
endpoint_address: LIBGREAT_BULK_OUT_ENDPOINT_ADDRESS, // OUT
attributes: 0x02, // Bulk
endpoint_address: shared::libgreat::endpoints::bulk_out_address, // OUT
attributes: 0x02, // Bulk
max_packet_size: 512,
interval: 0,
..EndpointDescriptor::new()
Expand All @@ -190,19 +169,18 @@ pub const OTHER_SPEED_CONFIGURATION_DESCRIPTOR_0: ConfigurationDescriptor =
)],
);

pub const USB_STRING_DESCRIPTOR_0: StringDescriptorZero =
pub static USB_STRING_DESCRIPTOR_0: StringDescriptorZero =
StringDescriptorZero::new(&[LanguageId::EnglishUnitedStates]);

pub const USB_STRING_DESCRIPTOR_1: StringDescriptor = StringDescriptor::new("Great Scott Gadgets"); // manufacturer
pub const USB_STRING_DESCRIPTOR_2: StringDescriptor =
StringDescriptor::new("Cynthion USB Multitool"); // product
pub const USB_STRING_DESCRIPTOR_3: StringDescriptor = StringDescriptor::new(DEVICE_SERIAL_STRING); // serial
pub const USB_STRING_DESCRIPTOR_4: StringDescriptor = StringDescriptor::new("config0"); // configuration #0
pub const USB_STRING_DESCRIPTOR_5: StringDescriptor = StringDescriptor::new("interface0"); // interface #0
pub const USB_STRING_DESCRIPTOR_6: StringDescriptor = StringDescriptor::new("interface1"); // interface #1
pub const USB_STRING_DESCRIPTOR_7: StringDescriptor = StringDescriptor::new("config1"); // configuration #1
pub static USB_STRING_DESCRIPTOR_1: StringDescriptor = StringDescriptor::new(shared::usb::bManufacturerString); // manufacturer
pub static USB_STRING_DESCRIPTOR_2: StringDescriptor = StringDescriptor::new(shared::usb::bProductString); // product
pub static USB_STRING_DESCRIPTOR_3: StringDescriptor = StringDescriptor::new(DEVICE_SERIAL_STRING); // serial
pub static USB_STRING_DESCRIPTOR_4: StringDescriptor = StringDescriptor::new("config0"); // configuration #0
pub static USB_STRING_DESCRIPTOR_5: StringDescriptor = StringDescriptor::new("interface0"); // interface #0
pub static USB_STRING_DESCRIPTOR_6: StringDescriptor = StringDescriptor::new("interface1"); // interface #1
pub static USB_STRING_DESCRIPTOR_7: StringDescriptor = StringDescriptor::new("config1"); // configuration #1

pub const USB_STRING_DESCRIPTORS: &[&StringDescriptor] = &[
pub static USB_STRING_DESCRIPTORS: &[&StringDescriptor] = &[
&USB_STRING_DESCRIPTOR_1,
&USB_STRING_DESCRIPTOR_2,
&USB_STRING_DESCRIPTOR_3,
Expand Down
5 changes: 3 additions & 2 deletions device/firmware/moondancer/test/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
from pygreat.comms_backends.usb1 import USB1CommsBackend as backend

import cynthion
from cynthion import shared

VENDOR_ID = cynthion.board.CYNTHION_VENDOR_ID
PRODUCT_ID = cynthion.board.CYNTHION_PRODUCT_ID
VENDOR_ID = shared.usb.bVendorId.cynthion
PRODUCT_ID = shared.usb.bProductId.cynthion

EP_MAX_PACKET_SIZE = 512

Expand Down
7 changes: 4 additions & 3 deletions device/firmware/smolusb/src/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl TryFrom<u8> for DescriptorType {
/// USB device descriptor
///
/// TODO consider renaming descriptor fields according to LUNA / industry-standard names
#[derive(AsBytes, FromBytes)]
#[derive(AsBytes, FromBytes, Clone, Copy)]
#[repr(C, packed)]
pub struct DeviceDescriptor {
pub _length: u8, // 18
Expand Down Expand Up @@ -123,7 +123,7 @@ impl Default for DeviceDescriptor {
// - DeviceQualifierDescriptor ------------------------------------------------

/// USB device qualifier descriptor
#[derive(AsBytes, FromBytes)]
#[derive(AsBytes, FromBytes, Clone, Copy)]
#[repr(C, packed)]
pub struct DeviceQualifierDescriptor {
pub _length: u8, // 10
Expand Down Expand Up @@ -351,7 +351,7 @@ impl Default for EndpointDescriptor {
// - StringDescriptorZero -----------------------------------------------------

/// USB string descriptor language id
#[derive(AsBytes, Copy, Clone, Debug)]
#[derive(AsBytes, Clone, Copy, Debug)]
#[repr(u16)]
pub enum LanguageId {
EnglishUnitedStates = 0x0409,
Expand All @@ -363,6 +363,7 @@ pub enum LanguageId {
impl AsByteSliceIterator for LanguageId {}

/// USB string zero descriptor
#[derive(Clone, Copy)]
pub struct StringDescriptorZero<'a> {
head: StringDescriptorHeader,
tail: &'a [LanguageId],
Expand Down
31 changes: 31 additions & 0 deletions host/cynthion/shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#
# This file is part of Cynthion.
#

"""
The values in this module are generated at runtime from the
corresponding TOML files located in the `cynthion.git/host/cynthion/shared/`
directory.
"""

import tomllib

from collections import namedtuple
from importlib.resources import files
from os import path

SHARED_TOML_DIR = files("cynthion").joinpath("shared")

def _dict_to_namedtuple(data, typename="_"):
return namedtuple(typename, data.keys())(
*(_dict_to_namedtuple(v, typename + '_' + k) if isinstance(v, dict) else v for k, v in data.items())
)

with open(path.join(SHARED_TOML_DIR, "libgreat.toml"), "rb") as f:
libgreat = _dict_to_namedtuple(tomllib.load(f))

with open(path.join(SHARED_TOML_DIR, "registers.toml"), "rb") as f:
registers = _dict_to_namedtuple(tomllib.load(f))

with open(path.join(SHARED_TOML_DIR, "usb.toml"), "rb") as f:
usb = _dict_to_namedtuple(tomllib.load(f))
14 changes: 14 additions & 0 deletions host/cynthion/shared/libgreat.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
### libgreat
###
### This configuration file defines constants that are shared between
### the host and device implementations of the libgreat protocol.
###

# endpoint configurations
[endpoints]
bulk_in_address = 0x81
bulk_out_address = 0x02

# Vendor request constants
[vendor]
command_request = 0x65
4 changes: 4 additions & 0 deletions host/cynthion/shared/registers.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### registers
###
### TODO
###
Loading

0 comments on commit c4f1d15

Please sign in to comment.