diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 4f6b31a703dc40d18292f9b75a30716eef0769b7..8db285174ccdfb05269e867d74ccda73c3b91029 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -5858,10 +5858,6 @@ inline void gcode_M42() {
#else
- #if !defined(z_servo_angle)
- const int z_servo_angle[2] = Z_SERVO_ANGLES;
- #endif
-
const uint8_t probe_index = code_seen('P') ? code_value_byte() : Z_ENDSTOP_SERVO_NR;
SERIAL_PROTOCOLLNPGM("Servo probe test");
@@ -11528,15 +11524,13 @@ void prepare_move_to_destination() {
#ifdef TCCR0A
case TIMER0A:
case TIMER0B:
- // TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02));
- // TCCR0B |= val;
+ //SET_CS(0, val);
break;
#endif
#ifdef TCCR1A
case TIMER1A:
case TIMER1B:
- // TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
- // TCCR1B |= val;
+ //SET_CS(1, val);
break;
#endif
#ifdef TCCR2
@@ -11549,32 +11543,28 @@ void prepare_move_to_destination() {
#ifdef TCCR2A
case TIMER2A:
case TIMER2B:
- TCCR2B &= ~(_BV(CS20) | _BV(CS21) | _BV(CS22));
- TCCR2B |= val;
+ SET_CS(2, val);
break;
#endif
#ifdef TCCR3A
case TIMER3A:
case TIMER3B:
case TIMER3C:
- TCCR3B &= ~(_BV(CS30) | _BV(CS31) | _BV(CS32));
- TCCR3B |= val;
+ SET_CS(3, val);
break;
#endif
#ifdef TCCR4A
case TIMER4A:
case TIMER4B:
case TIMER4C:
- TCCR4B &= ~(_BV(CS40) | _BV(CS41) | _BV(CS42));
- TCCR4B |= val;
+ SET_CS(4, val);
break;
#endif
#ifdef TCCR5A
case TIMER5A:
case TIMER5B:
case TIMER5C:
- TCCR5B &= ~(_BV(CS50) | _BV(CS51) | _BV(CS52));
- TCCR5B |= val;
+ SET_CS(5, val);
break;
#endif
}
diff --git a/Marlin/fastio.h b/Marlin/fastio.h
index 6cc2e85a72bb439a8bca9f5bdcd21475887fff3d..0e73a394838b914c7de2e21d1b7d806622518f1d 100644
--- a/Marlin/fastio.h
+++ b/Marlin/fastio.h
@@ -21,99 +21,135 @@
*/
/**
- This code contributed by Triffid_Hunter and modified by Kliment
- why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
-*/
+ * Contributed by Triffid_Hunter, modified by Kliment, extended by the Marlin team
+ * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
+ */
#ifndef _FASTIO_ARDUINO_H
#define _FASTIO_ARDUINO_H
#include <avr/io.h>
-/**
- utility functions
-*/
-
-#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+#ifndef _BV
+ #define _BV(PIN) (1 << PIN)
#endif
/**
- magic I/O routines
- now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0);
-*/
+ * Magic I/O routines
+ *
+ * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
+ */
+
+#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))
-/// Read a pin
-#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN)))
-/// write to a pin
-// On some boards pins > 0x100 are used. These are not converted to atomic actions. An critical section is needed.
+// On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed.
-#define _WRITE_NC(IO, v) do { if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); }; } while (0)
+#define _WRITE_NC(IO, v) do { if (v) {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); }; } while (0)
#define _WRITE_C(IO, v) do { if (v) { \
CRITICAL_SECTION_START; \
- {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } \
+ {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \
CRITICAL_SECTION_END; \
} \
else { \
CRITICAL_SECTION_START; \
- {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); } \
+ {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \
CRITICAL_SECTION_END; \
} \
} \
while (0)
-#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
+#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
-/// toggle a pin
-#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= MASK(DIO ## IO ## _PIN); } while (0)
+#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0)
-/// set pin as input
-#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0)
-/// set pin as output
-#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0)
+#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0)
+#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0)
-/// check if pin is an input
-#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0)
-/// check if pin is an output
-#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0)
+#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0)
+#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0)
+#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
-/// check if pin is an timer
-#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
+#define READ(IO) _READ(IO)
+#define WRITE(IO,V) _WRITE(IO,V)
+#define TOGGLE(IO) _TOGGLE(IO)
-// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
-
-/// Read a pin wrapper
-#define READ(IO) _READ(IO)
-/// Write to a pin wrapper
-#define WRITE(IO, v) _WRITE(IO, v)
-
-/// toggle a pin wrapper
-#define TOGGLE(IO) _TOGGLE(IO)
-
-/// set pin as input wrapper
-#define SET_INPUT(IO) _SET_INPUT(IO)
-/// set pin as input with pullup wrapper
+#define SET_INPUT(IO) _SET_INPUT(IO)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
-/// set pin as output wrapper
-#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
+#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
-/// check if pin is an input wrapper
-#define GET_INPUT(IO) _GET_INPUT(IO)
-/// check if pin is an output wrapper
-#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
+#define GET_INPUT(IO) _GET_INPUT(IO)
+#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
+#define GET_TIMER(IO) _GET_TIMER(IO)
-/// check if pin is an timer wrapper
-#define GET_TIMER(IO) _GET_TIMER(IO)
-
-// Shorthand
-#define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); }
+#define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0)
/**
- ports and functions
+ * Interrupt Control
+ */
- added as necessary or if I feel like it- not a comprehensive list!
-*/
+// Waveform Generation Modes
+typedef enum {
+ WGM_NORMAL, // 0
+ WGM_PWM_PC_8, // 1
+ WGM_PWM_PC_9, // 2
+ WGM_PWM_PC_10, // 3
+ WGM_CTC_OCRnA, // 4 COM OCnx
+ WGM_FAST_PWM_8, // 5
+ WGM_FAST_PWM_9, // 6
+ WGM_FAST_PWM_10, // 7
+ WGM_PWM_PC_FC_ICRn, // 8
+ WGM_PWM_PC_FC_OCRnA, // 9 COM OCnA
+ WGM_PWM_PC_ICRn, // 10
+ WGM_PWM_PC_OCRnA, // 11 COM OCnA
+ WGM_CTC_ICRn, // 12 COM OCnx
+ WGM_reserved, // 13
+ WGM_FAST_PWM_ICRn, // 14 COM OCnA
+ WGM_FAST_PWM_OCRnA // 15 COM OCnA
+} WaveGenMode;
+
+// Compare Modes
+typedef enum {
+ COM_NORMAL, // 0
+ COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
+ COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
+ COM_SET_CLEAR // 3 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
+} CompareMode;
+
+// Clock Sources
+typedef enum {
+ CS_NONE, // 0
+ CS_PRESCALER_1, // 1
+ CS_PRESCALER_8, // 2
+ CS_PRESCALER_64, // 3
+ CS_PRESCALER_256, // 4
+ CS_PRESCALER_1024, // 5
+ CS_EXT_FALLING, // 6
+ CS_EXT_RISING // 7
+} ClockSource;
+
+#define SET_WGM(T,V) do{ \
+ TCCR##T##A = (TCCR##T##A & ~(0x3 << WGM##T##0)) | (( int(V) & 0x3) << WGM##T##0); \
+ TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
+ }while(0)
+
+#define SET_CS(T,V) do{ \
+ TCCR##T##B = (TCCR##T##B & ~(0x7 << CS10)) | ((int(V) & 0x7) << CS10); \
+ }while(0)
+
+#define SET_COM(T,Q,V) do{ \
+ TCCR##T##Q = (TCCR##T##Q & !(0x3 << COM1##Q##0) | (int(V) & 0x3) << COM1##Q##0); \
+ }while(0)
+#define SET_COMA(T,V) SET_COM(T,A,V)
+#define SET_COMB(T,V) SET_COM(T,B,V)
+#define SET_COMS(T,V1,V2) do{ SET_COMA(T,V1); SET_COMB(T,V2); }while(0)
+
+#define SET_ICNC(T,V) (TCCR##T##B = (TCCR##T##B & ~_BV(7) | ((V) & 1) << 7))
+#define SET_ICES(T,V) (TCCR##T##B = (TCCR##T##B & ~_BV(6) | ((V) & 1) << 6))
+
+/**
+ * Ports and Functions
+ */
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
// UART
@@ -446,7 +482,7 @@
#define PD7_WPORT PORTD
#define PD7_DDR DDRD
#define PD7_PWM NULL
-#endif /* _AVR_ATmega{168,328,328P}__ */
+#endif // __AVR_ATmega(168|328|328P)__
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
// UART
@@ -949,7 +985,7 @@
#define PD7_WPORT PORTD
#define PD7_DDR DDRD
#define PD7_PWM OCR2A
-#endif /* _AVR_ATmega{644,644P,644PA}__ */
+#endif // __AVR_ATmega(644|644P|644PA)__
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// UART
@@ -2031,8 +2067,7 @@
#define PL7_WPORT PORTL
#define PL7_DDR DDRL
#define PL7_PWM NULL
-
-#endif
+#endif // __AVR_ATmega(1280|2560)__
#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
@@ -2040,8 +2075,8 @@
#define DEBUG_LED DIO31 /* led D5 red */
/**
- pins
- */
+ * pins
+ */
//#define AT90USBxx_TEENSYPP_ASSIGNMENTS // Use Teensy++ 2.0 assignments
#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // Use traditional Marlin pin assignments
@@ -3335,8 +3370,7 @@
#define PF7_DDR DDRF
#endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments
-#endif // __AVR_AT90usbxxx__
-
+#endif // __AVR_AT90USB(1287|1286|646|647)__
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
// UART
@@ -4027,12 +4061,10 @@
#define PG5_WPORT PORTG
#define PG5_DDR DDRG
#define PG5_PWM &OCR0B
-
-
-#endif
+#endif // __AVR_ATmega(1281|2561)__
#ifndef DIO0_PIN
#error "pins for this chip not defined in arduino.h! If you write an appropriate pin definition and have this firmware work on your chip, please submit a pull request"
#endif
-#endif /* _FASTIO_ARDUINO_H */
+#endif // _FASTIO_ARDUINO_H
diff --git a/Marlin/servo.cpp b/Marlin/servo.cpp
index 5be9441e44c58674d66559c015b45c7edebe5d4c..bfe24c8b6db181755ce964cd2b0820403a99bc67 100644
--- a/Marlin/servo.cpp
+++ b/Marlin/servo.cpp
@@ -168,8 +168,8 @@ static void initISR(timer16_Sequence_t timer) {
SBI(TIFR, OCF3A); // clear any pending interrupts;
SBI(ETIMSK, OCIE3A); // enable the output compare interrupt
#else
- TIFR3 = _BV(OCF3A); // clear any pending interrupts;
- TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt
+ SBI(TIFR3, OCF3A); // clear any pending interrupts;
+ SBI(TIMSK3, OCIE3A); // enable the output compare interrupt
#endif
#ifdef WIRING
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
@@ -183,7 +183,7 @@ static void initISR(timer16_Sequence_t timer) {
TCCR4B = _BV(CS41); // set prescaler of 8
TCNT4 = 0; // clear the timer count
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
- TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt
+ TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
}
#endif
@@ -193,7 +193,7 @@ static void initISR(timer16_Sequence_t timer) {
TCCR5B = _BV(CS51); // set prescaler of 8
TCNT5 = 0; // clear the timer count
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
- TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt
+ TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
}
#endif
}
@@ -203,21 +203,21 @@ static void finISR(timer16_Sequence_t timer) {
#ifdef WIRING
if (timer == _timer1) {
CBI(
- #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
- TIMSK1
- #else
- TIMSK
- #endif
+ #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
+ TIMSK1
+ #else
+ TIMSK
+ #endif
, OCIE1A); // disable timer 1 output compare interrupt
timerDetach(TIMER1OUTCOMPAREA_INT);
}
else if (timer == _timer3) {
CBI(
- #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
- TIMSK3
- #else
- ETIMSK
- #endif
+ #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
+ TIMSK3
+ #else
+ ETIMSK
+ #endif
, OCIE3A); // disable the timer3 output compare A interrupt
timerDetach(TIMER3OUTCOMPAREA_INT);
}
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 11d20251f3e0a3d0f227ce0342fd4e43ab7b9748..ed36a3124a51934d1c1b7428793cc70f34424324 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -271,7 +271,7 @@ volatile long Stepper::endstops_trigsteps[XYZ];
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
*/
void Stepper::wake_up() {
- // TCNT1 = 0;
+ // TCNT1 = 0;
ENABLE_STEPPER_DRIVER_INTERRUPT();
}
@@ -1081,21 +1081,17 @@ void Stepper::init() {
#endif
// waveform generation = 0100 = CTC
- CBI(TCCR1B, WGM13);
- SBI(TCCR1B, WGM12);
- CBI(TCCR1A, WGM11);
- CBI(TCCR1A, WGM10);
+ SET_WGM(1, WGM_CTC_OCRnA);
// output mode = 00 (disconnected)
- TCCR1A &= ~(3 << COM1A0);
- TCCR1A &= ~(3 << COM1B0);
+ SET_COMS(1, COM_NORMAL, COM_NORMAL);
// Set the timer pre-scaler
// Generally we use a divider of 8, resulting in a 2MHz timer
// frequency on a 16MHz MCU. If you are going to change this, be
// sure to regenerate speed_lookuptable.h with
// create_speed_lookuptable.py
- TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10);
+ SET_CS(1, CS_PRESCALER_8); // CS 2 = 1/8 prescaler
// Init Stepper ISR to 122 Hz for quick starting
OCR1A = 0x4000;
diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h
index 69272f98f2f75c61409fd8b9fc06fbee0cb8195b..3aa977596959b7d2c2f907b667d6e33c093863ec 100644
--- a/Marlin/ultralcd_impl_DOGM.h
+++ b/Marlin/ultralcd_impl_DOGM.h
@@ -791,7 +791,7 @@ static void lcd_implementation_status_screen() {
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj);
- DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(long, long5, ftostr5rj);
+ DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(unsigned long, long5, ftostr5rj);
#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index 9b0258862c79aa1a102f085abade16fcc176b813..26ef5d0059f63fa96dba92901b5909021b565f99 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -894,7 +894,7 @@ static void lcd_implementation_status_screen() {
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj);
- DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(long, long5, ftostr5rj);
+ DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(unsigned long, long5, ftostr5rj);
#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))