/ Repetier / Reptier.h
Reptier.h
  1  /*
  2      This file is part of Repetier-Firmware.
  3  
  4      Repetier-Firmware is free software: you can redistribute it and/or modify
  5      it under the terms of the GNU General Public License as published by
  6      the Free Software Foundation, either version 3 of the License, or
  7      (at your option) any later version.
  8  
  9      Repetier-Firmware is distributed in the hope that it will be useful,
 10      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12      GNU General Public License for more details.
 13  
 14      You should have received a copy of the GNU General Public License
 15      along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 16  
 17      This firmware is a nearly complete rewrite of the sprinter firmware
 18      by kliment (https://github.com/kliment/Sprinter)
 19      which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
 20  */
 21  
 22  #ifndef _REPETIER_H
 23  #define _REPETIER_H
 24  
 25  #include <avr/io.h>
 26  
 27  #define REPETIER_VERSION "0.80"
 28  
 29  // ##########################################################################################
 30  // ##                                  Debug configuration                                 ##
 31  // ##########################################################################################
 32  
 33  /** Uncomment, to see detailed data for every move. Only for debugging purposes! */
 34  //#define DEBUG_QUEUE_MOVE
 35  /** Allows M111 to set bit 5 (16) which disables all commands except M111. This can be used
 36  to test your data througput or search for communication problems. */
 37  #define INCLUDE_DEBUG_COMMUNICATION
 38  /** Allows M111 so set bit 6 (32) which disables moves, at the first tried step. In combination
 39  with a dry run, you can test the speed of path computations, which are still performed. */
 40  //#define INCLUDE_DEBUG_NO_MOVE
 41  /** Writes the free RAM to output, if it is less then at the last test. Should always return
 42  values >500 for safety, since it doesn't catch every function call. Nice to tweak cache
 43  usage or for seraching for memory induced errors. Switch it off for production, it costs execution time. */
 44  //#define DEBUG_FREE_MEMORY
 45  //#define DEBUG_ADVANCE
 46  /** \brief print ops related debug info. */
 47  //#define DEBUG_OPS
 48  /** If enabled, writes the created generic table to serial port at startup. */
 49  //#define DEBUG_GENERIC
 50  /** If enabled, steps to move and moved steps are compared. */
 51  //#define DEBUG_STEPCOUNT
 52  // Uncomment the following line to enable debugging. You can better control debugging below the following line
 53  //#define DEBUG
 54  
 55  
 56  // Uncomment if no analyzer is connected
 57  //#define ANALYZER
 58  // Channel->pin assignments
 59  #define ANALYZER_CH0 63 // New move
 60  #define ANALYZER_CH1 40 // Step loop
 61  #define ANALYZER_CH2 53 // X Step
 62  #define ANALYZER_CH3 65 // Y Step
 63  #define ANALYZER_CH4 59 // X Direction
 64  #define ANALYZER_CH5 64 // Y Direction
 65  #define ANALYZER_CH6 58 // xsig 
 66  #define ANALYZER_CH7 57 // ysig
 67  
 68  #ifdef ANALYZER
 69  #define ANALYZER_ON(a) {WRITE(a,HIGH);}
 70  #define ANALYZER_OFF(a) {WRITE(a,LOW);}
 71  #else
 72  #define ANALYZER_ON(a)
 73  #define ANALYZER_OFF(a)
 74  #endif
 75  
 76  
 77  // Bits of the ADC converter
 78  #define ANALOG_INPUT_BITS 10
 79  // Build median from 2^ANALOG_INPUT_SAMPLE samples
 80  #define ANALOG_INPUT_SAMPLE 5
 81  #define ANALOG_REF_AREF 0
 82  #define ANALOG_REF_AVCC _BV(REFS0)
 83  #define ANALOG_REF_INT_1_1 _BV(REFS1)
 84  #define ANALOG_REF_INT_2_56 _BV(REFS0) | _BV(REFS1)
 85  
 86  // MS1 MS2 Stepper Driver Microstepping mode table
 87  #define MICROSTEP1 LOW,LOW
 88  #define MICROSTEP2 HIGH,LOW
 89  #define MICROSTEP4 LOW,HIGH
 90  #define MICROSTEP8 HIGH,HIGH
 91  #define MICROSTEP16 HIGH,HIGH
 92  
 93  #define NEW_XY_GANTRY
 94  
 95  #include "Configuration.h"
 96  #if DRIVE_SYSTEM==1 || DRIVE_SYSTEM==2
 97  #define XY_GANTRY
 98  #endif
 99  
