From 4187928e26bce1c679b7f5294248bc0e02c4de9b Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Sun, 26 Apr 2020 17:01:54 +0200 Subject: [PATCH] Initial Commit with polling --- .cargo/config | 9 +++++ .gitignore | 4 +++ Cargo.toml | 14 ++++++++ build.rs | 15 ++++++++ memory.x | 6 ++++ openocd.gdb | 11 ++++++ openocd.sh | 2 ++ src/main.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 155 insertions(+) create mode 100644 .cargo/config create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 memory.x create mode 100644 openocd.gdb create mode 100755 openocd.sh create mode 100644 src/main.rs diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..452cdff --- /dev/null +++ b/.cargo/config @@ -0,0 +1,9 @@ +[target.thumbv7m-none-eabi] +runner = "arm-none-eabi-gdb -q -x openocd.gdb" +rustflags = [ + "-C", "linker=rust-lld", + "-C", "link-arg=-Tlink.x", +] + +[build] +target = "thumbv7m-none-eabi" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fc3d32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target/ +Cargo.lock + +.gdb_history diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..59a01ba --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "stm32-usbd-usart" +version = "0.1.0" +authors = ["Sebastian Schumb "] +edition = "2018" + +[dependencies] +cortex-m = "0.6" +cortex-m-rt = "0.6" +stm32f1xx-hal = { version = "0.5", features = ["stm32f103", "stm32-usbd", "rt"] } +panic-semihosting = "0.5" +usb-device = "0.2.4" +usbd-serial = "0.1" +embedded-hal = "0.2.3" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..6cba4d6 --- /dev/null +++ b/build.rs @@ -0,0 +1,15 @@ +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put the linker script somewhere the linker can find it + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + fs::File::create(out_dir.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..952e87e --- /dev/null +++ b/memory.x @@ -0,0 +1,6 @@ +/* STM32F103C8T6 */ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 64K + RAM : ORIGIN = 0x20000000, LENGTH = 20K +} diff --git a/openocd.gdb b/openocd.gdb new file mode 100644 index 0000000..7aed67f --- /dev/null +++ b/openocd.gdb @@ -0,0 +1,11 @@ +set history save on +set confirm off +target extended-remote :3333 +set print asm-demangle on +monitor arm semihosting enable +monitor reset halt +load +# monitor verify +# monitor reset +# quit +continue diff --git a/openocd.sh b/openocd.sh new file mode 100755 index 0000000..7d889ae --- /dev/null +++ b/openocd.sh @@ -0,0 +1,2 @@ +#!/bin/bash +openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..7e52706 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,94 @@ +#![no_std] +#![no_main] + +extern crate panic_semihosting; + +use cortex_m::asm::delay; +use cortex_m_rt::entry; +use embedded_hal::digital::v2::OutputPin; +use stm32f1xx_hal::usb::{Peripheral, UsbBus}; +use stm32f1xx_hal::{prelude::*, stm32}; +use usb_device::prelude::*; +use usbd_serial::{SerialPort, USB_CLASS_CDC}; + +#[entry] +fn main() -> ! { + let dp = stm32::Peripherals::take().unwrap(); + + let mut flash = dp.FLASH.constrain(); + let mut 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()); + + // Configure the on-board LED (PC13, green) + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); + let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); + led.set_high().ok(); // Turn off + + let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); + + // 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 = gpioa.pa12.into_push_pull_output(&mut gpioa.crh); + usb_dp.set_low().ok(); + delay(clocks.sysclk().0 / 100); + + let usb = Peripheral { + usb: dp.USB, + pin_dm: gpioa.pa11, + pin_dp: usb_dp.into_floating_input(&mut gpioa.crh), + }; + let usb_bus = UsbBus::new(usb); + + let mut serial = SerialPort::new(&usb_bus); + + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) + .manufacturer("Fake company") + .product("Serial port") + .serial_number("TEST") + .device_class(USB_CLASS_CDC) + .build(); + + loop { + if !usb_dev.poll(&mut [&mut serial]) { + continue; + } + + let mut buf = [0u8; 64]; + + match serial.read(&mut buf) { + Ok(count) if count > 0 => { + led.set_low().ok(); // Turn on + + // Echo back in upper case + for c in buf[0..count].iter_mut() { + if 0x61 <= *c && *c <= 0x7a { + *c &= !0x20; + } + } + + let mut write_offset = 0; + while write_offset < count { + match serial.write(&buf[write_offset..count]) { + Ok(len) if len > 0 => { + write_offset += len; + } + _ => {} + } + } + } + _ => {} + } + + led.set_high().ok(); // Turn off + } +}