program Alarm_1;
{
************************************************
* KIMENETEK                                    *
* ~~~~~~~~~                                    *
* RA0..RA5      : LCD (D7,6,5,4,RS,EN)         *
* RE0,1,2       : csipogó, lámpa, csengő       *
* RB5           : AUX                          *
*                                              *
* BEMENETEK                                    *
* ~~~~~~~~~                                    *
* RB4           : Pánik gomb                   *
* RD0123;RC0123 : Zónák 1..8                   *
*                                              *
* RD654;RC7654  : Keypad                       *
*                                              *
* Keypad bekötés:                              *
* Oszlopok:           | Sorok:                 *
*  1 : PIN 3 -> RD.6  |  1 : PIN 2 -> RC.7     *
*  2 : PIN 1 -> RD.5  |  2 : PIN 7 -> RC.6     *
*  3 : PIN 5 -> RD.4  |  3 : PIN 6 -> RC.5     *
*                     |  4 : PIN 4 -> RC.4     *
************************************************
}

{ LCD konfig }

var LCD_RS : sbit at RA4_bit;
var LCD_EN : sbit at RA5_bit;
var LCD_D4 : sbit at RA3_bit;
var LCD_D5 : sbit at RA2_bit;
var LCD_D6 : sbit at RA1_bit;
var LCD_D7 : sbit at RA0_bit;

var LCD_RS_Direction : sbit at TRISA4_bit;
var LCD_EN_Direction : sbit at TRISA5_bit;
var LCD_D4_Direction : sbit at TRISA3_bit;
var LCD_D5_Direction : sbit at TRISA2_bit;
var LCD_D6_Direction : sbit at TRISA1_bit;
var LCD_D7_Direction : sbit at TRISA0_bit;

var 
    sor1 : string[16];
    sor2 : string[16];
    old1 : string[16];
    old2 : string[16];
    keypressed : char;
    tmr_1, sec_rem, cnt0, cnt2, beep_tmr, time_10ms, alarmtmr: byte;
    i, oszlop, sor, menuindex, bufflen, buff : byte;
    altmr : word;
    alarm_on, panic, beep, pressed : bit;
    sec_rem_text: string[3];
    kp_buff, PIN : string[6];
//    chcnt : byte;

//var Zone: array[0..8] of byte;

const nyitott_chr: array[0..7] of byte = (0,0,4,31,0,10,27,0); //NYITOTT
const zart_chr: array[0..7] of byte = (0,0,0,0,4,31,27,0); //ZÁRT
const keypad: array[4] of array[3] of char =(('1','2','3'),
                                            ('4','5','6'),
                                            ('7','8','9'),
                                            ('*','0','#'));
                                            
const _service = 1;
      _monitor = 2;
      _arming  = 3;
      _armed   = 4;
      _alarm   = 5;

      chpin    = 1;
      armtmch  = 2;
      baltmch  = 3;
      altmch   = 4;

var mode, svmode : byte;
                                            

const Menu : array[1] of string[16] =
             ('PIN kod valtas  ');//,
//              'Elesites kesl.  ',
//              'Riasztas kesl.  ',
//              'Riasztas ideje  ');

//var menutxt: string[16];


// RIASZTÁS ELŐTTI VÁRAKOZÁS (riasztó deaktiválásához) [másodperc]
var varakozas : byte;

// ÉLESíTÉS ELŐTTI VÁRAKOZÁS (mp)
var elesites  : byte;

// RIASZTÁS IDŐTARTAMA (perc)
var alarmtime : byte;

procedure interrupt;
begin
 if TMR1IF_bit then
  begin
   if alarmtmr<200 then inc(alarmtmr) else alarmtmr:=0;
   if tmr_1<200 then inc(tmr_1) else tmr_1:=0;
   if (time_10ms<200) then inc(time_10ms) else time_10ms := 0;
//   if cnt1<200 then inc(cnt1) else cnt1:=0;
   if (mode=_alarm) or (mode=_arming) then inc(beep_tmr);
   
   TMR1IE_bit := 1;
   TMR1IF_bit := 0;
//   T1CON.TMR1ON  := 1;// bit 0 enables timer
   TMR1H := $C5;     // preset for timer1 MSB register
   TMR1L := $68;     // preset for timer1 LSB register
   
  end;
