-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathusb.rs
121 lines (99 loc) · 3.57 KB
/
usb.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![deny(warnings)] // If the Rust compiler generates a warning, stop the compilation with an error.
use cortex_m::asm::delay;
use stm32f1xx_hal::pac::USB;
use usb_device::{prelude::*, class_prelude::UsbBusAllocator};
use usbd_serial::{SerialPort, USB_CLASS_CDC};
use stm32f1xx_hal::{usb, rcc::Clocks};
pub struct UsbBus {
pub bus: UsbBusAllocator<usb::UsbBus<usb::Peripheral>>,
}
impl UsbBus {
pub fn new(
clocks: &Clocks,
usb: USB,
usb_dp: stm32f1xx_hal::gpio::Pin<stm32f1xx_hal::gpio::Input<stm32f1xx_hal::gpio::Floating>, stm32f1xx_hal::gpio::CRH, 'A', 12_u8>,
usb_dm: stm32f1xx_hal::gpio::Pin<stm32f1xx_hal::gpio::Input<stm32f1xx_hal::gpio::Floating>, stm32f1xx_hal::gpio::CRH, 'A', 11_u8>,
crh: &mut stm32f1xx_hal::gpio::Cr<stm32f1xx_hal::gpio::CRH, 'A'>,
) -> UsbBus {
assert!(clocks.usbclk_valid());
// BluePill board has a pull-up resistor on the D+ line.
// Pull the D+ pin down to send a RESET condition to the USB bus.
// This forced reset is needed only for development, without it host
// will not reset your device when you upload new firmware.
let mut usb_dp = usb_dp.into_push_pull_output(crh);
usb_dp.set_low();
delay(clocks.sysclk().raw() / 100);
let usb_dm = usb_dm.into_floating_input(crh);
let usb_dp = usb_dp.into_floating_input(crh);
let usb = usb::Peripheral {
usb,
pin_dm: usb_dm,
pin_dp: usb_dp,
};
UsbBus {
bus: usb::UsbBus::new(usb)
}
}
}
pub struct UsbSerial<'a> {
dev: UsbDevice<'a, usb::UsbBus<usb::Peripheral>>,
serial: SerialPort<'a, usb::UsbBus<usb::Peripheral>>,
quiet_mode: bool,
}
impl<'a> UsbSerial<'a> {
pub fn new(
mybus: &'a UsbBus
) -> UsbSerial {
let usb_serial = SerialPort::new(&mybus.bus);
// https://github.com/obdev/v-usb/blob/master/usbdrv/USB-IDs-for-free.txt
let usb_dev = UsbDeviceBuilder::new(&mybus.bus, UsbVidPid(0x16c0, 0x05e1))
.manufacturer("Castor https://avaruuskerho.fi")
.product("LED Matrix 72x16")
.serial_number("1")
.device_class(USB_CLASS_CDC)
.build();
UsbSerial {
dev: usb_dev,
serial: usb_serial,
quiet_mode: false,
}
}
pub fn poll(&mut self) -> bool {
self.dev.poll(&mut [&mut self.serial])
}
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, UsbError>{
self.serial.read(buf)
}
pub fn write(&mut self, buf: &[u8]) -> usize {
if self.quiet_mode {
return buf.len();
} else {
loop {
let result = self.serial.write(buf);
if let Ok(count) = result {
return count;
}
}
}
}
pub fn write_str(&mut self, message: &str) -> usize {
let bytes = message.as_bytes();
let mut bytes_remaining = message.len();
let mut bytes_written = 0;
while bytes_remaining > 0 {
let range_start = bytes_written;
let range_end = if bytes_remaining > 32 {
bytes_written + 32
} else {
bytes_written + bytes_remaining
};
let written = self.write(&bytes[range_start..range_end]);
bytes_written += written;
bytes_remaining -= written;
}
return bytes_written
}
pub fn set_quiet(&mut self, quiet_mode: bool) {
self.quiet_mode = quiet_mode;
}
}