direction commands updated to Up down RPM value

Dependencies:   MAX7219pot MCP23S17 mbed

Fork of POT_V_1_0 by Marine Electricals

Revision:
3:ae45e29f5d4f
Parent:
1:e116808d8b00
Child:
4:710464cb44fc
--- a/main.cpp	Fri Jan 05 04:37:54 2018 +0000
+++ b/main.cpp	Sat Jan 13 11:49:18 2018 +0000
@@ -1,5 +1,3 @@
-#include "mbed.h"
-
 #include "mbed.h"
 #include "pot.h"
 #include "max7219.h"
@@ -19,8 +17,10 @@
 Ticker flash_Ticker;
 Ticker R_A_Ticker;
 Ticker CMD_Ticker;
-Ticker disp_FLASH;                   //display blink
 Ticker DIR_Ticker;
+Ticker HB_fail;
+Ticker RTC_ticker;
+Ticker led_refresh;
 
 //SPI instances creation//
 SPI _SPI2(SPI2_MOSI, SPI2_MISO, SPI2_SCK);  //for displays max7219
@@ -31,7 +31,7 @@
 MCP23S17 mcp23s17_1(1,_SPI3, SPI3_CS1,SPI3_RST);  //class MCP23S17 object instance for mcp23s17 IC-1 key detection
 MCP23S17 mcp23s17_2(2,_SPI3, SPI3_CS2,SPI3_RST);  //class MCP23S17 object instance for mcp23s17 IC-2 key detection
 Max7219 max7219(SPI2_MOSI, SPI2_MISO, SPI2_SCK,SPI2_CS1);  //object instance for seven segment drivers
-
+max7219_configuration_t DEVICE1, DEVICE2;
 //interrupts definations
 InterruptIn int_A(INT_A);       //8commands
 InterruptIn int_B(INT_B);       //4  3commands+1ack
@@ -49,27 +49,35 @@
 DigitalOut buzzer(BUZ);
 DigitalOut hooter(HTR); 
 
-int addr,req,ack,cmd,dir,last_cmd, send_ADDR, rcvd_ADDR, ach_S,ach_M,test_cnt,req_ADDR,ack_ADDR, err_ID, err_Status;
-
-uint8_t digit_disp_1, digit_disp_2, digit_disp_3;        //disp1 for new rpm, disp2 for current rpm, disp3 for rtc
+int err_ALL,sync_count,Hrs_1,Hrs_2, Mins_1, Mins_2, current_cmd, current_status,current_status_dir;
+int addr, req,ack, send_ADDR, rcvd_ADDR, ach_S,ach_M,test_cnt,req_ADDR,ack_ADDR, err_ID, err_Status;
+int rpm_data[4] = {0,0,0,0};               //digits 0-3
+int last_entry[4] = {0,0,0,0};          //digits 0-3
 
-float brightness;
+uint8_t spi_error,no_pot_connected,num_bytes,ticker_count,ticker_count_fast,norm_count,set_bit;
 
-uint8_t spi_error,no_pot_connected;
+uint8_t digit_disp1, digit_disp2, digit_disp3;        //disp1 for new rpm, disp2 for current rpm, disp3 for rtc
+
+int dir, last_dir;
 
 char pot_Addr,addr_ID,checksum;
 
-float HB_timer;
+float HB_timer,duty_cycle,sync_time;
+
+bool device_ERR,pot_Error, norm_op;
+bool toggle,test,toggle_fast,display_flash;
+bool key_CMD,key_CTRL,key_SET;
+bool HB_rcvd, HB_ack_rcvd, REQ_rcvd, BROADCAST_rcvd, ACK_rcvd,time_RCVD;
 
-bool spi_ERR,pot_Error,_disp_FLASH;
-bool RPM_cmd,DIR_cmd, RPM_cmd_ack, DIR_cmd_ack;
-bool HB_rcvd, HB_ack_rcvd, CMD_rcvd, CMD_ack_rcvd, REQ_rcvd, BROADCAST_rcvd, ACK_rcvd, rcvd_DIR;
-bool HB_send, CMD_send, BROADCAST_send, REQ_send, ACK_send, CMD_ack_send;
-bool test;
-bool CMD_key;
+bool DIR_cmd,DIR_cmd_ack,DIR_cmd_ack_send;
+bool RPM_cmd,RPM_cmd_ack,RPM_cmd_ack_send;
+
+bool HB_send, CMD_send, BROADCAST_send, REQ_send, ACK_send;
+
+bool ENTER_ACK_key,DIR_key,REQ_key,ACK_key;
+
 bool switch_CH, pot_MCR_err, pot_ER_err, ACH_SW_over;
 
-char *key;                   // = new char[RX_BUFFER_SIZE];   //memory allocation for Receive buffer
 char valid;
 int device_addr = -1;
 
@@ -77,7 +85,7 @@
 char tx_buf[TX_BUFFER_SIZE+1];
 char RTC_buffer[5] = {1,2,3,4,0};
 
-DigitalOut LED_CMD(_CMD_ACK);                              //ack command in slave devices only
+DigitalOut LED_CMD_ACK(_CMD_ACK);                              //ack command in slave devices only
 DigitalOut LED_CTRL[2] = {_REQ,_ACK};                             //control transfer
 DigitalOut LED_DIR[2] = {_AHEAD,_ASTERN};                         //dir command
 DigitalOut LED_ACH[8] =  {_WH,_BRDG,_MCR,_ER,_WP,_WS,_OPS,_ASP};  //active channels
@@ -86,16 +94,13 @@
 
 PwmOut mypwm(_PWM);
 
-uint8_t rpm_data[4] = {0,0,0,0};               //digits 0-3
-uint8_t last_entry[4] = {0,0,0,0};          //digits 0-3
-
 struct _POT
 {
     int slave_ID;
-    uint8_t err_cnt;
-    bool c_err;         //communication error
+    int err_cnt;
+    bool err_status;
 }; 
-_POT* POT=NULL; 
+struct _POT* POT=NULL;  
 
 enum AddrID
 {
@@ -115,7 +120,7 @@
     ON,
     _FLASH = 2
 };          
-LED_STATUS led_cmd_ack[1];   //only in slave devices
+LED_STATUS led_cmd_ack;   //only in slave devices
 LED_STATUS led_ctrl[2];
 LED_STATUS led_dir[2];
 LED_STATUS led_ach[8];
@@ -180,21 +185,14 @@
 };          //keyscan channelA,B,C,Dof MCP23s17 1& 2 respectively
 enum CHANNEL ch;
 
-enum ack_dir_rpm
-{
-    _RPM = 1,
-    _DIR = 2
-};
+
 
 /**************************************************************************************
- EOT display update FUNCTIONS
+ EOT RTC display update FUNCTIONS
  **************************************************************************************/
-void display_update(bool RTC_disp, char* digits)
+void RTC_display(char* digits)
 {
-    if(RTC_disp)
-    {
-        RTC_disp = false;
-        for(uint8_t i = 0; i <= 3; i++)              //to write all the four digits
+    for(uint8_t i = 0; i <= 3; i++)              //to write all the four digits
         {
             if(i == 1)
               RTC_buffer[i] = RTC_buffer[i]|0b10000000;   // to inc
@@ -202,14 +200,6 @@
                 __nop();
             max7219.write_digit(1, i+1, *(digits+i));   //device 2, digit 1-4 ,data 0x01
         }  
-    }
-    else
-    {
-        for(uint8_t i = 0; i <= 3; i++)              //to write all the four digits
-        {
-            max7219.write_digit(2, i+1, *(digits+i));   //device 1, digit 1-4 ,data pointer
-        }
-    }
 }
 
 /**************************************************************************************
@@ -220,7 +210,7 @@
     time_t seconds = time(NULL);
     strftime(RTC_buffer, 5, "%H%M\n", localtime(&seconds));
     wait_ms(5);
-    display_update(true, RTC_buffer);
+    RTC_display(RTC_buffer);
     wait_ms(1);
 }
 
@@ -247,7 +237,7 @@
     
     if(test)
     {
-        LED_CMD = ON;
+        LED_CMD_ACK = ON;                  //in slave only
        
         for(uint8_t i=0;i<=1;i++)          //control
         {
@@ -261,32 +251,33 @@
         {
                 LED_ACH[i] = ON;                  //duty cycle 10%
         }
+        
+        /*TO DO DISPLAY TEST */
     }
     else
     {
-        for(uint8_t i=0;i<=10;i++)          //cmd
-        {
-            if(led_cmd[i] == ON)
-                LED_CMD[i] = ON;
+        ///////////////////////////////////
+            if(led_cmd_ack == ON)          //status update LED_CMD_ACK
+                LED_CMD_ACK = ON;
             else
                 __nop();
                 
-            if(led_cmd[i] == OFF)
-                LED_CMD[i] = OFF;
+            if(led_cmd_ack == OFF)
+                LED_CMD_ACK = OFF;
             else
                 __nop();
                 
-            if(led_cmd[i] == _FLASH)
+            if(led_cmd_ack == _FLASH)
             {
                 if(toggle)
-                    LED_CMD[i]= ON;
+                    LED_CMD_ACK= ON;
                 else
-                    LED_CMD[i] = OFF;
+                    LED_CMD_ACK = OFF;
             }
             else
                 __nop();
-        }
-        for(uint8_t i=0;i<=1;i++)          //control
+        /////////////////////////////////////
+        for(uint8_t i=0;i<=1;i++)          //status update LED_CTRL 
         {
             if(led_ctrl[i] == ON)
                 LED_CTRL[i] = ON;
@@ -308,7 +299,8 @@
             else
                 __nop();
         }
-        for(uint8_t i=0;i<=7;i++)          //active channel
+        ///////////////////////////////////
+        for(uint8_t i=0;i<=7;i++)          //status update LED_ACH
         {
             if(led_ach[i] == ON)
                 LED_ACH[i] = ON;                  //duty cycle 10%
@@ -345,107 +337,186 @@
 }
 
 /**************************************************************************************
- EOT State Machines FUNCTIONS
+  POT State Machines FUNCTIONS
  **************************************************************************************/
 void HB_State_Machine()                       //run for 50ms at an interval of 10ms,event driven start stop
 {
     static int hb_state_cnt = 0;
-    /* if(HB_send)
+    if(HB_send)
     {
         HB_send = false;
         hb_state_cnt = 0;
     }
     else
         __nop();
-    */  
+        
     if(HB_ack_rcvd)
     {
         HB_ack_rcvd = false;
         HB_Ticker.detach();
         POT[device_addr].err_cnt = 0;
-        POT[device_addr].c_err = false;
+        if(POT[device_addr].err_status)              //if that specific device is in error before but revert bak to healthy state
+        {
+            POT[device_addr].err_status = false;
+            err_Status = 0;
+            err_ID = POT[device_addr].slave_ID;
+            
+            set_bit =  (uint8_t)1<<(err_ID-1);
+            err_ALL = err_ALL^set_bit;                   //bitwise XOR
+            
+            BROADCAST_send = true;                      // to tell all device that error diminished
+            switch_CH = true;                           // to tell specific device active channell                                
+            if(POT[device_addr].slave_ID == pot_Slave_MCR)
+            {
+                pot_MCR_err = false;
+                if(pot_ER_err)
+                {
+                    ach_S = pot_Slave_MCR;
+                    switch_CH = true;                         //automatic takeover if ER is already faulty
+                }
+                else
+                    __nop();
+            }
+            else
+                __nop();
+                
+            if(POT[device_addr].slave_ID == pot_Slave_ER)
+            {
+                pot_ER_err = false;
+                if(pot_MCR_err)
+                {
+                    ach_S = pot_Slave_ER;
+                    switch_CH = true;                         //automatic takeover if ER is already faulty
+                }
+                else
+                    __nop();
+            }
+            else
+                __nop();
+        }
+        else
+            __nop();
+            
+        POT[device_addr].err_status = false;
         hb_state_cnt = 0;
+        err_Status = 0;
         if(POT[device_addr].slave_ID == ach_S)
-            LED_ACH[send_ADDR - 1].ON();
+            led_ach[send_ADDR - 1] = ON;
         else
-            LED_ACH[send_ADDR - 1].OFF();
+            led_ach[send_ADDR - 1] = OFF;
+        
     }
     else
     {
-        if(++hb_state_cnt >= 5)                         //50ms
+        if(++hb_state_cnt >= 5)
         {
-            if((++POT[device_addr].err_cnt >= 3) && (!POT[device_addr].c_err))         //hb ack not received in third attempt
+            hb_state_cnt=0;
+            HB_Ticker.detach();
+            
+            if((++POT[device_addr].err_cnt >= 3)&&(!POT[device_addr].err_status))  //specific device come to the error state
             {
-                POT[device_addr].c_err = true;
-                POT[device_addr].err_cnt = 0;
-                LED_ACH[send_ADDR - 1].FLASHH();
-                err_ID = POT[device_addr].slave_ID;
+                led_ach[send_ADDR - 1] = _FLASH;
+                err_ID = POT[device_addr].slave_ID; 
+                
+                set_bit =  (uint8_t)1<<(err_ID-1); 
+                err_ALL = err_ALL|set_bit;                //bitwise OR
+                
+                POT[device_addr].err_status = true;
                 err_Status = 1;
-                BROADCAST_send = true;                                       //broadcast needed to be sent
-                if((POT[device_addr].slave_ID == pot_Slave_MCR) && (ach_S == pot_Slave_MCR))
+                BROADCAST_send = true;                //broadcast needed to be sent
+                if(POT[device_addr].slave_ID == pot_Slave_MCR)  //means MCR fail
+                {   
+                    pot_MCR_err = true;
+                    if(ach_S == pot_Slave_MCR)
+                    {
+                        if(!pot_ER_err)                   //automatic changeover if ER healthy
+                        {
+                            ach_S = pot_Slave_ER;
+                            switch_CH = true;                  //transfer all slaves the new active slave
+                        }
+                        else
+                        {
+                            pot_Error = true;
+                            ach_S = 9;
+                            switch_CH = true;        //both start flashing for ER nd MCR in all slaves
+                        }
+                    }
+                    else 
+                        __nop();
+                }
+                else 
+                    __nop();
+                   
+                if(POT[device_addr].slave_ID == pot_Slave_ER)
                 {
-                    ach_S = pot_Slave_ER;
-                    pot_MCR_err = true;
-                    switch_CH = true;
-                }
-                else if((POT[device_addr].slave_ID == pot_Slave_ER) && (!POT[device_addr-1].c_err))
-                {
-                    //if((ach_S == pot_Slave_ER) && (pot_MCR_err))
-                     //   pot_Error = true;
-                   // if((ach_S == pot_Slave_ER) && (!pot_MCR_err))
-                   // {
-                    ach_S = pot_Slave_MCR;
                     pot_ER_err = true;
-                    switch_CH = true;
+                    if(ach_S == pot_Slave_ER)
+                    {
+                        if(!pot_MCR_err)                   //automatic changeover if MCR healthy
+                        {
+                            ach_S = pot_Slave_MCR;
+                            switch_CH = true;
+                        }
+                        else
+                        {
+                            pot_Error = true;
+                            ach_S = 9;
+                            switch_CH = true;    //both start flashing for all MCR nd ER
+                        } 
+                    }
+                    else
+                        __nop();
                 }
                 else
-                    pot_Error = false; 
+                    __nop();
             }
+            else
+                __nop();
         }
-            hb_state_cnt=0;
-           // pot_MCR_err = false;
-           // pot_ER_err = false;
-            err_Status = 0;      // no communication error
-            HB_Ticker.detach();
-        }
+        else                        
+            __nop();
     }    
 }
 
