PulseGen/speed_tables: cleanup constants
parent
006dfd4abc
commit
ed04bd02e2
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "axis.h"
|
#include "axis.h"
|
||||||
#include "todo.h"
|
|
||||||
|
|
||||||
/// Wrangler for assorted compile-time configuration and constants.
|
/// Wrangler for assorted compile-time configuration and constants.
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
@ -33,6 +32,15 @@ static constexpr const uint8_t buttonsADCIndex = 0; ///< ADC index of buttons in
|
||||||
/// microstepping interval.
|
/// microstepping interval.
|
||||||
static constexpr uint8_t uStepMaxRes = 32;
|
static constexpr uint8_t uStepMaxRes = 32;
|
||||||
|
|
||||||
|
/// Do not plan moves equal or shorter than the requested steps
|
||||||
|
static constexpr uint8_t dropSegments = 0;
|
||||||
|
|
||||||
|
/// Max step frequency 40KHz
|
||||||
|
static constexpr uint16_t maxStepFrequency = 40000;
|
||||||
|
|
||||||
|
/// Minimum stepping rate 120Hz
|
||||||
|
static constexpr uint16_t minStepRate = 120;
|
||||||
|
|
||||||
/// Idler configuration
|
/// Idler configuration
|
||||||
static constexpr AxisConfig idler = {
|
static constexpr AxisConfig idler = {
|
||||||
.dirOn = true,
|
.dirOn = true,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef __AVR__
|
|
||||||
#define F_CPU 16000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Max step frequency 40KHz
|
|
||||||
#define MAX_STEP_FREQUENCY 40000
|
|
||||||
|
|
||||||
// Minimum stepper rate 120Hz.
|
|
||||||
#define MINIMAL_STEP_RATE 120
|
|
||||||
|
|
||||||
// Step frequency divider (influences the speed tables!)
|
|
||||||
#define STEP_TIMER_DIVIDER 8
|
|
||||||
|
|
@ -5,6 +5,11 @@
|
||||||
namespace hal {
|
namespace hal {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
|
#ifndef F_CPU
|
||||||
|
/// Main clock frequency
|
||||||
|
#define F_CPU (16000000ul)
|
||||||
|
#endif
|
||||||
|
|
||||||
/// CPU init routines (not really necessary for the AVR)
|
/// CPU init routines (not really necessary for the AVR)
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,15 @@ using modules::speed_table::calc_timer;
|
||||||
namespace modules {
|
namespace modules {
|
||||||
namespace pulse_gen {
|
namespace pulse_gen {
|
||||||
|
|
||||||
PulseGen::PulseGen() {
|
PulseGen::PulseGen(steps_t max_jerk, steps_t acceleration) {
|
||||||
// Some initial values
|
// Axis status
|
||||||
position = 0;
|
position = 0;
|
||||||
acceleration = 1200;
|
this->max_jerk = max_jerk;
|
||||||
|
this->acceleration = acceleration;
|
||||||
|
|
||||||
|
// Block buffer
|
||||||
block_buffer_head = block_buffer_tail = 0;
|
block_buffer_head = block_buffer_tail = 0;
|
||||||
current_block = nullptr;
|
current_block = nullptr;
|
||||||
|
|
||||||
// TODO: configuration constants
|
|
||||||
dropsegments = 5;
|
|
||||||
max_jerk = 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseGen::CalculateTrapezoid(block_t *block, steps_t entry_speed, steps_t exit_speed) {
|
void PulseGen::CalculateTrapezoid(block_t *block, steps_t entry_speed, steps_t exit_speed) {
|
||||||
|
|
@ -28,12 +27,12 @@ void PulseGen::CalculateTrapezoid(block_t *block, steps_t entry_speed, steps_t e
|
||||||
rate_t final_rate = exit_speed;
|
rate_t final_rate = exit_speed;
|
||||||
|
|
||||||
// Limit minimal step rate (Otherwise the timer will overflow.)
|
// Limit minimal step rate (Otherwise the timer will overflow.)
|
||||||
if (initial_rate < MINIMAL_STEP_RATE)
|
if (initial_rate < config::minStepRate)
|
||||||
initial_rate = MINIMAL_STEP_RATE;
|
initial_rate = config::minStepRate;
|
||||||
if (initial_rate > block->nominal_rate)
|
if (initial_rate > block->nominal_rate)
|
||||||
initial_rate = block->nominal_rate;
|
initial_rate = block->nominal_rate;
|
||||||
if (final_rate < MINIMAL_STEP_RATE)
|
if (final_rate < config::minStepRate)
|
||||||
final_rate = MINIMAL_STEP_RATE;
|
final_rate = config::minStepRate;
|
||||||
if (final_rate > block->nominal_rate)
|
if (final_rate > block->nominal_rate)
|
||||||
final_rate = block->nominal_rate;
|
final_rate = block->nominal_rate;
|
||||||
|
|
||||||
|
|
@ -100,7 +99,7 @@ void PulseGen::Move(pos_t target, steps_t feed_rate) {
|
||||||
block->steps = abs(target - position);
|
block->steps = abs(target - position);
|
||||||
|
|
||||||
// Bail if this is a zero-length block
|
// Bail if this is a zero-length block
|
||||||
if (block->steps <= dropsegments)
|
if (block->steps <= config::dropSegments)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Direction and speed for this block
|
// Direction and speed for this block
|
||||||
|
|
@ -109,7 +108,7 @@ void PulseGen::Move(pos_t target, steps_t feed_rate) {
|
||||||
|
|
||||||
// Acceleration of the segment, in steps/sec^2
|
// Acceleration of the segment, in steps/sec^2
|
||||||
block->acceleration = acceleration;
|
block->acceleration = acceleration;
|
||||||
block->acceleration_rate = block->acceleration * (rate_t)((float)F_CPU / (F_CPU / STEP_TIMER_DIVIDER));
|
block->acceleration_rate = block->acceleration * (rate_t)((float)F_CPU / (F_CPU / speed_table::cpuFrequencyDivider));
|
||||||
|
|
||||||
// Perform the trapezoid calculations
|
// Perform the trapezoid calculations
|
||||||
CalculateTrapezoid(block, max_jerk, max_jerk);
|
CalculateTrapezoid(block, max_jerk, max_jerk);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ typedef int32_t pos_t; ///< Axis position (signed)
|
||||||
|
|
||||||
class PulseGen {
|
class PulseGen {
|
||||||
public:
|
public:
|
||||||
PulseGen();
|
PulseGen(steps_t max_jerk, steps_t acceleration);
|
||||||
|
|
||||||
/// @returns the acceleration for the axis
|
/// @returns the acceleration for the axis
|
||||||
steps_t Acceleration() const { return acceleration; };
|
steps_t Acceleration() const { return acceleration; };
|
||||||
|
|
@ -59,11 +59,6 @@ private:
|
||||||
rate_t acceleration; ///< acceleration steps/sec^2
|
rate_t acceleration; ///< acceleration steps/sec^2
|
||||||
};
|
};
|
||||||
|
|
||||||
//{ units constants
|
|
||||||
steps_t max_jerk;
|
|
||||||
steps_t dropsegments; // segments are dropped if lower than that
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Block buffer parameters
|
// Block buffer parameters
|
||||||
block_t block_buffer[2];
|
block_t block_buffer[2];
|
||||||
block_t *current_block;
|
block_t *current_block;
|
||||||
|
|
@ -72,6 +67,7 @@ private:
|
||||||
|
|
||||||
// Axis data
|
// Axis data
|
||||||
pos_t position; ///< Current axis position
|
pos_t position; ///< Current axis position
|
||||||
|
steps_t max_jerk; ///< Axis jerk (could be constant)
|
||||||
steps_t acceleration; ///< Current axis acceleration
|
steps_t acceleration; ///< Current axis acceleration
|
||||||
|
|
||||||
// Step parameters
|
// Step parameters
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../hal/progmem.h"
|
#include "../hal/progmem.h"
|
||||||
|
#include "../hal/cpu.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
namespace modules {
|
namespace modules {
|
||||||
|
|
@ -10,6 +11,11 @@ namespace speed_table {
|
||||||
|
|
||||||
typedef uint16_t st_timer_t;
|
typedef uint16_t st_timer_t;
|
||||||
|
|
||||||
|
/// CPU timer frequency divider required for the speed tables
|
||||||
|
static constexpr uint8_t cpuFrequencyDivider = 8;
|
||||||
|
static_assert(F_CPU / cpuFrequencyDivider == 2000000,
|
||||||
|
"speed tables not compatible for the requested frequency");
|
||||||
|
|
||||||
/// Lookup table for rates equal or higher than 8*256
|
/// Lookup table for rates equal or higher than 8*256
|
||||||
extern const st_timer_t speed_table_fast[256][2] PROGMEM;
|
extern const st_timer_t speed_table_fast[256][2] PROGMEM;
|
||||||
|
|
||||||
|
|
@ -18,8 +24,8 @@ extern const st_timer_t speed_table_slow[256][2] PROGMEM;
|
||||||
|
|
||||||
/// Calculate the next timer interval and steps according to current step rate
|
/// Calculate the next timer interval and steps according to current step rate
|
||||||
static inline st_timer_t calc_timer(st_timer_t step_rate, uint8_t &step_loops) {
|
static inline st_timer_t calc_timer(st_timer_t step_rate, uint8_t &step_loops) {
|
||||||
if (step_rate > MAX_STEP_FREQUENCY)
|
if (step_rate > config::maxStepFrequency)
|
||||||
step_rate = MAX_STEP_FREQUENCY;
|
step_rate = config::maxStepFrequency;
|
||||||
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
||||||
step_rate = (step_rate >> 2) & 0x3fff;
|
step_rate = (step_rate >> 2) & 0x3fff;
|
||||||
step_loops = 4;
|
step_loops = 4;
|
||||||
|
|
@ -51,8 +57,9 @@ static inline st_timer_t calc_timer(st_timer_t step_rate, uint8_t &step_loops) {
|
||||||
timer -= ((pm::read_word(table_address + 1) * (uint8_t)(step_rate & 0x0007)) >> 3);
|
timer -= ((pm::read_word(table_address + 1) * (uint8_t)(step_rate & 0x0007)) >> 3);
|
||||||
}
|
}
|
||||||
if (timer < 100) {
|
if (timer < 100) {
|
||||||
|
// 20kHz this should never happen
|
||||||
timer = 100;
|
timer = 100;
|
||||||
} // 20kHz this should never happen
|
}
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ TEST_CASE("pulse_gen::basic", "[pulse_gen]") {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int accel = 100; accel <= 5000; accel *= 2) {
|
for (int accel = 100; accel <= 5000; accel *= 2) {
|
||||||
PulseGen pg;
|
PulseGen pg(10, accel);
|
||||||
pg.SetAcceleration(accel);
|
|
||||||
pg.Move(100000, 10000);
|
pg.Move(100000, 10000);
|
||||||
|
|
||||||
unsigned long ts = 0;
|
unsigned long ts = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue