/*
 * master_slave.c
 *
 *  Created on: 13 нояб. 2024 г.
 *      Author: Evgeniy_Sokolov
 */

#include <edrk_main.h>

#include <params.h>
#include <params_alg.h>
#include <params_norma.h>
#include <params_pwm24.h>
#include <params_temper_p.h>
#include <project.h>
#include "IQmathLib.h"
#include "mathlib.h"
#include <optical_bus.h>
#include "synhro_tools.h"
#include "master_slave.h"

//////////////////////////////////////////////////////////

#pragma DATA_SECTION(buf_log_master_slave_status,".slow_vars");
unsigned int buf_log_master_slave_status[SIZE_LOG_MASTER_SLAVE_STATUS] = {0};
//AUTO_MASTER_SLAVE_DATA buf2[SIZE_BUF1] = {0};
//AUTO_MASTER_SLAVE_DATA buf3[SIZE_BUF1] = {0};
//OPTICAL_BUS_DATA_LOW_CMD buf4[SIZE_BUF1] = {0};
//OPTICAL_BUS_DATA_LOW_CMD buf5[SIZE_BUF1] = {0};


//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////

void auto_select_master_slave(void)
{
    static unsigned int count_try_master = 0;
    static unsigned int count_wait_answer_confirm_mode = 0;
    static unsigned int count_wait_slave_try_master = 0;
    unsigned int err_confirm_mode = 0; // ошибка подтверждения режима другим ПЧ
    static unsigned int c_buf_log_master_slave_status = 0, prev_status = 0;



// logs master_slave_status
    if (edrk.auto_master_slave.status != prev_status)
    {
        c_buf_log_master_slave_status++;
        if (c_buf_log_master_slave_status>=SIZE_LOG_MASTER_SLAVE_STATUS)
            c_buf_log_master_slave_status = 0;
        buf_log_master_slave_status[c_buf_log_master_slave_status] = edrk.auto_master_slave.status;
    }
    prev_status = edrk.auto_master_slave.status;
//end logs master_slave_status

    if (edrk.ms.ready2==0 && edrk.errors.e7.bits.AUTO_SET_MASTER==0)
    {
        edrk.auto_master_slave.remoute.all = 0;
        edrk.auto_master_slave.local.all = 0;
        edrk.auto_master_slave.prev_remoute.all = edrk.auto_master_slave.remoute.all;
        edrk.auto_master_slave.prev_local.all = edrk.auto_master_slave.local.all;

        edrk.auto_master_slave.status = 1;

//        if (prev_ready!=edrk.ms.ready2)
//            for (c_buf=0;c_buf<SIZE_BUF1;c_buf++)
//            {
//                buf2[c_buf].all = buf3[c_buf].all = buf1[c_buf] = buf4[c_buf].all = buf5[c_buf].all =0;
//            }
//
//        c_buf = 0;
//
//        prev_ready = edrk.ms.ready2;
        clear_wait_synhro_optical_bus();


        return;
    }
//    else
//        prev_ready = edrk.ms.ready2;


    if (edrk.errors.e7.bits.AUTO_SET_MASTER)
    {
        edrk.to_second_pch.bits.MASTER = edrk.auto_master_slave.local.bits.master;

        edrk.auto_master_slave.local.bits.master = 0;
        edrk.auto_master_slave.local.bits.slave  = 0;
        edrk.auto_master_slave.local.bits.try_master = 0;
        edrk.auto_master_slave.local.bits.try_slave = 0;
        edrk.auto_master_slave.local.bits.nothing = 1;


//        edrk.auto_master_slave.prev_remoute.all = edrk.auto_master_slave.remoute.all;
//        edrk.auto_master_slave.prev_local.all = edrk.auto_master_slave.local.all;

 //       edrk.auto_master_slave.status = 10;


        return;
    }

    edrk.auto_master_slave.prev_status = edrk.auto_master_slave.status;

//    c_buf++;
//    if (c_buf>=SIZE_BUF1)
//        c_buf = 0;
//
//    buf1[c_buf] = edrk.auto_master_slave.status;
//    buf2[c_buf].all = edrk.auto_master_slave.local.all;
//    buf3[c_buf].all = edrk.auto_master_slave.remoute.all;
//    buf4[c_buf].all = optical_read_data.data.cmd.all;
//    buf5[c_buf].all = optical_write_data.data.cmd.all;
//

    // сбросим счетчик времени перехода на мастер
    if (edrk.auto_master_slave.local.bits.try_master==0 ||
         (edrk.auto_master_slave.prev_local.bits.try_master != edrk.auto_master_slave.local.bits.try_master && edrk.auto_master_slave.local.bits.try_master==1))
        count_try_master = 0;

    // если шина OPTICAL_BUS сдохла, выходим
    if (edrk.errors.e7.bits.WRITE_OPTBUS==1 || edrk.errors.e7.bits.READ_OPTBUS==1 ||
            edrk.warnings.e7.bits.WRITE_OPTBUS==1 || edrk.warnings.e7.bits.READ_OPTBUS==1)
    {

        if (edrk.errors.e7.bits.WRITE_OPTBUS==1 || edrk.errors.e7.bits.READ_OPTBUS==1)
        {
            // шина не работает, и тот ПЧ включен
            // значит что-то случилось - выключаемся

            edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;

            edrk.auto_master_slave.remoute.bits.nothing = 1;
            edrk.auto_master_slave.remoute.bits.master  = 0;
            edrk.auto_master_slave.remoute.bits.slave   = 0;
            edrk.auto_master_slave.remoute.bits.try_master = 0;
            edrk.auto_master_slave.remoute.bits.try_slave = 0;


            edrk.auto_master_slave.local.bits.master = 0;
            edrk.auto_master_slave.local.bits.slave  = 0;
            edrk.auto_master_slave.local.bits.try_master = 0;
            edrk.auto_master_slave.local.bits.try_slave = 0;
            edrk.auto_master_slave.local.bits.nothing = 1;

            edrk.auto_master_slave.status = 10;
        }
        else
        {
            // шина не работает, и тот ПЧ выключен
            // значит мы сразу мастер
            edrk.warnings.e7.bits.AUTO_SET_MASTER = 1;

            edrk.auto_master_slave.remoute.bits.nothing = 1;
            edrk.auto_master_slave.remoute.bits.master  = 0;
            edrk.auto_master_slave.remoute.bits.slave   = 0;
            edrk.auto_master_slave.remoute.bits.try_master = 0;
            edrk.auto_master_slave.remoute.bits.try_slave = 0;



            edrk.auto_master_slave.local.bits.master = 1;
            edrk.auto_master_slave.local.bits.slave  = 0;
            edrk.auto_master_slave.local.bits.try_master = 0;
            edrk.auto_master_slave.local.bits.try_slave = 0;
            edrk.auto_master_slave.local.bits.nothing = 1;

            edrk.auto_master_slave.status = 2;
        }

        edrk.auto_master_slave.remoute.bits.sync_line_detect = 0;
        edrk.auto_master_slave.remoute.bits.bus_off = 1;
        edrk.auto_master_slave.remoute.bits.sync1_2 = 0;

    }
    else
    {
        edrk.warnings.e7.bits.AUTO_SET_MASTER = 0;

        edrk.auto_master_slave.remoute.bits.bus_off = 0;

        // синхронизируем свои программы через OPTICAL_BUS

        if (wait_synhro_optical_bus()==1)
        {

            edrk.auto_master_slave.status = 50; // wait synhro


        }
        else
        {


            edrk.auto_master_slave.remoute.bits.master = optical_read_data.data.cmd.bit.master;
            edrk.auto_master_slave.remoute.bits.slave = optical_read_data.data.cmd.bit.slave;
            edrk.auto_master_slave.remoute.bits.try_master = optical_read_data.data.cmd.bit.maybe_master;
            edrk.auto_master_slave.remoute.bits.sync1_2 = optical_read_data.data.cmd.bit.sync_1_2;
            edrk.auto_master_slave.remoute.bits.sync_line_detect = optical_read_data.data.cmd.bit.sync_line_detect;
            edrk.auto_master_slave.remoute.bits.tick = optical_read_data.data.cmd.bit.wdog_tick;

            if (optical_read_data.data.cmd.bit.master==0 && optical_read_data.data.cmd.bit.slave==0)
               edrk.auto_master_slave.remoute.bits.nothing = 1;


           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 1

           // тот ПЧ уже мастер
           if (edrk.auto_master_slave.remoute.bits.master)
           {

               // и этот ПЧ мастер почему-то?
               if (edrk.auto_master_slave.local.bits.master)
               {
                   edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                   edrk.auto_master_slave.status = 3;
               }
               else
               {
               // этот ПЧ еще не определился, поэтому переход на slave
                if (edrk.auto_master_slave.local.bits.master==0 && edrk.auto_master_slave.local.bits.slave==0)
                {
        //           edrk.auto_master_slave.local.bits.try_slave = 1;
                   // стали slave
                   edrk.auto_master_slave.local.bits.slave = 1;
                   // сняли свой запрос на мастера если он был
                   edrk.auto_master_slave.local.bits.try_master = 0;
                   edrk.auto_master_slave.status = 4;
                }
                else
                {
                    edrk.auto_master_slave.status = 21;
                }
               }
           }
           else
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 2
           // тот ПЧ уже slave

           if (edrk.auto_master_slave.remoute.bits.slave)
           {

               // и этот ПЧ slave почему-то?
               if (edrk.auto_master_slave.local.bits.slave)
               {

                   // был переход из мастер в slave
                   if (edrk.auto_master_slave.prev_remoute.bits.slave==0)
                   {
                      if (edrk.Go)
                      {
                          // запущен ШИМ
                          edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                          edrk.auto_master_slave.status = 5;
                      }
                      else
                      {
                          // пробуем перехватить master
                          edrk.auto_master_slave.local.bits.try_master = 1;
                          edrk.auto_master_slave.status = 6;
                      }
                   }
                   else
                   {
                      edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                      edrk.auto_master_slave.status = 7;
                   }

               }
               else
               {

               // этот ПЧ еще не определился, поэтому запрашивает на master
                if (edrk.auto_master_slave.local.bits.master==0 && edrk.auto_master_slave.local.bits.slave==0 && edrk.auto_master_slave.local.bits.try_master==0)
                {
                    if (edrk.flag_second_PCH==0)
                        edrk.auto_master_slave.local.bits.try_master = 1;
                    if (edrk.flag_second_PCH==1)
                        edrk.auto_master_slave.local.bits.try_master = 1;

                    edrk.auto_master_slave.status = 8;
    //               edrk.auto_master_slave.local.bits.slave = 1;
                }
                else
                // этот ПЧ уже в запросе на мастер, а тот ПЧ подтвердил в slave что он не против.
                if (edrk.auto_master_slave.local.bits.master==0 && edrk.auto_master_slave.local.bits.slave==0 && edrk.auto_master_slave.local.bits.try_master==1)
                {
                    // стали мастером
                   edrk.auto_master_slave.local.bits.master = 1;
                   edrk.auto_master_slave.local.bits.try_master = 0;
                   edrk.auto_master_slave.status = 9;
    //               edrk.auto_master_slave.local.bits.slave = 1;
                }
                else
                {
                    edrk.auto_master_slave.status = 22;
                }

               }
           }
           else
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 3
           // тот ПЧ запрашивает переход на мастер

           if (edrk.auto_master_slave.remoute.bits.master==0
               && edrk.auto_master_slave.remoute.bits.slave==0
               && edrk.auto_master_slave.remoute.bits.try_master)
           {
               // а этот ПЧ slave
               if (edrk.auto_master_slave.local.bits.slave)
               {
                   // вроде не норм, остаемся slave
                   // тут надо подождать некотрое время, пока тот ПЧ не поймет что мы стали слейвом и перейдет из try_master в мастер
                   if (count_wait_slave_try_master<MAX_COUNT_WAIT_SLAVE_TRY_MASTER)
                       count_wait_slave_try_master++;
                   else
                   {
                    edrk.auto_master_slave.status = 10;
                    edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                   }
               }
               else
               // а этот ПЧ master
               if (edrk.auto_master_slave.local.bits.master)
               {
                   // тут мы должны принять решение отдавать ли свой мастер другому ПЧ?
                   // пока выставим ошибку
                   edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                   edrk.auto_master_slave.status = 11;
               }
               else
               // этот ПЧ не мастер и не слейв и нет запросов от него на мастер
               if (edrk.auto_master_slave.local.bits.master==0 && edrk.auto_master_slave.local.bits.slave==0 && edrk.auto_master_slave.local.bits.try_master==0)
               {
                   // становимся slave
                   edrk.auto_master_slave.local.bits.slave = 1;
                   edrk.auto_master_slave.status = 12;
                   count_wait_slave_try_master = 0; // обнулим счетчик, т.к. нас надо чтоб тот ПЧ понял что мы стали slave
               }
               else
               // этот ПЧ не мастер и не слейв и есть запрос от него на мастер, т.е. оба ПЧ хотят быть мастерами
               if (edrk.auto_master_slave.local.bits.master==0 && edrk.auto_master_slave.local.bits.slave==0 && edrk.auto_master_slave.local.bits.try_master==1)
               {

                   // становимся master через некоторое время (для каждого ПЧ время разное)
                   if (edrk.flag_second_PCH==0)
                   {
                       //оба хотят, но приотритет даем всегда первому
                       edrk.auto_master_slave.local.bits.master = 1;
                       edrk.auto_master_slave.local.bits.try_master = 0;

    //                 if (count_try_master<MAX_COUNT_TRY_MASTER_BS1)
    //                     count_try_master++;
    //                 else
    //                     edrk.auto_master_slave.local.bits.master = 1;
                   }

                   if (edrk.flag_second_PCH==1)
                   {
                       //оба хотят, но приотритет даем всегда первому

                       edrk.auto_master_slave.local.bits.slave = 1;
                       edrk.auto_master_slave.local.bits.try_master = 0;

    //                 if (count_try_master<MAX_COUNT_TRY_MASTER_BS2)
    //                     count_try_master++;
    //                 else
    //                     edrk.auto_master_slave.local.bits.master = 1;
                   }
                   edrk.auto_master_slave.status = 13;
               }
               else
               {
                   edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                   edrk.auto_master_slave.status = 100;
               }


           }
           else
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 4
           // этот ПЧ запрашивает переход на мастер

           if (edrk.auto_master_slave.local.bits.master==0
                      && edrk.auto_master_slave.local.bits.slave==0
                      && edrk.auto_master_slave.local.bits.try_master)
           {
               // становимся master через некоторое время (для каждого ПЧ время разное)
               if (edrk.flag_second_PCH==0)
               {
                 if (count_try_master<MAX_COUNT_TRY_MASTER_BS1)
                 {
                     count_try_master++;
                     edrk.auto_master_slave.status = 14;
                 }
                 else
                 {
                     edrk.auto_master_slave.local.bits.master = 1;
                     edrk.auto_master_slave.local.bits.try_master = 0;
                     edrk.auto_master_slave.status = 15;

                 }
               }

               if (edrk.flag_second_PCH==1)
               {
                 if (count_try_master<MAX_COUNT_TRY_MASTER_BS2)
                 {
                     count_try_master++;
                     edrk.auto_master_slave.status = 14;
                 }
                 else
                 {
                     edrk.auto_master_slave.local.bits.master = 1;
                     edrk.auto_master_slave.local.bits.try_master = 0;
                     edrk.auto_master_slave.status = 15;
                 }
               }



           }
           else
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 5
           // тот ПЧ ничего не делает

           if (edrk.auto_master_slave.remoute.bits.master==0 && edrk.auto_master_slave.remoute.bits.slave==0 && edrk.auto_master_slave.remoute.bits.try_master==0)
           {
               // а этот ПЧ slave
               if (edrk.auto_master_slave.local.bits.slave)
               {
                   // были в слейве, а тот ПЧ почему-то потерял режим - ошибка или попытка захвата мастера!
                   if (edrk.auto_master_slave.prev_remoute.bits.master)
                   {
                       if (edrk.Go) // при ШИМе вырубаемся.
                       {
                           edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                           edrk.auto_master_slave.status = 24;

                       }
                       else
                       {
                         // а тут все ок.
                         edrk.auto_master_slave.local.bits.slave = 0;
                         edrk.auto_master_slave.local.bits.master = 1;

                         edrk.auto_master_slave.status = 23;
                       }
                   }
                   else
                   {
                        edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                        edrk.auto_master_slave.status = 16;
                   }
               }
               else
               // а этот ПЧ master
               if (edrk.auto_master_slave.local.bits.master)
               {
                   // тут мы остемся мастером вроде?
                   // но тот ПЧ не подтвердил переход, он должен стать мастером или слейвом
                   err_confirm_mode = 0;
//                   filter_err_count(&count_wait_answer_confirm_mode,
//                                                       MAX_COUNT_WAIT_ANSWER_CONFIRM_MODE,
//                                                       1,
//                                                       0);


                   if (err_confirm_mode)
                   {
                       // мы мастер, но тот ПЧ так и не понял это
                       edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
                       edrk.auto_master_slave.status = 20;
                   }
                   else
                       edrk.auto_master_slave.status = 17;

               }
               else
               {
                   // тут пытаемся захватить мастер
                   if (edrk.flag_second_PCH==0)
                       edrk.auto_master_slave.local.bits.try_master = 1;
                   if (edrk.flag_second_PCH==1)
                       edrk.auto_master_slave.local.bits.try_master = 1;
                   edrk.auto_master_slave.status = 18;
               }


           }
           else
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 5
           //
           {
               // что-то пошло не так
               edrk.errors.e7.bits.AUTO_SET_MASTER |= 1;
               edrk.auto_master_slave.status = 19;

           }
           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 6
           //

           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 7
           //

           //////////////////////////////////////////////////
           //////////////////////////////////////////////////
           // 8
           //
        }
    }





//    optical_write_data.cmd.bit. = edrk.auto_master_slave.local.bits.slave;



    edrk.to_second_pch.bits.MASTER = edrk.auto_master_slave.local.bits.master;

    edrk.auto_master_slave.prev_remoute.all = edrk.auto_master_slave.remoute.all;
    edrk.auto_master_slave.prev_local.all = edrk.auto_master_slave.local.all;

}
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////

