/**********************************************************/
/**********************************************************/
/**********************************************************/
/**     Genmap.c - used for generating MAP transfer      **/
/**           function files for MegaSquirt.             **/
/**                                                      **/
/**      Generates barofactor.inc and kpafactor.inc      **/
/**                                                      **/
/**          Bruce A Bowling - August 2001               **/
/**********************************************************/
/**********************************************************/
/**********************************************************/

#include <stdio.h>

/**************************/
/* User-defined area here */
/* Change the NPRES number for the number of KPA-volt points you have */
/* Be sure that the VOLT array is sorted acending values */
/* Both the MPX4115 and MPX4250 values are here (the MPX4250 is commented out) */


#if 0
#  define NPRES 2
   char *label = "; genmap 1.0, data from Robin <robinjo@tiscali.se>, Bosch 300 kPa MAP sensor";
   double  volt[NPRES] = {  0.25,   4.8 };
   double  pres[NPRES] = { 20.0 , 300.0 };
   int     pLo  =  15; // Pressure limits for this sensor.
   int     pHi  = 310;
#elif 0
   // GM stuff snagged from Tom Dolsky's site.
#  define NPRES 2
   //GM MAP PN                             //OLD ONE
   double  volt[NPRES] = {  0.425,    4.025 };
   double  pres[NPRES] = { 20.0,    100.0   };
   int     pLo  =  15; // Made up.
   int     pHi  = 105;
#elif 0
#  define NPRES 4
   // GM MAP                               //NEW Style
   double  volt[NPRES] = { 4.46,   3.20,   2.12,    1.06  };
   double  pres[NPRES] = { 6.90,  55.158, 96.527, 137.896 };
   int     pLo  =  15; // Made up.
   int     pHi  = 150;
#elif 0
#  define NPRES 2
   // MPX4115 values
   char *label = "; genmap 1.0 Motorola MPX4115A";
   double  volt[NPRES] = {  0.204,   4.794 };
   double  pres[NPRES] = { 15.0  , 115.0   };
   int     pLo  =  11; // Pressure limits for this sensor.
   int     pHi  = 118;
#elif 0
#  define NPRES 2
   // MPX4250 values; using Lance's corrected values
   char *label = "; genmap 1.0 Motorola MPX4250A, Lance Gardiner Corrected.";
   double  volt[NPRES] = {  0.165,   4.755 };
   double  pres[NPRES] = { 20.0,   250.0 };
   int     pLo  =  12; // Pressure limits for this sensor.
   int     pHi  = 255;
#else
#  define NPRES 2
   // MPX4250 values
// double  volt[NPRES] = {  0.204,   4.896 }; // From datasheet for vRef = 5.1
// double  pres[NPRES] = { 20.0,   250.0 };

// Slope is 20.4 mV / kPa
// Measured 1.79 V @ 103.183 kPa 06 APR 2003
   char *label = "; genmap 1.0 Motorola MPX4250A\n"
#if 1
                 "; Measured 1.807 V @ 103.183 kPa, box 3, vRef = 5.025";
#define V0 1.807
#define P0 103.183
#define vR 5.025
#else
                 "; Measured 1.780 V @ 103.183 kPa, box 1, vRef = 5.010";
#define V0 1.780
#define P0 103.183
#define vR 5.010
#endif
   double  volt[NPRES] = { V0, V0 + 10.0 };
   double  pres[NPRES] = { P0, P0 + 10.0/0.0204 };
   int     pLo  =   0; // Pressure limits for this sensor.
   int     pHi  = 255;
#endif

/* end user defined area here */
/******************************/

typedef int bool;
enum { false = 0, true = 1 };

bool outOfRange(int pressure)
{
   return pressure < pLo || pressure > pHi;
}

void main()
{
   double   voltage;
   int      pressure, barocor;
   int      i, adcCount;
   FILE    *kpa;
   FILE    *bcf;
   bool     out;

   kpa = fopen("kpafactor.inc", "w");
   fprintf(kpa, "%s\r\n", label);
   fprintf(kpa, "KPAFACTOR: ;\tKPA\t  ADC\tVolts (* = out of sensor range)\r\n");

   bcf = fopen("barofactor.inc", "w");
   fprintf(bcf, "%s\r\n", label);
   fprintf(bcf, "BAROFAC: ;\tcorrFac\t  ADC\tVolts (* = out of sensor range)\r\n");

   /* Loop over all of the A/D range (0 to 255 for 8 bits) */
   i = 1; // Since they are sorted by ascending values, we can do this once outside the loop.
   for (adcCount = 0; adcCount < 256; adcCount++) {
      /* determine voltage for corresponding adcCount */
      voltage = (double)adcCount * vR / 255.0;

      /* Find where voltage value lies in volt[] array */
      while (i < (NPRES - 1) && voltage > volt[i]) i++;

      /* Linear interpolate */
      pressure = pres[i] + ((pres[i] - pres[i - 1]) * (voltage - volt[i])) / (volt[i] - volt[i - 1]);

      /* Limit range to specified sensor values and write */
      out = outOfRange(pressure);
      if (out) {
         if (pressure < pLo)
            pressure = 100.0;
         else
            pressure = 255.0;
      }
/*pressure = (int)(pressure * 255.0 / 300.0);*/
      fprintf(kpa, "\tDB\t%3dT\t; %3d - %5.3f%s\r\n", (int) (pressure), adcCount, voltage, out?"*":"");

      /* Generate barometer correction factor based on pressure value */
      barocor = 100.0 * (1.0 - 0.0047 * ((double)pressure - 100.0));
      fprintf(bcf, "\tDB\t%3dT\t; %3d - %5.3f%s\r\n", (int) (barocor), adcCount, voltage, out?"*":"");
   }
   fprintf(kpa, "\r\n");
   fprintf(bcf, "\r\n");

   fclose(kpa);
   fclose(bcf);
}

