direction commands updated to Up down RPM value

Dependencies:   MAX7219pot MCP23S17 mbed

Fork of POT_V_1_0 by Marine Electricals

Revision:
0:ba33a62aea4e
Child:
1:e116808d8b00
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Sep 28 05:10:42 2017 +0000
@@ -0,0 +1,1664 @@
+#include "mbed.h"
+
+#include "mbed.h"
+#include "pot.h"
+#include "max7219.h"
+#include "MCP23S17.h"
+
+using namespace std;
+
+//------------------------------------
+// Hyperterminal configuration
+// 9600 bauds, 8-bit data, no parity
+//------------------------------------
+Serial UART(SERIAL_TX, SERIAL_RX); 
+
+//timer instances creation//
+Ticker pot_HB;              
+Ticker HB_Ticker;
+Ticker flash_Ticker;
+Ticker R_A_Ticker;
+Ticker CMD_Ticker;
+Ticker disp_FLASH;                   //display blink
+Ticker DIR_Ticker;
+
+//SPI instances creation//
+SPI _SPI2(SPI2_MOSI, SPI2_MISO, SPI2_SCK);  //for displays max7219
+SPI _SPI3(SPI3_MOSI, SPI3_MISO, SPI3_SCK);  //for keyscan  mcp23s17
+
+
+//class object instances for key I/O expander and segment driver//
+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
+
+//interrupts definations
+InterruptIn int_A(INT_A);       //8commands
+InterruptIn int_B(INT_B);       //4  3commands+1ack
+InterruptIn int_C(INT_C);       //4(3 controls(INC+,DEC-,TEST)+1 req) enbaled for all
+
+//chip select definations for max7219 & mcp23s17 as digitalout pins//
+DigitalOut cs_disp1(SPI2_CS1);   
+DigitalOut cs_disp2(SPI2_CS2);   //max7219
+DigitalOut cs_key1(SPI3_CS1);    
+DigitalOut cs_key2(SPI3_CS2);    //mcp23s17
+
+DigitalOut Drive_En(Tx_EN);      //uart driver enable
+
+//discrete outputs definations buzzer and hooter
+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
+
+float brightness;
+
+uint8_t spi_error,no_pot_connected;
+
+char pot_Addr,addr_ID,checksum;
+
+float HB_timer;
+
+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 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;
+
+/**************************************************************************************
+ EOT LED CLASS
+ **************************************************************************************/
+class LED{
+public:
+    LED(PinName led);                                 //constructor declaration
+    void set_Brightness(float bright);
+    void ON();
+    void OFF();
+    void FLASHH();
+private:
+    Ticker _flash;
+    bool on_off;
+    bool Fllash;
+    float brightness;
+    PwmOut _LED;    
+    void __flash();
+};
+LED::LED(PinName led): _LED(led)                         //constructor defination
+{
+    brightness = 0.000;
+    on_off = false;
+    Fllash = false;
+    _LED = brightness;
+}
+
+void LED::set_Brightness(float bright)
+{
+    brightness = bright;
+    if(!Fllash)
+        _LED = bright;
+    else
+        __nop();
+}
+
+void LED::ON()
+{
+    _LED = brightness;
+    Fllash = false;
+    _flash.detach();
+}
+
+void LED::OFF()
+{
+    _LED = 0;
+    Fllash = false;
+    _flash.detach();
+}
+
+void LED::FLASHH()
+{
+    Fllash = true;
+    _flash.attach(callback(this, &LED::__flash),0.5);
+}
+
+void LED::__flash()
+{
+    if(on_off)
+        _LED = brightness;
+    else
+        _LED = 0;
+    
+    on_off = !on_off;
+}
+/**************************************************************************************
+ EOT LED CLASS END
+ **************************************************************************************/
+//array of objects/instances of class LED & PwmOut//
+LED LED_DIR[2] = {_AHEAD,_ASTERN};                            // direction control
+LED LED_CTRL[2] = {_REQ,_ACK};                                 //transfer control
+LED LED_ACH[8] =  {_WH,_BRDG,_MCR,_ER,_WP,_WS,_OPS,_ASP};      //active channels
+
+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
+}; 
+_POT* POT=NULL; 
+
+enum AddrID
+{
+    pot_Master = 1,
+    pot_Submaster,
+    pot_Slave_MCR,
+    pot_Slave_ER,
+    pot_Listner_WP,
+    pot_Listner_WS,
+    pot_Listner_OPS,
+    pot_Listner_ASP = 8
+};
+
+enum pin_STATUS
+{
+    _OFF =0,
+    _ON =1
+};
+
+enum KEY
+{
+        ZERO = 0,
+        ONE,
+        TWO,
+        THREE,
+        FOUR,
+        FIVE,
+        SIX,
+        SEVEN,
+        EIGHT,
+        NINE,
+        FALSE0 = 10
+};
+enum KEY num_KEY; 
+
+enum CTRL
+{
+    REQ_ = 1,
+    ACK_ = 2,
+    FALSE1= 3
+    
+};
+enum CTRL ctrl_KEY; 
+
+enum direction_KEY
+{
+    AHEAD = 1,
+    ASTERN,
+    FALSE2 = 3
+};
+enum direction_KEY dir_KEY;
+
+enum display_KEY
+{
+    clr_ENTRY = 0,           //CE
+    last_ENTRY,              //C
+    ENTER_ACK,               //enter in case of master and ACK in case of slaves/repeaters
+    FALSE3 = 3
+};
+enum display_KEY disp_KEY;
+
+enum SET
+{
+    INC=0,
+    DEC,
+    TEST,
+    FALSE4 = 4
+};
+enum SET set_KEY; 
+
+enum CHANNEL
+{ 
+    ch_A=1,
+    ch_B,
+    ch_C,
+    ch_D=4
+};          //keyscan channelA,B,C,Dof MCP23s17 1& 2 respectively
+enum CHANNEL ch;
+
+enum ack_dir_rpm
+{
+    _RPM = 1,
+    _DIR = 2
+};
+
+/**************************************************************************************
+ EOT display update FUNCTIONS
+ **************************************************************************************/
+void display_update(bool RTC_disp, char* digits)
+{
+    if(RTC_disp)
+    {
+        for(uint8_t i = 0; i <= 3; i++)              //to write all the four digits
+        {
+            max7219.write_digit(2, 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(1, i+1, *(digits+i));   //device 1, digit 1-4 ,data pointer
+        }
+    }
+}
+
+/**************************************************************************************
+ EOT 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)
+    {
+        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;
+        hb_state_cnt = 0;
+        if(POT[device_addr].slave_ID == ach_S)
+            LED_ACH[send_ADDR - 1].ON();
+        else
+            LED_ACH[send_ADDR - 1].OFF();
+    }
+    else
+    {
+        if(++hb_state_cnt >= 5)                         //50ms
+        {
+            if((++POT[device_addr].err_cnt >= 3) && (!POT[device_addr].c_err))         //hb ack not received in third attempt
+            {
+                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;
+                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))
+                {
+                    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;
+                }
+                else
+                    pot_Error = false; 
+            }
+        }
+            hb_state_cnt=0;
+           // pot_MCR_err = false;
+           // pot_ER_err = false;
+            err_Status = 0;      // no communication error
+            HB_Ticker.detach();
+        }
+    }    
+}
+
+void CMD_State_Machine()                         //function run periodcally in all connected devices on bus
+{
+    int cmd_state_cnt=0;
+        
+    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;
+        cmd_state_cnt = 0;
+        RPM_cmd_ack = false;
+        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(hooter == _OFF)              //if hooter still off
+        {
+            if(++cmd_state_cnt >= 12)                       //Hotter ON after 3sec
+            {
+                hooter = _ON;
+               /* if(++cmd_state_cnt >= 96)                     //still command ack not recived for 24 sec
+                {
+                    LED_CMD[cmd].OFF();                //command suspended
+                    buzzer = OFF;
+                    hooter = OFF;
+                    int_A.rise(NULL);
+                    int_A.rise(NULL);
+                    CMD_ticker.detach();           //timer stoped in all connected devices if ack not received in 3sec
+                } */
+            }
+            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)
+    {
+        //req_ADDR = rcvd_ADDR;
+        REQ_rcvd = false;
+    }
+    
+    if(++state_cnt >= 10)             //REQ not acknowledged for 5 sec, leds turn off, timer stopped
+    {
+        R_A_Ticker.detach();
+        LED_CTRL[REQ_-1].OFF();
+        LED_CTRL[ACK_-1].OFF();
+    }
+    else
+    {
+        if(ACH_SW_over)               //active channel switchover true only after acknowledge receive
+        {
+            ACH_SW_over = false;
+            if(addr_ID == pot_Master)
+            {
+                if(ack_ADDR == 3 || ack_ADDR == 4)
+                {
+                    if(ach_S == pot_Slave_MCR)
+                        ach_S = pot_Slave_ER;
+                    else if(ach_S == pot_Slave_ER)
+                        ach_S = pot_Slave_MCR;
+                }
+                else 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;
+                }
+                switch_CH = true;
+                state_cnt = 0;
+                R_A_Ticker.detach();
+            }
+            else
+            {
+                state_cnt = 0;
+                R_A_Ticker.detach();
+            }
+        }
+    }
+}
+
+void DIR_Statemachine(void)
+{
+    static int dir_state_cnt = 0;
+    if(DIR_cmd_ack)
+    {
+        DIR_cmd_ack = false;
+        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
+            {
+                hooter = _ON;
+                dir_state_cnt = 0;
+            }
+        else
+            __nop();
+    }
+    
+}
+
+
+void DISP_FLASH(void)                                             //function attached to event driven ticker disp_FLASH
+{
+    _disp_FLASH = !_disp_FLASH;
+    if(_disp_FLASH)
+        max7219.disable_device(1);
+    else
+        max7219.enable_device(1);
+}
+
+void NUMERIC_handler(uint8_t key_ID)                             //function sacnning all the 0-9 number keys
+{  
+    uint8_t num;
+    num = key_ID;
+    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                        
+        }
+        else
+            __nop();
+        }
+    else
+        __nop();
+    }
+}
+
+void CTRL_handler(uint8_t CTRL_ID)                        //handle  control transfer 
+{
+    if(CTRL_ID != FALSE1)
+    {
+        if((addr_ID == pot_Slave_MCR) || (addr_ID == pot_Slave_ER))
+        {
+            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
+                R_A_Ticker.attach(&R_A_Statemachine,0.5);
+            }
+            if(CTRL_ID == ACK_ && REQ_rcvd)
+            {
+                ack = ACK_;                     //ack data updated 2 here
+                LED_CTRL[ACK_-1].OFF();                  //ack led turns off
+                R_A_Ticker.detach();
+            }
+        }
+    }
+    else 
+        __nop(); //then do nothing
+}
+
+void DIR_handler(uint8_t DIR_ID)                        //handle  control transfer 
+{
+    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)
+            {
+                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 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(); //then do nothing
+}
+
+void DISP_handler(uint8_t DISP_ID)                        //handle  control transfer 
+{
+    uint8_t disp_key;
+    disp_key = DISP_ID;
+    if(DISP_ID != FALSE3)
+    {
+        if((addr_ID == ach_M)||(addr_ID == ach_S)) 
+        {
+            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)
+                    {
+                        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
+                        }
+                    }
+                    else
+                    {
+                        __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
+                        }
+                    }
+                    else
+                    {
+                        __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
+                    }
+                    else
+                    {
+                        __nop();
+                    }
+                break;
+                
+                default:
+                
+                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);
+    }
+}
+
+void SET_handler(uint8_t Set_ID)
+{
+    if(Set_ID != FALSE4)
+    {
+        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)
+        {
+            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;
+            }
+        }
+    }
+    else
+        __nop();
+}
+
+
+
+
+/**************************************************************************************
+ EOT 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;
+        }
+        break;
+        
+        case 2:
+        if(spi_err<3)
+        {
+            _key=mcp23s17_1.intcapb();
+            if(mcp23s17_1.intcapb())             //if Interrupt pending
+                {
+                    spi_err++;
+                }
+            else
+                {
+                    spi_err=0;
+                }
+        }
+        else
+        {   
+            _key=0;
+            spi_ERR=true;
+        }
+        break;
+        
+        case 3:
+        if(spi_err<3)
+        {
+            _key=mcp23s17_2.intcapa();
+            if(mcp23s17_2.intcapa())            //if Interrupt pending
+                {
+                    spi_err++;
+                }
+            else
+                {
+                    spi_err=0;
+                }
+        }
+        else
+        {   
+            _key=0;
+            spi_ERR=true;
+        }
+        break;
+        
+        case 4:
+        _key = mcp23s17_2.gpiob(); //address read PORTB of chip2 for getting pot addresses
+        break;
+        default:
+        _key = 0;
+        break;
+    }
+    return(_key);
+}
+void read_KEY_A()                      //function check status of PORTA of MCP23S17 (1) chip
+{
+    char key_status = 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
+    {
+        switch(key_status)
+        {
+            case 0xfe:               //0xfe  GPA0
+                num_KEY = ZER0;
+            break;
+            case 0xfd:               //0xfd  GPA1
+                num_KEY = ONE;
+            break;
+            case 0xfb:               //0xfb  GPA2
+                num_KEY = TWO;
+            break;
+            case 0xf7:               //0xf7  GPA3
+                num_KEY = THREE;
+            break;
+            case 0xef:               //0xef  GPA4
+                num_KEY = FOUR;
+            break;
+            case 0xdf:               //0xdf  GPA5
+                num_KEY = FIVE;
+            break;
+            case 0xbf:               //0xbf  GPA6
+                num_KEY = SIX;
+            break;
+            case 0x7f:               //0x7f  GPA7
+                num_KEY = SEVEN;
+            break;
+            default:
+                num_KEY = FALSE0;
+            break;
+        }
+        NUMERIC_handler(num_KEY);
+    }
+}
+
+void read_KEY_B()
+{
+    char key_status = 0;
+    key_status = read_KEY_SPI(ch_B);   //to read portBof mcp23s17(1)
+    if(key_status != 0xff)
+    {   
+        switch(key_status)
+        {
+            case 0xfe:               //0xfe  GPA0
+                num_KEY = EIGHT;
+                NUMERIC_handler(num_KEY);
+            break;
+            case 0xfd:               //0xfd  GPA1
+                num_KEY = NINE;
+                NUMERIC_handler(num_KEY);
+            break;
+            case 0xfb:               //0xfb  GPA2
+                dir_KEY = AHEAD;
+                DIR_handler(dir_KEY);
+            break;
+            case 0xf7:               //0xf7  GPA3
+                dir_KEY = ASTERN;
+                DIR_handler(dir_KEY);
+            break;
+            case 0xef:               //0xef  GPA4
+                ctrl_KEY = ACK;
+                CTRL_handler(ctrl_KEY);
+            break;
+            case 0xdf:               //0xdf  GPA5
+                disp_KEY = clr_ENTRY;               //CE
+                DISP_handler(disp_KEY);
+            break;
+            case 0xbf:               //0xbf  GPA6
+                disp_KEY = last_ENTRY;             //C
+                DISP_handler(disp_KEY);
+            break;
+            case 0x7f:               //0x7f  GPA7
+                disp_KEY = ENTER_ACK;
+                DISP_handler(disp_KEY);
+            break;
+            default:
+                num_KEY = FALSE0;
+                ctrl_KEY = FALSE1;
+                dir_KEY = FALSE2;
+                disp_KEY = FALSE3;
+            break;
+        }
+    }
+}
+void read_KEY_C()
+{
+    char key_status = 0;
+    key_status = read_KEY_SPI(ch_C);   //to read portA of mcp23s17(2)
+    if(key_status != 0xff)
+    {
+        if(key_status==0xfe)
+        {
+            ctrl_KEY  = REQ_;                    //control transfer REQ button pressed
+            CTRL_handler(ctrl_KEY);
+        }
+        else
+        {
+            if(key_status==0xfd)
+                set_KEY = INC;                     //setting key INC
+            else if(key_status==0xfb)
+                set_KEY = DEC;                      //setting key DEC
+            else if(key_status==0xf7)
+                set_KEY = TEST;                       //setting key TEST
+            else 
+            {
+                set_KEY = FALSE4;                       //setting key TEST
+                ctrl_KEY = FALSE1;
+            }
+            
+            SET_handler(set_KEY);
+        }
+    }
+}
+
+
+/**************************************************************************************
+EOT Serial Data Out FUNCTIONS
+ **************************************************************************************/
+uint8_t get_checksum(const char *sentence)
+{
+    const char *n = sentence + 1; // Plus one, skip '$'
+    uint8_t chk = 0;
+
+    /* While current char isn't '*' or sentence ending (newline) */
+    while ('*' != *n && NMEA_END_CHAR_1 != *n) 
+    {
+        if ('\0' == *n || n - sentence > NMEA_MAX_LENGTH) 
+        {
+            /* Sentence too long or short */
+            return 0;
+        }
+        chk ^= (uint8_t) *n;
+        n++;
+    }
+
+    return chk;
+}
+
+void resp_HB(uint8_t seq)      //presentees(submaster,slaves,listeners will respond back to the HB along with REQ and CMD ack status
+{
+    switch(seq)
+    {
+        case 0:
+            sprintf(key,"$PEOTA,%u,%c*", addr_ID, *valid);
+        break;
+        case 1:
+            sprintf(key,"$PEOTR,%u,%u,%c*", addr_ID, req, *valid);
+        break;
+        case 2:
+            sprintf(key,"$PEOTK,%u,%u,%c*", addr_ID, ack, *valid);
+        break;
+        default:
+            sprintf(key,"$PEOTA,%u,%c*", addr_ID, *valid);
+        break;
+    }
+    checksum=get_checksum(key);                
+    sprintf(key,"%u\r\n",checksum);              
+    UART.printf("%s",key);
+}
+
+void send_ack_CMD(uint8_t _adr, uint8_t x)
+{
+    sprintf(key,"$PEOTX,%u,%u,%c*", _adr, x, *valid);
+    checksum=get_checksum(key);                
+    sprintf(key,"%u\r\n",checksum);              
+    UART.printf("%s",key);
+}
+
+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_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);
+}
+
+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);
+}
+
+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);
+    BROADCAST_send=false;
+}
+
+void send_ACH()
+{
+    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);
+}
+
+
+/**************************************************************************************
+ EOT Serial Data In FUNCTIONS
+ **************************************************************************************/
+void rcvd_HB()      //master check HB  along with req response for all presentees
+{
+    if(rcvd_ADDR == addr_ID)             //self address received
+    {           
+        if(addr_ID > pot_Slave_ER)
+        {                            //if no req
+            resp_HB(0);                  //normal HB response
+        }
+        else
+        {
+            if(req)
+            {
+                resp_HB(1);                 //req and ack status data in req=1 and ack=2 if true
+                req = 0;
+            }
+            else if(ack)
+            {
+                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
+        }
+    }
+    else
+      __nop(); 
+}
+
+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(send_ADDR == rcvd_ADDR)
+            HB_ack_rcvd = true;
+        else
+            HB_ack_rcvd = false;       
+    }
+    else
+        __nop();
+}
+
+void rcvd_rpm_CMD()         //all devices check for received command
+{
+    for(uint8_t i = 0; i >= 3 ; i--)
+    {
+        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 == 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
+    }
+    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
+}
+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 
+    if(ach_S == addr_ID)
+    {       
+        int_B.rise(&read_KEY_B);                      //enable keys bcoz ahead/astern keys co-grouped to PORTB of mcp23s17(1)
+    }
+}
+
+void rcvd_BROADCAST()
+{
+    if(err_Status==1)                       //err non zero
+    {
+        LED_ACH[err_ID].FLASHH();
+    }
+    else
+    {
+        LED_ACH[err_ID].OFF();
+    }
+    
+}
+
+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 *//
+    {
+        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();
+        }
+        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)
+        {
+            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))
+            {
+                LED_CTRL[ACK_-1].FLASHH();        //ack led blink
+            }
+            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].FLASHH();        //ack led blink
+            }
+            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
+                __nop();
+        }
+        else
+            __nop();
+    }
+}
+
+/**************************************************************************************
+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(ach_M == eot_Master)
+        {   
+            device_addr++;
+            if(device_addr >= no_eot_connected)
+            device_addr = 0;
+        }
+        else
+        __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(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             
+        }
+        else if(DIR_cmd)
+        {
+           send_CMD(send_ADDR);
+           HB_Ticker.attach(&HB_State_Machine,0.010);
+           DIR_Ticker.attach(&DIR_State_Machine,0.25); 
+        }
+        else if(BROADCAST_send)
+        {
+            send_BROADCAST();                                             //broadcast needed err_ID nd err_Status
+            BROADCAST_send = false;
+        }
+        else if(switch_CH)                                                //active channel switch over happened
+        {
+            send_ACH();                                                   //active channel changeover
+            switch_CH = false;
+        }
+        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
+        }
+    }
+    else
+        __nop();
+}
+
+
+
+/**************************************************************************************
+EOT config 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)
+    {
+        for( uint8_t i=0;i<=7;i++)
+        {
+            if(((1 << i) & pot_Addr)== 0)      // to check which bit of eot_Addr register is '0'
+            {
+                if(i==0)                       // bit 0 means master present and soon
+                {   
+                    addr_ID = pot_Master;
+                    ach_M = pot_Master;
+                    for(i = 1 ; i <= 7 ; i++)
+                    {
+                        if((((uint8_t)1<<i) & pot_Addr) == 0)
+                        {
+                            switch(i)
+                            {
+                                case 1:
+                                    POT[no_pot_connected].slave_ID = pot_Submaster;
+                                    POT[no_pot_connected].err_cnt=0;
+                                    no_eot_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;
+                                    no_pot_connected++;
+                                break;
+                                case 3:
+                                    if(ach_S == pot_Slave_MCR)                 //if MCR ispresent
+                                        __nop();
+                                    else
+                                    {                                            //if MCR is not present
+                                        ach_S = pot_Slave_ER;
+                                    }                                     
+                                    POT[no_pot_connected].slave_ID = pot_Slave_ER;
+                                    POT[no_pot_connected].err_cnt = 0;
+                                    no_pot_connected++;
+                                break;
+                                case 4:
+                                    POT[no_pot_connected].slave_ID = pot_Listner_WP;
+                                    POT[no_pot_connected].err_cnt = 0;
+                                    no_pot_connected++;
+                                break;
+                                case 5:
+                                    POT[no_pot_connected].slave_ID = pot_Listner_WS;
+                                    POT[no_pot_connected].err_cnt=0;
+                                    no_pot_connected++;
+                                break;
+                                case 6:
+                                    POT[no_pot_connected].slave_ID = pot_Listner_OPS;
+                                    POT[no_pot_connected].err_cnt=0;
+                                    no_pot_connected++;
+                                break;
+                                case 7:
+                                    POT[no_pot_connected].slave_ID = pot_Listner_ASP;
+                                    POT[no_pot_connected].err_cnt=0;       
+                                    no_pot_connected++;
+                                break;
+                            }
+                        }
+                    }    
+                }
+                else
+                {
+                    switch(i)
+                    {
+                        case 1:
+                        {
+                            addr_ID = pot_Submaster;
+                            break;
+                        }
+                        case 2:
+                        {
+                            addr_ID = pot_Slave_MCR;
+                            break;
+                        }
+                        case 3:
+                        {
+                            addr_ID = pot_Slave_ER;
+                            break;
+                        }
+                        case 4:
+                        {
+                            addr_ID = pot_Listner_WP;
+                            break;
+                        }
+                        case 5:
+                        {
+                            addr_ID = pot_Listner_WS;
+                            break;
+                        }
+                        case 6:
+                        {
+                            addr_ID = pot_Listner_OPS;
+                            break;
+                        }
+                        case 7:
+                        {
+                            addr_ID = pot_Listner_ASP;
+                            break;
+                        }
+                        default:
+                            pot_Error = true;
+                    }   
+                }
+            }
+        }
+    }
+}
+
+void Uart_Init()
+{                                     //buffer initialisation
+  Serial UART(SERIAL_TX, SERIAL_RX);
+  UART.baud(9600);
+  UART.format(8,SerialBase::None,1);
+  //UART.attach( &read_SERIAL, UART.RxIrq);    //receive interrupt enabled
+}
+
+
+void Spi3_Init()              //for mcp23s17
+{
+  _SPI3.format(8,0);         //8bit,mode 0
+  _SPI3.frequency(1000000);  //1mhz   
+}
+
+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.ipola(0x00);
+    mcp23s17_1.ipolb(0x00);
+    mcp23s17_1.gpintena(0xff);      //interrupt enabled on PORTA
+    mcp23s17_1.gpintenb(0xff);      //interrupt enabled on PORTB
+    mcp23s17_1.defvala(0xff);
+    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);
+    mcp23s17_1.gppua(0xff);
+    mcp23s17_1.gppub(0xff);
+    
+    //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.ipola(0x00);
+    mcp23s17_2.ipolb(0x00);
+    mcp23s17_2.gpintena(0xff);      //interrupt enabled on PORTA
+    mcp23s17_2.gpintenb(0x00);      //interrupts disabled for address PORTB
+    mcp23s17_2.defvala(0xff);
+    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);
+    mcp23s17_2.gppua(0xff);
+    mcp23s17_2.gppub(0xff);
+}
+
+void Spi2_Init()             // for max7219
+{
+       _SPI2.format(16,0);         //16bit,mode 0
+       _SPI2.frequency(1000000);  //1mhz
+}
+
+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;
+    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
+    
+    max7219.init_device(DEVICE1);               //DEVICE 1 configured as per above settings
+    max7219.enable_device(1);
+    max7219.init_device(DEVICE2);               //DEVICE 2 configured as per above settings
+    max7219.enable_device(2);
+    max7219.set_display_test();
+    wait(1);
+    max7219.clear_display_test();
+    for(uint8_t i=0; i<=07;i++)
+    {
+    max7219.write_digit(1, i+1, 0x01);   //device 1 cmd display, digit 0-7 ,data 0x01, ----, ---- on both displays
+    }
+    
+    for(uint8_t i=0; i<=03;i++)
+    {
+    max7219.write_digit(1, i+1, 0x01);   //device 2 RTC display, digit 0-3 ,data 0x01, ---- on display
+    }
+}
+void Discrete_Init()
+{
+     buzzer = _ON;
+     hooter = _ON;             //on
+     wait(1);   // one second delay
+     buzzer = _OFF;
+     hooter = _OFF;              //off
+}
+
+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 parameters_init()
+{ 
+    /*intialization of all bool data types indicating different error flags */     
+    pot_Error = false;
+    spi_ERR = false;  
+    pot_MCR_err = false;
+    pot_ER_err = false;
+    test = false;                   
+    
+    /*intialization of all bool data types indicating flag on key press interruption */
+    key_NUM = false;
+    key_CTRL = false;
+    key_DISP = false;
+    key_SET = false;
+    
+    RPM_cmd = false;              //if true RPM command is raised
+    DIR_cmd = false;              //if true DIR command is raised
+    
+    /*intialization of all bool data types indicating flags while serial receive */ 
+    CMD_ack_rcvd = false;
+    HB_ack_rcvd = false;
+    CMD_rcvd = false;
+    BROADCAST_rcvd = false;
+    HB_rcvd = false;
+    REQ_rcvd = false;
+    ACK_rcvd = false;
+    rcvd_DIR = false;
+    
+    /*intialization of all bool data types indicating flags while serial transmit */ 
+    BROADCAST_send = false;
+    CMD_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;
+    
+    /*intialization of all int  data types*/
+    addr = req = ack = cmd = dir = last_cmd = ach_S = ach_M = brightness = 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;
+    HB_timer =0;
+
+    device_addr = -1;
+    
+    digit_disp1 = 5;            //bcoz 5-1 = 4th digit is entered first
+    digit_disp2 = 0;
+    digit_disp3 = 0;
+    
+    POT = new _POT[NO_MAX_POT];
+}
+
+void POT_INIT()
+{   
+    parameters_init();
+    Led_Init();
+    Discrete_Init();
+    //INT_Init();
+    Spi2_Init();
+    max7219_init();
+    Spi3_Init();
+    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        
+        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
+    }
+    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);
+        }   
+    }
+}
+
+int main()
+{
+    POT_INIT();
+    while(1) 
+    {
+    }
+}