mirror of https://github.com/rusefi/wideband.git
132 lines
3.1 KiB
C++
132 lines
3.1 KiB
C++
#include "ch.h"
|
|
#include "hal.h"
|
|
#include "pwm.h"
|
|
|
|
#include "heater_control.h"
|
|
#include "port.h"
|
|
#include "sampling.h"
|
|
|
|
// 400khz / 1024 = 390hz PWM
|
|
static Pwm heaterPwm(HEATER_PWM_DEVICE);
|
|
static const PWMConfig heaterPwmConfig = {
|
|
.frequency = 400'000,
|
|
.period = 1024,
|
|
.callback = nullptr,
|
|
.channels = {
|
|
{PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW, nullptr},
|
|
{PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW, nullptr},
|
|
{PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW, nullptr},
|
|
{PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW, nullptr}
|
|
},
|
|
.cr2 = 0,
|
|
#if STM32_PWM_USE_ADVANCED
|
|
.bdtr = 0,
|
|
#endif
|
|
.dier = 0
|
|
};
|
|
|
|
class HeaterController : public HeaterControllerBase {
|
|
public:
|
|
HeaterController(int ch, int pwm_ch)
|
|
: HeaterControllerBase(ch, HEATER_PREHEAT_TIME, HEATER_WARMUP_TIMEOUT)
|
|
, pwm_ch(pwm_ch)
|
|
{
|
|
}
|
|
|
|
void SetDuty(float duty) const override
|
|
{
|
|
heaterPwm.SetDuty(pwm_ch, duty);
|
|
}
|
|
|
|
// TODO: private:
|
|
public:
|
|
const uint8_t pwm_ch;
|
|
};
|
|
|
|
HeaterController heaterControllers[AFR_CHANNELS] =
|
|
{
|
|
{ 0, HEATER_PWM_CHANNEL_0 },
|
|
|
|
#if AFR_CHANNELS >= 2
|
|
{ 1, HEATER_PWM_CHANNEL_1 },
|
|
#endif
|
|
|
|
#if AFR_CHANNELS >= 3
|
|
{ 1, HEATER_PWM_CHANNEL_2 },
|
|
#endif
|
|
|
|
#if AFR_CHANNELS >= 4
|
|
{ 1, HEATER_PWM_CHANNEL_3 },
|
|
#endif
|
|
};
|
|
|
|
const IHeaterController& GetHeaterController(int ch)
|
|
{
|
|
return heaterControllers[ch];
|
|
}
|
|
|
|
static THD_WORKING_AREA(waHeaterThread, 256);
|
|
static void HeaterThread(void*)
|
|
{
|
|
int i;
|
|
|
|
chRegSetThreadName("Heater");
|
|
|
|
// Wait for temperature sensing to stabilize so we don't
|
|
// immediately think we overshot the target temperature
|
|
chThdSleepMilliseconds(1000);
|
|
|
|
// Configure heater controllers for sensor type
|
|
for (i = 0; i < AFR_CHANNELS; i++) {
|
|
auto& h = heaterControllers[i];
|
|
switch (GetSensorType()) {
|
|
case SensorType::LSU42:
|
|
h.Configure(730, 80);
|
|
break;
|
|
case SensorType::LSUADV:
|
|
h.Configure(785, 300);
|
|
break;
|
|
case SensorType::LSU49:
|
|
default:
|
|
h.Configure(780, 300);
|
|
break;
|
|
}
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
auto heaterAllowState = GetHeaterAllowed();
|
|
|
|
for (i = 0; i < AFR_CHANNELS; i++) {
|
|
const auto& sampler = GetSampler(i);
|
|
auto& heater = heaterControllers[i];
|
|
|
|
heater.Update(sampler, heaterAllowState);
|
|
}
|
|
|
|
// Loop at ~20hz
|
|
chThdSleepMilliseconds(HEATER_CONTROL_PERIOD);
|
|
}
|
|
}
|
|
|
|
void StartHeaterControl()
|
|
{
|
|
heaterPwm.Start(heaterPwmConfig);
|
|
heaterPwm.SetDuty(heaterControllers[0].pwm_ch, 0);
|
|
#if (AFR_CHANNELS > 1)
|
|
heaterPwm.SetDuty(heaterControllers[1].pwm_ch, 0);
|
|
#endif
|
|
|
|
chThdCreateStatic(waHeaterThread, sizeof(waHeaterThread), NORMALPRIO + 1, HeaterThread, nullptr);
|
|
}
|
|
|
|
float GetHeaterDuty(int ch)
|
|
{
|
|
return heaterPwm.GetLastDuty(heaterControllers[ch].pwm_ch);
|
|
}
|
|
|
|
HeaterState GetHeaterState(int ch)
|
|
{
|
|
return heaterControllers[ch].GetHeaterState();
|
|
}
|