G6 Direct Stepping (#17853)

This commit is contained in:
Colin Godsey
2020-05-11 18:22:41 -06:00
committed by GitHub
parent 174e41c17d
commit 8a22ef0c83
17 changed files with 859 additions and 64 deletions

View File

@ -151,6 +151,11 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step
uint8_t Planner::last_extruder = 0; // Respond to extruder change
#endif
#if ENABLED(DIRECT_STEPPING)
uint32_t Planner::last_page_step_rate = 0;
xyze_bool_t Planner::last_page_dir{0};
#endif
#if EXTRUDERS
int16_t Planner::flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); // Extrusion factor for each extruder
float Planner::e_factor[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0f); // The flow percentage and volumetric multiplier combine to scale E movement
@ -235,6 +240,10 @@ void Planner::init() {
TERN_(ABL_PLANAR, bed_level_matrix.set_to_identity());
clear_block_buffer();
delay_before_delivering = 0;
#if ENABLED(DIRECT_STEPPING)
last_page_step_rate = 0;
last_page_dir.reset();
#endif
}
#if ENABLED(S_CURVE_ACCELERATION)
@ -906,7 +915,7 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e
streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
planner buffer that don't change with the addition of a new block, as describe above. In addition,
this block can never be less than block_buffer_tail and will always be pushed forward and maintain
this requirement when encountered by the Planner::discard_current_block() routine during a cycle.
this requirement when encountered by the Planner::release_current_block() routine during a cycle.
NOTE: Since the planner only computes on what's in the planner buffer, some motions with lots of short
line segments, like G2/3 arcs or complex curves, may seem to move slow. This is because there simply isn't
@ -994,8 +1003,8 @@ void Planner::reverse_pass() {
// Perform the reverse pass
block_t *current = &block_buffer[block_index];
// Only consider non sync blocks
if (!TEST(current->flag, BLOCK_BIT_SYNC_POSITION)) {
// Only consider non sync and page blocks
if (!TEST(current->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(current)) {
reverse_pass_kernel(current, next);
next = current;
}
@ -1089,8 +1098,8 @@ void Planner::forward_pass() {
// Perform the forward pass
block = &block_buffer[block_index];
// Skip SYNC blocks
if (!TEST(block->flag, BLOCK_BIT_SYNC_POSITION)) {
// Skip SYNC and page blocks
if (!TEST(block->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(block)) {
// If there's no previous block or the previous block is not
// BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
// the previous block became BUSY, so assume the current block's
@ -1139,8 +1148,8 @@ void Planner::recalculate_trapezoids() {
next = &block_buffer[block_index];
// Skip sync blocks
if (!TEST(next->flag, BLOCK_BIT_SYNC_POSITION)) {
// Skip sync and page blocks
if (!TEST(next->flag, BLOCK_BIT_SYNC_POSITION) && !IS_PAGE(next)) {
next_entry_speed = SQRT(next->entry_speed_sqr);
if (block) {
@ -2717,6 +2726,69 @@ bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, con
#endif
} // buffer_line()
#if ENABLED(DIRECT_STEPPING)
void Planner::buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps) {
if (!last_page_step_rate) {
kill(GET_TEXT(MSG_BAD_PAGE_SPEED));
return;
}
uint8_t next_buffer_head;
block_t * const block = get_next_free_block(next_buffer_head);
block->flag = BLOCK_FLAG_IS_PAGE;
#if FAN_COUNT > 0
FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
#endif
#if EXTRUDERS > 1
block->extruder = extruder;
#endif
block->page_idx = page_idx;
block->step_event_count = num_steps;
block->initial_rate =
block->final_rate =
block->nominal_rate = last_page_step_rate; // steps/s
block->accelerate_until = 0;
block->decelerate_after = block->step_event_count;
// Will be set to last direction later if directional format.
block->direction_bits = 0;
#define PAGE_UPDATE_DIR(AXIS) \
if (!last_page_dir[_AXIS(AXIS)]) SBI(block->direction_bits, _AXIS(AXIS));
if (!DirectStepping::Config::DIRECTIONAL) {
PAGE_UPDATE_DIR(X);
PAGE_UPDATE_DIR(Y);
PAGE_UPDATE_DIR(Z);
PAGE_UPDATE_DIR(E);
}
// If this is the first added movement, reload the delay, otherwise, cancel it.
if (block_buffer_head == block_buffer_tail) {
// If it was the first queued block, restart the 1st block delivery delay, to
// give the planner an opportunity to queue more movements and plan them
// As there are no queued movements, the Stepper ISR will not touch this
// variable, so there is no risk setting this here (but it MUST be done
// before the following line!!)
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
}
// Move buffer head
block_buffer_head = next_buffer_head;
enable_all_steppers();
stepper.wake_up();
}
#endif // DIRECT_STEPPING
/**
* Directly set the planner ABC position (and stepper positions)
* converting mm (or angles for SCARA) into steps.