Subversion Repositories testOled

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 mjames 1
#include <cstdint>
2
#include "timing.h"
3
 
4
namespace
5
{
6
 
7
    unsigned constexpr MAX_TIMING_POINTS = 8;
8
    unsigned constexpr MAX_VACUUM_POINTS = 8;
9
    unsigned constexpr TimingScale = TIMING_SCALE;
10
 
11
#pragma pack(push, 1)
12
    typedef union
13
    {
14
        struct
15
        {
16
            int16_t val;
17
            int16_t result;
18
        };
19
        uint32_t u32;
20
    } dataPoint;
21
#pragma pack(pop)
22
 
23
    // points in RPM, degrees
24
    dataPoint const timing_curve[MAX_TIMING_POINTS] = {
25
        {500, 3 * TimingScale},
26
        {750, 0 * TimingScale},
27
        {1000, 0 * TimingScale},
28
        {1500, 12 * TimingScale},
29
        {2500, 18 * TimingScale},
30
        {3500, 22 * TimingScale},
31
        {4500, 22 * TimingScale},
32
        {6000, 15 * TimingScale}};
33
 
34
    // points in mB of vacuum, degrees : initial points ordered
35
    dataPoint const vacuum_curve[MAX_VACUUM_POINTS] = {
36
        {0, 0 * TimingScale},
37
        {166, 2 * TimingScale},
38
        {225, 6 * TimingScale},
39
        {300, 10 * TimingScale},
40
        {700, 10 * TimingScale},
41
        {700, 10 * TimingScale},
42
        {-1, -1}, // filler
43
        {-1, -1}  // filler
44
    };
45
 
46
    // basic timing
47
    const int baseTiming = 7 * TimingScale;
48
 
49
    /// @brief Lookup a point using linear interpolation
50
    /// @param point value to lookup
51
    /// @param curve data point list
52
    /// @param size number of data points in list
53
    /// @return degrees * TIMING_SCALE
54
    int lookup(int point, const dataPoint curve[], int size)
55
 
56
    {
57
        // check lower bounds
58
        if (point < curve[0].val)
59
            return curve[0].result;
60
        // check upper bounds
61
        // find the upper boundary by looking for non -1 points
62
        int upper = size - 1;
63
        while (curve[upper].result <= 0)
64
            upper--;
65
 
66
        if (point >= curve[upper].val)
67
            return curve[upper].result;
68
        for (int pt = 1; pt <= upper; pt++)
69
        {
70
            if ((point >= curve[pt - 1].val) && (point < curve[pt].val))
71
            {
72
                // how far along axis ?
73
                int offset = point - curve[pt - 1].val;
74
 
75
                int range1 = curve[pt].val - curve[pt - 1].val;
76
 
77
                int range2 = curve[pt].result - curve[pt - 1].result;
78
                return ((offset * range2) / range1) + curve[pt - 1].result;
79
            }
80
        }
81
        return 0; // give up.
82
    }
83
};
84
 
85
extern "C"
86
{
87
 
88
    int timing(int rpm, int vacuumMb)
89
    {
90
        int angle = lookup(rpm, timing_curve, sizeof(timing_curve) / sizeof(dataPoint));
91
        angle += lookup(vacuumMb, vacuum_curve, sizeof(vacuum_curve) / sizeof(dataPoint));
92
        angle += baseTiming;
93
        return angle;
94
    }
95
}