Teensy 4 hardware PWM for laser/spindle/fan (#27608)

This commit is contained in:
phizev 2025-01-14 00:14:16 +02:00 committed by GitHub
parent b7f628ce2f
commit 854cfc016d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 86 additions and 19 deletions

View file

@ -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;
}
}

View file

@ -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);
};

View file

@ -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 <https://www.gnu.org/licenses/>.
*
*/
#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__

View file

@ -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

View file

@ -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,