-void CMD_State_Machine()                         //function run periodcally in all connected devices on bus
+void CMD_State_Machine()                //function run periodcally in all connected devices on bus
 {
-    int cmd_state_cnt=0;
+    static int cmd_state_cnt=0;
         
-    if(RPM_cmd_ack)                              //PEOTX,CMD received in Master/SUB_Master, non Active Slave & Listner
+    if(RPM_cmd_ack)                        //PEOTX,CMD received in Master/SUB_Master, non Active Slave & Listner
     {
-        RPM_cmd = false;                                        //no more PEOTC will be sent onwards
-        disp_FLASH.detach();                                    //timer stoped
-        max7219.enable_device(1);                               //disp 1 back in normal mode
-        buzzer = _OFF;
-        hooter = _OFF;
+        current_status =  1;              //display steady
         cmd_state_cnt = 0;
+        RPM_cmd = false; 
         RPM_cmd_ack = false;
+        display_flash = false;
+        buzzer = OFF;
+        hooter = OFF;
         CMD_Ticker.detach();                        //cmd state machine ticker stopped in all devices
     }
-    //else 
-   // {
-        //if(addr_ID != ach_S)                //PEOTC, CMD received in other than Active Slave
-          //  return;
-        else if((CMD_ack_send) && (addr_ID == ach_S))                              //if Hotter is ON then send ACK, in case of active Slave
-        {  
-            disp_FLASH.detach();                             //flash timer stoped
-            max7219.enable_device(1);                        //disp 1 back in normal mode steady ON
-            buzzer = _OFF;                                                       
-            hooter = _OFF;
-            cmd_state_cnt = 0;
-            CMD_ack_send = false;       
-            int_B.rise(NULL);               //cmd ack send so disable the key of active slave
-            CMD_Ticker.detach();            //would be stopped in active slave only
+    else 
+    {
+        if(addr_ID != ach_S)                //PEOTC, CMD received in other than Active Slave
+            return;
+        else if(RPM_cmd_ack_send)           //if RPM_cmd_ack in acitve slave
+        {
+            led_cmd_ack = ON;               //RPM cmd ACK by active slave
+            cmd_state_cnt = 0; 
+            buzzer = OFF;                                                       //steady ON 
+            hooter = OFF;
+            cmd_state_cnt=0;
+            RPM_cmd_ack_send = false;
+            RPM_cmd = false;                    
+            int_B.rise(NULL);             //all key functions/interrupt disabled for PORTA,B
+            mcp23s17_1.gpintenb(0x00);    //interrupts disabled
+            wait_us(10);
+            CMD_Ticker.detach();             //would be stopped in active slave only
         }
-        else if(hooter == _OFF)              //if hooter still off
+        else if(hooter == OFF)              //if hooter still off
         {
             if(++cmd_state_cnt >= 12)                       //Hotter ON after 3sec
             {
-                hooter = _ON;
+                cmd_state_cnt = 0;
+                hooter = ON;
                /* if(++cmd_state_cnt >= 96)                     //still command ack not recived for 24 sec
                 {
                     LED_CMD[cmd].OFF();                //command suspended
@@ -459,34 +530,38 @@
             else
                 __nop();
         }
+        else
+         __nop();
     }
 }
 
 void R_A_Statemachine()
 {
     static int state_cnt = 0;
-    if(ACK_rcvd)
-    {
-        //ack_ADDR = rcvd_ADDR;
-        ACK_rcvd = false;
-    }
-    else if(REQ_rcvd)
+    if(++state_cnt >= 60)             //REQ not acknowledged for 30 sec, leds turn off, timer stopped
     {
-        //req_ADDR = rcvd_ADDR;
-        REQ_rcvd = false;
-    }
-    
-    if(++state_cnt >= 10)             //REQ not acknowledged for 5 sec, leds turn off, timer stopped
-    {
+        state_cnt = 0;
         R_A_Ticker.detach();
-        LED_CTRL[REQ_-1].OFF();
-        LED_CTRL[ACK_-1].OFF();
+        
+        if(addr_ID != ach_M)               //*********** TODO****************//
+        {
+            int_B.rise(NULL);
+            mcp23s17_1.gpintenb(0x00);      //portb of mcp1 keys disabled related to ACK
+            wait_us(10);
+        }
+        else
+            __nop();
+            
+        led_ctrl[REQ_-1] = OFF;
+        led_ctrl[ACK_-1] = OFF;
     }
     else
-    {
-        if(ACH_SW_over)               //active channel switchover true only after acknowledge receive
+        __nop();
+        
+    if(ACK_rcvd)               //active channel switchover true only after acknowledge receive
         {
-            ACH_SW_over = false;
+            ACK_rcvd = false;
+            led_ctrl[REQ_-1] = OFF;
             if(addr_ID == pot_Master)
             {
                 if(ack_ADDR == 3 || ack_ADDR == 4)
@@ -496,13 +571,19 @@
                     else if(ach_S == pot_Slave_ER)
                         ach_S = pot_Slave_MCR;
                 }
-                else if(ack_ADDR == 2 || ack_ADDR == 1)       
+                else
+                    __nop();
+                    
+                if(ack_ADDR == 2 || ack_ADDR == 1)       
                 {
                     if(ach_M == pot_Master)
                         ach_M = pot_Submaster;
                     else if(ach_M == pot_Submaster)
                         ach_M = pot_Master;
                 }
+                else
+                    __nop();
+                    
                 switch_CH = true;
                 state_cnt = 0;
                 R_A_Ticker.detach();
@@ -513,41 +594,58 @@
                 R_A_Ticker.detach();
             }
         }
-    }
+        else
+            __nop();
 }
 
-void DIR_Statemachine(void)
+void DIR_state_machine(void)
 {
     static int dir_state_cnt = 0;
     if(DIR_cmd_ack)
     {
+        DIR_cmd =  false;
         DIR_cmd_ack = false;
-        LED_DIR[dir-1].ON();                //led direction acknowledged turn steady
-        buzzer = _OFF;                             //buzzer Off
-        hooter = _OFF
+        current_status_dir = 1;             //steady
+        led_dir[dir-1] = ON;                //led direction acknowledged turn steady
+        buzzer = OFF;                             //buzzer Off
+        hooter = OFF;
         DIR_Ticker.detach();
     }
     else
     {
-        if((++dir_state_cnt >= 12) && (hooter == _OFF))          //direction command not ack for 03 sec
+        if((++dir_state_cnt >= 12) && (hooter == OFF))          //direction command not ack for 03 sec
             {
-                hooter = _ON;
+                hooter = ON;
                 dir_state_cnt = 0;
             }
         else
             __nop();
-    }
-    
+    } 
 }
-
-
-void DISP_FLASH(void)                                             //function attached to event driven ticker disp_FLASH
+void HB_fail_state_machine()
 {
-    _disp_FLASH = !_disp_FLASH;
-    if(_disp_FLASH)
-        max7219.disable_device(1);
-    else
-        max7219.enable_device(1);
+    static uint8_t fail_count = 0;
+    if(HB_rcvd)
+    {
+        HB_rcvd = false;
+        device_ERR = false;
+    }
+    else if(++fail_count >=3)             // if max 07 number of connected eots 7x3=21, it takes 150x21=3.150 sec to alarm
+    {
+        fail_count = 0;
+        led_dir[dir] = OFF;               //current command if any turned OFF
+       // led_cmd[current_cmd] = OFF;
+        display_flash = false;
+        device_ERR = true;
+        max7219.disable_device(2);              //shutdown mode
+        wait_ms(2);
+        for(uint8_t i = 0; i <=7; i++)
+        {
+            led_ach[i] = OFF;             //all other active chnnels leds or device errors
+        }
+        led_ach[addr_ID - 1] = _FLASH;    //specific device is in error flshes only
+        HB_fail.detach();
+    }
 }
 
 void NUMERIC_handler(uint8_t key_ID)                             //function sacnning all the 0-9 number keys
@@ -557,23 +655,24 @@
     if(key_ID != FALSE0)
         {                                                                                  
         if(((ach_M == pot_Master) && (addr_ID == pot_Master)) || ((ach_M == pot_Submaster) && (addr_ID == pot_Submaster)))                               //for Master
-        {
-            if(digit_disp1 <= 1)
-                digit_disp1 = 4;
-            else
-                digit_disp1-- ;
-                
-            rpm_data[digit_disp1-1] = num;
-            max7219.write_digit(1,digit_disp1,rpm_data[digit_disp1-1]);                //4th digit updated on first press, then 3rd on next press....soon                        
-        }
+            {
+                if(digit_disp1 <= 1)
+                    digit_disp1 = 4;
+                else
+                    digit_disp1-- ;
+                    
+                rpm_data[digit_disp1-1] = num;                               //data stored in global buffer
+                max7219.write_digit(2,digit_disp1,rpm_data[digit_disp1-1]);  //4th digit updated on first press, then 3rd on next press....soon
+                wait_us(10);                             
+            }
         else
             __nop();
         }
     else
         __nop();
-    }
 }
 
