Skip to content

Commit

Permalink
HRTIM - Multiple changes
Browse files Browse the repository at this point in the history
* Allow disabling update of shadow registers
* Add `control` member to HrPwmControl
* HRTIM now has its own `FaultMonitor` trait
  • Loading branch information
usbalbin committed Jun 19, 2024
1 parent c5f7393 commit f73c1b3
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 30 deletions.
17 changes: 17 additions & 0 deletions src/hrtim/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ impl HrTimCalibrated {
pub fn constrain(self) -> HrPwmControl {
HrPwmControl {
_x: PhantomData,
control: HrPwmCtrl { _x: PhantomData },
fault_sys: FltMonitorSys { _x: PhantomData },
fault_1: FltMonitor1 { _x: PhantomData },
fault_2: FltMonitor2 { _x: PhantomData },
Expand All @@ -208,9 +209,25 @@ impl HrTimCalibrated {
}
}

impl<'a> Into<&'a mut HrPwmCtrl> for &'a mut HrPwmControl {
fn into(self) -> &'a mut HrPwmCtrl {
&mut self.control
}
}

/// Used as a token to guarantee unique access to resources common to multiple timers
///
/// An instance of this object can be obtained from [`HrPwmControl`].control
pub struct HrPwmCtrl {
_x: PhantomData<()>,
}

