Working version with interrupts and buffer for read

This commit is contained in:
Sebastian 2020-05-11 14:56:17 +02:00
parent 34365925d1
commit 402e8e64ab
2 changed files with 50 additions and 26 deletions

View File

@ -12,3 +12,4 @@ panic-semihosting = "0.5"
usb-device = "0.2.4"
usbd-serial = "0.1"
embedded-hal = "0.2.3"
bbqueue = "0.4.4"

View File

@ -7,17 +7,23 @@ use core::cell::RefCell;
use core::ops::DerefMut;
use cortex_m::asm::wfi;
use cortex_m::peripheral::NVIC;
use cortex_m::interrupt::{free as interrupt_free, Mutex};
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;
use stm32f1xx_hal::stm32::{self, interrupt, Interrupt};
use stm32f1xx_hal::{delay::Delay, prelude::*};
use stm32f1xx_hal::usb::{Peripheral, UsbBusType};
use stm32f1xx_hal::{delay::Delay, prelude::*};
use usb_device::bus::UsbBusAllocator;
use usb_device::prelude::*;
use usbd_serial::{SerialPort, USB_CLASS_CDC};
#[cfg(not(feature = "atomic"))]
use bbqueue::{consts::*, BBBuffer, ConstBBBuffer, Producer};
static RX_QUEUE: BBBuffer<U128> = BBBuffer(ConstBBBuffer::new());
static RX_PROD: Mutex<RefCell<Option<Producer<U128>>>> = Mutex::new(RefCell::new(None));
static mut USB_BUS: Option<UsbBusAllocator<UsbBusType>> = None;
static USB_DEVICE: Mutex<RefCell<Option<UsbDevice<'static, UsbBusType>>>> =
Mutex::new(RefCell::new(None));
@ -65,6 +71,8 @@ fn main() -> ! {
usb_bus = USB_BUS.as_ref().unwrap();
}
let (rx_prod, mut rx_cons) = RX_QUEUE.try_split().unwrap();
interrupt_free(|cs| {
SERIAL.borrow(cs).replace(Some(SerialPort::new(usb_bus)));
USB_DEVICE.borrow(cs).replace(Some(
@ -75,6 +83,8 @@ fn main() -> ! {
.device_class(USB_CLASS_CDC)
.build(),
));
RX_PROD.borrow(cs).replace(Some(rx_prod));
});
unsafe {
@ -84,6 +94,30 @@ fn main() -> ! {
loop {
wfi();
if let Ok(rgr) = rx_cons.read() {
for c in rgr.iter() {
let resp = match *c {
97u8 => {
led.set_high().unwrap();
"LED turned off\n\r"
}
98u8 => {
led.set_low().unwrap();
"LED turned on\n\r"
}
_ => "",
};
interrupt_free(|cs| {
if let Some(serial) = SERIAL.borrow(cs).borrow_mut().deref_mut() {
serial.write(resp.as_bytes()).unwrap();
}
});
}
let len = rgr.len();
rgr.release(len);
}
}
}
@ -99,34 +133,23 @@ fn USB_LP_CAN_RX0() {
fn usb_interrupt() {
interrupt_free(|cs| {
match USB_DEVICE.borrow(cs).borrow_mut().deref_mut() {
Some(usb_dev) => {
match SERIAL.borrow(cs).borrow_mut().deref_mut() {
Some(serial) => {
if !usb_dev.poll(&mut [serial]) {
return;
}
if let Some(usb_dev) = USB_DEVICE.borrow(cs).borrow_mut().deref_mut() {
if let Some(serial) = SERIAL.borrow(cs).borrow_mut().deref_mut() {
if !usb_dev.poll(&mut [serial]) {
return;
}
let mut buf = [0u8; 8];
match serial.read(&mut buf) {
if let Some(rx_prod) = RX_PROD.borrow(cs).borrow_mut().deref_mut() {
if let Ok(mut wgr) = rx_prod.grant_exact(64) {
match serial.read(&mut wgr) {
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();
wgr.commit(count);
}
_ => {}
};
_ => wgr.commit(0),
}
}
_ => {}
};
}
}
_ => {}
};
}
});
}