/*
Diplomova prace : Palubni pocitac

car_meas.h

Atmega128A 10 MHz XTAL

Autor: Ondrej Lutera

2011/2012

*/
#ifndef CAR_MEAS_H_INCLUDED
#define CAR_MEAS_H_INCLUDED

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <string.h>
#include "adc.h"
#include "timer.h"
#include "define.h"

#ifdef CAR_DEBUG
#include "uart.h"
#include "uart_addon.h"
#endif

#define TANK_CH CH2 // definice kanalu ADC pro mereni
#define V12_CH  CH1
/*  Ux = R2/(R1+R2)Uin
*/
#define TANK_R2         47          // odpory delice napeti pro AD nadrz 47k/100k
#define TANK_R1         100
#define TANKM_TIME      43       /* merici cas * 1/32s */
#define TANKV_MAX       10        /* pocet vzorku medianoveho filtru*/
#define TANK_INT_MIN    10           /* urcuje minimalni pocet interruptu za dany pooling merici cas, ktery zpusobi prejiti do modu mereni pres interrupt */
#define TANK_INT_MAX_POLL 2          /* urcuje maximalni pocet mericich interruptu za sebou - plneni dat prumeru z jednoho okamziku */
#define V12_R2          1         // odpory delice pro palubni sit pomer 10k/100k
#define V12_R1          10
#define V12_TIME        16        /* 16 * 1/32 */

#define AROSA_INJ     963
#define AROSA_V       4
#define AROSA_IMP     395

#define TICKS_MAX   40000       /* maximalni namereny vstrik kdyz automobil stoji, jakmile neni napeti na ventilech, tvari se jako log0 tj stale sepnuti */

#define GEN_PORT    B
#define GEN_PIN     4
#define GEN_TCCR    TCCR0
#define GEN_TCNT     TCNT0
#define GEN_OCR     OCR0
#define GEN_TCCR_INIT   1<< COM00 | 1<<WGM01 | 1 << CS00

#define GEN_FVZ    24

#define ODO_PORT   D
#define ODO_PIN    7
#define ODO_TCCR    TCCR2
#define ODO_TCNT    TCNT2
#define ODO_OCR     OCR2
#define ODO_TCCR_INIT  1<< CS20 | 1<< CS21 | 1 << CS22
#define ODO_TIMSK   TIMSK
#define ODO_TIMSK_INIT  _BV(TOIE2)
#define ODO_TIM_ISR()   ISR(TIMER2_OVF_vect)

#define RPM_PORT    E
#define RPM_PIN     6
#define RPM_TCCRA    TCCR3A
#define RPM_TCCRB    TCCR3B
#define RPM_OCR     OCR3
#define RPM_TCNT    TCNT3
#define RPM_TCCR_INIT   1<< CS30 | 1<< CS31 | 1 << CS32
#define RPM_TIMSK   ETIMSK
#define RPM_TIMSK_INIT  _BV(TOIE3)
#define RPM_TIM_ISR()   ISR(TIMER3_OVF_vect)

#define INJ_PORT1   D
#define INJ_PORT2   D
#define INJ_PIN1    6
#define INJ_PIN2    1

#define INJ_INT     INT1
#define INJ_EICR    EICRA
#define INJ_EICR_INIT  (1<<ISC11)        /* sestupna hrana znaci otevreni */
#define INJ_INT_ISR()  ISR(INT1_vect)
#define INJ_INT_PIN PIND
#define INJ_INT_BIT PD1
#define INJ_INT_EIMSK EIMSK

#define INJ_TCCRA   TCCR1A
#define INJ_TCCRB   TCCR1B
#define INJ_OCR     OCR1
#define INJ_TCNT    TCNT1
#define INJ_TCCR_INIT   1<<CS12 | 1 <<CS11
#define INJ_TIMSK       TIMSK
#define INJ_TIMSK_INIT  _BV(TOIE1)
#define INJ_TIM_ISR()   ISR(TIMER1_OVF_vect)

#define TANK_INT        INT4
#define TANK_INT_FLAG   INTF4
#define TANK_FLAG_REG   EIFR
#define TANK_EICR       EICRB
#define TANK_EICR_INIT  1<<ISC41        /* sestupna hrana protoze komparator invertuje */
#define TANK_EIMSK      EIMSK
#define TANK_INT_ISR()  ISR(INT4_vect)
#define TANK_INT_PORT   E
#define TANK_INT_PIN    4
#define TANK_INT_DISABLE    TANK_EIMSK&=~_BV(TANK_INT)
#define TANK_INT_ENABLE     TANK_EIMSK|=_BV(TANK_INT)

typedef uint32_t tm_t;
typedef uint64_t inj_t;         /* 2^64 mereni vstrikovace */
typedef uint64_t odo_t;         /* 2^64 impuls prevodovky  */
typedef uint64_t rpm_t;         /* 2^64 ukladani v imp*/
typedef uint16_t ipm_t;         /* impuls / 100metru */
typedef uint16_t ccmmin_t;        /* ccm / min */

typedef uint16_t speed_t;
typedef uint32_t fuel_t;
typedef uint32_t m_t ;
typedef uint16_t tank_t;
typedef uint16_t mv_t;
typedef uint16_t imprpm_t;
typedef uint16_t rpmmin_t;
#define EE_INIT_B 'T'
typedef struct
{

    uint8_t init;
    tank_t litr;
    mv_t mvolt;

} calctank_t;
#define CALCT_CNT 5

typedef struct
{

    uint8_t init;       // init bajt pro init eeprom

    inj_t AvgInj;
    inj_t TripInj;
    inj_t TotInj;

    rpm_t AvgRpm;
    rpm_t TripRpm;
    rpm_t TotRpm;

    odo_t AvgImp;
    odo_t TripImp;
    odo_t TotImp;

    tm_t TotTime;
    tm_t TripTime;
    tm_t ActTime;

} cm_t;

