![]() |
Repetier-Firmware
0.91
|
00001 /* 00002 This file is part of Repetier-Firmware. 00003 00004 Repetier-Firmware is free software: you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation, either version 3 of the License, or 00007 (at your option) any later version. 00008 00009 Repetier-Firmware is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with Repetier-Firmware. If not, see <http://www.gnu.org/licenses/>. 00016 00017 This firmware is a nearly complete rewrite of the sprinter firmware 00018 by kliment (https://github.com/kliment/Sprinter) 00019 which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 00020 # 00021 Functions in this file are used to communicate using ascii or repetier protocol. 00022 */ 00023 00024 #ifndef MOTION_H_INCLUDED 00025 #define MOTION_H_INCLUDED 00026 00028 #define FLAG_WARMUP 1 00029 #define FLAG_NOMINAL 2 00030 #define FLAG_DECELERATING 4 00031 #define FLAG_ACCELERATION_ENABLED 8 00032 #define FLAG_CHECK_ENDSTOPS 16 00033 #define FLAG_SKIP_ACCELERATING 32 00034 #define FLAG_SKIP_DEACCELERATING 64 00035 #define FLAG_BLOCKED 128 00036 00038 #define FLAG_JOIN_STEPPARAMS_COMPUTED 1 00039 00040 #define FLAG_JOIN_END_FIXED 2 00041 00042 #define FLAG_JOIN_START_FIXED 4 00043 00044 #define FLAG_JOIN_START_RETRACT 8 00045 00046 #define FLAG_JOIN_END_RETRACT 16 00047 00048 #define FLAG_JOIN_NO_RETRACT 32 00049 00050 #define FLAG_JOIN_WAIT_EXTRUDER_UP 64 00051 00052 #define FLAG_JOIN_WAIT_EXTRUDER_DOWN 128 00053 // Printing related data 00054 #if NONLINEAR_SYSTEM 00055 // Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast. 00056 // MAX_DELTA_SEGMENTS_PER_LINE * 00057 #define DELTA_CACHE_SIZE (MAX_DELTA_SEGMENTS_PER_LINE * MOVE_CACHE_SIZE) 00058 00059 class PrintLine; 00060 typedef struct 00061 { 00062 uint8_t dir; 00063 uint16_t deltaSteps[3]; 00064 inline void checkEndstops(PrintLine *cur,bool checkall); 00065 inline void setXMoveFinished() 00066 { 00067 dir&=~16; 00068 } 00069 inline void setYMoveFinished() 00070 { 00071 dir&=~32; 00072 } 00073 inline void setZMoveFinished() 00074 { 00075 dir&=~64; 00076 } 00077 inline void setXYMoveFinished() 00078 { 00079 dir&=~48; 00080 } 00081 inline bool isXPositiveMove() 00082 { 00083 return (dir & 17)==17; 00084 } 00085 inline bool isXNegativeMove() 00086 { 00087 return (dir & 17)==16; 00088 } 00089 inline bool isYPositiveMove() 00090 { 00091 return (dir & 34)==34; 00092 } 00093 inline bool isYNegativeMove() 00094 { 00095 return (dir & 34)==32; 00096 } 00097 inline bool isZPositiveMove() 00098 { 00099 return (dir & 68)==68; 00100 } 00101 inline bool isZNegativeMove() 00102 { 00103 return (dir & 68)==64; 00104 } 00105 inline bool isEPositiveMove() 00106 { 00107 return (dir & 136)==136; 00108 } 00109 inline bool isENegativeMove() 00110 { 00111 return (dir & 136)==128; 00112 } 00113 inline bool isXMove() 00114 { 00115 return (dir & 16); 00116 } 00117 inline bool isYMove() 00118 { 00119 return (dir & 32); 00120 } 00121 inline bool isXOrYMove() 00122 { 00123 return dir & 48; 00124 } 00125 inline bool isZMove() 00126 { 00127 return (dir & 64); 00128 } 00129 inline bool isEMove() 00130 { 00131 return (dir & 128); 00132 } 00133 inline bool isEOnlyMove() 00134 { 00135 return (dir & 240)==128; 00136 } 00137 inline bool isNoMove() 00138 { 00139 return (dir & 240)==0; 00140 } 00141 inline bool isXYZMove() 00142 { 00143 return dir & 112; 00144 } 00145 inline bool isMoveOfAxis(uint8_t axis) 00146 { 00147 return (dir & (16<<axis)); 00148 } 00149 inline void setMoveOfAxis(uint8_t axis) 00150 { 00151 dir |= 16<<axis; 00152 } 00153 inline void setPositiveDirectionForAxis(uint8_t axis) 00154 { 00155 dir |= 1<<axis; 00156 } 00157 } DeltaSegment; 00158 extern uint8_t lastMoveID; 00159 #endif 00160 class UIDisplay; 00161 class PrintLine // RAM usage: 24*4+15 = 113 Byte 00162 { 00163 friend class UIDisplay; 00164 #if CPU_ARCH==ARCH_ARM 00165 static volatile bool nlFlag; 00166 #endif 00167 static uint8_t linesPos; // Position for executing line movement 00168 static PrintLine lines[]; 00169 static uint8_t linesWritePos; // Position where we write the next cached line move 00170 uint8_t primaryAxis; 00171 volatile uint8_t flags; 00172 long timeInTicks; 00173 uint8_t joinFlags; 00174 uint8_t halfStep; 00175 uint8_t dir; 00176 long delta[4]; 00177 long error[4]; 00178 float speedX; 00179 float speedY; 00180 float speedZ; 00181 float speedE; 00182 float fullSpeed; 00183 float invFullSpeed; 00184 float accelerationDistance2; 00185 float maxJunctionSpeed; 00186 float startSpeed; 00187 float endSpeed; 00188 float minSpeed; 00189 float distance; 00190 #if NONLINEAR_SYSTEM 00191 uint8_t numDeltaSegments; 00192 uint8_t moveID; 00193 long numPrimaryStepPerSegment; 00194 DeltaSegment segments[MAX_DELTA_SEGMENTS_PER_LINE]; 00195 #endif 00196 ticks_t fullInterval; 00197 unsigned int accelSteps; 00198 unsigned int decelSteps; 00199 unsigned long accelerationPrim; 00200 unsigned long fAcceleration; 00201 speed_t vMax; 00202 speed_t vStart; 00203 speed_t vEnd; 00204 #ifdef USE_ADVANCE 00205 #ifdef ENABLE_QUADRATIC_ADVANCE 00206 long advanceRate; 00207 long advanceFull; 00208 long advanceStart; 00209 long advanceEnd; 00210 #endif 00211 unsigned int advanceL; 00212 #endif 00213 #ifdef DEBUG_STEPCOUNT 00214 long totalStepsRemaining; 00215 #endif 00216 public: 00217 long stepsRemaining; 00218 static PrintLine *cur; 00219 static volatile uint8_t linesCount; // Number of lines cached 0 = nothing to do 00220 inline bool areParameterUpToDate() 00221 { 00222 return joinFlags & FLAG_JOIN_STEPPARAMS_COMPUTED; 00223 } 00224 inline void invalidateParameter() 00225 { 00226 joinFlags &= ~FLAG_JOIN_STEPPARAMS_COMPUTED; 00227 } 00228 inline void setParameterUpToDate() 00229 { 00230 joinFlags |= FLAG_JOIN_STEPPARAMS_COMPUTED; 00231 } 00232 inline bool isStartSpeedFixed() 00233 { 00234 return joinFlags & FLAG_JOIN_START_FIXED; 00235 } 00236 inline void setStartSpeedFixed(bool newState) 00237 { 00238 joinFlags = (newState ? joinFlags | FLAG_JOIN_START_FIXED : joinFlags & ~FLAG_JOIN_START_FIXED); 00239 } 00240 inline void fixStartAndEndSpeed() 00241 { 00242 joinFlags |= FLAG_JOIN_END_FIXED | FLAG_JOIN_START_FIXED; 00243 } 00244 inline bool isEndSpeedFixed() 00245 { 00246 return joinFlags & FLAG_JOIN_END_FIXED; 00247 } 00248 inline void setEndSpeedFixed(bool newState) 00249 { 00250 joinFlags = (newState ? joinFlags | FLAG_JOIN_END_FIXED : joinFlags & ~FLAG_JOIN_END_FIXED); 00251 } 00252 inline bool isWarmUp() 00253 { 00254 return flags & FLAG_WARMUP; 00255 } 00256 inline uint8_t getWaitForXLinesFilled() 00257 { 00258 return primaryAxis; 00259 } 00260 inline void setWaitForXLinesFilled(uint8_t b) 00261 { 00262 primaryAxis = b; 00263 } 00264 inline bool isExtruderForwardMove() 00265 { 00266 return (dir & 136)==136; 00267 } 00268 inline void block() 00269 { 00270 flags |= FLAG_BLOCKED; 00271 } 00272 inline void unblock() 00273 { 00274 flags &= ~FLAG_BLOCKED; 00275 } 00276 inline bool isBlocked() 00277 { 00278 return flags & FLAG_BLOCKED; 00279 } 00280 inline bool isCheckEndstops() 00281 { 00282 return flags & FLAG_CHECK_ENDSTOPS; 00283 } 00284 inline bool isNominalMove() 00285 { 00286 return flags & FLAG_NOMINAL; 00287 } 00288 inline bool setNominalMove() 00289 { 00290 flags |= FLAG_NOMINAL; 00291 } 00292 inline void checkEndstops() 00293 { 00294 if(isCheckEndstops()) 00295 { 00296 if(isXNegativeMove() && Printer::isXMinEndstopHit()) 00297 setXMoveFinished(); 00298 if(isYNegativeMove() && Printer::isYMinEndstopHit()) 00299 setYMoveFinished(); 00300 if(isXPositiveMove() && Printer::isXMaxEndstopHit()) 00301 setXMoveFinished(); 00302 if(isYPositiveMove() && Printer::isYMaxEndstopHit()) 00303 setYMoveFinished(); 00304 } 00305 #if FEATURE_Z_PROBE 00306 if(Printer::isZProbingActive() && isZNegativeMove() && Printer::isZProbeHit()) 00307 { 00308 setZMoveFinished(); 00309 Printer::stepsRemainingAtZHit = stepsRemaining; 00310 } 00311 else 00312 #endif 00313 // Test Z-Axis every step if necessary, otherwise it could easyly ruin your printer! 00314 if(isZNegativeMove() && Printer::isZMinEndstopHit()) 00315 setZMoveFinished(); 00316 if(isZPositiveMove() && Printer::isZMaxEndstopHit()) 00317 { 00318 #if MAX_HARDWARE_ENDSTOP_Z 00319 Printer::stepsRemainingAtZHit = stepsRemaining; 00320 #endif 00321 setZMoveFinished(); 00322 } 00323 if(isZPositiveMove() && Printer::isZMaxEndstopHit()) 00324 setZMoveFinished(); 00325 } 00326 inline void setXMoveFinished() 00327 { 00328 #if DRIVE_SYSTEM==0 || NONLINEAR_SYSTEM 00329 dir&=~16; 00330 #else 00331 dir&=~48; 00332 #endif 00333 } 00334 inline void setYMoveFinished() 00335 { 00336 #if DRIVE_SYSTEM==0 || NONLINEAR_SYSTEM 00337 dir&=~32; 00338 #else 00339 dir&=~48; 00340 #endif 00341 } 00342 inline void setZMoveFinished() 00343 { 00344 dir&=~64; 00345 } 00346 inline void setXYMoveFinished() 00347 { 00348 dir&=~48; 00349 } 00350 inline bool isXPositiveMove() 00351 { 00352 return (dir & 17)==17; 00353 } 00354 inline bool isXNegativeMove() 00355 { 00356 return (dir & 17)==16; 00357 } 00358 inline bool isYPositiveMove() 00359 { 00360 return (dir & 34)==34; 00361 } 00362 inline bool isYNegativeMove() 00363 { 00364 return (dir & 34)==32; 00365 } 00366 inline bool isZPositiveMove() 00367 { 00368 return (dir & 68)==68; 00369 } 00370 inline bool isZNegativeMove() 00371 { 00372 return (dir & 68)==64; 00373 } 00374 inline bool isEPositiveMove() 00375 { 00376 return (dir & 136)==136; 00377 } 00378 inline bool isENegativeMove() 00379 { 00380 return (dir & 136)==128; 00381 } 00382 inline bool isXMove() 00383 { 00384 return (dir & 16); 00385 } 00386 inline bool isYMove() 00387 { 00388 return (dir & 32); 00389 } 00390 inline bool isXOrYMove() 00391 { 00392 return dir & 48; 00393 } 00394 inline bool isZMove() 00395 { 00396 return (dir & 64); 00397 } 00398 inline bool isEMove() 00399 { 00400 return (dir & 128); 00401 } 00402 inline bool isEOnlyMove() 00403 { 00404 return (dir & 240)==128; 00405 } 00406 inline bool isNoMove() 00407 { 00408 return (dir & 240)==0; 00409 } 00410 inline bool isXYZMove() 00411 { 00412 return dir & 112; 00413 } 00414 inline bool isMoveOfAxis(uint8_t axis) 00415 { 00416 return (dir & (16<<axis)); 00417 } 00418 inline void setMoveOfAxis(uint8_t axis) 00419 { 00420 dir |= 16<<axis; 00421 } 00422 inline void setPositiveDirectionForAxis(uint8_t axis) 00423 { 00424 dir |= 1<<axis; 00425 } 00426 inline static void resetPathPlanner() 00427 { 00428 linesCount = 0; 00429 linesPos = linesWritePos; 00430 } 00431 inline void updateAdvanceSteps(unsigned int v,uint8_t max_loops,bool accelerate) 00432 { 00433 #ifdef USE_ADVANCE 00434 if(!Printer::isAdvanceActivated()) return; 00435 #ifdef ENABLE_QUADRATIC_ADVANCE 00436 long advanceTarget = Printer::advanceExecuted; 00437 if(accelerate) 00438 { 00439 for(uint8_t loop = 0; loop<max_loops; loop++) advanceTarget += advanceRate; 00440 if(advanceTarget>advanceFull) 00441 advanceTarget = advanceFull; 00442 } 00443 else 00444 { 00445 for(uint8_t loop = 0; loop<max_loops; loop++) advanceTarget -= advanceRate; 00446 if(advanceTarget<advanceEnd) 00447 advanceTarget = advanceEnd; 00448 } 00449 long h = HAL::mulu16xu16to32(v,advanceL); 00450 int tred = ((advanceTarget + h) >> 16); 00451 HAL::forbidInterrupts(); 00452 Printer::extruderStepsNeeded += tred-Printer::advanceStepsSet; 00453 if(tred>0 && Printer::advanceStepsSet<=0) 00454 Printer::extruderStepsNeeded += Extruder::current->advanceBacklash; 00455 else if(tred<0 && Printer::advanceStepsSet>=0) 00456 Printer::extruderStepsNeeded -= Extruder::current->advanceBacklash; 00457 Printer::advanceStepsSet = tred; 00458 HAL::allowInterrupts(); 00459 Printer::advanceExecuted = advanceTarget; 00460 #else 00461 int tred = HAL::mulu6xu16shift16(v,advanceL); 00462 HAL::forbidInterrupts(); 00463 Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet; 00464 if(tred>0 && Printer::advanceStepsSet<=0) 00465 Printer::extruderStepsNeeded += (Extruder::current->advanceBacklash << 1); 00466 else if(tred<0 && Printer::advanceStepsSet>=0) 00467 Printer::extruderStepsNeeded -= (Extruder::current->advanceBacklash << 1); 00468 Printer::advanceStepsSet = tred; 00469 HAL::allowInterrupts(); 00470 #endif 00471 #endif 00472 } 00473 inline bool moveDecelerating() 00474 { 00475 if(stepsRemaining <= decelSteps) 00476 { 00477 if (!(flags & FLAG_DECELERATING)) 00478 { 00479 Printer::timer = 0; 00480 flags |= FLAG_DECELERATING; 00481 } 00482 return true; 00483 } 00484 else return false; 00485 } 00486 inline bool moveAccelerating() 00487 { 00488 return Printer::stepNumber <= accelSteps; 00489 } 00490 inline bool isFullstepping() 00491 { 00492 return halfStep == 4; 00493 } 00494 inline bool startXStep() 00495 { 00496 ANALYZER_ON(ANALYZER_CH6); 00497 #if DRIVE_SYSTEM==0 || !defined(XY_GANTRY) 00498 ANALYZER_ON(ANALYZER_CH2); 00499 WRITE(X_STEP_PIN,HIGH); 00500 #if FEATURE_TWO_XSTEPPER 00501 WRITE(X2_STEP_PIN,HIGH); 00502 #endif 00503 #else 00504 #if DRIVE_SYSTEM==1 00505 if(isXPositiveMove()) 00506 { 00507 Printer::motorX++; 00508 Printer::motorY++; 00509 } 00510 else 00511 { 00512 Printer::motorX--; 00513 Printer::motorY--; 00514 } 00515 #endif 00516 #if DRIVE_SYSTEM==2 00517 if(isXPositiveMove()) 00518 { 00519 Printer::motorX++; 00520 Printer::motorY--; 00521 } 00522 else 00523 { 00524 Printer::motorX--; 00525 Printer::motorY++; 00526 } 00527 #endif 00528 #endif 00529 #ifdef DEBUG_STEPCOUNT 00530 totalStepsRemaining--; 00531 #endif 00532 00533 } 00534 inline bool startYStep() 00535 { 00536 ANALYZER_ON(ANALYZER_CH7); 00537 #if DRIVE_SYSTEM==0 || !defined(XY_GANTRY) 00538 ANALYZER_ON(ANALYZER_CH3); 00539 WRITE(Y_STEP_PIN,HIGH); 00540 #if FEATURE_TWO_YSTEPPER 00541 WRITE(Y2_STEP_PIN,HIGH); 00542 #endif 00543 #else 00544 #if DRIVE_SYSTEM==1 00545 if(isYPositiveMove()) 00546 { 00547 Printer::motorX++; 00548 Printer::motorY--; 00549 } 00550 else 00551 { 00552 Printer::motorX--; 00553 Printer::motorY++; 00554 } 00555 #endif 00556 #if DRIVE_SYSTEM==2 00557 if(isYPositiveMove()) 00558 { 00559 Printer::motorX++; 00560 Printer::motorY++; 00561 } 00562 else 00563 { 00564 Printer::motorX--; 00565 Printer::motorY--; 00566 } 00567 #endif 00568 #endif // XY_GANTRY 00569 #ifdef DEBUG_STEPCOUNT 00570 totalStepsRemaining--; 00571 #endif 00572 } 00573 inline void startZStep() 00574 { 00575 WRITE(Z_STEP_PIN,HIGH); 00576 #if FEATURE_TWO_ZSTEPPER 00577 WRITE(Z2_STEP_PIN,HIGH); 00578 #endif 00579 } 00580 void updateStepsParameter(); 00581 inline float safeSpeed(); 00582 void calculateMove(float axis_diff[],uint8_t pathOptimize); 00583 void logLine(); 00584 inline long getWaitTicks() 00585 { 00586 return timeInTicks; 00587 } 00588 inline void setWaitTicks(long wait) 00589 { 00590 timeInTicks = wait; 00591 } 00592 00593 static inline bool hasLines() 00594 { 00595 return linesCount; 00596 } 00597 static inline void setCurrentLine() 00598 { 00599 cur = &lines[linesPos]; 00600 #if CPU_ARCH==ARCH_ARM 00601 PrintLine::nlFlag = true; 00602 #endif 00603 } 00604 static inline void removeCurrentLineForbidInterrupt() 00605 { 00606 linesPos++; 00607 if(linesPos>=MOVE_CACHE_SIZE) linesPos=0; 00608 cur = NULL; 00609 #if CPU_ARCH==ARCH_ARM 00610 nlFlag = false; 00611 #endif 00612 HAL::forbidInterrupts(); 00613 --linesCount; 00614 } 00615 static inline void pushLine() 00616 { 00617 linesWritePos++; 00618 if(linesWritePos>=MOVE_CACHE_SIZE) linesWritePos = 0; 00619 BEGIN_INTERRUPT_PROTECTED 00620 linesCount++; 00621 END_INTERRUPT_PROTECTED 00622 } 00623 static PrintLine *getNextWriteLine() 00624 { 00625 return &lines[linesWritePos]; 00626 } 00627 static inline void computeMaxJunctionSpeed(PrintLine *previous,PrintLine *current); 00628 static long bresenhamStep(); 00629 static void waitForXFreeLines(uint8_t b=1); 00630 static inline void forwardPlanner(uint8_t p); 00631 static inline void backwardPlanner(uint8_t p,uint8_t last); 00632 static void updateTrapezoids(); 00633 static uint8_t insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines); 00634 static void queueCartesianMove(uint8_t check_endstops,uint8_t pathOptimize); 00635 static void moveRelativeDistanceInSteps(long x,long y,long z,long e,float feedrate,bool waitEnd,bool check_endstop); 00636 #if ARC_SUPPORT 00637 static void arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise); 00638 #endif 00639 static inline void previousPlannerIndex(uint8_t &p) 00640 { 00641 p = (p ? p-1 : MOVE_CACHE_SIZE-1); 00642 } 00643 static inline void nextPlannerIndex(uint8_t& p) 00644 { 00645 p = (p==MOVE_CACHE_SIZE-1?0:p+1); 00646 } 00647 #if NONLINEAR_SYSTEM 00648 static void queueDeltaMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop); 00649 static inline void queueEMove(long e_diff,uint8_t check_endstops,uint8_t pathOptimize); 00650 inline uint16_t calculateDeltaSubSegments(uint8_t softEndstop); 00651 static inline void calculateDirectionAndDelta(long difference[], uint8_t *dir, long delta[]); 00652 static inline uint8_t calculateDistance(float axis_diff[], uint8_t dir, float *distance); 00653 #ifdef SOFTWARE_LEVELING && DRIVE_SYSTEM==3 00654 static void calculatePlane(long factors[], long p1[], long p2[], long p3[]); 00655 static float calcZOffset(long factors[], long pointX, long pointY); 00656 #endif 00657 #endif 00658 }; 00659 00660 00661 00662 #endif // MOTION_H_INCLUDED