Subversion Repositories Tronxy-X3A-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 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
/**
24
 * Fast I/O Routines for AVR
25
 * Use direct port manipulation to save scads of processor time.
26
 * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al.
27
 */
28
 
29
#include <stdint.h>
30
 
31
#ifndef _FASTIO_ARDUINO_H_
32
#define _FASTIO_ARDUINO_H_
33
 
34
#include <avr/io.h>
35
 
36
#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__)  || defined(__AVR_AT90USB647__))
37
#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
38
#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
39
#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
40
#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
41
 
42
/**
43
 * Include Ports and Functions
44
 */
45
#if AVR_ATmega328_FAMILY
46
  #include "fastio_168.h"
47
#elif AVR_ATmega1284_FAMILY
48
  #include "fastio_644.h"
49
#elif AVR_ATmega2560_FAMILY
50
  #include "fastio_1280.h"
51
#elif AVR_AT90USB1286_FAMILY
52
  #include "fastio_AT90USB.h"
53
#elif AVR_ATmega2561_FAMILY
54
  #include "fastio_1281.h"
55
#else
56
  #error "No FastIO definition for the selected AVR Board."
57
#endif
58
 
59
#include "macros.h"
60
 
61
/**
62
 * Magic I/O routines
63
 *
64
 * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
65
 *
66
 * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
67
 */
68
 
69
#define _READ(IO)             TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN)
70
 
71
#define _WRITE_NC(IO,V) do{ \
72
  if (V) SBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \
73
  else   CBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \
74
}while(0)
75
 
76
#define _WRITE_C(IO,V) do{ \
77
  uint8_t port_bits = DIO ## IO ## _WPORT;                  /* Get a mask from the current port bits */ \
78
  if (V) port_bits = ~port_bits;                            /* For setting bits, invert the mask */ \
79
  DIO ## IO ## _RPORT = port_bits & _BV(DIO ## IO ## _PIN); /* Atomically toggle the output port bits */ \
80
}while(0)
81
 
82
#define _WRITE(IO,V)          do{ if (&(DIO ## IO ## _RPORT) < (uint8_t*)0x100) _WRITE_NC(IO,V); else _WRITE_C(IO,V); }while(0)
83
 
84
#define _TOGGLE(IO)           (DIO ## IO ## _RPORT = _BV(DIO ## IO ## _PIN))
85
 
86
#define _SET_INPUT(IO)        CBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
87
#define _SET_OUTPUT(IO)       SBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
88
 
89
#define _GET_INPUT(IO)       !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
90
#define _GET_OUTPUT(IO)       TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
91
#define _GET_TIMER(IO)        DIO ## IO ## _PWM
92
 
93
#define READ(IO)              _READ(IO)
94
#define WRITE(IO,V)           _WRITE(IO,V)
95
#define TOGGLE(IO)            _TOGGLE(IO)
96
 
97
#define SET_INPUT(IO)         _SET_INPUT(IO)
98
#define SET_INPUT_PULLUP(IO)  do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
99
#define SET_OUTPUT(IO)        _SET_OUTPUT(IO)
100
 
101
#define GET_INPUT(IO)         _GET_INPUT(IO)
102
#define GET_OUTPUT(IO)        _GET_OUTPUT(IO)
103
#define GET_TIMER(IO)         _GET_TIMER(IO)
104
 
105
#define OUT_WRITE(IO,V)       do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
106
 
107
/**
108
 * Timer and Interrupt Control
109
 */
110
 
111
// Waveform Generation Modes
112
enum WaveGenMode : char {
113
  WGM_NORMAL,          //  0
114
  WGM_PWM_PC_8,        //  1
115
  WGM_PWM_PC_9,        //  2
116
  WGM_PWM_PC_10,       //  3
117
  WGM_CTC_OCRnA,       //  4  COM OCnx
118
  WGM_FAST_PWM_8,      //  5
119
  WGM_FAST_PWM_9,      //  6
120
  WGM_FAST_PWM_10,     //  7
121
  WGM_PWM_PC_FC_ICRn,  //  8
122
  WGM_PWM_PC_FC_OCRnA, //  9  COM OCnA
123
  WGM_PWM_PC_ICRn,     // 10
124
  WGM_PWM_PC_OCRnA,    // 11  COM OCnA
125
  WGM_CTC_ICRn,        // 12  COM OCnx
126
  WGM_reserved,        // 13
127
  WGM_FAST_PWM_ICRn,   // 14  COM OCnA
128
  WGM_FAST_PWM_OCRnA   // 15  COM OCnA
129
};
130
 
131
// Compare Modes
132
enum CompareMode : char {
133
  COM_NORMAL,          //  0
134
  COM_TOGGLE,          //  1  Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
135
  COM_CLEAR_SET,       //  2  Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
136
  COM_SET_CLEAR        //  3  Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
137
};
138
 
