Merge pull request #1488 from prusa3d/revert-1487-revert-1470-MK3-bed_fast_pwm

Revert "Revert "Mk3 bed fast pwm""
This commit is contained in:
PavelSindler 2019-01-28 14:20:54 +01:00 committed by GitHub
commit 517f8481cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 135 additions and 9 deletions

View File

@ -45,6 +45,12 @@
#include "Configuration_prusa.h" #include "Configuration_prusa.h"
extern "C" {
extern void timer02_init(void);
extern void timer02_set_pwm0(uint8_t pwm0);
}
//=========================================================================== //===========================================================================
//=============================public variables============================ //=============================public variables============================
//=========================================================================== //===========================================================================
@ -257,6 +263,7 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
if (extruder<0) if (extruder<0)
{ {
soft_pwm_bed = (MAX_BED_POWER)/2; soft_pwm_bed = (MAX_BED_POWER)/2;
timer02_set_pwm0(soft_pwm_bed << 1);
bias = d = (MAX_BED_POWER)/2; bias = d = (MAX_BED_POWER)/2;
} }
else else
@ -293,7 +300,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
if(millis() - t2 > 5000) { if(millis() - t2 > 5000) {
heating=false; heating=false;
if (extruder<0) if (extruder<0)
{
soft_pwm_bed = (bias - d) >> 1; soft_pwm_bed = (bias - d) >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else else
soft_pwm[extruder] = (bias - d) >> 1; soft_pwm[extruder] = (bias - d) >> 1;
t1=millis(); t1=millis();
@ -347,7 +357,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
} }
} }
if (extruder<0) if (extruder<0)
{
soft_pwm_bed = (bias + d) >> 1; soft_pwm_bed = (bias + d) >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
}
else else
soft_pwm[extruder] = (bias + d) >> 1; soft_pwm[extruder] = (bias + d) >> 1;
pid_cycle++; pid_cycle++;
@ -781,9 +794,11 @@ void manage_heater()
if(current_temperature_bed < BED_MAXTEMP) if(current_temperature_bed < BED_MAXTEMP)
{ {
soft_pwm_bed = (int)pid_output >> 1; soft_pwm_bed = (int)pid_output >> 1;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
else { else {
soft_pwm_bed = 0; soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
#elif !defined(BED_LIMIT_SWITCHING) #elif !defined(BED_LIMIT_SWITCHING)
@ -793,15 +808,18 @@ void manage_heater()
if(current_temperature_bed >= target_temperature_bed) if(current_temperature_bed >= target_temperature_bed)
{ {
soft_pwm_bed = 0; soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
else else
{ {
soft_pwm_bed = MAX_BED_POWER>>1; soft_pwm_bed = MAX_BED_POWER>>1;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
} }
else else
{ {
soft_pwm_bed = 0; soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
WRITE(HEATER_BED_PIN,LOW); WRITE(HEATER_BED_PIN,LOW);
} }
#else //#ifdef BED_LIMIT_SWITCHING #else //#ifdef BED_LIMIT_SWITCHING
@ -811,15 +829,18 @@ void manage_heater()
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS) if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
{ {
soft_pwm_bed = 0; soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS) else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
{ {
soft_pwm_bed = MAX_BED_POWER>>1; soft_pwm_bed = MAX_BED_POWER>>1;
timer02_set_pwm0(soft_pwm_bed << 1);
} }
} }
else else
{ {
soft_pwm_bed = 0; soft_pwm_bed = 0;
timer02_set_pwm0(soft_pwm_bed << 1);
WRITE(HEATER_BED_PIN,LOW); WRITE(HEATER_BED_PIN,LOW);
} }
#endif #endif
@ -996,7 +1017,6 @@ static void updateTemperaturesFromRawValues()
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
void tp_init() void tp_init()
{ {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
@ -1063,10 +1083,12 @@ void tp_init()
adc_init(); adc_init();
timer02_init();
// Use timer0 for temperature measurement // Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt // Interleave temperature interrupt with millies interrupt
OCR0B = 128; OCR2B = 128;
TIMSK0 |= (1<<OCIE0B); TIMSK2 |= (1<<OCIE2B);
// Wait for temperature measurement to settle // Wait for temperature measurement to settle
delay(250); delay(250);
@ -1374,6 +1396,7 @@ void disable_heater()
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
target_temperature_bed=0; target_temperature_bed=0;
soft_pwm_bed=0; soft_pwm_bed=0;
timer02_set_pwm0(soft_pwm_bed << 1);
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN,LOW); WRITE(HEATER_BED_PIN,LOW);
#endif #endif
@ -1538,8 +1561,8 @@ void adc_ready(void) //callback from adc when sampling finished
} // extern "C" } // extern "C"
// Timer 0 is shared with millies // Timer2 (originaly timer0) is shared with millies
ISR(TIMER0_COMPB_vect) // @ 1kHz ~ 1ms ISR(TIMER2_COMPB_vect)
{ {
static bool _lock = false; static bool _lock = false;
if (_lock) return; if (_lock) return;
@ -1606,7 +1629,7 @@ ISR(TIMER0_COMPB_vect) // @ 1kHz ~ 1ms
#endif #endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
soft_pwm_b = soft_pwm_bed; soft_pwm_b = soft_pwm_bed;
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0); //if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
#endif #endif
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
soft_pwm_fan = fanSpeedSoftPwm / 2; soft_pwm_fan = fanSpeedSoftPwm / 2;
@ -1740,7 +1763,7 @@ ISR(TIMER0_COMPB_vect) // @ 1kHz ~ 1ms
state_timer_heater_b = MIN_STATE_TIME; state_timer_heater_b = MIN_STATE_TIME;
} }
state_heater_b = 1; state_heater_b = 1;
WRITE(HEATER_BED_PIN, 1); //WRITE(HEATER_BED_PIN, 1);
} }
} else { } else {
// turn OFF heather only if the minimum time is up // turn OFF heather only if the minimum time is up

View File

@ -27,8 +27,8 @@
#include "stepper.h" #include "stepper.h"
#endif #endif
#define ENABLE_TEMPERATURE_INTERRUPT() TIMSK0 |= (1<<OCIE0B) #define ENABLE_TEMPERATURE_INTERRUPT() TIMSK2 |= (1<<OCIE2B)
#define DISABLE_TEMPERATURE_INTERRUPT() TIMSK0 &= ~(1<<OCIE0B) #define DISABLE_TEMPERATURE_INTERRUPT() TIMSK2 &= ~(1<<OCIE2B)
// public functions // public functions
void tp_init(); //initialize the heating void tp_init(); //initialize the heating

103
Firmware/timer02.c Normal file
View File

@ -0,0 +1,103 @@
//timer02.c
// use atmega timer2 as main system timer instead of timer0
// timer0 is used for fast pwm (OC0B output)
// original OVF handler is disabled
#include <avr/io.h>
#include <avr/interrupt.h>
#include <Arduino.h>
uint8_t timer02_pwm0 = 0;
void timer02_set_pwm0(uint8_t pwm0)
{
if (timer02_pwm0 == pwm0) return;
if (pwm0)
{
TCCR0A |= (2 << COM0B0);
OCR0B = pwm0 - 1;
}
else
{
TCCR0A &= ~(2 << COM0B0);
OCR0B = 0;
}
}
void timer02_init(void)
{
//save sreg
uint8_t _sreg = SREG;
//disable interrupts for sure
cli();
//mask timer0 interrupts - disable all
TIMSK0 &= ~(1<<TOIE0);
TIMSK0 &= ~(1<<OCIE0A);
TIMSK0 &= ~(1<<OCIE0B);
//setup timer0
TCCR0A = 0x00; //COM_A-B=00, WGM_0-1=00
TCCR0B = (1 << CS00); //WGM_2=0, CS_0-2=011
//switch timer0 to fast pwm mode
TCCR0A |= (3 << WGM00); //WGM_0-1=11
//set OCR0B register to zero
OCR0B = 0;
//disable OCR0B output (will be enabled in timer02_set_pwm0)
TCCR0A &= ~(2 << COM0B0);
//setup timer2
TCCR2A = 0x00; //COM_A-B=00, WGM_0-1=00
TCCR2B = (3 << CS20); //WGM_2=0, CS_0-2=011
//mask timer2 interrupts - enable OVF, disable others
TIMSK2 |= (1<<TOIE2);
TIMSK2 &= ~(1<<OCIE2A);
TIMSK2 &= ~(1<<OCIE2B);
//set timer2 OCR registers (OCRB interrupt generated 0.5ms after OVF interrupt)
OCR2A = 0;
OCR2B = 128;
//restore sreg (enable interrupts)
SREG = _sreg;
}
//following code is OVF handler for timer 2
//it is copy-paste from wiring.c and modified for timer2
//variables timer0_overflow_count and timer0_millis are declared in wiring.c
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)
extern volatile unsigned long timer0_overflow_count;
extern volatile unsigned long timer0_millis;
unsigned char timer0_fract = 0;
ISR(TIMER2_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX)
{
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}