aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2021-03-31 17:40:53 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2021-03-31 17:40:53 +0200
commit62fdd309c55286222d1add4ca3051353da0e11b8 (patch)
tree1beb88a3d2e4b977b170f41f6d6de020aad8bf46
parentb2b6ac9eea2eb5066942237bfced3f7f8b48c43c (diff)
downloadpicardy-62fdd309c55286222d1add4ca3051353da0e11b8.tar.gz
picardy-62fdd309c55286222d1add4ca3051353da0e11b8.tar.bz2
picardy-62fdd309c55286222d1add4ca3051353da0e11b8.zip
Enable USB CDC ACM for eval-clock-cw-tx
-rw-r--r--sw/eval-clock-cw-tx/Cargo.lock31
-rw-r--r--sw/eval-clock-cw-tx/Cargo.toml4
-rw-r--r--sw/eval-clock-cw-tx/Makefile2
-rw-r--r--sw/eval-clock-cw-tx/src/main.rs14
-rw-r--r--sw/eval-clock-cw-tx/src/usb.rs91
5 files changed, 140 insertions, 2 deletions
diff --git a/sw/eval-clock-cw-tx/Cargo.lock b/sw/eval-clock-cw-tx/Cargo.lock
index 8007053..e0152f2 100644
--- a/sw/eval-clock-cw-tx/Cargo.lock
+++ b/sw/eval-clock-cw-tx/Cargo.lock
@@ -146,6 +146,8 @@ dependencies = [
"shared-bus",
"si5351",
"stm32f1xx-hal",
+ "usb-device",
+ "usbd-serial",
]
[[package]]
@@ -281,6 +283,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
+name = "stm32-usbd"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70d13eca735cae37df697f599777b000cc0ee924df8452f2b4bfaa6798ab0338"
+dependencies = [
+ "cortex-m 0.6.7",
+ "usb-device",
+ "vcell",
+]
+
+[[package]]
name = "stm32f1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -304,6 +317,7 @@ dependencies = [
"embedded-dma",
"embedded-hal",
"nb 0.1.3",
+ "stm32-usbd",
"stm32f1",
"void",
]
@@ -332,6 +346,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
+name = "usb-device"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6be90410d4772074ea49525e2e753b65920b94b57eee21a6ef7b6a6fe6296245"
+
+[[package]]
+name = "usbd-serial"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db75519b86287f12dcf0d171c7cf4ecc839149fe9f3b720ac4cfce52959e1dfe"
+dependencies = [
+ "embedded-hal",
+ "nb 0.1.3",
+ "usb-device",
+]
+
+[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/sw/eval-clock-cw-tx/Cargo.toml b/sw/eval-clock-cw-tx/Cargo.toml
index b56ac96..ebf3e20 100644
--- a/sw/eval-clock-cw-tx/Cargo.toml
+++ b/sw/eval-clock-cw-tx/Cargo.toml
@@ -15,11 +15,13 @@ cortex-m-semihosting = "0.3"
panic-semihosting = "0.5"
nb = "1.0"
#stm32h7 = { version = "0.9", features = ["stm32h743", "rt"] }
-stm32f1xx-hal = { version = "0.7", features = ["rt", "stm32f103", "medium"] }
+stm32f1xx-hal = { version = "0.7", features = ["rt", "stm32f103", "medium", "stm32-usbd"] }
embedded-hal = { version = "0.2", features = [] }
shared-bus = { version = "0.2", features = ["cortex-m"] }
hd44780-driver = { path = "../deps/hd44780-driver"}
si5351 = { path = "../deps/si5351" }
+usb-device = { version = "0.2" }
+usbd-serial = { version = "0.1" }
[profile.dev]
codegen-units = 1
diff --git a/sw/eval-clock-cw-tx/Makefile b/sw/eval-clock-cw-tx/Makefile
index 8c5fc79..1679b79 100644
--- a/sw/eval-clock-cw-tx/Makefile
+++ b/sw/eval-clock-cw-tx/Makefile
@@ -1,7 +1,7 @@
.PHONY: all openocd debug
OPENOCD := openocd
-OPENOCD_OPT := -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
+OPENOCD_OPT := -f interface/stlink.cfg -f target/stm32f1x.cfg
BIN := target/thumbv7m-none-eabi/debug/picardy
# Build and flash in release mode
diff --git a/sw/eval-clock-cw-tx/src/main.rs b/sw/eval-clock-cw-tx/src/main.rs
index c91c545..d30318b 100644
--- a/sw/eval-clock-cw-tx/src/main.rs
+++ b/sw/eval-clock-cw-tx/src/main.rs
@@ -46,6 +46,7 @@ use embedded_hal::digital::v2::InputPin;
use hd44780_driver::{Cursor, CursorBlink, Display, DisplayMode, HD44780};
pub mod ui;
+pub mod usb;
pub mod cw;
pub mod state;
pub mod si_clock;
@@ -92,8 +93,14 @@ fn main() -> ! {
let mut rcc = dp.RCC.constrain();
let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
let clocks = rcc.cfgr
+ .use_hse(16.mhz())
+ .sysclk(48.mhz())
+ .pclk1(24.mhz())
.adcclk(2.mhz())
.freeze(&mut flash.acr);
+
+ assert!(clocks.usbclk_valid());
+
let mut delay = Delay::new(cp.SYST, clocks);
delay.delay_ms(200u16);
@@ -102,6 +109,10 @@ fn main() -> ! {
let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
+ let usb_dm = gpioa.pa11;
+ let usb_dp = gpioa.pa12.into_floating_input(&mut gpioa.crh);
+ let usb = usb::USB::new(dp.USB, usb_dm, usb_dp);
+
// Buttons as analog inputs (multi-level)
let pb0 = gpiob.pb0.into_floating_input(&mut gpiob.crl); // BTN1 Button B, has external pullup
let pb1 = gpiob.pb1.into_floating_input(&mut gpiob.crl); // BTN0 Button A, has external pullup
@@ -173,6 +184,7 @@ fn main() -> ! {
lcd.write_str(" 30m CW TX 2021 ", &mut delay).unwrap();
delay.delay_ms(1_500u16);
+ usb.enable_interrupts();
let mut siclock = {
let shared = unsafe { &mut *SHARED.as_mut_ptr() };
@@ -349,6 +361,7 @@ fn TIM2() {
}
}
+#[allow(non_snake_case)]
#[cortex_m_rt::exception]
fn HardFault(ef: &ExceptionFrame) -> ! {
let periph = unsafe { cortex_m::Peripherals::steal() };
@@ -360,6 +373,7 @@ fn HardFault(ef: &ExceptionFrame) -> ! {
loop { }
}
+#[allow(non_snake_case)]
#[cortex_m_rt::exception]
fn DefaultHandler(irqn: i16) {
hprintln!("Unhandled exception (IRQn = {})", irqn).unwrap();
diff --git a/sw/eval-clock-cw-tx/src/usb.rs b/sw/eval-clock-cw-tx/src/usb.rs
new file mode 100644
index 0000000..941a024
--- /dev/null
+++ b/sw/eval-clock-cw-tx/src/usb.rs
@@ -0,0 +1,91 @@
+
+use stm32f1xx_hal::gpio;
+use stm32f1xx_hal::pac;
+use stm32f1xx_hal::pac::{interrupt, Interrupt};
+use stm32f1xx_hal::usb::{Peripheral, UsbBus, UsbBusType};
+use usb_device::{bus::UsbBusAllocator, prelude::*};
+use usbd_serial::{SerialPort, USB_CLASS_CDC};
+
+static mut USB_BUS: Option<UsbBusAllocator<UsbBusType>> = None;
+static mut USB_SERIAL: Option<usbd_serial::SerialPort<UsbBusType>> = None;
+static mut USB_DEVICE: Option<UsbDevice<UsbBusType>> = None;
+
+pub struct USB {
+}
+
+impl USB {
+ pub fn new(
+ usb: stm32f1xx_hal::pac::USB,
+ pin_dm: gpio::gpioa::PA11<gpio::Input<gpio::Floating>>,
+ pin_dp: gpio::gpioa::PA12<gpio::Input<gpio::Floating>>) -> Self {
+
+ let peripheral = Peripheral {
+ usb,
+ pin_dm,
+ pin_dp,
+ };
+
+ unsafe {
+ let bus = UsbBus::new(peripheral);
+
+ USB_BUS = Some(bus);
+
+ USB_SERIAL = Some(SerialPort::new(USB_BUS.as_ref().unwrap()));
+
+ let usb_dev = UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x1d50, 0x5120)) // Openmoko Neo1973 serial
+ .manufacturer("HB9EGM")
+ .product("Beep Machine")
+ .serial_number("1")
+ .device_class(USB_CLASS_CDC)
+ .build();
+
+ USB_DEVICE = Some(usb_dev);
+ }
+
+ USB{}
+ }
+
+ pub fn enable_interrupts(&self) {
+ unsafe {
+ pac::NVIC::unmask(Interrupt::USB_HP_CAN_TX);
+ pac::NVIC::unmask(Interrupt::USB_LP_CAN_RX0);
+ }
+ }
+}
+
+#[allow(non_snake_case)]
+#[interrupt]
+fn USB_HP_CAN_TX() {
+ usb_interrupt();
+}
+
+#[allow(non_snake_case)]
+#[interrupt]
+fn USB_LP_CAN_RX0() {
+ usb_interrupt();
+}
+
+fn usb_interrupt() {
+ let usb_dev = unsafe { USB_DEVICE.as_mut().unwrap() };
+ let serial = unsafe { USB_SERIAL.as_mut().unwrap() };
+
+ if !usb_dev.poll(&mut [serial]) {
+ return;
+ }
+
+ let mut buf = [0u8; 8];
+
+ match serial.read(&mut buf) {
+ Ok(count) if count > 0 => {
+ // Echo back in upper case
+ for c in buf[0..count].iter_mut() {
+ if 0x61 <= *c && *c <= 0x7a {
+ *c &= !0x20;
+ }
+ }
+
+ serial.write(&buf[0..count]).ok();
+ }
+ _ => {}
+ }
+}