Subversion Repositories testOled

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. }