From bfe0b3a2c93400d662b150512a156abef08a4899 Mon Sep 17 00:00:00 2001 From: rusefillc <48498823+rusefillc@users.noreply.github.com> Date: Wed, 31 Aug 2022 21:02:02 -0400 Subject: [PATCH] Dac logic (#138) * auxout: support analog output through DAC * auxout: empty InitAuxDac for boards with no analog out * numbers * numbers * less fun comment Co-authored-by: Andrey Gusakov Co-authored-by: rusefillc --- firmware/auxout.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++- firmware/main.cpp | 3 -- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/firmware/auxout.cpp b/firmware/auxout.cpp index 74fa709..64f2d59 100644 --- a/firmware/auxout.cpp +++ b/firmware/auxout.cpp @@ -47,6 +47,72 @@ void SetAuxDac(int channel, float voltage) auxDac.SetDuty(auxOutPwmCh[channel], duty); } +#endif + +#ifdef AUXOUT_DAC_DEVICE + +class Dac +{ +public: + Dac(DACDriver& driver); + + void Start(DACConfig& config); + void SetVoltage(int channel, float duty); + float GetLastVoltage(int channel); + +private: + DACDriver* const m_driver; + float m_voltageFloat[2]; +}; + +Dac::Dac(DACDriver& driver) + : m_driver(&driver) +{ +} + +void Dac::Start(DACConfig& config) +{ + dacStart(m_driver, &config); +} + +void Dac::SetVoltage(int channel, float voltage) { + voltage = clampF(0, voltage, VCC_VOLTS); + m_voltageFloat[channel] = voltage; + + dacPutChannelX(m_driver, channel, voltage / VCC_VOLTS * (1 << 12)); +} + +float Dac::GetLastVoltage(int channel) +{ + return m_voltageFloat[channel]; +} + +static DACConfig auxDacConfig = { + .init = 2047U, + .datamode = DAC_DHRM_12BIT_RIGHT, + .cr = 0 +}; + +static Dac auxDac(AUXOUT_DAC_DEVICE); + +static const uint8_t auxOutDacCh[] = { + AUXOUT_DAC_CHANNEL_0, +#if (AFR_CHANNELS > 1) + AUXOUT_DAC_CHANNEL_1, +#endif +}; + +void SetAuxDac(int channel, float voltage) +{ + voltage = voltage / AUXOUT_GAIN; + + auxDac.SetVoltage(auxOutDacCh[channel], voltage); +} + +#endif /* AUXOUT_DAC_DEVICE */ + +#if (defined(AUXOUT_DAC_PWM_DEVICE) || defined(AUXOUT_DAC_DEVICE)) + /* TODO: merge with some other communication thread? */ static THD_WORKING_AREA(waAuxOutThread, 256); void AuxOutThread(void*) @@ -55,7 +121,16 @@ void AuxOutThread(void*) { for (int ch = 0; ch < AFR_CHANNELS; ch++) { - SetAuxDac(ch, GetLambda(ch)); + float lambda = GetLambda(ch); + // todo: make translation configurable + if (lambda < 0.7) + lambda = 0.7; + if (lambda > 1.3) + lambda = 1.3; + + // https://rusefi.com/forum/viewtopic.php?f=4&t=2410 for now + float voltage = 1 - (1.3 - lambda) / 0.6; + SetAuxDac(ch, voltage); } chThdSleepMilliseconds(10); @@ -64,12 +139,25 @@ void AuxOutThread(void*) void InitAuxDac() { +#if defined(AUXOUT_DAC_PWM_DEVICE) auxDac.Start(auxPwmConfig); SetAuxDac(0, 0.0); SetAuxDac(1, 0.0); +#endif +#if defined(AUXOUT_DAC_DEVICE) + auxDac.Start(auxDacConfig); + + SetAuxDac(0, 0.0); +#endif chThdCreateStatic(waAuxOutThread, sizeof(waAuxOutThread), NORMALPRIO, AuxOutThread, nullptr); } +#else /* (AUXOUT_DAC_PWM_DEVICE || AUXOUT_DAC_DEVICE) */ + +void InitAuxDac() +{ +} + #endif diff --git a/firmware/main.cpp b/firmware/main.cpp index aecca32..dbd955f 100644 --- a/firmware/main.cpp +++ b/firmware/main.cpp @@ -28,10 +28,7 @@ int main() { InitPumpDac(); StartHeaterControl(); StartPumpControl(); - -#ifdef AUXOUT_DAC_PWM_DEVICE InitAuxDac(); -#endif InitCan(); InitUart();