Skip to content

Commit 8b9c0c9

Browse files
committed
HRTIM - Make sure output pins are not set to alternate mode intil end of init
This ensures there is no sporadic output at the pins. This is a breaking change and does change and clean up quite a lot of things. Examples will need to be updated.
1 parent 4f6ac37 commit 8b9c0c9

File tree

4 files changed

+68
-242
lines changed

4 files changed

+68
-242
lines changed

Cargo.toml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,4 @@ path = "examples/hrtim/hrtim.rs"
176176
[[example]]
177177
name = "hrtim-master"
178178
required-features = ["hrtim"]
179-
path = "examples/hrtim/master.rs"
180-
181-
[[example]]
182-
name = "hrtim-simple"
183-
required-features = ["hrtim"]
184-
path = "examples/hrtim/simple.rs"
179+
path = "examples/hrtim/master.rs"

src/hrtim/external_event.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,6 @@ pub trait ToExternalEventSource<const N: u8, const IS_FAST: bool> {
240240
fn finalize(self, _calibrated: &mut HrTimCalibrated) -> ExternalEventSource<N, IS_FAST>;
241241
}
242242

243-
#[derive(Copy, Clone)]
244-
struct ExternalEventMuxOut<const N: u8> {
245-
_x: PhantomData<()>,
246-
}
247-
248243
macro_rules! impl_eev1_5_to_es {
249244
($eev:ident, $N:literal, $eeXsrc:ident, $eeXpol:ident, $eeXsns:ident, $eeXfast:ident) => {
250245
impl<const IS_FAST: bool> ExternalEventBuilder1To5 for SourceBuilder<$N, IS_FAST> {}

src/hrtim/mod.rs

Lines changed: 30 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,10 @@ use fugit::HertzU64;
2626
use self::control::HrPwmControl;
2727

2828
use self::deadtime::DeadtimeConfig;
29-
use self::output::{HrtimChannel, ToHrOut, CH1, CH2};
29+
use self::output::ToHrOut;
3030
use self::timer_eev_cfg::EevCfgs;
3131

32-
use crate::pwm::{
33-
self, Alignment, ComplementaryImpossible, Pins, Polarity, Pwm, PwmPinEnable, TimerType,
34-
};
32+
use crate::pwm::{self, Alignment, Polarity, TimerType};
3533
use crate::rcc::{GetBusFreq, Rcc};
3634
use crate::time::Hertz;
3735

@@ -152,41 +150,23 @@ pub enum InterleavedMode {
152150
Quad,
153151
}
154152

155-
// HrPwmExt trait
156-
/// Allows the pwm() method to be added to the peripheral register structs from the device crate
157-
pub trait HrPwmExt: Sized {
158-
/// The requested frequency will be rounded to the nearest achievable frequency; the actual frequency may be higher or lower than requested.
159-
fn pwm<PINS, T, U, V>(
160-
self,
161-
_pins: PINS,
162-
frequency: T,
163-
control: &mut HrPwmControl,
164-
rcc: &mut Rcc,
165-
) -> PINS::Channel
166-
where
167-
PINS: Pins<Self, U, V> + ToHrOut,
168-
T: Into<Hertz>,
169-
U: HrtimChannel<Pscl128>;
170-
}
171-
172153
pub trait HrPwmAdvExt: Sized {
173154
type PreloadSource;
174155

175-
fn pwm_advanced<PINS, CHANNEL, COMP>(
156+
fn pwm_advanced<PINS>(
176157
self,
177158
_pins: PINS,
178159
rcc: &mut Rcc,
179-
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS::Out<Pscl128>>
160+
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS>
180161
where
181-
PINS: Pins<Self, CHANNEL, COMP> + ToHrOut,
182-
CHANNEL: HrtimChannel<Pscl128>;
162+
PINS: ToHrOut<Self>;
183163
}
184164

185165
/// HrPwmBuilder is used to configure advanced HrTim PWM features
186-
pub struct HrPwmBuilder<TIM, PSCL, PS, OUT> {
166+
pub struct HrPwmBuilder<TIM, PSCL, PS, PINS> {
187167
_tim: PhantomData<TIM>,
188168
_prescaler: PhantomData<PSCL>,
189-
_out: PhantomData<OUT>,
169+
pins: PINS,
190170
timer_mode: HrTimerMode,
191171
counting_direction: HrCountingDirection,
192172
base_freq: HertzU64,
@@ -368,6 +348,9 @@ macro_rules! hrtim_finalize_body {
368348
//let master = unsafe { &*HRTIM_MASTER::ptr() };
369349
//master.mcr.modify(|_r, w| { w.$tXcen().set_bit() });
370350

351+
// Connect pins and let HRTIM take over control over them
352+
$this.pins.connect_to_hrtim();
353+
371354
unsafe {
372355
MaybeUninit::uninit().assume_init()
373356
}
@@ -421,17 +404,14 @@ macro_rules! hrtim_common_methods {
421404
}
422405

423406
/// Set the prescaler; PWM count runs at base_frequency/(prescaler+1)
424-
pub fn prescaler<P>(
425-
self,
426-
_prescaler: P,
427-
) -> HrPwmBuilder<$TIMX, P, $PS, <OUT as ToHrOut>::Out<P>>
407+
pub fn prescaler<P>(self, _prescaler: P) -> HrPwmBuilder<$TIMX, P, $PS, PINS>
428408
where
429409
P: HrtimPrescaler,
430410
{
431411
let HrPwmBuilder {
432412
_tim,
433413
_prescaler: _,
434-
_out,
414+
pins,
435415
timer_mode,
436416
fault_enable_bits,
437417
fault1_bits,
@@ -460,7 +440,7 @@ macro_rules! hrtim_common_methods {
460440
HrPwmBuilder {
461441
_tim,
462442
_prescaler: PhantomData,
463-
_out: PhantomData,
443+
pins,
464444
timer_mode,
465445
fault_enable_bits,
466446
fault1_bits,
@@ -521,38 +501,16 @@ macro_rules! hrtim_hal {
521501
($($TIMX:ident: ($timXcr:ident, $timXcr2:ident, $perXr:ident, $tXcen:ident, $rep:ident, $repx:ident, $dier:ident, $repie:ident,
522502
$fltXr:ident, $eefXr1:ident, $eefXr2:ident, $Xeefr3:ident, $outXr:ident, $dtXr:ident),)+) => {
523503
$(
524-
525-
// Implement HrPwmExt trait for hrtimer
526-
impl HrPwmExt for $TIMX {
527-
fn pwm<PINS, T, U, V>(
528-
self,
529-
pins: PINS,
530-
frequency: T,
531-
control: &mut HrPwmControl,
532-
rcc: &mut Rcc,
533-
) -> PINS::Channel
534-
where
535-
PINS: Pins<Self, U, V> + ToHrOut,
536-
T: Into<Hertz>,
537-
U: HrtimChannel<Pscl128>,
538-
{
539-
let _= self.pwm_advanced(pins, rcc).frequency(frequency).finalize(control);
540-
541-
unsafe { MaybeUninit::<PINS::Channel>::uninit().assume_init() }
542-
}
543-
}
544-
545504
impl HrPwmAdvExt for $TIMX {
546505
type PreloadSource = PreloadSource;
547506

548-
fn pwm_advanced<PINS, CHANNEL, COMP>(
507+
fn pwm_advanced<PINS>(
549508
self,
550-
_pins: PINS,
509+
pins: PINS,
551510
rcc: &mut Rcc,
552-
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS::Out<Pscl128>>
511+
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS>
553512
where
554-
PINS: Pins<Self, CHANNEL, COMP> + ToHrOut,
555-
CHANNEL: HrtimChannel<Pscl128>
513+
PINS: ToHrOut<$TIMX>,
556514
{
557515
// TODO: That 32x factor... Is that included below, or should we
558516
// do that? Also that will likely risk overflowing u32 since
@@ -562,7 +520,7 @@ macro_rules! hrtim_hal {
562520
HrPwmBuilder {
563521
_tim: PhantomData,
564522
_prescaler: PhantomData,
565-
_out: PhantomData,
523+
pins,
566524
timer_mode: HrTimerMode::Continuous,
567525
fault_enable_bits: 0b000000,
568526
fault1_bits: 0b00,
@@ -583,11 +541,11 @@ macro_rules! hrtim_hal {
583541
}
584542
}
585543

586-
impl<PSCL, OUT>
587-
HrPwmBuilder<$TIMX, PSCL, PreloadSource, OUT>
544+
impl<PSCL, PINS>
545+
HrPwmBuilder<$TIMX, PSCL, PreloadSource, PINS>
588546
where
589547
PSCL: HrtimPrescaler,
590-
OUT: ToHrOut,
548+
PINS: ToHrOut<$TIMX>,
591549
{
592550
pub fn finalize(self, _control: &mut HrPwmControl) -> (
593551
HrTim<$TIMX, PSCL,
@@ -599,7 +557,7 @@ macro_rules! hrtim_hal {
599557
HrCr3<$TIMX, PSCL>,
600558
HrCr4<$TIMX, PSCL>
601559
),
602-
OUT,
560+
PINS::Out<PSCL>,
603561
timer::DmaChannel<$TIMX>,
604562
) {
605563

@@ -702,14 +660,13 @@ macro_rules! hrtim_hal_master {
702660
impl HrPwmAdvExt for $TIMX {
703661
type PreloadSource = MasterPreloadSource;
704662

705-
fn pwm_advanced<PINS, CHANNEL, COMP>(
663+
fn pwm_advanced<PINS>(
706664
self,
707-
_pins: PINS,
665+
pins: PINS,
708666
rcc: &mut Rcc,
709-
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS::Out<Pscl128>>
667+
) -> HrPwmBuilder<Self, Pscl128, Self::PreloadSource, PINS>
710668
where
711-
PINS: Pins<Self, CHANNEL, COMP> + ToHrOut, // TODO: figure out
712-
CHANNEL: HrtimChannel<Pscl128>
669+
PINS: ToHrOut<$TIMX>,
713670
{
714671
// TODO: That 32x factor... Is that included below, or should we
715672
// do that? Also that will likely risk overflowing u32 since
@@ -719,7 +676,7 @@ macro_rules! hrtim_hal_master {
719676
HrPwmBuilder {
720677
_tim: PhantomData,
721678
_prescaler: PhantomData,
722-
_out: PhantomData,
679+
pins,
723680
timer_mode: HrTimerMode::Continuous,
724681
fault_enable_bits: 0b000000,
725682
fault1_bits: 0b00,
@@ -740,11 +697,11 @@ macro_rules! hrtim_hal_master {
740697
}
741698
}
742699

743-
impl<PSCL, OUT>
744-
HrPwmBuilder<$TIMX, PSCL, MasterPreloadSource, OUT>
700+
impl<PSCL, PINS>
701+
HrPwmBuilder<$TIMX, PSCL, MasterPreloadSource, PINS>
745702
where
746703
PSCL: HrtimPrescaler,
747-
OUT: ToHrOut,
704+
PINS: ToHrOut<$TIMX>,
748705
{
749706
pub fn finalize(self, _control: &mut HrPwmControl) -> (
750707
HrTim<$TIMX, PSCL,
@@ -767,97 +724,6 @@ macro_rules! hrtim_hal_master {
767724
)*}
768725
}
769726

770-
macro_rules! hrtim_pin_hal {
771-
($($TIMX:ident:
772-
($CH:ident, $perXr:ident, $cmpXYr:ident, $cmpYx:ident, $cmpY:ident, $tXYoen:ident, $tXYodis:ident),)+
773-
) => {
774-
$(
775-
impl<PSCL, COMP, POL, NPOL> hal::PwmPin for Pwm<$TIMX, $CH<PSCL>, COMP, POL, NPOL>
776-
where Pwm<$TIMX, $CH<PSCL>, COMP, POL, NPOL>: PwmPinEnable {
777-
type Duty = u16;
778-
779-
// You may not access self in the following methods!
780-
// See unsafe above
781-
782-
fn disable(&mut self) {
783-
self.ccer_disable();
784-
}
785-
786-
fn enable(&mut self) {
787-
self.ccer_enable();
788-
}
789-
790-
fn get_duty(&self) -> Self::Duty {
791-
let tim = unsafe { &*$TIMX::ptr() };
792-
793-
tim.$cmpXYr.read().$cmpYx().bits()
794-
}
795-
796-
fn get_max_duty(&self) -> Self::Duty {
797-
let tim = unsafe { &*$TIMX::ptr() };
798-
799-
let arr = tim.$perXr.read().perx().bits();
800-
801-
// One PWM cycle is ARR+1 counts long
802-
// Valid PWM duty cycles are 0 to ARR+1
803-
// However, if ARR is 65535 on a 16-bit timer, we can't add 1
804-
// In that case, 100% duty cycle is not possible, only 65535/65536
805-
if arr == Self::Duty::MAX {
806-
arr
807-
}
808-
else {
809-
arr + 1
810-
}
811-
}
812-
813-
/// Set duty cycle
814-
///
815-
/// NOTE: Please observe limits(RM0440 "Period and compare registers min and max values"):
816-
/// | Prescaler | Min duty | Max duty |
817-
/// |-----------|----------|----------|
818-
/// | 1 | 0x0060 | 0xFFDF |
819-
/// | 2 | 0x0030 | 0xFFEF |
820-
/// | 4 | 0x0018 | 0xFFF7 |
821-
/// | 8 | 0x000C | 0xFFFB |
822-
/// | 16 | 0x0006 | 0xFFFD |
823-
/// | 32 | 0x0003 | 0xFFFD |
824-
/// | 64 | 0x0003 | 0xFFFD |
825-
/// | 128 | 0x0003 | 0xFFFD |
826-
///
827-
/// Also, writing 0 as duty is only valid for CR1 and CR3 during a set of
828-
/// specific conditions(see RM0440 "Null duty cycle exception case"):
829-
/// – the output SET event is generated by the PERIOD event
830-
/// – the output RESET if generated by the compare 1 (respectively compare 3) event
831-
/// – the compare 1 (compare 3) event is active within the timer unit itself, and not used
832-
/// for other timing units
833-
fn set_duty(&mut self, duty: Self::Duty) {
834-
let tim = unsafe { &*$TIMX::ptr() };
835-
836-
tim.$cmpXYr.write(|w| unsafe { w.$cmpYx().bits(duty) });
837-
}
838-
}
839-
840-
// Enable implementation for ComplementaryImpossible
841-
impl<POL, NPOL, PSCL> PwmPinEnable for Pwm<$TIMX, $CH<PSCL>, ComplementaryImpossible, POL, NPOL> {
842-
fn ccer_enable(&mut self) {
843-
// TODO: Should this part only be in Pwm::enable?
844-
// Enable output Y on channel X
845-
// This is a set-only register, no risk for data race
846-
let common = unsafe { &*HRTIM_COMMON::ptr() };
847-
common.oenr.write(|w| { w.$tXYoen().set_bit() });
848-
}
849-
fn ccer_disable(&mut self) {
850-
// TODO: Should this part only be in Pwm::disable
851-
// Disable output Y on channel X
852-
// This is a write only register, no risk for data race
853-
let common = unsafe { &*HRTIM_COMMON::ptr() };
854-
common.odisr.write(|w| { w.$tXYodis().set_bit() });
855-
}
856-
}
857-
)+
858-
}
859-
}
860-
861727
hrtim_hal! {
862728
HRTIM_TIMA: (timacr, timacr2, perar, tacen, repar, repx, timadier, repie, fltar, eefar1, eefar2, aeefr3, outar, dtar),
863729
HRTIM_TIMB: (timbcr, timbcr2, perbr, tbcen, repbr, repx, timbdier, repie, fltbr, eefbr1, eefbr2, beefr3, outbr, dtbr),
@@ -871,26 +737,6 @@ hrtim_hal_master! {
871737
HRTIM_MASTER: (mcr, ck_psc, mper, mper, mrep, mcen, mdier, mrepie),
872738
}
873739

874-
hrtim_pin_hal! {
875-
HRTIM_TIMA: (CH1, perar, cmp1ar, cmp1x, cmp1, ta1oen, ta1odis),
876-
HRTIM_TIMA: (CH2, perar, cmp3ar, cmp3x, cmp3, ta2oen, ta2odis),
877-
878-
HRTIM_TIMB: (CH1, perbr, cmp1br, cmp1x, cmp1, tb1oen, tb1odis),
879-
HRTIM_TIMB: (CH2, perbr, cmp3br, cmp3x, cmp3, tb2oen, tb2odis),
880-
881-
HRTIM_TIMC: (CH1, percr, cmp1cr, cmp1x, cmp1, tc1oen, tc1odis),
882-
HRTIM_TIMC: (CH2, percr, cmp3cr, cmp3x, cmp3, tc2oen, tc2odis),
883-
884-
HRTIM_TIMD: (CH1, perdr, cmp1dr, cmp1x, cmp1, td1oen, td1odis),
885-
HRTIM_TIMD: (CH2, perdr, cmp3dr, cmp3x, cmp3, td2oen, td2odis),
886-
887-
HRTIM_TIME: (CH1, perer, cmp1er, cmp1x, cmp1, te1oen, te1odis),
888-
HRTIM_TIME: (CH2, perer, cmp3er, cmp3x, cmp3, te2oen, te2odis),
889-
890-
HRTIM_TIMF: (CH1, perfr, cmp1fr, cmp1x, cmp1, tf1oen, tf1odis),
891-
HRTIM_TIMF: (CH2, perfr, cmp3fr, cmp3x, cmp3, tf2oen, tf2odis),
892-
}
893-
894740
/// # Safety
895741
/// Only implement for valid prescalers with correct values
896742
pub unsafe trait HrtimPrescaler: Default {

0 commit comments

Comments
 (0)