Skip to content

Commit

Permalink
A bit less far from compiling...
Browse files Browse the repository at this point in the history
  • Loading branch information
usbalbin committed Oct 2, 2022
1 parent e9e7eb0 commit dd65cd0
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 83 deletions.
19 changes: 5 additions & 14 deletions src/mcpwm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ use core::borrow::Borrow;

use crate::gpio::OutputPin;
use crate::units::{FromValueType, Hertz};
use crate::mcpwm::operator::{HwOperator, OPERATOR0, OPERATOR1, OPERATOR2};
use esp_idf_sys::*;

// MCPWM clock source frequency for ESP32 and ESP32-s3
Expand Down Expand Up @@ -116,23 +117,13 @@ impl<U: Unit> MCPWM<U> {
}

pub trait Unit: Default {
fn unit() -> mcpwm_unit_t;
const ID: mcpwm_unit_t;
}

impl Unit for UnitZero {
fn unit() -> mcpwm_unit_t {
mcpwm_unit_t_MCPWM_UNIT_0
}
const ID: mcpwm_unit_t = mcpwm_unit_t_MCPWM_UNIT_0;
}

impl Unit for UnitOne {
fn unit() -> mcpwm_unit_t {
mcpwm_unit_t_MCPWM_UNIT_1
}
}

trait OptionalOperator<U: Unit, O: HwOperator<U>> {}

struct NoOperator;
impl<U: Unit, O: HwOperator> OptionalOperator<U, O> for NoOperator {}

const ID: mcpwm_unit_t = mcpwm_unit_t_MCPWM_UNIT_1;
}
94 changes: 48 additions & 46 deletions src/mcpwm/operator.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
use std::borrow::Borrow;

use esp_idf_sys::{mcpwm_io_signals_t, mcpwm_unit_t, mcpwm_operator_t,
mcpwm_io_signals_t_MCPWM0A, mcpwm_io_signals_t_MCPWM0B,
mcpwm_io_signals_t_MCPWM1A, mcpwm_io_signals_t_MCPWM1B,
mcpwm_io_signals_t_MCPWM2A, mcpwm_io_signals_t_MCPWM2B, EspError
};

use crate::{mcpwm::{Unit, UnitZero, UnitOne}, gpio::OutputPin};

use super::{Duty, timer_connection::OptionalOutputPin};

// The hardware for ESP32 and ESP32-S3 can associate any operator(within the mcpwm module) with any
// timer(within the mcpwm module) for example allowing using the same timer for all three operators.
// However at least as of IDF v4.4 timer0 is hardcoded to operator0 and timer1 to operator1 and so on...
pub trait HwOperator<U: Unit>: Into<Operator<U, Self>> {
fn signal_a() -> mcpwm_io_signals_t;
fn signal_b() -> mcpwm_io_signals_t;
fn unit() -> mcpwm_unit_t {
U::unit()
}
pub trait HwOperator<U: Unit> {
const SIGNAL_A: mcpwm_io_signals_t;
const SIGNAL_B: mcpwm_io_signals_t;
const UNIT_ID: mcpwm_unit_t = U::ID;
}

macro_rules! impl_operator_helper {
($instance:ident: $timer:expr, $signal_a:expr, $signal_b:expr, $unit:ty) => {
impl HwOperator<$unit> for $instance<$unit> {
fn signal_a() -> mcpwm_io_signals_t {
$signal_a
}

fn signal_b() -> mcpwm_io_signals_t {
$signal_b
}
const SIGNAL_A: mcpwm_io_signals_t = $signal_a;
const SIGNAL_B: mcpwm_io_signals_t = $signal_b;
}
};
}
Expand All @@ -40,16 +44,6 @@ macro_rules! impl_operator {
}
}

impl<U: Unit> Into<Operator<U>> for $instance<U> {
fn into(self) -> Operator<U> {
Operator {
_instance: self,
pin_a: NoPin,
pin_b: NoPin,
}
}
}