+
 void CTRL_handler(uint8_t CTRL_ID)                        //handle  control transfer 
 {
     if(CTRL_ID != FALSE1)
@@ -583,15 +682,27 @@
             if(CTRL_ID == REQ_)
             {   
                 req = REQ_;                     //req data updated 0 here, same int values as in enum
-                LED_CTRL[REQ_-1].FLASHH();                //req led flash starts
+                REQ_key = true;
+                led_ctrl[REQ_-1] = _FLASH;                //req led flash starts
                 R_A_Ticker.attach(&R_A_Statemachine,0.5);
             }
-            if(CTRL_ID == ACK_ && REQ_rcvd)
+            else
+                __nop();
+                
+            if((CTRL_ID == ACK_)&& (REQ_rcvd))
             {
+                REQ_rcvd = false;
                 ack = ACK_;                     //ack data updated 2 here
-                LED_CTRL[ACK_-1].OFF();                  //ack led turns off
+                ACK_key = true;
+                int_B.rise(NULL);               //interrupt disabled
+                wait_us(10);
+                mcp23s17_1.gpintenb(0x00);      //ACK key interrupts disabled
+                wait_us(10);
+                led_ctrl[ACK_-1] = OFF;                  //ack led turns off
                 R_A_Ticker.detach();
             }
+            else
+                __nop();
         }
     }
     else 
@@ -603,50 +714,36 @@
     if(DIR_ID != FALSE2)
     {
         if(addr_ID == ach_M)
-        {
-            if(DIR_ID == AHEAD)
-            {   
-                dir = AHEAD;                     
-                LED_DIR[dir-1].FLASHH();                //led direction AHEAD start flashing
-                buzzer = _ON;                             //buzzer ON
-                DIR_cmd = true;
-                DIR_Ticker.attach(&DIR_Statemachine,0.5);
-            }
-            else
-                __nop();
-            if(DIR_ID == ASTERN)
+        { 
+            current_status_dir = 2;                  //flash
+            led_dir[dir-1] = OFF;
+            dir = DIR_ID;                     
+            led_dir[dir-1] = _FLASH;                //led direction AHEAD start flashing
+            buzzer = ON;                             //buzzer ON
+            DIR_cmd = true;                          // dir cmd needs to be sent
+        }
+        else
+            __nop();
+            
+        if (addr_ID == ach_S)
+        { 
+            if((dir == DIR_ID)&&(DIR_cmd))         //direction command is received                  
             {
-                dir = ASTERN;              
-                LED_DIR[dir-1].FLASHH();                  //led direction AHEAD start flashing
-                buzzer = _ON;                             //buzzer ON
-                DIR_cmd = true;
-                DIR_Ticker.attach(&DIR_Statemachine,0.5);
+                current_status_dir = 1;
+                led_dir[dir-1] = OFF;
+                dir = DIR_ID;                     
+                led_dir[dir-1] = ON;                    //led direction AHEAD start flashing
+                buzzer = OFF;                             //buzzer OFF
+                DIR_key = true;                   //dir ack will be sent in response to HB
             }
             else
                 __nop();
         } 
-        else if (addr_ID == ach_S)
-        {
-            if(DIR_ID == AHEAD)
-            {   
-                if(rcvd_DIR && (dir == AHEAD));         //direction command is received                  
-                LED_DIR[dir-1].ON();                    //led direction AHEAD start flashing
-                buzzer = _OFF;                             //buzzer ON
-                DIR_cmd = true;
-                DIR_Ticker.attach(&DIR_Statemachine,0.5);
-            }
-            if(DIR_ID == ASTERN)
-            {
-                dir = ASTERN;              
-                LED_DIR[dir-1].FLASHH();                //led direction AHEAD start flashing
-                buzzer = _ON;                             //buzzer ON
-                DIR_cmd = true;
-                DIR_Ticker.attach(&DIR_Statemachine,0.5);
-            }
-        }
+        else
+                __nop();
     }
     else 
-        __nop(); //then do nothing
+        __nop();                                //then do nothing
 }
 
 void DISP_handler(uint8_t DISP_ID)                        //handle  control transfer 
@@ -655,213 +752,191 @@
     disp_key = DISP_ID;
     if(DISP_ID != FALSE3)
     {
-        if((addr_ID == ach_M)||(addr_ID == ach_S)) 
+        switch(disp_key)
         {
-            switch(disp_key)
-            {
-                case clr_ENTRY:                                      //CE     delete only last/4th digit and shift others digits towards right/4th digit
-                    if(addr_ID == ach_M)
+            case clr_ENTRY:                                      //CE,elete only last/4th digit and shift others digits towards right/4th digit
+                if(addr_ID == ach_M)
+                {
+                    for(uint8_t i = 3; i >= 0 ; i--)
+                    {
+                        rpm_data[i] = rpm_data[i-1];
+                        if(i==0)
+                        rpm_data[i] = 0;                         //data 0 means left most digit will be blank bcoz no decode mode is used
+                    }
+                    for(uint8_t i = 0; i <=3; i++)
                     {
-                        for(uint8_t i = 3; i >= 0 ; i--)
-                        {
-                            rpm_data[i] = rpm_data[i-1];
-                            if(i==0)
-                            rpm_data[i] = 0;                              //data 0 means left most digit will be blank bcoz no decode mode is used
-                        }
-                        for(uint8_t i = 0; i >=3; i++)
-                        {
-                            max7219.write_digit(1,i+1,rpm_data[i]);      //4th digit will be deleted whilers are shifted towards right 1st will be blank
-                        }
+                        max7219.write_digit(2,i+1,rpm_data[i]);    //4th digit will be deleted whilers are shifted towards right 1st will be blank
                     }
-                    else
+                }
+                else
+                {
+                    __nop();
+                }
+            break;
+            
+            case last_ENTRY: 
+                if(addr_ID == ach_M) 
+                {                                    //C      delete all digits in DS1 and show last entered value                                 
+                    for(uint8_t i = 0; i >=3; i++)
                     {
-                        __nop();
-                    }
-                break;
-                
-                case last_ENTRY:                                      //C      delete all digits in DS1 and show last entered value 
-                    if(addr_ID == ach_M)
-                    {                                   
-                        for(uint8_t i = 0; i >=3; i++)
-                        {
-                            max7219.write_digit(1,i+1,last_entry[i]);     //last entery displayed
-                        }
+                        max7219.write_digit(2,i+1,last_entry[i]);     //last entery displayed
                     }
-                    else
+                }
+                else
+                {
+                    __nop();
+                }  
+            break;
+            
+            case ENTER_ACK:                                    //work as Enter in master and CMD ACK in slave
+                if((addr_ID == ach_S)&&(RPM_cmd))                    //RPM command ack needs to be sent
+                {    
+                    display_flash = false; 
+                    buzzer = OFF;
+                    ENTER_ACK_key = true;                                               //flashing display1 turned steady
+                    RPM_cmd_ack = true;                              //RPM command acknowledged by active slave
+                } 
+                else  if (addr_ID == ach_M)                                 //in case of active masters
+                {                                              //disp1 start flashing, and data sent over UART for all digits 1-4
+                    for(uint8_t i = 0; i >=3; i++)
                     {
-                        __nop();
-                    } 
-                break;
-                
-                case ENTER_ACK:  
-                    if((addr_ID == ach_S)&&(CMD_rcvd))                    //RPM command ack needs to be sent
-                    {                                                    //flashing display1 turned steady
-                        RPM_cmd_ack = true;                              //RPM command acknowledged by active slave
-                    } 
-                    else  if (addr_ID == ach_M)                                 //in case of active masters
-                    {                                      //disp1 start flashing, and data sent over UART for all digits 1-4
-                        for(uint8_t i = 0; i >=3; i++)
-                        {
-                            last_entry[i] = rpm_data[i];                  //data saved to last entery
-                        }
-                        disp_FLASH.attach(&DISP_FLASH,0.500);             //timer started
-                        int_A.rise(NULL);              //all key functions DISabled for PORTA,B in active MASTER only        
-                        int_B.rise(NULL);
-                        RPM_cmd = true;                                   //command need to be send
+                        last_entry[i] = rpm_data[i];           //data saved to last entery
                     }
-                    else
-                    {
-                        __nop();
-                    }
-                break;
-                
-                default:
-                
-                break;
-            }
+                    display_flash = true;             //display starts flashing
+                    int_A.rise(NULL);                 //all key functions DISabled for PORTA,B in active MASTER only        
+                    int_B.rise(NULL);
+                    current_status =  2;              //flash
+                    buzzer = ON;
+                    RPM_cmd = true;                   //command need to be send
+                }
+                else
+                {
+                    __nop();
+                }
+            break;
+            
+            default:
+                __nop();
+            break;
         }
     }
     else 
         __nop(); //then do nothing
 }
 
