Browse Source

Move FAST_PWM_FAN code to HALs (#13491)

Chris Pepper 5 years ago
parent
commit
ffc2c2d7c5

+ 19
- 0
Marlin/src/HAL/HAL_AVR/HAL.h View File

@@ -372,3 +372,22 @@ inline void HAL_adc_init(void) {
372 372
 
373 373
 // AVR compatibility
374 374
 #define strtof strtod
375
+
376
+/**
377
+ *  set_pwm_frequency
378
+ *  Sets the frequency of the timer corresponding to the provided pin
379
+ *  as close as possible to the provided desired frequency. Internally
380
+ *  calculates the required waveform generation mode, prescaler and
381
+ *  resolution values required and sets the timer registers accordingly.
382
+ *  NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
383
+ *  NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
384
+ */
385
+void set_pwm_frequency(const pin_t pin, int f_desired);
386
+
387
+/**
388
+ * set_pwm_duty
389
+ *  Sets the PWM duty cycle of the provided pin to the provided value
390
+ *  Optionally allows inverting the duty cycle [default = false]
391
+ *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
392
+ */
393
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);

+ 250
- 0
Marlin/src/HAL/HAL_AVR/fast_pwm.cpp View File

@@ -0,0 +1,250 @@
1
+#ifdef __AVR__
2
+
3
+#include "../../inc/MarlinConfigPre.h"
4
+/**
5
+ * get_pwm_timer
6
+ *  Grabs timer information and registers of the provided pin
7
+ *  returns Timer struct containing this information
8
+ *  Used by set_pwm_frequency, set_pwm_duty
9
+ *
10
+ */
11
+
12
+#if ENABLED(FAST_PWM_FAN)
13
+#include "HAL.h"
14
+
15
+  struct Timer {
16
+    volatile uint8_t* TCCRnQ[3];  // max 3 TCCR registers per timer
17
+    volatile uint16_t* OCRnQ[3];  // max 3 OCR registers per timer
18
+    volatile uint16_t* ICRn;      // max 1 ICR register per timer
19
+    uint8_t n;                    // the timer number [0->5]
20
+    uint8_t q;                    // the timer output [0->2] (A->C)
21
+  };
22
+
23
+  Timer get_pwm_timer(pin_t pin) {
24
+    uint8_t q = 0;
25
+    switch (digitalPinToTimer(pin)) {
26
+      // Protect reserved timers (TIMER0 & TIMER1)
27
+      #ifdef TCCR0A
28
+        #if !AVR_AT90USB1286_FAMILY
29
+          case TIMER0A:
30
+        #endif
31
+        case TIMER0B:
32
+      #endif
33
+      #ifdef TCCR1A
34
+        case TIMER1A: case TIMER1B:
35
+      #endif
36
+                                          break;
37
+      #if defined(TCCR2) || defined(TCCR2A)
38
+        #ifdef TCCR2
39
+          case TIMER2: {
40
+            Timer timer = {
41
+              /*TCCRnQ*/  { &TCCR2, NULL, NULL},
42
+              /*OCRnQ*/   { (uint16_t*)&OCR2, NULL, NULL},
43
+              /*ICRn*/      NULL,
44
+              /*n, q*/      2, 0
45
+            };
46
+          }
47
+        #elif defined TCCR2A
48
+          #if ENABLED(USE_OCR2A_AS_TOP)
49
+            case TIMER2A:   break; // protect TIMER2A
50
+            case TIMER2B: {
51
+              Timer timer = {
52
+                /*TCCRnQ*/  { &TCCR2A,  &TCCR2B,  NULL},
53
+                /*OCRnQ*/   { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
54
+                /*ICRn*/      NULL,
55
+                /*n, q*/      2, 1
56
+              };
57
+              return timer;
58
+            }
59
+          #else
60
+            case TIMER2B:   ++q;
61
+            case TIMER2A: {
62
+              Timer timer = {
63
+                /*TCCRnQ*/  { &TCCR2A,  &TCCR2B,  NULL},
64
+                /*OCRnQ*/   { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
65
+                /*ICRn*/      NULL,
66
+                              2, q
67
+              };
68
+              return timer;
69
+            }
70
+          #endif
71
+        #endif
72
+      #endif
73
+      #ifdef TCCR3A
74
+        case TIMER3C:   ++q;
75
+        case TIMER3B:   ++q;
76
+        case TIMER3A: {
77
+          Timer timer = {
78
+            /*TCCRnQ*/  { &TCCR3A,  &TCCR3B,  &TCCR3C},
79
+            /*OCRnQ*/   { &OCR3A,   &OCR3B,   &OCR3C},
80
+            /*ICRn*/      &ICR3,
81
+            /*n, q*/      3, q
82
+          };
83
+          return timer;
84
+        }
85
+      #endif
86
+      #ifdef TCCR4A
87
+        case TIMER4C:   ++q;
88
+        case TIMER4B:   ++q;
89
+        case TIMER4A: {
90
+          Timer timer = {
91
+            /*TCCRnQ*/  { &TCCR4A,  &TCCR4B,  &TCCR4C},
92
+            /*OCRnQ*/   { &OCR4A,   &OCR4B,   &OCR4C},
93
+            /*ICRn*/      &ICR4,
94
+            /*n, q*/      4, q
95
+          };
96
+          return timer;
97
+        }
98
+      #endif
99
+      #ifdef TCCR5A
100
+        case TIMER5C:   ++q;
101
+        case TIMER5B:   ++q;
102
+        case TIMER5A: {
103
+          Timer timer = {
104
+            /*TCCRnQ*/  { &TCCR5A,  &TCCR5B,  &TCCR5C},
105
+            /*OCRnQ*/   { &OCR5A,   &OCR5B,   &OCR5C },
106
+            /*ICRn*/      &ICR5,
107
+            /*n, q*/      5, q
108
+          };
109
+          return timer;
110
+        }
111
+      #endif
112
+    }
113
+    Timer timer = {
114
+        /*TCCRnQ*/  { NULL, NULL, NULL},
115
+        /*OCRnQ*/   { NULL, NULL, NULL},
116
+        /*ICRn*/      NULL,
117
+                      0, 0
118
+    };
119
+    return timer;
120
+  }
121
+
122
+  void set_pwm_frequency(const pin_t pin, int f_desired) {
123
+    Timer timer = get_pwm_timer(pin);
124
+    if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
125
+    uint16_t size;
126
+    if (timer.n == 2) size = 255; else size = 65535;
127
+
128
+    uint16_t res = 255;   // resolution (TOP value)
129
+    uint8_t j = 0;        // prescaler index
130
+    uint8_t wgm = 1;      // waveform generation mode
131
+
132
+    // Calculating the prescaler and resolution to use to achieve closest frequency
133
+    if (f_desired != 0) {
134
+      int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
135
+      uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
136
+
137
+      // loop over prescaler values
138
+      for (uint8_t i = 1; i < 8; i++) {
139
+        uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
140
+        if (timer.n == 2) {
141
+          // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
142
+          #if ENABLED(USE_OCR2A_AS_TOP)
143
+            const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
144
+            res_temp_fast = rtf - 1;
145
+            res_temp_phase_correct = rtf / 2;
146
+          #endif
147
+        }
148
+        else {
149
+          // Skip TIMER2 specific prescalers when not TIMER2
150
+          if (i == 3 || i == 5) continue;
151
+          const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
152
+          res_temp_fast = rtf - 1;
153
+          res_temp_phase_correct = rtf / 2;
154
+        }
155
+
156
+        LIMIT(res_temp_fast, 1u, size);
157
+        LIMIT(res_temp_phase_correct, 1u, size);
158
+        // Calculate frequencies of test prescaler and resolution values
159
+        const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
160
+                  f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
161
+                  f_diff = ABS(f - f_desired),
162
+                  f_fast_diff = ABS(f_temp_fast - f_desired),
163
+                  f_phase_diff = ABS(f_temp_phase_correct - f_desired);
164
+
165
+        // If FAST values are closest to desired f
166
+        if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
167
+          // Remember this combination
168
+          f = f_temp_fast;
169
+          res = res_temp_fast;
170
+          j = i;
171
+          // Set the Wave Generation Mode to FAST PWM
172
+          if (timer.n == 2) {
173
+            wgm = (
174
+              #if ENABLED(USE_OCR2A_AS_TOP)
175
+                WGM2_FAST_PWM_OCR2A
176
+              #else
177
+                WGM2_FAST_PWM
178
+              #endif
179
+            );
180
+          }
181
+          else wgm = WGM_FAST_PWM_ICRn;
182
+        }
183
+        // If PHASE CORRECT values are closes to desired f
184
+        else if (f_phase_diff < f_diff) {
185
+          f = f_temp_phase_correct;
186
+          res = res_temp_phase_correct;
187
+          j = i;
188
+          // Set the Wave Generation Mode to PWM PHASE CORRECT
189
+          if (timer.n == 2) {
190
+            wgm = (
191
+              #if ENABLED(USE_OCR2A_AS_TOP)
192
+                WGM2_PWM_PC_OCR2A
193
+              #else
194
+                WGM2_PWM_PC
195
+              #endif
196
+            );
197
+          }
198
+          else wgm = WGM_PWM_PC_ICRn;
199
+        }
200
+      }
201
+    }
202
+    _SET_WGMnQ(timer.TCCRnQ, wgm);
203
+    _SET_CSn(timer.TCCRnQ, j);
204
+
205
+    if (timer.n == 2) {
206
+      #if ENABLED(USE_OCR2A_AS_TOP)
207
+        _SET_OCRnQ(timer.OCRnQ, 0, res);  // Set OCR2A value (TOP) = res
208
+      #endif
209
+    }
210
+    else
211
+      _SET_ICRn(timer.ICRn, res);         // Set ICRn value (TOP) = res
212
+  }
213
+
214
+  void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
215
+    // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
216
+    // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
217
+    if (v == 0)
218
+      digitalWrite(pin, invert);
219
+    else if (v == v_size)
220
+      digitalWrite(pin, !invert);
221
+    else {
222
+      Timer timer = get_pwm_timer(pin);
223
+      if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
224
+      // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
225
+      _SET_COMnQ(timer.TCCRnQ, (timer.q
226
+          #ifdef TCCR2
227
+            + (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
228
+          #endif
229
+        ), COM_CLEAR_SET + invert
230
+      );
231
+
232
+      uint16_t top;
233
+      if (timer.n == 2) { // if TIMER2
234
+        top = (
235
+          #if ENABLED(USE_OCR2A_AS_TOP)
236
+            *timer.OCRnQ[0] // top = OCR2A
237
+          #else
238
+            255 // top = 0xFF (max)
239
+          #endif
240
+        );
241
+      }
242
+      else
243
+        top = *timer.ICRn; // top = ICRn
244
+
245
+      _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
246
+    }
247
+  }
248
+
249
+#endif // FAST_PWM_FAN
250
+#endif // __AVR__

+ 5
- 5
Marlin/src/HAL/HAL_AVR/fastio_AVR.h View File

@@ -200,7 +200,7 @@ enum ClockSource2 : char {
200 200
     TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
201 201
   }while(0)
202 202
 #define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
203
-// Runtime (see Temperature::set_pwm_frequency):
203
+// Runtime (see set_pwm_frequency):
204 204
 #define _SET_WGMnQ(TCCRnQ, V) do{ \
205 205
     *(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V)       & 0x3) << 0); \
