heater: add max_pwm and software pwm also for stm32
This commit is contained in:
parent
fbe1af4013
commit
bcb6964ceb
|
|
@ -193,15 +193,19 @@ DEFINE_TEMP_SENSOR(extruder, TT_THERMISTOR, PB_0, THERMISTOR_EXTRUDER)
|
||||||
* *
|
* *
|
||||||
\***************************************************************************/
|
\***************************************************************************/
|
||||||
|
|
||||||
#ifndef DEFINE_HEATER
|
/** \def FORCE_SOFTWARE_PWM
|
||||||
#define DEFINE_HEATER(...)
|
Force software pwm when pwm is sets to 1.
|
||||||
#endif
|
|
||||||
|
Normally any pwm value >= 1 will set the pin to hardware pwm, if available.
|
||||||
|
When FORCE_SOFTWARE_PWM is defined, pwm = 1 is always set to software pwm.
|
||||||
|
*/
|
||||||
|
// #define FORCE_SOFTWARE_PWM
|
||||||
|
|
||||||
/** \def HEATER_PIN
|
/** \def HEATER_PIN
|
||||||
Heater pins a user should be able to choose from in configtool. All
|
Heater pins a user should be able to choose from in configtool. All
|
||||||
commented out.
|
commented out.
|
||||||
*/
|
*/
|
||||||
//#define HEATER_PIN AIO2
|
//#define HEATER_PIN PA_5
|
||||||
|
|
||||||
/** \def DEFINE_HEATER
|
/** \def DEFINE_HEATER
|
||||||
Define your heaters and devices here.
|
Define your heaters and devices here.
|
||||||
|
|
@ -227,14 +231,25 @@ DEFINE_TEMP_SENSOR(extruder, TT_THERMISTOR, PB_0, THERMISTOR_EXTRUDER)
|
||||||
for this pin, e.g. for a MOSFET with a driver.
|
for this pin, e.g. for a MOSFET with a driver.
|
||||||
|
|
||||||
Set 'pwm' to ...
|
Set 'pwm' to ...
|
||||||
1 for using PWM on a PWM-able pin and on/off on other pins.
|
frequency in Hertz (Hz) on ARM based controllers to set PWM frequency of
|
||||||
0 for using on/off on a PWM-able pin, too.
|
this pin's output. Frequency isn't always accurate, Teacup
|
||||||
|
will choose the closest possible one. FAST_PWM is ignored
|
||||||
|
on such controllers. Valid range is 2 to 200'000 Hz.
|
||||||
|
1 on AVR based controllers for using Pulse Width Modulation (PWM)
|
||||||
|
on a pin supporting it. PWM frequency can be influenced only
|
||||||
|
somewhat and only globally with FAST_PWM.
|
||||||
|
0 for using a PWM-able pin in on/off mode.
|
||||||
|
|
||||||
Using PWM usually gives smoother temperature control but can conflict
|
Using PWM usually gives smoother temperature control but can conflict
|
||||||
with slow switches, like solid state relays. PWM frequency can be
|
with slow switches, like solid state relays. A too high frequency can
|
||||||
influenced globally with FAST_PWM, see below.
|
overheat MOSFETs; a too low frequency can make your heater to emit audible
|
||||||
|
noise; so choose wisely.
|
||||||
|
|
||||||
|
Pins which don't allow PWM are operated in software pwm mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//DEFINE_HEATERS_START
|
//DEFINE_HEATERS_START
|
||||||
|
|
||||||
// name pin invert pwm max_pwm
|
// name pin invert pwm max_pwm
|
||||||
DEFINE_HEATER(extruder, PA_5, 0, 10000, 100)
|
DEFINE_HEATER(extruder, PA_5, 0, 10000, 100)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ DEFINE_TEMP_SENSOR(bed, TT_THERMISTOR, PIO1_0,THERMISTOR_BED)
|
||||||
overheat MOSFETs; a too low frequency can make your heater to emit audible
|
overheat MOSFETs; a too low frequency can make your heater to emit audible
|
||||||
noise; so choose wisely.
|
noise; so choose wisely.
|
||||||
|
|
||||||
Pins which don't allow PWM are always operated in on/off mode.
|
Pins which don't allow PWM are operated in software pwm mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//DEFINE_HEATERS_START
|
//DEFINE_HEATERS_START
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
frequency, so you should bother about PWM_SCALE only of you need frequencies
|
frequency, so you should bother about PWM_SCALE only of you need frequencies
|
||||||
below 6 Hz.
|
below 6 Hz.
|
||||||
*/
|
*/
|
||||||
#define PWM_SCALE 255
|
#define PWM_SCALE 1020
|
||||||
|
|
||||||
// some helper macros
|
// some helper macros
|
||||||
#define _EXPANDER(pre, val, post) pre ## val ## post
|
#define _EXPANDER(pre, val, post) pre ## val ## post
|
||||||
|
|
@ -68,23 +68,44 @@ typedef struct {
|
||||||
__IO uint32_t* bsrr;
|
__IO uint32_t* bsrr;
|
||||||
};
|
};
|
||||||
uint16_t masked_pin;
|
uint16_t masked_pin;
|
||||||
uint8_t uses_pwm;
|
|
||||||
|
uint16_t max_value; ///< max value for the heater, for PWM in percent * 256
|
||||||
|
pwm_type_t pwm_type; ///< saves the pwm-type: NO_PWM, SOFTWARE_PWM, HARDWARE_PWM
|
||||||
|
uint8_t invert; ///< Wether the heater pin signal needs to be inverted.
|
||||||
} heater_definition_t;
|
} heater_definition_t;
|
||||||
|
|
||||||
|
// When pwm >= 2 it's hardware pwm, if the pin has hardware pwm.
|
||||||
|
// When pwm == 1 it's software pwm.
|
||||||
|
// pwm == 0 is no pwm at all.
|
||||||
|
// Use this macro only in DEFINE_HEATER_ACTUAL-macros.
|
||||||
|
#define PWM_TYPE(pwm, pin) (((pwm) >= HARDWARE_PWM_START) ? ((pin ## _TIMER) ? HARDWARE_PWM : SOFTWARE_PWM) : (pwm))
|
||||||
|
|
||||||
#undef DEFINE_HEATER_ACTUAL
|
#undef DEFINE_HEATER_ACTUAL
|
||||||
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
|
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, max_value) \
|
||||||
{ \
|
{ \
|
||||||
{ pwm && pin ## _TIMER ? \
|
{ (PWM_TYPE(pwm, pin) == HARDWARE_PWM) ? \
|
||||||
&(pin ## _TIMER-> EXPANDER(CCR, pin ## _CHANNEL,)) : \
|
&(pin ## _TIMER-> EXPANDER(CCR, pin ## _CHANNEL,)) : \
|
||||||
&(pin ## _PORT->BSRR) }, \
|
&(pin ## _PORT->BSRR) }, \
|
||||||
MASK(pin ## _PIN), \
|
MASK(pin ## _PIN), \
|
||||||
pwm && pin ## _TIMER \
|
(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] = {
|
static const heater_definition_t heaters[NUM_HEATERS] = {
|
||||||
#include "config_wrapper.h"
|
#include "config_wrapper.h"
|
||||||
};
|
};
|
||||||
#undef DEFINE_HEATER_ACTUAL
|
#undef DEFINE_HEATER_ACTUAL
|
||||||
|
|
||||||
|
// We test any heater if we need software-pwm
|
||||||
|
#define DEFINE_HEATER_ACTUAL(name, pin, invert, pwm, ...) \
|
||||||
|
| (PWM_TYPE(pwm, pin) == SOFTWARE_PWM)
|
||||||
|
static const uint8_t software_pwm_needed = 0
|
||||||
|
#include "config_wrapper.h"
|
||||||
|
;
|
||||||
|
#undef DEFINE_HEATER_ACTUAL
|
||||||
|
|
||||||
/** Initialise heater subsystem.
|
/** Initialise heater subsystem.
|
||||||
|
|
||||||
Initialise PWM timers, etc. Inspired by heater-arm_lpc11xx.c (pwm.c in LPC1343CodeBase):
|
Initialise PWM timers, etc. Inspired by heater-arm_lpc11xx.c (pwm.c in LPC1343CodeBase):
|
||||||
|
|
@ -156,7 +177,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 && pin ## _TIMER) { \
|
if (PWM_TYPE(pwm, pin) == HARDWARE_PWM) { \
|
||||||
uint32_t freq; \
|
uint32_t freq; \
|
||||||
uint8_t macro_mask; \
|
uint8_t macro_mask; \
|
||||||
if (pin ## _TIMER == TIM1) { \
|
if (pin ## _TIMER == TIM1) { \
|
||||||
|
|
@ -223,22 +244,22 @@ void heater_init() {
|
||||||
heater, every few milliseconds by its PID handler. Using M106 on an output
|
heater, every few milliseconds by its PID handler. Using M106 on an output
|
||||||
with a sensor changes its setting only for a short moment.
|
with a sensor changes its setting only for a short moment.
|
||||||
*/
|
*/
|
||||||
void heater_set(heater_t index, uint8_t value) {
|
void do_heater(heater_t index, uint8_t value) {
|
||||||
|
|
||||||
if (index < NUM_HEATERS) {
|
if (index < NUM_HEATERS) {
|
||||||
|
|
||||||
heaters_runtime[index].heater_output = value;
|
if (heaters[index].pwm_type == HARDWARE_PWM) {
|
||||||
|
|
||||||
if (heaters[index].uses_pwm) {
|
|
||||||
// Remember, we scale, and duty cycle is inverted.
|
// Remember, we scale, and duty cycle is inverted.
|
||||||
*heaters[index].ccr = (uint32_t)value * (PWM_SCALE / 255);
|
*heaters[index].ccr = (uint32_t)((heaters[index].max_value * value) * (PWM_SCALE / 255) / 256);
|
||||||
|
|
||||||
if (DEBUG_PID && (debug_flags & DEBUG_PID))
|
if (DEBUG_PID && (debug_flags & DEBUG_PID))
|
||||||
sersendf_P(PSTR("PWM %su = %lu\n"), index, *heaters[index].ccr);
|
sersendf_P(PSTR("PWM %su = %lu\n"), index, *heaters[index].ccr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*(heaters[index].bsrr) =
|
*(heaters[index].bsrr) =
|
||||||
heaters[index].masked_pin << ((value >= HEATER_THRESHOLD) ? 0 : 16);
|
heaters[index].masked_pin <<
|
||||||
|
((value >= HEATER_THRESHOLD && ! heaters[index].invert) ?
|
||||||
|
0 : 16);
|
||||||
}
|
}
|
||||||
if (value)
|
if (value)
|
||||||
power_on();
|
power_on();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue