Skip to content
Snippets Groups Projects
Select Git revision
  • fe86543556c486bbe5ffa529eaf51bc77cd33c64
  • master default protected
2 results

rtt-pwm-saw.rs

Blame
  • Forked from Per Lindgren / e7020e_2021
    Source project has a limited visibility.
    rtt-pwm-saw.rs 4.83 KiB
    //! examples/rtt-pwm-saw.rs
    //! cargo run --examples rtt-pwm-saw
    
    // #![deny(unsafe_code)]
    #![deny(warnings)]
    #![no_main]
    #![no_std]
    
    // use cortex_m::{asm, peripheral::DWT};
    use panic_halt as _;
    use rtt_target::{rprint, rprintln, rtt_init_print};
    use stm32f4xx_hal::{bb, gpio::Speed, prelude::*, 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 constrained into SysConf and used to set clocks.)
            let rcc = unsafe { &(*stm32::RCC::ptr()) };
    
            // unsafe {
            //     bb::set(&rcc.apb2enr, 0u8);
            //     bb::set(&rcc.apb2rstr, 0u8);
            //     bb::clear(&rcc.apb2rstr, 0u8);
            // }
            //
            // For some reason bb:: hangs target in release mode,
            // so I implemented it using modify instead
            rcc.apb2enr.modify(|_, w| w.tim1en().set_bit());
            rcc.apb2rstr.modify(|_, w| w.tim1rst().set_bit());
            rcc.apb2rstr.modify(|_, w| w.tim1rst().clear_bit());
    
            // 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