Subversion Repositories libIgnTiming

Rev

Rev 11 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11 Rev 12
Line 1... Line 1...
1
#include <cstdint>
1
#include <cstdint>
2
#include <assert.h>
2
#include <assert.h>
3
#include "libIgnTiming/timing.h"
3
#include "libIgnTiming/timing.h"
-
 
4
#include "libIgnTiming/basemap.h"
4
 
5
 
5
#if !defined WRITABLE_TABLE
-
 
6
#define CONST_ATTR constexpr
-
 
7
#endif
-
 
8
 
6
 
9
#if defined __cplusplus
7
#if defined __cplusplus
10
extern "C"
8
extern "C"
11
{
9
{
12
#endif
10
#endif
13
 
11
 
14
    namespace
12
    namespace
15
    {
13
    {
16
        int8_t timingAdjust = 0 * TIMING_SCALE; // in TIMING_SCALE
14
        int8_t timingAdjust = 0 * TIMING_SCALE; // in TIMING_SCALE
17
 
-
 
18
        unsigned constexpr INTERP_SCALE = 256;
15
        // local copy of the data structure 
19
 
-
 
20
        int constexpr TimingScale = TIMING_SCALE;
16
        timingTable_t timingMap = baseTimingMap;
21
        int16_t constexpr NO_DATA = -1;
-
 
22
 
17
 
23
        int16_t constexpr MAX_ADVANCE = 50 * TIMING_SCALE;
18
        int16_t constexpr MAX_ADVANCE = 50 * TIMING_SCALE;
24
        int16_t constexpr MIN_ADVANCE = 7 * TIMING_SCALE;
19
        int16_t constexpr MIN_ADVANCE = 7 * TIMING_SCALE;
25
 
20
 
26
        // array of column headings
-
 
27
        int16_t CONST_ATTR rpmMap[MAX_RPM_POINTS] = {400, 750, 1000, 1500, 2500, 3500, 4500, 6000};
-
 
28
        // column of row values - in 1000-pressure
-
 
29
        int16_t CONST_ATTR vacuumMap[MAX_VACUUM_POINTS] = {0, 166, 225, 300, 700, 1000, NO_DATA, NO_DATA};
-
 
30
        uint8_t CONST_ATTR mapping[MAX_VACUUM_POINTS][MAX_RPM_POINTS] = {
-
 
31
            /* Table in degrees. */
-
 
32
            /* row for 0mb = centrifugal only */
-
 
33
            {12, 7, 7, 19, 25, 29, 29, 22},
-
 
34
            /* row for 166 mB*/
-
 
35
            {12, 7, 7, 21, 27, 31, 31, 24},
-
 
36
            /*   row for 225 mB */
-
 
37
            {12, 7, 7, 25, 31, 35, 35, 28},
-
 
38
            /* row for 300 mB*/
-
 
39
            {12, 7, 7, 29, 35, 39, 39, 33},
-
 
40
            /* row for 700 mB*/
-
 
41
            {12, 7, 7, 19, 25, 29, 29, 22},
-
 
42
            /* row for 1000 mB - used when pressure drops off the scale */
-
 
43
            {7, 7, 7, 7, 7, 7, 7, 7},
-
 
44
            /* unused */
-
 
45
            {0, 0, 0, 0, 0, 0, 0, 0},
-
 
46
            /* unused */
-
 
47
            {0, 0, 0, 0, 0, 0, 0, 0},
-
 
48
            /* unused */
-
 
49
 
21
 
50
        };
-
 
51
 
-
 
52
    }
22
    }
53
 
23
 
54
    uint8_t getTimingAdjust() { return timingAdjust; };
24
    uint8_t getTimingAdjust() { return timingAdjust; };
55
 
25
 
56
    void setTimingAdjust(int8_t adjust) { timingAdjust = adjust; }
26
    void setTimingAdjust(int8_t adjust) { timingAdjust = adjust; }
57
 
27
 
58
    int16_t getRpmMap(unsigned int i)
28
    int16_t getRpmMap(unsigned int i)
59
    {
29
    {
60
        if (i >= 0 && i < MAX_RPM_POINTS)
30
        if (i >= 0 && i < MAX_RPM_POINTS)
61
            return rpmMap[i];
31
            return timingMap.rpmMap[i];
62
        else
32
        else
63
            return 0;
33
            return 0;
64
    }
34
    }
65
 
35
 
-
 
36
 
-
 
37
    void setBaseMap(timingTable_t * map)
-
 
38
    {
-
 
39
        timingMap = *map;
-
 
40
    }
-
 
41
 
-
 
42
 
-
 
43
 
66
    void setRpmMap(unsigned int i, uint16_t val)
44
    void setRpmMap(unsigned int i, uint16_t val)
67
    {
45
    {
68
#if WRITABLE_TABLE
46
#if WRITABLE_TABLE
69
        if (i >= 0 && i < MAX_RPM_POINTS)
47
        if (i >= 0 && i < MAX_RPM_POINTS)
70
            rpmMap[i] = val;
48
            timingMap.rpmMap[i] = val;
71
#endif
49
#endif
72
    }
50
    }
73
 
51
 
74
    uint16_t getVacuumMap(unsigned int i)
52
    uint16_t getVacuumMap(unsigned int i)
75
    {
53
    {
76
        if (i >= 0 && i < MAX_VACUUM_POINTS)
54
        if (i >= 0 && i < MAX_VACUUM_POINTS)
77
            return vacuumMap[i];
55
            return timingMap.vacuumMap[i];
78
        else
56
        else
79
            return 0;
57
            return 0;
80
    }
58
    }
81
 
59
 
82
    void setVacuumMap(unsigned int i, uint16_t val)
60
    void setVacuumMap(unsigned int i, uint16_t val)
83
    {
61
    {
84
#if WRITABLE_TABLE
62
#if WRITABLE_TABLE
85
        if (i >= 0 && i < MAX_VACUUM_POINTS)
63
        if (i >= 0 && i < MAX_VACUUM_POINTS)
86
            vacuumMap[i] = val;
64
            timingMap.vacuumMap[i] = val;
87
#endif
65
#endif
88
    }
66
    }
89
 
67
 
90
    void setTiming(unsigned int vacuumIndex, unsigned int rpmIndex, uint8_t value)
68
    void setTiming(unsigned int vacuumIndex, unsigned int rpmIndex, uint8_t value)
91
    {
69
    {
Line 93... Line 71...
93
#if WRITABLE_TABLE
71
#if WRITABLE_TABLE
94
        if (vacuumIndex < 0 && vacuumIndex >= MAX_VACUUM_POINTS)
72
        if (vacuumIndex < 0 && vacuumIndex >= MAX_VACUUM_POINTS)
95
            return;
73
            return;
96
        if (rpmIndex < 0 && rpmIndex >= MAX_RPM_POINTS)
74
        if (rpmIndex < 0 && rpmIndex >= MAX_RPM_POINTS)
97
            return;
75
            return;
98
        mapping[vacuumIndex][rpmIndex] = value;
76
        timingMap.mapping[vacuumIndex][rpmIndex] = value;
99
#endif
77
#endif
100
    }
78
    }
101
 
79
 
102
    uint8_t getTiming(unsigned int vacuumIndex, unsigned int rpmIndex)
80
    uint8_t getTiming(unsigned int vacuumIndex, unsigned int rpmIndex)
103
    {
81
    {
104
        if (vacuumIndex < 0 && vacuumIndex >= MAX_VACUUM_POINTS)
82
        if (vacuumIndex < 0 && vacuumIndex >= MAX_VACUUM_POINTS)
105
            return 0;
83
            return 0;
106
        if (rpmIndex < 0 && rpmIndex >= MAX_RPM_POINTS)
84
        if (rpmIndex < 0 && rpmIndex >= MAX_RPM_POINTS)
107
            return 0;
85
            return 0;
108
        return mapping[vacuumIndex][rpmIndex];
86
        return timingMap.mapping[vacuumIndex][rpmIndex];
109
    }
87
    }
110
 
88
 
111
    /// @brief Lookup a point in a 1 dimensional array -
89
    /// @brief Lookup a point in a 1 dimensional array -
112
    /// @param point Value to lookup
90
    /// @param point Value to lookup
113
    /// @param curve Lookup table
91
    /// @param curve Lookup table
Line 165... Line 143...
165
        int mapTiming(int rpm, int vacuumMb)
143
        int mapTiming(int rpm, int vacuumMb)
166
        {
144
        {
167
            int angle = 0;
145
            int angle = 0;
168
            /* lookup the interpolated RPM point */
146
            /* lookup the interpolated RPM point */
169
            int16_t rpm_frac = 0;
147
            int16_t rpm_frac = 0;
170
            int rpm_index = lookup(rpm, rpmMap, MAX_RPM_POINTS, &rpm_frac);
148
            int rpm_index = lookup(rpm, timingMap.rpmMap, MAX_RPM_POINTS, &rpm_frac);
171
            if (rpm_index == NO_DATA)
149
            if (rpm_index == NO_DATA)
172
                return timingAdjust + MIN_ADVANCE;
150
                return timingAdjust + MIN_ADVANCE;
173
 
151
 
174
            /* lookup the interpolated vacuum point */
152
            /* lookup the interpolated vacuum point */
175
            int16_t vacuum_frac = 0;
153
            int16_t vacuum_frac = 0;
176
            int vacuum_index = lookup(vacuumMb, vacuumMap, MAX_VACUUM_POINTS, &vacuum_frac);
154
            int vacuum_index = lookup(vacuumMb, timingMap.vacuumMap, MAX_VACUUM_POINTS, &vacuum_frac);
177
            /* if there is a problem, bail out */
155
            /* if there is a problem, bail out */
178
            if (vacuum_index == NO_DATA)
156
            if (vacuum_index == NO_DATA)
179
                return timingAdjust + MIN_ADVANCE;
157
                return timingAdjust + MIN_ADVANCE;
180
 
158
 
181
            /* perform a bilinear mapping */
159
            /* perform a bilinear mapping */
182
            int top_advance;
160
            int top_advance;
183
            // we now have a position between two points in X and Y
161
            // we now have a position between two points in X and Y
184
            if (rpm_frac == 0)
162
            if (rpm_frac == 0)
185
                top_advance = mapping[vacuum_index][rpm_index] * INTERP_SCALE;
163
                top_advance = timingMap.mapping[vacuum_index][rpm_index] * INTERP_SCALE;
186
            // if fractional part then interpolate points off the map
164
            // if fractional part then interpolate points off the map
187
            else
165
            else
188
                top_advance = mapping[vacuum_index][rpm_index] * (INTERP_SCALE - rpm_frac) + mapping[vacuum_index][rpm_index + 1] * rpm_frac;
166
                top_advance = timingMap.mapping[vacuum_index][rpm_index] * (INTERP_SCALE - rpm_frac) +
-
 
167
                              timingMap.mapping[vacuum_index][rpm_index + 1] * rpm_frac;
189
 
168
 
190
            int bottom_advance;
169
            int bottom_advance;
191
            // if no fractional part, then the top and bottom advance point is the same
170
            // if no fractional part, then the top and bottom advance point is the same
192
            if (vacuum_frac == 0)
171
            if (vacuum_frac == 0)
193
            {
172
            {
194
                angle = top_advance * TimingScale / INTERP_SCALE;
173
                angle = top_advance * TIMING_SCALE / INTERP_SCALE;
195
            }
174
            }
196
            else
175
            else
197
            {
176
            {
198
                bottom_advance = mapping[vacuum_index + 1][rpm_index] * (INTERP_SCALE - rpm_frac) + mapping[vacuum_index + 1][rpm_index + 1] * rpm_frac;
177
                bottom_advance = timingMap.mapping[vacuum_index + 1][rpm_index] * (INTERP_SCALE - rpm_frac) +
-
 
178
                                 timingMap.mapping[vacuum_index + 1][rpm_index + 1] * rpm_frac;
199
                /* interpolate down Y axis this time */
179
                /* interpolate down Y axis this time */
200
                int advance = top_advance * (INTERP_SCALE - vacuum_frac) + bottom_advance * vacuum_frac;
180
                int advance = top_advance * (INTERP_SCALE - vacuum_frac) + bottom_advance * vacuum_frac;
201
                /* point is scaled by two multiplications */
181
                /* point is scaled by two multiplications */
202
                angle = advance * TimingScale / (INTERP_SCALE * INTERP_SCALE);
182
                angle = advance * TIMING_SCALE / (INTERP_SCALE * INTERP_SCALE);
203
            }
183
            }
204
 
184
 
205
            if (angle < MIN_ADVANCE)
185
            if (angle < MIN_ADVANCE)
206
                angle = MIN_ADVANCE;
186
                angle = MIN_ADVANCE;
207
            if (angle > MAX_ADVANCE)
187
            if (angle > MAX_ADVANCE)