heater: precalculate max_value for software PWM

PWM_TYPE macro for finding the correct pwm type.
This commit is contained in:
Nico Tonnhofer 2017-03-16 11:07:44 +01:00
parent 8e273c2789
commit d9f18f0780
3 changed files with 16 additions and 12 deletions

View File

@ -26,14 +26,16 @@ typedef struct {
uint16_t max_value; uint16_t max_value;
} heater_definition_t; } heater_definition_t;
#define PWM_TYPE(pwm, pin) (((pwm) >= HARDWARE_PWM) ? ((pin ## _PWM) ? (pin ## _PWM) : (U8_HEATER_PWM)SOFTWARE_PWM) : (U8_HEATER_PWM)(pwm))
#undef DEFINE_HEATER_ACTUAL #undef DEFINE_HEATER_ACTUAL
/// \brief helper macro to fill heater definition struct from config.h /// \brief helper macro to fill heater definition struct from config.h
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, max_value) { \ #define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, max_value) { \
&(pin ## _WPORT), \ &(pin ## _WPORT), \
pin ## _PIN, \ pin ## _PIN, \
invert ? 1 : 0, \ invert ? 1 : 0, \
(pwm >= HARDWARE_PWM) ? ((pin ## _PWM) ? (pin ## _PWM) : (U8_HEATER_PWM)SOFTWARE_PWM) : (U8_HEATER_PWM)pwm, \ PWM_TYPE(pwm, pin), \
((max_value * 64 + 12) / 25), \ (PWM_TYPE(pwm, pin) != (U8_HEATER_PWM)SOFTWARE_PWM) ? (((max_value) * 64 + 12) / 25) : (uint16_t)(255UL * 100 / (max_value)), \
}, },
static const heater_definition_t heaters[NUM_HEATERS] = static const heater_definition_t heaters[NUM_HEATERS] =
{ {
@ -43,7 +45,7 @@ static const heater_definition_t heaters[NUM_HEATERS] =
// We test any heater if we need software-pwm // We test any heater if we need software-pwm
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \ #define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
| (((pwm >= HARDWARE_PWM) ? ((pin ## _PWM) ? HARDWARE_PWM : SOFTWARE_PWM) : pwm) == SOFTWARE_PWM) | (PWM_TYPE(pwm, pin) == (U8_HEATER_PWM)SOFTWARE_PWM)
static const uint8_t software_pwm_needed = 0 static const uint8_t software_pwm_needed = 0
#include "config_wrapper.h" #include "config_wrapper.h"
; ;

View File

@ -73,14 +73,16 @@ typedef struct {
uint8_t invert; uint8_t invert;
} heater_definition_t; } heater_definition_t;
#define PWM_TYPE(pwm, pin) (((pwm) >= HARDWARE_PWM) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : (pwm))
#undef DEFINE_HEATER_ACTUAL #undef DEFINE_HEATER_ACTUAL
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, max_value) \ #define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, max_value) \
{ \ { \
{ pwm && pin ## _TIMER ? \ { (PWM_TYPE(pwm, pin) == HARDWARE_PWM ? \
&(pin ## _TIMER->MR[pin ## _MATCH]) : \ &(pin ## _TIMER->MR[pin ## _MATCH]) : \
&(pin ## _PORT->MASKED_ACCESS[MASK(pin ## _PIN)]) }, \ &(pin ## _PORT->MASKED_ACCESS[MASK(pin ## _PIN)]) }, \
((max_value * 64 + 12) / 25), \ (PWM_TYPE(pwm, pin) != SOFTWARE_PWM) ? ((max_value * 64 + 12) / 25) : (uint16_t)(255UL * 100 / max_value), \
((pwm >= HARDWARE_PWM) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : pwm), \ PWM_TYPE(pwm, pin), \
invert ? 1 : 0 \ invert ? 1 : 0 \
}, },
static const heater_definition_t heaters[NUM_HEATERS] = { static const heater_definition_t heaters[NUM_HEATERS] = {
@ -90,7 +92,7 @@ static const heater_definition_t heaters[NUM_HEATERS] = {
// We test any heater if we need software-pwm // We test any heater if we need software-pwm
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \ #define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
| (((pwm >= HARDWARE_PWM) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : pwm) == SOFTWARE_PWM) | (PWM_TYPE(pwm, pin) == SOFTWARE_PWM)
static const uint8_t software_pwm_needed = 0 static const uint8_t software_pwm_needed = 0
#include "config_wrapper.h" #include "config_wrapper.h"
; ;
@ -143,7 +145,7 @@ void heater_init() {
// Auto-generate pin setup. // Auto-generate pin setup.
#undef DEFINE_HEATER_ACTUAL #undef DEFINE_HEATER_ACTUAL
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \ #define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
if ((pwm >= HARDWARE_PWM) && pin ## _TIMER) { \ if (PWM_TYPE(pwm, pin) == HARDWARE_PWM) { \
uint32_t freq; \ uint32_t freq; \
\ \
if (pin ## _TIMER == LPC_TMR16B0) { \ if (pin ## _TIMER == LPC_TMR16B0) { \

View File

@ -252,7 +252,6 @@ void heater_tick(heater_t h, temp_type_t type, uint16_t current_temp, uint16_t t
/** \brief software PWM routine /** \brief software PWM routine
*/ */
#define PWM_MAX 255
void heater_soft_pwm(heater_t index) { void heater_soft_pwm(heater_t index) {
if (software_pwm_needed) { if (software_pwm_needed) {
@ -266,15 +265,16 @@ void heater_soft_pwm(heater_t index) {
} }
// here we are doing a small trick. normally this is // here we are doing a small trick. normally this is
// sd_accu += pwm - (sd_dir * PWM_MAX) // sd_accu += pwm - sd_dir, where sd_dir is 255 or 0.
// here we scale the (sd_dir * PWM_MAX) -part with the max_value. // here we scale the (sd_dir) -part with the max_value.
// max_value is precalculated with 255 * 100 / max_value(%).
// so we get a smooth PWM also for downscaled heaters. the "pwm"-value // so we get a smooth PWM also for downscaled heaters. the "pwm"-value
// is from 0 to 255 in any case, but the sd_accu becomes bigger with // is from 0 to 255 in any case, but the sd_accu becomes bigger with
// smaller max_values. // smaller max_values.
soft_pwm_runtime[index].sd_accu += pwm - soft_pwm_runtime[index].sd_dir; soft_pwm_runtime[index].sd_accu += pwm - soft_pwm_runtime[index].sd_dir;
if (soft_pwm_runtime[index].sd_accu > 0) { if (soft_pwm_runtime[index].sd_accu > 0) {
soft_pwm_runtime[index].sd_dir = PWM_MAX * 256 / heaters[index].max_value; soft_pwm_runtime[index].sd_dir = heaters[index].max_value;
do_heater(index, 255); do_heater(index, 255);
} }
else { else {