From e843bc8a6796a6202a3640e29309f0dca4845e4e Mon Sep 17 00:00:00 2001 From: Mitch Bradley Date: Tue, 6 Jul 2021 19:21:26 -1000 Subject: [PATCH] Fixed I2S_STATIC stepping --- Grbl_Esp32/src/I2SOut.cpp | 29 ++++++++++----------------- Grbl_Esp32/src/I2SOut.h | 2 ++ Grbl_Esp32/src/Machine/Axes.cpp | 1 + Grbl_Esp32/src/Pins/I2SOPinDetail.cpp | 1 + Grbl_Esp32/src/Stepping.cpp | 15 ++++++++++++++ Grbl_Esp32/src/Stepping.h | 1 + 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Grbl_Esp32/src/I2SOut.cpp b/Grbl_Esp32/src/I2SOut.cpp index f28e9032..cc461177 100644 --- a/Grbl_Esp32/src/I2SOut.cpp +++ b/Grbl_Esp32/src/I2SOut.cpp @@ -168,14 +168,16 @@ static inline void gpio_matrix_out_check(uint8_t gpio, uint32_t signal_idx, bool } } -static inline void i2s_out_single_data() { +void i2s_out_push() { + if (i2s_out_pulser_status == PASSTHROUGH) { #if I2S_OUT_NUM_BITS == 16 - uint32_t port_data = atomic_load(&i2s_out_port_data); - port_data <<= 16; // Shift needed. This specification is not spelled out in the manual. - I2S0.conf_single_data = port_data; // Apply port data in real-time (static I2S) + uint32_t port_data = atomic_load(&i2s_out_port_data); + port_data <<= 16; // Shift needed. This specification is not spelled out in the manual. + I2S0.conf_single_data = port_data; // Apply port data in real-time (static I2S) #else - I2S0.conf_single_data = atomic_load(&i2s_out_port_data); // Apply port data in real-time (static I2S) + I2S0.conf_single_data = atomic_load(&i2s_out_port_data); // Apply port data in real-time (static I2S) #endif + } } static inline void i2s_out_reset_fifo_without_lock() { @@ -561,15 +563,6 @@ void IRAM_ATTR i2s_out_write(uint8_t pin, uint8_t val) { } else { atomic_fetch_and(&i2s_out_port_data, ~bit); } -#ifdef USE_I2S_OUT_STREAM_IMPL - // It needs a lock for access, but I've given up because I need speed. - // This is not a problem as long as there is no overlap between the status change and digitalWrite(). - if (i2s_out_pulser_status == PASSTHROUGH) { - i2s_out_single_data(); - } -#else - i2s_out_single_data(); -#endif } uint8_t IRAM_ATTR i2s_out_read(uint8_t pin) { @@ -835,8 +828,8 @@ int IRAM_ATTR i2s_out_init(i2s_out_init_t& init_param) { } #else // For the static output mode - I2S0.conf_chan.tx_chan_mod = 3; // 3:right+constant 4:left+constant (when tx_msb_right = 1) - I2S0.conf_single_data = init_param.init_val; // initial constant value + I2S0.conf_chan.tx_chan_mod = 3; // 3:right+constant 4:left+constant (when tx_msb_right = 1) + I2S0.conf_single_data = init_param.init_val; // initial constant value #endif #if I2S_OUT_NUM_BITS == 16 I2S0.fifo_conf.tx_fifo_mod = 0; // 0: 16-bit dual channel data, 3: 32-bit single channel data @@ -844,8 +837,8 @@ int IRAM_ATTR i2s_out_init(i2s_out_init_t& init_param) { I2S0.sample_rate_conf.tx_bits_mod = 16; // default is 16-bits I2S0.sample_rate_conf.rx_bits_mod = 16; // default is 16-bits #else - I2S0.fifo_conf.tx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data - I2S0.fifo_conf.rx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data + I2S0.fifo_conf.tx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data + I2S0.fifo_conf.rx_fifo_mod = 3; // 0: 16-bit dual channel data, 3: 32-bit single channel data // Data width is 32-bit. Forgetting this setting will result in a 16-bit transfer. I2S0.sample_rate_conf.tx_bits_mod = 32; I2S0.sample_rate_conf.rx_bits_mod = 32; diff --git a/Grbl_Esp32/src/I2SOut.h b/Grbl_Esp32/src/I2SOut.h index 36bca3a2..6800f97e 100644 --- a/Grbl_Esp32/src/I2SOut.h +++ b/Grbl_Esp32/src/I2SOut.h @@ -110,6 +110,8 @@ int i2s_out_init(); */ uint8_t i2s_out_read(uint8_t pin); +void i2s_out_push(); + /* Set a bit in the internal pin state var. (not written electrically) pin: expanded pin No. (0..31) diff --git a/Grbl_Esp32/src/Machine/Axes.cpp b/Grbl_Esp32/src/Machine/Axes.cpp index 74c03cb4..bd043761 100644 --- a/Grbl_Esp32/src/Machine/Axes.cpp +++ b/Grbl_Esp32/src/Machine/Axes.cpp @@ -160,6 +160,7 @@ namespace Machine { a->unstep(); } } + config->_stepping->finishPulse(); } // Some small helpers to find the axis index and axis ganged index for a given motor. This diff --git a/Grbl_Esp32/src/Pins/I2SOPinDetail.cpp b/Grbl_Esp32/src/Pins/I2SOPinDetail.cpp index 1981cb58..f726b54e 100644 --- a/Grbl_Esp32/src/Pins/I2SOPinDetail.cpp +++ b/Grbl_Esp32/src/Pins/I2SOPinDetail.cpp @@ -60,6 +60,7 @@ namespace Pins { // Write and wait for completion. Not suitable for use from an ISR void I2SOPinDetail::synchronousWrite(int high) { write(high); + i2s_out_push(); i2s_out_delay(); } diff --git a/Grbl_Esp32/src/Stepping.cpp b/Grbl_Esp32/src/Stepping.cpp index bec8f2c2..ac675230 100644 --- a/Grbl_Esp32/src/Stepping.cpp +++ b/Grbl_Esp32/src/Stepping.cpp @@ -91,6 +91,7 @@ namespace Machine { i2s_out_push_sample(_pulseUsecs); break; case I2S_STATIC: + i2s_out_push(); case TIMED: spinDelay(_stepPulseStartTime, _pulseUsecs); break; @@ -135,6 +136,20 @@ namespace Machine { } } + void Stepping::finishPulse() { + switch (_engine) { + case stepper_id_t::I2S_STREAM: + break; + case stepper_id_t::I2S_STATIC: + i2s_out_push(); + break; + case stepper_id_t::TIMED: + break; + case stepper_id_t::RMT: + break; + } + } + // The argument is in units of ticks of the timer that generates ISRs void IRAM_ATTR Stepping::setTimerPeriod(uint16_t timerTicks) { if (_engine == I2S_STREAM) { diff --git a/Grbl_Esp32/src/Stepping.h b/Grbl_Esp32/src/Stepping.h index ddaed45d..2e5acd14 100644 --- a/Grbl_Esp32/src/Stepping.h +++ b/Grbl_Esp32/src/Stepping.h @@ -74,6 +74,7 @@ namespace Machine { void waitPulse(); // Wait for pulse length void waitDirection(); // Wait for direction delay void waitMotion(); // Wait for motion to complete + void finishPulse(); // Cleanup after unstep // Timers void setTimerPeriod(uint16_t timerTicks);