206 206
     *(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
@@ -230,7 +230,7 @@ enum ClockSource2 : char {
230 230
 #define SET_CS4(V) _SET_CS4(CS_##V)
231 231
 #define SET_CS5(V) _SET_CS5(CS_##V)
232 232
 #define SET_CS(T,V) SET_CS##T(V)
233
-// Runtime (see Temperature::set_pwm_frequency)
233
+// Runtime (see set_pwm_frequency)
234 234
 #define _SET_CSn(TCCRnQ, V) do{ \
235 235
     (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)); \
236 236
   }while(0)
@@ -243,19 +243,19 @@ enum ClockSource2 : char {
243 243
 #define SET_COMB(T,V) SET_COM(T,B,V)
244 244
 #define SET_COMC(T,V) SET_COM(T,C,V)
245 245
 #define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
246
-// Runtime (see Temperature::set_pwm_duty)
246
+// Runtime (see set_pwm_duty)
247 247
 #define _SET_COMnQ(TCCRnQ, Q, V) do{ \
248 248
     (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))); \
249 249
   }while(0)
250 250
 
251 251
 // Set OCRnQ register
252
-// Runtime (see Temperature::set_pwm_duty):
252
+// Runtime (see set_pwm_duty):
253 253
 #define _SET_OCRnQ(OCRnQ, Q, V) do{ \
