diff --git a/Grbl_Esp32/src/i2s_out.cpp b/Grbl_Esp32/src/i2s_out.cpp index 0ddbba61..a67a740c 100644 --- a/Grbl_Esp32/src/i2s_out.cpp +++ b/Grbl_Esp32/src/i2s_out.cpp @@ -101,8 +101,8 @@ static portMUX_TYPE i2s_out_spinlock = portMUX_INITIALIZER_UNLOCKED; static int i2s_out_initialized = 0; # ifdef USE_I2S_OUT_STREAM -static volatile uint32_t i2s_out_pulse_period; -static uint32_t i2s_out_remain_time_until_next_pulse; // Time remaining until the next pulse (μsec) +static volatile uint64_t i2s_out_pulse_period; +static uint64_t i2s_out_remain_time_until_next_pulse; // Time remaining until the next pulse (μsec) static volatile i2s_out_pulse_func_t i2s_out_pulse_func; # endif @@ -339,10 +339,12 @@ static int IRAM_ATTR i2s_fillout_dma_buffer(lldesc_t* dma_desc) { if (i2s_out_pulser_status == STEPPING) { // fillout future DMA buffer (tail of the DMA buffer chains) if (i2s_out_pulse_func != NULL) { + uint32_t old_rw_pos = o_dma.rw_pos; I2S_OUT_PULSER_EXIT_CRITICAL(); // Temporarily unlocked status lock as it may be locked in pulse callback. (*i2s_out_pulse_func)(); // should be pushed into buffer max DMA_SAMPLE_SAFE_COUNT I2S_OUT_PULSER_ENTER_CRITICAL(); // Lock again. - i2s_out_remain_time_until_next_pulse = i2s_out_pulse_period; + // Calculate pulse period. About magic number 2, refer to the st_wake_up(). (Ad hoc delay value) + i2s_out_remain_time_until_next_pulse = i2s_out_pulse_period - I2S_OUT_USEC_PER_PULSE * (o_dma.rw_pos - old_rw_pos) + 2; if (i2s_out_pulser_status == WAITING) { // i2s_out_set_passthrough() has called from the pulse function. // It needs to go into pass-through mode. @@ -610,9 +612,10 @@ int IRAM_ATTR i2s_out_set_stepping() { return 0; } -int IRAM_ATTR i2s_out_set_pulse_period(uint32_t period) { +int IRAM_ATTR i2s_out_set_pulse_period(uint64_t period) { # ifdef USE_I2S_OUT_STREAM - i2s_out_pulse_period = period; + // Use 64-bit values to avoid overflowing during the calculation. + i2s_out_pulse_period = period * 1000000 / F_STEPPER_TIMER; # endif return 0; } diff --git a/Grbl_Esp32/src/i2s_out.h b/Grbl_Esp32/src/i2s_out.h index 5c1078ca..816dbfb0 100644 --- a/Grbl_Esp32/src/i2s_out.h +++ b/Grbl_Esp32/src/i2s_out.h @@ -164,10 +164,10 @@ int i2s_out_set_stepping(); void i2s_out_delay(); /* - Set the pulse callback period in microseconds - (like the timer period for the ISR) + Set the pulse callback period in ISR ticks. + (same value of the timer period for the ISR) */ -int i2s_out_set_pulse_period(uint32_t period); +int i2s_out_set_pulse_period(uint64_t period); /* Register a callback function to generate pulse data diff --git a/Grbl_Esp32/src/stepper.cpp b/Grbl_Esp32/src/stepper.cpp index 96e1095d..843f1946 100644 --- a/Grbl_Esp32/src/stepper.cpp +++ b/Grbl_Esp32/src/stepper.cpp @@ -1176,7 +1176,7 @@ void IRAM_ATTR Stepper_Timer_WritePeriod(uint64_t alarm_val) { #ifdef USE_I2S_OUT_STREAM // 1 tick = F_TIMERS / F_STEPPER_TIMER // Pulse ISR is called for each tick of alarm_val. - i2s_out_set_pulse_period(alarm_val / 60); + i2s_out_set_pulse_period(alarm_val); #else timer_set_alarm_value(STEP_TIMER_GROUP, STEP_TIMER_INDEX, alarm_val); #endif