mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-27 08:14:31 +02:00
Fix the I2S stream generates a 3x faster pulse. (#525)
I completely misunderstood the calculation of the interruption interval. Change to calculate the correct μsec interval from the tick value.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user