139
// Clock Sources
140
enum ClockSource : char {
141
  CS_NONE,             //  0
142
  CS_PRESCALER_1,      //  1
143
  CS_PRESCALER_8,      //  2
144
  CS_PRESCALER_64,     //  3
145
  CS_PRESCALER_256,    //  4
146
  CS_PRESCALER_1024,   //  5
147
  CS_EXT_FALLING,      //  6
148
  CS_EXT_RISING        //  7
149
};
150
 
151
// Clock Sources (Timer 2 only)
152
enum ClockSource2 : char {
153
  CS2_NONE,            //  0
154
  CS2_PRESCALER_1,     //  1
155
  CS2_PRESCALER_8,     //  2
156
  CS2_PRESCALER_32,    //  3
157
  CS2_PRESCALER_64,    //  4
158
  CS2_PRESCALER_128,   //  5
159
  CS2_PRESCALER_256,   //  6
160
  CS2_PRESCALER_1024   //  7
161
};
162
 
163
// Get interrupt bits in an orderly way
164
// Ex: cs = GET_CS(0); coma1 = GET_COM(A,1);
165
#define GET_WGM(T)   (((TCCR##T##A >> WGM##T##0) & 0x3) | ((TCCR##T##B >> WGM##T##2 << 2) & 0xC))
166
#define GET_CS(T)    ((TCCR##T##B >> CS##T##0) & 0x7)
167
#define GET_COM(T,Q) ((TCCR##T##Q >> COM##T##Q##0) & 0x3)
168
#define GET_COMA(T)  GET_COM(T,A)
169
#define GET_COMB(T)  GET_COM(T,B)
170
#define GET_COMC(T)  GET_COM(T,C)
171
#define GET_ICNC(T)  (!!(TCCR##T##B & _BV(ICNC##T)))
172
#define GET_ICES(T)  (!!(TCCR##T##B & _BV(ICES##T)))
173
#define GET_FOC(T,Q) (!!(TCCR##T##C & _BV(FOC##T##Q)))
174
#define GET_FOCA(T)  GET_FOC(T,A)
175
#define GET_FOCB(T)  GET_FOC(T,B)
176
#define GET_FOCC(T)  GET_FOC(T,C)
177
 
178
// Set Wave Generation Mode bits
179
// Ex: SET_WGM(5,CTC_ICRn);
180
#define _SET_WGM(T,V) do{ \
181
    TCCR##T##A = (TCCR##T##A & ~(0x3 << WGM##T##0)) | (( int(V)       & 0x3) << WGM##T##0); \
182
    TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
183
  }while(0)
184
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
185
 
186
// Set Clock Select bits
187
// Ex: SET_CS3(PRESCALER_64);
188
#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0))
189
#define _SET_CS0(V) _SET_CS(0,V)
190
#define _SET_CS1(V) _SET_CS(1,V)
191
#ifdef TCCR2
192
  #define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
193
#else
194
  #define _SET_CS2(V) _SET_CS(2,V)
195
#endif
196
#define _SET_CS3(V) _SET_CS(3,V)
197
#define _SET_CS4(V) _SET_CS(4,V)
198
#define _SET_CS5(V) _SET_CS(5,V)
199
#define SET_CS0(V) _SET_CS0(CS_##V)
200
#define SET_CS1(V) _SET_CS1(CS_##V)
201
#ifdef TCCR2
202
  #define SET_CS2(V) _SET_CS2(CS2_##V)
203
#else
204
  #define SET_CS2(V) _SET_CS2(CS_##V)
205
#endif
206
#define SET_CS3(V) _SET_CS3(CS_##V)
207
#define SET_CS4(V) _SET_CS4(CS_##V)
208
#define SET_CS5(V) _SET_CS5(CS_##V)
209
#define SET_CS(T,V) SET_CS##T(V)
210
 
211
// Set Compare Mode bits
212
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
213
#define _SET_COM(T,Q,V) (TCCR##T##Q = (TCCR##T##Q & ~(0x3 << COM##T##Q##0)) | (int(V) << COM##T##Q##0))
214
#define SET_COM(T,Q,V) _SET_COM(T,Q,COM_##V)
215
#define SET_COMA(T,V) SET_COM(T,A,V)
216
#define SET_COMB(T,V) SET_COM(T,B,V)
217
#define SET_COMC(T,V) SET_COM(T,C,V)
218
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
219
 
220
// Set Noise Canceler bit
221
// Ex: SET_ICNC(2,1)
222
#define SET_ICNC(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICNC##T) : TCCR##T##B & ~_BV(ICNC##T))
223
 
224
// Set Input Capture Edge Select bit
225
// Ex: SET_ICES(5,0)
226
#define SET_ICES(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICES##T) : TCCR##T##B & ~_BV(ICES##T))
227
 
228
// Set Force Output Compare bit
229
// Ex: SET_FOC(3,A,1)
230
#define SET_FOC(T,Q,V) (TCCR##T##C = (V) ? TCCR##T##C | _BV(FOC##T##Q) : TCCR##T##C & ~_BV(FOC##T##Q))
231
#define SET_FOCA(T,V) SET_FOC(T,A,V)
232
#define SET_FOCB(T,V) SET_FOC(T,B,V)
233
#define SET_FOCC(T,V) SET_FOC(T,C,V)
234
 