-void BRT_handler(float brt)
-{ 
-    for(uint8_t i=0;i<=1;i++)          //cmd led initialisation
-    {
-        LED_DIR[i].set_Brightness(brt);        //setting period 100 ms
-    }
-    for(uint8_t i=0;i<=1;i++)         //ctrl led intialisation
-    {
-        LED_CTRL[i].set_Brightness(brt);
-    }
-    for(uint8_t i=0; i<=7;i++)            //ach led initialisation
-    {
-        LED_ACH[i].set_Brightness(brt);
-    }
-}
-
+/******************************************************************
+function to set brightness of leds and seven segment
+******************************************************************/
 void SET_handler(uint8_t Set_ID)
 {
-    if(Set_ID != FALSE4)
+    if(Set_ID != FALSE2)
     {
-        if(Set_ID == INC)
-        {
-            if(brightness <= 0.99f)
-            {
-                brightness = +0.01;
-                BRT_handler(brightness);
-            }
-            else
-            {
-                brightness = 0.99;
-                BRT_handler(brightness);
-            }
-            
-        }
-        else if(Set_ID == DEC)
+        switch(Set_ID)
         {
-            if(brightness >= 0.01f)
-            {   
-                brightness = -0.01;
-                BRT_handler(brightness);
-            }           
-            else
-            {
-                brightness = 0.01;       //minimum brightnes
-                BRT_handler(brightness);
-            }
-        }
-        else if(Set_ID == TEST)
-        {
-            test_cnt++;
-            if(test_cnt <= 1)
-            test = true;
-            else if(test_cnt >= 2)
-            {
-                test = false;
-                test_cnt = 0;
-            }
+            case INC:
+                duty_cycle = mypwm.read();     //as duty cycle decreases creases brightnes increases
+                if( duty_cycle >= 0.01f)
+                {
+                    duty_cycle = duty_cycle-0.01f;
+                    mypwm.write(duty_cycle);
+                }
+                else
+                {
+                    duty_cycle = 0.01;
+                }
+                if((DEVICE1.intensity || DEVICE2.intensity) <= 0x0f)
+                {
+                    DEVICE1.intensity ++;                               //intensity modified
+                    DEVICE2.intensity ++;
+                    max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
+                    max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
+                }
+                else
+                {
+                    DEVICE1.intensity =0x0f;
+                    DEVICE2.intensity =0x0f;
+                    max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
+                    max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
+                }
+            break;
+        
+            case DEC:
+                duty_cycle = mypwm.read();
+                if( duty_cycle < 0.99f)          //as duty cycle increases brightnes decreases
+                {
+                    duty_cycle = duty_cycle+0.01f;
+                    mypwm.write(duty_cycle);
+                }
+                else
+                {
+                    duty_cycle = 0.99;
+                }
+                if((DEVICE1.intensity || DEVICE2.intensity) >= 0x01)
+                {
+                    DEVICE1.intensity --;                              //intensity modified
+                    DEVICE2.intensity --;
+                    max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
+                    max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
+                }
+                else
+                {
+                    DEVICE1.intensity =0x01;
+                    DEVICE2.intensity =0x01;                                //minimum brightnes
+                    max7219.set_intensity(DEVICE1);       //updating brightness value of DEVICE1
+                    max7219.set_intensity(DEVICE2);       //updating brightness value of DEVICE2
+                }
+            break;
+        
+            case TEST:
+                test_cnt++;
+                if(test_cnt <= 1)
+                test = true;
+                else if(test_cnt >= 2)
+                {
+                    test = false;
+                    test_cnt = 0;
+                }
+                else
+                    __nop();
+            break;
+            
+            default:
+                __nop();
+            break;
         }
     }
     else
         __nop();
 }
-
-
-
-
 /**************************************************************************************
- EOT SPI Data Read KEY FUNCTIONS
+ POT SPI Data Read KEY FUNCTIONS
  **************************************************************************************/
 unsigned char read_KEY_SPI(int CH)
 {
     char _key;
-    uint8_t spi_err=0;
     switch(CH)
     {
         case 1:
-        if(spi_err<3)
-        {
-            _key=mcp23s17_1.intcapa();                        // read(INTCAPA_ADDR);
-            if(mcp23s17_1.intcapa())                          //read(INTCAPA_ADDR)) again if some non zero value obtained           //if Interrupt pending
-                {
-                    spi_err++;
-                }
-            else
-                {
-                    spi_err=0;
-                }
-        }
-        else
-        { 
-            _key=0;
-            spi_ERR=true;
-        }
+            wait_ms(1);
+            _key = mcp23s17_1.intcapa();                   // read(INTCAPA_ADDR);
+            wait_ms(1);
         break;
         
         case 2:
-        if(spi_err<3)
-        {
+            wait_ms(1);
             _key=mcp23s17_1.intcapb();
-            if(mcp23s17_1.intcapb())             //if Interrupt pending
-                {
-                    spi_err++;
-                }
-            else
-                {
-                    spi_err=0;
-                }
-        }
-        else
-        {   
-            _key=0;
-            spi_ERR=true;
-        }
+            wait_ms(1);
         break;
         
         case 3:
-        if(spi_err<3)
-        {
+            wait_ms(1);
             _key=mcp23s17_2.intcapa();
-            if(mcp23s17_2.intcapa())            //if Interrupt pending
-                {
-                    spi_err++;
-                }
-            else
-                {
-                    spi_err=0;
-                }
-        }
-        else
-        {   
-            _key=0;
-            spi_ERR=true;
-        }
+            wait_ms(1);
         break;
-        
         case 4:
-        _key = mcp23s17_2.gpiob(); //address read PORTB of chip2 for getting pot addresses
+        wait_ms(1);
+        _key = mcp23s17_2.gpiob(); //address read PORTB of chip2
+        wait_ms(1);
         break;
         default:
         _key = 0;
@@ -869,9 +944,11 @@
     }
     return(_key);
 }
