🐛 Fix AVR 644/1284 Timer / PWM conflicts (#23629)
This commit is contained in:
parent
68dfc50564
commit
c02bc3887a
|
@ -35,22 +35,20 @@
|
||||||
|
|
||||||
void spiBegin() {
|
void spiBegin() {
|
||||||
#if PIN_EXISTS(SD_SS)
|
#if PIN_EXISTS(SD_SS)
|
||||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
// Do not init HIGH for boards with pin 4 used as Fans or Heaters or otherwise, not likely to have multiple SPI devices anyway.
|
||||||
|
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
|
||||||
|
// SS must be in output mode even it is not chip select
|
||||||
|
SET_OUTPUT(SD_SS_PIN);
|
||||||
|
#else
|
||||||
|
// set SS high - may be chip select for another SPI device
|
||||||
|
OUT_WRITE(SD_SS_PIN, HIGH);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
SET_OUTPUT(SD_SCK_PIN);
|
SET_OUTPUT(SD_SCK_PIN);
|
||||||
SET_INPUT(SD_MISO_PIN);
|
SET_INPUT(SD_MISO_PIN);
|
||||||
SET_OUTPUT(SD_MOSI_PIN);
|
SET_OUTPUT(SD_MOSI_PIN);
|
||||||
|
|
||||||
#if DISABLED(SOFTWARE_SPI)
|
IF_DISABLED(SOFTWARE_SPI, spiInit(SPI_HALF_SPEED));
|
||||||
// SS must be in output mode even it is not chip select
|
|
||||||
//SET_OUTPUT(SD_SS_PIN);
|
|
||||||
// set SS high - may be chip select for another SPI device
|
|
||||||
//#if SET_SPI_SS_HIGH
|
|
||||||
//WRITE(SD_SS_PIN, HIGH);
|
|
||||||
//#endif
|
|
||||||
// set a default rate
|
|
||||||
spiInit(1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI)
|
#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI)
|
||||||
|
|
|
@ -70,7 +70,7 @@ const Timer get_pwm_timer(const pin_t pin) {
|
||||||
|
|
||||||
#ifdef TCCR0A
|
#ifdef TCCR0A
|
||||||
case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only
|
case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only
|
||||||
return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0B, nullptr, nullptr }, nullptr, 0, 0, true, true });
|
return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0A, (uint16_t*)&OCR0B, nullptr }, nullptr, 0, 1, true, true });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_TCCR2
|
#if HAS_TCCR2
|
||||||
|
@ -187,8 +187,8 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
||||||
const Timer timer = get_pwm_timer(pin);
|
const Timer timer = get_pwm_timer(pin);
|
||||||
if (timer.isPWM) {
|
if (timer.isPWM) {
|
||||||
if (timer.n == 0) {
|
if (timer.n == 0) {
|
||||||
TCCR0A |= _BV(COM0B1); // Only allow a TIMER0B select and OCR0B duty update for pin D4 outputs no frequency changes are permited.
|
_SET_COMnQ(timer, timer.q, COM_CLEAR_SET); // Only allow a TIMER0B select...
|
||||||
OCR0B = v;
|
_SET_OCRnQ(timer, timer.q, v); // ...and OCR0B duty update. For output pin D4 no frequency changes are permitted.
|
||||||
}
|
}
|
||||||
else if (!timer.isProtected) {
|
else if (!timer.isProtected) {
|
||||||
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
|
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
|
||||||
|
@ -197,7 +197,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
digitalWrite(pin, v < 128 ? LOW : HIGH);
|
digitalWrite(pin, v < v_size / 2 ? LOW : HIGH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,9 @@ typedef uint16_t hal_timer_t;
|
||||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
||||||
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
|
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
|
||||||
|
|
||||||
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
|
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0A)
|
||||||
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
|
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0A)
|
||||||
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
|
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0A)
|
||||||
|
|
||||||
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
||||||
switch (timer_num) {
|
switch (timer_num) {
|
||||||
|
@ -87,7 +87,7 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
||||||
case MF_TIMER_TEMP:
|
case MF_TIMER_TEMP:
|
||||||
// Use timer0 for temperature measurement
|
// Use timer0 for temperature measurement
|
||||||
// Interleave temperature interrupt with millies interrupt
|
// Interleave temperature interrupt with millies interrupt
|
||||||
OCR0B = 128;
|
OCR0A = 128;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ void TIMER1_COMPA_vect() { \
|
||||||
: \
|
: \
|
||||||
: [timsk0] "i" ((uint16_t)&TIMSK0), \
|
: [timsk0] "i" ((uint16_t)&TIMSK0), \
|
||||||
[timsk1] "i" ((uint16_t)&TIMSK1), \
|
[timsk1] "i" ((uint16_t)&TIMSK1), \
|
||||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
|
[msk0] "M" ((uint8_t)(1<<OCIE0A)),\
|
||||||
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
|
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
|
||||||
: \
|
: \
|
||||||
); \
|
); \
|
||||||
|
@ -193,9 +193,9 @@ void TIMER1_COMPA_vect_bottom()
|
||||||
|
|
||||||
/* 14 cycles maximum latency */
|
/* 14 cycles maximum latency */
|
||||||
#define HAL_TEMP_TIMER_ISR() \
|
#define HAL_TEMP_TIMER_ISR() \
|
||||||
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
extern "C" void TIMER0_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||||
extern "C" void TIMER0_COMPB_vect_bottom() asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
extern "C" void TIMER0_COMPA_vect_bottom() asm ("TIMER0_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||||
void TIMER0_COMPB_vect() { \
|
void TIMER0_COMPA_vect() { \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
A("push r16") /* 2 Save R16 */ \
|
A("push r16") /* 2 Save R16 */ \
|
||||||
A("in r16, __SREG__") /* 1 Get SREG */ \
|
A("in r16, __SREG__") /* 1 Get SREG */ \
|
||||||
|
@ -223,7 +223,7 @@ void TIMER0_COMPB_vect() { \
|
||||||
A("push r30") \
|
A("push r30") \
|
||||||
A("push r31") \
|
A("push r31") \
|
||||||
A("clr r1") /* C runtime expects this register to be 0 */ \
|
A("clr r1") /* C runtime expects this register to be 0 */ \
|
||||||
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
A("call TIMER0_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
||||||
A("pop r31") \
|
A("pop r31") \
|
||||||
A("pop r30") \
|
A("pop r30") \
|
||||||
A("pop r27") \
|
A("pop r27") \
|
||||||
|
@ -251,10 +251,10 @@ void TIMER0_COMPB_vect() { \
|
||||||
A("reti") /* 4 Return from interrupt */ \
|
A("reti") /* 4 Return from interrupt */ \
|
||||||
: \
|
: \
|
||||||
: [timsk0] "i"((uint16_t)&TIMSK0), \
|
: [timsk0] "i"((uint16_t)&TIMSK0), \
|
||||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
|
[msk0] "M" ((uint8_t)(1<<OCIE0A)) \
|
||||||
: \
|
: \
|
||||||
); \
|
); \
|
||||||
} \
|
} \
|
||||||
void TIMER0_COMPB_vect_bottom()
|
void TIMER0_COMPA_vect_bottom()
|
||||||
|
|
||||||
#endif // HAL_TEMP_TIMER_ISR
|
#endif // HAL_TEMP_TIMER_ISR
|
||||||
|
|
Loading…
Reference in a new issue