2022-07-03 12:11:12 -07:00
|
|
|
#include "pwm.h"
|
2023-04-17 14:11:34 -07:00
|
|
|
#include "dac.h"
|
2022-07-03 12:11:12 -07:00
|
|
|
#include "lambda_conversion.h"
|
2022-12-01 15:42:21 -08:00
|
|
|
#include "port.h"
|
|
|
|
#include "io_pins.h"
|
2022-07-03 12:11:12 -07:00
|
|
|
|
|
|
|
#include "wideband_config.h"
|
|
|
|
|
2023-05-29 15:16:28 -07:00
|
|
|
#include "max3185x.h"
|
2022-12-01 15:42:21 -08:00
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
#include "hal.h"
|
|
|
|
|
2022-07-16 19:42:30 -07:00
|
|
|
#include <rusefi/math.h>
|
2022-12-01 15:42:21 -08:00
|
|
|
#include <rusefi/interpolation.h>
|
2022-07-16 19:42:30 -07:00
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
#ifdef AUXOUT_DAC_PWM_DEVICE
|
|
|
|
|
2023-04-28 22:01:13 -07:00
|
|
|
#ifndef AUXOUT_DAC_PWM_OUTPUT_MODE
|
|
|
|
#define AUXOUT_DAC_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH
|
|
|
|
#endif
|
|
|
|
#ifndef AUXOUT_DAC_PWM_NC_OUTPUT_MODE
|
|
|
|
#define AUXOUT_DAC_PWM_NC_OUTPUT_MODE PWM_OUTPUT_ACTIVE_LOW
|
|
|
|
#endif
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
// Rev2 low pass filter cut frequency is about 21Hz (sic!)
|
|
|
|
// 48Mhz / (2 ^ 12) ~= 12 KHz
|
2022-12-03 17:23:02 -08:00
|
|
|
// 64mhz / (2 ^ 12) ~= 16 KHz
|
2023-04-28 22:01:13 -07:00
|
|
|
static PWMConfig auxPwmConfig = {
|
2023-04-27 12:55:05 -07:00
|
|
|
.frequency = STM32_SYSCLK,
|
|
|
|
.period = 1 << 12,
|
|
|
|
.callback = nullptr,
|
|
|
|
.channels = {
|
2023-04-28 22:01:13 -07:00
|
|
|
[0] = {0, nullptr},
|
|
|
|
[1] = {0, nullptr},
|
|
|
|
[2] = {0, nullptr},
|
|
|
|
[3] = {0, nullptr}
|
2022-07-03 12:11:12 -07:00
|
|
|
},
|
2023-04-27 12:55:05 -07:00
|
|
|
.cr2 = 0,
|
2022-07-03 12:11:12 -07:00
|
|
|
#if STM32_PWM_USE_ADVANCED
|
2023-04-27 12:55:05 -07:00
|
|
|
.bdtr = 0,
|
2022-07-03 12:11:12 -07:00
|
|
|
#endif
|
2023-04-27 12:55:05 -07:00
|
|
|
.dier = 0
|
2022-07-03 12:11:12 -07:00
|
|
|
};
|
|
|
|
|
2023-04-28 22:01:13 -07:00
|
|
|
static void auxDacFillPwmConfig(void)
|
|
|
|
{
|
|
|
|
auxPwmConfig.channels[AUXOUT_DAC_PWM_CHANNEL_0].mode = AUXOUT_DAC_PWM_OUTPUT_MODE;
|
|
|
|
auxPwmConfig.channels[AUXOUT_DAC_PWM_CHANNEL_1].mode = AUXOUT_DAC_PWM_OUTPUT_MODE;
|
|
|
|
#ifdef AUXOUT_DAC_PWM_CHANNEL_0_NC
|
|
|
|
auxPwmConfig.channels[AUXOUT_DAC_PWM_CHANNEL_0_NC].mode = AUXOUT_DAC_PWM_NC_OUTPUT_MODE;
|
|
|
|
#endif
|
|
|
|
#ifdef AUXOUT_DAC_PWM_CHANNEL_1_NC
|
|
|
|
auxPwmConfig.channels[AUXOUT_DAC_PWM_CHANNEL_1_NC].mode = AUXOUT_DAC_PWM_NC_OUTPUT_MODE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
static Pwm auxDac(AUXOUT_DAC_PWM_DEVICE);
|
|
|
|
|
2023-04-28 22:01:13 -07:00
|
|
|
static const uint8_t auxOutPwmCh[AFR_CHANNELS] = {
|
2022-07-15 23:02:02 -07:00
|
|
|
AUXOUT_DAC_PWM_CHANNEL_0,
|
|
|
|
#if (AFR_CHANNELS > 1)
|
|
|
|
AUXOUT_DAC_PWM_CHANNEL_1,
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2023-04-28 22:01:13 -07:00
|
|
|
static const int8_t auxOutPwmChN[AFR_CHANNELS] = {
|
|
|
|
#ifdef AUXOUT_DAC_PWM_CHANNEL_0_NC
|
|
|
|
AUXOUT_DAC_PWM_CHANNEL_0_NC,
|
|
|
|
#else
|
|
|
|
-1,
|
|
|
|
#endif
|
|
|
|
#if (AFR_CHANNELS > 1)
|
|
|
|
#ifdef AUXOUT_DAC_PWM_CHANNEL_1_NC
|
|
|
|
AUXOUT_DAC_PWM_CHANNEL_1_NC,
|
|
|
|
#else
|
|
|
|
-1,
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
void SetAuxDac(int channel, float voltage)
|
|
|
|
{
|
|
|
|
voltage = voltage / AUXOUT_GAIN;
|
|
|
|
auto duty = voltage / VCC_VOLTS;
|
|
|
|
duty = clampF(0, duty, 1);
|
|
|
|
|
2022-07-15 23:02:02 -07:00
|
|
|
auxDac.SetDuty(auxOutPwmCh[channel], duty);
|
2023-04-28 22:01:13 -07:00
|
|
|
// Ripple cancelation channel
|
|
|
|
if (auxOutPwmChN[channel >= 0]) {
|
|
|
|
auxDac.SetDuty(auxOutPwmChN[channel], duty);
|
|
|
|
}
|
2022-07-03 12:11:12 -07:00
|
|
|
}
|
|
|
|
|
2022-08-31 18:02:02 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef AUXOUT_DAC_DEVICE
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
2022-12-06 16:46:07 -08:00
|
|
|
static float AuxGetInputSignal(AuxOutputMode sel)
|
2022-12-01 15:42:21 -08:00
|
|
|
{
|
|
|
|
switch (sel)
|
|
|
|
{
|
2022-12-06 16:46:07 -08:00
|
|
|
case AuxOutputMode::Afr0:
|
|
|
|
return 14.7f * GetLambda(0);
|
|
|
|
case AuxOutputMode::Afr1:
|
|
|
|
return 14.7f * GetLambda(1);
|
|
|
|
case AuxOutputMode::Lambda0:
|
|
|
|
return GetLambda(0);
|
|
|
|
case AuxOutputMode::Lambda1:
|
|
|
|
return GetLambda(1);
|
2022-12-01 15:42:21 -08:00
|
|
|
#if HAL_USE_SPI
|
2022-12-06 16:46:07 -08:00
|
|
|
case AuxOutputMode::Egt0:
|
|
|
|
return getEgtDrivers()[0].temperature;
|
|
|
|
case AuxOutputMode::Egt1:
|
|
|
|
return getEgtDrivers()[1].temperature;
|
2022-12-01 15:42:21 -08:00
|
|
|
#endif
|
|
|
|
default:
|
2022-12-06 16:46:07 -08:00
|
|
|
return 0;
|
2022-12-01 15:42:21 -08:00
|
|
|
}
|
2022-12-06 16:46:07 -08:00
|
|
|
|
|
|
|
return 0;
|
2022-12-01 15:42:21 -08:00
|
|
|
}
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
/* TODO: merge with some other communication thread? */
|
|
|
|
static THD_WORKING_AREA(waAuxOutThread, 256);
|
|
|
|
void AuxOutThread(void*)
|
|
|
|
{
|
2022-12-02 01:46:23 -08:00
|
|
|
const auto cfg = GetConfiguration();
|
2022-12-01 15:42:21 -08:00
|
|
|
|
2022-12-12 19:29:32 -08:00
|
|
|
chRegSetThreadName("Aux out");
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
while(1)
|
|
|
|
{
|
2022-08-29 17:19:30 -07:00
|
|
|
for (int ch = 0; ch < AFR_CHANNELS; ch++)
|
|
|
|
{
|
2022-12-06 16:46:07 -08:00
|
|
|
float input = AuxGetInputSignal(cfg->auxOutputSource[ch]);
|
2022-12-02 01:46:23 -08:00
|
|
|
float voltage = interpolate2d(input, cfg->auxOutBins[ch], cfg->auxOutValues[ch]);
|
2022-12-01 15:42:21 -08:00
|
|
|
|
2022-08-31 18:02:02 -07:00
|
|
|
SetAuxDac(ch, voltage);
|
2022-08-29 17:19:30 -07:00
|
|
|
}
|
2022-07-03 12:11:12 -07:00
|
|
|
|
|
|
|
chThdSleepMilliseconds(10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void InitAuxDac()
|
|
|
|
{
|
2022-08-31 18:02:02 -07:00
|
|
|
#if defined(AUXOUT_DAC_PWM_DEVICE)
|
2023-04-28 22:01:13 -07:00
|
|
|
auxDacFillPwmConfig();
|
2022-07-03 12:11:12 -07:00
|
|
|
auxDac.Start(auxPwmConfig);
|
|
|
|
|
|
|
|
SetAuxDac(0, 0.0);
|
|
|
|
SetAuxDac(1, 0.0);
|
2022-08-31 18:02:02 -07:00
|
|
|
#endif
|
|
|
|
#if defined(AUXOUT_DAC_DEVICE)
|
|
|
|
auxDac.Start(auxDacConfig);
|
|
|
|
|
|
|
|
SetAuxDac(0, 0.0);
|
|
|
|
#endif
|
2022-07-03 12:11:12 -07:00
|
|
|
|
|
|
|
chThdCreateStatic(waAuxOutThread, sizeof(waAuxOutThread), NORMALPRIO, AuxOutThread, nullptr);
|
|
|
|
}
|
|
|
|
|
2022-08-31 18:02:02 -07:00
|
|
|
#else /* (AUXOUT_DAC_PWM_DEVICE || AUXOUT_DAC_DEVICE) */
|
|
|
|
|
|
|
|
void InitAuxDac()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-07-03 12:11:12 -07:00
|
|
|
#endif
|