end;

procedure ClearDisp;
begin
 LCD_Cmd(_LCD_Clear);
end;

procedure InitDisp;
begin
 LCD_Init();
 LCD_Cmd(_LCD_CURSOR_OFF);

 delay_ms(10);

 Lcd_Cmd(72);
 for i := 0 to 7 do 
  Lcd_Chr_CP(nyitott_chr[i]);

 Lcd_Cmd(80);
 for i := 0 to 7 do 
  Lcd_Chr_CP(zart_chr[i]);

ClearDisp;

end;

procedure DisplayZones;
begin
 if bufflen=0 then
  begin
   sor1:='12345678 P      ';
 
   sor2[0]:=(PORTC.0)+1;
   sor2[1]:=(PORTC.1)+1;
   sor2[2]:=(PORTC.2)+1;
   sor2[3]:=(PORTC.3)+1;
   sor2[4]:=(PORTD.0)+1;
   sor2[5]:=(PORTD.1)+1;
   sor2[6]:=(PORTD.2)+1;
   sor2[7]:=(PORTD.3)+1;
   sor2[8]:=' ';
   sor2[9]:=(PORTB.4)+1;
  end;
end;


(* Keypad bekötés:                              *
* Oszlopok:           | Sorok:                 *
*  1 : PIN 3 -> RD.6  |  1 : PIN 2 -> RC.7     *
*  2 : PIN 1 -> RD.5  |  2 : PIN 7 -> RC.6     *
*  3 : PIN 5 -> RD.4  |  3 : PIN 6 -> RC.5     *
*                     |  4 : PIN 4 -> RC.4     *)

procedure CheckKeyPad;
begin
 if not pressed then
  begin
   for oszlop:=4 to 6 do
    begin
     PORTC:=(PORTC and (%10001111)) or (%00010000 shl (oszlop-4));
     for sor:=4 to 7 do
      begin
       if PORTD.sor then
        begin
         pressed:= true;
//         if (bufflen=buff) then kp_buff:='';
         exit;
        end;
      end;

    end;
  end else
 if (PORTD.sor)=0 then
  begin
   keypressed := keypad[sor-4][oszlop-4];
   pressed:=false;

   if (keypressed<>'*') and (keypressed<>'#') then
   begin
    if (bufflen<buff) then
    begin
    strappendsuf(kp_buff, keypressed);
    kp_buff[buff]:=#0;
    cnt2 := 0;
    end;
   end else
   if keypressed='*' then kp_buff:='';
  end;
   bufflen := strlen(kp_buff);
end;

procedure CheckZones;
var i: byte;
begin
 for i:=0 to 3 do
  if PORTC.i then
   mode := _alarm 
  else
  if PORTD.i then
   mode := _alarm;

if (PORTB.4) or (PORTC.0) then
 begin
  mode  := _alarm;
  panic := true;
 end;
end;

begin
//orgall(0x200);

delay_ms(10);

TRISA    := %00000000;
PORTA    := %00000000;

TRISB    := %11111111;
PORTB    := %00000000;

TRISC    := %00001111;
PORTC    := %00000000;

TRISD    := %11111111;
PORTD    := %00000000;


ADCON0   := 0x00;
ADCON1   := 0x00;

TRISE    := %00001000;
PORTE    := %00000000;



ANSEL    := 0;                         // configure AN pins as digital I/O
ANSELH   := 0;
C1ON_bit := 0;                       // Disable comparators
C2ON_bit := 0;

InitDisp;

mode     := _monitor;
svmode   := 0;
menuindex:= 1;
tmr_1    := 0;
cnt0     := 0;
buff     := 6;
bufflen  := 1;
//cnt1     := 0;
cnt2     := 0;
oszlop   := 4;
sor      := 4;

time_10ms    := 0;
sec_rem      := 0;
beep_tmr     := 0;
alarmtmr     := 0;
altmr        := 0;

sec_rem_text := '00';

kp_buff      := '';
sor1         := '';
sor2         := '';

panic        := false;
alarm_on     := false;
beep         := false;
pressed      := false;
keypressed   := #0;

delay_ms(2);

INTCON.GIE    := 1;
INTCON.PEIE   := 1;

