|
|
@ -1,26 +1,47 @@ |
|
|
|
#ifdef __AVR__ |
|
|
|
|
|
|
|
#include "../../inc/MarlinConfigPre.h" |
|
|
|
/**
|
|
|
|
* get_pwm_timer |
|
|
|
* Grabs timer information and registers of the provided pin |
|
|
|
* returns Timer struct containing this information |
|
|
|
* Used by set_pwm_frequency, set_pwm_duty |
|
|
|
* Marlin 3D Printer Firmware |
|
|
|
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
|
|
|
* |
|
|
|
*/ |
|
|
|
#ifdef __AVR__ |
|
|
|
|
|
|
|
#include "../../inc/MarlinConfigPre.h" |
|
|
|
|
|
|
|
#if ENABLED(FAST_PWM_FAN) |
|
|
|
|
|
|
|
#include "HAL.h" |
|
|
|
|
|
|
|
struct Timer { |
|
|
|
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)
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
Timer get_pwm_timer(pin_t pin) { |
|
|
|
/**
|
|
|
|
* 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 |
|
|
|
*/ |
|
|
|
Timer get_pwm_timer(const pin_t pin) { |
|
|
|
uint8_t q = 0; |
|
|
|
switch (digitalPinToTimer(pin)) { |
|
|
|
// Protect reserved timers (TIMER0 & TIMER1)
|
|
|
@ -117,9 +138,9 @@ |
|
|
|
0, 0 |
|
|
|
}; |
|
|
|
return timer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void set_pwm_frequency(const pin_t pin, int f_desired) { |
|
|
|
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 recognised
|
|
|
|
uint16_t size; |
|
|
@ -209,9 +230,9 @@ |
|
|
|
} |
|
|
|
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*/) { |
|
|
|
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.
|
|
|
|
// Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
|
|
|
|
if (v == 0) |
|
|
@ -244,7 +265,7 @@ |
|
|
|
|
|
|
|
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif // FAST_PWM_FAN
|
|
|
|
#endif // __AVR__
|
|
|
|