+
 void read_KEY_A()                      //function check status of PORTA of MCP23S17 (1) chip
 {
     char key_status = 0;
+    uint8_t num_KEY = 0;
     key_status = read_KEY_SPI(ch_A);    //to read portA of mcp23s17(1)
     if(key_status != 0xff)                    //means some key must have been pressed
     {
@@ -912,6 +989,10 @@
 void read_KEY_B()
 {
     char key_status = 0;
+    uint8_t num_KEY = 0;
+    uint8_t dir_KEY = 0;
+    uint8_t disp_KEY = 0;
+    uint8_t ctrl_KEY = 0;
     key_status = read_KEY_SPI(ch_B);   //to read portBof mcp23s17(1)
     if(key_status != 0xff)
     {   
@@ -933,19 +1014,19 @@
                 dir_KEY = ASTERN;
                 DIR_handler(dir_KEY);
             break;
-            case 0xef:               //0xef  GPA4
-                ctrl_KEY = ACK;
+            case 0xef:                     //0xef  GPA4
+                ctrl_KEY = ACK_;
                 CTRL_handler(ctrl_KEY);
             break;
-            case 0xdf:               //0xdf  GPA5
+            case 0xdf:                     //0xdf  GPA5
                 disp_KEY = clr_ENTRY;               //CE
                 DISP_handler(disp_KEY);
             break;
-            case 0xbf:               //0xbf  GPA6
+            case 0xbf:                     //0xbf  GPA6
                 disp_KEY = last_ENTRY;             //C
                 DISP_handler(disp_KEY);
             break;
-            case 0x7f:               //0x7f  GPA7
+            case 0x7f:                    //0x7f  GPA7
                 disp_KEY = ENTER_ACK;
                 DISP_handler(disp_KEY);
             break;
@@ -961,6 +1042,8 @@
 void read_KEY_C()
 {
     char key_status = 0;
+    uint8_t ctrl_KEY = 0;
+    uint8_t set_KEY = 0;
     key_status = read_KEY_SPI(ch_C);   //to read portA of mcp23s17(2)
     if(key_status != 0xff)
     {
@@ -990,7 +1073,7 @@
 
 
 /**************************************************************************************
-EOT Serial Data Out FUNCTIONS
+POT Serial Data Out FUNCTIONS
  **************************************************************************************/
 uint8_t get_checksum(const char *sentence)
 {
@@ -1017,99 +1100,156 @@
     switch(seq)
     {
         case 0:
-            sprintf(key,"$PEOTA,%u,%c*", addr_ID, *valid);
+            sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid);
         break;
         case 1:
-            sprintf(key,"$PEOTR,%u,%u,%c*", addr_ID, req, *valid);
+            sprintf(tx_buf,"$PPOTR,%u,%u,%c", addr_ID, REQ_, valid);
         break;
         case 2:
-            sprintf(key,"$PEOTK,%u,%u,%c*", addr_ID, ack, *valid);
+            sprintf(tx_buf,"$PPOTK,%u,%u,%c", addr_ID, ACK_, valid);
         break;
         default:
-            sprintf(key,"$PEOTA,%u,%c*", addr_ID, *valid);
+            sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid);
         break;
     }
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
-void send_ack_CMD(uint8_t _adr, uint8_t x)
+void send_ack_CMD(uint8_t cmd_t)
 {
-    sprintf(key,"$PEOTX,%u,%u,%c*", _adr, x, *valid);
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    switch(cmd_t)
+    {
+        case 1:                                       //RPM cmd ack
+        sprintf(tx_buf,"$PPOTX,%u,%u,%c", addr_ID, cmd_t, valid);
+        break;
+        case 2:                                       //DIR cmd Ack
+        sprintf(tx_buf,"$PPOTX,%u,%u,%c", addr_ID, cmd_t, valid);
+        break;
+        default:
+        __nop();
+        break;
+    }
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
-void send_CMD(uint8_t _adr)
-{                                                  //digiit1        digit2            digit3           digit4
-    sprintf(key,"$PEOTC,%u,%u,%u,%u,%u,%c*", _adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3], *valid);
-    checksum = get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+void send_RPM(uint8_t _adr)
+{
+    sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c", _adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3], valid);
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
 void send_DIR(uint8_t _adr)             //addr 1-8 of leds,error=1 or 0(no error)
 {
-    sprintf(key,"$PEOTD,%u,%u,%c*",_adr,dir,*valid);             // dir is 1 for ahead, 2 for astern
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    sprintf(tx_buf,"$PPOTD,%u,%u,%c",_adr,dir,valid);             // dir is 1 for ahead, 2 for astern
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
 void send_HB(uint8_t _adr)                   //master will send the haertbeat to all presentees at periodic intervals
 {      
-    sprintf(key,"$PEOTH,%u,%c*", _adr, *valid);
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    sprintf(tx_buf,"$PPOTH,%u,%c", _adr, valid);
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
 void send_BROADCAST()             //addr 1-8 of leds,error=1 or 0(no error)
 {
-    sprintf(key,"$PEOTB,%u,%u,%c*",err_ID,err_Status,*valid);
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    sprintf(tx_buf,"$PPOTB,%u,%u,%c",err_ALL,err_Status,valid);
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
     BROADCAST_send=false;
 }
+ /** Function will send ac-M, ac-S, rpm-data(04digits), cmd_state)**/
+void send_ACH()                 
+{
+    sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,,%u,%u,%c", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],dir,current_status,current_status_dir,valid);
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
+}
 
-void send_ACH()
+void ask_TIME()
 {
-    sprintf(key,"$PEOTS,%u,%u,%c*", ach_M, ach_S, *valid);
-    checksum=get_checksum(key);                
-    sprintf(key,"%u\r\n",checksum);              
-    UART.printf("%s",key);
+    Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0;
+    sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c", Hrs_1,Hrs_2, Mins_1, Mins_2,valid);    //querry to CPU for time
+    //checksum=get_checksum(tx_buf);                
+    //sprintf(tx_buf,"%u",checksum);
+    Drive_En = 1;              
+    UART.printf("%s\r\n",tx_buf);
+    wait_ms(2);
+    Drive_En = 0;
 }
 
-
 /**************************************************************************************
  EOT Serial Data In FUNCTIONS
  **************************************************************************************/
-void rcvd_HB()      //master check HB  along with req response for all presentees
+void rcvd_HB()      //all devices check for HB  along with req response for all presentees
 {
-    if(rcvd_ADDR == addr_ID)             //self address received
-    {           
+    if(rcvd_ADDR == addr_ID)             //==addr_ID  self address received
+    {   
+        HB_rcvd = true;       
         if(addr_ID > pot_Slave_ER)
-        {                            //if no req
+        {                                //all listners replied with
             resp_HB(0);                  //normal HB response
         }
-        else
+        else                             //in case of active slave
         {
-            if(req)
+            if(ENTER_ACK_key)               //RPM ACK key is detected at active slave
+            {
+                send_ack_CMD(1);           
+                RPM_cmd_ack_send = true;
+                ENTER_ACK_key = false;
+            }
+            else if(DIR_key)                //dir ack key detected at active slave
             {
+                DIR_key = false;
+                DIR_cmd_ack_send = true;
+                send_ack_CMD(2);
+            }
+            else if(REQ_key)
+            {
+                REQ_key = false;
                 resp_HB(1);                 //req and ack status data in req=1 and ack=2 if true
-                req = 0;
             }
-            else if(ack)
+            else if(ACK_key)
             {
+                ACK_key = false;
                 resp_HB(2);                 //req and ack status data in req=1 and ack=2 if true
-                ack = 0;
             }
             else
                 resp_HB(0);                 //req and ack status data in req=1 and ack=2 if true
         }
+        HB_fail.attach(&HB_fail_state_machine,1);
     }
     else
       __nop(); 
@@ -1117,7 +1257,7 @@
 
 void resp_rcvd_HB()                  //master and active/passive slaves check HB response along with req/ack commands
 {   
-    if(addr_ID == eot_Master)                                       //only master will be able to monitor status of all eots connected
+    if(addr_ID == pot_Master)                                       //only master will be able to monitor status of all eots connected
     { 
         if(send_ADDR == rcvd_ADDR)
             HB_ack_rcvd = true;
@@ -1127,180 +1267,317 @@
     else
         __nop();
 }
-
-void rcvd_rpm_CMD()         //all devices check for received command
+void rcvd_ACH()
 {
-    for(uint8_t i = 0; i >= 3 ; i--)
+    led_ach[ach_M-1] = ON;
+    if(current_status == 2)
+    {
+        led_dir[dir-1] = _FLASH;
+        max7219.enable_device(2);
+        display_flash = true; 
+    }
+    else if(current_status == 1)
+    {
+        led_dir[dir-1] = ON;
+        max7219.enable_device(2);
+        display_flash = false;
+    }
+    else
+    {
+        led_dir[dir-1] = OFF;
+        max7219.enable_device(2);
+    }
+
+    if(current_status_dir == 2)
+    {
+        led_dir[dir-1] = _FLASH;
+    }
+    else if(current_status_dir == 1)
+    {
+        led_dir[dir-1] = ON;
+    }
+    else
+    {
+        led_dir[dir-1] = OFF;
+    }
+    
+    for(uint8_t i = 3; i <= 7 ; i++)
+        {
+            max7219.write_digit(1,i+1,rpm_data[i]);     //device 1 digits 1-4                  //data 0 means left most digit will be blank bcoz no decode mode is used
+        }
+        
+    if(ach_S != 9)
     {
-        max7219.write_digit(1,i+1,rpm_data[i]);     //disp1                  //data 0 means left most digit will be blank bcoz no decode mode is used
-    }                                        
-    buzzer = _ON;                                                                   //buzzer on                                                     
+        if(ach_S == pot_Slave_MCR)
+        {
+            led_ach[pot_Slave_MCR -1] = ON;
+            if(led_ach[pot_Slave_ER -1] == ON)
+                led_ach[pot_Slave_ER -1] = OFF;    //ER off
+            else
+                __nop();
+        }
+        else if(ach_S == pot_Slave_ER)
+        {
+            led_ach[pot_Slave_ER -1] = ON;    //ER ON 
+            if(led_ach[pot_Slave_MCR -1] == ON)
+                led_ach[pot_Slave_MCR -1] = OFF;    //ER off
+            else
+                __nop();   
+        }
+        else
+            __nop();
+            
+        if((RPM_cmd || DIR_cmd)&& (addr_ID == ach_S))      // cmd ack not received before its failure control shifted to another slave
+        {                                                //all key functions enabled for PORTB in active slave only        
+            int_B.rise(&read_KEY_B);
+            wait_us(10);
+            mcp23s17_1.gpintenb(0xff);    //ff
+            wait_us(10);
+        }
+        else
+            __nop();
+    }
+    else
+    {
+        led_ach[pot_Slave_MCR-1] = _FLASH;
+        led_ach[pot_Slave_ER-1]  = _FLASH;
+    }  
+}
+
+void rcvd_rpm_CMD()                         //all devices check for received command
+{
+    led_cmd_ack = _FLASH;                   //ack cmd led start flashing
+    for(uint8_t i = 0; i <= 3 ; i++)
+    {
+        max7219.write_digit(2,i+1,rpm_data[i]);     //device 2 digits 1-4                  //data 0 means left most digit will be blank bcoz no decode mode is used
+    }  
+    wait_us(10);                                      
+    buzzer = ON;
+    display_flash = true;                     //display start flashing                                                         //buzzer on                                                     
+    
     if(ach_S == addr_ID)
     {        
-        int_B.rise(&read_KEY_B);                                                 //portc is always enbaled in all cases and PORTA is enabled only for active master
-    }
-    else 
-    {
-        __nop();
-    }
-    if(addr_ID == rcvd_ADDR)                                                     //particular device responds cmd_ack
-    {        
-        resp_HB(0);                                                              //CMD_ack or response with PEOTA syntax send by devices as per their addresss
+        int_B.rise(&read_KEY_B);   //only PORTB needs to be enabled
+        wait_us(10);
+        mcp23s17_1.gpintenb(0xff);    //ff
+        wait_us(10);                                              //portc is always enbaled in all cases and PORTA is enabled only for active master
     }
     else 
     {
         __nop();
     }
-    
-    disp_FLASH.attach(&DISP_FLASH,0.50);                                         //disp1 flash timer started  in all connected devices except  master
-    CMD_Ticker.attach(&CMD_State_Machine,0.25);                                  //state machine timer started in all connected devices except  master
+    CMD_Ticker.attach(&CMD_State_Machine,0.25);                                 //state machine timer started in all connected devices except  master
 }
+
 void rcvd_dir_CMD()         //all devices check for received command
 {
-    rcvd_DIR = true;
-    LED_DIR[last_dir-1].OFF();
-    LED_DIR[dir-1].FLASHH();                                                    //led flash started
-    buzzer = _ON;                                                                 //buzzer on
-    last_dir = dir;
-    //ACK_pending = true;                                                         //HB-cmd ack pending with "A"  
-    DIR_Ticker.attach(&DIR_State_Machine,0.25);                                 //state machine timer started in all connected devices 
+    DIR_cmd =  true;
+    led_dir[last_dir-1] = OFF;
+    led_dir[dir-1] = _FLASH;                                                    //led flash started
+    buzzer = ON;                                                                 //buzzer on
+    last_dir = dir;                                                        //HB-cmd ack pending with "A"  
     if(ach_S == addr_ID)
     {       
-        int_B.rise(&read_KEY_B);                      //enable keys bcoz ahead/astern keys co-grouped to PORTB of mcp23s17(1)
+        int_B.rise(&read_KEY_B);                      //enable portb interupts
+        mcp23s17_1.gpintenb(0xff);    //ff
+        wait_us(10); 
     }
+    DIR_Ticker.attach(&DIR_state_machine,0.25);
 }
 
 void rcvd_BROADCAST()
 {
-    if(err_Status==1)                       //err non zero
+    for(uint8_t i = 0 ; i <= 7 ; i++)
     {
-        LED_ACH[err_ID].FLASHH();
+        if(((uint8_t)1<<i) & (uint8_t)err_ALL)
+        {
+            led_ach[i] = _FLASH;
+        }
+        else if(led_ach[i] != ON)
+        {
+            led_ach[i]= OFF;
+        }
+        else
+            __nop();
     }
-    else
+    for(uint8_t i = 3; i <= 7 ; i++)
     {
-        LED_ACH[err_ID].OFF();
-    }
+        max7219.write_digit(2,i+1,rpm_data[i]);     //device 2 digits 4-8                  //data 0 means left most digit will be blank bcoz no decode mode is used
+    }  
+    wait_us(10);
     
 }
+void rcvd_TIME()
+{
+    uint8_t Hrs,Mins;
+    struct tm t;
+    Hrs = 10*Hrs_1+Hrs_2;
+    Mins = 10*Mins_1+Mins_2;
+    t.tm_year = 2018-1900; 
+    t.tm_mon = 5;
+    t.tm_mday = 16;
+    t.tm_hour = Hrs;
+    t.tm_min = Mins;
+    t.tm_sec = 51;
+    set_time((time_t)mktime(&t));
+    wait_ms(1);
+    read_RTC();
+    wait_ms(1);
+    time_RCVD = true;
+}
 
 void read_SERIAL()
 {
-    UART.scanf("%s",key);
-    strtok(key,",");
-    if(strcmp(key,"$PEOTH") == 0)                           //* present submaster,Slaves or lsitners receive HB *// 
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
-        rcvd_HB();                                          //set flag when Heartbeat received
-    }
-    else if(strcmp(key,"$PEOTA") == 0)                      //* Master,submaster and Slaves receive  heartbeat resp *//
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-        if(RPM_cmd_ack && addr_ID == ach_S)                 //ENTER_ACK key  here is detected from active slave
-        {
-            send_ack_CMD(addr_ID,RPM);                                 //PEOTX,addr_ID,R(for RPM)
-            CMD_ack_send = true;
-            RPM_cmd_ack = false;                            //in active slave
-        }
-        else if(DIR_cmd_ack && addr_ID == ach_S)
-        {
-            send_ack_CMD(addr_ID,DIR);                                  //PEOTX,addr_ID,D(for direction)
-            DIR_cmd_ack = false;
-            DIR_Ticker.detach();                                   //DIR_state_machine suspended in active slave
-        }
-        else
-            resp_rcvd_HB();
-    }
-    else if(strcmp(key,"$PEOTB") == 0)                       //* submaster,Slaves or listener receive broadcast *//
-    {
-        sscanf(strtok (NULL,","), "%u", &err_ID);            //cmd extracted
-        sscanf(strtok (NULL,","), "%u", &err_Status);
-        rcvd_BROADCAST();
-    }
-    else if(strcmp(key,"$PEOTC") == 0)                 //* submaster,Slaves or listener receive CMD *//
+    char rcvd_char;
+    int cmd_t;
+    while(UART.readable() && (num_bytes < RX_BUFFER_SIZE))
     {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);       //address extracted
-        sscanf(strtok (NULL,","), "%u", &rpm_data[0]);     //rpm data digit 1 and soon
-        sscanf(strtok (NULL,","), "%u", &rpm_data[1]);       
-        sscanf(strtok (NULL,","), "%u", &rpm_data[2]);
-        sscanf(strtok (NULL,","), "%u", &rpm_data[3]);
-        CMD_rcvd = true;
-        rcvd_rpm_CMD();
-    }
-    else if(strcmp(key,"$PEOTD") == 0)                      //* present submaster,Slaves or lsitners receive HB *// 
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
-        sscanf(strtok (NULL,","), "%u", &dir);        // 1 for ahead and 2 for astern
-        rcvd_dir_CMD();                                   //set flag when Heartbeat received
-    }
-    else if(strcmp(key,"$PEOTX") == 0)                //* Master,submaster,Slave or listners receive CMD acknowledge *//
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);       //addr extracted
-        sscanf(strtok (NULL,","), "%u", &ack_rpm_dir);                //ack extracted
-        
-        if(ack_rpm_dir == RPM)
-            RPM_cmd_ack = true;  
-        else if (ack_rpm_dir == DIR)
-            DIR_cmd_ack = true;
-        else
-            __nop();   
-    }
-    else if(strcmp(key,"$PEOTS") == 0)                 //*active channel status recieved *//
-    {
-        int _M = ach_M;
-        int _S = ach_S;
-        sscanf(strtok (NULL,","), "%u", &ach_M);       //cmd extracted
-        sscanf(strtok (NULL,","), "%u", &ach_S);
-        if(_M != ach_M)
-        {
-            LED_ACH[ach_M-1].ON();                     //TODO in case of master submaster PORTA,B needs to be enabled/disabled
-            LED_ACH[_M-1].OFF();                       // along with HB_ticker attach/detach
-        }
-        else if(_S != ach_S)
-        {
-            LED_ACH[ach_S-1].ON();
-            LED_ACH[_S-1].OFF();
-        }
+        rcvd_char = UART.getc();
+        if(rcvd_char == '$')             //first character
+            num_bytes = 0;
         else
             __nop();
-    }
-    else if(strcmp(key,"$PEOTR") == 0)               //* control transfer request arrived*//
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-        sscanf(strtok (NULL,","), "%u", &req);    //e.g $R req or $K ack 
-        if(addr_ID < eot_Slave_ER)
+            
+        rx_buf[num_bytes] = rcvd_char;
+        num_bytes++;
+        if(rcvd_char == '\n')             //last character   
         {
-            REQ_rcvd = true;
-            req_ADDR = rcvd_ADDR;
-            R_A_Ticker.attach(&R_A_Statemachine,0.5);
-            if((rcvd_ADDR == eot_Master || rcvd_ADDR == eot_Submaster) && (addr_ID == eot_Master || addr_ID == eot_Submaster))
+            strtok(rx_buf,",");
+            if(strcmp(rx_buf,"$PPOTH") == 0)                      //* present submaster,Slaves or lsitners receive HB *// 
+            {
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
+                rcvd_HB();                                   //set flag when Heartbeat received
+            }
+            else if(strcmp(rx_buf,"$PPOTA") == 0)                  //* Master,submaster and Slaves receive  heartbeat resp *//
+            {
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
+                resp_rcvd_HB();
+            }
+            else if(strcmp(rx_buf,"$PPOTB") == 0)                 //* submaster,Slaves or listener receive broadcast *//
+            {
+                sscanf(strtok (NULL,","), "%u", &err_ALL);       //device in error with addr_ID =  err_ID
+                sscanf(strtok (NULL,","), "%u", &err_Status);
+                rcvd_BROADCAST();
+            }
+            else if(strcmp(rx_buf,"$PPOTC") == 0)                 //* submaster,Slaves or listener receive CMD *//
             {
-                LED_CTRL[ACK_-1].FLASHH();        //ack led blink
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);       //cmd extracted
+                sscanf(strtok (NULL,","), "%u", &rpm_data[0]);     //rpm data digit 1 and soon
+                sscanf(strtok (NULL,","), "%u", &rpm_data[1]);       
+                sscanf(strtok (NULL,","), "%u", &rpm_data[2]);
+                sscanf(strtok (NULL,","), "%u", &rpm_data[3]);
+                RPM_cmd = true;                                    // in all devices who receive RPM command
+                rcvd_rpm_CMD();
+            }
+            else if(strcmp(rx_buf,"$PPOTD") == 0)                      //* present submaster,Slaves or lsitners receive HB *// 
+            {
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);        //address of connected device
+                sscanf(strtok (NULL,","), "%u", &dir);        // 1 for ahead and 2 for astern
+                DIR_cmd = true;
+                rcvd_dir_CMD();                                   //set flag when Heartbeat received
             }
-            else if((rcvd_ADDR == eot_Slave_ER || rcvd_ADDR == eot_Slave_MCR) && (addr_ID == eot_Slave_ER || addr_ID == eot_Slave_MCR))
+            else if(strcmp(rx_buf,"$PPOTX") == 0)                //* Master,submaster,Slave or listners receive CMD acknowledge *//
             {
-                LED_CTRL[ACK_-1].FLASHH();        //ack led blink
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);       //address extracted
+                sscanf(strtok (NULL,","), "%u", &cmd_t);
+                switch(cmd_t)
+                {
+                    case 1:
+                        RPM_cmd_ack = true;
+                    break;
+                    
+                    case 2:
+                        DIR_cmd_ack = true;
+                        led_dir[last_dir-1] = OFF;
+                        last_dir = dir;
+                        led_dir[dir-1] = ON;
+                    break;
+                    
+                    default:
+                        __nop();
+                    break;       
+                }        
             }
-            else
-                __nop();
-        }
-        else
-            __nop();
-    }
-    else if(strcmp(key,"$PEOTK") == 0)               //* Master,submaster,Slave or listners receive CMD acknowledge *//
-    {
-        sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
-        sscanf(strtok (NULL,","), "%u", &ack);    //e.g $R req or $K ack
-        ACK_rcvd = true;
-        if(addr_ID < eot_Slave_ER)
-        {
-            ack_ADDR = rcvd_ADDR;
-            ACK_rcvd = true;
-            ACH_SW_over = true;
-            
-            if((rcvd_ADDR == eot_Master || rcvd_ADDR == eot_Submaster) && (addr_ID == eot_Master || addr_ID == eot_Submaster))
-                LED_CTRL[ACK_-1].OFF();
-            else if((rcvd_ADDR == eot_Slave_ER || rcvd_ADDR == eot_Slave_MCR) && (addr_ID == eot_Slave_ER || addr_ID == eot_Slave_MCR))
-                LED_CTRL[ACK_-1].OFF();
+            else if(strcmp(rx_buf,"$PPOTS") == 0)                 //*active channel status recieved *//
+            {
+                sscanf(strtok (NULL,","), "%u", &ach_M);       //cmd extracted
+                sscanf(strtok (NULL,","), "%u", &ach_S);
+                sscanf(strtok (NULL,","), "%u", &rpm_data[0]);
+                sscanf(strtok (NULL,","), "%u", &rpm_data[1]);
+                sscanf(strtok (NULL,","), "%u", &rpm_data[2]);
+                sscanf(strtok (NULL,","), "%u", &rpm_data[3]);
+                sscanf(strtok (NULL,","), "%u", &dir);
+                sscanf(strtok (NULL,","), "%u", &current_status);
+                sscanf(strtok (NULL,","), "%u", &current_status_dir);
+                rcvd_ACH(); 
+            }
+            else if(strcmp(rx_buf,"$PPOTR") == 0)               //* control transfer request arrived*//
+            {
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
+                sscanf(strtok (NULL,","), "%u", &req);    //e.g $R req or $K ack 
+                if(addr_ID <= pot_Slave_ER)
+                {
+                    REQ_rcvd = true;
+                    req_ADDR = rcvd_ADDR;
+                    if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
+                    {
+                        int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
+                        wait_us(10);
+                        mcp23s17_1.gpintenb(0xff);      // portb of mcp1 ACK key enabled
+                        wait_us(10);
+                        led_ctrl[ACK_-1] = _FLASH;        //ack led blink
+                    }
+                    else 
+                        __nop();
+                        
+                    if(((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)) || ((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)))
+                    {
+                        int_B.rise(&read_KEY_B);        //to enable ACK key interrupt
+                        wait_us(10);
+                        mcp23s17_1.gpintenb(0xff);      //portb of mcp1 ACK key enabled
+                        wait_us(10);
+                        led_ctrl[ACK_-1] = _FLASH;       //ack led blink
+                    }
+                    else
+                    __nop();
+                    
+                    R_A_Ticker.attach(&R_A_Statemachine,0.5);
+                }
+            }
+            else if(strcmp(rx_buf,"$PPOTK") == 0)               //* Master,submaster,Slave or listners REQ acknowledge *//
+            {
+                sscanf(strtok (NULL,","), "%u", &rcvd_ADDR);
+                sscanf(strtok (NULL,","), "%u", &ack);    //e.g $R req or $K ack
+                if(addr_ID <= pot_Slave_ER)
+                {
+                    ack_ADDR = rcvd_ADDR;
+                    ACK_rcvd = true;
+                    //ACH_SW_over = true;
+                
+                if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master)))
+                    {
+                         led_ctrl[ACK_-1] = OFF;
+                         //R_A_Ticker.detach();
+                    }
+                else if(((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)) || ((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)))
+                    {
+                        led_ctrl[ACK_-1] = OFF;
+                        //R_A_Ticker.detach();
+                    }
+                else
+                    __nop();
+                }
+                else
+                    __nop();
+            }
+            else if(strcmp(rx_buf,"$PEOTT") == 0)                 //* submaster,Slaves or listener receive CMD *//
+            {
+                sscanf(strtok (NULL,","), "%u", &Hrs_1);       //cmd extracted
+                sscanf(strtok (NULL,","), "%u", &Hrs_2); 
+                sscanf(strtok (NULL,","), "%u", &Mins_1);
+                sscanf(strtok (NULL,","), "%u", &Mins_2);
+                rcvd_TIME();
+            }
             else
                 __nop();
         }
