Files
FastAccelStepper/src/RampGenerator.h

119 lines
3.8 KiB
C++

#ifndef RAMP_GENERATOR_H
#define RAMP_GENERATOR_H
#include "FastAccelStepper.h"
#include "RampCalculator.h"
#include "RampControl.h"
#include "fas_arch/common.h"
class FastAccelStepper;
#ifdef SUPPORT_LOG2_TIMER_FREQ_VARIABLES
extern pmf_logarithmic log2_timer_freq;
extern pmf_logarithmic log2_timer_freq_div_sqrt_of_2;
extern pmf_logarithmic log2_timer_freq_square_div_2;
#endif
class RampGenerator {
private:
struct ramp_parameters_s _parameters;
// The ro variables are those, which are only read from _getNextCommand().
// The rw variables are only read and written by _getNextCommand() and
// commandEnqueued() Reading ro variables is safe in application
struct ramp_ro_s _ro;
struct ramp_rw_s _rw;
public:
uint32_t acceleration;
inline uint8_t rampState() { return _rw.rampState(); }
void init();
inline int32_t targetPosition() { return _ro.targetPosition(); }
inline void setTargetPosition(int32_t pos) { _ro.setTargetPosition(pos); }
void advanceTargetPosition(int32_t delta, const struct queue_end_s *queue);
inline void setSpeedInTicks(uint32_t min_step_ticks) {
_parameters.setSpeedInTicks(min_step_ticks);
}
inline uint32_t getSpeedInUs() {
return _parameters.min_travel_ticks / (TICKS_PER_S / 1000000);
}
inline uint32_t getSpeedInTicks() { return _parameters.min_travel_ticks; }
uint32_t divForMilliHz(uint32_t f) {
uint32_t base = (uint32_t)250 * TICKS_PER_S;
uint32_t res = base / f;
base -= res * f;
base <<= 2;
res <<= 2;
base += f / 2; // add rounding
res += base / f;
return res;
}
uint32_t divForHz(uint32_t f) {
uint32_t base = TICKS_PER_S;
base += f / 2; // add rounding
uint32_t res = base / f;
return res;
}
inline uint32_t getSpeedInMilliHz() {
if (_parameters.min_travel_ticks == 0) {
return 0;
}
return divForMilliHz(getSpeedInTicks());
}
int8_t setAcceleration(int32_t accel);
inline uint32_t getAcceleration() { return acceleration; }
inline void setLinearAcceleration(uint32_t linear_acceleration_steps) {
_parameters.setCubicAccelerationSteps(linear_acceleration_steps);
}
inline void setJumpStart(uint32_t jump_step) {
_parameters.setJumpStart(jump_step);
}
int32_t getCurrentAcceleration();
inline bool hasValidConfig() {
return _parameters.checkValidConfig() == MOVE_OK;
}
void applySpeedAcceleration();
MoveResultCode move(int32_t move, const struct queue_end_s *queue);
MoveResultCode moveTo(int32_t position, const struct queue_end_s *queue);
MoveResultCode startRun(bool countUp);
inline void forceStop() { _ro.immediateStop(); }
inline void initiateStop() { _ro.initiateStop(); }
inline bool isStopping() {
return _ro.isStopInitiated() && isRampGeneratorActive();
}
inline bool isRampGeneratorActive() { return rampState() != RAMP_STATE_IDLE; }
inline uint32_t stepsToStop() {
fasDisableInterrupts();
uint32_t v = _rw.performed_ramp_up_steps;
fasEnableInterrupts();
return v;
}
inline void stopRamp() { _rw.stopRamp(); }
inline void setKeepRunning() { _ro.setKeepRunning(); }
inline bool isRunningContinuously() { return _ro.isRunningContinuously(); }
void getNextCommand(const struct queue_end_s *queue_end,
NextCommand *cmd_out);
void afterCommandEnqueued(const NextCommand *cmd_in);
void getCurrentSpeedInTicks(struct actual_ticks_s *speed) {
fasDisableInterrupts();
speed->ticks = _rw.curr_ticks;
uint8_t rs = _rw.rampState();
fasEnableInterrupts();
speed->count_up = ((rs & RAMP_DIRECTION_COUNT_UP) != 0);
}
uint32_t getCurrentPeriodInTicks() {
fasDisableInterrupts();
uint32_t ticks = _rw.curr_ticks;
fasEnableInterrupts();
return ticks;
}
inline uint32_t getCurrentPeriodInUs() {
return TICKS_TO_US(getCurrentPeriodInTicks());
}
private:
void _startMove(bool position_changed);
};
#endif