direction commands updated to Up down RPM value

Dependencies:   MAX7219pot MCP23S17 mbed

Fork of POT_V_1_0 by Marine Electricals

main.cpp

Committer:
viewdeep51
Date:
2017-09-28
Revision:
0:ba33a62aea4e
Child:
1:e116808d8b00

File content as of revision 0:ba33a62aea4e:

#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) 
    {
    }
}