@@ -1309,78 +1586,98 @@
     }
 }
 
+/********END of FUNCTION****************/
+
 /**************************************************************************************
 EOT Handler FUNCTIONS
  **************************************************************************************/
 void HB_handler()                     //function run periodically within active master only
 {   
-    if(addr_ID == ach_M)                    //function run only in active master
+    if(++sync_count >= sync_time)
     {
-        if(ach_M == eot_Master)
+        time_RCVD = false;
+        norm_op = false;
+        sync_count = 0;
+        ask_TIME();                         //master will send querry for GPS time
+    }
+    else if(time_RCVD || norm_op)                     //as all receive time update normal operation starts
+    {
+        if(ach_M == pot_Master)
         {   
             device_addr++;
-            if(device_addr >= no_eot_connected)
-            device_addr = 0;
+            if(device_addr >= no_pot_connected)
+                device_addr = 0;
         }
         else
-        __nop();
+            __nop();
         /*else if(ach_M == eot_Submaster)
-            {   
-                if(device_addr==2)
-                {
-                    device_addr=3;
-                }
-                else
-                {
-                    device_addr++;
-                    if(device_addr>NO_MAX_EOT)
-                    device_addr=1;
-                }
-             }
-            */
-        send_ADDR = EOT[device_addr].slave_ID;
+        {   
+            if(device_addr==2)
+            {
+                device_addr=3;
+            }
+            else
+            {
+                device_addr++;
+                if(device_addr>NO_MAX_EOT)
+                device_addr=1;
+            }
+        }
+                        */
+        send_ADDR = POT[device_addr].slave_ID;
         if(RPM_cmd)
         {
-            send_CMD(send_ADDR);                                     //cmd to be send with current running address and rpm data value
-            HB_Ticker.attach(&HB_State_Machine,0.010);               //HB_state_machine runing for CMD_ack with PEOTA sentence in master only
-            CMD_Ticker.attach(&CMD_State_Machine,0.25);              //CMD_state_machine ticker started in master only             
+            send_RPM(send_ADDR);
+            RPM_cmd =  false;                                                      //cmd to be send with current running address and cmd value
+            wait_ms(2);
+            //HB_Ticker.attach(&HB_State_Machine,0.010);
+            CMD_Ticker.attach(&CMD_State_Machine,0.25);                   //CMD_state_machine ticker started              
         }
         else if(DIR_cmd)
         {
-           send_CMD(send_ADDR);
-           HB_Ticker.attach(&HB_State_Machine,0.010);
-           DIR_Ticker.attach(&DIR_State_Machine,0.25); 
+            send_DIR(send_ADDR);
+            DIR_cmd =  false;                                                      //cmd to be send with current running address and cmd value
+            wait_ms(2);
+            //HB_Ticker.attach(&HB_State_Machine,0.010);
+            DIR_Ticker.attach(&DIR_state_machine,0.25);                   //CMD_state_machine ticker started              
         }
-        else if(BROADCAST_send)
+        else  if(BROADCAST_send)
         {
-            send_BROADCAST();                                             //broadcast needed err_ID nd err_Status
+            send_BROADCAST();         //broadcast needed err_ID nd err_Status
             BROADCAST_send = false;
+            wait_ms(2);
         }
-        else if(switch_CH)                                                //active channel switch over happened
+        else if(switch_CH)                            //active channel switch over happened
         {
-            send_ACH();                                                   //active channel changeover
+            send_ACH();                              //active channel changeover
             switch_CH = false;
+            wait_ms(2);
         }
+        
         else
-        {
-            cmd=0x0;
-            send_HB(send_ADDR);                                                 //hb is to be going on
-            HB_ticker.attach(&HB_State_Machine,0.010);                          //HB_state_machine timer started
+        {    
+            send_HB(send_ADDR);   //hb is to be going on
+            HB_Ticker.attach(&HB_State_Machine,0.010);                          //HB_state_machine timer started
         }
     }
+    else if(++norm_count >= 5)
+    {
+        norm_count = 0;
+        if(!time_RCVD)
+            norm_op = true;
+        else
+            __nop();
+    }
     else
         __nop();
 }
 
-
-
 /**************************************************************************************
-EOT config FUNCTIONS
+POT config and address Read FUNCTIONS
  **************************************************************************************/
 void read_POT_ADDR()                     //function give present eots and no. of connected eots
 {   
     pot_Addr = read_KEY_SPI(ch_D);
-    
     if(pot_Addr==0xff)   //if 0xff it means no addressing done
         pot_Error=true;
     else if(pot_Addr!=0xff)
@@ -1402,12 +1699,14 @@
                                 case 1:
                                     POT[no_pot_connected].slave_ID = pot_Submaster;
                                     POT[no_pot_connected].err_cnt=0;
-                                    no_eot_connected++;
+                                    POT[no_pot_connected].err_status=false;
+                                    no_pot_connected++;
                                 break;
                                 case 2:
                                     ach_S = pot_Slave_MCR; 
                                     POT[no_pot_connected].slave_ID = pot_Slave_MCR;
                                     POT[no_pot_connected].err_cnt=0;
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                                 case 3:
@@ -1419,31 +1718,40 @@
                                     }                                     
                                     POT[no_pot_connected].slave_ID = pot_Slave_ER;
                                     POT[no_pot_connected].err_cnt = 0;
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                                 case 4:
                                     POT[no_pot_connected].slave_ID = pot_Listner_WP;
                                     POT[no_pot_connected].err_cnt = 0;
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                                 case 5:
                                     POT[no_pot_connected].slave_ID = pot_Listner_WS;
                                     POT[no_pot_connected].err_cnt=0;
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                                 case 6:
                                     POT[no_pot_connected].slave_ID = pot_Listner_OPS;
                                     POT[no_pot_connected].err_cnt=0;
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                                 case 7:
                                     POT[no_pot_connected].slave_ID = pot_Listner_ASP;
                                     POT[no_pot_connected].err_cnt=0;       
+                                    POT[no_pot_connected].err_status=false;
                                     no_pot_connected++;
                                 break;
                             }
                         }