254 254
     (*(OCRnQ)[(Q)] = (0x0000) | (int(V) & 0xFFFF)); \
255 255
   }while(0)
256 256
 
257 257
 // Set ICRn register (one per timer)
258
-// Runtime (see Temperature::set_pwm_frequency)
258
+// Runtime (see set_pwm_frequency)
259 259
 #define _SET_ICRn(ICRn, V) do{ \
260 260
     (*(ICRn) = (0x0000) | (int(V) & 0xFFFF)); \
261 261
   }while(0)

+ 4
- 0
Marlin/src/HAL/HAL_DUE/SanityCheck.h View File

@@ -50,3 +50,7 @@
50 50
     #error "DUE software SPI is required but is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix."
51 51
   #endif
52 52
 #endif
53
+
54
+#if ENABLED(FAST_PWM_FAN)
55
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
56
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_ESP32/SanityCheck.h View File

@@ -23,3 +23,7 @@
23 23
 #if ENABLED(EMERGENCY_PARSER)
24 24
   #error "EMERGENCY_PARSER is not yet implemented for ESP32. Disable EMERGENCY_PARSER to continue."
25 25
 #endif
26
+
27
+#if ENABLED(FAST_PWM_FAN)
28
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
29
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_LINUX/SanityCheck.h View File

