usb_serial_interrupt.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //! CDC-ACM serial port example using interrupts.
  2. //! Target board: Blue Pill
  3. #![no_std]
  4. #![no_main]
  5. extern crate panic_semihosting;
  6. use cortex_m::asm::{delay, wfi};
  7. use cortex_m_rt::entry;
  8. use embedded_hal::digital::v2::OutputPin;
  9. use stm32f1xx_hal::pac::{interrupt, Interrupt};
  10. use stm32f1xx_hal::usb::{Peripheral, UsbBus, UsbBusType};
  11. use stm32f1xx_hal::{prelude::*, stm32};
  12. use usb_device::{bus::UsbBusAllocator, prelude::*};
  13. use usbd_serial::{SerialPort, USB_CLASS_CDC};
  14. static mut USB_BUS: Option<UsbBusAllocator<UsbBusType>> = None;
  15. static mut USB_SERIAL: Option<usbd_serial::SerialPort<UsbBusType>> = None;
  16. static mut USB_DEVICE: Option<UsbDevice<UsbBusType>> = None;
  17. #[entry]
  18. fn main() -> ! {
  19. let p = cortex_m::Peripherals::take().unwrap();
  20. let dp = pac::Peripherals::take().unwrap();
  21. let mut flash = dp.FLASH.constrain();
  22. let mut rcc = dp.RCC.constrain();
  23. let clocks = rcc
  24. .cfgr
  25. .use_hse(8.mhz())
  26. .sysclk(48.mhz())
  27. .pclk1(24.mhz())
  28. .freeze(&mut flash.acr);
  29. assert!(clocks.usbclk_valid());
  30. let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
  31. // BluePill board has a pull-up resistor on the D+ line.
  32. // Pull the D+ pin down to send a RESET condition to the USB bus.
  33. // This forced reset is needed only for development, without it host
  34. // will not reset your device when you upload new firmware.
  35. let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);
  36. usb_dp.set_low();
  37. delay(clocks.sysclk().0 / 100);
  38. let usb_dm = gpioa.pa11;
  39. let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh);
  40. let usb = Peripheral {
  41. usb: dp.USB,
  42. pin_dm: usb_dm,
  43. pin_dp: usb_dp,
  44. };
  45. // Unsafe to allow access to static variables
  46. unsafe {
  47. let bus = UsbBus::new(usb);
  48. USB_BUS = Some(bus);
  49. USB_SERIAL = Some(SerialPort::new(USB_BUS.as_ref().unwrap()));
  50. let usb_dev = UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x16c0, 0x27dd))
  51. .manufacturer("Fake company")
  52. .product("Serial port")
  53. .serial_number("TEST")
  54. .device_class(USB_CLASS_CDC)
  55. .build();
  56. USB_DEVICE = Some(usb_dev);
  57. }
  58. let mut nvic = p.NVIC;
  59. nvic.enable(Interrupt::USB_HP_CAN_TX);
  60. nvic.enable(Interrupt::USB_LP_CAN_RX0);
  61. loop {
  62. wfi();
  63. }
  64. }
  65. #[interrupt]
  66. fn USB_HP_CAN_TX() {
  67. usb_interrupt();
  68. }
  69. #[interrupt]
  70. fn USB_LP_CAN_RX0() {
  71. usb_interrupt();
  72. }
  73. fn usb_interrupt() {
  74. let usb_dev = unsafe { USB_DEVICE.as_mut().unwrap() };
  75. let serial = unsafe { USB_SERIAL.as_mut().unwrap() };
  76. if !usb_dev.poll(&mut [serial]) {
  77. return;
  78. }
  79. let mut buf = [0u8; 8];
  80. match serial.read(&mut buf) {
  81. Ok(count) if count > 0 => {
  82. // Echo back in upper case
  83. for c in buf[0..count].iter_mut() {
  84. if 0x61 <= *c && *c <= 0x7a {
  85. *c &= !0x20;
  86. }
  87. }
  88. serial.write(&buf[0..count]).ok();
  89. }
  90. _ => {}
  91. }
  92. }