Prusa MINI Firmware overview
Stepper Class Reference

#include <stepper.h>

Collaboration diagram for Stepper:

Public Member Functions

 Stepper ()
 

Static Public Member Functions

static void init ()
 
static void isr ()
 
static void stepper_pulse_phase_isr ()
 
static uint32_t stepper_block_phase_isr ()
 
static bool is_block_busy (const block_t *const block)
 
static int32_t position (const AxisEnum axis)
 
static void report_positions ()
 
static void wake_up ()
 
static FORCE_INLINE void quick_stop ()
 
static FORCE_INLINE bool motor_direction (const AxisEnum axis)
 
static FORCE_INLINE bool axis_is_moving (const AxisEnum axis)
 
static FORCE_INLINE uint8_t movement_extruder ()
 
static void endstop_triggered (const AxisEnum axis)
 
static int32_t triggered_position (const AxisEnum axis)
 
static void digitalPotWrite (const int16_t address, const int16_t value)
 
static void digipot_current (const uint8_t driver, const int16_t current)
 
static void microstep_ms (const uint8_t driver, const int8_t ms1, const int8_t ms2, const int8_t ms3)
 
static void microstep_mode (const uint8_t driver, const uint8_t stepping)
 
static void microstep_readings ()
 
static FORCE_INLINE void set_separate_multi_axis (const bool state)
 
static FORCE_INLINE void set_z_lock (const bool state)
 
static FORCE_INLINE void set_z2_lock (const bool state)
 
static void set_position (const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e)
 
static void set_position (const xyze_long_t &abce)
 
static void set_axis_position (const AxisEnum a, const int32_t &v)
 
static void set_directions ()
 

Static Public Attributes

static bool separate_multi_axis = false
 

Constructor & Destructor Documentation

◆ Stepper()

Stepper::Stepper ( )
340 {};

Member Function Documentation

◆ init()

