289 lines
6.5 KiB
C++
289 lines
6.5 KiB
C++
/**
|
|
* 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__
|