mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-30 09:39:49 +02:00
Replace esp_delay_us() with ISR-friendly code in IRAM
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
// #define true 1
|
// #define true 1
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <esp_attr.h>
|
||||||
|
#include <xtensa/core-macros.h>
|
||||||
|
|
||||||
enum class DwellMode : uint8_t {
|
enum class DwellMode : uint8_t {
|
||||||
Dwell = 0, // (Default: Must be zero)
|
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
|
// 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);
|
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.
|
// Non-blocking delay function used for general operation and suspend features.
|
||||||
bool delay_msec(int32_t milliseconds, DwellMode mode);
|
bool delay_msec(int32_t milliseconds, DwellMode mode);
|
||||||
|
|
||||||
@@ -118,3 +123,38 @@ void swap(T& a, T& b) {
|
|||||||
a = b;
|
a = b;
|
||||||
b = c;
|
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_output(dev_speed);
|
||||||
set_enable(state != SpindleState::Disable);
|
set_enable(state != SpindleState::Disable);
|
||||||
spinDelay(state, speed);
|
spindleDelay(state, speed);
|
||||||
|
|
||||||
sys.report_ovr_counter = 0; // Set to report change immediately
|
sys.report_ovr_counter = 0; // Set to report change immediately
|
||||||
}
|
}
|
||||||
|
@@ -112,7 +112,7 @@ namespace Spindles {
|
|||||||
// converters on some boards.
|
// converters on some boards.
|
||||||
set_output(dev_speed);
|
set_output(dev_speed);
|
||||||
set_enable(state != SpindleState::Disable);
|
set_enable(state != SpindleState::Disable);
|
||||||
spinDelay(state, speed);
|
spindleDelay(state, speed);
|
||||||
|
|
||||||
sys.report_ovr_counter = 0; // Set to report change immediately
|
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
|
// log_debug("rpm " << speed << " speed " << dev_speed); // This will spew quite a bit of data on your output
|
||||||
return dev_speed;
|
return dev_speed;
|
||||||
}
|
}
|
||||||
void Spindle::spinDelay(SpindleState state, SpindleSpeed speed) {
|
void Spindle::spindleDelay(SpindleState state, SpindleSpeed speed) {
|
||||||
uint32_t up = 0, down = 0;
|
uint32_t up = 0, down = 0;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SpindleState::Unknown:
|
case SpindleState::Unknown:
|
||||||
|
@@ -59,7 +59,7 @@ namespace Spindles {
|
|||||||
|
|
||||||
static void switchSpindle(uint8_t new_tool, SpindleList spindles, Spindle*& spindle);
|
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
|
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
|
// Used by Protocol.cpp to restore the state during a restart
|
||||||
|
@@ -345,7 +345,7 @@ namespace Spindles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!supports_actual_speed()) {
|
if (!supports_actual_speed()) {
|
||||||
spinDelay(state, speed);
|
spindleDelay(state, speed);
|
||||||
} else {
|
} else {
|
||||||
// _sync_dev_speed is set by a callback that handles
|
// _sync_dev_speed is set by a callback that handles
|
||||||
// responses from periodic get_current_speed() requests.
|
// responses from periodic get_current_speed() requests.
|
||||||
@@ -386,7 +386,7 @@ namespace Spindles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_syncing = false;
|
_syncing = false;
|
||||||
// spinDelay() sets these when it is used
|
// spindleDelay() sets these when it is used
|
||||||
_current_state = state;
|
_current_state = state;
|
||||||
_current_speed = speed;
|
_current_speed = speed;
|
||||||
}
|
}
|
||||||
|
@@ -73,13 +73,6 @@ namespace Machine {
|
|||||||
_engine = I2S_STREAM;
|
_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() {
|
void IRAM_ATTR Stepping::waitPulse() {
|
||||||
uint64_t pulseEndTime;
|
uint64_t pulseEndTime;
|
||||||
switch (_engine) {
|
switch (_engine) {
|
||||||
@@ -90,7 +83,7 @@ namespace Machine {
|
|||||||
case I2S_STATIC:
|
case I2S_STATIC:
|
||||||
i2s_out_push();
|
i2s_out_push();
|
||||||
case TIMED:
|
case TIMED:
|
||||||
spinDelay(_stepPulseStartTime, _pulseUsecs);
|
spinUntil(_stepPulseEndTime);
|
||||||
break;
|
break;
|
||||||
case RMT:
|
case RMT:
|
||||||
// RMT generates the trailing edges in hardware
|
// 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
|
// 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.
|
// time that we turned on the direction pins so we can delay a bit.
|
||||||
// If we are using RMT, we can't delay here.
|
// If we are using RMT, we can't delay here.
|
||||||
spinDelay(esp_timer_get_time(), _directionDelayUsecs);
|
delay_us(_directionDelayUsecs);
|
||||||
break;
|
break;
|
||||||
case stepper_id_t::RMT:
|
case stepper_id_t::RMT:
|
||||||
break;
|
break;
|
||||||
@@ -126,7 +119,7 @@ namespace Machine {
|
|||||||
break;
|
break;
|
||||||
case stepper_id_t::I2S_STATIC:
|
case stepper_id_t::I2S_STATIC:
|
||||||
case stepper_id_t::TIMED:
|
case stepper_id_t::TIMED:
|
||||||
_stepPulseStartTime = esp_timer_get_time();
|
_stepPulseEndTime = usToEndTicks(_pulseUsecs);
|
||||||
break;
|
break;
|
||||||
case stepper_id_t::RMT:
|
case stepper_id_t::RMT:
|
||||||
break;
|
break;
|
||||||
|
@@ -35,9 +35,7 @@ namespace Machine {
|
|||||||
static const int ticksPerMicrosecond = fStepperTimer / 1000000;
|
static const int ticksPerMicrosecond = fStepperTimer / 1000000;
|
||||||
|
|
||||||
bool _switchedStepper = false;
|
bool _switchedStepper = false;
|
||||||
int64_t _stepPulseStartTime;
|
int32_t _stepPulseEndTime;
|
||||||
|
|
||||||
static void spinDelay(int64_t start_time, uint32_t duration);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Counts stepper ISR invocations. This variable can be inspected
|
// Counts stepper ISR invocations. This variable can be inspected
|
||||||
|
Reference in New Issue
Block a user