void Stepper::init ( )
static
1992  {
1993 
1994  #if MB(ALLIGATOR)
1995  const float motor_current[] = MOTOR_CURRENT;
1996  unsigned int digipot_motor = 0;
1997  for (uint8_t i = 0; i < 3 + EXTRUDERS; i++) {
1998  digipot_motor = 255 * (motor_current[i] / 2.5);
1999  dac084s085::setValue(i, digipot_motor);
2000  }
2001  #endif//MB(ALLIGATOR)
2002 
2003  // Init Microstepping Pins
2004  #if HAS_MICROSTEPS
2005  microstep_init();
2006  #endif
2007 
2008  // Init Dir Pins
2009  #if HAS_X_DIR
2010  X_DIR_INIT;
2011  #endif
2012  #if HAS_X2_DIR
2013  X2_DIR_INIT;
2014  #endif
2015  #if HAS_Y_DIR
2016  Y_DIR_INIT;
2017  #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_DIR
2018  Y2_DIR_INIT;
2019  #endif
2020  #endif
2021  #if HAS_Z_DIR
2022  Z_DIR_INIT;
2023  #if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_DIR
2024  Z2_DIR_INIT;
2025  #endif
2026  #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_DIR
2027  Z3_DIR_INIT;
2028  #endif
2029  #endif
2030  #if HAS_E0_DIR
2031  E0_DIR_INIT;
2032  #endif
2033  #if HAS_E1_DIR
2034  E1_DIR_INIT;
2035  #endif
2036  #if HAS_E2_DIR
2037  E2_DIR_INIT;
2038  #endif
2039  #if HAS_E3_DIR
2040  E3_DIR_INIT;
2041  #endif
2042  #if HAS_E4_DIR
2043  E4_DIR_INIT;
2044  #endif
2045  #if HAS_E5_DIR
2046  E5_DIR_INIT;
2047  #endif
2048 
2049  // Init Enable Pins - steppers default to disabled.
2050  #if HAS_X_ENABLE
2051  X_ENABLE_INIT;
2053  #if EITHER(DUAL_X_CARRIAGE, X_DUAL_STEPPER_DRIVERS) && HAS_X2_ENABLE
2056  #endif
2057  #endif
2058  #if HAS_Y_ENABLE
2059  Y_ENABLE_INIT;
2061  #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_ENABLE
2064  #endif
2065  #endif
2066  #if HAS_Z_ENABLE
2067  Z_ENABLE_INIT;
2069  #if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_ENABLE
2072  #endif
2073  #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_ENABLE
2076  #endif
2077  #endif
2078  #if HAS_E0_ENABLE
2081  #endif
2082  #if HAS_E1_ENABLE
2085  #endif
2086  #if HAS_E2_ENABLE
2089  #endif
2090  #if HAS_E3_ENABLE
2093  #endif
2094  #if HAS_E4_ENABLE
2097  #endif
2098  #if HAS_E5_ENABLE
2101  #endif
2102 
2103  #define _STEP_INIT(AXIS) AXIS ##_STEP_INIT
2104  #define _WRITE_STEP(AXIS, HIGHLOW) AXIS ##_STEP_WRITE(HIGHLOW)
2105  #define _DISABLE(AXIS) disable_## AXIS()
2106 
2107  #define AXIS_INIT(AXIS, PIN) \
2108  _STEP_INIT(AXIS); \
2109  _WRITE_STEP(AXIS, _INVERT_STEP_PIN(PIN)); \
2110  _DISABLE(AXIS)
2111 
2112  #define E_AXIS_INIT(NUM) AXIS_INIT(E## NUM, E)
2113 
2114  // Init Step Pins
2115  #if HAS_X_STEP
2116  #if EITHER(X_DUAL_STEPPER_DRIVERS, DUAL_X_CARRIAGE)
2117  X2_STEP_INIT;
2119  #endif
2120  AXIS_INIT(X, X);
2121  #endif
2122 
2123  #if HAS_Y_STEP
2124  #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
2125  Y2_STEP_INIT;
2127  #endif
2128  AXIS_INIT(Y, Y);
2129  #endif
2130 
2131  #if HAS_Z_STEP
2132  #if Z_MULTI_STEPPER_DRIVERS
2133  Z2_STEP_INIT;
2135  #endif
2136  #if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
2137  Z3_STEP_INIT;
2139  #endif
2140  AXIS_INIT(Z, Z);
2141  #endif
2142 
2143  #if E_STEPPERS > 0 && HAS_E0_STEP
2144  E_AXIS_INIT(0);
2145  #endif
2146  #if E_STEPPERS > 1 && HAS_E1_STEP
2147  E_AXIS_INIT(1);
2148  #endif
2149  #if E_STEPPERS > 2 && HAS_E2_STEP
2150  E_AXIS_INIT(2);
2151  #endif
2152  #if E_STEPPERS > 3 && HAS_E3_STEP
2153  E_AXIS_INIT(3);
2154  #endif
2155  #if E_STEPPERS > 4 && HAS_E4_STEP
2156  E_AXIS_INIT(4);
2157  #endif
2158  #if E_STEPPERS > 5 && HAS_E5_STEP
2159  E_AXIS_INIT(5);
2160  #endif
2161 
2162  #if DISABLED(I2S_STEPPER_STREAM)
2163  HAL_timer_start(STEP_TIMER_NUM, 122); // Init Stepper ISR to 122 Hz for quick starting
2165  sei();
2166  #endif
2167 
2168  // Init direction bits for first moves
2169  last_direction_bits = 0
2170  | (INVERT_X_DIR ? _BV(X_AXIS) : 0)
2171  | (INVERT_Y_DIR ? _BV(Y_AXIS) : 0)
2172  | (INVERT_Z_DIR ? _BV(Z_AXIS) : 0);
2173 
2174  set_directions();
2175 
2176  #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM
2177  #if HAS_MOTOR_CURRENT_PWM
2178  initialized = true;
2179  #endif
2180  digipot_init();
2181  #endif
2182 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isr()

void Stepper::isr ( )
static

This needs to avoid a race-condition caused by interleaving of interrupts required by both the LA and Stepper algorithms.

Assume the following tick times for stepper pulses: Stepper ISR (S): 1 1000 2000 3000 4000 Linear Adv. (E): 10 1010 2010 3010 4010

The current algorithm tries to interleave them, giving: 1:S 10:E 1000:S 1010:E 2000:S 2010:E 3000:S 3010:E 4000:S 4010:E

Ideal timing would yield these delta periods: 1:S 9:E 990:S 10:E 990:S 10:E 990:S 10:E 990:S 10:E

But, since each event must fire an ISR with a minimum duration, the minimum delta might be 900, so deltas under 900 get rounded up: 900:S d900:E d990:S d900:E d990:S d900:E d990:S d900:E d990:S d900:E

It works, but divides the speed of all motors by half, leading to a sudden reduction to 1/2 speed! Such jumps in speed lead to lost steps (not even accounting for double/quad stepping, which makes it even worse).

The following section must be done with global interrupts disabled. We want nothing to interrupt it, as that could mess the calculations we do for the next value to program in the period register of the stepper timer and lead to skipped ISRs (if the value we happen to program is less than the current count due to something preempting between the read and the write of the new period value).

Get the current tick value + margin Assuming at least 6µs between calls to this ISR... On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin

NB: If for some reason the stepper monopolizes the MPU, eventually the timer will wrap around (and so will 'next_isr_ticks'). So, limit the loop to 10 iterations. Beyond that, there's no way to ensure correct pulse timing, since the MCU isn't fast enough.

1262  {
1263  #ifndef __AVR__
1264  // Disable interrupts, to avoid ISR preemption while we reprogram the period
1265  // (AVR enters the ISR with global interrupts disabled, so no need to do it here)
1266  DISABLE_ISRS();
1267  #endif
1268 
1269  // Program timer compare for the maximum period, so it does NOT
1270  // flag an interrupt while this ISR is running - So changes from small
1271  // periods to big periods are respected and the timer does not reset to 0
1273 
1274  // Count of ticks for the next ISR
1275  hal_timer_t next_isr_ticks = 0;
1276 
1277  // Limit the amount of iterations
1278  uint8_t max_loops = 10;
1279 
1280  // We need this variable here to be able to use it in the following loop
1281  hal_timer_t min_ticks;
1282  do {
1283  // Enable ISRs to reduce USART processing latency
1284  ENABLE_ISRS();
1285 
1286  // Run main stepping pulse phase ISR if we have to
1287  if (!nextMainISR) Stepper::stepper_pulse_phase_isr();
1288 
1289  #if ENABLED(LIN_ADVANCE)
1290  // Run linear advance stepper ISR if we have to
1291  if (!nextAdvanceISR) nextAdvanceISR = Stepper::advance_isr();
1292  #endif
1293 
1294  // ^== Time critical. NOTHING besides pulse generation should be above here!!!
1295 
1296  // Run main stepping block processing ISR if we have to
1297  if (!nextMainISR) nextMainISR = Stepper::stepper_block_phase_isr();
1298 
1299  uint32_t interval =
1300  #if ENABLED(LIN_ADVANCE)
1301  _MIN(nextAdvanceISR, nextMainISR) // Nearest time interval
1302  #else
1303  nextMainISR // Remaining stepper ISR time
1304  #endif
1305  ;
1306 
1307  // Limit the value to the maximum possible value of the timer
1308  NOMORE(interval, uint32_t(HAL_TIMER_TYPE_MAX));
1309 
1310  // Compute the time remaining for the main isr
1311  nextMainISR -= interval;
1312 
1313  #if ENABLED(LIN_ADVANCE)
1314  // Compute the time remaining for the advance isr
1315  if (nextAdvanceISR != LA_ADV_NEVER) nextAdvanceISR -= interval;
1316  #endif
1317 
1318  /**
1319  * This needs to avoid a race-condition caused by interleaving
1320  * of interrupts required by both the LA and Stepper algorithms.
1321  *
1322  * Assume the following tick times for stepper pulses:
1323  * Stepper ISR (S): 1 1000 2000 3000 4000
1324  * Linear Adv. (E): 10 1010 2010 3010 4010
1325  *
1326  * The current algorithm tries to interleave them, giving:
1327  * 1:S 10:E 1000:S 1010:E 2000:S 2010:E 3000:S 3010:E 4000:S 4010:E
1328  *
1329  * Ideal timing would yield these delta periods:
1330  * 1:S 9:E 990:S 10:E 990:S 10:E 990:S 10:E 990:S 10:E
1331  *
1332  * But, since each event must fire an ISR with a minimum duration, the
1333  * minimum delta might be 900, so deltas under 900 get rounded up:
1334  * 900:S d900:E d990:S d900:E d990:S d900:E d990:S d900:E d990:S d900:E
1335  *
1336  * It works, but divides the speed of all motors by half, leading to a sudden
1337  * reduction to 1/2 speed! Such jumps in speed lead to lost steps (not even
1338  * accounting for double/quad stepping, which makes it even worse).
1339  */
1340 
1341  // Compute the tick count for the next ISR
1342  next_isr_ticks += interval;
1343 
1344  /**
1345  * The following section must be done with global interrupts disabled.
1346  * We want nothing to interrupt it, as that could mess the calculations
1347  * we do for the next value to program in the period register of the
1348  * stepper timer and lead to skipped ISRs (if the value we happen to program
1349  * is less than the current count due to something preempting between the
1350  * read and the write of the new period value).
1351  */
1352  DISABLE_ISRS();
1353 
1354  /**
1355  * Get the current tick value + margin
1356  * Assuming at least 6µs between calls to this ISR...
1357  * On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
1358  * On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
1359  */
1361  #ifdef __AVR__
1362  8
1363  #else
1364  1
1365  #endif
1367  );
1368 
1369  /**
1370  * NB: If for some reason the stepper monopolizes the MPU, eventually the
1371  * timer will wrap around (and so will 'next_isr_ticks'). So, limit the
1372  * loop to 10 iterations. Beyond that, there's no way to ensure correct pulse
1373  * timing, since the MCU isn't fast enough.
1374  */
1375  if (!--max_loops) next_isr_ticks = min_ticks;
1376 
1377  // Advance pulses if not enough time to wait for the next ISR
1378  } while (next_isr_ticks < min_ticks);
1379 
1380  // Now 'next_isr_ticks' contains the period to the next Stepper ISR - And we are
1381  // sure that the time has not arrived yet - Warrantied by the scheduler
1382 
1383  // Set the next ISR to fire at the proper time
1385 
1386  // Don't forget to finally reenable interrupts
1387  ENABLE_ISRS();
1388 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stepper_pulse_phase_isr()

void Stepper::stepper_pulse_phase_isr ( )
static

This phase of the ISR should ONLY create the pulses for the steppers. This prevents jitter caused by the interval between the start of the interrupt and the start of the pulses. DON'T add any logic ahead of the call to this method that might cause variation in the timing. The aim is to keep pulse timing as regular as possible.

1397  {
1398 
1399  // If we must abort the current block, do so!
1400  if (abort_current_block) {
1401  abort_current_block = false;
1402  if (current_block) {
1403  axis_did_move = 0;
1404  current_block = nullptr;
1406  }
1407  }
1408 
1409  // If there is no current block, do nothing
1410  if (!current_block) return;
1411 
1412  // Count of pending loops and events for this iteration
1413  const uint32_t pending_events = step_event_count - step_events_completed;
1414  uint8_t events_to_do = _MIN(pending_events, steps_per_isr);
1415 
1416  // Just update the value we will get at the end of the loop
1417  step_events_completed += events_to_do;
1418 
1419  // Get the timer count and estimate the end of the pulse
1421 
1422  const hal_timer_t added_step_ticks = hal_timer_t(ADDED_STEP_TICKS);
1423 
1424  // Take multiple steps per interrupt (For high speed moves)
1425  do {
1426 
1427  #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
1428  #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN
1429 
1430  // Start an active pulse, if Bresenham says so, and update position
1431  #define PULSE_START(AXIS) do{ \
1432  delta_error[_AXIS(AXIS)] += advance_dividend[_AXIS(AXIS)]; \
1433  if (delta_error[_AXIS(AXIS)] >= 0) { \
1434  _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); \
1435  count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
1436  } \
1437  }while(0)
1438 
1439  // Stop an active pulse, if any, and adjust error term
1440  #define PULSE_STOP(AXIS) do { \
1441  if (delta_error[_AXIS(AXIS)] >= 0) { \
1442  delta_error[_AXIS(AXIS)] -= advance_divisor; \
1443  _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), 0); \
1444  } \
1445  }while(0)
1446 
1447  // Pulse start
1448  #if HAS_X_STEP
1449  PULSE_START(X);
1450  #endif
1451  #if HAS_Y_STEP
1452  PULSE_START(Y);
1453  #endif
1454  #if HAS_Z_STEP
1455  PULSE_START(Z);
1456  #endif
1457 
1458  // Pulse Extruders
1459  // Tick the E axis, correct error term and update position
1460  #if EITHER(LIN_ADVANCE, MIXING_EXTRUDER)
1461  delta_error.e += advance_dividend.e;
1462  if (delta_error.e >= 0) {
1463  //count_position.e += count_direction.e;
1464  //temporary solution to get count_position[E_AXIS] with enabled LA
1465  //because with LA count_direction[E_AXIS] not set and is always =0
1466  //we use motor_direction(E_AXIS) instead of count_direction[E_AXIS]
1467  count_position[E_AXIS] += motor_direction(E_AXIS)?-1:1;
1468  #if ENABLED(LIN_ADVANCE)
1469  delta_error.e -= advance_divisor;
1470  // Don't step E here - But remember the number of steps to perform
1471  motor_direction(E_AXIS) ? --LA_steps : ++LA_steps;
1472  #else // !LIN_ADVANCE && MIXING_EXTRUDER
1473  // Don't adjust delta_error.e here!
1474  // Being positive is the criteria for ending the pulse.
1476  #endif
1477  }
1478  #else // !LIN_ADVANCE && !MIXING_EXTRUDER
1479  #if HAS_E0_STEP
1480  PULSE_START(E);
1481  #endif
1482  #endif
1483 
1484  #if ENABLED(I2S_STEPPER_STREAM)
1485  i2s_push_sample();
1486  #endif
1487 
1488  // TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s
1489  #if MINIMUM_STEPPER_PULSE && DISABLED(I2S_STEPPER_STREAM)
1490  // Just wait for the requested pulse duration
1491  while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
1492  #endif
1493 
1494  // Add the delay needed to ensure the maximum driver rate is enforced
1495  if (signed(added_step_ticks) > 0) pulse_end += hal_timer_t(added_step_ticks);
1496 
1497  // Pulse stop
1498  #if HAS_X_STEP
1499  PULSE_STOP(X);
1500  #endif
1501  #if HAS_Y_STEP
1502  PULSE_STOP(Y);
1503  #endif
1504  #if HAS_Z_STEP
1505  PULSE_STOP(Z);
1506  #endif
1507 
1508  #if DISABLED(LIN_ADVANCE)
1509  #if ENABLED(MIXING_EXTRUDER)
1510  if (delta_error.e >= 0) {
1511  delta_error.e -= advance_divisor;
1513  }
1514  #else // !MIXING_EXTRUDER
1515  #if HAS_E0_STEP
1516  PULSE_STOP(E);
1517  #endif
1518  #endif
1519  #endif // !LIN_ADVANCE
1520 
1521  // Decrement the count of pending pulses to do
1522  --events_to_do;
1523 
1524  // For minimum pulse time wait after stopping pulses also
1525  if (events_to_do) {
1526  // Just wait for the requested pulse duration
1527  while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
1528  #if MINIMUM_STEPPER_PULSE
1529  // Add to the value, the time that the pulse must be active (to be used on the next loop)
1530  pulse_end += hal_timer_t(MIN_PULSE_TICKS);
1531  #endif
1532  }
1533 
1534  } while (events_to_do);
1535 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stepper_block_phase_isr()

