/* * master_slave.c * * Created on: 13 нояб. 2024 г. * Author: Evgeniy_Sokolov */ #include #include #include #include #include #include #include #include "IQmathLib.h" #include "mathlib.h" #include #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 = 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