*/
// Timer assignments - see specific modules for details
-#define TIMER_STEP TCC0 // Step timer (see stepper.h)
-#define TIMER_TMC2660 TCC1 // TMC2660 timer (see tmc2660.h)
-#define TIMER_PWM TCD1 // PWM timer (see pwm_spindle.c)
+#define TIMER_STEP TCC0 // Step timer (see stepper.h)
+#define TIMER_TMC2660 TCC1 // TMC2660 timer (see tmc2660.h)
+#define TIMER_PWM TCD1 // PWM timer (see pwm_spindle.c)
-#define M1_TIMER TCE1
-#define M2_TIMER TCF0
-#define M3_TIMER TCE0
-#define M4_TIMER TCD0
+#define M1_TIMER TCE1
+#define M2_TIMER TCF0
+#define M3_TIMER TCE0
+#define M4_TIMER TCD0
-#define M1_DMA_CH DMA.CH0
-#define M2_DMA_CH DMA.CH1
-#define M3_DMA_CH DMA.CH2
-#define M4_DMA_CH DMA.CH3
+#define M1_DMA_CH DMA.CH0
+#define M2_DMA_CH DMA.CH1
+#define M3_DMA_CH DMA.CH2
+#define M4_DMA_CH DMA.CH3
-#define M1_DMA_TRIGGER DMA_CH_TRIGSRC_TCE1_CCA_gc
-#define M2_DMA_TRIGGER DMA_CH_TRIGSRC_TCF0_CCA_gc
-#define M3_DMA_TRIGGER DMA_CH_TRIGSRC_TCE0_CCA_gc
-#define M4_DMA_TRIGGER DMA_CH_TRIGSRC_TCD0_CCA_gc
+#define M1_DMA_TRIGGER DMA_CH_TRIGSRC_TCE1_CCA_gc
+#define M2_DMA_TRIGGER DMA_CH_TRIGSRC_TCF0_CCA_gc
+#define M3_DMA_TRIGGER DMA_CH_TRIGSRC_TCE0_CCA_gc
+#define M4_DMA_TRIGGER DMA_CH_TRIGSRC_TCD0_CCA_gc
// Timer setup for stepper and dwells
-#define STEP_TIMER_DISABLE 0
-#define STEP_TIMER_ENABLE TC_CLKSEL_DIV4_gc
-#define STEP_TIMER_DIV 4
-#define STEP_TIMER_FREQ (F_CPU / STEP_TIMER_DIV)
-#define STEP_TIMER_POLL (STEP_TIMER_FREQ * 0.001)
-#define STEP_TIMER_WGMODE TC_WGMODE_NORMAL_gc // count to TOP & rollover
-#define STEP_TIMER_ISR TCC0_OVF_vect
-#define STEP_TIMER_INTLVL TC_OVFINTLVL_HI_gc
-
-#define SEG_MIN_TIME EPSILON
-#define SEG_MAX_TIME ((float)0xffff / 60.0 / STEP_TIMER_FREQ)
+#define STEP_TIMER_DISABLE 0
+#define STEP_TIMER_ENABLE TC_CLKSEL_DIV4_gc
+#define STEP_TIMER_DIV 4
+#define STEP_TIMER_FREQ (F_CPU / STEP_TIMER_DIV)
+#define STEP_TIMER_POLL (STEP_TIMER_FREQ * 0.001)
+#define STEP_TIMER_WGMODE TC_WGMODE_NORMAL_gc // count to TOP & rollover
+#define STEP_TIMER_ISR TCC0_OVF_vect
+#define STEP_TIMER_INTLVL TC_OVFINTLVL_HI_gc
+
+#define MAX_SEGMENT_TIME ((float)0xffff / 60.0 / STEP_TIMER_FREQ)
+#define NOM_SEGMENT_USEC 5000.0 // nominal segment time
+#define MIN_SEGMENT_USEC 2500.0 // minimum segment time
// TMC2660 driver settings
STAT_MSG(MOTOR_OVERTEMP, "Motor over temperature")
STAT_MSG(MOTOR_SHORTED, "Motor shorted")
-STAT_MSG(PREP_LINE_MOVE_TIME_IS_INFINITE, "Move time is infinite")
-STAT_MSG(PREP_LINE_MOVE_TIME_IS_NAN, "Move time is NAN")
-STAT_MSG(MOVE_TARGET_IS_INFINITE, "Move target is infinite")
-STAT_MSG(MOVE_TARGET_IS_NAN, "Move target is NAN")
+STAT_MSG(PREP_LINE_MOVE_TIME_INFINITE, "Move time is infinite")
+STAT_MSG(PREP_LINE_MOVE_TIME_NAN, "Move time is NAN")
+STAT_MSG(MOVE_TARGET_INFINITE, "Move target is infinite")
+STAT_MSG(MOVE_TARGET_NAN, "Move target is NAN")
STAT_MSG(EXCESSIVE_MOVE_ERROR, "Excessive move error")
STAT_MSG(ESTOP_USER, "User triggered EStop")
// Errors and warnings
STAT_MSG(MINIMUM_LENGTH_MOVE, "Move less than minimum length")
STAT_MSG(MINIMUM_TIME_MOVE, "Move less than minimum time")
+STAT_MSG(MAXIMUM_TIME_MOVE, "Move greater than maximum time")
STAT_MSG(MACHINE_ALARMED, "Machine alarmed - Command not processed")
STAT_MSG(LIMIT_SWITCH_HIT, "Limit switch hit - Shutdown occurred")
STAT_MSG(SOFT_LIMIT_EXCEEDED, "Soft limit exceeded")
// Validate input
if (motor < 0 || MOTORS < motor) return ALARM(STAT_INTERNAL_ERROR);
if (clocks < 0) return ALARM(STAT_INTERNAL_ERROR);
- if (isinf(target)) return ALARM(STAT_MOVE_TARGET_IS_INFINITE);
- if (isnan(target)) return ALARM(STAT_MOVE_TARGET_IS_NAN);
+ if (isinf(target)) return ALARM(STAT_MOVE_TARGET_INFINITE);
+ if (isnan(target)) return ALARM(STAT_MOVE_TARGET_NAN);
// Compute error correction
#if 0
// len / avg. velocity
float move_time = 2 * length / (vin + vout);
- ex.segments = ceil(move_time * MICROSECONDS_PER_MINUTE / NOM_SEGMENT_USEC);
+ ex.segments = ceil(move_time / NOM_SEGMENT_TIME);
ex.segment_time = move_time / ex.segments;
ex.segment_count = (uint32_t)ex.segments;
static planner_t mp = {{0}};
-void mp_init() {mp_queue_init();}
+void mp_init() {
+ // Nominal segment time cannot be longer than maximum
+ if (MAX_SEGMENT_TIME < NOM_SEGMENT_USEC) ALARM(STAT_INTERNAL_ERROR);
+
+ mp_queue_init();
+}
/// Set planner position for a single axis
#include "machine.h" // used for gcode_state_t
#include "buffer.h"
#include "util.h"
+#include "config.h"
#include <stdbool.h>
#define JERK_MULTIPLIER 1000000.0
#define JERK_MATCH_PRECISION 1000.0 // jerk precision to be considered same
-#define NOM_SEGMENT_USEC 5000.0 // nominal segment time
-#define MIN_SEGMENT_USEC 2500.0 // minimum segment time
-
#define NOM_SEGMENT_TIME (NOM_SEGMENT_USEC / MICROSECONDS_PER_MINUTE)
#define MIN_SEGMENT_TIME (MIN_SEGMENT_USEC / MICROSECONDS_PER_MINUTE)
#define MIN_SEGMENT_TIME_PLUS_MARGIN \
((MIN_SEGMENT_USEC + 1) / MICROSECONDS_PER_MINUTE)
-/// Max iterations for convergence in the HT asymmetric case.
-#define TRAPEZOID_ITERATION_MAX 10
-
/// Error percentage for iteration convergence. As percent - 0.01 = 1%
#define TRAPEZOID_ITERATION_ERROR_PERCENT 0.1
-/// Tolerance for "exact fit" for H and T cases
-/// allowable mm of error in planning phase
-#define TRAPEZOID_LENGTH_FIT_TOLERANCE 0.0001
-
/// Adaptive velocity tolerance term
#define TRAPEZOID_VELOCITY_TOLERANCE (max(2, bf->entry_velocity / 100))
*/
#define HOLD_DECELERATION_TOLERANCE 1 // In mm
+
typedef enum {
SECTION_HEAD, // acceleration
SECTION_BODY, // cruise
if (!fp_ZERO(old_length_sqr)) {
float new_time = time * sqrt(new_length_sqr / old_length_sqr);
- if (SEG_MIN_TIME <= new_time && new_time <= SEG_MAX_TIME) {
+ if (EPSILON <= new_time && new_time <= MAX_SEGMENT_TIME) {
time = new_time;
use_error = true;
}
*/
stat_t st_prep_line(float time, const float target[], const int32_t error[]) {
// Trap conditions that would prevent queueing the line
- if (st.move_ready) return ALARM(STAT_INTERNAL_ERROR);
- if (isinf(time)) return ALARM(STAT_PREP_LINE_MOVE_TIME_IS_INFINITE);
- if (isnan(time)) return ALARM(STAT_PREP_LINE_MOVE_TIME_IS_NAN);
- if (time < EPSILON) return ALARM(STAT_MINIMUM_TIME_MOVE);
+ if (st.move_ready) return ALARM(STAT_INTERNAL_ERROR);
+ if (isinf(time)) return ALARM(STAT_PREP_LINE_MOVE_TIME_INFINITE);
+ if (isnan(time)) return ALARM(STAT_PREP_LINE_MOVE_TIME_NAN);
+ if (time < EPSILON) return ALARM(STAT_MINIMUM_TIME_MOVE);
+ if (MAX_SEGMENT_TIME < time) return ALARM(STAT_MAXIMUM_TIME_MOVE);
// Setup segment parameters
st.move_type = MOVE_TYPE_ALINE;