Reimplement disable_heater to take immediate effect
Split off setIsrTargetTemperatures and temp_mgr_pid() so that we can propagate the target temperatures instantaneously down the pid/pwm chain during emergencies. This reduces the amount of code in disable_heater() itself, making it a bit more maintenable. The bed still isn't disabled on-the-spot yet, due to the heatbed_pwm automaton. To be improved later.
This commit is contained in:
parent
e070bc6455
commit
7659844012
2 changed files with 79 additions and 62 deletions
|
@ -909,45 +909,6 @@ void temp_runaway_stop(bool isPreheat, bool isBed)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
void disable_heater()
|
||||
{
|
||||
setAllTargetHotends(0);
|
||||
setTargetBed(0);
|
||||
#if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
|
||||
target_temperature[0]=0;
|
||||
soft_pwm[0]=0;
|
||||
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1
|
||||
WRITE(HEATER_0_PIN,LOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1
|
||||
target_temperature[1]=0;
|
||||
soft_pwm[1]=0;
|
||||
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
|
||||
WRITE(HEATER_1_PIN,LOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2
|
||||
target_temperature[2]=0;
|
||||
soft_pwm[2]=0;
|
||||
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
|
||||
WRITE(HEATER_2_PIN,LOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
|
||||
target_temperature_bed=0;
|
||||
soft_pwm_bed=0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
bedPWMDisabled = 0;
|
||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||
//WRITE(HEATER_BED_PIN,LOW);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
//! codes of alert messages for the LCD - it is shorter to compare an uin8_t
|
||||
//! than raw const char * of the messages themselves.
|
||||
//! Could be used for MAXTEMP situations too - after reaching MAXTEMP and turning off the heater automagically
|
||||
|
@ -1786,6 +1747,25 @@ bool has_temperature_compensation()
|
|||
#define ENABLE_TEMP_MGR_INTERRUPT() TIMSK5 |= (1<<OCIE5A)
|
||||
#define DISABLE_TEMP_MGR_INTERRUPT() TIMSK5 &= ~(1<<OCIE5A)
|
||||
|
||||
// RAII helper class to run a code block with temp_mgr_isr disabled
|
||||
class TempMgrGuard
|
||||
{
|
||||
bool temp_mgr_state;
|
||||
|
||||
public:
|
||||
TempMgrGuard() {
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
temp_mgr_state = TEMP_MGR_INTERRUPT_STATE();
|
||||
}
|
||||
}
|
||||
|
||||
~TempMgrGuard() throw() {
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
if(temp_mgr_state) ENABLE_TEMP_MGR_INTERRUPT();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void temp_mgr_init()
|
||||
{
|
||||
// initialize the ADC and start a conversion
|
||||
|
@ -2048,35 +2028,36 @@ void adc_callback()
|
|||
adc_values_ready = true;
|
||||
}
|
||||
|
||||
/* Syncronize temperatures:
|
||||
- fetch updated values from temp_mgr_isr to current values
|
||||
- update target temperatures for temp_mgr_isr regulation
|
||||
This function is blocking: check temp_meas_ready before calling! */
|
||||
static void updateTemperatures()
|
||||
static void setCurrentTemperaturesFromIsr()
|
||||
{
|
||||
uint8_t temp_mgr_state;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
temp_mgr_state = TEMP_MGR_INTERRUPT_STATE();
|
||||
DISABLE_TEMP_MGR_INTERRUPT();
|
||||
}
|
||||
|
||||
for(uint8_t e=0;e<EXTRUDERS;e++) {
|
||||
for(uint8_t e=0;e<EXTRUDERS;e++)
|
||||
current_temperature[e] = current_temperature_isr[e];
|
||||
target_temperature_isr[e] = target_temperature[e];
|
||||
}
|
||||
current_temperature_bed = current_temperature_bed_isr;
|
||||
target_temperature_bed_isr = target_temperature_bed;
|
||||
#ifdef PINDA_THERMISTOR
|
||||
current_temperature_pinda = current_temperature_pinda_isr;
|
||||
#endif
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
current_temperature_ambient = current_temperature_ambient_isr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
if(temp_mgr_state) ENABLE_TEMP_MGR_INTERRUPT();
|
||||
temp_meas_ready = false;
|
||||
}
|
||||
static void setIsrTargetTemperatures()
|
||||
{
|
||||
for(uint8_t e=0;e<EXTRUDERS;e++)
|
||||
target_temperature_isr[e] = target_temperature[e];
|
||||
target_temperature_bed_isr = target_temperature_bed;
|
||||
}
|
||||
|
||||
/* Synchronize temperatures:
|
||||
- fetch updated values from temp_mgr_isr to current values
|
||||
- update target temperatures for temp_mgr_isr regulation
|
||||
This function is blocking: check temp_meas_ready before calling! */
|
||||
static void updateTemperatures()
|
||||
{
|
||||
TempMgrGuard temp_mgr_guard;
|
||||
setCurrentTemperaturesFromIsr();
|
||||
setIsrTargetTemperatures();
|
||||
temp_meas_ready = false;
|
||||
}
|
||||
|
||||
/* Convert raw values into actual temperatures for temp_mgr. The raw values are created in the ADC
|
||||
|
@ -2096,6 +2077,13 @@ static void setIsrTemperaturesFromRawValues()
|
|||
temp_meas_ready = true;
|
||||
}
|
||||
|
||||
static void temp_mgr_pid()
|
||||
{
|
||||
for(uint8_t e = 0; e < EXTRUDERS; e++)
|
||||
pid_heater(e, current_temperature_isr[e], target_temperature_isr[e]);
|
||||
pid_bed(current_temperature_bed_isr, target_temperature_bed_isr);
|
||||
}
|
||||
|
||||
static void temp_mgr_isr()
|
||||
{
|
||||
// update *_isr temperatures from raw values for PID regulation
|
||||
|
@ -2107,9 +2095,7 @@ static void temp_mgr_isr()
|
|||
check_min_temp();
|
||||
|
||||
// PID regulation
|
||||
for(uint8_t e = 0; e < EXTRUDERS; e++)
|
||||
pid_heater(e, current_temperature_isr[e], target_temperature_isr[e]);
|
||||
pid_bed(current_temperature_bed_isr, target_temperature_bed_isr);
|
||||
temp_mgr_pid();
|
||||
}
|
||||
|
||||
ISR(TIMER5_COMPA_vect)
|
||||
|
@ -2126,3 +2112,34 @@ ISR(TIMER5_COMPA_vect)
|
|||
cli();
|
||||
ENABLE_TEMP_MGR_INTERRUPT();
|
||||
}
|
||||
|
||||
void disable_heater()
|
||||
{
|
||||
setAllTargetHotends(0);
|
||||
setTargetBed(0);
|
||||
|
||||
CRITICAL_SECTION_START;
|
||||
|
||||
// propagate all values down the chain
|
||||
setIsrTargetTemperatures();
|
||||
temp_mgr_pid();
|
||||
|
||||
// we can't call soft_pwm_core directly to toggle the pins as it would require removing the inline
|
||||
// attribute, so disable each pin individually
|
||||
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 && EXTRUDERS > 0
|
||||
WRITE(HEATER_0_PIN,LOW);
|
||||
#endif
|
||||
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 && EXTRUDERS > 1
|
||||
WRITE(HEATER_1_PIN,LOW);
|
||||
#endif
|
||||
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 && EXTRUDERS > 2
|
||||
WRITE(HEATER_2_PIN,LOW);
|
||||
#endif
|
||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||
// TODO: this doesn't take immediate effect!
|
||||
timer02_set_pwm0(0);
|
||||
bedPWMDisabled = 0;
|
||||
#endif
|
||||
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ FORCE_INLINE bool isCoolingBed() {
|
|||
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
|
||||
|
||||
int getHeaterPower(int heater);
|
||||
void disable_heater(); // Disable all heaters
|
||||
void disable_heater(); // Disable all heaters *instantaneously*
|
||||
void updatePID();
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue