Commit a94d1afd authored by Per Lindgren's avatar Per Lindgren
Browse files

pwm dma wip

parent 834fcb6a
//! examples/rtt-pwm-dma.rs
//! cargo run --examples rtt-pwm-dma
// #![deny(unsafe_code)]
// #![deny(warnings)]
#![no_main]
#![no_std]
use cortex_m::{asm, peripheral::DWT};
use panic_halt as _;
use rtt_target::{rprintln, rtt_init_print};
use stm32f4xx_hal::{bb, dma, gpio::Speed, prelude::*, pwm, stm32};
#[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true)]
const APP: () = {
#[init]
fn init(mut cx: init::Context) {
rtt_init_print!();
rprintln!("init");
let dp = cx.device;
// Initialize (enable) the monotonic timer (CYCCNT)
cx.core.DCB.enable_trace();
cx.core.DWT.enable_cycle_counter();
let rcc = dp.RCC.constrain();
// Set up the system clock. 48 MHz?
let clocks = rcc
.cfgr
// .use_hse(8.mhz())
.sysclk(48.mhz())
.pclk1(24.mhz())
.freeze();
let gpioa = dp.GPIOA.split();
// we set the pins to VeryHigh to get the sharpest waveform possible
// (rise and fall times should have similar characteristics)
let channels = (
gpioa.pa8.into_alternate_af1().set_speed(Speed::VeryHigh),
gpioa.pa9.into_alternate_af1().set_speed(Speed::VeryHigh),
);
// Setup PWM RAW
let tim1 = dp.TIM1;
// Here we need unsafe as we are "stealing" the RCC peripheral
// At this point it has been contrained into SysConf and used to set clocks
let rcc = unsafe { &(*stm32::RCC::ptr()) };
// pwm_all_channels!(TIM1: (tim1, apb2enr, apb2rstr, 0u8, pclk2, ppre2));
// Enable and reset the timer peripheral,
// it's the same bit position for both registers (0 in this case)
// Notice the use of bit banding to set/clear bits individually
// It is unsafe, as the register address could be anything within range
// of the bitband region
unsafe {
bb::set(&rcc.apb2enr, 0u8);
bb::set(&rcc.apb2rstr, 0u8);
bb::clear(&rcc.apb2rstr, 0u8);
}
// Setup chanel 1 and 2 as pwm_mode1
tim1.ccmr1_output()
.modify(|_, w| w.oc1pe().set_bit().oc1m().pwm_mode1());
tim1.ccmr1_output()
.modify(|_, w| w.oc2pe().set_bit().oc2m().pwm_mode1());
// The reference manual is a bit ambiguous about when enabling this bit is really
// necessary, but since we MUST enable the preload for the output channels then we
// might as well enable for the auto-reload too
tim1.cr1.modify(|_, w| w.arpe().set_bit());
let clk = clocks.pclk2().0 * if clocks.ppre2() == 1 { 1 } else { 2 };
// check that its actually 48_000_000
rprintln!("clk {}", clk);
// we want maximum performance, thus we set the prescaler to 0
let pre = 0;
rprintln!("pre {}", pre);
tim1.psc.write(|w| w.psc().bits(pre));
// we want 8 bits of resolution
// so our ARR = 2^8 - 1 = 256 - 1 = 255
let arr = 255;
rprintln!("arr {}", arr);
tim1.arr.write(|w| unsafe { w.bits(arr) });
// Trigger update event to load the registers
tim1.cr1.modify(|_, w| w.urs().set_bit());
tim1.egr.write(|w| w.ug().set_bit());
tim1.cr1.modify(|_, w| w.urs().clear_bit());
// Set main output enable of all Output Compare (OC) registers
tim1.bdtr.modify(|_, w| w.moe().set_bit());
// Set output enable for channels 1 and 2
// Channel 1 (bit 0)
unsafe { bb::set(&tim1.ccer, 0) }
// Channel 4 (bit 0)
unsafe { bb::set(&tim1.ccer, 4) }
// Setup the timer
tim1.cr1.write(|w| {
w.cms()
.bits(0b00) // edge aligned mode
.dir() // counter used as upcounter
.clear_bit()
.opm() // one pulse mode
.clear_bit()
.cen() // enable counter
.set_bit()
});
// Set duty cycle of Channels
tim1.ccr1.write(|w| unsafe { w.ccr().bits(128) });
tim1.ccr2.write(|w| unsafe { w.ccr().bits(128) });
// loop {
// for i in 0..255 {
// tim1.ccr1.write(|w| unsafe { w.ccr().bits(i) });
// tim1.ccr2.write(|w| unsafe { w.ccr().bits(i) });
// while tim1.sr.read().tif().is_no_trigger() {}
// }
// }
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
rprintln!("idle");
loop {
continue;
}
}
};
mod dma_pwm {
// Not sure we need a dma mode
// DMA mode
// #[derive(Debug, Clone, Copy)]
// pub enum Dma {
// /// No DMA, disabled
// Disabled,
// /// Single DMA, DMA will be disabled after each conversion sequence
// Single,
// /// Continuous DMA, DMA will remain enabled after conversion
// Continuous,
// }
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment