dc motor api (#2869)

* iwpm

* dc motor has configure

* consume

* format

* spelling
This commit is contained in:
Matthew Kennedy 2021-06-26 18:42:40 -07:00 committed by GitHub
parent c1178a0464
commit cd055a687d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 68 deletions

View File

@ -31,7 +31,7 @@ private:
SimplePwm m_pwmDir2; SimplePwm m_pwmDir2;
public: public:
DcHardware() : dcMotor(&m_pwmEnable, &m_pwmDir1, &m_pwmDir2, &m_disablePin) {} DcHardware() : dcMotor(m_disablePin) {}
TwoPinDcMotor dcMotor; TwoPinDcMotor dcMotor;
@ -83,6 +83,8 @@ public:
0 0
); );
#endif /* EFI_UNIT_TEST */ #endif /* EFI_UNIT_TEST */
dcMotor.configure(m_pwmEnable, m_pwmDir1, m_pwmDir2);
} }
}; };

View File

@ -10,15 +10,18 @@
#include "efi_gpio.h" #include "efi_gpio.h"
#include "pwm_generator_logic.h" #include "pwm_generator_logic.h"
TwoPinDcMotor::TwoPinDcMotor(SimplePwm* enable, SimplePwm* dir1, SimplePwm* dir2, OutputPin* disablePin) TwoPinDcMotor::TwoPinDcMotor(OutputPin& disablePin)
: m_enable(enable) : m_disable(&disablePin)
, m_dir1(dir1)
, m_dir2(dir2)
, m_disable(disablePin)
{ {
disable(); disable();
} }
void TwoPinDcMotor::configure(IPwm& enable, IPwm& dir1, IPwm& dir2) {
m_enable = &enable;
m_dir1 = &dir1;
m_dir2 = &dir2;
}
void TwoPinDcMotor::enable() { void TwoPinDcMotor::enable() {
if (m_disable) { if (m_disable) {
m_disable->setValue(false); m_disable->setValue(false);
@ -49,34 +52,43 @@ bool TwoPinDcMotor::set(float duty)
{ {
m_value = duty; m_value = duty;
bool isPositive = duty > 0; // If not init, don't try to set
if (!m_dir1 || !m_dir2 || !m_enable) {
if (m_disable) {
m_disable->setValue(true);
}
if (!isPositive) { return false;
duty = -duty; }
}
// below here 'duty' is a not negative bool isPositive = duty > 0;
// Clamp to 100% if (!isPositive) {
if (duty > 1.0f) { duty = -duty;
duty = 1.0f; }
}
// Disable for very small duty
else if (duty < 0.01f)
{
duty = 0.0f;
}
// If we're in two pin mode, force 100%, else use this pin to PWM // below here 'duty' is a not negative
float enableDuty = m_type == ControlType::PwmEnablePin ? duty : 1;
// Direction pins get 100% duty unless we're in PwmDirectionPins mode // Clamp to 100%
float dirDuty = m_type == ControlType::PwmDirectionPins ? duty : 1; if (duty > 1.0f) {
duty = 1.0f;
}
// Disable for very small duty
else if (duty < 0.01f)
{
duty = 0.0f;
}
m_enable->setSimplePwmDutyCycle(enableDuty); // If we're in two pin mode, force 100%, else use this pin to PWM
m_dir1->setSimplePwmDutyCycle(isPositive ? dirDuty : 0); float enableDuty = m_type == ControlType::PwmEnablePin ? duty : 1;
m_dir2->setSimplePwmDutyCycle(isPositive ? 0 : dirDuty);
// This motor has no fault detection, so always return false (indicate success). // Direction pins get 100% duty unless we're in PwmDirectionPins mode
return false; float dirDuty = m_type == ControlType::PwmDirectionPins ? duty : 1;
m_enable->setSimplePwmDutyCycle(enableDuty);
m_dir1->setSimplePwmDutyCycle(isPositive ? dirDuty : 0);
m_dir2->setSimplePwmDutyCycle(isPositive ? 0 : dirDuty);
// This motor has no fault detection, so always return false (indicate success).
return false;
} }

View File

@ -19,26 +19,26 @@
class DcMotor class DcMotor
{ {
public: public:
/** /**
* @brief Sets the motor duty cycle. * @brief Sets the motor duty cycle.
* @param duty +1.0f represents full power forward, and -1.0f represents full power backward. * @param duty +1.0f represents full power forward, and -1.0f represents full power backward.
* @return True if any fault was detected driving the motor, and false if successful. * @return True if any fault was detected driving the motor, and false if successful.
*/ */
virtual bool set(float duty) = 0; virtual bool set(float duty) = 0;
/** /**
* @brief Get the current motor duty cycle. * @brief Get the current motor duty cycle.
* @return The current duty cycle setting. +1.0f represents full power forward, and -1.0f represents full power backward. * @return The current duty cycle setting. +1.0f represents full power forward, and -1.0f represents full power backward.
*/ */
virtual float get() const = 0; virtual float get() const = 0;
virtual void disable() = 0; virtual void disable() = 0;
virtual void enable() = 0; virtual void enable() = 0;
virtual bool isOpenDirection() const = 0; virtual bool isOpenDirection() const = 0;
}; };
class SimplePwm; struct IPwm;
class OutputPin; class OutputPin;
/** /**
@ -48,13 +48,13 @@ class OutputPin;
class TwoPinDcMotor : public DcMotor class TwoPinDcMotor : public DcMotor
{ {
public: public:
enum class ControlType enum class ControlType
{ {
/** /**
* For example TLE7209 - two control wires: * For example TLE7209 - two control wires:
* PWM on both wires - one to open, another to close * PWM on both wires - one to open, another to close
*/ */
PwmDirectionPins, PwmDirectionPins,
/** /**
* The control/enable pin is used for PWM and disable, and the two direction pins are used * The control/enable pin is used for PWM and disable, and the two direction pins are used
* to set the polarity of each half of the H bridge. setting {dir1,dir2} = 10 should, * to set the polarity of each half of the H bridge. setting {dir1,dir2} = 10 should,
@ -67,31 +67,33 @@ public:
* TLE9201 with two wire control also uses this mode * TLE9201 with two wire control also uses this mode
* PWM on one pin, open/close using one binary direction pin, second direction pin unused * PWM on one pin, open/close using one binary direction pin, second direction pin unused
*/ */
PwmEnablePin, PwmEnablePin,
}; };
private: private:
SimplePwm* const m_enable; IPwm* m_enable;
SimplePwm* const m_dir1; IPwm* m_dir1;
SimplePwm* const m_dir2; IPwm* m_dir2;
OutputPin* const m_disable; OutputPin* const m_disable;
float m_value = 0; float m_value = 0;
ControlType m_type = ControlType::PwmDirectionPins; ControlType m_type = ControlType::PwmDirectionPins;
public: public:
/** /**
* @param enable SimplePwm driver for enable pin, for PWM speed control. * @param enable IPwm driver for enable pin, for PWM speed control.
* @param dir1 Enable 1 or direction 1 pin. Gets set high to rotate forward. * @param dir1 Enable 1 or direction 1 pin. Gets set high to rotate forward.
* @param dir2 Enable 2 or direction 2 pin. Gets set high to rotate backward. * @param dir2 Enable 2 or direction 2 pin. Gets set high to rotate backward.
*/ */
TwoPinDcMotor(SimplePwm* enable, SimplePwm* dir1, SimplePwm* dir2, OutputPin* disable); TwoPinDcMotor(OutputPin& disable);
virtual bool set(float duty) override; void configure(IPwm& enable, IPwm& dir1, IPwm& dir2);
float get() const override;
bool isOpenDirection() const override; virtual bool set(float duty) override;
float get() const override;
bool isOpenDirection() const override;
void enable() override; void enable() override;
void disable() override; void disable() override;
void setType(ControlType type) { m_type = type; } void setType(ControlType type) { m_type = type; }
}; };

View File

@ -117,11 +117,15 @@ private:
struct hardware_pwm; struct hardware_pwm;
class SimplePwm : public PwmConfig { struct IPwm {
virtual void setSimplePwmDutyCycle(float dutyCycle) = 0;
};
class SimplePwm : public PwmConfig, public IPwm {
public: public:
SimplePwm(); SimplePwm();
explicit SimplePwm(const char *name); explicit SimplePwm(const char *name);
virtual void setSimplePwmDutyCycle(float dutyCycle); void setSimplePwmDutyCycle(float dutyCycle) override;
pin_state_t pinStates[2]; pin_state_t pinStates[2];
SingleChannelStateSequence sr[1]; SingleChannelStateSequence sr[1];
float _switchTimes[2]; float _switchTimes[2];