uint32_t Stepper::stepper_block_phase_isr ( )
static

Head direction in -X axis for CoreXY and CoreXZ bots.

If steps differ, both axes are moving. If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below) If DeltaA == DeltaB, the movement is only in the 1st axis (X)

Head direction in -Y axis for CoreXY / CoreYZ bots.

If steps differ, both axes are moving If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y) If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)

Head direction in -Z axis for CoreXZ or CoreYZ bots.

If steps differ, both axes are moving If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above) If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)

1541  {
1542 
1543  // If no queued movements, just wait 1ms for the next move
1544  uint32_t interval = (STEPPER_TIMER_RATE / 1000);
1545 
1546  // If there is a current block
1547  if (current_block) {
1548 
1549  // If current block is finished, reset pointer
1550  if (step_events_completed >= step_event_count) {
1551  #ifdef FILAMENT_RUNOUT_DISTANCE_MM
1552  runout.block_completed(current_block);
1553  #endif
1554  axis_did_move = 0;
1555  current_block = nullptr;
1557  }
1558  else {
1559  // Step events not completed yet...
1560 
1561  // Are we in acceleration phase ?
1562  if (step_events_completed <= accelerate_until) { // Calculate new timer value
1563 
1564  #if ENABLED(S_CURVE_ACCELERATION)
1565  // Get the next speed to use (Jerk limited!)
1566  uint32_t acc_step_rate =
1567  acceleration_time < current_block->acceleration_time
1568  ? _eval_bezier_curve(acceleration_time)
1569  : current_block->cruise_rate;
1570  #else
1571  acc_step_rate = STEP_MULTIPLY(acceleration_time, current_block->acceleration_rate) + current_block->initial_rate;
1572  NOMORE(acc_step_rate, current_block->nominal_rate);
1573  #endif
1574 
1575  // acc_step_rate is in steps/second
1576 
1577  // step_rate to timer interval and steps per stepper isr
1578  interval = calc_timer_interval(acc_step_rate, oversampling_factor, &steps_per_isr);
1579  acceleration_time += interval;
1580 
1581  #if ENABLED(LIN_ADVANCE)
1582  if (LA_use_advance_lead) {
1583  // Fire ISR if final adv_rate is reached
1584  if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
1585  }
1586  else if (LA_steps) nextAdvanceISR = 0;
1587  #endif // LIN_ADVANCE
1588  }
1589  // Are we in Deceleration phase ?
1590  else if (step_events_completed > decelerate_after) {
1591  uint32_t step_rate;
1592 
1593  #if ENABLED(S_CURVE_ACCELERATION)
1594  // If this is the 1st time we process the 2nd half of the trapezoid...
1595  if (!bezier_2nd_half) {
1596  // Initialize the Bézier speed curve
1597  _calc_bezier_curve_coeffs(current_block->cruise_rate, current_block->final_rate, current_block->deceleration_time_inverse);
1598  bezier_2nd_half = true;
1599  // The first point starts at cruise rate. Just save evaluation of the Bézier curve
1600  step_rate = current_block->cruise_rate;
1601  }
1602  else {
1603  // Calculate the next speed to use
1604  step_rate = deceleration_time < current_block->deceleration_time
1605  ? _eval_bezier_curve(deceleration_time)
1606  : current_block->final_rate;
1607  }
1608  #else
1609 
1610  // Using the old trapezoidal control
1611  step_rate = STEP_MULTIPLY(deceleration_time, current_block->acceleration_rate);
1612  if (step_rate < acc_step_rate) { // Still decelerating?
1613  step_rate = acc_step_rate - step_rate;
1614  NOLESS(step_rate, current_block->final_rate);
1615  }
1616  else
1617  step_rate = current_block->final_rate;
1618  #endif
1619 
1620  // step_rate is in steps/second
1621 
1622  // step_rate to timer interval and steps per stepper isr
1623  interval = calc_timer_interval(step_rate, oversampling_factor, &steps_per_isr);
1624  deceleration_time += interval;
1625 
1626  #if ENABLED(LIN_ADVANCE)
1627  if (LA_use_advance_lead) {
1628  // Wake up eISR on first deceleration loop and fire ISR if final adv_rate is reached
1629  if (step_events_completed <= decelerate_after + steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
1630  nextAdvanceISR = 0;
1631  LA_isr_rate = current_block->advance_speed;
1632  }
1633  }
1634  else if (LA_steps) nextAdvanceISR = 0;
1635  #endif // LIN_ADVANCE
1636  }
1637  // We must be in cruise phase otherwise
1638  else {
1639 
1640  #if ENABLED(LIN_ADVANCE)
1641  // If there are any esteps, fire the next advance_isr "now"
1642  if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
1643  #endif
1644 
1645  // Calculate the ticks_nominal for this nominal speed, if not done yet
1646  if (ticks_nominal < 0) {
1647  // step_rate to timer interval and loops for the nominal speed
1648  ticks_nominal = calc_timer_interval(current_block->nominal_rate, oversampling_factor, &steps_per_isr);
1649  }
1650 
1651  // The timer interval is just the nominal value for the nominal speed
1652  interval = ticks_nominal;
1653  }
1654  }
1655  }
1656 
1657  // If there is no current block at this point, attempt to pop one from the buffer
1658  // and prepare its movement
1659  if (!current_block) {
1660 
1661  // Anything in the buffer?
1662  if ((current_block = planner.get_current_block())) {
1663 
1664  // Sync block? Sync the stepper counts and return
1665  while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) {
1666  _set_position(current_block->position);
1668 
1669  // Try to get a new block
1670  if (!(current_block = planner.get_current_block()))
1671  return interval; // No more queued movements!
1672  }
1673 
1674  #if HAS_CUTTER
1675  cutter.apply_power(current_block->cutter_power);
1676  #endif
1677 
1678  #if ENABLED(POWER_LOSS_RECOVERY)
1679  recovery.info.sdpos = current_block->sdpos;
1680  #endif
1681 
1682  // Flag all moving axes for proper endstop handling
1683 
1684  #if IS_CORE
1685  // Define conditions for checking endstops
1686  #define S_(N) current_block->steps[CORE_AXIS_##N]
1687  #define D_(N) TEST(current_block->direction_bits, CORE_AXIS_##N)
1688  #endif
1689 
1690  #if CORE_IS_XY || CORE_IS_XZ
1691  /**
1692  * Head direction in -X axis for CoreXY and CoreXZ bots.
1693  *
1694  * If steps differ, both axes are moving.
1695  * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below)
1696  * If DeltaA == DeltaB, the movement is only in the 1st axis (X)
1697  */
1698  #if EITHER(COREXY, COREXZ)
1699  #define X_CMP ==
1700  #else
1701  #define X_CMP !=
1702  #endif
1703  #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) X_CMP D_(2)) )
1704  #else
1705  #define X_MOVE_TEST !!current_block->steps.a
1706  #endif
1707 
1708  #if CORE_IS_XY || CORE_IS_YZ
1709  /**
1710  * Head direction in -Y axis for CoreXY / CoreYZ bots.
1711  *
1712  * If steps differ, both axes are moving
1713  * If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y)
1714  * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)
1715  */
1716  #if EITHER(COREYX, COREYZ)
1717  #define Y_CMP ==
1718  #else
1719  #define Y_CMP !=
1720  #endif
1721  #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Y_CMP D_(2)) )
1722  #else
1723  #define Y_MOVE_TEST !!current_block->steps.b
1724  #endif
1725 
1726  #if CORE_IS_XZ || CORE_IS_YZ
1727  /**
1728  * Head direction in -Z axis for CoreXZ or CoreYZ bots.
1729  *
1730  * If steps differ, both axes are moving
1731  * If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above)
1732  * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)
1733  */
1734  #if EITHER(COREZX, COREZY)
1735  #define Z_CMP ==
1736  #else
1737  #define Z_CMP !=
1738  #endif
1739  #define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Z_CMP D_(2)) )
1740  #else
1741  #define Z_MOVE_TEST !!current_block->steps.c
1742  #endif
1743 
1744  uint8_t axis_bits = 0;
1745  if (X_MOVE_TEST) SBI(axis_bits, A_AXIS);
1746  if (Y_MOVE_TEST) SBI(axis_bits, B_AXIS);
1747  if (Z_MOVE_TEST) SBI(axis_bits, C_AXIS);
1748  if (!!current_block->steps.e) SBI(axis_bits, E_AXIS);
1749  //if (!!current_block->steps.a) SBI(axis_bits, X_HEAD);
1750  //if (!!current_block->steps.b) SBI(axis_bits, Y_HEAD);
1751  //if (!!current_block->steps.c) SBI(axis_bits, Z_HEAD);
1752  axis_did_move = axis_bits;
1753 
1754  // No acceleration / deceleration time elapsed so far
1755  acceleration_time = deceleration_time = 0;
1756 
1757  uint8_t oversampling = 0; // Assume we won't use it
1758 
1759  #if ENABLED(ADAPTIVE_STEP_SMOOTHING)
1760  // At this point, we must decide if we can use Stepper movement axis smoothing.
1761  uint32_t max_rate = current_block->nominal_rate; // Get the maximum rate (maximum event speed)
1762  while (max_rate < MIN_STEP_ISR_FREQUENCY) {
1763  max_rate <<= 1;
1764  if (max_rate >= MAX_STEP_ISR_FREQUENCY_1X) break;
1765  ++oversampling;
1766  }
1767  oversampling_factor = oversampling;
1768  #endif
1769 
1770  // Based on the oversampling factor, do the calculations
1771  step_event_count = current_block->step_event_count << oversampling;
1772 
1773  // Initialize Bresenham delta errors to 1/2
1774  delta_error = -int32_t(step_event_count);
1775 
1776  // Calculate Bresenham dividends and divisors
1777  advance_dividend = current_block->steps << 1;
1778  advance_divisor = step_event_count << 1;
1779 
1780  // No step events completed so far
1781  step_events_completed = 0;
1782 
1783  // Compute the acceleration and deceleration points
1784  accelerate_until = current_block->accelerate_until << oversampling;
1785  decelerate_after = current_block->decelerate_after << oversampling;
1786 
1787  #if ENABLED(MIXING_EXTRUDER)
1789  #endif
1790 
1791  #if EXTRUDERS > 1
1792  stepper_extruder = current_block->extruder;
1793  #endif
1794 
1795  // Initialize the trapezoid generator from the current block.
1796  #if ENABLED(LIN_ADVANCE)
1797  #if DISABLED(MIXING_EXTRUDER) && E_STEPPERS > 1
1798  // If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
1799  if (stepper_extruder != last_moved_extruder) LA_current_adv_steps = 0;
1800  #endif
1801 
1802  if ((LA_use_advance_lead = current_block->use_advance_lead)) {
1803  LA_final_adv_steps = current_block->final_adv_steps;
1804  LA_max_adv_steps = current_block->max_adv_steps;
1805  //Start the ISR
1806  nextAdvanceISR = 0;
1807  LA_isr_rate = current_block->advance_speed;
1808  }
1809  else LA_isr_rate = LA_ADV_NEVER;
1810  #endif
1811 
1812  if (
1813  #if HAS_DRIVER(L6470)
1814  true // Always set direction for L6470 (This also enables the chips)
1815  #else
1816  current_block->direction_bits != last_direction_bits
1817  #if DISABLED(MIXING_EXTRUDER)
1818  || stepper_extruder != last_moved_extruder
1819  #endif
1820  #endif
1821  ) {
1822  last_direction_bits = current_block->direction_bits;
1823  #if EXTRUDERS > 1
1824  last_moved_extruder = stepper_extruder;
1825  #endif
1826  set_directions();
1827  }
1828 
1829  // At this point, we must ensure the movement about to execute isn't
1830  // trying to force the head against a limit switch. If using interrupt-
1831  // driven change detection, and already against a limit then no call to
1832  // the endstop_triggered method will be done and the movement will be
1833  // done against the endstop. So, check the limits here: If the movement
1834  // is against the limits, the block will be marked as to be killed, and
1835  // on the next call to this ISR, will be discarded.
1836  endstops.update();
1837 
1838  #if ENABLED(Z_LATE_ENABLE)
1839  // If delayed Z enable, enable it now. This option will severely interfere with
1840  // timing between pulses when chaining motion between blocks, and it could lead
1841  // to lost steps in both X and Y axis, so avoid using it unless strictly necessary!!
1842  if (current_block->steps.z) enable_Z();
1843  #endif
1844 
1845  // Mark the time_nominal as not calculated yet
1846  ticks_nominal = -1;
1847 
1848  #if DISABLED(S_CURVE_ACCELERATION)
1849  // Set as deceleration point the initial rate of the block
1850  acc_step_rate = current_block->initial_rate;
1851  #endif
1852 
1853  #if ENABLED(S_CURVE_ACCELERATION)
1854  // Initialize the Bézier speed curve
1855  _calc_bezier_curve_coeffs(current_block->initial_rate, current_block->cruise_rate, current_block->acceleration_time_inverse);
1856  // We haven't started the 2nd half of the trapezoid
1857  bezier_2nd_half = false;
1858  #endif
1859 
1860  // Calculate the initial timer interval
1861  interval = calc_timer_interval(current_block->initial_rate, oversampling_factor, &steps_per_isr);
1862  }
1863  }
1864 
1865  // Return the interval to wait
1866  return interval;
1867 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_block_busy()

