Guard ISR-processed data in ATOMIC_BLOCK
parent
8e8a17c34e
commit
90be0f8665
|
|
@ -1,6 +1,12 @@
|
||||||
/// @file pulse_gen.cpp
|
/// @file pulse_gen.cpp
|
||||||
#include "pulse_gen.h"
|
#include "pulse_gen.h"
|
||||||
|
|
||||||
|
#ifdef AVR
|
||||||
|
#include <util/atomic.h>
|
||||||
|
#else
|
||||||
|
#define ATOMIC_BLOCK(x) /**/
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modules {
|
namespace modules {
|
||||||
namespace pulse_gen {
|
namespace pulse_gen {
|
||||||
|
|
||||||
|
|
@ -90,59 +96,62 @@ void PulseGen::CalculateTrapezoid(block_t *block, steps_t entry_speed, steps_t e
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PulseGen::PlanMoveTo(pos_t target, steps_t feed_rate, steps_t end_rate) {
|
bool PulseGen::PlanMoveTo(pos_t target, steps_t feed_rate, steps_t end_rate) {
|
||||||
// Prepare to set up new block
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
if (block_index.full())
|
// Prepare to set up new block
|
||||||
return false;
|
if (block_index.full())
|
||||||
block_t *block = &block_buffer[block_index.back()];
|
return false;
|
||||||
|
block_t *block = &block_buffer[block_index.back()];
|
||||||
|
|
||||||
// Bail if this is a zero-length block
|
// Bail if this is a zero-length block
|
||||||
block->steps = abs(target - position);
|
block->steps = abs(target - position);
|
||||||
if (block->steps <= config::dropSegments) {
|
if (block->steps <= config::dropSegments) {
|
||||||
// behave as-if the block has been scheduled
|
// behave as-if the block has been scheduled
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direction and speed for this block
|
||||||
|
block->direction = (target >= position);
|
||||||
|
block->nominal_rate = feed_rate;
|
||||||
|
|
||||||
|
// Acceleration of the segment, in steps/sec^2
|
||||||
|
block->acceleration = acceleration;
|
||||||
|
block->acceleration_rate = block->acceleration * (rate_t)((float)F_CPU / (F_CPU / config::stepTimerFrequencyDivider));
|
||||||
|
|
||||||
|
// Simplified forward jerk: do not handle reversals
|
||||||
|
steps_t entry_speed;
|
||||||
|
if (feed_rate >= last_rate)
|
||||||
|
entry_speed = last_rate + min(feed_rate - last_rate, max_jerk);
|
||||||
|
else
|
||||||
|
entry_speed = last_rate - min(last_rate - feed_rate, max_jerk);
|
||||||
|
|
||||||
|
// Perform the trapezoid calculations
|
||||||
|
CalculateTrapezoid(block, entry_speed, end_rate);
|
||||||
|
last_rate = block->final_rate;
|
||||||
|
|
||||||
|
// Move forward and update the state
|
||||||
|
block_index.push();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Direction and speed for this block
|
|
||||||
block->direction = (target >= position);
|
|
||||||
block->nominal_rate = feed_rate;
|
|
||||||
|
|
||||||
// Acceleration of the segment, in steps/sec^2
|
|
||||||
block->acceleration = acceleration;
|
|
||||||
block->acceleration_rate = block->acceleration * (rate_t)((float)F_CPU / (F_CPU / config::stepTimerFrequencyDivider));
|
|
||||||
|
|
||||||
// Simplified forward jerk: do not handle reversals
|
|
||||||
steps_t entry_speed;
|
|
||||||
if (feed_rate >= last_rate)
|
|
||||||
entry_speed = last_rate + min(feed_rate - last_rate, max_jerk);
|
|
||||||
else
|
|
||||||
entry_speed = last_rate - min(last_rate - feed_rate, max_jerk);
|
|
||||||
|
|
||||||
// Perform the trapezoid calculations
|
|
||||||
CalculateTrapezoid(block, entry_speed, end_rate);
|
|
||||||
last_rate = block->final_rate;
|
|
||||||
|
|
||||||
// Move forward and update the state
|
|
||||||
block_index.push();
|
|
||||||
position = target;
|
position = target;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos_t PulseGen::CurPosition() const {
|
pos_t PulseGen::CurPosition() const {
|
||||||
pos_t cur_pos = position;
|
pos_t cur_pos = position;
|
||||||
circular_index_t iter = block_index;
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // manipulating current_block needs sync
|
||||||
|
circular_index_t iter = block_index;
|
||||||
|
|
||||||
// if we have a live block remove the partial offset
|
// if we have a live block remove the partial offset
|
||||||
if (current_block) {
|
if (current_block) {
|
||||||
cur_pos -= CurBlockShift();
|
cur_pos -= CurBlockShift();
|
||||||
iter.pop();
|
iter.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// rollback remaining blocks
|
||||||
|
while (!iter.empty()) {
|
||||||
|
cur_pos -= BlockShift(&block_buffer[iter.front()]);
|
||||||
|
iter.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rollback remaining blocks
|
|
||||||
while (!iter.empty()) {
|
|
||||||
cur_pos -= BlockShift(&block_buffer[iter.front()]);
|
|
||||||
iter.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur_pos;
|
return cur_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,17 +159,19 @@ void PulseGen::AbortPlannedMoves(bool halt) {
|
||||||
// always update to effective position
|
// always update to effective position
|
||||||
position = CurPosition();
|
position = CurPosition();
|
||||||
|
|
||||||
// destroy the current block
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // manipulating current_block needs sync
|
||||||
if (current_block) {
|
// destroy the current block
|
||||||
last_rate = acc_step_rate;
|
if (current_block) {
|
||||||
current_block = nullptr;
|
last_rate = acc_step_rate;
|
||||||
while (!block_index.empty()) // drop all remaining blocks
|
current_block = nullptr;
|
||||||
block_index.pop();
|
while (!block_index.empty()) // drop all remaining blocks
|
||||||
|
block_index.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncate the last rate if halting
|
// truncate the last rate if halting
|
||||||
if (halt)
|
if (halt) {
|
||||||
last_rate = 0;
|
last_rate = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace motor
|
} // namespace motor
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ public:
|
||||||
bool Full() const { return block_index.full(); }
|
bool Full() const { return block_index.full(); }
|
||||||
|
|
||||||
/// Single-step the axis
|
/// Single-step the axis
|
||||||
|
/// Called from ISR
|
||||||
/// @returns the interval for the next tick
|
/// @returns the interval for the next tick
|
||||||
inline st_timer_t Step(const hal::tmc2130::MotorParams &motorParams) {
|
inline st_timer_t Step(const hal::tmc2130::MotorParams &motorParams) {
|
||||||
if (!current_block) {
|
if (!current_block) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue