Split some settings to cfg file. Add info for wizard.
[bertos.git] / bertos / algo / ramp.h
1
2 /**
3  * \file
4  * <!--
5  * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
6  * All Rights Reserved.
7  * -->
8  *
9  * \brief Compute, save and load ramps for stepper motors (interace)
10  *
11  * \version $Id$
12  *
13  * \author Simone Zinanni <s.zinanni@develer.com>
14  * \author Giovanni Bajo <rasky@develer.com>
15  * \author Daniele Basile <asterix@develer.com>
16  *
17  * The acceleration ramp is used to properly accelerate a stepper motor. The main
18  * entry point is the function ramp_evaluate(), which must be called at every step
19  * of the motor: it gets as input the time elapsed since the stepper started
20  * accelerating, and returns the time to wait before sending the next step. A pseudo
21  * usage pattern is as follows:
22  *
23  * <pre>
24  *  float time = 0;
25  *  while (1)
26  *  {
27  *      float delta = ramp_evaluate(&my_ramp, time);
28  *      sleep(delta);
29  *      do_motor_step();
30  *      time += delta;
31  *  }
32  * </pre>
33  *
34  * A similar pattern can be used to decelerate (it is sufficient to move the total
35  * time backward, such as "time -= delta").
36  *
37  * The ramp can be configured with ramp_setup(), providing it with the minimum and
38  * maximum operating frequency of the motor, and the total acceleration time in
39  * milliseconds (that is, the time that will be needed to accelerate from the
40  * minimum frequency to the maximum frequency).
41  *
42  * Both a very precise floating point and a very fast fixed point implementation
43  * of the ramp evaluation are provided. The fixed point is hand-optimized assembly
44  * for DSP56000 (but a portable C version of it can be easily written, see the
45  * comments in the code).
46  *
47  * $WIZARD_MODULE = {
48  * "name" : "ramp",
49  * "depends" : [],
50  * "configuration" : "bertos/cfg/cfg_ramp.h"
51  * }
52  */
53
54 #ifndef ALGO_RAMP_H
55 #define ALGO_RAMP_H
56
57 #include "hw/hw_stepper.h"
58
59 #include "cfg/cfg_ramp.h"
60
61 #include <cfg/compiler.h>
62
63
64 /**
65  * Convert microseconds to timer clock ticks
66  */
67 #define TIME2CLOCKS(micros) ((uint32_t)(micros) * (STEPPER_CLOCK / 1000000))
68
69 /**
70  * Convert timer clock ticks back to microseconds
71  */
72 #define CLOCKS2TIME(clocks) ((uint32_t)(clocks) / (STEPPER_CLOCK / 1000000))
73
74 /**
75  * Convert microseconds to Hz
76  */
77 #define MICROS2FREQ(micros) (1000000UL / ((uint32_t)(micros)))
78
79 /**
80  * Convert frequency (in Hz) to time (in microseconds)
81  */
82 #define FREQ2MICROS(hz) (1000000UL / ((uint32_t)(hz)))
83
84 /**
85  * Multiply \p a and \p b two integer at 32 bit and extract the high 16 bit word.
86  */
87 #define FIX_MULT32(a,b)  (((uint64_t)(a)*(uint32_t)(b)) >> 16)
88
89 /**
90  * Structure holding pre-calculated data for speeding up real-time evaluation
91  * of the ramp. This structure is totally different between the fixed and the
92  * floating point version of the code.
93  *
94  * Consult the file-level documentation of ramp.c for more information about
95  * the values of this structure.
96  */
97 struct RampPrecalc
98 {
99 #if RAMP_USE_FLOATING_POINT
100         float beta;
101         float alpha;
102         float gamma;
103 #else
104         uint16_t max_div_min;
105         uint32_t inv_total_time;
106 #endif
107 };
108
109
110 /**
111  * Ramp structure
112  */
113 struct Ramp
114 {
115         uint32_t clocksRamp;
116         uint16_t clocksMinWL;
117         uint16_t clocksMaxWL;
118
119         struct RampPrecalc precalc; ///< pre-calculated values for speed
120 };
121
122
123 /*
124  * Function prototypes
125  */
126 void ramp_compute(
127         struct Ramp * ramp,
128         uint32_t clocksInRamp,
129         uint16_t clocksInMinWavelength,
130         uint16_t clocksInMaxWavelength);
131
132
133 /** Setup an acceleration ramp for a stepper motor
134  *
135  *  \param ramp Ramp to fill
136  *  \param length Length of the ramp (milliseconds)
137  *  \param minFreq Minimum operating frequency of the motor (hertz)
138  *  \param maxFreq Maximum operating frequency of the motor (hertz)
139  *
140  */
141 void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq);
142
143
144 /**
145  * Initialize a new ramp with default values
146  */
147 void ramp_default(struct Ramp *ramp);
148
149
150 /**
151  * Evaluate the ramp at the given point. Given a \a ramp, and the current \a clock since
152  * the start of the acceleration, compute the next step, that is the interval at which
153  * send the signal to the motor.
154  *
155  * \note The fixed point version does not work when curClock is zero. Anyway,
156  * the first step is always clocksMaxWL, as stored within the ramp structure.
157  */
158 #if RAMP_USE_FLOATING_POINT
159         float ramp_evaluate(const struct Ramp* ramp, float curClock);
160 #else
161         uint16_t ramp_evaluate(const struct Ramp* ramp, uint32_t curClock);
162 #endif
163
164
165 /** Self test */
166 int ramp_testSetup(void);
167 int ramp_testRun(void);
168 int ramp_testTearDown(void);
169
170 #endif /* ALGO_RAMP_H */
171