@@ -65,3 +65,7 @@
65 65
     #endif
66 66
   #endif
67 67
 #endif // SPINDLE_LASER_ENABLE
68
+
69
+#if ENABLED(FAST_PWM_FAN)
70
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
71
+#endif

+ 16
- 0
Marlin/src/HAL/HAL_LPC1768/HAL.h View File

@@ -157,3 +157,19 @@ void HAL_idletask(void);
157 157
 
158 158
 #define PLATFORM_M997_SUPPORT
159 159
 void flashFirmware(int16_t value);
160
+
161
+/**
162
+ * set_pwm_frequency
163
+ *  Set the frequency of the timer corresponding to the provided pin
164
+ *  All Hardware PWM pins run at the same frequency and all
165
+ *  Software PWM pins run at the same frequency
166
+ */
167
+void set_pwm_frequency(const pin_t pin, int f_desired);
168
+
169
+/**
170
+ * set_pwm_duty
171
+ *  Set the PWM duty cycle of the provided pin to the provided value
172
+ *  Optionally allows inverting the duty cycle [default = false]
173
+ *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
174
+ */
175
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);

+ 40
- 0
Marlin/src/HAL/HAL_LPC1768/fast_pwm.cpp View File

@@ -0,0 +1,40 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifdef TARGET_LPC1768
24
+
25
+#include "../../inc/MarlinConfigPre.h"
26
+
27
+#if ENABLED(FAST_PWM_FAN)
28
+
29
+#include <pwm.h>
30
+
31
+void set_pwm_frequency(const pin_t pin, int f_desired) {
32
+  pwm_set_frequency(pin, f_desired);
33
+}
34
+
35
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
36
+  pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
37
+}
38
+
39
+#endif // FAST_PWM_FAN
40
+#endif // TARGET_LPC1768

+ 4
- 0
Marlin/src/HAL/HAL_STM32/SanityCheck.h View File

@@ -69,3 +69,7 @@
69 69
 #if ENABLED(EMERGENCY_PARSER)
70 70
   #error "EMERGENCY_PARSER is not yet implemented for STM32. Disable EMERGENCY_PARSER to continue."
71 71
 #endif
72
+
73
+#if ENABLED(FAST_PWM_FAN)
74
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
75
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_STM32F1/SanityCheck.h View File

@@ -74,3 +74,7 @@
74 74
 #if ENABLED(SDIO_SUPPORT) && DISABLED(SDSUPPORT)
75 75
   #error "SDIO_SUPPORT requires SDSUPPORT. Enable SDSUPPORT to continue."
76 76
 #endif
77
+
78
+#if ENABLED(FAST_PWM_FAN)
79
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
80
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_STM32F4/SanityCheck.h View File