100  //Step to split a cirrcle in small Lines 
101  #ifndef MM_PER_ARC_SEGMENT
102  #define MM_PER_ARC_SEGMENT 1
103  #define MM_PER_ARC_SEGMENT_BIG 3
104  #else
105  #define MM_PER_ARC_SEGMENT_BIG MM_PER_ARC_SEGMENT
106  #endif
107  //After this count of steps a new SIN / COS caluclation is startet to correct the circle interpolation
108  #define N_ARC_CORRECTION 25
109  #if CPU_ARCH==ARCH_AVR
110  #include <avr/io.h>
111  #else
112  #define PROGMEM
113  #define PGM_P const char *
114  #define PSTR(s) s
115  #define pgm_read_byte_near(x) (*(char*)x)
116  #define pgm_read_byte(x) (*(char*)x)
117  #endif
118  
119  #define KOMMA
120  #if NUM_EXTRUDER>0 && EXT0_TEMPSENSOR_TYPE<100
121  #define EXT0_ANALOG_INPUTS 1
122  #define EXT0_SENSOR_INDEX 0
123  #define EXT0_ANALOG_CHANNEL EXT0_TEMPSENSOR_PIN
124  #undef KOMMA
125  #define KOMMA ,
126  #else
127  #define EXT0_ANALOG_INPUTS 0
128  #define EXT0_SENSOR_INDEX EXT0_TEMPSENSOR_PIN
129  #define EXT0_ANALOG_CHANNEL
130  #endif
131  
132  #if NUM_EXTRUDER>1 && EXT1_TEMPSENSOR_TYPE<100
133  #define EXT1_ANALOG_INPUTS 1
134  #define EXT1_SENSOR_INDEX EXT0_ANALOG_INPUTS
135  #define EXT1_ANALOG_CHANNEL KOMMA EXT1_TEMPSENSOR_PIN
136  #undef KOMMA
137  #define KOMMA ,
138  #else
139  #define EXT1_ANALOG_INPUTS 0
140  #define EXT1_SENSOR_INDEX EXT1_TEMPSENSOR_PIN
141  #define EXT1_ANALOG_CHANNEL
142  #endif
143  
144  #if NUM_EXTRUDER>2 && EXT2_TEMPSENSOR_TYPE<100
145  #define EXT2_ANALOG_INPUTS 1
146  #define EXT2_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS
147  #define EXT2_ANALOG_CHANNEL KOMMA EXT2_TEMPSENSOR_PIN
148  #undef KOMMA
149  #define KOMMA ,
150  #else
151  #define EXT2_ANALOG_INPUTS 0
152  #define EXT2_SENSOR_INDEX EXT2_TEMPSENSOR_PIN
153  #define EXT2_ANALOG_CHANNEL
154  #endif
155  
156  #if NUM_EXTRUDER>3 && EXT3_TEMPSENSOR_TYPE<100
157  #define EXT3_ANALOG_INPUTS 1
158  #define EXT3_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS
159  #define EXT3_ANALOG_CHANNEL KOMMA EXT3_TEMPSENSOR_PIN
160  #undef KOMMA
161  #define KOMMA ,
162  #else
163  #define EXT3_ANALOG_INPUTS 0
164  #define EXT3_SENSOR_INDEX EXT3_TEMPSENSOR_PIN
165  #define EXT3_ANALOG_CHANNEL
166  #endif
167  
168  #if NUM_EXTRUDER>4 && EXT4_TEMPSENSOR_TYPE<100
169  #define EXT4_ANALOG_INPUTS 1
170  #define EXT4_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS
171  #define EXT4_ANALOG_CHANNEL KOMMA EXT4_TEMPSENSOR_PIN
172  #undef KOMMA
173  #define KOMMA ,
174  #else
175  #define EXT4_ANALOG_INPUTS 0
176  #define EXT4_SENSOR_INDEX EXT4_TEMPSENSOR_PIN
177  #define EXT4_ANALOG_CHANNEL
178  #endif
179  
180  #if NUM_EXTRUDER>5 && EXT5_TEMPSENSOR_TYPE<100
181  #define EXT5_ANALOG_INPUTS 1
182  #define EXT5_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS
183  #define EXT5_ANALOG_CHANNEL KOMMA EXT5_TEMPSENSOR_PIN
184  #undef KOMMA
185  #define KOMMA ,
186  #else
187  #define EXT5_ANALOG_INPUTS 0
188  #define EXT5_SENSOR_INDEX EXT5_TEMPSENSOR_PIN
189  #define EXT5_ANALOG_CHANNEL
190  #endif
191  
192  #if HAVE_HEATED_BED==true && HEATED_BED_SENSOR_TYPE<100
193  #define BED_ANALOG_INPUTS 1
194  #define BED_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS
195  #define BED_ANALOG_CHANNEL KOMMA  HEATED_BED_SENSOR_PIN
196  #undef KOMMA
197  #define KOMMA ,
198  #else
199  #define BED_ANALOG_INPUTS 0
200  #define BED_SENSOR_INDEX HEATED_BED_SENSOR_PIN
201  #define BED_ANALOG_CHANNEL
202  #endif
203  
204  #ifndef DEBUG_FREE_MEMORY
205  #define DEBUG_MEMORY
206  #else
207  #define DEBUG_MEMORY check_mem();
208  #endif
209  
210  /** \brief number of analog input signals. Normally 1 for each temperature sensor */
211  #define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS)
212  #if ANALOG_INPUTS>0
213  /** Channels are the MUX-part of ADMUX register */
214  #define  ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL EXT2_ANALOG_CHANNEL EXT3_ANALOG_CHANNEL EXT4_ANALOG_CHANNEL EXT5_ANALOG_CHANNEL BED_ANALOG_CHANNEL}
215  #endif
216  #define ANALOG_PRESCALER _BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2)
217  
218  #if MOTHERBOARD==8 || MOTHERBOARD==9 || CPU_ARCH!=ARCH_AVR
219  #define EXTERNALSERIAL
220  #endif
221  //#define EXTERNALSERIAL  // Force using arduino serial
222  #ifndef EXTERNALSERIAL
223  #define  HardwareSerial_h // Don't use standard serial console
224  #endif
225  #include <inttypes.h>
226  #include "Print.h"
227  
228  #if defined(ARDUINO) && ARDUINO >= 100
229  #include "Arduino.h"
230  #else
231  #include "WProgram.h"
232  #define COMPAT_PRE1
233  #endif
234  #include "gcode.h"
235  #if CPU_ARCH==ARCH_AVR
236  #include "fastio.h"
237  #else
238  #define	READ(IO)  digitalRead(IO)
239  #define	WRITE(IO, v)  digitalWrite(IO, v)
240  #define	SET_INPUT(IO)  pinMode(IO, INPUT)
241  #define	SET_OUTPUT(IO)  pinMode(IO, OUTPUT)
242  #endif
243  #define SD_MAX_FOLDER_DEPTH 2
244  
245  #include "ui.h"
246  
247  #ifndef SDSUPPORT
248  #define SDSUPPORT false
249  #endif
250  #if SDSUPPORT
251  #include "SdFat.h"
252  #endif
253  #ifndef SDSUPPORT
254  #define SDSUPPORT false
255  #endif
256  #if SDSUPPORT
257  #include "SdFat.h"
258  #endif
259  
260  #if ENABLE_BACKLASH_COMPENSATION && DRIVE_SYSTEM!=0
261  #undef ENABLE_BACKLASH_COMPENSATION
262  #define ENABLE_BACKLASH_COMPENSATION false
263  #endif
264  
265  #define uint uint16_t
266  #define uint8 uint8_t
267  #define int8 int8_t
268  #define uint32 uint32_t
269  #define int32 int32_t
270  
271  /*#if MOTHERBOARD==6 || MOTHERBOARD==62 || MOTHERBOARD==7
272  #if MOTHERBOARD!=7
273  #define SIMULATE_PWM
274  #endif
275  #define EXTRUDER_TIMER_VECTOR TIMER2_COMPA_vect
276  #define EXTRUDER_OCR OCR2A
277  #define EXTRUDER_TCCR TCCR2A
278  #define EXTRUDER_TIMSK TIMSK2
279  #define EXTRUDER_OCIE OCIE2A
280  #define PWM_TIMER_VECTOR TIMER2_COMPB_vect
281  #define PWM_OCR OCR2B
282  #define PWM_TCCR TCCR2B
283  #define PWM_TIMSK TIMSK2
284  #define PWM_OCIE OCIE2B
285  #else*/
286  #define EXTRUDER_TIMER_VECTOR TIMER0_COMPA_vect
287  #define EXTRUDER_OCR OCR0A
288  #define EXTRUDER_TCCR TCCR0A
289  #define EXTRUDER_TIMSK TIMSK0
290  #define EXTRUDER_OCIE OCIE0A
291  #define PWM_TIMER_VECTOR TIMER0_COMPB_vect
292  #define PWM_OCR OCR0B
293  #define PWM_TCCR TCCR0A
294  #define PWM_TIMSK TIMSK0
295  #define PWM_OCIE OCIE0B
296  //#endif
297  
298  /** TemperatureController manages one heater-temperature sensore loop. You can have up to
299  4 loops allowing pid/bang bang for up to 3 extruder and the heated bed.
300  
301  */
302  typedef struct {
303    byte pwmIndex; ///< pwm index for output control. 0-2 = Extruder, 3 = Fan, 4 = Heated Bed
304    byte sensorType; ///< Type of temperature sensor.
305    byte sensorPin; ///< Pin to read extruder temperature.
306    int currentTemperature; ///< Currenttemperature value read from sensor.
307    int targetTemperature; ///< Target temperature value in units of sensor.
308    float currentTemperatureC; ///< Current temperature in °C.
309    float targetTemperatureC; ///< Target temperature in °C.
310    unsigned long lastTemperatureUpdate; ///< Time in millis of the last temperature update.
311    char heatManager; ///< How is temperature controled. 0 = on/off, 1 = PID-Control
312  #ifdef TEMP_PID
313    long tempIState; ///< Temp. var. for PID computation.
314    byte pidDriveMax; ///< Used for windup in PID calculation.
315    byte pidDriveMin; ///< Used for windup in PID calculation.
316    float pidPGain; ///< Pgain (proportional gain) for PID temperature control [0,01 Units].
317    float pidIGain; ///< Igain (integral) for PID temperature control [0,01 Units].
318    float pidDGain;  ///< Dgain (damping) for PID temperature control [0,01 Units].
319    byte pidMax; ///< Maximum PWM value, the heater should be set.
320    float tempIStateLimitMax;
321    float tempIStateLimitMin;
322    byte tempPointer;
323    float tempArray[4];
324  #endif
325  } TemperatureController;
326  /** \brief Data to drive one extruder.
327  
328  This structure contains all definitions for an extruder and all
329  current state variables, like current temperature, feeder position etc.
330  */
331  typedef struct { // Size: 12*1 Byte+12*4 Byte+4*2Byte = 68 Byte
332    byte id;
333    long xOffset;
334    long yOffset;
335    float stepsPerMM;        ///< Steps per mm.
336    byte enablePin;          ///< Pin to enable extruder stepper motor.
337  //  byte directionPin; ///< Pin number to assign the direction.
338  //  byte stepPin; ///< Pin number for a step.
339    byte enableOn;
340  //  byte invertDir; ///< 1 if the direction of the extruder should be inverted.
341    float maxFeedrate;      ///< Maximum feedrate in mm/s.
342    float maxAcceleration;  ///< Maximum acceleration in mm/s^2.
343    float maxStartFeedrate; ///< Maximum start feedrate in mm/s.
344    long extrudePosition;   ///< Current extruder position in steps.
345    int watchPeriod;        ///< Time in seconds, a M109 command will wait to stabalize temperature
346    int waitRetractTemperature; ///< Temperature to retract the filament when waiting for heatup
347    int waitRetractUnits;   ///< Units to retract the filament when waiting for heatup
348  #ifdef USE_ADVANCE
349  #ifdef ENABLE_QUADRATIC_ADVANCE
350    float advanceK;         ///< Koefficient for advance algorithm. 0 = off
351  #endif
352    float advanceL;
353  #endif
354    TemperatureController tempControl;
355    const char * PROGMEM selectCommands;
356    const char * PROGMEM deselectCommands;
357    byte coolerSpeed; ///< Speed to use when enabled
358    byte coolerPWM; ///< current PWM setting
359  } Extruder;
360  
361  extern const uint8 osAnalogInputChannels[] PROGMEM;
362  extern uint8 osAnalogInputCounter[ANALOG_INPUTS];
363  extern uint osAnalogInputBuildup[ANALOG_INPUTS];
364  extern uint8 osAnalogInputPos; // Current sampling position
365  extern volatile uint osAnalogInputValues[ANALOG_INPUTS];
366  extern byte pwm_pos[NUM_EXTRUDER+3]; // 0-NUM_EXTRUDER = Heater 0-NUM_EXTRUDER of extruder, NUM_EXTRUDER = Heated bed, NUM_EXTRUDER+1 Board fan, NUM_EXTRUDER+2 = Fan
367  #ifdef USE_ADVANCE
368  #ifdef ENABLE_QUADRATIC_ADVANCE
369  extern int maxadv;
370  #endif
371  extern int maxadv2;
372  extern float maxadvspeed;
373  #endif
374  
375  extern Extruder *current_extruder;
376  extern Extruder extruder[];
377  // Initalize extruder and heated bed related pins
378  extern void initExtruder();
379  extern void initHeatedBed();
380  extern void updateTempControlVars(TemperatureController *tc);
381  extern void extruder_select(byte ext_num);
382  // Set current extruder position
383  //extern void extruder_set_position(float pos,bool relative);
384  // set the temperature of current extruder
385  extern void extruder_set_temperature(float temp_celsius,byte extr);
386  // Set temperature of heated bed
387  extern void heated_bed_set_temperature(float temp_celsius);
388  //extern long extruder_steps_to_position(float value,byte relative);
389  extern void extruder_set_direction(byte steps);
390  extern void extruder_disable();
391  #ifdef TEMP_PID
392  void autotunePID(float temp,int controllerId);
393  #endif
394  
395  //#ifdef TEMP_PID
396  //extern byte current_extruder_out;
397  //#endif
398  
399  /** \brief Sends the high-signal to the stepper for next extruder step. 
400  
401  Call this function only, if interrupts are disabled.
402  */
403  inline void extruder_step() {
404  #if NUM_EXTRUDER==1
405    WRITE(EXT0_STEP_PIN,HIGH);
406  #else
407    switch(current_extruder->id) {
408    case 0:
409  #if NUM_EXTRUDER>0
410      WRITE(EXT0_STEP_PIN,HIGH);
411  #endif
412      break;
413  #if defined(EXT1_STEP_PIN) && NUM_EXTRUDER>1
414    case 1:
415      WRITE(EXT1_STEP_PIN,HIGH);
416      break;
417  #endif
418  #if defined(EXT2_STEP_PIN) && NUM_EXTRUDER>2
419    case 2:
420      WRITE(EXT2_STEP_PIN,HIGH);
421      break;
422  #endif
423  #if defined(EXT3_STEP_PIN) && NUM_EXTRUDER>3
424    case 3:
425      WRITE(EXT3_STEP_PIN,HIGH);
426      break;
427  #endif
428  #if defined(EXT4_STEP_PIN) && NUM_EXTRUDER>4
429    case 4:
430      WRITE(EXT4_STEP_PIN,HIGH);
431      break;
432  #endif
433  #if defined(EXT5_STEP_PIN) && NUM_EXTRUDER>5
434    case 5:
435      WRITE(EXT5_STEP_PIN,HIGH);
436      break;
437  #endif
438    }
439  #endif
440  }
441  /** \brief Sets stepper signal to low for current extruder. 
442  
443  Call this function only, if interrupts are disabled.
444  */
445  inline void extruder_unstep() {
446  #if NUM_EXTRUDER==1
447    WRITE(EXT0_STEP_PIN,LOW);
448  #else
449    switch(current_extruder->id) {
450    case 0:
451  #if NUM_EXTRUDER>0
452      WRITE(EXT0_STEP_PIN,LOW);
453  #endif
454      break;
455  #if defined(EXT1_STEP_PIN) && NUM_EXTRUDER>1
456    case 1:
457      WRITE(EXT1_STEP_PIN,LOW);
458      break;
459  #endif
460  #if defined(EXT2_STEP_PIN) && NUM_EXTRUDER>2
461    case 2:
462      WRITE(EXT2_STEP_PIN,LOW);
463      break;
464  #endif
465  #if defined(EXT3_STEP_PIN) && NUM_EXTRUDER>3
466    case 3:
467      WRITE(EXT3_STEP_PIN,LOW);
468      break;
469  #endif
470  #if defined(EXT4_STEP_PIN) && NUM_EXTRUDER>4
471    case 4:
472      WRITE(EXT4_STEP_PIN,LOW);
473      break;
474  #endif
475  #if defined(EXT5_STEP_PIN) && NUM_EXTRUDER>5
476    case 5:
477      WRITE(EXT5_STEP_PIN,LOW);
478      break;
479  #endif
480    }
481  #endif
482  }
483  /** \brief Activates the extruder stepper and sets the direction. */
484  inline void extruder_set_direction(byte dir) {  
485  #if NUM_EXTRUDER==1
486    if(dir)
487      WRITE(EXT0_DIR_PIN,!EXT0_INVERSE);
488    else
489      WRITE(EXT0_DIR_PIN,EXT0_INVERSE);
490  #else
491    switch(current_extruder->id) {
492  #if NUM_EXTRUDER>0
493    case 0:
494    if(dir)
495      WRITE(EXT0_DIR_PIN,!EXT0_INVERSE);
496    else
497      WRITE(EXT0_DIR_PIN,EXT0_INVERSE);
498      break;
499  #endif
500  #if defined(EXT1_DIR_PIN) && NUM_EXTRUDER>1
501    case 1:
502    if(dir)
503      WRITE(EXT1_DIR_PIN,!EXT1_INVERSE);
504    else
505      WRITE(EXT1_DIR_PIN,EXT1_INVERSE);
506      break;
507  #endif
508  #if defined(EXT2_DIR_PIN) && NUM_EXTRUDER>2
509    case 2:
510    if(dir)
511      WRITE(EXT2_DIR_PIN,!EXT2_INVERSE);
512    else
513      WRITE(EXT2_DIR_PIN,EXT2_INVERSE);
514      break;
515  #endif
516  #if defined(EXT3_DIR_PIN) && NUM_EXTRUDER>3
517    case 3:
518    if(dir)
519      WRITE(EXT3_DIR_PIN,!EXT3_INVERSE);
520    else
521      WRITE(EXT3_DIR_PIN,EXT3_INVERSE);
522      break;
523  #endif
524  #if defined(EXT4_DIR_PIN) && NUM_EXTRUDER>4
525    case 4:
526    if(dir)
527      WRITE(EXT4_DIR_PIN,!EXT4_INVERSE);
528    else
529      WRITE(EXT4_DIR_PIN,EXT4_INVERSE);
530      break;
531  #endif
532  #if defined(EXT5_DIR_PIN) && NUM_EXTRUDER>5
533    case 5:
534    if(dir)
535      WRITE(EXT5_DIR_PIN,!EXT5_INVERSE);
536    else
537      WRITE(EXT5_DIR_PIN,EXT5_INVERSE);
538      break;
539  #endif
540    }
541  #endif
542  }
543  inline void extruder_enable() {
544  #if NUM_EXTRUDER==1
545  #if EXT0_ENABLE_PIN>-1
546      WRITE(EXT0_ENABLE_PIN,EXT0_ENABLE_ON ); 
547  #endif
548  #else
549    if(current_extruder->enablePin > -1) 
550      digitalWrite(current_extruder->enablePin,current_extruder->enableOn); 
551  #endif
552  }
553  extern void(* resetFunc) (void); 
554  // Read a temperature and return its value in °C
555  // this high level method supports all known methods
556  extern int read_raw_temperature(byte type,byte pin);
557  extern float heated_bed_get_temperature();
558  // Convert a raw temperature value into °C
559  extern float conv_raw_temp(byte type,int raw_temp);
560  // Converts a temperture temp in °C into a raw value
561  // which can be compared with results of read_raw_temperature
562  extern int conv_temp_raw(byte type,float temp);
563  // Updates the temperature of all extruders and heated bed if it's time.
564  // Toggels the heater power if necessary.
565  extern void manage_temperatures();
566  extern bool reportTempsensorError(); ///< Report defect sensors
567  extern byte manage_monitor;
568  
569  void process_command(GCode *code,byte bufferedCommand);
570  
571  void manage_inactivity(byte debug);
572  
573  extern void wait_until_end_of_move();
574  extern void update_ramps_parameter();
575  extern void update_extruder_flags();
576  extern void finishNextSegment();
577  extern void printPosition();
578  extern void defaultLoopActions();
579  extern void change_feedrate_multiply(int factor); ///< Set feedrate multiplier
580  extern void set_fan_speed(int speed,bool wait); /// Set fan speed 0..255
581  extern void home_axis(bool xaxis,bool yaxis,bool zaxis); /// Home axis
582  extern byte get_coordinates(GCode *com);
583  extern void move_steps(long x,long y,long z,long e,float feedrate,bool waitEnd,bool check_endstop);
584  extern void queue_move(byte check_endstops,byte pathOptimize);
585  #if DRIVE_SYSTEM==3
586  extern byte calculate_delta(long cartesianPosSteps[], long deltaPosSteps[]);
587  extern void set_delta_position(long xaxis, long yaxis, long zaxis);
588  extern float rodMaxLength;
589  extern void split_delta_move(byte check_endstops,byte pathOptimize, byte softEndstop);
590  #ifdef SOFTWARE_LEVELING
591  extern void calculate_plane(long factors[], long p1[], long p2[], long p3[]);
592  extern float calc_zoffset(long factors[], long pointX, long pointY);
593  #endif
594  #endif
595  extern void linear_move(long steps_remaining[]);
596  extern inline void disable_x();
597  extern inline void disable_y();
598  extern inline void disable_z();
599  extern inline void enable_x();
600  extern inline void enable_y();
601  extern inline void enable_z();
602  
603  #define PREVIOUS_PLANNER_INDEX(p) {p--;if(p==255) p = MOVE_CACHE_SIZE-1;}
604  #define NEXT_PLANNER_INDEX(idx) {++idx;if(idx==MOVE_CACHE_SIZE) idx=0;}
605  
606  extern void kill(byte only_steppers);
607  
608  extern float axis_steps_per_unit[];
609  extern float inv_axis_steps_per_unit[];
610  extern float max_feedrate[];
611  extern float homing_feedrate[];
612  extern float max_start_speed_units_per_second[];
613  extern long max_acceleration_units_per_sq_second[];
614  extern long max_travel_acceleration_units_per_sq_second[];
615  extern unsigned long axis_steps_per_sqr_second[];
616  extern unsigned long axis_travel_steps_per_sqr_second[];
617  extern byte relative_mode;    ///< Determines absolute (false) or relative Coordinates (true).
618  extern byte relative_mode_e;  ///< Determines Absolute or Relative E Codes while in Absolute Coordinates mode. E is always relative in Relative Coordinates mode.
619  
620  extern byte unit_inches;
621  extern unsigned long previous_millis_cmd;
622  extern unsigned long max_inactive_time;
623  extern unsigned long stepper_inactive_time;
624  
625  extern void setupTimerInterrupt();
626  extern void current_control_init();
627  extern void microstep_init();
628  extern void print_temperatures();
629  extern void check_mem();
630  #if ARC_SUPPORT
631  extern void mc_arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise);
632  #endif
633  
634  #define PRINTER_FLAG0_STEPPER_DISABLED      1
635  #define PRINTER_FLAG0_SEPERATE_EXTRUDER_INT 2
636  #define PRINTER_FLAG0_TEMPSENSOR_DEFECT     4
637  typedef struct { 
638    byte flag0; // 1 = stepper disabled, 2 = use external extruder interrupt, 4 = temp Sensor defect 
639  #if USE_OPS==1 || defined(USE_ADVANCE)
640    volatile int extruderStepsNeeded; ///< This many extruder steps are still needed, <0 = reverse steps needed.
641  //  float extruderSpeed;              ///< Extruder speed in mm/s.
642    byte minExtruderSpeed;            ///< Timer delay for start extruder speed
643    byte maxExtruderSpeed;            ///< Timer delay for end extruder speed
644    byte extruderAccelerateDelay;     ///< delay between 2 speec increases
645  #endif
646    long interval;                    ///< Last step duration in ticks.
647  #if USE_OPS==1
648    bool filamentRetracted;           ///< Is the extruder filament retracted
649  #endif
650    unsigned long timer;              ///< used for acceleration/deceleration timing
651    unsigned long stepNumber;         ///< Step number in current move.
652  #ifdef USE_ADVANCE
653  #ifdef ENABLE_QUADRATIC_ADVANCE
654    long advance_executed;             ///< Executed advance steps
655  #endif
656    int advance_steps_set;
657    unsigned int advance_lin_set;
658  #endif
659    long currentPositionSteps[4];     ///< Position in steps from origin.
660    long destinationSteps[4];         ///< Target position in steps.
661  #if DRIVE_SYSTEM==3
662  #ifdef STEP_COUNTER
663    long countZSteps;					///< Count of steps from last position reset
664  #endif
665    long currentDeltaPositionSteps[4];
666    long maxDeltaPositionSteps;
667  #endif
668  #ifdef SOFTWARE_LEVELING
669    long levelingP1[3];
670    long levelingP2[3];
671    long levelingP3[3];
672  #endif
673  #if USE_OPS==1
674    int opsRetractSteps;              ///< Retract filament this much steps
675    int opsPushbackSteps;             ///< Retract+extra distance for backsash
676    float opsMinDistance;
677    float opsRetractDistance;
678    float opsRetractBacklash;
679    byte opsMode;                     ///< OPS operation mode. 0 = Off, 1 = Classic, 2 = Fast
680    float opsMoveAfter;               ///< Start move after opsModeAfter percent off full retract.
681    int opsMoveAfterSteps;            ///< opsMoveAfter converted in steps (negative value!).
682  #endif
683    long xMaxSteps;                   ///< For software endstops, limit of move in positive direction.
684    long yMaxSteps;                   ///< For software endstops, limit of move in positive direction.
685    long zMaxSteps;                   ///< For software endstops, limit of move in positive direction.
686    long xMinSteps;                   ///< For software endstops, limit of move in negative direction.
687    long yMinSteps;                   ///< For software endstops, limit of move in negative direction.
688    long zMinSteps;                   ///< For software endstops, limit of move in negative direction.
689    float xLength;
690    float xMin;
691    float yLength;
692    float yMin;
693    float zLength;
694    float zMin;
695    float feedrate;                   ///< Last requested feedrate.
696    int feedrateMultiply;             ///< Multiplier for feedrate in percent (factor 1 = 100)
697    unsigned int extrudeMultiply;     ///< Flow multiplier in percdent (factor 1 = 100)
698    float maxJerk;                    ///< Maximum allowed jerk in mm/s
699    float maxZJerk;                   ///< Maximum allowed jerk in z direction in mm/s
700    long offsetX;                     ///< X-offset for different extruder positions.
701    long offsetY;                     ///< Y-offset for different extruder positions.
702    unsigned int vMaxReached;         ///< MAximumu reached speed
703    byte stepper_loops;
704    unsigned long msecondsPrinting;            ///< Milliseconds of printing time (means time with heated extruder)
705    float filamentPrinted;            ///< mm of filament printed since counting started
706    byte waslasthalfstepping;         ///< Indicates if last move had halfstepping enabled
707  #if ENABLE_BACKLASH_COMPENSATION
708    float backlashX;
709    float backlashY;
710    float backlashZ;
711    byte backlashDir;
712  #endif
713  #ifdef DEBUG_STEPCOUNT
714    long totalStepsRemaining;
715  #endif
716  #if FEATURE_MEMORY_POSITION
717    long memoryX;
718    long memoryY;
719    long memoryZ;
720  #endif
721  #ifdef XY_GANTRY
722    char motorX;
723    char motorY;
724  #endif
725  } PrinterState;
726  extern PrinterState printer_state;
727  
728  /** Marks the first step of a new move */
729  #define FLAG_WARMUP 1
730  #define FLAG_NOMINAL 2
731  #define FLAG_DECELERATING 4
732  #define FLAG_ACCELERATION_ENABLED 8
733  #define FLAG_CHECK_ENDSTOPS 16
734  #define FLAG_SKIP_ACCELERATING 32
735  #define FLAG_SKIP_DEACCELERATING 64
736  #define FLAG_BLOCKED 128
737  
738  /** Are the step parameter computed */
739  #define FLAG_JOIN_STEPPARAMS_COMPUTED 1
740  /** The right speed is fixed. Don't check this block or any block to the left. */
741  #define FLAG_JOIN_END_FIXED 2
742  /** The left speed is fixed. Don't check left block. */
743  #define FLAG_JOIN_START_FIXED 4
744  /** Start filament retraction at move start */
745  #define FLAG_JOIN_START_RETRACT 8
746  /** Wait for filament pushback, before ending move */
747  #define FLAG_JOIN_END_RETRACT 16
748  /** Disable retract for this line */
749  #define FLAG_JOIN_NO_RETRACT 32
750  /** Wait for the extruder to finish it's up movement */
751  #define FLAG_JOIN_WAIT_EXTRUDER_UP 64
752  /** Wait for the extruder to finish it's down movement */
753  #define FLAG_JOIN_WAIT_EXTRUDER_DOWN 128
754  // Printing related data
755  #if DRIVE_SYSTEM==3
756  // Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast.
757  // MAX_DELTA_SEGMENTS_PER_LINE * 
758  #define DELTA_CACHE_SIZE (MAX_DELTA_SEGMENTS_PER_LINE * MOVE_CACHE_SIZE)
759  typedef struct { 
760  	byte dir; 									///< Direction of delta movement.
761  	unsigned int deltaSteps[3]; 				///< Number of steps in move.
762  } DeltaSegment;
763  extern DeltaSegment segments[];					// Delta segment cache
764  extern unsigned int delta_segment_write_pos; 	// Position where we write the next cached delta move
765  extern volatile unsigned int delta_segment_count; // Number of delta moves cached 0 = nothing in cache
766  extern byte lastMoveID;
767  #endif
768  typedef struct { // RAM usage: 24*4+15 = 113 Byte
769    byte primaryAxis;
770    volatile byte flags;
771    long timeInTicks;
772    byte joinFlags;
773    byte halfstep;                  ///< 0 = disabled, 1 = halfstep, 2 = fulstep
774    byte dir;                       ///< Direction of movement. 1 = X+, 2 = Y+, 4= Z+, values can be combined.
775    long delta[4];                  ///< Steps we want to move.
776    long error[4];                  ///< Error calculation for Bresenham algorithm
777    float speedX;                   ///< Speed in x direction at fullInterval in mm/s
778    float speedY;                   ///< Speed in y direction at fullInterval in mm/s
779    float speedZ;                   ///< Speed in z direction at fullInterval in mm/s
780    float speedE;                   ///< Speed in E direction at fullInterval in mm/s
781    float fullSpeed;                ///< Desired speed mm/s
782    float invFullSpeed;             ///< 1.0/fullSpeed for fatser computation
783    float acceleration;             ///< Real 2.0*distanceÜacceleration mm²/s²
784    float maxJunctionSpeed;         ///< Max. junction speed between this and next segment
785    float startSpeed;               ///< Staring speed in mm/s
786    float endSpeed;                 ///< Exit speed in mm/s
787    float distance;
788  #if DRIVE_SYSTEM==3
789    byte numDeltaSegments;		  		///< Number of delta segments left in line. Decremented by stepper timer.
790    byte moveID;							///< ID used to identify moves which are all part of the same line
791    int deltaSegmentReadPos; 	 			///< Pointer to next DeltaSegment
792    long numPrimaryStepPerSegment;		///< Number of primary bresenham axis steps in each delta segment
793  #endif
794    unsigned long fullInterval;     ///< interval at full speed in ticks/step.
795    unsigned long stepsRemaining;   ///< Remaining steps, until move is finished
796    unsigned int accelSteps;        ///< How much steps does it take, to reach the plateau.
797    unsigned int decelSteps;        ///< How much steps does it take, to reach the end speed.
798    unsigned long accelerationPrim; ///< Acceleration along primary axis
799    unsigned long facceleration;    ///< accelerationPrim*262144/F_CPU
800    unsigned int vMax;              ///< Maximum reached speed in steps/s.
801    unsigned int vStart;            ///< Starting speed in steps/s.
802    unsigned int vEnd;              ///< End speed in steps/s
803  #ifdef USE_ADVANCE
804  #ifdef ENABLE_QUADRATIC_ADVANCE
805    long advanceRate;               ///< Advance steps at full speed
806    long advanceFull;               ///< Maximum advance at fullInterval [steps*65536]
807    long advanceStart;
808    long advanceEnd;
809  #endif
810    unsigned int advanceL;         ///< Recomputated L value
811  #endif
812  #if USE_OPS==1
813    long opsReverseSteps;           ///< How many steps are needed to reverse retracted filament at full speed
814  #endif
815  #ifdef DEBUG_STEPCOUNT
816    long totalStepsRemaining;
817  #endif
818  } PrintLine;
819  
820  extern PrintLine lines[];
821  extern byte lines_write_pos; // Position where we write the next cached line move
822  extern byte lines_pos; // Position for executing line movement
823  extern volatile byte lines_count; // Number of lines cached 0 = nothing to do
824  extern byte printmoveSeen;
825  extern long baudrate;
826  #if OS_ANALOG_INPUTS>0
827  // Get last result for pin x
828  extern volatile uint osAnalogInputValues[OS_ANALOG_INPUTS];
829  #endif
830  #define BEGIN_INTERRUPT_PROTECTED {byte sreg=SREG;__asm volatile( "cli" ::: "memory" );
831  #define END_INTERRUPT_PROTECTED SREG=sreg;}
832  #define ESCAPE_INTERRUPT_PROTECTED SREG=sreg;
833  
834  #define SECONDS_TO_TICKS(s) (unsigned long)(s*(float)F_CPU)
835  extern long CPUDivU2(unsigned int divisor);
836  
837  extern unsigned int counter_periodical;
838  extern volatile byte execute_periodical;
839  extern byte counter_250ms;
840  extern void write_monitor();
841  extern void check_periodical();
842  #define CELSIUS_EXTRA_BITS 3
843  #define ANALOG_REDUCE_BITS 0
844  #define ANALOG_REDUCE_FACTOR 1
845  
846  #if HAVE_HEATED_BED
847  #define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER+1
848  extern TemperatureController heatedBedController;
849  #else
850  #define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER
851  #endif
852  #define TEMP_INT_TO_FLOAT(temp) ((float)(temp)/(float)(1<<CELSIUS_EXTRA_BITS))
853  #define TEMP_FLOAT_TO_INT(temp) ((int)((temp)*(1<<CELSIUS_EXTRA_BITS)))
854  
855  extern TemperatureController *tempController[NUM_TEMPERATURE_LOOPS];
856  extern byte autotuneIndex;
857  
858  #if SDSUPPORT
859  
860  
861  #include "SdFat.h"
862  
863  enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
864  class SDCard {
865  public:
866    SdFat fat;
867    //Sd2Card card; // ~14 Byte
868    //SdVolume volume;
869    //SdFile root;
870    //SdFile dir[SD_MAX_FOLDER_DEPTH+1];
871    SdFile file;
872    uint32_t filesize;
873    uint32_t sdpos;
874    char fullName[13*SD_MAX_FOLDER_DEPTH+13]; // Fill name
875    char *shortname; // Pointer to start of filename itself
876    char *pathend; // File to char where pathname in fullname ends
877    bool sdmode;  // true if we are printing from sd card
878    bool sdactive;
879    //int16_t n;
880    bool savetosd;
881    SDCard();
882    void initsd();
883    void write_command(GCode *code);
884    void selectFile(char *filename);
885    inline void mount() {
886      sdmode = false;
887      initsd();
888    }
889    inline void unmount() {
890      sdmode = false;
891      sdactive = false;
892    }
893    inline void startPrint() {if(sdactive) sdmode = true; }
894    inline void pausePrint() {sdmode = false;}
895    inline void setIndex(uint32_t  newpos) { if(!sdactive) return; sdpos = newpos;file.seekSet(sdpos);}
896    void printStatus();
897    void ls();
898    void startWrite(char *filename);
899    void deleteFile(char *filename);
900    void finishWrite();
901    char *createFilename(char *buffer,const dir_t &p);
902    void makeDirectory(char *filename);
903    bool showFilename(const uint8_t *name);
904    void automount();
905  private:
906    void lsRecursive(SdBaseFile *parent,byte level);
907   // SdFile *getDirectory(char* name);
908  };
909  
910  extern SDCard sd;
911  #endif
912  
913  extern int waitRelax; // Delay filament relax at the end of print, could be a simple timeout
914  #ifdef USE_OPS
915  extern byte printmoveSeen;
916  #endif
917  extern void updateStepsParameter(PrintLine *p/*,byte caller*/);
918  
919  /** \brief Disable stepper motor for x direction. */
920  inline void disable_x() {
921  #if (X_ENABLE_PIN > -1)
922    WRITE(X_ENABLE_PIN,!X_ENABLE_ON);
923  #endif
924  }
925  /** \brief Disable stepper motor for y direction. */
926  inline void disable_y() {
927  #if (Y_ENABLE_PIN > -1)
928    WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON);
929  #endif
930  }
931  /** \brief Disable stepper motor for z direction. */
932  inline void disable_z() {
933  #if (Z_ENABLE_PIN > -1)
934   WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON);
935  #endif
936  }
937  /** \brief Enable stepper motor for x direction. */
938  inline void  enable_x() {
939  #if (X_ENABLE_PIN > -1)
940   WRITE(X_ENABLE_PIN, X_ENABLE_ON);
941  #endif
942  }
943  /** \brief Enable stepper motor for y direction. */
944  inline void  enable_y() {
945  #if (Y_ENABLE_PIN > -1)
946    WRITE(Y_ENABLE_PIN, Y_ENABLE_ON);
947  #endif
948  }
949  /** \brief Enable stepper motor for z direction. */
950  inline void  enable_z() {
951  #if (Z_ENABLE_PIN > -1)
952   WRITE(Z_ENABLE_PIN, Z_ENABLE_ON);
953  #endif
954  }
955  
956  
957  #if DRIVE_SYSTEM==3
958  #define SIN_60 0.8660254037844386
959  #define COS_60 0.5
960  #define DELTA_DIAGONAL_ROD_STEPS (AXIS_STEPS_PER_MM * DELTA_DIAGONAL_ROD)
961  #define DELTA_DIAGONAL_ROD_STEPS_SQUARED (DELTA_DIAGONAL_ROD_STEPS * DELTA_DIAGONAL_ROD_STEPS)
962  #define DELTA_ZERO_OFFSET_STEPS (AXIS_STEPS_PER_MM * DELTA_ZERO_OFFSET)
963  #define DELTA_RADIUS_STEPS (AXIS_STEPS_PER_MM * DELTA_RADIUS)
964  
965  #define DELTA_TOWER1_X_STEPS -SIN_60*DELTA_RADIUS_STEPS
966  #define DELTA_TOWER1_Y_STEPS -COS_60*DELTA_RADIUS_STEPS
967  #define DELTA_TOWER2_X_STEPS SIN_60*DELTA_RADIUS_STEPS
968  #define DELTA_TOWER2_Y_STEPS -COS_60*DELTA_RADIUS_STEPS
969  #define DELTA_TOWER3_X_STEPS 0.0
970  #define DELTA_TOWER3_Y_STEPS DELTA_RADIUS_STEPS
971  
972  #define NUM_AXIS 4
973  #define X_AXIS 0
974  #define Y_AXIS 1
975  #define Z_AXIS 2
976  #define E_AXIS 3
977  
978  #endif
979  
980  #define STR(s) #s
981  #define XSTR(s) STR(s)
982  
983  #endif