bool Stepper::is_block_busy ( const block_t *const  block)
static
1967  {
1968  #ifdef __AVR__
1969  // A SW memory barrier, to ensure GCC does not overoptimize loops
1970  #define sw_barrier() asm volatile("": : :"memory");
1971 
1972  // Keep reading until 2 consecutive reads return the same value,
1973  // meaning there was no update in-between caused by an interrupt.
1974  // This works because stepper ISRs happen at a slower rate than
1975  // successive reads of a variable, so 2 consecutive reads with
1976  // the same value means no interrupt updated it.
1977  block_t* vold, *vnew = current_block;
1978  sw_barrier();
1979  do {
1980  vold = vnew;
1981  vnew = current_block;
1982  sw_barrier();
1983  } while (vold != vnew);
1984  #else
1985  block_t *vnew = current_block;
1986  #endif
1987 
1988  // Return if the block is busy or not
1989  return block == vnew;
1990 }

◆ position()

int32_t Stepper::position ( const AxisEnum  axis)
static

Get a stepper's position in steps.

2214  {
2215  #ifdef __AVR__
2216  // Protect the access to the position. Only required for AVR, as
2217  // any 32bit CPU offers atomic access to 32bit variables
2218  const bool was_enabled = STEPPER_ISR_ENABLED();
2219  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
2220  #endif
2221 
2222  const int32_t v = count_position[axis];
2223 
2224  #ifdef __AVR__
2225  // Reenable Stepper ISR
2226  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
2227  #endif
2228  return v;
2229 }
Here is the caller graph for this function:

◆ report_positions()

void Stepper::report_positions ( )
static
2276  {
2277 
2278  #ifdef __AVR__
2279  // Protect the access to the position.
2280  const bool was_enabled = STEPPER_ISR_ENABLED();
2281  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
2282  #endif
2283 
2284  const xyz_long_t pos = count_position;
2285 
2286  #ifdef __AVR__
2287  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
2288  #endif
2289 
2290  #if CORE_IS_XY || CORE_IS_XZ || ENABLED(DELTA) || IS_SCARA
2291  SERIAL_ECHOPAIR(MSG_COUNT_A, pos.x, " B:", pos.y);
2292  #else
2293  SERIAL_ECHOPAIR(MSG_COUNT_X, pos.x, " Y:", pos.y);
2294  #endif
2295  #if CORE_IS_XZ || CORE_IS_YZ || ENABLED(DELTA)
2296  SERIAL_ECHOLNPAIR(" C:", pos.z);
2297  #else
2298  SERIAL_ECHOLNPAIR(" Z:", pos.z);
2299  #endif
2300 }
Here is the caller graph for this function:

◆ wake_up()

void Stepper::wake_up ( )
static
342  {
343  // TCNT1 = 0;
345 }
Here is the caller graph for this function:

◆ quick_stop()

static FORCE_INLINE void Stepper::quick_stop ( )
static
375 { abort_current_block = true; }
Here is the caller graph for this function:

◆ motor_direction()

static FORCE_INLINE bool Stepper::motor_direction ( const AxisEnum  axis)
static
378 { return TEST(last_direction_bits, axis); }
Here is the caller graph for this function:

◆ axis_is_moving()

static FORCE_INLINE bool Stepper::axis_is_moving ( const AxisEnum  axis)
static
381 { return TEST(axis_did_move, axis); }
Here is the caller graph for this function:

◆ movement_extruder()

static FORCE_INLINE uint8_t Stepper::movement_extruder ( )
static
384  {
385  return (0
386  #if EXTRUDERS > 1 && DISABLED(MIXING_EXTRUDER)
387  + last_moved_extruder
388  #endif
389  );
390  }

◆ endstop_triggered()

void Stepper::endstop_triggered ( const AxisEnum  axis)
static
2237  {
2238 
2239  const bool was_enabled = STEPPER_ISR_ENABLED();
2240  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
2241  endstops_trigsteps[axis] = (
2242  #if IS_CORE
2243  (axis == CORE_AXIS_2
2244  ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2])
2245  : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2]
2246  ) * 0.5f
2247  #else // !IS_CORE
2248  count_position[axis]
2249  #endif
2250  );
2251 
2252  // Discard the rest of the move if there is a current block
2253  quick_stop();
2254 
2255  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
2256 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ triggered_position()

int32_t Stepper::triggered_position ( const AxisEnum  axis)
static
2258  {
2259  #ifdef __AVR__
2260  // Protect the access to the position. Only required for AVR, as
2261  // any 32bit CPU offers atomic access to 32bit variables
2262  const bool was_enabled = STEPPER_ISR_ENABLED();
2263  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
2264  #endif
2265 
2266  const int32_t v = endstops_trigsteps[axis];
2267 
2268  #ifdef __AVR__
2269  // Reenable Stepper ISR
2270  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
2271  #endif
2272 
2273  return v;
2274 }
Here is the caller graph for this function:

◆ digitalPotWrite()

static void Stepper::digitalPotWrite ( const int16_t  address,
const int16_t  value 
)
static
Here is the caller graph for this function:

◆ digipot_current()

void Stepper::digipot_current ( const uint8_t  driver,
const int16_t  current 
)
static

Software-controlled Stepper Motor Current