@@ -68,3 +68,7 @@
68 68
 #if ENABLED(EMERGENCY_PARSER)
69 69
   #error "EMERGENCY_PARSER is not yet implemented for STM32F4. Disable EMERGENCY_PARSER to continue."
70 70
 #endif
71
+
72
+#if ENABLED(FAST_PWM_FAN)
73
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
74
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_STM32F7/SanityCheck.h View File

@@ -70,3 +70,7 @@
70 70
 #if ENABLED(EMERGENCY_PARSER)
71 71
   #error "EMERGENCY_PARSER is not yet implemented for STM32F7. Disable EMERGENCY_PARSER to continue."
72 72
 #endif
73
+
74
+#if ENABLED(FAST_PWM_FAN)
75
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
76
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_TEENSY31_32/SanityCheck.h View File

@@ -27,3 +27,7 @@
27 27
 #if ENABLED(EMERGENCY_PARSER)
28 28
   #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.1/3.2. Disable EMERGENCY_PARSER to continue."
29 29
 #endif
30
+
31
+#if ENABLED(FAST_PWM_FAN)
32
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
33
+#endif

+ 4
- 0
Marlin/src/HAL/HAL_TEENSY35_36/SanityCheck.h View File

@@ -27,3 +27,7 @@
27 27
 #if ENABLED(EMERGENCY_PARSER)
28 28
   #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.5/3.6. Disable EMERGENCY_PARSER to continue."
29 29
 #endif
30
+
31
+#if ENABLED(FAST_PWM_FAN)
32
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
33
+#endif

+ 0
- 4
Marlin/src/inc/SanityCheck.h View File

@@ -2015,10 +2015,6 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
2015 2015
   #error "POWER_LOSS_RECOVERY currently requires an LCD Controller."
2016 2016
 #endif
2017 2017
 
2018
-#if ENABLED(FAST_PWM_FAN) && !(defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM))
2019
-  #error "FAST_PWM_FAN is only supported for ARDUINO and ARDUINO_ARCH_SAM."
2020
-#endif
2021
-
2022 2018
 #if ENABLED(Z_STEPPER_AUTO_ALIGN)
2023 2019
   #if !Z_MULTI_STEPPER_DRIVERS
2024 2020
     #error "Z_STEPPER_AUTO_ALIGN requires Z_DUAL_STEPPER_DRIVERS or Z_TRIPLE_STEPPER_DRIVERS."

+ 3
- 3
Marlin/src/module/planner.cpp View File