PIE1.TMR1IE   := 1;
PIE1.CCP1IE   := 0;
PIE1.RCIE     := 0;
PIR1          := 0;
T1CON.T1CKPS1 := 0;// bits 5-4  Prescaler Rate Select bits
T1CON.T1CKPS0 := 0;
T1CON.T1OSCEN := 0;// bit 3 Timer1 Oscillator Enable Control: bit 1=on
T1CON.T1SYNC  := 1;// bit 2 Timer1 External Clock Input Synchronization Control bit: 1=Do not synchronize external clock input
T1CON.TMR1CS  := 0;// bit 1 Timer1 Clock Source Select bit: 0=Internal clock (FOSC/4) / 1 = External clock from pin T1CKI (on the rising edge)
T1CON.TMR1ON  := 1;// bit 0 enables timer
TMR1H := $C5;     // preset for timer1 MSB register
TMR1L := $68;     // preset for timer1 LSB register

TRISB.5 := 0;
PORTB.5 := 0;

if PORTE.3=0 then
begin
  mode := _service;
  sor1 := '[ Szerviz mod ]';
end;

for i:=0 to 5 do
 PIN[i] := EEPROM_Read(i);
 PIN[6] := #0;
 

elesites  := EEPROM_Read(7);
varakozas := EEPROM_Read(6);
alarmtime := EEPROM_Read(8);

//delay_ms(800);

//mode := 8;
while true do
begin
keypressed := #0;
 CheckKeyPad;

 case mode of
  _monitor: begin
             DisplayZones;
             if (mode<>_armed) and (keypressed='#') then
              begin
              cnt0 := 0;
              mode := _arming;
              end;
//             keypressed := #0;
            end;
  
  _arming : begin
             if (time_10ms>=100) and (cnt0<elesites+1) then
               begin
                time_10ms := 0;
                inc(cnt0);
                beep:=true;
                sec_rem := (elesites+1 - cnt0);
                ByteToStr(sec_rem,sec_rem_text);
                if bufflen=0 then
                begin
                 sor1:='ELESITES:'+sec_rem_text+'mp  ';
                 sor2:='mulva!          ';
                end;

                if cnt0 = elesites+1 then
                 begin
                  alarmtmr  := 0;
                  altmr     := 0;
                  beep      := false;
                  kp_buff   := '';
                  menuindex := 1;
                  PORTE     := %00000001;
                  PORTB.5   := 0;
//                  PORTE.0   := 1;
                  
                  cnt0      := 0;
                  mode      := _armed;
                 end;
               end;
            end;
            
  _armed  : begin
             DisplayZones;
             CheckZones;
            end;
            
  _alarm  : begin
              if (mode=_alarm) and (time_10ms>=100) and (cnt0<varakozas+1) then
               begin
                time_10ms := 0;
                if not panic then
                begin
                 beep:=true;
                 sec_rem := (varakozas - cnt0);
                 ByteToStr(sec_rem,sec_rem_text);
                if bufflen=0 then
                begin
                 sor1:='BEHATOLAS! '+sec_rem_text+'mp';
                 sor2:='  a riasztasig  ';
                end;
                end else
                 cnt0:=varakozas;

                if cnt0 = varakozas then
                 begin
                  ALARM_ON := TRUE;
                  beep := false;
                  kp_buff :='';
             //     PORTB.5 := 1;
                  PORTE.1 := 1;
                  sor1:='    BEHATOLAS   ';
                  sor2:='     TORTENT    ';
                 end;
                inc(cnt0);
               end;
            end;
            
  _service : begin
              case svmode of
               0 : begin
                    if (menuindex>4) then menuindex := 1 else
                    if (menuindex<1) then menuindex := 4;

                    sor2:=menu[menuindex-1];
                    
                    case keypressed of
                    '4': dec(menuindex);
                    '6': inc(menuindex);
                    '5': begin
                         svmode:=menuindex;

                         case menuindex of
                          1: begin
                              buff := 6;
                             end;
                          2: begin
                              buff := 2;
                             end;

                          3: begin
                              buff := 2;
                             end;

                          4: begin
                              buff := 1;
                             end;
                         end;
                           kp_buff:='';
                           cnt2:=0;
                         end;
                    end;
                   end;
                   
               chpin: begin
                       sor2:='Uj PIN: [      ]';
                       i:=0;
                       while i<bufflen do
                        begin
                         sor2[9+i]:='*';
                         inc(i);
                        end;
                  
                       if (keypressed='#') and (bufflen=6) then
                        begin
                         for i:=0 to 5 do
                           EEPROM_Write(i,kp_buff[i]);

                         svmode:=0;

                        end;
                  
