|
@@ -21,99 +21,135 @@
|
21
|
21
|
*/
|
22
|
22
|
|
23
|
23
|
/**
|
24
|
|
- This code contributed by Triffid_Hunter and modified by Kliment
|
25
|
|
- why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
26
|
|
-*/
|
|
24
|
+ * Contributed by Triffid_Hunter, modified by Kliment, extended by the Marlin team
|
|
25
|
+ * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
|
26
|
+ */
|
27
|
27
|
|
28
|
28
|
#ifndef _FASTIO_ARDUINO_H
|
29
|
29
|
#define _FASTIO_ARDUINO_H
|
30
|
30
|
|
31
|
31
|
#include <avr/io.h>
|
32
|
32
|
|
33
|
|
-/**
|
34
|
|
- utility functions
|
35
|
|
-*/
|
36
|
|
-
|
37
|
|
-#ifndef MASK
|
38
|
|
- #define MASK(PIN) (1 << PIN)
|
|
33
|
+#ifndef _BV
|
|
34
|
+ #define _BV(PIN) (1 << PIN)
|
39
|
35
|
#endif
|
40
|
36
|
|
41
|
37
|
/**
|
42
|
|
- magic I/O routines
|
43
|
|
- now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0);
|
44
|
|
-*/
|
|
38
|
+ * Magic I/O routines
|
|
39
|
+ *
|
|
40
|
+ * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
|
|
41
|
+ */
|
|
42
|
+
|
|
43
|
+#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))
|
45
|
44
|
|
46
|
|
-/// Read a pin
|
47
|
|
-#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN)))
|
48
|
|
-/// write to a pin
|
49
|
|
-// On some boards pins > 0x100 are used. These are not converted to atomic actions. An critical section is needed.
|
|
45
|
+// On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed.
|
50
|
46
|
|
51
|
|
-#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)
|
|
47
|
+#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)
|
52
|
48
|
|
53
|
49
|
#define _WRITE_C(IO, v) do { if (v) { \
|
54
|
50
|
CRITICAL_SECTION_START; \
|
55
|
|
- {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } \
|
|
51
|
+ {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \
|
56
|
52
|
CRITICAL_SECTION_END; \
|
57
|
53
|
} \
|
58
|
54
|
else { \
|
59
|
55
|
CRITICAL_SECTION_START; \
|
60
|
|
- {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); } \
|
|
56
|
+ {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \
|
61
|
57
|
CRITICAL_SECTION_END; \
|
62
|
58
|
} \
|
63
|
59
|
} \
|
64
|
60
|
while (0)
|
65
|
61
|
|
66
|
|
-#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
|
|
62
|
+#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
|
67
|
63
|
|
68
|
|
-/// toggle a pin
|
69
|
|
-#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= MASK(DIO ## IO ## _PIN); } while (0)
|
|
64
|
+#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0)
|
70
|
65
|
|
71
|
|
-/// set pin as input
|
72
|
|
-#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0)
|
73
|
|
-/// set pin as output
|
74
|
|
-#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0)
|
|
66
|
+#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0)
|
|
67
|
+#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0)
|
75
|
68
|
|
76
|
|
-/// check if pin is an input
|
77
|
|
-#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0)
|
78
|
|
-/// check if pin is an output
|
79
|
|
-#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0)
|
|
69
|
+#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0)
|
|
70
|
+#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0)
|
|
71
|
+#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
|
80
|
72
|
|
81
|
|
-/// check if pin is an timer
|
82
|
|
-#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
|
|
73
|
+#define READ(IO) _READ(IO)
|
|
74
|
+#define WRITE(IO,V) _WRITE(IO,V)
|
|
75
|
+#define TOGGLE(IO) _TOGGLE(IO)
|
83
|
76
|
|
84
|
|
-// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
85
|
|
-
|
86
|
|
-/// Read a pin wrapper
|
87
|
|
-#define READ(IO) _READ(IO)
|
88
|
|
-/// Write to a pin wrapper
|
89
|
|
-#define WRITE(IO, v) _WRITE(IO, v)
|
90
|
|
-
|
91
|
|
-/// toggle a pin wrapper
|
92
|
|
-#define TOGGLE(IO) _TOGGLE(IO)
|
93
|
|
-
|
94
|
|
-/// set pin as input wrapper
|
95
|
|
-#define SET_INPUT(IO) _SET_INPUT(IO)
|
96
|
|
-/// set pin as input with pullup wrapper
|
|
77
|
+#define SET_INPUT(IO) _SET_INPUT(IO)
|
97
|
78
|
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
|
98
|
|
-/// set pin as output wrapper
|
99
|
|
-#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
|
79
|
+#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
100
|
80
|
|
101
|
|
-/// check if pin is an input wrapper
|
102
|
|
-#define GET_INPUT(IO) _GET_INPUT(IO)
|
103
|
|
-/// check if pin is an output wrapper
|
104
|
|
-#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
|
|
81
|
+#define GET_INPUT(IO) _GET_INPUT(IO)
|
|
82
|
+#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
|
|
83
|
+#define GET_TIMER(IO) _GET_TIMER(IO)
|
105
|
84
|
|
106
|
|
-/// check if pin is an timer wrapper
|
107
|
|
-#define GET_TIMER(IO) _GET_TIMER(IO)
|
108
|
|
-
|
109
|
|
-// Shorthand
|
110
|
|
-#define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); }
|
|
85
|
+#define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0)
|
111
|
86
|
|
112
|
87
|
/**
|
113
|
|
- ports and functions
|
|
88
|
+ * Interrupt Control
|
|
89
|
+ */
|
114
|
90
|
|
115
|
|
- added as necessary or if I feel like it- not a comprehensive list!
|
116
|
|
-*/
|
|
91
|
+// Waveform Generation Modes
|
|
92
|
+typedef enum {
|
|
93
|
+ WGM_NORMAL, // 0
|
|
94
|
+ WGM_PWM_PC_8, // 1
|
|
95
|
+ WGM_PWM_PC_9, // 2
|
|
96
|
+ WGM_PWM_PC_10, // 3
|
|
97
|
+ WGM_CTC_OCRnA, // 4 COM OCnx
|
|
98
|
+ WGM_FAST_PWM_8, // 5
|
|
99
|
+ WGM_FAST_PWM_9, // 6
|
|
100
|
+ WGM_FAST_PWM_10, // 7
|
|
101
|
+ WGM_PWM_PC_FC_ICRn, // 8
|
|
102
|
+ WGM_PWM_PC_FC_OCRnA, // 9 COM OCnA
|
|
103
|
+ WGM_PWM_PC_ICRn, // 10
|
|
104
|
+ WGM_PWM_PC_OCRnA, // 11 COM OCnA
|
|
105
|
+ WGM_CTC_ICRn, // 12 COM OCnx
|
|
106
|
+ WGM_reserved, // 13
|
|
107
|
+ WGM_FAST_PWM_ICRn, // 14 COM OCnA
|
|
108
|
+ WGM_FAST_PWM_OCRnA // 15 COM OCnA
|
|
109
|
+} WaveGenMode;
|
|
110
|
+
|
|
111
|
+// Compare Modes
|
|
112
|
+typedef enum {
|
|
113
|
+ COM_NORMAL, // 0
|
|
114
|
+ COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
|
|
115
|
+ COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
|
|
116
|
+ COM_SET_CLEAR // 3 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
|
|
117
|
+} CompareMode;
|
|
118
|
+
|
|
119
|
+// Clock Sources
|
|
120
|
+typedef enum {
|
|
121
|
+ CS_NONE, // 0
|
|
122
|
+ CS_PRESCALER_1, // 1
|
|
123
|
+ CS_PRESCALER_8, // 2
|
|
124
|
+ CS_PRESCALER_64, // 3
|
|
125
|
+ CS_PRESCALER_256, // 4
|
|
126
|
+ CS_PRESCALER_1024, // 5
|
|
127
|
+ CS_EXT_FALLING, // 6
|
|
128
|
+ CS_EXT_RISING // 7
|
|
129
|
+} ClockSource;
|
|
130
|
+
|
|
131
|
+#define SET_WGM(T,V) do{ \
|
|
132
|
+ TCCR##T##A = (TCCR##T##A & ~(0x3 << WGM##T##0)) | (( int(V) & 0x3) << WGM##T##0); \
|
|
133
|
+ TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
|
|
134
|
+ }while(0)
|
|
135
|
+
|
|
136
|
+#define SET_CS(T,V) do{ \
|
|
137
|
+ TCCR##T##B = (TCCR##T##B & ~(0x7 << CS10)) | ((int(V) & 0x7) << CS10); \
|
|
138
|
+ }while(0)
|
|
139
|
+
|
|
140
|
+#define SET_COM(T,Q,V) do{ \
|
|
141
|
+ TCCR##T##Q = (TCCR##T##Q & !(0x3 << COM1##Q##0) | (int(V) & 0x3) << COM1##Q##0); \
|
|
142
|
+ }while(0)
|
|
143
|
+#define SET_COMA(T,V) SET_COM(T,A,V)
|
|
144
|
+#define SET_COMB(T,V) SET_COM(T,B,V)
|
|
145
|
+#define SET_COMS(T,V1,V2) do{ SET_COMA(T,V1); SET_COMB(T,V2); }while(0)
|
|
146
|
+
|
|
147
|
+#define SET_ICNC(T,V) (TCCR##T##B = (TCCR##T##B & ~_BV(7) | ((V) & 1) << 7))
|
|
148
|
+#define SET_ICES(T,V) (TCCR##T##B = (TCCR##T##B & ~_BV(6) | ((V) & 1) << 6))
|
|
149
|
+
|
|
150
|
+/**
|
|
151
|
+ * Ports and Functions
|
|
152
|
+ */
|
117
|
153
|
|
118
|
154
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
|
119
|
155
|
// UART
|
|
@@ -446,7 +482,7 @@
|
446
|
482
|
#define PD7_WPORT PORTD
|
447
|
483
|
#define PD7_DDR DDRD
|
448
|
484
|
#define PD7_PWM NULL
|
449
|
|
-#endif /* _AVR_ATmega{168,328,328P}__ */
|
|
485
|
+#endif // __AVR_ATmega(168|328|328P)__
|
450
|
486
|
|
451
|
487
|
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
|
452
|
488
|
// UART
|
|
@@ -949,7 +985,7 @@
|
949
|
985
|
#define PD7_WPORT PORTD
|
950
|
986
|
#define PD7_DDR DDRD
|
951
|
987
|
#define PD7_PWM OCR2A
|
952
|
|
-#endif /* _AVR_ATmega{644,644P,644PA}__ */
|
|
988
|
+#endif // __AVR_ATmega(644|644P|644PA)__
|
953
|
989
|
|
954
|
990
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
955
|
991
|
// UART
|
|
@@ -2031,8 +2067,7 @@
|
2031
|
2067
|
#define PL7_WPORT PORTL
|
2032
|
2068
|
#define PL7_DDR DDRL
|
2033
|
2069
|
#define PL7_PWM NULL
|
2034
|
|
-
|
2035
|
|
-#endif
|
|
2070
|
+#endif // __AVR_ATmega(1280|2560)__
|
2036
|
2071
|
|
2037
|
2072
|
#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
|
2038
|
2073
|
|
|
@@ -2040,8 +2075,8 @@
|
2040
|
2075
|
#define DEBUG_LED DIO31 /* led D5 red */
|
2041
|
2076
|
|
2042
|
2077
|
/**
|
2043
|
|
- pins
|
2044
|
|
- */
|
|
2078
|
+ * pins
|
|
2079
|
+ */
|
2045
|
2080
|
|
2046
|
2081
|
//#define AT90USBxx_TEENSYPP_ASSIGNMENTS // Use Teensy++ 2.0 assignments
|
2047
|
2082
|
#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // Use traditional Marlin pin assignments
|
|
@@ -3335,8 +3370,7 @@
|
3335
|
3370
|
#define PF7_DDR DDRF
|
3336
|
3371
|
|
3337
|
3372
|
#endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments
|
3338
|
|
-#endif // __AVR_AT90usbxxx__
|
3339
|
|
-
|
|
3373
|
+#endif // __AVR_AT90USB(1287|1286|646|647)__
|
3340
|
3374
|
|
3341
|
3375
|
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
3342
|
3376
|
// UART
|
|
@@ -4027,12 +4061,10 @@
|
4027
|
4061
|
#define PG5_WPORT PORTG
|
4028
|
4062
|
#define PG5_DDR DDRG
|
4029
|
4063
|
#define PG5_PWM &OCR0B
|
4030
|
|
-
|
4031
|
|
-
|
4032
|
|
-#endif
|
|
4064
|
+#endif // __AVR_ATmega(1281|2561)__
|
4033
|
4065
|
|
4034
|
4066
|
#ifndef DIO0_PIN
|
4035
|
4067
|
#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"
|
4036
|
4068
|
#endif
|
4037
|
4069
|
|
4038
|
|
-#endif /* _FASTIO_ARDUINO_H */
|
|
4070
|
+#endif // _FASTIO_ARDUINO_H
|