@@ -1278,13 +1278,13 @@ void Planner::check_axes_activity() {
1278 1278
     #elif ENABLED(FAST_PWM_FAN)
1279 1279
 
1280 1280
       #if HAS_FAN0
1281
-        thermalManager.set_pwm_duty(FAN_PIN, CALC_FAN_SPEED(0));
1281
+        set_pwm_duty(FAN_PIN, CALC_FAN_SPEED(0));
1282 1282
       #endif
1283 1283
       #if HAS_FAN1
1284
-        thermalManager.set_pwm_duty(FAN1_PIN, CALC_FAN_SPEED(1));
1284
+        set_pwm_duty(FAN1_PIN, CALC_FAN_SPEED(1));
1285 1285
       #endif
1286 1286
       #if HAS_FAN2
1287
-        thermalManager.set_pwm_duty(FAN2_PIN, CALC_FAN_SPEED(2));
1287
+        set_pwm_duty(FAN2_PIN, CALC_FAN_SPEED(2));
1288 1288
       #endif
1289 1289
 
1290 1290
     #else

+ 0
- 231
Marlin/src/module/temperature.cpp View File

@@ -1544,237 +1544,6 @@ void Temperature::init() {
1544 1544
   #endif
1545 1545
 }
1546 1546
 
1547
-
1548
-#if ENABLED(FAST_PWM_FAN)
1549
-  Temperature::Timer Temperature::get_pwm_timer(pin_t pin) {
1550
-    #if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
1551
-      uint8_t q = 0;
1552
-      switch (digitalPinToTimer(pin)) {
1553
-        // Protect reserved timers (TIMER0 & TIMER1)
1554
-        #ifdef TCCR0A
1555
-          #if !AVR_AT90USB1286_FAMILY
1556
-            case TIMER0A:
1557
-          #endif
1558
-          case TIMER0B:
1559
-        #endif
1560
-        #ifdef TCCR1A
1561
-          case TIMER1A: case TIMER1B:
1562
-        #endif
1563
-                                            break;
1564
-        #if defined(TCCR2) || defined(TCCR2A)
1565
-          #ifdef TCCR2
1566
-            case TIMER2: {
1567
-              Temperature::Timer timer = {
1568
-                /*TCCRnQ*/  { &TCCR2, NULL, NULL},
1569
-                /*OCRnQ*/   { (uint16_t*)&OCR2, NULL, NULL},
1570
-                /*ICRn*/      NULL,
1571
-                /*n, q*/      2, 0
1572
-              };
1573
-            }
1574
-          #elif defined TCCR2A
1575
-            #if ENABLED(USE_OCR2A_AS_TOP)
1576
-              case TIMER2A:   break; // protect TIMER2A
1577
-              case TIMER2B: {
1578
-                Temperature::Timer timer = {
1579
-                  /*TCCRnQ*/  { &TCCR2A,  &TCCR2B,  NULL},
1580
-                  /*OCRnQ*/   { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
1581
-                  /*ICRn*/      NULL,
1582
-                  /*n, q*/      2, 1
1583
-                };
1584
-                return timer;
1585
-              }
1586
-            #else
1587
-              case TIMER2B:   q += 1;
1588
-              case TIMER2A: {
1589
-                Temperature::Timer timer = {
1590
-                  /*TCCRnQ*/  { &TCCR2A,  &TCCR2B,  NULL},
1591
-                  /*OCRnQ*/   { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
1592
-                  /*ICRn*/      NULL,
1593
-                                2, q
1594
-                };
1595
-                return timer;
1596
-              }
1597
-            #endif
1598
-          #endif
1599
-        #endif
1600
-        #ifdef TCCR3A
1601
-          case TIMER3C:   q += 1;
1602
-          case TIMER3B:   q += 1;
1603
-          case TIMER3A: {
1604
-            Temperature::Timer timer = {
1605
-              /*TCCRnQ*/  { &TCCR3A,  &TCCR3B,  &TCCR3C},
1606
-              /*OCRnQ*/   { &OCR3A,   &OCR3B,   &OCR3C},
1607
-              /*ICRn*/      &ICR3,
1608
-              /*n, q*/      3, q
1609
-            };
1610
-            return timer;
1611
-          }
1612
-        #endif
1613
-        #ifdef TCCR4A
1614
-          case TIMER4C:   q += 1;
1615
-          case TIMER4B:   q += 1;
1616
-          case TIMER4A: {
1617
-            Temperature::Timer timer = {
1618
-              /*TCCRnQ*/  { &TCCR4A,  &TCCR4B,  &TCCR4C},
1619
-              /*OCRnQ*/   { &OCR4A,   &OCR4B,   &OCR4C},
1620
-              /*ICRn*/      &ICR4,
1621
-              /*n, q*/      4, q
1622
-            };
1623
-            return timer;
1624
-          }
1625
-        #endif
1626
-        #ifdef TCCR5A
1627
-          case TIMER5C:   q += 1;
1628
-          case TIMER5B:   q += 1;
1629
-          case TIMER5A: {
1630
-            Temperature::Timer timer = {
1631
-              /*TCCRnQ*/  { &TCCR5A,  &TCCR5B,  &TCCR5C},
1632
-              /*OCRnQ*/   { &OCR5A,   &OCR5B,   &OCR5C },
1633
-              /*ICRn*/      &ICR5,
1634
-              /*n, q*/      5, q
1635
-            };
1636
-            return timer;
1637
-          }
1638
-        #endif
1639
-      }
1640
-      Temperature::Timer timer = {
1641
-          /*TCCRnQ*/  { NULL, NULL, NULL},
1642
-          /*OCRnQ*/   { NULL, NULL, NULL},
1643
-          /*ICRn*/      NULL,
1644
-                        0, 0
1645
-      };
1646
-      return timer;
1647
-    #endif // ARDUINO && !ARDUINO_ARCH_SAM
1648
-  }
1649
-
1650
-  void Temperature::set_pwm_frequency(const pin_t pin, int f_desired) {
1651
-    #if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
1652
-      Temperature::Timer timer = get_pwm_timer(pin);
1653
-      if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
1654
-      uint16_t size;
1655
-      if (timer.n == 2) size = 255; else size = 65535;
1656
-
1657
-      uint16_t res = 255;   // resolution (TOP value)
1658
-      uint8_t j = 0;        // prescaler index
1659
-      uint8_t wgm = 1;      // waveform generation mode
1660
-
1661
-      // Calculating the prescaler and resolution to use to achieve closest frequency
1662
-      if (f_desired != 0) {
1663
-        int f = F_CPU/(2*1024*size) + 1; // Initialize frequency as lowest (non-zero) achievable
1664
-        uint16_t prescaler[] = {0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024};
1665
-
1666
-        // loop over prescaler values
1667
-        for (uint8_t i = 1; i < 8; i++) {
1668
-          uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
1669
-          if (timer.n == 2) {
1670
-            // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
1671
-            #if ENABLED(USE_OCR2A_AS_TOP)
1672
-              res_temp_fast = (F_CPU / (prescaler[i] * f_desired)) - 1;
1673
-              res_temp_phase_correct = F_CPU / (2 * prescaler[i] * f_desired);
1674
-            #endif
1675
-          }
1676
-          else {
1677
-            // Skip TIMER2 specific prescalers when not TIMER2
1678
-            if (i == 3 || i == 5) continue;
1679
-            res_temp_fast = (F_CPU / (prescaler[i] * f_desired)) - 1;
1680
-            res_temp_phase_correct = F_CPU / (2 * prescaler[i] * f_desired);
1681
-          }
1682
-
1683
-          LIMIT(res_temp_fast, 1u, size);
1684
-          LIMIT(res_temp_phase_correct, 1u, size);
1685
-          // Calculate frequncies of test prescaler and resolution values
1686
-          int f_temp_fast = F_CPU / (prescaler[i] * (1 + res_temp_fast));
1687
-          int f_temp_phase_correct = F_CPU / (2 * prescaler[i] * res_temp_phase_correct);
1688
-
1689
-          // If FAST values are closest to desired f
1690
-          if (ABS(f_temp_fast - f_desired) < ABS(f - f_desired)
1691
-              && ABS(f_temp_fast - f_desired) <= ABS(f_temp_phase_correct - f_desired)) {
1692
-            // Remember this combination
1693
-            f = f_temp_fast;
1694
-            res = res_temp_fast;
1695
-            j = i;
1696
-            // Set the Wave Generation Mode to FAST PWM
1697
-            if(timer.n == 2){
1698
-              wgm =
1699
-                #if ENABLED(USE_OCR2A_AS_TOP)
1700
-                  WGM2_FAST_PWM_OCR2A;
1701
-                #else
1702
-                  WGM2_FAST_PWM;
1703
-                #endif
1704
-            }
1705
-            else wgm = WGM_FAST_PWM_ICRn;
1706
-          }
1707
-          // If PHASE CORRECT values are closes to desired f
1708
-          else if (ABS(f_temp_phase_correct - f_desired) < ABS(f - f_desired)) {
1709
-            f = f_temp_phase_correct;
1710
-            res = res_temp_phase_correct;
1711
-            j = i;
1712
-            // Set the Wave Generation Mode to PWM PHASE CORRECT
1713
-            if (timer.n == 2) {
1714
-              wgm =
1715
-                #if ENABLED(USE_OCR2A_AS_TOP)
1716
-                  WGM2_PWM_PC_OCR2A;
1717
-                #else
1718
-                  WGM2_PWM_PC;
1719
-                #endif
1720
-            }
1721
-            else wgm = WGM_PWM_PC_ICRn;
1722
-          }
1723
-        }
1724
-      }
1725
-      _SET_WGMnQ(timer.TCCRnQ, wgm);
1726
-      _SET_CSn(timer.TCCRnQ, j);
1727
-
1728
-      if (timer.n == 2) {
1729
-        #if ENABLED(USE_OCR2A_AS_TOP)
1730
-          _SET_OCRnQ(timer.OCRnQ, 0, res);  // Set OCR2A value (TOP) = res
1731
-        #endif
1732
-      }
1733
-      else {
1734
-        _SET_ICRn(timer.ICRn, res);         // Set ICRn value (TOP) = res
1735
-      }
1736
-    #endif // ARDUINO && !ARDUINO_ARCH_SAM
1737
-  }
1738
-
1739
-  void Temperature::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
1740
-    #if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
1741
-      // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
1742
-      // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
1743
-      if (v == 0)
1744
-        digitalWrite(pin, invert);
1745
-      else if (v == v_size)
1746
-        digitalWrite(pin, !invert);
1747
-      else {
1748
-        Temperature::Timer timer = get_pwm_timer(pin);
1749
-        if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
1750
-        // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
1751
-        _SET_COMnQ(timer.TCCRnQ, timer.q
1752
-            #ifdef TCCR2
1753
-              + (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
1754
-            #endif
1755
-          , COM_CLEAR_SET + invert
1756
-        );
1757
-
1758
-        uint16_t top;
1759
-        if (timer.n == 2) { // if TIMER2
1760
-          top =
1761
-            #if ENABLED(USE_OCR2A_AS_TOP)
1762
-              *timer.OCRnQ[0] // top = OCR2A
1763
-            #else
1764
-              255 // top = 0xFF (max)
1765
-            #endif
1766
-          ;
1767
-        }
1768
-        else
1769
-          top = *timer.ICRn; // top = ICRn
1770
-
1771
-        _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
1772
-      }
1773
-    #endif // ARDUINO && !ARDUINO_ARCH_SAM
1774
-  }
1775
-
1776
-#endif // FAST_PWM_FAN
1777
-
1778 1547
 #if WATCH_HOTENDS
1779 1548
   /**
1780 1549
    * Start Heating Sanity Check for hotends that are below

+ 0
- 41
Marlin/src/module/temperature.h View File

@@ -266,16 +266,6 @@ class Temperature {
266 266
                      soft_pwm_count_fan[FAN_COUNT];
267 267
     #endif
268 268
 
269
-    /**
270
-     * set_pwm_duty (8-bit AVRs only)
271
-     *  Sets the PWM duty cycle of the provided pin to the provided value
272
-     *  Optionally allows inverting the duty cycle [default = false]
273
-     *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
274
-     */
275
-    #if ENABLED(FAST_PWM_FAN)
276
-      static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
277
-    #endif
278
-
279 269
     #if ENABLED(BABYSTEPPING)
280 270
       static volatile int16_t babystepsTodo[3];
281 271
     #endif
@@ -744,38 +734,7 @@ class Temperature {
744 734
     #endif
745 735
 
746 736
   private:
747
-
748
-    /**
749
-     * (8-bit AVRs only)
750
-     *
751
-     * get_pwm_timer
752
-     *  Grabs timer information and registers of the provided pin
753
-     *  returns Timer struct containing this information
754
-     *  Used by set_pwm_frequency, set_pwm_duty
755
-     *
756
-     * set_pwm_frequency
757
-     *  Sets the frequency of the timer corresponding to the provided pin
758
-     *  as close as possible to the provided desired frequency. Internally
759
-     *  calculates the required waveform generation mode, prescaler and
760
-     *  resolution values required and sets the timer registers accordingly.
761
-     *  NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
762
-     *  NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
763
-     */
764
-    #if ENABLED(FAST_PWM_FAN)
765
-      typedef struct Timer {
766
-          volatile uint8_t* TCCRnQ[3];  // max 3 TCCR registers per timer
767
-          volatile uint16_t* OCRnQ[3];  // max 3 OCR registers per timer
768
-          volatile uint16_t* ICRn;      // max 1 ICR register per timer
769
-          uint8_t n;                    // the timer number [0->5]
770
-          uint8_t q;                    // the timer output [0->2] (A->C)
771
-      } Timer;
772
-
773
-      static Timer get_pwm_timer(const pin_t pin);
774
-      static void set_pwm_frequency(const pin_t pin, int f_desired);
775
-    #endif
776
-
777 737
     static void set_current_temp_raw();
778
-
779 738
     static void updateTemperaturesFromRawValues();
780 739
 
781 740
     #define HAS_MAX6675 EITHER(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675)

Loading…
Cancel
Save