//                pressed:= false;
//                keypressed:= #0;
                      end;
              armtmch: begin
                        if (keypressed='#') and (bufflen=2) then
                          begin
                           svmode := 10 * (ord(sor2[10])-48) + (ord(sor2[11])-48);
                           EEPROM_Write(6,svmode);

//                           delay_ms(30);

//                           svmode := EEPROM_Read(6);
//                           ByteToStr(svmode,sor1);

                           svmode:=0;

                          end;
                        
                        sor2:='Elesites: ';
//                        if kp_buff[0]=#0 then sor2[10]:=' ' else
                                              sor2[10]:=kp_buff[0];
//                        if kp_buff[1]=#0 then sor2[11]:=' ' else
                                              sor2[11]:=kp_buff[1];

                        sor2[13]:='m';
                        sor2[14]:='p';
//                        if i = buff then i:=0;
//                        inc(i);



//                pressed:= false;
//                keypressed:= #0;
                       end;
                       
              baltmch: begin
                        if (keypressed='#') and (bufflen=2) then
                          begin
                           svmode := 10 * (ord(sor2[10])-48) + (ord(sor2[11])-48);
                           EEPROM_Write(6,svmode);

//                           delay_ms(30);

//                           svmode := EEPROM_Read(6);
//                           ByteToStr(svmode,sor1);

                           svmode:=0;

                          end;

                        sor2:='R. elott: ';
//                        if kp_buff[0]=#0 then sor2[10]:=' ' else
                                              sor2[10]:=kp_buff[0];
//                        if kp_buff[1]=#0 then sor2[11]:=' ' else
                                              sor2[11]:=kp_buff[1];

                        sor2[13]:='m';
                        sor2[14]:='p';
//                        if i = buff then i:=0;
//                        inc(i);



//                pressed:= false;
//                keypressed:= #0;
                       end;
                       
                       end;
                       end;
              

 end;

 if (mode>=_arming) and (keypressed<>#0) then
   begin
    cnt2:=0;
    sor1:='PIN: [      ]   ';
    i:=0;
    while i<bufflen do
     begin
      sor1[6+i]:='*';
      inc(i);
     end;

    sor2:='Torol: *        ';

    if strcmp(kp_buff, PIN)=0 then //(kp_buff[1]=pin[1]) and (kp_buff[2]=pin[2]) and (kp_buff[3]=pin[3]) and (kp_buff[4]=pin[4]) then
     begin
      mode     := _monitor;
      alarm_on := false;
      panic    := false;
      kp_buff  := '';
      cnt0     := 0;
      cnt2     := 0;
      PORTE    := 0;
      PORTB.5  := 0;
     end;
  end;

 if (alarmtmr>=100) then
 begin
  alarmtmr := 0;
  if alarm_on then
  begin
   PORTE.2 := not PORTE.2;
   PORTB.5 := not PORTB.5;
  
   inc(altmr);
   if altmr=alarmtime*60 then
    begin
     ALARM_ON := false;
     PORTE    := 0;
     PORTB.5  := 0;
     altmr    := 0;
    end;
   end;

   inc(cnt2);
   if cnt2=5 then
    begin
   if bufflen>0 then
    kp_buff:='';
    
   if svmode>0 then
    svmode := 0;
       
//      keypressed:=#0;
      cnt2:=0;
     end;
    end;
// end;
 
 if (beep_tmr>=5) and beep then
  PORTB.5 := 1;
  
 if (beep_tmr>=8) and beep then
  begin
   PORTB.5 := 0;
   beep_tmr:=0;
  end;

// Csak akkor írunk ki az LCD-re, ha a jelenleginél újabb adat van

if (strcmp(sor1,old1)<>0) or (strcmp(sor2,old2)<>0) then
 begin
  LCD_Out(1,1,sor1);
  LCD_Out(2,1,sor2);

  old1 := sor1;
  old2 := sor2;
  sor1 := '';
  sor2 := '';
 end;
//delay_ms(5);
end;
end.