diff --git a/examples/mco.rs b/examples/mco.rs index ecd85c9b558e0904730915cd2203a91bac85f1b2..0d8673b992f09e6b004c8ba4927336385dff1263 100644 --- a/examples/mco.rs +++ b/examples/mco.rs @@ -21,23 +21,27 @@ fn init(p: init::Peripherals) { // RM0368 6.2.10 // Configure PA8 as MCO_1 alternate function to output HSI clock p.RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); //Enable GPIOA clock - p.GPIOA.ospeedr.modify(|_,w| w.ospeedr8().bits(0b11)); //Highest output speed - p.GPIOA.afrh.modify(|_,w| w.afrh8().bits(0)); //Alternate function AF0 MCO_1 on pin 8 - p.GPIOA.moder.modify(|_,w| w.moder8().bits(0b10)); //Alternate function push-pull - p.RCC.cfgr.modify(|_, w| unsafe {w.mco1().bits(0b00)}); //HSI clock selected - p.RCC.cfgr.modify(|_, w| unsafe {w.mco1pre().bits(0)}); //No division + p.GPIOA.ospeedr.modify(|_, w| w.ospeedr8().bits(0b11)); //Highest output speed + p.GPIOA.afrh.modify(|_, w| w.afrh8().bits(0)); //Alternate function AF0 MCO_1 on pin 8 + p.GPIOA.moder.modify(|_, w| w.moder8().bits(0b10)); //Alternate function push-pull + p.RCC.cfgr.modify(|_, w| unsafe { w.mco1().bits(0b00) }); //HSI clock selected + p.RCC.cfgr.modify(|_, w| unsafe { w.mco1pre().bits(0) }); //No division // Configure PC9 as MCO_2 alternate function to output System clock p.RCC.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); //Enable GPIOC clock - p.GPIOC.ospeedr.modify(|_,w| unsafe {w.ospeedr9().bits(0b11)}); //Highest output speed - p.GPIOC.afrh.modify(|_,w| unsafe {w.afrh9().bits(0)}); //Alternate function AF0 MCO_2 on pin 9 - p.GPIOC.moder.modify(|_,w| unsafe {w.moder9().bits(0b10)}); //Alternate function push-pull - p.RCC.cfgr.modify(|_, w| unsafe {w.mco2().bits(0b00)}); //MCO2 SYSCLK clock selected - p.RCC.cfgr.modify(|_, w| unsafe {w.mco2pre().bits(0b110)}); //Divide SYSCLK by 4 + p.GPIOC + .ospeedr + .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) }); //Highest output speed + p.GPIOC.afrh.modify(|_, w| unsafe { w.afrh9().bits(0) }); //Alternate function AF0 MCO_2 on pin 9 + p.GPIOC + .moder + .modify(|_, w| unsafe { w.moder9().bits(0b10) }); //Alternate function push-pull + p.RCC.cfgr.modify(|_, w| unsafe { w.mco2().bits(0b00) }); //MCO2 SYSCLK clock selected + p.RCC.cfgr.modify(|_, w| unsafe { w.mco2pre().bits(0b110) }); //Divide SYSCLK by 4 let sysclk = clock::set_100_mhz(&p.RCC, &p.FLASH); println!("SYSCLK set to {}", sysclk); - // PC9 should now output sysclk/4 MHz and PA8 the frequency of the HSI RC + // PC9 should now output SYSCLK/4 MHz and PA8 the frequency of the HSI RC led::init(&p.GPIOA, &p.RCC); } diff --git a/examples/usart2-rx-dma.rs b/examples/usart2-rx-dma.rs new file mode 100644 index 0000000000000000000000000000000000000000..e704972a234ca5bcc64933459a4d870bf403d4d4 --- /dev/null +++ b/examples/usart2-rx-dma.rs @@ -0,0 +1,51 @@ +//! Test receiving serial data using the DMA. Program will stop at breakpoint after 8 bytes are received. +#![deny(unsafe_code)] +#![deny(warnings)] +#![feature(const_fn)] +#![feature(proc_macro)] +#![no_std] + +extern crate cortex_m_rtfm as rtfm; +extern crate f4; + +use f4::Serial; +use f4::dma::{Buffer, Dma1Channel5}; +use f4::time::Hertz; +use rtfm::{app, Threshold}; + +const BAUD_RATE: Hertz = Hertz(115_200); + +app! { + device: f4::stm32f40x, + + resources: { + static BUFFER: Buffer<[u8; 8], Dma1Channel5> = Buffer::new([0; 8]); + }, + + tasks: { + DMA1_STREAM5: { + path: transfer_done, + resources: [BUFFER, DMA1], + }, + }, +} + +fn init(p: init::Peripherals, r: init::Resources) { + let serial = Serial(p.USART2); + + serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); + + serial.read_exact(p.DMA1, r.BUFFER).unwrap(); +} + +fn idle() -> ! { + loop { + rtfm::wfi(); + } +} + +fn transfer_done(_t: &mut Threshold, r: DMA1_STREAM5::Resources) { + r.BUFFER.release(r.DMA1).unwrap(); + + rtfm::bkpt(); +} diff --git a/examples/usart2-tx-dma.rs b/examples/usart2-tx-dma.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d36f40f8fe3a4e0c0be328ec59f284918540437 --- /dev/null +++ b/examples/usart2-tx-dma.rs @@ -0,0 +1,52 @@ +//! Test sending serial data using the DMA +#![deny(unsafe_code)] +#![deny(warnings)] +#![feature(const_fn)] +#![feature(proc_macro)] +#![no_std] + +extern crate cortex_m_rtfm as rtfm; +extern crate f4; + +use f4::Serial; +use f4::dma::{Buffer, Dma1Channel6}; +use f4::time::Hertz; +use rtfm::{app, Threshold}; + +const BAUD_RATE: Hertz = Hertz(115_200); + +app! { + device: f4::stm32f40x, + + resources: { + static BUFFER: Buffer<[u8; 15], Dma1Channel6> = Buffer::new([0; 15]); + }, + + tasks: { + DMA1_STREAM6: { + path: transfer_done, + resources: [BUFFER, DMA1], + }, + }, +} + +fn init(p: init::Peripherals, r: init::Resources) { + let serial = Serial(p.USART2); + + serial.init(BAUD_RATE.invert(), Some(p.DMA1), p.GPIOA, p.RCC); + r.BUFFER.borrow_mut().clone_from_slice(b"Hello, world!\r\n"); + + serial.write_all(p.DMA1, r.BUFFER).unwrap(); +} + +fn idle() -> ! { + loop { + rtfm::wfi(); + } +} + +fn transfer_done(_t: &mut Threshold, r: DMA1_STREAM6::Resources) { + r.BUFFER.release(r.DMA1).unwrap(); + + rtfm::bkpt(); +} diff --git a/examples/ws2812.rs b/examples/ws2812.rs index 5a9bb77561535f675dbb4084d6e32bfdc68ea8d3..7465d34b9805f1409ffbefa50be826fcc91b54a0 100644 --- a/examples/ws2812.rs +++ b/examples/ws2812.rs @@ -7,8 +7,8 @@ #![feature(proc_macro)] #![no_std] -extern crate f4; extern crate cortex_m_rtfm as rtfm; +extern crate f4; #[macro_use] extern crate nb; @@ -38,7 +38,15 @@ app! { fn init(p: init::Peripherals, r: init::Resources) { let pwm = Pwm(p.TIM3); - pwm.init(FREQUENCY.invert(), Channel::_1, Some(p.DMA1), p.GPIOA, p.GPIOB, p.GPIOC, p.RCC); + pwm.init( + FREQUENCY.invert(), + Channel::_1, + Some(p.DMA1), + p.GPIOA, + p.GPIOB, + p.GPIOC, + p.RCC, + ); pwm.enable(Channel::_1); // end of frame diff --git a/src/capture.rs b/src/capture.rs index 44604d64c98d9719dac42b163974171d0fa96560..6f04cac67739e79d9f77540131bc8427ceaca786 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -36,7 +36,7 @@ use core::any::{Any, TypeId}; use core::u32; -use cast::{u32}; +use cast::u32; use hal; use nb; use stm32f40x::{TIM1, TIM2, TIM3, TIM4, GPIOA, GPIOB, GPIOC, RCC}; diff --git a/src/clock.rs b/src/clock.rs index 4b581212bbf9fab4b7163fe3de36ac57e61c1354..a1dc1caf5c29c9920f1bb5ff141e662d8802ff5a 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -37,8 +37,6 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) { (pll_bitmask, pll_output) } - - /// Set system clock pub fn set(rcc: &RCC, flash: &FLASH, m: u8, n: u16, p: u8) -> u32 { let (pll_bitmask, sysclk) = calculate_pll(m, n, p); diff --git a/src/led.rs b/src/led.rs index dc691f0a03ea912fce5d53c1497733b7eeb86a0f..bca68e662ee293ce0ca1672b989afcd22e681c2b 100644 --- a/src/led.rs +++ b/src/led.rs @@ -14,21 +14,21 @@ pub fn init(gpioa: &GPIOA, rcc: &RCC) { rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); // configure PA5 as output - gpioa.moder.modify(|_,w| w.moder5().bits(1)); + gpioa.moder.modify(|_, w| w.moder5().bits(1)); } impl PA5 { /// Turns the LED on pub fn on(&self) { unsafe { - (*GPIOA.get()).odr.modify(|_,w| w.odr5().bit(true)); + (*GPIOA.get()).odr.modify(|_, w| w.odr5().bit(true)); } } /// Turns the LED off pub fn off(&self) { unsafe { - (*GPIOA.get()).odr.modify(|_,w| w.odr5().bit(false)); + (*GPIOA.get()).odr.modify(|_, w| w.odr5().bit(false)); } } } diff --git a/src/pwm.rs b/src/pwm.rs index 980cd5844c4195e45743b1e45993f67b2f4096ae..d741f1bfd2063b30a4400ddde746ff878445bb86 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -244,6 +244,7 @@ macro_rules! impl_Pwm { if tim.get_type_id() == TypeId::of::<TIM3>() { // TIM3_CH4/UP + // chsel: Channel 5 (RM0368 9.3.3 Table 27) // pl: Medium priority // msize: Memory size = 8 bits // psize: Peripheral size = 16 bits @@ -254,7 +255,9 @@ macro_rules! impl_Pwm { // tceie: Transfer complete interrupt enabled // en: Disabled dma1.s2cr.write(|w| unsafe { - w.pl() + w.chsel() + .bits(5) + .pl() .bits(0b01) .msize() .bits(0b00) diff --git a/src/serial.rs b/src/serial.rs index 254082011f9cc55e7725a46395d1ba3696a6850c..262d30a35fc1ef006cba9edb5476eca943e3fbb6 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -118,17 +118,19 @@ where // set output mode for GPIOA // PA2 = TX (output mode), PA3 = RX (input mode) if usart.get_type_id() == TypeId::of::<USART2>() { - // we don't care about the speed register atm + // we don't care about the speed register atm // DM00102166 // AF7, Table 9 // PA2 and PA3 is connected to USART2 TX and RX respectively gpio.afrl.modify(|_, w| w.afrl2().bits(7).afrl3().bits(7)); - gpio.moder.modify(|_, w| w.moder2().bits(2).moder3().bits(2)); + gpio.moder + .modify(|_, w| w.moder2().bits(2).moder3().bits(2)); } if let Some(dma1) = dma1 { if usart.get_type_id() == TypeId::of::<USART2>() { // TX DMA transfer + // chsel: Channel 4 (RM0368 9.3.3 Table 27) // pl: Medium priority // msize: Memory size = 8 bits // psize: Peripheral size = 8 bits @@ -136,10 +138,12 @@ where // pinc: Peripheral increment mode disabled // circ: Circular mode disabled // dir: Transfer from memory to peripheral - // tceie: Transfer complete interrupt enabled + // tcie: Transfer complete interrupt enabled // en: Disabled dma1.s6cr.write(|w| unsafe { - w.pl() + w.chsel() + .bits(4) + .pl() .bits(0b01) .msize() .bits(0b00) @@ -160,6 +164,7 @@ where }); // RX DMA transfer + // chsel: Channel 4 (RM0368 9.3.3 Table 27) // pl: Medium priority // msize: Memory size = 8 bits // psize: Peripheral size = 8 bits @@ -167,10 +172,12 @@ where // pinc: Peripheral increment mode disabled // circ: Circular mode disabled // dir: Transfer from peripheral to memory - // tceie: Transfer complete interrupt enabled + // tcie: Transfer complete interrupt enabled // en: Disabled dma1.s5cr.write(|w| unsafe { - w.pl() + w.chsel() + .bits(4) + .pl() .bits(0b01) .msize() .bits(0b00)