impl_operator_helper!($instance: $timer, $signal_a, $signal_b, UnitZero);
impl_operator_helper!($instance: $timer, $signal_a, $signal_b, UnitOne);
};
Expand Down Expand Up @@ -79,21 +73,20 @@ impl_operator!(
///
/// Every Motor Control module has three operators. Every operator can generate two output signals called A and B.
/// A and B share the same timer and thus frequency and phase but can have induvidual duty set.
pub struct Operator<U: Unit, O: HwOperator<U>, M: Borrow<Mcpwm<U>>, PA: OptionalPin, PB: OptionalPin, D> {
pub struct Operator<U: Unit, O: HwOperator<U>, PA: OptionalOutputPin, PB: OptionalOutputPin> {
handle: mcpwm_operator_t,
_instance: O,

_pin_a: PA,
_pin_b: PB,

deadtime: D
//deadtime: D
}

impl<U, O, M, PA, PB> Operator<U, O, M, PA, PB>
impl<U, O, PA, PB> Operator<U, O, PA, PB>
where
U: Unit,
O: HwOperator<U>,
M: Borrow<Mcpwm<U>>,
PA: OutputPin,
PB: OptionalOutputPin,
{
Expand All @@ -108,11 +101,10 @@ where
}
}

impl<U, O, M, PA, PB> Operator<U, O, M, PA, PB>
impl<U, O, PA, PB> Operator<U, O, PA, PB>
where
U: Unit,
O: HwOperator<U>,
M: Borrow<Mcpwm<U>>,
PA: OptionalOutputPin,
PB: OutputPin,
{
Expand All @@ -134,7 +126,7 @@ pub struct OperatorConfig {

duty_mode: DutyMode,

deadtime: Option<DeadtimeConfig>,
//deadtime: Option<DeadtimeConfig>,
}

impl OperatorConfig {
Expand All @@ -159,26 +151,22 @@ impl OperatorConfig {
self
}

#[must_use]
/*#[must_use]
pub fn deadtime(mut self, deadtime: impl Into<Option<DeadtimeConfig>>) -> Self {
self.deadtime = deadtime.into();
self
}
}*/
}

impl Default for OperatorConfig {
fn default() -> Self {
Self {
frequency: 1000.Hz(),
duty_a: 50.0,
duty_b: 50.0,

#[cfg(not(esp_idf_version = "4.3"))]
lowest_frequency: 16.Hz(),
duty_a: 0.0,
duty_b: 0.0,

duty_mode: DutyMode::ActiveHigh,

deadtime: None,
//deadtime: None,
}
}
}
Expand All @@ -199,6 +187,13 @@ pub enum DutyMode {
ActiveLow,
}

pub trait OptionalOperator<U: Unit, O: HwOperator<U>> {}

pub struct NoOperator;
impl<U: Unit, O: HwOperator<U>> OptionalOperator<U, O> for NoOperator {}

/*
#[derive(Default, Clone)]
struct DutyConfig {
on_matches_cmp_a: CountingDirection,
Expand Down Expand Up @@ -226,23 +221,30 @@ impl Default for GeneratorAction {
}
}
impl From<DutyMode> for DutyConfig {
fn from(val: DutyMode) -> Self {
impl DutyMode {
fn into_duty_cfg<G: Generator>(self) -> DutyConfig<G> {
match val {
DutyMode::ActiveHigh => {
let mut duty_config: DutyConfig = Default::default();
duty_config.on_is_empty.counting_up = GeneratorAction::SetHigh;
duty_config.on_matches_cmp_a.counting_up = GeneratorAction::SetLow;

if G::IS_A {
duty_config.on_matches_cmp_a.counting_up = GeneratorAction::SetLow;
} else {
duty_config.on_matches_cmp_b.counting_up = GeneratorAction::SetLow;
}
duty_config
},
DutyMode::ActiveLow => {
let mut duty_config: DutyConfig = Default::default();
duty_config.on_is_empty.counting_up = GeneratorAction::SetLow;
duty_config.on_matches_cmp_a.counting_up = GeneratorAction::SetHigh;
if G::IS_A {
duty_config.on_matches_cmp_a.counting_up = GeneratorAction::SetHigh;
} else {
duty_config.on_matches_cmp_b.counting_up = GeneratorAction::SetHigh;
}
duty_config
},
}
}
}
} */
51 changes: 39 additions & 12 deletions src/mcpwm/timer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
use std::ptr;

use esp_idf_sys::{mcpwm_counter_type_t_MCPWM_UP_DOWN_COUNTER, mcpwm_counter_type_t_MCPWM_DOWN_COUNTER, mcpwm_counter_type_t_MCPWM_UP_COUNTER, mcpwm_timer_t, mcpwm_timer_handle_t, mcpwm_timer_enable, mcpwm_timer_t_MCPWM_TIMER_0, mcpwm_timer_t_MCPWM_TIMER_1, mcpwm_timer_t_MCPWM_TIMER_2, mcpwm_counter_type_t};

use crate::units::Hertz;
use crate::mcpwm::Unit;

use super::operator::NoOperator;
use super::timer_connection::TimerConnection;


#[derive(Clone, Copy, Debug)]
struct TimerConfig {
frequency: Hertz,
resolution: Hertz,
counter_mode: CounterMode,

// TODO
// on_full,
// on_empty,
// on_stop,
// on_full: FF,
// on_empty: FE,
// on_stop: FS,
}

impl TimerConfig {
Expand Down Expand Up @@ -40,12 +51,12 @@ impl TimerConfig {
//}
//}

struct Timer<U: Unit, T: HwTimer<U>> {
pub struct Timer<U: Unit, T: HwTimer<U>> {
handle: mcpwm_timer_handle_t,
_timer: T,
}

impl Timer {
impl<U: Unit, T: HwTimer<U>> Timer {
pub fn new(timer: T, config: TimerConfig) -> Self {
let config = mcpwm_timer_config_t {
resolution
Expand All @@ -71,7 +82,7 @@ impl Timer {
}

pub fn timer(&self) -> mcpwm_timer_t {
T::timer()
T::ID
}

pub fn release(self) -> T {
Expand All @@ -88,7 +99,7 @@ impl Timer {
}
}

impl Drop for Timer {
impl<U: Unit, T: HwTimer<U>> Drop for Timer<U, T> {
fn drop(self) {
mcpwm_del_timer(self.handle)
}
Expand All @@ -99,8 +110,8 @@ impl Drop for Timer {
#[derive(Clone, Copy, Debug)]
pub enum CounterMode {
/// Timer is frozen or paused
#[cfg(not(esp_idf_version = "4.3"))]
Frozen,
//#[cfg(not(esp_idf_version = "4.3"))]
//Frozen,
/// Edge aligned. The counter will start from its lowest value and increment every clock cycle until the period is reached.
///
/// The wave form will end up looking something like the following:
Expand Down Expand Up @@ -158,11 +169,27 @@ pub enum CounterMode {
impl From<CounterMode> for mcpwm_counter_type_t {
fn from(val: CounterMode) -> Self {
match val {
#[cfg(not(esp_idf_version = "4.3"))]
CounterMode::Frozen => mcpwm_counter_type_t_MCPWM_FREEZE_COUNTER,
//CounterMode::Frozen => mcpwm_counter_type_t_MCPWM_FREEZE_COUNTER,
CounterMode::Up => mcpwm_counter_type_t_MCPWM_UP_COUNTER,
CounterMode::Down => mcpwm_counter_type_t_MCPWM_DOWN_COUNTER,
CounterMode::UpDown => mcpwm_counter_type_t_MCPWM_UP_DOWN_COUNTER,
}
}
}
}

unsafe trait HwTimer<U: Unit> {
const ID: mcpwm_timer_t;
}

macro_rules! impl_timer {
($t:ident, $id:expr) => {
struct $t;
impl<U: Unit> HwTimer<U> for $t {
const ID: mcpwm_timer_t = $id;
}
};
}

impl_timer!(TIMER0, mcpwm_timer_t_MCPWM_TIMER_0);
impl_timer!(TIMER1, mcpwm_timer_t_MCPWM_TIMER_1);
impl_timer!(TIMER2, mcpwm_timer_t_MCPWM_TIMER_2);
Loading

0 comments on commit dd65cd0

Please sign in to comment.