From 15b243ceb623db77c0d6c7b0b712fc23f3aa9051 Mon Sep 17 00:00:00 2001 From: descipher Date: Thu, 6 Jan 2022 09:14:57 -0600 Subject: [PATCH 01/30] Fix AVR set_pwm_duty unset default frequency --- Marlin/src/HAL/AVR/HAL.h | 1 + Marlin/src/HAL/AVR/fast_pwm.cpp | 6 ++++++ Marlin/src/module/stepper.cpp | 17 ++++++++++++----- Marlin/src/module/stepper.h | 4 ++++ Marlin/src/pins/mega/pins_HJC2560C_REV2.h | 4 ++-- Marlin/src/pins/mega/pins_INTAMSYS40.h | 4 ++-- Marlin/src/pins/rambo/pins_MINIRAMBO.h | 4 ++-- Marlin/src/pins/ramps/pins_ULTIMAIN_2.h | 3 ++- 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 2217f239d64e..a8b778115911 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -207,6 +207,7 @@ inline void HAL_adc_init() { #define strtof strtod #define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment +#define PWM_FREQUENCY 1000 // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency() /** * set_pwm_frequency diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 804e5fad3070..8c61379cc6d4 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -25,6 +25,7 @@ #include "HAL.h" #if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM +static uint16_t timer_freq[5]; struct Timer { volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer @@ -153,6 +154,7 @@ Timer get_pwm_timer(const pin_t pin) { void set_pwm_frequency(const pin_t pin, int f_desired) { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized + timer_freq[timer.n] = f_desired; uint16_t size; if (timer.n == 2) size = 255; else size = 65535; @@ -243,6 +245,10 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted) + if (timer_freq[timer.n] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY + set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. + timer_freq[timer.n] = PWM_FREQUENCY; + } _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index b61f36bbb45d..e8a2c0c61f45 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3262,31 +3262,43 @@ void Stepper::report_positions() { #elif HAS_MOTOR_CURRENT_PWM #define _WRITE_CURRENT_PWM(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) + #ifdef defined(__AVR__) || defined(__AVR_ATmega2560__) + #define _WRITE_FREQUENCY_PWM(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) + #else + #define _WRITE_FREQUENCY_PWM(P) NOOP + #endif switch (driver) { case 0: #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) + _WRITE_FREQUENCY_PWM(X); _WRITE_CURRENT_PWM(X); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) + _WRITE_FREQUENCY_PWM(Y); _WRITE_CURRENT_PWM(Y); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + _WRITE_FREQUENCY_PWM(XY); _WRITE_CURRENT_PWM(XY); #endif break; case 1: #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + _WRITE_FREQUENCY_PWM(Z); _WRITE_CURRENT_PWM(Z); #endif break; case 2: #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + _WRITE_FREQUENCY_PWM(E); _WRITE_CURRENT_PWM(E); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0) + _WRITE_FREQUENCY_PWM(E0); _WRITE_CURRENT_PWM(E0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1) + _WRITE_FREQUENCY_PWM(E1); _WRITE_CURRENT_PWM(E1); #endif break; @@ -3329,11 +3341,6 @@ void Stepper::report_positions() { #endif refresh_motor_power(); - - // Set Timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise) - #ifdef __AVR__ - SET_CS5(PRESCALER_1); - #endif #endif } diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 6b190889cd31..072983d2da8e 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -317,6 +317,10 @@ class Stepper { #ifndef PWM_MOTOR_CURRENT #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT #endif + #ifndef MOTOR_CURRENT_PWM_FREQUENCY + #define MOTOR_CURRENT_PWM_FREQUENCY 1000 + #endif + #define MOTOR_CURRENT_COUNT LINEAR_AXES #elif HAS_MOTOR_CURRENT_SPI static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; diff --git a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h index 73d4bac47273..e4539d4ab1d5 100644 --- a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h +++ b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h @@ -73,10 +73,10 @@ #define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } - +#define MOTOR_CURRENT_PWM_FREQUENCY 31400 // // Temperature Sensors // diff --git a/Marlin/src/pins/mega/pins_INTAMSYS40.h b/Marlin/src/pins/mega/pins_INTAMSYS40.h index 2e2a9b85db14..123e2922b858 100644 --- a/Marlin/src/pins/mega/pins_INTAMSYS40.h +++ b/Marlin/src/pins/mega/pins_INTAMSYS40.h @@ -80,10 +80,10 @@ // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } - +#define MOTOR_CURRENT_PWM_FREQUENCY 31400 // // Temperature Sensors // diff --git a/Marlin/src/pins/rambo/pins_MINIRAMBO.h b/Marlin/src/pins/rambo/pins_MINIRAMBO.h index ab25e2e692af..a44112d18831 100644 --- a/Marlin/src/pins/rambo/pins_MINIRAMBO.h +++ b/Marlin/src/pins/rambo/pins_MINIRAMBO.h @@ -84,10 +84,10 @@ #define MOTOR_CURRENT_PWM_E_PIN 44 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} - +#define MOTOR_CURRENT_PWM_FREQUENCY 31400 // // Temperature Sensors // diff --git a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h index 9823d4cf4b75..2b1585f1b132 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h @@ -75,9 +75,10 @@ #define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} +#define MOTOR_CURRENT_PWM_FREQUENCY 31400 // // Temperature Sensors From e363120cb2e8d2e60474b1764228b3b50c5c1dae Mon Sep 17 00:00:00 2001 From: descipher Date: Thu, 6 Jan 2022 16:34:05 -0600 Subject: [PATCH 02/30] Set MOTOR_CURRENT_PWM_FREQUENCY default as 31400 --- Marlin/src/HAL/AVR/fast_pwm.cpp | 3 --- Marlin/src/inc/Conditionals_adv.h | 3 ++- Marlin/src/module/stepper.cpp | 6 +++--- Marlin/src/module/stepper.h | 2 +- Marlin/src/pins/mega/pins_HJC2560C_REV2.h | 2 +- Marlin/src/pins/mega/pins_INTAMSYS40.h | 2 +- Marlin/src/pins/rambo/pins_MINIRAMBO.h | 2 +- Marlin/src/pins/ramps/pins_ULTIMAIN_2.h | 1 - 8 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 8c61379cc6d4..d56633dabb96 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -24,7 +24,6 @@ #include "../../inc/MarlinConfigPre.h" #include "HAL.h" -#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM static uint16_t timer_freq[5]; struct Timer { @@ -230,8 +229,6 @@ void set_pwm_frequency(const pin_t pin, int f_desired) { _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res } -#endif // NEEDS_HARDWARE_PWM - void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { #if NEEDS_HARDWARE_PWM diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 8c6e79f36ab1..bff35f9102d3 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -678,10 +678,11 @@ #endif // Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM) +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE) #define NEEDS_HARDWARE_PWM 1 #endif + #if !defined(__AVR__) || !defined(USBCON) // Define constants and variables for buffering serial data. // Use only 0 or powers of 2 greater than 1 diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index e8a2c0c61f45..2a6d1f4e0cb8 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3262,10 +3262,10 @@ void Stepper::report_positions() { #elif HAS_MOTOR_CURRENT_PWM #define _WRITE_CURRENT_PWM(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) - #ifdef defined(__AVR__) || defined(__AVR_ATmega2560__) + #ifdef __SAM3X8E__ + #define _WRITE_FREQUENCY_PWM(P) NOOP + #else #define _WRITE_FREQUENCY_PWM(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) - #else - #define _WRITE_FREQUENCY_PWM(P) NOOP #endif switch (driver) { case 0: diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 072983d2da8e..67f568a60424 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -318,7 +318,7 @@ class Stepper { #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT #endif #ifndef MOTOR_CURRENT_PWM_FREQUENCY - #define MOTOR_CURRENT_PWM_FREQUENCY 1000 + #define MOTOR_CURRENT_PWM_FREQUENCY 31400 #endif #define MOTOR_CURRENT_COUNT LINEAR_AXES diff --git a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h index e4539d4ab1d5..84e3af9bb25b 100644 --- a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h +++ b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h @@ -76,7 +76,7 @@ #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } -#define MOTOR_CURRENT_PWM_FREQUENCY 31400 + // // Temperature Sensors // diff --git a/Marlin/src/pins/mega/pins_INTAMSYS40.h b/Marlin/src/pins/mega/pins_INTAMSYS40.h index 123e2922b858..10afb73c14f4 100644 --- a/Marlin/src/pins/mega/pins_INTAMSYS40.h +++ b/Marlin/src/pins/mega/pins_INTAMSYS40.h @@ -83,7 +83,7 @@ #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } -#define MOTOR_CURRENT_PWM_FREQUENCY 31400 + // // Temperature Sensors // diff --git a/Marlin/src/pins/rambo/pins_MINIRAMBO.h b/Marlin/src/pins/rambo/pins_MINIRAMBO.h index a44112d18831..084c54ae5f2b 100644 --- a/Marlin/src/pins/rambo/pins_MINIRAMBO.h +++ b/Marlin/src/pins/rambo/pins_MINIRAMBO.h @@ -87,7 +87,7 @@ #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} -#define MOTOR_CURRENT_PWM_FREQUENCY 31400 + // // Temperature Sensors // diff --git a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h index 2b1585f1b132..3c502e443b1d 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h @@ -78,7 +78,6 @@ #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} -#define MOTOR_CURRENT_PWM_FREQUENCY 31400 // // Temperature Sensors From df4f122a1ecfc816541a7ba1c813ac1b0b1e504b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 00:13:20 -0600 Subject: [PATCH 03/30] defer to pinsformat.js --- Marlin/src/inc/Conditionals_adv.h | 1 - Marlin/src/pins/mega/pins_HJC2560C_REV2.h | 2 +- Marlin/src/pins/mega/pins_INTAMSYS40.h | 2 +- Marlin/src/pins/rambo/pins_MINIRAMBO.h | 2 +- Marlin/src/pins/ramps/pins_ULTIMAIN_2.h | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index bff35f9102d3..b44646b80dba 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -682,7 +682,6 @@ #define NEEDS_HARDWARE_PWM 1 #endif - #if !defined(__AVR__) || !defined(USBCON) // Define constants and variables for buffering serial data. // Use only 0 or powers of 2 greater than 1 diff --git a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h index 84e3af9bb25b..73d4bac47273 100644 --- a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h +++ b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h @@ -73,7 +73,7 @@ #define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } diff --git a/Marlin/src/pins/mega/pins_INTAMSYS40.h b/Marlin/src/pins/mega/pins_INTAMSYS40.h index 10afb73c14f4..2e2a9b85db14 100644 --- a/Marlin/src/pins/mega/pins_INTAMSYS40.h +++ b/Marlin/src/pins/mega/pins_INTAMSYS40.h @@ -80,7 +80,7 @@ // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT { 1300, 1300, 1250 } diff --git a/Marlin/src/pins/rambo/pins_MINIRAMBO.h b/Marlin/src/pins/rambo/pins_MINIRAMBO.h index 084c54ae5f2b..ab25e2e692af 100644 --- a/Marlin/src/pins/rambo/pins_MINIRAMBO.h +++ b/Marlin/src/pins/rambo/pins_MINIRAMBO.h @@ -84,7 +84,7 @@ #define MOTOR_CURRENT_PWM_E_PIN 44 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} diff --git a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h index 3c502e443b1d..9823d4cf4b75 100644 --- a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h +++ b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h @@ -75,7 +75,7 @@ #define MOTOR_CURRENT_PWM_E_PIN 46 // Motor current PWM conversion, PWM value = MotorCurrentSetting * 255 / range #ifndef MOTOR_CURRENT_PWM_RANGE - #define MOTOR_CURRENT_PWM_RANGE 2000 + #define MOTOR_CURRENT_PWM_RANGE 2000 #endif #define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} From 359415d3653f913462abfcc075ac5a964bf3c0e1 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 00:19:20 -0600 Subject: [PATCH 04/30] delete red highlighted trailing spaces --- Marlin/src/HAL/AVR/fast_pwm.cpp | 2 +- Marlin/src/inc/Conditionals_adv.h | 2 +- Marlin/src/module/stepper.cpp | 10 +++++----- Marlin/src/module/stepper.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index d56633dabb96..ce56d170454d 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -243,7 +243,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 if (timer.n == 0) return; // Don't proceed if protected timer or not recognized // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted) if (timer_freq[timer.n] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY - set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. + set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. timer_freq[timer.n] = PWM_FREQUENCY; } _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index b44646b80dba..08154120e9d0 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -678,7 +678,7 @@ #endif // Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE) +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE) #define NEEDS_HARDWARE_PWM 1 #endif diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index cffcda3b824b..85aea212c11f 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3259,10 +3259,10 @@ void Stepper::report_positions() { #define _WRITE_CURRENT_PWM(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) #ifdef __SAM3X8E__ - #define _WRITE_FREQUENCY_PWM(P) NOOP - #else + #define _WRITE_FREQUENCY_PWM(P) NOOP + #else #define _WRITE_FREQUENCY_PWM(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) - #endif + #endif switch (driver) { case 0: #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) @@ -3290,11 +3290,11 @@ void Stepper::report_positions() { _WRITE_CURRENT_PWM(E); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0) - _WRITE_FREQUENCY_PWM(E0); + _WRITE_FREQUENCY_PWM(E0); _WRITE_CURRENT_PWM(E0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1) - _WRITE_FREQUENCY_PWM(E1); + _WRITE_FREQUENCY_PWM(E1); _WRITE_CURRENT_PWM(E1); #endif break; diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 67f568a60424..7967e58c355a 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -320,7 +320,7 @@ class Stepper { #ifndef MOTOR_CURRENT_PWM_FREQUENCY #define MOTOR_CURRENT_PWM_FREQUENCY 31400 #endif - + #define MOTOR_CURRENT_COUNT LINEAR_AXES #elif HAS_MOTOR_CURRENT_SPI static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; From fe1f75dff3e908ab3eb70c2ef1ab5a10626cb5f0 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 00:30:06 -0600 Subject: [PATCH 05/30] clarify --- Marlin/src/module/stepper.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 85aea212c11f..61b27a3cf38e 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3257,45 +3257,45 @@ void Stepper::report_positions() { #elif HAS_MOTOR_CURRENT_PWM - #define _WRITE_CURRENT_PWM(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) + #define _WRITE_CURRENT_PWM_DUTY(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) #ifdef __SAM3X8E__ - #define _WRITE_FREQUENCY_PWM(P) NOOP + #define _RESET_CURRENT_PWM_FREQ(P) NOOP #else - #define _WRITE_FREQUENCY_PWM(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) + #define _RESET_CURRENT_PWM_FREQ(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) #endif switch (driver) { case 0: #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) - _WRITE_FREQUENCY_PWM(X); - _WRITE_CURRENT_PWM(X); + _RESET_CURRENT_PWM_FREQ(X); + _WRITE_CURRENT_PWM_DUTY(X); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) - _WRITE_FREQUENCY_PWM(Y); - _WRITE_CURRENT_PWM(Y); + _RESET_CURRENT_PWM_FREQ(Y); + _WRITE_CURRENT_PWM_DUTY(Y); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) - _WRITE_FREQUENCY_PWM(XY); - _WRITE_CURRENT_PWM(XY); + _RESET_CURRENT_PWM_FREQ(XY); + _WRITE_CURRENT_PWM_DUTY(XY); #endif break; case 1: #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - _WRITE_FREQUENCY_PWM(Z); - _WRITE_CURRENT_PWM(Z); + _RESET_CURRENT_PWM_FREQ(Z); + _WRITE_CURRENT_PWM_DUTY(Z); #endif break; case 2: #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - _WRITE_FREQUENCY_PWM(E); - _WRITE_CURRENT_PWM(E); + _RESET_CURRENT_PWM_FREQ(E); + _WRITE_CURRENT_PWM_DUTY(E); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0) - _WRITE_FREQUENCY_PWM(E0); - _WRITE_CURRENT_PWM(E0); + _RESET_CURRENT_PWM_FREQ(E0); + _WRITE_CURRENT_PWM_DUTY(E0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1) - _WRITE_FREQUENCY_PWM(E1); - _WRITE_CURRENT_PWM(E1); + _RESET_CURRENT_PWM_FREQ(E1); + _WRITE_CURRENT_PWM_DUTY(E1); #endif break; } From eaef837fa656daef70334e764cb90341917d2161 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 00:36:09 -0600 Subject: [PATCH 06/30] trust pins to retain freq after init ? --- Marlin/src/module/stepper.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 61b27a3cf38e..0221f4c8be50 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3258,43 +3258,31 @@ void Stepper::report_positions() { #elif HAS_MOTOR_CURRENT_PWM #define _WRITE_CURRENT_PWM_DUTY(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) - #ifdef __SAM3X8E__ - #define _RESET_CURRENT_PWM_FREQ(P) NOOP - #else - #define _RESET_CURRENT_PWM_FREQ(P) set_pwm_frequency(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), MOTOR_CURRENT_PWM_FREQUENCY) - #endif switch (driver) { case 0: #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) - _RESET_CURRENT_PWM_FREQ(X); _WRITE_CURRENT_PWM_DUTY(X); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) - _RESET_CURRENT_PWM_FREQ(Y); _WRITE_CURRENT_PWM_DUTY(Y); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) - _RESET_CURRENT_PWM_FREQ(XY); _WRITE_CURRENT_PWM_DUTY(XY); #endif break; case 1: #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - _RESET_CURRENT_PWM_FREQ(Z); _WRITE_CURRENT_PWM_DUTY(Z); #endif break; case 2: #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - _RESET_CURRENT_PWM_FREQ(E); _WRITE_CURRENT_PWM_DUTY(E); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0) - _RESET_CURRENT_PWM_FREQ(E0); _WRITE_CURRENT_PWM_DUTY(E0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1) - _RESET_CURRENT_PWM_FREQ(E1); _WRITE_CURRENT_PWM_DUTY(E1); #endif break; @@ -3314,29 +3302,37 @@ void Stepper::report_positions() { #elif HAS_MOTOR_CURRENT_PWM + #ifdef __SAM3X8E__ + #define _RESET_CURRENT_PWM_FREQ(P) NOOP + #else + #define _RESET_CURRENT_PWM_FREQ(P) set_pwm_frequency(pin_t(P), MOTOR_CURRENT_PWM_FREQUENCY) + #endif + #define INIT_CURRENT_PWM(P) do{ SET_PWM(MOTOR_CURRENT_PWM_## P ##_PIN); _RESET_CURRENT_PWM_FREQ(MOTOR_CURRENT_PWM_## P ##_PIN); }while(0) + #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) - SET_PWM(MOTOR_CURRENT_PWM_X_PIN); + INIT_CURRENT_PWM(X); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) - SET_PWM(MOTOR_CURRENT_PWM_Y_PIN); + INIT_CURRENT_PWM(Y); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) - SET_PWM(MOTOR_CURRENT_PWM_XY_PIN); + INIT_CURRENT_PWM(XY); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - SET_PWM(MOTOR_CURRENT_PWM_Z_PIN); + INIT_CURRENT_PWM(Z); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - SET_PWM(MOTOR_CURRENT_PWM_E_PIN); + INIT_CURRENT_PWM(E); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0) - SET_PWM(MOTOR_CURRENT_PWM_E0_PIN); + INIT_CURRENT_PWM(E0); #endif #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1) - SET_PWM(MOTOR_CURRENT_PWM_E1_PIN); + INIT_CURRENT_PWM(E1); #endif refresh_motor_power(); + #endif } From 8cd296fabbaa727f7feb5839a7e9254d87dc128c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 00:47:12 -0600 Subject: [PATCH 07/30] track init as a debug option --- Marlin/src/HAL/AVR/fast_pwm.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index ce56d170454d..cb97449bd1a9 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -24,7 +24,12 @@ #include "../../inc/MarlinConfigPre.h" #include "HAL.h" -static uint16_t timer_freq[5]; +//#define DEBUG_PWM_INIT + +#if ENABLED(DEBUG_PWM_INIT) + #include "../../core/serial.h" + static uint16_t timer_freq[5]; +#endif struct Timer { volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer @@ -153,9 +158,10 @@ Timer get_pwm_timer(const pin_t pin) { void set_pwm_frequency(const pin_t pin, int f_desired) { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - timer_freq[timer.n] = f_desired; - uint16_t size; - if (timer.n == 2) size = 255; else size = 65535; + + TERN_(DEBUG_PWM_INIT, timer_freq[timer.n - 1] = f_desired); + + const uint16_t size = (timer.n == 2) ? 255 : 65535; uint16_t res = 255; // resolution (TOP value) uint8_t j = 0; // prescaler index @@ -242,10 +248,12 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted) - if (timer_freq[timer.n] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY - set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. - timer_freq[timer.n] = PWM_FREQUENCY; - } + #if ENABLED(DEBUG_PWM_INIT) + if (timer_freq[timer.n - 1] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY + set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. + SERIAL_ECHOLNPGM("PWM Timer ", timer.n, " Frequency Not Initialized!"); + } + #endif _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value From ffd97500e671e2cbddde8a29080ded866664de3f Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 01:06:34 -0600 Subject: [PATCH 08/30] arg tweak, keep wrapper ? --- Marlin/src/HAL/AVR/HAL.h | 2 +- Marlin/src/HAL/AVR/fast_pwm.cpp | 6 +++++- Marlin/src/HAL/LPC1768/HAL.h | 2 +- Marlin/src/HAL/LPC1768/fast_pwm.cpp | 2 +- Marlin/src/HAL/STM32/HAL.h | 2 +- Marlin/src/HAL/STM32/fast_pwm.cpp | 2 +- Marlin/src/HAL/STM32F1/HAL.h | 2 +- Marlin/src/HAL/STM32F1/fast_pwm.cpp | 2 +- Marlin/src/inc/Conditionals_adv.h | 5 ----- Marlin/src/inc/Conditionals_post.h | 5 +++++ 10 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index a8b778115911..6ca5daa85906 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -218,7 +218,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 int f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index cb97449bd1a9..3d325dbf60e8 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -24,6 +24,8 @@ #include "../../inc/MarlinConfigPre.h" #include "HAL.h" +#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM + //#define DEBUG_PWM_INIT #if ENABLED(DEBUG_PWM_INIT) @@ -155,7 +157,7 @@ Timer get_pwm_timer(const pin_t pin) { return timer; } -void set_pwm_frequency(const pin_t pin, int f_desired) { +void set_pwm_frequency(const pin_t pin, const int f_desired) { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized @@ -235,6 +237,8 @@ void set_pwm_frequency(const pin_t pin, int f_desired) { _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res } +#endif // NEEDS_HARDWARE_PWM + void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { #if NEEDS_HARDWARE_PWM diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index 348ea6b21a04..2cd7c659f3db 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 int f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/LPC1768/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp index eae0e36b0b0e..cdf3c0be9559 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 int 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 adaf14223f32..df125f7790d4 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 int f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/STM32/fast_pwm.cpp b/Marlin/src/HAL/STM32/fast_pwm.cpp index b1bea5ce20eb..e0b7c57bcbb4 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 int 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 153cfe8ac89e..af518b0718b3 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 int f_desired); /** * set_pwm_duty diff --git a/Marlin/src/HAL/STM32F1/fast_pwm.cpp b/Marlin/src/HAL/STM32F1/fast_pwm.cpp index 98d56bc5e931..7a3f47b2e490 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 int f_desired) { if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer timer_dev *timer; UNUSED(timer); diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 08154120e9d0..f2a316d8330e 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -677,11 +677,6 @@ #define CUTTER_UNIT_IS(V) (_CUTTER_POWER(CUTTER_POWER_UNIT) == _CUTTER_POWER(V)) #endif -// Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE) - #define NEEDS_HARDWARE_PWM 1 -#endif - #if !defined(__AVR__) || !defined(USBCON) // Define constants and variables for buffering serial data. // Use only 0 or powers of 2 greater than 1 diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 08130d31b7a1..1f4506ec954d 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2860,6 +2860,11 @@ #define HAS_MOTOR_CURRENT_PWM 1 #endif +// Add features that need hardware PWM here +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE, HAS_MOTOR_CURRENT_PWM) + #define NEEDS_HARDWARE_PWM 1 +#endif + #if ANY(HAS_Z_MS_PINS, HAS_Z2_MS_PINS, HAS_Z3_MS_PINS, HAS_Z4_MS_PINS) #define HAS_SOME_Z_MS_PINS 1 #endif From dbd37f21c37ec325f894add1679c7fd5380813d2 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 7 Jan 2022 07:12:15 -0600 Subject: [PATCH 09/30] set_pwm_frequency with all HAL_CAN_SET_PWM_FREQ --- Marlin/src/HAL/AVR/fast_pwm.cpp | 4 ---- Marlin/src/HAL/AVR/inc/SanityCheck.h | 2 +- Marlin/src/HAL/LPC1768/fast_pwm.cpp | 10 +++------- Marlin/src/feature/spindle_laser.cpp | 8 +++----- Marlin/src/inc/Conditionals_post.h | 2 +- Marlin/src/lcd/menu/menu_spindle_laser.cpp | 2 +- 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 3d325dbf60e8..8b9489a036d0 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -24,8 +24,6 @@ #include "../../inc/MarlinConfigPre.h" #include "HAL.h" -#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM - //#define DEBUG_PWM_INIT #if ENABLED(DEBUG_PWM_INIT) @@ -237,8 +235,6 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res } -#endif // NEEDS_HARDWARE_PWM - void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { #if NEEDS_HARDWARE_PWM diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h index 2f80d1fee165..331d0b04648b 100644 --- a/Marlin/src/HAL/AVR/inc/SanityCheck.h +++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h @@ -42,7 +42,7 @@ #elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5) #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system." #endif -#elif defined(SPINDLE_LASER_FREQUENCY) +#elif SPINDLE_LASER_FREQUENCY #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM." #endif diff --git a/Marlin/src/HAL/LPC1768/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp index cdf3c0be9559..c92cb0e71ed5 100644 --- a/Marlin/src/HAL/LPC1768/fast_pwm.cpp +++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp @@ -30,12 +30,8 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range } -#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM - - void set_pwm_frequency(const pin_t pin, const int f_desired) { - LPC176x::pwm_set_frequency(pin, f_desired); - } - -#endif +void set_pwm_frequency(const pin_t pin, const int f_desired) { + LPC176x::pwm_set_frequency(pin, f_desired); +} #endif // TARGET_LPC1768 diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp index cde2b47d90aa..9ca7cb948e69 100644 --- a/Marlin/src/feature/spindle_laser.cpp +++ b/Marlin/src/feature/spindle_laser.cpp @@ -68,7 +68,7 @@ void SpindleLaser::init() { SET_PWM(SPINDLE_LASER_PWM_PIN); set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed #endif - #if ENABLED(HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY) + #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY); TERN_(MARLIN_DEV_MODE, frequency = SPINDLE_LASER_FREQUENCY); #endif @@ -78,9 +78,7 @@ void SpindleLaser::init() { #if ENABLED(AIR_ASSIST) OUT_WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); // Init Air Assist OFF #endif - #if ENABLED(I2C_AMMETER) - ammeter.init(); // Init I2C Ammeter - #endif + TERN_(I2C_AMMETER, ammeter.init()); // Init I2C Ammeter } #if ENABLED(SPINDLE_LASER_USE_PWM) @@ -90,7 +88,7 @@ void SpindleLaser::init() { * @param ocr Power value */ void SpindleLaser::_set_ocr(const uint8_t ocr) { - #if NEEDS_HARDWARE_PWM && SPINDLE_LASER_FREQUENCY + #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), TERN(MARLIN_DEV_MODE, frequency, SPINDLE_LASER_FREQUENCY)); #endif set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF); diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 1f4506ec954d..4de066263a7d 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2861,7 +2861,7 @@ #endif // Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, MOTOR_CURRENT_PWM_FEATURE, HAS_MOTOR_CURRENT_PWM) +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM) #define NEEDS_HARDWARE_PWM 1 #endif diff --git a/Marlin/src/lcd/menu/menu_spindle_laser.cpp b/Marlin/src/lcd/menu/menu_spindle_laser.cpp index 26f555ad620d..ca3d6f66a6d4 100644 --- a/Marlin/src/lcd/menu/menu_spindle_laser.cpp +++ b/Marlin/src/lcd/menu/menu_spindle_laser.cpp @@ -74,7 +74,7 @@ ACTION_ITEM(MSG_LASER_FIRE_PULSE, cutter.test_fire_pulse); #endif - #if BOTH(MARLIN_DEV_MODE, HAL_CAN_SET_PWM_FREQ) && defined(SPINDLE_LASER_FREQUENCY) + #if BOTH(MARLIN_DEV_MODE, HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY EDIT_ITEM_FAST(CUTTER_MENU_FREQUENCY_TYPE, MSG_CUTTER_FREQUENCY, &cutter.frequency, 2000, 80000, cutter.refresh_frequency); #endif From 8e10265d5a013853ed8f65beda98c65df54c76af Mon Sep 17 00:00:00 2001 From: descipher Date: Fri, 7 Jan 2022 09:16:27 -0600 Subject: [PATCH 10/30] Add HAS_LCD_BRIGHTNESS Needs PWM condition check --- Marlin/src/inc/Conditionals_post.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 4de066263a7d..a7159fe62086 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2861,7 +2861,7 @@ #endif // Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM) +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM, HAS_LCD_BRIGHTNESS) #define NEEDS_HARDWARE_PWM 1 #endif From 19531245305916f85084843f1d3a1696c17f5e78 Mon Sep 17 00:00:00 2001 From: descipher Date: Fri, 7 Jan 2022 15:37:37 -0600 Subject: [PATCH 11/30] Corrected include and frequency init tracking --- Marlin/src/HAL/AVR/fast_pwm.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 8b9489a036d0..3a891c00a9bb 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -21,15 +21,10 @@ */ #ifdef __AVR__ -#include "../../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfig.h" #include "HAL.h" -//#define DEBUG_PWM_INIT - -#if ENABLED(DEBUG_PWM_INIT) - #include "../../core/serial.h" - static uint16_t timer_freq[5]; -#endif +static uint16_t timer_freq[5]; struct Timer { volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer @@ -159,7 +154,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - TERN_(DEBUG_PWM_INIT, timer_freq[timer.n - 1] = f_desired); + timer_freq[timer.n - 1] = f_desired; const uint16_t size = (timer.n == 2) ? 255 : 65535; @@ -247,13 +242,11 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 else { Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted) - #if ENABLED(DEBUG_PWM_INIT) - if (timer_freq[timer.n - 1] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY - set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. - SERIAL_ECHOLNPGM("PWM Timer ", timer.n, " Frequency Not Initialized!"); - } - #endif + + if (timer_freq[timer.n - 1] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY + set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. + } + _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value From ea74cdcd800f8c985d507531df8fde88be4d069a Mon Sep 17 00:00:00 2001 From: descipher Date: Sat, 8 Jan 2022 10:07:02 -0600 Subject: [PATCH 12/30] Cleanup condition check state --- Marlin/src/HAL/AVR/fast_pwm.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 3a891c00a9bb..47334864cb1b 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -22,8 +22,8 @@ #ifdef __AVR__ #include "../../inc/MarlinConfig.h" -#include "HAL.h" +#if NEEDS_HARDWARE_PWM static uint16_t timer_freq[5]; struct Timer { @@ -228,7 +228,8 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { } else _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res -} +} // NEEDS_HARDWARE_PWM +#endif void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { #if NEEDS_HARDWARE_PWM From 8b334fdb40f63a77a3ef853352235371d025c603 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 Jan 2022 04:47:46 -0600 Subject: [PATCH 13/30] Update fast_pwm.cpp --- Marlin/src/HAL/AVR/fast_pwm.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 47334864cb1b..ca43864f5785 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -24,6 +24,7 @@ #include "../../inc/MarlinConfig.h" #if NEEDS_HARDWARE_PWM + static uint16_t timer_freq[5]; struct Timer { @@ -228,8 +229,9 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { } else _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res -} // NEEDS_HARDWARE_PWM -#endif +} + +#endif // NEEDS_HARDWARE_PWM void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { #if NEEDS_HARDWARE_PWM @@ -244,9 +246,8 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 Timer timer = get_pwm_timer(pin); if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - if (timer_freq[timer.n - 1] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY + if (timer_freq[timer.n - 1] == 0) // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. - } _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; From 741078e33dfaaa0c54d5229fc5638d44d4ed6968 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 Jan 2022 04:52:16 -0600 Subject: [PATCH 14/30] would other platforms ever use it? --- Marlin/src/HAL/AVR/fast_pwm.cpp | 5 +++++ Marlin/src/inc/Conditionals_post.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index ca43864f5785..292e75ccc22e 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -23,6 +23,11 @@ #include "../../inc/MarlinConfig.h" +// Add features that need hardware PWM here +#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM, HAS_LCD_BRIGHTNESS) + #define NEEDS_HARDWARE_PWM 1 +#endif + #if NEEDS_HARDWARE_PWM static uint16_t timer_freq[5]; diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index a7159fe62086..08130d31b7a1 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2860,11 +2860,6 @@ #define HAS_MOTOR_CURRENT_PWM 1 #endif -// Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM, HAS_LCD_BRIGHTNESS) - #define NEEDS_HARDWARE_PWM 1 -#endif - #if ANY(HAS_Z_MS_PINS, HAS_Z2_MS_PINS, HAS_Z3_MS_PINS, HAS_Z4_MS_PINS) #define HAS_SOME_Z_MS_PINS 1 #endif From e18008f14ef41f716fbf1e2f7dcfa2b721dcd43c Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 Jan 2022 04:56:18 -0600 Subject: [PATCH 15/30] tweak wgm --- Marlin/src/HAL/AVR/fast_pwm.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 292e75ccc22e..041f807f4288 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -208,10 +208,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { res = res_temp_fast; j = i; // Set the Wave Generation Mode to FAST PWM - if (timer.n == 2) - wgm = TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM); - else - wgm = WGM_FAST_PWM_ICRn; + wgm = (timer.n == 2) ? TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM) : WGM_FAST_PWM_ICRn; } // If PHASE CORRECT values are closes to desired f else if (f_phase_diff < f_diff) { @@ -219,10 +216,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { res = res_temp_phase_correct; j = i; // Set the Wave Generation Mode to PWM PHASE CORRECT - if (timer.n == 2) - wgm = TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM); - else - wgm = WGM_PWM_PC_ICRn; + wgm = (timer.n == 2) ? TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM) : WGM_PWM_PC_ICRn; } } } From aaa15d6cd690a760a4e0260811c291f9e9317b69 Mon Sep 17 00:00:00 2001 From: descipher Date: Sun, 9 Jan 2022 23:11:13 -0600 Subject: [PATCH 16/30] Init AVR timers 2,3,4,5 in HAL --- Marlin/src/HAL/AVR/HAL.cpp | 2 + Marlin/src/HAL/AVR/HAL.h | 6 ++ Marlin/src/HAL/AVR/fast_pwm.cpp | 129 ++++++++++++++++++++------------ 3 files changed, 89 insertions(+), 48 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp index d7bf2a6f6fbb..2babea6619c9 100644 --- a/Marlin/src/HAL/AVR/HAL.cpp +++ b/Marlin/src/HAL/AVR/HAL.cpp @@ -75,6 +75,8 @@ void HAL_init() { #if HAS_SERVO_3 INIT_SERVO(3); #endif + //Init user timers to default frequency - 1000HZ + init_pwm_timers(); } void HAL_reboot() { diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 6ca5daa85906..1b2fce801b13 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -227,3 +227,9 @@ void set_pwm_frequency(const pin_t pin, const int f_desired); * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255] */ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); + +/* + * init_pwm_timers + * sets the default frequency for timers 2-5 to 1000HZ + */ +void init_pwm_timers(); \ No newline at end of file diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 47334864cb1b..59a6d8f8a218 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -23,15 +23,14 @@ #include "../../inc/MarlinConfig.h" -#if NEEDS_HARDWARE_PWM -static uint16_t timer_freq[5]; - struct Timer { volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer volatile uint16_t* ICRn; // max 1 ICR register per timer uint8_t n; // the timer number [0->5] uint8_t q; // the timer output [0->2] (A->C) + bool isPWMpin; // True if pin is a hardware timer. + bool isProtected; // True if timer is protected }; /** @@ -42,48 +41,81 @@ struct Timer { */ Timer get_pwm_timer(const pin_t pin) { uint8_t q = 0; + + Timer timer = { + /*TCCRnQ*/ { nullptr, nullptr, nullptr }, + /*OCRnQ*/ { nullptr, nullptr, nullptr }, + /*ICRn*/ nullptr, + /*n, q*/ 0, 0, + /*isT, isP*/ false,false + }; + switch (digitalPinToTimer(pin)) { // Protect reserved timers (TIMER0 & TIMER1) #ifdef TCCR0A #if !AVR_AT90USB1286_FAMILY case TIMER0A: + timer = { + /*TCCRnQ*/ { nullptr, nullptr, nullptr }, + /*OCRnQ*/ { nullptr, nullptr, nullptr }, + /*ICRn*/ nullptr, + /*n, q*/ 0, 0, + /*isT, isP*/ true,true + }; #endif case TIMER0B: + timer = { + /*TCCRnQ*/ { nullptr, nullptr, nullptr }, + /*OCRnQ*/ { nullptr, nullptr, nullptr }, + /*ICRn*/ nullptr, + /*n, q*/ 0, 0, + /*isT, isP*/ true,true + }; #endif #ifdef TCCR1A case TIMER1A: case TIMER1B: + timer = { + /*TCCRnQ*/ { nullptr, nullptr, nullptr }, + /*OCRnQ*/ { nullptr, nullptr, nullptr }, + /*ICRn*/ nullptr, + /*n, q*/ 0, 0, + /*isT, isP*/ true,true + }; #endif break; #if HAS_TCCR2 || defined(TCCR2A) #if HAS_TCCR2 case TIMER2: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR2, nullptr, nullptr }, /*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr }, /*ICRn*/ nullptr, - /*n, q*/ 2, 0 + /*n, q*/ 2, 0, + /*isT, isP*/ true,false }; } #elif defined(TCCR2A) #if ENABLED(USE_OCR2A_AS_TOP) case TIMER2A: break; // protect TIMER2A case TIMER2B: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, /*ICRn*/ nullptr, - /*n, q*/ 2, 1 + /*n, q*/ 2, 1, + /*isT, isP*/ true,false }; return timer; } #else case TIMER2B: ++q; case TIMER2A: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, /*ICRn*/ nullptr, - 2, q + /*n, q*/ 2, q, + /*isT, isP*/ true,false }; return timer; } @@ -94,22 +126,24 @@ Timer get_pwm_timer(const pin_t pin) { case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C }, /*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C }, /*ICRn*/ &ICR3, - /*n, q*/ 3, q + /*n, q*/ 3, q, + /*isT, isP*/ true,false }; return timer; } #elif defined(OCR3B) case TIMER3B: ++q; case TIMER3A: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr }, /*OCRnQ*/ { &OCR3A, &OCR3B, nullptr }, /*ICRn*/ &ICR3, - /*n, q*/ 3, q + /*n, q*/ 3, q, + /*isT, isP*/ true,false }; return timer; } @@ -118,11 +152,12 @@ Timer get_pwm_timer(const pin_t pin) { case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A: { - Timer timer = { + timer = { /*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C }, /*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C }, /*ICRn*/ &ICR4, - /*n, q*/ 4, q + /*n, q*/ 4, q, + /*isT, isP*/ true,false }; return timer; } @@ -135,26 +170,19 @@ Timer get_pwm_timer(const pin_t pin) { /*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C }, /*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C }, /*ICRn*/ &ICR5, - /*n, q*/ 5, q + /*n, q*/ 5, q, + /*isT, isP*/ true,false }; return timer; } #endif } - Timer timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - 0, 0 - }; return timer; } void set_pwm_frequency(const pin_t pin, const int f_desired) { Timer timer = get_pwm_timer(pin); - if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - - timer_freq[timer.n - 1] = f_desired; + if (timer.isProtected || !timer.isPWMpin) return; // Don't proceed if protected timer or not recognized const uint16_t size = (timer.n == 2) ? 255 : 65535; @@ -228,38 +256,43 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { } else _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res -} // NEEDS_HARDWARE_PWM -#endif +} void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { - #if NEEDS_HARDWARE_PWM - - // If v is 0 or v_size (max), digitalWrite to LOW or HIGH. - // Note that digitalWrite also disables pwm output for us (sets COM bit to 0) - if (v == 0) - digitalWrite(pin, invert); - else if (v == v_size) - digitalWrite(pin, !invert); - else { - Timer timer = get_pwm_timer(pin); - if (timer.n == 0) return; // Don't proceed if protected timer or not recognized - - if (timer_freq[timer.n - 1] == 0) { // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY - set_pwm_frequency(pin, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. - } - + // If v is 0 or v_size (max), digitalWrite to LOW or HIGH. + // Note that digitalWrite also disables pwm output for us (sets COM bit to 0) + if (v == 0) + digitalWrite(pin, invert); + else if (v == v_size) + digitalWrite(pin, !invert); + else { + Timer timer = get_pwm_timer(pin); + if (timer.isProtected) return; // Don't proceed if protected timer + if (timer.isPWMpin) { _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value + } else { + if (v < 128) { + digitalWrite(pin, LOW); + } else { + digitalWrite(pin, HIGH); + } } + } +} - #else - - analogWrite(pin, v); - UNUSED(v_size); - UNUSED(invert); +void init_pwm_timers() { +// Simply init timers 2 to 5 frequencies using the pin map to a default value on 1000HZ + #ifdef __AVR_ATmega2560__ + uint8_t pwm_pin[] = { 10, 5, 6, 46 }; #endif + + for (uint8_t i=0; i < sizeof(pwm_pin); i++) { + set_pwm_frequency(pwm_pin[i], 1000); + SERIAL_ECHO_MSG("PWM F init",pwm_pin[i]); + } } #endif // __AVR__ From 4b01add3e19ff7c12febab88ced0299f8d6a4022 Mon Sep 17 00:00:00 2001 From: descipher Date: Mon, 10 Jan 2022 01:14:42 -0600 Subject: [PATCH 17/30] Add AT90 pins --- Marlin/src/HAL/AVR/fast_pwm.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 34872ed61394..f57f43a83bb0 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -287,10 +287,15 @@ void init_pwm_timers() { #ifdef __AVR_ATmega2560__ uint8_t pwm_pin[] = { 10, 5, 6, 46 }; #endif + #ifdef __AVR_ATmega1280__ + uint8_t pwm_pin[] = { 12, 31 }; + #endif + #if defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128) + uint8_t pwm_pin[] = { 16, 24 }; + #endif for (uint8_t i=0; i < sizeof(pwm_pin); i++) { set_pwm_frequency(pwm_pin[i], 1000); - SERIAL_ECHO_MSG("PWM F init",pwm_pin[i]); } } From c1e1b75c83ce449d0fc7f297ce304664b2b09962 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 00:36:21 -0600 Subject: [PATCH 18/30] kHz => KHz --- Marlin/Configuration_adv.h | 8 ++++---- Marlin/src/HAL/DUE/HAL_SPI.cpp | 6 +++--- Marlin/src/HAL/DUE/timers.cpp | 2 +- Marlin/src/HAL/DUE/usb/genclk.h | 6 +++--- Marlin/src/HAL/DUE/usb/osc.h | 12 ++++++------ Marlin/src/HAL/DUE/usb/sysclk.h | 6 +++--- Marlin/src/HAL/DUE/watchdog.cpp | 2 +- Marlin/src/HAL/ESP32/i2s.cpp | 2 +- Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c | 2 +- Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h | 2 +- Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp | 2 +- Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h | 2 +- Marlin/src/HAL/STM32/timers.h | 2 +- Marlin/src/HAL/STM32F1/timers.cpp | 2 +- Marlin/src/HAL/TEENSY31_32/timers.h | 2 +- Marlin/src/HAL/TEENSY35_36/timers.h | 2 +- Marlin/src/HAL/shared/HAL_SPI.h | 6 +++--- Marlin/src/feature/digipot/digipot_mcp4451.cpp | 2 +- Marlin/src/module/planner.cpp | 2 +- Marlin/src/module/planner.h | 2 +- 20 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 16c5587f9c6e..0d6cde48d479 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -561,7 +561,7 @@ * FAST_PWM_FAN_FREQUENCY * Set this to your desired frequency. * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1) - * i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers. + * i.e., F = 31.4KHz on 16MHz microcontrollers or F = 39.2KHz on 20MHz microcontrollers. * For non AVR, if left undefined this defaults to F = 1Khz. * This F value is only to protect the hardware from an absence of configuration * and not to complete it when users are not aware that the frequency must be specifically set to support the target board. @@ -1179,7 +1179,7 @@ /** * Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies - * below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible + * below 1KHz (for AVR) or 10KHz (for ARM), where aliasing between axes in multi-axis moves causes audible * vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the * lowest stepping frequencies. */ @@ -3414,14 +3414,14 @@ /** * PHOTO_PULSES_US may need adjustment depending on board and camera model. - * Pin must be running at 48.4kHz. + * Pin must be running at 48.4KHz. * Be sure to use a PHOTOGRAPH_PIN which can rise and fall quick enough. * (e.g., MKS SBase temp sensor pin was too slow, so used P1.23 on J8.) * * Example pulse data for Nikon: https://bit.ly/2FKD0Aq * IR Wiring: https://git.io/JvJf7 */ - //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4kHz oscillation + //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4KHz oscillation #ifdef PHOTO_PULSES_US #define PHOTO_PULSE_DELAY_US 13 // (µs) Approximate duration of each HIGH and LOW pulse in the oscillation #endif diff --git a/Marlin/src/HAL/DUE/HAL_SPI.cpp b/Marlin/src/HAL/DUE/HAL_SPI.cpp index c5e8f2433d7d..2b613a45baec 100644 --- a/Marlin/src/HAL/DUE/HAL_SPI.cpp +++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp @@ -491,9 +491,9 @@ * 1 : 4 - 5 MHz * 2 : 2 - 2.5 MHz * 3 : 1 - 1.25 MHz - * 4 : 500 - 625 kHz - * 5 : 250 - 312 kHz - * 6 : 125 - 156 kHz + * 4 : 500 - 625 KHz + * 5 : 250 - 312 KHz + * 6 : 125 - 156 KHz */ void spiInit(uint8_t spiRate) { switch (spiRate) { diff --git a/Marlin/src/HAL/DUE/timers.cpp b/Marlin/src/HAL/DUE/timers.cpp index a7bf7fbd6d85..6555edece3f3 100644 --- a/Marlin/src/HAL/DUE/timers.cpp +++ b/Marlin/src/HAL/DUE/timers.cpp @@ -62,7 +62,7 @@ const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = { Timer_clock1: Prescaler 2 -> 42MHz Timer_clock2: Prescaler 8 -> 10.5MHz Timer_clock3: Prescaler 32 -> 2.625MHz - Timer_clock4: Prescaler 128 -> 656.25kHz + Timer_clock4: Prescaler 128 -> 656.25KHz */ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { diff --git a/Marlin/src/HAL/DUE/usb/genclk.h b/Marlin/src/HAL/DUE/usb/genclk.h index cde03bc0d107..9831701f836f 100644 --- a/Marlin/src/HAL/DUE/usb/genclk.h +++ b/Marlin/src/HAL/DUE/usb/genclk.h @@ -74,9 +74,9 @@ extern "C" { //@{ enum genclk_source { - GENCLK_PCK_SRC_SLCK_RC = 0, //!< Internal 32kHz RC oscillator as PCK source clock - GENCLK_PCK_SRC_SLCK_XTAL = 1, //!< External 32kHz crystal oscillator as PCK source clock - GENCLK_PCK_SRC_SLCK_BYPASS = 2, //!< External 32kHz bypass oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_RC = 0, //!< Internal 32KHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_XTAL = 1, //!< External 32KHz crystal oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_BYPASS = 2, //!< External 32KHz bypass oscillator as PCK source clock GENCLK_PCK_SRC_MAINCK_4M_RC = 3, //!< Internal 4MHz RC oscillator as PCK source clock GENCLK_PCK_SRC_MAINCK_8M_RC = 4, //!< Internal 8MHz RC oscillator as PCK source clock GENCLK_PCK_SRC_MAINCK_12M_RC = 5, //!< Internal 12MHz RC oscillator as PCK source clock diff --git a/Marlin/src/HAL/DUE/usb/osc.h b/Marlin/src/HAL/DUE/usb/osc.h index 953bcbbed1d3..06f59c676a60 100644 --- a/Marlin/src/HAL/DUE/usb/osc.h +++ b/Marlin/src/HAL/DUE/usb/osc.h @@ -93,9 +93,9 @@ extern "C" { //! \name Oscillator identifiers //@{ -#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator. -#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator. -#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator. +#define OSC_SLCK_32K_RC 0 //!< Internal 32KHz RC oscillator. +#define OSC_SLCK_32K_XTAL 1 //!< External 32KHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS 2 //!< External 32KHz bypass oscillator. #define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator. #define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator. #define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator. @@ -105,9 +105,9 @@ extern "C" { //! \name Oscillator clock speed in hertz //@{ -#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator. -#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator. -#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator. +#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32KHz RC oscillator. +#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32KHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32KHz bypass oscillator. #define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator. #define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator. #define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator. diff --git a/Marlin/src/HAL/DUE/usb/sysclk.h b/Marlin/src/HAL/DUE/usb/sysclk.h index 16db8c86d373..4398cc0fc9fa 100644 --- a/Marlin/src/HAL/DUE/usb/sysclk.h +++ b/Marlin/src/HAL/DUE/usb/sysclk.h @@ -156,9 +156,9 @@ extern "C" { //! \name Master Clock Sources (MCK) //@{ -#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock -#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock -#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock +#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32KHz RC oscillator as master source clock +#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32KHz crystal oscillator as master source clock +#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32KHz bypass oscillator as master source clock #define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock #define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock #define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock diff --git a/Marlin/src/HAL/DUE/watchdog.cpp b/Marlin/src/HAL/DUE/watchdog.cpp index e144db8291e3..6cbf39d1d11f 100644 --- a/Marlin/src/HAL/DUE/watchdog.cpp +++ b/Marlin/src/HAL/DUE/watchdog.cpp @@ -39,7 +39,7 @@ void watchdogSetup() { uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000); // Calculate timeout value in WDT counter ticks: This assumes - // the slow clock is running at 32.768 kHz watchdog + // the slow clock is running at 32.768 KHz watchdog // frequency is therefore 32768 / 128 = 256 Hz timeout = (timeout << 8) / 1000; if (timeout == 0) diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp index 3e77b658360b..e9f418689e89 100644 --- a/Marlin/src/HAL/ESP32/i2s.cpp +++ b/Marlin/src/HAL/ESP32/i2s.cpp @@ -176,7 +176,7 @@ int i2s_init() { * * fwclk = fbclk / 32 * - * for fwclk = 250kHz (4µS pulse time) + * for fwclk = 250KHz (4µS pulse time) * N = 10 * M = 20 */ diff --git a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c index 466fc8020335..bb203cf8d472 100644 --- a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.c @@ -26,7 +26,7 @@ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. * * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which + * With an intermediate level the softspi was running in the 10-20KHz range which * resulted in using about about 25% of the CPU's time. */ diff --git a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h index d60d93daddbd..4661202e8ace 100644 --- a/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/LPC1768/u8g/LCD_pin_routines.h @@ -27,7 +27,7 @@ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. * * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which + * With an intermediate level the softspi was running in the 10-20KHz range which * resulted in using about about 25% of the CPU's time. */ diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp index 3b5acc1656cd..69ea29172482 100644 --- a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp +++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp @@ -26,7 +26,7 @@ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. * * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which + * With an intermediate level the softspi was running in the 10-20KHz range which * resulted in using about about 25% of the CPU's time. */ diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h index c27c84e8c398..3c959cd4911e 100644 --- a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h +++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h @@ -27,7 +27,7 @@ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. * * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which + * With an intermediate level the softspi was running in the 10-20KHz range which * resulted in using about about 25% of the CPU's time. */ diff --git a/Marlin/src/HAL/STM32/timers.h b/Marlin/src/HAL/STM32/timers.h index aad543229e16..37512da95986 100644 --- a/Marlin/src/HAL/STM32/timers.h +++ b/Marlin/src/HAL/STM32/timers.h @@ -48,7 +48,7 @@ #define TIMER_INDEX_(T) TIMER##T##_INDEX // TIMER#_INDEX enums (timer_index_t) depend on TIM#_BASE defines. #define TIMER_INDEX(T) TIMER_INDEX_(T) // Convert Timer ID to HardwareTimer_Handle index. -#define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz +#define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1KHz // TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp #define STEPPER_TIMER_RATE 2000000 // 2 Mhz diff --git a/Marlin/src/HAL/STM32F1/timers.cpp b/Marlin/src/HAL/STM32F1/timers.cpp index 112c730b9acc..f00ac9e3fb19 100644 --- a/Marlin/src/HAL/STM32F1/timers.cpp +++ b/Marlin/src/HAL/STM32F1/timers.cpp @@ -40,7 +40,7 @@ * Timer_clock1: Prescaler 2 -> 36 MHz * Timer_clock2: Prescaler 8 -> 9 MHz * Timer_clock3: Prescaler 32 -> 2.25 MHz - * Timer_clock4: Prescaler 128 -> 562.5 kHz + * Timer_clock4: Prescaler 128 -> 562.5 KHz */ /** diff --git a/Marlin/src/HAL/TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h index 3b073d63ab29..85381ea48163 100644 --- a/Marlin/src/HAL/TEENSY31_32/timers.h +++ b/Marlin/src/HAL/TEENSY31_32/timers.h @@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t; #define FTM0_TIMER_PRESCALE_BITS 0b011 #define FTM1_TIMER_PRESCALE_BITS 0b010 -#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz +#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500KHz #define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz #define HAL_TIMER_RATE (FTM0_TIMER_RATE) diff --git a/Marlin/src/HAL/TEENSY35_36/timers.h b/Marlin/src/HAL/TEENSY35_36/timers.h index 6c342bbe0d25..63ec5e4895ec 100644 --- a/Marlin/src/HAL/TEENSY35_36/timers.h +++ b/Marlin/src/HAL/TEENSY35_36/timers.h @@ -40,7 +40,7 @@ typedef uint32_t hal_timer_t; #define FTM0_TIMER_PRESCALE_BITS 0b011 #define FTM1_TIMER_PRESCALE_BITS 0b010 -#define FTM0_TIMER_RATE (F_BUS / FTM0_TIMER_PRESCALE) // 60MHz / 8 = 7500kHz +#define FTM0_TIMER_RATE (F_BUS / FTM0_TIMER_PRESCALE) // 60MHz / 8 = 7500KHz #define FTM1_TIMER_RATE (F_BUS / FTM1_TIMER_PRESCALE) // 60MHz / 4 = 15MHz #define HAL_TIMER_RATE (FTM0_TIMER_RATE) diff --git a/Marlin/src/HAL/shared/HAL_SPI.h b/Marlin/src/HAL/shared/HAL_SPI.h index 6611f9ec4e0f..50a2bf9df21c 100644 --- a/Marlin/src/HAL/shared/HAL_SPI.h +++ b/Marlin/src/HAL/shared/HAL_SPI.h @@ -38,9 +38,9 @@ * 1 : 4 - 5 MHz * 2 : 2 - 2.5 MHz * 3 : 1 - 1.25 MHz - * 4 : 500 - 625 kHz - * 5 : 250 - 312 kHz - * 6 : 125 - 156 kHz + * 4 : 500 - 625 KHz + * 5 : 250 - 312 KHz + * 6 : 125 - 156 KHz * * On AVR, actual speed is F_CPU/2^(1 + index). * On other platforms, speed should be in range given above where possible. diff --git a/Marlin/src/feature/digipot/digipot_mcp4451.cpp b/Marlin/src/feature/digipot/digipot_mcp4451.cpp index ba5ecdad050a..f59e0aae8068 100644 --- a/Marlin/src/feature/digipot/digipot_mcp4451.cpp +++ b/Marlin/src/feature/digipot/digipot_mcp4451.cpp @@ -82,7 +82,7 @@ void DigipotI2C::set_current(const uint8_t channel, const float current) { void DigipotI2C::init() { #if MB(MKS_SBASE) - configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz + configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400KHz #else Wire.begin(); #endif diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 4c86c06efe6f..bfc8782dba7a 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -2495,7 +2495,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio) SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed."); if (block->advance_speed < 200) - SERIAL_ECHOLNPGM("eISR running at > 10kHz."); + SERIAL_ECHOLNPGM("eISR running at > 10KHz."); #endif } #endif diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 380c35755c96..b83c445260f9 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -883,7 +883,7 @@ class Planner { static void finish_and_disable(); // Periodic handler to manage the cleaning buffer counter - // Called from the Temperature ISR at ~1kHz + // Called from the Temperature ISR at ~1KHz static void isr() { if (cleaning_buffer_counter) --cleaning_buffer_counter; } /** From e17742964550fe171bab2ba4b9c399357aef5f5a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 00:40:33 -0600 Subject: [PATCH 19/30] unsigned PWM frequency --- Marlin/src/HAL/AVR/HAL.h | 8 ++++---- Marlin/src/HAL/AVR/fast_pwm.cpp | 16 ++++++++-------- Marlin/src/HAL/LPC1768/HAL.h | 2 +- Marlin/src/HAL/LPC1768/fast_pwm.cpp | 2 +- Marlin/src/HAL/STM32/HAL.h | 2 +- Marlin/src/HAL/STM32/fast_pwm.cpp | 2 +- Marlin/src/HAL/STM32F1/HAL.h | 2 +- Marlin/src/HAL/STM32F1/fast_pwm.cpp | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 1b2fce801b13..f5cbcc9d51e1 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -218,7 +218,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, const int f_desired); +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); /** * set_pwm_duty @@ -229,7 +229,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired); void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); /* - * init_pwm_timers - * sets the default frequency for timers 2-5 to 1000HZ + * init_pwm_timers + * sets the default frequency for timers 2-5 to 1000HZ */ -void init_pwm_timers(); \ No newline at end of file +void init_pwm_timers(); diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index f57f43a83bb0..c22243515034 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -185,7 +185,7 @@ Timer get_pwm_timer(const pin_t pin) { return timer; } -void set_pwm_frequency(const pin_t pin, const int f_desired) { +void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { Timer timer = get_pwm_timer(pin); if (timer.isProtected || !timer.isPWMpin) return; // Don't proceed if protected timer or not recognized @@ -197,7 +197,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { // Calculating the prescaler and resolution to use to achieve closest frequency if (f_desired != 0) { - int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable + uint16_t f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 }; // loop over prescaler values @@ -222,11 +222,11 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { LIMIT(res_temp_fast, 1U, size); LIMIT(res_temp_phase_correct, 1U, size); // Calculate frequencies of test prescaler and resolution values - const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), - f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), - f_diff = ABS(f - f_desired), - f_fast_diff = ABS(f_temp_fast - f_desired), - f_phase_diff = ABS(f_temp_phase_correct - f_desired); + const uint16_t f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), + f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), + f_diff = ABS(f - f_desired), + f_fast_diff = ABS(f_temp_fast - f_desired), + f_phase_diff = ABS(f_temp_phase_correct - f_desired); // If FAST values are closest to desired f if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) { @@ -255,7 +255,7 @@ void set_pwm_frequency(const pin_t pin, const int f_desired) { } else _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res -} +} void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { // If v is 0 or v_size (max), digitalWrite to LOW or HIGH. diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index 2cd7c659f3db..f5e432698317 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, const 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 c92cb0e71ed5..ece115aa01ae 100644 --- a/Marlin/src/HAL/LPC1768/fast_pwm.cpp +++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp @@ -30,7 +30,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range } -void set_pwm_frequency(const pin_t pin, const 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 df125f7790d4..9429bb7e7ca7 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, const 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 e0b7c57bcbb4..f661e11350ef 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, const 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 af518b0718b3..a766babe155b 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, const 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 7a3f47b2e490..c783dda60683 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, const 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); From 7ffc23a55e5032bebcf16b556431a98d4ff6abae Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 01:25:50 -0600 Subject: [PATCH 20/30] 32 bits may be better --- Marlin/src/HAL/AVR/fast_pwm.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index c22243515034..b93b1fe3a5bc 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -222,11 +222,11 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { LIMIT(res_temp_fast, 1U, size); LIMIT(res_temp_phase_correct, 1U, size); // Calculate frequencies of test prescaler and resolution values - const uint16_t f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), - f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), - f_diff = ABS(f - f_desired), - f_fast_diff = ABS(f_temp_fast - f_desired), - f_phase_diff = ABS(f_temp_phase_correct - f_desired); + const int32_t f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), + f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), + f_diff = ABS(f - f_desired), + f_fast_diff = ABS(f_temp_fast - f_desired), + f_phase_diff = ABS(f_temp_phase_correct - f_desired); // If FAST values are closest to desired f if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) { From 092666ea79454e9eda6294d16dec5be7ec4e6520 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 01:27:43 -0600 Subject: [PATCH 21/30] fix formatting --- Marlin/src/HAL/AVR/HAL.cpp | 4 +- Marlin/src/HAL/AVR/fast_pwm.cpp | 71 ++++++++++++++++----------------- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp index 2babea6619c9..666802725bc0 100644 --- a/Marlin/src/HAL/AVR/HAL.cpp +++ b/Marlin/src/HAL/AVR/HAL.cpp @@ -75,8 +75,8 @@ void HAL_init() { #if HAS_SERVO_3 INIT_SERVO(3); #endif - //Init user timers to default frequency - 1000HZ - init_pwm_timers(); + + init_pwm_timers(); // Init user timers to default frequency - 1000HZ } void HAL_reboot() { diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index b93b1fe3a5bc..2d65b62651ec 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -35,7 +35,7 @@ struct Timer { uint8_t n; // the timer number [0->5] uint8_t q; // the timer output [0->2] (A->C) bool isPWMpin; // True if pin is a hardware timer. - bool isProtected; // True if timer is protected + bool isProtected; // True if timer is protected }; /** @@ -52,9 +52,9 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { nullptr, nullptr, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 0, 0, - /*isT, isP*/ false,false + /*isT, isP*/ false,false }; - + switch (digitalPinToTimer(pin)) { // Protect reserved timers (TIMER0 & TIMER1) #ifdef TCCR0A @@ -65,7 +65,7 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { nullptr, nullptr, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 0, 0, - /*isT, isP*/ true,true + /*isT, isP*/ true,true }; #endif case TIMER0B: @@ -74,7 +74,7 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { nullptr, nullptr, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 0, 0, - /*isT, isP*/ true,true + /*isT, isP*/ true,true }; #endif #ifdef TCCR1A @@ -84,8 +84,8 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { nullptr, nullptr, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 0, 0, - /*isT, isP*/ true,true - }; + /*isT, isP*/ true,true + }; #endif break; #if HAS_TCCR2 || defined(TCCR2A) @@ -108,7 +108,7 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 2, 1, - /*isT, isP*/ true,false + /*isT, isP*/ true,false }; return timer; } @@ -120,7 +120,7 @@ Timer get_pwm_timer(const pin_t pin) { /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, /*ICRn*/ nullptr, /*n, q*/ 2, q, - /*isT, isP*/ true,false + /*isT, isP*/ true,false }; return timer; } @@ -189,7 +189,8 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { Timer timer = get_pwm_timer(pin); if (timer.isProtected || !timer.isPWMpin) return; // Don't proceed if protected timer or not recognized - const uint16_t size = (timer.n == 2) ? 255 : 65535; + const bool is_timer2 = timer.n == 2; + const uint16_t size = is_timer2 ? 255 : 65535; uint16_t res = 255; // resolution (TOP value) uint8_t j = 0; // prescaler index @@ -202,13 +203,15 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { // loop over prescaler values LOOP_S_L_N(i, 1, 8) { - uint16_t res_temp_fast = 255, res_temp_phase_correct = 255; - if (timer.n == 2) { + uint16_t res_temp_fast, res_temp_phase_correct; + if (is_timer2) { // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP #if ENABLED(USE_OCR2A_AS_TOP) const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired); res_temp_fast = rtf - 1; res_temp_phase_correct = rtf / 2; + #else + res_temp_fast = res_temp_phase_correct = 255; #endif } else { @@ -235,7 +238,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res = res_temp_fast; j = i; // Set the Wave Generation Mode to FAST PWM - wgm = (timer.n == 2) ? TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM) : WGM_FAST_PWM_ICRn; + wgm = is_timer2 ? TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM) : WGM_FAST_PWM_ICRn; } // If PHASE CORRECT values are closes to desired f else if (f_phase_diff < f_diff) { @@ -243,18 +246,18 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res = res_temp_phase_correct; j = i; // Set the Wave Generation Mode to PWM PHASE CORRECT - wgm = (timer.n == 2) ? TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM) : WGM_PWM_PC_ICRn; + wgm = is_timer2 ? TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM) : WGM_PWM_PC_ICRn; } } } _SET_WGMnQ(timer.TCCRnQ, wgm); _SET_CSn(timer.TCCRnQ, j); - if (timer.n == 2) { - TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer.OCRnQ, 0, res)); // Set OCR2A value (TOP) = res + if (is_timer2) { + TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer.OCRnQ, 0, res)); // Set OCR2A value (TOP) = res } else - _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res + _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res } void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { @@ -271,32 +274,28 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value - } else { - if (v < 128) { - digitalWrite(pin, LOW); - } else { - digitalWrite(pin, HIGH); - } } + else if (v < 128) + digitalWrite(pin, LOW); + else + digitalWrite(pin, HIGH); } } void init_pwm_timers() { + // Init some timer frequencies to a default 1KHZ + const pin_t pwm_pin[] = { + #ifdef __AVR_ATmega2560__ + 10, 5, 6, 46 + #elif defined(__AVR_ATmega1280__) + 12, 31 + #elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128) + 16, 24 + #endif + }; -// Simply init timers 2 to 5 frequencies using the pin map to a default value on 1000HZ - #ifdef __AVR_ATmega2560__ - uint8_t pwm_pin[] = { 10, 5, 6, 46 }; - #endif - #ifdef __AVR_ATmega1280__ - uint8_t pwm_pin[] = { 12, 31 }; - #endif - #if defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128) - uint8_t pwm_pin[] = { 16, 24 }; - #endif - - for (uint8_t i=0; i < sizeof(pwm_pin); i++) { + LOOP_L_N(i, COUNT(pwm_pin)) set_pwm_frequency(pwm_pin[i], 1000); - } } #endif // __AVR__ From 1755e788adeab9c7501f47f807072507706d0318 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 02:05:03 -0600 Subject: [PATCH 22/30] suppress warning --- Marlin/src/HAL/AVR/fast_pwm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 2d65b62651ec..946469843e4b 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -238,7 +238,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res = res_temp_fast; j = i; // Set the Wave Generation Mode to FAST PWM - wgm = is_timer2 ? TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM) : WGM_FAST_PWM_ICRn; + wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn); } // If PHASE CORRECT values are closes to desired f else if (f_phase_diff < f_diff) { @@ -246,7 +246,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res = res_temp_phase_correct; j = i; // Set the Wave Generation Mode to PWM PHASE CORRECT - wgm = is_timer2 ? TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM) : WGM_PWM_PC_ICRn; + wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_PWM_PC_ICRn); } } } From 14795aa3d2d6586307e5693cc181aae334aff800 Mon Sep 17 00:00:00 2001 From: descipher Date: Mon, 10 Jan 2022 08:26:52 -0600 Subject: [PATCH 23/30] Add more pins --- Marlin/src/HAL/AVR/fast_pwm.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 946469843e4b..eebcc6679b4f 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -289,6 +289,8 @@ void init_pwm_timers() { 10, 5, 6, 46 #elif defined(__AVR_ATmega1280__) 12, 31 + #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__) + 15, 6 #elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128) 16, 24 #endif From f95f6064faefa0639db77f88aaf1d9424830f3e4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 18:45:02 -0600 Subject: [PATCH 24/30] unsigned enums --- Marlin/src/HAL/AVR/fastio.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h index db6e598b8670..7adb57094c13 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,7 +138,7 @@ enum WaveGenMode : char { }; // Wavefore Generation Modes (Timer 2 only) -enum WaveGenMode2 : char { +enum WaveGenMode2 : uint8_t { WGM2_NORMAL, // 0 WGM2_PWM_PC, // 1 WGM2_CTC_OCR2A, // 2 @@ -150,7 +150,7 @@ enum WaveGenMode2 : char { }; // 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 From 54501eb9ccc52a54dadcca18968e0f4b652ef674 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 19:22:40 -0600 Subject: [PATCH 25/30] move macros, tweak get_pwm_timer --- Marlin/src/HAL/AVR/fast_pwm.cpp | 226 ++++++++++++++++---------------- Marlin/src/HAL/AVR/fastio.h | 33 ++--- 2 files changed, 121 insertions(+), 138 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index eebcc6679b4f..e3853b650e03 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -38,6 +38,24 @@ struct Timer { bool isProtected; // True if timer is protected }; +// 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. @@ -45,143 +63,128 @@ struct Timer { * Used by set_pwm_frequency, set_pwm_duty */ Timer get_pwm_timer(const pin_t pin) { - uint8_t q = 0; - Timer timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 0, 0, - /*isT, isP*/ false,false - }; + uint8_t q = 0; switch (digitalPinToTimer(pin)) { // Protect reserved timers (TIMER0 & TIMER1) #ifdef TCCR0A #if !AVR_AT90USB1286_FAMILY case TIMER0A: - timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 0, 0, - /*isT, isP*/ true,true - }; #endif case TIMER0B: - timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 0, 0, - /*isT, isP*/ true,true - }; + break; #endif + #ifdef TCCR1A case TIMER1A: case TIMER1B: - timer = { - /*TCCRnQ*/ { nullptr, nullptr, nullptr }, - /*OCRnQ*/ { nullptr, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 0, 0, - /*isT, isP*/ true,true - }; + break; #endif - break; - #if HAS_TCCR2 || defined(TCCR2A) - #if HAS_TCCR2 - case TIMER2: { - timer = { - /*TCCRnQ*/ { &TCCR2, nullptr, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 2, 0, - /*isT, isP*/ true,false + + #if HAS_TCCR2 + case TIMER2: { + Timer timer = { + { &TCCR2, nullptr, nullptr }, + { (uint16_t*)&OCR2, nullptr, nullptr }, + nullptr, + 2, 0, + true, false + }; + return timer; + } + #elif defined(TCCR2A) + #if ENABLED(USE_OCR2A_AS_TOP) + case TIMER2A: break; // protect TIMER2A + case TIMER2B: { + Timer timer = { + { &TCCR2A, &TCCR2B, nullptr }, + { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, + nullptr, + 2, 1, + true, false }; + return timer; + } + #else + case TIMER2B: ++q; + case TIMER2A: { + Timer timer = { + { &TCCR2A, &TCCR2B, nullptr }, + { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, + nullptr, + 2, q, + true, false + }; + return timer; } - #elif defined(TCCR2A) - #if ENABLED(USE_OCR2A_AS_TOP) - case TIMER2A: break; // protect TIMER2A - case TIMER2B: { - timer = { - /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 2, 1, - /*isT, isP*/ true,false - }; - return timer; - } - #else - case TIMER2B: ++q; - case TIMER2A: { - timer = { - /*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr }, - /*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - /*ICRn*/ nullptr, - /*n, q*/ 2, q, - /*isT, isP*/ true,false - }; - return timer; - } - #endif #endif #endif + #ifdef OCR3C - case TIMER3C: ++q; - case TIMER3B: ++q; + case TIMER3C: ++q; + case TIMER3B: ++q; case TIMER3A: { - timer = { - /*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C }, - /*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C }, - /*ICRn*/ &ICR3, - /*n, q*/ 3, q, - /*isT, isP*/ true,false + Timer timer = { + { &TCCR3A, &TCCR3B, &TCCR3C }, + { &OCR3A, &OCR3B, &OCR3C }, + &ICR3, + 3, q, + true, false }; return timer; } #elif defined(OCR3B) - case TIMER3B: ++q; + case TIMER3B: ++q; case TIMER3A: { - timer = { - /*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr }, - /*OCRnQ*/ { &OCR3A, &OCR3B, nullptr }, - /*ICRn*/ &ICR3, - /*n, q*/ 3, q, - /*isT, isP*/ true,false + Timer timer = { + { &TCCR3A, &TCCR3B, nullptr }, + { &OCR3A, &OCR3B, nullptr }, + &ICR3, + 3, q, + true, false }; return timer; } #endif + #ifdef TCCR4A - case TIMER4C: ++q; - case TIMER4B: ++q; + case TIMER4C: ++q; + case TIMER4B: ++q; case TIMER4A: { - timer = { - /*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C }, - /*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C }, - /*ICRn*/ &ICR4, - /*n, q*/ 4, q, - /*isT, isP*/ true,false + Timer timer = { + { &TCCR4A, &TCCR4B, &TCCR4C }, + { &OCR4A, &OCR4B, &OCR4C }, + &ICR4, + 4, q, + true, false }; 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, - /*isT, isP*/ true,false + { &TCCR5A, &TCCR5B, &TCCR5C }, + { &OCR5A, &OCR5B, &OCR5C }, + &ICR5, + 5, q, + true, false }; return timer; } #endif } + + Timer timer = { + { nullptr, nullptr, nullptr }, + { nullptr, nullptr, nullptr }, + nullptr, + 0, 0, + true,true + }; return timer; } @@ -198,16 +201,17 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { // Calculating the prescaler and resolution to use to achieve closest frequency if (f_desired != 0) { + constexpr uint16_t prescaler[] = { 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 }; uint16_t f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable - uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 }; // loop over prescaler values - LOOP_S_L_N(i, 1, 8) { + LOOP_L_N(i, 8) { + const uint16_t p = prescaler[i]; uint16_t res_temp_fast, res_temp_phase_correct; if (is_timer2) { // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP #if ENABLED(USE_OCR2A_AS_TOP) - const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired); + const uint16_t rtf = (F_CPU) / (p * f_desired); res_temp_fast = rtf - 1; res_temp_phase_correct = rtf / 2; #else @@ -216,8 +220,8 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { } else { // Skip TIMER2 specific prescalers when not TIMER2 - if (i == 3 || i == 5) continue; - const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired); + if (p == 32 || p == 128) continue; + const uint16_t rtf = (F_CPU) / (p * f_desired); res_temp_fast = rtf - 1; res_temp_phase_correct = rtf / 2; } @@ -225,26 +229,24 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { LIMIT(res_temp_fast, 1U, size); LIMIT(res_temp_phase_correct, 1U, size); // Calculate frequencies of test prescaler and resolution values - const int32_t f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)), - f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct), - f_diff = ABS(f - f_desired), + const int32_t f_temp_fast = (F_CPU) / (p * (1 + res_temp_fast)), f_fast_diff = ABS(f_temp_fast - f_desired), + f_diff = ABS(f - f_desired), + f_temp_phase_correct = (F_CPU) / (2 * p * res_temp_phase_correct), f_phase_diff = ABS(f_temp_phase_correct - f_desired); - // If FAST values are closest to desired f - if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) { + if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) { // FAST values are closest to desired f // Remember this combination f = f_temp_fast; res = res_temp_fast; - j = i; + j = i + 1; // Set the Wave Generation Mode to FAST PWM wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn); } - // If PHASE CORRECT values are closes to desired f - else if (f_phase_diff < f_diff) { + else if (f_phase_diff < f_diff) { // PHASE CORRECT values are closes to desired f f = f_temp_phase_correct; res = res_temp_phase_correct; - j = i; + j = i + 1; // Set the Wave Generation Mode to PWM PHASE CORRECT wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_PWM_PC_ICRn); } @@ -271,14 +273,12 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 Timer timer = get_pwm_timer(pin); if (timer.isProtected) return; // Don't proceed if protected timer if (timer.isPWMpin) { - _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 + _SET_COMnQ(timer.TCCRnQ, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value } - else if (v < 128) - digitalWrite(pin, LOW); else - digitalWrite(pin, HIGH); + digitalWrite(pin, v < 128 ? LOW : HIGH); } } diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h index 7adb57094c13..51d3b311ee9d 100644 --- a/Marlin/src/HAL/AVR/fastio.h +++ b/Marlin/src/HAL/AVR/fastio.h @@ -139,14 +139,14 @@ enum WaveGenMode : uint8_t { // Wavefore Generation Modes (Timer 2 only) 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 + 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 @@ -203,11 +203,6 @@ enum ClockSource2 : uint8_t { 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 : uint8_t { #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 : uint8_t { #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) From 78cb32fce69071236c8ad273ded5f91ff2e2c7b5 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 19:42:11 -0600 Subject: [PATCH 26/30] tweak var names and maths --- Marlin/src/HAL/AVR/fast_pwm.cpp | 51 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index e3853b650e03..393bd69e7baf 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -205,47 +205,46 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { uint16_t f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable // loop over prescaler values - LOOP_L_N(i, 8) { + LOOP_L_N(i, COUNT(prescaler)) { const uint16_t p = prescaler[i]; - uint16_t res_temp_fast, res_temp_phase_correct; + uint16_t res_fast_temp, res_pc_temp; if (is_timer2) { - // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP - #if ENABLED(USE_OCR2A_AS_TOP) - const uint16_t rtf = (F_CPU) / (p * f_desired); - res_temp_fast = rtf - 1; - res_temp_phase_correct = rtf / 2; + #if ENABLED(USE_OCR2A_AS_TOP) // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP + const uint16_t rft = (F_CPU) / (p * f_desired); + res_fast_temp = rft - 1; + res_pc_temp = rft / 2; #else - res_temp_fast = res_temp_phase_correct = 255; + res_fast_temp = res_pc_temp = 255; #endif } else { - // Skip TIMER2 specific prescalers when not TIMER2 - if (p == 32 || p == 128) continue; - const uint16_t rtf = (F_CPU) / (p * f_desired); - res_temp_fast = rtf - 1; - res_temp_phase_correct = rtf / 2; + if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2 + const uint16_t rft = (F_CPU) / (p * f_desired); + res_fast_temp = rft - 1; + res_pc_temp = rft / 2; } - LIMIT(res_temp_fast, 1U, size); - LIMIT(res_temp_phase_correct, 1U, size); + LIMIT(res_fast_temp, 1U, size); + LIMIT(res_pc_temp, 1U, size); + // Calculate frequencies of test prescaler and resolution values - const int32_t f_temp_fast = (F_CPU) / (p * (1 + res_temp_fast)), - f_fast_diff = ABS(f_temp_fast - f_desired), - f_diff = ABS(f - f_desired), - f_temp_phase_correct = (F_CPU) / (2 * p * res_temp_phase_correct), - f_phase_diff = ABS(f_temp_phase_correct - f_desired); + const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired), + f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)), + f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired), + f_pc_temp = (F_CPU) / (2 * p * res_pc_temp), + f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired); - if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) { // FAST values are closest to desired f + if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f // Remember this combination - f = f_temp_fast; - res = res_temp_fast; + f = f_fast_temp; + res = res_fast_temp; j = i + 1; // Set the Wave Generation Mode to FAST PWM wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn); } - else if (f_phase_diff < f_diff) { // PHASE CORRECT values are closes to desired f - f = f_temp_phase_correct; - res = res_temp_phase_correct; + else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f + f = f_pc_temp; + res = res_pc_temp; j = i + 1; // Set the Wave Generation Mode to PWM PHASE CORRECT wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_PWM_PC_ICRn); From 90ba936ccc035ce64582d03162650eac25dcd00f Mon Sep 17 00:00:00 2001 From: descipher Date: Mon, 10 Jan 2022 21:25:49 -0600 Subject: [PATCH 27/30] Timer check default return as non-PWM and not protected. --- Marlin/src/HAL/AVR/fast_pwm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index ae7d802d75b5..04cc6aa80363 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -180,7 +180,7 @@ Timer get_pwm_timer(const pin_t pin) { { nullptr, nullptr, nullptr }, nullptr, 0, 0, - true, true + false, false }; return timer; } From 0871ea36bb51bbb2b318e28febf9ae015bd10933 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 Jan 2022 00:28:59 -0600 Subject: [PATCH 28/30] return timer structs more directly --- Marlin/src/HAL/AVR/fast_pwm.cpp | 76 +++++++++++---------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 04cc6aa80363..806140fdb377 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -23,11 +23,6 @@ #include "../../inc/MarlinConfig.h" -// Add features that need hardware PWM here -#if ANY(FAST_PWM_FAN, SPINDLE_LASER_USE_PWM, HAS_MOTOR_CURRENT_PWM, HAS_LCD_BRIGHTNESS) - #define NEEDS_HARDWARE_PWM 1 -#endif - struct Timer { volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer @@ -79,110 +74,87 @@ Timer get_pwm_timer(const pin_t pin) { break; #if HAS_TCCR2 - case TIMER2: { - Timer timer = { + case TIMER2: + return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false - }; - return timer; - } + }); #elif defined(TCCR2A) #if ENABLED(USE_OCR2A_AS_TOP) - case TIMER2A: break; // protect TIMER2A - case TIMER2B: { - Timer timer = { + case TIMER2A: break; // protect TIMER2A + case TIMER2B: + return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false - }; - return timer; - } + }); #else - case TIMER2B: ++q; - case TIMER2A: { - Timer timer = { + case TIMER2B: ++q; case TIMER2A: + return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false - }; - return timer; - } + }); #endif #endif #ifdef OCR3C - case TIMER3C: ++q; - case TIMER3B: ++q; - case TIMER3A: { - Timer timer = { + case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A: + return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false - }; - return timer; - } + }); #elif defined(OCR3B) - case TIMER3B: ++q; - case TIMER3A: { - Timer timer = { + case TIMER3B: ++q; case TIMER3A: + return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false - }; - return timer; - } + }); #endif #ifdef TCCR4A - case TIMER4C: ++q; - case TIMER4B: ++q; - case TIMER4A: { - Timer timer = { + case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A: + return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false - }; - return timer; - } + }); #endif #ifdef TCCR5A - case TIMER5C: ++q; - case TIMER5B: ++q; - case TIMER5A: { - Timer timer = { + case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A: + return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false - }; - return timer; - } + }); #endif } - Timer timer = { + return Timer({ { nullptr, nullptr, nullptr }, { nullptr, nullptr, nullptr }, nullptr, 0, 0, false, false - }; - return timer; + }); } void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { From 0f5fbe7e6bd4f3e065b418b986782f43478e905a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Tue, 11 Jan 2022 01:59:34 -0600 Subject: [PATCH 29/30] fallback to WGM2_PWM_PC --- Marlin/src/HAL/AVR/fast_pwm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 806140fdb377..165adb30956b 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -216,7 +216,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res = res_pc_temp; j = i + 1; // Set the Wave Generation Mode to PWM PHASE CORRECT - wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_PWM_PC_ICRn); + wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn); } } } From 6a5eaec21828cf14eb67402fda06ee8573ad9783 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Jan 2022 23:45:22 -0600 Subject: [PATCH 30/30] style tweaks --- Marlin/src/HAL/AVR/fast_pwm.cpp | 130 +++++++++----------------------- Marlin/src/HAL/AVR/fastio.cpp | 2 +- 2 files changed, 37 insertions(+), 95 deletions(-) diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp index 165adb30956b..071f008e8974 100644 --- a/Marlin/src/HAL/AVR/fast_pwm.cpp +++ b/Marlin/src/HAL/AVR/fast_pwm.cpp @@ -29,7 +29,7 @@ struct Timer { volatile uint16_t* ICRn; // max 1 ICR register per timer uint8_t n; // the timer number [0->5] uint8_t q; // the timer output [0->2] (A->C) - bool isPWMpin; // True if pin is a hardware timer. + bool isPWM; // True if pin is a "hardware timer" bool isProtected; // True if timer is protected }; @@ -52,17 +52,13 @@ struct Timer { #define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF) /** - * get_pwm_timer - * Get the timer information and register of the provided pin. - * Return a Timer struct containing this information. - * Used by set_pwm_frequency, set_pwm_duty + * Return a Timer struct describing a pin's timer. */ Timer get_pwm_timer(const pin_t pin) { uint8_t q = 0; switch (digitalPinToTimer(pin)) { - // Protect reserved timers (TIMER0 & TIMER1) #ifdef TCCR0A IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:) case TIMER0B: @@ -71,110 +67,59 @@ Timer get_pwm_timer(const pin_t pin) { case TIMER1A: case TIMER1B: #endif - break; + break; // Protect reserved timers (TIMER0 & TIMER1) #if HAS_TCCR2 case TIMER2: - return Timer({ - { &TCCR2, nullptr, nullptr }, - { (uint16_t*)&OCR2, nullptr, nullptr }, - nullptr, - 2, 0, - true, false - }); + return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false }); + #elif ENABLED(USE_OCR2A_AS_TOP) + case TIMER2A: break; // protect TIMER2A since its OCR is used by TIMER2B + case TIMER2B: + return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false }); #elif defined(TCCR2A) - #if ENABLED(USE_OCR2A_AS_TOP) - case TIMER2A: break; // protect TIMER2A - case TIMER2B: - return Timer({ - { &TCCR2A, &TCCR2B, nullptr }, - { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - nullptr, - 2, 1, - true, false - }); - #else - case TIMER2B: ++q; case TIMER2A: - return Timer({ - { &TCCR2A, &TCCR2B, nullptr }, - { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, - nullptr, - 2, q, - true, false - }); - #endif + case TIMER2B: ++q; case TIMER2A: + return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false }); #endif #ifdef OCR3C case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A: - return Timer({ - { &TCCR3A, &TCCR3B, &TCCR3C }, - { &OCR3A, &OCR3B, &OCR3C }, - &ICR3, - 3, q, - true, false - }); + return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false }); #elif defined(OCR3B) case TIMER3B: ++q; case TIMER3A: - return Timer({ - { &TCCR3A, &TCCR3B, nullptr }, - { &OCR3A, &OCR3B, nullptr }, - &ICR3, - 3, q, - true, false - }); + return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false }); #endif #ifdef TCCR4A case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A: - return Timer({ - { &TCCR4A, &TCCR4B, &TCCR4C }, - { &OCR4A, &OCR4B, &OCR4C }, - &ICR4, - 4, q, - true, false - }); + return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false }); #endif #ifdef TCCR5A case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A: - return Timer({ - { &TCCR5A, &TCCR5B, &TCCR5C }, - { &OCR5A, &OCR5B, &OCR5C }, - &ICR5, - 5, q, - true, false - }); + return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false }); #endif } - return Timer({ - { nullptr, nullptr, nullptr }, - { nullptr, nullptr, nullptr }, - nullptr, - 0, 0, - false, false - }); + return Timer(); } void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { Timer timer = get_pwm_timer(pin); - if (timer.isProtected || !timer.isPWMpin) return; // Don't proceed if protected timer or not recognized + if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized const bool is_timer2 = timer.n == 2; - const uint16_t size = is_timer2 ? 255 : 65535; + const uint16_t maxtop = is_timer2 ? 0xFF : 0xFFFF; - uint16_t res = 255; // resolution (TOP value) - uint8_t j = 0; // prescaler index - uint8_t wgm = 1; // waveform generation mode + uint16_t res = 0xFF; // resolution (TOP value) + uint8_t j = CS_NONE; // prescaler index + uint8_t wgm = WGM_PWM_PC_8; // waveform generation mode // Calculating the prescaler and resolution to use to achieve closest frequency if (f_desired != 0) { - constexpr uint16_t prescaler[] = { 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 }; - uint16_t f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable + constexpr uint16_t prescaler[] = { 1, 8, (32), 64, (128), 256, 1024 }; // (*) are Timer 2 only + uint16_t f = (F_CPU) / (2 * 1024 * maxtop) + 1; // Start with the lowest non-zero frequency achievable (1 or 31) - // loop over prescaler values - LOOP_L_N(i, COUNT(prescaler)) { + LOOP_L_N(i, COUNT(prescaler)) { // Loop through all prescaler values const uint16_t p = prescaler[i]; uint16_t res_fast_temp, res_pc_temp; if (is_timer2) { @@ -183,7 +128,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res_fast_temp = rft - 1; res_pc_temp = rft / 2; #else - res_fast_temp = res_pc_temp = 255; + res_fast_temp = res_pc_temp = maxtop; #endif } else { @@ -193,33 +138,30 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { res_pc_temp = rft / 2; } - LIMIT(res_fast_temp, 1U, size); - LIMIT(res_pc_temp, 1U, size); + LIMIT(res_fast_temp, 1U, maxtop); + LIMIT(res_pc_temp, 1U, maxtop); // Calculate frequencies of test prescaler and resolution values - const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired), + const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired), f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)), f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired), - f_pc_temp = (F_CPU) / (2 * p * res_pc_temp), - f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired); + f_pc_temp = (F_CPU) / (2 * p * res_pc_temp), + f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired); if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f - // Remember this combination - f = f_fast_temp; - res = res_fast_temp; - j = i + 1; // Set the Wave Generation Mode to FAST PWM wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn); + // Remember this combination + f = f_fast_temp; res = res_fast_temp; j = i + 1; } else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f - f = f_pc_temp; - res = res_pc_temp; - j = i + 1; // Set the Wave Generation Mode to PWM PHASE CORRECT wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn); + f = f_pc_temp; res = res_pc_temp; j = i + 1; } } } + _SET_WGMnQ(timer.TCCRnQ, wgm); _SET_CSn(timer.TCCRnQ, j); @@ -239,8 +181,8 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 digitalWrite(pin, !invert); else { Timer timer = get_pwm_timer(pin); - if (timer.isProtected) return; // Don't proceed if protected timer - if (timer.isPWMpin) { + if (timer.isProtected) return; // Leave protected timer unchanged + if (timer.isPWM) { _SET_COMnQ(timer.TCCRnQ, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value @@ -251,7 +193,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255 } void init_pwm_timers() { - // Init some timer frequencies to a default 1KHZ + // Init some timer frequencies to a default 1KHz const pin_t pwm_pin[] = { #ifdef __AVR_ATmega2560__ 10, 5, 6, 46 diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp index 8af3ef805efa..a76a35aa65bb 100644 --- a/Marlin/src/HAL/AVR/fastio.cpp +++ b/Marlin/src/HAL/AVR/fastio.cpp @@ -257,7 +257,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb const float pwm_top = round(count); // Get the rounded count ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP - OCR5A = pwm_top * ABS(dca); // Update and scale DCs + OCR5A = pwm_top * ABS(dca); // Update and scale DCs OCR5B = pwm_top * ABS(dcb); OCR5C = pwm_top * ABS(dcc); _SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes