PulseGen/speed_tables: cleanup constants

pull/47/head
Yuri D'Elia 2021-07-05 20:31:08 +02:00
parent 006dfd4abc
commit ed04bd02e2
7 changed files with 39 additions and 39 deletions

View File

@ -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,

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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;
} }

View File

@ -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;