diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 2217f239d6..451ed1ee9f 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -217,7 +217,7 @@ inline void HAL_adc_init() { * NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B) * NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings) */ -void set_pwm_frequency(const pin_t pin, int f_desired); +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 804e5fad30..9c6d6f5514 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -34,6 +34,24 @@ struct Timer { uint8_t q; // the timer output [0->2] (A->C) }; +// Macros for the Timer structure +#define _SET_WGMnQ(TCCRnQ, V) do{ \ + *(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \ + *(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \ + }while(0) + +// Set TCCR CS bits +#define _SET_CSn(TCCRnQ, V) (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)) + +// Set TCCR COM bits +#define _SET_COMnQ(TCCRnQ, Q, V) (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))) + +// Set OCRnQ register +#define _SET_OCRnQ(OCRnQ, Q, V) (*(OCRnQ)[Q] = int(V) & 0xFFFF) + +// Set ICRn register (one per timer) +#define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF) + /** * get_pwm_timer * Get the timer information and register of the provided pin. @@ -42,115 +60,119 @@ struct Timer { */ Timer get_pwm_timer(const pin_t pin) { uint8_t q = 0; + switch (digitalPinToTimer(pin)) { // Protect reserved timers (TIMER0 & TIMER1) #ifdef TCCR0A - #if !AVR_AT90USB1286_FAMILY - case TIMER0A: - #endif + IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:) case TIMER0B: #endif #ifdef TCCR1A case TIMER1A: case TIMER1B: #endif - break; - #if HAS_TCCR2 || defined(TCCR2A) - #if HAS_TCCR2 - case TIMER2: { + + break; + + #if HAS_TCCR2 + case TIMER2: { + Timer timer = { + { &TCCR2, nullptr, nullptr }, + { (uint16_t*)&OCR2, nullptr, nullptr }, + nullptr, + 2, 0 + }; + return timer; + } + #elif defined(TCCR2A) + #if ENABLED(USE_OCR2A_AS_TOP) + case TIMER2A: break; // protect TIMER2A + case TIMER2B: { Timer timer = { - /*TCCRnQ*/ { &TCCR2, nullptr, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 2, 0 + { &TCCR2A, &TCCR2B, nullptr }, + { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, + nullptr, + 2, 1 }; + return timer; + } + #else + case TIMER2B: ++q; + case TIMER2A: { + Timer timer = { + { &TCCR2A, &TCCR2B, nullptr }, + { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, + nullptr, + 2, q + }; + return timer; } - #elif defined(TCCR2A) - #if ENABLED(USE_OCR2A_AS_TOP) - case TIMER2A: break; // protect TIMER2A - case TIMER2B: { - Timer timer = { - /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 2, 1 - }; - return timer; - } - #else - case TIMER2B: ++q; - case TIMER2A: { - Timer timer = { - /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - /*ICRn*/ nullptr, - 2, q - }; - return timer; - } - #endif #endif #endif + #ifdef OCR3C - case TIMER3C: ++q; - case TIMER3B: ++q; + case TIMER3C: ++q; + case TIMER3B: ++q; case TIMER3A: { Timer timer = { - /*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C }, - /*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C }, - /*ICRn*/ &ICR3, - /*n, q*/ 3, q + { &TCCR3A, &TCCR3B, &TCCR3C }, + { &OCR3A, &OCR3B, &OCR3C }, + &ICR3, + 3, q }; return timer; } #elif defined(OCR3B) - case TIMER3B: ++q; + case TIMER3B: ++q; case TIMER3A: { Timer timer = { - /*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr }, - /*OCRnQ*/ { &OCR3A, &OCR3B, nullptr }, - /*ICRn*/ &ICR3, - /*n, q*/ 3, q + { &TCCR3A, &TCCR3B, nullptr }, + { &OCR3A, &OCR3B, nullptr }, + &ICR3, + 3, q }; return timer; } #endif + #ifdef TCCR4A - case TIMER4C: ++q; - case TIMER4B: ++q; + case TIMER4C: ++q; + case TIMER4B: ++q; case TIMER4A: { Timer timer = { - /*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C }, - /*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C }, - /*ICRn*/ &ICR4, - /*n, q*/ 4, q + { &TCCR4A, &TCCR4B, &TCCR4C }, + { &OCR4A, &OCR4B, &OCR4C }, + &ICR4, + 4, q }; return timer; } #endif + #ifdef TCCR5A - case TIMER5C: ++q; - case TIMER5B: ++q; + case TIMER5C: ++q; + case TIMER5B: ++q; case TIMER5A: { Timer timer = { - /*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C }, - /*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C }, - /*ICRn*/ &ICR5, - /*n, q*/ 5, q + { &TCCR5A, &TCCR5B, &TCCR5C }, + { &OCR5A, &OCR5B, &OCR5C }, + &ICR5, + 5, q }; return timer; } #endif } + Timer timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - 0, 0 + { nullptr, nullptr, nullptr }, + { nullptr, nullptr, nullptr }, + nullptr, + 0, 0 }; return timer; } -void set_pwm_frequency(const pin_t pin, int f_desired) { +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized uint16_t size; diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h index db6e598b86..51d3b311ee 100644 --- a/Marlin/src/HAL/AVR/fastio.h +++ b/Marlin/src/HAL/AVR/fastio.h @@ -118,7 +118,7 @@ */ // Waveform Generation Modes -enum WaveGenMode : char { +enum WaveGenMode : uint8_t { WGM_NORMAL, // 0 WGM_PWM_PC_8, // 1 WGM_PWM_PC_9, // 2 @@ -138,19 +138,19 @@ enum WaveGenMode : char { }; // Wavefore Generation Modes (Timer 2 only) -enum WaveGenMode2 : char { - WGM2_NORMAL, // 0 - WGM2_PWM_PC, // 1 - WGM2_CTC_OCR2A, // 2 - WGM2_FAST_PWM, // 3 - WGM2_reserved_1, // 4 - WGM2_PWM_PC_OCR2A, // 5 - WGM2_reserved_2, // 6 - WGM2_FAST_PWM_OCR2A, // 7 +enum WaveGenMode2 : uint8_t { + WGM2_NORMAL, // 0 + WGM2_PWM_PC, // 1 + WGM2_CTC_OCR2A, // 2 + WGM2_FAST_PWM, // 3 + WGM2_reserved_1, // 4 + WGM2_PWM_PC_OCR2A, // 5 + WGM2_reserved_2, // 6 + WGM2_FAST_PWM_OCR2A, // 7 }; // Compare Modes -enum CompareMode : char { +enum CompareMode : uint8_t { COM_NORMAL, // 0 COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down @@ -158,7 +158,7 @@ enum CompareMode : char { }; // Clock Sources -enum ClockSource : char { +enum ClockSource : uint8_t { CS_NONE, // 0 CS_PRESCALER_1, // 1 CS_PRESCALER_8, // 2 @@ -170,7 +170,7 @@ enum ClockSource : char { }; // Clock Sources (Timer 2 only) -enum ClockSource2 : char { +enum ClockSource2 : uint8_t { CS2_NONE, // 0 CS2_PRESCALER_1, // 1 CS2_PRESCALER_8, // 2 @@ -203,11 +203,6 @@ enum ClockSource2 : char { TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \ }while(0) #define SET_WGM(T,V) _SET_WGM(T,WGM_##V) -// Runtime (see set_pwm_frequency): -#define _SET_WGMnQ(TCCRnQ, V) do{ \ - *(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \ - *(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \ - }while(0) // Set Clock Select bits // Ex: SET_CS3(PRESCALER_64); @@ -235,8 +230,6 @@ enum ClockSource2 : char { #define SET_CS4(V) _SET_CS4(CS_##V) #define SET_CS5(V) _SET_CS5(CS_##V) #define SET_CS(T,V) SET_CS##T(V) -// Runtime (see set_pwm_frequency) -#define _SET_CSn(TCCRnQ, V) (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)) // Set Compare Mode bits // Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET); @@ -246,16 +239,6 @@ enum ClockSource2 : char { #define SET_COMB(T,V) SET_COM(T,B,V) #define SET_COMC(T,V) SET_COM(T,C,V) #define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0) -// Runtime (see set_pwm_duty) -#define _SET_COMnQ(TCCRnQ, Q, V) (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))) - -// Set OCRnQ register -// Runtime (see set_pwm_duty): -#define _SET_OCRnQ(OCRnQ, Q, V) (*(OCRnQ)[Q] = int(V) & 0xFFFF) - -// Set ICRn register (one per timer) -// Runtime (see set_pwm_frequency) -#define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF) // Set Noise Canceler bit // Ex: SET_ICNC(2,1) diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index 348ea6b21a..f5e4326983 100644 --- a/Marlin/src/HAL/LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -206,7 +206,7 @@ void flashFirmware(const int16_t); * All Hardware PWM pins run at the same frequency and all * Software PWM pins run at the same frequency */ -void set_pwm_frequency(const pin_t pin, int f_desired); +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/LPC1768/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp index eae0e36b0b..d760cd0fd0 100644 --- a/Marlin/src/HAL/LPC1768/fast_pwm.cpp +++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp @@ -32,7 +32,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 #if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM - void set_pwm_frequency(const pin_t pin, int f_desired) { + void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { LPC176x::pwm_set_frequency(pin, f_desired); } diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index adaf14223f..9429bb7e7c 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -231,7 +231,7 @@ extern volatile uint32_t systick_uptime_millis; * Set the frequency of the timer corresponding to the provided pin * All Timer PWM pins run at the same frequency */ -void set_pwm_frequency(const pin_t pin, int f_desired); +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/STM32/fast_pwm.cpp b/Marlin/src/HAL/STM32/fast_pwm.cpp index b1bea5ce20..f661e11350 100644 --- a/Marlin/src/HAL/STM32/fast_pwm.cpp +++ b/Marlin/src/HAL/STM32/fast_pwm.cpp @@ -56,7 +56,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) HT->resume(); } -void set_pwm_frequency(const pin_t pin, int f_desired) { +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer const PinName pin_name = digitalPinToPinName(pin); TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index 153cfe8ac8..a766babe15 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -274,7 +274,7 @@ void flashFirmware(const int16_t); * Set the frequency of the timer corresponding to the provided pin * All Timer PWM pins run at the same frequency */ -void set_pwm_frequency(const pin_t pin, int f_desired); +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/STM32F1/fast_pwm.cpp b/Marlin/src/HAL/STM32F1/fast_pwm.cpp index 98d56bc5e9..c783dda606 100644 --- a/Marlin/src/HAL/STM32F1/fast_pwm.cpp +++ b/Marlin/src/HAL/STM32F1/fast_pwm.cpp @@ -51,7 +51,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 timer_set_mode(timer, channel, TIMER_PWM); // PWM Output Mode } -void set_pwm_frequency(const pin_t pin, int f_desired) { +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer timer_dev *timer; UNUSED(timer);