From 0c4eb964b015961e3c90e45ef498f6c7f89eddba Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Tue, 25 Oct 2022 12:20:32 -0400 Subject: convert to gd32f303 (stm32f103) bluepill variant --- src/main.rs | 285 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 135 insertions(+), 150 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index dce005a..d0dfe1a 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,191 +1,176 @@ -/* #![no_std] #![no_main] -mod blink; +//extern crate panic_semihosting; + mod led; mod log; -mod usb; - -use gd32vf103xx_hal::{ - afio::AfioExt, - eclic::{self, EclicExt}, - gpio::GpioExt, - pac::{self, Peripherals}, - rcu::RcuExt, - serial::Serial, - time::{Hertz, MegaHertz}, - timer::Timer, -}; -use riscv::{ - asm::wfi, - interrupt, -}; -use riscv_rt::entry; -use usb_device::prelude::*; use led::LED; -use usb::{USB, UsbBus}; -static mut EP_MEMORY: [u32; 1024] = [0; 1024]; +use cortex_m::{ + asm::{bkpt, wfi}, + interrupt, +}; +use cortex_m_rt::entry; +use embedded_hal::spi::{Mode, Phase, Polarity}; +use stm32f1xx_hal::{ + pac, + prelude::*, + serial::{Config, Serial, StopBits, WordLength}, + spi::Spi, + usb::{self, UsbBus}, +}; +use usb_device::prelude::*; +use usbd_serial::{SerialPort, USB_CLASS_CDC}; #[entry] -fn main(_hartid: usize) -> ! { - let p = Peripherals::take().expect("couldn't take peripherals"); - - pac::ECLIC::reset(); - pac::ECLIC::set_threshold_level(eclic::Level::L0); - pac::ECLIC::set_level_priority_bits(eclic::LevelPriorityBits::L3P1); - - let mut rcu = p.RCU - .configure() - .ext_hf_clock(MegaHertz(8)) - .sysclk(MegaHertz(96)) - .freeze(); - let mut afio = p.AFIO.constrain(&mut rcu); - let gpioa = p.GPIOA.split(&mut rcu); - - // TODO: figure out how to use the usb serial on the start board. - // - // this version has to be wired up physically. - let serial = Serial::new( - p.USART1, - (gpioa.pa2, gpioa.pa3), - Default::default(), - &mut afio, - &mut rcu, +fn main() -> ! { + let dp = pac::Peripherals::take().unwrap(); + + let mut flash = dp.FLASH.constrain(); + let rcc = dp.RCC.constrain(); + + let clocks = rcc + .cfgr + .use_hse(8.MHz()) + .sysclk(72.MHz()) // TODO: gd32 can get up to 120MHz + // .pclk1(24.MHz()) // TODO: causes issues with gd32 usb (dropped packets) and garbled usart1 output + .freeze(&mut flash.acr); + + assert!(clocks.usbclk_valid()); + + let mut gpiob = dp.GPIOB.split(); + let mut led = LED::new(gpiob.pb2, &mut gpiob.crl); + + let mut afio = dp.AFIO.constrain(); + let mut gpioa = dp.GPIOA.split(); + + let tx_pin = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh); + let rx_pin = gpioa.pa10; + let serial = Serial::usart1( + dp.USART1, + (tx_pin, rx_pin), + &mut afio.mapr, + Config::default() + .baudrate(115200.bps()) + .wordlength(WordLength::Bits8) + .parity_none() + .stopbits(StopBits::STOP1), + clocks, ); - let (tx, _rx) = serial.split(); + let (tx, _) = serial.split(); + log::init(tx); - let timer = Timer::::timer6(p.TIMER6, Hertz(5), &mut rcu); - let led = LED::new(gpioa.pa7); - let mut blink = blink::Task::new(timer, Hertz(5), led); + logln!("luchie started!"); + + // cirque spi connections to spi1: + // + // pb0 - dr + // pa4 - ss1 + // pa5 - clk1 + // pa6 - miso1 + // pa7 - mosi1 + + let dr_pin = gpiob.pb0; + let sck_pin = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl); + let miso_pin = gpioa.pa6; + let mosi_pin = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl); + let cs_pin = gpioa.pa4.into_push_pull_output(&mut gpioa.crl); + let spi_mode = Mode { + phase: Phase::CaptureOnSecondTransition, + polarity: Polarity::IdleHigh, + }; + let spi = Spi::spi1( + dp.SPI1, + (sck_pin, miso_pin, mosi_pin), + &mut afio.mapr, + spi_mode, + 1.MHz(), + clocks, + ); - let usb = USB { - usb_global: p.USBFS_GLOBAL, - usb_device: p.USBFS_DEVICE, - usb_pwrclk: p.USBFS_PWRCLK, + // 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(); + // let mut delay = dp.TIM2.delay_us(&clocks); + // delay.delay_ms(10u8); + cortex_m::asm::delay(clocks.sysclk().raw() / 100); + + let usb = usb::Peripheral { + usb: dp.USB, pin_dm: gpioa.pa11, - pin_dp: gpioa.pa12, - hclk: rcu.clocks.hclk() + pin_dp: usb_dp.into_floating_input(&mut gpioa.crh), }; + let usb_bus = UsbBus::new(usb); - let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY }); + let mut serial = SerialPort::new(&usb_bus); - let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0xdead, 0xbeef)) .manufacturer("Fake company") - .product("Enumeration test") + .product("Serial port") .serial_number("TEST") - .device_class(0) + .device_class(USB_CLASS_CDC) .build(); - //let mut serial = SerialPort::new(&bus_alloc); - - unsafe { interrupt::enable() }; - loop { - let mut can_sleep = true; - - if let Ok(_) = blink.poll() { - can_sleep = false; - } - if usb_dev.poll(&mut []) { - logln!("usb"); - can_sleep = false; + logln!("."); + if !usb_dev.poll(&mut [&mut serial]) { + continue; } - if can_sleep && false { - log!("!"); - unsafe { wfi() }; + let mut buf = [0u8; 64]; + + match serial.read(&mut buf) { + Ok(count) if count > 0 => { + led.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; + } + _ => {} + } + } + } + _ => {} } - } -} -#[export_name="ExceptionHandler"] -fn exception_handler(_frame: &riscv_rt::TrapFrame) -> ! { - spin(); -} - -#[export_name="DefaultHandler"] -fn default_handler() -> ! { - spin(); -} -#[export_name="MachineTimer"] -fn machine_timer() { - spin(); -} -*/ - -#![no_std] -#![no_main] - -mod usb; - -use riscv::asm::wfi; -use riscv_rt::entry; -use gd32vf103xx_hal::prelude::*; -use gd32vf103xx_hal::pac; - -use usb::{USB, UsbBus}; -use usb_device::prelude::*; -use usbd_serial::SerialPort; - -static mut EP_MEMORY: [u32; 1024] = [0; 1024]; - -#[entry] -fn main() -> ! { - let dp = pac::Peripherals::take().unwrap(); - - // Configure clocks - let mut rcu = dp.RCU.configure() - .ext_hf_clock(8.mhz()) - .sysclk(96.mhz()) - .freeze(); - - assert!(rcu.clocks.usbclk_valid()); - - let gpioa = dp.GPIOA.split(&mut rcu); - let usb = USB { - usb_global: dp.USBFS_GLOBAL, - usb_device: dp.USBFS_DEVICE, - usb_pwrclk: dp.USBFS_PWRCLK, - pin_dm: gpioa.pa11, - pin_dp: gpioa.pa12, - hclk: rcu.clocks.hclk() - }; - - let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY }); - - let mut serial = SerialPort::new(&usb_bus); - let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) - .manufacturer("Fake company") - .product("Enumeration test") - .serial_number("TEST") - .device_class(0) - .build(); - - loop { - if usb_dev.poll(&mut [&mut serial]) { - } + led.off(); } } #[panic_handler] fn panic(info: &core::panic::PanicInfo) -> ! { -// interrupt::free(|_cs| { -// log!("!!! panic "); + interrupt::free(|_cs| { + log!("!!! panic "); if let Some(loc) = info.location() { -// log!("in {}:{} ", loc.file(), loc.line()); + log!("in {}:{} ", loc.file(), loc.line()); } if let Some(msg) = info.payload().downcast_ref::<&str>() { -// log!("⇒ {} ", msg); + log!("⇒ {} ", msg); } -// logln!("!!!"); -// }); + logln!("!!!"); + }); spin(); } fn spin() -> ! { - loop { unsafe { wfi() } }; + bkpt(); + loop { + wfi(); + } } -- cgit v1.2.3