diff --git a/firmware/Makefile b/firmware/Makefile index dd37fc4..86bbabd 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -146,6 +146,7 @@ CPPSRC = $(ALLCPPSRC) \ uart.cpp \ shared/crc.cpp \ interpolation.cpp \ + auxout.cpp \ console/binary/tunerstudio_io_serial.cpp \ console/binary/tunerstudio_io.cpp \ main.cpp diff --git a/firmware/auxout.cpp b/firmware/auxout.cpp new file mode 100644 index 0000000..b94681f --- /dev/null +++ b/firmware/auxout.cpp @@ -0,0 +1,65 @@ +#include "pwm.h" +#include "lambda_conversion.h" + +#include "wideband_config.h" + +#include "hal.h" + +#ifdef AUXOUT_DAC_PWM_DEVICE + +// Rev2 low pass filter cut frequency is about 21Hz (sic!) +// 48Mhz / (2 ^ 12) ~= 12 KHz +PWMConfig auxPwmConfig = { + 48'000'000, + 1 << 12, + nullptr, + { + {PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, nullptr}, + {PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, nullptr}, + {PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, nullptr}, + {PWM_OUTPUT_ACTIVE_HIGH | PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH, nullptr} + }, + 0, + 0, +#if STM32_PWM_USE_ADVANCED + 0 +#endif +}; + +static Pwm auxDac(AUXOUT_DAC_PWM_DEVICE); + +extern float clampF(float min, float clamp, float max); + +void SetAuxDac(int channel, float voltage) +{ + voltage = voltage / AUXOUT_GAIN; + auto duty = voltage / VCC_VOLTS; + duty = 1.0 - duty; + duty = clampF(0, duty, 1); + + auxDac.SetDuty(channel ? AUXOUT_DAC_PWM_CHANNEL_1 : AUXOUT_DAC_PWM_CHANNEL_0, duty); +} + +/* TODO: merge with some other communication thread? */ +static THD_WORKING_AREA(waAuxOutThread, 256); +void AuxOutThread(void*) +{ + while(1) + { + SetAuxDac(0, GetLambda()); + + chThdSleepMilliseconds(10); + } +} + +void InitAuxDac() +{ + auxDac.Start(auxPwmConfig); + + SetAuxDac(0, 0.0); + SetAuxDac(1, 0.0); + + chThdCreateStatic(waAuxOutThread, sizeof(waAuxOutThread), NORMALPRIO, AuxOutThread, nullptr); +} + +#endif diff --git a/firmware/auxout.h b/firmware/auxout.h new file mode 100644 index 0000000..c78ea7d --- /dev/null +++ b/firmware/auxout.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +void InitAuxDac(); +void SetAuxDac(int channel, float voltage); diff --git a/firmware/boards/f1_rev2/io/io_pins.h b/firmware/boards/f1_rev2/io/io_pins.h index ad6afee..aba3891 100644 --- a/firmware/boards/f1_rev2/io/io_pins.h +++ b/firmware/boards/f1_rev2/io/io_pins.h @@ -26,6 +26,13 @@ #define PUMP_DAC_PWM_DEVICE PWMD2 #define PUMP_DAC_PWM_CHANNEL 1 +// TIM1 - DAC for AUX outputs +#define AUXOUT_DAC_PWM_DEVICE PWMD1 +// PB14 - TIM1_CH2N +#define AUXOUT_DAC_PWM_CHANNEL_0 1 +// PB15 - TIM1_CH3N +#define AUXOUT_DAC_PWM_CHANNEL_1 2 + #define ID_SEL1_PORT GPIOC #define ID_SEL1_PIN 13 diff --git a/firmware/boards/f1_rev2/mcuconf.h b/firmware/boards/f1_rev2/mcuconf.h index 6512bfa..feccd54 100644 --- a/firmware/boards/f1_rev2/mcuconf.h +++ b/firmware/boards/f1_rev2/mcuconf.h @@ -133,8 +133,8 @@ /* * PWM driver system settings. */ -#define STM32_PWM_USE_ADVANCED FALSE -#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_ADVANCED TRUE +#define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 TRUE #define STM32_PWM_USE_TIM3 FALSE #define STM32_PWM_USE_TIM4 TRUE diff --git a/firmware/boards/f1_rev2/wideband_board_config.h b/firmware/boards/f1_rev2/wideband_board_config.h index de916dd..71b3529 100644 --- a/firmware/boards/f1_rev2/wideband_board_config.h +++ b/firmware/boards/f1_rev2/wideband_board_config.h @@ -35,3 +35,9 @@ // Nernst voltage & ESR sense // ******************************* #define VM_RESISTOR_VALUE (0) + +// ******************************* +// AUX outputs +// ******************************* +// OpAmp with 82K + 160K +#define AUXOUT_GAIN ((82.0 + 160.0) / 160.0) diff --git a/firmware/main.cpp b/firmware/main.cpp index 769a3bc..905f753 100644 --- a/firmware/main.cpp +++ b/firmware/main.cpp @@ -9,6 +9,7 @@ #include "sampling.h" #include "uart.h" #include "io_pins.h" +#include "auxout.h" using namespace wbo; @@ -25,6 +26,10 @@ int main() { StartHeaterControl(); StartPumpControl(); +#ifdef AUXOUT_DAC_PWM_DEVICE + InitAuxDac(); +#endif + InitCan(); #ifdef ECHO_UART InitUart();