235
 
236
/**
237
 * PWM availability macros
238
 */
239
 
240
// Determine which harware PWMs are already in use
241
#if PIN_EXISTS(CONTROLLER_FAN)
242
  #define PWM_CHK_FAN_B(p) (p == CONTROLLER_FAN_PIN || p == E0_AUTO_FAN_PIN || p ==  E1_AUTO_FAN_PIN || p ==  E2_AUTO_FAN_PIN || p ==  E3_AUTO_FAN_PIN || p ==  E4_AUTO_FAN_PIN || p == CHAMBER_AUTO_FAN_PIN)
243
#else
244
  #define PWM_CHK_FAN_B(p) (p == E0_AUTO_FAN_PIN || p ==  E1_AUTO_FAN_PIN || p ==  E2_AUTO_FAN_PIN || p ==  E3_AUTO_FAN_PIN || p ==  E4_AUTO_FAN_PIN || p == CHAMBER_AUTO_FAN_PIN)
245
#endif
246
 
247
#if PIN_EXISTS(FAN) || PIN_EXISTS(FAN1) || PIN_EXISTS(FAN2)
248
  #if PIN_EXISTS(FAN2)
249
    #define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN || p == FAN2_PIN)
250
  #elif PIN_EXISTS(FAN1)
251
    #define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN)
252
  #else
253
    #define PWM_CHK_FAN_A(p) (p == FAN_PIN)
254
  #endif
255
#else
256
  #define PWM_CHK_FAN_A(p) false
257
#endif
258
 
259
#if HAS_MOTOR_CURRENT_PWM
260
  #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
261
    #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z || p == MOTOR_CURRENT_PWM_XY)
262
  #elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
263
    #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z)
264
  #else
265
    #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E)
266
  #endif
267
#else
268
  #define PWM_CHK_MOTOR_CURRENT(p) false
269
#endif
270
 
271
#ifdef NUM_SERVOS
272
  #if AVR_ATmega2560_FAMILY
273
    #define PWM_CHK_SERVO(p) (p == 5 || (NUM_SERVOS > 12 && p == 6) || (NUM_SERVOS > 24 && p == 46))  // PWMS 3A, 4A & 5A
274
  #elif AVR_ATmega2561_FAMILY
275
    #define PWM_CHK_SERVO(p)   (p == 5)  // PWM3A
276
  #elif AVR_ATmega1284_FAMILY
277
    #define PWM_CHK_SERVO(p)   false
278
  #elif AVR_AT90USB1286_FAMILY
279
    #define PWM_CHK_SERVO(p)   (p == 16) // PWM3A
280
  #elif AVR_ATmega328_FAMILY
281
    #define PWM_CHK_SERVO(p)   false
282
  #endif
283
#else
284
  #define PWM_CHK_SERVO(p) false
285
#endif
286
 
287
#if ENABLED(BARICUDA)
288
  #if HAS_HEATER_1 && HAS_HEATER_2
289
    #define PWM_CHK_HEATER(p) (p == HEATER_1_PIN || p == HEATER_2_PIN)
290
  #elif HAS_HEATER_1
291
    #define PWM_CHK_HEATER(p) (p == HEATER_1_PIN)
292
  #endif
293
#else
294
    #define PWM_CHK_HEATER(p) false
295
#endif
296
 
297
#define PWM_CHK(p) (PWM_CHK_HEATER(p) || PWM_CHK_SERVO(p)  || PWM_CHK_MOTOR_CURRENT(p)\
298
                     || PWM_CHK_FAN_A(p) || PWM_CHK_FAN_B(p))
299
 
300
// define which hardware PWMs are available for the current CPU
301
// all timer 1 PWMS deleted from this list because they are never available
302
#if AVR_ATmega2560_FAMILY
303
  #define PWM_PINS(p)  ((p >= 2 && p <= 10) || p == 13 || p == 44 || p == 45 || p == 46)
304
#elif AVR_ATmega2561_FAMILY
305
  #define PWM_PINS(p)  ((p >= 2 && p <= 6) || p == 9)
306
#elif AVR_ATmega1284_FAMILY
307
  #define PWM_PINS(p)  (p == 3 || p == 4 || p == 14 || p == 15)
308
#elif AVR_AT90USB1286_FAMILY
309
  #define PWM_PINS(p)  (p == 0 || p == 1 || p == 14 || p == 15 || p == 16 || p == 24)
310
#elif AVR_ATmega328_FAMILY
311
  #define PWM_PINS(p)  (p == 3 || p == 5 || p == 6 || p == 11)
312
#else
313
  #error "unknown CPU"
314
#endif
315
 
316
// finally - the macro that tells us if a pin is an available hardware PWM
317
#define USEABLE_HARDWARE_PWM(p) (PWM_PINS(p) && !PWM_CHK(p))
318
 
319
#endif // _FASTIO_ARDUINO_H_