-                    }    
+                    }
+                    if(no_pot_connected <=0)
+                        pot_Error = true;
+                    else
+                        pot_Error = false;  
                 }
                 else
                 {
@@ -1452,36 +1760,50 @@
                         case 1:
                         {
                             addr_ID = pot_Submaster;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 2:
                         {
                             addr_ID = pot_Slave_MCR;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 3:
                         {
                             addr_ID = pot_Slave_ER;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 4:
                         {
                             addr_ID = pot_Listner_WP;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 5:
                         {
                             addr_ID = pot_Listner_WS;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 6:
                         {
                             addr_ID = pot_Listner_OPS;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         case 7:
                         {
                             addr_ID = pot_Listner_ASP;
+                            ach_S = pot_Slave_MCR;
+                            led_ach[ach_S-1] = ON;
                             break;
                         }
                         default:
@@ -1493,254 +1815,390 @@
     }
 }
 
-void Uart_Init()
-{                                     //buffer initialisation
-  Serial UART(SERIAL_TX, SERIAL_RX);
+void interrupt_init()
+{
+    int_A.mode(PullUp);
+    wait_ms(1);
+    int_B.mode(PullUp);
+    wait_ms(1);
+    int_C.mode(PullUp);
+    wait_ms(1); 
+}
+
+void Uart_init()
+{                                    
   UART.baud(9600);
   UART.format(8,SerialBase::None,1);
-  //UART.attach( &read_SERIAL, UART.RxIrq);    //receive interrupt enabled
+  wait_ms(1);
 }
 
+void Led_init()
+{   
+    
+    LED_CMD_ACK = ON;                  
+    wait_ms(1);
+        
+    for(uint8_t i=0;i<=1;i++)             //ctrl led intialisation
+    {
+        LED_CTRL[i] = ON;
+        wait_ms(1);
+    }
+    for(uint8_t i=0; i<=7;i++)            //ach led initialisation
+    {
+        LED_ACH[i] = ON ; 
+        wait_ms(1);
+    } 
+    
+    wait(1);
+    
+    led_cmd_ack = OFF;
+    wait_ms(1);
+    
+    for(uint8_t i=0;i<=1;i++)         //ctrl led turned off
+    {
+        LED_CTRL[i] = OFF;
+        led_ctrl[i] = OFF;
+        wait_ms(1);
+    }
+    for(uint8_t i=0; i<=7;i++)         //ach led turned off
+    {
+        LED_ACH[i] = OFF; 
+        led_ach[i] = OFF;
+        wait_ms(1);
+    } 
+}
 
-void Spi3_Init()              //for mcp23s17
+void pwm_init()
 {
-  _SPI3.format(8,0);         //8bit,mode 0
-  _SPI3.frequency(1000000);  //1mhz   
+    mypwm.period_ms(50);           //initialy 20ms
+    wait_us(1);
+    mypwm.write(.90);      //90%duty cycle
+    wait_us(1);
 }
 
 void mcp23s17_init()
 {
     //device1 configuration
-    mcp23s17_1.reset();             //reset on power-up
-    mcp23s17_1.iodira(0xff);        //set 8-bits PORTA as inputs
-    mcp23s17_1.iodirb(0xff);        //set 8-bits PORTb as inputs
+    mcp23s17_1.reset();           //reset on power-up
+    wait_ms(1);
+    mcp23s17_2.reset();           //reset on power-up
+    wait_ms(1);
+    mcp23s17_1.iocon(0x2a);
+    wait_ms(1);
+    mcp23s17_2.iocon(0x2a);
+    wait_ms(1);
+    mcp23s17_1.iodira(0xff);     //set 8-bits PORTA as inputs
+    wait_ms(1);
+    mcp23s17_1.iodirb(0xff);     //set 8-bits PORTB as inputs
+    wait_ms(1);
     mcp23s17_1.ipola(0x00);
+    wait_ms(1);
     mcp23s17_1.ipolb(0x00);
-    mcp23s17_1.gpintena(0xff);      //interrupt enabled on PORTA
-    mcp23s17_1.gpintenb(0xff);      //interrupt enabled on PORTB
+    wait_ms(1);
+    mcp23s17_1.gpintena(0x00);   //initially disabled
+    wait_ms(1);
+    mcp23s17_1.gpintenb(0x00);    
+    wait_ms(1);
     mcp23s17_1.defvala(0xff);
+    wait_ms(1);
     mcp23s17_1.defvalb(0xff);
-    mcp23s17_1.intcona(0x2a);       //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed
-    mcp23s17_1.intconb(0x2a);
+    wait_ms(1);
+    mcp23s17_1.intcona(0x00);     //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed
+    wait_ms(1);
+    mcp23s17_1.intconb(0x00);
+    wait_ms(1);
     mcp23s17_1.gppua(0xff);
+    wait_ms(1);
     mcp23s17_1.gppub(0xff);
+    wait_ms(1);
     
     //device2 configuration
-    mcp23s17_2.reset();           //reset on power-up
-    mcp23s17_2.iodira(0xff);     //set 8-bits PORTA as inputs
-    mcp23s17_2.iodirb(0xff);     //set 8-bits PORTb as inputs
+   
+    mcp23s17_2.iodira(0xff);       //set 8-bits PORTA as inputs
+    wait_ms(1);
+    mcp23s17_2.iodirb(0xff);       //set 8-bits PORTb as inputs
+    wait_ms(1);
     mcp23s17_2.ipola(0x00);
+    wait_ms(1);
     mcp23s17_2.ipolb(0x00);
-    mcp23s17_2.gpintena(0xff);      //interrupt enabled on PORTA
-    mcp23s17_2.gpintenb(0x00);      //interrupts disabled for address PORTB
+    wait_ms(1);
+    mcp23s17_2.gpintena(0xff);     //initially 0xff will be always enabled req/inc/dec/test
+    wait_ms(1);
+    mcp23s17_2.gpintenb(0x00);     //interrupts disabled for address PORT
+    wait_ms(1);
     mcp23s17_2.defvala(0xff);
+    wait_ms(1);
     mcp23s17_2.defvalb(0xff);
-    mcp23s17_2.intcona(0x2a);      //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed
-    mcp23s17_2.intconb(0x2a);
+    wait_ms(1);
+    mcp23s17_2.intcona(0x00);    //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed
+    wait_ms(1);
+    mcp23s17_2.intconb(0x00);
+    wait_ms(1);
     mcp23s17_2.gppua(0xff);
+    wait_ms(1);
     mcp23s17_2.gppub(0xff);
+    wait_ms(1);
+    mcp23s17_1.intcapa();    //dummy read performed to clear any interrupt on power up
+    wait_ms(1);
+    mcp23s17_1.intcapb();
+    wait_ms(1);
+    mcp23s17_2.intcapa();
+    wait_ms(1);
+    
 }
 
-void Spi2_Init()             // for max7219
+void Spi3_init()              //for mcp23s17
+{
+  _SPI3.format(8,0);         //8bit,mode 0
+  _SPI3.frequency(1000000);  //1mhz   
+  wait_ms(1);
+}
+
+void RTC_init()
 {
-       _SPI2.format(16,0);         //16bit,mode 0
-       _SPI2.frequency(1000000);  //1mhz
+    read_RTC();
+    wait_ms(1);
+    RTC_display(RTC_buffer);
+    wait_ms(1);
+}
+
+void SetDateTime
+(    int           year = 0
+    ,int           mon = 0
+    ,int           day = 0
+    ,int           hour = 0
+    ,int           min = 0
+    ,int           sec = 0
+)
+{
+    struct     tm Clock;
+    Clock.tm_year = year - 1900;
+    Clock.tm_mon  = mon;
+    Clock.tm_mday = day;
+    Clock.tm_hour = hour;
+    Clock.tm_min  = min;
+    Clock.tm_sec  = sec;
+    time_t epoch = mktime(&Clock);
+    set_time(epoch);                              //time set
 }
 
 void max7219_init()
 {
-    max7219.set_num_devices(2);                 //total 02 no. of devices which will drive 03 displays
-    max7219_configuration_t DEVICE1, DEVICE2;
-    DEVICE1.device_number = 1;
-    DEVICE1.decode_mode = 0xff;                 //bcd decode mode
-    DEVICE1.intensity = 8;                      //Max7219::MAX7219_INTENSITY_8,     //intensity moderate
-    DEVICE1.scan_limit = 8;                     // Max7219::MAX7219_SCAN_8, 8-digit scan driving two displays ds1 nd ds2
-      
-    DEVICE2.device_number = 2;
+    max7219.set_num_devices(2);                 //total 02 no. of devices
+    DEVICE1.device_number = 0x01;
+    DEVICE1.decode_mode = 0x00;                 //bcd decode mode
+    DEVICE1.intensity = 0x01;                   //Max7219::MAX7219_INTENSITY_8,
+    DEVICE1.scan_limit = 0x08;                  // 1-4 digits current CMD
+    wait_ms(1);
+    DEVICE2.device_number = 0x02;               //
     DEVICE2.decode_mode = 0xff;                 //bcd decode mode
-    DEVICE2.intensity = 8;                      //Max7219::MAX7219_INTENSITY_8,     //intensity moderate
-    DEVICE2.scan_limit = 4;                     //Max7219::MAX7219_SCAN_4, 4-digit scan driving one display
-    
+    DEVICE2.intensity = 0x01;                   //Max7219::MAX7219_INTENSITY_8,     //intensity moderate
+    DEVICE2.scan_limit = 0x04;                  //1-4 digits RTC,5-8 digits last cmd RPM
+    wait_ms(1);
+
     max7219.init_device(DEVICE1);               //DEVICE 1 configured as per above settings
-    max7219.enable_device(1);
+    wait_ms(1);
+    max7219.enable_device(1);                   //normal operation
+    wait_ms(1);
     max7219.init_device(DEVICE2);               //DEVICE 2 configured as per above settings
-    max7219.enable_device(2);
-    max7219.set_display_test();
+    wait_ms(1);
+    max7219.enable_device(2);                   //normal operation
+    wait_ms(1);
+    max7219.set_display_test();                  //all on
     wait(1);
-    max7219.clear_display_test();
-    for(uint8_t i=0; i<=07;i++)
+    max7219.clear_display_test();                //normal operation
+    wait_ms(1);
+    for(uint8_t i=0; i<=3;i++)
     {
-    max7219.write_digit(1, i+1, 0x01);   //device 1 cmd display, digit 0-7 ,data 0x01, ----, ---- on both displays
+        max7219.write_digit(1, i+1, 0x00);   //device 1 current cmd, digit 1-4 ,data 0x01
     }
-    
-    for(uint8_t i=0; i<=03;i++)
+    wait_ms(1);
+    for(uint8_t i=3; i<=7;i++)
     {
-    max7219.write_digit(1, i+1, 0x01);   //device 2 RTC display, digit 0-3 ,data 0x01, ---- on display
+        max7219.write_digit(1, i+1, 0x02);   //device 2 RTC, digit 1-4 ,data 0x01
     }
-}
-void Discrete_Init()
-{
-     buzzer = _ON;
-     hooter = _ON;             //on
-     wait(1);   // one second delay
-     buzzer = _OFF;
-     hooter = _OFF;              //off
+    wait_ms(100);
+    for(uint8_t i=0; i<=3;i++)
+    {
+        max7219.write_digit(2, i+1, 0x00);   //device 2 Last CMD, digit 4-8 ,data 0x01
+    }
+    wait_ms(100);
 }
 
-void Led_Init()
-{   
-    /* setting brightness as 50% duty cycle*/
-    
-    for(uint8_t i=0;i<=1;i++)                       //direction led initialisation  02 no.s
-    {
-        LED_DIR[i].set_Brightness(0.50);            //setting duty cycle 50%
-    }
-    for(uint8_t i=0;i<=1;i++)                       //ctrl led intialisation   02 no.s
-    {
-        LED_CTRL[i].set_Brightness(0.50);
-    }
-    for(uint8_t i=0; i<=7;i++)                      //ach led initialisation  08 no.s
-    { 
-        LED_ACH[i].set_Brightness(0.50);
-    }
-    
-    /* turning all leds ON*/
-    
-    for(uint8_t i=0;i<=1;i++)          
-    {
-        LED_DIR[i].ON();                 
-    }
-    for(uint8_t i=0;i<=1;i++)            
-    {
-        LED_CTRL[i].ON();
-    }
-    for(uint8_t i=0; i<=7;i++)           
-    {
-       LED_ACH[i].ON(); 
-    } 
-      
-    wait(1);                                   //wait for a 1 sec
-    
-    /* turning all leds OFF*/
-    
-    for(uint8_t i=0;i<=1;i++)          
-    {
-        LED_DIR[i].OFF();                 
-    }
-    for(uint8_t i=0;i<=1;i++)         
-    {
-        LED_CTRL[i].OFF();
-    }
-    for(uint8_t i=0; i<=7;i++)           
-    {
-       LED_ACH[i].OFF(); 
-    }   
+void Spi2_init()             // for max7219
+{
+       _SPI2.format(16,0);         //16bit,mode 0
+       _SPI2.frequency(1000000);  //1mhz
+       wait_ms(1);
 }
 
-void parameters_init()
+void Discrete_init()
+{
+     buzzer = ON;
+     hooter = ON;             //on
+     wait(1);   // one second delay
+     buzzer = OFF;
+     hooter = OFF;              //off
+}
+
+void Parameters_init()
 { 
     /*intialization of all bool data types indicating different error flags */     
     pot_Error = false;
-    spi_ERR = false;  
+    device_ERR = false;  
     pot_MCR_err = false;
     pot_ER_err = false;
-    test = false;                   
+    test = false; 
+    toggle = false;
+    toggle_fast = false;  
+    display_flash = false;   
+    norm_op = false;                    
     
     /*intialization of all bool data types indicating flag on key press interruption */
-    key_NUM = false;
+    key_CMD = false;
     key_CTRL = false;
-    key_DISP = false;
     key_SET = false;
-    
+    REQ_key = false;
+    ACK_key = false;
     RPM_cmd = false;              //if true RPM command is raised
     DIR_cmd = false;              //if true DIR command is raised
+    ENTER_ACK_key = false;
     
     /*intialization of all bool data types indicating flags while serial receive */ 
-    CMD_ack_rcvd = false;
+    RPM_cmd_ack = false;
     HB_ack_rcvd = false;
-    CMD_rcvd = false;
     BROADCAST_rcvd = false;
     HB_rcvd = false;
     REQ_rcvd = false;
     ACK_rcvd = false;
-    rcvd_DIR = false;
+    time_RCVD = false;
     
     /*intialization of all bool data types indicating flags while serial transmit */ 
     BROADCAST_send = false;
-    CMD_send = false;
+    RPM_cmd_ack_send = false;
+    DIR_cmd_ack_send = false;
     REQ_send = false;
     ACK_send = false;
     HB_send = false;
-    CMD_ack_send = false;
     
     /*intialization of all bool data types indicating active channel changeover*/
     test=false;
     ACH_SW_over = switch_CH = false;
     
-    _disp_FLASH = false;
+    display_flash = false;
     
     /*intialization of all int  data types*/
-    addr = req = ack = cmd = dir = last_cmd = ach_S = ach_M = brightness = 0;
+    addr = req = ack = ach_S = ach_M = duty_cycle = sync_count = 0;
     pot_Addr = addr_ID = send_ADDR = rcvd_ADDR = req_ADDR = ack_ADDR = 0;
-    test_cnt = err_ID = err_Status = 0;
-    spi_error = no_pot_connected = checksum =0;
+    test_cnt = err_ID = err_Status = ticker_count = ticker_count_fast  = current_status = current_status_dir= 0;
+    spi_error = set_bit = err_ALL = no_pot_connected = checksum = norm_count = Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0;
     HB_timer =0;
+    sync_time = 0;
+    num_bytes = 0;
 
     device_addr = -1;
     
-    digit_disp1 = 5;            //bcoz 5-1 = 4th digit is entered first
-    digit_disp2 = 0;
-    digit_disp3 = 0;
+    valid = 'V';
     
-    POT = new _POT[NO_MAX_POT];
+    POT = new  _POT[NO_MAX_POT];
 }
 
 void POT_INIT()
 {   
-    parameters_init();
-    Led_Init();
-    Discrete_Init();
-    //INT_Init();
-    Spi2_Init();
+    Parameters_init();
+    wait_ms(1);
+    
+    Discrete_init();
+    wait_ms(1);
+    
+    Spi2_init();
+    wait_ms(1);
+    
     max7219_init();
-    Spi3_Init();
+    wait_ms(1);
+    
+    SetDateTime(2017,11,16,16,45,40); // set default date and time
+    wait_ms(1);
+    
+    RTC_init();
+    wait_ms(1);
+    
+    Spi3_init();
+    wait_ms(1);
+    
     mcp23s17_init();
-    Uart_Init(); 
-    read_EOT_ADDR();
-    //config_EOT();
-    if(addr_ID == pot_Master)                               //if addres of master eot found, by default master
-    {      
-        int_A.rise(&read_KEY_A);                         //all key functions enabled for PORTA,B,C        
+    wait_ms(1);
+    
+    pwm_init();
+    wait_ms(1);
+    
+    Led_init();
+    wait_ms(1);
+    
+    Uart_init(); 
+    wait_ms(1);
+    
+    read_POT_ADDR();
+    wait_ms(1);
+    
+    interrupt_init();
+    wait_ms(1);
+    
+    if((addr_ID == pot_Master)&&(!pot_Error))                         //if addres of master eot found, by default master
+    {   
+        led_ach[ach_M-1] = ON;   
+        int_A.rise(&read_KEY_A);              //all key functions enabled for PORTA,B,C        
         int_B.rise(&read_KEY_B);                
-        int_C.rise(&read_KEY_C);     
-        HB_timer=(float)(1/no_pot_connected);
-      //  NVIC_SetPriority(UART2_IRQn,0);
-        pot_HB.attach(&HB_handler,HB_timer);                    //HB timer started
-        UART.attach( &read_SERIAL, UART.RxIrq);                 //receive interrupt enabled
+        int_C.rise(&read_KEY_C); 
+        wait_ms(2);
+        mcp23s17_1.gpintena(0xff);    //interrupts enabled
+        wait_us(100);
+        mcp23s17_1.gpintenb(0xff);    //ff
+        wait_us(100);
+        HB_timer = 1.0/no_pot_connected;
+        sync_time = 3600/HB_timer;                //   3600.0/HB_timer; required
+        pot_HB.attach(&HB_handler,HB_timer);    //
+        wait_ms(1);
+        UART.attach( &read_SERIAL);    //receive interrupt enabled
+        wait_ms(1);
+        ask_TIME();                    //send enquiry to Central power unit for time setting
+        wait_ms(2);
+        send_ACH();
+        wait_ms(2);
     }
-    else 
-    { 
-        if(pot_Submaster <= addr_ID <= pot_Listner_ASP)
-        {
-            int_A.rise(NULL);                                      //all key functions/interrupt disabled for PORTA & B     
-            int_B.rise(NULL);            
-            int_C.rise(&read_KEY_C);                               //only PORTC needs to be intialized in other all cases req,inc,dec,tst
-            UART.attach( &read_SERIAL, UART.RxIrq);                //receive interrupt enabled
-        }
-        else
-        {
-            int_A.rise(NULL);
-            int_B.rise(NULL);
-            int_C.rise(NULL);
-            pot_Error = true;
-            //return(-1);
-        }   
+    else if(pot_Submaster <= addr_ID <= pot_Listner_ASP)
+    {
+        int_A.rise(NULL);          //all key functions/interrupt disabled for PORTA,B       
+        int_B.rise(NULL);
+        int_C.rise(&read_KEY_C);   //only PORTC needs to be intialized in other all cases,inc,dec,tst,req
+        wait_ms(1);
+        UART.attach( &read_SERIAL);    //receive interrupt enabled
+        wait_ms(1);
+    }
+    else if(pot_Error)
+    {
+        int_A.rise(NULL);
+        int_B.rise(NULL);
+        int_C.rise(NULL);
+        pot_Error = true;
+        //return(-1);
+    }   
+    else
+    {
+        __nop();
     }
 }
 
 int main()
 {
     POT_INIT();
+    
+    led_refresh.attach(&update_led , 0.020);   
+    wait_ms(2);
+    
+    RTC_ticker.attach(&read_RTC , 59);   //after 60 sec
+    wait_ms(2);
+    
     while(1) 
     {
     }