2495  {
2496 
2497  #if HAS_DIGIPOTSS
2498 
2499  const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;
2500  digitalPotWrite(digipot_ch[driver], current);
2501 
2502  #elif HAS_MOTOR_CURRENT_PWM
2503 
2504  if (!initialized) return;
2505 
2506  if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1))
2507  motor_current_setting[driver] = current; // update motor_current_setting
2508 
2509  #define _WRITE_CURRENT_PWM(P) analogWrite(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE))
2510  switch (driver) {
2511  case 0:
2512  #if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
2513  _WRITE_CURRENT_PWM(X);
2514  #endif
2515  #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
2516  _WRITE_CURRENT_PWM(Y);
2517  #endif
2518  #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
2519  _WRITE_CURRENT_PWM(XY);
2520  #endif
2521  break;
2522  case 1:
2523  #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
2524  _WRITE_CURRENT_PWM(Z);
2525  #endif
2526  break;
2527  case 2:
2528  #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
2529  _WRITE_CURRENT_PWM(E);
2530  #endif
2531  #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0)
2532  _WRITE_CURRENT_PWM(E0);
2533  #endif
2534  #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1)
2535  _WRITE_CURRENT_PWM(E1);
2536  #endif
2537  break;
2538  }
2539  #endif
2540  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ microstep_ms()

void Stepper::microstep_ms ( const uint8_t  driver,
const int8_t  ms1,
const int8_t  ms2,
const int8_t  ms3 
)
static
2701  {
2702  if (ms1 >= 0) switch (driver) {
2703  #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS
2704  case 0:
2705  #if HAS_X_MICROSTEPS
2706  WRITE(X_MS1_PIN, ms1);
2707  #endif
2708  #if HAS_X2_MICROSTEPS
2709  WRITE(X2_MS1_PIN, ms1);
2710  #endif
2711  break;
2712  #endif
2713  #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS
2714  case 1:
2715  #if HAS_Y_MICROSTEPS
2716  WRITE(Y_MS1_PIN, ms1);
2717  #endif
2718  #if HAS_Y2_MICROSTEPS
2719  WRITE(Y2_MS1_PIN, ms1);
2720  #endif
2721  break;
2722  #endif
2723  #if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
2724  case 2:
2725  #if HAS_Z_MICROSTEPS
2726  WRITE(Z_MS1_PIN, ms1);
2727  #endif
2728  #if HAS_Z2_MICROSTEPS
2729  WRITE(Z2_MS1_PIN, ms1);
2730  #endif
2731  #if HAS_Z3_MICROSTEPS
2732  WRITE(Z3_MS1_PIN, ms1);
2733  #endif
2734  break;
2735  #endif
2736  #if HAS_E0_MICROSTEPS
2737  case 3: WRITE(E0_MS1_PIN, ms1); break;
2738  #endif
2739  #if HAS_E1_MICROSTEPS
2740  case 4: WRITE(E1_MS1_PIN, ms1); break;
2741  #endif
2742  #if HAS_E2_MICROSTEPS
2743  case 5: WRITE(E2_MS1_PIN, ms1); break;
2744  #endif
2745  #if HAS_E3_MICROSTEPS
2746  case 6: WRITE(E3_MS1_PIN, ms1); break;
2747  #endif
2748  #if HAS_E4_MICROSTEPS
2749  case 7: WRITE(E4_MS1_PIN, ms1); break;
2750  #endif
2751  #if HAS_E5_MICROSTEPS
2752  case 8: WRITE(E5_MS1_PIN, ms1); break;
2753  #endif
2754  }
2755  if (ms2 >= 0) switch (driver) {
2756  #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS
2757  case 0:
2758  #if HAS_X_MICROSTEPS
2759  WRITE(X_MS2_PIN, ms2);
2760  #endif
2761  #if HAS_X2_MICROSTEPS
2762  WRITE(X2_MS2_PIN, ms2);
2763  #endif
2764  break;
2765  #endif
2766  #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS
2767  case 1:
2768  #if HAS_Y_MICROSTEPS
2769  WRITE(Y_MS2_PIN, ms2);
2770  #endif
2771  #if HAS_Y2_MICROSTEPS
2772  WRITE(Y2_MS2_PIN, ms2);
2773  #endif
2774  break;
2775  #endif
2776  #if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
2777  case 2:
2778  #if HAS_Z_MICROSTEPS
2779  WRITE(Z_MS2_PIN, ms2);
2780  #endif
2781  #if HAS_Z2_MICROSTEPS
2782  WRITE(Z2_MS2_PIN, ms2);
2783  #endif
2784  #if HAS_Z3_MICROSTEPS
2785  WRITE(Z3_MS2_PIN, ms2);
2786  #endif
2787  break;
2788  #endif
2789  #if HAS_E0_MICROSTEPS
2790  case 3: WRITE(E0_MS2_PIN, ms2); break;
2791  #endif
2792  #if HAS_E1_MICROSTEPS
2793  case 4: WRITE(E1_MS2_PIN, ms2); break;
2794  #endif
2795  #if HAS_E2_MICROSTEPS
2796  case 5: WRITE(E2_MS2_PIN, ms2); break;
2797  #endif
2798  #if HAS_E3_MICROSTEPS
2799  case 6: WRITE(E3_MS2_PIN, ms2); break;
2800  #endif
2801  #if HAS_E4_MICROSTEPS
2802  case 7: WRITE(E4_MS2_PIN, ms2); break;
2803  #endif
2804  #if HAS_E5_MICROSTEPS
2805  case 8: WRITE(E5_MS2_PIN, ms2); break;
2806  #endif
2807  }
2808  if (ms3 >= 0) switch (driver) {
2809  #if HAS_X_MICROSTEPS || HAS_X2_MICROSTEPS
2810  case 0:
2811  #if HAS_X_MICROSTEPS && PIN_EXISTS(X_MS3)
2812  WRITE(X_MS3_PIN, ms3);
2813  #endif
2814  #if HAS_X2_MICROSTEPS && PIN_EXISTS(X2_MS3)
2815  WRITE(X2_MS3_PIN, ms3);
2816  #endif
2817  break;
2818  #endif
2819  #if HAS_Y_MICROSTEPS || HAS_Y2_MICROSTEPS
2820  case 1:
2821  #if HAS_Y_MICROSTEPS && PIN_EXISTS(Y_MS3)
2822  WRITE(Y_MS3_PIN, ms3);
2823  #endif
2824  #if HAS_Y2_MICROSTEPS && PIN_EXISTS(Y2_MS3)
2825  WRITE(Y2_MS3_PIN, ms3);
2826  #endif
2827  break;
2828  #endif
2829  #if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
2830  case 2:
2831  #if HAS_Z_MICROSTEPS && PIN_EXISTS(Z_MS3)
2832  WRITE(Z_MS3_PIN, ms3);
2833  #endif
2834  #if HAS_Z2_MICROSTEPS && PIN_EXISTS(Z2_MS3)
2835  WRITE(Z2_MS3_PIN, ms3);
2836  #endif
2837  #if HAS_Z3_MICROSTEPS && PIN_EXISTS(Z3_MS3)
2838  WRITE(Z3_MS3_PIN, ms3);
2839  #endif
2840  break;
2841  #endif
2842  #if HAS_E0_MICROSTEPS && PIN_EXISTS(E0_MS3)
2843  case 3: WRITE(E0_MS3_PIN, ms3); break;
2844  #endif
2845  #if HAS_E1_MICROSTEPS && PIN_EXISTS(E1_MS3)
2846  case 4: WRITE(E1_MS3_PIN, ms3); break;
2847  #endif
2848  #if HAS_E2_MICROSTEPS && PIN_EXISTS(E2_MS3)
2849  case 5: WRITE(E2_MS3_PIN, ms3); break;
2850  #endif
2851  #if HAS_E3_MICROSTEPS && PIN_EXISTS(E3_MS3)
2852  case 6: WRITE(E3_MS3_PIN, ms3); break;
2853  #endif
2854  #if HAS_E4_MICROSTEPS && PIN_EXISTS(E4_MS3)
2855  case 7: WRITE(E4_MS3_PIN, ms3); break;
2856  #endif
2857  #if HAS_E5_MICROSTEPS && PIN_EXISTS(E5_MS3)
2858  case 8: WRITE(E5_MS3_PIN, ms3); break;
2859  #endif
2860  }
2861  }
Here is the caller graph for this function:

◆ microstep_mode()

void Stepper::microstep_mode ( const uint8_t  driver,
const uint8_t  stepping 
)
static
2863  {
2864  switch (stepping_mode) {
2865  #if HAS_MICROSTEP1
2866  case 1: microstep_ms(driver, MICROSTEP1); break;
2867  #endif
2868  #if HAS_MICROSTEP2
2869  case 2: microstep_ms(driver, MICROSTEP2); break;
2870  #endif
2871  #if HAS_MICROSTEP4
2872  case 4: microstep_ms(driver, MICROSTEP4); break;
2873  #endif
2874  #if HAS_MICROSTEP8
2875  case 8: microstep_ms(driver, MICROSTEP8); break;
2876  #endif
2877  #if HAS_MICROSTEP16
2878  case 16: microstep_ms(driver, MICROSTEP16); break;
2879  #endif
2880  #if HAS_MICROSTEP32
2881  case 32: microstep_ms(driver, MICROSTEP32); break;
2882  #endif
2883  #if HAS_MICROSTEP64
2884  case 64: microstep_ms(driver, MICROSTEP64); break;
2885  #endif
2886  #if HAS_MICROSTEP128
2887  case 128: microstep_ms(driver, MICROSTEP128); break;
2888  #endif
2889 
2890  default: SERIAL_ERROR_MSG("Microsteps unavailable"); break;
2891  }
2892  }
Here is the call graph for this function:

