mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-30 01:30:05 +02:00
Replace esp_delay_us() with ISR-friendly code in IRAM
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
// #define true 1
|
||||
|
||||
#include <cstdint>
|
||||
#include <esp_attr.h>
|
||||
#include <xtensa/core-macros.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user