ramp.c
Go to the documentation of this file.00001
00105 #include "ramp.h"
00106 #include <cfg/debug.h>
00107
00108 #include <string.h>
00109
00110 void ramp_compute(struct Ramp *ramp, uint32_t clocksRamp, uint16_t clocksMinWL, uint16_t clocksMaxWL)
00111 {
00112 ASSERT(clocksMaxWL >= clocksMinWL);
00113
00114
00115 ramp->clocksRamp = clocksRamp;
00116 ramp->clocksMinWL = clocksMinWL;
00117 ramp->clocksMaxWL = clocksMaxWL;
00118
00119 #if RAMP_USE_FLOATING_POINT
00120 ramp->precalc.gamma = ramp->clocksMaxWL - ramp->clocksMinWL;
00121 ramp->precalc.beta = (float)ramp->clocksMinWL * (float)ramp->clocksRamp;
00122 ramp->precalc.alpha = ramp->precalc.beta * (float)ramp->clocksMaxWL;
00123
00124 #else
00125 ramp->precalc.max_div_min = ((uint32_t)clocksMinWL << 16) / (uint32_t)clocksMaxWL;
00126
00127
00128
00129
00130
00131
00132 ASSERT(ramp->clocksRamp < (1UL << (24 + RAMP_CLOCK_SHIFT_PRECISION)));
00133 ramp->precalc.inv_total_time = 0xFFFFFFFFUL / (ramp->clocksRamp >> RAMP_CLOCK_SHIFT_PRECISION);
00134 ASSERT(ramp->precalc.inv_total_time < 0x1000000UL);
00135
00136 #endif
00137 }
00138
00139
00140 void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq)
00141 {
00142 uint32_t minWL, maxWL;
00143
00144 minWL = TIME2CLOCKS(FREQ2MICROS(maxFreq));
00145 maxWL = TIME2CLOCKS(FREQ2MICROS(minFreq));
00146
00147 ASSERT2(minWL < 65536UL, "Maximum frequency too high");
00148 ASSERT2(maxWL < 65536UL, "Minimum frequency too high");
00149 ASSERT(maxFreq > minFreq);
00150
00151 ramp_compute(
00152 ramp,
00153 TIME2CLOCKS(length),
00154 TIME2CLOCKS(FREQ2MICROS(maxFreq)),
00155 TIME2CLOCKS(FREQ2MICROS(minFreq))
00156 );
00157 }
00158
00159 void ramp_default(struct Ramp *ramp)
00160 {
00161 ramp_setup(ramp, RAMP_DEF_TIME, RAMP_DEF_MINFREQ, RAMP_DEF_MAXFREQ);
00162 }
00163
00164 #if RAMP_USE_FLOATING_POINT
00165
00166 float ramp_evaluate(const struct Ramp* ramp, float curClock)
00167 {
00168 return ramp->precalc.alpha / (curClock * ramp->precalc.gamma + ramp->precalc.beta);
00169 }
00170
00171 #else
00172
00173 INLINE uint32_t fix_mult32(uint32_t m1, uint32_t m2)
00174 {
00175 uint32_t accum = 0;
00176 accum += m1 * ((m2 >> 0) & 0xFF);
00177 accum >>= 8;
00178 accum += m1 * ((m2 >> 8) & 0xFF);
00179 accum >>= 8;
00180 accum += m1 * ((m2 >> 16) & 0xFF);
00181 return accum;
00182 }
00183
00184
00185 INLINE uint16_t fix_mult16(uint16_t a, uint32_t b)
00186 {
00187 return (b*(uint32_t)a) >> 16;
00188 }
00189
00190 uint16_t FAST_FUNC ramp_evaluate(const struct Ramp* ramp, uint32_t curClock)
00191 {
00192 uint16_t t = FIX_MULT32(curClock >> RAMP_CLOCK_SHIFT_PRECISION, ramp->precalc.inv_total_time);
00193 uint16_t denom = fix_mult16((uint16_t)~t + 1, ramp->precalc.max_div_min) + t;
00194 uint16_t cur_delta = ((uint32_t)ramp->clocksMinWL << 16) / denom;
00195
00196 return cur_delta;
00197 }
00198
00199 #endif
00200
00201