usb_serial_rtfm.rs 3.0 KB

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