/*
 * another_bs.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 "adc_tools.h"
#include "CAN_project.h"
#include "CAN_Setup.h"
#include "global_time.h"
#include "v_rotor.h"
#include "ukss_tools.h"
#include "another_bs.h"
#include "control_station_project.h"
#include "control_station.h"
#include "can_bs2bs.h"
#include "sync_tools.h"
#include "vector_control.h"
#include "master_slave.h"
#include "digital_filters.h"


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

//////////////////////////////////////////////////////////
void read_data_from_bs(void)
{
    int g;

    if (control_station.alive_control_station[CONTROL_STATION_ANOTHER_BS])
    {
        g = Unites[ANOTHER_BSU1_CAN_DEVICE][5];
        edrk.int_koef_ogran_power_another_bs = g;
        edrk.iq_koef_ogran_power_another_bs = ((float)edrk.int_koef_ogran_power_another_bs);

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][6];
        edrk.power_kw_another_bs = g;
        edrk.iq_power_kw_another_bs = _IQ(((float)edrk.power_kw_another_bs * 1000.0)/NORMA_ACP/NORMA_ACP);

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][7];
        edrk.active_post_upravl_another_bs = g;

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][9];
        edrk.Ready1_another_bs = g;

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][10];
        edrk.Ready2_another_bs = g;

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][11];
        edrk.MasterSlave_another_bs = g;

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][3] & 0x1;
        edrk.ump_cmd_another_bs = g;

        g = (Unites[ANOTHER_BSU1_CAN_DEVICE][3] & 0x2) >> 1;
        edrk.qtv_cmd_another_bs = g;

        g = Unites[ANOTHER_BSU1_CAN_DEVICE][13];
        edrk.errors_another_bs_from_can = g;
    }
    else
    {
        edrk.errors_another_bs_from_can = 0;
    }


}


//////////////////////////////////////////////////////////
unsigned int read_cmd_sbor_from_bs(void)
{
    unsigned int g;
    g = Unites[ANOTHER_BSU1_CAN_DEVICE][4];
    return g;


}




void UpdateTableSecondBS(void)
{
  int cmd;
  int i,k;

  static unsigned int counter_sum_errors = 0;

  Unites2SecondBS[0]++;

  Unites2SecondBS[1] = global_time.miliseconds;
  Unites2SecondBS[2] = edrk.flag_second_PCH;
  Unites2SecondBS[3] = (edrk.to_shema.bits.QTV_ON_OFF << 1) | (edrk.to_shema.bits.UMP_ON_OFF);
  Unites2SecondBS[4] = edrk.SumSbor;
  Unites2SecondBS[5] = edrk.int_koef_ogran_power;
  Unites2SecondBS[6] = (int)edrk.power_kw;
  Unites2SecondBS[7] = (int)edrk.active_post_upravl;
  Unites2SecondBS[8] = (int)edrk.power_kw;
  Unites2SecondBS[9] =  edrk.Status_Ready.bits.ready1;
  Unites2SecondBS[10] = edrk.Status_Ready.bits.ready_final;
  Unites2SecondBS[11] = edrk.MasterSlave;

  Unites2SecondBS[12] = _IQtoF(vect_control.iqId_min) * NORMA_ACP;

  Unites2SecondBS[13] = pause_detect_error(&counter_sum_errors, 10,  edrk.summ_errors);


  for (i=0;i<CONTROL_STATION_CMD_LAST;i++)
  {
      if ((POS_STATION_CMD_ANOTHER_BSU1+i)<SIZE_ARR_CAN_UNITES_BS2BS)
          Unites2SecondBS[POS_STATION_CMD_ANOTHER_BSU1+i] =  control_station.active_array_cmd[i];
  }


//  Unites2SecondBS[3] = _IQtoIQ15(edrk.zadanie.iq_fzad);
//  Unites2SecondBS[4] = _IQtoIQ15(edrk.zadanie.iq_kzad);
//  Unites2SecondBS[5] = _IQtoIQ15(edrk.zadanie.iq_Izad);
//  Unites2SecondBS[6] = (edrk.zadanie.oborots_zad);
//  Unites2SecondBS[7] = _IQtoIQ15(edrk.zadanie.iq_power_zad);


  if (edrk.flag_second_PCH==0)
  {

//      Unites2SecondBS[5] = Unites[ANOTHER_BSU1_CAN_DEVICE][8];
//      Unites2SecondBS[8] = 0xaa;
//
//      max_count_send_to_can2second_bs = 10;
  }
  else
  {

//      Unites2SecondBS[5] = Unites[ANOTHER_BSU1_CAN_DEVICE][8];
//      Unites2SecondBS[8] = 0x55;
//
//      max_count_send_to_can2second_bs = 10;
  }



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


//////////////////////////////////////////////////////////
void detect_error_from_another_bs(void)
{
    if (edrk.errors_another_bs_from_can)
        edrk.errors.e7.bits.ANOTHER_BS_ALARM |= 1;

}
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
#define MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS          30 //20
#define MAX_WAIT_READY1_DETECT_ALIVE_ANOTHER_BS      100
#define MAX_WAIT_READY2_DETECT_ALIVE_ANOTHER_BS      70 //30 // должен быть больше чем MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
void detect_alive_another_bs(void)
{
 //   static unsigned int count_wait_ready = 0;
    static unsigned int prev_another_bs_maybe_on = 0;
    static unsigned int prev_another_bs_maybe_on_after_ready1 = 0,
            prev_alive_can_to_another_bs = 0;
    int real_box;


    real_box = get_real_in_mbox(UNITS_TYPE_BOX,ANOTHER_BSU1_CAN_DEVICE);
    if (real_box != -1)
    {
        edrk.ms.err_signals.alive_can_to_another_bs = CAN_timeout[real_box];


        if (edrk.ms.err_signals.alive_can_to_another_bs == 1
                && prev_alive_can_to_another_bs == 0)
        {
            // reinit CAN
            InitCanSoft();
        }
        prev_alive_can_to_another_bs = edrk.ms.err_signals.alive_can_to_another_bs;
    }

#if (USE_TK_3)
    edrk.ms.err_signals.alive_opt_bus_read      = !project.cds_tk[3].optical_data_in.ready;
    edrk.ms.err_signals.alive_opt_bus_write     = !project.cds_tk[3].optical_data_out.ready;
#else
    edrk.ms.err_signals.alive_opt_bus_read      = 1;
    edrk.ms.err_signals.alive_opt_bus_write     = 1;
#endif
    edrk.ms.err_signals.alive_sync_line         = !sync_data.global_flag_sync_1_2;
    edrk.ms.err_signals.alive_sync_line_local   = !sync_data.local_flag_sync_1_2;
//    edrk.ms.err_signals.input_alarm_another_bs  = edrk.from_ing1.bits.
    // тут пока отключен канал.
 //   edrk.ms.err_signals.fast_optical_alarm      = 0;//!project.cds_tk[3].read.sbus.status_tk_40pin.bit.tk5_ack;
    edrk.ms.err_signals.another_rascepitel      = edrk.from_second_pch.bits.RASCEPITEL;

    if (edrk.ms.err_signals.alive_can_to_another_bs
            && (edrk.ms.err_signals.alive_opt_bus_read
            || edrk.ms.err_signals.alive_opt_bus_write)
            && edrk.ms.err_signals.alive_sync_line
//            && edrk.ms.err_signals.fast_optical_alarm
            )
    {
        edrk.ms.another_bs_maybe_off = 1;
        edrk.ms.another_bs_maybe_on = 0;
    }
    else
    {
        edrk.ms.another_bs_maybe_off = 0;
        edrk.ms.another_bs_maybe_on = 1;
    }

    // если связь восстановилась, то опять ждем некоторое время пока запустятся все остальные каналы связи.
    if (prev_another_bs_maybe_on!=edrk.ms.another_bs_maybe_on && edrk.ms.another_bs_maybe_on)
    {
//        edrk.ms.count_time_wait_ready1 = 0;
        edrk.ms.count_time_wait_ready2 = 0;
        prev_another_bs_maybe_on_after_ready1 = 0;
        clear_errors_master_slave();
    }


    //
    // выставляем флаг только через время MAX_WAIT_READY_DETECT_ALIVE_ANOTHER_BS
    //
    edrk.ms.ready1 = filter_err_count(&edrk.ms.count_time_wait_ready1,
                               MAX_WAIT_READY1_DETECT_ALIVE_ANOTHER_BS,
                               1,
                               0);

    if (edrk.Status_Ready.bits.ready5)
    {
        edrk.ms.ready2 = filter_err_count(&edrk.ms.count_time_wait_ready2,
                                       MAX_WAIT_READY2_DETECT_ALIVE_ANOTHER_BS,
                                       1,
                                       0);
    }
    else
    {
        edrk.ms.count_time_wait_ready2 = 0;
        edrk.ms.ready2 = 0;
    }

//    edrk.ms.ready2 = edrk.Status_Ready.bits.ready5 && filter_err_count(&edrk.ms.count_time_wait_ready2,
//                               MAX_WAIT_READY2_DETECT_ALIVE_ANOTHER_BS,
//                               1,
//                               0);





    prev_another_bs_maybe_on = edrk.ms.another_bs_maybe_on;


    // ждем пока пройдет некоторое время
    if (edrk.ms.ready1==0)
    {


        edrk.ms.status = 1;
        return;
    }


    // если связь была после edrk.ms.ready1==1, но вся пропала, даем ошибку
    if (prev_another_bs_maybe_on_after_ready1!=edrk.ms.another_bs_maybe_on && edrk.ms.another_bs_maybe_on==0)
    {
        edrk.errors.e4.bits.ANOTHER_BS_POWER_OFF |= 1;
    }
    prev_another_bs_maybe_on_after_ready1 = edrk.ms.another_bs_maybe_on;




    edrk.ms.err_lock_signals.alive_can_to_another_bs |= filter_err_count(&edrk.ms.errors_count.alive_can_to_another_bs,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.alive_can_to_another_bs,
                                                                        0);

    edrk.ms.err_lock_signals.alive_opt_bus_read |= filter_err_count(&edrk.ms.errors_count.alive_opt_bus_read,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.alive_opt_bus_read,
                                                                        0);
    edrk.ms.err_lock_signals.alive_opt_bus_write |= filter_err_count(&edrk.ms.errors_count.alive_opt_bus_write,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.alive_opt_bus_write,
                                                                        0);

    edrk.ms.err_lock_signals.alive_sync_line = filter_err_count(&edrk.ms.errors_count.alive_sync_line,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.alive_sync_line,
                                                                        0);

    edrk.ms.err_lock_signals.alive_sync_line_local = filter_err_count(&edrk.ms.errors_count.alive_sync_line_local,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.alive_sync_line_local,
                                                                        0);

    edrk.ms.err_lock_signals.fast_optical_alarm |= filter_err_count(&edrk.ms.errors_count.fast_optical_alarm,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.fast_optical_alarm,
                                                                        0);

    edrk.ms.err_lock_signals.input_alarm_another_bs |= filter_err_count(&edrk.ms.errors_count.input_alarm_another_bs,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.input_alarm_another_bs,
                                                                        0);

    edrk.ms.err_lock_signals.another_rascepitel |= filter_err_count(&edrk.ms.errors_count.another_rascepitel,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.another_rascepitel,
                                                                        0);

    edrk.ms.err_lock_signals.input_master_slave |= filter_err_count(&edrk.ms.errors_count.input_master_slave,
                                                                        MAX_ERRORS_DETECT_ALIVE_ANOTHER_BS,
                                                                        edrk.ms.err_signals.input_master_slave,
                                                                        0);


    if (edrk.ms.err_signals.alive_can_to_another_bs
            && (edrk.ms.err_signals.alive_opt_bus_read
            || edrk.ms.err_signals.alive_opt_bus_write)
            && edrk.ms.err_signals.alive_sync_line
  //          && edrk.ms.err_signals.fast_optical_alarm
 //         &&  edrk.ms.err_signals.input_alarm_another_bs &&
//            && edrk.ms.err_signals.another_rascepitel == 0
//            && edrk.ms.err_signals.input_master_slave
            )
    {

        if (edrk.ms.err_signals.another_rascepitel)
            edrk.errors.e7.bits.ANOTHER_RASCEPITEL_ON |= 1;

//        edrk.ms.another_bs_maybe_off = 1;
//        edrk.ms.another_bs_maybe_on = 0;

        edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF = 1;
  //      edrk.warnings.e4.bits.FAST_OPTICAL_ALARM = 1;
        edrk.warnings.e7.bits.MASTER_SLAVE_SYNC = 1;
        edrk.warnings.e7.bits.READ_OPTBUS = edrk.ms.err_signals.alive_opt_bus_read;
        edrk.warnings.e7.bits.WRITE_OPTBUS = edrk.ms.err_signals.alive_opt_bus_write;
        edrk.warnings.e7.bits.CAN2CAN_BS = 1;

        edrk.ms.status = 2;

    }
    else
    {

        edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF = 0;

//
        if (edrk.ms.err_lock_signals.alive_can_to_another_bs)
            edrk.errors.e7.bits.CAN2CAN_BS |= 1;
        else
            edrk.warnings.e7.bits.CAN2CAN_BS = 0;
//
        if (edrk.ms.err_lock_signals.alive_opt_bus_read)
            edrk.errors.e7.bits.READ_OPTBUS |= 1;
        else
            edrk.warnings.e7.bits.READ_OPTBUS = 0;
//
        if (edrk.ms.err_lock_signals.alive_opt_bus_write)
            edrk.errors.e7.bits.WRITE_OPTBUS |= 1;
        else
            edrk.warnings.e7.bits.WRITE_OPTBUS = 0;
//
        if (edrk.ms.err_lock_signals.alive_sync_line)
            edrk.warnings.e7.bits.MASTER_SLAVE_SYNC = 1;
        else
            edrk.warnings.e7.bits.MASTER_SLAVE_SYNC = 0;
//
//        if (edrk.ms.err_lock_signals.fast_optical_alarm)
//            edrk.errors.e4.bits.FAST_OPTICAL_ALARM |= 1;
//        else
//            edrk.warnings.e4.bits.FAST_OPTICAL_ALARM = 0;


 //       edrk.ms.another_bs_maybe_on = 1;
 //       edrk.ms.another_bs_maybe_off = 0;

        if (edrk.ms.err_signals.alive_can_to_another_bs
                    || edrk.ms.err_signals.alive_opt_bus_read
                    || edrk.ms.err_signals.alive_opt_bus_write
                    || edrk.ms.err_signals.alive_sync_line
                    || edrk.ms.err_signals.fast_optical_alarm
                    )
            edrk.ms.status = 3;
        else
            edrk.ms.status = 4;

    }





}


////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//  обновлЯем другой БСУ по CAN
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

void update_bsu_can(unsigned int pause)
{
    int real_mbox;
    int t1;

//    if (edrk.flag_second_PCH==0)
//        t1 = 125;
//    if (edrk.flag_second_PCH==1)
//        t1 = 150;

    SendAll2SecondBS(pause);

}

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

////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//  спец настройки для межблочного обмена БС1 БС2 по CAN
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

void init_can_box_between_bs1_bs2(void)
{
    // включаем реверс адресов только для одного БС
    // имитируем ящик Unites какбы
    //
    if (edrk.flag_second_PCH==0)
    {
       unites_can_setup.revers_box[ANOTHER_BSU1_CAN_DEVICE] = 1;
    }

    unites_can_setup.adr_detect_refresh[ZADATCHIK_CAN] = 16;

}

