#![no_std]
#![no_main]
extern crate panic_semihosting;
use cortex_m::asm::{delay, wfi};
use cortex_m_rt::entry;
use stm32f1xx_hal::pac::{self, interrupt, Interrupt, NVIC};
use stm32f1xx_hal::prelude::*;
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;
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(8.MHz())
.sysclk(48.MHz())
.pclk1(24.MHz())
.freeze(&mut flash.acr);
assert!(clocks.usbclk_valid());
let mut gpioa = dp.GPIOA.split();
let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);
usb_dp.set_low();
delay(clocks.sysclk().raw() / 100);
let usb_dm = gpioa.pa11;
let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh);
let usb = Peripheral {
usb: dp.USB,
pin_dm: usb_dm,
pin_dp: usb_dp,
};
unsafe {
let bus = UsbBus::new(usb);
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(0x16c0, 0x27dd))
.manufacturer("Fake company")
.product("Serial port")
.serial_number("TEST")
.device_class(USB_CLASS_CDC)
.build();
USB_DEVICE = Some(usb_dev);
}
unsafe {
NVIC::unmask(Interrupt::USB_HP_CAN_TX);
NVIC::unmask(Interrupt::USB_LP_CAN_RX0);
}
loop {
wfi();
}
}
#[interrupt]
fn USB_HP_CAN_TX() {
usb_interrupt();
}
#[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 => {
for c in buf[0..count].iter_mut() {
if 0x61 <= *c && *c <= 0x7a {
*c &= !0x20;
}
}
serial.write(&buf[0..count]).ok();
}
_ => {}
}
}