use core::fmt::Write; 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> = None; static mut USB_SERIAL: Option> = None; static mut USB_DEVICE: Option> = None; pub struct USB { } impl USB { pub fn new( usb: stm32f1xx_hal::pac::USB, pin_dm: gpio::gpioa::PA11>, pin_dp: gpio::gpioa::PA12>) -> 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]; let mut string = arrayvec::ArrayString::<[_; 16]>::new(); match serial.read(&mut buf) { Ok(count) if count > 0 => { // Echo back in upper case for c in buf[0..count].iter_mut() { write!(string, "{:02x}", *c).ok(); } serial.write(string.as_bytes()).ok(); string.clear(); } _ => {} } }