diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.cpp b/Marlin/src/HAL/TEENSY40_41/HAL.cpp index 4dd5c3678d..d40f620c81 100644 --- a/Marlin/src/HAL/TEENSY40_41/HAL.cpp +++ b/Marlin/src/HAL/TEENSY40_41/HAL.cpp @@ -202,18 +202,13 @@ uint16_t MarlinHAL::adc_value() { // Free Memory Accessor // ------------------------ -#define __bss_end _ebss - extern "C" { - extern char __bss_end; - extern char __heap_start; - extern void* __brkval; + // Reference for Teensy 4.x: https://forum.pjrc.com/index.php?threads/how-to-display-free-ram.33443/#post-275013 + extern unsigned long _heap_end; + extern char *__brkval; - // Doesn't work on Teensy 4.x uint32_t freeMemory() { - uint32_t free_memory; - free_memory = ((uint32_t)&free_memory) - (((uint32_t)__brkval) ?: ((uint32_t)&__bss_end)); - return free_memory; + return (char *)&_heap_end - __brkval; } } diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h index 355d1d75ac..7fa285ae62 100644 --- a/Marlin/src/HAL/TEENSY40_41/HAL.h +++ b/Marlin/src/HAL/TEENSY40_41/HAL.h @@ -61,6 +61,8 @@ #undef PSTR #define PSTR(str) ({static const char *data = (str); &data[0];}) +#define HAL_CAN_SET_PWM_FREQ + // ------------------------ // Serial ports // ------------------------ @@ -221,11 +223,15 @@ public: /** * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] + * Optionally invert the duty cycle [default = false] + * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255] */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } + static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); + /** + * Set the PWM output frequency. This may affect multiple pins, though + * Teensy 4.x provides many timers affecting only a single pin. + * See: https://www.pjrc.com/teensy/td_pulse.html + */ + static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); }; diff --git a/Marlin/src/HAL/TEENSY40_41/fast_pwm.cpp b/Marlin/src/HAL/TEENSY40_41/fast_pwm.cpp new file mode 100644 index 0000000000..21531d115d --- /dev/null +++ b/Marlin/src/HAL/TEENSY40_41/fast_pwm.cpp @@ -0,0 +1,54 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifdef __IMXRT1062__ + +#include "../../inc/MarlinConfig.h" + +#include "HAL.h" + +void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size /*=255*/, const bool invert) { + + uint32_t bits = 1; + uint16_t value = _MIN(v, v_size); + + if (invert) value = v_size - value; + + // Choose scale as smallest power of 2 which holds v_size. + uint32_t scale = 1; + while (scale < v_size) { + bits++; + scale *= 2; + } + + uint32_t scaled_val = scale * value / v_size; + + uint32_t prior = analogWriteResolution(bits); + analogWrite(pin, scaled_val); + analogWriteResolution(prior); +} + +void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { + analogWriteFrequency(pin, f_desired); +} + +#endif // __IMXRT1062__ diff --git a/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h b/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h index 731658b4a3..7b1c466f23 100644 --- a/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h +++ b/Marlin/src/HAL/TEENSY40_41/inc/SanityCheck.h @@ -33,10 +33,6 @@ #error "EMERGENCY_PARSER is not yet implemented for Teensy 4.0/4.1. Disable EMERGENCY_PARSER to continue." #endif -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported for Teensy 4.0/4.1." -#endif - #if HAS_TMC_SW_SERIAL #error "TMC220x Software Serial is not supported for Teensy 4.0/4.1." #endif @@ -44,3 +40,19 @@ #if ENABLED(POSTMORTEM_DEBUGGING) #error "POSTMORTEM_DEBUGGING is not yet supported for Teensy 4.0/4.1." #endif + +#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) || ENABLED(SERIAL_STATS_DROPPED_RX) || ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) || ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + #error "SERIAL_STATS_* features not supported on Teensy 4.0/4.1." +#endif + +#if ENABLED(BAUD_RATE_GCODE) && SERIAL_PORT_2 == -2 + #error "BAUD_RATE_GCODE cannot be enabled when using the Ethernet serial port." +#endif + +#if ENABLED(SPINDLE_LASER_USE_PWM) && !ENABLED(SILENCE_TEENSY_SPINDLE_LASER_WARNING) + #warning "SPINDLE_LASER_USE_PWM is untested on Teensy 4.0/4.1, see https://www.pjrc.com/teensy/td_pulse.html for details on frequencies, and resolution. #define SILENCE_TEENSY_SPINDLE_LASER_WARNING to silence warning." +#endif + +#if ENABLED(FAST_PWM_FAN) && FAST_PWM_FAN_FREQUENCY == 1000U + #warning "FAST_PWM_FAN_FREQUENCY has been left as default, see https://www.pjrc.com/teensy/td_pulse.html and consider raising it to reduce noise." +#endif diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp index c05fe12fc3..93045e955c 100644 --- a/Marlin/src/gcode/calibrate/M100.cpp +++ b/Marlin/src/gcode/calibrate/M100.cpp @@ -60,7 +60,7 @@ #define TEST_BYTE ((char) 0xE5) -#if ANY(__AVR__, IS_32BIT_TEENSY) +#if ANY(__AVR__, IS_32BIT_TEENSY) && !IS_TEENSY_40_41 extern char __bss_end; char *end_bss = &__bss_end,