/// Used as a token to guarantee unique access to resources common to multiple timers
pub struct HrPwmControl {
_x: PhantomData<()>,

pub control: HrPwmCtrl,

pub fault_sys: FltMonitorSys,
pub fault_1: FltMonitor1,
pub fault_2: FltMonitor2,
Expand Down
43 changes: 29 additions & 14 deletions src/hrtim/fault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,24 @@ use crate::gpio::gpiob::{PB0, PB10, PB11};
use crate::gpio::gpioc::{PC10, PC7};
use crate::gpio::{self, AF13, AF3};
use crate::hrtim::control::HrPwmControl;
use crate::pwm::FaultMonitor;
use crate::stm32::HRTIM_COMMON;

use super::control::HrPwmCtrl;

/// Allows a FaultMonitor to monitor faults
pub trait FaultMonitor {
fn enable_interrupt(&mut self, hr_control: &mut HrPwmCtrl);

/// Returns true if a fault is preventing PWM output
fn is_fault_active(&self) -> bool;

/// Clear the fault interrupt flag
///
/// This will *NOT* resume normal PWM operation. The affected outputs need to be re-enabled to resume operation;
/// This will do nothing if the fault is still active.
fn clear_fault(&mut self);
}

pub enum FaultAction {
/// Output never enters fault mode
None = 0b00,
Expand Down Expand Up @@ -227,12 +242,17 @@ pub enum FaultSamplingFilter {
}

macro_rules! impl_flt_monitor {
($($t:ident: ($fltx:ident, $fltxc:ident),)+) => {$(
($($t:ident: ($fltx:ident, $fltxc:ident, $fltxie:ident),)+) => {$(
pub struct $t {
pub(crate) _x: PhantomData<()>
}

impl FaultMonitor for $t {
fn enable_interrupt(&mut self, _hr_control: &mut HrPwmCtrl) {
let common = unsafe { &*HRTIM_COMMON::ptr() };
common.ier.modify(|_r, w| w.$fltxie().set_bit());
}

fn is_fault_active(&self) -> bool {
let common = unsafe { &*HRTIM_COMMON::ptr() };
common.isr.read().$fltx().bit()
Expand All @@ -242,21 +262,16 @@ macro_rules! impl_flt_monitor {
let common = unsafe { &*HRTIM_COMMON::ptr() };
common.icr.write(|w| w.$fltxc().set_bit());
}

// TODO: Should we have our own trait since it does not seem possible to implement this
fn set_fault(&mut self) {
todo!()
}
}
)+};
}

impl_flt_monitor!(
FltMonitorSys: (sysflt, sysfltc),
FltMonitor1: (flt1, flt1c),
FltMonitor2: (flt2, flt2c),
FltMonitor3: (flt3, flt3c),
FltMonitor4: (flt4, flt4c),
FltMonitor5: (flt5, flt5c),
FltMonitor6: (flt6, flt6c),
FltMonitorSys: (sysflt, sysfltc, sysflte),
FltMonitor1: (flt1, flt1c, flt1ie),
FltMonitor2: (flt2, flt2c, flt2ie),
FltMonitor3: (flt3, flt3c, flt3ie),
FltMonitor4: (flt4, flt4c, flt4ie),
FltMonitor5: (flt5, flt5c, flt5ie),
FltMonitor6: (flt6, flt6c, flt6ie),
);
14 changes: 14 additions & 0 deletions src/hrtim/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ pub enum State {
Fault,
}

impl State {
pub fn is_idle(self) -> bool {
matches!(self, State::Idle)
}

pub fn is_running(self) -> bool {
matches!(self, State::Running)
}

pub fn is_fault(self) -> bool {
matches!(self, State::Fault)
}
}

pub unsafe trait ToHrOut {
type Out<PSCL>: ToHrOut;
}
Expand Down
69 changes: 54 additions & 15 deletions src/hrtim/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::marker::PhantomData;

use super::{
capture::{self, HrCapt, HrCapture},
control::HrPwmControl,
control::HrPwmCtrl,
HrtimPrescaler,
};

Expand Down Expand Up @@ -42,13 +42,13 @@ pub trait HrTimer {
fn set_period(&mut self, period: u16);

/// Start timer
fn start(&mut self, _hr_control: &mut HrPwmControl);
fn start(&mut self, _hr_control: &mut HrPwmCtrl);

/// Stop timer
fn stop(&mut self, _hr_control: &mut HrPwmControl);
fn stop(&mut self, _hr_control: &mut HrPwmCtrl);

/// Stop timer and reset counter
fn stop_and_reset(&mut self, _hr_control: &mut HrPwmControl);
fn stop_and_reset(&mut self, _hr_control: &mut HrPwmCtrl);

fn clear_repetition_interrupt(&mut self);

Expand All @@ -57,6 +57,21 @@ pub trait HrTimer {

/// Make a handle to this timers period event to use as adc trigger
fn as_period_adc_trigger(&self) -> super::adc_trigger::TimerPeriod<Self::Timer>;

/// Disable register updates
///
/// Calling this function temporarily disables the transfer from preload to active registers,
/// whatever the selected update event. This allows to modify several registers.
/// The regular update event takes place once [`Self::enable_register_updates`] is called.
fn disable_register_updates(&mut self, _hr_control: &mut HrPwmCtrl);

/// Enable register updates
///
/// See [`Self::disable_register_updates`].
///
/// NOTE: Register updates are enabled by default, no need to call this
/// unless [`Self::disable_register_updates`] has been called.
fn enable_register_updates(&mut self, _hr_control: &mut HrPwmCtrl);
}

pub trait HrSlaveTimer: HrTimer {
Expand Down Expand Up @@ -106,6 +121,7 @@ macro_rules! hrtim_timer {
$repie:ident,
$icr:ident,
$repc:ident,
$tXudis:ident,
$(($rstXr:ident))*,
)+) => {$(
impl<PSCL: HrtimPrescaler, CPT1, CPT2> HrTimer for HrTim<$TIMX, PSCL, CPT1, CPT2> {
Expand All @@ -124,7 +140,7 @@ macro_rules! hrtim_timer {
}

/// Start timer
fn start(&mut self, _hr_control: &mut HrPwmControl) {
fn start(&mut self, _hr_control: &mut HrPwmCtrl) {
// Start timer

// SAFETY: Since we hold _hr_control there is no risk for a race condition
Expand All @@ -133,15 +149,15 @@ macro_rules! hrtim_timer {
}

/// Stop timer
fn stop(&mut self, _hr_control: &mut HrPwmControl) {
fn stop(&mut self, _hr_control: &mut HrPwmCtrl) {
// Stop counter
// SAFETY: Since we hold _hr_control there is no risk for a race condition
let master = unsafe { &*HRTIM_MASTER::ptr() };
master.mcr.modify(|_r, w| { w.$tXcen().set_bit() });
}

/// Stop timer and reset counter
fn stop_and_reset(&mut self, _hr_control: &mut HrPwmControl) {
fn stop_and_reset(&mut self, _hr_control: &mut HrPwmCtrl) {
self.stop(_hr_control);

// Reset counter
Expand All @@ -164,6 +180,29 @@ macro_rules! hrtim_timer {

tim.$icr.write(|w| w.$repc().set_bit());
}

/// Disable register updates
///
/// Calling this function temporarily disables the transfer from preload to active registers,
/// whatever the selected update event. This allows to modify several registers.
/// The regular update event takes place once [`Self::enable_register_updates`] is called.
fn disable_register_updates(&mut self, _hr_control: &mut HrPwmCtrl) {
use super::HRTIM_COMMON;
let common = unsafe { &*HRTIM_COMMON::ptr() };
common.cr1.modify(|_r, w| w.$tXudis().set_bit());
}

/// Enable register updates
///
/// See [`Self::disable_register_updates`].
///
/// NOTE: Register updates are enabled by default, no need to call this
/// unless [`Self::disable_register_updates`] has been called.
fn enable_register_updates<'a>(&mut self, _hr_control: &mut HrPwmCtrl) {
use super::HRTIM_COMMON;
let common = unsafe { &*HRTIM_COMMON::ptr() };
common.cr1.modify(|_r, w| w.$tXudis().clear_bit());
}
}

impl<PSCL, CPT1, CPT2> HrTim<$TIMX, PSCL, CPT1, CPT2> {
Expand Down Expand Up @@ -290,14 +329,14 @@ use super::adc_trigger::Adc579Trigger as Adc579;
use super::adc_trigger::Adc6810Trigger as Adc6810;

hrtim_timer! {
HRTIM_MASTER: mcntr, mcnt, mper, mcen, mper, mrep, mrep, mdier, mrepie, micr, mrepc,,

HRTIM_TIMA: cntar, cntx, perar, tacen, perx, repar, repx, timadier, repie, timaicr, repc, (rstar),
HRTIM_TIMB: cntr, cntx, perbr, tbcen, perx, repbr, repx, timbdier, repie, timbicr, repc, (rstbr),
HRTIM_TIMC: cntcr, cntx, percr, tccen, perx, repcr, repx, timcdier, repie, timcicr, repc, (rstcr),
HRTIM_TIMD: cntdr, cntx, perdr, tdcen, perx, repdr, repx, timddier, repie, timdicr, repc, (rstdr),
HRTIM_TIME: cnter, cntx, perer, tecen, perx, reper, repx, timedier, repie, timeicr, repc, (rster),
HRTIM_TIMF: cntfr, cntx, perfr, tfcen, perx, repfr, repx, timfdier, repie, timficr, repc, (rstfr),
HRTIM_MASTER: mcntr, mcnt, mper, mcen, mper, mrep, mrep, mdier, mrepie, micr, mrepc, mudis,,

HRTIM_TIMA: cntar, cntx, perar, tacen, perx, repar, repx, timadier, repie, timaicr, repc, taudis, (rstar),
HRTIM_TIMB: cntr, cntx, perbr, tbcen, perx, repbr, repx, timbdier, repie, timbicr, repc, tbudis, (rstbr),
HRTIM_TIMC: cntcr, cntx, percr, tccen, perx, repcr, repx, timcdier, repie, timcicr, repc, tcudis, (rstcr),
HRTIM_TIMD: cntdr, cntx, perdr, tdcen, perx, repdr, repx, timddier, repie, timdicr, repc, tdudis, (rstdr),
HRTIM_TIME: cnter, cntx, perer, tecen, perx, reper, repx, timedier, repie, timeicr, repc, teudis, (rster),
HRTIM_TIMF: cntfr, cntx, perfr, tfcen, perx, repfr, repx, timfdier, repie, timficr, repc, tfudis, (rstfr),
}

hrtim_timer_adc_trigger! {
Expand Down
3 changes: 2 additions & 1 deletion src/serial/usart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ macro_rules! uart_shared {
let config = crate::dma::config::DmaConfig::default()
.transfer_complete_interrupt(false)
.circular_buffer(false)
.memory_increment(true);
.memory_increment(true)
.priority(crate::dma::config::Priority::Low);
stream.apply_config(config);

Tx {
Expand Down

0 comments on commit f73c1b3

Please sign in to comment.