◆ microstep_readings()

void Stepper::microstep_readings ( )
static
2894  {
2895  SERIAL_ECHOPGM("MS1,MS2,MS3 Pins\nX: ");
2896  #if HAS_X_MICROSTEPS
2897  SERIAL_CHAR('0' + READ(X_MS1_PIN));
2898  SERIAL_CHAR('0' + READ(X_MS2_PIN));
2899  #if PIN_EXISTS(X_MS3)
2900  SERIAL_ECHOLN((int)READ(X_MS3_PIN));
2901  #endif
2902  #endif
2903  #if HAS_Y_MICROSTEPS
2904  SERIAL_ECHOPGM("Y: ");
2905  SERIAL_CHAR('0' + READ(Y_MS1_PIN));
2906  SERIAL_CHAR('0' + READ(Y_MS2_PIN));
2907  #if PIN_EXISTS(Y_MS3)
2908  SERIAL_ECHOLN((int)READ(Y_MS3_PIN));
2909  #endif
2910  #endif
2911  #if HAS_Z_MICROSTEPS
2912  SERIAL_ECHOPGM("Z: ");
2913  SERIAL_CHAR('0' + READ(Z_MS1_PIN));
2914  SERIAL_CHAR('0' + READ(Z_MS2_PIN));
2915  #if PIN_EXISTS(Z_MS3)
2916  SERIAL_ECHOLN((int)READ(Z_MS3_PIN));
2917  #endif
2918  #endif
2919  #if HAS_E0_MICROSTEPS
2920  SERIAL_ECHOPGM("E0: ");
2921  SERIAL_CHAR('0' + READ(E0_MS1_PIN));
2922  SERIAL_CHAR('0' + READ(E0_MS2_PIN));
2923  #if PIN_EXISTS(E0_MS3)
2924  SERIAL_ECHOLN((int)READ(E0_MS3_PIN));
2925  #endif
2926  #endif
2927  #if HAS_E1_MICROSTEPS
2928  SERIAL_ECHOPGM("E1: ");
2929  SERIAL_CHAR('0' + READ(E1_MS1_PIN));
2930  SERIAL_CHAR('0' + READ(E1_MS2_PIN));
2931  #if PIN_EXISTS(E1_MS3)
2932  SERIAL_ECHOLN((int)READ(E1_MS3_PIN));
2933  #endif
2934  #endif
2935  #if HAS_E2_MICROSTEPS
2936  SERIAL_ECHOPGM("E2: ");
2937  SERIAL_CHAR('0' + READ(E2_MS1_PIN));
2938  SERIAL_CHAR('0' + READ(E2_MS2_PIN));
2939  #if PIN_EXISTS(E2_MS3)
2940  SERIAL_ECHOLN((int)READ(E2_MS3_PIN));
2941  #endif
2942  #endif
2943  #if HAS_E3_MICROSTEPS
2944  SERIAL_ECHOPGM("E3: ");
2945  SERIAL_CHAR('0' + READ(E3_MS1_PIN));
2946  SERIAL_CHAR('0' + READ(E3_MS2_PIN));
2947  #if PIN_EXISTS(E3_MS3)
2948  SERIAL_ECHOLN((int)READ(E3_MS3_PIN));
2949  #endif
2950  #endif
2951  #if HAS_E4_MICROSTEPS
2952  SERIAL_ECHOPGM("E4: ");
2953  SERIAL_CHAR('0' + READ(E4_MS1_PIN));
2954  SERIAL_CHAR('0' + READ(E4_MS2_PIN));
2955  #if PIN_EXISTS(E4_MS3)
2956  SERIAL_ECHOLN((int)READ(E4_MS3_PIN));
2957  #endif
2958  #endif
2959  #if HAS_E5_MICROSTEPS
2960  SERIAL_ECHOPGM("E5: ");
2961  SERIAL_CHAR('0' + READ(E5_MS1_PIN));
2962  SERIAL_ECHOLN((int)READ(E5_MS2_PIN));
2963  #if PIN_EXISTS(E5_MS3)
2964  SERIAL_ECHOLN((int)READ(E5_MS3_PIN));
2965  #endif
2966  #endif
2967  }

◆ set_separate_multi_axis()

static FORCE_INLINE void Stepper::set_separate_multi_axis ( const bool  state)
static
Here is the caller graph for this function:

◆ set_z_lock()

static FORCE_INLINE void Stepper::set_z_lock ( const bool  state)
static
421 { locked_Z_motor = state; }
Here is the caller graph for this function:

◆ set_z2_lock()

static FORCE_INLINE void Stepper::set_z2_lock ( const bool  state)
static
422 { locked_Z2_motor = state; }
Here is the caller graph for this function:

◆ set_position() [1/2]

