diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 8200d01f5b..a2c43bd3d1 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -362,6 +362,15 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o #define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) #define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) +//=========================================================================== +//============================= Filament Runout Sensor ====================== +//=========================================================================== +//#define FILAMENT_RUNOUT_SENSOR // Uncomment for defining a filament runout sensor such as a mechanical or opto endstop to check the existence of filament + // In RAMPS uses servo pin 2. Can be changed in pins file. For other boards pin definition should be made. + // It is assumed that when logic high = filament available + // when logic low = filament ran out +//const bool FIL_RUNOUT_INVERTING = true; // Should be uncommented and true or false should assigned +//#define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. //=========================================================================== //============================= Bed Auto Leveling =========================== diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index a8611f197a..286a8d5aed 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -32,6 +32,9 @@ #include "WProgram.h" #endif +#define BIT(b) (1<<(b)) +#define TEST(n,b) ((n)&BIT(b)!=0) + // Arduino < 1.0.0 does not define this, so we need to do it ourselves #ifndef analogInputToDigitalPin #define analogInputToDigitalPin(p) ((p) + 0xA0) @@ -199,6 +202,10 @@ void prepare_move(); void kill(); void Stop(); +#ifdef FILAMENT_RUNOUT_SENSOR +void filrunout(); +#endif + bool IsStopped(); bool enquecommand(const char *cmd); //put a single ASCII command at the end of the current buffer or return false when it is full diff --git a/Marlin/Marlin.ino b/Marlin/Marlin.ino index 7b0c790694..402edcd8a8 100644 --- a/Marlin/Marlin.ino +++ b/Marlin/Marlin.ino @@ -47,8 +47,8 @@ #endif #endif -#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 -#include +#if HAS_DIGIPOTSS + #include #endif #if defined(DIGIPOT_I2C) diff --git a/Marlin/Marlin.pde b/Marlin/Marlin.pde index 79c934bf0f..9eae6d440e 100644 --- a/Marlin/Marlin.pde +++ b/Marlin/Marlin.pde @@ -47,8 +47,8 @@ #endif #endif -#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 -#include +#if HAS_DIGIPOTSS + #include #endif #if defined(DIGIPOT_I2C) diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp index 7aef2291da..d8477b6db1 100644 --- a/Marlin/MarlinSerial.cpp +++ b/Marlin/MarlinSerial.cpp @@ -76,7 +76,7 @@ void MarlinSerial::begin(long baud) { #endif if (useU2X) { - M_UCSRxA = 1 << M_U2Xx; + M_UCSRxA = BIT(M_U2Xx); baud_setting = (F_CPU / 4 / baud - 1) / 2; } else { M_UCSRxA = 0; diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h index f836872b81..b56880c23f 100644 --- a/Marlin/MarlinSerial.h +++ b/Marlin/MarlinSerial.h @@ -97,14 +97,14 @@ class MarlinSerial { //: public Stream } FORCE_INLINE void write(uint8_t c) { - while (!((M_UCSRxA) & (1 << M_UDREx))) + while (!TEST(M_UCSRxA, M_UDREx)) ; M_UDRx = c; } FORCE_INLINE void checkRx(void) { - if ((M_UCSRxA & (1< -1 +#if HAS_DIGIPOTSS #include #endif @@ -370,6 +370,10 @@ bool cancel_heatup = false; int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting #endif +#ifdef FILAMENT_RUNOUT_SENSOR + static bool filrunoutEnqued = false; +#endif + const char errormagic[] PROGMEM = "Error:"; const char echomagic[] PROGMEM = "echo:"; @@ -529,6 +533,16 @@ void setup_killpin() #endif } +void setup_filrunoutpin() +{ +#if defined(FILRUNOUT_PIN) && FILRUNOUT_PIN > -1 + pinMode(FILRUNOUT_PIN,INPUT); + #if defined(ENDSTOPPULLUP_FIL_RUNOUT) + WRITE(FILLRUNOUT_PIN,HIGH); + #endif +#endif +} + // Set home pin void setup_homepin(void) { @@ -605,6 +619,7 @@ void servo_init() void setup() { setup_killpin(); + setup_filrunoutpin(); setup_powerhold(); MYSERIAL.begin(BAUDRATE); SERIAL_PROTOCOLLNPGM("start"); @@ -2015,14 +2030,15 @@ inline void gcode_G28() { if (verbose_level) { SERIAL_PROTOCOLPGM("Eqn coefficients: a: "); - SERIAL_PROTOCOL(plane_equation_coefficients[0] + 0.0001); + SERIAL_PROTOCOL_F(plane_equation_coefficients[0], 8); SERIAL_PROTOCOLPGM(" b: "); - SERIAL_PROTOCOL(plane_equation_coefficients[1] + 0.0001); + SERIAL_PROTOCOL_F(plane_equation_coefficients[1], 8); SERIAL_PROTOCOLPGM(" d: "); - SERIAL_PROTOCOLLN(plane_equation_coefficients[2] + 0.0001); + SERIAL_PROTOCOL_F(plane_equation_coefficients[2], 8); + SERIAL_EOL; if (verbose_level > 2) { SERIAL_PROTOCOLPGM("Mean of sampled points: "); - SERIAL_PROTOCOL_F(mean, 6); + SERIAL_PROTOCOL_F(mean, 8); SERIAL_EOL; } } @@ -2033,15 +2049,20 @@ inline void gcode_G28() { SERIAL_PROTOCOLPGM(" \nBed Height Topography: \n"); #if TOPO_ORIGIN == OriginFrontLeft + SERIAL_PROTOCOLPGM("+-----------+\n"); + SERIAL_PROTOCOLPGM("|...Back....|\n"); + SERIAL_PROTOCOLPGM("|Left..Right|\n"); + SERIAL_PROTOCOLPGM("|...Front...|\n"); + SERIAL_PROTOCOLPGM("+-----------+\n"); for (yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) #else for (yy = 0; yy < auto_bed_leveling_grid_points; yy++) #endif { #if TOPO_ORIGIN == OriginBackRight - for (xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--) - #else for (xx = 0; xx < auto_bed_leveling_grid_points; xx++) + #else + for (xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--) #endif { int ind = @@ -4130,6 +4151,11 @@ inline void gcode_M503() { plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], target[E_AXIS], fr60, active_extruder); //move z back plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], lastpos[E_AXIS], fr60, active_extruder); //final untretract #endif + + #ifdef FILAMENT_RUNOUT_SENSOR + filrunoutEnqued = false; + #endif + } #endif // FILAMENTCHANGEENABLE @@ -4184,7 +4210,7 @@ inline void gcode_M503() { * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S */ inline void gcode_M907() { - #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 + #if HAS_DIGIPOTSS for (int i=0;i -1 +#if HAS_DIGIPOTSS /** * M908: Control digital trimpot directly (M908 P S) @@ -4219,7 +4245,7 @@ inline void gcode_M907() { ); } -#endif // DIGIPOTSS_PIN +#endif // HAS_DIGIPOTSS // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. inline void gcode_M350() { @@ -4806,11 +4832,11 @@ void process_commands() { gcode_M907(); break; - #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 + #if HAS_DIGIPOTSS case 908: // M908 Control digital trimpot directly. gcode_M908(); break; - #endif // DIGIPOTSS_PIN + #endif // HAS_DIGIPOTSS case 350: // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. gcode_M350(); @@ -5269,6 +5295,12 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s const int KILL_DELAY = 10000; #endif +#if defined(FILRUNOUT_PIN) && FILRUNOUT_PIN > -1 + if(card.sdprinting) { + if(!(READ(FILRUNOUT_PIN))^FIL_RUNOUT_INVERTING) + filrunout(); } +#endif + #if defined(HOME_PIN) && HOME_PIN > -1 static int homeDebounceCount = 0; // poor man's debouncing count const int HOME_DEBOUNCE_DELAY = 10000; @@ -5417,6 +5449,16 @@ void kill() while(1) { /* Intentionally left empty */ } // Wait for reset } +#ifdef FILAMENT_RUNOUT_SENSOR + void filrunout() + { + if filrunoutEnqued == false { + filrunoutEnqued = true; + enquecommand("M600"); + } + } +#endif + void Stop() { disable_heater(); diff --git a/Marlin/Sd2Card.cpp b/Marlin/Sd2Card.cpp index 69ae777358..1182c99628 100644 --- a/Marlin/Sd2Card.cpp +++ b/Marlin/Sd2Card.cpp @@ -35,14 +35,14 @@ */ static void spiInit(uint8_t spiRate) { // See avr processor documentation - SPCR = (1 << SPE) | (1 << MSTR) | (spiRate >> 1); - SPSR = spiRate & 1 || spiRate == 6 ? 0 : 1 << SPI2X; + SPCR = BIT(SPE) | BIT(MSTR) | (spiRate >> 1); + SPSR = spiRate & 1 || spiRate == 6 ? 0 : BIT(SPI2X); } //------------------------------------------------------------------------------ /** SPI receive a byte */ static uint8_t spiRec() { SPDR = 0XFF; - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } return SPDR; } //------------------------------------------------------------------------------ @@ -52,18 +52,18 @@ void spiRead(uint8_t* buf, uint16_t nbyte) { if (nbyte-- == 0) return; SPDR = 0XFF; for (uint16_t i = 0; i < nbyte; i++) { - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } buf[i] = SPDR; SPDR = 0XFF; } - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } buf[nbyte] = SPDR; } //------------------------------------------------------------------------------ /** SPI send a byte */ static void spiSend(uint8_t b) { SPDR = b; - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } } //------------------------------------------------------------------------------ /** SPI send block - only one call so force inline */ @@ -71,12 +71,12 @@ static inline __attribute__((always_inline)) void spiSendBlock(uint8_t token, const uint8_t* buf) { SPDR = token; for (uint16_t i = 0; i < 512; i += 2) { - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } SPDR = buf[i]; - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } SPDR = buf[i + 1]; } - while (!(SPSR & (1 << SPIF))) { /* Intentionally left empty */ } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } } //------------------------------------------------------------------------------ #else // SOFTWARE_SPI diff --git a/Marlin/Sd2PinMap.h b/Marlin/Sd2PinMap.h index 93ab943cef..0556bd301c 100644 --- a/Marlin/Sd2PinMap.h +++ b/Marlin/Sd2PinMap.h @@ -334,9 +334,9 @@ static inline __attribute__((always_inline)) void setPinMode(uint8_t pin, uint8_t mode) { if (__builtin_constant_p(pin) && pin < digitalPinCount) { if (mode) { - *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; + *digitalPinMap[pin].ddr |= BIT(digitalPinMap[pin].bit); } else { - *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); + *digitalPinMap[pin].ddr &= ~BIT(digitalPinMap[pin].bit); } } else { badPinNumber(); @@ -354,9 +354,9 @@ static inline __attribute__((always_inline)) void fastDigitalWrite(uint8_t pin, uint8_t value) { if (__builtin_constant_p(pin) && pin < digitalPinCount) { if (value) { - *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; + *digitalPinMap[pin].port |= BIT(digitalPinMap[pin].bit); } else { - *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); + *digitalPinMap[pin].port &= ~BIT(digitalPinMap[pin].bit); } } else { badPinNumber(); diff --git a/Marlin/SdBaseFile.h b/Marlin/SdBaseFile.h index dea299a646..b0e77ecb48 100644 --- a/Marlin/SdBaseFile.h +++ b/Marlin/SdBaseFile.h @@ -171,9 +171,9 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) { return 2*(fatTime & 0X1F); } /** Default date for file timestamps is 1 Jan 2000 */ -uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | BIT(5) | 1; /** Default time for file timestamp is 1 am */ -uint16_t const FAT_DEFAULT_TIME = (1 << 11); +uint16_t const FAT_DEFAULT_TIME = BIT(11); //------------------------------------------------------------------------------ /** * \class SdBaseFile diff --git a/Marlin/SdVolume.cpp b/Marlin/SdVolume.cpp index f14d7bc70b..6297e2a7bd 100644 --- a/Marlin/SdVolume.cpp +++ b/Marlin/SdVolume.cpp @@ -360,7 +360,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) { blocksPerCluster_ = fbs->sectorsPerCluster; // determine shift that is same as multiply by blocksPerCluster_ clusterSizeShift_ = 0; - while (blocksPerCluster_ != (1 << clusterSizeShift_)) { + while (blocksPerCluster_ != BIT(clusterSizeShift_)) { // error if not power of 2 if (clusterSizeShift_++ > 7) goto fail; } diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index 4e2a567fff..c1b5d2b826 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -24,9 +24,9 @@ #define BLEN_A 0 #define BLEN_B 1 #define BLEN_C 2 - #define EN_A (1<= 0) + #endif //__PINS_H diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h index d85b778656..71287f6832 100644 --- a/Marlin/pins_RAMPS_13.h +++ b/Marlin/pins_RAMPS_13.h @@ -61,6 +61,11 @@ #define FILWIDTH_PIN 5 #endif +#if defined(FILAMENT_RUNOUT_SENSOR) + // define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector + #define FILRUNOUT_PIN 4 +#endif + #if MB(RAMPS_13_EFB) || MB(RAMPS_13_EFF) #define FAN_PIN 9 // (Sprinter config) #if MB(RAMPS_13_EFF) diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 999716612b..9bcad5661d 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -59,7 +59,7 @@ #include "language.h" //=========================================================================== -//=============================public variables ============================ +//============================= public variables ============================ //=========================================================================== unsigned long minsegmenttime; @@ -623,37 +623,37 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi #ifndef COREXY if (target[X_AXIS] < position[X_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(X_AXIS); } if (target[Y_AXIS] < position[Y_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(Y_AXIS); } #else if (target[X_AXIS] < position[X_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(X_HEAD); //AlexBorro: Save the real Extruder (head) direction in X Axis } if (target[Y_AXIS] < position[Y_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(Y_HEAD); //AlexBorro: Save the real Extruder (head) direction in Y Axis } if ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]) < 0) { - block->direction_bits |= (1<direction_bits |= BIT(X_AXIS); //AlexBorro: Motor A direction (Incorrectly implemented as X_AXIS) } if ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]) < 0) { - block->direction_bits |= (1<direction_bits |= BIT(Y_AXIS); //AlexBorro: Motor B direction (Incorrectly implemented as Y_AXIS) } #endif if (target[Z_AXIS] < position[Z_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(Z_AXIS); } if (target[E_AXIS] < position[E_AXIS]) { - block->direction_bits |= (1<direction_bits |= BIT(E_AXIS); } block->active_extruder = extruder; @@ -864,7 +864,7 @@ Having the real displacement of the head, we can calculate the total movement le old_direction_bits = block->direction_bits; segment_time = lround((float)segment_time / speed_factor); - if((direction_change & (1< -1 -#include +#if HAS_DIGIPOTSS + #include #endif //=========================================================================== -//=============================public variables ============================ +//============================= public variables ============================ //=========================================================================== block_t *current_block; // A pointer to the block currently being traced //=========================================================================== -//=============================private variables ============================ +//============================= private variables =========================== //=========================================================================== //static makes it impossible to be called from outside of this file by extern.! // Variables used by The Stepper Driver Interrupt static unsigned char out_bits; // The next stepping-bits to be output -static long counter_x, // Counter variables for the bresenham line tracer - counter_y, - counter_z, - counter_e; + +// Counter variables for the bresenham line tracer +static long counter_x, counter_y, counter_z, counter_e; volatile static unsigned long step_events_completed; // The number of step events executed in the current block + #ifdef ADVANCE static long advance_rate, advance, final_advance = 0; static long old_advance = 0; static long e_steps[4]; #endif + static long acceleration_time, deceleration_time; //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; static unsigned short acc_step_rate; // needed for deccelaration start point @@ -63,161 +64,198 @@ static char step_loops; static unsigned short OCR1A_nominal; static unsigned short step_loops_nominal; -volatile long endstops_trigsteps[3]={0,0,0}; -volatile long endstops_stepsTotal,endstops_stepsDone; -static volatile bool endstop_x_hit=false; -static volatile bool endstop_y_hit=false; -static volatile bool endstop_z_hit=false; +volatile long endstops_trigsteps[3] = { 0 }; +volatile long endstops_stepsTotal, endstops_stepsDone; +static volatile bool endstop_x_hit = false; +static volatile bool endstop_y_hit = false; +static volatile bool endstop_z_hit = false; + #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED -bool abort_on_endstop_hit = false; + bool abort_on_endstop_hit = false; #endif + #ifdef MOTOR_CURRENT_PWM_XY_PIN int motor_current_setting[3] = DEFAULT_PWM_MOTOR_CURRENT; #endif -static bool old_x_min_endstop=false; -static bool old_x_max_endstop=false; -static bool old_y_min_endstop=false; -static bool old_y_max_endstop=false; -static bool old_z_min_endstop=false; -static bool old_z_max_endstop=false; +static bool old_x_min_endstop = false, + old_x_max_endstop = false, + old_y_min_endstop = false, + old_y_max_endstop = false, + old_z_min_endstop = false, + old_z_max_endstop = false; static bool check_endstops = true; -volatile long count_position[NUM_AXIS] = { 0, 0, 0, 0}; -volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1}; +volatile long count_position[NUM_AXIS] = { 0 }; +volatile signed char count_direction[NUM_AXIS] = { 1 }; //=========================================================================== -//=============================functions ============================ +//================================ functions ================================ //=========================================================================== -#define CHECK_ENDSTOPS if(check_endstops) +#ifdef DUAL_X_CARRIAGE + #define X_APPLY_DIR(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_DIR_WRITE(v); \ + X2_DIR_WRITE(v); \ + } \ + else{ \ + if (current_block->active_extruder) \ + X2_DIR_WRITE(v); \ + else \ + X_DIR_WRITE(v); \ + } + #define X_APPLY_STEP(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_STEP_WRITE(v); \ + X2_STEP_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder != 0) \ + X2_STEP_WRITE(v); \ + else \ + X_STEP_WRITE(v); \ + } +#else + #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) + #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) +#endif + +#ifdef Y_DUAL_STEPPER_DRIVERS + #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v), Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR) + #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v), Y2_STEP_WRITE(v) +#else + #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) + #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) +#endif + +#ifdef Z_DUAL_STEPPER_DRIVERS + #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v), Z2_DIR_WRITE(v) + #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v), Z2_STEP_WRITE(v) +#else + #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v) + #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v) +#endif + +#define E_APPLY_STEP(v,Q) E_STEP_WRITE(v) // intRes = intIn1 * intIn2 >> 16 // uses: // r26 to store 0 // r27 to store the byte 1 of the 24 bit result #define MultiU16X8toH16(intRes, charIn1, intIn2) \ -asm volatile ( \ -"clr r26 \n\t" \ -"mul %A1, %B2 \n\t" \ -"movw %A0, r0 \n\t" \ -"mul %A1, %A2 \n\t" \ -"add %A0, r1 \n\t" \ -"adc %B0, r26 \n\t" \ -"lsr r0 \n\t" \ -"adc %A0, r26 \n\t" \ -"adc %B0, r26 \n\t" \ -"clr r1 \n\t" \ -: \ -"=&r" (intRes) \ -: \ -"d" (charIn1), \ -"d" (intIn2) \ -: \ -"r26" \ -) + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %A1, %A2 \n\t" \ + "add %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r0 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (charIn1), \ + "d" (intIn2) \ + : \ + "r26" \ + ) // intRes = longIn1 * longIn2 >> 24 // uses: // r26 to store 0 // r27 to store the byte 1 of the 48bit result #define MultiU24X24toH16(intRes, longIn1, longIn2) \ -asm volatile ( \ -"clr r26 \n\t" \ -"mul %A1, %B2 \n\t" \ -"mov r27, r1 \n\t" \ -"mul %B1, %C2 \n\t" \ -"movw %A0, r0 \n\t" \ -"mul %C1, %C2 \n\t" \ -"add %B0, r0 \n\t" \ -"mul %C1, %B2 \n\t" \ -"add %A0, r0 \n\t" \ -"adc %B0, r1 \n\t" \ -"mul %A1, %C2 \n\t" \ -"add r27, r0 \n\t" \ -"adc %A0, r1 \n\t" \ -"adc %B0, r26 \n\t" \ -"mul %B1, %B2 \n\t" \ -"add r27, r0 \n\t" \ -"adc %A0, r1 \n\t" \ -"adc %B0, r26 \n\t" \ -"mul %C1, %A2 \n\t" \ -"add r27, r0 \n\t" \ -"adc %A0, r1 \n\t" \ -"adc %B0, r26 \n\t" \ -"mul %B1, %A2 \n\t" \ -"add r27, r1 \n\t" \ -"adc %A0, r26 \n\t" \ -"adc %B0, r26 \n\t" \ -"lsr r27 \n\t" \ -"adc %A0, r26 \n\t" \ -"adc %B0, r26 \n\t" \ -"clr r1 \n\t" \ -: \ -"=&r" (intRes) \ -: \ -"d" (longIn1), \ -"d" (longIn2) \ -: \ -"r26" , "r27" \ -) + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "mov r27, r1 \n\t" \ + "mul %B1, %C2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %C1, %C2 \n\t" \ + "add %B0, r0 \n\t" \ + "mul %C1, %B2 \n\t" \ + "add %A0, r0 \n\t" \ + "adc %B0, r1 \n\t" \ + "mul %A1, %C2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %B2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %C1, %A2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %A2 \n\t" \ + "add r27, r1 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r27 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (longIn1), \ + "d" (longIn2) \ + : \ + "r26" , "r27" \ + ) // Some useful constants -#define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= (1< MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY; + if (step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY; - if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times - step_rate = (step_rate >> 2)&0x3fff; + if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times + step_rate = (step_rate >> 2) & 0x3fff; step_loops = 4; } - else if(step_rate > 10000) { // If steprate > 10kHz >> step 2 times - step_rate = (step_rate >> 1)&0x7fff; + else if (step_rate > 10000) { // If steprate > 10kHz >> step 2 times + step_rate = (step_rate >> 1) & 0x7fff; step_loops = 2; } else { step_loops = 1; } - if(step_rate < (F_CPU/500000)) step_rate = (F_CPU/500000); - step_rate -= (F_CPU/500000); // Correct for minimal speed - if(step_rate >= (8*256)){ // higher step rate + if (step_rate < (F_CPU / 500000)) step_rate = (F_CPU / 500000); + step_rate -= (F_CPU / 500000); // Correct for minimal speed + if (step_rate >= (8 * 256)) { // higher step rate unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0]; unsigned char tmp_step_rate = (step_rate & 0x00ff); unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2); @@ -271,7 +309,7 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { timer = (unsigned short)pgm_read_word_near(table_address); timer -= (((unsigned short)pgm_read_word_near(table_address+2) * (unsigned char)(step_rate & 0x0007))>>3); } - if(timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen) + if (timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen) return timer; } @@ -294,49 +332,45 @@ FORCE_INLINE void trapezoid_generator_reset() { acceleration_time = calc_timer(acc_step_rate); OCR1A = acceleration_time; -// SERIAL_ECHO_START; -// SERIAL_ECHOPGM("advance :"); -// SERIAL_ECHO(current_block->advance/256.0); -// SERIAL_ECHOPGM("advance rate :"); -// SERIAL_ECHO(current_block->advance_rate/256.0); -// SERIAL_ECHOPGM("initial advance :"); -// SERIAL_ECHO(current_block->initial_advance/256.0); -// SERIAL_ECHOPGM("final advance :"); -// SERIAL_ECHOLN(current_block->final_advance/256.0); - + // SERIAL_ECHO_START; + // SERIAL_ECHOPGM("advance :"); + // SERIAL_ECHO(current_block->advance/256.0); + // SERIAL_ECHOPGM("advance rate :"); + // SERIAL_ECHO(current_block->advance_rate/256.0); + // SERIAL_ECHOPGM("initial advance :"); + // SERIAL_ECHO(current_block->initial_advance/256.0); + // SERIAL_ECHOPGM("final advance :"); + // SERIAL_ECHOLN(current_block->final_advance/256.0); } // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. -ISR(TIMER1_COMPA_vect) -{ +ISR(TIMER1_COMPA_vect) { // If there is no current block, attempt to pop one from the buffer - if (current_block == NULL) { + if (!current_block) { // Anything in the buffer? current_block = plan_get_current_block(); - if (current_block != NULL) { + if (current_block) { current_block->busy = true; trapezoid_generator_reset(); counter_x = -(current_block->step_event_count >> 1); - counter_y = counter_x; - counter_z = counter_x; - counter_e = counter_x; + counter_y = counter_z = counter_e = counter_x; step_events_completed = 0; #ifdef Z_LATE_ENABLE - if(current_block->steps_z > 0) { + if (current_block->steps_z > 0) { enable_z(); OCR1A = 2000; //1ms wait return; } #endif -// #ifdef ADVANCE -// e_steps[current_block->active_extruder] = 0; -// #endif + // #ifdef ADVANCE + // e_steps[current_block->active_extruder] = 0; + // #endif } else { - OCR1A=2000; // 1kHz. + OCR1A = 2000; // 1kHz. } } @@ -344,186 +378,114 @@ ISR(TIMER1_COMPA_vect) // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt out_bits = current_block->direction_bits; - // Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY) - if((out_bits & (1<active_extruder != 0) - X2_DIR_WRITE(INVERT_X_DIR); - else - X_DIR_WRITE(INVERT_X_DIR); - } - #else - X_DIR_WRITE(INVERT_X_DIR); - #endif - count_direction[X_AXIS]=-1; + if (TEST(out_bits, X_AXIS)) { + X_APPLY_DIR(INVERT_X_DIR,0); + count_direction[X_AXIS] = -1; } - else{ - #ifdef DUAL_X_CARRIAGE - if (extruder_duplication_enabled){ - X_DIR_WRITE(!INVERT_X_DIR); - X2_DIR_WRITE( !INVERT_X_DIR); - } - else{ - if (current_block->active_extruder != 0) - X2_DIR_WRITE(!INVERT_X_DIR); - else - X_DIR_WRITE(!INVERT_X_DIR); - } - #else - X_DIR_WRITE(!INVERT_X_DIR); - #endif - count_direction[X_AXIS]=1; - } - if((out_bits & (1<steps_x == current_block->steps_y) && ((out_bits & (1<>X_AXIS != (out_bits & (1<>Y_AXIS))) // AlexBorro: If DeltaX == -DeltaY, the movement is only in Y axis - if ((out_bits & (1<steps_## axis > 0)) { \ + endstops_trigsteps[AXIS ##_AXIS] = count_position[AXIS ##_AXIS]; \ + endstop_## axis ##_hit = true; \ + step_events_completed = current_block->step_event_count; \ + } \ + old_## axis ##_## minmax ##_endstop = axis ##_## minmax ##_endstop; + + // Check X and Y endstops + if (check_endstops) { + #ifndef COREXY + if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular cartesians bot) + #else + // Head direction in -X axis for CoreXY bots. + // If DeltaX == -DeltaY, the movement is only in Y axis + if (TEST(out_bits, X_HEAD) && (current_block->steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) == TEST(out_bits, Y_AXIS)))) + #endif { // -direction - #ifdef DUAL_X_CARRIAGE + #ifdef DUAL_X_CARRIAGE // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1)) - #endif + #endif { - #if defined(X_MIN_PIN) && X_MIN_PIN > -1 - bool x_min_endstop=(READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTING); - if(x_min_endstop && old_x_min_endstop && (current_block->steps_x > 0)) - { - endstops_trigsteps[X_AXIS] = count_position[X_AXIS]; - endstop_x_hit=true; - step_events_completed = current_block->step_event_count; - } - old_x_min_endstop = x_min_endstop; - #endif + #if defined(X_MIN_PIN) && X_MIN_PIN >= 0 + UPDATE_ENDSTOP(x, X, min, MIN); + #endif } } - else - { // +direction - #ifdef DUAL_X_CARRIAGE + else { // +direction + #ifdef DUAL_X_CARRIAGE // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1)) - #endif + #endif { - #if defined(X_MAX_PIN) && X_MAX_PIN > -1 - bool x_max_endstop=(READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTING); - if(x_max_endstop && old_x_max_endstop && (current_block->steps_x > 0)) - { - endstops_trigsteps[X_AXIS] = count_position[X_AXIS]; - endstop_x_hit=true; - step_events_completed = current_block->step_event_count; - } - old_x_max_endstop = x_max_endstop; - #endif + #if defined(X_MAX_PIN) && X_MAX_PIN >= 0 + UPDATE_ENDSTOP(x, X, max, MAX); + #endif } } #ifndef COREXY - if ((out_bits & (1<steps_x == current_block->steps_y) && ((out_bits & (1<>X_AXIS == (out_bits & (1<>Y_AXIS))) // AlexBorro: If DeltaX == DeltaY, the movement is only in X axis - if ((out_bits & (1<steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) != TEST(out_bits, Y_AXIS)))) #endif { // -direction - #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1 - bool y_min_endstop=(READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTING); - if(y_min_endstop && old_y_min_endstop && (current_block->steps_y > 0)) - { - endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS]; - endstop_y_hit=true; - step_events_completed = current_block->step_event_count; - } - old_y_min_endstop = y_min_endstop; - #endif + #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0 + UPDATE_ENDSTOP(y, Y, min, MIN); + #endif } - else - { // +direction - #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1 - bool y_max_endstop=(READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTING); - if(y_max_endstop && old_y_max_endstop && (current_block->steps_y > 0)) - { - endstops_trigsteps[Y_AXIS] = count_position[Y_AXIS]; - endstop_y_hit=true; - step_events_completed = current_block->step_event_count; - } - old_y_max_endstop = y_max_endstop; - #endif - + else { // +direction + #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0 + UPDATE_ENDSTOP(y, Y, max, MAX); + #endif } } - if ((out_bits & (1< -1 - bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING); - if(z_min_endstop && old_z_min_endstop && (current_block->steps_z > 0)) { - endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; - endstop_z_hit=true; - step_events_completed = current_block->step_event_count; - } - old_z_min_endstop = z_min_endstop; + count_direction[Z_AXIS] = -1; + if (check_endstops) { + #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0 + UPDATE_ENDSTOP(z, Z, min, MIN); #endif } } else { // +direction Z_DIR_WRITE(!INVERT_Z_DIR); - #ifdef Z_DUAL_STEPPER_DRIVERS Z2_DIR_WRITE(!INVERT_Z_DIR); #endif - count_direction[Z_AXIS]=1; - CHECK_ENDSTOPS - { - #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1 - bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING); - if(z_max_endstop && old_z_max_endstop && (current_block->steps_z > 0)) { - endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; - endstop_z_hit=true; - step_events_completed = current_block->step_event_count; - } - old_z_max_endstop = z_max_endstop; + count_direction[Z_AXIS] = 1; + if (check_endstops) { + #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0 + UPDATE_ENDSTOP(z, Z, max, MAX); #endif } } #ifndef ADVANCE - if ((out_bits & (1<steps_e; - if (counter_e > 0) { - counter_e -= current_block->step_event_count; - if ((out_bits & (1<active_extruder]--; + counter_e += current_block->steps_e; + if (counter_e > 0) { + counter_e -= current_block->step_event_count; + e_steps[current_block->active_extruder] += TEST(out_bits, E_AXIS) ? -1 : 1; } - else { - e_steps[current_block->active_extruder]++; - } - } #endif //ADVANCE - counter_x += current_block->steps_x; - -#ifdef CONFIG_STEPPERS_TOSHIBA - /* The Toshiba stepper controller require much longer pulses. - * So we 'stage' decompose the pulses between high and low - * instead of doing each in turn. The extra tests add enough - * lag to allow it work with without needing NOPs - */ - if (counter_x > 0) X_STEP_WRITE(HIGH); - - counter_y += current_block->steps_y; - if (counter_y > 0) Y_STEP_WRITE(HIGH); - - counter_z += current_block->steps_z; - if (counter_z > 0) Z_STEP_WRITE(HIGH); - - #ifndef ADVANCE - counter_e += current_block->steps_e; - if (counter_e > 0) WRITE_E_STEP(HIGH); - #endif //!ADVANCE - - if (counter_x > 0) { - counter_x -= current_block->step_event_count; - count_position[X_AXIS] += count_direction[X_AXIS]; - X_STEP_WRITE(LOW); - } - - if (counter_y > 0) { - counter_y -= current_block->step_event_count; - count_position[Y_AXIS] += count_direction[Y_AXIS]; - Y_STEP_WRITE( LOW); - } - - if (counter_z > 0) { - counter_z -= current_block->step_event_count; - count_position[Z_AXIS] += count_direction[Z_AXIS]; - Z_STEP_WRITE(LOW); - } - - #ifndef ADVANCE - if (counter_e > 0) { - counter_e -= current_block->step_event_count; - count_position[E_AXIS] += count_direction[E_AXIS]; - WRITE_E_STEP(LOW); - } - #endif //!ADVANCE -#else - if (counter_x > 0) { - #ifdef DUAL_X_CARRIAGE - if (extruder_duplication_enabled){ - X_STEP_WRITE(!INVERT_X_STEP_PIN); - X2_STEP_WRITE( !INVERT_X_STEP_PIN); - } - else { - if (current_block->active_extruder != 0) - X2_STEP_WRITE( !INVERT_X_STEP_PIN); - else - X_STEP_WRITE(!INVERT_X_STEP_PIN); - } - #else - X_STEP_WRITE(!INVERT_X_STEP_PIN); - #endif - counter_x -= current_block->step_event_count; - count_position[X_AXIS] += count_direction[X_AXIS]; - #ifdef DUAL_X_CARRIAGE - if (extruder_duplication_enabled){ - X_STEP_WRITE(INVERT_X_STEP_PIN); - X2_STEP_WRITE(INVERT_X_STEP_PIN); - } - else { - if (current_block->active_extruder != 0) - X2_STEP_WRITE(INVERT_X_STEP_PIN); - else - X_STEP_WRITE(INVERT_X_STEP_PIN); - } - #else - X_STEP_WRITE(INVERT_X_STEP_PIN); - #endif - } - + #ifdef CONFIG_STEPPERS_TOSHIBA + /** + * The Toshiba stepper controller require much longer pulses. + * So we 'stage' decompose the pulses between high and low + * instead of doing each in turn. The extra tests add enough + * lag to allow it work with without needing NOPs + */ + counter_x += current_block->steps_x; + if (counter_x > 0) X_STEP_WRITE(HIGH); counter_y += current_block->steps_y; - if (counter_y > 0) { - Y_STEP_WRITE(!INVERT_Y_STEP_PIN); - - #ifdef Y_DUAL_STEPPER_DRIVERS - Y2_STEP_WRITE( !INVERT_Y_STEP_PIN); - #endif - - counter_y -= current_block->step_event_count; - count_position[Y_AXIS] += count_direction[Y_AXIS]; - Y_STEP_WRITE(INVERT_Y_STEP_PIN); - - #ifdef Y_DUAL_STEPPER_DRIVERS - Y2_STEP_WRITE( INVERT_Y_STEP_PIN); - #endif - } - - counter_z += current_block->steps_z; - if (counter_z > 0) { - Z_STEP_WRITE( !INVERT_Z_STEP_PIN); - #ifdef Z_DUAL_STEPPER_DRIVERS - Z2_STEP_WRITE(!INVERT_Z_STEP_PIN); + if (counter_y > 0) Y_STEP_WRITE(HIGH); + counter_z += current_block->steps_z; + if (counter_z > 0) Z_STEP_WRITE(HIGH); + #ifndef ADVANCE + counter_e += current_block->steps_e; + if (counter_e > 0) E_STEP_WRITE(HIGH); #endif - counter_z -= current_block->step_event_count; - count_position[Z_AXIS] += count_direction[Z_AXIS]; - Z_STEP_WRITE( INVERT_Z_STEP_PIN); + #define STEP_IF_COUNTER(axis, AXIS) \ + if (counter_## axis > 0) { + counter_## axis -= current_block->step_event_count; \ + count_position[AXIS ##_AXIS] += count_direction[AXIS ##_AXIS]; \ + AXIS ##_STEP_WRITE(LOW); + } - #ifdef Z_DUAL_STEPPER_DRIVERS - Z2_STEP_WRITE(INVERT_Z_STEP_PIN); + STEP_IF_COUNTER(x, X); + STEP_IF_COUNTER(y, Y); + STEP_IF_COUNTER(z, Z); + #ifndef ADVANCE + STEP_IF_COUNTER(e, E); #endif - } - #ifndef ADVANCE - counter_e += current_block->steps_e; - if (counter_e > 0) { - WRITE_E_STEP(!INVERT_E_STEP_PIN); - counter_e -= current_block->step_event_count; - count_position[E_AXIS] += count_direction[E_AXIS]; - WRITE_E_STEP(INVERT_E_STEP_PIN); - } - #endif //!ADVANCE -#endif // CONFIG_STEPPERS_TOSHIBA - step_events_completed += 1; - if(step_events_completed >= current_block->step_event_count) break; + #else // !CONFIG_STEPPERS_TOSHIBA + + #define APPLY_MOVEMENT(axis, AXIS) \ + counter_## axis += current_block->steps_## axis; \ + if (counter_## axis > 0) { \ + AXIS ##_APPLY_STEP(!INVERT_## AXIS ##_STEP_PIN,0); \ + counter_## axis -= current_block->step_event_count; \ + count_position[AXIS ##_AXIS] += count_direction[AXIS ##_AXIS]; \ + AXIS ##_APPLY_STEP(INVERT_## AXIS ##_STEP_PIN,0); \ + } + + APPLY_MOVEMENT(x, X); + APPLY_MOVEMENT(y, Y); + APPLY_MOVEMENT(z, Z); + #ifndef ADVANCE + APPLY_MOVEMENT(e, E); + #endif + + #endif // CONFIG_STEPPERS_TOSHIBA + step_events_completed++; + if (step_events_completed >= current_block->step_event_count) break; } // Calculare new timer value unsigned short timer; @@ -688,7 +572,7 @@ ISR(TIMER1_COMPA_vect) acc_step_rate += current_block->initial_rate; // upper limit - if(acc_step_rate > current_block->nominal_rate) + if (acc_step_rate > current_block->nominal_rate) acc_step_rate = current_block->nominal_rate; // step_rate to timer interval @@ -699,7 +583,7 @@ ISR(TIMER1_COMPA_vect) for(int8_t i=0; i < step_loops; i++) { advance += advance_rate; } - //if(advance > current_block->advance) advance = current_block->advance; + //if (advance > current_block->advance) advance = current_block->advance; // Do E steps + advance steps e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); old_advance = advance >>8; @@ -709,7 +593,7 @@ ISR(TIMER1_COMPA_vect) else if (step_events_completed > (unsigned long int)current_block->decelerate_after) { MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate); - if(step_rate > acc_step_rate) { // Check step_rate stays positive + if (step_rate > acc_step_rate) { // Check step_rate stays positive step_rate = current_block->final_rate; } else { @@ -717,7 +601,7 @@ ISR(TIMER1_COMPA_vect) } // lower limit - if(step_rate < current_block->final_rate) + if (step_rate < current_block->final_rate) step_rate = current_block->final_rate; // step_rate to timer interval @@ -728,7 +612,7 @@ ISR(TIMER1_COMPA_vect) for(int8_t i=0; i < step_loops; i++) { advance -= advance_rate; } - if(advance < final_advance) advance = final_advance; + if (advance < final_advance) advance = final_advance; // Do E steps + advance steps e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); old_advance = advance >>8; @@ -759,7 +643,7 @@ ISR(TIMER1_COMPA_vect) // Set E direction (Depends on E direction + advance) for(unsigned char i=0; i<4;i++) { if (e_steps[0] != 0) { - E0_STEP_WRITE( INVERT_E_STEP_PIN); + E0_STEP_WRITE(INVERT_E_STEP_PIN); if (e_steps[0] < 0) { E0_DIR_WRITE(INVERT_E0_DIR); e_steps[0]++; @@ -821,200 +705,186 @@ ISR(TIMER1_COMPA_vect) } #endif // ADVANCE -void st_init() -{ +void st_init() { digipot_init(); //Initialize Digipot Motor Current microstep_init(); //Initialize Microstepping Pins // initialise TMC Steppers #ifdef HAVE_TMCDRIVER - tmc_init(); + tmc_init(); #endif // initialise L6470 Steppers #ifdef HAVE_L6470DRIVER - L6470_init(); + L6470_init(); #endif - - //Initialize Dir Pins - #if defined(X_DIR_PIN) && X_DIR_PIN > -1 + // Initialize Dir Pins + #if defined(X_DIR_PIN) && X_DIR_PIN >= 0 X_DIR_INIT; #endif - #if defined(X2_DIR_PIN) && X2_DIR_PIN > -1 + #if defined(X2_DIR_PIN) && X2_DIR_PIN >= 0 X2_DIR_INIT; #endif - #if defined(Y_DIR_PIN) && Y_DIR_PIN > -1 + #if defined(Y_DIR_PIN) && Y_DIR_PIN >= 0 Y_DIR_INIT; - - #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_DIR_PIN) && (Y2_DIR_PIN > -1) - Y2_DIR_INIT; - #endif + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_DIR_PIN) && Y2_DIR_PIN >= 0 + Y2_DIR_INIT; + #endif #endif - #if defined(Z_DIR_PIN) && Z_DIR_PIN > -1 + #if defined(Z_DIR_PIN) && Z_DIR_PIN >= 0 Z_DIR_INIT; - - #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && (Z2_DIR_PIN > -1) + #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && Z2_DIR_PIN >= 0 Z2_DIR_INIT; #endif #endif - #if defined(E0_DIR_PIN) && E0_DIR_PIN > -1 + #if defined(E0_DIR_PIN) && E0_DIR_PIN >= 0 E0_DIR_INIT; #endif - #if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1) + #if defined(E1_DIR_PIN) && E1_DIR_PIN >= 0 E1_DIR_INIT; #endif - #if defined(E2_DIR_PIN) && (E2_DIR_PIN > -1) + #if defined(E2_DIR_PIN) && E2_DIR_PIN >= 0 E2_DIR_INIT; #endif - #if defined(E3_DIR_PIN) && (E3_DIR_PIN > -1) + #if defined(E3_DIR_PIN) && E3_DIR_PIN >= 0 E3_DIR_INIT; #endif //Initialize Enable Pins - steppers default to disabled. - #if defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 + #if defined(X_ENABLE_PIN) && X_ENABLE_PIN >= 0 X_ENABLE_INIT; - if(!X_ENABLE_ON) X_ENABLE_WRITE(HIGH); + if (!X_ENABLE_ON) X_ENABLE_WRITE(HIGH); #endif - #if defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1 + #if defined(X2_ENABLE_PIN) && X2_ENABLE_PIN >= 0 X2_ENABLE_INIT; - if(!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH); + if (!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH); #endif - #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 + #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN >= 0 Y_ENABLE_INIT; - if(!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH); + if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH); - #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_ENABLE_PIN) && (Y2_ENABLE_PIN > -1) + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_ENABLE_PIN) && Y2_ENABLE_PIN >= 0 Y2_ENABLE_INIT; - if(!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH); + if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH); #endif #endif - #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 + #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN >= 0 Z_ENABLE_INIT; - if(!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH); + if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH); - #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && (Z2_ENABLE_PIN > -1) + #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && Z2_ENABLE_PIN >= 0 Z2_ENABLE_INIT; - if(!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH); + if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH); #endif #endif - #if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1) + #if defined(E0_ENABLE_PIN) && E0_ENABLE_PIN >= 0 E0_ENABLE_INIT; - if(!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH); + if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH); #endif - #if defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1) + #if defined(E1_ENABLE_PIN) && E1_ENABLE_PIN >= 0 E1_ENABLE_INIT; - if(!E_ENABLE_ON) E1_ENABLE_WRITE(HIGH); + if (!E_ENABLE_ON) E1_ENABLE_WRITE(HIGH); #endif - #if defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1) + #if defined(E2_ENABLE_PIN) && E2_ENABLE_PIN >= 0 E2_ENABLE_INIT; - if(!E_ENABLE_ON) E2_ENABLE_WRITE(HIGH); + if (!E_ENABLE_ON) E2_ENABLE_WRITE(HIGH); #endif - #if defined(E3_ENABLE_PIN) && (E3_ENABLE_PIN > -1) + #if defined(E3_ENABLE_PIN) && E3_ENABLE_PIN >= 0 E3_ENABLE_INIT; - if(!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH); + if (!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH); #endif //endstops and pullups - #if defined(X_MIN_PIN) && X_MIN_PIN > -1 + #if defined(X_MIN_PIN) && X_MIN_PIN >= 0 SET_INPUT(X_MIN_PIN); #ifdef ENDSTOPPULLUP_XMIN WRITE(X_MIN_PIN,HIGH); #endif #endif - #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1 + #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0 SET_INPUT(Y_MIN_PIN); #ifdef ENDSTOPPULLUP_YMIN WRITE(Y_MIN_PIN,HIGH); #endif #endif - #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1 + #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0 SET_INPUT(Z_MIN_PIN); #ifdef ENDSTOPPULLUP_ZMIN WRITE(Z_MIN_PIN,HIGH); #endif #endif - #if defined(X_MAX_PIN) && X_MAX_PIN > -1 + #if defined(X_MAX_PIN) && X_MAX_PIN >= 0 SET_INPUT(X_MAX_PIN); #ifdef ENDSTOPPULLUP_XMAX WRITE(X_MAX_PIN,HIGH); #endif #endif - #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1 + #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0 SET_INPUT(Y_MAX_PIN); #ifdef ENDSTOPPULLUP_YMAX WRITE(Y_MAX_PIN,HIGH); #endif #endif - #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1 + #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0 SET_INPUT(Z_MAX_PIN); #ifdef ENDSTOPPULLUP_ZMAX WRITE(Z_MAX_PIN,HIGH); #endif #endif + #define AXIS_INIT(axis, AXIS, PIN) \ + AXIS ##_STEP_INIT; \ + AXIS ##_STEP_WRITE(INVERT_## PIN ##_STEP_PIN); \ + disable_## axis() - //Initialize Step Pins - #if defined(X_STEP_PIN) && (X_STEP_PIN > -1) - X_STEP_INIT; - X_STEP_WRITE(INVERT_X_STEP_PIN); - disable_x(); + #define E_AXIS_INIT(NUM) AXIS_INIT(e## NUM, E## NUM, E) + + // Initialize Step Pins + #if defined(X_STEP_PIN) && X_STEP_PIN >= 0 + AXIS_INIT(x, X, X); #endif - #if defined(X2_STEP_PIN) && (X2_STEP_PIN > -1) - X2_STEP_INIT; - X2_STEP_WRITE(INVERT_X_STEP_PIN); - disable_x(); + #if defined(X2_STEP_PIN) && X2_STEP_PIN >= 0 + AXIS_INIT(x, X2, X); #endif - #if defined(Y_STEP_PIN) && (Y_STEP_PIN > -1) - Y_STEP_INIT; - Y_STEP_WRITE(INVERT_Y_STEP_PIN); - #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_STEP_PIN) && (Y2_STEP_PIN > -1) + #if defined(Y_STEP_PIN) && Y_STEP_PIN >= 0 + #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_STEP_PIN) && Y2_STEP_PIN >= 0 Y2_STEP_INIT; Y2_STEP_WRITE(INVERT_Y_STEP_PIN); #endif - disable_y(); + AXIS_INIT(y, Y, Y); #endif - #if defined(Z_STEP_PIN) && (Z_STEP_PIN > -1) - Z_STEP_INIT; - Z_STEP_WRITE(INVERT_Z_STEP_PIN); - #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && (Z2_STEP_PIN > -1) + #if defined(Z_STEP_PIN) && Z_STEP_PIN >= 0 + #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && Z2_STEP_PIN >= 0 Z2_STEP_INIT; Z2_STEP_WRITE(INVERT_Z_STEP_PIN); #endif - disable_z(); + AXIS_INIT(z, Z, Z); #endif - #if defined(E0_STEP_PIN) && (E0_STEP_PIN > -1) - E0_STEP_INIT; - E0_STEP_WRITE(INVERT_E_STEP_PIN); - disable_e0(); + #if defined(E0_STEP_PIN) && E0_STEP_PIN >= 0 + E_AXIS_INIT(0); #endif - #if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1) - E1_STEP_INIT; - E1_STEP_WRITE(INVERT_E_STEP_PIN); - disable_e1(); + #if defined(E1_STEP_PIN) && E1_STEP_PIN >= 0 + E_AXIS_INIT(1); #endif - #if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1) - E2_STEP_INIT; - E2_STEP_WRITE(INVERT_E_STEP_PIN); - disable_e2(); + #if defined(E2_STEP_PIN) && E2_STEP_PIN >= 0 + E_AXIS_INIT(2); #endif - #if defined(E3_STEP_PIN) && (E3_STEP_PIN > -1) - E3_STEP_INIT; - E3_STEP_WRITE(INVERT_E_STEP_PIN); - disable_e3(); + #if defined(E3_STEP_PIN) && E3_STEP_PIN >= 0 + E_AXIS_INIT(3); #endif // waveform generation = 0100 = CTC - TCCR1B &= ~(1< -1 +// From Arduino DigitalPotControl example +void digitalPotWrite(int address, int value) { + #if HAS_DIGIPOTSS digitalWrite(DIGIPOTSS_PIN,LOW); // take the SS pin low to select the chip SPI.transfer(address); // send in the address and value via SPI: SPI.transfer(value); @@ -1268,16 +1057,17 @@ void digitalPotWrite(int address, int value) // From Arduino DigitalPotControl e #endif } -void digipot_init() //Initialize Digipot Motor Current -{ - #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 +// Initialize Digipot Motor Current +void digipot_init() { + #if HAS_DIGIPOTSS const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; SPI.begin(); pinMode(DIGIPOTSS_PIN, OUTPUT); - for(int i=0;i<=4;i++) + for (int i = 0; i <= 4; i++) { //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); digipot_current(i,digipot_motor_current[i]); + } #endif #ifdef MOTOR_CURRENT_PWM_XY_PIN pinMode(MOTOR_CURRENT_PWM_XY_PIN, OUTPUT); @@ -1291,69 +1081,64 @@ void digipot_init() //Initialize Digipot Motor Current #endif } -void digipot_current(uint8_t driver, int current) -{ - #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 +void digipot_current(uint8_t driver, int current) { + #if HAS_DIGIPOTSS const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; digitalPotWrite(digipot_ch[driver], current); #endif #ifdef MOTOR_CURRENT_PWM_XY_PIN - if (driver == 0) analogWrite(MOTOR_CURRENT_PWM_XY_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); - if (driver == 1) analogWrite(MOTOR_CURRENT_PWM_Z_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); - if (driver == 2) analogWrite(MOTOR_CURRENT_PWM_E_PIN, (long)current * 255L / (long)MOTOR_CURRENT_PWM_RANGE); + switch(driver) { + case 0: analogWrite(MOTOR_CURRENT_PWM_XY_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; + case 1: analogWrite(MOTOR_CURRENT_PWM_Z_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; + case 2: analogWrite(MOTOR_CURRENT_PWM_E_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; + } #endif } -void microstep_init() -{ +void microstep_init() { const uint8_t microstep_modes[] = MICROSTEP_MODES; - #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 - pinMode(E1_MS1_PIN,OUTPUT); - pinMode(E1_MS2_PIN,OUTPUT); + #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0 + pinMode(E1_MS1_PIN,OUTPUT); + pinMode(E1_MS2_PIN,OUTPUT); #endif - #if defined(X_MS1_PIN) && X_MS1_PIN > -1 - pinMode(X_MS1_PIN,OUTPUT); - pinMode(X_MS2_PIN,OUTPUT); - pinMode(Y_MS1_PIN,OUTPUT); - pinMode(Y_MS2_PIN,OUTPUT); - pinMode(Z_MS1_PIN,OUTPUT); - pinMode(Z_MS2_PIN,OUTPUT); - pinMode(E0_MS1_PIN,OUTPUT); - pinMode(E0_MS2_PIN,OUTPUT); - for(int i=0;i<=4;i++) microstep_mode(i,microstep_modes[i]); + #if defined(X_MS1_PIN) && X_MS1_PIN >= 0 + pinMode(X_MS1_PIN,OUTPUT); + pinMode(X_MS2_PIN,OUTPUT); + pinMode(Y_MS1_PIN,OUTPUT); + pinMode(Y_MS2_PIN,OUTPUT); + pinMode(Z_MS1_PIN,OUTPUT); + pinMode(Z_MS2_PIN,OUTPUT); + pinMode(E0_MS1_PIN,OUTPUT); + pinMode(E0_MS2_PIN,OUTPUT); + for (int i = 0; i <= 4; i++) microstep_mode(i, microstep_modes[i]); #endif } -void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) -{ - if(ms1 > -1) switch(driver) - { - case 0: digitalWrite( X_MS1_PIN,ms1); break; - case 1: digitalWrite( Y_MS1_PIN,ms1); break; - case 2: digitalWrite( Z_MS1_PIN,ms1); break; - case 3: digitalWrite(E0_MS1_PIN,ms1); break; - #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 - case 4: digitalWrite(E1_MS1_PIN,ms1); break; +void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) { + if (ms1 >= 0) switch(driver) { + case 0: digitalWrite(X_MS1_PIN, ms1); break; + case 1: digitalWrite(Y_MS1_PIN, ms1); break; + case 2: digitalWrite(Z_MS1_PIN, ms1); break; + case 3: digitalWrite(E0_MS1_PIN, ms1); break; + #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0 + case 4: digitalWrite(E1_MS1_PIN, ms1); break; #endif } - if(ms2 > -1) switch(driver) - { - case 0: digitalWrite( X_MS2_PIN,ms2); break; - case 1: digitalWrite( Y_MS2_PIN,ms2); break; - case 2: digitalWrite( Z_MS2_PIN,ms2); break; - case 3: digitalWrite(E0_MS2_PIN,ms2); break; - #if defined(E1_MS2_PIN) && E1_MS2_PIN > -1 - case 4: digitalWrite(E1_MS2_PIN,ms2); break; + if (ms2 >= 0) switch(driver) { + case 0: digitalWrite(X_MS2_PIN, ms2); break; + case 1: digitalWrite(Y_MS2_PIN, ms2); break; + case 2: digitalWrite(Z_MS2_PIN, ms2); break; + case 3: digitalWrite(E0_MS2_PIN, ms2); break; + #if defined(E1_MS2_PIN) && E1_MS2_PIN >= 0 + case 4: digitalWrite(E1_MS2_PIN, ms2); break; #endif } } -void microstep_mode(uint8_t driver, uint8_t stepping_mode) -{ - switch(stepping_mode) - { +void microstep_mode(uint8_t driver, uint8_t stepping_mode) { + switch(stepping_mode) { case 1: microstep_ms(driver,MICROSTEP1); break; case 2: microstep_ms(driver,MICROSTEP2); break; case 4: microstep_ms(driver,MICROSTEP4); break; @@ -1362,24 +1147,23 @@ void microstep_mode(uint8_t driver, uint8_t stepping_mode) } } -void microstep_readings() -{ - SERIAL_PROTOCOLPGM("MS1,MS2 Pins\n"); - SERIAL_PROTOCOLPGM("X: "); - SERIAL_PROTOCOL( digitalRead(X_MS1_PIN)); - SERIAL_PROTOCOLLN( digitalRead(X_MS2_PIN)); - SERIAL_PROTOCOLPGM("Y: "); - SERIAL_PROTOCOL( digitalRead(Y_MS1_PIN)); - SERIAL_PROTOCOLLN( digitalRead(Y_MS2_PIN)); - SERIAL_PROTOCOLPGM("Z: "); - SERIAL_PROTOCOL( digitalRead(Z_MS1_PIN)); - SERIAL_PROTOCOLLN( digitalRead(Z_MS2_PIN)); - SERIAL_PROTOCOLPGM("E0: "); - SERIAL_PROTOCOL( digitalRead(E0_MS1_PIN)); - SERIAL_PROTOCOLLN( digitalRead(E0_MS2_PIN)); - #if defined(E1_MS1_PIN) && E1_MS1_PIN > -1 - SERIAL_PROTOCOLPGM("E1: "); - SERIAL_PROTOCOL( digitalRead(E1_MS1_PIN)); - SERIAL_PROTOCOLLN( digitalRead(E1_MS2_PIN)); - #endif +void microstep_readings() { + SERIAL_PROTOCOLPGM("MS1,MS2 Pins\n"); + SERIAL_PROTOCOLPGM("X: "); + SERIAL_PROTOCOL(digitalRead(X_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(X_MS2_PIN)); + SERIAL_PROTOCOLPGM("Y: "); + SERIAL_PROTOCOL(digitalRead(Y_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(Y_MS2_PIN)); + SERIAL_PROTOCOLPGM("Z: "); + SERIAL_PROTOCOL(digitalRead(Z_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(Z_MS2_PIN)); + SERIAL_PROTOCOLPGM("E0: "); + SERIAL_PROTOCOL(digitalRead(E0_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(E0_MS2_PIN)); + #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0 + SERIAL_PROTOCOLPGM("E1: "); + SERIAL_PROTOCOL(digitalRead(E1_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN)); + #endif } diff --git a/Marlin/stepper.h b/Marlin/stepper.h index 2d316225a3..a1f2916090 100644 --- a/Marlin/stepper.h +++ b/Marlin/stepper.h @@ -25,26 +25,26 @@ #include "stepper_indirection.h" #if EXTRUDERS > 3 - #define WRITE_E_STEP(v) { if(current_block->active_extruder == 3) { E3_STEP_WRITE(v); } else { if(current_block->active_extruder == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}}} + #define E_STEP_WRITE(v) { if(current_block->active_extruder == 3) { E3_STEP_WRITE(v); } else { if(current_block->active_extruder == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}}} #define NORM_E_DIR() { if(current_block->active_extruder == 3) { E3_DIR_WRITE( !INVERT_E3_DIR); } else { if(current_block->active_extruder == 2) { E2_DIR_WRITE(!INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }}}} #define REV_E_DIR() { if(current_block->active_extruder == 3) { E3_DIR_WRITE(INVERT_E3_DIR); } else { if(current_block->active_extruder == 2) { E2_DIR_WRITE(INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { E1_DIR_WRITE(INVERT_E1_DIR); } else { E0_DIR_WRITE(INVERT_E0_DIR); }}}} #elif EXTRUDERS > 2 - #define WRITE_E_STEP(v) { if(current_block->active_extruder == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}} + #define E_STEP_WRITE(v) { if(current_block->active_extruder == 2) { E2_STEP_WRITE(v); } else { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }}} #define NORM_E_DIR() { if(current_block->active_extruder == 2) { E2_DIR_WRITE(!INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }}} #define REV_E_DIR() { if(current_block->active_extruder == 2) { E2_DIR_WRITE(INVERT_E2_DIR); } else { if(current_block->active_extruder == 1) { E1_DIR_WRITE(INVERT_E1_DIR); } else { E0_DIR_WRITE(INVERT_E0_DIR); }}} #elif EXTRUDERS > 1 #ifndef DUAL_X_CARRIAGE - #define WRITE_E_STEP(v) { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }} + #define E_STEP_WRITE(v) { if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }} #define NORM_E_DIR() { if(current_block->active_extruder == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }} #define REV_E_DIR() { if(current_block->active_extruder == 1) { E1_DIR_WRITE(INVERT_E1_DIR); } else { E0_DIR_WRITE(INVERT_E0_DIR); }} #else extern bool extruder_duplication_enabled; - #define WRITE_E_STEP(v) { if(extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }} + #define E_STEP_WRITE(v) { if(extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if(current_block->active_extruder == 1) { E1_STEP_WRITE(v); } else { E0_STEP_WRITE(v); }} #define NORM_E_DIR() { if(extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if(current_block->active_extruder == 1) { E1_DIR_WRITE(!INVERT_E1_DIR); } else { E0_DIR_WRITE(!INVERT_E0_DIR); }} #define REV_E_DIR() { if(extruder_duplication_enabled) { E0_DIR_WRITE(INVERT_E0_DIR); E1_DIR_WRITE(INVERT_E1_DIR); } else if(current_block->active_extruder == 1) { E1_DIR_WRITE(INVERT_E1_DIR); } else { E0_DIR_WRITE(INVERT_E0_DIR); }} #endif #else - #define WRITE_E_STEP(v) E0_STEP_WRITE(v) + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) #define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR) #define REV_E_DIR() E0_DIR_WRITE(INVERT_E0_DIR) #endif diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 4d01c701cc..9a30726639 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -75,6 +75,10 @@ //============================= public variables ============================ //=========================================================================== +#ifdef K1 // Defined in Configuration.h in the PID settings + #define K2 (1.0-K1) +#endif + // Sampling period of the temperature routine #ifdef PID_dT #undef PID_dT @@ -127,8 +131,6 @@ static volatile bool temp_meas_ready = false; static float pid_error[EXTRUDERS]; static float temp_iState_min[EXTRUDERS]; static float temp_iState_max[EXTRUDERS]; - // static float pid_input[EXTRUDERS]; - // static float pid_output[EXTRUDERS]; static bool pid_reset[EXTRUDERS]; #endif //PIDTEMP #ifdef PIDTEMPBED @@ -546,12 +548,102 @@ void bed_max_temp_error(void) { _temp_error(-1, MSG_MAXTEMP_BED_OFF, MSG_ERR_MAXTEMP_BED); } +float get_pid_output(int e) { + float pid_output; + #ifdef PIDTEMP + #ifndef PID_OPENLOOP + pid_error[e] = target_temperature[e] - current_temperature[e]; + if (pid_error[e] > PID_FUNCTIONAL_RANGE) { + pid_output = BANG_MAX; + pid_reset[e] = true; + } + else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) { + pid_output = 0; + pid_reset[e] = true; + } + else { + if (pid_reset[e]) { + temp_iState[e] = 0.0; + pid_reset[e] = false; + } + pTerm[e] = PID_PARAM(Kp,e) * pid_error[e]; + temp_iState[e] += pid_error[e]; + temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); + iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e]; + + dTerm[e] = K2 * PID_PARAM(Kd,e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e]; + pid_output = pTerm[e] + iTerm[e] - dTerm[e]; + if (pid_output > PID_MAX) { + if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration + pid_output = PID_MAX; + } + else if (pid_output < 0) { + if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration + pid_output = 0; + } + } + temp_dState[e] = current_temperature[e]; + #else + pid_output = constrain(target_temperature[e], 0, PID_MAX); + #endif //PID_OPENLOOP + + #ifdef PID_DEBUG + SERIAL_ECHO_START; + SERIAL_ECHO(MSG_PID_DEBUG); + SERIAL_ECHO(e); + SERIAL_ECHO(MSG_PID_DEBUG_INPUT); + SERIAL_ECHO(current_temperature[e]); + SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT); + SERIAL_ECHO(pid_output); + SERIAL_ECHO(MSG_PID_DEBUG_PTERM); + SERIAL_ECHO(pTerm[e]); + SERIAL_ECHO(MSG_PID_DEBUG_ITERM); + SERIAL_ECHO(iTerm[e]); + SERIAL_ECHO(MSG_PID_DEBUG_DTERM); + SERIAL_ECHOLN(dTerm[e]); + #endif //PID_DEBUG + + #else /* PID off */ + pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0; + #endif + + return pid_output; +} + +#ifdef PIDTEMPBED + float get_pid_output_bed() { + float pid_output; + #ifndef PID_OPENLOOP + pid_error_bed = target_temperature_bed - current_temperature_bed; + pTerm_bed = bedKp * pid_error_bed; + temp_iState_bed += pid_error_bed; + temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed); + iTerm_bed = bedKi * temp_iState_bed; + + dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed; + temp_dState_bed = current_temperature_bed; + + pid_output = pTerm_bed + iTerm_bed - dTerm_bed; + if (pid_output > MAX_BED_POWER) { + if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = MAX_BED_POWER; + } + else if (pid_output < 0) { + if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = 0; + } + #else + pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); + #endif // PID_OPENLOOP + + return pid_output; + } +#endif + void manage_heater() { if (!temp_meas_ready) return; - float pid_input, pid_output; - updateTemperaturesFromRawValues(); #ifdef HEATER_0_USES_MAX6675 @@ -569,69 +661,7 @@ void manage_heater() { thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS); #endif - #ifdef PIDTEMP - pid_input = current_temperature[e]; - - #ifndef PID_OPENLOOP - pid_error[e] = target_temperature[e] - pid_input; - if (pid_error[e] > PID_FUNCTIONAL_RANGE) { - pid_output = BANG_MAX; - pid_reset[e] = true; - } - else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) { - pid_output = 0; - pid_reset[e] = true; - } - else { - if (pid_reset[e] == true) { - temp_iState[e] = 0.0; - pid_reset[e] = false; - } - pTerm[e] = PID_PARAM(Kp,e) * pid_error[e]; - temp_iState[e] += pid_error[e]; - temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); - iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e]; - - //K1 defined in Configuration.h in the PID settings - #define K2 (1.0-K1) - dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e])) * K2 + (K1 * dTerm[e]); - pid_output = pTerm[e] + iTerm[e] - dTerm[e]; - if (pid_output > PID_MAX) { - if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration - pid_output = PID_MAX; - } - else if (pid_output < 0) { - if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration - pid_output = 0; - } - } - temp_dState[e] = pid_input; - #else - pid_output = constrain(target_temperature[e], 0, PID_MAX); - #endif //PID_OPENLOOP - - #ifdef PID_DEBUG - SERIAL_ECHO_START; - SERIAL_ECHO(MSG_PID_DEBUG); - SERIAL_ECHO(e); - SERIAL_ECHO(MSG_PID_DEBUG_INPUT); - SERIAL_ECHO(pid_input); - SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT); - SERIAL_ECHO(pid_output); - SERIAL_ECHO(MSG_PID_DEBUG_PTERM); - SERIAL_ECHO(pTerm[e]); - SERIAL_ECHO(MSG_PID_DEBUG_ITERM); - SERIAL_ECHO(iTerm[e]); - SERIAL_ECHO(MSG_PID_DEBUG_DTERM); - SERIAL_ECHOLN(dTerm[e]); - #endif //PID_DEBUG - - #else /* PID off */ - - pid_output = 0; - if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX; - - #endif + float pid_output = get_pid_output(e); // Check if temperature is within the correct range soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0; @@ -678,33 +708,7 @@ void manage_heater() { #endif #ifdef PIDTEMPBED - pid_input = current_temperature_bed; - - #ifndef PID_OPENLOOP - pid_error_bed = target_temperature_bed - pid_input; - pTerm_bed = bedKp * pid_error_bed; - temp_iState_bed += pid_error_bed; - temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed); - iTerm_bed = bedKi * temp_iState_bed; - - //K1 defined in Configuration.h in the PID settings - #define K2 (1.0-K1) - dTerm_bed = (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed); - temp_dState_bed = pid_input; - - pid_output = pTerm_bed + iTerm_bed - dTerm_bed; - if (pid_output > MAX_BED_POWER) { - if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration - pid_output = MAX_BED_POWER; - } - else if (pid_output < 0) { - if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration - pid_output = 0; - } - - #else - pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); - #endif //PID_OPENLOOP + float pid_output = get_pid_output_bed(); soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0; @@ -878,8 +882,8 @@ void tp_init() { #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector - MCUCR=(1< 7) ADCSRB = 1 << MUX5; else ADCSRB = 0; SET_ADMUX_ADCSRA(pin) + #define START_ADC(pin) if (pin > 7) ADCSRB = BIT(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin) #else #define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin) #endif diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 39b0923443..8575abbd0a 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1426,7 +1426,7 @@ void lcd_buttons_update() { WRITE(SHIFT_LD, HIGH); for(int8_t i = 0; i < 8; i++) { newbutton_reprapworld_keypad >>= 1; - if (READ(SHIFT_OUT)) newbutton_reprapworld_keypad |= (1 << 7); + if (READ(SHIFT_OUT)) newbutton_reprapworld_keypad |= BIT(7); WRITE(SHIFT_CLK, HIGH); WRITE(SHIFT_CLK, LOW); } @@ -1439,7 +1439,7 @@ void lcd_buttons_update() { unsigned char tmp_buttons = 0; for(int8_t i=0; i<8; i++) { newbutton >>= 1; - if (READ(SHIFT_OUT)) newbutton |= (1 << 7); + if (READ(SHIFT_OUT)) newbutton |= BIT(7); WRITE(SHIFT_CLK, HIGH); WRITE(SHIFT_CLK, LOW); } diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index d861e9d732..9d89f514de 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -57,20 +57,20 @@ void lcd_ignore_click(bool b=true); #ifdef NEWPANEL - #define EN_C (1< -1 // encoder click is directly connected #define BLEN_C 2 - #define EN_C (1<