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

View File

@ -73,14 +73,16 @@ typedef struct {
uint8_t invert;
} heater_definition_t;
#define PWM_TYPE(pwm, pin) (((pwm) >= HARDWARE_PWM) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : (pwm))
#undef DEFINE_HEATER_ACTUAL
#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 ## _PORT->MASKED_ACCESS[MASK(pin ## _PIN)]) }, \
((max_value * 64 + 12) / 25), \
((pwm >= HARDWARE_PWM) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : pwm), \
(PWM_TYPE(pwm, pin) != SOFTWARE_PWM) ? ((max_value * 64 + 12) / 25) : (uint16_t)(255UL * 100 / max_value), \
PWM_TYPE(pwm, pin), \
invert ? 1 : 0 \
},
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
#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
#include "config_wrapper.h"
;
@ -143,7 +145,7 @@ void heater_init() {
// Auto-generate pin setup.
#undef DEFINE_HEATER_ACTUAL
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
if ((pwm >= HARDWARE_PWM) && pin ## _TIMER) { \
if (PWM_TYPE(pwm, pin) == HARDWARE_PWM) { \
uint32_t freq; \
\
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
*/
#define PWM_MAX 255
void heater_soft_pwm(heater_t index) {
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
// sd_accu += pwm - (sd_dir * PWM_MAX)
// here we scale the (sd_dir * PWM_MAX) -part with the max_value.
// sd_accu += pwm - sd_dir, where sd_dir is 255 or 0.
// 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
// is from 0 to 255 in any case, but the sd_accu becomes bigger with
// smaller max_values.
soft_pwm_runtime[index].sd_accu += pwm - soft_pwm_runtime[index].sd_dir;
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);
}
else {