aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock22
-rw-r--r--Cargo.toml2
-rw-r--r--README.md13
-rw-r--r--src/device.rs16
-rw-r--r--src/hid.rs88
-rw-r--r--src/main.rs35
6 files changed, 172 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 66b28e2..5437476 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -72,7 +72,9 @@ dependencies = [
"cortex-m-rt 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stm32f103xx-usb 0.1.0 (git+https://github.com/mvirkkunen/stm32f103xx-usb?rev=57d23751367461bec5f39322727bdd65e5c2aa30)",
"stm32f1xx-hal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "usb-device 0.2.0 (git+https://github.com/mvirkkunen/usb-device?rev=e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3)",
]
[[package]]
@@ -150,6 +152,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m-rt 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "stm32f103xx-usb"
+version = "0.1.0"
+source = "git+https://github.com/mvirkkunen/stm32f103xx-usb?rev=57d23751367461bec5f39322727bdd65e5c2aa30#57d23751367461bec5f39322727bdd65e5c2aa30"
+dependencies = [
+ "bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cortex-m 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stm32f1xx-hal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "usb-device 0.2.0 (git+https://github.com/mvirkkunen/usb-device?rev=e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3)",
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -183,6 +198,11 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "usb-device"
+version = "0.2.0"
+source = "git+https://github.com/mvirkkunen/usb-device?rev=e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3#e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3"
+
+[[package]]
name = "vcell"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -220,9 +240,11 @@ dependencies = [
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum stm32f1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48763f6f093674476399efbd8d2e52349dc32c3bbf57657234cbb15d309cd8a3"
+"checksum stm32f103xx-usb 0.1.0 (git+https://github.com/mvirkkunen/stm32f103xx-usb?rev=57d23751367461bec5f39322727bdd65e5c2aa30)" = "<none>"
"checksum stm32f1xx-hal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f410543fc282d51e181e3cf5c8adff303d9e5ae8b9eb731e6a07f58a4cec4265"
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum usb-device 0.2.0 (git+https://github.com/mvirkkunen/usb-device?rev=e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3)" = "<none>"
"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
diff --git a/Cargo.toml b/Cargo.toml
index aa96ab0..e3614d5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,8 @@ cortex-m = "0.5.8"
cortex-m-rt = "0.6.7"
embedded-hal = "0.2.2"
panic-halt = "0.2.0"
+stm32f103xx-usb = { git = "https://github.com/mvirkkunen/stm32f103xx-usb", rev = "57d23751367461bec5f39322727bdd65e5c2aa30" }
+usb-device = { git = "https://github.com/mvirkkunen/usb-device", rev = "e58e30f3b9c9bf4aab00ea039d129b964a3fd2d3" }
[dependencies.hal]
package = "stm32f1xx-hal"
diff --git a/README.md b/README.md
index d026801..7570d2e 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,9 @@ SPDX-License-Identifier: CC0-1.0
# ntw
`ntw` is an experimental firmware for the Nitrokey Pro. It is in very early
-development and currently does not support any commands.
+development and supports:
+
+- connecting as a USB device with the Nitrokey Pro’s product and vendor ID
## Resources
@@ -21,6 +23,15 @@ development and currently does not support any commands.
[STM32F103RB-ds]: https://www.st.com/resource/en/datasheet/stm32f103rb.pdf
[STM32F103RB-rm]: https://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf
+### Protocols
+
+- [Universal Serial Bus Specification][usb], Revision 1.1
+- [Universal Serial Bus: Device Class Definition for Human Interface Devices
+ (HID)][hid], Firmware Specification, Version 1.11
+
+[usb]: http://esd.cs.ucr.edu/webres/usb11.pdf
+[hid]: https://www.usb.org/sites/default/files/documents/hid1_11.pdf
+
## Contact
For bug reports, patches, feature requests or other messages, please send a
diff --git a/src/device.rs b/src/device.rs
new file mode 100644
index 0000000..ea732e6
--- /dev/null
+++ b/src/device.rs
@@ -0,0 +1,16 @@
+// Copyright 2019 Robin Krahl <robin.krahl@ireas.org>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+use usb_device::bus::{UsbBus, UsbBusAllocator};
+use usb_device::device::{UsbDevice, UsbDeviceBuilder, UsbVidPid};
+
+const VID_CLAY_LOGIC: u16 = 0x20a0;
+const PID_NITROKEY_PRO: u16 = 0x4108;
+
+pub fn create_usb_device<B: UsbBus>(alloc: &UsbBusAllocator<B>) -> UsbDevice<'_, B> {
+ UsbDeviceBuilder::new(alloc, UsbVidPid(VID_CLAY_LOGIC, PID_NITROKEY_PRO))
+ .manufacturer("Nitrokey/ntw")
+ .product("Nitrokey Pro/ntw")
+ .serial_number("?")
+ .build()
+}
diff --git a/src/hid.rs b/src/hid.rs
new file mode 100644
index 0000000..4f1d506
--- /dev/null
+++ b/src/hid.rs
@@ -0,0 +1,88 @@
+// Copyright 2019 Robin Krahl <robin.krahl@ireas.org>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+use core::marker::PhantomData;
+
+use usb_device::bus::{InterfaceNumber, StringIndex, UsbBus, UsbBusAllocator};
+use usb_device::class::{ControlIn, ControlOut, UsbClass};
+use usb_device::descriptor::DescriptorWriter;
+use usb_device::endpoint::EndpointAddress;
+use usb_device::Result;
+
+const INTERFACE_CLASS_HID: u8 = 0x03;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(u8)]
+pub enum Subclass {
+ None = 0x00,
+ BootInterface = 0x01,
+}
+
+impl From<Subclass> for u8 {
+ fn from(subclass: Subclass) -> u8 {
+ subclass as u8
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(u8)]
+pub enum Protocol {
+ None = 0x00,
+ Keyboard = 0x01,
+ Mouse = 0x02,
+}
+
+impl From<Protocol> for u8 {
+ fn from(protocol: Protocol) -> u8 {
+ protocol as u8
+ }
+}
+
+pub struct HidClass<'a, B: UsbBus> {
+ interface: InterfaceNumber,
+ subclass: Subclass,
+ protocol: Protocol,
+ marker: PhantomData<&'a B>,
+}
+
+impl<B: UsbBus> HidClass<'_, B> {
+ pub fn new(
+ alloc: &UsbBusAllocator<B>,
+ subclass: Subclass,
+ protocol: Protocol,
+ ) -> HidClass<'_, B> {
+ HidClass {
+ interface: alloc.interface(),
+ subclass,
+ protocol,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<B: UsbBus> UsbClass<B> for HidClass<'_, B> {
+ fn poll(&mut self) {}
+
+ fn reset(&mut self) {}
+
+ fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
+ writer.interface(
+ self.interface,
+ INTERFACE_CLASS_HID,
+ self.subclass.into(),
+ self.protocol.into(),
+ )
+ }
+
+ fn get_string(&self, _index: StringIndex, _lang_id: u16) -> Option<&str> {
+ None
+ }
+
+ fn endpoint_in_complete(&mut self, _addr: EndpointAddress) {}
+
+ fn endpoint_out(&mut self, _addr: EndpointAddress) {}
+
+ fn control_in(&mut self, _xfer: ControlIn<B>) {}
+
+ fn control_out(&mut self, _xfer: ControlOut<B>) {}
+}
diff --git a/src/main.rs b/src/main.rs
index d76cf33..b0ecafd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,14 +5,43 @@
#![no_main]
extern crate panic_halt;
-extern crate hal;
-use cortex_m::asm;
+mod device;
+mod hid;
+
use cortex_m_rt::entry;
+use hal::prelude::*;
+use stm32f103xx_usb::UsbBus;
+use usb_device::class::UsbClass;
+
+use crate::hid::{HidClass, Protocol, Subclass};
#[entry]
fn main() -> ! {
+ let p = hal::stm32::Peripherals::take().unwrap();
+
+ let mut flash = p.FLASH.constrain();
+ let mut rcc = p.RCC.constrain();
+
+ let clocks = rcc
+ .cfgr
+ .use_hse(8.mhz())
+ .sysclk(48.mhz())
+ .pclk1(24.mhz())
+ .freeze(&mut flash.acr);
+
+ assert!(clocks.usbclk_valid(), "USB clocks not valid");
+
+ let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
+
+ let usb_bus = UsbBus::usb_with_reset(p.USB, &mut rcc.apb1, &clocks, &mut gpioa.crh, gpioa.pa12);
+ let mut usb_class = HidClass::new(&usb_bus, Subclass::BootInterface, Protocol::Keyboard);
+ let mut usb_dev = device::create_usb_device(&usb_bus);
+ usb_dev.force_reset().expect("USB reset failed");
+
loop {
- asm::nop();
+ if usb_dev.poll(&mut [&mut usb_class]) {
+ usb_class.poll();
+ }
}
}