4 * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
8 * \brief Compute, save and load ramps for stepper motors.
10 * The acceleration ramp is used to properly accelerate a stepper motor. The main
11 * entry point is the function ramp_evaluate(), which must be called at every step
12 * of the motor: it gets as input the time elapsed since the stepper started
13 * accelerating, and returns the time to wait before sending the next step. A pseudo
14 * usage pattern is as follows:
20 * float delta = ramp_evaluate(&my_ramp, time);
27 * A similar pattern can be used to decelerate (it is sufficient to move the total
28 * time backward, such as "time -= delta").
30 * The ramp can be configured with ramp_setup(), providing it with the minimum and
31 * maximum operating frequency of the motor, and the total acceleration time in
32 * milliseconds (that is, the time that will be needed to accelerate from the
33 * minimum frequency to the maximum frequency).
35 * Both a very precise floating point and a very fast fixed point implementation
36 * of the ramp evaluation are provided. The fixed point is hand-optimized assembly
37 * for DSP56000 (but a portable C version of it can be easily written, see the
38 * comments in the code).
42 * \author Simone Zinanni <s.zinanni@develer.com>
43 * \author Giovanni Bajo <rasky@develer.com>
44 * \author Daniele Basile <asterix@develer.com>
46 * $WIZ$ module_name = "ramp"
47 * $WIZ$ module_configuration = "bertos/cfg/cfg_ramp.h"
53 #include "hw/hw_stepper.h"
55 #include "cfg/cfg_ramp.h"
57 #include <cfg/compiler.h>
61 * Convert microseconds to timer clock ticks
63 #define TIME2CLOCKS(micros) ((uint32_t)(micros) * (STEPPER_CLOCK / 1000000))
66 * Convert timer clock ticks back to microseconds
68 #define CLOCKS2TIME(clocks) ((uint32_t)(clocks) / (STEPPER_CLOCK / 1000000))
71 * Convert microseconds to Hz
73 #define MICROS2FREQ(micros) (1000000UL / ((uint32_t)(micros)))
76 * Convert frequency (in Hz) to time (in microseconds)
78 #define FREQ2MICROS(hz) (1000000UL / ((uint32_t)(hz)))
81 * Multiply \p a and \p b two integer at 32 bit and extract the high 16 bit word.
83 #define FIX_MULT32(a,b) (((uint64_t)(a)*(uint32_t)(b)) >> 16)
86 * Structure holding pre-calculated data for speeding up real-time evaluation
87 * of the ramp. This structure is totally different between the fixed and the
88 * floating point version of the code.
90 * Consult the file-level documentation of ramp.c for more information about
91 * the values of this structure.
95 #if RAMP_USE_FLOATING_POINT
100 uint16_t max_div_min;
101 uint32_t inv_total_time;
112 uint16_t clocksMinWL;
113 uint16_t clocksMaxWL;
115 struct RampPrecalc precalc; ///< pre-calculated values for speed
120 * Function prototypes
124 uint32_t clocksInRamp,
125 uint16_t clocksInMinWavelength,
126 uint16_t clocksInMaxWavelength);
129 /** Setup an acceleration ramp for a stepper motor
131 * \param ramp Ramp to fill
132 * \param length Length of the ramp (milliseconds)
133 * \param minFreq Minimum operating frequency of the motor (hertz)
134 * \param maxFreq Maximum operating frequency of the motor (hertz)
137 void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq);
141 * Initialize a new ramp with default values
143 void ramp_default(struct Ramp *ramp);
147 * Evaluate the ramp at the given point. Given a \a ramp, and the current \a clock since
148 * the start of the acceleration, compute the next step, that is the interval at which
149 * send the signal to the motor.
151 * \note The fixed point version does not work when curClock is zero. Anyway,
152 * the first step is always clocksMaxWL, as stored within the ramp structure.
154 #if RAMP_USE_FLOATING_POINT
155 float ramp_evaluate(const struct Ramp* ramp, float curClock);
157 uint16_t ramp_evaluate(const struct Ramp* ramp, uint32_t curClock);
162 int ramp_testSetup(void);
163 int ramp_testRun(void);
164 int ramp_testTearDown(void);
166 #endif /* ALGO_RAMP_H */