mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-28 08:39:51 +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;
|
static int i2s_out_initialized = 0;
|
||||||
|
|
||||||
# ifdef USE_I2S_OUT_STREAM
|
# ifdef USE_I2S_OUT_STREAM
|
||||||
static volatile uint32_t i2s_out_pulse_period;
|
static volatile uint64_t i2s_out_pulse_period;
|
||||||
static uint32_t i2s_out_remain_time_until_next_pulse; // Time remaining until the next pulse (μsec)
|
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;
|
static volatile i2s_out_pulse_func_t i2s_out_pulse_func;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -339,10 +339,12 @@ static int IRAM_ATTR i2s_fillout_dma_buffer(lldesc_t* dma_desc) {
|
|||||||
if (i2s_out_pulser_status == STEPPING) {
|
if (i2s_out_pulser_status == STEPPING) {
|
||||||
// fillout future DMA buffer (tail of the DMA buffer chains)
|
// fillout future DMA buffer (tail of the DMA buffer chains)
|
||||||
if (i2s_out_pulse_func != NULL) {
|
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_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_pulse_func)(); // should be pushed into buffer max DMA_SAMPLE_SAFE_COUNT
|
||||||
I2S_OUT_PULSER_ENTER_CRITICAL(); // Lock again.
|
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) {
|
if (i2s_out_pulser_status == WAITING) {
|
||||||
// i2s_out_set_passthrough() has called from the pulse function.
|
// i2s_out_set_passthrough() has called from the pulse function.
|
||||||
// It needs to go into pass-through mode.
|
// It needs to go into pass-through mode.
|
||||||
@@ -610,9 +612,10 @@ int IRAM_ATTR i2s_out_set_stepping() {
|
|||||||
return 0;
|
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
|
# 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
|
# endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -164,10 +164,10 @@ int i2s_out_set_stepping();
|
|||||||
void i2s_out_delay();
|
void i2s_out_delay();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the pulse callback period in microseconds
|
Set the pulse callback period in ISR ticks.
|
||||||
(like the timer period for the ISR)
|
(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
|
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
|
#ifdef USE_I2S_OUT_STREAM
|
||||||
// 1 tick = F_TIMERS / F_STEPPER_TIMER
|
// 1 tick = F_TIMERS / F_STEPPER_TIMER
|
||||||
// Pulse ISR is called for each tick of alarm_val.
|
// 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
|
#else
|
||||||
timer_set_alarm_value(STEP_TIMER_GROUP, STEP_TIMER_INDEX, alarm_val);
|
timer_set_alarm_value(STEP_TIMER_GROUP, STEP_TIMER_INDEX, alarm_val);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user