// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This // implements the reverse pass. void planner_reverse_pass() { uint8_t block_index = block_buffer_head; //Make a local copy of block_buffer_tail, because the interrupt can alter it CRITICAL_SECTION_START; unsigned char tail = block_buffer_tail; CRITICAL_SECTION_END if (BLOCK_MOD(block_buffer_head - tail + BLOCK_BUFFER_SIZE) > 3) { // moves queued block_index = BLOCK_MOD(block_buffer_head - 3); block_t *block[3] = { NULL, NULL, NULL }; while (block_index != tail) { block_index = prev_block_index(block_index); block[2]= block[1]; block[1]= block[0]; block[0] = &block_buffer[block_index]; planner_reverse_pass_kernel(block[0], block[1], block[2]); } } }
/** * recalculate() needs to go over the current plan twice. * Once in reverse and once forward. This implements the reverse pass. */ void Planner::reverse_pass() { if (movesplanned() > 3) { block_t* block[3] = { NULL, NULL, NULL }; // Make a local copy of block_buffer_tail, because the interrupt can alter it CRITICAL_SECTION_START; uint8_t tail = block_buffer_tail; CRITICAL_SECTION_END uint8_t b = BLOCK_MOD(block_buffer_head - 3); while (b != tail) { b = prev_block_index(b); block[2] = block[1]; block[1] = block[0]; block[0] = &block_buffer[b]; reverse_pass_kernel(block[0], block[1], block[2]); } } }
FORCE_INLINE int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
// Get the next / previous index of the next block in the ring buffer // NOTE: Using & here (not %) because BLOCK_BUFFER_SIZE is always a power of 2 FORCE_INLINE int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }