diff --git a/Grbl_Esp32/src/NutsBolts.h b/Grbl_Esp32/src/NutsBolts.h index 9e4a239a..d8e2b6d6 100644 --- a/Grbl_Esp32/src/NutsBolts.h +++ b/Grbl_Esp32/src/NutsBolts.h @@ -24,6 +24,8 @@ // #define true 1 #include +#include +#include enum class DwellMode : uint8_t { Dwell = 0, // (Default: Must be zero) @@ -93,6 +95,9 @@ const float INCH_PER_MM = (0.0393701f); // a pointer to the result variable. Returns true when it succeeds uint8_t read_float(const char* line, uint8_t* char_counter, float* float_ptr); +// Blocking delay for very short time intervals +void delay_us(int32_t microseconds); + // Non-blocking delay function used for general operation and suspend features. bool delay_msec(int32_t milliseconds, DwellMode mode); @@ -118,3 +123,38 @@ void swap(T& a, T& b) { a = b; b = c; } + +// Short delays measured using the CPU cycle counter. There is a ROM +// routine "esp_delay_us(us)" that almost does what what we need, +// except that it is in ROM and thus dodgy for use from ISRs. We +// duplicate the esp_delay_us() here, but placed in IRAM, inlined, +// and factored so it can be used in different ways. + +inline int32_t IRAM_ATTR getCpuTicks() { + return XTHAL_GET_CCOUNT(); +} + +extern uint32_t g_ticks_per_us_pro; // For CPU 0 - typically 240 MHz +extern uint32_t g_ticks_per_us_app; // For CPU 1 - typically 240 MHz + +inline int32_t IRAM_ATTR usToCpuTicks(int32_t us) { + return us * g_ticks_per_us_pro; +} + +inline int32_t IRAM_ATTR usToEndTicks(int32_t us) { + return getCpuTicks() + usToCpuTicks(us); +} + +// At the usual ESP32 clock rate of 240MHz, the range of this is +// just under 18 seconds, but it really should be used only for +// short delays up to a few tens of microseconds. + +inline void IRAM_ATTR spinUntil(int32_t endTicks) { + while ((XTHAL_GET_CCOUNT() - endTicks) < 0) { + asm volatile("nop"); + } +} + +inline void IRAM_ATTR delay_us(int32_t us) { + spinUntil(usToEndTicks(us)); +} diff --git a/Grbl_Esp32/src/Spindles/OnOffSpindle.cpp b/Grbl_Esp32/src/Spindles/OnOffSpindle.cpp index e615b7ae..a2ed64e9 100644 --- a/Grbl_Esp32/src/Spindles/OnOffSpindle.cpp +++ b/Grbl_Esp32/src/Spindles/OnOffSpindle.cpp @@ -52,7 +52,7 @@ namespace Spindles { } set_output(dev_speed); set_enable(state != SpindleState::Disable); - spinDelay(state, speed); + spindleDelay(state, speed); sys.report_ovr_counter = 0; // Set to report change immediately } diff --git a/Grbl_Esp32/src/Spindles/PWMSpindle.cpp b/Grbl_Esp32/src/Spindles/PWMSpindle.cpp index bf1dc810..5a980b3e 100644 --- a/Grbl_Esp32/src/Spindles/PWMSpindle.cpp +++ b/Grbl_Esp32/src/Spindles/PWMSpindle.cpp @@ -112,7 +112,7 @@ namespace Spindles { // converters on some boards. set_output(dev_speed); set_enable(state != SpindleState::Disable); - spinDelay(state, speed); + spindleDelay(state, speed); sys.report_ovr_counter = 0; // Set to report change immediately } diff --git a/Grbl_Esp32/src/Spindles/Spindle.cpp b/Grbl_Esp32/src/Spindles/Spindle.cpp index 2ad3cb97..ec59c86c 100644 --- a/Grbl_Esp32/src/Spindles/Spindle.cpp +++ b/Grbl_Esp32/src/Spindles/Spindle.cpp @@ -140,7 +140,7 @@ namespace Spindles { // log_debug("rpm " << speed << " speed " << dev_speed); // This will spew quite a bit of data on your output return dev_speed; } - void Spindle::spinDelay(SpindleState state, SpindleSpeed speed) { + void Spindle::spindleDelay(SpindleState state, SpindleSpeed speed) { uint32_t up = 0, down = 0; switch (state) { case SpindleState::Unknown: diff --git a/Grbl_Esp32/src/Spindles/Spindle.h b/Grbl_Esp32/src/Spindles/Spindle.h index 262646ea..a2457f4e 100644 --- a/Grbl_Esp32/src/Spindles/Spindle.h +++ b/Grbl_Esp32/src/Spindles/Spindle.h @@ -59,7 +59,7 @@ namespace Spindles { static void switchSpindle(uint8_t new_tool, SpindleList spindles, Spindle*& spindle); - void spinDelay(SpindleState state, SpindleSpeed speed); + void spindleDelay(SpindleState state, SpindleSpeed speed); virtual void init() = 0; // not in constructor because this also gets called when $$ settings change // Used by Protocol.cpp to restore the state during a restart diff --git a/Grbl_Esp32/src/Spindles/VFDSpindle.cpp b/Grbl_Esp32/src/Spindles/VFDSpindle.cpp index a6062db7..fad10b74 100644 --- a/Grbl_Esp32/src/Spindles/VFDSpindle.cpp +++ b/Grbl_Esp32/src/Spindles/VFDSpindle.cpp @@ -345,7 +345,7 @@ namespace Spindles { } } if (!supports_actual_speed()) { - spinDelay(state, speed); + spindleDelay(state, speed); } else { // _sync_dev_speed is set by a callback that handles // responses from periodic get_current_speed() requests. @@ -386,7 +386,7 @@ namespace Spindles { } _syncing = false; - // spinDelay() sets these when it is used + // spindleDelay() sets these when it is used _current_state = state; _current_speed = speed; } diff --git a/Grbl_Esp32/src/Stepping.cpp b/Grbl_Esp32/src/Stepping.cpp index 293c440c..f942610f 100644 --- a/Grbl_Esp32/src/Stepping.cpp +++ b/Grbl_Esp32/src/Stepping.cpp @@ -73,13 +73,6 @@ namespace Machine { _engine = I2S_STREAM; } } - void IRAM_ATTR Stepping::spinDelay(int64_t start_time, uint32_t durationUs) { - int64_t endTime = start_time + durationUs; - while ((esp_timer_get_time() - endTime) < 0) { - NOP(); - } - } - void IRAM_ATTR Stepping::waitPulse() { uint64_t pulseEndTime; switch (_engine) { @@ -90,7 +83,7 @@ namespace Machine { case I2S_STATIC: i2s_out_push(); case TIMED: - spinDelay(_stepPulseStartTime, _pulseUsecs); + spinUntil(_stepPulseEndTime); break; case RMT: // RMT generates the trailing edges in hardware @@ -112,7 +105,7 @@ namespace Machine { // If we are using GPIO stepping as opposed to RMT, record the // time that we turned on the direction pins so we can delay a bit. // If we are using RMT, we can't delay here. - spinDelay(esp_timer_get_time(), _directionDelayUsecs); + delay_us(_directionDelayUsecs); break; case stepper_id_t::RMT: break; @@ -126,7 +119,7 @@ namespace Machine { break; case stepper_id_t::I2S_STATIC: case stepper_id_t::TIMED: - _stepPulseStartTime = esp_timer_get_time(); + _stepPulseEndTime = usToEndTicks(_pulseUsecs); break; case stepper_id_t::RMT: break; diff --git a/Grbl_Esp32/src/Stepping.h b/Grbl_Esp32/src/Stepping.h index 16411ef0..bc69a4e9 100644 --- a/Grbl_Esp32/src/Stepping.h +++ b/Grbl_Esp32/src/Stepping.h @@ -35,9 +35,7 @@ namespace Machine { static const int ticksPerMicrosecond = fStepperTimer / 1000000; bool _switchedStepper = false; - int64_t _stepPulseStartTime; - - static void spinDelay(int64_t start_time, uint32_t duration); + int32_t _stepPulseEndTime; public: // Counts stepper ISR invocations. This variable can be inspected