static void Stepper::set_position ( const int32_t &  a,
const int32_t &  b,
const int32_t &  c,
const int32_t &  e 
)
static
437  {
439  const bool was_enabled = STEPPER_ISR_ENABLED();
440  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
441  _set_position(a, b, c, e);
442  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
443  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_position() [2/2]

static void Stepper::set_position ( const xyze_long_t abce)
static
444 { set_position(abce.a, abce.b, abce.c, abce.e); }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_axis_position()

static void Stepper::set_axis_position ( const AxisEnum  a,
const int32_t &  v 
)
static
446  {
448 
449  #ifdef __AVR__
450  // Protect the access to the position. Only required for AVR, as
451  // any 32bit CPU offers atomic access to 32bit variables
452  const bool was_enabled = STEPPER_ISR_ENABLED();
453  if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
454  #endif
455 
456  count_position[a] = v;
457 
458  #ifdef __AVR__
459  // Reenable Stepper ISR
460  if (was_enabled) ENABLE_STEPPER_DRIVER_INTERRUPT();
461  #endif
462  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_directions()

void Stepper::set_directions ( )
static

Set the stepper direction of each axis

COREXY: X_AXIS=A_AXIS and Y_AXIS=B_AXIS COREXZ: X_AXIS=A_AXIS and Z_AXIS=C_AXIS COREYZ: Y_AXIS=B_AXIS and Z_AXIS=C_AXIS

354  {
355 
356  #if HAS_DRIVER(L6470)
357  uint8_t L6470_buf[MAX_L6470 + 1]; // chip command sequence - element 0 not used
358  #endif
359 
360  #if MINIMUM_STEPPER_PRE_DIR_DELAY > 0
362  #endif
363 
364  #define SET_STEP_DIR(A) \
365  if (motor_direction(_AXIS(A))) { \
366  A##_APPLY_DIR(INVERT_## A##_DIR, false); \
367  count_direction[_AXIS(A)] = -1; \
368  } \
369  else { \
370  A##_APPLY_DIR(!INVERT_## A##_DIR, false); \
371  count_direction[_AXIS(A)] = 1; \
372  }
373 
374  #if HAS_X_DIR
375  SET_STEP_DIR(X); // A
376  #endif
377 
378  #if HAS_Y_DIR
379  SET_STEP_DIR(Y); // B
380  #endif
381 
382  #if HAS_Z_DIR
383  SET_STEP_DIR(Z); // C
384  #endif
385 
386  #if DISABLED(LIN_ADVANCE)
387  #if ENABLED(MIXING_EXTRUDER)
388  // Because this is valid for the whole block we don't know
389  // what e-steppers will step. Likely all. Set all.
390  if (motor_direction(E_AXIS)) {
392  count_direction.e = -1;
393  }
394  else {
396  count_direction.e = 1;
397  }
398  #else
399  if (motor_direction(E_AXIS)) {
400  REV_E_DIR(stepper_extruder);
401  count_direction.e = -1;
402  }
403  else {
404  NORM_E_DIR(stepper_extruder);
405  count_direction.e = 1;
406  }
407  #endif
408  #endif // !LIN_ADVANCE
409 
410  #if HAS_DRIVER(L6470)
411 
412  if (L6470.spi_active) {
413  L6470.spi_abort = true; // interrupted a SPI transfer - need to shut it down gracefully
414  for (uint8_t j = 1; j <= L6470::chain[0]; j++)
415  L6470_buf[j] = dSPIN_NOP; // fill buffer with NOOP commands
416  L6470.transfer(L6470_buf, L6470::chain[0]); // send enough NOOPs to complete any command
417  L6470.transfer(L6470_buf, L6470::chain[0]);
418  L6470.transfer(L6470_buf, L6470::chain[0]);
419  }
420 
421  // The L6470.dir_commands[] array holds the direction command for each stepper
422 
423  //scan command array and copy matches into L6470.transfer
424  for (uint8_t j = 1; j <= L6470::chain[0]; j++)
425  L6470_buf[j] = L6470.dir_commands[L6470::chain[j]];
426 
427  L6470.transfer(L6470_buf, L6470::chain[0]); // send the command stream to the drivers
428 
429  #endif
430 
431  // A small delay may be needed after changing direction
432  #if MINIMUM_STEPPER_POST_DIR_DELAY > 0
434  #endif
435 }
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ separate_multi_axis

bool Stepper::separate_multi_axis = false
static
X2_DIR_INIT
#define X2_DIR_INIT
Definition: indirection.h:109
WITHIN
#define WITHIN(N, L, H)
Definition: macros.h:195
XYZval::z
T z
Definition: types.h:286
E3_DIR_INIT
#define E3_DIR_INIT
Definition: indirection.h:241
Y_ENABLE_ON
#define Y_ENABLE_ON
Definition: Configuration_A3ides_2209_MINI.h:927
SERIAL_CHAR
#define SERIAL_CHAR(x)
Definition: serial.h:69
Stepper::separate_multi_axis
static bool separate_multi_axis
Definition: stepper.h:231
STEP_MULTIPLY
#define STEP_MULTIPLY(A, B)
Definition: stepper.cpp:1259
NOLESS
#define NOLESS(v, n)
Definition: macros.h:127
Planner::discard_current_block
static FORCE_INLINE void discard_current_block()
Definition: planner.h:820
X_MS3_PIN
#define X_MS3_PIN
Definition: pins.h:559
E5_DIR_INIT
#define E5_DIR_INIT
Definition: indirection.h:275
XYZEval::z
T z
Definition: types.h:383
Planner::synchronize
static void synchronize()
Definition: planner.cpp:1556
INVERT_Y_STEP_PIN
#define INVERT_Y_STEP_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:501
MIN_STEP_ISR_FREQUENCY
#define MIN_STEP_ISR_FREQUENCY
Definition: stepper.h:221
mixer
Mixer mixer
Z_ENABLE_INIT
#define Z_ENABLE_INIT
Definition: indirection.h:86
block_t::flag
volatile uint8_t flag
Definition: planner.h:97
MSG_COUNT_X
#define MSG_COUNT_X
Definition: language.h:172
XYZval::x
T x
Definition: types.h:286
X2_MS1_PIN
#define X2_MS1_PIN
Definition: pins.h:989
PULSE_TIMER_NUM
#define PULSE_TIMER_NUM
Definition: HAL.h:129
E3_MS2_PIN
#define E3_MS2_PIN
Definition: pins.h:610
PrintJobRecovery::info
static job_recovery_info_t info
Definition: power_loss_recovery.h:111
X2_ENABLE_WRITE
#define X2_ENABLE_WRITE(STATE)
Definition: indirection.h:105
Z_ENABLE_WRITE
#define Z_ENABLE_WRITE(STATE)
Definition: indirection.h:87
E5_ENABLE_INIT
#define E5_ENABLE_INIT
Definition: indirection.h:270
E5_MS1_PIN
#define E5_MS1_PIN
Definition: pins.h:625
ADDED_STEP_TICKS
#define ADDED_STEP_TICKS
Definition: stepper.h:180
L6470_Marlin::spi_abort
static volatile bool spi_abort
Definition: L6470_Marlin.h:44
E1_ENABLE_WRITE
#define E1_ENABLE_WRITE(STATE)
Definition: indirection.h:203
X2_STEP_INIT
#define X2_STEP_INIT
Definition: indirection.h:113
E1
Definition: L6470_Marlin.h:30
INVERT_E_STEP_PIN
#define INVERT_E_STEP_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:503
X_AXIS
Definition: types.h:37
X_MS2_PIN
#define X_MS2_PIN
Definition: pins.h:556
PULSE_START
#define PULSE_START(AXIS)
Y_DIR_INIT
#define Y_DIR_INIT
Definition: indirection.h:74
MSG_COUNT_A
#define MSG_COUNT_A
Definition: language.h:173
INVERT_X_DIR
#define INVERT_X_DIR
Definition: Configuration_A3ides_2209_MINI.h:948
E4_DIR_INIT
#define E4_DIR_INIT
Definition: indirection.h:258
E_ENABLE_ON
#define E_ENABLE_ON
Definition: Configuration_A3ides_2209_MINI.h:929
i2s_push_sample
void i2s_push_sample()
SERIAL_ECHOPAIR
#define SERIAL_ECHOPAIR(V...)
Definition: serial.h:114
E0_MS1_PIN
#define E0_MS1_PIN
Definition: pins.h:580
E0
Definition: L6470_Marlin.h:30
C_AXIS
Definition: types.h:39
Stepper::motor_direction
static FORCE_INLINE bool motor_direction(const AxisEnum axis)
Definition: stepper.h:378
XYZEval::e
T e
Definition: types.h:383
Z_MS2_PIN
#define Z_MS2_PIN
Definition: pins.h:574
PULSE_STOP
#define PULSE_STOP(AXIS)
Z2_STEP_INIT
#define Z2_STEP_INIT
Definition: indirection.h:153
Z2_STEP_WRITE
#define Z2_STEP_WRITE(STATE)
Definition: indirection.h:155
Z3_ENABLE_WRITE
#define Z3_ENABLE_WRITE(STATE)
Definition: indirection.h:166
i
uint8_t i
Definition: screen_test_graph.c:72
_MIN
#define _MIN(V...)
Definition: macros.h:333
Y
Definition: L6470_Marlin.h:30
X_ENABLE_INIT
#define X_ENABLE_INIT
Definition: indirection.h:52
state
static volatile fsensor_t state
Definition: filament_sensor.c:23
Z2_ENABLE_INIT
#define Z2_ENABLE_INIT
Definition: indirection.h:144
enable_Z
#define enable_Z()
Definition: Marlin.h:142
X_MS1_PIN
#define X_MS1_PIN
Definition: pins.h:553
X_ENABLE_ON
#define X_ENABLE_ON
Definition: Configuration_A3ides_2209_MINI.h:926
Z3_DIR_INIT
#define Z3_DIR_INIT
Definition: indirection.h:170
recovery
PrintJobRecovery recovery
Z_MOVE_TEST
#define Z_MOVE_TEST
dac084s085::setValue
static void setValue(const uint8_t channel, const uint8_t value)
SERIAL_ECHOLN
#define SERIAL_ECHOLN(x)
Definition: serial.h:72
block_t::steps
abce_ulong_t steps
Definition: planner.h:107
X_ENABLE_WRITE
#define X_ENABLE_WRITE(STATE)
Definition: indirection.h:53
STEPPER_ISR_ENABLED
#define STEPPER_ISR_ENABLED()
Definition: HAL.h:143
Y_ENABLE_INIT
#define Y_ENABLE_INIT
Definition: indirection.h:69
INVERT_Z_STEP_PIN
#define INVERT_Z_STEP_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:502
STEP_TIMER_NUM
#define STEP_TIMER_NUM
Definition: HAL.h:127
HAL_timer_start
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t)
Definition: HAL.h:149
L6470_Marlin::dir_commands
static uint8_t dir_commands[MAX_L6470]
Definition: L6470_Marlin.h:41
E2_DIR_INIT
#define E2_DIR_INIT
Definition: indirection.h:224
E0_ENABLE_INIT
#define E0_ENABLE_INIT
Definition: indirection.h:185
cutter
SpindleLaser cutter
Definition: spindle_laser.cpp:33
E1_ENABLE_INIT
#define E1_ENABLE_INIT
Definition: indirection.h:202
Z
Definition: L6470_Marlin.h:30
MAX_L6470
Definition: L6470_Marlin.h:30
NOMORE
#define NOMORE(v, n)
Definition: macros.h:133
X2_ENABLE_INIT
#define X2_ENABLE_INIT
Definition: indirection.h:104
Y_MS1_PIN
#define Y_MS1_PIN
Definition: pins.h:562
Z2_DIR_INIT
#define Z2_DIR_INIT
Definition: indirection.h:149
block_t::cutter_power
cutter_power_t cutter_power
Definition: planner.h:153
NORM_E_DIR
#define NORM_E_DIR(E)
Definition: indirection.h:396
DISABLE_ISRS
#define DISABLE_ISRS()
Definition: HAL.h:53
E2_MS3_PIN
#define E2_MS3_PIN
Definition: pins.h:604
E3_MS1_PIN
#define E3_MS1_PIN
Definition: pins.h:607
TFilamentMonitor::block_completed
static void block_completed(const block_t *const b)
Definition: runout.h:94
Z3_STEP_WRITE
#define Z3_STEP_WRITE(STATE)
Definition: indirection.h:176
E5_MS2_PIN
#define E5_MS2_PIN
Definition: pins.h:628
E1_MS1_PIN
#define E1_MS1_PIN
Definition: pins.h:589
XYZEval::a
T a
Definition: types.h:384
block_t::position
abce_long_t position
Definition: planner.h:108
job_recovery_info_t::sdpos
volatile uint32_t sdpos
Definition: power_loss_recovery.h:97
XYZEval::c
T c
Definition: types.h:384
BLOCK_BIT_SYNC_POSITION
Definition: planner.h:76
L6470
L6470_Marlin L6470
Z_MS1_PIN
#define Z_MS1_PIN
Definition: pins.h:571
E5_ENABLE_WRITE
#define E5_ENABLE_WRITE(STATE)
Definition: indirection.h:271
Z3_ENABLE_INIT
#define Z3_ENABLE_INIT
Definition: indirection.h:165
Y_MS3_PIN
#define Y_MS3_PIN
Definition: pins.h:568
COUNT
#define COUNT(a)
Definition: macros.h:200
XYZEval::b
T b
Definition: types.h:384
E4_MS2_PIN
#define E4_MS2_PIN
Definition: pins.h:619
E4_ENABLE_WRITE
#define E4_ENABLE_WRITE(STATE)
Definition: indirection.h:254
E2_MS2_PIN
#define E2_MS2_PIN
Definition: pins.h:601
INVERT_X_STEP_PIN
#define INVERT_X_STEP_PIN
Definition: Configuration_A3ides_2209_MINI_adv.h:500
X_MOVE_TEST
#define X_MOVE_TEST
block_t::acceleration_rate
uint32_t acceleration_rate
Definition: planner.h:133
ENABLE_STEPPER_DRIVER_INTERRUPT
#define ENABLE_STEPPER_DRIVER_INTERRUPT()
Definition: HAL.h:141
Stepper::set_directions
static void set_directions()
Definition: stepper.cpp:354
X2_MS3_PIN
#define X2_MS3_PIN
Definition: pins.h:995
DISABLED
#define DISABLED(V...)
Definition: macros.h:178
block_t::final_rate
uint32_t final_rate
Definition: planner.h:147
E2_MS1_PIN
#define E2_MS1_PIN
Definition: pins.h:598
Z3_STEP_INIT
#define Z3_STEP_INIT
Definition: indirection.h:174
runout
FilamentMonitor runout
HAL_TIMER_TYPE_MAX
#define HAL_TIMER_TYPE_MAX
Definition: HAL.h:63
HAL_timer_get_count
#define HAL_timer_get_count(timer)
Definition: HAL.h:188
XY
#define XY
Definition: macros.h:28
Y2_ENABLE_WRITE
#define Y2_ENABLE_WRITE(STATE)
Definition: indirection.h:124
WRITE
#define WRITE(IO, V)
Definition: fastio.h:96
Stepper::microstep_ms
static void microstep_ms(const uint8_t driver, const int8_t ms1, const int8_t ms2, const int8_t ms3)
Definition: stepper.cpp:2701
SERIAL_ECHOPGM
#define SERIAL_ECHOPGM(S)
Definition: serial.h:173
E2_ENABLE_INIT
#define E2_ENABLE_INIT
Definition: indirection.h:219
E0_DIR_INIT
#define E0_DIR_INIT
Definition: indirection.h:190
MINIMUM_STEPPER_PRE_DIR_DELAY
#define MINIMUM_STEPPER_PRE_DIR_DELAY
Definition: Conditionals_post.h:571
Stepper::digitalPotWrite
static void digitalPotWrite(const int16_t address, const int16_t value)
SERIAL_ECHOLNPAIR
#define SERIAL_ECHOLNPAIR(V...)
Definition: serial.h:144
E0_MS2_PIN
#define E0_MS2_PIN
Definition: pins.h:583
createSpeedLookupTable.a
list a
Definition: createSpeedLookupTable.py:29
Stepper::quick_stop
static FORCE_INLINE void quick_stop()
Definition: stepper.h:375
X_DIR_INIT
#define X_DIR_INIT
Definition: indirection.h:57
SpindleLaser::apply_power
static void apply_power(const cutter_power_t inpow)
Definition: spindle_laser.cpp:64
Y2_STEP_INIT
#define Y2_STEP_INIT
Definition: indirection.h:132
Z_MS3_PIN
#define Z_MS3_PIN
Definition: pins.h:577
MIXER_STEPPER_LOOP
#define MIXER_STEPPER_LOOP(VAR)
Definition: mixing.h:68
MINIMUM_STEPPER_POST_DIR_DELAY
#define MINIMUM_STEPPER_POST_DIR_DELAY
Definition: Conditionals_post.h:566
Y2_DIR_INIT
#define Y2_DIR_INIT
Definition: indirection.h:128
uint8_t
const uint8_t[]
Definition: 404_html.c:3
Stepper::stepper_pulse_phase_isr
static void stepper_pulse_phase_isr()
Definition: stepper.cpp:1397
block_t::direction_bits
uint8_t direction_bits
Definition: planner.h:136
DISABLE_STEPPER_DRIVER_INTERRUPT
#define DISABLE_STEPPER_DRIVER_INTERRUPT()
Definition: HAL.h:142
_BV
#define _BV(bit)
Definition: wiring_constants.h:99
INVERT_Y_DIR
#define INVERT_Y_DIR
Definition: Configuration_A3ides_2209_MINI.h:949
sei
void sei()
X2_MS2_PIN
#define X2_MS2_PIN
Definition: pins.h:992
L6470_Marlin::spi_active
static bool spi_active
Definition: L6470_Marlin.h:45
XYZval::y
T y
Definition: types.h:286
block_t::initial_rate
uint32_t initial_rate
Definition: planner.h:147
Z_DIR_INIT
#define Z_DIR_INIT
Definition: indirection.h:91
MAX_STEP_ISR_FREQUENCY_1X
#define MAX_STEP_ISR_FREQUENCY_1X
Definition: stepper.h:218
E5_MS3_PIN
#define E5_MS3_PIN
Definition: pins.h:631
X2_STEP_WRITE
#define X2_STEP_WRITE(STATE)
Definition: indirection.h:115
SERIAL_ERROR_MSG
#define SERIAL_ERROR_MSG(S)
Definition: serial.h:184
E3_ENABLE_INIT
#define E3_ENABLE_INIT
Definition: indirection.h:236
Y_AXIS
Definition: types.h:38
Y_MS2_PIN
#define Y_MS2_PIN
Definition: pins.h:565
block_t::step_event_count
uint32_t step_event_count
Definition: planner.h:110
E3_ENABLE_WRITE
#define E3_ENABLE_WRITE(STATE)
Definition: indirection.h:237
REV_E_DIR
#define REV_E_DIR(E)
Definition: indirection.h:397
E4_MS3_PIN
#define E4_MS3_PIN
Definition: pins.h:622
STEPPER_TIMER_TICKS_PER_US
#define STEPPER_TIMER_TICKS_PER_US
Definition: HAL.h:135
Y2_STEP_WRITE
#define Y2_STEP_WRITE(STATE)
Definition: indirection.h:134
E2_ENABLE_WRITE
#define E2_ENABLE_WRITE(STATE)
Definition: indirection.h:220
Z_AXIS
Definition: types.h:39
EXTRUDERS
#define EXTRUDERS
Definition: Configuration_A3ides_2209_MINI.h:148
E4_ENABLE_INIT
#define E4_ENABLE_INIT
Definition: indirection.h:253
A_AXIS
Definition: types.h:37
Mixer::get_next_stepper
static FORCE_INLINE uint8_t get_next_stepper()
Definition: mixing.h:248
E_STEP_WRITE
#define E_STEP_WRITE(E, V)
Definition: indirection.h:395
HIGH
#define HIGH
Definition: wiring_constants.h:71
E3_MS3_PIN
#define E3_MS3_PIN
Definition: pins.h:613
block_t::decelerate_after
uint32_t decelerate_after
Definition: planner.h:123
E4_MS1_PIN
#define E4_MS1_PIN
Definition: pins.h:616
Mixer::get_stepper
static FORCE_INLINE uint8_t get_stepper()
Definition: mixing.h:247
HAL_timer_set_compare
#define HAL_timer_set_compare(timer, compare)
Definition: HAL.h:186
E0_MS3_PIN
#define E0_MS3_PIN
Definition: pins.h:586
INVERT_Z_DIR
#define INVERT_Z_DIR
Definition: Configuration_A3ides_2209_MINI.h:950
block_t::nominal_rate
uint32_t nominal_rate
Definition: planner.h:147
MIXER_STEPPER_SETUP
#define MIXER_STEPPER_SETUP()
Definition: mixing.h:73
TEST
#define TEST(n, b)
Definition: macros.h:81
HAS_DRIVER
#define HAS_DRIVER(T)
Definition: drivers.h:74
DELAY_NS
#define DELAY_NS(x)
Definition: Delay.h:172
Endstops::update
static void update()
Definition: endstops.cpp:496
E_AXIS_INIT
#define E_AXIS_INIT(NUM)
Y2_ENABLE_INIT
#define Y2_ENABLE_INIT
Definition: indirection.h:123
hal_timer_t
#define hal_timer_t
Definition: timers.h:33
Y_ENABLE_WRITE
#define Y_ENABLE_WRITE(STATE)
Definition: indirection.h:70
Planner::get_current_block
static block_t * get_current_block()
Definition: planner.h:769
XYZval
Definition: types.h:100
Z_ENABLE_ON
#define Z_ENABLE_ON
Definition: Configuration_A3ides_2209_MINI.h:928
Y_MOVE_TEST
#define Y_MOVE_TEST
E0_ENABLE_WRITE
#define E0_ENABLE_WRITE(STATE)
Definition: indirection.h:186
E_AXIS
Definition: types.h:40
SET_STEP_DIR
#define SET_STEP_DIR(A)
Z2_ENABLE_WRITE
#define Z2_ENABLE_WRITE(STATE)
Definition: indirection.h:145
B_AXIS
Definition: types.h:38
SBI
#define SBI(A, B)
Definition: macros.h:85
ENABLE_ISRS
#define ENABLE_ISRS()
Definition: HAL.h:52
X
Definition: L6470_Marlin.h:30
createSpeedLookupTable.b
list b
Definition: createSpeedLookupTable.py:30
E1_MS2_PIN
#define E1_MS2_PIN
Definition: pins.h:592
DIGIPOT_CHANNELS
#define DIGIPOT_CHANNELS
Definition: pins_RAMBO.h:111
READ
#define READ(IO)
Definition: fastio.h:95
hal_timer_t
uint16_t hal_timer_t
Definition: HAL.h:62
block_t::accelerate_until
uint32_t accelerate_until
Definition: planner.h:123
block_t
Definition: planner.h:95
endstops
Endstops endstops
Definition: endstops.cpp:51
AXIS_INIT
#define AXIS_INIT(AXIS, PIN)
block_t::extruder
static constexpr uint8_t extruder
Definition: planner.h:115
E1_DIR_INIT
#define E1_DIR_INIT
Definition: indirection.h:207
Stepper::set_position
static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e)
Definition: stepper.h:437
E1_MS3_PIN
#define E1_MS3_PIN
Definition: pins.h:595
Stepper::stepper_block_phase_isr
static uint32_t stepper_block_phase_isr()
Definition: stepper.cpp:1541
planner
Planner planner
Definition: planner.cpp:111
STEPPER_TIMER_RATE
#define STEPPER_TIMER_RATE
Definition: HAL.h:133
MIN_PULSE_TICKS
#define MIN_PULSE_TICKS
Definition: stepper.h:176