aboutsummaryrefslogtreecommitdiff
path: root/Marlin/src/HAL/AVR/fastio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Marlin/src/HAL/AVR/fastio.cpp')
-rw-r--r--Marlin/src/HAL/AVR/fastio.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp
new file mode 100644
index 0000000..b51d7f9
--- /dev/null
+++ b/Marlin/src/HAL/AVR/fastio.cpp
@@ -0,0 +1,288 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 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/>.
+ *
+ */
+
+/**
+ * Fast I/O for extended pins
+ */
+
+#ifdef __AVR__
+
+#include "fastio.h"
+
+#ifdef FASTIO_EXT_START
+
+#include "../shared/Marduino.h"
+
+#define _IS_EXT(P) WITHIN(P, FASTIO_EXT_START, FASTIO_EXT_END)
+
+void extDigitalWrite(const int8_t pin, const uint8_t state) {
+ #define _WCASE(N) case N: WRITE(N, state); break
+ switch (pin) {
+ default: digitalWrite(pin, state);
+ #if _IS_EXT(70)
+ _WCASE(70);
+ #endif
+ #if _IS_EXT(71)
+ _WCASE(71);
+ #endif
+ #if _IS_EXT(72)
+ _WCASE(72);
+ #endif
+ #if _IS_EXT(73)
+ _WCASE(73);
+ #endif
+ #if _IS_EXT(74)
+ _WCASE(74);
+ #endif
+ #if _IS_EXT(75)
+ _WCASE(75);
+ #endif
+ #if _IS_EXT(76)
+ _WCASE(76);
+ #endif
+ #if _IS_EXT(77)
+ _WCASE(77);
+ #endif
+ #if _IS_EXT(78)
+ _WCASE(78);
+ #endif
+ #if _IS_EXT(79)
+ _WCASE(79);
+ #endif
+ #if _IS_EXT(80)
+ _WCASE(80);
+ #endif
+ #if _IS_EXT(81)
+ _WCASE(81);
+ #endif
+ #if _IS_EXT(82)
+ _WCASE(82);
+ #endif
+ #if _IS_EXT(83)
+ _WCASE(83);
+ #endif
+ #if _IS_EXT(84)
+ _WCASE(84);
+ #endif
+ #if _IS_EXT(85)
+ _WCASE(85);
+ #endif
+ #if _IS_EXT(86)
+ _WCASE(86);
+ #endif
+ #if _IS_EXT(87)
+ _WCASE(87);
+ #endif
+ #if _IS_EXT(88)
+ _WCASE(88);
+ #endif
+ #if _IS_EXT(89)
+ _WCASE(89);
+ #endif
+ #if _IS_EXT(90)
+ _WCASE(90);
+ #endif
+ #if _IS_EXT(91)
+ _WCASE(91);
+ #endif
+ #if _IS_EXT(92)
+ _WCASE(92);
+ #endif
+ #if _IS_EXT(93)
+ _WCASE(93);
+ #endif
+ #if _IS_EXT(94)
+ _WCASE(94);
+ #endif
+ #if _IS_EXT(95)
+ _WCASE(95);
+ #endif
+ #if _IS_EXT(96)
+ _WCASE(96);
+ #endif
+ #if _IS_EXT(97)
+ _WCASE(97);
+ #endif
+ #if _IS_EXT(98)
+ _WCASE(98);
+ #endif
+ #if _IS_EXT(99)
+ _WCASE(99);
+ #endif
+ #if _IS_EXT(100)
+ _WCASE(100);
+ #endif
+ }
+}
+
+uint8_t extDigitalRead(const int8_t pin) {
+ #define _RCASE(N) case N: return READ(N)
+ switch (pin) {
+ default: return digitalRead(pin);
+ #if _IS_EXT(70)
+ _RCASE(70);
+ #endif
+ #if _IS_EXT(71)
+ _RCASE(71);
+ #endif
+ #if _IS_EXT(72)
+ _RCASE(72);
+ #endif
+ #if _IS_EXT(73)
+ _RCASE(73);
+ #endif
+ #if _IS_EXT(74)
+ _RCASE(74);
+ #endif
+ #if _IS_EXT(75)
+ _RCASE(75);
+ #endif
+ #if _IS_EXT(76)
+ _RCASE(76);
+ #endif
+ #if _IS_EXT(77)
+ _RCASE(77);
+ #endif
+ #if _IS_EXT(78)
+ _RCASE(78);
+ #endif
+ #if _IS_EXT(79)
+ _RCASE(79);
+ #endif
+ #if _IS_EXT(80)
+ _RCASE(80);
+ #endif
+ #if _IS_EXT(81)
+ _RCASE(81);
+ #endif
+ #if _IS_EXT(82)
+ _RCASE(82);
+ #endif
+ #if _IS_EXT(83)
+ _RCASE(83);
+ #endif
+ #if _IS_EXT(84)
+ _RCASE(84);
+ #endif
+ #if _IS_EXT(85)
+ _RCASE(85);
+ #endif
+ #if _IS_EXT(86)
+ _RCASE(86);
+ #endif
+ #if _IS_EXT(87)
+ _RCASE(87);
+ #endif
+ #if _IS_EXT(88)
+ _RCASE(88);
+ #endif
+ #if _IS_EXT(89)
+ _RCASE(89);
+ #endif
+ #if _IS_EXT(90)
+ _RCASE(90);
+ #endif
+ #if _IS_EXT(91)
+ _RCASE(91);
+ #endif
+ #if _IS_EXT(92)
+ _RCASE(92);
+ #endif
+ #if _IS_EXT(93)
+ _RCASE(93);
+ #endif
+ #if _IS_EXT(94)
+ _RCASE(94);
+ #endif
+ #if _IS_EXT(95)
+ _RCASE(95);
+ #endif
+ #if _IS_EXT(96)
+ _RCASE(96);
+ #endif
+ #if _IS_EXT(97)
+ _RCASE(97);
+ #endif
+ #if _IS_EXT(98)
+ _RCASE(98);
+ #endif
+ #if _IS_EXT(99)
+ _RCASE(99);
+ #endif
+ #if _IS_EXT(100)
+ _RCASE(100);
+ #endif
+ }
+}
+
+#if 0
+/**
+ * Set Timer 5 PWM frequency in Hz, from 3.8Hz up to ~16MHz
+ * with a minimum resolution of 100 steps.
+ *
+ * DC values -1.0 to 1.0. Negative duty cycle inverts the pulse.
+ */
+uint16_t set_pwm_frequency_hz(const float &hz, const float dca, const float dcb, const float dcc) {
+ float count = 0;
+ if (hz > 0 && (dca || dcb || dcc)) {
+ count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
+ uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31)
+
+ if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); }
+ else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); }
+ else if (count >= 255. * 8.) { prescaler = 64; SET_CS(5, PRESCALER_64); }
+ else if (count >= 255.) { prescaler = 8; SET_CS(5, PRESCALER_8); }
+ else { prescaler = 1; SET_CS(5, PRESCALER_1); }
+
+ count /= float(prescaler);
+ 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
+ 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
+ _SET_COM(5, B, dcb ? (dcb < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL);
+ _SET_COM(5, C, dcc ? (dcc < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL);
+
+ SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP
+
+ //SERIAL_ECHOLNPGM("Timer 5 Settings:");
+ //SERIAL_ECHOLNPAIR(" Prescaler=", prescaler);
+ //SERIAL_ECHOLNPAIR(" TOP=", ICR5);
+ //SERIAL_ECHOLNPAIR(" OCR5A=", OCR5A);
+ //SERIAL_ECHOLNPAIR(" OCR5B=", OCR5B);
+ //SERIAL_ECHOLNPAIR(" OCR5C=", OCR5C);
+ }
+ else {
+ // Restore the default for Timer 5
+ SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct)
+ SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing
+ SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz
+ OCR5A = OCR5B = OCR5C = 0;
+ }
+ return round(count);
+}
+#endif
+
+#endif // FASTIO_EXT_START
+#endif // __AVR__