typedef struct
{

    uint8_t init;       /* pomocny inicializacni byte, pokud je tento inicializovan, pak jsou platna data ve strukture */
    imprpm_t Rpm;       /* 10 = 10imp/ot udava mnozstvi impulzu prichozich na jednu otacku motoru od hallova snimace otacek motoru */
    ipm_t Meters;      /* 500 = 500imp/100m kalibracni konstanta, udava pocet impulzu, ktere snimac vysle za ujetou vzdalenost 100m */
    ccmmin_t InjFlow; /* 3500 = 350,0 ccm/min  kalibracni konstanta vstrikovace udavana ve standardni jednotce s presnosti na jedno platne des. misto */
    tank_t TankL;                       /* objem nadrze */
    calctank_t TankCalib[CALCT_CNT];    /* pole kalibracnich hodnot nadrze , linearizace nadrze primkami po castech */
    uint16_t NumV;  /* pocet valcu motoru - uint16_t pouze z duvodu kompatibility editacnich funkci a homogenity struktury */
    uint8_t tankInt;
    uint8_t nothing;    /* prazdny byte */

} clb_t;

#ifdef MEAS_DEBUG

void setDebugInjTicks(uint16_t ticks);
void setDebugRpmTicks(uint16_t ticks);
void setDebugOdoTicks(uint8_t ticks);

#endif

fuel_t GetFuel(inj_t *inj);
fuel_t RetFuelCons(odo_t * imp, inj_t *inj);      // funkce ktera vypocitava spotrebu paliva v xx,x l/100km -- pro interni pouziti knihovny
fuel_t RetFuelConsLh();      // vraci spotrebu paliva aktualni v  xx,x L/h
m_t RetMeters(odo_t* imp);      // vraci impulzy prepocitane na metry
speed_t RetSpeed(odo_t*  imp,tm_t* time);
rpmmin_t RetRpm(rpm_t * impRpm,tm_t *time);
/* funkce pro inicializaci mereni */

void InitCMeas(void);

/* ----------------Nutno pridat do hlavni smycky main ---------------*/
void RpmPoll(void);            // vyzvednuti citace rpm za 0.125s
void CMeasPoll(void);       // polling ktery je v v wdt timer preruseni - odber namerenych hodnot 1x za 1s
void V12MeasPoll(void);     // odmery napeti palubni site - nutno pridat do main
void TankMeasPoll(void);        // odmery nadrze - nutno pridat do main

/* ---------------- zjisteni aktualnich mereni ---------------------*/

void ClearTankMeas(void);       // nuluje prumerovani nadrze
uint8_t RetTankMeasMax(void);   // vraci 0/1 zda je je plny buffer vzorku paliva
tank_t GetTankL(void);          // vrati aktualni stav nadrze v L -- prumeruje plovoucim prumerem
mv_t RetTmV(uint16_t ad);   // vraci napeti nadrze v mV
mv_t RetTankmV(void);       // vraci prumerovane napeti nadrze v mV

mv_t GetV12mV(void);        //  vraci napeti palubni site v mV

uint32_t GetRpmCnt(void);
uint32_t GetInjCnt(void);   // vraci aktualni stav nacitanych jednotek vstrikovace
uint32_t GetImpCnt(void);

/* zjisteni stavu mereni ---------------*/

uint8_t IsRunning(void);        // detekce zda motor bezi ci auto jede
uint8_t isNewMeas(void);
inj_t getTmpInjImp(void);
tm_t getTmpTime(void);
odo_t getTmpImp(void);
rpm_t getTmpRpm(void);

/* --------kalibracni funkce ---------------*/
uint8_t GetCalibTankInt(void);
ipm_t GetCalibMeters(void); // vraci kalib. konstantu pro metry
ccmmin_t GetCalibInjFlow(void);     // vraci kalib. konst pro vstrik
void SetCalibMeters(ipm_t cm);  // nastavuje kalib. metry
void SetCalibInjFlow(ccmmin_t ij);  // nastavuje kalib vstrik
uint8_t GetCalibValve(void);    // vraci pocet valcu
void SetCalibValve(uint8_t v);  // nastavuje pocet valcu
tank_t GetCalibL(void);     // vraci kalib konst objemu nadrze v L
void SetCalibL(tank_t l);      // nastavuje kalib kosnt objemu nadrze v L
tank_t GetCalibLx(uint8_t i);   // vraci i-ty prvek Litry kalibracni tabulky
mv_t GetCalibVx(uint8_t i);     // vraci i-ty prvek Napeti kalibracni tabulky
uint8_t GetCalibIx(uint8_t i);  // vraci stav i-teho prvku tabulky- zda je nastaven
void SetCalibLx(uint8_t i,tank_t litr);  // nastavi i-ty prvek Litry kalibracni tabulky
void SetCalibVx(uint8_t i,mv_t mv);       // nastavi i-ty prvek Napeti kalibracni tabulky
void SetCalibIx(uint8_t i,uint8_t init);    // nastavi i-ty prvek init hodnotu

void GetCalibData(clb_t *data);     // vraci ukazatel na kalib strukturu
void SetCalibData(clb_t *data);     // nastavuje kalib strukturu predanymy daty

uint16_t * getRpmOvfPtr(void);      // ukazatele na udaje citacu a preteceniŔ
uint32_t * getRpmTicksPtr(void);
uint16_t * getInjOvfPtr(void);
uint32_t * getInjTicksPtr(void);
uint16_t * getImpOvfPtr(void);
uint32_t * getImpTicksPtr(void);
#endif // CAR_MEAS_H_INCLUDED
