Total rework of simulator for dev branch. Create separate thread for interrupt processes. Tick-accurate simulation of timers. Non-blocking character input for running in realtime mode. Decouple hardware sim from grbl code as much as possible. Expanded command line options. Provisions for cross-platform solution.

This commit is contained in:
ashelly
2014-07-04 11:14:54 -04:00
parent 92d6c2bca5
commit 8c9f3bca65
33 changed files with 1062 additions and 437 deletions

View File

@@ -76,6 +76,9 @@ typedef struct {
#else
uint8_t prescaler; // Without AMASS, a prescaler is required to adjust for slow timing.
#endif
#ifdef AUTO_REPORT_MOVE_DONE
uint8_t block_end; //true for last segment of a block
#endif
} segment_t;
static segment_t segment_buffer[SEGMENT_BUFFER_SIZE];
@@ -242,7 +245,7 @@ void st_go_idle()
is usually not a physical problem at higher frequencies, although audible.
To improve Bresenham multi-axis performance, Grbl uses what we call an Adaptive Multi-Axis
Step Smoothing (AMASS) algorithm, which does what the name implies. At lower step frequencies,
AMASS artificially increases the Bresenham resolution without effecting the algorithm's
AMASS artificially increases the Bresenham resolution without affecting the algorithm's
innate exactness. AMASS adapts its resolution levels automatically depending on the step
frequency to be executed, meaning that for even lower step frequencies the step smoothing
level increases. Algorithmically, AMASS is acheived by a simple bit-shifting of the Bresenham
@@ -281,7 +284,7 @@ void st_go_idle()
// with probing and homing cycles that require true real-time positions.
ISR(TIMER1_COMPA_vect)
{
// SPINDLE_ENABLE_PORT ^= 1<<SPINDLE_ENABLE_BIT; // Debug: Used to time ISR
// TIMING_ENABLE_PORT ^= 1<<TIMING_ENABLE_BIT; // Debug: Used to time ISR
if (busy) { return; } // The busy-flag is used to avoid reentering this interrupt
// Set the direction pins a couple of nanoseconds before we step the steppers
@@ -395,6 +398,9 @@ ISR(TIMER1_COMPA_vect)
st.step_count--; // Decrement step events count
if (st.step_count == 0) {
// Segment is complete. Discard current segment and advance segment indexing.
#ifdef AUTO_REPORT_MOVE_DONE
sys.execute |= st.exec_segment->block_end;
#endif
st.exec_segment = NULL;
if ( ++segment_buffer_tail == SEGMENT_BUFFER_SIZE) { segment_buffer_tail = 0; }
}
@@ -793,8 +799,14 @@ void st_prep_buffer()
// Normal operation. Block incomplete. Distance remaining in block to be executed.
pl_block->millimeters = mm_remaining;
prep.steps_remaining = steps_remaining;
#ifdef AUTO_REPORT_MOVE_DONE
prep_segment->block_end = 0;
#endif
} else {
// End of planner block or forced-termination. No more distance to be executed.
#ifdef AUTO_REPORT_MOVE_DONE
prep_segment->block_end = EXEC_STATUS_REPORT; // force move-done report
#endif
if (mm_remaining > 0.0) { // At end of forced-termination.
// Reset prep parameters for resuming and then bail.
// NOTE: Currently only feed holds qualify for this scenario. May change with overrides.