//**********************************************************************
//            INFO BATTERY PACK
//**********************************************************************
// (c) OK1XGL 2008


#include <16F88.h>
#device *=16
#device adc=10

#fuses WDT,INTRC_IO, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOFCMEN, NOIESO, CCPB3
#use delay(clock=4000000,RESTART_WDT)
#use FAST_IO (A)
#use FAST_IO (B)


// definice pinu


// vystupy LED diody
#define LED1_G          PIN_A6
#define LED2_Y          PIN_A7
#define LED3_Y          PIN_A4
#define LED4_R          PIN_B0

// analogove vstupy
#define I_SENSE         PIN_A0
#define IB_CAN          0
#define V_SENSE         PIN_A1
#define VB_CAN          1
#define TM_PIN            PIN_B7

#define TB_CAN          6
#define REF_25V         PIN_A3

// vstupy rizeni funkcnosti
#define SOURCE_ON       PIN_B6   // analogovy vstup
#define VS_CAN          5
#define LOAD_ON         PIN_B4

// vystupy rizeni funkcnosti
#define CHRG_ON         PIN_B1
#define BATT_ON         PIN_B3

// nastavovaci signaly
#define SET             PIN_A5
#define UP              PIN_B7

#define UP_MASK         0x01    // maska pro stisknute tlacitko UP
#define SET_MASK        0x02    // maska pro stisknute tlacitko SET

// debug seriovka
#ifdef DEBUG
  #use rs232 (baud = 9600, xmit = PIN_B5, DISABLE_INTS)
#endif



#define VS_MIN_mV       8000  // minimalni vstupni napeti napajeciho zdroje pro nabijeni

#define VB_MIN_mV       10000       // minimalni napeti baterie - dojde k odpojeni
#define VB_LOW_mV       11000       // nizke napeti baterie - upozorneni pred odpojenim

#define TB_MAX          45          // max teplota baterie pri nabijeni
#define TB_MIN          5           // min teplota baterie pri nabijeni
#define TB_DEFAULT      25          // teplota baterie, kdyz teplomer neni pouzit

#define VREF_DIS_mV     2500
#define VREF_CHRG_mV    5000

#define VS_STEP_mV      ((VREF_CHRG_mV / 1024.0) * ((8.2 + 1) / 1))    // rozliseni mereni vstupniho napeti mV ()
#define VB_STEP_mV      ((VREF_DIS_mV / 1024.0) * ((68 + 10) / 10.0))  // rozliseni mereni napeti baterie v mV (19 mV -> 1.9 mv na clanek)
//#define VS_MIN          (int16)(VS_MIN_mV / VS_STEP_mV)
#define VS_MIN          (int16)44
#define VB_MIN          (int16)(VB_MIN_mV / VB_STEP_mV)
#define VB_LOW          (int16)(VB_LOW_mV / VB_STEP_mV)

#define I_STEP_mA       ((VREF_DIS_mV / 1024.0) * 10 * 0.1) // rozliseni mereni proudu v mV (2.44 mA)

#define TICK_mS         4             // tik kratkeho casovace v ms
#define S_TICK_TIME     ~4000         // hodnota pro natazeni kratkeho casovace
#define L_TICK_TIME     300 / TICK_mS //
#define HOUR_TIME_WDT   9000   // cas v ms / 400 ms nastav na 1 hod

#define CAP_BATT        ((60.0 * 60.0 * 1000.0) / (TICK_ms * I_STEP_mA))  // pro prevod kapacity baterie na vnitrni reprezentaci

// adresy parametru programu v eeprom
#define B_CAP_H_ADDR    0
#define B_CAP_L_ADDR    1
#define EFF_ADDR        2
#define LOSS_CAP_H_ADDR 3
#define LOSS_CAP_L_ADDR 4
#define LOSS_DAY_H_ADDR 5
#define LOSS_DAY_L_ADDR 6
#define TB_REF_ADDR     7

// maximalni hodnoty parametru programu
const int8 PAR_MAX_TAB [8]  = {5,
                               9,
                               9,
                               9,
                               9,
                               6,
                               9};

// tabulka pro ziskani koeficientu ucinnosti
// hodnoty se ziskaji ze vztahu:  64 / koeficient ucinnosti (pr: 64 / 1.2 = 53)
const int8 CHRG_EFF_TAB [10] = {71,        // ucinnost 0.9
                                67,        // 0.95  
                                64,        // 1.0
                                61,        // 1.05
                                58,        // 1.10
                                55,        // 1.15
                                53,        // 1.20
                                51,        // 1.25
                                49,        // 1.30
                                47};       // 1.35
                                
// globalni promenne
int8 TB_val;          // teplota baterie
int8 TB_ref;          // teplota baterie, pri ktere se merilo samovybijeni
int8 TB_avr24;        // prumerna teplota baterie za 24 hod

int8 l_timer;         // pro dlouhy periodicky casovac
int1 s_tick;          // kratky tik periodickeho casovace
int1 l_tick;          // dlouhy tik periodickeho casovace

int1 blink;           // zrcadlo pro rychle blikani ledkami
int1 slow_blink;      // zrcadlo pro pomale blikani ledkami

int1 invalid_cap;     // neplatny zaznam o aktualni kapacite baterie
int32 B_cap;          // aktualini kapacita baterie

int16 hour_time;      // cas pro odmereni 1 hod pomoci wdt

// promenne vypocitane z parametru programu
int32 B_cap_4_4;      // mez pro plnou kapacitu baterie
int32 B_cap_3_4;      // mez pro 3/4 kapacitu baterie
int32 B_cap_2_4;      // mez pro 2/3 kapacitu baterie
int32 B_cap_1_4;      // mez pro 1/4 kapacitu baterie

int16 chrg_01C;       // regulace proudu na 0.1C
int16 chrg_02C;       // regulace proudu na 0.2C
int8 chrg_eff;        // ucinnost nabijeni

int8 k;               // strmost samovybijeni

// definice potrebnych registru CPU
#bit     ADIE = 0x8c.6      // povoleni interruptu od AD
#bit     PEIE = 0x0b.6      // povoleni interruptu od periferii
#bit     ADIF = 0x0c.6
#bit     TMR1IF = 0x0c.0    // preteceni casovace 1

// Makro pro nastaveni pinu jao vystup (reverzni funke k output_float () )
#define output_fixed(pin) { #asm BCF ((pin) / 8 + 0x80).((pin) % 8) #endasm }


// defaultni parametry programu ulozene v eeprom
#rom  0x2100={3,        // kpacita baterie tisice
              5,        // kapacita baterie stovky
              0,        // ucinnost nabijeni ve tvaru 1.xx s krokem 05
              3,        // ztracena kapacita samovybijenim desitky procent
              0,        // ztracena kapacita samovybijenim jednotky procent
              3,        // za dobu desitky dni
              0,        // za dobu jednotky dni
              25}       // referencni teplota pri ktere probihalo samovybijeni