void clear_errors_master_slave(void)
{

//    if (edrk.errors.e7.bits.AUTO_SET_MASTER)
    {

//    if (edrk.errors.e7.bits.MASTER_SLAVE_SYNC
//            || edrk.errors.e1.bits.NO_INPUT_SYNC_SIGNAL)
//      edrk.ms.count_time_wait_ready1 = 0;

    edrk.ms.count_time_wait_ready2 = 0;

    edrk.ms.errors_count.alive_can_to_another_bs = 0;
    edrk.ms.errors_count.alive_opt_bus_read = 0;
    edrk.ms.errors_count.alive_opt_bus_write = 0;
    edrk.ms.errors_count.alive_sync_line = 0;
    edrk.ms.errors_count.alive_sync_line_local = 0;
    edrk.ms.errors_count.another_rascepitel = 0;
    edrk.ms.errors_count.fast_optical_alarm = 0;
    edrk.ms.errors_count.input_alarm_another_bs = 0;
    edrk.ms.errors_count.input_master_slave = 0;

    edrk.ms.err_lock_signals.alive_can_to_another_bs = 0;
    edrk.ms.err_lock_signals.alive_opt_bus_read = 0;
    edrk.ms.err_lock_signals.alive_opt_bus_write = 0;
    edrk.ms.err_lock_signals.alive_sync_line = 0;
    edrk.ms.err_lock_signals.alive_sync_line_local = 0;
    edrk.ms.err_lock_signals.another_rascepitel = 0;
    edrk.ms.err_lock_signals.fast_optical_alarm = 0;
    edrk.ms.err_lock_signals.input_alarm_another_bs = 0;
    edrk.ms.err_lock_signals.input_master_slave = 0;

    }

}

//////////////////////////////////////////////////////////
