From da2cd65e9a05b7c279a5aef82cd0a7492ba13ccf Mon Sep 17 00:00:00 2001 From: Razvalyaev <wot890089@mail.ru> Date: Fri, 27 Dec 2024 10:50:32 +0300 Subject: [PATCH] init --- .gitignore | 25 + Inu/Src/.vscode/c_cpp_properties.json | 21 + Inu/Src/VectorControl/abc_to_alphabeta.c | 23 + Inu/Src/VectorControl/abc_to_alphabeta.h | 39 + Inu/Src/VectorControl/abc_to_dq.c | 39 + Inu/Src/VectorControl/abc_to_dq.h | 42 + Inu/Src/VectorControl/alg_pll.c | 577 ++++ Inu/Src/VectorControl/alg_pll.h | 188 ++ Inu/Src/VectorControl/alphabeta_to_dq.c | 24 + Inu/Src/VectorControl/alphabeta_to_dq.h | 32 + Inu/Src/VectorControl/dq_to_alphabeta_cos.c | 39 + Inu/Src/VectorControl/dq_to_alphabeta_cos.h | 40 + Inu/Src/VectorControl/params_pll.h | 41 + Inu/Src/VectorControl/regul_power.c | 88 + Inu/Src/VectorControl/regul_power.h | 30 + Inu/Src/VectorControl/regul_turns.c | 143 + Inu/Src/VectorControl/regul_turns.h | 29 + Inu/Src/VectorControl/smooth.c | 180 ++ Inu/Src/VectorControl/smooth.h | 78 + Inu/Src/VectorControl/teta_calc.c | 91 + Inu/Src/VectorControl/teta_calc.h | 36 + Inu/Src/VectorControl/vector_control.c | 297 ++ Inu/Src/VectorControl/vector_control.h | 82 + Inu/Src/main/281xEvTimersInit.c | 636 ++++ Inu/Src/main/281xEvTimersInit.h | 18 + Inu/Src/main/CAN_project.h | 256 ++ Inu/Src/main/Main.c | 126 + Inu/Src/main/PWMTMSHandle.c | 510 +++ Inu/Src/main/PWMTMSHandle.h | 25 + Inu/Src/main/PWMTools.c | 2438 +++++++++++++++ Inu/Src/main/PWMTools.h | 54 + Inu/Src/main/adc_internal.h | 33 + Inu/Src/main/adc_tools.c | 1412 +++++++++ Inu/Src/main/adc_tools.h | 402 +++ Inu/Src/main/alarm_log.c | 196 ++ Inu/Src/main/alarm_log.h | 16 + Inu/Src/main/alg_simple_scalar.c | 976 ++++++ Inu/Src/main/alg_simple_scalar.h | 101 + Inu/Src/main/alg_uf_const.c | 80 + Inu/Src/main/alg_uf_const.h | 34 + Inu/Src/main/another_bs.c | 458 +++ Inu/Src/main/another_bs.h | 21 + Inu/Src/main/break_regul.c | 204 ++ Inu/Src/main/break_regul.h | 70 + Inu/Src/main/calc_rms_vals.c | 265 ++ Inu/Src/main/calc_rms_vals.h | 66 + Inu/Src/main/calc_tempers.c | 284 ++ Inu/Src/main/calc_tempers.h | 16 + Inu/Src/main/can_bs2bs.c | 83 + Inu/Src/main/can_bs2bs.h | 21 + Inu/Src/main/can_protocol_ukss.h | 63 + Inu/Src/main/control_station_project.c | 2493 +++++++++++++++ Inu/Src/main/control_station_project.h | 109 + Inu/Src/main/detect_error_3_phase.c | 167 + Inu/Src/main/detect_error_3_phase.h | 148 + Inu/Src/main/detect_errors.c | 1606 ++++++++++ Inu/Src/main/detect_errors.h | 80 + Inu/Src/main/detect_errors_adc.c | 310 ++ Inu/Src/main/detect_errors_adc.h | 45 + Inu/Src/main/detect_overload.c | 92 + Inu/Src/main/detect_overload.h | 32 + Inu/Src/main/detect_phase_break.c | 112 + Inu/Src/main/detect_phase_break.h | 36 + Inu/Src/main/detect_phase_break2.c | 203 ++ Inu/Src/main/detect_phase_break2.h | 50 + Inu/Src/main/digital_filters.c | 103 + Inu/Src/main/digital_filters.h | 19 + Inu/Src/main/edrk_main.c | 2736 +++++++++++++++++ Inu/Src/main/edrk_main.h | 1838 +++++++++++ Inu/Src/main/f281xbmsk.h | 244 ++ Inu/Src/main/f281xpwm.c | 288 ++ Inu/Src/main/f281xpwm.h | 163 + Inu/Src/main/limit_lib.c | 50 + Inu/Src/main/limit_lib.h | 15 + Inu/Src/main/limit_power.c | 237 ++ Inu/Src/main/limit_power.h | 21 + Inu/Src/main/logs_hmi.c | 1150 +++++++ Inu/Src/main/logs_hmi.h | 86 + Inu/Src/main/manch.h | 182 ++ Inu/Src/main/master_slave.c | 586 ++++ Inu/Src/main/master_slave.h | 34 + Inu/Src/main/message2.c | 907 ++++++ Inu/Src/main/message2.h | 33 + Inu/Src/main/message2can.c | 278 ++ Inu/Src/main/message2can.h | 18 + Inu/Src/main/message2test.c | 678 ++++ Inu/Src/main/message2test.h | 33 + Inu/Src/main/message_modbus.c | 897 ++++++ Inu/Src/main/message_modbus.h | 61 + Inu/Src/main/message_terminals_can.c | 128 + Inu/Src/main/message_terminals_can.h | 15 + Inu/Src/main/modbus_hmi.c | 393 +++ Inu/Src/main/modbus_hmi.h | 39 + Inu/Src/main/modbus_hmi_read.c | 222 ++ Inu/Src/main/modbus_hmi_read.h | 15 + Inu/Src/main/modbus_hmi_update.c | 2022 ++++++++++++ Inu/Src/main/modbus_hmi_update.h | 39 + Inu/Src/main/modbus_svu_update.c | 710 +++++ Inu/Src/main/modbus_svu_update.h | 17 + Inu/Src/main/not_use/log_to_mem.c | 249 ++ Inu/Src/main/not_use/log_to_mem.h | 201 ++ Inu/Src/main/optical_bus.c | 413 +++ Inu/Src/main/optical_bus.h | 109 + Inu/Src/main/optical_bus_tools.c | 791 +++++ Inu/Src/main/optical_bus_tools.h | 14 + Inu/Src/main/overheat_limit.c | 80 + Inu/Src/main/overheat_limit.h | 13 + Inu/Src/main/params.h | 182 ++ Inu/Src/main/params_alg.h | 218 ++ Inu/Src/main/params_bsu.h | 123 + Inu/Src/main/params_hwp.h | 9 + Inu/Src/main/params_motor.h | 59 + Inu/Src/main/params_norma.h | 70 + Inu/Src/main/params_protect_adc.h | 25 + Inu/Src/main/params_pwm24.h | 48 + Inu/Src/main/params_temper_p.h | 58 + Inu/Src/main/pll_tools.c | 105 + Inu/Src/main/pll_tools.h | 22 + Inu/Src/main/project.c | 1049 +++++++ Inu/Src/main/project.h | 74 + Inu/Src/main/project_setup.h | 414 +++ Inu/Src/main/protect_levels.h | 119 + Inu/Src/main/pump_control.c | 255 ++ Inu/Src/main/pump_control.h | 27 + Inu/Src/main/pwm_logs.c | 476 +++ Inu/Src/main/pwm_logs.h | 16 + Inu/Src/main/pwm_test_lines.c | 36 + Inu/Src/main/pwm_test_lines.h | 63 + Inu/Src/main/ramp_zadanie_tools.c | 417 +++ Inu/Src/main/ramp_zadanie_tools.h | 20 + Inu/Src/main/sbor_shema.c | 1764 +++++++++++ Inu/Src/main/sbor_shema.h | 24 + Inu/Src/main/sim_model.c | 222 ++ Inu/Src/main/sim_model.h | 21 + Inu/Src/main/sync_tools.c | 520 ++++ Inu/Src/main/sync_tools.h | 113 + Inu/Src/main/synhro_tools.c | 144 + Inu/Src/main/synhro_tools.h | 19 + Inu/Src/main/temper_p_tools.c | 77 + Inu/Src/main/temper_p_tools.h | 22 + Inu/Src/main/tk_Test.c | 369 +++ Inu/Src/main/tk_Test.h | 12 + Inu/Src/main/ukss_tools.c | 605 ++++ Inu/Src/main/ukss_tools.h | 33 + Inu/Src/main/uom_tools.c | 149 + Inu/Src/main/uom_tools.h | 15 + Inu/Src/main/v_pwm24_v2.c | 948 ++++++ Inu/Src/main/v_pwm24_v2.h | 161 + Inu/Src/main/v_rotor.c | 1095 +++++++ Inu/Src/main/v_rotor.h | 185 ++ Inu/Src/main/v_rotor_22220.c | 666 ++++ Inu/Src/main/v_rotor_22220.h | 54 + Inu/Src/main/vector.h | 254 ++ Inu/Src/main/xPlatesAddress.h | 21 + Inu/Src/main_matlab/DSP281x_Device.h | 3 + Inu/Src/main_matlab/DSP281x_Ev.h | 1 + Inu/Src/main_matlab/DSP281x_Examples.h | 1 + .../main_matlab/DSP281x_GlobalPrototypes.h | 2 + .../DSP281x_SWPrioritizedIsrLevels.h | 1 + Inu/Src/main_matlab/IQmathLib.h | 684 +++++ Inu/Src/main_matlab/IQmathLib_matlab.c | 229 ++ Inu/Src/main_matlab/adc_tools.h | 445 +++ Inu/Src/main_matlab/adc_tools_matlab.c | 748 +++++ Inu/Src/main_matlab/dmctype.h | 32 + Inu/Src/main_matlab/errors_matlab.c | 25 + Inu/Src/main_matlab/io_verbal_names.h | 73 + Inu/Src/main_matlab/main_matlab.c | 269 ++ Inu/Src/main_matlab/main_matlab.h | 22 + Inu/Src/main_matlab/old/PWMTools.c | 719 +++++ Inu/Src/main_matlab/old/v_pwm24.c | 1642 ++++++++++ Inu/Src/main_matlab/old/v_pwm24.h | 190 ++ Inu/Src/main_matlab/old/xp_write_xpwm_time.h | 183 ++ Inu/Src/main_matlab/rotation_speed_matlab.c | 428 +++ Inu/Src/main_matlab/v_pwm24_matlab.c | 1644 ++++++++++ .../main_matlab/xp_write_xpwm_time_matlab.c | 361 +++ Inu/Src2/VectorControl/abc_to_alphabeta.c | 23 + Inu/Src2/VectorControl/abc_to_alphabeta.h | 39 + Inu/Src2/VectorControl/abc_to_dq.c | 38 + Inu/Src2/VectorControl/abc_to_dq.h | 42 + Inu/Src2/VectorControl/alphabeta_to_abc.c | 24 + Inu/Src2/VectorControl/alphabeta_to_abc.h | 38 + Inu/Src2/VectorControl/alphabeta_to_dq.c | 22 + Inu/Src2/VectorControl/alphabeta_to_dq.h | 32 + Inu/Src2/VectorControl/dq_to_alphabeta_cos.c | 39 + Inu/Src2/VectorControl/dq_to_alphabeta_cos.h | 40 + .../VectorControl/efficiency_compensation.c | 107 + .../VectorControl/efficiency_compensation.h | 13 + Inu/Src2/VectorControl/params_motor.h | 23 + Inu/Src2/VectorControl/pwm_vector_regul.c | 666 ++++ Inu/Src2/VectorControl/pwm_vector_regul.h | 81 + Inu/Src2/VectorControl/regul_power.c | 269 ++ Inu/Src2/VectorControl/regul_power.h | 32 + Inu/Src2/VectorControl/regul_turns.c | 185 ++ Inu/Src2/VectorControl/regul_turns.h | 12 + Inu/Src2/VectorControl/teta_calc.c | 262 ++ Inu/Src2/VectorControl/teta_calc.h | 39 + Inu/Src2/main/IQmathLib.c | 182 ++ Inu/Src2/main/IQmathLib.h | 661 ++++ Inu/Src2/main/PWMTools.c | 719 +++++ Inu/Src2/main/PWMTools.h | 19 + Inu/Src2/main/adc_tools.c | 528 ++++ Inu/Src2/main/adc_tools.h | 137 + Inu/Src2/main/dmctype.h | 31 + Inu/Src2/main/my_filter.c | 122 + Inu/Src2/main/my_filter.h | 76 + Inu/Src2/main/params.h | 181 ++ Inu/Src2/main/pid_reg3.c | 107 + Inu/Src2/main/pid_reg3.h | 117 + Inu/Src2/main/rotation_speed.h | 44 + Inu/Src2/main/svgen_dq.h | 38 + Inu/Src2/main/svgen_dq_v2.c | 120 + Inu/Src2/main/v_pwm24.c | 1635 ++++++++++ Inu/Src2/main/v_pwm24.h | 190 ++ Inu/Src2/main/vector.h | 256 ++ Inu/Src2/main/word_structurs.h | 64 + Inu/Src2/main/xp_write_xpwm_time.c | 361 +++ Inu/Src2/main/xp_write_xpwm_time.h | 183 ++ Inu/controller.c | 1355 ++++++++ Inu/controller.h | 222 ++ Inu/def.h | 482 +++ Inu/detcoeff.c | 242 ++ Inu/detcoeff.h | 47 + Inu/init28335.c | 1621 ++++++++++ Inu/init28335.h | 24 + Inu/isr.c | Bin 0 -> 11865 bytes Inu/isr.h | 72 + Inu/main.c | 144 + Inu/main.h | 17 + Inu/param.c | 426 +++ Inu/param.h | 41 + Inu/upr.c | 974 ++++++ Inu/upr.h | 50 + Inu/wrapper_inu.c | 267 ++ Inu/wrapper_inu.h | 25 + ReadMe.txt | 2 + allmex.m | 24 + am_two_wind.mexw64 | Bin 0 -> 27648 bytes asynchronous_machine.p | Bin 0 -> 1232 bytes electr_mach.slx | Bin 0 -> 41878 bytes init.m | 78 + inu_im_2wnd_3lvl.slx | Bin 0 -> 80373 bytes inu_im_2wnd_3lvl.slx.original | Bin 0 -> 88153 bytes inu_im_2wnd_3lvl.slx.r2021a | Bin 0 -> 64466 bytes inu_im_2wnd_3lvl.slxc | Bin 0 -> 113909 bytes run_mex.bat | 59 + 245 files changed, 65707 insertions(+) create mode 100644 .gitignore create mode 100644 Inu/Src/.vscode/c_cpp_properties.json create mode 100644 Inu/Src/VectorControl/abc_to_alphabeta.c create mode 100644 Inu/Src/VectorControl/abc_to_alphabeta.h create mode 100644 Inu/Src/VectorControl/abc_to_dq.c create mode 100644 Inu/Src/VectorControl/abc_to_dq.h create mode 100644 Inu/Src/VectorControl/alg_pll.c create mode 100644 Inu/Src/VectorControl/alg_pll.h create mode 100644 Inu/Src/VectorControl/alphabeta_to_dq.c create mode 100644 Inu/Src/VectorControl/alphabeta_to_dq.h create mode 100644 Inu/Src/VectorControl/dq_to_alphabeta_cos.c create mode 100644 Inu/Src/VectorControl/dq_to_alphabeta_cos.h create mode 100644 Inu/Src/VectorControl/params_pll.h create mode 100644 Inu/Src/VectorControl/regul_power.c create mode 100644 Inu/Src/VectorControl/regul_power.h create mode 100644 Inu/Src/VectorControl/regul_turns.c create mode 100644 Inu/Src/VectorControl/regul_turns.h create mode 100644 Inu/Src/VectorControl/smooth.c create mode 100644 Inu/Src/VectorControl/smooth.h create mode 100644 Inu/Src/VectorControl/teta_calc.c create mode 100644 Inu/Src/VectorControl/teta_calc.h create mode 100644 Inu/Src/VectorControl/vector_control.c create mode 100644 Inu/Src/VectorControl/vector_control.h create mode 100644 Inu/Src/main/281xEvTimersInit.c create mode 100644 Inu/Src/main/281xEvTimersInit.h create mode 100644 Inu/Src/main/CAN_project.h create mode 100644 Inu/Src/main/Main.c create mode 100644 Inu/Src/main/PWMTMSHandle.c create mode 100644 Inu/Src/main/PWMTMSHandle.h create mode 100644 Inu/Src/main/PWMTools.c create mode 100644 Inu/Src/main/PWMTools.h create mode 100644 Inu/Src/main/adc_internal.h create mode 100644 Inu/Src/main/adc_tools.c create mode 100644 Inu/Src/main/adc_tools.h create mode 100644 Inu/Src/main/alarm_log.c create mode 100644 Inu/Src/main/alarm_log.h create mode 100644 Inu/Src/main/alg_simple_scalar.c create mode 100644 Inu/Src/main/alg_simple_scalar.h create mode 100644 Inu/Src/main/alg_uf_const.c create mode 100644 Inu/Src/main/alg_uf_const.h create mode 100644 Inu/Src/main/another_bs.c create mode 100644 Inu/Src/main/another_bs.h create mode 100644 Inu/Src/main/break_regul.c create mode 100644 Inu/Src/main/break_regul.h create mode 100644 Inu/Src/main/calc_rms_vals.c create mode 100644 Inu/Src/main/calc_rms_vals.h create mode 100644 Inu/Src/main/calc_tempers.c create mode 100644 Inu/Src/main/calc_tempers.h create mode 100644 Inu/Src/main/can_bs2bs.c create mode 100644 Inu/Src/main/can_bs2bs.h create mode 100644 Inu/Src/main/can_protocol_ukss.h create mode 100644 Inu/Src/main/control_station_project.c create mode 100644 Inu/Src/main/control_station_project.h create mode 100644 Inu/Src/main/detect_error_3_phase.c create mode 100644 Inu/Src/main/detect_error_3_phase.h create mode 100644 Inu/Src/main/detect_errors.c create mode 100644 Inu/Src/main/detect_errors.h create mode 100644 Inu/Src/main/detect_errors_adc.c create mode 100644 Inu/Src/main/detect_errors_adc.h create mode 100644 Inu/Src/main/detect_overload.c create mode 100644 Inu/Src/main/detect_overload.h create mode 100644 Inu/Src/main/detect_phase_break.c create mode 100644 Inu/Src/main/detect_phase_break.h create mode 100644 Inu/Src/main/detect_phase_break2.c create mode 100644 Inu/Src/main/detect_phase_break2.h create mode 100644 Inu/Src/main/digital_filters.c create mode 100644 Inu/Src/main/digital_filters.h create mode 100644 Inu/Src/main/edrk_main.c create mode 100644 Inu/Src/main/edrk_main.h create mode 100644 Inu/Src/main/f281xbmsk.h create mode 100644 Inu/Src/main/f281xpwm.c create mode 100644 Inu/Src/main/f281xpwm.h create mode 100644 Inu/Src/main/limit_lib.c create mode 100644 Inu/Src/main/limit_lib.h create mode 100644 Inu/Src/main/limit_power.c create mode 100644 Inu/Src/main/limit_power.h create mode 100644 Inu/Src/main/logs_hmi.c create mode 100644 Inu/Src/main/logs_hmi.h create mode 100644 Inu/Src/main/manch.h create mode 100644 Inu/Src/main/master_slave.c create mode 100644 Inu/Src/main/master_slave.h create mode 100644 Inu/Src/main/message2.c create mode 100644 Inu/Src/main/message2.h create mode 100644 Inu/Src/main/message2can.c create mode 100644 Inu/Src/main/message2can.h create mode 100644 Inu/Src/main/message2test.c create mode 100644 Inu/Src/main/message2test.h create mode 100644 Inu/Src/main/message_modbus.c create mode 100644 Inu/Src/main/message_modbus.h create mode 100644 Inu/Src/main/message_terminals_can.c create mode 100644 Inu/Src/main/message_terminals_can.h create mode 100644 Inu/Src/main/modbus_hmi.c create mode 100644 Inu/Src/main/modbus_hmi.h create mode 100644 Inu/Src/main/modbus_hmi_read.c create mode 100644 Inu/Src/main/modbus_hmi_read.h create mode 100644 Inu/Src/main/modbus_hmi_update.c create mode 100644 Inu/Src/main/modbus_hmi_update.h create mode 100644 Inu/Src/main/modbus_svu_update.c create mode 100644 Inu/Src/main/modbus_svu_update.h create mode 100644 Inu/Src/main/not_use/log_to_mem.c create mode 100644 Inu/Src/main/not_use/log_to_mem.h create mode 100644 Inu/Src/main/optical_bus.c create mode 100644 Inu/Src/main/optical_bus.h create mode 100644 Inu/Src/main/optical_bus_tools.c create mode 100644 Inu/Src/main/optical_bus_tools.h create mode 100644 Inu/Src/main/overheat_limit.c create mode 100644 Inu/Src/main/overheat_limit.h create mode 100644 Inu/Src/main/params.h create mode 100644 Inu/Src/main/params_alg.h create mode 100644 Inu/Src/main/params_bsu.h create mode 100644 Inu/Src/main/params_hwp.h create mode 100644 Inu/Src/main/params_motor.h create mode 100644 Inu/Src/main/params_norma.h create mode 100644 Inu/Src/main/params_protect_adc.h create mode 100644 Inu/Src/main/params_pwm24.h create mode 100644 Inu/Src/main/params_temper_p.h create mode 100644 Inu/Src/main/pll_tools.c create mode 100644 Inu/Src/main/pll_tools.h create mode 100644 Inu/Src/main/project.c create mode 100644 Inu/Src/main/project.h create mode 100644 Inu/Src/main/project_setup.h create mode 100644 Inu/Src/main/protect_levels.h create mode 100644 Inu/Src/main/pump_control.c create mode 100644 Inu/Src/main/pump_control.h create mode 100644 Inu/Src/main/pwm_logs.c create mode 100644 Inu/Src/main/pwm_logs.h create mode 100644 Inu/Src/main/pwm_test_lines.c create mode 100644 Inu/Src/main/pwm_test_lines.h create mode 100644 Inu/Src/main/ramp_zadanie_tools.c create mode 100644 Inu/Src/main/ramp_zadanie_tools.h create mode 100644 Inu/Src/main/sbor_shema.c create mode 100644 Inu/Src/main/sbor_shema.h create mode 100644 Inu/Src/main/sim_model.c create mode 100644 Inu/Src/main/sim_model.h create mode 100644 Inu/Src/main/sync_tools.c create mode 100644 Inu/Src/main/sync_tools.h create mode 100644 Inu/Src/main/synhro_tools.c create mode 100644 Inu/Src/main/synhro_tools.h create mode 100644 Inu/Src/main/temper_p_tools.c create mode 100644 Inu/Src/main/temper_p_tools.h create mode 100644 Inu/Src/main/tk_Test.c create mode 100644 Inu/Src/main/tk_Test.h create mode 100644 Inu/Src/main/ukss_tools.c create mode 100644 Inu/Src/main/ukss_tools.h create mode 100644 Inu/Src/main/uom_tools.c create mode 100644 Inu/Src/main/uom_tools.h create mode 100644 Inu/Src/main/v_pwm24_v2.c create mode 100644 Inu/Src/main/v_pwm24_v2.h create mode 100644 Inu/Src/main/v_rotor.c create mode 100644 Inu/Src/main/v_rotor.h create mode 100644 Inu/Src/main/v_rotor_22220.c create mode 100644 Inu/Src/main/v_rotor_22220.h create mode 100644 Inu/Src/main/vector.h create mode 100644 Inu/Src/main/xPlatesAddress.h create mode 100644 Inu/Src/main_matlab/DSP281x_Device.h create mode 100644 Inu/Src/main_matlab/DSP281x_Ev.h create mode 100644 Inu/Src/main_matlab/DSP281x_Examples.h create mode 100644 Inu/Src/main_matlab/DSP281x_GlobalPrototypes.h create mode 100644 Inu/Src/main_matlab/DSP281x_SWPrioritizedIsrLevels.h create mode 100644 Inu/Src/main_matlab/IQmathLib.h create mode 100644 Inu/Src/main_matlab/IQmathLib_matlab.c create mode 100644 Inu/Src/main_matlab/adc_tools.h create mode 100644 Inu/Src/main_matlab/adc_tools_matlab.c create mode 100644 Inu/Src/main_matlab/dmctype.h create mode 100644 Inu/Src/main_matlab/errors_matlab.c create mode 100644 Inu/Src/main_matlab/io_verbal_names.h create mode 100644 Inu/Src/main_matlab/main_matlab.c create mode 100644 Inu/Src/main_matlab/main_matlab.h create mode 100644 Inu/Src/main_matlab/old/PWMTools.c create mode 100644 Inu/Src/main_matlab/old/v_pwm24.c create mode 100644 Inu/Src/main_matlab/old/v_pwm24.h create mode 100644 Inu/Src/main_matlab/old/xp_write_xpwm_time.h create mode 100644 Inu/Src/main_matlab/rotation_speed_matlab.c create mode 100644 Inu/Src/main_matlab/v_pwm24_matlab.c create mode 100644 Inu/Src/main_matlab/xp_write_xpwm_time_matlab.c create mode 100644 Inu/Src2/VectorControl/abc_to_alphabeta.c create mode 100644 Inu/Src2/VectorControl/abc_to_alphabeta.h create mode 100644 Inu/Src2/VectorControl/abc_to_dq.c create mode 100644 Inu/Src2/VectorControl/abc_to_dq.h create mode 100644 Inu/Src2/VectorControl/alphabeta_to_abc.c create mode 100644 Inu/Src2/VectorControl/alphabeta_to_abc.h create mode 100644 Inu/Src2/VectorControl/alphabeta_to_dq.c create mode 100644 Inu/Src2/VectorControl/alphabeta_to_dq.h create mode 100644 Inu/Src2/VectorControl/dq_to_alphabeta_cos.c create mode 100644 Inu/Src2/VectorControl/dq_to_alphabeta_cos.h create mode 100644 Inu/Src2/VectorControl/efficiency_compensation.c create mode 100644 Inu/Src2/VectorControl/efficiency_compensation.h create mode 100644 Inu/Src2/VectorControl/params_motor.h create mode 100644 Inu/Src2/VectorControl/pwm_vector_regul.c create mode 100644 Inu/Src2/VectorControl/pwm_vector_regul.h create mode 100644 Inu/Src2/VectorControl/regul_power.c create mode 100644 Inu/Src2/VectorControl/regul_power.h create mode 100644 Inu/Src2/VectorControl/regul_turns.c create mode 100644 Inu/Src2/VectorControl/regul_turns.h create mode 100644 Inu/Src2/VectorControl/teta_calc.c create mode 100644 Inu/Src2/VectorControl/teta_calc.h create mode 100644 Inu/Src2/main/IQmathLib.c create mode 100644 Inu/Src2/main/IQmathLib.h create mode 100644 Inu/Src2/main/PWMTools.c create mode 100644 Inu/Src2/main/PWMTools.h create mode 100644 Inu/Src2/main/adc_tools.c create mode 100644 Inu/Src2/main/adc_tools.h create mode 100644 Inu/Src2/main/dmctype.h create mode 100644 Inu/Src2/main/my_filter.c create mode 100644 Inu/Src2/main/my_filter.h create mode 100644 Inu/Src2/main/params.h create mode 100644 Inu/Src2/main/pid_reg3.c create mode 100644 Inu/Src2/main/pid_reg3.h create mode 100644 Inu/Src2/main/rotation_speed.h create mode 100644 Inu/Src2/main/svgen_dq.h create mode 100644 Inu/Src2/main/svgen_dq_v2.c create mode 100644 Inu/Src2/main/v_pwm24.c create mode 100644 Inu/Src2/main/v_pwm24.h create mode 100644 Inu/Src2/main/vector.h create mode 100644 Inu/Src2/main/word_structurs.h create mode 100644 Inu/Src2/main/xp_write_xpwm_time.c create mode 100644 Inu/Src2/main/xp_write_xpwm_time.h create mode 100644 Inu/controller.c create mode 100644 Inu/controller.h create mode 100644 Inu/def.h create mode 100644 Inu/detcoeff.c create mode 100644 Inu/detcoeff.h create mode 100644 Inu/init28335.c create mode 100644 Inu/init28335.h create mode 100644 Inu/isr.c create mode 100644 Inu/isr.h create mode 100644 Inu/main.c create mode 100644 Inu/main.h create mode 100644 Inu/param.c create mode 100644 Inu/param.h create mode 100644 Inu/upr.c create mode 100644 Inu/upr.h create mode 100644 Inu/wrapper_inu.c create mode 100644 Inu/wrapper_inu.h create mode 100644 ReadMe.txt create mode 100644 allmex.m create mode 100644 am_two_wind.mexw64 create mode 100644 asynchronous_machine.p create mode 100644 electr_mach.slx create mode 100644 init.m create mode 100644 inu_im_2wnd_3lvl.slx create mode 100644 inu_im_2wnd_3lvl.slx.original create mode 100644 inu_im_2wnd_3lvl.slx.r2021a create mode 100644 inu_im_2wnd_3lvl.slxc create mode 100644 run_mex.bat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16adf2c --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +/.vs/Inu_im_2wnd_3lvl_23550/v16/.suo +/.vs/Inu_im_2wnd_3lvl_23550/v16/Browse.VC.db +/.vs/Inu_im_2wnd_3lvl_23550/v16/Browse.VC.db-shm +/.vs/Inu_im_2wnd_3lvl_23550/v16/Browse.VC.db-wal +/.vs/Inu_im_2wnd_3lvl_23550/v16/Browse.VC.opendb +/.vs/ProjectSettings.json +/.vs/slnx.sqlite +/slprj/_cgxe/inu_im_2wnd_3lvl/inu_im_2wnd_3lvl_Cache.mat +/slprj/_jitprj/4jSHq6tpkAOru8OWjpPNFB.l +/slprj/_jitprj/4jSHq6tpkAOru8OWjpPNFB.mat +/slprj/accel/inu_im_2wnd_3lvl/amsi_serial.mat +/slprj/accel/inu_im_2wnd_3lvl/inu_im_2wnd_3lvl_instrumentation_settings.mat +/slprj/accel/inu_im_2wnd_3lvl/inu_im_2wnd_3lvl_SolverChangeInfo.mat +/slprj/accel/inu_im_2wnd_3lvl/inu_im_2wnd_3lvl_top_vm.bc +/slprj/accel/inu_im_2wnd_3lvl/inu_im_2wnd_3lvl_top_vm.ll +/slprj/accel/inu_im_2wnd_3lvl/tmwinternal/simulink_cache.xml +/slprj/sim/varcache/inu_im_2wnd_3lvl/checksumOfCache.mat +/slprj/sim/varcache/inu_im_2wnd_3lvl/tmwinternal/simulink_cache.xml +/slprj/sim/varcache/inu_im_2wnd_3lvl/varInfo.mat +/slprj/sl_proj.tmw + + + +/slprj/ +/.vs/ \ No newline at end of file diff --git a/Inu/Src/.vscode/c_cpp_properties.json b/Inu/Src/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..c6f5321 --- /dev/null +++ b/Inu/Src/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**;", + "C:/ti/ccs1011/ccs/tools/compiler/ti-cgt-c2000_20.2.1.LTS/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "cStandard": "c99", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64", + "compilerPath": "C:/ti/ccs1011/ccs/tools/compiler/ti-cgt-c2000_20.2.1.LTS/bin/cl2000.exe" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Inu/Src/VectorControl/abc_to_alphabeta.c b/Inu/Src/VectorControl/abc_to_alphabeta.c new file mode 100644 index 0000000..e0ea922 --- /dev/null +++ b/Inu/Src/VectorControl/abc_to_alphabeta.c @@ -0,0 +1,23 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "abc_to_alphabeta.h" + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(abc_to_alphabeta_calc,".fast_run"); +void abc_to_alphabeta_calc(ABC_TO_ALPHABETA *v) +{ + static _iq iq_1_sqrt3 = _IQ(0.57735026918962576450914878050196); // = 1/sqrt(3) + static _iq iq_2_sqrt3 = _IQ(1.1547005383792515290182975610039); // =2/sqrt(3) + + v->Ualpha = v->Ua; + v->Ubeta = _IQmpy(iq_1_sqrt3,v->Ua) + _IQmpy(iq_2_sqrt3,v->Ub); + +} + + + +///////////////////////////////////////////////// diff --git a/Inu/Src/VectorControl/abc_to_alphabeta.h b/Inu/Src/VectorControl/abc_to_alphabeta.h new file mode 100644 index 0000000..8d3f23b --- /dev/null +++ b/Inu/Src/VectorControl/abc_to_alphabeta.h @@ -0,0 +1,39 @@ +#ifndef __ABC_ALPHABETA_H__ +#define __ABC_ALPHABETA_H__ + + + +typedef struct { _iq Ua; //phase A voltage, input + _iq Ub; //phase B voltage, input + _iq Uc; //phase C voltage, input +// _iq Tetta; //phase angle, input + _iq Ualpha; // axis d voltage, output + _iq Ubeta; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + }ABC_TO_ALPHABETA; + + + + + +typedef ABC_TO_ALPHABETA *ABC_TO_ALPHABETA_handle; + +#define ABC_TO_ALPHABETA_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(unsigned long))abc_to_alphabeta_calc\ + } + + +void abc_to_alphabeta_calc(ABC_TO_ALPHABETA_handle); + + + + + + + + +#endif // end __ABC_ALPHABETA_H diff --git a/Inu/Src/VectorControl/abc_to_dq.c b/Inu/Src/VectorControl/abc_to_dq.c new file mode 100644 index 0000000..8044f2c --- /dev/null +++ b/Inu/Src/VectorControl/abc_to_dq.c @@ -0,0 +1,39 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "abc_to_dq.h" + + + + + + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(abc_to_dq_calc,".fast_run"); +void abc_to_dq_calc(ABC_TO_DQ *v) +{ + static _iq iq_two_third_pi = _IQ(6.283185307179586476925286766559/3.0); + static _iq iq_two_third = _IQ(2.0/3.0); + + v->Id = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQsin(v->Tetta)) + _IQmpy(v->Ib, _IQsin(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQsin(v->Tetta + iq_two_third_pi))); + v->Iq = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQcos(v->Tetta)) + _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); +} + + +#pragma CODE_SECTION(abc_to_dq_calc_v2,".fast_run"); +void abc_to_dq_calc_v2(ABC_TO_DQ *v) +{ + static _iq iq_two_third_pi = _IQ(6.283185307179586476925286766559/3.0); + static _iq iq_two_third = _IQ(2.0/3.0); + + v->Id = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQcos(v->Tetta)) + _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); + v->Iq = _IQmpy(iq_two_third,_IQmpy(-v->Ia, _IQsin(v->Tetta)) - _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) - _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); +} + + +///////////////////////////////////////////////// + + diff --git a/Inu/Src/VectorControl/abc_to_dq.h b/Inu/Src/VectorControl/abc_to_dq.h new file mode 100644 index 0000000..57e3de6 --- /dev/null +++ b/Inu/Src/VectorControl/abc_to_dq.h @@ -0,0 +1,42 @@ +#ifndef __ABC_DQ_H__ +#define __ABC_DQ_H__ + + + +typedef struct { _iq Ia; //phase A voltage, input + _iq Ib; //phase B voltage, input + _iq Ic; //phase C voltage, input + _iq Tetta; //phase angle, input + _iq Id; // axis d voltage, output + _iq Iq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + void (*calc_v2)(); // Pointer to calculation function + }ABC_TO_DQ; + + + + + +typedef ABC_TO_DQ *ABC_TO_DQ_handle; + +#define ABC_TO_DQ_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))abc_to_dq_calc, \ + (void (*)(Uint32))abc_to_dq_calc_v2 } + + +void abc_to_dq_calc(ABC_TO_DQ_handle); +void abc_to_dq_calc_v2(ABC_TO_DQ_handle); + + + + + + + + +#endif // end __ABC_DQ_H diff --git a/Inu/Src/VectorControl/alg_pll.c b/Inu/Src/VectorControl/alg_pll.c new file mode 100644 index 0000000..b7f3a9c --- /dev/null +++ b/Inu/Src/VectorControl/alg_pll.c @@ -0,0 +1,577 @@ +#include "IQmathLib.h" +#include "alg_pll.h" +#include "params_pll.h" + +#include "params_norma.h" + +//#define NORMA_ACP 3000 +//#define FREQ_PWM_VIPR 1975 + +//#define SIZE_PLL_AVG 50 + +//_iq w_in_avg[SIZE_PLL_AVG]; +//_iq w_out_avg[SIZE_PLL_AVG]; + +#define DETECT_PLL_D (2000.0/NORMA_ACP) // ampl +#define DETECT_PLL_Q (500.0/NORMA_ACP) // zero + +_iq iqDetect_PLL_d=_IQ(DETECT_PLL_D); +_iq iqDetect_PLL_q=_IQ(DETECT_PLL_Q); + +#define MAX_COUNT_ERR_PLL 5000 //20 + +#ifdef USE_SMOOTH_FOR_CALC_WC +SMOOTH mysmooth=SMOOTH_DEFAULTS; +#endif + + +// +/////////////////////////////////////////// +//PLL_REC pll2 = PLL_REC_DEFAULT; +/////////////////////////////////////////// + + +ABC_TO_ALPHABETA abc_to_alphabeta_u_input = ABC_TO_ALPHABETA_DEFAULTS; +ALPHABETA_TO_DQ alphabeta_to_dq_u_input = ALPHABETA_TO_DQ_DEFAULTS; +PIDREG3 pidUdq = PIDREG3_DEFAULTS; + +//int count_wait_pll=0; +int count_err_pll = 0; + + +//int c_start=0; +//int c_stop=0; + +#define MAX_TIME_WAIT_PLL 5000 + + +//_iq iqUab=0, iqUbc=0, iqUca=0; + + +//_iq koef_Um_filter = _IQ(0.000125/0.09); + + +//_iq koef_AddIq_minus_1_filter = _IQ(0.00034/0.009);//9576244354248046875 + +#pragma CODE_SECTION(minus_plus_2_pi,".fast_run"); +_iq minus_plus_2_pi(_iq a) +{ + + while (a>=CONST_IQ_2PI) + a -= CONST_IQ_2PI; + + while (a<=-CONST_IQ_2PI) + a += CONST_IQ_2PI; + + return a; +} + + +#pragma CODE_SECTION(minus_plus_2_pi_v2,".fast_run"); +_iq minus_plus_2_pi_v2(_iq a) +{ + + while (a>=CONST_IQ_2PI) + a -= CONST_IQ_2PI; + + while (a<0) + a += CONST_IQ_2PI; + + return a; +} + + + +#pragma CODE_SECTION(AB_BC_CA_To_ABC,".fast_run"); +void AB_BC_CA_To_ABC(_iq U_AB, _iq U_BC, _iq U_CA, _iq *Ua, _iq *Ub, _iq *Uc) +{ +// static _iq c2 = _IQ(2.0); + +// static _iq c13_sqrt = _IQ(1.7320508075688772935274463415059 / 3.0); + + *Ua = U_AB; + *Ub = U_BC; + *Uc = U_CA; +/* + + + *Ua = _IQmpy(c13_sqrt, (_IQmpy(c2,U_AB)+U_BC));// 2*U_AB/3+U_BC/3; + *Ub = _IQmpy(c13_sqrt, (_IQmpy(c2,U_BC)+U_CA));// 2*U_BC/3+U_CA/3; + *Uc = _IQmpy(c13_sqrt, (_IQmpy(c2,U_CA)+U_AB));// 2*U_CA/3+U_AB/3; +*/ +} + + + + +///////////////////////////////////////////////// +#pragma CODE_SECTION(PLLController,".fast_run"); +///////////////////////////////////////////////// +void PLLController(PLL_REC *v) +{ + static unsigned int count_wait_pll=0; + static _iq prev_Tetta_z=0; + _iq Tetta_z_t=0; + static int prev_flag_find_pll = 0; + static int flag_reset_Tetta_p = 0; +// static _iq prev_Tetta_v2 = 0; + + + v->vars.Uab = v->input.Input_U_AB - v->vars.iqZeroUAB; + v->vars.Ubc = v->input.Input_U_BC - v->vars.iqZeroUBC; + v->vars.Uca = v->input.Input_U_CA - v->vars.iqZeroUCA; + + v->vars.sum_zeroU_AB_BC_CA = v->vars.Uab + v->vars.Ubc + v->vars.Uca; + + if (v->setup.rotation_u_cba) + { + AB_BC_CA_To_ABC(v->vars.Uab, v->vars.Uca, v->vars.Ubc, &v->vars.Ua, &v->vars.Ub, &v->vars.Uc); + } + else + { + AB_BC_CA_To_ABC(v->vars.Uab,v->vars.Ubc,v->vars.Uca, &v->vars.Ua, &v->vars.Ub, &v->vars.Uc); + } +#ifdef ROTATION_U_CBA + +#else + +#endif + + v->vars.sum_zeroU_A_B_C = v->vars.Ua + v->vars.Ub + v->vars.Uc; + + abc_to_alphabeta_u_input.Ua = v->vars.Ua; + abc_to_alphabeta_u_input.Ub = v->vars.Ub; + abc_to_alphabeta_u_input.Uc = v->vars.Uc; + + abc_to_alphabeta_u_input.calc(&abc_to_alphabeta_u_input); + + + v->vars.Ualpha = abc_to_alphabeta_u_input.Ualpha; + v->vars.Ubeta = abc_to_alphabeta_u_input.Ubeta; + + + alphabeta_to_dq_u_input.Ualpha = v->vars.Ualpha; + alphabeta_to_dq_u_input.Ubeta = v->vars.Ubeta; + alphabeta_to_dq_u_input.Tetta = v->vars.Tetta; + + alphabeta_to_dq_u_input.calc(&alphabeta_to_dq_u_input); + + + v->vars.pll_Ud = alphabeta_to_dq_u_input.Ud; + v->vars.pll_Uq = alphabeta_to_dq_u_input.Uq; + + +// pidUdq.Fdb = v->pll_Ud;//.pll_Uq; //err = Ref - Fdb +// pidUdq.Ref = 0; + + pidUdq.Ref = v->vars.pll_Uq; //err = Ref - Fdb + pidUdq.Fdb = 0; + + pidUdq.calc(&pidUdq); + v->vars.wc = pidUdq.Out; + + + if (prev_flag_find_pll==0) + { + flag_reset_Tetta_p = 0; + } + + if (v->output.flag_find_pll) + { +#ifdef USE_SMOOTH_FOR_CALC_WC + mysmooth.input = _IQtoIQ23(v->vars.wc); + mysmooth.add(&mysmooth); + mysmooth.calc(&mysmooth); + v->vars.w_shtrih = _IQ23toIQ(mysmooth.av); +#else + v->vars.w_shtrih = v->vars.wc; +#endif + } + else + { + v->vars.w_shtrih = v->vars.wc; + } + + + v->vars.Tetta += v->vars.wc; + v->vars.Tetta = minus_plus_2_pi(v->vars.Tetta); // +- 2PI + + if (v->output.flag_find_pll) + { + v->vars.dwc = v->vars.wc - v->vars.w_shtrih; + + v->vars.Tetta_p += v->vars.dwc; + v->vars.Tetta_p = minus_plus_2_pi(v->vars.Tetta_p); // +- 2PI + + v->vars.dTetta = v->vars.Tetta - v->vars.Tetta_p;// + iq_05Pi; + + v->vars.dTetta = minus_plus_2_pi(v->vars.dTetta); // +- 2PI + + v->vars.Tetta_z = v->vars.dTetta; + +// if (v->Tetta_z>=iq_05Pi && prev_Tetta_z<iq_05Pi) +// v->Tetta_p = 0; + + Tetta_z_t = minus_plus_2_pi_v2(v->vars.Tetta_z); + + if ( (Tetta_z_t>=0) && (Tetta_z_t<CONST_IQ_PI05) && ( (prev_Tetta_z>(CONST_IQ_2PI-CONST_IQ_PI05)) ) ) + { + if (flag_reset_Tetta_p==0) + { + v->vars.Tetta_p = 0; +// flag_reset_Tetta_p = 1; + } + } + + + prev_Tetta_z = Tetta_z_t; + +#ifdef USE_FILTER_TETTA +//use filter teta + v->vars.Tetta_v2 = v->vars.Tetta_z;//v->Tetta; +#else +//use mgnoven teta + v->vars.Tetta_v2 = v->vars.Tetta; +#endif + v->vars.delta_Tetta_c = v->vars.Tetta_z - v->vars.Tetta; + +// prev_Tetta_v2 = v->Tetta_v2; + + } + else + { + v->vars.Tetta_v2 = v->vars.Tetta; + flag_reset_Tetta_p = 0; + } + + +// PLL OK? +//count_wait_pll=0 +//new alg find pll + if (v->vars.w_shtrih >= v->vars.find_min_w_strih && v->vars.w_shtrih <= v->vars.find_max_w_strih) + { + if (v->vars.count_wait_pll_w_shtrih < v->vars.max_time_wait_pll_w_strih) + v->vars.count_wait_pll_w_shtrih++; + } + else + { + if (v->vars.count_wait_pll_w_shtrih>0) + v->vars.count_wait_pll_w_shtrih--; + } + + if (v->vars.count_wait_pll_w_shtrih == v->vars.max_time_wait_pll_w_strih) + v->output.flag_find_pll = 1; + + if (v->vars.count_wait_pll_w_shtrih == 0) + v->output.flag_find_pll = 0; + +//end new alg find pll + + + + if ( (_IQabs(v->vars.pll_Uq)<=_IQabs(iqDetect_PLL_q)) // zero + && (_IQabs(v->vars.pll_Ud)>=_IQabs(iqDetect_PLL_d) ) //ampl + ) + { + count_err_pll=0; + if (count_wait_pll<MAX_TIME_WAIT_PLL) + count_wait_pll++; + else + // ok, pll finded + v->output.flag_find_pll = 1; + } + else + { + if (count_err_pll>=MAX_COUNT_ERR_PLL) + { + // fail find pll + count_wait_pll=0; + + v->output.flag_find_pll = 0; + + if (v->output.flag_find_pll==1) + { + v->vars.pll_Uq = 0; + v->vars.pll_Ud = 0; + } + + } + else + { + count_err_pll++; + if ((v->output.flag_find_pll==0) && (count_wait_pll>0)) + count_wait_pll--; + } + } + +// end PLL Ok? + + + v->vars.pi_teta_u_out = pidUdq.Out; + v->vars.pi_teta_u_i = pidUdq.Ui; + v->vars.pi_teta_u_p = pidUdq.Up; + + + prev_flag_find_pll = v->output.flag_find_pll; +} + +////////////////////////////////////////////////// +////////////////////////////////////////////////// +////////////////////////////////////////////////// +///////////////////////////////////////////////// +//#pragma CODE_SECTION(pll_get_freq,".fast_run"); +///////////////////////////////////////////////// +void pll_get_freq_float(PLL_REC *v) +{ + + if (v->output.flag_find_pll) + { + v->output.int_freq_net = _IQtoF( v->vars.w_shtrih) * v->setup.freq_run_pll / PI * 50.00; // freq*100 + } + else + { + v->output.int_freq_net = 0; + } + +} + +////////////////////////////////////////////////// +////////////////////////////////////////////////// +void pll_get_freq_iq(PLL_REC *v) +{ + + if (v->output.flag_find_pll) + { + v->output.iq_freq_net = v->vars.w_shtrih;//_IQtoF( v->vars.w_shtrih) * v->setup.freq_run_pll / PI * 50.00; // freq*100 + } + else + { + v->output.iq_freq_net = 0; + } + +} + +////////////////////////////////////////////////// +//#pragma CODE_SECTION(detect_phase_count,".fast_run"); +void detect_phase_count(PLL_REC *v) +{ + static _iq prev_Ua = 0; + static int prev_flag_find_pll=0; + + + +// abc_to_dq.Ua + + if ((v->output.flag_find_pll != prev_flag_find_pll) && (v->output.flag_find_pll == 1)) + { + prev_Ua = v->vars.Ua; + v->vars.enable_detect_phase_count = 1; + v->vars.error_phase_count = 0; + } + + + if (v->output.flag_find_pll==0) + v->vars.enable_detect_phase_count = 0; + + + if (v->output.flag_find_pll) + { + if (v->vars.enable_detect_phase_count) + { + if ( (prev_Ua<0) && (v->vars.Ua>=0) ) + { + + if (v->vars.Uc > v->vars.Ub) + v->vars.enable_detect_phase_count = 0; + + if (v->vars.Ub > v->vars.Uc) + { + v->vars.enable_detect_phase_count = 0; + v->vars.error_phase_count = 1; + } + } + } + } + + + prev_flag_find_pll = v->output.flag_find_pll; + prev_Ua = v->vars.Ua; + +} +///////////////////////////////////////////////// + + +//////////////////////////////////////////////// + +#pragma CODE_SECTION(Find_zero_Uabc,".fast_run"); +void Find_zero_Uabc(PLL_REC *v) +{ + static int c_a=0; +// static int c_b=0; +// static int c_c=0; + + static _iq sum_a=0; + static _iq sum_b=0; + static _iq sum_c=0; + + _iq22 sum_t,c_t; + + _iq22 sum_div; + + +// AB_BC_CA_To_ABC(analog.iqUin_AB-iqZeroUABC, analog.iqUin_BC-iqZeroUABC, analog.iqUin_CA-iqZeroUABC); + + + sum_a += v->input.Input_U_AB; // analog.iqUin_AB; + sum_b += v->input.Input_U_BC; // analog.iqUin_BC; + sum_c += v->input.Input_U_CA; // analog.iqUin_CA; + + c_a++; + + if (c_a >= v->vars.count_sum_find_zero_uabc) + { + sum_div = v->vars.sum_div_find_zero_uabc; + + sum_t = _IQtoIQ22(sum_a); + c_t = _IQ22div(sum_t,sum_div); + v->vars.iqZeroUAB = _IQ22toIQ(c_t); + + sum_t = _IQtoIQ22(sum_b); + c_t = _IQ22div(sum_t,sum_div); + v->vars.iqZeroUBC = _IQ22toIQ(c_t); + + sum_t = _IQtoIQ22(sum_c); + c_t = _IQ22div(sum_t,sum_div); + v->vars.iqZeroUCA = _IQ22toIQ(c_t); + + sum_a = 0; + sum_b = 0; + sum_c = 0; + c_a = 0; + } + +} + + + + + +void pll_init(PLL_REC *v) +{ + v->output.status = STATUS_PLL_NOT_INITED; + + abc_to_alphabeta_u_input.Ua = 0; + abc_to_alphabeta_u_input.Ub = 0; + abc_to_alphabeta_u_input.Uc = 0; + abc_to_alphabeta_u_input.Ualpha = 0; + abc_to_alphabeta_u_input.Ubeta = 0; + + alphabeta_to_dq_u_input.Tetta = 0; + alphabeta_to_dq_u_input.Ualpha = 0; + alphabeta_to_dq_u_input.Ubeta = 0; + alphabeta_to_dq_u_input.Ud = 0; + alphabeta_to_dq_u_input.Uq = 0; + + v->vars.count_wait_pll_w_shtrih = 0; + + v->vars.pll_Ud = 0; + v->vars.pll_Uq = 0; + v->vars.Tetta = 0; + v->vars.Tetta_p = 0; + + v->vars.Ua = 0; + v->vars.Ub = 0; + v->vars.Uc = 0; + + v->vars.Ualpha = 0; + v->vars.Ubeta = 0; + +// count_wait_pll = 0; + count_err_pll = 0; + v->output.flag_find_pll = 0; + + pidUdq.Kp = _IQ(v->setup.pid_kp_pll); + pidUdq.Ki = _IQ(v->setup.pid_ki_pll); + + pidUdq.Kc = _IQ(PID_KC_PLL); + pidUdq.Kd = _IQ(0.0); + + pidUdq.OutMax = _IQ(K_PLL_MAX); + pidUdq.OutMin = _IQ(K_PLL_MIN); + + pidUdq.Err = 0; + pidUdq.Out = 0; + pidUdq.OutPreSat = 0; + pidUdq.SatErr = 0; + + if (v->setup.freq_run_pll == 0) + v->setup.freq_run_pll = DEFAULT_FREQ_RUN_PLL; + + pidUdq.Ui = _IQ(2.0*PI*DEFAULT_FREQ_NET/(v->setup.freq_run_pll)); + +// iqDetect_PLL_d = iqDetect_PLL_d; +// iqDetect_PLL_q = iqDetect_PLL_q; + +#ifdef USE_SMOOTH_FOR_CALC_WC + mysmooth.init(&mysmooth); +#endif + + + v->vars.count_sum_find_zero_uabc = v->setup.freq_run_pll/DEFAULT_FREQ_NET; //79*2 //1975/50*2 + v->vars.sum_div_find_zero_uabc = _IQ22(v->vars.count_sum_find_zero_uabc); + + v->vars.find_max_w_strih = _IQ(FIND_MAX_W_STRIH*2.0*PI*DEFAULT_FREQ_NET/(v->setup.freq_run_pll)); + v->vars.find_min_w_strih = _IQ(FIND_MIN_W_STRIH*2.0*PI*DEFAULT_FREQ_NET/(v->setup.freq_run_pll)); + + v->vars.max_time_wait_pll_w_strih = (v->vars.count_sum_find_zero_uabc * MAX_PERIOD_WAIT_PLL_W_SHTRIH); + + v->output.status = STATUS_PLL_INITED; + +} + + + + +#pragma CODE_SECTION(read_error_find_pll,".fast_run2"); +int read_error_find_pll(PLL_REC *v) +{ +// static int enable_detect_pll_err=0; +// static int prev_flag_find_pll=0; + static int err_pll=0; + + + err_pll = 0; +/* + if ((v->output.flag_find_pll!=prev_flag_find_pll) + && (v->output.flag_find_pll==1)) + { + enable_detect_pll_err = 1; + } + prev_flag_find_pll = v->output.flag_find_pll; + + if (v->input.enable_find_pll==0) + enable_detect_pll_err = 0; + + if ((enable_detect_pll_err) && (v->output.flag_find_pll==0) && (v->input.enable_find_pll==1)) + { + err_pll = 1; + } +*/ + return err_pll; +} + + + + +#pragma CODE_SECTION(pll_calc,".fast_run"); +void pll_calc(PLL_REC *v) +{ + if (v->output.status >= STATUS_PLL_INITED) + { + Find_zero_Uabc(v); + PLLController(v); +// detect_phase_count(v); + v->output.status = STATUS_PLL_OK; + } + +} diff --git a/Inu/Src/VectorControl/alg_pll.h b/Inu/Src/VectorControl/alg_pll.h new file mode 100644 index 0000000..0a63dde --- /dev/null +++ b/Inu/Src/VectorControl/alg_pll.h @@ -0,0 +1,188 @@ +#ifndef __ALG_PLL_H__ +#define __ALG_PLL_H__ + +#include "IQmathLib.h" +#include "math_pi.h" +#include "pid_reg3.h" +#include "abc_to_alphabeta.h" +#include "alphabeta_to_dq.h" +#include "smooth.h" +#include "smooth.h" + + +#define DEFAULT_FREQ_NET 50.00 // Hz + +#define DEFAULT_FREQ_RUN_PLL 4000 // Hz + +#define DEFAULT_PID_KP_PLL 0.0375 +#define DEFAULT_PID_KI_PLL 0.0128 + +#define STATUS_PLL_OK 10 + +#define STATUS_PLL_ERROR 2 +#define STATUS_PLL_INITED 1 +#define STATUS_PLL_NOT_INITED 0 + +#define FIND_MAX_W_STRIH 1.5 //0.12 //75Hz +#define FIND_MIN_W_STRIH 0.5 //0.045 //33Hz + +#define MAX_PERIOD_WAIT_PLL_W_SHTRIH 3 + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +typedef struct { + float pid_kp_pll; // ����. ���������� Kp ��� ������ ���� + float pid_ki_pll; // ����. ���������� Ki ��� ������ ���� + int freq_run_pll; // ������� ������� �������, ��. + int rotation_u_cba; // ����������� ���: 0 - ���������� A-B-C, 1 - ������������ A-C-B + } PLL_SETUP; + +#define PLL_SETUP_DEFAULT {DEFAULT_PID_KP_PLL, DEFAULT_PID_KI_PLL, DEFAULT_FREQ_RUN_PLL,0} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +typedef struct { _iq Input_U_AB; // ������� ���������� Uab + _iq Input_U_BC; // ������� ���������� Ubc + _iq Input_U_CA; // ������� ���������� Uca + } PLL_INPUT; + +#define PLL_INPUT_DEFAULT {0, 0, 0} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +typedef struct { int flag_find_pll; + int int_freq_net; + _iq iq_freq_net; + int status; + } PLL_OUTPUT; + +#define PLL_OUTPUT_DEFAULT {0, 0, 0, STATUS_PLL_NOT_INITED} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +typedef struct { + int enable_detect_phase_count; + int error_phase_count; + + _iq pll_Ud; + _iq pll_Uq; + _iq Tetta; + _iq Tetta_v2; + + _iq wc; + _iq dwc; + _iq w_shtrih; + + _iq Tetta_z; + _iq Tetta_p; + _iq dTetta; + + _iq zeroPLL; + _iq pi_teta_u_out; + _iq pi_teta_u_p; + _iq pi_teta_u_i; + _iq add_teta; + _iq add_teta2; + + _iq Ua; + _iq Ub; + _iq Uc; + + + _iq Uab; + _iq Ubc; + _iq Uca; + + _iq Ualpha; + _iq Ubeta; + + _iq iqZeroUAB; + _iq iqZeroUBC; + _iq iqZeroUCA; + + _iq sum_zeroU_AB_BC_CA; + _iq sum_zeroU_A_B_C; + + _iq delta_Tetta_c; + _iq22 sum_div_find_zero_uabc; + int count_sum_find_zero_uabc; + + _iq find_max_w_strih; + _iq find_min_w_strih; + + int count_wait_pll_w_shtrih; + int max_time_wait_pll_w_strih;//MAX_TIME_WAIT_PLL_W_SHTRIH + + int enable_find_pll; + + + }PLL_VARS;//39 + +#define PLL_VARS_DEFAULT {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +typedef struct { PLL_INPUT input; + PLL_OUTPUT output; + PLL_SETUP setup; + PLL_VARS vars; + void (*init)(); // Pointer to calculation function + void (*calc_pll)(); // Pointer to calculation function + void (*get_freq_float)(); // Pointer to calculation function + void (*get_freq_iq)(); + }PLL_REC; + +typedef PLL_REC *PLL_REC_handle; + +#define PLL_REC_DEFAULT {\ + PLL_INPUT_DEFAULT,\ + PLL_OUTPUT_DEFAULT,\ + PLL_SETUP_DEFAULT,\ + PLL_VARS_DEFAULT,\ + (void (*)(unsigned long))pll_init,\ + (void (*)(unsigned long))pll_calc,\ + (void (*)(unsigned long))pll_get_freq_float,\ + (void (*)(unsigned long))pll_get_freq_iq \ + } + +void pll_init(PLL_REC_handle); +void pll_calc(PLL_REC_handle); +void pll_get_freq_float(PLL_REC_handle); +void pll_get_freq_iq(PLL_REC_handle); + +void Find_zero_Uabc(PLL_REC_handle); +void PLLController(PLL_REC *v); +void AB_BC_CA_To_ABC(_iq U_AB, _iq U_BC, _iq U_CA, _iq *Ua, _iq *Ub, _iq *Uc); +void detect_phase_count(PLL_REC *v); +int read_error_find_pll(PLL_REC *v); + + + +_iq minus_plus_2_pi(_iq a); +_iq minus_plus_2_pi_v2(_iq a); + + + + + + + +#endif + + + + + + diff --git a/Inu/Src/VectorControl/alphabeta_to_dq.c b/Inu/Src/VectorControl/alphabeta_to_dq.c new file mode 100644 index 0000000..ffa5a73 --- /dev/null +++ b/Inu/Src/VectorControl/alphabeta_to_dq.c @@ -0,0 +1,24 @@ +#include "IQmathLib.h" // Include header for IQmath library + +#include "alphabeta_to_dq.h" + + + + + + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(alphabeta_to_dq_calc,".fast_run"); +void alphabeta_to_dq_calc(ALPHABETA_TO_DQ *v) +{ + + v->Ud = _IQmpy(v->Ualpha, _IQcos(v->Tetta)) + _IQmpy(v->Ubeta, _IQsin(v->Tetta)); + v->Uq = -_IQmpy(v->Ualpha, _IQsin(v->Tetta)) + _IQmpy(v->Ubeta, _IQcos(v->Tetta)); + +} +///////////////////////////////////////////////// diff --git a/Inu/Src/VectorControl/alphabeta_to_dq.h b/Inu/Src/VectorControl/alphabeta_to_dq.h new file mode 100644 index 0000000..8484e14 --- /dev/null +++ b/Inu/Src/VectorControl/alphabeta_to_dq.h @@ -0,0 +1,32 @@ +#ifndef __ALPHABETA_DQ_H__ +#define __ALPHABETA_DQ_H__ + + + +typedef struct { _iq Ualpha; //phase A voltage, input + _iq Ubeta; //phase B voltage, input + _iq Tetta; //phase angle, input + _iq Ud; // axis d voltage, output + _iq Uq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + }ALPHABETA_TO_DQ; + + + + + +typedef ALPHABETA_TO_DQ *ALPHABETA_TO_DQ_handle; + +#define ALPHABETA_TO_DQ_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(unsigned long))alphabeta_to_dq_calc \ + } + + +void alphabeta_to_dq_calc(ALPHABETA_TO_DQ_handle); + + +#endif // end __ALPHABETA_DQ_H diff --git a/Inu/Src/VectorControl/dq_to_alphabeta_cos.c b/Inu/Src/VectorControl/dq_to_alphabeta_cos.c new file mode 100644 index 0000000..d075df4 --- /dev/null +++ b/Inu/Src/VectorControl/dq_to_alphabeta_cos.c @@ -0,0 +1,39 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "dq_to_alphabeta_cos.h" + + + + + + +///////////////////////////////////////////////// + + +//#pragma CODE_SECTION(dq_to_alphabeta_calc,".fast_run2"); +void dq_to_alphabeta_calc(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQcos(v->Tetta)) + _IQmpy(v->Uq, _IQsin(v->Tetta)); + v->Ubeta = -_IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + +} + + +//#pragma CODE_SECTION(dq_to_alphabeta_calc2,".fast_run2"); +void dq_to_alphabeta_calc2(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + v->Ubeta = -_IQmpy(v->Ud, _IQcos(v->Tetta)) + _IQmpy(v->Uq, _IQsin(v->Tetta)); + +} + +//#pragma CODE_SECTION(dq_to_alphabeta_calc_cos,".fast_run2"); +void dq_to_alphabeta_calc_cos(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQcos(v->Tetta)) - _IQmpy(v->Uq, _IQsin(v->Tetta)); + v->Ubeta = _IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + +} +///////////////////////////////////////////////// diff --git a/Inu/Src/VectorControl/dq_to_alphabeta_cos.h b/Inu/Src/VectorControl/dq_to_alphabeta_cos.h new file mode 100644 index 0000000..b261ced --- /dev/null +++ b/Inu/Src/VectorControl/dq_to_alphabeta_cos.h @@ -0,0 +1,40 @@ + + + +#ifndef __DQ_ALPHABETA_H__ +#define __DQ_ALPHABETA_H__ + +#include "IQmathLib.h" + +typedef struct { _iq Ualpha; //phase A voltage, input + _iq Ubeta; //phase B voltage, input + _iq Tetta; //phase angle, input + _iq Ud; // axis d voltage, output + _iq Uq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + void (*calc2)(); // Pointer to calculation function. Like in MATLAB + void (*calc_cos)(); // Pointer to calculation function, Ualpha = Uq*Cos(Tetta) + }DQ_TO_ALPHABETA; + + + + + +typedef DQ_TO_ALPHABETA *DQ_TO_ALPHABETA_handle; + +#define DQ_TO_ALPHABETA_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))dq_to_alphabeta_calc, \ + (void (*)(Uint32))dq_to_alphabeta_calc2, \ + (void (*)(Uint32))dq_to_alphabeta_calc_cos \ + } + + +void dq_to_alphabeta_calc(DQ_TO_ALPHABETA_handle); +void dq_to_alphabeta_calc2(DQ_TO_ALPHABETA_handle); +void dq_to_alphabeta_calc_cos(DQ_TO_ALPHABETA_handle); + +#endif // end __DQ_ALPHABETA_H__ diff --git a/Inu/Src/VectorControl/params_pll.h b/Inu/Src/VectorControl/params_pll.h new file mode 100644 index 0000000..2ec9466 --- /dev/null +++ b/Inu/Src/VectorControl/params_pll.h @@ -0,0 +1,41 @@ +#ifndef __PARAMS_PLL_H__ +#define __PARAMS_PLL_H__ + + +//#define USE_SMOOTH_FOR_CALC_WC 1 // ������������ ���. �������� ���������� ��� ������ ���� + + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +// stend params +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +//////////// +//PLL +/////////// + +//23470 params +//#define PID_KP_PLL 0.00375 +//#define PID_KI_PLL 0.128 + +//ship1 +#define DEFAULT_PID_KP_PLL 0.0375 +#define DEFAULT_PID_KI_PLL 0.0128 + + +// + +#define PID_KC_PLL 1.000 //0.16 //0.05 //0.1 //20 //200 +// +#define K_PLL_MAX 10.0 //1000000 +#define K_PLL_MIN -10.0 //-1000000 +// + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +// end params +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + +#endif + diff --git a/Inu/Src/VectorControl/regul_power.c b/Inu/Src/VectorControl/regul_power.c new file mode 100644 index 0000000..d78f216 --- /dev/null +++ b/Inu/Src/VectorControl/regul_power.c @@ -0,0 +1,88 @@ +/* + * regul_power.c + * + * Created on: 16 ����. 2020 �. + * Author: star + */ +#include "IQmathLib.h" +#include "regul_power.h" + +#include <edrk_main.h> +#include <master_slave.h> +#include <params_motor.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include "math.h" + +#include "mathlib.h" + +#define TIME_RMP_SLOW 20.0 //sec +#define TIME_RMP_FAST 20.0 //sec + +POWER power = POWER_DEFAULTS; + +void init_Pvect(void) { + power.pidP.Ref = 0; + power.pidP.Kp = _IQ(1); + power.pidP.Ki = _IQ(0.1); + power.pidP.Kc = _IQ(0.5); + power.pidP.OutMax = _IQ(MOTOR_CURRENT_MAX / 2.0 / NORMA_ACP); + power.pidP.OutMin = -_IQ(MOTOR_CURRENT_MAX / 2.0 / NORMA_ACP); + + power.Pzad_rmp = 0; + power.koef_fast = _IQ(FROT_NOMINAL / (float)NORMA_FROTOR / TIME_RMP_FAST / (float)FREQ_PWM); + power.koef_slow = _IQ(FROT_NOMINAL / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM); + power.Iq_out_max = _IQ(MOTOR_CURRENT_MAX / 2.0 / NORMA_ACP); + power.Pnominal = _IQ(P_NOMINAL * 1000.0 / NORMA_ACP / NORMA_ACP); +} + +#pragma CODE_SECTION(vector_power,".fast_run"); +_iq vector_power(_iq Pzad, _iq P_measured, int n_alg, unsigned int master, + _iq Iq_measured, _iq Iq_limit, _iq *Iq_zad, int reset) +{ + static int prev_n_alg = 0; + _iq Iq_out = 0; + _iq koef_rmp = 0; + if (n_alg != ALG_MODE_FOC_POWER || !edrk.Go || master != MODE_MASTER || reset) { + power.pidP.Ui = Iq_measured; + power.pidP.Out = Iq_measured; + if (reset) { power.Pzad_rmp = 0; } + } + if (n_alg == ALG_MODE_FOC_OBOROTS) { + Pzad = power.Pnominal; + } + if (master == MODE_SLAVE) { + power.Pzad_rmp = P_measured; + return *Iq_zad; + } + + //��� �������� �� ������ ����������� �������� � ����� ����������� ��������, + //�.�. � ������ ����������� �������� ������ ������� ������������ ���������� �������� + if (n_alg == ALG_MODE_FOC_POWER && prev_n_alg != ALG_MODE_FOC_POWER) { + power.Pzad_rmp = P_measured; + } + + if((_IQabs(power.Pzad_rmp) <= _IQabs(Pzad)) && + (((Pzad >= 0) && (power.Pzad_rmp >= 0)) || ((Pzad < 0) && (power.Pzad_rmp < 0)))) + { + koef_rmp = power.koef_slow; + } + else + { + koef_rmp = power.koef_fast; + } + power.Pzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, power.Pzad_rmp, Pzad); + + power.pidP.OutMax = Iq_limit; + power.pidP.OutMin = -Iq_limit; + power.pidP.Ref = power.Pzad_rmp; + power.pidP.Fdb = P_measured; + power.pidP.calc(&power.pidP); + Iq_out = power.pidP.Out; + Iq_out = _IQsat(Iq_out, Iq_limit, -Iq_limit); + *Iq_zad = Iq_out; + + prev_n_alg = n_alg; + + return Iq_out; +} diff --git a/Inu/Src/VectorControl/regul_power.h b/Inu/Src/VectorControl/regul_power.h new file mode 100644 index 0000000..80d3e06 --- /dev/null +++ b/Inu/Src/VectorControl/regul_power.h @@ -0,0 +1,30 @@ +/* + * regul_power.h + * + * Created on: 16 ����. 2020 �. + * Author: star + */ + +#ifndef SRC_VECTORCONTROL_NIO12_REGUL_POWER_H_ +#define SRC_VECTORCONTROL_NIO12_REGUL_POWER_H_ + +#include "pid_reg3.h" + +typedef struct { + PIDREG3 pidP; + _iq Pzad_rmp; + _iq koef_fast; + _iq koef_slow; + _iq Iq_out_max; + _iq Pnominal; +} POWER; + +#define POWER_DEFAULTS {PIDREG3_DEFAULTS, 0,0,0,0,0} + +_iq vector_power(_iq Pzad, _iq P_measured, int mode, unsigned int master, + _iq Iq_measured, _iq Iq_limit, _iq* Frot_zad, int reset); +void init_Pvect(void); + +extern POWER power; + +#endif /* SRC_VECTORCONTROL_NIO12_REGUL_POWER_H_ */ diff --git a/Inu/Src/VectorControl/regul_turns.c b/Inu/Src/VectorControl/regul_turns.c new file mode 100644 index 0000000..95ca611 --- /dev/null +++ b/Inu/Src/VectorControl/regul_turns.c @@ -0,0 +1,143 @@ +#include "DSP281x_Device.h" +#include "IQmathLib.h" + +#include "regul_turns.h" + +#include <adc_tools.h> +#include <edrk_main.h> +#include <master_slave.h> +#include <params.h> +#include <params_motor.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include "math.h" +#include "mathlib.h" +#include "pid_reg3.h" +#include "vector_control.h" + +#pragma DATA_SECTION(turns,".fast_vars1"); +TURNS turns = TURNS_DEFAULTS; + + //IQ_OUT_NOM TODO:set Iq nominal + +#define IQ_165_RPM 2306867 //165��/��� +#define IQ_170_RPM 2376772 //170��/��� +#define IQ_5_RPM 69905 //5��/��� + +#define TIME_RMP_FAST 10.0 //sec +#define TIME_RMP_SLOW 30.0 //sec +#define F_DEST 3.0 //Hz + +void init_Fvect() +{ + turns.pidFvect.Ref = 0; + turns.pidFvect.Kp = _IQ(5); // //_IQ(30); + turns.pidFvect.Ki = _IQ(0.005); //_IQ(0.008);//_IQ(0.002); // + turns.pidFvect.Kc = _IQ(0.5); + turns.pidFvect.OutMax = _IQ(MOTOR_CURRENT_MAX / 2.0 / NORMA_ACP); + turns.pidFvect.OutMin = -_IQ(MOTOR_CURRENT_MAX / 2.0 / NORMA_ACP); + + turns.Fzad_rmp = 0; + turns.Fnominal = _IQ(FROT_MAX / NORMA_FROTOR); + turns.koef_fast = + _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 1.0); + turns.koef_slow = + _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 1.0); + turns.Iq_out_max = _IQ(MOTOR_CURRENT_MAX / NORMA_ACP); + turns.Id_out_max = 0;//_IQ(ID_OUT_NOM / NORMA_ACP); + turns.mzz_zad_int = 0; +} + +void reset_F_pid() +{ + turns.pidFvect.Up = 0; + turns.pidFvect.Up1 = 0; + turns.pidFvect.Ui = 0; + turns.pidFvect.Ud = 0; + turns.pidFvect.Out = 0; +} + +//#pragma CODE_SECTION(vector_turns,".fast_run2"); +void vector_turns(_iq Fzad, _iq Frot, + _iq Iq_measured, _iq Iq_limit, int n_alg, + unsigned int master, _iq *Iq_zad, int reset) +{ + static int prev_n_alg = 0; + _iq koef_rmp; //, koef_spad; + _iq Iq_out_unsat, Iq_out_sat, Id_out_sat, Id_out_unsat; + _iq deltaVar; + +// turns.mzz_zad_int = zad_intensiv_q(35480, 35480, turns.mzz_zad_int, Iq_limit); + turns.mzz_zad_int = Iq_limit; + + turns.pidFvect.OutMax = turns.mzz_zad_int; + turns.pidFvect.OutMin = -turns.mzz_zad_int; + + //������� ����� ���������� + if (Fzad >= 0 && Frot > 0) + { + turns.pidFvect.OutMin = 0; + } + if (Fzad <= 0 && Frot < 0) + { + turns.pidFvect.OutMax = 0; + } + if (reset) { turns.Fzad_rmp = Frot;} + + if ((n_alg < ALG_MODE_FOC_OBOROTS) || (!edrk.Go)) + //������� ������� ��������� � �����-���, ��� �� ��� ����� ������ �� ���� ������� + { // + turns.Fzad_rmp = Frot; +// prev_Fzad = Frot; + reset_F_pid(); //���� ����, ����� ���� ���-�� ���� �� ��� + turns.pidFvect.Ui = Iq_measured; + turns.pidFvect.Out = Iq_measured; + *Iq_zad = Iq_measured; + + if (!edrk.Go) + { + *Iq_zad = 0; + } + + return; + } + if (master == MODE_SLAVE) { + turns.Fzad_rmp = Frot; + turns.pidFvect.Ui = Iq_measured; + turns.pidFvect.Out = Iq_measured; + return; + } + //� ������ ����������� �������� �������� ������������ ���������� ������� + if (n_alg == ALG_MODE_FOC_POWER) { + Fzad = turns.Fnominal; + } + //��� �������� �� ������ ����������� ������� � ����� ����������� �������� + //����� ����� �� �������� �������� �������� + if (n_alg == ALG_MODE_FOC_OBOROTS && prev_n_alg != ALG_MODE_FOC_OBOROTS) { + turns.Fzad_rmp = Frot; + } + + if (_IQabs(turns.Fzad_rmp) <= _IQabs(Fzad) + && (((Fzad >= 0) && (turns.Fzad_rmp >= 0)) + || ((Fzad < 0) && (turns.Fzad_rmp < 0)))) + { + koef_rmp = turns.koef_slow; + } + else + { + koef_rmp = turns.koef_fast; + } + + turns.Fzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, turns.Fzad_rmp, Fzad); + + turns.pidFvect.Ref = turns.Fzad_rmp; + turns.pidFvect.Fdb = Frot; + + turns.pidFvect.calc(&turns.pidFvect); + Iq_out_unsat = turns.pidFvect.Out; + + Iq_out_sat = _IQsat(Iq_out_unsat, turns.mzz_zad_int, -turns.mzz_zad_int); //Test + *Iq_zad = Iq_out_sat; + + prev_n_alg = n_alg; +} diff --git a/Inu/Src/VectorControl/regul_turns.h b/Inu/Src/VectorControl/regul_turns.h new file mode 100644 index 0000000..f765b88 --- /dev/null +++ b/Inu/Src/VectorControl/regul_turns.h @@ -0,0 +1,29 @@ +#ifndef REGUL_TURNS +#define REGUL_TURNS +#include "IQmathLib.h" +#include "pid_reg3.h" + +typedef struct { + PIDREG3 pidFvect; + + _iq Fzad_rmp; + _iq Fnominal; + _iq koef_fast; + _iq koef_slow; + _iq Iq_out_max; + _iq Id_out_max; + _iq mzz_zad_int; +} TURNS; + +#define TURNS_DEFAULTS {PIDREG3_DEFAULTS, 0,0,0,0,0,0,0} + +void init_Fvect(void); +void vector_turns(_iq Fzad, _iq Frot, + _iq Iq, _iq Iq_limit, int mode, + unsigned int master, _iq *Iq_zad, int reset); + +extern TURNS turns; + +#endif //REGUL_TURNS + + diff --git a/Inu/Src/VectorControl/smooth.c b/Inu/Src/VectorControl/smooth.c new file mode 100644 index 0000000..dcf63c8 --- /dev/null +++ b/Inu/Src/VectorControl/smooth.c @@ -0,0 +1,180 @@ +#include "IQmathLib.h" // Include header for IQmath library + +#include "smooth.h" +#include "math_pi.h" +#include "math_pi.h" + + +#define SIZE_SMOOTH_INPUT 180 + + +#pragma CODE_SECTION(my_mean,".fast_run"); +_iq23 my_mean(int cnt, SMOOTH *v) +{ + _iq23 summ = 0; + int start; + + + start = v->current_pos_buf_input; + if (start==0) + start = (MAX_SIZE_SMOOTH_INPUT-1); + + while(cnt>0) + { + cnt--; + start--; + summ += v->buf_input[start]; + if (start==0) + start = (MAX_SIZE_SMOOTH_INPUT-1); + } + return summ; + +} + + + +void smooth_init(SMOOTH *v) +{ + int i=0; + + v->c = 1; + v->av = 0; + v->w = _IQ23(WINDOW_START); + + for (i=0;i<MAX_SIZE_SMOOTH_INPUT;i++) + { + v->buf_input[i] = 0; + } +// current_pos_buf_input = 0; + v->current_pos_buf_input = 0; + +} + +#pragma CODE_SECTION(smooth_add,".fast_run"); +void smooth_add(SMOOTH *v) +{ + volatile int i; + + i = v->current_pos_buf_input; + v->buf_input[i] = v->input; + + v->current_pos_buf_input++; + if (v->current_pos_buf_input>=MAX_SIZE_SMOOTH_INPUT) + v->current_pos_buf_input = 0; + +} + + +#pragma CODE_SECTION(smooth_calc,".fast_run"); +void smooth_calc(SMOOTH *v) +{ + _iq23 e=0; + _iq23 summ=0; + _iq23 w_new; + long w_int; + + w_int = _IQ23int(v->w); + + if (v->c <= (WINDOW_START*2)) + { + summ = my_mean(v->c,v); + v->av = _IQ23div(summ,_IQ23(v->c)); + e = 0; + } + else + { + e = _IQ23div(CONST_IQ_2PI,v->av) - v->w; //(2*pi*fs/av) - w + v->ee = v->ee + _IQ23mpy(v->kp,(e - v->e0)) + _IQ23mpy(v->ki, e); + w_new = v->w + v->ee; + + if (w_new>_IQ23(SIZE_SMOOTH_INPUT)) + w_new = _IQ23(SIZE_SMOOTH_INPUT); + + w_int = _IQ23int(w_new); + summ = my_mean(w_int,v); + v->w = _IQ23(w_int); + v->av = _IQ23div(summ, v->w); + + } + + if (v->c<SIZE_SMOOTH_INPUT) + v->c++; + + v->e0 = e; + v->w_int = w_int; +} + + +#pragma CODE_SECTION(smooth_simple_calc,".fast_run"); +void smooth_simple_calc(SMOOTH *v) +{ + volatile _iq23 summ=0; + + if (v->c <= v->w_int_simple ) + { + summ = my_mean(v->c, v); + v->summ = summ; + v->av = _IQ23div(summ,_IQ23(v->c)); + } + else + { + summ = my_mean(v->w_int_simple, v); + v->summ = summ; + v->av = _IQ23div(summ, _IQ23(v->w_int_simple)); + } + + if (v->c<MAX_SIZE_SMOOTH_INPUT) + v->c++; + + +} + + + + +void iq_smooth (_iq23 *input, _iq23 *output, int n, int window) +{ + int i,j,z,k1,k2,hw; + int fm1,fm2; + + _iq23 tmp; + + + fm1 = window/2; + fm2 = fm1*2; + if ((window-fm2)==0) + window++; + + hw = (window-1)/2; + output[0] = input[0]; + + for (i=1;i<n;i++) + { + tmp=0; + if(i<hw) + { + k1=0; + k2=2*i; + z=k2+1; + } + else if((i+hw)>(n-1)) + { + k1=i-n+i+1; + k2=n-1; + z=k2-k1+1; + } + else + { + k1=i-hw; + k2=i+hw; + z=window; + } + + for (j=k1;j<=k2;j++) + { + tmp=tmp + input[j]; + } + output[i] = _IQ23div(tmp,_IQ23(z)); + } + +} diff --git a/Inu/Src/VectorControl/smooth.h b/Inu/Src/VectorControl/smooth.h new file mode 100644 index 0000000..c91e6f1 --- /dev/null +++ b/Inu/Src/VectorControl/smooth.h @@ -0,0 +1,78 @@ +#ifndef __SMOOTH_H__ +#define __SMOOTH_H__ + +#define WINDOW_START 79.0 //39.0 +#define MAX_SIZE_SMOOTH_INPUT 180 + +typedef struct { int current_pos_buf_input; + _iq23 kp; + _iq23 ki; + int c; + int w_int_simple; + _iq23 w; + long w_int; + _iq23 ee; + _iq23 e0; + _iq23 av; + _iq23 input; + _iq23 summ; + _iq23 buf_input[MAX_SIZE_SMOOTH_INPUT]; + void (*init)(); // Pointer to calculation function + void (*add)(); // Pointer to calculation function + void (*calc)(); // Pointer to calculation function + void (*simple_calc)(); // Pointer to calculation function + + }SMOOTH; + + + + + +typedef SMOOTH *SMOOTH_handle; + +#define SMOOTH_DEFAULTS { 0, \ + _IQ23(0.1), \ + _IQ23(0.01), \ + 1, \ + 1, \ + _IQ23(WINDOW_START), \ + WINDOW_START, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + {0},\ + (void (*)(unsigned long))smooth_init,\ + (void (*)(unsigned long))smooth_add,\ + (void (*)(unsigned long))smooth_calc,\ + (void (*)(unsigned long))smooth_simple_calc\ + } + + +void smooth_calc(SMOOTH_handle); +void smooth_init(SMOOTH_handle); +void smooth_add(SMOOTH_handle); +void smooth_simple_calc(SMOOTH_handle); + + + + + + +void iq_smooth (_iq23 *input, _iq23 *output, int n, int window); + + + + +#endif // end __ABC_ALPHABETA_H + + + + + + + + + + diff --git a/Inu/Src/VectorControl/teta_calc.c b/Inu/Src/VectorControl/teta_calc.c new file mode 100644 index 0000000..8a64daf --- /dev/null +++ b/Inu/Src/VectorControl/teta_calc.c @@ -0,0 +1,91 @@ +#include "IQmathLib.h" + +#include "teta_calc.h" + +#include <master_slave.h> +#include <params_alg.h> +#include <params_motor.h> +#include <params_norma.h> +#include <params_pwm24.h> + +#include "mathlib.h" +#include "pid_reg3.h" + + +#define CONST_IQ_2PI 105414357 +#define PI 3.1415926535897932384626433832795 + +#define MAX_Ud_Pid_Out_Id 176160 //0.2 ~ 167772 //0.21 ~ 176160 +#define BPSI_START 0.17 //0.15 + +TETTA_CALC tetta_calc = TETTA_CALC_DEF; + +void init_teta_calc_struct() +{ + float Tr_cm = (L_M + L_SIGMA_R) / (R_ROTOR_SHTRIH / SLIP_NOM); +// tetta_calc.k_r = _IQ(1 / FREQ_PWM / Tr_cm); +// tetta_calc.k_t = _IQ(R_ROTOR / (L_M + L_SIGMA_R) / 2.0 / 3.14 / 50 / NORMA_FROTOR); + tetta_calc.k_r = _IQ(0.005168); //_IQ(0.015); + tetta_calc.k_t = _IQ(0.0074); //_IQ(0.0045); + tetta_calc.Imds = 0; + tetta_calc.theta = 0; + tetta_calc.hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM); +} + +//#pragma CODE_SECTION(calc_teta_Id,".fast_run"); +void calc_teta_Id(_iq Frot, _iq Id, _iq Iq, _iq *theta_out, _iq *theta_to_slave, _iq *Fsl_out, _iq *Fstator_out, + unsigned int master, int reset) { + + _iq Fsl, Fst; + _iq add_to_tic = 0; + _iq to_slave = 0; + + if (reset) { + tetta_calc.Imds = 0; + } + + tetta_calc.Imds = tetta_calc.Imds + _IQmpy(tetta_calc.k_r, (Id - tetta_calc.Imds)); + + if (master == MODE_SLAVE){ + return; + } + + Fsl = _IQmpy(tetta_calc.k_t, Iq); + if (tetta_calc.Imds != 0) { + Fsl = _IQdiv(Fsl, tetta_calc.Imds); + } else { + Fsl = 0; + } + + if (Fsl > MAX_Ud_Pid_Out_Id) { Fsl = MAX_Ud_Pid_Out_Id;} + if (Fsl < -MAX_Ud_Pid_Out_Id) { Fsl = -MAX_Ud_Pid_Out_Id;} +// if (Fsl < 0) { Fsl = 0;} + + Fst = Frot * POLUS + Fsl; + add_to_tic = _IQmpy(Fst, tetta_calc.hz_to_angle); + tetta_calc.theta += add_to_tic; + to_slave = tetta_calc.theta + add_to_tic; + + if (tetta_calc.theta > CONST_IQ_2PI) { + tetta_calc.theta -= CONST_IQ_2PI; + } else if (tetta_calc.theta < 0) { + tetta_calc.theta += CONST_IQ_2PI; + } + + if (to_slave > CONST_IQ_2PI) { + to_slave -= CONST_IQ_2PI; + } else if (to_slave < 0) { + to_slave += CONST_IQ_2PI; + } + + *Fsl_out = Fsl; + *theta_out = tetta_calc.theta; + *theta_to_slave = to_slave; + *Fstator_out = Fst; + +// logpar.log26 = (int16)(_IQtoIQ15(Fsl)); +// logpar.log27 = (int16)(_IQtoIQ15(tetta_calc.Imds)); +// logpar.log28 = (int16)(_IQtoIQ15(Iq)); +// logpar.log3 = (int16)(_IQtoIQ15(Id)); +} + diff --git a/Inu/Src/VectorControl/teta_calc.h b/Inu/Src/VectorControl/teta_calc.h new file mode 100644 index 0000000..d2e7b03 --- /dev/null +++ b/Inu/Src/VectorControl/teta_calc.h @@ -0,0 +1,36 @@ +#ifndef TETA_CALC +#define TETA_CALC + +#include "IQmathLib.h" +#include "pid_reg3.h" + +void calc_teta_Id(_iq Frot, _iq Id, _iq Iq, _iq *tetta_out, _iq *theta_to_slave, _iq *Fsl_out, _iq *Fstator_out, + unsigned int master, int reset); +void init_teta_calc_struct(void); + +// k_r = Ts / Tr_cm +// Tr_cm = Lr / Rr +// Lr - ������������� ������ +// Rr - ������������� ������ +// +// k_t = 1 / (Tr_cm * 2 * Pi * f_b) +// � ����� ������ f_b = NORMA_FROT +// K = Ts * f_b +// f_b - ������� ������������� ������� (12 ��) +// Ts - ������ ������� (840 ��) + +typedef struct { + _iq Imds; + _iq theta; + + _iq hz_to_angle; + _iq k_r; + _iq k_t; +} TETTA_CALC; + +#define TETTA_CALC_DEF {0,0,0,0,0} + +extern TETTA_CALC tetta_calc; + +#endif //TETA_CALC + diff --git a/Inu/Src/VectorControl/vector_control.c b/Inu/Src/VectorControl/vector_control.c new file mode 100644 index 0000000..901b75d --- /dev/null +++ b/Inu/Src/VectorControl/vector_control.c @@ -0,0 +1,297 @@ +/* + * vector_control.c + * + * Created on: 16 ����. 2020 �. + * Author: star + */ +#include "IQmathLib.h" + +#include "vector_control.h" + +#include <adc_tools.h> +#include <edrk_main.h> +#include <master_slave.h> +#include <params_motor.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include "math.h" +#include "mathlib.h" +#include "filter_v1.h" +#include "abc_to_dq.h" +#include "regul_power.h" +#include "regul_turns.h" +#include "teta_calc.h" + +//#define CALC_TWO_WINDINGS + +#define I_ZERO_LEVEL_IQ 27962 // 111848 ~ 20A //279620 ~ 50A //55924 ~ 10A + + +#pragma DATA_SECTION(vect_control,".fast_vars"); +VECTOR_CONTROL vect_control = VECTOR_CONTROL_DEFAULTS; + + +void Idq_to_Udq_2_windings(_iq Id_zad, _iq Iq_zad, + _iq Id_measured1, _iq Iq_measured1, _iq* Ud_zad1, _iq* Uq_zad1, + _iq Id_measured2, _iq Iq_measured2, _iq* Ud_zad2, _iq* Uq_zad2, int reset); +void analog_Udq_calc(_iq Ud1, _iq Uq1, _iq Ud2, _iq Uq2); +void analog_dq_calc(_iq winding_displacement); +_iq calcId(_iq Iq_limit, _iq Iq, int reset, int prepare_stop_PWM); +inline void calcUdUqCompensation(_iq Frot); + +void initVectorControl() { + vect_control.pidD1.Kp = _IQ(0.3);//_IQ(0.2); + vect_control.pidD1.Ki = _IQ(0.01);//_IQ(0.9); + vect_control.pidD1.OutMax = _IQ(0.9); + vect_control.pidD1.OutMin = -_IQ(0.9); + vect_control.pidQ1.Kp = _IQ(0.3); + vect_control.pidQ1.Ki = _IQ(0.01); + vect_control.pidQ1.OutMax = _IQ(0.9); + vect_control.pidQ1.OutMin = -_IQ(0.9); + vect_control.pidD2.Kp = _IQ(0.3); + vect_control.pidD2.Ki = _IQ(0.3); + vect_control.pidD2.OutMax = _IQ(0.9); + vect_control.pidD2.OutMin = -_IQ(0.9); + vect_control.pidQ2.Kp = _IQ(0.3); + vect_control.pidQ2.Ki = _IQ(0.3); + vect_control.pidQ2.OutMax = _IQ(0.9); + vect_control.pidQ2.OutMin = -_IQ(0.9); + +// vect_control.iqId_nominal = _IQ(MOTOR_CURRENT_NOMINAL * sqrtf(1 - COS_FI * COS_FI) / NORMA_ACP); + vect_control.iqId_nominal = _IQ(MOTOR_CURRENT_NOMINAL * 0.4 / NORMA_ACP); + vect_control.iqId_min = _IQ(200 / NORMA_ACP); + vect_control.iqId_start = _IQ(200.0 / NORMA_ACP); + vect_control.koef_rmp_Id = (_iq)(vect_control.iqId_nominal / FREQ_PWM); + vect_control.koef_filt_I = _IQ(0.5); + + + vect_control.koef_Ud_comp = _IQ((L_SIGMA_S + L_M * L_SIGMA_R / (L_M + L_SIGMA_R)) * 2 * 3.14 * NORMA_FROTOR); //Lsigm_s + Lm*Lsigm_r / (Lm + Lsigm_r) + vect_control.koef_Uq_comp = _IQ((L_M + L_SIGMA_S) * 2 * 3.14 * NORMA_FROTOR); //Lm + Lsigm_s +// vect_control.koef_Ud_comp = _IQ(0.0002369 * 2 * 3.14 * NORMA_FROTOR); //Lsigm_s + Lm*Lsigm_r / (Lm + Lsigm_r) +// vect_control.koef_Uq_comp = _IQ(0.0043567 * 2 * 3.14 * NORMA_FROTOR); //Lm + Lsigm_s + vect_control.koef_zero_Uzad = _IQ(0.993); //_IQ(0.993); //_IQ(0.03); + init_Pvect(); + init_Fvect(); + init_teta_calc_struct(); +} + +void vectorControlConstId (_iq Pzad, _iq Fzad, int direction, _iq Frot, + int n_alg, unsigned int master, _iq mzz_zad, + _iq winding_displacement, + _iq theta_from_master, _iq Iq_from_master, _iq P_from_slave, + _iq *theta_to_slave, _iq *Iq_to_slave, _iq *P_to_master, + int reset, int prepare_stop_PWM) { + _iq Iq_zad = 0, Iq_zad_power = 0, Id_zad = 0; + _iq P_measured = 0; + static _iq Ud_zad1 = 0, Uq_zad1 = 0, Ud_zad2 = 0, Uq_zad2 = 0; + +// if(direction < 0) { Frot = -Frot; } + + if (reset) { + Ud_zad1 = 0; + Uq_zad1 = 0; + Ud_zad2 = 0; + Uq_zad2 = 0; + } + analog_dq_calc(winding_displacement); + + P_measured = vect_control.iqPvsi1 + vect_control.iqPvsi2; + *P_to_master = P_measured; + P_measured += P_from_slave; + + + + vector_power(Pzad, P_measured, n_alg, master, (vect_control.iqIq1 + vect_control.iqIq2), + edrk.zadanie.iq_Izad_rmp, &Iq_zad_power, reset); + vector_turns(Fzad, Frot, (vect_control.iqIq1 + vect_control.iqIq2), + Iq_zad_power, n_alg, master, &Iq_zad, reset); + + Id_zad = calcId(edrk.zadanie.iq_Izad, Iq_zad, reset, prepare_stop_PWM); + + if (master == MODE_SLAVE) { + vect_control.iqTheta = theta_from_master; + *theta_to_slave = theta_from_master; + Iq_zad = Iq_from_master; + Iq_zad_power = Iq_from_master; + } else { +// calc_teta_Id(Frot, vect_control.iqId1, vect_control.iqIq1, &vect_control.iqTheta, theta_to_slave, +// &vect_control.iqFsl, &vect_control.iqFstator, master, reset); + calc_teta_Id(Frot, Id_zad, Iq_zad, &vect_control.iqTheta, theta_to_slave, + &vect_control.iqFsl, &vect_control.iqFstator, master, reset); + } + + calcUdUqCompensation(Frot); + + if (prepare_stop_PWM && Id_zad == 0) { + vect_control.iqUdKm = _IQmpy(vect_control.iqUdKm, vect_control.koef_zero_Uzad); + vect_control.iqUqKm = _IQmpy(vect_control.iqUqKm, vect_control.koef_zero_Uzad); + } else { + Idq_to_Udq_2_windings((Id_zad >> 1), (Iq_zad >> 1), + vect_control.iqId1, vect_control.iqIq1, &Ud_zad1, &Uq_zad1, + vect_control.iqId2, vect_control.iqIq2, &Ud_zad2, &Uq_zad2, reset); + + vect_control.iqUdKm = Ud_zad1 + vect_control.iqUdCompensation; + vect_control.iqUqKm = Uq_zad1 + vect_control.iqUqCompensation; + } + + vect_control.sqrtIdq1 = _IQsqrt(_IQmpy(vect_control.iqId1, vect_control.iqId1) + _IQmpy(vect_control.iqIq1, vect_control.iqIq1)); + analog_Udq_calc(Ud_zad1, Uq_zad1, Ud_zad2, Uq_zad2); + *Iq_to_slave = Iq_zad; + + vect_control.Iq_zad1 = Iq_zad; + vect_control.Id_zad1 = Id_zad; + +} + + +#pragma CODE_SECTION(analog_dq_calc,".fast_run"); +void analog_dq_calc(_iq winding_displacement) +{ + ABC_TO_DQ abc_dq_converter = ABC_TO_DQ_DEFAULTS; + + abc_dq_converter.Ia = analog.iqIu_1; + abc_dq_converter.Ib = analog.iqIv_1; + abc_dq_converter.Ic = analog.iqIw_1; + abc_dq_converter.Tetta = vect_control.iqTheta + winding_displacement; + abc_dq_converter.calc(&abc_dq_converter); + vect_control.iqId1 = abc_dq_converter.Id; + vect_control.iqIq1 = abc_dq_converter.Iq; + vect_control.iqId1_filt = exp_regul_iq(vect_control.koef_filt_I, vect_control.iqId1_filt, vect_control.iqId1); + vect_control.iqIq1_filt = exp_regul_iq(vect_control.koef_filt_I, vect_control.iqIq1_filt, vect_control.iqIq1); + + abc_dq_converter.Ia = analog.iqIu_2; + abc_dq_converter.Ib = analog.iqIv_2; + abc_dq_converter.Ic = analog.iqIw_2; + abc_dq_converter.Tetta = vect_control.iqTheta + winding_displacement; + abc_dq_converter.calc(&abc_dq_converter); + vect_control.iqId2 = abc_dq_converter.Id; + vect_control.iqIq2 = abc_dq_converter.Iq; + vect_control.iqId2_filt = exp_regul_iq(vect_control.koef_filt_I, vect_control.iqId2_filt, vect_control.iqId2); + vect_control.iqIq2_filt = exp_regul_iq(vect_control.koef_filt_I, vect_control.iqIq2_filt, vect_control.iqIq2); + + + if (_IQabs(vect_control.iqId1) < I_ZERO_LEVEL_IQ) { vect_control.iqId1 = 0; } + if (_IQabs(vect_control.iqIq1) < I_ZERO_LEVEL_IQ) { vect_control.iqIq1 = 0; } + if (_IQabs(vect_control.iqId2) < I_ZERO_LEVEL_IQ) { vect_control.iqId2 = 0; } + if (_IQabs(vect_control.iqIq2) < I_ZERO_LEVEL_IQ) { vect_control.iqIq2 = 0; } + + vect_control.iqPvsi1 = _IQmpy(_IQmpy(vect_control.iqIq1, _IQabs(vect_control.iqUq1)), 25165824L); + vect_control.iqPvsi2 = _IQmpy(_IQmpy(vect_control.iqIq2, _IQabs(vect_control.iqUq2)), 25165824L); + +} + +#pragma CODE_SECTION(analog_dq_calc_external,".fast_run"); +void analog_dq_calc_external(_iq winding_displacement, _iq theta) +{ + ABC_TO_DQ abc_dq_converter = ABC_TO_DQ_DEFAULTS; + + abc_dq_converter.Ia = analog.iqIu_1; + abc_dq_converter.Ib = analog.iqIv_1; + abc_dq_converter.Ic = analog.iqIw_1; + abc_dq_converter.Tetta = theta + winding_displacement; + abc_dq_converter.calc(&abc_dq_converter); + vect_control.iqId1 = abc_dq_converter.Id; + vect_control.iqIq1 = abc_dq_converter.Iq; + + + abc_dq_converter.Ia = analog.iqIu_2; + abc_dq_converter.Ib = analog.iqIv_2; + abc_dq_converter.Ic = analog.iqIw_2; + abc_dq_converter.Tetta = theta + winding_displacement; + abc_dq_converter.calc(&abc_dq_converter); + vect_control.iqId2 = abc_dq_converter.Id; + vect_control.iqIq2 = abc_dq_converter.Iq; + + if (_IQabs(vect_control.iqId1) < I_ZERO_LEVEL_IQ) { vect_control.iqId1 = 0; } + if (_IQabs(vect_control.iqIq1) < I_ZERO_LEVEL_IQ) { vect_control.iqIq1 = 0; } + if (_IQabs(vect_control.iqId2) < I_ZERO_LEVEL_IQ) { vect_control.iqId2 = 0; } + if (_IQabs(vect_control.iqIq2) < I_ZERO_LEVEL_IQ) { vect_control.iqIq2 = 0; } + + vect_control.iqPvsi1 = _IQmpy(_IQmpy(vect_control.iqIq1, _IQabs(vect_control.iqUq1)), 25165824L); + vect_control.iqPvsi2 = _IQmpy(_IQmpy(vect_control.iqIq2, _IQabs(vect_control.iqUq2)), 25165824L); + +} + +void Idq_to_Udq_2_windings(_iq Id_zad, _iq Iq_zad, + _iq Id_measured1, _iq Iq_measured1, _iq* Ud_zad1, _iq* Uq_zad1, + _iq Id_measured2, _iq Iq_measured2, _iq* Ud_zad2, _iq* Uq_zad2, int reset) +{ + if (reset) { + vect_control.pidD1.Ui = 0; + vect_control.pidD1.Out = 0; + vect_control.pidQ1.Ui = 0; + vect_control.pidQ1.Out = 0; +#ifdef CALC_TWO_WINDINGS + vect_control.pidD2.Ui = 0; + vect_control.pidD2.Out = 0; + vect_control.pidQ2.Ui = 0; + vect_control.pidQ2.Out = 0; +#endif + } + vect_control.pidD1.Ref = Id_zad; + vect_control.pidD1.Fdb = Id_measured1; + vect_control.pidD1.calc(&vect_control.pidD1); + *Ud_zad1 = vect_control.pidD1.Out; + + vect_control.pidQ1.Ref = Iq_zad; + vect_control.pidQ1.Fdb = Iq_measured1; + vect_control.pidQ1.calc(&vect_control.pidQ1); + *Uq_zad1 = vect_control.pidQ1.Out; +#ifdef CALC_TWO_WINDINGS + vect_control.pidD2.Ref = Id_zad; + vect_control.pidD2.Fdb = Id_measured2; + vect_control.pidD2.calc(&vect_control.pidD2); + *Ud_zad2 = vect_control.pidD2.Out; + + vect_control.pidQ2.Ref = Iq_zad; + vect_control.pidQ2.Fdb = Iq_measured2; + vect_control.pidQ2.calc(&vect_control.pidQ2); + *Uq_zad2 = vect_control.pidQ2.Out; +#else + *Ud_zad2 = *Ud_zad1; + *Uq_zad2 = *Ud_zad1; +// *Uq_zad2 = *Uq_zad1; +#endif +} + +#pragma CODE_SECTION(analog_Udq_calc,".fast_run"); +void analog_Udq_calc(_iq Ud1, _iq Uq1, _iq Ud2, _iq Uq2) +{ + _iq Uzpt = filter.iqU_1_long + filter.iqU_2_long; + vect_control.iqUd1 = _IQmpy(Ud1, _IQmpy(Uzpt, 8388608L)); // 8388608 = _IQ(0.5) + vect_control.iqUq1 = _IQmpy(Uq1, _IQmpy(Uzpt, 8388608L)); + vect_control.iqUd2 = _IQmpy(Ud2, _IQmpy(Uzpt, 8388608L)); + vect_control.iqUq2 = _IQmpy(Uq2, _IQmpy(Uzpt, 8388608L)); + +} + +_iq calcId(_iq Iq_limit, _iq Iq, int reset, int prepare_stop_PWM) { + static _iq Id_rmp = 0; + _iq Id_zad = 0; + if (reset) { + Id_rmp = 0; + } + + + if (prepare_stop_PWM) { + Id_zad = 0; + } else if (Iq < vect_control.iqId_min) { + Id_zad = vect_control.iqId_min; + } else if (Iq > vect_control.iqId_nominal) { + Id_zad = vect_control.iqId_nominal; + } else { + Id_zad = Iq; + } +// Id_zad = Iq_limit < vect_control.iqId_nominal ? Iq_limit : vect_control.iqId_nominal; + Id_rmp = zad_intensiv_q(vect_control.koef_rmp_Id, vect_control.koef_rmp_Id << 1, Id_rmp, Id_zad); + return Id_rmp; +} + +void calcUdUqCompensation(_iq Frot) { + _iq Uzpt = (filter.iqU_1_long + filter.iqU_2_long) >> 1; + _iq UdVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Ud_comp), vect_control.iqIq1 + vect_control.iqIq2); + _iq UqVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Uq_comp), vect_control.iqId1 + vect_control.iqId2); + vect_control.iqUdCompensation = -_IQdiv(UdVolt, Uzpt); + vect_control.iqUqCompensation = _IQdiv(UqVolt, Uzpt); +} + diff --git a/Inu/Src/VectorControl/vector_control.h b/Inu/Src/VectorControl/vector_control.h new file mode 100644 index 0000000..3307fb1 --- /dev/null +++ b/Inu/Src/VectorControl/vector_control.h @@ -0,0 +1,82 @@ +/* + * vector_control.h + * + * Created on: 16 ����. 2020 �. + * Author: star + */ + +#ifndef SRC_VECTORCONTROL_NIO12_VECTOR_CONTROL_H_ +#define SRC_VECTORCONTROL_NIO12_VECTOR_CONTROL_H_ + +#include "pid_reg3.h" +#include "regul_power.h" +#include "regul_turns.h" + +typedef struct { + PIDREG3 pidD1; + PIDREG3 pidQ1; + PIDREG3 pidD2; + PIDREG3 pidQ2; + + _iq iqId1; + _iq iqIq1; + _iq iqId2; + _iq iqIq2; + _iq iqUd1; + _iq iqUq1; + _iq iqUd2; + _iq iqUq2; + _iq iqUdKm; + _iq iqUqKm; + _iq iqUdCompensation; + _iq iqUqCompensation; + + _iq iqId1_filt; + _iq iqIq1_filt; + _iq iqId2_filt; + _iq iqIq2_filt; + + _iq iqPvsi1; + _iq iqPvsi2; + _iq iqTheta; + _iq iqFsl; + _iq iqFstator; + _iq iqId_nominal; + _iq iqId_min; + _iq iqId_start; + _iq koef_rmp_Id; + _iq koef_filt_I; + _iq koef_Ud_comp; + _iq koef_Uq_comp; + _iq koef_zero_Uzad; + _iq add_tetta; + + _iq sqrtIdq1; + _iq sqrtIdq2; + + _iq Iq_zad1; + _iq Id_zad1; + + _iq add_bpsi; + +} VECTOR_CONTROL; + +#define VECTOR_CONTROL_DEFAULTS {PIDREG3_DEFAULTS, PIDREG3_DEFAULTS, \ + PIDREG3_DEFAULTS, PIDREG3_DEFAULTS, \ + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + +void vectorControlConstId (_iq Pzad, _iq Fzad, int direction, _iq Frot, + int n_alg, unsigned int master, _iq mzz_zad, + _iq winding_displacement, + _iq theta_from_master, _iq Iq_from_master, _iq P_from_slave, + _iq *theta_to_slave, _iq *Iq_to_slave, _iq *P_to_master, + int reset, int prepare_stop_PWM); + +void analog_dq_calc_external(_iq winding_displacement, _iq theta); +void initVectorControl(); + +extern VECTOR_CONTROL vect_control; + + +#endif /* SRC_VECTORCONTROL_NIO12_VECTOR_CONTROL_H_ */ diff --git a/Inu/Src/main/281xEvTimersInit.c b/Inu/Src/main/281xEvTimersInit.c new file mode 100644 index 0000000..59b7005 --- /dev/null +++ b/Inu/Src/main/281xEvTimersInit.c @@ -0,0 +1,636 @@ +// TI File $Revision: /main/3 $ +// Checkin $Date: July 2, 2007 11:32:13 $ +//########################################################################### +// +// FILE: Example_281xEvTimerPeriod.c +// +// TITLE: DSP281x Event Manager GP Timer example program. +// +// ASSUMPTIONS: +// +// This program requires the DSP281x V1.00 header files. +// As supplied, this project is configured for "boot to H0" operation. +// +// Other then boot mode pin configuration, no other hardware configuration +// is required. +// +// DESCRIPTION: +// +// This program sets up EVA Timer 1, EVA Timer 2, EVB Timer 3 +// and EVB Timer 4 to fire an interrupt on a period overflow. +// A count is kept each time each interrupt passes through +// the interrupt service routine. +// +// EVA Timer 1 has the shortest period while EVB Timer4 has the +// longest period. +// +// Watch Variables: +// +// EvaTimer1InterruptCount; +// EvaTimer2InterruptCount; +// EvbTimer3InterruptCount; +// EvbTimer4InterruptCount; +// +//########################################################################### +// $TI Release: DSP281x C/C++ Header Files V1.20 $ +// $Release Date: July 27, 2009 $ +//########################################################################### + +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "DSP281x_Examples.h" // DSP281x Examples Include File + +#include <281xEvTimersInit.h> +#include <f281xbmsk.h> + +#include "TuneUpPlane.h" +#include "profile_interrupt.h" + +// Prototype statements for functions found within this file. +interrupt void eva_timer1_isr(void); +interrupt void eva_timer2_isr(void); +interrupt void evb_timer3_isr(void); +interrupt void evb_timer4_isr(void); + + +// Global counts used in this example +Uint32 EvaTimer1InterruptCount = 0; +Uint32 EvaTimer2InterruptCount = 0; +Uint32 EvbTimer3InterruptCount = 0; +Uint32 EvbTimer4InterruptCount = 0; + +//unsigned int enable_profile_led1_Timer1 = 1; +//unsigned int enable_profile_led1_Timer2 = 1; +//unsigned int enable_profile_led1_Timer3 = 1; +//unsigned int enable_profile_led1_Timer4 = 1; +// +//unsigned int enable_profile_led2_Timer1 = 0; +//unsigned int enable_profile_led2_Timer2 = 0; +//unsigned int enable_profile_led2_Timer3 = 0; +//unsigned int enable_profile_led2_Timer4 = 0; + +//Pointers to handler functions +void (*timer1_handler)() = NULL; +void (*timer2_handler)() = NULL; +void (*timer3_handler)() = NULL; +void (*timer4_handler)() = NULL; + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +void init_eva_timer1(int freq, void (*timer_handler)()) +{ + // Initialize EVA Timer 1: + // Setup Timer 1 Registers (EV A) + EvaRegs.GPTCONA.all = 0; + + // Set the Period for the GP timer 1 to 0x0200; + EvaRegs.T1PR = 0x0200; // Period + EvaRegs.T1CMPR = 0x0000; // Compare Reg + + // Enable Period interrupt bits for GP timer 1 + // Count up, x128, internal clk, enable compare, use own period + EvaRegs.EVAIMRA.bit.T1PINT = 0;//1; + EvaRegs.EVAIFRA.all = BIT7; +// EvaRegs.EVAIFRA.bit.T1PINT = 1; + + // Clear the counter for GP timer 1 + EvaRegs.T1CNT = 0x0000; +// EvaRegs.T1PR = (float64)HSPCLK/(float64)(freq / 2); + EvaRegs.T1PR = (float64)HSPCLK/(float64)(freq); + EvaRegs.T1CON.all = FREE_RUN_FLAG + TIMER_CONT_UP + TIMER_CLK_PRESCALE_X_1 + + TIMER_ENABLE_BY_OWN + TIMER_ENABLE + TIMER_ENABLE_COMPARE; // + + // Start EVA ADC Conversion on timer 1 Period interrupt + EvaRegs.GPTCONA.bit.T1TOADC = 2; + + // Save pointer to handler in variable + timer1_handler = timer_handler; + + EALLOW; // This is needed to write to EALLOW protected registers + PieVectTable.T1PINT = &eva_timer1_isr; + EDIS; // This is needed to disable write to EALLOW protected registers + + // Enable PIE group 2 interrupt 4 for T1PINT +// PieCtrlRegs.PIEIER2.all = M_INT4; + PieCtrlRegs.PIEIER2.bit.INTx4 = 1; + + // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT + // and INT5 for T4PINT: + // IER |= M_INT2; +} + +void stop_eva_timer1() +{ + IER &= ~(M_INT2); + EvaRegs.EVAIMRA.bit.T1PINT = 0; +} + +void start_eva_timer1() +{ + IER |= (M_INT2); + EvaRegs.EVAIFRA.all = BIT7; + EvaRegs.EVAIMRA.bit.T1PINT = 1; +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +void init_eva_timer2(int freq, void (*timer_handler)()) +{ + // Initialize EVA Timer 2: + // Setup Timer 2 Registers (EV A) + EvaRegs.GPTCONA.all = 0; + + // Set the Period for the GP timer 2 to 0x0200; + EvaRegs.T2PR = 0x0400; // Period + EvaRegs.T2CMPR = 0x0000; // Compare Reg + + // Enable Period interrupt bits for GP timer 2 + // Count up, x128, internal clk, enable compare, use own period + EvaRegs.EVAIMRB.bit.T2PINT = 0;//1; + EvaRegs.EVAIFRB.all = BIT0; + // EvaRegs.EVAIFRB.bit.T2PINT = 1; + + // Clear the counter for GP timer 2 + EvaRegs.T2CNT = 0x0000; +// EvaRegs.T2PR = (float64)HSPCLK/(float64)(freq / 2); + EvaRegs.T2PR = (float64)HSPCLK/(float64)(freq); + EvaRegs.T2CON.all = FREE_RUN_FLAG + TIMER_CONT_UP + TIMER_CLK_PRESCALE_X_1 + + TIMER_ENABLE_BY_OWN + TIMER_ENABLE + TIMER_ENABLE_COMPARE; // + + // Start EVA ADC Conversion on timer 2 Period interrupt + EvaRegs.GPTCONA.bit.T2TOADC = 2; + + // Save pointer to handler in variable + timer2_handler = timer_handler; + + EALLOW; // This is needed to write to EALLOW protected registers + PieVectTable.T2PINT = &eva_timer2_isr; + EDIS; // This is needed to disable write to EALLOW protected registers + + // Enable PIE group 3 interrupt 1 for T2PINT +// PieCtrlRegs.PIEIER3.all = M_INT1; + PieCtrlRegs.PIEIER3.bit.INTx1 = 1;//M_INT1; + + // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT + // and INT5 for T4PINT: +// IER |= (M_INT3); +} + +void stop_eva_timer2() +{ + IER &= ~(M_INT3); + EvaRegs.EVAIMRB.bit.T2PINT = 0; +} + +void start_eva_timer2() +{ + IER |= (M_INT3); + EvaRegs.EVAIFRB.all = BIT0; + EvaRegs.EVAIMRB.bit.T2PINT = 1; +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +void init_evb_timer3(int freq, void (*timer_handler)()) +{ + // Initialize EVB Timer 3: + // Setup Timer 3 Registers (EV B) + EvbRegs.GPTCONB.all = 0; + + // Set the Period for the GP timer 3 to 0x0200; + EvbRegs.T3PR = 0x0800; // Period + EvbRegs.T3CMPR = 0x0000; // Compare Reg + + // Enable Period interrupt bits for GP timer 3 + // Count up, x128, internal clk, enable compare, use own period + EvbRegs.EVBIMRA.bit.T3PINT = 0;//1; + EvbRegs.EVBIFRA.all = BIT7; + // EvbRegs.EVBIFRA.bit.T3PINT = 1; + + // Clear the counter for GP timer 3 + EvbRegs.T3CNT = 0x0000; +// EvbRegs.T3PR = (float64)HSPCLK/(float64)(freq / 2); + EvbRegs.T3PR = (float64)HSPCLK/(float64)(freq); + EvbRegs.T3CON.all = FREE_RUN_FLAG + TIMER_CONT_UP + TIMER_CLK_PRESCALE_X_1 + + TIMER_ENABLE_BY_OWN + TIMER_ENABLE + TIMER_ENABLE_COMPARE; +// EvbRegs.T3CON.all = SOFT_STOP_FLAG + TIMER_CONT_UP + TIMER_CLK_PRESCALE_X_1 + // + TIMER_ENABLE_BY_OWN + TIMER_ENABLE + TIMER_ENABLE_COMPARE; + + // Save pointer to handler in variable + timer3_handler = timer_handler; + + // Start EVA ADC Conversion on timer 3 Period interrupt + EvbRegs.GPTCONB.bit.T3TOADC = 2; + + EALLOW; // This is needed to write to EALLOW protected registers + PieVectTable.T3PINT = &evb_timer3_isr; + EDIS; // This is needed to disable write to EALLOW protected registers + + // Enable PIE group 4 interrupt 4 for T3PINT +// PieCtrlRegs.PIEIER4.all = M_INT4; + PieCtrlRegs.PIEIER4.bit.INTx4 = 1; + + // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT + // and INT5 for T4PINT: + // IER |= M_INT4; +} + +void stop_evb_timer3() +{ + IER &= ~(M_INT4); + EvbRegs.EVBIMRA.bit.T3PINT = 0; +} + +void start_evb_timer3() +{ + IER |= (M_INT4); + + // Make sure PIEACK for group 2 is clear (default after reset) +// PieCtrlRegs.PIEACK.all = M_INT4; + EvbRegs.EVBIFRA.all = BIT7; + EvbRegs.EVBIMRA.bit.T3PINT = 1; +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +void init_evb_timer4(int freq, void (*timer_handler)()) +{ + // Initialize EVB Timer 4: + // Setup Timer 4 Registers (EV B) + EvbRegs.GPTCONB.all = 0; + + // Set the Period for the GP timer 4 to 0x0200; + EvbRegs.T4PR = 0x1000; // Period + EvbRegs.T4CMPR = 0x0000; // Compare Reg + + // Enable Period interrupt bits for GP timer 4 + // Count up, x128, internal clk, enable compare, use own period + EvbRegs.EVBIMRB.bit.T4PINT = 0;//1; + EvbRegs.EVBIFRB.all = BIT0; +// EvbRegs.EVBIFRB.bit.T4PINT = 1; + + // Clear the counter for GP timer 4 + EvbRegs.T4CNT = 0x0000; +// EvbRegs.T4PR = (float64)HSPCLK/(float64)(freq / 2); + EvbRegs.T4PR = (float64)HSPCLK/(float64)(freq); + EvbRegs.T4CON.all = FREE_RUN_FLAG + TIMER_CONT_UP + TIMER_CLK_PRESCALE_X_1 + + TIMER_ENABLE_BY_OWN + TIMER_ENABLE + TIMER_ENABLE_COMPARE; + + // Start EVA ADC Conversion on timer 4 Period interrupt + EvbRegs.GPTCONB.bit.T4TOADC = 2; + + // Save pointer to handler in variable + timer4_handler = timer_handler; + + EALLOW; // This is needed to write to EALLOW protected registers + PieVectTable.T4PINT = &evb_timer4_isr; + EDIS; // This is needed to disable write to EALLOW protected registers + + // Enable PIE group 5 interrupt 1 for T4PINT +// PieCtrlRegs.PIEIER5.all = M_INT1; + PieCtrlRegs.PIEIER5.bit.INTx1 = 1; + + // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT + // and INT5 for T4PINT: + // IER |= M_INT5; +} + +void stop_evb_timer4() +{ + IER &= ~(M_INT5); + EvbRegs.EVBIMRB.bit.T4PINT = 0; +} + +void start_evb_timer4() +{ + IER |= (M_INT5); + EvbRegs.EVBIFRB.all = BIT0; + EvbRegs.EVBIMRB.bit.T4PINT = 1; +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(eva_timer1_isr,".fast_run2"); +interrupt void eva_timer1_isr(void) +{ + // Set interrupt priority: + volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER2.all; + IER |= M_INT2; + IER &= MINT2; // Set "global" priority + PieCtrlRegs.PIEIER2.all &= MG24; // Set "group" priority + PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer1) + i_led1_on_off_special(1); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer1) + i_led2_on_off_special(1); +#endif + EINT; + + // Insert ISR Code here....... + if(timer1_handler) + { + timer1_handler(); + } + + // Next line for debug only (remove after inserting ISR Code): +// ESTOP0; + EvaRegs.EVAIFRA.all = BIT7; + // Restore registers saved: + DINT; + PieCtrlRegs.PIEIER2.all = TempPIEIER; +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer1) + i_led1_on_off_special(0); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer1) + i_led2_on_off_special(0); +#endif + +// +// +// IER &= ~(M_INT2);// stop_eva_timer1(); +// // Enable more interrupts from this timer +// EvaRegs.EVAIMRA.bit.T1PINT = 1; +// +// // Note: To be safe, use a mask value to write to the entire +// // EVAIFRA register. Writing to one bit will cause a read-modify-write +// // operation that may have the result of writing 1's to clear +// // bits other then those intended. +//// EvaRegs.EVAIFRA.bit.T1PINT = 1; +// EvaRegs.EVAIFRA.all = BIT7; +// +// // Acknowledge interrupt to receive more interrupts from PIE group 2 +// PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; +// +// // EINT; +// +// +// if(timer1_handler) +// { +// timer1_handler(); +// } + +// DINT; +// IER |= (M_INT2);//start_eva_timer1(); +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(eva_timer2_isr,".fast_run2"); +interrupt void eva_timer2_isr(void) +{ + + // Set interrupt priority: + volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER3.all; + IER |= M_INT3; + IER &= MINT3; // Set "global" priority + PieCtrlRegs.PIEIER3.all &= MG31; // Set "group" priority + PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer2) + i_led1_on_off_special(1); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer2) + i_led2_on_off_special(1); +#endif + + EINT; + + // Insert ISR Code here....... + if(timer2_handler) + { + timer2_handler(); + } + + // Next line for debug only (remove after inserting ISR Code): +// ESTOP0; + EvaRegs.EVAIFRB.all = BIT0; + // Restore registers saved: + DINT; + PieCtrlRegs.PIEIER3.all = TempPIEIER; + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer2) + i_led1_on_off_special(0); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer2) + i_led2_on_off_special(0); +#endif + + + +// +// +// // IER &= ~(M_INT3);// stop_eva_timer2(); +// +// // Enable more interrupts from this timer +// EvaRegs.EVAIMRB.bit.T2PINT = 1; +// +// // Note: To be safe, use a mask value to write to the entire +// // EVAIFRB register. Writing to one bit will cause a read-modify-write +// // operation that may have the result of writing 1's to clear +// // bits other then those intended. +// EvaRegs.EVAIFRB.all = BIT0; +//// EvaRegs.EVAIFRB.bit.T2PINT = 1; +// +// +// // Acknowledge interrupt to receive more interrupts from PIE group 3 +// PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; +// +// +//// EnableInterrupts(); +// +// if(timer2_handler) +// { +// timer2_handler(); +// } + + +// DINT; + // IER |= (M_INT3);//start_eva_timer2(); + + +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(evb_timer3_isr,".fast_run2"); +interrupt void evb_timer3_isr(void) +{ + // Set interrupt priority: + volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER4.all; + IER |= M_INT4; + IER &= MINT4; // Set "global" priority + PieCtrlRegs.PIEIER4.all &= MG44; // Set "group" priority + PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer3) + i_led1_on_off_special(1); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer3) + i_led2_on_off_special(1); +#endif + + EINT; + + // Insert ISR Code here....... + if(timer3_handler) + { + timer3_handler(); + } + + // Next line for debug only (remove after inserting ISR Code): +// ESTOP0; + +// EvbRegs.EVBIMRA.bit.T3PINT = 1; + EvbRegs.EVBIFRA.all = BIT7; +// PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; // Enable PIE interrupts + // Restore registers saved: + DINT; + PieCtrlRegs.PIEIER4.all = TempPIEIER; + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer3) + i_led1_on_off_special(0); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer3) + i_led2_on_off_special(0); +#endif + + +// +// +// IER &= ~(M_INT4);//stop_evb_timer3(); +// +// // Enable more interrupts from this timer +// EvbRegs.EVBIMRA.bit.T3PINT = 1; +// +// +// // IER &= ~(M_INT4); +// //EvbTimer3InterruptCount++; +// // Note: To be safe, use a mask value to write to the entire +// // EVBIFRA register. Writing to one bit will cause a read-modify-write +// // operation that may have the result of writing 1's to clear +// // bits other then those intended. +// EvbRegs.EVBIFRA.all = BIT7; +// +// // Acknowledge interrupt to receive more interrupts from PIE group 4 +// PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; +// +// EINT; +// +// +// if(timer3_handler) +// { +// timer3_handler(); +// } +// // IFR &= ~(M_INT4); // ������� ���� ����� ���������� ��� ������! +// // IER |= (M_INT4); +// +// DINT; +// IER |= (M_INT4);//start_evb_timer3(); +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(evb_timer4_isr,".fast_run2"); +interrupt void evb_timer4_isr(void) +{ + // Set interrupt priority: + volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER5.all; + IER |= M_INT5; + IER &= MINT5; // Set "global" priority + PieCtrlRegs.PIEIER5.all &= MG51; // Set "group" priority + PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer4) + i_led1_on_off_special(1); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer4) + i_led2_on_off_special(1); +#endif + + EINT; + + // Insert ISR Code here....... + if(timer4_handler) + { + timer4_handler(); + } + + // Next line for debug only (remove after inserting ISR Code): +// ESTOP0; + EvbRegs.EVBIFRB.all = BIT0; + // Restore registers saved: + DINT; + PieCtrlRegs.PIEIER5.all = TempPIEIER; + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.timer4) + i_led1_on_off_special(0); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.timer4) + i_led2_on_off_special(0); +#endif + +// +// +// +// IER &= ~(M_INT5);//stop_evb_timer4(); +// +// EvbRegs.EVBIMRB.bit.T4PINT = 1; +// //EvbTimer4InterruptCount++; +// // Note: To be safe, use a mask value to write to the entire +// // EVBIFRB register. Writing to one bit will cause a read-modify-write +// // operation that may have the result of writing 1's to clear +// // bits other then those intended. +// EvbRegs.EVBIFRB.all = BIT0; +// +// // Acknowledge interrupt to receive more interrupts from PIE group 5 +// PieCtrlRegs.PIEACK.all = PIEACK_GROUP5; +// EINT; +// +// +// if(timer4_handler) +// { +// timer4_handler(); +// } +// +// DINT; +// IER |= (M_INT5);//start_evb_timer4(); +} +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + + +//=========================================================================== +// No more. +//=========================================================================== diff --git a/Inu/Src/main/281xEvTimersInit.h b/Inu/Src/main/281xEvTimersInit.h new file mode 100644 index 0000000..2498fc9 --- /dev/null +++ b/Inu/Src/main/281xEvTimersInit.h @@ -0,0 +1,18 @@ +#ifndef EV_TIMERS +#define EV_TIMERS + +void init_eva_timer1(int freqHz, void (*timer_handler)()); +void init_eva_timer2(int freqHz, void (*timer_handler)()); +void init_evb_timer3(int freqHz, void (*timer_handler)()); +void init_evb_timer4(int freqHz, void (*timer_handler)()); + +void start_eva_timer1(); +void stop_eva_timer1(); +void start_eva_timer2(); +void stop_eva_timer2(); +void start_evb_timer3(); +void stop_evb_timer3(); +void start_evb_timer4(); +void stop_evb_timer4(); + +#endif //EV_TIMERS diff --git a/Inu/Src/main/CAN_project.h b/Inu/Src/main/CAN_project.h new file mode 100644 index 0000000..3454f1e --- /dev/null +++ b/Inu/Src/main/CAN_project.h @@ -0,0 +1,256 @@ +/* + * CAN_project.h + * + * Created on: 21 ��� 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_CAN_PROJECT_H_ +#define SRC_MAIN_CAN_PROJECT_H_ + + +#include "can_protocol_ukss.h" + +////////////////////////////////////////////////////////////////// +// ��������� ������� ������� CAN +// PCH_1 ��� PCH_2 ���������� ��������� �� ��67 +////////////////////////////////////////////////////////////////// +#define CAN_BASE_ADR_MPU_PCH_1 0x0CEB0E1 +#define CAN_BASE_ADR_MPU_PCH_2 0x0CEB0E1 //0x0CEB0E2 +////////////////////////////////////// +#define CAN_BASE_ADR_TERMINAL_PCH_1 0x0EEEE01 +#define CAN_BASE_ADR_TERMINAL_PCH_2 0x0EEEE03 +////////////////////////////////////// +#define CAN_BASE_ADR_UNITS_PCH_1 0x235500 +#define CAN_BASE_ADR_UNITS_PCH_2 0x235500 +////////////////////////////////////// +#define CAN_BASE_ADR_ALARM_LOG_PCH_1 0x0BCDEF01 +#define CAN_BASE_ADR_ALARM_LOG_PCH_2 0x0BCDEF02 +////////////////////////////////////////////////////////////////// + +//#define CAN_PROTOCOL_VERSION 1 +#define CAN_PROTOCOL_VERSION 2 + +#define CAN_SPEED_BITS 125000 +//#define CAN_SPEED_BITS 250000 +//#define CAN_SPEED_BITS 500000 + + + +#define ENABLE_CAN_SEND_TO_UKSS_FROM_MAIN 1 +#define ENABLE_CAN_SEND_TO_MPU_FROM_MAIN 1 +#define ENABLE_CAN_SEND_TO_TERMINAL_FROM_MAIN 0//1 +#define ENABLE_CAN_SEND_TO_TERMINAL_OSCIL 0//1 +#define ENABLE_CAN_SEND_TO_ANOTHER_BSU_FROM_MAIN 1 + + +////////////////////////////////////////////////////// + +#ifndef ENABLE_CAN_SEND_TO_UKSS_FROM_MAIN +#define ENABLE_CAN_SEND_TO_UKSS_FROM_MAIN 0 +#endif + +#ifndef ENABLE_CAN_SEND_TO_MPU_FROM_MAIN +#define ENABLE_CAN_SEND_TO_MPU_FROM_MAIN 0 +#endif + + +#ifndef ENABLE_CAN_SEND_TO_TERMINAL_FROM_MAIN +#define ENABLE_CAN_SEND_TO_TERMINAL_FROM_MAIN 0 +#endif + +#ifndef ENABLE_CAN_SEND_TO_TERMINAL_OSCIL +#define ENABLE_CAN_SEND_TO_TERMINAL_OSCIL 0 +#endif + +#ifndef ENABLE_CAN_SEND_TO_ANOTHER_BSU_FROM_MAIN +#define ENABLE_CAN_SEND_TO_ANOTHER_BSU_FROM_MAIN 0 +#endif + +/////////////////////////////////////////////////////////////////// +// setup ukss boxs +/////////////////////////////////////////////////////////////////// + +// ���� ����������� ���������� ������� ������������ +#define USE_UKSS_0 1 +#define USE_UKSS_1 1 +#define USE_UKSS_2 1 +#define USE_UKSS_3 1 +#define USE_UKSS_4 1 +//#define USE_UKSS_5 1 +//#define USE_UKSS_6 1 +//#define USE_UKSS_7 1 +//#define USE_UKSS_8 1 +//#define USE_UKSS_9 1 +//#define USE_UKSS_10 1 +//#define USE_UKSS_11 1 +//#define USE_UKSS_12 1 +//#define USE_UKSS_13 1 +//#define USE_UKSS_14 1 +//#define USE_UKSS_15 1 + + + +#define OFFSET_CAN_ADR_UNITS 0x10 + +// ���� ����������� �������� ������ + +#if USE_UKSS_0 +#define ZADATCHIK_CAN 0 //Zadatchik +#endif + +#if USE_UKSS_1 +#define VPU_CAN 1 //VPU +#endif + +#if USE_UKSS_2 +#define UMU_CAN_DEVICE 2 //Voltage control UMU +#endif + +#if USE_UKSS_3 +#define BKSSD_CAN_DEVICE 3 //AC DRIVE +#endif + + +#if USE_UKSS_4 +#define ANOTHER_BSU1_CAN_DEVICE 4 //Another BSU1 +// Unites revers box or not +// revers box used only on CAN between BS1 BS2 +//#define USE_R_B_4 1 //0 +#endif + + +//#if USE_UKSS_5 +//#define ANOTHER_BSU2_CAN_DEVICE 5 //Another BSU2 +//// Unites revers box or not +//// revers box used only on CAN between BS1 BS2 +////#define USE_R_B_5 1 //0 +//#endif + + + + +/////////////////////////////////////////////////////////////////// +// setup mpu boxes +/////////////////////////////////////////////////////////////////// + +// ���� ����������� ���������� ������� ������������ +#define USE_MPU_0 1 +#define USE_MPU_1 1 +//#define USE_MPU_2 1 +//#define USE_MPU_3 1 + + +#define OFFSET_CAN_ADR_MPU 0x10 + +//#define MPU_CAN_DEVICE 2 // MPU +#define TIME_PAUSE_CAN_FROM_MPU 1000 + + + + +/////////////////////////////////////////////////////////////////// +// setup terminal boxes +/////////////////////////////////////////////////////////////////// +// ���� ����������� ���������� ������� ������������ +#define USE_TERMINAL_1_OSCIL 1 +#define USE_TERMINAL_1_CMD 1 +#define USE_TERMINAL_2_OSCIL 1 +#define USE_TERMINAL_2_CMD 1 + + +#define OFFSET_CAN_ADR_TERMINAL 0x10 +#define TIME_PAUSE_CAN_FROM_TERMINAL 2 + +/////////////////////////////////////////////////////////////////// +// setup ALARM_LOG box +/////////////////////////////////////////////////////////////////// +#define USE_ALARM_LOG_0 1 + +/////////////////////////////////////////////////////////////////// +// setup can_open boxes +/////////////////////////////////////////////////////////////////// +//#define BWC_CAN_DEVICE 7 // Water cooler +//#define INGITIM 9 + +//#define BWC_CAN_FATEC 1 +//#define BWC_CAN_SIEMENS 1 +//#define INGITIM_CAN_OPEN 1 + + +#define CANOPENUNIT_LEN 30 + + +/////////words from zadatchik from Ingitim +#define PDO1_W1_ADR 0x11 +#define PDO1_W2_ADR 0x12 +#define PDO1_W3_ADR 0x13 +#define PDO1_W4_ADR 0x14 +#define PDO2_W1_ADR 0x15 +#define PDO2_W2_ADR 0x16 +#define PDO2_W3_ADR 0x17 +#define PDO2_W4_ADR 0x18 +#define PDO3_W1_ADR 0x19 +#define PDO3_W2_ADR 0x1A +#define PDO3_W3_ADR 0x1B +#define PDO3_W4_ADR 0x1C +#define PDO5_W1_ADR 0x1D +#define PDO5_W2_ADR 0x1E +#define PDO5_W3_ADR 0x1F +#define PDO5_W4_ADR 0x20 +#define PDO6_W1_ADR 0x21 +#define PDO6_W2_ADR 0x22 +#define PDO6_W3_ADR 0x23 +#define PDO6_W4_ADR 0x24 +////////////////////////////////////// + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +#define UNITS_NUMERATION_FROM_0_OR_1 0 //1 + + +#define MAX_CAN_WAIT_TIMEOUT 7500 // 2500 +//-------------------------------------------------// + +//#define CAN_ADR_TEST_LAMP 0x0CE031 //0x1CE030 + + +/////////////////////////////////////////////////////////////////// + + + + + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +// ��� ukss ������� +////////////////////////////////////////////////////////////////// +#define ADR_CAN_NUMBER1_ON_ZAD 0x00 +#define ADR_CAN_NUMBER2_ON_ZAD 0x01 +#define ADR_CAN_LAMPS_ON_ZAD 0x02 +#define ADR_CAN_LAMPS_2_ON_ZAD 0x03 +#define ADR_CAN_KEY_ON_ZAD 0x10 + +////////////////////////////////////// +////////////////////////////////////// + +#define CAN_SPEED_UKSS8 10 +#define CAN_SPEED_VPU1 20 +#define CAN_SPEED_VPU2 20 +#define CAN_SPEED_UMP1 5//30 + +//#define ADR_CAN_SPEED 99 +//#define ADR_CAN_LENGTH_FINISH_ADR 97 +//#define ADR_CAN_CMD 127 +//#define ADR_CAN_KEY_ON_VPU 16 // +//#define ADR_CAN_DOOR 0 // + + +////////////////////////////////////// +////////////////////////////////////// + + + +#endif /* SRC_MAIN_CAN_PROJECT_H_ */ diff --git a/Inu/Src/main/Main.c b/Inu/Src/main/Main.c new file mode 100644 index 0000000..9716206 --- /dev/null +++ b/Inu/Src/main/Main.c @@ -0,0 +1,126 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" + +#include <edrk_main.h> +#include "RS_Functions.h" +#include "xp_project.h" +#include "x_wdog.h" + +void main() +{ + // Step 1. Initialize System Control: + // PLL, WatchDog, enable Peripheral Clocks + // This example function is found in the DSP281x_SysCtrl.c file. + InitSysCtrl(); + + XintfZone0_Timing();//Xilinx Zone + XintfZone6_And7_Timing();//Flash Zone + XintfZone2_Timing();//External RAM Zone + + // Step 2. Initalize GPIO: + // This example function is found in the DSP281x_Gpio.c file and + // illustrates how to set the GPIO to it's default state. + // InitGpio(); // Skipped for this example + + // For this example use the following configuration: + //Gpio_select(); + + // Step 3. Clear all interrupts and initialize PIE vector table: + // Disable CPU interrupts + DINT; + +// status_interrupts = __disable_interrupts(); + + // Initialize PIE control registers to their default state. + // The default state is all PIE interrupts disabled and flags + // are cleared. + // This function is found in the DSP281x_PieCtrl.c file. + + InitPieCtrl(); + +// __disable_interrupts(); + + // Disable CPU interrupts and clear all CPU interrupt flags: + IER = 0x0000; + IFR = 0x0000; + + // Initialize the PIE vector table with pointers to the shell Interrupt + // Service Routines (ISR). + // This will populate the entire table, even if the interrupt + // is not used in this example. This is useful for debug purposes. + // The shell ISR routines are found in DSP281x_DefaultIsr.c. + // This function is found in DSP281x_PieVect.c. + + InitPieVectTable(); + + // Step 4. Initialize all the Device Peripherals: + // This function is found in DSP281x_InitPeripherals.c + // InitPeripherals(); // Not required for this example + + FlashInit(); + + SetupLedsLine(); +//while(1) +{ + i_led2_on_off(0); + i_led1_on_off(1); + DELAY_US(500000); + i_led2_on_off(1); + i_led1_on_off(0); + DELAY_US(500000); + i_led2_on_off(0); + i_led1_on_off(0); +} + + + RS232_TuneUp(RS232_SPEED_A, RS232_SPEED_B); + + KickDog(); + + // ��������� �������, ��� ���! + edrk_init_before_main(); + + // ��������� ����������, ���� ��������� RS232 + project.enable_all_interrupt(); + + + DINT; + i_led2_on_off(1); + i_led1_on_off(1); + DELAY_US(500000); + i_led2_on_off(0); + i_led1_on_off(0); + DELAY_US(500000); + i_led2_on_off(1); + i_led1_on_off(1); + DELAY_US(500000); + i_led2_on_off(0); + i_led1_on_off(0); + DELAY_US(500000); + project.enable_all_interrupt(); + + // ��������� ������� ����� ����������� ������ + edrk_init_before_loop(); + + // ��� �������� ���� main + for(;;) + { + // ������ � ������, ������ ��������� + + edrk_go_main(); + // ����� �� rs232 + RS232_WorkingWith(1,0,0); +// static int fff=0; +// if (fff) +// { +// Answer(&rs_a, CMD_RS232_POKE); +// fff = 0; +// } + + } + + +} + + diff --git a/Inu/Src/main/PWMTMSHandle.c b/Inu/Src/main/PWMTMSHandle.c new file mode 100644 index 0000000..2fe71b1 --- /dev/null +++ b/Inu/Src/main/PWMTMSHandle.c @@ -0,0 +1,510 @@ + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File + + +#include <f281xpwm.h> +#include <params.h> +#include <project.h> +#include <PWMTMSHandle.h> +#include <PWMTools.h> +#include <v_pwm24_v2.h> + +#include "CAN_Setup.h" +#include "global_time.h" +#include "RS_Functions.h" + + + +int + m_PWM = 1, /* 1-��� ������, 0-��� ������ */ + Dpwm = 12500, + Fpwm = 1000, + Dpwm2 = 6250, + Dpwm4 = 3125, + Zpwm = 1; // �������� +//TODO ��������� ���������� ����� +static int mPWM_a = 0, mPWM_b = 0; //��� ������� � � b 1 - ���., 0 - ����. + +PWMGEND pwmd = PWMGEND_DEFAULTS; + + +#if (TMSPWMGEN==1) + +#define DMIN 750 // 15mks Dminimum + +interrupt void PWM_Handler(void) +{ + +// static unsigned int time_tick_sec_mks=0; + static unsigned int pwm_run=0; + + // Enable more interrupts from this timer + EvaRegs.EVAIMRA.bit.T1PINT = 1; + + // Note: To be safe, use a mask value to write to the entire + // EVAIFRA register. Writing to one bit will cause a read-modify-write + // operation that may have the result of writing 1's to clear + // bits other then those intended. + EvaRegs.EVAIFRA.all = BIT7; + + // Acknowledge interrupt to receive more interrupts from PIE group 2 + PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; + + + + // PWM_ticks++; + + if (pwm_run==1) + { +// stop_pwm(); + } + else + { + + pwm_run=1; + + + EnableInterrupts(); + + + // if (time_tick_sec_mks>FREQ_PWM) +// { +// time_tick_sec++; +// time_tick_sec_mks=0; + // } +// else + // time_tick_sec_mks++; + + // rs_a.time_wait_rs_out++; +// rs_b.time_wait_rs_out++; + // rs_a.time_wait_rs_out_mpu++; +// rs_b.time_wait_rs_out_mpu++; + + + global_time.calc(&global_time); + inc_RS_timeout_cicle(); + inc_CAN_timeout_cicle(); + +// led1_on_off(1); + PWM_interrupt(); /* ����� ������� ���������y ����� */ +// led1_on_off(0); + + pwm_run=0; + + } +/* + // Enable more interrupts from this timer + EvaRegs.EVAIMRA.bit.T1PINT = 1; + + // Note: To be safe, use a mask value to write to the entire + // EVAIFRA register. Writing to one bit will cause a read-modify-write + // operation that may have the result of writing 1's to clear + // bits other then those intended. + EvaRegs.EVAIFRA.all = BIT7; + + // Acknowledge interrupt to receive more interrupts from PIE group 2 + PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; + +*/ + +// led2_on_off(0); +// disable(); /* ��������� ���������y TMS */ + + +// SCIb_RX_Int_enable(); +// SCIa_RX_Int_enable(); + + + +} +#endif + + +#if (TMSPWMGEN==1) +void init_eva_evb() +{ + +// unsigned int tload; + +// stop_pwm(); + + EALLOW; + +// EVA Configure T1PWM, T2PWM, PWM1-PWM6 +// Initalize the timers + // Initalize EVA Timer1 + + + PieVectTable.T1PINT=&PWM_Handler; + + + EvaRegs.EVAIMRA.bit.T1PINT = 1; + EvaRegs.EVAIFRA.bit.T1PINT = 1; + // Enable PIE group 2 interrupt 4 for T1PINT + PieCtrlRegs.PIEIER2.bit.INTx4 = 1; + + +// EvaRegs.EVAIFRA.bit.T1OFINT=1; +// PieVectTable.T1OFINT = &PWM_Handler2; +// EvaRegs.EVAIMRA.bit.T1OFINT = 1; +// EvaRegs.EVAIFRA.bit.T1OFINT = 1; + // Enable PIE group 2 interrupt 7 for T1PINT +// PieCtrlRegs.PIEIER2.bit.INTx7 = 1; + + +//#ifdef DOUBLE_UPDATE_PWM + +// PieVectTable.T1UFINT = &PWM_Handler2; +// EvaRegs.EVAIMRA.bit.T1UFINT = 1; +// EvaRegs.EVAIFRA.bit.T1UFINT = 1; + + // Enable PIE group 2 interrupt 7 for T1PINT +// PieCtrlRegs.PIEIER2.bit.INTx6 = 1; + +//#endif + + +// EvaRegs.EVAIFRA.bit.T1CINT=1; +// PieVectTable.T1CINT = &PWM_Handler2; +// EvaRegs.EVAIMRA.bit.T1CINT = 1; +// EvaRegs.EVAIFRA.bit.T1CINT = 1; + // Enable PIE group 2 interrupt 7 for T1PINT +// PieCtrlRegs.PIEIER2.bit.INTx5 = 1; + + + IER |= M_INT2; + + EDIS; +// start_pwm(); + + +} +#endif + + +#if (TMSPWMGEN==1) +void setup_tms_pwm_int(int pwm_freq, int one_two, int pwm_protect) +{ + + + float64 pwm_period; +// pwm_tick; + +// int prev_interrupt; + + // init_vector(); + +// f_disable(); /* ��������� ���������y TMS */ +// *(int *)(VECT_TABLE + VECT_INT2) = (int)PWM_Handler; /* ������������� ���������� */ +// SET_IEMASK_INT2(); /* ����� �� ���������y */ + + pwm_period = (float64)HSPCLK/(float64)pwm_freq/2.0; + + Fpwm = (int)pwm_freq; + Dpwm = (int)pwm_period; + Dpwm2 = (int)(pwm_period/2); + Dpwm4 = (int)(pwm_period/4); + + // stop_pwm(); /* ���������� ������� ��� */ + // setup_pwm_out(); + + + + + init_eva_evb(); + + + + + EvbRegs.EVBIFRA.bit.PDPINTB=1; + EvaRegs.EVAIFRA.bit.PDPINTA=1; + +// EVBIFRB + // Initialize PWM module + pwmd.PeriodMax = Dpwm; // Perscaler X1 (T1), ISR period = T x 1 + pwmd.PeriodMin = DMIN; // Perscaler X1 (T1), ISR period = T x 1 + +// ARpwmd.PeriodMax = Dpwm; +// ARpwmd.PeriodMin = DMIN; +// + pwmd.ShiftPhaseA = 0;//Dpwm/6.0; + pwmd.ShiftPhaseB = 0; + + pwmd.init(&pwmd); + +// ARpwmd.init(&pwmd); + // m.m2.bit.WDog_pwm = 0; + + + +/* pwm1.PeriodMax = Dpwm; // Perscaler X1 (T1), ISR period = T x 1 + pwm1.init(&pwm1); + + pwm2.PeriodMax = Dpwm; // Perscaler X1 (T1), ISR period = T x 1 + pwm2.init(&pwm2); */ + + +// if(one_two < 1.5) one_two = 0; +// if(one_two > 1.5) one_two = 0x80000000; + + +// addr_xilinx(WG_COUNT) = pwm_divisor; /* �������� ������� ���� */ +// addr_xilinx(WG_PERIOD) = Dpwm<<16; /* ������ ��� */ +// addr_xilinx(ADR_INT) = one_two; /* ���������� �� ������ */ +// addr_xilinx(WG_PROTECT) = pwm_protect; /* ���������� ���������� ��� */ + + + +//Invoking the computation function +//svgen_mf1. + +// Initialize the SVGEN_MF module +/* + svgen_mf1.FreqMax = _IQ(6*BASE_FREQ*T); + svgen_mf2.FreqMax = _IQ(6*BASE_FREQ*T); + + + svgen_mf2.Offset=_IQ(0); + svgen_mf1.Offset=_IQ(0); + + svgen_mf1.Alpha = _IQ(0); + svgen_mf2.Alpha = _IQ(0.52359877559829887307710723054658); + + + k=0.1; //0.9; + freq = 0.499; + +*/ +//svgen_mf1.calc(&svgen_mf1); +//svgen_mf2.calc(&svgen_mf2); + +// start_pwm_a(); +// start_pwm_b(); + + + i_WriteMemory(ADR_PWM_DRIVE_MODE, 0x0000); //�������� � �������� ��������� ��� TMS + +} +#endif + +/********************************************************************/ +/* ���������� ������� ���� */ +/********************************************************************/ +void start_tms_pwm_a() +{ + unsigned int mask_tk_lines; + mPWM_a = 1; + + + EALLOW; + EvaRegs.COMCONA.all = 0xa600;//0xA600; // Init COMCONA Register + + EvaRegs.ACTRA.all = 0x0999; + EDIS; + + +} + +void start_tms_pwm_b() +{ + unsigned int mask_tk_lines; + mPWM_b = 1; + + + EALLOW; + EvbRegs.COMCONB.all = 0xa600;//0xA600; // Init COMCONA Register + + EvbRegs.ACTRB.all = 0x0999; + EDIS; + + + +} + + + +void start_tms_pwm(void) +{ + mPWM_a = 1; + mPWM_b = 1; + + + m_PWM = 0; + // m.m1.bit.PWM=0; + // m.m1.bit.PWM_A=0; + // m.m1.bit.PWM_B=0; + + EALLOW; + // addr_xilinx(WG_OUT)=0x00; + + EvaRegs.COMCONA.all = 0xa600;//0xA600; // Init COMCONA Register + EvbRegs.COMCONB.all = 0xa600;//0xA600; // Init COMCONA Register + + EvaRegs.ACTRA.all = 0x0999; + EvbRegs.ACTRB.all = 0x0999; + +// EvaRegs.GPTCONA.bit.TCMPOE=0; +// EvbRegs.GPTCONB.bit.TCMPOE=0; +// EvaRegs.T1CON.bit.TECMPR=1; +// EvbRegs.T3CON.bit.TECMPR=1; + EDIS; + +} + +/********************************************************************/ +/* ���������� ������������ ������� ���� */ +/********************************************************************/ +void start_select_tms_pwm(unsigned int mask) +{ + unsigned int mask_pwm_a,mask_pwm_b; + unsigned char b,i; + + + EALLOW; + + + + EvaRegs.ACTRA.all = 0x0fff; + EvbRegs.ACTRB.all = 0x0fff; + + EvaRegs.COMCONA.all = 0xa600;//0xA600; // Init COMCONA Register + EvbRegs.COMCONB.all = 0xa600;//0xA600; // Init COMCONA Register + + + mask_pwm_a=0; + for (i=0;i<6;i++) + { + b=(mask >> i) & 1; + if (b==0) + mask_pwm_a |= (1 << (2*i) ); + else + mask_pwm_a |= (3 << (2*i) ); + + + } + + mask_pwm_b=0; + for (i=0;i<6;i++) + { + b=(mask >> (i+8)) & 1; + if (b==0) + mask_pwm_b |= (1 << (2*i) ); + else + mask_pwm_b |= (3 << (2*i) ); + + } + + EvaRegs.ACTRA.all = mask_pwm_a; + EvbRegs.ACTRB.all = mask_pwm_b; + + EDIS; +} + + +/********************************************************************/ +/* ���������� ������� ���� */ +/********************************************************************/ +//#pragma CODE_SECTION(stop_pwm,".fast_run"); +void stop_tms_pwm(void) +{ + mPWM_a = 0; + mPWM_b = 0; + + + m_PWM = 1; + // m.m1.bit.PWM=1; + // m.m1.bit.PWM_A=1; + // m.m1.bit.PWM_B=1; + + EALLOW; + // EvaRegs.GPTCONA.bit.TCMPOE=1; + // EvbRegs.GPTCONB.bit.TCMPOE=1; + // EvaRegs.T1CON.bit.TECMPR=0; + // EvbRegs.T3CON.bit.TECMPR=0; + + // addr_xilinx(WG_OUT)=0x0fff; // ������� ��������� ���� + EvaRegs.ACTRA.all = 0x0fff; + EvbRegs.ACTRB.all = 0x0fff; + + // EvaRegs.COMCONA.all = 0xa400;//0xA600; // Init COMCONA Register + // EvbRegs.COMCONB.all = 0xa400;//0xA600; // Init COMCONA Register + + // EvaRegs.COMCONA.bit.FCMP6OE=0; + + + + //EvbRegs.COMCONB.bit.FCOMPOE=0; + //EvaRegs.COMCONA.bit.CENABLE=0; + //EvbRegs.COMCONB.bit.CENABLE=0; + + + EDIS; + + +} + +void stop_tms_pwm_a() +{ + unsigned int mask_tk_lines; +// m_PWM = 1; + mPWM_a = 0; + + EALLOW; + EvaRegs.ACTRA.all = 0x0fff; + EDIS; + +} + + +void stop_tms_pwm_b() +{ + unsigned int mask_tk_lines; + m_PWM = 1; + mPWM_b = 0; + + + + EALLOW; + EvbRegs.ACTRB.all = 0x0fff; + EDIS; + +} + +void setup_tms_pwm_out(void) +{ +//int b; +#if (TMSPWMGEN==1) + EALLOW; + +// GpioMuxRegs.GPDMUX.bit.T3CTRIP_PDPB_GPIOD5=0; +// GpioMuxRegs.GPDDIR.bit.GPIOD5=0; +// GpioDataRegs.GPDSET.bit.GPIOD5=1; + + +// GpioDataRegs.GPDCLEAR.bit.GPIOD5=1; + + + + GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0=1; + GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1=1; + GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2=1; + GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3=1; + GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4=1; + GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5=1; + + GpioMuxRegs.GPBMUX.bit.PWM7_GPIOB0=1; + GpioMuxRegs.GPBMUX.bit.PWM8_GPIOB1=1; + GpioMuxRegs.GPBMUX.bit.PWM9_GPIOB2=1; + GpioMuxRegs.GPBMUX.bit.PWM10_GPIOB3=1; + GpioMuxRegs.GPBMUX.bit.PWM11_GPIOB4=1; + GpioMuxRegs.GPBMUX.bit.PWM12_GPIOB5=1; + + EDIS; + // ��������� ������ +// write_memory(adr_oe_buf_v,0); +#endif +} + + + diff --git a/Inu/Src/main/PWMTMSHandle.h b/Inu/Src/main/PWMTMSHandle.h new file mode 100644 index 0000000..ab1675c --- /dev/null +++ b/Inu/Src/main/PWMTMSHandle.h @@ -0,0 +1,25 @@ +#ifndef _PWMTMSHANDLE_H +#define _PWMTMSHANDLE_H + +void setup_tms_pwm_out(void); +void start_tms_pwm(void); +void stop_tms_pwm(void); + +void start_tms_pwm_b(); +void start_tms_pwm_a(); +void stop_tms_pwm_a(); +void stop_tms_pwm_b(); + + +void setup_tms_pwm_int(int pwm_freq, int one_two, int pwm_protect); + +void start_break_pwm(void); +void stop_break_pwm(void); + + + + + + +#endif + diff --git a/Inu/Src/main/PWMTools.c b/Inu/Src/main/PWMTools.c new file mode 100644 index 0000000..b62f7b3 --- /dev/null +++ b/Inu/Src/main/PWMTools.c @@ -0,0 +1,2438 @@ +#include <adc_tools.h> +#include <alg_simple_scalar.h> +#include <alg_uf_const.h> +#include <break_regul.h> +#include <calc_rms_vals.h> +#include <control_station_project.h> //22.06 +#include <detect_errors_adc.h> +#include <detect_overload.h> +#include <edrk_main.h> +#include <f281xpwm.h> +//#include <log_to_mem.h> +#include <master_slave.h> +#include <math.h> +#include <message_modbus.h> //22.06 +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include <project.h> +#include <PWMTMSHandle.h> +#include <PWMTools.h> +#include <sync_tools.h> +#include <v_pwm24_v2.h> +#include <v_pwm24_v2.h> +#include <v_rotor.h> +#include <vector.h> +#include "f281xpwm.h" + +//#include "SpaceVectorPWM.h" +#include "CAN_Setup.h" +#include "global_time.h" +#include "IQmathLib.h" +#include "mathlib.h" +#include "oscil_can.h" +#include "rmp_cntl_v1.h" +#include "uf_alg_ing.h" +#include "vhzprof.h" +#include "vector_control.h" +#include "MemoryFunctions.h" +#include "RS_Functions.h" +#include "TuneUpPlane.h" +#include "xp_write_xpwm_time.h" +#include "pwm_test_lines.h" +#include "detect_errors.h" +#include "modbus_table_v2.h" +#include "params_alg.h" +#include "v_rotor_22220.h" +#include "log_to_memory.h" +#include "log_params.h" +#include "limit_power.h" +#include "pwm_logs.h" +#include "optical_bus_tools.h" +#include "ramp_zadanie_tools.h" +#include "pll_tools.h" + + +///////////////////////////////////// +#if (_SIMULATE_AC==1) +#include "sim_model.h" +#endif + +//#pragma DATA_SECTION(freq1,".fast_vars1"); +//_iq freq1; + +//#pragma DATA_SECTION(k1,".fast_vars1"); +//_iq k1 = 0; + +#define ENABLE_LOG_INTERRUPTS 0 //1 + + +#if (ENABLE_LOG_INTERRUPTS) + +#pragma DATA_SECTION(log_interrupts,".slow_vars"); +#define MAX_COUNT_LOG_INTERRUPTS 100 +unsigned int log_interrupts[MAX_COUNT_LOG_INTERRUPTS+2] = {0}; + + + + +///////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////// + + +void add_log_interrupts(int cmd) +{ + static int count_log_interrupst = 0; + + if (count_log_interrupst>=MAX_COUNT_LOG_INTERRUPTS) + count_log_interrupst = 0; + + + log_interrupts[count_log_interrupst++] = cmd; + log_interrupts[count_log_interrupst++] = EvbRegs.T3CNT; + + +//#if (ENABLE_LOG_INTERRUPTS) +// add_log_interrupts(0); +//#endif + +} + +#endif //if (ENABLE_LOG_INTERRUPTS) + + + +#pragma DATA_SECTION(iq_U_1_save,".fast_vars1"); +_iq iq_U_1_save = 0; +#pragma DATA_SECTION(iq_U_2_save,".fast_vars1"); +_iq iq_U_2_save = 0; + + +unsigned int enable_calc_vector = 0; + + + +//WINDING winding1 = WINDING_DEFAULT; + +//#define COUNT_SAVE_LOG_OFF 50 //������� ������ ��� ����������� ����� ��������� +#define COUNT_START_IMP 5 //10 + +#define CONST_005 838860 +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(global_time_interrupt,".fast_run2"); +void global_time_interrupt(void) +{ + +// inc_RS_timeout_cicle(); +// inc_CAN_timeout_cicle(); + +#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_18_ON; +#endif + + if (edrk.disable_interrupt_timer3) + return; + +//i_led1_on_off(1); + + + if (sync_data.latch_interrupt && sync_data.enabled_interrupt) + { + // ���������� ���������� ���! + // ��� ���������� �������� + start_sync_interrupt(); + } + +#if (ENABLE_LOG_INTERRUPTS) + add_log_interrupts(1); +#endif + + global_time.calc(&global_time); + +#if (ENABLE_LOG_INTERRUPTS) + add_log_interrupts(101); +#endif + +/* +static unsigned int oldest_time = 0, time_pause = TIME_PAUSE_MODBUS_REMOUTE; +control_station_test_alive_all_control(); + if (detect_pause_milisec(time_pause,&oldest_time)) + modbusNetworkSharing(0); + + RS232_WorkingWith(0,1); +*/ + + +//i_led1_on_off(0); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + // PWM_LINES_TK_18_OFF; +#endif +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +//#define get_tics_timer_pwm2(k) {time_buf2[k] = (EvbRegs.T3CNT-start_tics_4timer);k++;} +//unsigned int time_buf2[10] = {0}; + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +#define PAUSE_INC_TIMEOUT_CICLE 10 // FREQPWM/10 +void pwm_inc_interrupt(void) +{ + static unsigned int t_inc = 0; + + if (t_inc>=PAUSE_INC_TIMEOUT_CICLE) + { + inc_RS_timeout_cicle(); + inc_CAN_timeout_cicle(); + t_inc = 0; + } + else + t_inc++; +} +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(pwm_analog_ext_interrupt,".fast_run2"); +void pwm_analog_ext_interrupt(void) +{ +// static int count_timer_buf2=0, start_tics_4timer = 0, c_rms = 0; +// static _iq prev_Iu=0, prev_Ua=0; + //static _iq iq_50hz_norma = _IQ(50.0/NORMA_FROTOR); + +// i_led2_on(); + + // ���������� �������� ������� ������ � ���������� +// start_tics_4timer = EvaRegs.T1CNT; + +// count_timer_buf2 = 0; +// get_tics_timer_pwm2(count_timer_buf2); + + if (edrk.SumSbor == 1) { +// detect_protect_adc(uf_alg.tetta_bs, uf_alg.tetta_bs); + } + + + + calc_pll_50hz(); + +// +// if (c_rms>=9) +// { +// edrk.test_rms_Iu = calc_rms(analog.iqIu,prev_Iu,edrk. f_stator); +// edrk.test_rms_Ua = calc_rms(analog.iqUin_A1B1,prev_Ua, iq_50hz_norma); +// +// prev_Iu = analog.iqIu; +// prev_Ua = analog.iqUin_A1B1; +// c_rms = 0; +// } +// else +// c_rms++; + +// fill_RMS_buff_interrupt(uf_alg.tetta_bs, uf_alg.tetta_bs); + + // get_tics_timer_pwm2(count_timer_buf2); +// i_led2_off(); + + +// global_time.calc(&global_time); + +} +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +inline void init_regulators() +{ +// if(f.Mode != 0) +// { +//// pwm_vector_model_titov(0, 0, /*rotor.iqW*/0, 0); +// } +} + +#define select_working_channels(go_a, go_b) {go_a = !f.Obmotka1; \ + go_b = !f.Obmotka2;} + +#define MAX_COUNT_WAIT_GO_0 FREQ_PWM // 1 ���. + + +#define PAUSE_ERROR_DETECT_UPDATE_OPTBUS_DATA 900// ((unsigned int)(1*FREQ_PWM*2)) // ~1sec //50 +#define MAX_TIMER_WAIT_SET_TO_ZERO_ZADANIE 27000 //((unsigned int)(30*FREQ_PWM*2)) // 60 sec +//#define MAX_TIMER_WAIT_BOTH_READY2 108000 //(120*FREQ_PWM*2) // 120 sec +#define MAX_TIMER_WAIT_BOTH_READY2 216000 //(120*FREQ_PWM*2) // 240 sec +#define MAX_TIMER_WAIT_MASTER_SLAVE 4500 // 5 sec + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +//#define _ENABLE_PWM_LED2_PROFILE 1 + + +#if (_ENABLE_PWM_LED2_PROFILE) +unsigned int profile_pwm[30]={0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0}; +unsigned int pos_profile_pwm = 0; +#endif + +/////////////////////////////////////////////////////////////////// +#define _ENABLE_LOG_TICS_PWM 0//1 +#define _ENABLE_SLOW_PWM 0//1 +#define _ENABLE_INTERRUPT_PWM_LED2 0//1 + +#if (_ENABLE_LOG_TICS_PWM==1) + +static int c_run=0; +static int c_run_start=0; +static int i_log; + + +#pragma DATA_SECTION(time_buf,".slow_vars"); +#define MAX_COUNT_TIME_BUF 50 +int time_buf[MAX_COUNT_TIME_BUF] = {0}; + +//#define get_tics_timer_pwm(flag,k) {if (flag) {time_buf[k] = (unsigned int)(EvbRegs.T3CNT-start_tics_4timer);k++;}else{time_buf[k] = -1; k++;}} + +#define set_tics_timer_pwm(flag,k) { time_buf[k] = flag;k++; } + +//#define get_tics_timer_pwm(flag,k) if (flag) ? {time_buf[k] = (EvbRegs.T3CNT-start_tics_4timer);k++;} : {time_buf[k] = -1; k++;}; +static int count_timer_buf=0; + +#else + +#define get_tics_timer_pwm(flag) asm(" NOP;") +#define set_tics_timer_pwm(flag,k) asm(" NOP;") +//static int count_timer_buf=0; + +#endif + + +#if(_ENABLE_SLOW_PWM) +static int slow_pwm_pause = 0; +#endif + +unsigned int count_time_buf = 0; +int stop_count_time_buf=0; +unsigned int log_wait; + +unsigned int end_tics_4timer, start_tics_4timer; +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////// +#if (_ENABLE_LOG_TICS_PWM==1) +//#pragma CODE_SECTION(get_tics_timer_pwm,".fast_run"); +void get_tics_timer_pwm(unsigned int flag) +{ + unsigned int delta; + + if (flag) + { + delta = (unsigned int)(EvbRegs.T3CNT-start_tics_4timer); + if (count_timer_buf>=3) + time_buf[count_timer_buf] = delta - time_buf[count_timer_buf-2]; + else + time_buf[count_timer_buf] = delta; + time_buf[count_timer_buf] = time_buf[count_timer_buf]*33/1000; + count_timer_buf++; + } + else + { + time_buf[count_timer_buf] = -1; + count_timer_buf++; + } +} +#else + +#endif + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////// +// �������� ������ � ������� �������� +/////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(calc_rotors,".fast_run"); +void calc_rotors(int flag) +{ + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_17_ON; +#endif + + update_rot_sensors(); + + + + set_tics_timer_pwm(6,count_timer_buf); + get_tics_timer_pwm(flag); + + +#if(C_cds_in_number>=1) + project.cds_in[0].read_pbus(&project.cds_in[0]); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_17_OFF; +#endif + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_19_ON; +#endif + +#if(SENSOR_ALG==SENSOR_ALG_23550) +// 23550 + RotorMeasureDetectDirection(); + RotorMeasure();// ���������� +#endif + +#if(SENSOR_ALG==SENSOR_ALG_22220) +// 22220 + Rotor_measure_22220(); + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_19_OFF; +#endif + + set_tics_timer_pwm(7,count_timer_buf); + get_tics_timer_pwm(flag); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_20_ON; +#endif + +// RotorMeasurePBus(); +#if(SENSOR_ALG==SENSOR_ALG_23550) +// 23550 + RotorDirectionFilter(WRotorPBus.RotorDirectionInstant, &WRotorPBus.RotorDirectionSlow, &WRotorPBus.RotorDirectionSlow2, &WRotorPBus.RotorDirectionCount); +#endif + +#if(SENSOR_ALG==SENSOR_ALG_22220) + // 22220 + // nothing +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_20_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_20_ON; +#endif + +#if(SENSOR_ALG==SENSOR_ALG_23550) +// 23550 + select_values_wrotor(); +#endif +#if(SENSOR_ALG==SENSOR_ALG_22220) +// 22220 + select_values_wrotor_22220(); + +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_20_OFF; +#endif + + set_tics_timer_pwm(8,count_timer_buf); + get_tics_timer_pwm(flag); + +#endif //(C_cds_in_number>=1) + + + edrk.rotor_direction = WRotor.RotorDirectionSlow; + +#if(SENSOR_ALG==SENSOR_ALG_23550) +// 23550 + edrk.iq_f_rotor_hz = WRotor.iqWRotorSumFilter; +#endif + +#if(SENSOR_ALG==SENSOR_ALG_22220) +// 22220 + edrk.iq_f_rotor_hz = WRotor.iqWRotorSum; +#endif + +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(calc_zadanie_rampa,".fast_run"); +void calc_zadanie_rampa(void) +{ +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_19_ON; +#endif + + + // ������� ��� ����� ������ + load_current_ramp_oborots_power(); + + if (edrk.StartGEDfromControl==0) + ramp_all_zadanie(2); // ��������� � ���� + else + if (edrk.flag_wait_set_to_zero_zadanie || edrk.flag_block_zadanie || edrk.Status_Ready.bits.ready_final==0 || /*edrk.StartGEDfromControl==0 ||*/ edrk.run_razbor_shema == 1) + ramp_all_zadanie(1); // ������� ����� � ����, �� ������� ��� ������ � ����, �� ��������� edrk.StartGEDfromZadanie + else + ramp_all_zadanie(0); // ��� ��� �� �������� + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_19_OFF; +#endif + +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +#pragma CODE_SECTION(async_pwm_ext_interrupt,".fast_run2"); +void async_pwm_ext_interrupt(void) +{ + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_19_ON; +#endif + if (edrk.run_to_pwm_async) + { + PWM_interrupt(); + edrk.run_to_pwm_async = 0; + } + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_19_OFF; +#endif + +} +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +void run_detect_fast_error(void) +{ + + detect_error_u_zpt_fast(); + detect_error_u_in(); + +} +//////////////////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(PWM_interrupt_main,".fast_run"); +void PWM_interrupt_main(void) +{ + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_16_ON; +#endif + + norma_adc_nc(0); + + edrk.run_to_pwm_async = 1; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_16_OFF; +#endif + +} +//////////////////////////////////////////////////////////////////////////////// + + +#define MAX_COUNT_COUNTSTARTGEDFROMZADANIE FREQ_PWM //3000 // �������� � ������ ��������� ������� � edrk.StartGEDfromZadanie + + + +#pragma CODE_SECTION(PWM_interrupt,".fast_run"); +void PWM_interrupt(void) +{ + + static unsigned int pwm_run = 0; + static _iq Uzad1=0, Fzad=0, Uzad2=0, Izad_out = 0, Uzad_from_master = 0; + +// static int count_step_ram_off = 0; +// static int count_start_impuls = 0; + + static int prevGo = -1; + static volatile unsigned int go_a = 0; + static volatile unsigned int go_b = 0; + + static int prev_go_a = 0; + static int prev_go_b = 0; + + static _iq iq_U_1_prev = 0; + static _iq iq_U_2_prev = 0; + static unsigned int prev_timer = 0; + unsigned int cur_timer; + static unsigned int count_lost_interrupt=0; + static int en_rotor = 1;//1; + + static unsigned long timer_wait_set_to_zero_zadanie = 0; + static unsigned long timer_wait_both_ready2 = 0; + + static unsigned int prev_error_controller = 0,error_controller=0; + + static unsigned long time_delta = 0; + + static unsigned int run_calc_uf = 0, prev_run_calc_uf = 0, count_wait_go_0 = 0; + + int pwm_enable_calc_main = 0, pwm_up_down = 0, err_interr = 0, slow_error = 0; + + static unsigned int count_err_read_opt_bus = 0, prev_edrk_Kvitir = 0; + + static unsigned int count_wait_read_opt_bus = 0, old_count_ok = 0, data_ready_optbus = 0, count_ok_read_opt_bus = 0; + +// static T_cds_optical_bus_data_in buff[25]={0}; + static unsigned int flag_last_error_read_opt_bus = 0, sum_count_err_read_opt_bus1=0; + + static unsigned int count_read_slave = 0, flag1_change_moment_read_optbus = 0, flag2_change_moment_read_optbus = 0; + + static unsigned int count_updated_sbus = 0, prev_ManualDischarge = 0; + + static unsigned int prev_flag_detect_update_optbus_data=0, flag_detect_update_optbus_data = 0, pause_error_detect_update_optbus_data = 0; + static unsigned int timer_wait_to_master_slave = 0; + static unsigned int prev_master = 0; + + static int pwm_enable_calc_main_log = 1; + + static int what_pwm = 0; + + int localStartGEDfromZadanie; + static unsigned int countStartGEDfromZadanie = 0; + + +// OPTICAL_BUS_CODE_STATUS optbus_status = {0}; + static STATUS_DATA_READ_OPT_BUS optbus_status; + _iq wd; + +// if (edrk.disable_interrupt_sync==0) +// start_sync_interrupt(); + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_ON; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_16_ON; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_16_ON; +#endif + + + +#if (_ENABLE_INTERRUPT_PWM_LED2) +i_led2_on_off(1); +#endif + + if (edrk.disable_interrupt_pwm) + { + pwm_inc_interrupt(); + return; + } + + if (flag_special_mode_rs==1) + { + calc_norm_ADC_0(1); + calc_norm_ADC_1(1); + pwm_inc_interrupt(); + + return; + } + +#if (_ENABLE_PWM_LED2_PROFILE) + pos_profile_pwm = 0; +#endif + + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + +// if (xpwm_time.what_next_interrupt==PWM_LOW_LEVEL_INTERRUPT) +// { +//#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) +// PWM_LINES_TK_17_ON; +//#endif +// +// i_sync_pin_on(); +// +// } +// else +// { +//#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) +// PWM_LINES_TK_17_OFF; +//#endif +// +// i_sync_pin_off(); +// } + + + +//////////////// +//PWN_COUNT_RUN_PER_INTERRUPT PWM_TWICE_INTERRUPT_RUN + err_interr = detect_level_interrupt(edrk.flag_second_PCH); + + if (err_interr) + edrk.errors.e3.bits.ERR_INT_PWM_LONG |=1; + + if (xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + pwm_up_down = 2; + else + if (xpwm_time.where_interrupt == PWM_LOW_LEVEL_INTERRUPT) + { + pwm_up_down = 0; + } + else + pwm_up_down = 1; + + // sync line + if (pwm_up_down==2 || pwm_up_down==0) + { +// what_pwm = 0; + // i_sync_pin_on(); + calculate_sync_detected(); + } + +///////////////// +#if (ENABLE_LOG_INTERRUPTS) + add_log_interrupts(3); +#endif + + +#if (_ENABLE_LOG_TICS_PWM==1) + + count_timer_buf = 0; + // optical_read_data.timer=0; +#endif + + +#if (_FLOOR6==0) +// if (edrk.Stop==0) +// i_led1_on_off(1); +#else + // i_led1_on_off(1); +#endif + + + edrk.into_pwm_interrupt = 1; + + // ���������� �������� ������� ������ � ���������� + start_tics_4timer = EvbRegs.T3CNT; + cur_timer = global_time.pwm_tics; + if (prev_timer>cur_timer) + { + if ((prev_timer-cur_timer)<2) + { +// stop_pwm(); + edrk.count_lost_interrupt++; + } + } + else + { + if ((cur_timer==prev_timer) || (cur_timer-prev_timer)>2) + { +// stop_pwm(); + edrk.count_lost_interrupt++; + } + } + prev_timer = cur_timer; + // ��������� ���������� �������� ������� ������ � ���������� + + set_tics_timer_pwm(1,count_timer_buf); + get_tics_timer_pwm(1); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_17_ON; +#endif + +#if (_SIMULATE_AC==1) + calc_norm_ADC_0_sim(0); +#else + calc_norm_ADC_0(0); // ������ ��� � norma ���� �������� � Pwm_main() +#endif + run_detect_fast_error(); //������� ������ + + + + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + if (edrk.Kvitir==0 && prev_edrk_Kvitir==1) + { + count_err_read_opt_bus = 0; + edrk.sum_count_err_read_opt_bus = 0; + } + + set_tics_timer_pwm(2,count_timer_buf); + get_tics_timer_pwm(1); + + ////////////////////////////// +// inc_RS_timeout_cicle(); + //////////////////////////////// + //////////////////////////////////////////// + //////////////////////////////////////////// +// inc_CAN_timeout_cicle(); + //////////////////////////////////////////// + + if (edrk.ms.another_bs_maybe_on==1 && + (edrk.auto_master_slave.local.bits.master || edrk.auto_master_slave.local.bits.slave) ) + { + + flag_detect_update_optbus_data = 1; + + if (prev_flag_detect_update_optbus_data == 0) + pause_error_detect_update_optbus_data = 0; + + + count_updated_sbus = optical_read_data.data_was_update_between_pwm_int; + + // ���� �������� PAUSE_ERROR_DETECT_UPDATE_OPTBUS_DATA ����� ����� � ����� �� OPT_BUS + // ����� ������� �������� ������ ������ �� �������������� ���������� ������ �� OPT_BUS + if (pause_error_detect_update_optbus_data<PAUSE_ERROR_DETECT_UPDATE_OPTBUS_DATA) + pause_error_detect_update_optbus_data++; + else + { + if (optical_read_data.error_wdog || (optical_read_data.data_was_update_between_pwm_int==0)) + { + if (optical_read_data.error_wdog) + edrk.errors.e8.bits.WDOG_OPTICAL_BUS |= 1; + + if (optical_read_data.data_was_update_between_pwm_int==0) + edrk.errors.e7.bits.ANOTHER_PCH_NOT_ANSWER |= 1; + } + else + { + edrk.ms.ready3 = 1; + optical_read_data.data_was_update_between_pwm_int = 0; + } + + } +// sum_count_err_read_opt_bus++; + } + else + { + pause_error_detect_update_optbus_data = 0; + flag_detect_update_optbus_data = 0; + edrk.ms.ready3 = 0; + } + prev_flag_detect_update_optbus_data = flag_detect_update_optbus_data; + + optical_read_data.flag_clear = 1; + + + if (xpwm_time.where_interrupt == PWM_LOW_LEVEL_INTERRUPT || + xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + { + pwm_enable_calc_main = 1; + + if (sync_data.what_main_pch) + { + if (sync_data.what_main_pch==2) + { + if (edrk.flag_second_PCH==1) // ������ �� ������ �� + { + fix_pwm_freq_synchro_ain(); + } + } + + if (sync_data.what_main_pch==1) + { + if (edrk.flag_second_PCH==0) // ������ �� ������ �� + { + fix_pwm_freq_synchro_ain(); + } + } + } + else + fix_pwm_freq_synchro_ain(); + + } + else + { + pwm_enable_calc_main = 0; + } + + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + +//#if(C_cds_in_number>=1) +// project.cds_in[0].read_pbus(&project.cds_in[0]); +//#endif + +#if(C_cds_in_number>=2) + project.cds_in[1].read_pbus(&project.cds_in[1]); +#endif + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_17_OFF; +#endif + + + + set_tics_timer_pwm(10,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + if (pwm_run == 1) + { + // ����� � ���������� �� ������-�� �� ��� ���� ���, ��������� �����? + soft_stop_x24_pwm_all(); + edrk.errors.e9.bits.ERR_INT_PWM_VERY_LONG |=1; + } + else + { + pwm_run = 1; + +// detect_I_M_overload(); +// if (edrk.from_rs.bits.ACTIVE) +// edrk.Go = edrk.StartGEDRS; + +// project_read_errors_controller(); // ������ ADR_ERRORS_TOTAL_INFO + + if ( (edrk.errors.e0.all) + || (edrk.errors.e1.all) + || (edrk.errors.e2.all) + || (edrk.errors.e3.all) + || (edrk.errors.e4.all) + || (edrk.errors.e5.all) + || (edrk.errors.e6.all) + || (edrk.errors.e7.all) + || (edrk.errors.e8.all) + || (edrk.errors.e9.all) + || (edrk.errors.e10.all) + || (edrk.errors.e11.all) + || (edrk.errors.e12.all) + ) + edrk.Stop |= 1; + else + edrk.Stop = 0; + + + + project.read_errors_controller(); + error_controller = (project.controller.read.errors.all | project.controller.read.errors_buses.bit.slave_addr_error | project.controller.read.errors_buses.bit.count_error_pbus); +// project.controller.read.errors.all = error_controller; + + + + if(error_controller && prev_error_controller==0) + { + edrk.errors.e11.bits.ERROR_CONTROLLER_BUS |= 1; + svgen_set_time_keys_closed(&svgen_pwm24_1); + svgen_set_time_keys_closed(&svgen_pwm24_2); + + write_swgen_pwm_times(PWM_MODE_RELOAD_FORCE); + +// xerror(main_er_ID(1),(void *)0); + } + prev_error_controller = error_controller;//project.controller.read.errors.all; + + + if (pwm_enable_calc_main==0)// ������� � ������ ������ ��� �� ������ ���� - ������ ����� + { + + if (en_rotor) + { +#if (_SIMULATE_AC==1) +// calc_rotors_sim(); +#else + calc_rotors(pwm_enable_calc_main_log); // �������� ������ � ������� �������� +#endif + + + + } + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + calc_zadanie_rampa(); + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + calc_norm_ADC_1(1); // ����� ���������� + + calc_power_full(); + + calc_all_limit_koeffs(); + + } + + ///////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////// + + + if (pwm_enable_calc_main)// ������� � ������ ������ ��� �� ������ ���� + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_18_ON; +#endif + + if (edrk.Obmotka1 == 0) + go_a = 1; + else + go_a = 0; + + if (edrk.Obmotka2 == 0) + go_b = 1; + else + go_b = 0; + + ////////////////////////// + + if (optical_read_data.data.cmd.bit.start_pwm && edrk.auto_master_slave.local.bits.slave ) + edrk.StartGEDfromSyncBus = 1; + else + edrk.StartGEDfromSyncBus = 0; + + edrk.master_Uzad = _IQ15toIQ( optical_read_data.data.pzad_or_wzad); + edrk.master_theta = _IQ12toIQ( optical_read_data.data.angle_pwm); + edrk.master_Izad = _IQ15toIQ( optical_read_data.data.iq_zad_i_zad); + edrk.master_Iq = _IQ15toIQ( optical_read_data.data.iq_zad_i_zad); + + set_tics_timer_pwm(11,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + ///////////////////////// + + if ((edrk.auto_master_slave.local.bits.slave==1 && edrk.auto_master_slave.local.bits.master==0) + || (edrk.auto_master_slave.local.bits.slave==0 && edrk.auto_master_slave.local.bits.master==1) ) + { + + if (edrk.auto_master_slave.local.bits.master != prev_master) + timer_wait_to_master_slave = 0; + + // ����� ������ ���� ��� ��������� �����. + if (timer_wait_to_master_slave>MAX_TIMER_WAIT_MASTER_SLAVE) + { + edrk.Status_Ready.bits.MasterSlaveActive = 1; + + if (edrk.auto_master_slave.local.bits.master) + edrk.MasterSlave = MODE_MASTER; + else + edrk.MasterSlave = MODE_SLAVE; + } + else + { + edrk.Status_Ready.bits.MasterSlaveActive = 0; + edrk.MasterSlave = MODE_DONTKNOW; + timer_wait_to_master_slave++; + } + prev_master = edrk.auto_master_slave.local.bits.master; + } + else + { + + edrk.Status_Ready.bits.MasterSlaveActive = 0; + edrk.MasterSlave = MODE_DONTKNOW; + + timer_wait_to_master_slave = 0; + } + + + set_tics_timer_pwm(12,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) { + if (edrk.MasterSlave == MODE_MASTER) { + if (get_start_ged_from_zadanie()) { + edrk.prepare_stop_PWM = 0; + //edrk.StartGEDfromZadanie = 1; + localStartGEDfromZadanie = 1; + } else { + edrk.prepare_stop_PWM = 1; + if (edrk.k_stator1 < 41943) { //335544 ~ 2% + //edrk.StartGEDfromZadanie = 0; + localStartGEDfromZadanie = 0; + } + } + } else { + if (get_start_ged_from_zadanie()) { + //edrk.StartGEDfromZadanie = 1; + localStartGEDfromZadanie = 1; + } else { + if (edrk.k_stator1 < 41943) { //335544 ~ 2% + //edrk.StartGEDfromZadanie = 0; + localStartGEDfromZadanie = 0; + } + } + edrk.prepare_stop_PWM = optical_read_data.data.cmd.bit.prepare_stop_PWM; + } + } else { + //edrk.StartGEDfromZadanie = + localStartGEDfromZadanie = get_start_ged_from_zadanie(); + } + + // �������� ����������� localStartGEDfromZadanie=1 � edrk.StartGEDfromZadanie + if (localStartGEDfromZadanie && edrk.prevStartGEDfromZadanie==0) + { + if (countStartGEDfromZadanie<MAX_COUNT_COUNTSTARTGEDFROMZADANIE) + countStartGEDfromZadanie++; + else + edrk.StartGEDfromZadanie = localStartGEDfromZadanie; + } + else + { + edrk.StartGEDfromZadanie = localStartGEDfromZadanie; + countStartGEDfromZadanie = 0; + } + + + edrk.prevStartGEDfromZadanie = edrk.StartGEDfromZadanie; + + set_tics_timer_pwm(13,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + + // �� ������ � ���� ������ �� ����������� �����������? + if (optical_read_data.data.cmd.bit.rascepitel_cmd==CODE_RASCEPITEL_CMD_REQUEST_AND_THIS_OFF) + { + if (edrk.StartGEDfromZadanie==1) + { + edrk.flag_wait_set_to_zero_zadanie = 1; + edrk.you_can_on_rascepitel = 0; + } + else + edrk.flag_block_zadanie = 1; + } + else + { + if (edrk.StartGEDfromZadanie) + edrk.you_can_on_rascepitel = 0; + else + edrk.you_can_on_rascepitel = 1; + } +// edrk.flag_wait_set_to_zero_zadanie = 0; + + + + set_tics_timer_pwm(131,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + if (optical_read_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY1TO2 + && optical_write_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY1TO2) + { + // ��� �� ����� � ����� ����� �� ����������1 � 2. + edrk.flag_wait_both_ready2 = 1; + } + + +// if (optical_read_data.data.cmd.bit.ready_cmd) +// +// edrk.flag_another_bs_first_ready12 + + if (optical_read_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY2 + && optical_write_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY2 && edrk.flag_wait_both_ready2) + { + // ��������� ����� ����� + edrk.flag_wait_both_ready2 = 0; + } + + if (optical_write_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY1) + edrk.flag_wait_both_ready2 = 0; + + if (edrk.flag_wait_both_ready2) + { + if (timer_wait_both_ready2>MAX_TIMER_WAIT_BOTH_READY2) + edrk.errors.e1.bits.VERY_LONG_BOTH_READY2 |= 1; + else + timer_wait_both_ready2++; + + } + else + timer_wait_both_ready2 = 0; + + + if (optical_read_data.data.cmd.bit.rascepitel_cmd==CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON + && optical_read_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY2) // ��� ����������� ������� ��� ��������� � ��� �� �������� + { + edrk.flag_block_zadanie = 0; + edrk.flag_wait_set_to_zero_zadanie = 0; + } + + if (optical_read_data.data.cmd.bit.rascepitel_cmd==CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_OFF + && optical_read_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY1) // ��� ����������� �������� � ����� �� ��� �� ��������� + { + edrk.flag_block_zadanie = 0; + edrk.flag_wait_set_to_zero_zadanie = 0; + } + + + if (edrk.StartGEDfromZadanie==0 && edrk.flag_block_zadanie + && (optical_read_data.data.cmd.bit.rascepitel_cmd==CODE_RASCEPITEL_CMD_REQUEST_AND_THIS_OFF)) + // ��������� ������� �� ������� ����������� + edrk.you_can_on_rascepitel = 1; + + + if (edrk.flag_wait_set_to_zero_zadanie) + { + if (timer_wait_set_to_zero_zadanie>MAX_TIMER_WAIT_SET_TO_ZERO_ZADANIE) + { + // ������ �� �������� ��������� ������ �����������, �� �������� ������� � ����� ���� ��� �� ������� ���� ����� + // �� ����� �� ���������!!!! + edrk.errors.e1.bits.ANOTHER_BS_NOT_ON_RASCEPITEL |= 1; + + } + else + timer_wait_set_to_zero_zadanie++; + + } + else + timer_wait_set_to_zero_zadanie = 0; + + + // ���� ������ �����������, �� �������� ������ �� �����������. + if (edrk.errors.e1.bits.ANOTHER_BS_NOT_ON_RASCEPITEL) + edrk.flag_wait_set_to_zero_zadanie = 0; + + + edrk.StartGED = ((edrk.StartGEDfromControl==1) && (edrk.StartGEDfromZadanie==1) && (edrk.flag_block_zadanie==0)); + + + if (edrk.MasterSlave == MODE_MASTER) + { + edrk.GoWait = ( (edrk.StartGED ) && (edrk.Stop == 0) + && (project.controller.read.errors.all==0) && + (slow_error==0) && + (edrk.Status_Ready.bits.ready_final) + && edrk.Status_Ready.bits.MasterSlaveActive + && edrk.warnings.e9.bits.BREAKER_GED_ON==0 + ); + } + else + if (edrk.MasterSlave == MODE_SLAVE) + { + edrk.GoWait = ( (edrk.StartGED && edrk.StartGEDfromSyncBus) && (edrk.Stop == 0) + && (project.controller.read.errors.all==0) && + (slow_error==0) && + (edrk.Status_Ready.bits.ready_final) + && edrk.Status_Ready.bits.MasterSlaveActive + ); + } + else + edrk.GoWait = 0; + + // if (edrk.GoWait==0 && edrk.Go == 0 && + + + // ��������� ������� ������� edrk.Go + if (edrk.GoWait) + { + if (count_wait_go_0>=MAX_COUNT_WAIT_GO_0) + edrk.Go = edrk.GoWait; + else + { + edrk.Go = 0; + edrk.errors.e7.bits.VERY_FAST_GO_0to1 |=1; // ������! ������� ������ ������ ��������� edrk.Go!!! + } + } + else + { + if (edrk.Go) + count_wait_go_0 = 0; + + edrk.Go = 0; + if (count_wait_go_0<MAX_COUNT_WAIT_GO_0) + count_wait_go_0++; + } + + + if (optical_read_data.data.cmd.bit.ready_cmd == CODE_READY_CMD_READY2) + edrk.count_bs_work = 1; + else + edrk.count_bs_work = 0; + +#if (_ENABLE_LOG_TICS_PWM==1) +/* + if (stop_count_time_buf==0) + { + count_time_buf++; + if (count_time_buf>=(MAX_COUNT_TIME_BUF-1)) + count_time_buf = 0; + + log_wait = 0; + if (edrk.MasterSlave == MODE_MASTER) + log_wait |= 0x1; + if (edrk.MasterSlave == MODE_SLAVE) + log_wait |= 0x2; + if (edrk.StartGED) + log_wait |= 0x4; + if (edrk.Stop) + log_wait |= 0x8; + if (edrk.Status_Ready.bits.ready_final) + log_wait |= 0x10; + if (edrk.Status_Ready.bits.MasterSlaveActive) + log_wait |= 0x20; + if (edrk.GoWait) + log_wait |= 0x40; + if (edrk.Go) + log_wait |= 0x80; + if (project.controller.read.errors.all==0) + log_wait |= 0x100; + if (slow_error) + log_wait |= 0x200; + if (edrk.StartGEDfromSyncBus) + log_wait |= 0x400; + + + time_buf[count_time_buf] = log_wait; + + if (edrk.errors.e7.bits.VERY_FAST_GO_0to1) + stop_count_time_buf = 1; + } +*/ +#endif + + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_GO) + if (edrk.StartGEDfromSyncBus) + { + PWM_LINES_TK_17_ON; + } + else + { + PWM_LINES_TK_17_OFF; + } + + if (edrk.StartGEDfromZadanie) + { + PWM_LINES_TK_18_ON; + } + else + { + PWM_LINES_TK_18_OFF; + } + if (edrk.flag_block_zadanie) + { + PWM_LINES_TK_19_ON; + } + else + { + PWM_LINES_TK_19_OFF; + } + + if (edrk.StartGEDfromControl) + { + PWM_LINES_TK_16_ON; + } + else + { + PWM_LINES_TK_16_OFF; + } + +#endif + + + + set_tics_timer_pwm(15,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + ////////////////////////////////// + ////////////////////////////////// + + if(edrk.Go == 1) + { + if (edrk.Go != prevGo) + { + edrk.count_run++; +// clear_mem(FAST_LOG); +// count_start_impuls = 0; +// count_step = 0; + f.count_step_ram_off = COUNT_SAVE_LOG_OFF; +// count_step_run = 0; + + // set_start_mem(FAST_LOG); + // set_start_mem(SLOW_LOG); + + // logpar.start_write_fast_log = 1; + + init_uf_const(); + init_simple_scalar(); + + Fzad = 0; + Uzad1 = 0; + Uzad2 = 0; + + clear_logpar(); + } + else + { + + if (f.count_start_impuls < COUNT_START_IMP) + { + f.count_start_impuls++; + } + else + { + f.count_start_impuls = COUNT_START_IMP; + + f.flag_record_log = 1; + enable_calc_vector = 1; + + } + + } + } + else // (edrk.Go == 0) + { + + if (f.count_step_ram_off > 0) + { + f.count_step_ram_off--; + f.flag_record_log = 1; + } else { + f.flag_record_log = 0; + } + + // ������ ������ + if (edrk.ManualDischarge && prev_ManualDischarge!=edrk.ManualDischarge) + edrk.Discharge = 1; + + prev_ManualDischarge =edrk.ManualDischarge; + + if (f.count_start_impuls == 0) + { + + if (edrk.Discharge || (edrk.ManualDischarge ) ) + { + break_resistor_managment_calc(); + soft_start_x24_break_1(); + } + else + { + + if (f.count_step_ram_off > 0) + { + break_resistor_recup_calc(edrk.zadanie.iq_set_break_level); + // soft_start_x24_break_1(); + } + else + { + // ��� ���������� ������ �� ��������� ����� ���������� + soft_stop_x24_pwm_all(); + + } + } + + } + + set_tics_timer_pwm(16,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + if (f.count_start_impuls==COUNT_START_IMP) + { + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) + { + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } + + vectorControlConstId(edrk.zadanie.iq_power_zad_rmp, edrk.zadanie.iq_oborots_zad_hz_rmp, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.iq_power_kw_another_bs, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, + 0, 1); + + test_calc_vect_dq_pwm24_Ing(vect_control.iqTheta, vect_control.iqUdKm, vect_control.iqUqKm, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance_rmp, edrk.zadanie.iq_k_u_disbalance_rmp, + filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.Uzad_to_slave); + analog.PowerFOC = edrk.P_to_master; + Fzad = vect_control.iqFstator; + Izad_out = edrk.Iq_to_slave; + } else { + test_calc_simple_dq_pwm24_Ing(Fzad, 0, 0, + 0, 0, filter.iqU_1_fast, filter.iqU_2_fast, + 1, + edrk.Uzad_max, + edrk.master_theta, + edrk.master_Uzad, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.tetta_to_slave, + &edrk.Uzad_to_slave); + } + } + else + { + if (f.count_start_impuls==COUNT_START_IMP-1) + { + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) + { + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } + + vectorControlConstId(edrk.zadanie.iq_power_zad_rmp, edrk.zadanie.iq_oborots_zad_hz_rmp, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.iq_power_kw_another_bs, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, + 0, 1); + + test_calc_vect_dq_pwm24_Ing(vect_control.iqTheta, vect_control.iqUdKm, vect_control.iqUqKm, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance_rmp, edrk.zadanie.iq_k_u_disbalance_rmp, + filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.Uzad_to_slave); + analog.PowerFOC = edrk.P_to_master; + Fzad = vect_control.iqFstator; + Izad_out = edrk.Iq_to_slave; + } else { + test_calc_simple_dq_pwm24_Ing(Fzad, 0, 0, + 0, 0, filter.iqU_1_fast, filter.iqU_2_fast, + 1, + edrk.Uzad_max, + edrk.master_theta, + edrk.master_Uzad, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.tetta_to_slave, + &edrk.Uzad_to_slave); + } + + } + else + { + if (f.count_start_impuls==COUNT_START_IMP-2) + { + // ��� ����� middle ��������� ����� ����������� ������ +// svgen_set_time_keys_closed(&svgen_pwm24_1); +// svgen_set_time_keys_closed(&svgen_pwm24_2); + svgen_set_time_middle_keys_open(&svgen_pwm24_1); + svgen_set_time_middle_keys_open(&svgen_pwm24_2); + } + else + // � ��� �� ��� ����������� + { + svgen_set_time_keys_closed(&svgen_pwm24_1); + svgen_set_time_keys_closed(&svgen_pwm24_2); + } + + Fzad = 0; + + } + } + + + if (f.count_start_impuls > 0) { + f.count_start_impuls -= 1; + } else { + f.count_start_impuls = 0; + } + enable_calc_vector = 0; + + + + Uzad1 = 0; + Uzad2 = 0; + + } // end if Go==1 + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_18_OFF; +#endif + + + } // end pwm_enable_calc_main one interrupt one period only + +/* + * + // if ((m.m0.bit.EnableGoA == 1) && (f.Obmotka1 == 0)) + + + // if ((m.m0.bit.EnableGoB == 1) && (f.Obmotka2 == 0)) + if (f.Obmotka2 == 0) + { + go_b = 1; + } + else + { + go_b = 0; + } + + if (go_a == 0 && prev_go_a != go_a) + { + //��������� 1 ������� + soft_stop_x24_pwm_1(); + } + + if (go_a == 1 && prev_go_a != go_a) + { + //�������� 1 ������� + soft_start_x24_pwm_1(); + } + + if (go_b == 0 && prev_go_b != go_b) + { + //��������� 2 ������� + soft_stop_x24_pwm_2(); + } + + if (go_b == 1 && prev_go_b != go_b) + { + //�������� 2 ������� + soft_start_x24_pwm_2(); + } + + prev_go_a = go_a; + prev_go_b = go_b; + * + * + */ + + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + + if (pwm_enable_calc_main) // ������� � ������ ������ ��� �� ������ ���� + { + + + if (f.count_start_impuls==1 && edrk.Go==1) + { + // � ��� �� ��� �� ���������� + svgen_set_time_keys_closed(&svgen_pwm24_1); + svgen_set_time_keys_closed(&svgen_pwm24_2); + // soft_start_x24_pwm_1_2(); + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) { + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } + vectorControlConstId(edrk.zadanie.iq_power_zad_rmp, edrk.zadanie.iq_oborots_zad_hz_rmp, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.P_from_slave, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, 1, edrk.prepare_stop_PWM); + } + } + + if (f.count_start_impuls==2 && edrk.Go==1) + { + // �������� ��� + if (go_a == 1 && go_b == 1) { + // start_pwm(); ������ ��������� ���� ��� �� ��������� edrk.Go + soft_start_x24_pwm_1_2(); + } else if (go_a == 1) { + soft_start_x24_pwm_1(); + } else if (go_b == 1) { + soft_start_x24_pwm_2(); + } + + // enable work break +#if (DISABLE_WORK_BREAK==1) + +#else +// if (edrk.disable_break_work==0) + { + soft_start_x24_break_1(); + } +#endif + + } // end if (count_start_impuls==5) + + + if (f.count_start_impuls==3 && edrk.Go==1) + { + // ��������� ��������� ��� + svgen_set_time_middle_keys_open(&svgen_pwm24_1); + svgen_set_time_middle_keys_open(&svgen_pwm24_2); + } + + + + if (f.count_start_impuls==4 && edrk.Go==1) + { + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) + { + +// void simple_scalar(int n_alg, int n_wind_pump, _iq Frot_pid, _iq Frot,_iq fzad,_iq mzz_zad, _iq bpsi_const, _iq fzad_provorot, +// _iq iqIm_1, _iq iqIm_2, _iq iqUin, _iq Iin, _iq powerzad, _iq power_pid, +// _iq *Fz, _iq *Uz1) + + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } + + vectorControlConstId(0, 0, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.iq_power_kw_another_bs, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, + 0, edrk.prepare_stop_PWM); + + test_calc_vect_dq_pwm24_Ing(vect_control.iqTheta, vect_control.iqUdKm, vect_control.iqUqKm, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance_rmp, edrk.zadanie.iq_k_u_disbalance_rmp, + filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.Uzad_to_slave); + Fzad = vect_control.iqFstator; + Izad_out = edrk.Iq_to_slave; + } else { + test_calc_simple_dq_pwm24_Ing(Fzad, 0, 0, + 0, 0, filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.master_theta, + edrk.master_Uzad, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.tetta_to_slave, &edrk.Uzad_to_slave); + + + simple_scalar(1,0, WRotor.RotorDirectionSlow, + WRotor.iqWRotorSumFilter2, WRotor.iqWRotorSumFilter, + 0, + 0, + 0, edrk.iq_bpsi_normal, + 0, + // analog.iqU_1_long+analog.iqU_2_long, + edrk.zadanie.iq_ZadanieU_Charge_rmp+edrk.zadanie.iq_ZadanieU_Charge_rmp, + 0, + edrk.zadanie.iq_power_zad_rmp, 0, + edrk.zadanie.iq_limit_power_zad_rmp, edrk.Mode_ScalarVectorUFConst, + 0,0, edrk.count_bs_work+1, + &Fzad, &Uzad1, &Uzad2, &Izad_out); + } + + } + + if (f.count_start_impuls == COUNT_START_IMP && edrk.Go==1) + { + if (pwm_enable_calc_main) // ������� � ������ ������ ��� �� ������ ���� + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_21_ON; +#endif + + + //break_resistor_recup_calc(edrk.zadanie.iq_ZadanieU_Charge); + break_resistor_recup_calc(edrk.zadanie.iq_set_break_level); + + set_tics_timer_pwm(17,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + run_calc_uf = 1; + + // �������� ������ ���, ��� ��� ������� � middle + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + uf_const(&Fzad,&Uzad1,&Uzad2); +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + + test_calc_simple_dq_pwm24_Ing(Fzad, + Uzad1, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance, + edrk.zadanie.iq_k_u_disbalance, + filter.iqU_1_fast, + filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.master_theta, + edrk.master_Uzad, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, + &edrk.tetta_to_slave, + &edrk.Uzad_to_slave); +// rmp_freq.DesiredInput = alg_pwm24.freq1; +// rmp_freq.calc(&rmp_freq); +// Fzad = rmp_freq.Out; +// +// vhz1.Freq = Fzad; +// vhz1.calc(&vhz1); +// +// +// Uzad1 = alg_pwm24.k1; +// Uzad2 = alg_pwm24.k1; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + + // test_calc_pwm24(Uzad1, Uzad2, Fzad); + // analog_dq_calc_const(); + + } // end ALG_MODE_UF_CONST + else + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_POWER) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + simple_scalar(1, + 0, + WRotor.RotorDirectionSlow, + WRotor.iqWRotorSumFilter, //rotor_22220.iqFlong * rotor_22220.direct_rotor; + WRotor.iqWRotorSumFilter, //rotor_22220.iqFout * rotor_22220.direct_rotor; + //0, 0, + edrk.zadanie.iq_oborots_zad_hz_rmp, + edrk.all_limit_koeffs.sum_limit, + edrk.zadanie.iq_Izad_rmp, + edrk.iq_bpsi_normal, + analog.iqIm, +// analog.iqU_1_long+analog.iqU_2_long, + edrk.zadanie.iq_ZadanieU_Charge_rmp+edrk.zadanie.iq_ZadanieU_Charge_rmp, + analog.iqIin_sum, + edrk.zadanie.iq_power_zad_rmp, + edrk.iq_power_kw_full_znak,//(filter.PowerScalar+edrk.iq_power_kw_another_bs), + edrk.zadanie.iq_limit_power_zad_rmp, edrk.Mode_ScalarVectorUFConst, + edrk.master_Izad, + edrk.MasterSlave, + edrk.count_bs_work+1, + &Fzad, + &Uzad1, + &Uzad2, + &Izad_out); + + set_tics_timer_pwm(18,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + + + + if (edrk.cmd_disable_calc_km_on_slave) + Uzad_from_master = edrk.master_Uzad; + else + { +#if (DISABLE_CALC_KM_ON_SLAVE==1) + Uzad_from_master = edrk.master_Uzad; +#else + Uzad_from_master = Uzad1; +#endif + + } + + test_calc_simple_dq_pwm24_Ing(Fzad, Uzad1, edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance, edrk.zadanie.iq_k_u_disbalance, filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.master_theta, + Uzad_from_master, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.tetta_to_slave, &edrk.Uzad_to_slave); +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + + set_tics_timer_pwm(19,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } + + analog_dq_calc_external(wd, uf_alg.tetta); + + } // end ALG_MODE_SCALAR_OBOROTS + else + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) + { + +// void simple_scalar(int n_alg, int n_wind_pump, _iq Frot_pid, _iq Frot,_iq fzad,_iq mzz_zad, _iq bpsi_const, _iq fzad_provorot, +// _iq iqIm_1, _iq iqIm_2, _iq iqUin, _iq Iin, _iq powerzad, _iq power_pid, +// _iq *Fz, _iq *Uz1) + + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } else { + wd = uf_alg.winding_displacement_bs2; + } +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + vectorControlConstId(edrk.zadanie.iq_power_zad_rmp, edrk.zadanie.iq_oborots_zad_hz_rmp, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.iq_power_kw_another_bs, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, + 0, edrk.prepare_stop_PWM); +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_ON; +#endif + + test_calc_vect_dq_pwm24_Ing(vect_control.iqTheta, vect_control.iqUdKm, vect_control.iqUqKm, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance_rmp, edrk.zadanie.iq_k_u_disbalance_rmp, + filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.Uzad_to_slave); + + analog.PowerFOC = edrk.P_to_master; + Fzad = vect_control.iqFstator; + Izad_out = edrk.Iq_to_slave; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_20_OFF; +#endif + } // end ALG_MODE_FOC_OBOROTS + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_21_OFF; +#endif + + } // end pwm_enable_calc_main + + } // end (count_start_impuls == COUNT_START_IMP && edrk.Go==1) + else + { + run_calc_uf = 0; + if (pwm_enable_calc_main) // ������� � ������ ������ ��� �� ������ ���� + { + + } + svgen_pwm24_1.Ta_imp = 0; + svgen_pwm24_1.Tb_imp = 0; + svgen_pwm24_1.Tc_imp = 0; + svgen_pwm24_2.Ta_imp = 0; + svgen_pwm24_2.Tb_imp = 0; + svgen_pwm24_2.Tc_imp = 0; + + } // end else (count_start_impuls == COUNT_START_IMP && edrk.Go==1) + + prevGo = edrk.Go; + + + + ////////////////////////////////// + optical_write_data.data.cmd.bit.start_pwm = edrk.Go; + optical_write_data.data.cmd.bit.prepare_stop_PWM = edrk.prepare_stop_PWM; + + optical_write_data.data.angle_pwm = _IQtoIQ12(edrk.tetta_to_slave + vect_control.add_tetta); + optical_write_data.data.pzad_or_wzad = _IQtoIQ15(edrk.Uzad_to_slave); + optical_write_data.data.iq_zad_i_zad = _IQtoIQ15(edrk.Izad_out); + + optical_bus_update_data_write(); + + set_tics_timer_pwm(20,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + if (edrk.ms.another_bs_maybe_on==1 && edrk.auto_master_slave.local.bits.master) + { + // i_led2_on(); + } + + ////////////////////////////////// + ////////////////////////////////// + + edrk.Izad_out = Izad_out; + + if (edrk.MasterSlave==MODE_SLAVE) + { + edrk.f_stator = Fzad; + edrk.k_stator1 = edrk.Uzad_to_slave;//Uzad1; + edrk.k_stator2 = edrk.Uzad_to_slave;//Uzad2; + + } + else + if (edrk.MasterSlave==MODE_MASTER) + { + edrk.f_stator = Fzad; + edrk.k_stator1 = edrk.Uzad_to_slave;//Uzad1; + edrk.k_stator2 = edrk.Uzad_to_slave; + } + else + { + edrk.f_stator = 0; + edrk.k_stator1 = 0; + edrk.k_stator2 = 0; + } + + } // end pwm_enable_calc_main + + + + + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + /////////////////////////////////////////// + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_22_ON; +#endif + + if (xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + write_swgen_pwm_times(PWM_MODE_RELOAD_FORCE); + else + { + if (edrk.Go==1) + { + if (f.count_start_impuls==COUNT_START_IMP-1) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times(PWM_MODE_RELOAD_LEVEL_LOW); + } + else +// if (pwm_enable_calc_main) + write_swgen_pwm_times(PWM_MODE_RELOAD_FORCE); + } + else + { + if (f.count_start_impuls==COUNT_START_IMP-3) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times(PWM_MODE_RELOAD_LEVEL_LOW); + + } + else + write_swgen_pwm_times(PWM_MODE_RELOAD_FORCE); + } + + + + // if (pwm_enable_calc_main) + // prev_run_calc_uf = run_calc_uf; + + + + } +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_22_OFF; +#endif + + + set_tics_timer_pwm(21,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + // test write oscil buf + + if ( pwm_enable_calc_main==0) // ������� � ������ ������ ��� �� ������ ���� + { + + run_write_logs(); + + } + + + // i_led2_on(); + // + if (edrk.SumSbor == 1) { + detect_protect_adc(uf_alg.tetta_bs, uf_alg.tetta_bs); + //// get_tics_timer_pwm(pwm_enable_calc_main,count_timer_buf); + } + + // fill_RMS_buff_interrupt(uf_alg.tetta_bs, uf_alg.tetta_bs); + + set_tics_timer_pwm(24,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + + // out_I_over_1_6.calc(&out_I_over_1_6); + // i_led2_off(); + + + pwm_run = 0; + + + } // end if pwm_run==1 + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_ON; +#endif + + if (pwm_enable_calc_main==0) // ������� � ������ ������ ��� �� ������ ���� + { + + + // pwm_analog_ext_interrupt(); + +// inc_RS_timeout_cicle(); +// inc_CAN_timeout_cicle(); + +#if (_SIMULATE_AC==1) + sim_model_execute(); +#endif + + } + + pwm_analog_ext_interrupt(); + pwm_inc_interrupt(); + + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_ON; +#endif + + + + + set_tics_timer_pwm(25,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + + +#if (_ENABLE_SLOW_PWM) +// pause_1000(slow_pwm_pause); +#endif + + set_tics_timer_pwm(26,count_timer_buf); + get_tics_timer_pwm(pwm_enable_calc_main_log); + +///////////////////////////////////////////////// + // ������� ����� ������ � ���������� + end_tics_4timer = EvbRegs.T3CNT; + + if (end_tics_4timer>start_tics_4timer) + { + time_delta = (end_tics_4timer - start_tics_4timer); + time_delta = time_delta * 33/1000; + if (pwm_enable_calc_main) + edrk.period_calc_pwm_int1 = time_delta;//(end_tics_4timer - start_tics_4timer)*33/1000; + else + edrk.period_calc_pwm_int2 = time_delta;//(end_tics_4timer - start_tics_4timer)*33/1000; + } + // ��������� ������� ����� ������ � ���������� + ///////////////////////////////////////////////// + + // get_tics_timer_pwm(pwm_enable_calc_main,count_timer_buf); + + + + + +#if (_ENABLE_LOG_TICS_PWM==1) + + for (i_log=count_timer_buf;i_log<MAX_COUNT_TIME_BUF;i_log++) + { + time_buf[i_log] = 0; + } + + set_tics_timer_pwm(100,count_timer_buf); + time_buf[count_timer_buf] = time_delta; + +// set_tics_timer_pwm(edrk.period_calc_pwm_int); + + + if (c_run>=10000) + c_run=c_run_start; + else + c_run++; +#endif + +#if (ENABLE_LOG_INTERRUPTS) + add_log_interrupts(103); +#endif + + + +// i_sync_pin_off(); + edrk.into_pwm_interrupt = 0; + +#if (_ENABLE_INTERRUPT_PWM_LED2) +i_led2_on_off(0); +#endif + + + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + // PWM_LINES_TK_16_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_16_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_16_OFF; +#endif + + +#if (_ENABLE_PWM_LED2_PROFILE) + i_led2_on_off(0); + if (pwm_enable_calc_main==0) + profile_pwm[pos_profile_pwm] = 2; +#endif + + +} +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + + + +#pragma CODE_SECTION(fix_pwm_freq_synchro_ain,".fast_run"); +void fix_pwm_freq_synchro_ain(void) +{ + unsigned int new_freq; + static unsigned int delta_freq = 1; +// if (f.Sync_input_or_output == SYNC_INPUT) + { + sync_inc_error(); + + if (sync_data.disable_sync || sync_data.timeout_sync_signal == 1 || sync_data.enable_do_sync == 0) + { + + new_freq = xpwm_time.pwm_tics; + i_WriteMemory(ADR_PWM_PERIOD, new_freq); + + return; + } + + if (sync_data.pwm_freq_plus_minus_zero==1) + { + + + //Increment xtics + new_freq = xpwm_time.pwm_tics + delta_freq; + i_WriteMemory(ADR_PWM_PERIOD, new_freq); // Saw period in tics. 1 tic = 16.67 nsec + + // change_freq_pwm(VAR_FREQ_PWM_XTICS); + + + } + + if (sync_data.pwm_freq_plus_minus_zero==-1) + { + //4464 + //Decrement xtics + new_freq = xpwm_time.pwm_tics - delta_freq; + i_WriteMemory(ADR_PWM_PERIOD, new_freq); // Saw period in tics. 1 tic = 16.67 nsec + + // change_freq_pwm(VAR_FREQ_PWM_XTICS); + + } + + if (sync_data.pwm_freq_plus_minus_zero==0) + { + new_freq = xpwm_time.pwm_tics; + i_WriteMemory(ADR_PWM_PERIOD, new_freq); + // change_freq_pwm(VAR_FREQ_PWM_XTICS); + } + + } + + + +} + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +/* +void slow_vector_update() +{ + _iq iqKzad = 0; + + freq1 = _IQ (f.fzad/F_STATOR_MAX);//f.iqFRotorSetHz; + iqKzad = _IQ(f.kzad); + k1 = zad_intensiv_q(20000, 20000, k1, iqKzad); + +} +*/ + +void detect_work_revers(int direction, _iq fzad, _iq frot) +{ + static int prev_revers = 0; + int flag_revers; + // ����������� ��� ����������� + if (direction == -1 && fzad > 0) + { + flag_revers = 1; + } + else + if (direction == 1 && fzad < 0) + { + flag_revers = 1; + } + else + { + flag_revers = 0; + } + + if (flag_revers && prev_revers==0) + edrk.count_revers++; + + prev_revers = flag_revers; + +} + + +void calc_power_full(void) +{ + _iq power_full_abs, power_one_abs, power_full_abs_f, power_one_abs_f; + + // + power_one_abs = _IQabs(filter.PowerScalar); + power_one_abs_f = _IQabs(filter.PowerScalarFilter2); + power_full_abs = power_one_abs + _IQabs(edrk.iq_power_kw_another_bs); + power_full_abs_f = power_one_abs_f + _IQabs(edrk.iq_power_kw_another_bs); + + if (edrk.oborots>=0) + { + edrk.iq_power_kw_full_znak = power_full_abs; + edrk.iq_power_kw_one_znak = power_one_abs; + edrk.iq_power_kw_full_filter_znak = power_full_abs_f; + edrk.iq_power_kw_one_filter_znak = power_one_abs_f; + } + else + { + edrk.iq_power_kw_full_znak = -power_full_abs; + edrk.iq_power_kw_one_znak = -power_one_abs; + edrk.iq_power_kw_full_filter_znak = -power_full_abs_f; + edrk.iq_power_kw_one_filter_znak = -power_one_abs_f; + } + + edrk.iq_power_kw_full_abs = power_full_abs; + edrk.iq_power_kw_one_abs = power_one_abs; + edrk.iq_power_kw_full_filter_abs = power_full_abs_f; + edrk.iq_power_kw_one_filter_abs = power_one_abs_f; + +} diff --git a/Inu/Src/main/PWMTools.h b/Inu/Src/main/PWMTools.h new file mode 100644 index 0000000..67f30b2 --- /dev/null +++ b/Inu/Src/main/PWMTools.h @@ -0,0 +1,54 @@ +#ifndef PWMTOOLS_H +#define PWMTOOLS_H +#include <f281xpwm.h> +#include <v_pwm24_v2.h> + + +////////////////////////////////////////////////// +////////////////////////////////////////////////// +////////////////////////////////////////////////// + + +void InitPWM(void); +void PWM_interrupt(void); +void PWM_interrupt_main(void); + + + +void stop_wdog(void); +void start_wdog(void); + + +void global_time_interrupt(void); +void optical_bus_read_write_interrupt(void); +void pwm_analog_ext_interrupt(void); +void pwm_inc_interrupt(void); + +void fix_pwm_freq_synchro_ain(void); +void async_pwm_ext_interrupt(void); + + + +void calc_rotors(int flag); + +void detect_work_revers(int direction, _iq fzad, _iq frot); + +void calc_power_full(void); + + + +////////////////////////////////////////////////// +////////////////////////////////////////////////// +////////////////////////////////////////////////// +////////////////////////////////////////////////// + +extern PWMGEND pwmd; + +//extern int var_freq_pwm_xtics; +//extern int var_period_max_xtics; +//extern int var_period_min_xtics; + + + +#endif //PWMTOOLS_H + diff --git a/Inu/Src/main/adc_internal.h b/Inu/Src/main/adc_internal.h new file mode 100644 index 0000000..c74a174 --- /dev/null +++ b/Inu/Src/main/adc_internal.h @@ -0,0 +1,33 @@ + + +#define ADC_usDELAY 8000L +#define ADC_usDELAY2 20L + + + + + +// Determine when the shift to right justify the data takes place +// Only one of these should be defined as 1. +// The other two should be defined as 0. +#define POST_SHIFT 0 // Shift results after the entire sample table is full +#define INLINE_SHIFT 1 // Shift results as the data is taken from the results regsiter +#define NO_SHIFT 0 // Do not shift the results + +// ADC start parameters +#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25MHz +#define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25MHz/(1) = 25MHz +#define ADC_SHCLK 0x1 // S/H width in ADC module periods = 2 ADC cycle +#define AVG 1000 // Average sample limit +#define ZOFFSET 0x00 // Average Zero offset +#define BUF_SIZE 100 // Sample buffer size + + + +#define FREQ_ADC 15000.0//26.08.2009//73000.0 + + +#define read_ADC(c) (*(&AdcRegs.ADCRESULT0+c)>>4) + +#define SDVIG_K_FILTER_S 2 //1//(27.08.2009) //3 + diff --git a/Inu/Src/main/adc_tools.c b/Inu/Src/main/adc_tools.c new file mode 100644 index 0000000..80b3b8d --- /dev/null +++ b/Inu/Src/main/adc_tools.c @@ -0,0 +1,1412 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include <adc_internal.h> +#include <adc_tools.h> +#include <edrk_main.h> +#include <master_slave.h> +#include <project.h> + +#include "mathlib.h" +#include "filter_v1.h" +#include "xp_project.h" + +//#include "spartan_tools.h" + + + +//#define LOG_ACP_TO_BUF 1 + +#ifdef LOG_ACP_TO_BUF + +#define SIZE_BUF_LOG_ACP 500 +#pragma DATA_SECTION(BUF_ADC,".slow_vars") +int BUF_ADC[SIZE_BUF_LOG_ACP]; +#pragma DATA_SECTION(BUF_ADC_2,".slow_vars") +int BUF_ADC_2[SIZE_BUF_LOG_ACP]; + +#endif + + + +#if (USE_INTERNAL_ADC==1) + +#if(C_adc_number==1) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_INTERNAL}; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_INTERNAL}; +#endif +#if(C_adc_number==2) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_INTERNAL }; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_INTERNAL }; +#endif +#if(C_adc_number==3) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1, R_ADC_DEFAULT_2,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_2, K_LEM_ADC_DEFAULT_INTERNAL }; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_2, NORMA_ADC_DEFAULT_INTERNAL }; +#endif + +#else + +#if(C_adc_number==1) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0}; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0}; +#endif +#if(C_adc_number==2) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1 }; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1 }; +#endif +#if(C_adc_number==3) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1, R_ADC_DEFAULT_2 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_2 }; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_2 }; +#endif + +#endif + +//unsigned int const R_ADC_1[16] = R_ADC_DEFAULT_1; +//unsigned int const K_LEM_ADC_1[16] = K_LEM_ADC_DEFAULT_1; + + + + +#if (USE_INTERNAL_ADC==1) +int error_ADC[COUNT_ARR_ADC_BUF][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; +#else + +#if(C_adc_number==1) +int error_ADC[COUNT_ARR_ADC_BUF][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; +#endif +#if(C_adc_number==2) +int error_ADC[COUNT_ARR_ADC_BUF][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; +#endif +#if(C_adc_number==3) +int error_ADC[COUNT_ARR_ADC_BUF][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; +#endif + +#endif + + +#pragma DATA_SECTION(ADC_f,".fast_vars"); +int ADC_f[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(ADC_fast,".fast_vars"); +int ADC_fast[COUNT_ARR_ADC_BUF][16][COUNT_ARR_ADC_BUF_FAST_POINT]; + + +#pragma DATA_SECTION(ADC_sf,".fast_vars"); +int ADC_sf[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(analog,".fast_vars"); +ANALOG_VALUE analog = ANALOG_VALUE_DEFAULT; + +#pragma DATA_SECTION(filter,".fast_vars"); +ANALOG_VALUE filter = ANALOG_VALUE_DEFAULT; + +#pragma DATA_SECTION(analog_zero,".fast_vars"); +ANALOG_VALUE analog_zero = ANALOG_VALUE_DEFAULT; + + + +unsigned int const level_err_ADC_PLUS[16] = level_err_ADC_PLUS_default; +unsigned int const level_err_ADC_MINUS[16] = level_err_ADC_MINUS_default; + + +#pragma DATA_SECTION(err_adc_protect,".fast_vars"); +#pragma DATA_SECTION(mask_err_adc_protect,".fast_vars"); +ERR_ADC_PROTECT err_adc_protect[COUNT_ARR_ADC_BUF],mask_err_adc_protect[COUNT_ARR_ADC_BUF]; + + + +_iq koef_Im_filter=0; +_iq koef_Power_filter=0; +_iq koef_Power_filter2=0; + +#pragma DATA_SECTION(k_norm_ADC,".slow_vars") +_iq19 k_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq19_zero_ADC,".fast_vars"); +_iq19 iq19_zero_ADC[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(zero_ADC,".slow_vars") +int zero_ADC[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(iq19_k_norm_ADC,".fast_vars"); +_iq19 iq19_k_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq_norm_ADC,".fast_vars"); +_iq iq_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq_norm_ADC_sf,".fast_vars"); +_iq iq_norm_ADC_sf[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(koef_Uzpt_long_filter,".fast_vars"); +_iq koef_Uzpt_long_filter=0; + +#pragma DATA_SECTION(koef_Uzpt_fast_filter,".fast_vars"); +_iq koef_Uzpt_fast_filter=0; + +#pragma DATA_SECTION(koef_Uin_filter,".fast_vars"); +_iq koef_Uin_filter=0; + + +void fast_detect_protect_ACP(); +//void fast_read_all_adc_one(int cc); +//void fast_read_all_adc_more(void); + + +#if (USE_INTERNAL_ADC==1) +#pragma CODE_SECTION(adc_isr,".fast_run"); +interrupt void adc_isr(void) +{ +// unsigned char k; + static char l_ir=0; + static char step_acp=0; + +//i_led1_on_off(1); + +// i_led1_on_off(1); + + project.adc->read_pbus(&project.adc[0]); + + ADC_f[0][0] = project.adc[0].read.pbus.adc_value[0]; + ADC_f[0][1] = project.adc[0].read.pbus.adc_value[1]; + ADC_f[0][2] = project.adc[0].read.pbus.adc_value[2]; + ADC_f[0][3] = project.adc[0].read.pbus.adc_value[3]; + ADC_f[0][4] = project.adc[0].read.pbus.adc_value[4]; + ADC_f[0][5] = project.adc[0].read.pbus.adc_value[5]; + ADC_f[0][6] = project.adc[0].read.pbus.adc_value[6]; + ADC_f[0][7] = project.adc[0].read.pbus.adc_value[7]; + ADC_f[0][8] = project.adc[0].read.pbus.adc_value[8]; + ADC_f[0][9] = project.adc[0].read.pbus.adc_value[9]; + ADC_f[0][10] = project.adc[0].read.pbus.adc_value[10]; + ADC_f[0][11] = project.adc[0].read.pbus.adc_value[11]; + ADC_f[0][12] = project.adc[0].read.pbus.adc_value[12]; + ADC_f[0][13] = project.adc[0].read.pbus.adc_value[13]; + ADC_f[0][14] = project.adc[0].read.pbus.adc_value[14]; + ADC_f[0][15] = project.adc[0].read.pbus.adc_value[15]; + + + ADC_sf[0][0] += (ADC_f[0][0] - ADC_sf[0][0]) >> Shift_Filter; + ADC_sf[0][1] += (ADC_f[0][1] - ADC_sf[0][1]) >> Shift_Filter; + ADC_sf[0][2] += (ADC_f[0][2] - ADC_sf[0][2]) >> Shift_Filter; + ADC_sf[0][3] += (ADC_f[0][3] - ADC_sf[0][3]) >> Shift_Filter; + + +/* + + + if (ADC_sf[2][0]>ERR_LEVEL_ADC_PLUS || ADC_sf[2][0]<ERR_LEVEL_ADC_MINUS //�� ��������� � ADC_f �� ADC_f + || ADC_sf[2][1]>ERR_LEVEL_ADC_PLUS || ADC_sf[2][1]<ERR_LEVEL_ADC_MINUS //��� ����������� ������ �� 26.08.2009 +// || ADC_f[2]>ERR_LEVEL_ADC_PLUS || ADC_f[2]<ERR_LEVEL_ADC_MINUS + || ADC_sf[2][3]>ERR_LEVEL_ADC_PLUS || ADC_sf[2][3]<ERR_LEVEL_ADC_MINUS + +// || ADC_f[8]>ERR_LEVEL_ADC_PLUS || ADC_f[8]<ERR_LEVEL_ADC_MINUS + // || ADC_f[9]>ERR_LEVEL_ADC_PLUS || ADC_f[9]<ERR_LEVEL_ADC_MINUS + // || ADC_f[10]>ERR_LEVEL_ADC_PLUS || ADC_f[10]<ERR_LEVEL_ADC_MINUS +// || ADC_f[2][11]>ERR_LEVEL_ADC_PLUS_6 || ADC_f[2][11]<ERR_LEVEL_ADC_MINUS_6 + ) + { +// fast_detect_protect_ACP(); + if (active_rect1.disable_error_pwm_start==0) + fast_detect_protect_ACP_internal(); + } + +*/ +// time_adc++; + + + + + + + + + // Reinitialize for next ADC sequence + AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1 + AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit + PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE + + +// i_led1_on_off(0); + +// i_led2_on_off(0); +//i_led1_on_off(0); + + return; + +} + + + +// ��� �� ��� ��� +#pragma CODE_SECTION(timer2_isr,".fast_run"); +interrupt void timer2_isr(void) +{ + +//led2_on_off(1); +//i_led2_on_off(1); +// EvaTimer2InterruptCount++; + // Enable more interrupts from this timer + + EvaRegs.EVAIMRB.bit.T2PINT = 1; + + // Note: To be safe, use a mask value to write to the entire + // EVAIFRB register. Writing to one bit will cause a read-modify-write + // operation that may have the result of writing 1's to clear + // bits other then those intended. + EvaRegs.EVAIFRB.all = BIT0; + + // Acknowledge interrupt to receive more interrupts from PIE group 3 + PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; +// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; + +/* + ADC_filter[15] = 333; +// DOut(Error,1); +// GpioDataRegs.GPDTOGGLE.bit.GPIOD5=1; + + EvaRegs.EVAIMRA.bit.T1PINT = 1; + EvaRegs.EVAIFRA.all=0x80; + PieCtrlRegs.PIEACK.bit.ACK2=1; // Issue PIE ack + + EvbRegs.EVBIFRA.all = BIT7; + // Acknowledge interrupt to receive more interrupts from PIE group 4 + PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; +*/ +// i_led2_on_off(1); +//i_led2_on_off(0); + +} + + + + + +//--------------------------------------------------------------------------- +// InitAdc: +//--------------------------------------------------------------------------- +// This function initializes ADC to a known state. +// +void Init_Internal_Adc(void) +{ + static float adc_period=0; + int k,i; + + extern void DSP28x_usDelay(Uint32 Count); + + // To powerup the ADC the ADCENCLK bit should be set first to enable + // clocks, followed by powering up the bandgap and reference circuitry. + // After a 5ms delay the rest of the ADC can be powered up. After ADC + // powerup, another 20us delay is required before performing the first + // ADC conversion. Please note that for the delay function below to + // operate correctly the CPU_CLOCK_SPEED define statement in the + // DSP28_Examples.h file must contain the correct CPU clock period in + // nanoseconds. For example: + + + +// SQRT_32 = _IQ(0.8660254037844); +// CONST_23 = _IQ(2.0/3.0); +// CONST_15 = _IQ(1.5); + + AdcRegs.ADCTRL3.bit.ADCPWDN = 0; // Power up rest of ADC + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x0; // Power up bandgap/reference circuitry + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + + + + AdcRegs.ADCTRL3.bit.EXTREF=0; +// DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + +// asm(� RPT #10 || NOP;�); // Time to enable of external ref + + AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // Power up bandgap/reference circuitry + DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC + AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Power up rest of ADC + DELAY_US(ADC_usDELAY2); // Delay after powering up ADC + + + AdcRegs.ADCTRL1.bit.ACQ_PS=0x0; + AdcRegs.ADCTRL1.bit.CPS = 0; // Core clock prescaler. The prescaler is applied to divided device peripheral clock +// AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Continues run + +// AdcRegs.ADCTRL3.bit.ADCCLKPS=0; + // Configure ADC + + AdcRegs.ADCTRL3.bit.ADCCLKPS=0x3; + + AdcRegs.ADCTRL1.bit.SEQ_CASC=1; // cascaded mode + + AdcRegs.ADCMAXCONV.all = 0x000f; // Setup 16 conv's on SEQ1 + + AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv. + AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // Setup ADCINA2 as 2nd SEQ1 conv. + + AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8; // Setup ADCINA3 as 1st SEQ1 conv. + AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xa; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xb; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xc; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xd; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xe; // Setup ADCINA2 as 2nd SEQ1 conv. + AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xf; // Setup ADCINA2 as 2nd SEQ1 conv. + + AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1 + AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS) + + +// AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1 +// AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS) + + +// Enable ADCINT in PIE + EALLOW; + PieCtrlRegs.PIEIER1.bit.INTx6 = 1; + IER |= M_INT1; // Enable CPU Interrupt 1 + PieVectTable.ADCINT = &adc_isr; + EDIS; + + + EALLOW; + PieVectTable.T2PINT = &timer2_isr; + + + // Initialize EVA Timer 2: + // Setup Timer 2 Registers (EV A) + EvaRegs.GPTCONA.all = 0; + + // Set the Period for the GP timer 2 to 0x0200; + adc_period = (float)HSPCLK/(float)FREQ_ADC; + EvaRegs.T2PR = adc_period; // Period + EvaRegs.T2CMPR = 0x0000; // Compare Reg + + // Enable Period interrupt bits for GP timer 2 + // Count up, x128, internal clk, enable compare, use own period + + EvaRegs.EVAIMRB.bit.T2PINT = 1;// 1; + EvaRegs.EVAIFRB.bit.T2PINT = 1;//1; + + + // Clear the counter for GP timer 2 + EvaRegs.T2CNT = 0x0000; + EvaRegs.T2CON.all = 0x1042; + + // Start EVA ADC Conversion on timer 2 Period interrupt + EvaRegs.GPTCONA.bit.T2TOADC = 1; + + + + + + + + // Enable PIE group 3 interrupt 1 for T2PINT + PieCtrlRegs.PIEIER3.bit.INTx1 = 1; + + // Enable CPU INT2 for T1PINT, INT3 for T2PINT, INT4 for T3PINT + // and INT5 for T4PINT: + IER |= (M_INT3); + + EDIS; + + +// Start SEQ1 +// AdcRegs.ADCTRL2.all = 0x2000; + + +// EvaRegs.T1CON.bit.TENABLE=1; + + + + for (k=0;k<16;k++) + { + +// ADC_filter[k]=0; + ADC_f[2][k]=0; + ADC_sf[2][k]=0; + + k_norm_ADC[2][k] = _IQ19(K_LEM_ADC[2][k]*3.0/R_ADC[2][k]/4096.0); +// iq_k_norm_ADC[k] = _IQ(K_LEM_ADC[k]*300.0/R_ADC[k]/NORMA_ACP); + iq19_k_norm_ADC[2][k] = _IQ19(K_LEM_ADC[2][k]*300.0/R_ADC[2][k]/K_NORMA_ADC[2][k]/4096.0); + iq19_zero_ADC[2][k]=_IQ19(2100);//_IQ19(1770); + zero_ADC[2][k]=2100;//1835; + } + + for (i=0;i<4;i++) + zero_ADC[2][i]=1768;//1770; + + for (i=4;i<16;i++) + zero_ADC[2][i]=2130; + + zero_ADC[2][0]=1787; + zero_ADC[2][1]=1774; + + + + + for (i=0;i<16;i++) + iq19_zero_ADC[2][i]=_IQ19(zero_ADC[2][i]); + + + +// koef_allADC_filter = _IQ19(0.00002/0.00003185);//koef_ADC_filter[0]; +// koef_zero_ADC_filter=_IQ19(0.00002/0.0003185); +// koef_Ud_long_filter = _IQ(0.001/0.016666); +// koef_Ud_fast_filter = _IQ(0.001/0.00931); //_IQ(0.001/0.00131); + +// koef_Im_filter = _IQ(0.001/0.006); +// koef_Im_filter = _IQ(0.001/0.065); + +// koef_Iabc_filter = _IQ(0.001/0.006); + + + mask_err_adc_protect[2].plus.all=0; + mask_err_adc_protect[2].minus.all=0x0; + +// mask_err_adc_protect.minus.all=0xffff; // ����. ������ �� ���� �� ������ +// mask_err_adc_protect.plus.all=0xffff; // ����. ������ �� ���� �� ����� + + err_adc_protect[2].plus.all=0; + err_adc_protect[2].minus.all=0x0; + + AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; +} + + +#endif + +//#pragma DATA_SECTION(buf_U1_3point,".fast_vars"); +//_iq buf_U1_3point[3]={0,0,0}; + +//#pragma CODE_SECTION(filter_U1_3point,".fast_run"); +//_iq filter_U1_3point(_iq d) +//{ +// _iq maxU, minU, sumU; +// +// buf_U1_3point[2] = buf_U1_3point[1]; +// buf_U1_3point[1] = buf_U1_3point[0]; +// buf_U1_3point[0] = d; +// +// maxU = d; +// minU = d; +// +// +// if (buf_U1_3point[1]>maxU) maxU = buf_U1_3point[1]; +// if (buf_U1_3point[2]>maxU) maxU = buf_U1_3point[2]; +// +// if (buf_U1_3point[1]<minU) minU = buf_U1_3point[1]; +// if (buf_U1_3point[2]<minU) minU = buf_U1_3point[2]; +// +// sumU = buf_U1_3point[0] + buf_U1_3point[1] + buf_U1_3point[2] - maxU - minU; +// +// return sumU; +//} + + +//--------------------------------------------------------------------------- +// InitAdc: +//--------------------------------------------------------------------------- +// This function initializes ADC to a known state. +// +void Init_Adc_Variables(void) +{ + unsigned int k,i,j; + int *panalog, *pfilter; + volatile float k_f; + + + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + for (k=0;k<16;k++) + { + ADC_f[i][k]=0; + ADC_sf[i][k]=0; + + for (j=0;j<COUNT_ARR_ADC_BUF_FAST_POINT;j++) + ADC_fast[i][k][j]=0; + + k_f = K_LEM_ADC[i][k]*2.5/R_ADC[i][k]/4096.0; + k_norm_ADC[i][k] = _IQ19(k_f); + + k_f = K_LEM_ADC[i][k]*250.0/R_ADC[i][k]/K_NORMA_ADC[i][k]/4096.0; + iq19_k_norm_ADC[i][k] = _IQ19(k_f); + + zero_ADC[i][k] = DEFAULT_ZERO_ADC;//1835; + + iq19_zero_ADC[i][k] = _IQ19 (zero_ADC[i][k]); //_IQ19(2030);//_IQ19(1770); + + } + } + + + panalog = (int*)&analog; + pfilter = (int*)&filter; + for (k=0;k < sizeof(ANALOG_VALUE)/sizeof(int) ;k++) + { + + *(panalog + k) = 0; + *(pfilter + k) = 0; + } + + + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + if (project.adc[i].status >= component_Ready) + detect_zero_analog(i); + } + +// zero_ADC[1][2] = 2010;//1976; // uab +// zero_ADC[1][3] = 2010;//1989; // ubc +// zero_ADC[1][4] = 2010;//1994; // uca + + + zero_ADC[0][0]=zero_ADC[0][2];//2042;//1992;//1835; //uzpt + zero_ADC[0][1]=zero_ADC[0][2];//2042;//1992;//1835; //uzpt + + + +#if (COUNT_ARR_ADC_BUF>1) + zero_ADC[1][1]=zero_ADC[1][15]; + zero_ADC[1][2]=zero_ADC[1][15]; + zero_ADC[1][3]=zero_ADC[1][15]; + zero_ADC[1][4]=zero_ADC[1][15]; + zero_ADC[1][5]=zero_ADC[1][15]; + zero_ADC[1][6]=zero_ADC[1][15]; + zero_ADC[1][7]=zero_ADC[1][15]; + zero_ADC[1][8]=zero_ADC[1][15]; + zero_ADC[1][9]=zero_ADC[1][15]; + zero_ADC[1][10]=zero_ADC[1][15]; + zero_ADC[1][11]=zero_ADC[1][15]; + zero_ADC[1][12]=zero_ADC[1][15]; + zero_ADC[1][13]=zero_ADC[1][15]; + zero_ADC[1][14]=zero_ADC[1][15]; +#endif + + + for (k=0;k<16;k++) + { + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + if ((zero_ADC[i][k]>2200) || (zero_ADC[i][k]<1900)) + zero_ADC[i][k] = DEFAULT_ZERO_ADC; + } + } + + + + for (k=0;k<16;k++) + { + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + iq19_zero_ADC[i][k]=_IQ19(zero_ADC[i][k]);//_IQ19(1770); + } + } + + +// koef_allADC_filter = _IQ19(0.00002/0.00003185);//koef_ADC_filter[0]; +// koef_zero_ADC_filter=_IQ19(0.00002/0.0003185); + koef_Uzpt_long_filter = _IQ(0.001/0.016666); + koef_Uzpt_fast_filter = _IQ(0.001/0.002); //_IQ(0.001/0.00131); + koef_Uin_filter = _IQ(0.001/0.00931); + +// koef_Im_filter = _IQ(0.001/0.006); + koef_Im_filter = _IQ(0.001/0.065); + koef_Power_filter = _IQ(0.001/0.065); + koef_Power_filter2 = _IQ(0.001/0.2); + +// koef_Iabc_filter = _IQ(0.001/0.006); + + + filter.iqU_1_fast = 0; + filter.iqU_1_long = 0; + + filter.iqU_2_fast = 0; + filter.iqU_2_long = 0; + + filter.iqUin_m1 = 0; + filter.iqUin_m2 = 0; + + +// filter.iqU_3_fast = 0; +// filter.iqU_4_fast = 0; + +// filter.iqU_1_long = 0; +// filter.iqU_2_long = 0; +// filter.iqU_3_long = 0; +// filter.iqU_4_long = 0; + +// filter.iqIin_1 = 0; +// filter.iqIin_2 = 0; + + + filter.iqIm_1 = 0; + filter.iqIm_2 = 0; +// filter.iqUin_m1 = 0; +// filter.iqUin_m2 = 0; + + + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + mask_err_adc_protect[i].plus.all=0; + mask_err_adc_protect[i].minus.all=0x0; + + err_adc_protect[i].plus.all=0; + err_adc_protect[i].minus.all=0x0; + } + +#if (USE_INTERNAL_ADC==1) + Init_Internal_Adc(); +#endif + + +} + + + +#pragma CODE_SECTION(detect_protect_ACP_plus,".fast_run"); +void detect_protect_ACP_plus(unsigned char nacp, unsigned char nc) +{ + unsigned long mask; + + mask=(unsigned int)(1 << nc); + + if (mask_err_adc_protect[nacp].plus.all & mask) return; + + +// led1_on_off(1); +// led1_on_off(0); + +// EvaRegs.COMCONA.all = 0xa400;//0xA600; // Init COMCONA Register +// EvbRegs.COMCONB.all = 0xa400;//0xA600; // Init COMCONA Register + + +// pwm_tms.stop_all(&pwm_tms); + + + +// f.Restart=0; +// led1_on_off(1); + + + +// stop_pwm(); + + if (err_adc_protect[nacp].plus.all==0 ) + err_adc_protect[nacp].plus.all |= mask; + +// led2_on_off(0); + + +} + + +#pragma CODE_SECTION(detect_protect_ACP_minus,".fast_run"); +void detect_protect_ACP_minus(unsigned char nacp, unsigned char nc) +{ + unsigned long mask; + + mask=(unsigned int)(1 << nc); + + if (mask_err_adc_protect[nacp].minus.all & mask) return; + + +// EvaRegs.COMCONA.all = 0xa400;//0xA600; // Init COMCONA Register +// EvbRegs.COMCONB.all = 0xa400;//0xA600; // Init COMCONA Register + + + +// pwm_tms.stop_all(&pwm_tms); +// f.Restart=0; + + if (err_adc_protect[nacp].minus.all==0 ) + err_adc_protect[nacp].minus.all |= mask; + +} + + +#pragma CODE_SECTION(fast_detect_protect_ACP,".fast_run"); +void read_error_ACP() +{ + int i,k; +// T_cds_paralle_bus_read_all* pr; + +// pr = project.controller.fpga.cds_fpga_parallel_bus.pread; + + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + if (project.adc[i].status == component_Ready) + for (k=0;k<16;k++) + { +// if (pr->error_counts.adc_0) +// if (ADC_sf[i][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (i, k); + // if (ADC_sf[i][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(i, k); + } + } + + +} + +#if (USE_INTERNAL_ADC==1) +#pragma CODE_SECTION(fast_detect_protect_ACP_internal,".fast_run"); +void fast_detect_protect_ACP_internal(void) +{ + int k; + k=0; + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (2, k); + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(2, k); + k=1; + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (2, k); + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(2, k); + k=3; + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (2, k); + if (ADC_sf[COUNT_ARR_ADC_BUF-1][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(2, k); + + +} +#endif + + +#pragma CODE_SECTION(fast_detect_protect_ACP,".fast_run"); +void fast_detect_protect_ACP() +{ + int i,k; + +// for (i=0;i<2;i++) + { +// if (project.adc[i].status == component_Ready) +#if(C_adc_number>=1) + i = 0; + for (k=0;k<14;k++) + { + if (ADC_f[i][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (i, k); + if (ADC_f[i][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(i, k); + } +#endif +#if(C_adc_number>=2) + i = 1; + for (k=2;k<5;k++) + { + if (ADC_f[i][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (i, k); + if (ADC_f[i][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(i, k); + } +#endif +#if(C_adc_number>=3) + i = 2; + for (k=0;k<15;k++) + { + if (ADC_f[i][k] >= ERR_LEVEL_ADC_PLUS) detect_protect_ACP_plus (i, k); + if (ADC_f[i][k] <= ERR_LEVEL_ADC_MINUS) detect_protect_ACP_minus(i, k); + } +#endif + + } + +} + +#pragma CODE_SECTION(norma_adc,".fast_run"); +inline _iq norma_adc(int plane, int chan) +{ +// return _IQ19toIQ(_IQ19mpy((iq19_zero_ADC[n_norm] - ((long)ADC_sf[plane][chan]<<19) ),iq19_k_norm_ADC[n_norm])); + return _IQ19toIQ(_IQ19mpy((((long)ADC_f[plane][chan]<<19) - iq19_zero_ADC[plane][chan]),iq19_k_norm_ADC[plane][chan])); +} + + + +#if (USE_INTERNAL_ADC==1) +#pragma CODE_SECTION(norma_adc_internal_sf,".fast_run2"); +_iq norma_adc_internal_sf(int l) +{ + return _IQ19toIQ(_IQ19mpy((((long)ADC_sf[2][l]<<19) - iq19_zero_ADC[2][l]),iq19_k_norm_ADC[2][l])); +} +#endif + + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +// +//#pragma CODE_SECTION(fast_read_all_adc_one,".fast_run"); +//void fast_read_all_adc_one(int cc) +//{ +// int i,k; +// int t; +// +// i_led1_on_off(1); +// +// project.adc[0].read_pbus(&project.adc[0]); +// +// for (k=0;k<16;k++) +// { +// t = project.adc[0].read.pbus.adc_value[k]; +// ADC_fast[0][k][cc] = t; +// +// // save max values +// if (t>ADC_fast[0][k][1] || cc==3) +// ADC_fast[0][k][1] = t; +// // save min values +// if (t<ADC_fast[0][k][2] || cc==3) +// ADC_fast[0][k][2] = t; +// } +// +// +// +// +// +////i_led2_off(); +// i_led1_on_off(0); +// +//} + +//#pragma CODE_SECTION(fast_read_all_adc_two,".fast_run"); +//void fast_read_all_adc_two(void) +//{ +// int i,k; +// int t; +// +//// i_led2_on_off(1); +// +// project.adc[1].read_pbus(&project.adc[1]); +// +// for (k=0;k<16;k++) +// { +// t = project.adc[1].read.pbus.adc_value[k]; +// ADC_fast[1][k][0] = t; +// } +// +//// i_led2_on_off(0); +// +//} + +///////////////////////////////////////////////////////// + +//#define PAUSE_BETWEEN_ADC_FAST 5 +//#pragma CODE_SECTION(fast_read_all_adc_more,".fast_run"); +//void fast_read_all_adc_more(void) +//{ +// int i,k; +// static int p = PAUSE_BETWEEN_ADC_FAST; +// +// project.read_errors_controller(); +// +// if (project.adc[0].status == component_Ready +// && project.controller.read.errors.bit.error_pbus == 0 +// && project.controller.read.errors_buses.bit.slave_addr_error==0 +// && project.x_parallel_bus->flags.bit.error==0 ) +// { +// +// +// +// fast_read_all_adc_one(3); +// pause_1000(p); +// fast_read_all_adc_one(4); +// pause_1000(p); +// fast_read_all_adc_one(5); +// pause_1000(p); +// fast_read_all_adc_one(6); +// pause_1000(p); +// fast_read_all_adc_one(7); +// pause_1000(p); +// fast_read_all_adc_one(8); +// +// +// +// for (k=0;k<16;k++) +// { +// ADC_fast[0][k][0] = (-ADC_fast[0][k][1] - ADC_fast[0][k][2] + ADC_fast[0][k][3] + ADC_fast[0][k][4] +// +ADC_fast[0][k][5] + ADC_fast[0][k][6] + ADC_fast[0][k][7] + ADC_fast[0][k][8]) >> 2; // ����� ����� �� 4 +// } +// +// } +// else +// { +// for (k=0;k<16;k++) +// { +// ADC_fast[0][k][0] = 5000; // error +// } +// } +// +// +// if (project.adc[1].status == component_Ready +// && project.controller.read.errors.bit.error_pbus == 0 +// && project.controller.read.errors_buses.bit.slave_addr_error==0 +// && project.x_parallel_bus->flags.bit.error==0 ) +// { +// +// fast_read_all_adc_two(); +// } +// else +// { +// for (k=0;k<16;k++) +// { +// ADC_fast[1][k][0] = 5000; // error +// } +// } +// +//} + +///////////////////////////////////////////////////////// +// +//#pragma CODE_SECTION(norma_fast_adc,".fast_run"); +//void norma_fast_adc(void) +//{ +// int i,k; +//// int bb; +// +//#ifdef LOG_ACP_TO_BUF +// static int c_log=0; +// static int n_log_acp_p=0; +// static int n_log_acp_c=2; +// static int n_log_acp_p_2=0; +// static int n_log_acp_c_2=2; +// +//#endif +// +// for (i=0;i<COUNT_ARR_ADC_BUF_EXTERNAL;i++) +// { +// +// if ( project.adc[i].status == component_Ready +// && project.controller.read.errors.bit.error_pbus == 0 +// && project.controller.read.errors_buses.bit.slave_addr_error==0 +// && project.x_parallel_bus->flags.bit.error==0 ) +// { +// for (k=0;k<16;k++) +// { +// iq_norm_ADC[i][k] = _IQ19toIQ(_IQ19mpy((-iq19_zero_ADC[i][k] + ((long)ADC_fast[i][k][0]<<19) ),iq19_k_norm_ADC[i][k])); +// } +// } +// else +// { +// for (k=0;k<16;k++) +// { +// iq_norm_ADC[i][k] = 0; +// } +// +// } +// +// } +// +//#ifdef LOG_ACP_TO_BUF +// if (c_log>=SIZE_BUF_LOG_ACP) +// c_log=0; +// BUF_ADC[c_log]=ADC_fast[n_log_acp_p][n_log_acp_c][0]; +// BUF_ADC_2[c_log]=ADC_fast[n_log_acp_p_2][n_log_acp_c_2][3]; +// c_log++; +//#endif +// +////i_led2_off(); +//} + +///////////////////////////////////////////////////////// + +/* +#pragma CODE_SECTION(norma_all_adc,".fast_run"); +void norma_all_adc(void) +{ + int i,k; +// int bb; +#ifdef LOG_ACP_TO_BUF + static int c_log=0; + static int n_log_acp_p=0; + static int n_log_acp_c=2; + static int n_log_acp_p_2=0; + static int n_log_acp_c_2=5; + +#endif + + for (i=0;i<COUNT_ARR_ADC_BUF;i++) + { + project.read_errors_controller(); + project.adc[i].read_pbus(&project.adc[i]); + +// project.adc->read_pbus(&project.adc[i]); + + if ( project.adc[i].status == component_Ready + && project.controller.read.errors.bit.error_pbus == 0 + && project.controller.read.errors_buses.bit.slave_addr_error==0 + && project.x_parallel_bus->flags.bit.error==0 ) + { + for (k=0;k<16;k++) + { + +// ADC_f[i][k] = (int)pr->data.adc[i].acc_short[k]; + +#ifdef ADC_READ_FROM_PARALLEL_BUS + ADC_f[i][k] = project.adc[i].read.pbus.adc_value[k]; + ADC_sf[i][k] += (((int)(ADC_f[i][k] - ADC_sf[i][k]))>>SDVIG_K_FILTER_S); +#else +// ADC_f[i][k] = project.adc[i].fpga.read.channels[k].value.acc_short;//iq_norm_ADC[i][k] = _IQ19toIQ(_IQ19mpy((iq19_zero_ADC[i][k] - ((long)project.adc[i].fpga.read.channels[k].value.acc_short<<19) ),iq19_k_norm_ADC[i][k])); +#endif + iq_norm_ADC[i][k] = _IQ19toIQ(_IQ19mpy((-iq19_zero_ADC[i][k] + ((long)ADC_f[i][k]<<19) ),iq19_k_norm_ADC[i][k])); +// iq_norm_ADC_sf[i][k] = _IQ19toIQ(_IQ19mpy((iq19_zero_ADC[i][k] - ((long)ADC_sf[i][k]<<19) ),iq19_k_norm_ADC[i][k])); + } + } + else + { + for (k=0;k<16;k++) + { + ADC_f[i][k] = 5000;//DEFAULT_ZERO_ADC; + ADC_sf[i][k] = 5000;//DEFAULT_ZERO_ADC; + iq_norm_ADC[i][k] = 0; + } + + } + + } + +#ifdef LOG_ACP_TO_BUF + if (c_log>=SIZE_BUF_LOG_ACP) + c_log=0; + BUF_ADC[c_log]=ADC_f[n_log_acp_p][n_log_acp_c]; + BUF_ADC_2[c_log]=ADC_f[n_log_acp_p_2][n_log_acp_c_2]; + c_log++; +#endif + + +#if (USE_INTERNAL_ADC==1) + iq_norm_ADC[COUNT_ARR_ADC_BUF-1][0] = norma_adc_internal_sf(0); + iq_norm_ADC[COUNT_ARR_ADC_BUF-1][1] = norma_adc_internal_sf(1); + iq_norm_ADC[COUNT_ARR_ADC_BUF-1][3] = norma_adc_internal_sf(3); +#endif +//i_led2_off(); +} +*/ +//////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(norma_adc_nc,".fast_run"); +void norma_adc_nc(int nc) +{ + int k; +// int bb; + + project.read_errors_controller(); + project.adc[nc].read_pbus(&project.adc[nc]); + + if ( project.adc[nc].status == component_Ready + && project.controller.read.errors.bit.error_pbus == 0 + && project.controller.read.errors_buses.bit.slave_addr_error==0 + && project.x_parallel_bus->flags.bit.error==0 ) + { + for (k=0;k<16;k++) + { + + ADC_f[nc][k] = project.adc[nc].read.pbus.adc_value[k]; + ADC_sf[nc][k] += (((int)(ADC_f[nc][k] - ADC_sf[nc][k]))>>SDVIG_K_FILTER_S); + iq_norm_ADC[nc][k] = _IQ19toIQ(_IQ19mpy((-iq19_zero_ADC[nc][k] + ((long)ADC_f[nc][k]<<19) ),iq19_k_norm_ADC[nc][k])); + } + } + else + { + for (k=0;k<16;k++) + { + ADC_f[nc][k] = 5000;//DEFAULT_ZERO_ADC; + ADC_sf[nc][k] = 5000;//DEFAULT_ZERO_ADC; + iq_norm_ADC[nc][k] = 0; + } + + } +} + +//////////////////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(calc_norm_ADC_1,".fast_run"); +void calc_norm_ADC_1(int run_norma) +{ + _iq a1,a2,a3; + +#if (USE_ADC_1) + + if (run_norma) + norma_adc_nc(1); + + +#if (_FLOOR6==1) + + analog.T_U01 = + analog.T_U02 = + analog.T_U03 = + analog.T_U04 = + analog.T_U05 = + analog.T_U06 = + analog.T_U07 = + analog.T_Water_external = + analog.T_Water_internal = + + analog.P_Water_internal = + + analog.T_Air_01 = + analog.T_Air_02 = + analog.T_Air_03 = + analog.T_Air_04 = 0; + +#else + analog.T_U01 = iq_norm_ADC[1][1]; + analog.T_U02 = iq_norm_ADC[1][2]; + analog.T_U03 = iq_norm_ADC[1][3]; + analog.T_U04 = iq_norm_ADC[1][4]; + analog.T_U05 = iq_norm_ADC[1][5]; + analog.T_U06 = iq_norm_ADC[1][6]; + analog.T_U07 = iq_norm_ADC[1][7]; + analog.T_Water_external = iq_norm_ADC[1][9]; + analog.T_Water_internal = iq_norm_ADC[1][8]; + + analog.P_Water_internal = iq_norm_ADC[1][14]; + + analog.T_Air_01 = iq_norm_ADC[1][10]; + analog.T_Air_02 = iq_norm_ADC[1][11]; + analog.T_Air_03 = iq_norm_ADC[1][12]; + analog.T_Air_04 = iq_norm_ADC[1][13]; + + +#endif +#else + + analog.T_U01 = + analog.T_U02 = + analog.T_U03 = + analog.T_U04 = + analog.T_U05 = + analog.T_U06 = + analog.T_U07 = + analog.T_Water_external = + analog.T_Water_internal = + + analog.P_Water_internal = + + analog.T_Air_01 = + analog.T_Air_02 = + analog.T_Air_03 = + analog.T_Air_04 = 0; + +#endif +// analog.iqI_vozbud = iq_norm_ADC[1][13]; + +} + +//////////////////////////////////////////////////////////////////// +#pragma CODE_SECTION(calc_norm_ADC_0,".fast_run"); +void calc_norm_ADC_0(int run_norma) +{ + _iq a1,a2,a3; + +#if (USE_ADC_0) + + if (run_norma) + norma_adc_nc(0); + +#if (_FLOOR6) + analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1 + analog.iqU_1_imit; + analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2 + analog.iqU_1_imit; +#else + analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1; + analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2; +#endif + analog.iqIu_1 = iq_norm_ADC[0][2]; + analog.iqIv_1 = iq_norm_ADC[0][3]; + analog.iqIw_1 = iq_norm_ADC[0][4]; + + analog.iqIu_2 = iq_norm_ADC[0][5]; + analog.iqIv_2 = iq_norm_ADC[0][6]; + analog.iqIw_2 = iq_norm_ADC[0][7]; + + analog.iqIin_1 = -iq_norm_ADC[0][9]; // ������ ���������� + analog.iqIin_2 = -iq_norm_ADC[0][9]; // ������ ���������� + + analog.iqUin_A1B1 = iq_norm_ADC[0][10]; + +// ��� �������� ����������� �������� 23550.1 ����� ���������� - �� ����� +// 23550.1 + + analog.iqUin_B1C1 = iq_norm_ADC[0][11]; // 23550.1 + analog.iqUin_A2B2 = iq_norm_ADC[0][12]; // 23550.1 + +// 23550.3 bs1 bs2 + +// analog.iqUin_B1C1 = iq_norm_ADC[0][12]; // 23550.3 +// analog.iqUin_A2B2 = iq_norm_ADC[0][11]; // 23550.3 +// + analog.iqUin_B2C2 = iq_norm_ADC[0][13]; + + analog.iqIbreak_1 = iq_norm_ADC[0][14]; + analog.iqIbreak_2 = iq_norm_ADC[0][15]; + +#else + analog.iqU_1 = analog.iqIu_1 = analog.iqIu_2 = analog.iqIv_1 = analog.iqIv_2 = + analog.iqIw_1 = analog.iqIw_2 = analog.iqIin_1 = analog.iqIin_2 = analog.iqUin_A1B1 = + analog.iqUin_B1C1 = analog.iqUin_A2B2 = analog.iqUin_B2C2 = analog.iqIbreak_1 = analog.iqIbreak_2 + = 0; +#endif + + analog.iqUin_C1A1 = -(analog.iqUin_A1B1 + analog.iqUin_B1C1); + analog.iqUin_C2A2 = -(analog.iqUin_A2B2 + analog.iqUin_B2C2); + + + + filter.iqU_1_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_1_long, analog.iqU_1); + filter.iqU_2_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_2_long, analog.iqU_2); + + +// analog.iqU_1_fast = filter_U1_3point(analog.iqU_1_fast); + filter.iqU_1_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_1_fast, analog.iqU_1); + filter.iqU_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_2_fast, analog.iqU_2); + + +// filter.iqUzpt_2_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqUzpt_2_2_fast, analog.iqUzpt_2_2); + + + +//15 + + + analog.iqIm_1 = im_calc(analog.iqIu_1, analog.iqIv_1, analog.iqIw_1); + analog.iqIm_2 = im_calc(analog.iqIu_2, analog.iqIv_2, analog.iqIw_2); + + analog.iqIu = analog.iqIu_1+analog.iqIu_2; + analog.iqIv = analog.iqIv_1+analog.iqIv_2; + analog.iqIw = analog.iqIw_1+analog.iqIw_2; + + analog.iqIm = im_calc(analog.iqIu, analog.iqIv, analog.iqIw); + + + analog.iqIin_sum = analog.iqIin_1+analog.iqIin_2; + +// analog.iqIm_3 = im_calc(analog.iqIa1_1_fir_n+analog.iqIa2_1_fir_n, analog.iqIb1_1_fir_n+analog.iqIb2_1_fir_n, analog.iqIc1_1_fir_n+analog.iqIc2_1_fir_n); + + analog.iqUin_m1 = im_calc(analog.iqUin_A1B1, analog.iqUin_B1C1, analog.iqUin_C1A1); + analog.iqUin_m2 = im_calc(analog.iqUin_A2B2, analog.iqUin_B2C2, analog.iqUin_C2A2); + +// analog.iqUin_m2 = im_calc(analog.UinA2, analog.UinB2, analog.UinC2); + + filter.iqUin_m1 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m1, analog.iqUin_m1); + filter.iqUin_m2 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m2, analog.iqUin_m2); + + + +// i_led1_on_off(0); +// i_led1_on_off(1); + +//1 + + filter.iqIm_1 = exp_regul_iq(koef_Im_filter, filter.iqIm_1, analog.iqIm_1); + filter.iqIm_2 = exp_regul_iq(koef_Im_filter, filter.iqIm_2, analog.iqIm_2); + filter.iqIm = exp_regul_iq(koef_Im_filter, filter.iqIm, analog.iqIm); + + filter.iqIin_sum = exp_regul_iq(koef_Im_filter, filter.iqIin_sum, analog.iqIin_sum); + +//3 +// filter_batter2_Iin.InpVarCurr = (analog.iqIin_1)-ZERO_I_IN; + // filter_batter2_Iin.calc(&filter_batter2_Iin); + +// filter.iqIin = _IQmpy(filter_batter2_Iin.Out,_IQ_09); + + + filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); + filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); + + a1 = analog.iqU_1+analog.iqU_2; + a2 = analog.iqIin_1; + a3 = _IQmpy(a1,a2); + analog.PowerScalar = a3; +// filter.Power = analog.iqU_1+analog.iqU_2; + filter.PowerScalar = exp_regul_iq(koef_Power_filter, filter.PowerScalar, analog.PowerScalar); + filter.PowerScalarFilter2 = exp_regul_iq(koef_Power_filter2, filter.PowerScalarFilter2, filter.PowerScalar); + +} + + + +#pragma DATA_SECTION(acp_zero,".slow_vars") +_iq19 acp_zero[16]; +#pragma DATA_SECTION(acp_summ,".slow_vars") +long acp_summ[16]; +/********************************************************************/ +/* ����������� ���y ��������� ��� */ +/********************************************************************/ +void detect_zero_analog(int nc) +{ + long i,k; + + + _iq koef_zero_ADC_filter = _IQ19(0.00002/0.0003185); + + + for (k=0;k<16;k++) + { + acp_zero[k] = 0; + acp_summ[k] = 0; + } + + + + for (i=0; i<COUNT_DETECT_ZERO; i++) + { +// norma_all_adc(); + norma_adc_nc(nc); + // norma_adc_nc(1); + + + for (k=0;k<16;k++) + { + acp_zero[k] = exp_regul_iq(koef_zero_ADC_filter, acp_zero[k], ((long)ADC_f[nc][k]<<19)); + acp_summ[k] = acp_summ[k]+ADC_f[nc][k]; + } + + + + pause_1000(1000); + } + + // 16 � 7 ����� ���������� �.�. ��� ����� ����y����y + for (k=0;k<16;k++) + { + +// if ((k==15)) +// { + // if (ADC_sf[k]<MIN_DETECT_UD_ZERO) + // iq19_zero_ADC[k] = acp_zero[k]; + // } + // else + { + iq19_zero_ADC[nc][k] = acp_zero[k]; + } + +// zero_ADC[k] =_IQ19toF(acp_zero[k]); + zero_ADC[nc][k] = acp_summ[k]/COUNT_DETECT_ZERO;//_IQ19toF(acp_zero[k]); + } + + + + + + +} + + + diff --git a/Inu/Src/main/adc_tools.h b/Inu/Src/main/adc_tools.h new file mode 100644 index 0000000..bb8af73 --- /dev/null +++ b/Inu/Src/main/adc_tools.h @@ -0,0 +1,402 @@ + + +#ifndef _ADC_TOOLS +#define _ADC_TOOLS + +#include "IQmathLib.h" +#include "xp_project.h" +#include "params_norma.h" + + +#define COUNT_DETECT_ZERO 3000 + +#define COUNT_ARR_ADC_BUF_FAST_POINT 10 + + + +#define DELTA_ACP_TEMPER 0.0 // ������� ����� pt100 ����� ���������� �������� 0.0 ��������, ��� �������� ���� SG3013 + +#define ADC_READ_FROM_PARALLEL_BUS 1 + +#define DEFAULT_ZERO_ADC 2048 + +#ifndef USE_INTERNAL_ADC +#define USE_INTERNAL_ADC 0 +#endif + + +#if (USE_INTERNAL_ADC==1) +#define COUNT_ARR_ADC_BUF (C_adc_number+1) +#else +#define COUNT_ARR_ADC_BUF C_adc_number +#endif + +#define COUNT_ARR_ADC_BUF_EXTERNAL C_adc_number + + + +// 23550.3 + +#if(C_adc_number>=1) +#define R_ADC_DEFAULT_0 { 271, 271, 876, 876, 876, 876, 876, 876, 249, 249, 301, 301, 301, 301, 301, 301 } +#define K_LEM_ADC_DEFAULT_0 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 8400, 8400, 8400, 8400, 5000, 5000 } +#define NORMA_ADC_DEFAULT_0 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + +#if(C_adc_number>=2) +#define R_ADC_DEFAULT_1 { 1, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190 } +#define K_LEM_ADC_DEFAULT_1 { 1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1 } +#define NORMA_ADC_DEFAULT_1 { NORMA_ACP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_P, NORMA_ACP } +#endif + +#if(C_adc_number>=3) +#define R_ADC_DEFAULT_2 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 3125, 3125, 3125, 3125, 309, 309 } +#define K_LEM_ADC_DEFAULT_2 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 60000, 60000, 60000, 60000, 5000, 5000 } +#define NORMA_ADC_DEFAULT_2 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + +// 23550.1 + +//#if(C_adc_number>=1) +//#define R_ADC_DEFAULT_0 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 312, 312, 312, 312, 309, 309 } +//#define K_LEM_ADC_DEFAULT_0 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 8400, 8400, 8400, 8400, 5000, 5000 } +//#define NORMA_ADC_DEFAULT_0 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +//#endif +// +//#if(C_adc_number>=2) +//#define R_ADC_DEFAULT_1 { 1, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190 } +//#define K_LEM_ADC_DEFAULT_1 { 1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1 } +//#define NORMA_ADC_DEFAULT_1 { NORMA_ACP, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_P, NORMA_ACP } +//#endif +// +//#if(C_adc_number>=3) +//#define R_ADC_DEFAULT_2 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 3125, 3125, 3125, 3125, 309, 309 } +//#define K_LEM_ADC_DEFAULT_2 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 60000, 60000, 60000, 60000, 5000, 5000 } +//#define NORMA_ADC_DEFAULT_2 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +//#endif + + + + +#if (USE_INTERNAL_ADC==1) +#define R_ADC_DEFAULT_INTERNAL { 100,100,100,100,100,100,100,100,1248,1248,1248,100,100,100,100,100 } +#define K_LEM_ADC_DEFAULT_INTERNAL { 30,30,30,30,10,10,10,10,621,621,621,100,10,10,10,10 } +#define NORMA_ADC_DEFAULT_INTERNAL { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + + + + + +/* + //awa3 + //14 ����� out1 + 0 - 11 ������ ������� + //15 ����� out2 + 0 - 11 ������ ������� + //8 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + //9 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + + //10 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + + //11 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + //12 ����� + 4 - 20 �� | 0 ��� - 10 ��� / �������� + 0.3V - 1.5V / 0 ��� - 10 ��� / �������� + + //13 ����� + 4 - 20 �� | 0 ��� - 10 ��� / �������� + 0.3V - 1.5V / 0 ��� - 10 ��� / �������� +*/ + + +typedef union +{ + + struct + { + unsigned int c0_plus :1; /* 0 ������+ */ + unsigned int c1_plus :1; /* 0 ������+ */ + unsigned int c2_plus :1; /* 0 ������+ */ + unsigned int c3_plus :1; /* 0 ������+ */ + unsigned int c4_plus :1; /* 0 ������+ */ + unsigned int c5_plus :1; /* 0 ������+ */ + unsigned int c6_plus :1; /* 0 ������+ */ + unsigned int c7_plus :1; /* 0 ������+ */ + unsigned int c8_plus :1; /* 0 ������+ */ + unsigned int c9_plus :1; /* 0 ������+ */ + unsigned int c10_plus :1; /* 0 ������+ */ + unsigned int c11_plus :1; /* 0 ������+ */ + unsigned int c12_plus :1; /* 0 ������+ */ + unsigned int c13_plus :1; /* 0 ������+ */ + unsigned int c14_plus :1; /* 0 ������+ */ + unsigned int c15_plus :1; /* 0 ������+ */ + } bit; /* ������ ������� */ + unsigned long all; /* ������ ������ */ + +} ERR_ADC_PLUS_PROTECT; + + +typedef union +{ + + struct + { + unsigned int c0_minus :1; /* 0 ������- */ + unsigned int c1_minus :1; /* 0 ������- */ + unsigned int c2_minus :1; /* 0 ������- */ + unsigned int c3_minus :1; /* 0 ������- */ + unsigned int c4_minus :1; /* 0 ������- */ + unsigned int c5_minus :1; /* 0 ������- */ + unsigned int c6_minus :1; /* 0 ������- */ + unsigned int c7_minus :1; /* 0 ������- */ + unsigned int c8_minus :1; /* 0 ������- */ + unsigned int c9_minus :1; /* 0 ������- */ + unsigned int c10_minus :1; /* 0 ������- */ + unsigned int c11_minus :1; /* 0 ������- */ + unsigned int c12_minus :1; /* 0 ������- */ + unsigned int c13_minus :1; /* 0 ������- */ + unsigned int c14_minus :1; /* 0 ������- */ + unsigned int c15_minus :1; /* 0 ������- */ + + } bit; /* ������ ������� */ + unsigned int all; /* ������ ������ */ + +} ERR_ADC_MINUS_PROTECT; + + +typedef struct +{ + ERR_ADC_PLUS_PROTECT plus; + ERR_ADC_MINUS_PROTECT minus; +} ERR_ADC_PROTECT; + + +/* ���������y ��������� �������� ����� � ����y����� ��� */ +typedef struct +{ + _iq iqU_1; + _iq iqU_2; + + _iq iqU_1_fast; + _iq iqU_2_fast; + + _iq iqU_1_long; + _iq iqU_2_long; + + _iq iqIu_1; + _iq iqIv_1; + _iq iqIw_1; + + _iq iqIu_2; + _iq iqIv_2; + _iq iqIw_2; + + _iq iqIu_1_rms; + _iq iqIv_1_rms; + _iq iqIw_1_rms; + + _iq iqIu_2_rms; + _iq iqIv_2_rms; + _iq iqIw_2_rms; + + _iq iqIu; + _iq iqIv; + _iq iqIw; + + _iq iqIin_1; + _iq iqIin_2; + + _iq iqUin_A1B1; + _iq iqUin_B1C1; + _iq iqUin_C1A1; + + _iq iqUin_A2B2; + _iq iqUin_B2C2; + _iq iqUin_C2A2; + + _iq iqUin_A1B1_rms; + _iq iqUin_B1C1_rms; + _iq iqUin_C1A1_rms; + + _iq iqUin_A2B2_rms; + _iq iqUin_B2C2_rms; + _iq iqUin_C2A2_rms; + + _iq iqUin_m1; + _iq iqUin_m2; + + _iq iqIbreak_1; + _iq iqIbreak_2; //39 + + _iq T_U01; + _iq T_U02; + _iq T_U03; + _iq T_U04; + _iq T_U05; + _iq T_U06; + _iq T_U07; + + _iq T_Water_external; + _iq T_Water_internal; + + _iq T_Air_01; + _iq T_Air_02; + _iq T_Air_03; + _iq T_Air_04; + + _iq P_Water_internal; //53 + + + _iq iqI_vozbud; + + _iq iqIin_sum; + + _iq iqIm_1; + _iq iqIm_2; + + _iq iqIm; + + + _iq iqM; + + _iq PowerScalar; + _iq PowerScalarFilter2; + _iq PowerFOC; + + _iq iqU_1_imit; //63 + + + /* + _iq iqUzpt_1_2; //uzpt1 bs2 + _iq iqUzpt_2_2; //uzpt2 bs2 + _iq iqUzpt_1_2_fast; //uzpt1 bs2 + _iq iqUzpt_2_2_fast; //uzpt2 bs2 + _iq iqUzpt_1_2_long; //uzpt1 bs2 + _iq iqUzpt_2_2_long; //uzpt2 bs2 + _iq iqIin_1_1; //Iin AF1 BS1 + _iq iqIin_2_1; //Iin AF2 BS1 + _iq iqIin_3_1; //Iin AF3 BS1 + _iq iqIin_4_1; //Iin AF4 BS1 + _iq iqIin_5_1; //Iin AF5 BS1 + _iq iqIin_6_1; //Iin AF6 BS1 + _iq iqIin_1_2; //Iin AF1 BS2 + _iq iqIin_2_2; //Iin AF2 BS2 + _iq iqIin_3_2; //Iin AF3 BS2 + _iq iqIin_4_2; //Iin AF4 BS2 + _iq iqIin_5_2; //Iin AF5 BS2 + _iq iqIin_6_2; //Iin AF6 BS2 + _iq iqUin_AB; //������� �������� ���������� AB + _iq iqUin_BC; //������� �������� ���������� BC + _iq iqUin_CA; //������� �������� ���������� CA + _iq iqUin_AB_sf; //������� �������� ���������� AB + _iq iqUin_BC_sf; //������� �������� ���������� BC + _iq iqUin_CA_sf; //������� �������� ���������� CA + _iq iqT_WATER_in; // ����������� ���� �� ����� �� + _iq iqT_WATER_out; // ����������� ���� �� ������ �� + _iq iqT_AIR_in_up; // ����������� ������� �� ����� �� (����) + _iq iqT_AIR_in_down;// ����������� ������� �� ����� �� (���) + _iq iqP_WATER_in; // �������� ���� �� ����� �� + _iq iqP_WATER_out; // �������� ���� �� ������ �� + + _iq iqT_BK1_BK12; // ������� ��������� ������ �� �������� BK1_BK12 + _iq iqT_BK13_BK24; // ������� ��������� ������ �� �������� BK13_BK24 + + _iq iqUin_m1; //��������� ������� �������� ���������� + + + _iq iqIu_1_1; //Iu AF1 BS1 + _iq iqIu_1_2; //Iu AF2 BS1 + _iq iqIv_1_1; //Iv AF3 BS1 + _iq iqIv_1_2; //Iv AF4 BS1 + _iq iqIw_1_1; //Iw AF5 BS1 + _iq iqIw_1_2; //Iw AF6 BS1 + + + + _iq iqIu_2_1; //Iu AF1 BS2 + _iq iqIu_2_2; //Iu AF2 BS2 + _iq iqIv_2_1; //Iv AF3 BS2 + _iq iqIv_2_2; //Iv AF4 BS2 + _iq iqIw_2_1; //Iw AF5 BS2 + _iq iqIw_2_2; //Iw AF6 BS2 + + _iq iqIm_1; + _iq iqIm_2; + + _iq iqWexp; + _iq iqWout; + + _iq iqM; +*/ +} ANALOG_VALUE; + + +#define ANALOG_VALUE_DEFAULT {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0, 0} +/* ���������y ��������� �������� ����� � ����y����� ��� */ + + +#define ERR_LEVEL_ADC_PLUS 3950 //+1270A //2950 // +650A //3467 // 3367 //3367 //3267 // 0xfff-0x29c +#define ERR_LEVEL_ADC_MINUS 150 //-1270A //1150 //-650A // 267 //367 + +#define ERR_LEVEL_ADC_PLUS_6 3800 //3783 //3623~1150 // 3462 ~ 1050 A // 3320 ~ 960A //3680 //3267 // 0xfff-0x29c +#define ERR_LEVEL_ADC_MINUS_6 1000 //267 //367 + +#define MIN_DETECT_UD_ZERO 2300 + + +#define level_err_ADC_PLUS_default {ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS} + +#define level_err_ADC_MINUS_default {ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS} + + +extern ANALOG_VALUE analog; +extern ANALOG_VALUE filter; +extern ANALOG_VALUE analog_zero; + +//void calc_norm_ADC(int fast); +void calc_norm_ADC_0(int run_norma); +void calc_norm_ADC_1(int run_norma); +void Init_Adc_Variables(void); +void norma_adc_nc(int nc); + + + +extern int ADC_f[COUNT_ARR_ADC_BUF][16]; +extern int zero_ADC[COUNT_ARR_ADC_BUF][16]; + +extern ERR_ADC_PROTECT err_adc_protect[COUNT_ARR_ADC_BUF],mask_err_adc_protect[COUNT_ARR_ADC_BUF]; + +extern unsigned int R_ADC[COUNT_ARR_ADC_BUF][16]; +extern unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16]; +extern float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16]; + +//void norma_all_adc(void); +extern _iq koef_Uzpt_long_filter, koef_Uzpt_fast_filter, koef_Uin_filter, koef_Im_filter, koef_Power_filter, koef_Power_filter2; + +void detect_zero_analog(int nc); + + +#if (USE_INTERNAL_ADC==1) + +void Init_Internal_Adc(void); + +#endif + + +#endif // end _ADC_TOOLS diff --git a/Inu/Src/main/alarm_log.c b/Inu/Src/main/alarm_log.c new file mode 100644 index 0000000..7dd9e2e --- /dev/null +++ b/Inu/Src/main/alarm_log.c @@ -0,0 +1,196 @@ +/* + * alarm_log.c + * + * Created on: 11 ����. 2024 �. + * Author: yura + */ + +#include "edrk_main.h" +#include "alarm_log_can.h" +#include "alarm_log.h" +#include "log_params.h" +#include "logs_hmi.h" +#include "global_time.h" + + +#define PAUSE_AUTO_SAVE_ALARM_LOG_SECONDS 20 // 20 sec +#define PAUSE_AUTO_STOP_ALARM_LOG_SECONDS 5 // 5 sec + +void send_alarm_log_pult(void) +{ + static int prev_imit_send_alarm_log_pult = 0; + int to_store = 0; + + static int flag_wait_alarm = 0, prev_Ready2 = 0, flag_store_log = 0, flag_store_log_prepare = 0, flag_auto_logs = 0, flag_stop_alarm = 0; + + static unsigned int pause_store_logs = 0, pause_stop_logs = 0; + + + + // �������� � ���������� + if (edrk.imit_send_alarm_log_pult && prev_imit_send_alarm_log_pult == 0) + flag_store_log = 1; + prev_imit_send_alarm_log_pult = edrk.imit_send_alarm_log_pult; + + + // ���� ������������ ��������� ����� �� ����� + + + // ����� ���������? ������ ����� ������ + if (prev_Ready2==0 && edrk.Status_Ready.bits.ready_final) + { + flag_wait_alarm = 1; + flag_stop_alarm = 0; + } + + if (prev_Ready2==1 && edrk.Status_Ready.bits.ready_final==0) + { + // ���� �����, ���� ������ + init_timer_sec(&pause_stop_logs); + + flag_stop_alarm = 1; + } + prev_Ready2 = edrk.Status_Ready.bits.ready_final; + + + //����� ���� ������� � ��������� ������ + if (flag_wait_alarm && edrk.summ_errors) + { + // ����� ����������� + flag_store_log_prepare = 1; + flag_wait_alarm = 0; + flag_stop_alarm = 0; + init_timer_sec(&pause_store_logs); + } + +// //����� ���� ���������, �� ������ ����� � �� ���� +// if (flag_stop_alarm) +// { +// +// +// } + + // ������ �� ���������, ���������� ����� + if (flag_stop_alarm && detect_pause_sec(PAUSE_AUTO_STOP_ALARM_LOG_SECONDS, &pause_stop_logs)) + { + flag_stop_alarm = 0; + flag_wait_alarm = 0; + } + + + if (flag_store_log_prepare) + { + flag_auto_logs = detect_pause_sec(PAUSE_AUTO_SAVE_ALARM_LOG_SECONDS, &pause_store_logs); + } + + if (flag_auto_logs) + { + flag_store_log_prepare = 0; + flag_auto_logs = 0; + // ��������� + flag_store_log = 1; + + flag_wait_alarm = 0; + flag_stop_alarm = 0; + } + + + + + + + + // ���������� ����� ����� �� ����� + if (flag_store_log) + { + + if (edrk.pult_cmd.log_what_memory >= 2) + to_store = 2; + else + if (edrk.pult_cmd.log_what_memory >= 1) + to_store = 1; + else + to_store = 0; + + log_to_HMI.sdusb = to_store; + + + // ���� ���� �������� �� ��������� + if (log_to_HMI.sdusb) + { + log_to_HMI.send_log = 3; + } + + flag_store_log = 0; + + } + + + + +} + + +void test_send_alarm_log(int alarm_cmd) +{ + static unsigned int points_alarm_log = 1000; + // static unsigned int nchannel_alarm_log = 30; + static int prev_alarm_cmd = 0; + static int local_alarm_cmd = 0; + + + + if (alarm_cmd && prev_alarm_cmd==0 && alarm_log_can.stage==0) + { +// i_led2_on(); + + alarm_log_can.post_points = COUNT_SAVE_LOG_OFF;//100; // ���������� �������������� ������� + alarm_log_can.oscills = log_params.BlockSizeErr;//nchannel_alarm_log; // ���������� ������� + + alarm_log_can.global_enable = 1; + + alarm_log_can.start_adr_temp = (int *)0xc0000; // ����� ��� ���������� ���������� ����� ����, ��� ����������� �� ������������ ������ � ���� �������������. + + // alarm_log_can.finish_adr_temp = (int *)0xa0000; // ����� ��� ���������� ���������� ����� ����, ��� ����������� �� ������������ ������ � ���� �������������. + + alarm_log_can.start_adr_real_logs = (int *)log_params.start_address_log;//(int *)START_ADDRESS_LOG; // ����� ������ �������� ����� � ����������� ������ + alarm_log_can.finish_adr_real_log = (int *)log_params.end_address_log;//(int *)logpar.; // ����� ����� � ����������� ������ + + alarm_log_can.current_adr_real_log = (int *)log_params.addres_mem; + + + alarm_log_can.temp_points = points_alarm_log; // �������� ������ ����������� ������ � ������. + // alarm_log_can.real_points = 1000; // ������ ����� ��� �����, ������ ���������� ����������� �� ������������ ������ �� ��������� ���. + + alarm_log_can.step = 450; // mks + local_alarm_cmd = alarm_cmd; +// alarm_log_can.status_alarm = alarm_cmd;//cmd_alarm_log; // ��� ������ + alarm_log_can.start = 0x1; + alarm_log_can.stop = 0x1; + alarm_log_can.copy2temp = 0x1; + + + alarm_log_can.clear(&alarm_log_can); +// alarm_log_can.send(&alarm_log_can); + +// i_led2_off(); + } + else + local_alarm_cmd = 0; + + alarm_log_can.status_alarm = local_alarm_cmd;//cmd_alarm_log; // ��� ������ + alarm_log_can.send(&alarm_log_can); + + if (alarm_log_can.stage) + { +// i_led2_on_off(1); + } + else + { +// i_led2_on_off(0); + } + + prev_alarm_cmd = alarm_cmd; + +} +//////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/alarm_log.h b/Inu/Src/main/alarm_log.h new file mode 100644 index 0000000..c8fef58 --- /dev/null +++ b/Inu/Src/main/alarm_log.h @@ -0,0 +1,16 @@ +/* + * alarm_log.h + * + * Created on: 11 ����. 2024 �. + * Author: yura + */ + +#ifndef SRC_MAIN_ALARM_LOG_H_ +#define SRC_MAIN_ALARM_LOG_H_ + +void test_send_alarm_log(int alarm_cmd); +void send_alarm_log_pult(void); + + + +#endif /* SRC_MAIN_ALARM_LOG_H_ */ diff --git a/Inu/Src/main/alg_simple_scalar.c b/Inu/Src/main/alg_simple_scalar.c new file mode 100644 index 0000000..7fc3c8f --- /dev/null +++ b/Inu/Src/main/alg_simple_scalar.c @@ -0,0 +1,976 @@ +/* + * alg_simple_scalar.c + * + * Created on: 26 ���. 2020 �. + * Author: Yura + */ + + +#include <alg_simple_scalar.h> +#include <edrk_main.h> +//#include <log_to_mem.h> +#include <master_slave.h> +#include <math.h> +#include <params_alg.h> +#include <params_norma.h> +#include <project.h> +//#include "log_to_mem.h" +#include "IQmathLib.h" +#include "math_pi.h" +#include "mathlib.h" +#include "params_pwm24.h" +#include "filter_v1.h" +#include "log_to_memory.h" + + +#pragma DATA_SECTION(simple_scalar1,".slow_vars"); +ALG_SIMPLE_SCALAR simple_scalar1 = ALG_SIMPLE_SCALAR_DEFAULT; + +_iq koefBpsi = _IQ(0.05); //0.05 + +void init_simple_scalar(void) +{ + simple_scalar1.mzz_add_1 = _IQ(MZZ_ADD_1/NORMA_MZZ); + simple_scalar1.mzz_add_2 = _IQ(MZZ_ADD_2/NORMA_MZZ); + simple_scalar1.mzz_add_3 = _IQ(MZZ_ADD_3/NORMA_MZZ); + + simple_scalar1.poluses = _IQ(POLUS); + simple_scalar1.iq_mzz_max_for_fzad = _IQ(1000.0/NORMA_MZZ); + + simple_scalar1.powerzad_add = _IQ(POWERZAD_ADD_MAX); + simple_scalar1.powerzad_dec = _IQ(POWERZAD_DEC); + +// simple_scalar1.k_freq_for_pid = _IQ(1.0); + simple_scalar1.k_freq_for_pid = _IQ(450.0/FREQ_PWM); + + simple_scalar1.iq_add_kp_df = _IQ(ADD_KP_DF); + simple_scalar1.iq_add_ki_df = _IQ(ADD_KI_DF); + + simple_scalar1.min_mzz_for_df = _IQ(MIN_MZZ_FOR_DF/NORMA_MZZ); + + simple_scalar1.pidF_Kp = _IQ(PID_KP_F); + simple_scalar1.pidF_Ki = _IQ(PID_KI_F); + + + + simple_scalar1.pidIm1.Kp=_IQ(PID_KP_IM); + simple_scalar1.pidIm1.Ki=_IQ(PID_KI_IM); + + simple_scalar1.pidIm_Ki = simple_scalar1.pidIm1.Ki; + + simple_scalar1.pidIm1.Kc=_IQ(PID_KC_IM); + simple_scalar1.pidIm1.Kd=_IQ(PID_KD_IM); + + + simple_scalar1.pidIm1.OutMax=_IQ(K_STATOR_MAX); + simple_scalar1.pidIm1.OutMin=_IQ(K_STATOR_MIN); + +////////////// + + + simple_scalar1.pidF.Kp=_IQ(PID_KP_F); + simple_scalar1.pidF.Ki=_IQ(PID_KI_F); + simple_scalar1.pidF.Kc=_IQ(PID_KC_F); + simple_scalar1.pidF.Kd=_IQ(PID_KD_F); + + + simple_scalar1.pidF.OutMax=_IQ(500/NORMA_MZZ); + simple_scalar1.pidF.OutMin=_IQ(0); + // iq_MAX_DELTA_pidF = _IQ(MAX_DELTA_pidF/NORMA_WROTOR); +///////////////////////// +// simple_scalar1.pidPower_Kp = _IQ(PID_KP_POWER); +// simple_scalar1.pidPower_Ki = _IQ(PID_KI_POWER); + + + // iq_add_kp_dpower = _IQ(ADD_KP_DPOWER); + // iq_add_ki_dpower = _IQ(ADD_KI_DPOWER); + + simple_scalar1.pidPower.Kp=_IQ(PID_KP_POWER); + simple_scalar1.pidPower.Ki=_IQ(PID_KI_POWER); + simple_scalar1.pidPower.Ki = _IQmpy(simple_scalar1.pidPower.Ki, simple_scalar1.k_freq_for_pid); // ������ ��������� Ki �� ������� ���� + + simple_scalar1.pidPower.Kc=_IQ(PID_KC_POWER); + simple_scalar1.pidPower.Kd=_IQ(PID_KD_POWER); + + simple_scalar1.pidPower.OutMax=_IQ(500/NORMA_MZZ); + simple_scalar1.pidPower.OutMin=_IQ(0); + + + simple_scalar1.iq_spad_k = _IQ(0.993); //0.993 ~ 0.4 sek �� 5% + + + // ���. ���������� + simple_scalar1.min_bpsi = _IQ(BPSI_MINIMAL/NORMA_FROTOR); + simple_scalar1.max_bpsi = _IQ(BPSI_MAXIMAL/NORMA_FROTOR); + +} + +/***************************************************************/ +/* �/� ���������y ������ ������ 3 - + vector_moment(real Frot, - ������� ������ + real fzad, - �������� ������� ������ + real mzz_zad, - ������������ ��������� ������-����������� ���� + real *Fz, - ��������� ������� - ������� ����y����y � ������� + real *Uz1, - ��������� ������� - ����. �����y��� � 1 ������� ������� + real *Uz2) - ��������� ������� - ����. �����y��� � 2 ������� ������� + + + �����������y �����y��� ��������, ������� ������y�� ������� fzad �� �������� + + ��������y �����y���� ���������� = 0.5 + + ���� ������ ����y����y ����� ������ ���� �� ����� �� 3-� ������ �����. + ���������y �������y ��y�� �� �������� */ +/****************************************************************/ + + +//#pragma CODE_SECTION(simple_scalar,".fast_run"); +void simple_scalar(int n_alg, + int n_wind_pump, + int direction, + _iq Frot_pid, + _iq Frot, + _iq fzad, + _iq iqKoefOgran, + _iq mzz_zad, + _iq bpsi_const, + _iq iqIm, + _iq iqUin, + _iq Iin, + _iq powerzad, + _iq power_pid, + _iq power_limit, + int mode_oborots_power, + _iq Izad_from_master, + int master, + int count_bs_work, + _iq *Fz, + _iq *Uz1, + _iq *Uz2, + _iq *Izad_out) +{ + + _iq mzz, dF, dI1, Izad, Uz_t1, Kpred_Ip, pred_Ip;//, znak_moment; + _iq dI2, Uz_t2; + + _iq pkk=0,ikk=0; + _iq Im_regul=0; + + + + static _iq bpsi=0; + // static _iq IQ_POLUS=0; + + + static _iq mzz_zad_int=0; + static _iq mzzi=0; + + static _iq I1_i=0; + static _iq I2_i=0; + + static _iq Im1=0; + static _iq Im2=0; + + static _iq Uze_t1=0; + static _iq Uze_t2=0; + + // static _iq fzad_ogr=0; + + + +// static _iq koef_Uz_t_filter=0; + static _iq dI1_prev=0; + static _iq Uz_t1_prev=0; + + static _iq dF_prev = 0; + static _iq mzz_prev = 0; + + // static _iq mzz_add_1, mzz_add_2; + + static _iq fzad_int=0;//, fzad_add_max;//,iq_mzz_max_for_fzad ; + static _iq fzad_add=0; //fzad_dec + _iq halfIm1, halfIm2; + + static _iq powerzad_int=0, powerzad_add_max=0, pidFOutMax = 0, pidFOutMin = 0 ; +//powerzad_dec powerzad_add +// static _iq koef_bpsi=0; + // static _iq min_bpsi=0; + static int flag_uz_t1=0; + + // static _iq correct_err=0; +// static _iq iq_dF_min1=0; +// static _iq iq_dF_min2=0; + _iq pred_dF,Kpred_dF; + static _iq dF_PREDEL_LEVEL2 = 0,dF_PREDEL_LEVEL1=0; + _iq Uze_ogr=0; + + // static _iq iq_spad_k=1; + static _iq myq_temp=0; + static _iq bpsi_filter=0; + static _iq _iq_koef_im_on_tormog = _IQ(KOEF_IM_ON_TORMOG); + static _iq _iq_koef_im_on_tormog_max_temper_break = _IQ(KOEF_IM_ON_TORMOG_WITH_MAX_TEMPER_BREAK); + static _iq n_iq_koef_im_on_tormog = CONST_IQ_1, t_iq_koef_im_on_tormog = CONST_IQ_1; + + static _iq _iq_koef_im_on_tormog_add =_IQ(0.0005), _iq_koef_im_on_tormog_dec = _IQ(0.01); + +// static _iq F_revers_level00= _IQ(70.0/60.0/NORMA_FROTOR); + static _iq F_revers_level0 = _IQ(90.0/60.0/NORMA_FROTOR); + static _iq F_revers_level1 = _IQ(100.0/60.0/NORMA_FROTOR); + static _iq F_revers_level2 = _IQ(110.0/60.0/NORMA_FROTOR); + static _iq F_revers_level3 = _IQ(120.0/60.0/NORMA_FROTOR); + static _iq F_revers_level4 = _IQ(130.0/60.0/NORMA_FROTOR); + static _iq F_revers_level5 = _IQ(140.0/60.0/NORMA_FROTOR); + static _iq F_revers_level6 = _IQ(150.0/60.0/NORMA_FROTOR); + static _iq F_revers_level7 = _IQ(160.0/60.0/NORMA_FROTOR); + static _iq F_revers_level8 = _IQ(170.0/60.0/NORMA_FROTOR); + static _iq F_revers_level9 = _IQ(180.0/60.0/NORMA_FROTOR); + static _iq F_revers_level10 = _IQ(190.0/60.0/NORMA_FROTOR); + static _iq F_revers_level11 = _IQ(200.0/60.0/NORMA_FROTOR); + static _iq F_revers_level12 = _IQ(210.0/60.0/NORMA_FROTOR); + static _iq F_revers_level13 = _IQ(220.0/60.0/NORMA_FROTOR); + + static _iq kF_revers_level00 = _IQ(0.65); + static _iq kF_revers_level0 = _IQ(0.70); + static _iq kF_revers_level1 = _IQ(0.75); + static _iq kF_revers_level2 = _IQ(0.78); + static _iq kF_revers_level3 = _IQ(0.80); + static _iq kF_revers_level4 = _IQ(0.82); + static _iq kF_revers_level5 = _IQ(0.84); + static _iq kF_revers_level6 = _IQ(0.86); + static _iq kF_revers_level7 = _IQ(0.88); + static _iq kF_revers_level8 = _IQ(0.90); + static _iq kF_revers_level9 = _IQ(0.91); + static _iq kF_revers_level10 = _IQ(0.92); + static _iq kF_revers_level11 = _IQ(0.93); + static _iq kF_revers_level12 = _IQ(0.94); + static _iq kF_revers_level13 = _IQ(0.96); + + + static _iq P_level0 = _IQ(70.0/60.0/NORMA_FROTOR); + static _iq P_level1 = _IQ(150.0/60.0/NORMA_FROTOR); + static _iq P_level2 = _IQ(160.0/60.0/NORMA_FROTOR); + static _iq P_level3 = _IQ(170.0/60.0/NORMA_FROTOR); + static _iq P_level4 = _IQ(180.0/60.0/NORMA_FROTOR); + static _iq P_level5 = _IQ(190.0/60.0/NORMA_FROTOR); + static _iq P_level6 = _IQ(200.0/60.0/NORMA_FROTOR); + static _iq P_level7 = _IQ(210.0/60.0/NORMA_FROTOR); + static _iq P_level8 = _IQ(220.0/60.0/NORMA_FROTOR); + static _iq P_level9 = _IQ(230.0/60.0/NORMA_FROTOR); +// static _iq P_level9 = _IQ(300.0/60.0/NORMA_FROTOR); + + static _iq kP_level0 = _IQ(0.9); + static _iq kP_level1 = _IQ(0.9); + static _iq kP_level2 = _IQ(0.9); + static _iq kP_level3 = _IQ(0.85); + static _iq kP_level4 = _IQ(0.8); + static _iq kP_level5 = _IQ(0.75); + static _iq kP_level6 = _IQ(0.7); + static _iq kP_level7 = _IQ(0.65); + static _iq kP_level8 = _IQ(0.6); + static _iq kP_level9 = _IQ(0.55); + + static _iq pid_kp_power = _IQ(PID_KP_POWER); + static _iq add_mzz_outmax_pidp = _IQ(100.0/NORMA_MZZ); + _iq new_pidP_OutMax = 0; + + _iq k_ogr_p_koef_1 = 0; + _iq k_ogr_p_koef_2 = 0; + + _iq k_ogr_n = 0; + + + _iq Frot_pid_abs; + + _iq d_m=0; + + _iq iq_decr_mzz_power; + + _iq level1_power_ain_decr_mzz, level2_power_ain_decr_mzz; + _iq new_power_limit = 0; + + static _iq koef_Power_filter2 = _IQ(1.0/(FREQ_PWM*EXP_FILTER_KOEF_OGRAN_POWER_LIMIT));//2.2 ��� //30000;// 0,0012//16777;//0,001//13981; + + + + + + Frot_pid_abs = _IQabs(Frot_pid); + +// ������� ����������� pidPower.Kp �� ���� +// +// if (Frot_pid_abs>=P_level0) +// { +// k_ogr_p_koef_1 = CONST_IQ_1 - _IQdiv( (Frot_pid_abs-P_level0) , (P_level9-P_level0) ); +// if (k_ogr_p_koef_1<0) k_ogr_p_koef_1 = 0; +// } +// else +// k_ogr_p_koef_1 = CONST_IQ_1; +// +// //k_ogr_p_koef_1 �������� �� 1 �� 0 � +// +// k_ogr_p_koef_2 = CONST_IQ_01 + _IQmpy(CONST_IQ_09, k_ogr_p_koef_1); + +// simple_scalar1.pidPower.Kp = _IQmpy (pid_kp_power, k_ogr_p_koef_2);// _IQ(PID_KP_POWER) + + simple_scalar1.pidPower.Kp = pid_kp_power;//_IQmpy (pid_kp_power, k_ogr_p_koef_2);// _IQ(PID_KP_POWER) + + if (mode_oborots_power == ALG_MODE_SCALAR_OBOROTS) + { + if (simple_scalar1.cmd_new_calc_p_limit) + { + simple_scalar1.flag_decr_mzz_power = 0; + simple_scalar1.iq_decr_mzz_power_filter = CONST_IQ_1; + simple_scalar1.iq_decr_mzz_power = CONST_IQ_1; + new_power_limit = power_limit; + } + else + { + // ������ ���� ����������� �������� �� ���������� ������, ���� ������ + // ���� ��� �������� ������������ � ������ �� �������� ���������������� ��������� ��� ����� ����. + // simple_scalar1.iq_decr_mzz_power_filter ������� ���� �� 1.0 - ��� �����������, + // �� 1-MAX_KOEF_OGRAN_POWER_LIMIT - ������ ����������� + new_power_limit = power_limit - simple_scalar1.sdvig_power_limit; + if (new_power_limit<MIN_DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF) + new_power_limit = MIN_DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF; + + // ������ ������� + level1_power_ain_decr_mzz = new_power_limit - DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF - simple_scalar1.add_power_limit; + + if (level1_power_ain_decr_mzz<0) + level1_power_ain_decr_mzz = 0; + + // ������ ������� + level2_power_ain_decr_mzz = level1_power_ain_decr_mzz + DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF + simple_scalar1.add_power_limit; + + // �������� ������ �� SMEWENIE_LEVEL_POWER_AIN_DECR_MZZ_DEF ����� + level1_power_ain_decr_mzz = level1_power_ain_decr_mzz + SMEWENIE_LEVEL_POWER_AIN_DECR_MZZ_DEF; + level2_power_ain_decr_mzz = level2_power_ain_decr_mzz + SMEWENIE_LEVEL_POWER_AIN_DECR_MZZ_DEF; + + d_m = power_pid - level1_power_ain_decr_mzz; + + if (d_m<0) + d_m=0; // ��� � ����� + else + { + // ���� ������������ ������ + if (d_m>=(level2_power_ain_decr_mzz-level1_power_ain_decr_mzz)) + d_m = CONST_IQ_1; + else + d_m = _IQdiv(d_m,(level2_power_ain_decr_mzz - level1_power_ain_decr_mzz)); + } + + if (d_m<0) + d_m=0; // ��� � ����� + + if (d_m>CONST_IQ_1) + d_m=CONST_IQ_1; // ������ ����������� + + // �������� ������� �� 1.0 �� 0.0 � ������� �� MAX_KOEF_OGRAN_POWER_LIMIT �� 0.0 + d_m = _IQmpy(d_m, MAX_KOEF_OGRAN_POWER_LIMIT); // + + simple_scalar1.iq_decr_mzz_power = CONST_IQ_1 - d_m;// ������ ���� �������� �� 1.0 - ��� �����. �� MAX_KOEF_OGRAN_POWER_LIMIT ����. �������. + + if (simple_scalar1.iq_decr_mzz_power<0) + simple_scalar1.iq_decr_mzz_power=0; + + + simple_scalar1.iq_decr_mzz_power_filter = exp_regul_iq(koef_Power_filter2, + simple_scalar1.iq_decr_mzz_power_filter, + simple_scalar1.iq_decr_mzz_power); + + if (simple_scalar1.iq_decr_mzz_power_filter<0) + simple_scalar1.iq_decr_mzz_power_filter = 0; + + + if (d_m>0) + simple_scalar1.flag_decr_mzz_power = 1; + else + simple_scalar1.flag_decr_mzz_power=0; + + } + } + else + { + simple_scalar1.flag_decr_mzz_power = 0; + simple_scalar1.iq_decr_mzz_power_filter = CONST_IQ_1; + simple_scalar1.iq_decr_mzz_power = CONST_IQ_1; + new_power_limit = power_limit; + } + +#if (ENABLE_DECR_MZZ_POWER_IZAD) + if (simple_scalar1.disable_KoefOgranIzad==0) + simple_scalar1.iqKoefOgranIzad = _IQmpy(iqKoefOgran,simple_scalar1.iq_decr_mzz_power_filter); + else + simple_scalar1.iqKoefOgranIzad = iqKoefOgran; +#else + simple_scalar1.iqKoefOgranIzad = iqKoefOgran; +#endif + //static _iq _iq_1 = _IQ(1.0); + + // static _iq mzz_int_level1_on_F=0; + + +// mzz = _IQsat(mzz,mzz_zad_int,0); + + + simple_scalar1.mzz_zad_in1 = mzz_zad; + simple_scalar1.Izad_from_master = Izad_from_master; + + iqKoefOgran = _IQsat(iqKoefOgran,CONST_IQ_1,0); + + /* ������������� ��������� ������y ���� �����y����� */ + if ( (Frot==0) && (fzad==0) ) + { + mzzi = 0; + fzad_int = 0; + powerzad_int = 0; + bpsi_filter = 0; + pidFOutMax = pidFOutMin = 0; + n_iq_koef_im_on_tormog = CONST_IQ_1;//_IQ(1.0); + simple_scalar1.iq_decr_mzz_power_filter = CONST_IQ_1; + + } + + if (mzz_zad==0) + { + bpsi_filter = 0; + mzz=0; + I1_i=0; + mzzi=0; + mzz_zad_int = 0; + fzad_int = 0; + powerzad_int = 0; + + simple_scalar1.pidIm1.Up1 = 0; + simple_scalar1.pidIm1.Ui = 0; + + simple_scalar1.pidF.Up1 = 0; + simple_scalar1.pidF.Ui = 0; + + simple_scalar1.pidPower.Up1 = 0; + simple_scalar1.pidPower.Ui = 0; + + Uze_t1=0; + Uze_t2=0; + + dI1_prev = 0; + Uz_t1_prev = 0; + + dF_prev = 0; + mzz_prev = 0; + + + // �������� ������������� fzad + fzad_add = _IQ(FZAD_ADD_MAX/NORMA_FROTOR); + // �������� ������������� fzad �� ������ + // fzad_dec = _IQ(FZAD_DEC/NORMA_FROTOR); +// +// + // �������� ������������� mzz_max + // iq_mzz_max_for_fzad = _IQ(1000.0/NORMA_MZZ); + + + // ����. ������� Uz_t_filter + // koef_Uz_t_filter = _IQ(0.001/0.5); //0.0333 + + + + // ����. ������� ���������� �� mzz + // koef_bpsi = _IQ((0.6/NORMA_WROTOR)/(200.0/NORMA_MZZ)); + + flag_uz_t1=0; + + + // ����. �������� ��� ������������� ����������� ����. � ���������� �������� + // correct_err = _IQ(2.5/NORMA_WROTOR); + + // ���. ������� ��� ������ ����. �������� ��� ������������� ����������� ����. � ���������� �������� + // iq_dF_min1 = _IQ(1.0/NORMA_WROTOR); + + // iq_dF_min2 = _IQ(1.5/NORMA_WROTOR); + + // ����. ������� �������� ����� Km + // iq_spad_k = _IQ(0.993); //0.993 ~ 0.4 sek �� 5% + +// iq_spad_k = _IQ(0.9965); //0.993 ~ 0.4 sek �� 5% + + +// dF_PREDEL_LEVEL1 = _IQ(0.5/NORMA_WROTOR); +// dF_PREDEL_LEVEL2 = _IQ(1.5/NORMA_WROTOR); + + // mzz_int_level1_on_F = _IQ(1.0/NORMA_WROTOR); +// mzz_int_level2_on_F = _IQ(1.5/NORMA_WROTOR); + + + } + + + // ����������� ��� ����������� + if (direction==0) + { + // ����� + n_iq_koef_im_on_tormog = CONST_IQ_1;//_IQ(1.0); + } + else + if (direction==-1 && fzad <= 0) + { +// ���� �����, ������� ��������� � ������������ �������� + if (Frot_pid<-F_revers_level13) + n_iq_koef_im_on_tormog = kF_revers_level13; + else + if (Frot_pid<-F_revers_level12) + n_iq_koef_im_on_tormog = kF_revers_level12; + else + if (Frot_pid<-F_revers_level11) + n_iq_koef_im_on_tormog = kF_revers_level11; + else + if (Frot_pid<-F_revers_level10) + n_iq_koef_im_on_tormog = kF_revers_level10; + else + if (Frot_pid<-F_revers_level9) + n_iq_koef_im_on_tormog = kF_revers_level9; + else + if (Frot_pid<-F_revers_level8) + n_iq_koef_im_on_tormog = kF_revers_level8; + else + if (Frot_pid<-F_revers_level7) + n_iq_koef_im_on_tormog = kF_revers_level7; + else + if (Frot_pid<-F_revers_level6) + n_iq_koef_im_on_tormog = kF_revers_level6; + else + if (Frot_pid<-F_revers_level5) + n_iq_koef_im_on_tormog = kF_revers_level5; + else + if (Frot_pid<-F_revers_level4) + n_iq_koef_im_on_tormog = kF_revers_level4; + else + if (Frot_pid<-F_revers_level3) + n_iq_koef_im_on_tormog = kF_revers_level3; + else + if (Frot_pid<-F_revers_level2) + n_iq_koef_im_on_tormog = kF_revers_level2; + else + if (Frot_pid<-F_revers_level1) + n_iq_koef_im_on_tormog = kF_revers_level1; + if (Frot_pid<-F_revers_level0) + n_iq_koef_im_on_tormog = kF_revers_level0; + else + n_iq_koef_im_on_tormog = kF_revers_level00; + + } + else + if (direction==1 && fzad>=0) + { + // ���� ������, ������� ��������� � ������������ �������� + n_iq_koef_im_on_tormog = CONST_IQ_1;//_IQ(1.0); + } + else + { + // ���� ����������� �� �������� ��� � _iq_koef_im_on_tormog ��� ������ �� ��������� +// mzz_zad = _IQmpy(mzz_zad, _iq_koef_im_on_tormog); + + if (edrk.warnings.e9.bits.BREAK_TEMPER_ALARM == 1) + // ���� �������� ���������, ������� �������� + n_iq_koef_im_on_tormog = _iq_koef_im_on_tormog_max_temper_break; + else + n_iq_koef_im_on_tormog = _iq_koef_im_on_tormog; + } + + t_iq_koef_im_on_tormog = zad_intensiv_q(_iq_koef_im_on_tormog_add, + _iq_koef_im_on_tormog_dec, + t_iq_koef_im_on_tormog, + n_iq_koef_im_on_tormog); + + + mzz_zad = _IQmpy(mzz_zad, t_iq_koef_im_on_tormog); + + simple_scalar1.mzz_zad_in2 = mzz_zad; + + /* �������� ������������� ������� */ + if (n_alg==1) + { + + mzz_zad_int = zad_intensiv_q(simple_scalar1.mzz_add_2, simple_scalar1.mzz_add_2, mzz_zad_int, mzz_zad); + +// if (Frot_pid>mzz_int_level1_on_F) +// mzz_zad_int = zad_intensiv_q(mzz_add_1, mzz_add_1, mzz_zad_int, mzz_zad); +// else +// mzz_zad_int = zad_intensiv_q(mzz_add_2, mzz_add_2, mzz_zad_int, mzz_zad); + + } + + + if (n_alg==2) + mzz_zad_int = zad_intensiv_q(simple_scalar1.mzz_add_2, simple_scalar1.mzz_add_2, mzz_zad_int, mzz_zad); + +// myq_temp = _IQdiv(mzz_zad, simple_scalar1.iq_mzz_max_for_fzad); +// myq_temp = _IQmpy( myq_temp, fzad_add_max); +// fzad_add = myq_temp; + + fzad_int = zad_intensiv_q(fzad_add, fzad_add, fzad_int, fzad ); + + + + + powerzad_int = zad_intensiv_q(simple_scalar1.powerzad_add, simple_scalar1.powerzad_add, powerzad_int, powerzad); + + if (n_alg==1) + { + /* �����y��� �������� */ + if (mzz_zad_int>=0) + { + dF = fzad_int - Frot_pid;//*direction; + +////////// Power PI ////////////// + + + //if (_IQabs(simple_scalar1.pidF.Out)) + + k_ogr_n = (_IQabs(power_pid) - _IQabs(powerzad_int)); + // if (k_ogr_n<0) k_ogr_n = 0; + + k_ogr_n = CONST_IQ_1 - _IQdiv(k_ogr_n, _IQabs(powerzad_int)); + + simple_scalar1.k_ogr_n = _IQsat(k_ogr_n,CONST_IQ_1,-CONST_IQ_1); + + + // ����� ����������� ��� pidP OutMax + new_pidP_OutMax = _IQabs(simple_scalar1.pidF.Out)+add_mzz_outmax_pidp; + new_pidP_OutMax = _IQsat(new_pidP_OutMax, mzz_zad_int, add_mzz_outmax_pidp ); // �� 100 �� ���������� ������ ���������� simple_scalar1.pidF.Out + + // ������ ������� ����������� +// new_pidP_OutMax = mzz_zad_int; + + simple_scalar1.pidPower.OutMax = new_pidP_OutMax; + simple_scalar1.pidPower.OutMin = 0; + + +// pidPower.Kp = _IQmpy( _IQdiv(iq_add_kp_dpower, _IQsat(mzz_zad,mzz_zad,MIN_MZZ_FOR_DPOWER)), pidPower_Kp); +// pidPower.Ki = _IQmpy( _IQdiv(iq_add_ki_dpower, _IQsat(mzz_zad,mzz_zad,MIN_MZZ_FOR_DPOWER)), pidPower_Ki); + +// simple_scalar1.pidPower.Ki = _IQmpy(simple_scalar1.pidPower.Ki, simple_scalar1.k_freq_for_pid); + + + simple_scalar1.pidPower.Ref = _IQabs(powerzad_int); // ��� ������ ������������� �������� + + simple_scalar1.pidPower.Fdb = _IQabs(power_pid); + simple_scalar1.pidPower.calc(&simple_scalar1.pidPower); + + + // Saturate the integral output + + if (simple_scalar1.pidPower.Ui > simple_scalar1.pidPower.OutMax) + simple_scalar1.pidPower.Ui = simple_scalar1.pidPower.OutMax; + else if (simple_scalar1.pidPower.Ui < simple_scalar1.pidPower.OutMin) + simple_scalar1.pidPower.Ui = simple_scalar1.pidPower.OutMin; + + +////////////////////////////// +////////////////////////////// + + + // ����������� ����. �������� ������ ���������� + // pidF.OutMax=mzz_zad_int; + // ��� ��� + + pidFOutMax = zad_intensiv_q(simple_scalar1.mzz_add_3, simple_scalar1.mzz_add_1, pidFOutMax, simple_scalar1.pidPower.Out); + pidFOutMin = zad_intensiv_q(simple_scalar1.mzz_add_3, simple_scalar1.mzz_add_1, pidFOutMin, simple_scalar1.pidPower.Out); + + +// fzad + if (direction==-1 && fzad <= 0) + { + pidFOutMax = 0; + simple_scalar1.pidF.OutMax = 0;//simple_scalar1.pidPower.Out; + simple_scalar1.pidF.OutMin = -pidFOutMin;//-simple_scalar1.pidPower.Out; + + } + else + if (direction==1 && fzad>=0) + { + pidFOutMin = 0; + simple_scalar1.pidF.OutMax = pidFOutMax;//simple_scalar1.pidPower.Out; + simple_scalar1.pidF.OutMin = 0;//-simple_scalar1.pidPower.Out; + } + else + { + simple_scalar1.pidF.OutMax = pidFOutMax;//simple_scalar1.pidPower.Out; + simple_scalar1.pidF.OutMin = -pidFOutMin;//-simple_scalar1.pidPower.Out; + } + +/* +// pzad + if (direction==-1 && powerzad <= 0) + { + + + } + else + if (direction==1 && powerzad>=0) + { + + } + else + { + + } +*/ + +// pidF.OutMax = mzz_zad; + if (count_bs_work==2) + simple_scalar1.pidF.Kp = simple_scalar1.pidF_Kp;//_IQmpy( _IQdiv(simple_scalar1.iq_add_kp_df, _IQsat(mzz_zad,mzz_zad,simple_scalar1.min_mzz_for_df)), simple_scalar1.pidF_Kp); + else + simple_scalar1.pidF.Kp = _IQmpy2(simple_scalar1.pidF_Kp); + + simple_scalar1.pidF.Ki = simple_scalar1.pidF_Ki;//_IQmpy( _IQdiv(simple_scalar1.iq_add_ki_df, _IQsat(mzz_zad,mzz_zad,simple_scalar1.min_mzz_for_df)), simple_scalar1.pidF_Ki); + + simple_scalar1.pidF.Ki = _IQmpy(simple_scalar1.pidF.Ki,simple_scalar1.k_freq_for_pid); + +///////////////////////// + +// if (_IQabs(dF)<iq_dF_min1) +// { +// dF=iq_dF_min1; +// m.m1.bit.w_rotor_ust = 1; +// } +// +// if (_IQabs(dF)>iq_dF_min2) +// { +// m.m1.bit.w_rotor_ust = 0; +// } +////////////////////////////////// + + // ��� ��������� dF + //fzad_int = + simple_scalar1.pidF.Ref = _IQmpy(fzad_int, iqKoefOgran); + + simple_scalar1.pidF.Fdb = Frot_pid;//*direction; + simple_scalar1.pidF.calc(&simple_scalar1.pidF); + + + // Saturate the integral output + + if (simple_scalar1.pidF.Ui > simple_scalar1.pidF.OutMax) + simple_scalar1.pidF.Ui = simple_scalar1.pidF.OutMax; + else if (simple_scalar1.pidF.Ui < simple_scalar1.pidF.OutMin) + simple_scalar1.pidF.Ui = simple_scalar1.pidF.OutMin; +///////////////////////////////////// + + mzz = _IQabs(simple_scalar1.pidF.Out); // ��� ������!!! + +/////////////////////////////////////// + + + +// �������� ������������� �� ��� +// mzz = zad_intensiv_q(mzz_add_2, mzz_add_2, mzz, pidF.Out); + +// mzzi = zad_intensiv_q(mzz_add_2, mzz_add_2, mzzi, mzz); + + // ���������� �������� mzz + mzz = _IQsat(mzz,mzz_zad_int,0); + + } + else + { + mzz = 0; + } + + } + + if (n_alg==2) + { + mzz = mzz_zad_int; + } + + + if (master == MODE_SLAVE) + { + mzz = Izad_from_master; + // ���������� �������� mzz + mzz = _IQsat(mzz,mzz_zad_int,0); + } + + + *Izad_out = mzz; + /* ��� ���������� ���� ���������� ���������� �������y I_PREDEL_LEVEL1 + �������� ������� �����y�� ������ */ + +/* + pred_Ip = (filter.I_3+filter.I_6)-I_PREDEL_LEVEL1; + + + if (pred_Ip<0) + Kpred_Ip=0.0; // ��� � ����� + else + { + // ���� ������������ ������ + if (pred_Ip>=(I_PREDEL_LEVEL2-I_PREDEL_LEVEL1)) + Kpred_Ip=1; + else + Kpred_Ip = pred_Ip/(I_PREDEL_LEVEL2-I_PREDEL_LEVEL1); + + } + + // � ��� � ����������� + Izad = mzz * (1-Kpred_Ip); + */ + + + + Izad = _IQmpy(mzz, simple_scalar1.iqKoefOgranIzad); + +// if ((n_alg==1) || (n_alg==2)) +// { +// +// Im1 = iqIm_1; +// Im2 = iqIm_2; +// +// if (n_wind_pump==0) // ������ �� ���� �������� +// { +// +// halfIm1 = Im1 >> 1; +// halfIm2 = Im2 >> 1; +// +// if (Im1>halfIm2) //if (Im1>IQdiv(Im2,_IQ(2.0))) +// { +// Im_regul=Im1; +// simple_scalar1.UpravIm1=1; +// simple_scalar1.UpravIm2=0; +// } +// else +// { +// if (Im2>halfIm1) +// { +// Im_regul=Im2; +// simple_scalar1.UpravIm2=1; +// simple_scalar1.UpravIm1=0; +// } +// else +// { +// Im_regul=Im1; //Im1 +// simple_scalar1.UpravIm1=1;//1 +// simple_scalar1.UpravIm2=0;//0 +// } +// } +// } +// +// if (n_wind_pump==1) // �� ������ 1 ������� ������ ����� ��� � 2-�� +// { +// Im_regul=Im2; +// simple_scalar1.UpravIm1=0; +// simple_scalar1.UpravIm2=1; +// } +// +// if (n_wind_pump==2) // �� ������ 2 ������� ������ ����� ��� � 1-�� +// { +// Im_regul=Im1; +// simple_scalar1.UpravIm1=1; +// simple_scalar1.UpravIm2=0; +// } + + Im_regul = iqIm; + + simple_scalar1.Im_regul = Im_regul; + simple_scalar1.Izad = Izad; + + dI1 = (Izad - Im_regul ); + + simple_scalar1.pidIm1.Ki = simple_scalar1.pidIm_Ki; + simple_scalar1.pidIm1.Ki = _IQmpy(simple_scalar1.pidIm1.Ki,simple_scalar1.k_freq_for_pid); + + + simple_scalar1.pidIm1.Ref = _IQdiv(Izad,iqUin); + simple_scalar1.pidIm1.Fdb = _IQdiv(Im_regul,iqUin); + simple_scalar1.pidIm1.calc(&simple_scalar1.pidIm1); + + + Uz_t1 = simple_scalar1.pidIm1.Out; + + // ����������� ����� Km + if (Uz_t1<Uze_t1) + { + Uze_ogr =_IQmpy(Uze_t1, simple_scalar1.iq_spad_k); + if (Uze_ogr>Uz_t1) Uze_t1 = Uze_ogr; + else + Uze_t1 = Uz_t1; + } + else + { + Uze_t1 = Uz_t1; + } + + Uze_t1 = _IQsat(Uze_t1,simple_scalar1.pidIm1.OutMax, simple_scalar1.pidIm1.OutMin); + +// } + + + /* ���������� ������ ������ */ + *Uz1 = Uze_t1; + *Uz2 = Uze_t1; + + + bpsi = bpsi_const + simple_scalar1.add_bpsi; + + // ������. ~ ������� +// bpsi = _IQmpy(koef_bpsi,mzz); + + + bpsi = _IQsat(bpsi,simple_scalar1.max_bpsi, simple_scalar1.min_bpsi); + +#ifdef BAN_ROTOR_REVERS_DIRECT +// ���������� ������ �� ������������� �������� + if (analog.filter_direct_rotor==-1) + // �������� � ������ �������, ������� �������� ������� �� ���������� � ���������� �������� + *Fz = bpsi; + else + // ��� ���������, ����������� ���������� + *Fz = _IQmpy(Frot,IQ_POLUS) + bpsi; + +#else + + if (simple_scalar1.pidF.Out < 0) + { + bpsi_filter = exp_regul_iq(koefBpsi, bpsi_filter, -bpsi); + } + else + if (simple_scalar1.pidF.Out > 0) + { + bpsi_filter = exp_regul_iq(koefBpsi, bpsi_filter, bpsi); + } + else + bpsi_filter = exp_regul_iq(koefBpsi, bpsi_filter, 0); + + +// *Fz = _IQmpy(Frot*direction,simple_scalar1.poluses) + bpsi_filter; + *Fz = _IQmpy(Frot, simple_scalar1.poluses) + bpsi_filter; + + + simple_scalar1.bpsi_curent = bpsi_filter; + +#endif + + + simple_scalar1.mzz_zad_int = mzz_zad_int; + simple_scalar1.Uze_t1 = Uze_t1; + simple_scalar1.iqKoefOgran = iqKoefOgran; + simple_scalar1.Fz = *Fz; + simple_scalar1.direction = direction; + simple_scalar1.fzad_int = fzad_int; + + + +// if (n_alg==2) +// { +// +// *Fz = fzad_provorot; +// /* bpsi - ����������, ����� ���� +// ���������� ���y ���� ������ �������������y */ +// } + + +} + + + diff --git a/Inu/Src/main/alg_simple_scalar.h b/Inu/Src/main/alg_simple_scalar.h new file mode 100644 index 0000000..f05ca38 --- /dev/null +++ b/Inu/Src/main/alg_simple_scalar.h @@ -0,0 +1,101 @@ +/* + * alg_simple_scalar.h + * + * Created on: 26 ���. 2020 �. + * Author: Vladislav + */ + +#ifndef SRC_MAIN_ALG_SIMPLE_SCALAR_H_ +#define SRC_MAIN_ALG_SIMPLE_SCALAR_H_ + +#include "IQmathLib.h" +#include "pid_reg3.h" + +typedef struct { PIDREG3 pidIm1; + PIDREG3 pidF; + PIDREG3 pidPower; + + _iq mzz_add_1; + _iq mzz_add_2; + _iq poluses; + _iq fzad_add_max; + _iq fzad_dec; + + _iq powerzad_add; + _iq powerzad_dec; + _iq min_bpsi; + _iq koef_Uz_t_filter; + _iq iq_spad_k; + + _iq iq_mzz_max_for_fzad; + _iq k_freq_for_pid; + _iq iq_add_kp_df; + _iq iq_add_ki_df; + _iq min_mzz_for_df; + + _iq pidF_Kp; + _iq pidF_Ki; + int UpravIm1; + int UpravIm2; + _iq pidIm_Ki; + + _iq mzz_zad_in1; + _iq mzz_zad_in2; + + _iq mzz_zad_int; + _iq Im_regul; + _iq Izad; + _iq Izad_from_master; + _iq bpsi_curent; + _iq Uze_t1; + + _iq iqKoefOgran; + _iq Fz; + int direction; + _iq fzad_int; + + _iq add_bpsi; + _iq max_bpsi; + + _iq mzz_add_3; + + _iq k_ogr_n; + _iq iq_decr_mzz_power; + _iq iq_decr_mzz_power_filter; + int flag_decr_mzz_power; + + _iq iqKoefOgranIzad; + int disable_KoefOgranIzad; + _iq add_power_limit; + _iq sdvig_power_limit; + + int cmd_new_calc_p_limit; + + +} ALG_SIMPLE_SCALAR; + +#define ALG_SIMPLE_SCALAR_DEFAULT {PIDREG3_DEFAULTS,PIDREG3_DEFAULTS,PIDREG3_DEFAULTS,\ + 0,0,0,0,0,\ + 0,0,0,0,0,\ + 0,0,0,0,0,\ + 0,0,0,0,0,\ + 0,0,0,0,0,0,0, \ + 0,0, 0,0,0, 0,0, 0, 0, 0,0,0,0,0,0, 0,0 \ +} + + +extern ALG_SIMPLE_SCALAR simple_scalar1; + + + +void simple_scalar(int n_alg, int n_wind_pump, int direction, + _iq Frot_pid, _iq Frot,_iq fzad,_iq mzz_zad, _iq bpsi_const, + _iq iqKoefOgran, + _iq iqIm, _iq iqUin, _iq Iin, _iq powerzad, _iq power_pid, + _iq power_limit, int mode_oborots_power, + _iq Izad_from_master, int master, int count_bs_work, + _iq *Fz, _iq *Uz1, _iq *Uz2, _iq *Izad); + +void init_simple_scalar(void); + +#endif /* SRC_MAIN_ALG_SIMPLE_SCALAR_H_ */ diff --git a/Inu/Src/main/alg_uf_const.c b/Inu/Src/main/alg_uf_const.c new file mode 100644 index 0000000..3e5b8fa --- /dev/null +++ b/Inu/Src/main/alg_uf_const.c @@ -0,0 +1,80 @@ +/* + * alg_uf_const.c + * + * Created on: 26 ���. 2020 �. + * Author: Yura + */ +#include <alg_uf_const.h> +#include <edrk_main.h> +#include <params_alg.h> +#include <params_norma.h> +#include <params_pwm24.h> + +#include "mathlib.h" + + + + +#define T_NARAST 15 // ���. + +//VHZPROF vhz1 = VHZPROF_DEFAULTS; + + +ALG_UF_CONST uf_const1 = ALG_UF_CONST_DEFAULT; + +void init_uf_const(void) +{ + uf_const1.freq = 0; + uf_const1.km = 0; + + uf_const1.zad_plus_km = _IQ(1.0/(FREQ_PWM*T_NARAST)); + + + uf_const1.rmp_freq.RampLowLimit = _IQ(-4); //0 + uf_const1.rmp_freq.RampHighLimit = _IQ(4); + + uf_const1.rmp_freq.RampPlus = _IQ(0.0002); + + uf_const1.rmp_freq.RampMinus = _IQ(-0.0002); + uf_const1.rmp_freq.DesiredInput = 0; + uf_const1.rmp_freq.Out = 0; + + uf_const1.max_km = _IQ(K_STATOR_MAX); + +} + + +void uf_const(_iq *Fz, _iq *Uz1, _iq *Uz2) +{ + + +// vhz1.HighFreq = _IQ(f.fmax_uf/F_STATOR_MAX); +///////////// + + uf_const1.km = edrk.zadanie.iq_kzad_rmp; +// uf_const1.km = zad_intensiv_q(uf_const1.zad_plus_km, uf_const1.zad_plus_km, uf_const1.km, edrk.zadanie.iq_kzad); +// uf_const1.km = _IQsat(uf_const1.km,uf_const1.max_km,0); + *Uz1 = uf_const1.km; + *Uz2 = uf_const1.km; + + +///////////////// + uf_const1.freq = edrk.zadanie.iq_fzad_rmp; + +// uf_const1.rmp_freq.DesiredInput = uf_const1.freq; +// uf_const1.rmp_freq.calc(&uf_const1.rmp_freq); + *Fz = uf_const1.freq; + +/* + vhz1.Freq = Fzad; + vhz1.calc(&vhz1); + + + + *Fz = rmp_freq.Out; + */ + + +} + + diff --git a/Inu/Src/main/alg_uf_const.h b/Inu/Src/main/alg_uf_const.h new file mode 100644 index 0000000..50276f0 --- /dev/null +++ b/Inu/Src/main/alg_uf_const.h @@ -0,0 +1,34 @@ +/* + * alg_uf_const.h + * + * Created on: 26 ���. 2020 �. + * Author: Yura + */ + +#ifndef SRC_MAIN_ALG_UF_CONST_H_ +#define SRC_MAIN_ALG_UF_CONST_H_ + + +#include "IQmathLib.h" +#include "rmp_cntl_v1.h" + + +typedef struct { + RMP_V1 rmp_freq; + _iq freq; + _iq km; + _iq zad_plus_km; + _iq max_km; +} ALG_UF_CONST; + +extern ALG_UF_CONST uf_const1; + +#define ALG_UF_CONST_DEFAULT {RMP_V1_DEFAULTS, 0, 0, 0, 0 } + + + + +void init_uf_const(void); +void uf_const(_iq *Fz, _iq *Uz1, _iq *Uz2); + +#endif /* SRC_MAIN_ALG_UF_CONST_H_ */ diff --git a/Inu/Src/main/another_bs.c b/Inu/Src/main/another_bs.c new file mode 100644 index 0000000..542df74 --- /dev/null +++ b/Inu/Src/main/another_bs.c @@ -0,0 +1,458 @@ +/* + * 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; + +} + diff --git a/Inu/Src/main/another_bs.h b/Inu/Src/main/another_bs.h new file mode 100644 index 0000000..27e5d63 --- /dev/null +++ b/Inu/Src/main/another_bs.h @@ -0,0 +1,21 @@ +/* + * another_bs.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_ANOTHER_BS_H_ +#define SRC_MAIN_ANOTHER_BS_H_ + +void update_bsu_can(unsigned int pause); +void init_can_box_between_bs1_bs2(void); +void detect_alive_another_bs(void); +void detect_error_from_another_bs(void); +void UpdateTableSecondBS(void); +unsigned int read_cmd_sbor_from_bs(void); +void read_data_from_bs(void); + + + +#endif /* SRC_MAIN_ANOTHER_BS_H_ */ diff --git a/Inu/Src/main/break_regul.c b/Inu/Src/main/break_regul.c new file mode 100644 index 0000000..1de2cd1 --- /dev/null +++ b/Inu/Src/main/break_regul.c @@ -0,0 +1,204 @@ +#include <adc_tools.h> +#include <break_regul.h> +#include <edrk_main.h> +#include <params_pwm24.h> +#include <PWMTools.h> + +#include "IQmathLib.h" +#include "pid_reg3.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File + + +#pragma DATA_SECTION(break_result_1,".fast_vars"); +_iq break_result_1 = 0; + +#pragma DATA_SECTION(break_result_2,".fast_vars"); +_iq break_result_2 = 0; + +#pragma DATA_SECTION(break_result_3,".fast_vars"); +_iq break_result_3 = 0; + +#pragma DATA_SECTION(break_result_4,".fast_vars"); +_iq break_result_4 = 0; + +#pragma DATA_SECTION(koef_Krecup,".fast_vars"); +_iq koef_Krecup = 0; + +#pragma DATA_SECTION(koef_Min_recup,".fast_vars"); +_iq koef_Min_recup = 0; + +BREAK_REGUL break_reg = BREAK_REGUL_DEFAULTS; + +_iq calc_recup(_iq voltage, _iq recup_level, _iq max_recup_level); +//#pragma DATA_SECTION(pidF,".fast_vars"); +//PIDREG3 pidF=PIDREG3_DEFAULTS; + +void break_resistor_managment_init(unsigned int freq_pwm) +{ + volatile float percent;//, percent2; + _iq iq_percent1 = 0, iq_percent2 = 0;// iq_percent3 = 0, iq_percent4 = 0; + + break_reg.pwm_tics = (FREQ_INTERNAL_GENERATOR_XILINX_TMS / freq_pwm ); + break_reg.pwm_minimal_tics = (float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0; + break_reg.pwm_max_tics = break_reg.pwm_tics - break_reg.pwm_minimal_tics; + + + //����������� ����������� �����-��� ��������� ������. ���������� ����� � IQ15. + percent = (break_reg.pwm_max_tics * RECUP_PERCENT_MIN/100.0) * 32768.0;//����� � ����� ���������� � _IQ15 + iq_percent1 = percent; + + //������������ ����������� �����-��� ��������� ������. ���������� ����� � IQ15. + percent = (break_reg.pwm_max_tics * RECUP_PERCENT_MAX/100.0) * 32768.0; + iq_percent2 = percent; + + //����������� ����� ��������� ����-����� � ��� �� ����� �������� ������ + koef_Krecup = _IQdiv((iq_percent1 - iq_percent2),(IQ_RECUP_LEVEL_MIN - IQ_RECUP_LEVEL_MAX)); + koef_Min_recup = iq_percent1; //����������� ����� �������� ��������� ������ � ����� +} + + +//int break_resistor_managment_calc(int flag_on_off) +#pragma CODE_SECTION(break_resistor_managment_calc,".fast_run"); +void break_resistor_managment_calc() +{ + static unsigned int break_counter = 0;//MAX_BREAK_IMPULSE + 1; + + if(edrk.Discharge && edrk.from_shema_filter.bits.QTV_ON_OFF==0 + && edrk.from_shema_filter.bits.UMP_ON_OFF==0)// && edrk.to_shema.bits.QTV_ON == 0) + { + if (break_counter < MAX_BREAK_IMPULSE) + { + break_counter++; + + + if ((filter.iqU_1_fast > BREAK_INSENSITIVE_LEVEL_MIN) + || edrk.ManualDischarge || edrk.NoDetectUZeroDischarge) + { + if (edrk.Obmotka1 == 0) + break_result_1 = 300; + else + break_result_1 = 0; + } + else + { + break_result_1 = 0; + } + + if ((filter.iqU_2_fast > BREAK_INSENSITIVE_LEVEL_MIN) + || edrk.ManualDischarge || edrk.NoDetectUZeroDischarge ) + { + if (edrk.Obmotka2 == 0) + break_result_2 = 300; + else + break_result_2 = 0; + } + else + { + break_result_2 = 0; + } + +// if (filter.iqU_3_fast < BREAK_INSENSITIVE_LEVEL_MIN) +// { +// break_result_3 = 0; +// } +// else +// { +// break_result_3 = 300; +//// break_result_3 = calc_stop_run_recup(filter.iqU_3_fast); +// } +// +// if (filter.iqU_4_fast < BREAK_INSENSITIVE_LEVEL_MIN) +// { +// break_result_4 = 0; +// } +// else +// { +// break_result_4 = 300; +//// break_result_4 = calc_stop_run_recup(filter.iqU_4_fast); +// } + + if((!break_result_1 && !break_result_2 && !break_result_3 && !break_result_4) + || (break_counter >= (MAX_BREAK_IMPULSE - 1))) + { + edrk.Discharge = 0; + break_counter = 0; + } + } + else + { + break_result_1 = 0; + break_result_2 = 0; + break_result_3 = 0; + break_result_4 = 0; + break_counter = 0; + edrk.Discharge = 0; + } + } + +} + +#pragma CODE_SECTION(calc_recup,".fast_run"); +_iq calc_recup(_iq voltage, _iq recup_level, _iq max_recup_level) +{ + if (voltage <= recup_level) + { + return 0; + } + else + { + voltage = _IQsat(voltage,max_recup_level,recup_level); + voltage = _IQmpy(koef_Krecup,voltage - recup_level) + koef_Min_recup; + return voltage >> 15; + } +} + +#pragma CODE_SECTION(break_resistor_recup_calc,".fast_run"); +void break_resistor_recup_calc(_iq Uzpt_nominal) +{ + _iq Uzpt_start_recup = Uzpt_nominal + IQ_DELTA_U_START_RECUP; + _iq Uzpt_max_open_break_keys = Uzpt_nominal + IQ_DELTA_U_MAX_OPEN_BREAK_KEYS; + + if (/*edrk.Go &&*/ (edrk.SborFinishOk || edrk.Status_Ready.bits.ImitationReady2) ) + { + break_result_1 = calc_recup(filter.iqU_1_fast, Uzpt_start_recup, Uzpt_max_open_break_keys); + break_result_2 = calc_recup(filter.iqU_2_fast, Uzpt_start_recup, Uzpt_max_open_break_keys); + } +} + +#pragma CODE_SECTION(break_resistor_managment_update,".fast_run"); +void break_resistor_managment_update() +{ + if (break_result_1 < break_reg.pwm_minimal_tics) + break_result_1 = 0; + + if (break_result_2 < break_reg.pwm_minimal_tics) + break_result_2 = 0; + +// if (break_result_3 < break_reg.pwm_minimal_tics) +// break_result_3 = 0; +// +// if (break_result_4 < break_reg.pwm_minimal_tics) +// break_result_4 = 0; + + if (break_result_1 > break_reg.pwm_max_tics) + break_result_1 = break_reg.pwm_max_tics; + + if (break_result_2 > break_reg.pwm_max_tics) + break_result_2 = break_reg.pwm_max_tics; + +// if (break_result_3 > break_reg.pwm_max_tics) +// break_result_3 = break_reg.pwm_max_tics; +// +// if (break_result_4 > break_reg.pwm_max_tics) +// break_result_4 = break_reg.pwm_max_tics; +} + +//#pragma CODE_SECTION(break_resistor_set_closed,".fast_run"); +void break_resistor_set_closed() +{ + break_result_1 = 0; + break_result_2 = 0; + break_result_3 = 0; + break_result_4 = 0; +} diff --git a/Inu/Src/main/break_regul.h b/Inu/Src/main/break_regul.h new file mode 100644 index 0000000..1e79cdd --- /dev/null +++ b/Inu/Src/main/break_regul.h @@ -0,0 +1,70 @@ +#ifndef _BREAK_REGUL_H +#define _BREAK_REGUL_H + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct { + unsigned int pwm_tics; + unsigned int pwm_minimal_tics; + unsigned int pwm_max_tics; +} BREAK_REGUL; + +#define BREAK_REGUL_DEFAULTS {0,0,0} + + +#define BREAK_INSENSITIVE_LEVEL_MIN 279620 //50V +#define BREAK_INSENSITIVE_LEVEL_MAX 4194304//500V//5872025//700 V//2516582//300 V//4194304//500 V//2516582 // 838860 //100 V +#define PERCENT_BREAK_MAX 13421772//80 percent +#define PERCENT_BREAK_MIN 838860//5 percent +#define MAX_RECUP_LEVEL 5872025 //700 V +#define K_RECUP_LEVEL 56 //5.6 /// 838860 / 4697620 //700 V +#define MAX_BREAK_IMPULSE 9000 + +#define RECUP_PERCENT_MIN 10.0 +#define RECUP_PERCENT_MAX 90.0 + +//#define IQ_RECUP_LEVEL_MIN_ACCUM 16777216 //3000V +//#define IQ_RECUP_LEVEL_MAX_ACCUM 17895697 //3200V + +#define IQ_RECUP_LEVEL_MIN 15658734L //2800V //15099494L //2700V //9507089L //1700V //8947848L //1600V // +#define IQ_RECUP_LEVEL_MAX 16777216L //3000V //16777216L //16217975L //2900V //11184810L //2000V //17895697 //3200V 10066329 //1800V // + +#define IQ_DELTA_U_START_RECUP 559240 //100V //279620LL //50V +#define IQ_DELTA_U_MAX_OPEN_BREAK_KEYS 1677721LL//300 V + + +#define IQ_MIN_VOLTAGE_STOP_RUN 279620L //50V +#define IQ_MAX_VOLTAGE_STOP_RUN 16777216L //3000V + +#define BRK_STOP_RUN_PERCENT_MIN 5 +#define BRK_STOP_RUN_PERCENT_MAX 50 + +//int break_resistor_managment_calc(int flag_on_off); +void break_resistor_managment_calc(void); +void break_resistor_managment_init(unsigned int freq_pwm); +void break_resistor_managment_update(void); +void break_resistor_recup_calc(_iq Uzpt_nominal); +void break_resistor_set_closed(void); +_iq calc_stop_run_recup(_iq voltage); + + +//extern PIDREG3 break_struct_1; +//extern PIDREG3 break_struct_2; + + + + +extern _iq break_result_1; +extern _iq break_result_2; +extern _iq break_result_3; +extern _iq break_result_4; + +extern _iq kp_break; + +#ifdef __cplusplus + } +#endif + +#endif /* _BREAK_REGUL_H */ diff --git a/Inu/Src/main/calc_rms_vals.c b/Inu/Src/main/calc_rms_vals.c new file mode 100644 index 0000000..7363ce2 --- /dev/null +++ b/Inu/Src/main/calc_rms_vals.c @@ -0,0 +1,265 @@ +/* + * calc_rms_vals.c + * + * Created on: 14 ���. 2020 �. + * Author: star + */ +#include <adc_tools.h> +#include <calc_rms_vals.h> +#include <edrk_main.h> +#include <params_norma.h> +#include <params_pwm24.h> + +#include "IQmathLib.h" +#include "mathlib.h" + +#define NUM_OF_CHANNELS 6 + +//#define USE_CALC_U_IN_RMS 1 +//#define USE_CALC_I_OUT_RMS 1 + + +#pragma DATA_SECTION(in_U_rms_calc_buffer,".slow_vars") +RMS_BUFFER in_U_rms_calc_buffer[NUM_OF_CHANNELS] = {RMS_BUFFER_DEFAULTS, RMS_BUFFER_DEFAULTS, \ + RMS_BUFFER_DEFAULTS, RMS_BUFFER_DEFAULTS, \ + RMS_BUFFER_DEFAULTS, RMS_BUFFER_DEFAULTS}; + +#pragma DATA_SECTION(out_I_rms_calc_buffer,".slow_vars") +RMS_BUFFER_WITH_THINNING out_I_rms_calc_buffer[6] = {RMS_BUFFER_WITH_THINNING_DEFAULTS, RMS_BUFFER_WITH_THINNING_DEFAULTS, \ + RMS_BUFFER_WITH_THINNING_DEFAULTS, RMS_BUFFER_WITH_THINNING_DEFAULTS, \ + RMS_BUFFER_WITH_THINNING_DEFAULTS, RMS_BUFFER_WITH_THINNING_DEFAULTS}; + +/////////////////////////////////////////////////// +void init_Uin_rms(void) +{ + int k,l; + // ������ ������ ������ � �� ������ + for (k=0;k<NUM_OF_CHANNELS;k++) + { + for (l=0;l<RMS_BUFFER_SIZE;l++) + in_U_rms_calc_buffer[k].values[l] = 0; + in_U_rms_calc_buffer[k].position = 0; + in_U_rms_calc_buffer[k].array_size = RMS_BUFFER_SIZE; + } +} +/////////////////////////////////////////////////// + +void add_to_buff(RMS_BUFFER *b, _iq val) { + b->values[b->position++] = val; + if (b->position >= b->array_size) { b->position = 0;} +} + +#define add_to_buff_def(b, val) { (b)->values[(b)->position++] = (val); if ((b)->position >= (b)->array_size) { (b)->position = 0;}} + +static void calc_Uin_rms(void); +static void calc_Iout_rms(void); + +#define CONST_PI 52707178 + +//#pragma CODE_SECTION(fill_rms_array_IQ15,".fast_run1"); +void fill_rms_array_IQ15(RMS_BUFFER_WITH_THINNING *v) { + static _iq norma_f_rot = NORMA_FROTOR; + int period_by_teta = 0; +// int freq = _IQtoF(v->signal_freq) * NORMA_FROTOR; +// int freq = _IQtoF(v->signal_freq * norma_f_rot); //Max IQ24 = 127. ������� � �� ������ ������ + int freq = (v->signal_freq * norma_f_rot) / (1LL << GLOBAL_Q); //� 10 ��� �������, ������ �������� + int count_miss_writing = 100; + if (freq != 0) { + freq *= v->elements_in_period; //"�����������" + count_miss_writing = (int)(v->freq_pwm / freq); + if (count_miss_writing > 100) {count_miss_writing = 100;} + } + + if (v->use_teta) { + v->internal.teta_period_counter += 1; + if ((v->teta < CONST_PI && v->internal.teta_prev > CONST_PI) || + (v->teta > CONST_PI && v->internal.teta_prev < CONST_PI)) { + v->internal.zero_teta_period = v->internal.teta_period_counter; + v->internal.teta_period_counter = 0; + } + v->internal.teta_prev = v->teta; + period_by_teta = v->internal.zero_teta_period / v->elements_in_period; + if (period_by_teta != 0) { + count_miss_writing = (count_miss_writing + period_by_teta) / 2; + } + } + + + if (v->internal.miss_write_counter++ < count_miss_writing) { + return; + } + + v->internal.miss_write_counter = 0; + v->values[v->position++] = _IQtoIQ15(v->val); + if (v->position >= v->array_size) { + v->position = 0; + } +} + +void fill_RMS_buff_interrupt(_iq teta_ch1, _iq teta_ch2) { +#ifdef USE_CALC_U_IN_RMS +// add_to_buff(&in_U_rms_calc_buffer[0], analog.iqUin_A1B1); +// add_to_buff(&in_U_rms_calc_buffer[1], analog.iqUin_B1C1); +// add_to_buff(&in_U_rms_calc_buffer[2], analog.iqUin_C1A1); +// add_to_buff(&in_U_rms_calc_buffer[3], analog.iqUin_A2B2); +// add_to_buff(&in_U_rms_calc_buffer[4], analog.iqUin_B2C2); +// add_to_buff(&in_U_rms_calc_buffer[5], analog.iqUin_C2A2); +// + add_to_buff_def(&in_U_rms_calc_buffer[0], analog.iqUin_A1B1); //define � 10 ��� ������� + add_to_buff_def(&in_U_rms_calc_buffer[1], analog.iqUin_B1C1); + add_to_buff_def(&in_U_rms_calc_buffer[2], analog.iqUin_C1A1); + add_to_buff_def(&in_U_rms_calc_buffer[3], analog.iqUin_A2B2); + add_to_buff_def(&in_U_rms_calc_buffer[4], analog.iqUin_B2C2); + add_to_buff_def(&in_U_rms_calc_buffer[5], analog.iqUin_C2A2); +#endif //USE_CALC_U_IN_RMS +#ifdef USE_CALC_I_OUT_RMS + out_I_rms_calc_buffer[0].val = analog.iqIu_1; + out_I_rms_calc_buffer[0].teta = teta_ch1; + out_I_rms_calc_buffer[0].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[0].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[0].add_value(&out_I_rms_calc_buffer[0]); + out_I_rms_calc_buffer[1].val = analog.iqIv_1; + out_I_rms_calc_buffer[1].teta = teta_ch1; + out_I_rms_calc_buffer[1].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[1].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[1].add_value(&out_I_rms_calc_buffer[1]); + out_I_rms_calc_buffer[2].val = analog.iqIw_1; + out_I_rms_calc_buffer[2].teta = teta_ch1; + out_I_rms_calc_buffer[2].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[2].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[2].add_value(&out_I_rms_calc_buffer[2]); + + out_I_rms_calc_buffer[3].val = analog.iqIu_1; + out_I_rms_calc_buffer[3].teta = teta_ch2; + out_I_rms_calc_buffer[3].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[3].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[3].add_value(&out_I_rms_calc_buffer[3]); + out_I_rms_calc_buffer[4].val = analog.iqIu_1; + out_I_rms_calc_buffer[4].teta = teta_ch2; + out_I_rms_calc_buffer[4].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[4].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[4].add_value(&out_I_rms_calc_buffer[4]); + out_I_rms_calc_buffer[5].val = analog.iqIu_1; + out_I_rms_calc_buffer[5].teta = teta_ch2; + out_I_rms_calc_buffer[5].freq_pwm = FREQ_PWM * 2; + out_I_rms_calc_buffer[5].signal_freq = edrk.f_stator; + out_I_rms_calc_buffer[5].add_value(&out_I_rms_calc_buffer[5]); +#endif //USE_CALC_I_OUT_RMS +} + + +void calc_Uin_rms(void) { + + RMS_CALC_ARRAY rc = RMS_CALC_DEFAULTS; + + rc.size_array = in_U_rms_calc_buffer[0].array_size; + rc.data_array = in_U_rms_calc_buffer[0].values; + analog.iqUin_A1B1_rms = rc.calc(&rc); + rc.size_array = in_U_rms_calc_buffer[1].array_size; + rc.data_array = in_U_rms_calc_buffer[1].values; + analog.iqUin_B1C1_rms = rc.calc(&rc); + rc.size_array = in_U_rms_calc_buffer[2].array_size; + rc.data_array = in_U_rms_calc_buffer[2].values; + analog.iqUin_C1A1_rms = rc.calc(&rc); + + rc.size_array = in_U_rms_calc_buffer[3].array_size; + rc.data_array = in_U_rms_calc_buffer[3].values; + analog.iqUin_A2B2_rms = rc.calc(&rc); + rc.size_array = in_U_rms_calc_buffer[4].array_size; + rc.data_array = in_U_rms_calc_buffer[4].values; + analog.iqUin_B2C2_rms = rc.calc(&rc); + rc.size_array = in_U_rms_calc_buffer[5].array_size; + rc.data_array = in_U_rms_calc_buffer[5].values; + analog.iqUin_C2A2_rms = rc.calc(&rc); + +} + + +void calc_Iout_rms() { + int i = 0; + _iq results[NUM_OF_CHANNELS]; + RMS_CALC_ARRAY_THINNING rc_Iout = RMS_CALC_THINNING_DEFAULTS; + + //Calc rms + for (i = 0; i < NUM_OF_CHANNELS; i++) { + rc_Iout.data_array = out_I_rms_calc_buffer[i].values; + rc_Iout.last_elem_position = out_I_rms_calc_buffer[i].position; + rc_Iout.size_array = out_I_rms_calc_buffer[i].array_size; + rc_Iout.signal_period = out_I_rms_calc_buffer[i].elements_in_period; + results[i] = rc_Iout.calc(&rc_Iout); + } + analog.iqIu_1_rms = results[0]; + analog.iqIv_1_rms = results[1]; + analog.iqIw_1_rms = results[2]; + analog.iqIu_2_rms = results[3]; + analog.iqIv_2_rms = results[4]; + analog.iqIw_2_rms = results[5]; +} + +void calc_RMS_values_main() { +#ifdef USE_CALC_U_IN_RMS + calc_Uin_rms(); +#endif +// i_led2_off(); +// i_led2_on(); +#ifdef USE_CALC_I_OUT_RMS + calc_Iout_rms(); +#endif +} + +//float signal_amplitude = 141; +//_iq data_arr[RMS_BUFFER_SIZE]; +//_iq16 data_arr_IQ16[RMS_BUFFER_SIZE]; +//_iq position = 0; +//_iq result_simple = 0; +//_iq result_simple_t = 0; +// +//RMS_BUFFER_WITH_THINNING buffer_var_freq = RMS_BUFFER_WITH_THINNING_DEFAULTS; +//int freq_mian_signal = 1; +//int counter_wait_change_freq = 0; +//#define WAIT_CHANGE_FREQ_TICS 2000 +/* +void test_calc_rms (_iq teta) { + _iq amplitude = _IQ (signal_amplitude / NORMA_ACP); + _iq current_val = 0; + _iq add_var_freq = 0; + static _iq add_50hz = _IQ(6.28 * 50.0 / FREQ_PWM / 2.0); + static _iq teta_50hz = 0, teta_Low = 0; + RMS_CALC_ARRAY rc = RMS_CALC_DEFAULTS; + + RMS_CALC_ARRAY_THINNING rct = RMS_CALC_THINNING_DEFAULTS; + + current_val = _IQmpy(amplitude, _IQcos(teta_50hz)); + data_arr[position] = current_val; + data_arr_IQ16[position] = _IQtoIQ16(current_val); + position += 1; + if (position >= RMS_BUFFER_SIZE) position = 0; + teta_50hz += add_50hz; + rc.data_array = data_arr; + rc.size_array = RMS_BUFFER_SIZE; + result_simple = rc.calc(&rc); + + if (counter_wait_change_freq >= WAIT_CHANGE_FREQ_TICS) { + if (freq_mian_signal < 20) { freq_mian_signal +=1;} + counter_wait_change_freq = 0; + } else { + counter_wait_change_freq += 1; + } + + add_var_freq = _IQ(6.28 * freq_mian_signal / FREQ_PWM / 2.0); + teta_Low += add_var_freq; + current_val = _IQmpy(amplitude, _IQcos(teta_Low)); + buffer_var_freq.val = current_val; + buffer_var_freq.signal_freq = _IQ((float)freq_mian_signal / NORMA_FROTOR); + buffer_var_freq.teta = teta_Low; + buffer_var_freq.add_value(&buffer_var_freq); + + + + rct.data_array = buffer_var_freq.values; + rct.size_array = buffer_var_freq.array_size; + rct.last_elem_position = buffer_var_freq.position; + rct.signal_period = buffer_var_freq.array_size; + result_simple_t = rct.calc(&rct); +} +*/ diff --git a/Inu/Src/main/calc_rms_vals.h b/Inu/Src/main/calc_rms_vals.h new file mode 100644 index 0000000..a01b3da --- /dev/null +++ b/Inu/Src/main/calc_rms_vals.h @@ -0,0 +1,66 @@ +/* + * calc_rms_vals.h + * + * Created on: 14 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_CALC_RMS_VALS_H_ +#define SRC_MAIN_CALC_RMS_VALS_H_ + + +#include <params_pwm24.h> + +#include "IQmathLib.h" + +#define RMS_BUFFER_SIZE (FREQ_PWM * 2 / 50) +//#define RMS_BUFFER_SIZE 18 //For FREQ_PWM 450 and signal frequency 50 Hz + + +typedef struct { + _iq values[RMS_BUFFER_SIZE]; + int array_size; + int position; +} RMS_BUFFER; + +#define RMS_BUFFER_DEFAULTS {{0}, RMS_BUFFER_SIZE, 0} + +#define RMS_THINNING_BUFFER_SIZE 40 //������ ���������� ����� 30 ��������� �� ������ ������� +#define RMS_THINNING_PERIOD (RMS_THINNING_BUFFER_SIZE * 3 / 4) +typedef struct { + _iq val; //in + _iq16 values[RMS_THINNING_BUFFER_SIZE]; + int array_size; + int position; + int elements_in_period; // ������� ��������� � ������� �������� 1 ������ ����������� ������� + + int freq_pwm; //in + _iq signal_freq; //in + int use_teta; //���������� ������ ������� � ������� teta + _iq teta; //in + + struct { + int miss_write_counter; + int teta_period_counter; + _iq teta_prev; + int zero_teta_period; +// int zero_teta_counter_prev; + } internal; + void (*add_value)(); +} RMS_BUFFER_WITH_THINNING; + + +#define RMS_BUFFER_WITH_THINNING_DEFAULTS {0, {0}, RMS_THINNING_BUFFER_SIZE,0, \ + RMS_THINNING_PERIOD,\ + (FREQ_PWM * 2),0,0,0, {0,0,0,0}, \ + fill_rms_array_IQ15} + +void fill_rms_array_IQ15(RMS_BUFFER_WITH_THINNING *v); +void fill_RMS_buff_interrupt(_iq teta_ch1, _iq teta_ch2); +void calc_RMS_values_main(); +void init_Uin_rms(void); + + +void test_calc_rms (_iq teta); + +#endif /* SRC_MAIN_CALC_RMS_VALS_H_ */ diff --git a/Inu/Src/main/calc_tempers.c b/Inu/Src/main/calc_tempers.c new file mode 100644 index 0000000..a5988cc --- /dev/null +++ b/Inu/Src/main/calc_tempers.c @@ -0,0 +1,284 @@ +/* + * calc_tempers.c + * + * Created on: 4 ���. 2020 �. + * Author: star + */ + +#include <adc_tools.h> +#include <calc_tempers.h> +#include <CAN_project.h> +#include <edrk_main.h> +#include <params_temper_p.h> + +#include "CAN_Setup.h" +#include "IQmathLib.h" + +int calc_max_temper_acdrive_bear(void); +int calc_max_temper_acdrive_winding(void); +int calc_max_temper_edrk_u(void); +int calc_max_temper_edrk_water(void); +int calc_max_temper_edrk_air(void); +int calc_min_temper_edrk_air(void); + + + + +//////////////////////////////////////////////////////////////////// +int calc_max_temper_acdrive_bear(void) +{ + int i, max_t=0; + + for (i=0;i<edrk.temper_acdrive.bear.max_size;i++) + if (edrk.temper_acdrive.winding.filter_real_int_temper[i]>max_t) + max_t = edrk.temper_acdrive.winding.filter_real_int_temper[i]; + + return max_t; + +} +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +int calc_max_temper_acdrive_winding(void) +{ + int i, max_t=0; + + for (i=0;i<edrk.temper_acdrive.winding.max_size;i++) + if (edrk.temper_acdrive.winding.filter_real_int_temper[i]>max_t) + max_t = edrk.temper_acdrive.winding.filter_real_int_temper[i]; + + return max_t; + +} +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +int calc_max_temper_edrk_u(void) +{ + int i, max_t=0; + + for (i=0;i<7;i++) + if (edrk.temper_edrk.real_int_temper_u[i]>max_t) + max_t = edrk.temper_edrk.real_int_temper_u[i]; + + return max_t; + +} +//////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +int calc_max_temper_edrk_water(void) +{ + int i, max_t=0; + + for (i=0;i<2;i++) + if (edrk.temper_edrk.real_int_temper_water[i]>max_t) + max_t = edrk.temper_edrk.real_int_temper_water[i]; + + return max_t; + +} +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +int calc_max_temper_edrk_air(void) +{ + int i, max_t=0; + + for (i=0;i<4;i++) + if (edrk.temper_edrk.real_int_temper_air[i]>max_t) + max_t = edrk.temper_edrk.real_int_temper_air[i]; + + return max_t; + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +int calc_min_temper_edrk_air(void) +{ + int i, min_t=1000; + + for (i=0;i<4;i++) + if (edrk.temper_edrk.real_int_temper_air[i]<min_t) + min_t = edrk.temper_edrk.real_int_temper_air[i]; + + return min_t; + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +// ACP[V]/61.9[Om]/2.0*10000 + + +#define koef_Temper_ENGINE_filter 1600000 +#define INDEX_ACDRIVE_WINDING_CAN_UNITES 24 +#define INDEX_ACDRIVE_BEAR_CAN_UNITES 30 + + + +void calc_temper_acdrive(void) +{ + int i; + _iq iqtain,iq_temp; + +// Winding + for (i=0;i<edrk.temper_acdrive.winding.max_size;i++) + { + edrk.temper_acdrive.winding.real_temper[i] = Unites[BKSSD_CAN_DEVICE][INDEX_ACDRIVE_WINDING_CAN_UNITES+i]/10.0; + if (Unites[BKSSD_CAN_DEVICE][INDEX_ACDRIVE_WINDING_CAN_UNITES+i]==0) + { + edrk.temper_acdrive.winding.flag_init_filter_temp[i] = 0; + edrk.temper_acdrive.winding.filter_real_int_temper[i] = 0; + edrk.temper_acdrive.winding.real_int_temper[i] = 0; + edrk.temper_acdrive.winding.real_temper[i] = 0; + + continue; + } + + edrk.temper_acdrive.winding.real_int_temper[i] = edrk.temper_acdrive.winding.real_temper[i]*K_TEMPER_TO_SVU; + + iqtain = _IQ(edrk.temper_acdrive.winding.real_temper[i]/100.0); + iq_temp = _IQ(edrk.temper_acdrive.winding.filter_real_temper[i]/100.0); + + if (edrk.temper_acdrive.winding.flag_init_filter_temp[i]==0) + { + iq_temp = iqtain; + edrk.temper_acdrive.winding.flag_init_filter_temp[i]=1; + } + + // iq_temp_engine[i] = exp_regul_iq(koef_Temper_ENGINE_filter, iq_temp_engine[i], iqtain); + + iq_temp += _IQmpy( (iqtain-iq_temp), koef_Temper_ENGINE_filter); + edrk.temper_acdrive.winding.filter_real_temper[i] = _IQtoF(iq_temp)*100.0; + edrk.temper_acdrive.winding.filter_real_int_temper[i] = edrk.temper_acdrive.winding.filter_real_temper[i]*K_TEMPER_TO_SVU; + } + + edrk.temper_acdrive.winding.max_real_int_temper = calc_max_temper_acdrive_winding(); + + +// Bearing + for (i=0;i<edrk.temper_acdrive.bear.max_size;i++) + { + edrk.temper_acdrive.bear.real_temper[i] = Unites[BKSSD_CAN_DEVICE][INDEX_ACDRIVE_BEAR_CAN_UNITES+i]/10.0; + if (Unites[BKSSD_CAN_DEVICE][INDEX_ACDRIVE_BEAR_CAN_UNITES+i]==0) + { + edrk.temper_acdrive.bear.flag_init_filter_temp[i] = 0; + edrk.temper_acdrive.bear.filter_real_int_temper[i] = 0; + edrk.temper_acdrive.bear.real_int_temper[i] = 0; + edrk.temper_acdrive.bear.real_temper[i] = 0; + + continue; + + } + + edrk.temper_acdrive.bear.real_int_temper[i] = edrk.temper_acdrive.bear.real_temper[i]*K_TEMPER_TO_SVU; + + iqtain = _IQ(edrk.temper_acdrive.bear.real_temper[i]/100.0); + iq_temp = _IQ(edrk.temper_acdrive.bear.filter_real_temper[i]/100.0); + + if (edrk.temper_acdrive.bear.flag_init_filter_temp[i]==0) + { + iq_temp = iqtain; + edrk.temper_acdrive.bear.flag_init_filter_temp[i]=1; + } + + // iq_temp_engine[i] = exp_regul_iq(koef_Temper_ENGINE_filter, iq_temp_engine[i], iqtain); + + iq_temp += _IQmpy( (iqtain-iq_temp), koef_Temper_ENGINE_filter); + edrk.temper_acdrive.bear.filter_real_temper[i] = _IQtoF(iq_temp)*100.0; + edrk.temper_acdrive.bear.filter_real_int_temper[i] = edrk.temper_acdrive.bear.filter_real_temper[i]*K_TEMPER_TO_SVU; + + + + + } + + edrk.temper_acdrive.bear.max_real_int_temper = calc_max_temper_acdrive_bear(); + +////// +} + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + +void calc_temper_edrk(void) +{ + int i; + +//// + edrk.temper_edrk.adc_temper_u[0] = ADC_f[1][1]; + edrk.temper_edrk.adc_temper_u[1] = ADC_f[1][2]; + edrk.temper_edrk.adc_temper_u[2] = ADC_f[1][3]; + edrk.temper_edrk.adc_temper_u[3] = ADC_f[1][4]; + edrk.temper_edrk.adc_temper_u[4] = ADC_f[1][5]; + edrk.temper_edrk.adc_temper_u[5] = ADC_f[1][6]; + edrk.temper_edrk.adc_temper_u[6] = ADC_f[1][7]; + + edrk.temper_edrk.real_temper_u[0] = (_IQtoF(analog.T_U01)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[1] = (_IQtoF(analog.T_U02)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[2] = (_IQtoF(analog.T_U03)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[3] = (_IQtoF(analog.T_U04)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[4] = (_IQtoF(analog.T_U05)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[5] = (_IQtoF(analog.T_U06)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_u[6] = (_IQtoF(analog.T_U07)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + + + for (i=0;i<7;i++) + edrk.temper_edrk.real_int_temper_u[i] = edrk.temper_edrk.real_temper_u[i]*K_TEMPER_TO_SVU; + + edrk.temper_edrk.max_real_int_temper_u = calc_max_temper_edrk_u(); +///// + + edrk.temper_edrk.adc_temper_water[0] = ADC_f[1][8]; + edrk.temper_edrk.adc_temper_water[1] = ADC_f[1][9]; + + edrk.temper_edrk.real_temper_water[0] = (_IQtoF(analog.T_Water_internal)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_water[1] = (_IQtoF(analog.T_Water_external)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + + for (i=0;i<2;i++) + edrk.temper_edrk.real_int_temper_water[i] = edrk.temper_edrk.real_temper_water[i]*K_TEMPER_TO_SVU; + + edrk.temper_edrk.max_real_int_temper_water = calc_max_temper_edrk_water(); + +////// + edrk.temper_edrk.adc_temper_air[0] = ADC_f[1][10]; + edrk.temper_edrk.adc_temper_air[1] = ADC_f[1][11]; + edrk.temper_edrk.adc_temper_air[2] = ADC_f[1][12]; + edrk.temper_edrk.adc_temper_air[3] = ADC_f[1][13]; + + + edrk.temper_edrk.real_temper_air[0] = (_IQtoF(analog.T_Air_01)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_air[1] = (_IQtoF(analog.T_Air_02)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_air[2] = (_IQtoF(analog.T_Air_03)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + edrk.temper_edrk.real_temper_air[3] = (_IQtoF(analog.T_Air_04)*100.0 - 4.0)/16.0 * NORMA_ACP_TEMPER - DELTA_ACP_TEMPER; + + for (i=0;i<4;i++) + edrk.temper_edrk.real_int_temper_air[i] = edrk.temper_edrk.real_temper_air[i]*K_TEMPER_TO_SVU; + + edrk.temper_edrk.max_real_int_temper_air = calc_max_temper_edrk_air(); + edrk.temper_edrk.min_real_int_temper_air = calc_min_temper_edrk_air(); + + + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + + + diff --git a/Inu/Src/main/calc_tempers.h b/Inu/Src/main/calc_tempers.h new file mode 100644 index 0000000..d2b1bc9 --- /dev/null +++ b/Inu/Src/main/calc_tempers.h @@ -0,0 +1,16 @@ +/* + * calc_tempers.h + * + * Created on: 4 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_CALC_TEMPERS_H_ +#define SRC_MAIN_CALC_TEMPERS_H_ + +void calc_temper_acdrive(void); +void calc_temper_edrk(void); + + + +#endif /* SRC_MAIN_CALC_TEMPERS_H_ */ diff --git a/Inu/Src/main/can_bs2bs.c b/Inu/Src/main/can_bs2bs.c new file mode 100644 index 0000000..f383e47 --- /dev/null +++ b/Inu/Src/main/can_bs2bs.c @@ -0,0 +1,83 @@ +/* + * can_bs2bs.c + * + * Created on: 27 ���. 2020 �. + * Author: stud + */ + +#include <281xEvTimersInit.h> +#include <can_bs2bs.h> +#include <edrk_main.h> +#include <math.h> +#include <project.h> + +#include "control_station.h" +#include "CAN_Setup.h" +#include "global_time.h" +#include "IQmathLib.h" +#include "mathlib.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" +#include "xp_project.h" +#include "another_bs.h" + + + + + + +#pragma DATA_SECTION(Unites2SecondBS, ".slow_vars") +int Unites2SecondBS[SIZE_ARR_CAN_UNITES_BS2BS]={0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0\ + }; + + + +int max_count_send_to_can2second_bs = SIZE_ARR_CAN_UNITES_BS2BS; + + + + + +void SendAll2SecondBS(unsigned int pause) +{ + static int time_tick_modbus_can=0; + static unsigned int old_PWM_ticks=0; + static int count_write_to_modbus_can=0; + static int time_send_to_can=0; + int real_mbox, n_box; + + + + +//send to another BS + if (detect_pause_milisec(pause, &old_PWM_ticks)) + { + // if (edrk.flag_second_PCH==0) + // n_box = ANOTHER_BSU2_CAN_DEVICE; + // else + n_box = ANOTHER_BSU1_CAN_DEVICE; + + time_tick_modbus_can=0; + time_send_to_can=0; + + UpdateTableSecondBS(); + + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, n_box); + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + CAN_cycle_send( UNITS_TYPE_BOX, n_box, 0, &Unites2SecondBS[0], max_count_send_to_can2second_bs, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + } + + + +} + + + diff --git a/Inu/Src/main/can_bs2bs.h b/Inu/Src/main/can_bs2bs.h new file mode 100644 index 0000000..b3d69cf --- /dev/null +++ b/Inu/Src/main/can_bs2bs.h @@ -0,0 +1,21 @@ +/* + * can_bs2bs.h + * + * Created on: 27 ���. 2020 �. + * Author: stud + */ + +#ifndef SRC_MAIN_CAN_BS2BS_H_ +#define SRC_MAIN_CAN_BS2BS_H_ + +#define SIZE_ARR_CAN_UNITES_BS2BS 50 //100 + + +extern int Unites2SecondBS[SIZE_ARR_CAN_UNITES_BS2BS]; + +void SendAll2SecondBS(unsigned int pause); + + + + +#endif /* SRC_MAIN_CAN_BS2BS_H_ */ diff --git a/Inu/Src/main/can_protocol_ukss.h b/Inu/Src/main/can_protocol_ukss.h new file mode 100644 index 0000000..18bf157 --- /dev/null +++ b/Inu/Src/main/can_protocol_ukss.h @@ -0,0 +1,63 @@ +/* + * can_protocol_ukss.h + * + * Created on: 23 ���. 2024 �. + * Author: yura + */ + +#ifndef SRC_MAIN_CAN_PROTOCOL_UKSS_H_ +#define SRC_MAIN_CAN_PROTOCOL_UKSS_H_ + + + +#define CAN_PROTOCOL_UKSS 2 // 2 + + +#ifndef CAN_PROTOCOL_UKSS +#define CAN_PROTOCOL_UKSS 1 +#endif + + + + +#if (CAN_PROTOCOL_UKSS == 2) + + +#define ADR_CYCLES_TIMER_MAIN 96 //������ ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_TIMER_ADD 97 //������ ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_PAUSE_MAIN 98 //����� ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_PAUSE_ADD 99 //����� ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_REPEATE_MAIN 100 //������ ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_REPEATE_ADD 101 //������ ������. ������� CAN, * 10 m��� +#define ADR_CYCLES_REPEATE_DIGIO 102 //��������� ������� �����. ������, ��� + +#define ADR_LIGHT_LED_1 104 //������� ����� 1 +#define ADR_LIGHT_LED_2 105 //������� ����� 2 +#define ADR_LIGHT_LED_3 106 //������� ����� 3 +#define ADR_LIGHT_LED_4 107 //������� ����� 4 +#define ADR_LIGHT_LED_5 108 //������� ����� 5 +#define ADR_LIGHT_LED_6 109 //������� ����� 6 +#define ADR_LIGHT_LED_7 110 //������� ����� 7 + + + +#define ADR_COUNT_CYCLES_MAIN 120 //���������� ������ ������. ������� CAN +#define ADR_COUNT_CYCLES_ADD 121 //���������� ������ ������. ������� CAN +#define ADR_COUNT_FULL_CYCLES_MAIN 122 //���-�� ������ ������ ������. ������� CAN +#define ADR_COUNT_FULL_CYCLES_ADD 123 //���-�� ������ ������ ������. ������� CAN + +#define ADR_PROTOCOL_VERSION 125 //������ ��������� +#define ADR_UKSS_NUMBER 126 //����� ���������� + +#endif + + + + + + + + + + +#endif /* SRC_MAIN_CAN_PROTOCOL_UKSS_H_ */ diff --git a/Inu/Src/main/control_station_project.c b/Inu/Src/main/control_station_project.c new file mode 100644 index 0000000..877b4fb --- /dev/null +++ b/Inu/Src/main/control_station_project.c @@ -0,0 +1,2493 @@ +/* + * control_station_project.c + * + * Created on: 1 ���. 2020 �. + * Author: Yura + */ +#include <can_bs2bs.h> +#include <control_station_project.h> +#include <CAN_project.h> +#include <edrk_main.h> +#include <master_slave.h> +#include <math.h> + +#include <modbus_hmi_update.h> +#include <modbus_svu_update.h> +#include <params_alg.h> +#include <params_motor.h> +#include <params_norma.h> + +#include "control_station.h" +#include "CAN_Setup.h" +#include "global_time.h" +#include "IQmathLib.h" +#include "mathlib.h" +#include "modbus_table_v2.h" +#include "vector_control.h" +#include "RS_Functions.h" +#include "adc_tools.h" +#include "RS_Function_terminal.h" +#include "alg_simple_scalar.h" + + + + + + +/*CONTROL_STATION_TERMINAL_RS232 + CONTROL_STATION_TERMINAL_CAN, + + CONTROL_STATION_INGETEAM_PULT_RS485, + CONTROL_STATION_MPU_SVU_CAN, + CONTROL_STATION_MPU_KEY_CAN, + CONTROL_STATION_MPU_SVU_RS485, + CONTROL_STATION_MPU_KEY_RS485, + CONTROL_STATION_ZADATCHIK_CAN, + + + + CONTROL_STATION_CMD_GO = 0,// cmd_go �� ����� ����/���� ���� + CONTROL_STATION_CMD_SET_IZAD,// ��� �� ����� + CONTROL_STATION_CMD_SET_ROTOR,// ������� �� ����� + CONTROL_STATION_CMD_CHARGE,// ���� ����� �� ����� + CONTROL_STATION_CMD_UNCHARGE,// ������ ����� �� ����� + CONTROL_STATION_CMD_CHECKBACK,// ������������ �� ����� + CONTROL_STATION_CMD_TEST_LEDS + */ + + +#define DEC_ZAD_OBOROTS 1 +#define INC_ZAD_OBOROTS 1 + + + + + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void detect_active_from_all_signals(void) +{ + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + // control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station + } + + +} +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +float plus_minus_oborots(int key_plus, int key_minus, float ff, int ufconst_vector, int flag) +{ + static float ff_add=0, ff_dec=0; + + float ff_add1=0, ff_dec1=0; + float ff_add2=0, ff_dec2=0; + float ff_add3=0, ff_dec3=0; + + static int prev_key_plus=0, prev_key_minus=0, count_press2 = 0, level_d1 = 2; + + static int direct_zad=0, direct_cur=0, only_plus=0, only_minus=0; + static unsigned int old_time_plus_minus=0, count_press = 0; + + if (flag==1) + { + count_press = 0; + + ff_dec = 0; + ff_add = 0; + + prev_key_plus = key_plus; + prev_key_minus = key_minus; + + return ff; + } + + if (ff>0) + { +// if (key_minus || key_plus) + only_plus = 1; + only_minus = 0; + } + else + if (ff<0) + { +// if (key_minus || key_plus) + only_minus = 1; + only_plus = 0; + } + else + { + if (key_minus==0 && key_plus==0) + { + only_plus = 0; + only_minus = 0; + } + + } + + +// +// +// if (key_plus) +// { +// if (ff>0) +// direct_zad = 1; +// if (ff<0) +// direct_zad = -1; +// if (ff==0) +// direct_zad = 0; +// +// } +// if (key_minus) +// { +// if (ff>0) +// direct_zad = -1; +// if (ff<0) +// direct_zad = 1; +// if (ff==0) +// direct_zad = 0; +// } + + + if (ufconst_vector==0) + { + ff_add1 = INC_ZAD_OBOROTS*10.0; + ff_dec1 = DEC_ZAD_OBOROTS*10.0; + + ff_add2 = INC_ZAD_OBOROTS*30.0; + ff_dec2 = DEC_ZAD_OBOROTS*30.0; + ff_add3 = INC_ZAD_OBOROTS*60.0; + ff_dec3 = DEC_ZAD_OBOROTS*60.0; + + } + else + { + ff_add1 = INC_ZAD_OBOROTS; + ff_dec1 = DEC_ZAD_OBOROTS; + + ff_add2 = INC_ZAD_OBOROTS*1.0; + ff_dec2 = DEC_ZAD_OBOROTS*1.0; + ff_add3 = INC_ZAD_OBOROTS*2.0; + ff_dec3 = DEC_ZAD_OBOROTS*2.0; + } + + + if (detect_pause_milisec(250,&old_time_plus_minus)) + { + if (key_minus || key_plus) + { + if (count_press<300) + count_press++; + + if (count_press2<10) + count_press2++; + + } + else + { + count_press = 0; + count_press2 = 0; + } + + if (count_press==1) + { +// ff_dec = 0; +// ff_add = 0; + ff_dec = ff_dec1; + ff_add = ff_add1; + level_d1 = 4; + } + + if (count_press==6) + { + ff_dec = ff_dec1; + ff_add = ff_add1; + level_d1 = 2; + } + + if (count_press==15) + { + ff_dec = ff_dec1; + ff_add = ff_add1; + level_d1 = 0; + } +// if (count_press==60) +// { +// ff_dec = ff_dec2; +// ff_add = ff_add2; +// level_d1 = 0; +// } + + if (count_press==30) + { + ff_dec = ff_dec3; + ff_add = ff_add3; + } + + + if (key_minus) + { + if ((count_press2>=level_d1) || (count_press==1)) + { + if (ff>ff_dec) + { + ff=ff-ff_dec; + if (ff<DEAD_ZONE_ZADANIE_OBOROTS_ROTOR && ff>0) + ff = 0; + } + else + if (ff<=ff_dec && ff>0) + ff=0; + else + if (ff<0 && only_plus==0) + ff=ff-ff_add; + else + if (ff==0 && only_plus==0) + ff=ff-DEAD_ZONE_ZADANIE_OBOROTS_ROTOR; + + count_press2 = 0; + } + } + else + if (key_plus) + { + if ((count_press2>=level_d1) || (count_press==1)) + { + if (ff==0 && only_minus==0) + ff=ff+DEAD_ZONE_ZADANIE_OBOROTS_ROTOR; + else + if (ff>=0 && only_minus==0) + ff=ff+ff_add; + else + if (ff>=-ff_dec && ff<0) + ff=0; + else + if (ff<-ff_dec) + { + ff=ff+ff_dec; + if (ff>-DEAD_ZONE_ZADANIE_OBOROTS_ROTOR && ff<0) + ff = 0; + } + + count_press2 = 0; + } + } + + } + + if (ufconst_vector==0) + ff = my_satur_float(ff,fast_round(MAX_ZADANIE_F*100.0),fast_round(-MAX_ZADANIE_F*100.0), 0); + else + ff = my_satur_float(ff, MAX_ZADANIE_OBOROTS_ROTOR, MIN_ZADANIE_OBOROTS_ROTOR, 0); + + + prev_key_plus = key_plus; + prev_key_minus = key_minus; + + + return ff; +} + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_another_bs(int cc) +{ + int i;//, pos_numbercmd; + static int prev_checkback = 0; + static int flag_wait_revers_go = 0; + + _iq _iq_ff; + static unsigned int prev_charge=0, prev_uncharge=0, key_local_charge=0, key_local_uncharge=0; + static unsigned int old_time_pult_ing = 0; + float ff=0, ff_add=0, ff_dec=0; + int key_plus = 0, key_minus = 0; + + + + + if (edrk.ms.err_signals.alive_can_to_another_bs==0) + { + + // + // edrk.zadanie_from_another_bs.int_fzad = Unites[ANOTHER_BSU1_CAN_DEVICE][3]; + // edrk.zadanie_from_another_bs.int_kzad = Unites[ANOTHER_BSU1_CAN_DEVICE][4]; + // edrk.zadanie_from_another_bs.int_Izad = Unites[ANOTHER_BSU1_CAN_DEVICE][5]; + // edrk.zadanie_from_another_bs.int_oborots_zad = Unites[ANOTHER_BSU1_CAN_DEVICE][6]; + // edrk.zadanie_from_another_bs.int_power_zad = Unites[ANOTHER_BSU1_CAN_DEVICE][7]; + // // + // edrk.zadanie_from_another_bs.iq_fzad = _IQ15toIQ(edrk.zadanie_from_another_bs.int_fzad); + // edrk.zadanie_from_another_bs.iq_kzad = _IQ15toIQ(edrk.zadanie_from_another_bs.int_kzad); + // edrk.zadanie_from_another_bs.iq_Izad = _IQ15toIQ(edrk.zadanie_from_another_bs.int_Izad); + // edrk.zadanie_from_another_bs.oborots_zad = edrk.zadanie_from_another_bs.int_oborots_zad; + // edrk.zadanie_from_another_bs.iq_power_zad = _IQ15toIQ(edrk.zadanie_from_another_bs.int_power_zad); + + + } + else + { + + + + } + + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = 0; // clear all data + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + + + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = Unites[ANOTHER_BSU1_CAN_DEVICE][POS_STATION_CMD_ANOTHER_BSU1+i]; + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + + + + } + if (edrk.MasterSlave == MODE_SLAVE && Unites[ANOTHER_BSU1_CAN_DEVICE][12] > 0 && Unites[ANOTHER_BSU1_CAN_DEVICE][12] < 600) { + vect_control.iqId_min = _IQ((float)Unites[ANOTHER_BSU1_CAN_DEVICE][12] / NORMA_ACP); + } +/* + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_VPU_CAN]; + + +// scalar, vector, ufconst + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC]; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = 0; + +// ���������� +// if + + if ((detect_pause_milisec(100,&old_time_pult_ing)) && control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + +// control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.raw_array_data[cc][4].all; + ff = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]; + + key_plus = edrk.from_vpu.bits.PLUS; + key_minus = edrk.from_vpu.bits.MINUS; + + ff = plus_minus_oborots(key_plus, key_minus, ff, control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR]); + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = ff; + } + + +// �������� +// pos_numbercmd = 15; // � ������ �������� ������� ���� �������, ��� ����� ���������� ������ + + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = edrk.from_vpu.bits.KVITIR; + +// �����, ������ + key_local_charge = 0;//edrk.from_shema.bits.SBOR_SHEMA; + key_local_uncharge = 0;//edrk.from_shema.bits.RAZBOR_SHEMA; + + if (key_local_charge && prev_charge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge = key_local_charge; + + + if (key_local_uncharge && prev_uncharge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + prev_uncharge = key_local_uncharge; + + +/////////////////////////////////////////// +// ��� ����� � ���������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]; + + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 1; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO]; + +// +// control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = 0; +// +// prev_checkback = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + + // �������� �� rs232 + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + // ����� ������ ���������� ������� �� ������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MODE_PUMP]; + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; +*/ + +} +///////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_pult_vpu(int cc) +{ + int i;//, pos_numbercmd; + static int prev_checkback = 0, prev_key_oborots = 0; + static int flag_wait_revers_go = 0; + + _iq _iq_ff; + static unsigned int prev_charge=0, prev_uncharge=0, key_local_charge=0, key_local_uncharge=0; + static unsigned int old_time_pult_ing = 0, old_time_pult_ing2 = 0; + float ff=0, ff_add=0, ff_dec=0; + int key_plus = 0, key_minus = 0; + + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = 0; // clear all data + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_VPU_CAN]; + +/////////////////////////////////////////// +// ��� ����� � ���������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD;//control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER] = my_satur_int(control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER], + SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + + +// scalar, vector, ufconst + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC]; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = 0; + +// ���������� + + if ((detect_pause_milisec(100,&old_time_pult_ing)) && control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + ff = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]; + + key_plus = edrk.from_vpu.bits.PLUS; + key_minus = edrk.from_vpu.bits.MINUS; + +/////////////// + if (edrk.from_vpu.bits.PROVOROT) + { + if (detect_pause_milisec(1000,&old_time_pult_ing2)) + { + edrk.Provorot = 1; + ff = PROVOROT_OBOROTS; + } + } + else + old_time_pult_ing2 = global_time.miliseconds; + + if (edrk.from_vpu.bits.PROVOROT != prev_key_oborots && edrk.from_vpu.bits.PROVOROT == 0 && edrk.Provorot==1) + { + ff = 0; + edrk.Provorot = 0; + } + + prev_key_oborots = edrk.from_vpu.bits.PROVOROT; +///////////// + ff = plus_minus_oborots(key_plus, key_minus, ff, control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR], 0); + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = ff; + + // control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_SET_ROTOR] = ff; + // control_station.array_cmd[CONTROL_STATION_ZADATCHIK_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + } + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]>=0) + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = -control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + + + + + +// �������� +// pos_numbercmd = 15; // � ������ �������� ������� ���� �������, ��� ����� ���������� ������ + + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = edrk.from_vpu.bits.KVITIR; + +// �����, ������ + key_local_charge = 0;//edrk.from_shema.bits.SBOR_SHEMA; + key_local_uncharge = 0;//edrk.from_shema.bits.RAZBOR_SHEMA; + + if (key_local_charge && prev_charge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge = key_local_charge; + + + if (key_local_uncharge) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + prev_uncharge = key_local_uncharge; + + + + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 1; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; +// +// control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = 0; +// +// prev_checkback = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + + + // �������� �� rs232 + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_STOP_LOGS] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_STOP_LOGS]; + + } + else + if (control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + + edrk.Status_Ready.bits.ImitationReady2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][181].all; + edrk.Obmotka1 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][194].all; + edrk.Obmotka2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][195].all; + edrk.disable_alg_u_disbalance = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][193].all; + + + edrk.Run_Rascepitel_from_RS = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][182].all; + edrk.stop_logs_rs232 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][183].all; + edrk.stop_slow_log = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][184].all; + edrk.disable_limit_power_from_svu = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][185].all; + edrk.disable_uom = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][186].all; + + + + + } + + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + // ����� ������ ���������� ������� �� ������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MODE_PUMP]; + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; + + +} +///////////////////////////////////////////////////////////// + + + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_pult_zadat4ik(int cc) +{ + int i;//, pos_numbercmd; + static int prev_checkback = 0, prev_key_oborots = 0; + static int flag_wait_revers_go = 0; + + float ff=0, ff_add=0, ff_dec=0; + int key_plus = 0, key_minus = 0; + + _iq _iq_ff; + static unsigned int prev_charge=0, prev_uncharge=0, key_local_charge=0, key_local_uncharge=0; + static unsigned int old_time_pult_ing = 0, old_time_pult_ing2 = 0; + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = 0; // clear all data + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN]; +/////////////////////////////////////////// +// ��� ����� � ���������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD;//control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER] = my_satur_int(control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER], + SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + + + +// scalar, vector, ufconst + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = 0; + +// ���������� +// if + + if ((detect_pause_milisec(100,&old_time_pult_ing)) && control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + +// control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.raw_array_data[cc][4].all; + ff = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]; + + key_plus = edrk.from_zadat4ik.bits.PLUS; + key_minus =edrk.from_zadat4ik.bits.MINUS; + + if (edrk.from_zadat4ik.bits.PROVOROT) + { + if (detect_pause_milisec(1000,&old_time_pult_ing2)) + { + edrk.Provorot = 1; + ff = PROVOROT_OBOROTS; + } + } + else + old_time_pult_ing2 = global_time.miliseconds; + + if (edrk.from_zadat4ik.bits.PROVOROT != prev_key_oborots && edrk.from_zadat4ik.bits.PROVOROT == 0 && edrk.Provorot==1) + { + ff = 0; + edrk.Provorot = 0; + } + + prev_key_oborots = edrk.from_zadat4ik.bits.PROVOROT; + + ff = plus_minus_oborots(key_plus, key_minus, ff, control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR], 0); + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = ff; + + // control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_SET_ROTOR] = ff; + // control_station.array_cmd[CONTROL_STATION_VPU_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + + } + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]>=0) + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = -control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + +// �������� +// pos_numbercmd = 15; // � ������ �������� ������� ���� �������, ��� ����� ���������� ������ + + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = edrk.from_zadat4ik.bits.KVITIR; + +// �����, ������ + key_local_charge = edrk.from_shema_filter.bits.SBOR_SHEMA; + key_local_uncharge = edrk.from_shema_filter.bits.RAZBOR_SHEMA; + + + if (key_local_uncharge && key_local_charge) + { + key_local_uncharge = 0; + key_local_charge = 0; + //edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE |=1; + } + + if (key_local_charge && prev_charge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge = key_local_charge; + + + if (key_local_uncharge) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + prev_uncharge = key_local_uncharge; + + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 1; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; + +// +// control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = 0; +// +// prev_checkback = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + + + // �������� �� rs232 + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + } + else + if (control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + + edrk.Status_Ready.bits.ImitationReady2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][181].all; + edrk.Obmotka1 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][194].all; + edrk.Obmotka2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][195].all; + edrk.disable_alg_u_disbalance = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][193].all; + + edrk.Run_Rascepitel_from_RS = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][182].all; + edrk.stop_logs_rs232 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][183].all; + edrk.stop_slow_log = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][184].all; + edrk.disable_limit_power_from_svu = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][185].all; + edrk.disable_uom = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][186].all; + + } + + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + // ����� ������ ���������� ������� �� ������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MODE_PUMP]; + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; + + +} +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_pult_ingeteam(int cc) +{ + int i, zad_power; //pos_numbercmd + static int prev_checkback = 0; + static int flag_wait_revers_go = 0; + float ff=0, ff_add=0, ff_dec=0; + int key_plus = 0, key_minus = 0; + _iq _iq_ff=0; + static unsigned int prev_key_local_charge_key=0, prev_key_local_uncharge_key=0, + key_local_charge_key=0, key_local_uncharge_key=0; + static unsigned int prev_key_local_charge_display=0, prev_key_local_uncharge_display=0, + key_local_charge_display=0, key_local_uncharge_display=0; + + static unsigned int prev_charge=0, prev_uncharge=0, key_local_charge=0, key_local_uncharge=0; + + static unsigned int old_time_pult_ing = 0, old_time_pult_ing2 = 0; + static unsigned int prev_key_local_charge_uncharge_display=0, key_local_charge_uncharge_display=0; + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = 0; // clear all data + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + + + // control_station.raw_array_data[CONTROL_STATION_TERMINAL_RS232] + + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]; + + + /////////////////////////////////////////// + // ��� ����� � ���������� + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD;//control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER] = my_satur_int(control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER], + SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + +// vector, ufconst + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC]; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = control_station.raw_array_data[cc][3].all; + +// ���������� + + // if + + if ((detect_pause_milisec(100,&old_time_pult_ing)) && control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER]==1) + { + zad_power = (int)control_station.raw_array_data[cc][4].all; + if (zad_power<0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = zad_power; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = -MAX_ZADANIE_OBOROTS_ROTOR; + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.raw_array_data[cc][4].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = MAX_ZADANIE_OBOROTS_ROTOR; + } + } + else + { + + + ff = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]; + + key_plus = edrk.from_ing2.bits.KEY_PLUS; + key_minus = edrk.from_ing2.bits.KEY_MINUS; + + if (key_plus || key_minus) + { + ff = plus_minus_oborots(key_plus, key_minus, ff, control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR], 0); + old_time_pult_ing2 = global_time.miliseconds; + // �������� ��� ������� �� ���������� �������� ������ � ������� + control_station.flag_refresh_array[cc] = 2; // ���-�� ��������� ���������� ������� �� �������� + } + else + { + plus_minus_oborots(0, 0, ff, control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR], 1);//������ + + if (detect_pause_milisec(3000,&old_time_pult_ing2)) + if (control_station.flag_refresh_array[cc] == 0) + ff = (int)(control_station.raw_array_data[cc][5].all); + } + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = ff; + +// control_station.array_cmd[CONTROL_STATION_ZADATCHIK_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + // control_station.array_cmd[CONTROL_STATION_VPU_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]>=0) + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = -control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + + } + + + + } + + +// �������� +// pos_numbercmd = 15; // � ������ �������� ������� ���� �������, ��� ����� ���������� ������ + + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = control_station.raw_array_data[cc][1].all; + + +// �����, ������ �� ������ + key_local_charge_key = edrk.from_ing2.bits.KEY_SBOR; + key_local_uncharge_key = edrk.from_ing2.bits.KEY_RAZBOR; + + + +// �����, ������ �� ������� + key_local_charge_uncharge_display = control_station.raw_array_data[cc][2].all; + + + prev_key_local_charge_key = key_local_charge_key; + prev_key_local_uncharge_key = key_local_uncharge_key; + + + if (prev_key_local_charge_uncharge_display != key_local_charge_uncharge_display) + { + if (key_local_charge_uncharge_display==1) + { + key_local_charge_display = 1; + key_local_uncharge_display = 0; + } + else + { + key_local_charge_display = 0; + key_local_uncharge_display =1; + } + } + else + { + key_local_charge_display = 0; + key_local_uncharge_display = 0; + } + + prev_key_local_charge_uncharge_display = key_local_charge_uncharge_display; + + + prev_key_local_charge_display = key_local_charge_display; + prev_key_local_uncharge_display = key_local_uncharge_display; + + key_local_charge = key_local_charge_key || key_local_charge_display; + key_local_uncharge = key_local_uncharge_key || key_local_uncharge_display; + + if (key_local_uncharge_key && key_local_charge_key) + { + key_local_uncharge_key = 0; + key_local_charge_key = 0; +// edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE |=1; + } + + + + if (edrk.Status_Ready.bits.ImitationReady2==0) // �������� ���� � ������, �.�. �� ����� ��� �������� + { + if (key_local_charge && prev_charge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + + + + if (key_local_uncharge) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + + prev_charge = key_local_charge; + prev_uncharge = key_local_uncharge; + + + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 1; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; +// + +// +// control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = 0; +// +// prev_checkback = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + + + // �������� �� rs232 + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP] + || control_station.raw_array_data[cc][188].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] + || control_station.raw_array_data[cc][191].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV] + || control_station.raw_array_data[cc][189].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_UMP] + || control_station.raw_array_data[cc][190].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_MANUAL_DISCHARGE] + || control_station.raw_array_data[cc][180].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO] + || !control_station.raw_array_data[cc][192].all; + } + else + { + + edrk.Status_Ready.bits.ImitationReady2 = control_station.raw_array_data[cc][181].all; + edrk.Run_Rascepitel_from_RS = control_station.raw_array_data[cc][182].all; + edrk.stop_logs_rs232 = control_station.raw_array_data[cc][183].all; + edrk.stop_slow_log = control_station.raw_array_data[cc][184].all; + edrk.disable_limit_power_from_svu = control_station.raw_array_data[cc][185].all; + edrk.disable_uom = control_station.raw_array_data[cc][186].all; + + + + edrk.Obmotka1 = control_station.raw_array_data[cc][194].all; + edrk.Obmotka2 = control_station.raw_array_data[cc][195].all; + edrk.disable_alg_u_disbalance = control_station.raw_array_data[cc][193].all; + + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.raw_array_data[cc][188].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.raw_array_data[cc][189].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.raw_array_data[cc][190].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.raw_array_data[cc][191].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.raw_array_data[cc][180].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = !control_station.raw_array_data[cc][192].all; + + } + + + + //control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.raw_array_data[cc][188].all; +// control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.raw_array_data[cc][189].all; + //control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.raw_array_data[cc][190].all; + //control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.raw_array_data[cc][191].all; +// control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.raw_array_data[cc][180].all; +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = !control_station.raw_array_data[cc][192].all; + + + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + if (control_station.raw_array_data[cc][9].all<=2) //��� �����_����(0)_������(1) + { + if (control_station.raw_array_data[cc][9].all==0) // ���� ����� ������(0) 1_2(1) + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 0; + if (control_station.raw_array_data[cc][9].all==1) //������ ����� ������_1 + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 1; + if (control_station.raw_array_data[cc][9].all==2) //������ ����� ������_2 + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 2; + } + else + { + if (control_station.raw_array_data[cc][9].all==3) //������ ����� ������_1_2 + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 3; + if (control_station.raw_array_data[cc][9].all==4) //������ ����� ������_1_2 + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 4; + } + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; + +} +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_MPU_SVU(int cc) +{ + int i, zad_power, limit_power; + _iq _iq_ff; + + static unsigned int old_time_MPU_SVU = 0; + + static int prev_checkback_3 = 0; + static int flag_wait_revers_go_3 = 0; + static unsigned int prev_charge_3 = 0, prev_uncharge_3 = 0, cmd_local_charge_3 = 0, cmd_local_uncharge_3 = 0; + static unsigned int old_time_MPU_SVU_3 = 0; + + static int prev_checkback_4 = 0; + static int flag_wait_revers_go_4 = 0; + static unsigned int prev_charge_4 = 0, prev_uncharge_4 = 0, cmd_local_charge_4 = 0, cmd_local_uncharge_4 = 0; + static unsigned int old_time_MPU_SVU_4 = 0; + + + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[cc][i] = 0; // clear all data + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + + + // control_station.raw_array_data[CONTROL_STATION_TERMINAL_RS232] + + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + + +// control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN]; +// control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.active_control_station[cc]; + + + /////////////////////////////////////////// + // ��� ����� � ���������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD;//control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]; + + + if (edrk.disable_limit_power_from_svu) + limit_power = my_satur_int(control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER], + SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + else + limit_power = control_station.raw_array_data[cc][12].all; // ����� �������� + + if (limit_power==0) + limit_power = MIN_ZADANIE_LIMIT_POWER; + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER] = limit_power; //my_satur_int(control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER], + // MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, DEAD_ZONE_ZADANIE_LIMIT_POWER); + +// //control_station.raw_array_data[cc][12].all; // ����� �������� +// vector, ufconst + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC]; + + + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = control_station.raw_array_data[cc][1].all; + +// ���������� + + // if + + if (cc==CONTROL_STATION_MPU_SVU_CAN) + old_time_MPU_SVU = old_time_MPU_SVU_3; + if (cc==CONTROL_STATION_MPU_KEY_CAN) + old_time_MPU_SVU = old_time_MPU_SVU_4; + + if ((detect_pause_milisec(100, &old_time_MPU_SVU)) + && control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] == 1) + { + zad_power = (int)control_station.raw_array_data[cc][3].all; + if (zad_power<0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = zad_power; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = -MAX_ZADANIE_OBOROTS_ROTOR; + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = zad_power; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = MAX_ZADANIE_OBOROTS_ROTOR; + } + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = (int)control_station.raw_array_data[cc][2].all; + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]>=0) + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = -control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + + } + } + //������������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = control_station.raw_array_data[cc][0].all; + + + if (cc==CONTROL_STATION_MPU_SVU_CAN) + { + // �����, ������ + if (edrk.flag_second_PCH == 0) { + cmd_local_charge_3 = control_station.raw_array_data[cc][6].all; + cmd_local_uncharge_3 = control_station.raw_array_data[cc][9].all; + } else { + cmd_local_charge_3 = control_station.raw_array_data[cc][7].all;//modbus_table_can_in[129].all; //control_station.raw_array_data[cc][7].all; + cmd_local_uncharge_3 = control_station.raw_array_data[cc][10].all; + } + + + if (cmd_local_charge_3 && cmd_local_uncharge_3) + { + cmd_local_charge_3 = 0; + cmd_local_uncharge_3 = 0; + // edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE |=1; + } + + + + if (cmd_local_charge_3 && prev_charge_3==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge_3 = cmd_local_charge_3; + + + if (cmd_local_uncharge_3) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + + prev_uncharge_3 = cmd_local_uncharge_3; + } + + if (cc==CONTROL_STATION_MPU_KEY_CAN) + { + // �����, ������ + if (edrk.flag_second_PCH == 0) { + cmd_local_charge_4 = control_station.raw_array_data[cc][6].all; + cmd_local_uncharge_4 = control_station.raw_array_data[cc][9].all; + } else { + cmd_local_charge_4 = control_station.raw_array_data[cc][7].all;//modbus_table_can_in[129].all; //control_station.raw_array_data[cc][7].all; + cmd_local_uncharge_4 = control_station.raw_array_data[cc][10].all; + } + + + if (cmd_local_charge_4 && cmd_local_uncharge_4) + { + cmd_local_charge_4 = 0; + cmd_local_uncharge_4 = 0; + // edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE |=1; + } + + + + if (cmd_local_charge_4 && prev_charge_4==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge_4 = cmd_local_charge_4; + + + if (cmd_local_uncharge_4) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + + prev_uncharge_4 = cmd_local_uncharge_4; + } + + control_station.array_cmd[cc][CONTROL_STATION_CMD_BLOCK_BS] = control_station.raw_array_data[cc][4].all; + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 1; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; +// +// +// control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = 0; +// +// prev_checkback = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + + + // �������� �� rs232 + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + } + else + if (control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_GO]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_PUMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_ENABLE_ON_CHARGE]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_QTV]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_UMP]; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MANUAL_DISCHARGE]; + + edrk.Status_Ready.bits.ImitationReady2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][181].all; + edrk.Obmotka1 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][194].all; + edrk.Obmotka2 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][195].all; + edrk.disable_alg_u_disbalance = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][193].all; + + edrk.Run_Rascepitel_from_RS = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][182].all; + edrk.stop_logs_rs232 = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][183].all; + edrk.stop_slow_log = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][184].all; + edrk.disable_limit_power_from_svu = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][185].all; + edrk.disable_uom = control_station.raw_array_data[CONTROL_STATION_INGETEAM_PULT_RS485][186].all; + + + } + + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + //��������� ������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MODE_PUMP]; + + + edrk.breaker_on = control_station.raw_array_data[cc][17].all; + + edrk.break_tempers[0] = control_station.raw_array_data[cc][18].all; + edrk.break_tempers[1] = control_station.raw_array_data[cc][19].all; + edrk.break_tempers[2] = control_station.raw_array_data[cc][20].all; + edrk.break_tempers[3] = control_station.raw_array_data[cc][21].all; + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; + +} +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_one_control_station_terminal_rs232(int cc) +{ + static int pos_numbercmd = (sizeof(CMD_ANALOG_DATA_STRUCT) >> 1); + int i, fint; + static int prev_checkback = 0, lock_ImitationReady2 = 0; + static int flag_wait_revers_go = 0; + static unsigned int prev_charge=0, prev_uncharge=0, key_local_charge=0, key_local_uncharge=0; + float ff; + _iq _iq_ff; + int zad_power=0; + + if (control_station.alive_control_station[cc]) + { + + } + else + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + { + // control_station.array_cmd[cc][i] = 0; // clear all data + // �� ��������, �.�. ���� ����� ���� �� ���������� �� + } + + return; // ��� ����� ������� ��� ����������� ������� + // � "�� �����������" ������ �� ���������. + } + + + + // control_station.raw_array_data[CONTROL_STATION_TERMINAL_RS232] + + + edrk.test_mode = 0; +// f.RScount = SECOND * 3; + +// pos_numbercmd = sizeof(CMD_ANALOG_DATA_STRUCT);//15; // � ������ �������� ������� ���� �������, ��� ����� ���������� ������ + control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit0; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UFCONST_VECTOR] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit2; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit3; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SCALAR_FOC] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit4; + + + //control_station.raw_array_data[cc][pos_numbercmd].bits.bit4 = Go + + //control_station.raw_array_data[cc][pos_numbercmd].bits.bit5 + +// control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit6; + // control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit7; + + // �����, ������ + key_local_charge = control_station.raw_array_data[cc][pos_numbercmd].bits.bit6;; + key_local_uncharge = control_station.raw_array_data[cc][pos_numbercmd].bits.bit7; + + if (key_local_uncharge && key_local_charge) + { + key_local_charge = 0; + key_local_uncharge = 0; +// edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE |=1; + } + + if (key_local_charge && prev_charge==0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + prev_charge = key_local_charge; + + + if (key_local_uncharge) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 1; + control_station.array_cmd[cc][CONTROL_STATION_CMD_CHARGE] = 0; + } + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_UNCHARGE] = 0; + prev_uncharge = key_local_uncharge; + + + + + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit8==0) // ��� �����_����(0)_������(1) + { + + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit9==0) // ���� ����� + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 0; + else + // ������ ����� ��� ���� ��������� + { + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit10==0) //������ ����� ������_1_2 ������������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 1; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 2; + } + } + else // ������ ��������� + { + + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit9==0) // ���� ����� + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 6; + } + else + // ������ ����� ��� ������� ��������� + { + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit10==0) //������ ����� ������_1_2 ������ ��������� + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 3; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_MODE_PUMP] = 4; + } + } + + control_station.array_cmd[cc][CONTROL_STATION_CMD_TEST_LEDS] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit11; + + //control_station.raw_array_data[cc][pos_numbercmd].bits.bit12 + + if (edrk.Stop) + { + if (control_station.raw_array_data[cc][pos_numbercmd].bits.bit13) + lock_ImitationReady2 = 1; + edrk.Status_Ready.bits.ImitationReady2 = 0; + } + + if (lock_ImitationReady2) + edrk.Status_Ready.bits.ImitationReady2 = 0; + + if (edrk.Stop == 0 && lock_ImitationReady2 && control_station.raw_array_data[cc][pos_numbercmd].bits.bit13 == 0) + lock_ImitationReady2 = 0; + + if (edrk.Stop == 0 && lock_ImitationReady2 == 0) + edrk.Status_Ready.bits.ImitationReady2 = control_station.raw_array_data[cc][pos_numbercmd].bits.bit13; + + + edrk.Run_Rascepitel_from_RS = control_station.raw_array_data[cc][pos_numbercmd].bits.bit14; + edrk.Obmotka1 = control_station.raw_array_data[cc][pos_numbercmd].bits.bit15; + + edrk.Obmotka2 = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit0; + edrk.disable_alg_u_disbalance = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit1; + +// control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit2; +// control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit3; +// control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit4; + + control_station.array_cmd[cc][CONTROL_STATION_CMD_WDOG_OFF] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit2; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_UMP] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit3; + control_station.array_cmd[cc][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit4; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit5; + control_station.array_cmd[cc][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit6; + control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_ON_QTV] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit7; + + + + + +// control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_INTERRUPT_SYNC] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit8; +// control_station.array_cmd[cc][CONTROL_STATION_CMD_DISABLE_INTERRUPT_TIMER2] = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit9; + + // edrk.disable_break_work = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit8; + edrk.disable_rascepitel_work = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit10; + edrk.enable_pwm_test_lines = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit11; + + edrk.stop_logs_rs232 = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit12; + edrk.stop_slow_log = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit13; + + edrk.disable_limit_power_from_svu = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit14; + edrk.disable_uom = control_station.raw_array_data[cc][pos_numbercmd+1].bits.bit15; + + + edrk.imit_limit_freq = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit0; + edrk.imit_limit_uom = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit1; + edrk.set_limit_uom_50 = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit2; + + + edrk.imit_save_slow_logs = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit3; + edrk.imit_send_alarm_log_pult = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit4; + +// edrk.cmd_clear_can_error = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit5; + + edrk.cmd_imit_low_isolation = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit5; + edrk.cmd_very_slow_start = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit6; + + simple_scalar1.disable_KoefOgranIzad = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit7; + + + edrk.cmd_disable_calc_km_on_slave = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit8; + simple_scalar1.cmd_new_calc_p_limit = control_station.raw_array_data[cc][pos_numbercmd+2].bits.bit9; + + + +// analog + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER] = my_satur_int(control_station.raw_array_data[cc][7].all, + SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER]==1) + { + zad_power = my_satur_int(control_station.raw_array_data[cc][2].all, MAX_ZADANIE_POWER, MIN_ZADANIE_POWER, DEAD_ZONE_ZADANIE_POWER); + if (zad_power<0) + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = zad_power; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = -MAX_ZADANIE_OBOROTS_ROTOR; + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = zad_power; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = MAX_ZADANIE_OBOROTS_ROTOR; + } + } + else + { + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = (int)control_station.raw_array_data[cc][0].all; + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]>=0) + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + else + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = -control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_LIMIT_POWER]; + } + + //control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR] = (int)control_station.raw_array_data[cc][0].all; + //control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER] = my_satur_int(control_station.raw_array_data[cc][2].all, MAX_ZADANIE_POWER, MIN_ZADANIE_POWER); + + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_KM] = control_station.raw_array_data[cc][1].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_IZAD] = my_satur_int(control_station.raw_array_data[cc][3].all, MAX_ZADANIE_I_M, 0, 0); + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_U_ZARYAD] = control_station.raw_array_data[cc][4].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = control_station.raw_array_data[cc][5].all; + control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = control_station.raw_array_data[cc][6].all; + + + + if (control_station.raw_array_data[cc][8].all > 0 && control_station.raw_array_data[cc][8].all <= 600 && edrk.MasterSlave == MODE_MASTER) { + vect_control.iqId_min = _IQ((float)control_station.raw_array_data[cc][8].all / NORMA_ACP); + } + + fint = (int)control_station.raw_array_data[cc][9].all; + if (fint>=-360 && fint<=360 && edrk.MasterSlave == MODE_MASTER) + { + vect_control.add_tetta = _IQ(fint / 180.0 * PI); + } + else + vect_control.add_tetta = 0; + + fint = (int)control_station.raw_array_data[cc][10].all; + if (fint>=0) + { + edrk.t_slow_log = fint; + } + else + edrk.t_slow_log = 0; + + fint = (int)control_station.raw_array_data[cc][11].all; + if (fint) + { + simple_scalar1.add_bpsi = _IQ(fint/1000.0/NORMA_FROTOR);//_IQ(0.05/NORMA_FROTOR); + } + else + simple_scalar1.add_bpsi = 0; + + fint = (int)control_station.raw_array_data[cc][12].all; + if (fint) + { + simple_scalar1.add_power_limit = _IQ(fint*1000.0/(NORMA_MZZ*NORMA_MZZ));//_IQ(0.05/NORMA_FROTOR); + } + else + simple_scalar1.add_power_limit = 0; + + + fint = (int)control_station.raw_array_data[cc][13].all; + if (fint) + { + simple_scalar1.sdvig_power_limit = _IQ(fint*1000.0/(NORMA_MZZ*NORMA_MZZ));//_IQ(0.05/NORMA_FROTOR); + } + else + simple_scalar1.sdvig_power_limit = 0; + + +//#if (_FLOOR6) + fint = (int)control_station.raw_array_data[cc][14].all; + if (fint>=0 && fint<=3200) + { + analog.iqU_1_imit = _IQ(fint/NORMA_ACP); + } + else + analog.iqU_1_imit = 0; +//#else +// analog.iqU_1_imit = 0; +//#endif + + prev_checkback = control_station.array_cmd[cc][CONTROL_STATION_CMD_CHECKBACK];//control_station.raw_array_data[cc][pos_numbercmd].bits.bit1; + // edrk.KvitirRS = 1; + + control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit5; + +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ROTOR_POWER]==0) +// { +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit5; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; +// } +// else +// { +// if (control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_POWER]!=0) +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = control_station.raw_array_data[cc][pos_numbercmd].bits.bit5; +// else +// control_station.array_cmd[cc][CONTROL_STATION_CMD_GO] = 0; +// } + + +/* + edrk.from_rs.bits.ACTIVE = control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]; + + + if (edrk.from_rs.bits.ACTIVE==0) + return; + + edrk.from_can.bits.ACTIVE = 0; + +*/ + + + + if (control_station.array_cmd[cc][CONTROL_STATION_CMD_ACTIVE_CONTROL]==0) + return; + + // �� � ������� CAN ������ � �������� ���������� � RS232 + if (control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ACTIVE_CONTROL] && cc==CONTROL_STATION_TERMINAL_CAN) + return; + + + + + +// edrk.DirectOUT = control_station.raw_array_data[cc][pos_numbercmd].bits.bit7; + +// edrk.DirectNagrevOff = control_station.raw_array_data[cc][pos_numbercmd].bits.bit8; +// edrk.DirectBlockKeyOff = control_station.raw_array_data[cc][pos_numbercmd].bits.bit9; +//// edrk.DirectPumpON = control_station.raw_array_data[cc][pos_numbercmd].bits.bit10; +// edrk.DirectZaryadOn = control_station.raw_array_data[cc][pos_numbercmd].bits.bit11; + + +// edrk.SetSpeed = control_station.raw_array_data[cc][pos_numbercmd].bits.bit14; + + + + + + //////////////////////////// + ///////////////////////// + + +} + +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +void parse_data_from_master_to_alg(void) +{ + + if (edrk.MasterSlave==MODE_SLAVE) + { + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR] = control_station.array_cmd[CONTROL_STATION_ANOTHER_BS][CONTROL_STATION_CMD_SET_ROTOR]; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_KM] = control_station.array_cmd[CONTROL_STATION_ANOTHER_BS][CONTROL_STATION_CMD_SET_KM]; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_IZAD] = control_station.array_cmd[CONTROL_STATION_ANOTHER_BS][CONTROL_STATION_CMD_SET_IZAD]; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER] = control_station.array_cmd[CONTROL_STATION_ANOTHER_BS][CONTROL_STATION_CMD_SET_POWER]; + } + +} +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// + +void parse_analog_data_from_active_control_station_to_alg(void) +{ + float ff, ff1; + _iq _iq_ff; + int i; + +// edrk.disable_interrupt_sync = control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_INTERRUPT_SYNC]; +// edrk.disable_interrupt_timer2 = control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_INTERRUPT_TIMER2]; + + edrk.NoDetectUZeroDischarge = control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_QTV]; + + // if (current_active_control==CONTROL_STATION_TERMINAL_RS232) + edrk.StartGEDfromControl = control_station.active_array_cmd[CONTROL_STATION_CMD_GO]; + + + +////////////////// + if (control_station.active_array_cmd[CONTROL_STATION_CMD_UFCONST_VECTOR]==0) + edrk.Mode_ScalarVectorUFConst = ALG_MODE_UF_CONST; + else + if (control_station.active_array_cmd[CONTROL_STATION_CMD_SCALAR_FOC]==0) + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ROTOR_POWER]==0) + edrk.Mode_ScalarVectorUFConst = ALG_MODE_SCALAR_OBOROTS; + else + edrk.Mode_ScalarVectorUFConst = ALG_MODE_SCALAR_POWER; + } + else + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ROTOR_POWER]==0) + edrk.Mode_ScalarVectorUFConst = ALG_MODE_FOC_OBOROTS; + else + edrk.Mode_ScalarVectorUFConst = ALG_MODE_FOC_POWER; + } + + + ////////////////////////////////////////////////////// +// edrk.W_from_RS = control_station.array_cmd[cc][CONTROL_STATION_CMD_SET_ROTOR]; //DataAnalog1; +// ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_I_VOZBUD];//0;//DataAnalog4; +// edrk.I_zad_vozb_add_from_RS = my_satur_float(ff,MAX_ZADANIE_I_VOZBUD,0); + + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_U_ZARYAD]; + + edrk.zadanie.ZadanieU_Charge = my_satur_float(ff,MAX_ZADANIE_U_CHARGE,0,0); + edrk.zadanie.iq_ZadanieU_Charge = _IQ(edrk.zadanie.ZadanieU_Charge/NORMA_ACP); + + + if (edrk.Status_Ready.bits.ready_final==0) + { + // ���� ����� �� �������, �������� ������� �� ���� ������ + for (i=0;i<CONTROL_STATION_LAST;i++) + { + control_station.array_cmd[i][CONTROL_STATION_CMD_SET_ROTOR] = 0; +// control_station.array_cmd[i][CONTROL_STATION_CMD_SET_KM] = 0; + // control_station.array_cmd[i][CONTROL_STATION_CMD_SET_IZAD] = 0; + control_station.array_cmd[i][CONTROL_STATION_CMD_SET_POWER] = 0; + } + + + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR] = 0; + // control_station.active_array_cmd[CONTROL_STATION_CMD_SET_KM] = 0; + // control_station.active_array_cmd[CONTROL_STATION_CMD_SET_IZAD] = 0; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER] = 0; + } + + + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_UF_CONST) + { + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR]/100.0; + ff = my_satur_float(ff,MAX_ZADANIE_F,MIN_ZADANIE_F,0); + edrk.zadanie.fzad = ff; // ��. + edrk.zadanie.iq_fzad = _IQ(edrk.zadanie.fzad/NORMA_FROTOR); + } + else + { + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR]; + ff = my_satur_float(ff,MAX_ZADANIE_OBOROTS_ROTOR,MIN_ZADANIE_OBOROTS_ROTOR, 0); + edrk.zadanie.oborots_zad_no_dead_zone = ff; + ff = my_satur_float(ff,MAX_ZADANIE_OBOROTS_ROTOR,MIN_ZADANIE_OBOROTS_ROTOR, DEAD_ZONE_ZADANIE_OBOROTS_ROTOR); + edrk.zadanie.oborots_zad = ff;// ��/��� + edrk.zadanie.oborots_zad_hz = ff/60.0;// �� �������� � ��. + edrk.zadanie.iq_oborots_zad_hz = _IQ(edrk.zadanie.oborots_zad_hz/NORMA_FROTOR); + } + + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_KM]/10000.0; + edrk.zadanie.kzad = my_satur_float(ff,K_STATOR_MAX,0,0); + edrk.zadanie.iq_kzad = _IQ(edrk.zadanie.kzad); + + ff = (control_station.active_array_cmd[CONTROL_STATION_CMD_SET_K_U_DISBALANCE]/100.0); + edrk.zadanie.k_u_disbalance = my_satur_float(ff,MAX_ZADANIE_K_U_DISBALANCE,0.0,0); + edrk.zadanie.iq_k_u_disbalance = _IQ(edrk.zadanie.k_u_disbalance); + + + ff = (control_station.active_array_cmd[CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE]/1000.0); + edrk.zadanie.kplus_u_disbalance = my_satur_float(ff,1.0,0.0,0); + edrk.zadanie.iq_kplus_u_disbalance = _IQ(edrk.zadanie.kplus_u_disbalance); + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_IZAD]; + edrk.zadanie.Izad = my_satur_float(ff,MAX_ZADANIE_I_M,0,0); + edrk.zadanie.iq_Izad = _IQ(edrk.zadanie.Izad/NORMA_MZZ); + + if (edrk.from_uom.level_value == 0) + { + ff1 = SUPER_MAX_ZADANIE_LIMIT_POWER; + } + else + ff1 = MAX_ZADANIE_LIMIT_POWER * (1.0 - edrk.from_uom.level_value/100.0) - POWER_ZAPAS_FOR_UOM; //kWt + + ff1 = my_satur_float(ff1, SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_LIMIT_POWER];// * (1.0 - edrk.from_uom.level_value/100.0); //kWt + ff = my_satur_float(ff, ff1, MIN_ZADANIE_LIMIT_POWER, 0); + edrk.zadanie.limit_power_zad = my_satur_float(ff,SUPER_MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); // kWt + edrk.zadanie.iq_limit_power_zad = _IQ(edrk.zadanie.limit_power_zad*1000.0/(NORMA_MZZ*NORMA_MZZ)); //Wt + + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER]; //kWt + ff = my_satur_float(ff,MAX_ZADANIE_POWER,MIN_ZADANIE_POWER,DEAD_ZONE_ZADANIE_POWER); // kWt + ff = my_satur_float(ff,edrk.zadanie.limit_power_zad,-edrk.zadanie.limit_power_zad,DEAD_ZONE_ZADANIE_POWER); // kWt + + edrk.zadanie.power_zad = ff; // kWt + edrk.zadanie.iq_power_zad = _IQ(edrk.zadanie.power_zad*1000.0/(NORMA_MZZ*NORMA_MZZ)); //Wt + + + +// StartGED +////////////////////////////////////////////////////// + // edrk.StartGEDRS = control_station.array_cmd[cc][CONTROL_STATION_CMD_GO]; +/* + if (edrk.summ_errors) + { + flag_wait_revers_go = 1; + } + + if (flag_wait_revers_go==1) + edrk.StartGEDRS = 0; + if (pcommand->digit_data.Byte01.bit_data.bit0 && flag_wait_revers_go) + edrk.StartGEDRS = 0; + if (pcommand->digit_data.Byte01.bit_data.bit0==0) + edrk.StartGEDRS = 0; + if (pcommand->digit_data.Byte01.bit_data.bit0==0 && flag_wait_revers_go) + flag_wait_revers_go = 0; + if (pcommand->digit_data.Byte01.bit_data.bit0==1 && flag_wait_revers_go==0) + edrk.StartGEDRS = 1; + +// edrk.StartGEDRS = pcommand->digit_data.Byte01.bit_data.bit0; +*/ +// end StartGED + + + + +//////////////// + + + + +// edrk.from_rs.bits.RAZBOR_SHEMA = pcommand->digit_data.Byte01.bit_data.bit5; + + + +// SBOR SHEMA +/* + if (edrk.summ_errors) + { + flag_wait_revers_sbor = 1; + } + + if (flag_wait_revers_sbor==1) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (pcommand->digit_data.Byte01.bit_data.bit4 && flag_wait_revers_sbor) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (pcommand->digit_data.Byte01.bit_data.bit4==0) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (pcommand->digit_data.Byte01.bit_data.bit4==0 && flag_wait_revers_sbor) + flag_wait_revers_sbor = 0; + + if (pcommand->digit_data.Byte01.bit_data.bit4==1 && flag_wait_revers_sbor==0) + edrk.from_can.bits.SBOR_SHEMA = pcommand->digit_data.Byte01.bit_data.bit4; + + prev_byte01_bit4 = pcommand->digit_data.Byte01.bit_data.bit4; +*/ +// end SBOR SHEMA + + + + + +// if (edrk.from_rs.bits.RAZBOR_SHEMA) + // edrk.from_rs.bits.SBOR_SHEMA = 0; + + //edrk.SborRS = pcommand->digit_data.Byte01.bit_data.bit4; + + +// edrk.to_shema.bits.QTV_ON = pcommand->digit_data.Byte02.bit_data.bit3; + + + + +// edrk.RemouteFromRS = pcommand->digit_data.Byte01.bit_data.bit3; + + + + +// edrk.VozbudOnOffFromRS = pcommand->digit_data.Byte01.bit_data.bit1; +// edrk.enable_set_vozbud = pcommand->digit_data.Byte01.bit_data.bit1; +// edrk.SborRS = pcommand->digit_data.Byte01.bit_data.bit2; +// edrk.RazborRS = pcommand->digit_data.Byte01.bit_data.bit3; +// edrk.DirectOUT = pcommand->digit_data.Byte01.bit_data.bit4; + +// edrk.StartGED = pcommand->digit_data.Byte01.bit_data.bit6; + + +// f.flag_distance = pcommand->digit_data.Byte01.bit_data.bit6; +// f.Set_power = pcommand->digit_data.Byte01.bit_data.bit7; + + + // f.Down50 = pcommand->digit_data.Byte02.bit_data.bit2; +// f.Up50 = pcommand->digit_data.Byte02.bit_data.bit3; +// f.Ciclelog = pcommand->digit_data.Byte02.bit_data.bit4; + + // if (SPEED_SELECT_ZADAT==1) +// f.Provorot = pcommand->digit_data.Byte02.bit_data.bit5; + + + + + + + + + + + + + +} + + + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void parse_parameters_from_all_control_station(void) +{ + + parse_parameters_from_one_control_station_terminal_rs232(CONTROL_STATION_TERMINAL_RS232); + parse_parameters_from_one_control_station_terminal_rs232(CONTROL_STATION_TERMINAL_CAN); + load_parameters_from_can_control_station_to_rs232(); + + if (edrk.get_new_data_from_hmi==1) // ������ ������? + { + func_unpack_answer_from_Ingeteam(CONTROL_STATION_INGETEAM_PULT_RS485); + parse_parameters_from_one_control_station_pult_ingeteam(CONTROL_STATION_INGETEAM_PULT_RS485); + edrk.get_new_data_from_hmi = 2; // ������ ���������� � ������� � modbus + } + parse_parameters_from_one_control_station_pult_zadat4ik(CONTROL_STATION_ZADATCHIK_CAN); + parse_parameters_from_one_control_station_pult_vpu(CONTROL_STATION_VPU_CAN); + parse_parameters_from_one_control_station_another_bs(CONTROL_STATION_ANOTHER_BS); +// unpack_answer_from_MPU_SVU_CAN(CONTROL_STATION_MPU_SVU_CAN); + unpack_answer_from_MPU_SVU_CAN(CONTROL_STATION_MPU_KEY_CAN); //4 + unpack_answer_from_MPU_SVU_CAN(CONTROL_STATION_MPU_SVU_CAN); //3 +// unpack_answer_from_MPU_SVU_RS(CONTROL_STATION_MPU_SVU_RS485); + parse_parameters_from_one_control_station_MPU_SVU(CONTROL_STATION_MPU_SVU_CAN); //3 + parse_parameters_from_one_control_station_MPU_SVU(CONTROL_STATION_MPU_KEY_CAN); //4 +// parse_parameters_from_one_control_station_MPU_SVU(CONTROL_STATION_MPU_SVU_RS485); + + +} + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +void load_parameters_from_active_control_station(int current_control) +{ + int i; + + if (current_control>=CONTROL_STATION_LAST || current_control<0 ) + { + // ���-�� �� ��! ���� �� ���������! + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.active_array_cmd[i] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][i]; + + + // control_station.active_array_cmd[CONTROL_STATION_CMD_SET_IZAD] = NOMINAL_SET_IZAD; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SET_KM] = 0; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = NOMINAL_SET_K_U_DISBALANCE; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = 0; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SET_LIMIT_POWER] = NOMINAL_SET_LIMIT_POWER; +// control_station.active_array_cmd[CONTROL_STATION_CMD_UFCONST_VECTOR] = 1; +// control_station.active_array_cmd[CONTROL_STATION_CMD_SCALAR_FOC] = 0; +// control_station.active_array_cmd[CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = 0; +// control_station.active_array_cmd[CONTROL_STATION_CMD_GO] = 1; + + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR] = 0; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_KM] = 0; + // control_station.active_array_cmd[CONTROL_STATION_CMD_SET_IZAD] = NOMINAL_SET_IZAD; + control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER] = 0; + +// for (i=0;i<CONTROL_STATION_CMD_LAST;i++) +// control_station.active_array_cmd[i] = 0; // clear + + + return; + } + + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.active_array_cmd[i] = control_station.array_cmd[current_control][i]; + + + + +} + +///////////////////////////////////////////////////////////// +// ���� rs232 �����, � CAN ���, �� �������� ������ �� CAN � RS232 +// ��� ������������� ��������� ������ �� ���������� ����� +///////////////////////////////////////////////////////////// +void load_parameters_from_can_control_station_to_rs232(void) +{ + int i; + + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_CAN] && + control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]==0) + { + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][i] = control_station.array_cmd[CONTROL_STATION_TERMINAL_CAN][i]; + } + + + +} + + +///////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////// +int get_current_station_control(void) +{ + int i; + + for (i=0;i<COUNT_CONTROL_STATION;i++) + if (control_station.active_control_station[i]) + return i; // ������� ������� ����. + + return CONTROL_STATION_LAST; // ���������� �������� ��� ������ + +} + + + +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +// ���������� ��� ����� alive_control +///////////////////////////////////////////////////////////// +void control_station_test_alive_all_control(void) +{ + int test_a,test_b, real_box; + + // terminals can + real_box = get_real_in_mbox(TERMINAL_TYPE_BOX,edrk.number_can_box_terminal_cmd); + if (real_box != -1) + if (CAN_timeout[real_box] == 0) + control_station.detect_get_data_control_station[CONTROL_STATION_TERMINAL_CAN] = 1; + + // terminals rs232 + // test ������� � RS_Function.c + if (rs_a.RS_DataReadyRequest) + { + rs_a.RS_DataReadyRequest = 0; + control_station.detect_get_data_control_station[CONTROL_STATION_TERMINAL_RS232] = 1; + } + + + // mpu svu+key rs485 + // test ������� � RS_Function.c + // control_station.detect_get_data_control_station[CONTROL_STATION_MPU_KEY_RS485] = 1; + // control_station.detect_get_data_control_station[CONTROL_STATION_MPU_SVU_RS485] = 1; + + // mpu svu+key can + real_box = get_real_in_mbox(MPU_TYPE_BOX,0); + if (real_box != -1) + if (CAN_timeout[real_box]==0) + { + control_station.detect_get_data_control_station[CONTROL_STATION_MPU_KEY_CAN] = 1; + control_station.detect_get_data_control_station[CONTROL_STATION_MPU_SVU_CAN] = 1; + } + + // zadatchik can + real_box = get_real_in_mbox(UNITS_TYPE_BOX,ZADATCHIK_CAN); + if (real_box != -1) + if (CAN_timeout[real_box] == 0) + control_station.detect_get_data_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 1; + + // vpu can + real_box = get_real_in_mbox(UNITS_TYPE_BOX,VPU_CAN); + if (real_box != -1) + if (CAN_timeout[real_box] == 0) + control_station.detect_get_data_control_station[CONTROL_STATION_VPU_CAN] = 1; + + // Ingeteam pult + // test ������� � RS_Function.c + // control_station.detect_get_data_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + if (rs_b.RS_DataReadyRequest) + { + rs_b.RS_DataReadyRequest = 0; + control_station.detect_get_data_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + } + + if (rs_b.RS_DataReadyFullUpdate) // �������� ���� ������? + { + + if (control_station.flag_refresh_array[CONTROL_STATION_INGETEAM_PULT_RS485]) + control_station.flag_refresh_array[CONTROL_STATION_INGETEAM_PULT_RS485]--; + + rs_b.RS_DataReadyFullUpdate = 0; + } + + // another bs can + real_box = get_real_in_mbox(UNITS_TYPE_BOX,ANOTHER_BSU1_CAN_DEVICE); + if (real_box != -1) + if (CAN_timeout[real_box] == 0) + control_station.detect_get_data_control_station[CONTROL_STATION_ANOTHER_BS] = 1; + + +} + + +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +int control_station_select_active(void) +{ + int i; + /// + /// if (edrk.from_shema.bits.SVU) return; +// if (edrk.from_shema.bits.ZADA_DISPLAY) return; + //edrk.from_ing.bits.LOCAL_REMOUTE + // edrk.from_shema.bits.RAZBOR_SHEMA = !FROM_BSU_RAZBOR_SHEMA; + //edrk.from_shema.bits.SBOR_SHEMA = !FROM_BSU_SBOR_SHEMA; + // if (CAN_timeout[get_real_in_mbox(MPU_TYPE_BOX,0)]==0) + //{ + // edrk.W_from_SVU = modbus_table_can_in[14].all; + // edrk.W_from_DISPLAY = modbus_table_can_in[16].all; + // + //edrk.from_rs.bits.ACTIVE + + +////////////////////////////////////// +// terminal rs232 +////////////////////////////////////// + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + if (control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232] = 1; + } + else + control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232] = 0; + } + else + control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232] = 0; + + // ���� ������ RS232 �� ��� ���� ������ ���������, ��������� ����� ��������� + if (control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232]) + { + for (i=0;i<COUNT_CONTROL_STATION;i++) + if (i != CONTROL_STATION_TERMINAL_RS232) + control_station.active_control_station[i] = 0; + return 0; // all ok + } + +////////////////////////////////////// +// terminal can +////////////////////////////////////// + + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_CAN]) + { + if (control_station.array_cmd[CONTROL_STATION_TERMINAL_CAN][CONTROL_STATION_CMD_ACTIVE_CONTROL]) + { + control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN] = 1; + } + else + control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN] = 0; + } + else + control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN] = 0; + + + // ���� ������ CAN �� ��� ���� ������ ���������, ��������� ����� ��������� + if (control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN]) + { + for (i=0;i<COUNT_CONTROL_STATION;i++) + if (i != CONTROL_STATION_TERMINAL_CAN) + control_station.active_control_station[i] = 0; + return 0; // all ok + } + +////////////////////////////////////// +// ingeteam pult rs485 +////////////////////////////////////// + + if (edrk.from_ing1.bits.LOCAL_REMOUTE == 1) //LOCAL DISPLAY ON + { + if (control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + } + else + control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + + // ���� ������ PULT �� ��� ���� ������ ���������, ��������� ����� ��������� + for (i=0;i<COUNT_CONTROL_STATION;i++) + if (i != CONTROL_STATION_INGETEAM_PULT_RS485) + control_station.active_control_station[i] = 0; + + if (control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + return 0; // ��� �� + } + else + { + return 1; // ������, �������. ���� ������ � ����� � ��� ����!!! + } + } + else + control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + +////////////////////////////////////////////////////////////////// +// svu CAN, svu RS485, zadatchik CAN, mpu CAN, mpu RS485 +////////////////////////////////////////////////////////////////// + if (edrk.from_ing1.bits.LOCAL_REMOUTE == 0) //REMOUTE on INGETEAM ON + { + //////////////////////////// + // svu CAN RS485 + //////////////////////////// + if (edrk.from_shema_filter.bits.SVU) // ��� ��� ��� ������� + { + if (edrk.from_vpu.bits.UOM_READY_ACTIVE==1) // ��� ����������� + { + if (control_station.alive_control_station[CONTROL_STATION_VPU_CAN]) + { + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 1; + } + else + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 0; + + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 0; + + + if (control_station.active_control_station[CONTROL_STATION_VPU_CAN]==0) + return 1; // ������, �������. ���� ������ � ����� � ��� ����!!! + } + else // ��� �� ������ + { + if (control_station.alive_control_station[CONTROL_STATION_MPU_SVU_CAN]) + { + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 1; // � CAN ��������� ���� ��� � RS485 + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + } + else + { + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 0; + + if (control_station.alive_control_station[CONTROL_STATION_MPU_SVU_RS485]) + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 1; + else + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + } + + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 0; + + if (control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN]==0 && + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485]==0) + return 1; // ������, �������. ���� ������ � ����� � ��� ����!!! + } + } + else // ��� �������� + { + //////////////////////////// + // zadatchik can + //////////////////////////// + if (edrk.from_shema_filter.bits.ZADA_DISPLAY == 0) // �������� ����������� � ��� �������� + { + if (control_station.alive_control_station[CONTROL_STATION_ZADATCHIK_CAN]) + { + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 1; + } + else + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 0; + + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 0; + + if (control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN]==0) + return 1; // ������, �������. ���� ������ � ����� � ��� ����!!! + + } + else // �������� ��������, KEY + { + //////////////////////////// + // mpu CAN RS485 + //////////////////////////// + if (control_station.alive_control_station[CONTROL_STATION_MPU_KEY_CAN]) + { + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 1; // � CAN ��������� ���� ��� � RS485 + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + } + else + { + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 0; + + if (control_station.alive_control_station[CONTROL_STATION_MPU_KEY_RS485]) + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 1; + else + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + } + + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 0; + + if (control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN]==0 && + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485]==0) + return 1; // ������, �������. ���� ������ � ����� � ��� ����!!! + + } // end if �������� ��������, KEY + + } // end if // ��� �������� + } + else + { + // ��� �������� ��� ����� ����� ������� ������ ��� ������� ����� + // ���� �� ������� �� �������, �.�. (edrk.from_ing.bits.LOCAL_REMOUTE == 1) ����������� ���� + control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485] = 0; + control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN] = 0; + control_station.active_control_station[CONTROL_STATION_VPU_CAN] = 0; + } // end if REMOUTE on INGETEAM ON + + + return 0; +} diff --git a/Inu/Src/main/control_station_project.h b/Inu/Src/main/control_station_project.h new file mode 100644 index 0000000..3e89763 --- /dev/null +++ b/Inu/Src/main/control_station_project.h @@ -0,0 +1,109 @@ +/* + * control_station_project.h + * + * Created on: 1 ���. 2020 �. + * Author: Yura + */ + +#ifndef SRC_MAIN_CONTROL_STATION_PROJECT_H_ +#define SRC_MAIN_CONTROL_STATION_PROJECT_H_ + + +#define POS_STATION_CMD_ANOTHER_BSU1 15 // ������� � ������� ��� CONTROL_STATION_CMD ��� �������� � ������ �� + + +// ����� ����� ��������: +/* + * �������� - RS232 - ��������� �� PC + * �������� - CAN - ��������� �� PC + * ����� ingeteam - RS485 + * ����� ��� ���- RS485 + * ����� ��� ��� - CAN + * ����� ��� ����� - RS485 + * ����� ��� ����� - CAN + * �������� �� ��� - CAN + * �������� ��� - CAN + * �������� ���2 - CAN + * �������� ���-�� - CAN + * + */ + +enum +{ + CONTROL_STATION_TERMINAL_RS232 = 0, + CONTROL_STATION_TERMINAL_CAN, + + CONTROL_STATION_INGETEAM_PULT_RS485, + CONTROL_STATION_MPU_SVU_CAN, // svu + CONTROL_STATION_MPU_KEY_CAN, // bsu key + CONTROL_STATION_MPU_SVU_RS485, // ? + CONTROL_STATION_MPU_KEY_RS485, // ? + CONTROL_STATION_ZADATCHIK_CAN, // bsu zo + CONTROL_STATION_VPU_CAN, // vpu + CONTROL_STATION_ANOTHER_BS, // �� ������� �� � ������ slave/master + CONTROL_STATION_LAST // ��������� ��� � ������, ������ ������ ����, �� ������� ���, ���������� ��� ����������� �������. +}; + + +enum +{ + CONTROL_STATION_CMD_GO = 0,// cmd_go �� ����� ����/���� ���� + CONTROL_STATION_CMD_SET_IZAD,// ��� �� ����� + CONTROL_STATION_CMD_SET_ROTOR,// ������� �� ����� + CONTROL_STATION_CMD_SET_POWER,// �������� �� ����� + CONTROL_STATION_CMD_CHARGE, // ���� ����� �� ����� + CONTROL_STATION_CMD_UNCHARGE, // ������ ����� �� ����� + CONTROL_STATION_CMD_CHECKBACK,// ������������ �� ����� + CONTROL_STATION_CMD_TEST_LEDS,// ���� ���� �� ����� + CONTROL_STATION_CMD_ACTIVE_CONTROL,// ���� ���� �����������, �������� ������� ��������� �������� �� ����������. + // � �� �����-�� ������ ������� ������������� �������� + CONTROL_STATION_CMD_UFCONST_VECTOR,// Mode 0-ufconst, 1 - ������/��������� + CONTROL_STATION_CMD_ROTOR_POWER, // Mode 0-�������, 1 - �������� + CONTROL_STATION_CMD_SCALAR_FOC, // Mode 0-������, 1 - ��������� + CONTROL_STATION_CMD_SET_KM,// Km ��� Mode 0-ufconst +// CONTROL_STATION_CMD_SET_I_VOZBUD, // ������� ���� ����������� + CONTROL_STATION_CMD_SET_U_ZARYAD, // ������� ���������� ������ ��� + CONTROL_STATION_CMD_SET_K_U_DISBALANCE, // ������� � ���������� ���������� ����. �������� ����� �� ����������, ���� >0 ���� ������� �������� + CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE, //kplus_u_disbalance, ���� =0, �� �������� �������� ����������, ��������� ��� ����. ���������, ���� <>0 �� �� ����� ����������. + CONTROL_STATION_CMD_MODE_PUMP, //����� ������ ������ // // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + // 5- ������� �� manual � ���������� ��������� + CONTROL_STATION_CMD_DISABLE_ON_PUMP, + CONTROL_STATION_CMD_ENABLE_ON_CHARGE, + CONTROL_STATION_CMD_DISABLE_ON_QTV, + CONTROL_STATION_CMD_MANUAL_DISCHARGE, + CONTROL_STATION_CMD_DISABLE_ON_UMP, + CONTROL_STATION_CMD_WDOG_OFF, + CONTROL_STATION_CMD_SET_LIMIT_POWER,// ����� �������� �� ����� + CONTROL_STATION_CMD_BLOCK_BS, // ���������� � �������� ������ + CONTROL_STATION_CMD_DISABLE_INTERRUPT_SYNC, + CONTROL_STATION_CMD_DISABLE_INTERRUPT_TIMER2, + CONTROL_STATION_CMD_DISABLE_RASCEPITEL, // �� ��������� ������������, ���� �� ������ � �� �������� ����� ����������� + CONTROL_STATION_CMD_PWM_TEST_LINES, // ��� ����� �� 96��� ���� ��� ��������, ������ ��� �����!!! + CONTROL_STATION_CMD_STOP_LOGS, // ���� ����� + CONTROL_STATION_CMD_LAST // ��������� ��� � ������, ������ ������ ����, �� ������� ���, ���������� ��� ����������� �������. +}; + + +void control_station_test_alive_all_control(void); +int control_station_select_active(void); +int get_current_station_control(void); +void load_parameters_from_active_control_station(int current_control); +void parse_parameters_from_all_control_station(void); +void parse_parameters_from_one_control_station_terminal_rs232(int cc); +void parse_parameters_from_one_control_station_pult_ingeteam(int cc); +void parse_parameters_from_one_control_station_pult_zadat4ik(int cc); +void parse_parameters_from_one_control_station_pult_vpu(int cc); +void parse_parameters_from_one_control_station_another_bs(int cc); +void parse_parameters_from_one_control_station_MPU_SVU(int cc); + +void parse_analog_data_from_active_control_station_to_alg(void); +void parse_data_from_master_to_alg(void); + +void load_parameters_from_can_control_station_to_rs232(void); + + +#endif /* SRC_MAIN_CONTROL_STATION_PROJECT_H_ */ diff --git a/Inu/Src/main/detect_error_3_phase.c b/Inu/Src/main/detect_error_3_phase.c new file mode 100644 index 0000000..9b6fd87 --- /dev/null +++ b/Inu/Src/main/detect_error_3_phase.c @@ -0,0 +1,167 @@ +/* + * detect_error_3_phase.c + * + * Created on: 7 ���. 2020 �. + * Author: star + */ + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + + +#include <detect_error_3_phase.h> +#include <detect_phase_break.h> + +#include "global_time.h" + +static int detect_system_asymmetry(DETECT_PROTECT_3_PHASE *v); +static int detect_system_asymmetry_rms(DETECT_PROTECT_3_PHASE *v); + +int detect_error_3_phase(DETECT_PROTECT_3_PHASE *v) { + int err = 0; + int asymmetry = 0; + int break_channel = 0; + + v->errors.all = 0; + v->over_limit.all = 0; + if (v->setup.timers_inited == 0) { + v->setup.timers_inited = 1; + init_timer_milisec(&v->timer_low_minus_10); + init_timer_milisec(&v->timer_low_minus_20); + init_timer_milisec(&v->timer_high_plus_10); + init_timer_milisec(&v->timer_high_plus_20); + } + + if (v->setup.use.bits.phase_U != 0 && + v->iqVal_U > v->setup.levels.iqVal_U_max) { + v->errors.bits.phase_U_max = 1; + v->over_limit.bits.phase_U_max = 1; + err = 1; + } + if (v->setup.use.bits.phase_V != 0 && + v->iqVal_V > v->setup.levels.iqVal_V_max) { + v->errors.bits.phase_V_max = 1; + v->over_limit.bits.phase_V_max = 1; + err = 1; + } + if (v->setup.use.bits.phase_W != 0 && + v->iqVal_W > v->setup.levels.iqVal_W_max) { + v->errors.bits.phase_W_max = 1; + v->over_limit.bits.phase_W_max = 1; + err = 1; + } + //-------------------------------------------------------------------------// + if (v->setup.use.bits.module) { + if (v->iqVal_mod > v->setup.levels.iqVal_module_max) { + v->errors.bits.module_max = 1; + v->over_limit.bits.module_max = 1; + err = 1; + } + } + //-------------------------------------------------------------------------// + if (v->setup.use.bits.detect_minus_10 != 0) { + if (v->iqVal_mod < v->setup.levels.iqNominal_minus10) { + if (detect_pause_milisec(PAUSE_VAL_MINIS_10_S, &v->timer_low_minus_10)){ + v->errors.bits.module_10_percent_low = 1; + err = 1; + } + v->over_limit.bits.module_10_percent_low = 1; + } else { + init_timer_milisec(&v->timer_low_minus_10); + } + v->new_timer_low_minus_10 = v->timer_low_minus_10; + } + + if (v->setup.use.bits.detect_minus_20 != 0) { + if (v->iqVal_mod < v->setup.levels.iqNominal_minus20) { + if (detect_pause_milisec(PAUSE_VAL_MINIS_20_S, &v->timer_low_minus_20)) { + v->errors.bits.module_20_percent_low = 1; + err = 1; + } + v->over_limit.bits.module_20_percent_low = 1; + } else { + init_timer_milisec(&v->timer_low_minus_20); + } + v->new_timer_low_minus_20 = v->timer_low_minus_20; + } + + if (v->setup.use.bits.detect_plus_10 != 0) { + if (v->iqVal_mod > v->setup.levels.iqNominal_plus10) { + if (detect_pause_milisec(PAUSE_VAL_PLUS_10_S, &v->timer_high_plus_10)) { + v->errors.bits.module_10_percent_hi = 1; + err = 1; + } + v->over_limit.bits.module_10_percent_hi = 1; + } else { + init_timer_milisec(&v->timer_high_plus_10); + } + v->new_timer_high_plus_10 = v->timer_high_plus_10; + } + + if (v->setup.use.bits.detect_plus_20 != 0) { + if (v->iqVal_mod > v->setup.levels.iqNominal_plus20) { + if (detect_pause_milisec(PAUSE_VAL_PLUS_20_S, &v->timer_high_plus_20)) { + v->errors.bits.module_20_percent_hi = 1; + err = 1; + } + v->over_limit.bits.module_20_percent_hi = 1; + } else { + init_timer_milisec(&v->timer_high_plus_20); + } + v->new_timer_high_plus_20 = v->timer_high_plus_20; + } + //�������� �� �������������� 3-� ������ �������. ����� 3-� ������������ ����� 0 + if (v->setup.use.bits.system_asymmetry_by_summ != 0) { + asymmetry = detect_system_asymmetry(v); + if (asymmetry != 0) { + v->errors.bits.system_asymmetry = 1; + err = 1; + } + } + //�������� �� �������������� 3-� ������ �������. ����������� �������� 3-� ������������ ����� ����� ����� + if (v->setup.use.bits.system_asymmetry_by_delta != 0) { + asymmetry = detect_system_asymmetry_rms(v); + if (asymmetry != 0) { + v->errors.bits.system_asymmetry = 1; + err = 1; + } + } + //�������� �� ����� ����. �������� � ����� ������ ����� ����, � ��������� � ����������� � ����� �� ������ + if (v->setup.use.bits.break_phase != 0 && v->break_phase != 0) { + v->break_phase->iqIu = v->iqVal_U; + v->break_phase->iqIv = v->iqVal_V; + v->break_phase->iqIw = v->iqVal_W; + v->break_phase->iqImod = v->iqVal_mod; + v->break_phase->teta = v->iqTeta; + break_channel = v->break_phase->calc(v->break_phase); + if (break_channel) { + v->errors.bits.break_phase = 1; + err = 1; + switch (break_channel) { + case 1: v->errors.bits.break_phase_U = 1; break; + case 2: v->errors.bits.break_phase_V = 1; break; + case 3: v->errors.bits.break_phase_W = 1; break; + default: break; + } + } + } + + + return err; +} + +int detect_system_asymmetry(DETECT_PROTECT_3_PHASE *v) { + _iq sum = v->iqVal_U + v->iqVal_V + v->iqVal_W; + return _IQabs(sum) > v->setup.levels.iqAsymmetry_delta ? 1 : 0; +} + +int detect_system_asymmetry_rms(DETECT_PROTECT_3_PHASE *v) { + _iq d1 = _IQabs(v->iqVal_U - v->iqVal_V); + _iq d2 = _IQabs(v->iqVal_V - v->iqVal_W); + _iq d3 = _IQabs(v->iqVal_U - v->iqVal_W); + return d1 > v->setup.levels.iqAsymmetry_delta || + d2 > v->setup.levels.iqAsymmetry_delta || + d3 > v->setup.levels.iqAsymmetry_delta ? 1 : 0; +} + diff --git a/Inu/Src/main/detect_error_3_phase.h b/Inu/Src/main/detect_error_3_phase.h new file mode 100644 index 0000000..bdb7307 --- /dev/null +++ b/Inu/Src/main/detect_error_3_phase.h @@ -0,0 +1,148 @@ +/* + * detect_error_3_phase.h + * + * Created on: 7 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_DETECT_ERROR_3_PHASE_H_ +#define SRC_MAIN_DETECT_ERROR_3_PHASE_H_ + +#include <detect_phase_break.h> + +typedef struct { + _iq iqVal_module_max; + _iq iqVal_U_max; + _iq iqVal_V_max; + _iq iqVal_W_max; + _iq iqNominal_plus10; + _iq iqNominal_plus20; + _iq iqNominal_minus10; + + _iq iqNominal_minus20; + _iq iqAsymmetry_delta; +} PROTECT_LEVELS_3_PHASE; + +#define PROTECT_LEVELS_3_PHASE_DEFAULTS {0,0,0,0,0,0,0, 0,0} + +typedef struct { + PROTECT_LEVELS_3_PHASE levels; + union { + unsigned int all; + struct { + unsigned int phase_U :1; + unsigned int phase_V :1; + unsigned int phase_W :1; + unsigned int module :1; + + unsigned int detect_minus_10 :1; + unsigned int detect_minus_20 :1; + unsigned int detect_plus_10 :1; + unsigned int detect_plus_20 :1; + + unsigned int system_asymmetry_by_summ :1; //����� 3-� ������������ ����� 0 + unsigned int system_asymmetry_by_delta :1; //����������� �������� 3-� ������������ ����� ����� ����� + unsigned int break_phase :1; + unsigned int reserved :5; + } bits; + } use; + unsigned int timers_inited; +} SETUP_3_PHASE_PROTECT; + +#define SETUP_3_PHASE_PROTECT_DEFAULTS {PROTECT_LEVELS_3_PHASE_DEFAULTS, {0}, 0} + +typedef struct { + //In values + _iq iqVal_U; + _iq iqVal_V; + _iq iqVal_W; + _iq iqVal_mod; + _iq iqTeta; //����� ��� ����������� ������ ���� + + unsigned int timer_low_minus_10; + unsigned int timer_low_minus_20; + unsigned int timer_high_plus_10; + unsigned int timer_high_plus_20; + + //Break phase I state values + BREAK_PHASE_I *break_phase; + + //Out values + union { + unsigned int all; + struct { + unsigned int phase_U_max :1; + unsigned int phase_V_max :1; + unsigned int phase_W_max :1; + unsigned int module_max :1; + unsigned int module_10_percent_hi :1; + unsigned int module_20_percent_hi :1; + unsigned int module_10_percent_low :1; + unsigned int module_20_percent_low :1; + + unsigned int system_asymmetry :1; + unsigned int break_phase :1; + unsigned int break_phase_U :1; + unsigned int break_phase_V :1; + unsigned int break_phase_W :1; + unsigned int reserved :3; + + } bits; + } errors; + union { + unsigned int all; + struct { + unsigned int phase_U_max :1; + unsigned int phase_V_max :1; + unsigned int phase_W_max :1; + unsigned int module_max :1; + unsigned int module_10_percent_hi :1; + unsigned int module_20_percent_hi :1; + unsigned int module_10_percent_low :1; + unsigned int module_20_percent_low :1; + + unsigned int system_asymmetry_by_summ :1; + unsigned int break_phase :1; + unsigned int break_phase_U :1; + unsigned int break_phase_V :1; + unsigned int break_phase_W :1; + unsigned int reserved :3; + + } bits; + } over_limit; + unsigned int new_timer_low_minus_10; + unsigned int new_timer_low_minus_20; + unsigned int new_timer_high_plus_10; + unsigned int new_timer_high_plus_20; + + //Setup + SETUP_3_PHASE_PROTECT setup; + + int (*calc_detect_error_3_phase)(); + +} DETECT_PROTECT_3_PHASE; + +#define DETECT_PROTECT_3_PHASE_DEFAULTS {0,0,0,0,0, 0,0,0,0, 0, {0},{0}, 0,0,0,0,\ + SETUP_3_PHASE_PROTECT_DEFAULTS, \ + detect_error_3_phase} + + +#define ADC_PROTECT_LEVELS_DEFAULT {0,0,0,0, 0,0,0,0, 0} + +#define PAUSE_VAL_MINIS_10_S 10000 +#define PAUSE_VAL_MINIS_20_S 1000 +#define PAUSE_VAL_PLUS_10_S 10000 +#define PAUSE_VAL_PLUS_20_S 1000 + +#define PLUS_10_PERCENT 1.1 +#define PLUS_20_PERCENT 1.2 +#define MINUS_10_PERCENT 0.9 +#define MINUS_20_PERCENT 0.8 +#define ASYMMETRY_DELTA_PERCENTS 0.2 + +int detect_error_3_phase(DETECT_PROTECT_3_PHASE *v); + + + + +#endif /* SRC_MAIN_DETECT_ERROR_3_PHASE_H_ */ diff --git a/Inu/Src/main/detect_errors.c b/Inu/Src/main/detect_errors.c new file mode 100644 index 0000000..07ff17c --- /dev/null +++ b/Inu/Src/main/detect_errors.c @@ -0,0 +1,1606 @@ +/* + * detect_errors.c + * + * Created on: 4 ���. 2020 �. + * Author: star + */ + +#include <adc_tools.h> +#include <detect_errors.h> +#include <detect_overload.h> +#include <edrk_main.h> +#include <optical_bus.h> +#include <params.h> +#include <params_temper_p.h> +#include <protect_levels.h> +#include <sync_tools.h> +#include <vector.h> +#include "v_rotor.h" + + +#include "control_station.h" +#include "DSP281x_Device.h" +#include "master_slave.h" +#include "another_bs.h" +#include "digital_filters.h" + + +void detect_error_from_knopka_avaria(void); +void detect_error_ute4ka_water(void); +void detect_error_t_vipr(void); +void detect_error_power_upc(void); +void detect_error_op_pit(void); +void detect_error_p_water(void); +void detect_error_pump_2(void); +void detect_error_pump_1(void); +void detect_error_pre_ready_pump(void); +void detect_error_fan(void); +void detect_error_block_qtv_from_svu(void); + +void detect_error_predohr_vipr(void); +void detect_error_qtv(void); +void detect_error_pre_charge(void); +void detect_error_block_izol(void); +void detect_error_nagrev(void); +void detect_error_ground(void); +void detect_error_block_door(void); +void detect_error_optical_bus(void); +void detect_error_sync_bus(void); +int get_status_temper_acdrive_winding(int nc); +int get_status_temper_acdrive_winding_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_acdrive_bear(int nc); +int get_status_temper_acdrive_bear_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_air(int nc); +int get_status_temper_air_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_u(int nc); +int get_status_temper_u_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_water(int nc); +int get_status_p_water_max(void); +int get_status_p_water_min(int pump_on_off); +void detect_error_t_water(void); +void detect_error_t_air(void); +void detect_error_t_u(void); +void detect_error_acdrive_winding(void); + +int get_common_state_warning(void); +int get_common_state_overheat(void); +void detect_error_sensor_rotor(void); + + + + +#pragma DATA_SECTION(protect_levels,".slow_vars"); +PROTECT_LEVELS protect_levels = PROTECT_LEVELS_DEFAULTS; + + + + +/////////////////////////////////////////////// +int get_status_temper_acdrive_winding(int nc) +{ + if (edrk.temper_acdrive.winding.filter_real_int_temper[nc]>=ALARM_TEMPER_ACDRIVE_WINDING) + return 4; + if (edrk.temper_acdrive.winding.filter_real_int_temper[nc]>=ABNORMAL_TEMPER_ACDRIVE_WINDING) + return 2; + return 1; +} + +int get_status_temper_acdrive_winding_with_limits(int nc, int alarm, int abnormal) +{ + if (edrk.temper_acdrive.winding.filter_real_int_temper[nc]>=alarm) + return 4; + if (edrk.temper_acdrive.winding.filter_real_int_temper[nc]>=abnormal) + return 2; + return 1; +} +/////////////////////////////////////////////// +int get_status_temper_acdrive_bear(int nc) +{ + + if (edrk.temper_acdrive.bear.filter_real_int_temper[nc]>=ALARM_TEMPER_ACDRIVE_WINDING) + return 4; + if (edrk.temper_acdrive.bear.filter_real_int_temper[nc]>=ABNORMAL_TEMPER_ACDRIVE_WINDING) + return 2; + return 1; +} + +int get_status_temper_acdrive_bear_with_limits(int nc, int alarm, int abnormal) +{ + + if (edrk.temper_acdrive.bear.filter_real_int_temper[nc]>=alarm) + return 4; + if (edrk.temper_acdrive.bear.filter_real_int_temper[nc]>=abnormal) + return 2; + return 1; +} + +/////////////////////////////////////////////// +int get_status_temper_air(int nc) +{ + if (edrk.temper_edrk.real_int_temper_air[nc]>=ALARM_TEMPER_AIR_INT) + return 4; + if (edrk.temper_edrk.real_int_temper_air[nc]>=ABNORMAL_TEMPER_AIR_INT) + return 2; + return 1; +} + +int get_status_temper_air_with_limits(int nc, int alarm, int abnormal) +{ + if (edrk.temper_edrk.real_int_temper_air[nc]>=alarm) + return 4; + if (edrk.temper_edrk.real_int_temper_air[nc]>=abnormal) + return 2; + return 1; +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +int get_status_temper_u(int nc) +{ + if (edrk.temper_edrk.real_int_temper_u[nc]>=ALARM_TEMPER_AF) + return 4; + if (edrk.temper_edrk.real_int_temper_u[nc]>=ABNORMAL_TEMPER_AF) + return 2; + return 1; +} + +int get_status_temper_u_with_limits(int nc, int alarm, int abnormal) +{ + if (edrk.temper_edrk.real_int_temper_u[nc]>=alarm) + return 4; + if (edrk.temper_edrk.real_int_temper_u[nc]>=abnormal) + return 2; + return 1; +} + +/////////////////////////////////////////////// +int get_status_temper_water(int nc) +{ + + if (nc==INDEX_T_WATER_EXT) // ext + { + if (edrk.temper_edrk.real_int_temper_water[nc]>=protect_levels.alarm_temper_water_ext) + return 4; + if (edrk.temper_edrk.real_int_temper_water[nc]>=protect_levels.abnormal_temper_water_ext) + return 2; + return 1; + } + + if (nc==INDEX_T_WATER_INT) // int + { + if (edrk.temper_edrk.real_int_temper_water[nc]>=protect_levels.alarm_temper_water_int) + return 4; + if (edrk.temper_edrk.real_int_temper_water[nc]>=protect_levels.abnormal_temper_water_int) + return 2; + return 1; + } + + return 0; +} + +/////////////////////////////////////////////// +int get_status_p_water_max(void) +{ + if (edrk.p_water_edrk.filter_real_int_p_water[0]>=protect_levels.alarm_p_water_max_int) + return 4; + if (edrk.p_water_edrk.filter_real_int_p_water[0]>=protect_levels.abnormal_p_water_max_int) + return 2; + return 1; +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +int get_status_p_water_min(int pump_on_off) +{ + if (pump_on_off == 0) + { + if (edrk.p_water_edrk.filter_real_int_p_water[0]<=ALARM_P_WATER_MIN_INT_ON_OFF_PUMP) + return 4; + if (edrk.p_water_edrk.filter_real_int_p_water[0]<=ABNORMAL_P_WATER_MIN_INT_ON_OFF_PUMP) + return 2; + return 1; + } + + if (pump_on_off == 1) + { + if (edrk.p_water_edrk.filter_real_int_p_water[0]<=protect_levels.alarm_p_water_min_int) + return 4; + if (edrk.p_water_edrk.filter_real_int_p_water[0]<=protect_levels.abnormal_p_water_min_int) + return 2; + return 1; + } + return 0; +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void detect_error_sensor_rotor(void) +{ + static unsigned int count_err1 = 0, count_err2 = 0, count_err3 = 0, count_err4 = 0; + + + if (edrk.Go) + { + // ����� �� �����? + if (edrk.iq_f_rotor_hz==0) + { + // ����� �����! + if (pause_detect_error(&count_err3,TIME_WAIT_SENSOR_ROTOR_BREAK_ALL,1)) + { + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 1; + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 1; + //edrk.errors.e9.bits.SENSOR_ROTOR_1_2_BREAK |= 1; // ���� ������! + } + else + { +// edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 0; +// edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 0; + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = pause_detect_error(&count_err1,TIME_WAIT_SENSOR_ROTOR_BREAK_ONE_SENSOR, + inc_sensor.break_sensor1); + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = pause_detect_error(&count_err2,TIME_WAIT_SENSOR_ROTOR_BREAK_ONE_SENSOR, + inc_sensor.break_sensor2); + } + } + else + { + count_err3 = 0; +// edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 0; +// edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 0; + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK |= pause_detect_error(&count_err1,TIME_WAIT_ERROR,inc_sensor.break_sensor1); + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK |= pause_detect_error(&count_err2,TIME_WAIT_ERROR,inc_sensor.break_sensor2); + + } + } + else + { + + count_err1 = count_err2 = 0; + count_err3 = 0; + + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 0; + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 0; + } + +} +/////////////////////////////////////////////// +#define TIME_WAIT_T_WATER 30 +void detect_error_t_water(void) +{ + static unsigned int count_run = 0, count_run_static = 0; + int status; + + status = get_status_temper_water(INDEX_T_WATER_INT); + if (status==4) + edrk.errors.e2.bits.T_WATER_INT_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_WATER_INT_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_WATER_INT_MAX = 0; + + status = get_status_temper_water(INDEX_T_WATER_EXT); + if (status==4) + edrk.errors.e2.bits.T_WATER_EXT_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_WATER_EXT_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_WATER_EXT_MAX = 0; + +} +/////////////////////////////////////////////// + +void detect_error_t_air(void) +{ + static unsigned int count_run = 0, count_run_static = 0; + int status,i; + + + status = get_status_temper_air_with_limits(0, protect_levels.alarm_temper_air_int_01, + protect_levels.abnormal_temper_air_int_01); + if (status==4) + edrk.errors.e2.bits.T_AIR0_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_AIR0_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_AIR0_MAX = 0; + + + status = get_status_temper_air_with_limits(1, protect_levels.alarm_temper_air_int_02, + protect_levels.abnormal_temper_air_int_02); + if (status==4) + edrk.errors.e2.bits.T_AIR1_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_AIR1_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_AIR1_MAX = 0; + + + status = get_status_temper_air_with_limits(2, protect_levels.alarm_temper_air_int_03, + protect_levels.abnormal_temper_air_int_03); + if (status==4) + edrk.errors.e2.bits.T_AIR2_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_AIR2_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_AIR2_MAX = 0; + + + status = get_status_temper_air_with_limits(3, protect_levels.alarm_temper_air_int_04, + protect_levels.abnormal_temper_air_int_04); + if (status==4) + edrk.errors.e2.bits.T_AIR3_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_AIR3_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_AIR3_MAX = 0; +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +void detect_error_t_u(void) +{ + static unsigned int count_run = 0, count_run_static = 0; + int status,i; + + + status = get_status_temper_u_with_limits(0, protect_levels.alarm_temper_u_01, + protect_levels.abnormal_temper_u_01); + if (status == 4) + edrk.errors.e2.bits.T_UO1_MAX |= 1; + if (status == 2) + edrk.warnings.e2.bits.T_UO1_MAX = 1; + if (status == 1) + edrk.warnings.e2.bits.T_UO1_MAX = 0; + + status = get_status_temper_u_with_limits(1, protect_levels.alarm_temper_u_02, + protect_levels.abnormal_temper_u_02); + if (status==4) + edrk.errors.e2.bits.T_UO2_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO2_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO2_MAX = 0; + + status = get_status_temper_u_with_limits(2, protect_levels.alarm_temper_u_03, + protect_levels.abnormal_temper_u_03); + if (status==4) + edrk.errors.e2.bits.T_UO3_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO3_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO3_MAX = 0; + + status = get_status_temper_u_with_limits(3, protect_levels.alarm_temper_u_04, + protect_levels.abnormal_temper_u_04); + if (status==4) + edrk.errors.e2.bits.T_UO4_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO4_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO4_MAX = 0; + + status = get_status_temper_u_with_limits(4, protect_levels.alarm_temper_u_05, + protect_levels.abnormal_temper_u_05); + if (status==4) + edrk.errors.e2.bits.T_UO5_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO5_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO5_MAX = 0; + + status = get_status_temper_u_with_limits(5, protect_levels.alarm_temper_u_06, + protect_levels.abnormal_temper_u_06); + if (status==4) + edrk.errors.e2.bits.T_UO6_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO6_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO6_MAX = 0; + + status = get_status_temper_u_with_limits(6, protect_levels.alarm_temper_u_07, + protect_levels.abnormal_temper_u_07); + if (status==4) + edrk.errors.e2.bits.T_UO7_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.T_UO7_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.T_UO7_MAX = 0; + +} + +void detect_error_t_bsu(void) { + +} +/////////////////////////////////////////////// +void detect_error_acdrive_winding(void) +{ +// static unsigned int count_run = 0, count_run_static = 0; + int status, i; + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 0, protect_levels.alarm_temper_acdrive_winding_U1, + protect_levels.abnormal_temper_acdrive_winding_U1); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_U1 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1 = 0; + } + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 1, protect_levels.alarm_temper_acdrive_winding_V1, + protect_levels.abnormal_temper_acdrive_winding_V1); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_V1 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1 = 0; + } + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 2, protect_levels.alarm_temper_acdrive_winding_W1, + protect_levels.abnormal_temper_acdrive_winding_W1); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_W1 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1 = 0; + } + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 3, protect_levels.alarm_temper_acdrive_winding_U2, + protect_levels.abnormal_temper_acdrive_winding_U2); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_U2 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2 = 0; + } + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 4, protect_levels.alarm_temper_acdrive_winding_V2, + protect_levels.abnormal_temper_acdrive_winding_V2); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_V2 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2 = 0; + } + + status = 0; + status |= get_status_temper_acdrive_winding_with_limits( + 5, protect_levels.alarm_temper_acdrive_winding_W2, + protect_levels.abnormal_temper_acdrive_winding_W2); + if (status == 4) { + edrk.errors.e10.bits.T_ACDRIVE_WINDING_W2 = 1; + } + if (status == 2) { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2 = 1; + } else { + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2 = 0; + } + + if (edrk.errors.e10.bits.T_ACDRIVE_WINDING_U1 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_V1 || + edrk.errors.e10.bits.T_ACDRIVE_WINDING_W1 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_U2 || + edrk.errors.e10.bits.T_ACDRIVE_WINDING_V2 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_W2) { + edrk.errors.e7.bits.T_ACDRIVE_WINDING_MAX |= 1; + } + if (edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1 || + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2 || + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2) { + edrk.warnings.e7.bits.T_ACDRIVE_WINDING_MAX = 1; + } + else + edrk.warnings.e7.bits.T_ACDRIVE_WINDING_MAX = 0; +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void detect_error_acdrive_bear(void) +{ + static unsigned int count_run = 0, count_run_static = 0; + int status,i; + +// status = 0; + + status = get_status_temper_acdrive_bear_with_limits(0, protect_levels.alarm_temper_acdrive_bear_DNE, + protect_levels.abnormal_temper_acdrive_bear_DNE); + if (status & 4) + edrk.errors.e7.bits.T_ACDRIVE_BEAR_MAX_DNE |= 1; + if (status == 2) + edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE = 1; + if (status == 1) + edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE = 0; + + status = get_status_temper_acdrive_bear_with_limits(1, protect_levels.alarm_temper_acdrive_bear_NE, + protect_levels.abnormal_temper_acdrive_bear_NE); + if (status & 4) + edrk.errors.e9.bits.T_ACDRIVE_BEAR_MAX_NE |= 1; + if (status == 2) + edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE = 1; + if (status == 1) + edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE = 0; + +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +#define TIME_WAIT_RUN_PUMP 100 //50 +void detect_error_p_water(void) +{ + static unsigned int count_run = 0, count_run_static = 0; + int status,i; + + if (edrk.from_ing1.bits.NASOS_ON == 1) + { + if (pause_detect_error(&count_run,TIME_WAIT_RUN_PUMP,1)) + { + status = get_status_p_water_max(); + + if (status & 4) + edrk.errors.e2.bits.P_WATER_INT_MAX |= 1; + if (status==2) + edrk.warnings.e2.bits.P_WATER_INT_MAX = 1; + if (status==1) + edrk.warnings.e2.bits.P_WATER_INT_MAX = 0; + + status = get_status_p_water_min(1); + + if (status & 4) + edrk.errors.e2.bits.P_WATER_INT_MIN |= 1; + if (status==2) + edrk.warnings.e2.bits.P_WATER_INT_MIN = 1; + if (status==1) + edrk.warnings.e2.bits.P_WATER_INT_MIN = 0; + + } + } + else + count_run = 0; + + + // test if nasos off + status = get_status_p_water_min(0); + if (status>1) + { + if (pause_detect_error(&count_run_static,TIME_WAIT_RUN_PUMP,1)) + { + if (status==4) + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_PUMP]==0) + edrk.errors.e2.bits.P_WATER_INT_MIN |= 1; + } + if (status==2) + edrk.warnings.e2.bits.P_WATER_INT_MIN = 1; + } + } + else + { + count_run_static = 0; + edrk.warnings.e2.bits.P_WATER_INT_MIN = 0; + } + +} + +/////////////////////////////////////////////// + +/////////////////////////////////////////////// + +void detect_error_ground(void) +{ + static unsigned int count_err = 0; + + + if (edrk.from_ing1.bits.ZAZEML_OFF == 0) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.ERROR_GROUND_NET |= 1; + } + + if (edrk.from_ing1.bits.ZAZEML_ON == 1) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.ERROR_GROUND_NET |= 1; + } + + if ((edrk.from_ing1.bits.ZAZEML_OFF == 1) && (edrk.from_ing1.bits.ZAZEML_ON == 0)) + count_err = 0; + +} + +/////////////////////////////////////////////// +void detect_error_nagrev(void) +{ + + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.NAGREV_ON == edrk.to_ing.bits.NAGREV_OFF) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.ERROR_HEAT |= 1; + } + else + count_err = 0; + + +} +/////////////////////////////////////////////// +#define TIME_WAIT_ERROR_BLOCK_DOOR 30 //20 +void detect_error_block_door(void) +{ + static unsigned int count_err = 0; + + if ((edrk.from_ing2.bits.SOST_ZAMKA == 1 && edrk.to_ing.bits.BLOCK_KEY_OFF==1) + || (edrk.from_ing2.bits.SOST_ZAMKA == 0 && edrk.to_ing.bits.BLOCK_KEY_OFF==0)) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_BLOCK_DOOR,1)) + edrk.errors.e1.bits.BLOCK_DOOR |= 1; + } + else + count_err = 0; + +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void detect_error_block_izol(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.BLOCK_IZOL_AVARIA == 1 ) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_IZOL,1)) + edrk.errors.e5.bits.ERROR_ISOLATE |= 1; + } + + if (edrk.from_ing1.bits.BLOCK_IZOL_AVARIA == 0 && edrk.from_ing1.bits.BLOCK_IZOL_NORMA == 0 ) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_IZOL,1)) + edrk.warnings.e5.bits.ERROR_ISOLATE |= 1; + } + else + edrk.warnings.e5.bits.ERROR_ISOLATE = 0; + + if (edrk.from_ing1.bits.BLOCK_IZOL_AVARIA == 0 && edrk.from_ing1.bits.BLOCK_IZOL_NORMA == 1 ) + { + count_err = 0; + } + + if (edrk.cmd_imit_low_isolation) + edrk.errors.e5.bits.ERROR_ISOLATE |= 1; + +} + +/////////////////////////////////////////////// +void detect_error_pre_charge(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.ZARYAD_ON == 1 && edrk.to_ing.bits.ZARYAD_ON == 0) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_CHARGE_ANSWER,1)) + edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER |= 1; + } + + if (edrk.from_ing1.bits.ZARYAD_ON == 0 && edrk.to_ing.bits.ZARYAD_ON == 1) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_CHARGE_ANSWER,1)) + edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER |= 1; + + + if (edrk.from_ing1.bits.ZARYAD_ON == 0 && edrk.to_ing.bits.ZARYAD_ON == 0) + count_err = 0; + + +// edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER |= 1; +// edrk.errors.e6.bits.ERROR_PRE_CHARGE_U |= 1; +} + +/////////////////////////////////////////////// +void detect_error_qtv(void) +{ + static unsigned int count_err_off = 0; + static unsigned int count_err_on = 0; + + + // ��� ������� �� ����, �� ����� ������� ������ + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 1 && edrk.cmd_to_qtv == 0) + { + if (pause_detect_error(&count_err_off,TIME_WAIT_ERROR_QTV,1)) + edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER |= 1; + } + else + { + count_err_off = 0; + } + +// ���� ������� �� ���, �� ����� ������� �� ������ + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 0 && edrk.cmd_to_qtv == 1) + { + if (pause_detect_error(&count_err_on,TIME_WAIT_ERROR_QTV,1)) + edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER |= 1; + } + else + { + count_err_on = 0; + } + +// +// if (edrk.from_shema.bits.QTV_ON_OFF == 0 && edrk.cmd_to_qtv == 0) +// count_err = 0; + +// edrk.errors.e6.bits.QTV_ERROR_NOT_U |= 1; + +// edrk.errors.e6.bits.QTV_ERROR_NOT_U |= detect_error_u_zpt(); + edrk.errors.e6.bits.QTV_ERROR_NOT_U |= detect_error_u_in(); +// edrk.errors.e6.bits.QTV_ERROR_NOT_U |= detect_error_u_zpt_on_predzaryad(); +} + +/////////////////////////////////////////////// +void detect_error_predohr_vipr(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.VIPR_PREDOHR_NORMA == 0) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.ERROR_PRED_VIPR |= 1; + + if (edrk.from_ing1.bits.VIPR_PREDOHR_NORMA == 1) + count_err = 0; +} + +/////////////////////////////////////////////// +#define TIME_WAIT_ERROR_UMP_READY 1200 //120 ��� //750 // ���� 75 ��� �.�. �������� ��� ����� �� ���� ������� �� +#define TIME_WAIT_WARNING_UMP_READY 10 +void detect_error_ump(void) +{ + static unsigned int count_err = 0; + static unsigned int count_err2 = 0; + + static unsigned int prev_SumSbor = 0; + static unsigned int StageUMP = 0; + static unsigned int count_UMP_NOT_READY = 0; + int local_warning_ump = 0; + + if (edrk.SumSbor==1) + { + switch (StageUMP) { + case 0: if (edrk.from_shema_filter.bits.UMP_ON_OFF == 1) + StageUMP++; + break; + case 1: if (edrk.from_shema_filter.bits.UMP_ON_OFF == 0) + StageUMP++; + break; + case 2: + break; + case 3: + break; + + + default: break; + } + + if ((edrk.from_shema_filter.bits.READY_UMP == 0) && (StageUMP==0) && control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_UMP]==0) + { + + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_UMP_READY,1)) + edrk.errors.e7.bits.UMP_NOT_READY |= 1; + } + if (edrk.from_shema_filter.bits.READY_UMP == 1) + count_err = 0; + } + else + { + count_err= 0; + + // ��� �������, � �� ������! + if (edrk.from_shema_filter.bits.UMP_ON_OFF==1) + if (pause_detect_error(&count_err2,TIME_WAIT_ERROR,1)) + edrk.errors.e11.bits.ERROR_UMP_NOT_OFF |= 1; + + if (edrk.from_shema_filter.bits.UMP_ON_OFF == 0) + count_err2 = 0; + + // ��� ���������� + if (edrk.ump_cmd_another_bs==0) // ������ �� �� ����� ��� + local_warning_ump = !edrk.from_shema_filter.bits.READY_UMP; + // edrk.warnings.e7.bits.UMP_NOT_READY = !edrk.from_shema_filter.bits.READY_UMP; + + + + StageUMP = 0; + } + + edrk.warnings.e7.bits.UMP_NOT_READY = filter_digital_input( edrk.warnings.e7.bits.UMP_NOT_READY, + &count_UMP_NOT_READY, + TIME_WAIT_WARNING_UMP_READY, + local_warning_ump); + + prev_SumSbor = edrk.SumSbor; +} + + +#define TIME_WAIT_BLOCK_QTV_FROM_SVU 20 +/////////////////////////////////////////////// +void detect_error_block_qtv_from_svu(void) +{ + static unsigned int count_err = 0; + + + if (edrk.from_shema.bits.SVU_BLOCK_QTV == 1 || control_station.active_array_cmd[CONTROL_STATION_CMD_BLOCK_BS]) + { + if (pause_detect_error(&count_err,TIME_WAIT_BLOCK_QTV_FROM_SVU,1)) + edrk.errors.e7.bits.SVU_BLOCK_ON_QTV |= 1; + } + else + { + count_err = 0; + } + +} + +/////////////////////////////////////////////// +void detect_error_fan(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.VENTIL_ON == 0 && (edrk.to_ing.bits.NASOS_1_ON || edrk.to_ing.bits.NASOS_2_ON)) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_FAN,1)) + edrk.errors.e5.bits.FAN |= 1; + + if (edrk.from_ing1.bits.VENTIL_ON == 1 && (edrk.to_ing.bits.NASOS_1_ON == 0 && edrk.to_ing.bits.NASOS_2_ON == 0)) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_FAN,1)) + edrk.errors.e5.bits.FAN |= 1; + + if (edrk.from_ing1.bits.VENTIL_ON == 0 && (edrk.to_ing.bits.NASOS_1_ON == 0 && edrk.to_ing.bits.NASOS_2_ON == 0)) + count_err = 0; + +} + + + +/////////////////////////////////////////////// +void detect_error_pre_ready_pump(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.NASOS_NORMA == 0) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + { +// edrk.errors.e5.bits.PRE_READY_PUMP |= 1; + edrk.warnings.e5.bits.PRE_READY_PUMP = 1; + } + + if (edrk.from_ing1.bits.NASOS_NORMA == 1) + { + count_err = 0; + edrk.warnings.e5.bits.PRE_READY_PUMP = 0; + } +} +/////////////////////////////////////////////// +void detect_error_pump_1(void) +{ + static unsigned int count_err = 0; + + // ������ �� ���, � ����� �� �������� + if (edrk.from_ing1.bits.NASOS_ON == 0 && edrk.to_ing.bits.NASOS_1_ON) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_PUMP,1)) + { +// edrk.errors.e5.bits.PUMP_1 |= 1; + edrk.warnings.e5.bits.PUMP_1 = 1; + } + } + + + // ������ �� ����, � ����� �� ����������� + if (edrk.from_ing1.bits.NASOS_ON == 1 && edrk.to_ing.bits.NASOS_1_ON==0 && edrk.SelectPump1_2==1) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_PUMP,1)) + edrk.errors.e5.bits.PUMP_1 |= 1; + + + if (edrk.from_ing1.bits.NASOS_ON == 0 && edrk.to_ing.bits.NASOS_1_ON==0 && edrk.SelectPump1_2==1) + { + // ��� ��� �� + count_err = 0; + } + + if (edrk.from_ing1.bits.NASOS_ON == 1 && edrk.to_ing.bits.NASOS_1_ON==1 && edrk.SelectPump1_2==1) + { + // ��� ��� �� + count_err = 0; + edrk.warnings.e5.bits.PUMP_1 = 0; + } + + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void detect_error_pump_2(void) +{ + static unsigned int count_err = 0; + + // ������ �� ���, � ����� �� �������� + if (edrk.from_ing1.bits.NASOS_ON == 0 && edrk.to_ing.bits.NASOS_2_ON) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_PUMP,1)) +// edrk.errors.e5.bits.PUMP_2 |= 1; + edrk.warnings.e5.bits.PUMP_2 = 1; + } + + if (edrk.from_ing1.bits.NASOS_ON == 1 && edrk.to_ing.bits.NASOS_2_ON==0 && edrk.SelectPump1_2==2) + { + if (pause_detect_error(&count_err,TIME_WAIT_ERROR_PUMP,1)) + edrk.errors.e5.bits.PUMP_2 |= 1; + } + + if (edrk.from_ing1.bits.NASOS_ON == 0 && edrk.to_ing.bits.NASOS_2_ON==0 && edrk.SelectPump1_2==2) + { + // ��� ��� �� + count_err = 0; + } + + if (edrk.from_ing1.bits.NASOS_ON == 1 && edrk.to_ing.bits.NASOS_2_ON==1 && edrk.SelectPump1_2==2) + { + // ��� ��� �� + count_err = 0; + edrk.warnings.e5.bits.PUMP_2 = 0; + } +} +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +void detect_error_op_pit(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.OP_PIT_NORMA == 0 ) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.OP_PIT |= 1; + + if (edrk.from_ing1.bits.OP_PIT_NORMA == 1 ) + count_err = 0; +} +/////////////////////////////////////////////// +void detect_error_power_upc(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.UPC_24V_NORMA == 0 ) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.POWER_UPC |= 1; + + if (edrk.from_ing1.bits.UPC_24V_NORMA == 1 ) + count_err = 0; +} +/////////////////////////////////////////////// +void detect_error_t_vipr(void) +{ + static unsigned int count_err = 0; + +// if (edrk.from_ing.bits.VIPR_TEMPER_OK == 0 ) +// if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) +// edrk.errors.e5.bits.T_VIPR_MAX |= 1; +// +// if (edrk.from_ing.bits.VIPR_TEMPER_OK == 1 ) +// pause_detect_error(&count_err,TIME_WAIT_ERROR,0); +} +/////////////////////////////////////////////// +void detect_error_ute4ka_water(void) +{ + static unsigned int count_err = 0; + + if (edrk.from_ing1.bits.OHLAD_UTE4KA_WATER == 1 ) + if (pause_detect_error(&count_err,TIME_WAIT_ERROR,1)) + edrk.errors.e5.bits.UTE4KA_WATER |= 1; + + + if (edrk.from_ing1.bits.OHLAD_UTE4KA_WATER == 0 ) + count_err = 0; +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void detect_error_from_knopka_avaria(void) +{ + edrk.errors.e5.bits.KEY_AVARIA |= edrk.from_ing1.bits.ALL_KNOPKA_AVARIA; +} +/////////////////////////////////////////////// +void detect_error_optical_bus(void) +{ +// if () + + + +} + +#define TIME_WAIT_SYNC_SIGNAL 20 // 2 sec +/////////////////////////////////////////////// +void detect_error_sync_bus(void) +{ + static unsigned int count_err = 0; + +// if (sync_data.flag_sync_1_2==0) +// edrk.errors.e7.bits.MASTER_SLAVE_SYNC |= 1; + + if (!edrk.ms.ready1) + { + edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL = 0; + count_err = 0; + return; + } + + // � ����� �� ������������� ���, �� ���� � �������, ����� �������������� + if (sync_data.timeout_sync_signal && optical_read_data.data.cmd.bit.sync_line_detect + && optical_read_data.status==1) + { + edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL = 1; + return; + } + else + edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL = 0; + + + // � ����� �� ������������� ���, � � ������� ���� ���, ����� ������ + if (sync_data.timeout_sync_signal && optical_read_data.data.cmd.bit.sync_line_detect==0 + && edrk.ms.another_bs_maybe_on && optical_read_data.status==1) + { + if (pause_detect_error(&count_err,TIME_WAIT_SYNC_SIGNAL,1)) + edrk.errors.e1.bits.NO_INPUT_SYNC_SIGNAL |= 1; + } + else + count_err = 0; + + +} +/////////////////////////////////////////////// +#pragma CODE_SECTION(detect_error_u_zpt_fast,".fast_run"); +int detect_error_u_zpt_fast(void) +{ + int err; + + err = 0; + + + if (analog.iqU_1>=edrk.iqMAX_U_ZPT_Global) + edrk.errors.e0.bits.U_1_MAX |= 1; + + if (analog.iqU_2>=edrk.iqMAX_U_ZPT_Global) + edrk.errors.e0.bits.U_2_MAX |= 1; + + + if (analog.iqU_1>=edrk.iqMAX_U_ZPT) + edrk.errors.e0.bits.U_1_MAX |= 1; + + + if (analog.iqU_2>=edrk.iqMAX_U_ZPT) + edrk.errors.e0.bits.U_2_MAX |= 1; + + + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 1 + // && edrk.to_shema.bits.QTV_ON + ) + { + if (analog.iqU_1<=edrk.iqMIN_U_ZPT) + edrk.errors.e0.bits.U_1_MIN |= 1; + + if (analog.iqU_2<=edrk.iqMIN_U_ZPT) + edrk.errors.e0.bits.U_2_MIN |= 1; + } + + err = (edrk.errors.e0.bits.U_1_MAX || edrk.errors.e0.bits.U_2_MAX || edrk.errors.e0.bits.U_1_MIN || edrk.errors.e0.bits.U_2_MIN); + return err; + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +int detect_error_u_zpt(void) +{ + int err; + + err = 0; + + if (edrk.iqMAX_U_ZPT>MINIMAL_LEVEL_ZAD_U) + { + if (analog.iqU_1>=edrk.iqMAX_U_ZPT_Global) + edrk.errors.e0.bits.U_1_MAX |= 1; + + if (analog.iqU_2>=edrk.iqMAX_U_ZPT_Global) + edrk.errors.e0.bits.U_2_MAX |= 1; + } + + + if (edrk.iqMAX_U_ZPT>MINIMAL_LEVEL_ZAD_U && edrk.from_shema_filter.bits.QTV_ON_OFF == 1 + // && edrk.to_shema.bits.QTV_ON + ) + { + if (analog.iqU_1>=edrk.iqMAX_U_ZPT) + edrk.errors.e0.bits.U_1_MAX |= 1; + + + if (analog.iqU_2>=edrk.iqMAX_U_ZPT) + edrk.errors.e0.bits.U_2_MAX |= 1; + } + + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 1 + //&& edrk.to_shema.bits.QTV_ON + ) + { + if (analog.iqU_1<=edrk.iqMIN_U_ZPT) + edrk.errors.e0.bits.U_1_MIN |= 1; + + if (analog.iqU_2<=edrk.iqMIN_U_ZPT) + edrk.errors.e0.bits.U_2_MIN |= 1; + } + + err = (edrk.errors.e0.bits.U_1_MAX || edrk.errors.e0.bits.U_2_MAX || edrk.errors.e0.bits.U_1_MIN || edrk.errors.e0.bits.U_2_MIN); + return err; + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +int detect_error_u_zpt_on_predzaryad(void) +{ + int err; + + err = 0; + + if (edrk.iqMAX_U_ZPT>MINIMAL_LEVEL_ZAD_U) + { + if (analog.iqU_1>=edrk.iqMAX_U_ZPT_Predzaryad) + edrk.errors.e0.bits.U_1_MAX |= 1; + + + if (analog.iqU_2>=edrk.iqMAX_U_ZPT_Predzaryad) + edrk.errors.e0.bits.U_2_MAX |= 1; + } + + err = (edrk.errors.e0.bits.U_1_MAX || edrk.errors.e0.bits.U_2_MAX || edrk.errors.e0.bits.U_1_MIN || edrk.errors.e0.bits.U_2_MIN); + return err; + +} + +/////////////////////////////////////////////// +#pragma CODE_SECTION(detect_error_u_in,".fast_run"); +int detect_error_u_in(void) +{ + int err; + static unsigned int count_err_on = 0; + + err = 0; + + if (edrk.iqMAX_U_ZPT>MINIMAL_LEVEL_ZAD_U) + { + if (filter.iqUin_m1>=edrk.iqMAX_U_IN) + edrk.errors.e0.bits.U_IN_MAX |= 1; + + + if (filter.iqUin_m2>=edrk.iqMAX_U_IN) + edrk.errors.e0.bits.U_IN_MAX |= 1; + } + + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 1 && edrk.SumSbor + // && edrk.to_shema.bits.QTV_ON + ) + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_QTV]==1) + { + err = 0; + } + else + { + if ((filter.iqUin_m1<=edrk.iqMIN_U_IN) || (filter.iqUin_m2<=edrk.iqMIN_U_IN)) + err = 1; + else + err = 0; + } + +#if (WORK_ON_STEND_D) + if (err) + { + if (pause_detect_error(&count_err_on,TIME_WAIT_ERROR_QTV,1)) + edrk.errors.e0.bits.U_IN_MIN |= 1; + } + else + count_err_on = 0; + + + +#else + + edrk.errors.e0.bits.U_IN_MIN |= err; +#endif + + } + + + + + + err = (edrk.errors.e0.bits.U_IN_MAX || edrk.errors.e0.bits.U_IN_MIN ); + return err; + +} +/////////////////////////////////////////////// +#define MAX_WAIT_AFTER_KVITIR 100//50 +void detect_error_all(void) +{ + unsigned int pause_after_kvitir=0; + + + if (f.count_wait_after_kvitir<=MAX_WAIT_AFTER_KVITIR) + { + f.count_wait_after_kvitir++; + pause_after_kvitir = 0; + } + else + pause_after_kvitir = 1; + + + + detect_error_ute4ka_water(); +// detect_error_t_vipr(); + detect_error_power_upc(); + detect_error_op_pit(); + + detect_error_pump_2(); + detect_error_pump_1(); + + if (edrk.warnings.e5.bits.PUMP_1 && edrk.warnings.e5.bits.PUMP_2) + { + edrk.errors.e5.bits.PUMP_1 |= 1; + edrk.errors.e5.bits.PUMP_2 |= 1; + } + + detect_error_pre_ready_pump(); + detect_error_fan(); + detect_error_qtv(); + detect_error_pre_charge(); + detect_error_block_izol(); + detect_error_nagrev(); + detect_error_ground(); + detect_error_ump(); + + + // ��� ������ � ������ �� ��������� ������ �� ������� ��, ����� �������� ������. ������ ����������! + if (pause_after_kvitir) + { + detect_error_from_knopka_avaria(); + detect_error_from_another_bs(); + } + +#if (_FLOOR6==1) + +#else + detect_error_p_water(); +#endif + + detect_error_t_water(); + detect_error_t_air(); + detect_error_t_u(); + detect_error_acdrive_bear(); + detect_error_acdrive_winding(); + detect_error_block_qtv_from_svu(); + detect_error_block_door(); + + + detect_error_optical_bus(); + detect_error_sync_bus(); + detect_alive_another_bs(); + + edrk.warning = get_common_state_warning(); + edrk.overheat = get_common_state_overheat(); + + edrk.warnings.e10.bits.WARNING_I_OUT_OVER_1_6_NOMINAL = out_I_over_1_6.overload_detected; + +// edrk.errors.e7.bits.ANOTHER_BS_ALARM |= optical_read_data.data.cmd.bit.alarm; + detect_error_sensor_rotor(); + + +} +/////////////////////////////////////////////// +void clear_errors(void) +{ + + clear_errors_master_slave(); + clear_sync_error(); + + edrk.errors.e0.all = 0; + edrk.errors.e1.all = 0; + edrk.errors.e2.all = 0; + edrk.errors.e3.all = 0; + edrk.errors.e4.all = 0; + edrk.errors.e5.all = 0; + edrk.errors.e6.all = 0; + edrk.errors.e7.all = 0; + edrk.errors.e8.all = 0; + edrk.errors.e9.all = 0; + edrk.errors.e10.all = 0; + edrk.errors.e11.all = 0; + edrk.errors.e12.all = 0; + +// edrk.errors.e0.all = 0; +// edrk.errors.e0.all = 0; + edrk.Stop = 0; + + edrk.count_lost_interrupt = 0; + + f.count_wait_after_kvitir = 0; + + +} +/////////////////////////////////////////////// +void clear_warnings(void) +{ + + edrk.warnings.e0.all = 0; + edrk.warnings.e1.all = 0; + edrk.warnings.e2.all = 0; + edrk.warnings.e3.all = 0; + edrk.warnings.e4.all = 0; + edrk.warnings.e5.all = 0; + edrk.warnings.e6.all = 0; + edrk.warnings.e7.all = 0; + edrk.warnings.e8.all = 0; + edrk.warnings.e9.all = 0; + edrk.warnings.e10.all = 0; + edrk.warnings.e11.all = 0; + edrk.warnings.e12.all = 0; +} + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +void read_plane_errors(void) +{ + if (project.controller.read.errors.bit.pwm_wdog) + edrk.errors.e9.bits.ERR_PWM_WDOG |= 1; + +#if USE_TK_0 +//af1 + if (project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_current || + project.cds_tk[0].read.sbus.time_err_tk_all.bit.tk_3210 || + project.cds_tk[0].read.sbus.lock_status_error.bit.line_err_keys_3210) + edrk.errors.e6.bits.UO2_KEYS |= 1; +//af2 + if (project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_current || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_ack || + project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_current || + project.cds_tk[0].read.sbus.time_err_tk_all.bit.tk_7654 || + project.cds_tk[0].read.sbus.lock_status_error.bit.line_err_keys_7654) + edrk.errors.e6.bits.UO3_KEYS |= 1; +#endif + +#if USE_TK_1 +//af3 + if (project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_current || + project.cds_tk[1].read.sbus.time_err_tk_all.bit.tk_3210 || + project.cds_tk[1].read.sbus.lock_status_error.bit.line_err_keys_3210) + edrk.errors.e6.bits.UO4_KEYS |= 1; +//af4 + if (project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_current || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_ack || + project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_current || + project.cds_tk[1].read.sbus.time_err_tk_all.bit.tk_7654 || + project.cds_tk[1].read.sbus.lock_status_error.bit.line_err_keys_7654) + edrk.errors.e6.bits.UO5_KEYS |= 1; +#endif + +#if USE_TK_2 +//af5 + if (project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_current || + project.cds_tk[2].read.sbus.time_err_tk_all.bit.tk_3210 || + project.cds_tk[2].read.sbus.lock_status_error.bit.line_err_keys_3210) + edrk.errors.e6.bits.UO6_KEYS |= 1; +//af6 + if (project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_current || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_ack || + project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_current || + project.cds_tk[2].read.sbus.time_err_tk_all.bit.tk_7654 || + project.cds_tk[2].read.sbus.lock_status_error.bit.line_err_keys_7654) + edrk.errors.e6.bits.UO7_KEYS |= 1; + + +#endif + +#if USE_TK_3 + + if (project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_ack || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_current || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_ack || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_current || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk2_ack || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk2_current || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk3_ack || + project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk3_current || + project.cds_tk[3].read.sbus.time_err_tk_all.bit.tk_3210 || + project.cds_tk[3].read.sbus.lock_status_error.bit.line_err_keys_3210) + edrk.errors.e6.bits.UO1_KEYS |= 1; + +#endif + +//all errors local status + + +#if USE_TK_0 + if (project.cds_tk[0].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_TK_0 |= 1; +#endif +#if USE_TK_1 + if (project.cds_tk[1].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_TK_1 |= 1; +#endif +#if USE_TK_2 + if (project.cds_tk[2].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_TK_2 |= 1; +#endif +#if USE_TK_3 + if (project.cds_tk[3].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_TK_3 |= 1; +#endif + + +#if USE_IN_0 + if (project.cds_in[0].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_IN_0 |= 1; +#endif +#if USE_IN_1 + if (project.cds_in[1].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_IN_1 |= 1; +#endif + +#if USE_OUT_0 + if (project.cds_out[0].read.sbus.lock_status_error.bit.err0_local) + edrk.errors.e4.bits.ERR_OUT_0 |= 1; +#endif + +#if USE_ADC_0 + if (project.adc[0].read.sbus.lock_status_error.all) + edrk.errors.e4.bits.ERR_ADC_0 |= 1; +#endif +#if USE_ADC_1 + if (project.adc[1].read.sbus.lock_status_error.all) + edrk.errors.e4.bits.ERR_ADC_1 |= 1; +#endif +// + if (project.controller.read.errors.bit.status_er0) + edrk.errors.e5.bits.LINE_ERR0 |= 1; + if (project.controller.read.errors.bit.errHWP_trig) + edrk.errors.e5.bits.LINE_HWP |= 1; + + if (project.controller.read.errors.bit.error_pbus + || project.controller.read.errors_buses.bit.slave_addr_error + || project.controller.read.errors_buses.bit.count_error_pbus + || project.x_parallel_bus->flags.bit.error) + edrk.errors.e6.bits.ERR_PBUS |= 1; + + if (project.controller.read.errors_buses.bit.err_sbus) + edrk.errors.e6.bits.ERR_SBUS |= 1; + +/// + +#if USE_HWP_0 + if (project.hwp[0].read.comp_s.minus.all || project.hwp[0].read.comp_s.plus.all) + edrk.errors.e1.bits.HWP_ERROR |= 1; +#endif + + +#if USE_TK_0 + if (project.all_status_plates.tk0 != component_Ready) + edrk.errors.e3.bits.NOT_READY_TK_0 |= 1; +#endif +#if USE_TK_1 + if (project.all_status_plates.tk1 != component_Ready) + edrk.errors.e3.bits.NOT_READY_TK_1 |= 1; +#endif +#if USE_TK_2 + if (project.all_status_plates.tk2 != component_Ready) + edrk.errors.e3.bits.NOT_READY_TK_2 |= 1; +#endif +#if USE_TK_3 + if (project.all_status_plates.tk3 != component_Ready) + edrk.errors.e3.bits.NOT_READY_TK_3 |= 1; +#endif + +#if USE_ADC_0 + if (project.all_status_plates.adc0 != component_Ready) + edrk.errors.e3.bits.NOT_READY_ADC_0 |= 1; +#endif +#if USE_ADC_1 + if (project.all_status_plates.adc1 != component_Ready) + edrk.errors.e3.bits.NOT_READY_ADC_1 |= 1; +#endif + +#if USE_HWP_0 + if (project.all_status_plates.hwp0 != component_Ready) + edrk.errors.e3.bits.NOT_READY_HWP_0 |= 1; +#endif + +#if USE_IN_0 + if (project.all_status_plates.in0 != component_Ready) + edrk.errors.e3.bits.NOT_READY_IN_0 |= 1; +#endif +#if USE_IN_1 + if (project.all_status_plates.in1 != component_Ready) + edrk.errors.e3.bits.NOT_READY_IN_1 |= 1; +#endif + +#if USE_OUT_0 + if (project.all_status_plates.out0 != component_Ready) + edrk.errors.e3.bits.NOT_READY_OUT_0 |= 1; +#endif +} + +int get_common_state_warning() { + return edrk.warnings.e0.all != 0 || edrk.warnings.e1.all != 0 || + edrk.warnings.e2.all != 0 || edrk.warnings.e3.all != 0 || + edrk.warnings.e4.all != 0 || edrk.warnings.e5.all != 0 || + edrk.warnings.e6.all != 0 || edrk.warnings.e7.all != 0 || + edrk.warnings.e8.all != 0 || edrk.warnings.e9.all != 0 || + edrk.warnings.e10.all != 0 || edrk.warnings.e11.all != 0 || + edrk.warnings.e12.all != 0 ? 1 : 0; +} + +int get_common_state_overheat() { + return edrk.warnings.e2.bits.T_AIR0_MAX | edrk.warnings.e2.bits.T_AIR1_MAX | + edrk.warnings.e2.bits.T_AIR2_MAX | edrk.warnings.e2.bits.T_AIR3_MAX | + edrk.warnings.e2.bits.T_UO1_MAX | edrk.warnings.e2.bits.T_UO2_MAX | + edrk.warnings.e2.bits.T_UO3_MAX | edrk.warnings.e2.bits.T_UO4_MAX | + edrk.warnings.e2.bits.T_UO5_MAX | edrk.warnings.e2.bits.T_UO6_MAX | + edrk.warnings.e2.bits.T_UO7_MAX | edrk.warnings.e2.bits.T_WATER_EXT_MAX | + edrk.warnings.e2.bits.T_WATER_INT_MAX | + edrk.errors.e2.bits.T_AIR0_MAX | edrk.errors.e2.bits.T_AIR1_MAX | + edrk.errors.e2.bits.T_AIR2_MAX | edrk.errors.e2.bits.T_AIR3_MAX | + edrk.errors.e2.bits.T_UO1_MAX | edrk.errors.e2.bits.T_UO2_MAX | + edrk.errors.e2.bits.T_UO3_MAX | edrk.errors.e2.bits.T_UO4_MAX | + edrk.errors.e2.bits.T_UO5_MAX | edrk.errors.e2.bits.T_UO6_MAX | + edrk.errors.e2.bits.T_UO7_MAX | edrk.errors.e2.bits.T_WATER_EXT_MAX | + edrk.errors.e2.bits.T_WATER_INT_MAX; +} + diff --git a/Inu/Src/main/detect_errors.h b/Inu/Src/main/detect_errors.h new file mode 100644 index 0000000..48e3126 --- /dev/null +++ b/Inu/Src/main/detect_errors.h @@ -0,0 +1,80 @@ +/* + * detect_errors.h + * + * Created on: 4 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MYLIBS_DETECT_ERRORS_H_ +#define SRC_MYLIBS_DETECT_ERRORS_H_ + + + +#define TIME_WAIT_ERROR 20 // 2 sec +#define TIME_WAIT_ERROR_QTV 100 // 10 sec +#define TIME_WAIT_ERROR_CHARGE_ANSWER 60 // 6 sec +#define TIME_WAIT_ERROR_IZOL 50 //5 sec //200 // 20 sec +#define TIME_WAIT_ERROR_PUMP 100 // 10 sec +#define TIME_WAIT_ERROR_FAN 300 // 30 sec +#define TIME_WAIT_SENSOR_ROTOR_BREAK_ALL 200 // 20 sec +#define TIME_WAIT_SENSOR_ROTOR_BREAK_DIRECTION 10 // 1 sec +#define TIME_WAIT_SENSOR_ROTOR_BREAK_ONE_SENSOR 20 // 2 sec + + + + +#define MINIMAL_LEVEL_ZAD_U 27962 // 10 V + +void clear_errors(void); +void clear_warnings(void); +void detect_error_all(void); +void read_plane_errors(void); +int detect_error_u_zpt_on_predzaryad(void); +int detect_error_u_in(void); +int detect_error_u_zpt_fast(void); + + +void detect_error_from_knopka_avaria(void); +void detect_error_ute4ka_water(void); +void detect_error_t_vipr(void); +void detect_error_power_upc(void); +void detect_error_op_pit(void); +void detect_error_p_water(void); +void detect_error_pump_2(void); +void detect_error_pump_1(void); +void detect_error_pre_ready_pump(void); +void detect_error_fan(void); +void detect_error_block_qtv_from_svu(void); + +void detect_error_predohr_vipr(void); +void detect_error_qtv(void); +void detect_error_pre_charge(void); +void detect_error_block_izol(void); +void detect_error_nagrev(void); +void detect_error_ground(void); +void detect_error_block_door(void); +void detect_error_optical_bus(void); +void detect_error_sync_bus(void); +int get_status_temper_acdrive_winding(int nc); +int get_status_temper_acdrive_winding_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_acdrive_bear(int nc); +int get_status_temper_acdrive_bear_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_air(int nc); +int get_status_temper_air_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_u(int nc); +int get_status_temper_u_with_limits(int nc, int alarm, int abnormal); +int get_status_temper_water(int nc); +int get_status_p_water_max(void); +int get_status_p_water_min(int pump_on_off); +void detect_error_t_water(void); +void detect_error_t_air(void); +void detect_error_t_u(void); +void detect_error_acdrive_winding(void); + +int get_common_state_warning(void); +int get_common_state_overheat(void); +void detect_error_sensor_rotor(void); + + + +#endif /* SRC_MYLIBS_DETECT_ERRORS_H_ */ diff --git a/Inu/Src/main/detect_errors_adc.c b/Inu/Src/main/detect_errors_adc.c new file mode 100644 index 0000000..634ea2f --- /dev/null +++ b/Inu/Src/main/detect_errors_adc.c @@ -0,0 +1,310 @@ +/* + * detect_errors_adc.c + * + * Created on: 7 ���. 2020 �. + * Author: star + */ +#include <adc_tools.h> +#include <detect_error_3_phase.h> +#include <detect_errors_adc.h> +#include <detect_phase_break.h> +#include <edrk_main.h> +#include <params_protect_adc.h> +#include <protect_levels.h> +#include "digital_filters.h" + +#include "IQmathLib.h" + +//ANALOG_PROTECT_LEVELS analog_protect_levels = ANALOG_PROTECT_LEVELS_DEFAULTS; + +//#pragma DATA_SECTION(analog_protect,".fast_vars"); +#pragma DATA_SECTION(analog_protect,".slow_vars"); +ANALOG_ADC_PROTECT analog_protect = ANALOG_ADC_PROTECT_DEFAULTS; + +//#pragma DATA_SECTION(break_Iout_1_state,".fast_vars"); +#pragma DATA_SECTION(break_Iout_1_state,".slow_vars"); +BREAK_PHASE_I break_Iout_1_state = BREAK_PHASE_I_DEFAULTS; + +//#pragma DATA_SECTION(break_Iout_2_state,".fast_vars"); +#pragma DATA_SECTION(break_Iout_2_state,".slow_vars"); +BREAK_PHASE_I break_Iout_2_state = BREAK_PHASE_I_DEFAULTS; + +int detect_error_Izpt(); +int detect_error_Ibreak(int res_num); +void init_protect_3_phase(void); + +void init_analog_protect_levels(void) { + init_protect_3_phase(); +} + +#define AMPL_TO_RMS 0.709 + +//#define LEVEL_I_1_2_DIBALANCE 1118481 // 200 A +#define LEVEL_I_1_2_DIBALANCE 1677721 // 300 A + +void init_protect_3_phase(void) { + analog_protect.in_voltage[0].setup.levels.iqVal_module_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_U_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_V_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_W_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqNominal_plus10 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_plus20 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_minus10 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_minus20 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqAsymmetry_delta = _IQ(edrk.zadanie.ZadanieU_Charge*ASYMMETRY_DELTA_PERCENTS/NORMA_ACP); + analog_protect.in_voltage[0].setup.use.all = 0; + analog_protect.in_voltage[0].setup.use.bits.phase_U = 0; + analog_protect.in_voltage[0].setup.use.bits.phase_V = 0; + analog_protect.in_voltage[0].setup.use.bits.phase_W = 0; + analog_protect.in_voltage[0].setup.use.bits.module = 0; + analog_protect.in_voltage[0].setup.use.bits.detect_minus_10 = 1; + analog_protect.in_voltage[0].setup.use.bits.detect_minus_20 = 1; + analog_protect.in_voltage[0].setup.use.bits.detect_plus_10 = 0; + analog_protect.in_voltage[0].setup.use.bits.detect_plus_20 = 1; + analog_protect.in_voltage[0].setup.use.bits.system_asymmetry_by_delta = 1; + + analog_protect.in_voltage[1].setup.levels.iqVal_module_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqVal_U_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqVal_V_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqNominal_plus10 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_plus20 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_minus10 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_minus20 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqAsymmetry_delta = _IQ(edrk.zadanie.ZadanieU_Charge*ASYMMETRY_DELTA_PERCENTS/NORMA_ACP); + analog_protect.in_voltage[1].setup.use.all = 0; + analog_protect.in_voltage[1].setup.use.bits.phase_U = 0; + analog_protect.in_voltage[1].setup.use.bits.phase_V = 0; + analog_protect.in_voltage[1].setup.use.bits.phase_W = 0; + analog_protect.in_voltage[1].setup.use.bits.module = 0; + analog_protect.in_voltage[1].setup.use.bits.detect_minus_10 = 1; + analog_protect.in_voltage[1].setup.use.bits.detect_minus_20 = 1; + analog_protect.in_voltage[1].setup.use.bits.detect_plus_10 = 0; + analog_protect.in_voltage[1].setup.use.bits.detect_plus_20 = 1; + analog_protect.in_voltage[1].setup.use.bits.system_asymmetry_by_delta = 1; + + ///////////////// + analog_protect.out_I[0].setup.levels.iqVal_module_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_U_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_V_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_W_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[0].setup.use.all = 0; + analog_protect.out_I[0].setup.use.bits.phase_U = 1; + analog_protect.out_I[0].setup.use.bits.phase_V = 1; + analog_protect.out_I[0].setup.use.bits.phase_W = 1; + analog_protect.out_I[0].setup.use.bits.break_phase = 1; + + analog_protect.out_I[1].setup.levels.iqVal_module_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_U_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_V_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_W_max = _IQ(LEVEL_ADC_I_AF / NORMA_ACP); + analog_protect.out_I[1].setup.use.all = 0; + analog_protect.out_I[1].setup.use.bits.phase_U = 1; + analog_protect.out_I[1].setup.use.bits.phase_V = 1; + analog_protect.out_I[1].setup.use.bits.phase_W = 1; + analog_protect.out_I[1].setup.use.bits.break_phase = 1; + + analog_protect.iqI_zpt_level = _IQ(LEVEL_ADC_I_ZPT / NORMA_ACP); + analog_protect.iqI_break_level = _IQ(LEVEL_ADC_I_BREAK / NORMA_ACP); +} + +#define min(x,y) (x) < (y) ? (x) : (y) +#define max(x,y) (x) > (y) ? (x) : (y) + +void reinit_protect_I_and_U_settings(void) { + int max_I = 0; + analog_protect.in_voltage[0].setup.levels.iqVal_module_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_U_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_V_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqVal_W_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[0].setup.levels.iqNominal_plus10 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_plus20 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_minus10 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqNominal_minus20 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[0].setup.levels.iqAsymmetry_delta = _IQ(edrk.zadanie.ZadanieU_Charge*ASYMMETRY_DELTA_PERCENTS/NORMA_ACP); + + analog_protect.in_voltage[1].setup.levels.iqVal_module_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqVal_U_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqVal_V_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqVal_W_max = edrk.iqMAX_U_IN; + analog_protect.in_voltage[1].setup.levels.iqNominal_plus10 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_plus20 = _IQ(edrk.zadanie.ZadanieU_Charge*PLUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_minus10 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_10_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqNominal_minus20 = _IQ(edrk.zadanie.ZadanieU_Charge*MINUS_20_PERCENT/NORMA_ACP); + analog_protect.in_voltage[1].setup.levels.iqAsymmetry_delta = _IQ(edrk.zadanie.ZadanieU_Charge*ASYMMETRY_DELTA_PERCENTS/NORMA_ACP); + + max_I = max(protect_levels.alarm_Imax_U02, protect_levels.alarm_Imax_U03); + max_I = max(max_I, protect_levels.alarm_Imax_U04); + analog_protect.out_I[0].setup.levels.iqVal_module_max = _IQ(((float)max_I) / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_U_max = _IQ(((float)protect_levels.alarm_Imax_U02) / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_V_max = _IQ(((float)protect_levels.alarm_Imax_U03) / NORMA_ACP); + analog_protect.out_I[0].setup.levels.iqVal_W_max = _IQ(((float)protect_levels.alarm_Imax_U04) / NORMA_ACP); + + max_I = max(protect_levels.alarm_Imax_U05, protect_levels.alarm_Imax_U06); + max_I = max(max_I, protect_levels.alarm_Imax_U07); + analog_protect.out_I[1].setup.levels.iqVal_module_max = _IQ(((float)max_I) / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_U_max = _IQ(((float)protect_levels.alarm_Imax_U05) / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_V_max = _IQ(((float)protect_levels.alarm_Imax_U06) / NORMA_ACP); + analog_protect.out_I[1].setup.levels.iqVal_W_max = _IQ(((float)protect_levels.alarm_Imax_U07) / NORMA_ACP); + + analog_protect.iqI_zpt_level = _IQ(protect_levels.alarm_Izpt_max / NORMA_ACP); + analog_protect.iqI_break_level = _IQ(protect_levels.alarm_Imax_U01 / NORMA_ACP); + + if (edrk.SumSbor == 0) { + analog_protect.in_voltage[0].setup.timers_inited = 0; + analog_protect.in_voltage[1].setup.timers_inited = 0; + analog_protect.out_I[0].setup.timers_inited = 0; + analog_protect.out_I[1].setup.timers_inited = 0; + } +} + +#define TIME_DETECT_WARNING_U_PREDELS 100 + +void detect_protect_adc(_iq teta_ch1, _iq teta_ch2) { + static unsigned int timer_U_in1_minus10 = 0; + static unsigned int timer_U_in1_minus20 = 0; + static unsigned int timer_U_in1_plus20 = 0; + + static unsigned int timer_U_in2_minus10 = 0; + static unsigned int timer_U_in2_minus20 = 0; + static unsigned int timer_U_in2_plus20 = 0; + + static unsigned int counter_in1_minus10 = 0; + static unsigned int counter_in2_minus10 = 0; + static unsigned int counter_in1_minus20 = 0; + static unsigned int counter_in2_minus20 = 0; + + + //������� ���������� + //0 + analog_protect.in_voltage[0].errors.all = 0; + analog_protect.in_voltage[0].iqVal_U = analog.iqUin_A1B1_rms; + analog_protect.in_voltage[0].iqVal_V = analog.iqUin_B1C1_rms; + analog_protect.in_voltage[0].iqVal_W = analog.iqUin_C1A1_rms; + analog_protect.in_voltage[0].iqVal_mod = filter.iqUin_m1; + +// analog_protect.in_voltage[0].calc(&analog_protect.in_voltage[0]); + + //1 + analog_protect.in_voltage[1].errors.all = 0; + analog_protect.in_voltage[1].iqVal_U = analog.iqUin_A2B2_rms; + analog_protect.in_voltage[1].iqVal_V = analog.iqUin_B2C2_rms; + analog_protect.in_voltage[1].iqVal_W = analog.iqUin_C2A2_rms; + analog_protect.in_voltage[1].iqVal_mod = filter.iqUin_m2; + +// analog_protect.in_voltage[1].calc(&analog_protect.in_voltage[1]); + + // + edrk.errors.e0.bits.U_A1B1_MAX |= analog_protect.in_voltage[0].errors.bits.phase_U_max; + edrk.errors.e0.bits.U_B1C1_MAX |= analog_protect.in_voltage[0].errors.bits.phase_V_max; + edrk.errors.e0.bits.U_IN_MAX |= analog_protect.in_voltage[0].errors.bits.module_max; + // + edrk.errors.e0.bits.U_A2B2_MAX |= analog_protect.in_voltage[1].errors.bits.phase_U_max; + edrk.errors.e0.bits.U_B2C2_MAX |= analog_protect.in_voltage[1].errors.bits.phase_V_max; + edrk.errors.e0.bits.U_IN_MAX |= analog_protect.in_voltage[1].errors.bits.module_max; + + edrk.warnings.e8.bits.U_IN_20_PROCENTS_HIGH = analog_protect.in_voltage[0].over_limit.bits.module_20_percent_hi || analog_protect.in_voltage[1].over_limit.bits.module_20_percent_hi; + edrk.errors.e8.bits.U_IN_20_PROCENTS_HIGH |= analog_protect.in_voltage[0].errors.bits.module_20_percent_hi; + edrk.errors.e8.bits.U_IN_20_PROCENTS_HIGH |= analog_protect.in_voltage[1].errors.bits.module_20_percent_hi; + + if (edrk.from_shema_filter.bits.QTV_ON_OFF == 1 + // && edrk.to_shema.bits.QTV_ON + ) + { + + // �������� ���������� ������ ��� ���������� ������� �������� + edrk.errors.e8.bits.U_IN_10_PROCENTS_LOW |= analog_protect.in_voltage[0].errors.bits.module_10_percent_low; + edrk.errors.e8.bits.U_IN_20_PROCENTS_LOW |= analog_protect.in_voltage[0].errors.bits.module_20_percent_low; + + edrk.errors.e8.bits.U_IN_10_PROCENTS_LOW |= analog_protect.in_voltage[1].errors.bits.module_10_percent_low; + edrk.errors.e8.bits.U_IN_20_PROCENTS_LOW |= analog_protect.in_voltage[1].errors.bits.module_20_percent_low; + + edrk.warnings.e8.bits.U_IN_10_PROCENTS_LOW = pause_detect_error(&counter_in1_minus10, + TIME_DETECT_WARNING_U_PREDELS, + analog_protect.in_voltage[0].over_limit.bits.module_10_percent_low); + + edrk.warnings.e8.bits.U_IN_10_PROCENTS_LOW = pause_detect_error(&counter_in2_minus10, + TIME_DETECT_WARNING_U_PREDELS, + analog_protect.in_voltage[1].over_limit.bits.module_10_percent_low); + + edrk.warnings.e8.bits.U_IN_20_PROCENTS_LOW = pause_detect_error(&counter_in1_minus20, + TIME_DETECT_WARNING_U_PREDELS, + analog_protect.in_voltage[0].over_limit.bits.module_20_percent_low); + + edrk.warnings.e8.bits.U_IN_20_PROCENTS_LOW = pause_detect_error(&counter_in2_minus20, + TIME_DETECT_WARNING_U_PREDELS, + analog_protect.in_voltage[1].over_limit.bits.module_20_percent_low); + + edrk.errors.e9.bits.DISBALANCE_Uin_1 |= analog_protect.in_voltage[0].errors.bits.system_asymmetry; + edrk.errors.e9.bits.DISBALANCE_Uin_2 |= analog_protect.in_voltage[1].errors.bits.system_asymmetry; + + } + else + { + edrk.warnings.e8.bits.U_IN_10_PROCENTS_LOW = 0; + edrk.warnings.e8.bits.U_IN_20_PROCENTS_LOW = 0; + } + + //�������� ���� + analog_protect.out_I[0].errors.all = 0; + analog_protect.out_I[0].iqVal_U = analog.iqIu_1; + analog_protect.out_I[0].iqVal_V = analog.iqIv_1; + analog_protect.out_I[0].iqVal_W = analog.iqIw_1; + analog_protect.out_I[0].iqVal_mod = analog.iqIm_1; + analog_protect.out_I[0].break_phase = &break_Iout_1_state; + analog_protect.out_I[0].iqTeta = teta_ch1; + +// analog_protect.out_I[0].calc(&analog_protect.out_I[0]); + + edrk.errors.e1.bits.I_UO2_MAX = analog_protect.out_I[0].errors.bits.phase_U_max; + edrk.errors.e1.bits.I_UO3_MAX = analog_protect.out_I[0].errors.bits.phase_V_max; + edrk.errors.e1.bits.I_UO4_MAX = analog_protect.out_I[0].errors.bits.phase_W_max; + + if (analog_protect.out_I[0].errors.bits.break_phase) { + edrk.errors.e8.bits.LOSS_OUTPUT_U1 = analog_protect.out_I[0].errors.bits.break_phase_U; + edrk.errors.e8.bits.LOSS_OUTPUT_V1 = analog_protect.out_I[0].errors.bits.break_phase_V; + edrk.errors.e8.bits.LOSS_OUTPUT_W1 = analog_protect.out_I[0].errors.bits.break_phase_W; + } + + analog_protect.out_I[1].errors.all = 0; + analog_protect.out_I[1].iqVal_U = analog.iqIu_2; + analog_protect.out_I[1].iqVal_V = analog.iqIv_2; + analog_protect.out_I[1].iqVal_W = analog.iqIw_2; + analog_protect.out_I[1].iqVal_mod = analog.iqIm_2; + analog_protect.out_I[1].break_phase = &break_Iout_2_state; + analog_protect.out_I[1].iqTeta = teta_ch2; + +// analog_protect.out_I[1].calc(&analog_protect.out_I[1]); + + edrk.errors.e1.bits.I_UO5_MAX = analog_protect.out_I[1].errors.bits.phase_U_max; + edrk.errors.e1.bits.I_UO6_MAX = analog_protect.out_I[1].errors.bits.phase_V_max; + edrk.errors.e1.bits.I_UO7_MAX = analog_protect.out_I[1].errors.bits.phase_W_max; + if (analog_protect.out_I[1].errors.bits.break_phase) { + edrk.errors.e8.bits.LOSS_OUTPUT_U2 = analog_protect.out_I[1].errors.bits.break_phase_U; + edrk.errors.e8.bits.LOSS_OUTPUT_V2 = analog_protect.out_I[1].errors.bits.break_phase_V; + edrk.errors.e8.bits.LOSS_OUTPUT_W2 = analog_protect.out_I[1].errors.bits.break_phase_W; + } + + edrk.errors.e8.bits.DISBALANCE_IM1_IM2 |= _IQabs(analog.iqIm_1 - analog.iqIm_2) > LEVEL_I_1_2_DIBALANCE ? 1 : 0; + + //I zpt + edrk.errors.e0.bits.I_1_MAX |= detect_error_Izpt(); + //��������� ��������� + edrk.errors.e1.bits.I_BREAK_1_MAX |= detect_error_Ibreak(1); + edrk.errors.e1.bits.I_BREAK_2_MAX |= detect_error_Ibreak(2); +} + +int detect_error_Izpt() { + return analog.iqIin_1 > analog_protect.iqI_zpt_level ? 1 : 0; +} + +int detect_error_Ibreak(int res_num) { + if (res_num == 1) { + return analog.iqIbreak_1 > analog_protect.iqI_break_level || + analog.iqIbreak_1 < -analog_protect.iqI_break_level ? 1 : 0; + } else if (res_num == 2) { + return analog.iqIbreak_2 > analog_protect.iqI_break_level || + analog.iqIbreak_2 < -analog_protect.iqI_break_level ? 1 : 0; + } else { + return 0; + } +} diff --git a/Inu/Src/main/detect_errors_adc.h b/Inu/Src/main/detect_errors_adc.h new file mode 100644 index 0000000..6aa850d --- /dev/null +++ b/Inu/Src/main/detect_errors_adc.h @@ -0,0 +1,45 @@ +/* + * detect_errors_adc.h + * + * Created on: 7 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_DETECT_ERRORS_ADC_H_ +#define SRC_MAIN_DETECT_ERRORS_ADC_H_ + +#include <detect_error_3_phase.h> + +typedef struct { + SETUP_3_PHASE_PROTECT U_in; + SETUP_3_PHASE_PROTECT I_out; + + _iq iqI_zpt; + _iq iqI_break; + +} ANALOG_PROTECT_LEVELS; + +#define ANALOG_PROTECT_LEVELS_DEFAULTS { SETUP_3_PHASE_PROTECT_DEFAULTS, \ + SETUP_3_PHASE_PROTECT_DEFAULTS, \ + 0,0} + +typedef struct { + DETECT_PROTECT_3_PHASE in_voltage[2]; + DETECT_PROTECT_3_PHASE out_I[2]; + + _iq iqI_zpt_level; + _iq iqI_break_level; +} ANALOG_ADC_PROTECT; + +#define ANALOG_ADC_PROTECT_DEFAULTS { \ + {DETECT_PROTECT_3_PHASE_DEFAULTS,DETECT_PROTECT_3_PHASE_DEFAULTS},\ + {DETECT_PROTECT_3_PHASE_DEFAULTS,DETECT_PROTECT_3_PHASE_DEFAULTS},\ + 0,0 } + +void init_analog_protect_levels(void); +void detect_protect_adc (_iq teta_ch1, _iq teta_ch2); +void reinit_protect_I_and_U_settings(void); + + +extern ANALOG_ADC_PROTECT analog_protect; +#endif /* SRC_MAIN_DETECT_ERRORS_ADC_H_ */ diff --git a/Inu/Src/main/detect_overload.c b/Inu/Src/main/detect_overload.c new file mode 100644 index 0000000..fce38dd --- /dev/null +++ b/Inu/Src/main/detect_overload.c @@ -0,0 +1,92 @@ +/* + * detect_overload.c + * + * Created on: 15 ���. 2020 �. + * Author: star + */ +#include <adc_tools.h> +#include <detect_overload.h> +#include <edrk_main.h> +#include <params_motor.h> +#include <params_pwm24.h> +#include "alg_simple_scalar.h" + +#include "IQmathLib.h" + +DETECT_OVERLOAD out_I_over_1_6 = DETECT_OVERLOAD_DEFAULTS; + +#define CALLS_IN_PWM_INT 2 //���������� ���������� �� ������ ��� (1 ��� 2) + +void init_detect_overloads(void) { + out_I_over_1_6.level_overload = _IQmpy(I_OUT_NOMINAL_IQ, _IQ(1.6)); + out_I_over_1_6.time_over_tics = (long) 15 * FREQ_PWM * CALLS_IN_PWM_INT; + out_I_over_1_6.time_latch_tics = (long) 45 * FREQ_PWM * CALLS_IN_PWM_INT; + out_I_over_1_6.tics_counter = 0; + out_I_over_1_6.overload_detected = 0; + +} + +int calc_detect_overload(DETECT_OVERLOAD *v) { + if (v->val > v->level_overload) { + v->tics_counter += 1; + if (v->tics_counter > v->time_over_tics) { v->tics_counter = v->time_over_tics;} + } else { + if (v->tics_counter > 0) { v->tics_counter -= 1; } + else {v->tics_counter = 0;} + if (v->overload_detected && v->tics_counter == 0) { + v->overload_detected = 0; + } + } + if (v->tics_counter >= v->time_over_tics) { + v->overload_detected = 1; + v->tics_counter = v->time_latch_tics; + } + return v->overload_detected; +} + +#define LIMIT_DETECT_LEVEL 16273899 // 0.97 //15938355 //95% + +void check_all_power_limits() { + _iq level_I_nominal = 0; + + //edrk.power_limit.bits.limit_by_temper = edrk.temper_limit_koeffs.code_status; + + if (edrk.Go) + { + + level_I_nominal = _IQmpy(LIMIT_DETECT_LEVEL, edrk.zadanie.iq_Izad_rmp); + + if ((filter.iqIm > level_I_nominal) || + out_I_over_1_6.overload_detected) + { + edrk.power_limit.bits.limit_Iout = 1; + } else + { + edrk.power_limit.bits.limit_Iout = 0; + } + } + else + edrk.power_limit.bits.limit_Iout = 0; + +// if (edrk.from_uom.code>1) +// edrk.power_limit.bits.limit_UOM = 1; +// else +// edrk.power_limit.bits.limit_UOM = 0; + +//filter.PowerScalar + edrk.iq_power_kw_another_bs + if ( (edrk.iq_power_kw_full_filter_abs > _IQmpy(LIMIT_DETECT_LEVEL, edrk.zadanie.iq_limit_power_zad_rmp)) + || simple_scalar1.flag_decr_mzz_power + // ������ ������ ��� ���������� ����������, ��� FOC, ��������, ����� ��������� ��������. + ) + { + edrk.power_limit.bits.limit_from_SVU = 1; + } + else + { + edrk.power_limit.bits.limit_from_SVU = 0; + } + + +} + + diff --git a/Inu/Src/main/detect_overload.h b/Inu/Src/main/detect_overload.h new file mode 100644 index 0000000..897e24a --- /dev/null +++ b/Inu/Src/main/detect_overload.h @@ -0,0 +1,32 @@ +/* + * detect_overload.h + * + * Created on: 15 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_DETECT_OVERLOAD_H_ +#define SRC_MAIN_DETECT_OVERLOAD_H_ + +typedef struct { + _iq val; //������� �������� + _iq level_overload; //������� ���������� + int overload_detected; //����������� �������� + + unsigned long time_over_tics; + unsigned long time_latch_tics; + unsigned long tics_counter; + + int (*calc)(); +} DETECT_OVERLOAD; + +#define DETECT_OVERLOAD_DEFAULTS {0,0,0, 0,0,0, \ + calc_detect_overload } + +void init_detect_overloads(void); +int calc_detect_overload(DETECT_OVERLOAD *v); +void check_all_power_limits(); + +extern DETECT_OVERLOAD out_I_over_1_6; + +#endif /* SRC_MAIN_DETECT_OVERLOAD_H_ */ diff --git a/Inu/Src/main/detect_phase_break.c b/Inu/Src/main/detect_phase_break.c new file mode 100644 index 0000000..69f0b55 --- /dev/null +++ b/Inu/Src/main/detect_phase_break.c @@ -0,0 +1,112 @@ +/* + * detect_phase_break.c + * + * Created on: 10 ���. 2020 �. + * Author: star + */ + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include <detect_phase_break.h> + + +#define CONST_IQ_2PI 105414357 // 360 �������� +#define CONST_IQ_PI2 26353589 // 90 �������� + + +static void clear_alg_vars(BREAK_PHASE_I *v); +static int calc_direction(BREAK_PHASE_I *v); +static int calc_error_if_break(BREAK_PHASE_I *v, int num, int field_direction); + +//������� ���������� ����� ������, �� ����������� ����� ���� +// 0 - ��� ������ +// 1- ���� U +// 2- ���� V +// 3- ���� W +int calc_break_I_phase(BREAK_PHASE_I *v) { + + int field_direction = 1; //1 - forward, 0 - reverse + int err = 0; + + if (v->teta > CONST_IQ_2PI) { + v->teta = CONST_IQ_2PI; + } + if(v->teta < 0) { + v->teta = 0; + } + field_direction = calc_direction(v); + if (v->iqImod < v->config.iqLevelZero) { + clear_alg_vars(v); + return 0; + } + + if (_IQabs(v->iqIu) < v->config.iqLevelZero && + _IQabs(v->iqIv + v->iqIw) < v->config.iqLevelZero && + _IQabs(v->iqIv) > v->config.iqLevelZero && _IQabs(v->iqIw) > v->config.iqLevelZero) { + err = calc_error_if_break(v, 0, field_direction); + } else { + v->latch_break_start[0] = 0; + } + if (_IQabs(v->iqIv) < v->config.iqLevelZero && + _IQabs(v->iqIu + v->iqIw) < v->config.iqLevelZero && + _IQabs(v->iqIu) > v->config.iqLevelZero && _IQabs(v->iqIw) > v->config.iqLevelZero) { + err = calc_error_if_break(v, 1, field_direction); + } else { + v->latch_break_start[1] = 0; + } + if (_IQabs(v->iqIw) < v->config.iqLevelZero && + _IQabs(v->iqIv + v->iqIu) < v->config.iqLevelZero && + _IQabs(v->iqIv) > v->config.iqLevelZero && _IQabs(v->iqIu) > v->config.iqLevelZero) { + err = calc_error_if_break(v, 2, field_direction); + } else { + v->latch_break_start[2] = 0; + } + + return err; +} + +void clear_alg_vars(BREAK_PHASE_I *v) { + int i = 0; + for (i = 0; i < 3; i++) { + v->latch_break_start[i] = 0; + v->latched_teta[i] = 0; + } +} + +int calc_direction(BREAK_PHASE_I *v) { + int direction = 1; + if (v->teta > v->prev_teta) { + if (v->teta - v->prev_teta < CONST_IQ_PI2) { direction = 1;} + else { direction = 0;} + } else { + if (v->prev_teta - v->teta < CONST_IQ_2PI) { direction = 0;} + else { direction = 1;} + } + v->prev_teta = v->teta; + return direction; +} + +int calc_error_if_break(BREAK_PHASE_I *v, int num, int field_direction) { + int err = 0; + if (v->latch_break_start[num] == 0) { + v->latch_break_start[num] = 1; + v->latched_teta[num] = v->teta; + } else { + if (field_direction == 0) { + if (v->latched_teta[num] > v->teta) { + err = v->latched_teta[num] - v->teta > CONST_IQ_PI2 ? num + 1 : 0; + } else { + err = v->teta - v->latched_teta[num] < CONST_IQ_PI2 - CONST_IQ_2PI ? num + 1 : 0; + } + } else { + if (v->latched_teta[num] < v->teta) { + err = v->teta - v->latched_teta[num] > CONST_IQ_PI2 ? num + 1 : 0; + } else { + err = v->latched_teta[num] - v->teta < CONST_IQ_PI2 - CONST_IQ_2PI ? num + 1 : 0; + } + } + } + return err; +} diff --git a/Inu/Src/main/detect_phase_break.h b/Inu/Src/main/detect_phase_break.h new file mode 100644 index 0000000..66104d8 --- /dev/null +++ b/Inu/Src/main/detect_phase_break.h @@ -0,0 +1,36 @@ +/* + * detect_phase_break.h + * + * Created on: 10 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_DETECT_PHASE_BREAK_H_ +#define SRC_MAIN_DETECT_PHASE_BREAK_H_ + +typedef struct { + _iq iqIu; + _iq iqIv; + _iq iqIw; + _iq iqImod; + _iq teta; + _iq prev_teta; + + _iq latched_teta[3]; + int latch_break_start[3]; + + struct { + _iq iqLevelZero; + + } config; + + int (*calc)(); +} BREAK_PHASE_I; + +#define BREAK_PHASE_I_DEFAULTS {0,0,0,0,0,0, \ + {0,0,0}, {0,0,0}, {0}, \ + calc_break_I_phase } + +int calc_break_I_phase(BREAK_PHASE_I *v); + +#endif /* SRC_MAIN_DETECT_PHASE_BREAK_H_ */ diff --git a/Inu/Src/main/detect_phase_break2.c b/Inu/Src/main/detect_phase_break2.c new file mode 100644 index 0000000..4cfb921 --- /dev/null +++ b/Inu/Src/main/detect_phase_break2.c @@ -0,0 +1,203 @@ +/* + * detect_phase_break.c + * + * Created on: 10 ���. 2020 �. + * Author: star + */ + +#include "IQmathLib.h" + +//#include "DSP281x_Examples.h" // DSP281x Examples Include File +//#include "DSP281x_Device.h" // DSP281x Headerfile Include File + +#include "detect_phase_break2.h" + + +#define CONST_IQ_2PI 105414357 // 2*pi 360 �������� +#define CONST_IQ_3_2PI 79060767 // 4/3 pi 270 �������� +#define CONST_IQ_PI2 26353589 // 90 �������� + + + +void check_brocken_phase(BREAK2_PHASE *v) +{ + int i; + int ph_a=0, ph_b=0, ph_c=0; + _iq plus_a, max_a; + + if ( (v->iqCh[0] >= v->iqCh[1] && v->iqCh[0] < v->iqCh[2]) + || (v->iqCh[0] >= v->iqCh[2] && v->iqCh[0] < v->iqCh[1]) ) + ph_a = 1; + else + ph_a = -1; + + if ( (v->iqCh[1] >= v->iqCh[0] && v->iqCh[1] < v->iqCh[2]) + || (v->iqCh[1] >= v->iqCh[2] && v->iqCh[1] < v->iqCh[0]) ) + ph_b = 1; + else + ph_b = -1; + + if ( (v->iqCh[2] >= v->iqCh[0] && v->iqCh[2] < v->iqCh[1]) + || (v->iqCh[2] >= v->iqCh[1] && v->iqCh[2] < v->iqCh[0]) ) + ph_c = 1; + else + ph_c = -1; + + + // plus_a = _IQ(360.0/v->config.freq_pwm * v->freq_signal); + plus_a = _IQmpy(v->config.calc_const, v->freq_signal); + + + v->sum_brocken_out[0] += plus_a*ph_a; + v->sum_brocken_out[1] += plus_a*ph_b; + v->sum_brocken_out[2] += plus_a*ph_c; + + v->plus_a = plus_a; + + for (i=0;i<3;i++) + { + if (v->sum_brocken_out[i]>=CONST_IQ_2PI) v->sum_brocken_out[i] = CONST_IQ_2PI; + if (v->sum_brocken_out[i]<=0) v->sum_brocken_out[i] = 0; + + if (v->sum_brocken_out[i]>CONST_IQ_3_2PI) + v->return_brocken_code |= (1<<i); + } + + max_a = 0; + if (v->sum_brocken_out[0]>=max_a) max_a = v->sum_brocken_out[0]; + if (v->sum_brocken_out[1]>=max_a) max_a = v->sum_brocken_out[1]; + if (v->sum_brocken_out[2]>=max_a) max_a = v->sum_brocken_out[2]; + v->sum_brocken_out[3] = max_a; // ����� �������� + +} + + + +void check_i_out_brocken(float freq) +{ + + + +} + + + + + +//������� ���������� ����� ������, �� ����������� ����� ���� +// 0 - ��� ������ +// 1- ���� U +// 2- ���� V +// 3- ���� W +int calc_break2_phase(BREAK2_PHASE *v) { + +// int field_direction = 1; //1 - forward, 0 - reverse + int err = 0; + + if (v->freq_signal==0) + { + v->sum_brocken_out[0] = 0; + v->sum_brocken_out[1] = 0; + v->sum_brocken_out[2] = 0; + v->sum_brocken_out[3] = 0; + v->brocken_i_out = 0; + } + else + { + if (_IQabs(v->iqCh[0])>v->config.minimal_level + || _IQabs(v->iqCh[1])>v->config.minimal_level + || _IQabs(v->iqCh[2])>v->config.minimal_level ) + { + check_brocken_phase(v); + } + else + { + + v->iqCh[0] = 0; + v->iqCh[1] = 0; + v->iqCh[2] = 0; + + check_brocken_phase(v); + + } + } + +// if (brocken_i_out & 0x1) +// error.power_errors.bit.phase_a_brocken |= 1; +// if (brocken_i_out & 0x2) +// error.power_errors.bit.phase_b_brocken |= 1; +// if (brocken_i_out & 0x4) +// error.power_errors.bit.phase_c_brocken |= 1; +// +// if(is_errors()) set_err_state(); + + +// +// if (v->teta > CONST_IQ_2PI) { +// v->teta = CONST_IQ_2PI; +// } +// if(v->teta < 0) { +// v->teta = 0; +// } +// field_direction = calc_direction(v); +// if (v->iqImod < v->config.iqLevelZero) { +// clear_alg_vars(v); +// return 0; +// } +// +// if (_IQabs(v->iqIu) < v->config.iqLevelZero && +// _IQabs(v->iqIv + v->iqIw) < v->config.iqLevelZero && +// _IQabs(v->iqIv) > v->config.iqLevelZero && _IQabs(v->iqIw) > v->config.iqLevelZero) { +// err = calc_error_if_break(v, 0, field_direction); +// } else { +// v->latch_break_start[0] = 0; +// } +// if (_IQabs(v->iqIv) < v->config.iqLevelZero && +// _IQabs(v->iqIu + v->iqIw) < v->config.iqLevelZero && +// _IQabs(v->iqIu) > v->config.iqLevelZero && _IQabs(v->iqIw) > v->config.iqLevelZero) { +// err = calc_error_if_break(v, 1, field_direction); +// } else { +// v->latch_break_start[1] = 0; +// } +// if (_IQabs(v->iqIw) < v->config.iqLevelZero && +// _IQabs(v->iqIv + v->iqIu) < v->config.iqLevelZero && +// _IQabs(v->iqIv) > v->config.iqLevelZero && _IQabs(v->iqIu) > v->config.iqLevelZero) { +// err = calc_error_if_break(v, 2, field_direction); +// } else { +// v->latch_break_start[2] = 0; +// } + + return err; +} + + + + +void init_break2_phase(BREAK2_PHASE *v) +{ + v->config.iq_freq = _IQ(v->config.freq_pwm / v->config.norma_freq); + v->config.calc_const = _IQdiv(CONST_IQ_2PI, v->config.iq_freq); + v->return_brocken_code = 0; + + +} + +void clear_break2_phase(BREAK2_PHASE *v) +{ + + v->iqCh[0] = 0; + v->iqCh[1] = 0; + v->iqCh[2] = 0; + v->sum_brocken_out[0] = 0; + v->sum_brocken_out[1] = 0; + v->sum_brocken_out[2] = 0; + v->sum_brocken_out[3] = 0; + v->brocken_i_out = 0; + + v->return_brocken_code = 0; +} + + + + + diff --git a/Inu/Src/main/detect_phase_break2.h b/Inu/Src/main/detect_phase_break2.h new file mode 100644 index 0000000..c32608e --- /dev/null +++ b/Inu/Src/main/detect_phase_break2.h @@ -0,0 +1,50 @@ +/* + * detect_phase_break2.h + * + * Created on: 10 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_DETECT_PHASE_BREAK2_H_ +#define SRC_MAIN_DETECT_PHASE_BREAK2_H_ + +#include "IQmathLib.h" + + +typedef struct { + _iq iqCh[3]; + _iq sum_brocken_out[4]; // 4 ������� - ��� ����. �� ������ ���� + _iq freq_signal; + + int brocken_i_out; + int return_brocken_code; + _iq plus_a; + + + struct { + unsigned int freq_pwm; + unsigned int norma_freq; + + _iq minimal_level; + _iq calc_const; + _iq iq_freq; + } config; + + int (*calc)(); + void (*init)(); + void (*clear_error)(); + +} BREAK2_PHASE; + +#define BREAK2_PHASE_DEFAULTS {{0,0,0},\ + {0,0,0,0},\ + 0,0,0,0,\ + 0,0,0,0,0, \ + calc_break2_phase, init_break2_phase, clear_break2_phase } + +void check_brocken_phase(BREAK2_PHASE *v); +int calc_break2_phase(BREAK2_PHASE *v); +void init_break2_phase(BREAK2_PHASE *v); +void clear_break2_phase(BREAK2_PHASE *v); + +#endif /* SRC_MAIN_DETECT_PHASE_BREAK2_H_ */ diff --git a/Inu/Src/main/digital_filters.c b/Inu/Src/main/digital_filters.c new file mode 100644 index 0000000..a94d46b --- /dev/null +++ b/Inu/Src/main/digital_filters.c @@ -0,0 +1,103 @@ +/* + * digital_filters.c + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + + + +//////////////////////////////////////////////////////////////////// +unsigned int filter_digital_input(unsigned int prev_valus, unsigned int *c_plus, unsigned int max_wait, unsigned int flag) +{ + + if (flag) + { + if ((*c_plus)>=max_wait) + { + return 1; + } + else + { + (*c_plus)++; + return (prev_valus); + } + } + else + { + if ((*c_plus)==0) + { + return 0; + } + else + { + (*c_plus)--; + return (prev_valus); + } + } +} +/////////////////////////////////////////////////////////////////// +//TODO: may be move to detect_errors.c +unsigned int pause_detect_error(unsigned int *c_err, unsigned int max_wait,unsigned int flag) +{ + if (flag) + { + if ((*c_err)>=max_wait) + { + return 1; + } + else + { + (*c_err)++; + return 0; + } + } + else + { + (*c_err) = 0; + return 0; + + } + + + +} + + + +////////////////////////////////////////////////////////// + + + +unsigned int filter_err_count(unsigned int *counter, unsigned int max_errors, unsigned int err, unsigned int cmd) +{ + if (cmd==1) + { + (*counter) = 0; + return 0; + } + + if (err) + { + if ((*counter)>=max_errors) + return 1; + else + (*counter)++; + + return 0; + } + + if (err==0) + { + if ((*counter)==0) + return 0; + else + (*counter)--; + + return 0; + } + return 0; +} + + + diff --git a/Inu/Src/main/digital_filters.h b/Inu/Src/main/digital_filters.h new file mode 100644 index 0000000..bc24cac --- /dev/null +++ b/Inu/Src/main/digital_filters.h @@ -0,0 +1,19 @@ +/* + * digital_filters.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_DIGITAL_FILTERS_H_ +#define SRC_MAIN_DIGITAL_FILTERS_H_ + +unsigned int filter_digital_input(unsigned int prev_valus, unsigned int *c_plus, unsigned int max_wait, unsigned int flag); + +unsigned int pause_detect_error(unsigned int *c_err, unsigned int max_wait,unsigned int flag); + + +unsigned int filter_err_count(unsigned int *counter, unsigned int max_errors, unsigned int err, unsigned int cmd); + + +#endif /* SRC_MAIN_DIGITAL_FILTERS_H_ */ diff --git a/Inu/Src/main/edrk_main.c b/Inu/Src/main/edrk_main.c new file mode 100644 index 0000000..c89a473 --- /dev/null +++ b/Inu/Src/main/edrk_main.c @@ -0,0 +1,2736 @@ +#include <281xEvTimersInit.h> +#include <adc_tools.h> +#include <alg_simple_scalar.h> +#include <break_regul.h> +#include <calc_rms_vals.h> +#include <calc_tempers.h> +#include <can_bs2bs.h> +#include <detect_errors.h> +#include <detect_errors_adc.h> +#include <detect_overload.h> +#include <detect_overload.h> +#include <edrk_main.h> +//#include <log_to_mem.h> +#include <math.h> +#include <message_modbus.h> +#include <modbus_hmi.h> +#include <modbus_hmi_update.h> +#include <modbus_svu_update.h> +#include <optical_bus.h> +#include <overheat_limit.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 <pump_control.h> +#include <PWMTMSHandle.h> +#include <PWMTools.h> +#include <sync_tools.h> +#include <v_rotor.h> +#include <vector.h> + +#include "mathlib.h" +#include "params_hwp.h" + +//#include "modbus_fill_table.h" + +#include "big_dsp_module.h" +#include "control_station.h" +#include "CAN_Setup.h" + +#include "global_time.h" +#include "IQmathLib.h" +#include "mathlib.h" + +#include "modbus_table_v2.h" +#include "oscil_can.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" +#include "alg_pll.h" +#include "vector_control.h" +#include "CRC_Functions.h" +#include "RS_Functions.h" +#include "xp_project.h" +#include "sbor_shema.h" +#include "alarm_log_can.h" +#include "pwm_test_lines.h" +#include "master_slave.h" +#include "xp_write_xpwm_time.h" +#include "v_rotor_22220.h" +#include "log_to_memory.h" +#include "log_params.h" +#include "build_version.h" +#include "profile_interrupt.h" +#include "limit_power.h" +#include "pwm_logs.h" +#include "logs_hmi.h" +#include "alarm_log.h" +#include "can_protocol_ukss.h" + +#include "ukss_tools.h" +#include "another_bs.h" +#include "temper_p_tools.h" +#include "digital_filters.h" +#include "pll_tools.h" +#include "ramp_zadanie_tools.h" +#include "uom_tools.h" +#include "synhro_tools.h" + +#if (_SIMULATE_AC==1) +#include "sim_model.h" +#endif +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +//#pragma DATA_SECTION(ccc, ".slow_vars") +//int ccc[40] = {0,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1}; + + + +#pragma DATA_SECTION(f, ".slow_vars") +FLAG f = FLAG_DEFAULTS; + +int cur1=0; +int cur2=0; + +unsigned int old_time_edrk1 = 0, old_time_edrk2 = 0, prev_flag_special_mode_rs = 0; + +#pragma DATA_SECTION(edrk, ".slow_vars") +EDRK edrk = EDRK_DEFAULT; + + + + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ������� �������� �� ��������� PLUS, MINUS +// ���� ������ ������ ����� +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +void set_oborots_from_zadat4ik(void) +{ +static unsigned int old_time_edrk3 = 0, prev_PROVOROT; + + + if (!(detect_pause_milisec(100,&old_time_edrk3))) + return; + +} + + +////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ��������� �������� ����� +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +#define RASCEPITEL_MANUAL_ALWAYS_ON_2 1 // 1 +#define TIME_ON_OFF_FOR_IMITATION_RASCEPITEL 50 // 5 ���. +#define TIME_FILTER_UMP_SIGNALS 5 // 0.5 ��� +#define TIME_FILTER_ALL_SIGNALS 5 // 0.5 ��� + + +#pragma DATA_SECTION(count_wait_filter, ".slow_vars") +unsigned int count_wait_filter[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; +unsigned int counter_imit_rascepitel = 0; + +void update_input_edrk(void) +{ + static unsigned int flag_imit_rascepitel = 0; + static int st1=0; + +// ANOTHER PCH + edrk.from_second_pch.bits.RASCEPITEL = !FROM_ING_ANOTHER_RASCEPITEL; + edrk.from_second_pch.bits.MASTER = FROM_ING_ANOTHER_MASTER_PCH; + + +// ING +#if (_FLOOR6==1) + + if (st1==0) + { + edrk.from_zadat4ik.all = 0; + edrk.from_vpu.all = 0; + + edrk.from_ing1.bits.ALL_KNOPKA_AVARIA = 0;//!FROM_ALL_KNOPKA_AVARIA; + edrk.from_ing1.bits.BLOCK_IZOL_AVARIA = 0;//!FROM_ING_BLOCK_IZOL_AVARIA; + edrk.from_ing1.bits.BLOCK_IZOL_NORMA = 1;//!FROM_ING_BLOCK_IZOL_NORMA; + edrk.from_ing1.bits.LOCAL_REMOUTE = 1;//0;//!FROM_ING_LOCAL_REMOUTE; + edrk.from_ing1.bits.NAGREV_ON = 1;//!FROM_ING_NAGREV_ON; + edrk.from_ing1.bits.NASOS_NORMA = 1;//!FROM_ING_NASOS_NORMA; + edrk.from_ing1.bits.NASOS_ON = 0;//!FROM_ING_NASOS_ON; + edrk.from_ing1.bits.OHLAD_UTE4KA_WATER = 0;//!FROM_ING_OHLAD_UTE4KA_WATER; + edrk.from_ing1.bits.UPC_24V_NORMA = 1;//!FROM_ING_UPC_24V_NORMA; + edrk.from_ing1.bits.OP_PIT_NORMA = 1;//!FROM_ING_OP_PIT_NORMA; + edrk.from_ing1.bits.VENTIL_ON = 0;//!FROM_ING_VENTIL_ON; + edrk.from_ing1.bits.VIPR_PREDOHR_NORMA = 1;//!FROM_ING_VIPR_PREDOHR_NORMA; + + edrk.from_ing1.bits.ZARYAD_ON = 0;//!FROM_ING_ZARYAD_ON; + edrk.from_ing1.bits.ZAZEML_OFF = 1;//!FROM_ING_ZAZEML_OFF; + edrk.from_ing1.bits.ZAZEML_ON = 0;//!FROM_ING_ZAZEML_ON; + + edrk.from_ing2.bits.KEY_MINUS = 0;//FROM_ING_OBOROTS_MINUS; + edrk.from_ing2.bits.KEY_PLUS = 0;//!FROM_ING_OBOROTS_PLUS; + edrk.from_ing2.bits.KEY_KVITIR = 0;//FROM_ING_LOCAL_KVITIR; + + edrk.from_ing2.bits.KEY_SBOR = 0;//FROM_ING_SBOR_SHEMA; + edrk.from_ing2.bits.KEY_RAZBOR = 0;//FROM_ING_RAZBOR_SHEMA; + + // edrk.from_ing1.bits.RASCEPITEL_ON = 0;//FROM_ING_RASCEPITEL_ON_OFF; + + // edrk.from_ing2.bits.SOST_ZAMKA = !edrk.to_ing.bits.BLOCK_KEY_OFF;//1;//!FROM_ING_SOST_ZAMKA; + + + // SHEMA + edrk.from_shema.bits.RAZBOR_SHEMA = 0;//FROM_BSU_RAZBOR_SHEMA; + edrk.from_shema.bits.SBOR_SHEMA = 0;//FROM_BSU_SBOR_SHEMA; + + edrk.from_shema.bits.ZADA_DISPLAY = 0;//!FROM_BSU_ZADA_DISPLAY; + edrk.from_shema.bits.SVU = 0;//!FROM_BSU_SVU; + // edrk.from_shema.bits.KNOPKA_AVARIA = FROM_ALL_KNOPKA_AVARIA; + edrk.from_shema.bits.QTV_ON_OFF = 0;//!FROM_SHEMA_QTV_ON_OFF; + edrk.from_shema.bits.UMP_ON_OFF = 0;//!FROM_SHEMA_UMP_ON_OFF; + edrk.from_shema.bits.READY_UMP = 1;//!FROM_SHEMA_READY_UMP; + edrk.from_shema.bits.SVU_BLOCK_QTV = 0;//!FROM_SVU_BLOCK_QTV; + st1 = 1; + } + + // �������� ����������� + if (edrk.to_ing.bits.RASCEPITEL_ON) + flag_imit_rascepitel = 1; + if (edrk.to_ing.bits.RASCEPITEL_OFF) + flag_imit_rascepitel = 0; + + edrk.from_ing1.bits.RASCEPITEL_ON = imit_signals_rascepitel(&counter_imit_rascepitel, TIME_ON_OFF_FOR_IMITATION_RASCEPITEL, flag_imit_rascepitel, 0); + ///// + + + edrk.from_ing2.bits.SOST_ZAMKA = !edrk.to_ing.bits.BLOCK_KEY_OFF; + if (edrk.to_ing.bits.NASOS_2_ON || edrk.to_ing.bits.NASOS_1_ON) + { + edrk.from_ing1.bits.VENTIL_ON = 1; + edrk.from_ing1.bits.NASOS_ON = 1; + } + else + { + edrk.from_ing1.bits.VENTIL_ON = 0; + edrk.from_ing1.bits.NASOS_ON = 0; + } +#else + + + // ZADAT4IK + if (control_station.alive_control_station[CONTROL_STATION_ZADATCHIK_CAN]) + edrk.from_zadat4ik.all = Unites[ZADATCHIK_CAN][16]; + else + edrk.from_zadat4ik.all = 0; + + if (control_station.alive_control_station[CONTROL_STATION_VPU_CAN]) + edrk.from_vpu.all = Unites[VPU_CAN][16]; + else + edrk.from_vpu.all = 0; + + + + edrk.from_ing1.bits.ALL_KNOPKA_AVARIA = !FROM_ALL_KNOPKA_AVARIA; + edrk.from_ing1.bits.BLOCK_IZOL_AVARIA = !FROM_ING_BLOCK_IZOL_AVARIA; + edrk.from_ing1.bits.BLOCK_IZOL_NORMA = !FROM_ING_BLOCK_IZOL_NORMA; + edrk.from_ing1.bits.LOCAL_REMOUTE = !FROM_ING_LOCAL_REMOUTE; + edrk.from_ing1.bits.NAGREV_ON = !FROM_ING_NAGREV_ON; + edrk.from_ing1.bits.NASOS_NORMA = !FROM_ING_NASOS_NORMA; + edrk.from_ing1.bits.NASOS_ON = !FROM_ING_NASOS_ON; + edrk.from_ing1.bits.OHLAD_UTE4KA_WATER = !FROM_ING_OHLAD_UTE4KA_WATER; + edrk.from_ing1.bits.UPC_24V_NORMA = !FROM_ING_UPC_24V_NORMA; + edrk.from_ing1.bits.OP_PIT_NORMA = !FROM_ING_OP_PIT_NORMA; + edrk.from_ing1.bits.VENTIL_ON = !FROM_ING_VENTIL_ON; + edrk.from_ing1.bits.VIPR_PREDOHR_NORMA = !FROM_ING_VIPR_PREDOHR_NORMA; + + edrk.from_ing1.bits.ZARYAD_ON = !FROM_ING_ZARYAD_ON; + edrk.from_ing1.bits.ZAZEML_OFF = !FROM_ING_ZAZEML_OFF; + edrk.from_ing1.bits.ZAZEML_ON = !FROM_ING_ZAZEML_ON; + + edrk.from_ing2.bits.KEY_MINUS = FROM_ING_OBOROTS_MINUS; + edrk.from_ing2.bits.KEY_PLUS = !FROM_ING_OBOROTS_PLUS; + edrk.from_ing2.bits.KEY_KVITIR = FROM_ING_LOCAL_KVITIR; + + edrk.from_ing2.bits.KEY_SBOR = FROM_ING_SBOR_SHEMA; + edrk.from_ing2.bits.KEY_RAZBOR = FROM_ING_RAZBOR_SHEMA; + +#if(RASCEPITEL_MANUAL_ALWAYS_ON_2) + + // �������� ����������� + if (edrk.to_ing.bits.RASCEPITEL_ON) + flag_imit_rascepitel = 1; + if (edrk.to_ing.bits.RASCEPITEL_OFF) + flag_imit_rascepitel = 0; + + edrk.from_ing1.bits.RASCEPITEL_ON = imit_signals_rascepitel(&counter_imit_rascepitel, TIME_ON_OFF_FOR_IMITATION_RASCEPITEL, flag_imit_rascepitel, 0); + +#else + edrk.from_ing1.bits.RASCEPITEL_ON = FROM_ING_RASCEPITEL_ON_OFF; +#endif + edrk.from_ing2.bits.SOST_ZAMKA = !FROM_ING_SOST_ZAMKA; + + +// SHEMA + edrk.from_shema.bits.RAZBOR_SHEMA = FROM_BSU_RAZBOR_SHEMA; + edrk.from_shema.bits.SBOR_SHEMA = FROM_BSU_SBOR_SHEMA; + + if (edrk.from_shema.bits.RAZBOR_SHEMA==1 && edrk.from_shema.bits.SBOR_SHEMA) + { + // ������ �� ��������� � �������������� ������� + edrk.from_shema.bits.RAZBOR_SHEMA = 0; + edrk.from_shema.bits.SBOR_SHEMA = 0; + } + edrk.from_shema_filter.bits.RAZBOR_SHEMA = filter_digital_input( edrk.from_shema_filter.bits.RAZBOR_SHEMA, + &count_wait_filter[0], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.RAZBOR_SHEMA); + + + edrk.from_shema_filter.bits.SBOR_SHEMA = filter_digital_input( edrk.from_shema_filter.bits.SBOR_SHEMA, + &count_wait_filter[1], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.SBOR_SHEMA); + + edrk.from_shema.bits.ZADA_DISPLAY = !FROM_BSU_ZADA_DISPLAY; + edrk.from_shema_filter.bits.ZADA_DISPLAY = filter_digital_input( edrk.from_shema_filter.bits.ZADA_DISPLAY, + &count_wait_filter[2], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.ZADA_DISPLAY); + + edrk.from_shema.bits.SVU = !FROM_BSU_SVU; + edrk.from_shema_filter.bits.SVU = filter_digital_input( edrk.from_shema_filter.bits.SVU, + &count_wait_filter[3], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.SVU); + + +// edrk.from_shema.bits.KNOPKA_AVARIA = FROM_ALL_KNOPKA_AVARIA; + edrk.from_shema.bits.QTV_ON_OFF = !FROM_SHEMA_QTV_ON_OFF; + edrk.from_shema_filter.bits.QTV_ON_OFF = filter_digital_input( edrk.from_shema_filter.bits.QTV_ON_OFF, + &count_wait_filter[4], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.QTV_ON_OFF); + + + + /// ���������� FROM_SHEMA_UMP_ON_OFF +// edrk.local_ump_on_off = !FROM_SHEMA_UMP_ON_OFF; +// +// if (edrk.local_ump_on_off) +// { +// if (edrk.local_ump_on_off_count>=TIME_FILTER_UMP_SIGNALS) +// edrk.from_shema.bits.UMP_ON_OFF = 1; +// else +// edrk.local_ump_on_off_count++; +// } +// else +// { +// if (edrk.local_ump_on_off_count==0) +// edrk.from_shema.bits.UMP_ON_OFF = 0; +// else +// edrk.local_ump_on_off_count--; +// } +// +// + edrk.from_shema.bits.UMP_ON_OFF = !FROM_SHEMA_UMP_ON_OFF; + edrk.from_shema_filter.bits.UMP_ON_OFF = filter_digital_input( edrk.from_shema_filter.bits.UMP_ON_OFF, + &count_wait_filter[5], + TIME_FILTER_UMP_SIGNALS, + edrk.from_shema.bits.UMP_ON_OFF); + + + + + + + /// ���������� FROM_SHEMA_READY_UMP +// edrk.local_ready_ump = !FROM_SHEMA_READY_UMP; +// +// if (edrk.local_ready_ump) +// { +// if (edrk.local_ready_ump_count>=TIME_FILTER_UMP_SIGNALS) +// edrk.from_shema.bits.READY_UMP = 1; +// else +// edrk.local_ready_ump_count++; +// } +// else +// { +// if (edrk.local_ready_ump_count==0) +// edrk.from_shema.bits.READY_UMP = 0; +// else +// edrk.local_ready_ump_count--; +// } +// + + edrk.from_shema.bits.READY_UMP = !FROM_SHEMA_READY_UMP; + edrk.from_shema_filter.bits.READY_UMP = filter_digital_input( edrk.from_shema_filter.bits.READY_UMP, + &count_wait_filter[6], + TIME_FILTER_UMP_SIGNALS, + edrk.from_shema.bits.READY_UMP); + + + + edrk.from_shema.bits.SVU_BLOCK_QTV = !FROM_SVU_BLOCK_QTV; + edrk.from_shema_filter.bits.SVU_BLOCK_QTV = filter_digital_input( edrk.from_shema_filter.bits.SVU_BLOCK_QTV, + &count_wait_filter[7], + TIME_FILTER_ALL_SIGNALS, + edrk.from_shema.bits.SVU_BLOCK_QTV); + +#endif +} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ����������� ������ �������� ������ �� ������� +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +void get_where_oborots(void) +{ + +//// if (CAN_timeout[get_real_out_mbox(MPU_TYPE_BOX,0)-1]==0) +// if (CAN_timeout[get_real_in_mbox(MPU_TYPE_BOX,0)]==0) +// { +// edrk.W_from_SVU = modbus_table_can_in[14].all; +// edrk.W_from_DISPLAY = modbus_table_can_in[16].all; +// } +// else +// { +// edrk.W_from_SVU = 0; +// edrk.W_from_DISPLAY = 0; +// } +// +// +// +// +// if (edrk.from_shema.bits.SVU) +// { +// edrk.W_from_all = edrk.W_from_SVU; +// edrk.W_from_ZADAT4IK = edrk.W_from_all; +// } +// else +// { +// if (edrk.from_shema.bits.ZADA_DISPLAY) +// { +// edrk.W_from_all = edrk.W_from_DISPLAY; +// edrk.W_from_ZADAT4IK = edrk.W_from_all; +// } +// else +// edrk.W_from_all = edrk.W_from_ZADAT4IK; +// } + +} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// + +unsigned int toggle_status_lamp(unsigned int bb1, unsigned int flag) +{ + + if (bb1==1 && flag==0) + { + return 0; + } + + if (bb1==0 && flag==0) + { + return 0; + } + + if (bb1==1 && flag==1) + { + return 0; + } + + if (bb1==0 && flag==1) + { + return 1; + } + return 0; +} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ���������� �������� ������ +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +void update_output_edrk(void) +{ + unsigned int b; + static unsigned int time_toggle1=0,time_toggle2=0; + +//to ingetim + + TO_ING_NAGREV_OFF = !edrk.to_ing.bits.NAGREV_OFF; + TO_ING_NASOS_1_ON = !edrk.to_ing.bits.NASOS_1_ON; + TO_ING_NASOS_2_ON = !edrk.to_ing.bits.NASOS_2_ON; + // TO_ING_RESET_BLOCK_IZOL = !edrk.to_ing.bits.RESET_BLOCK_IZOL; + TO_ING_SMALL_LAMPA_AVARIA = edrk.to_ing.bits.SMALL_LAMPA_AVARIA; + + if (edrk.disable_rascepitel_work) + { + + } + else + { + TO_ING_RASCEPITEL_OFF = !edrk.to_ing.bits.RASCEPITEL_OFF; + TO_ING_RASCEPITEL_ON = !edrk.to_ing.bits.RASCEPITEL_ON; + } + +// ANOTHER PCH + TO_SECOND_PCH_MASTER = edrk.to_second_pch.bits.MASTER; + TO_SECOND_PCH_ALARM = !edrk.to_second_pch.bits.ALARM; + + + +//to_shema +// +//#if (ENABLE_USE_QTV==1) +// TO_STEND_QM_ON_INVERS = !edrk.to_shema.bits.QTV_ON; +//#endif + + + TO_ING_LAMPA_ZARYAD = !edrk.Status_Ready.bits.Batt; + TO_ING_ZARYAD_ON = !edrk.to_ing.bits.ZARYAD_ON; + TO_ING_BLOCK_KEY_OFF = !edrk.to_ing.bits.BLOCK_KEY_OFF; + +#if (MODE_QTV_UPRAVLENIE==1) + TO_SHEMA_QTV_ON_OFF = !edrk.to_shema.bits.QTV_ON_OFF; +#endif + + +#if (MODE_QTV_UPRAVLENIE==2) + TO_SHEMA_QTV_OFF = !edrk.to_shema.bits.QTV_OFF; + TO_SHEMA_QTV_ON = !edrk.to_shema.bits.QTV_ON; +#endif + + TO_SHEMA_ENABLE_QTV = !edrk.to_shema.bits.ENABLE_QTV; + TO_SHEMA_UMP_ON_OFF = !edrk.to_shema.bits.UMP_ON_OFF; + + + + + + + +//lamps APL +// if (edrk.Sbor)// && edrk.from_ing.bits2.GED_NAMAGNI4EN==0) +// { +// if (edrk.Status_Ready.bits.ready5==0) +// edrk.to_zadat4ik.APL_LAMS0.bits.SBOR_SIL_SHEMA = 1; +// else +// edrk.to_zadat4ik.APL_LAMS0.bits.SBOR_SIL_SHEMA = 0; +// } +// else +// { +// edrk.to_zadat4ik.APL_LAMS0.bits.SBOR_SIL_SHEMA = 0; +// } + + + + edrk.to_vpu.BIG_LAMS.bits.GOTOV2 = edrk.Status_Ready.bits.ready_final; + edrk.to_vpu.BIG_LAMS.bits.PEREGRUZKA = edrk.to_zadat4ik.BIG_LAMS.bits.OGRAN_POWER; + edrk.to_vpu.BIG_LAMS.bits.PODDERG_OBOROTS = 0;// + edrk.to_vpu.BIG_LAMS.bits.VPU = edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU; + +} + + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +// �������� ��������� +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +void update_lamp_alarm(void) +{ + if ((edrk.errors.e0.all) + || (edrk.errors.e1.all) + || (edrk.errors.e2.all) + || (edrk.errors.e3.all) + || (edrk.errors.e4.all) + || (edrk.errors.e5.all) + || (edrk.errors.e6.all) + || (edrk.errors.e7.all) + || (edrk.errors.e8.all) + || (edrk.errors.e9.all) + || (edrk.errors.e10.all) + || (edrk.errors.e11.all) + || (edrk.errors.e12.all) + ) + { + edrk.to_ing.bits.SMALL_LAMPA_AVARIA = 1; + // edrk.to_second_pch.bits.ALARM = 1; + edrk.summ_errors = 1; + edrk.Stop |= 1; + } + else + { + edrk.to_ing.bits.SMALL_LAMPA_AVARIA = 0; + edrk.to_second_pch.bits.ALARM = 0; + edrk.summ_errors = 0; + } + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// + + + + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +#define TIME_WAIT_RELE_QTV_ON 30 //2 sec +#define TIME_WAIT_RELE_QTV_OFF 30 //2 sec + +#define TIME_WAIT_ANSWER_QTV_ON TIME_WAIT_ERROR_QTV //150 //15 sec +#define TIME_WAIT_ANSWER_QTV_OFF 50 //4 sec + +/////////////////////////////////////////////// +int qtv_on_off(unsigned int flag) +{ +static unsigned int time_wait_rele_on_qtv=0; +static unsigned int time_wait_rele_off_qtv=0; +static unsigned int time_wait_answer_on_qtv=0; +static unsigned int time_wait_answer_off_qtv=0; +static unsigned int count_err_on = 0; + + +int cmd_qtv=0;//,cmd_p2=0; +static int QTV_Ok = 0; +static int prev_error = 0; + + + cmd_qtv = 0; +// cmd_p2 = 0; + + if ( flag==1 && edrk.summ_errors==0) + { + cmd_qtv = 1; + } + else + { + cmd_qtv = 0; + } + + + + edrk.cmd_to_qtv = cmd_qtv; + + if (cmd_qtv) + { + edrk.to_shema.bits.ENABLE_QTV = 1; + edrk.to_shema.bits.QTV_OFF = 1; + + if ((pause_detect_error(&time_wait_rele_on_qtv,TIME_WAIT_RELE_QTV_ON,1)==0) && edrk.from_shema_filter.bits.QTV_ON_OFF==0) + { +#if (MODE_QTV_UPRAVLENIE==2) + edrk.to_shema.bits.QTV_ON = 1; +#endif +#if (MODE_QTV_UPRAVLENIE==1) + edrk.to_shema.bits.QTV_ON_OFF = 1; +#endif + } + else + edrk.to_shema.bits.QTV_ON = 0; + + + if (pause_detect_error(&time_wait_answer_on_qtv,TIME_WAIT_ANSWER_QTV_ON,1)==0) + { + + if (edrk.from_shema_filter.bits.QTV_ON_OFF==1) + QTV_Ok = 1; + + } + else + { + + // ���� ������� �� ���, �� ����� ������� �� ������ + if (edrk.from_shema_filter.bits.QTV_ON_OFF==0) + { +#if (WORK_ON_STEND_D) + if (pause_detect_error(&count_err_on,TIME_WAIT_ANSWER_QTV_ON,1)) + { + edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER |= 1; + QTV_Ok = 0; + } +#else + edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER |= 1; + QTV_Ok = 0; +#endif + } + else + count_err_on = 0; + + } + + time_wait_rele_off_qtv = 0; + time_wait_answer_off_qtv = 0; + } + else + { + QTV_Ok = 0; + edrk.to_shema.bits.ENABLE_QTV = 0; + time_wait_rele_on_qtv = 0; + time_wait_answer_on_qtv = 0; + + edrk.to_shema.bits.QTV_ON = 0; + + edrk.to_shema.bits.QTV_ON_OFF = 0; + +// if (pause_detect_error(&time_wait_rele_off_qtv,TIME_WAIT_RELE_QTV_OFF,1)==0) +// edrk.to_shema.bits.QTV_OFF = 1; +// else + edrk.to_shema.bits.QTV_OFF = 0; + + + if (pause_detect_error(&time_wait_answer_off_qtv,TIME_WAIT_ANSWER_QTV_OFF,1)==0) + { + + } + else + { + if (edrk.from_shema_filter.bits.QTV_ON_OFF==1) + edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER |= 1; + } + + + if (prev_error!=edrk.summ_errors && edrk.summ_errors) + { + if (pause_detect_error(&time_wait_rele_off_qtv,TIME_WAIT_RELE_QTV_OFF,1)==1) + time_wait_rele_off_qtv = 0; + } + + + } + + prev_error = edrk.summ_errors; + return (QTV_Ok); + + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +void detect_kvitir_from_all(void) +{ + + static int prev_kvitir=0; + + edrk.Kvitir = control_station.active_array_cmd[CONTROL_STATION_CMD_CHECKBACK] + || edrk.from_ing2.bits.KEY_KVITIR + || edrk.from_zadat4ik.bits.KVITIR; + + /* + if (edrk.RemouteFromRS) + edrk.Kvitir = edrk.KvitirRS; + + if (edrk.RemouteFromVPU) + edrk.Kvitir = edrk.KvitirVPU; + + if (edrk.RemouteFromDISPLAY) + edrk.Kvitir = edrk.from_display.bits.KVITIR;//edrk.KvitirDISPLAY; + + if (edrk.RemouteFromMPU) + edrk.Kvitir = edrk.KvitirMPU; +*/ + + if (edrk.Kvitir==1 && prev_kvitir==0) + { + + if (edrk.Status_Ready.bits.ready_final==0 && edrk.Go==0 && edrk.Stop == 1) + { + edrk.KvitirProcess = 1; + project.clear_errors_all_plates(); + clear_errors(); + edrk.KvitirProcess = 0; + } + clear_warnings(); + /* edrk.KvitirDISPLAY = 0; + edrk.KvitirVPU = 0; + edrk.KvitirMPU = 0; + edrk.KvitirSVU = 0; + edrk.KvitirRS = 0; + */ + } + + prev_kvitir = edrk.Kvitir; +} + +/////////////////////////////////////////////// +unsigned int get_ready_1(void) +{ + unsigned int r1, r2; + + + + if (project.cds_in[0].status == component_Ready + && project.cds_in[1].status == component_Ready + && project.cds_out[0].status == component_Ready + && project.cds_tk[0].status == component_Ready + && project.cds_tk[1].status == component_Ready + && project.cds_tk[2].status == component_Ready + && project.cds_tk[3].status == component_Ready + && project.adc[0].status == component_Ready + && project.adc[1].status == component_Ready + && project.hwp[0].status == component_Ready + ) + r2 = 1; + else + r2 = 0; + + + r1 = (edrk.ms.ready1 && edrk.from_ing1.bits.NASOS_NORMA + && edrk.from_ing1.bits.ZAZEML_ON==0 && edrk.from_ing1.bits.ZAZEML_OFF==1 + && edrk.from_ing1.bits.VIPR_PREDOHR_NORMA + && edrk.from_ing1.bits.BLOCK_IZOL_NORMA + && edrk.from_ing1.bits.OP_PIT_NORMA + && edrk.from_ing1.bits.UPC_24V_NORMA + && r2); + + return r1; + + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// + + + +void set_zadanie_u_charge(void) +{ + +// edrk.ZadanieU_Charge = edrk.ZadanieU_Charge_RS; + +// edrk.iq_ZadanieU_Charge = _IQ(edrk.ZadanieU_Charge/NORMA_ACP); + + if (edrk.zadanie.ZadanieU_Charge<=100) + { + edrk.iqMIN_U_ZPT = _IQ(-50.0/NORMA_ACP); + edrk.iqMIN_U_IN = _IQ(-50.0/NORMA_ACP); + } + else + { + + edrk.iqMIN_U_ZPT = _IQ(edrk.zadanie.ZadanieU_Charge*MIN_U_PROC/NORMA_ACP); + edrk.iqMIN_U_IN = _IQ(edrk.zadanie.ZadanieU_Charge*MIN_U_PROC/NORMA_ACP); + + } + + if (edrk.zadanie.ZadanieU_Charge<LEVEL_DETECT_U_SMALL) + { + edrk.iqMAX_U_ZPT_Predzaryad = _IQ(edrk.zadanie.ZadanieU_Charge*MAX_U_PROC_SMALL/NORMA_ACP); + edrk.iqMAX_U_ZPT_Global = edrk.iqMAX_U_ZPT_Predzaryad + _IQ(ADD_U_MAX_GLOBAL_SMALL/NORMA_ACP); // +500V + + } + else + { + edrk.iqMAX_U_ZPT_Predzaryad = _IQ(edrk.zadanie.ZadanieU_Charge*MAX_U_PROC/NORMA_ACP); + edrk.iqMAX_U_ZPT_Global = edrk.iqMAX_U_ZPT_Predzaryad + _IQ(ADD_U_MAX_GLOBAL/NORMA_ACP); // +200V + + if (edrk.iqMAX_U_ZPT_Global>U_D_MAX_ERROR_GLOBAL) + edrk.iqMAX_U_ZPT_Global = U_D_MAX_ERROR_GLOBAL; + } + + edrk.iqMAX_U_ZPT = edrk.iqMAX_U_ZPT_Global;//_IQ(edrk.zadanie.ZadanieU_Charge*MAX_U_PROC/NORMA_ACP); + edrk.iqMAX_U_IN = _IQ(edrk.zadanie.ZadanieU_Charge*MAX_U_PROC/NORMA_ACP); + + edrk.zadanie.iq_set_break_level = _IQ(NOMINAL_U_BREAK_LEVEL/NORMA_ACP); + +} + + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +// �������� ��������� +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +#define TIME_WAIT_SBOR_1 1 +#define TIME_WAIT_SBOR_2 3 + +void get_sumsbor_command(void) +{ + static unsigned int prev_SBOR_SHEMA = 0; + static unsigned int prev_SBOR_SHEMA_ANOTHER_BS = 0; + unsigned int SBOR_SHEMA_ANOTHER_BS = 0; + static unsigned int Sbor, first=1, w_sbor = 0, Sbor_f = 0; + + Sbor = edrk.SumSbor; + + if (Sbor == 0) + edrk.run_razbor_shema = 0; + + SBOR_SHEMA_ANOTHER_BS = read_cmd_sbor_from_bs(); + + // ���� ������� ���� ����� � ��������� ������ + if (edrk.Status_Ready.bits.ImitationReady2==0 && + control_station.active_array_cmd[CONTROL_STATION_CMD_CHARGE]==1 && (prev_SBOR_SHEMA==0) + && edrk.from_ing1.bits.ALL_KNOPKA_AVARIA==0 && edrk.summ_errors==0 + && control_station.active_array_cmd[CONTROL_STATION_CMD_UNCHARGE]==0 + ) + { + Sbor = 1; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_UNCHARGE]==1 + // || edrk.from_shema_filter.bits.RAZBOR_SHEMA // ���������� ������ �� ������ � �� ����� �������� ���� ���������� + ) + { + edrk.run_razbor_shema = 1; + // Sbor = 0; + } + + + if (edrk.StartGEDfromZadanie==0 && edrk.run_razbor_shema) + Sbor = 0; + + +// ������ ����� �� �� ������� ������� ��? + if (SBOR_SHEMA_ANOTHER_BS==0 && prev_SBOR_SHEMA_ANOTHER_BS==1) + { + Sbor = 0; + } + + prev_SBOR_SHEMA = control_station.active_array_cmd[CONTROL_STATION_CMD_CHARGE]; + + prev_SBOR_SHEMA_ANOTHER_BS = SBOR_SHEMA_ANOTHER_BS; + + + // ������ �� ������ � ������! + if (edrk.from_ing1.bits.ALL_KNOPKA_AVARIA || edrk.summ_errors) + { + Sbor = 0; + } + + if (Sbor) + { +// if (edrk.flag_second_PCH == 0) +// { +// if (w_sbor<TIME_WAIT_SBOR_1) +// w_sbor++; +// else +// Sbor_f = 1; +// } +// else +// { +// if (w_sbor<TIME_WAIT_SBOR_2) +// w_sbor++; +// else +// Sbor_f = 1; +// } + Sbor_f = 1; + } + else + { + Sbor_f = 0; + w_sbor = 0; + + } + + ///////////////////////////////// + ///////////////////////////////// + ///////////////////////////////// + + if (Sbor_f) + { + if (first) + { + if (optical_read_data.data.cmd.bit.ready_cmd==CODE_READY_CMD_READY1TO2) // ������ �� ��� ������ ���������� + edrk.flag_another_bs_first_ready12 = 1; + else + edrk.flag_this_bs_first_ready12 = 1; + } + first = 0; + } + else + { + edrk.flag_another_bs_first_ready12 = 0; + edrk.flag_this_bs_first_ready12 = 0; + first = 1; + } + + edrk.SumSbor = Sbor_f; + +} +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + + + +void edrk_init(void) +{ + + edrk.Uzad_max = _IQ(K_STATOR_MAX); // ���� ��������� � �� ��� ������������ �������� = DEF_PERIOD_MIN_MKS + edrk.iq_bpsi_normal = _IQ(BPSI_NORMAL/NORMA_FROTOR); + // edrk.iq_bpsi_max = _IQ(BPSI_MAXIMAL/NORMA_FROTOR); +// edrk.iq_f_provorot = _IQ(F_PROVOROT/NORMA_FROTOR); + + init_simple_scalar(); + + edrk.flag_enable_update_hmi = 1; + + + edrk.zadanie.ZadanieU_Charge = NOMINAL_U_ZARYAD; + edrk.zadanie.iq_ZadanieU_Charge = _IQ(NOMINAL_U_ZARYAD/NORMA_ACP); + + edrk.zadanie.iq_set_break_level = _IQ(NOMINAL_U_BREAK_LEVEL/NORMA_ACP); + + control_station.setup_time_detect_active[CONTROL_STATION_TERMINAL_RS232] = 50; + +#if (_SIMULATE_AC==1) + sim_model_init(); +#endif + +} + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + + +void edrk_init_variables(void) { + unsigned int i = 0, size_data_logs = 0; + + + int *pf = (int*)&f; + for (i = 0; i < sizeof(f) / sizeof(int); i++) { + *(pf + i) = 0; + } + + + init_profile_interrupt(); + edrk_clear_cmd_ukss(); + + edrk.flag_second_PCH = get_adr_pcb_controller(); + + edrk.number_can_box_terminal_cmd = 1; + edrk.number_can_box_terminal_oscil = 0; + + edrk.buildDay = build_day; + edrk.buildMonth = build_month; + edrk.buildYear = build_year; + + +/* if (edrk.flag_second_PCH==0) + { + edrk.number_can_box_terminal_cmd = 1; + edrk.number_can_box_terminal_oscil = 0; + } + else + { + edrk.number_can_box_terminal_cmd = 3; + edrk.number_can_box_terminal_oscil = 2; + } +*/ + +// clear_all_i_phase(); +#if(SENSOR_ALG==SENSOR_ALG_23550) + rotorInit(); +#endif +#if(SENSOR_ALG==SENSOR_ALG_22220) +// 22220 + rotorInit_22220(); +#endif + clear_table_remoute(); + initModbusTable(); + clear_modbus_table_in(); + clear_modbus_table_out(); +// init_global_time_struct(FREQ_PWM); + // fillLogArea(); + + oscil_can.clear(&oscil_can); + oscil_can.number_can_box_terminal_oscil = edrk.number_can_box_terminal_oscil; + oscil_can.number_can_box_terminal_cmd = edrk.number_can_box_terminal_cmd; + + + control_station.clear(&control_station); + + init_detect_overloads(); + edrk_init(); + size_data_logs = prepare_data_to_logs(); + initLogSize(size_data_logs, size_data_logs ); + + init_ramp_all_zadanie(); + init_analog_protect_levels(); + init_detect_overloads(); + init_50hz_input_net50hz(); + init_all_limit_koeffs(); + + + + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_IZAD] = NOMINAL_SET_IZAD; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_KM] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_U_DISBALANCE] = NOMINAL_SET_K_U_DISBALANCE; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_K_PLUS_U_DISBALANCE] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SET_LIMIT_POWER] = NOMINAL_SET_LIMIT_POWER; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_UFCONST_VECTOR] = 1; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_SCALAR_FOC] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_GO] = 1; + + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_QTV] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_ON_UMP] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = 0; + + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_ROTOR_POWER] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_INTERRUPT_SYNC] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_DISABLE_INTERRUPT_TIMER2] = 0; + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_STOP_LOGS] = 0; + + control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD; + control_station.array_cmd[CONTROL_STATION_MPU_SVU_CAN][CONTROL_STATION_CMD_SET_U_ZARYAD] = NOMINAL_U_ZARYAD; + + control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_WDOG_OFF] = 0; + + + for (i=0;i<CONTROL_STATION_CMD_LAST;i++) + control_station.array_cmd[CONTROL_STATION_TERMINAL_CAN][i] = control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][i]; + + + ramp_all_zadanie(2); + + set_zadanie_u_charge(); + init_Uin_rms(); +} + + +////////////////////////////////////////////////////////// +void edrk_init_before_loop(void) +{ +#if (MODE_DISABLE_ENABLE_WDOG==1) + stop_wdog(); +#else + +#if (_FLOOR6==1) +#else + start_wdog(); +#endif + +#endif + + disable_flag_special_mode_rs = 0; +} +////////////////////////////////////////////////////////// + +#define FREQ_TIMER_3 (FREQ_PWM*2) + +void edrk_init_before_main(void) +{ + static int f_cmd1 = 0; + static int f_cmd2 = 0; + static int f_cmd3 = 0; + static int p_f_cmd1 = 0; + static int p_f_cmd2 = 0; + static int p_f_cmd3 = 0; + + + volatile int final_code = 0; + int i = 0, k = 0; + + setup_sync_line(); + edrk.disable_interrupt_sync = -1; + + edrk_init_variables(); + +//////////////////////////////////////// +// global timer +//////////////////////////////////////// + init_global_time_struct(FREQ_TIMER_3); + init_evb_timer3(FREQ_TIMER_3,&global_time_interrupt); + start_evb_timer3();// run global_time_interrupt +/////////////////////////////////////// + + /// ��� ����� 2 +/* + while(1) + { + static int f_s_set = 0; + static int f_s_read = 0; + + + if (f_s_set) + i_sync_pin_on(); + else + i_sync_pin_off(); + + f_s_read = get_status_sync_line(); + } + */ + + +/// ��� ����� 1 +/* + project.enable_all_interrupt(); + + //start_sync_interrupt(); + + while(1) + { + static int f_s_set = 0; + static int f_s_read = 0; + + + if (f_s_set) + i_sync_pin_on(); + else + i_sync_pin_off(); + + f_s_read = get_status_sync_line(); + + if (f_cmd1 != p_f_cmd1) + { + if (f_cmd1) + { + start_evb_timer3(); + } + else + { + stop_evb_timer3(); + } + p_f_cmd1 = f_cmd1; + } + + if (f_cmd2 != p_f_cmd2) + { + if (f_cmd2) + { + start_eva_timer2(); + } + else + { + stop_eva_timer2(); + } + p_f_cmd2 = f_cmd2; + } + + if (f_cmd3 != p_f_cmd3) + { + if (f_cmd3) + { + start_sync_interrupt(); + } + else + { + stop_sync_interrupt(); + } + p_f_cmd3 = f_cmd3; + } + + } + /// ����� ����� +*/ + project.enable_all_interrupt(); + + final_code = update_progress_load_hmi(1); + + project.disable_all_interrupt(); + + InitXilinxSpartan2E(&PWM_interrupt_main); + + project.enable_all_interrupt(); + + final_code = update_progress_load_hmi(2); + + init_can_box_between_bs1_bs2(); + + initVectorControl(); + + +///////////////////////////// + if (edrk.flag_second_PCH==0) + InitCan(CAN_BASE_ADR_UNITS_PCH_1, CAN_BASE_ADR_MPU_PCH_1, CAN_BASE_ADR_ALARM_LOG_PCH_1, CAN_BASE_ADR_TERMINAL_PCH_1); + else + InitCan(CAN_BASE_ADR_UNITS_PCH_2, CAN_BASE_ADR_MPU_PCH_2, CAN_BASE_ADR_ALARM_LOG_PCH_2, CAN_BASE_ADR_TERMINAL_PCH_2); +///////////////////////////// + + KickDog(); + + // clear_mem(FAST_LOG); + +/* + //TODO: remove (for test) + logpar.start_write_fast_log = 1; + + for (k = 0; k < 7000; k++) { + for (i = 0; i < 21; i++) { + if (i==0) +// write_to_mem(FAST_LOG, k); + write_to_mem(FAST_LOG, 0); + else +// write_to_mem(FAST_LOG, 10 + i); + write_to_mem(FAST_LOG, 0); + } + if (logpar.start_write_fast_log) { + get_log_params_count(); + logpar.start_write_fast_log = 0; + } + } + + //END for test +*/ + + //Init ADC +// Init_Adc_Variables(); +// init_eva_timer2(1000, acp_Handler); + + final_code = update_progress_load_hmi(3); + +///////////////////////////////////////// + project.read_errors_controller(); // ������ ADR_ERRORS_TOTAL_INFO + + project.init(); +// project_prepare_config(); + + final_code = update_progress_load_hmi(4); + +// initRotPlane(); + +// project_prepare_config(); +// �������� CDS, ADC, HWP � �.�. + project.reload_all_plates_with_reset(); +// ����� ����������� ���� + // project.find_all_cds(); + + project_prepare_config(); + project_run_init_all_plates(); + + project.load_cfg_to_plates(); + + project.clear_errors_all_plates(); + + + final_code = update_progress_load_hmi(5); + +///////////////////////////////////////////// + enable_er0_control(); + + + project.read_errors_controller(); + + project_read_errors_controller(); // ������ ADR_ERRORS_TOTAL_INFO + if(project.controller.read.errors.all || project.controller.read.errors_buses.all) + { + xerror(main_er_ID(3),(void *)0); + } + + final_code = update_progress_load_hmi(6); + +//////////////////////////////////////////// + project.reset_errors_controller(); + project.read_errors_controller(); + project.start_parallel_bus(); + project.read_errors_controller(); + project.reset_errors_controller(); + project.read_errors_controller(); + + project.stop_parallel_bus(); + + project.reset_errors_controller(); + project.read_errors_controller(); + + project.start_parallel_bus(); + project.read_errors_controller(); + + final_code = update_progress_load_hmi(7); +//////////////////////////////////////////////// + + + +#if (TMSPWMGEN==1) + setup_pwm_out();// ��������� ��������������� ���� ��� ������ ��� + setup_pwm_int(FREQ_PWM, 0 ,0); +#else //TMSPWMGEN + +#if (XPWMGEN==1) + InitXPWM(FREQ_PWM); + stop_wdog(); +#else + + #error "������ ��������� �������. �� ������ ��� ����!!!" + +#endif //XPWMGEN +#endif //TMSPWMGEN + + InitPWM_Variables(edrk.flag_second_PCH); + + break_resistor_managment_init(FREQ_PWM); + +// start_int13_interrupt(); + + +// ��������� SYNC + setup_sync_int(); //use timer4 + //start_sync_interrupt(); + edrk.disable_interrupt_sync = 0; + + + // pause_1000(100000); + final_code = update_progress_load_hmi(8); + +// project.enable_all_interrupt(); +// status_interrupts = __enable_interrupts(); + +// pause_1000(100000); + + + project.read_errors_controller(); + x_parallel_bus_project.read_status(&x_parallel_bus_project); + +// err_main = ReadMemory(ADR_ERRORS_TOTAL_INFO); +// if(enable_er0_control() || err_main) + if (project.controller.read.errors.bit.error_pbus + || project.controller.read.errors_buses.bit.slave_addr_error + || project.controller.read.errors_buses.bit.count_error_pbus) + { + xerror(xparall_bus_er_ID(2),(void *)0); + + project.stop_parallel_bus(); + + project.reset_errors_controller(); + project.read_errors_controller(); + + project.start_parallel_bus(); + project.read_errors_controller(); + } + +/* + while(1) + { + project.adc[0].read_pbus(&project.adc[0]); +// project.adc[1].read_pbus(&project.adc[1]); + project.cds_tk[3].read_pbus(&project.cds_tk[3]); + project.read_errors_controller(); + } +*/ +// project_stop_parallel_bus(); + + + project.start_parallel_bus(); + x_parallel_bus_project.read_status(&x_parallel_bus_project); + +// ���� ������ ����� ������� PBUS ����� �� ����� ������ ��� ������� ���� + Init_Adc_Variables(); + final_code = update_progress_load_hmi(9); + + +///////////////////////////// +// optical bus timer +///////////////////////////// + if (edrk.flag_second_PCH==0) + init_eva_timer2(FREQ_PWM*20*2, &optical_bus_read_write_interrupt); + if (edrk.flag_second_PCH==1) + init_eva_timer2(FREQ_PWM*20*2, &optical_bus_read_write_interrupt); + + //start_eva_timer2();// run global_time_interrupt +///////////////////////////// + + ///////////////////////////// + // add bus timer + init_eva_timer1(FREQ_PWM*50,&async_pwm_ext_interrupt); + start_eva_timer1();// run global_time_interrupt + ///////////////////////////// + + + run_can_from_mpu(); + + i_led1_on_off(1); + i_led2_on_off(0); + + final_code = update_progress_load_hmi(10); + +#if (XPWMGEN==1) + project.enable_int13(); +#endif + + start_int13_interrupt(); + + pause_1000(10000); + + + +// project.enable_all_interrupt(); + + +//#if (MODE_DISABLE_ENABLE_WDOG==1) +// stop_wdog(); +//#else +// start_wdog(); +//#endif +// static unsigned int ccc = 0; +// static STATUS_DATA_READ_OPT_BUS optbus_status = {0}; +// +// project.disable_all_interrupt(); +// while(1) +// { +// +// +// if (edrk.flag_second_PCH==1) +// { +// project.cds_tk[3].read_pbus(&project.cds_tk[3]); +// optbus_status = optical_bus_get_status_and_read(); +// } +// if (edrk.flag_second_PCH==0) +// { +// +// ccc++; +// optical_write_data.data.angle_pwm = ccc; +// +// optical_bus_write(); +// +// } +// } + + + start_sync_interrupt(); // ��������� ������ SYNC + start_eva_timer2();// run global_time_interrupt optical_bus_read_write_interrupt + start_can_interrupt(); + + prev_flag_special_mode_rs = flag_special_mode_rs; + +} + +////////////////////////////////////////////////////////// +void edrk_go_main(void) +{ + static int disable_can=0; + static int pbus_cmd=1; + static int prev_pbus_cmd=1; + + static int f_reset = 0; + static int np_reset = 0; + static int level_go_main = 0; + + + if(f_reset) + { + ResetNPeriphPlane(np_reset); + f_reset = 0; + } + + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_21_ON; +#endif + +// new_fifo_calc_load(); +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_ON; +#endif + + project.read_errors_controller(); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_OFF; +#endif + +// project.read_all_pbus(); +// project.read_all_hwp(); + + if (edrk.flag_slow_in_main==0 || level_go_main==0) + project.read_all_sbus(); //22 msec + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_ON; +#endif + + x_parallel_bus_project.read_status(&x_parallel_bus_project); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_OFF; +#endif + +// project.write_all_sbus(); + + + + +////////////////////// + if ((prev_pbus_cmd != pbus_cmd) && pbus_cmd==0) + { +// project.disable_int13(); + project.stop_parallel_bus(); + } + + if ((prev_pbus_cmd != pbus_cmd) && pbus_cmd==1) + { +// project.enable_int13(); + project.start_parallel_bus(); + } + prev_pbus_cmd = pbus_cmd; + + prev_flag_special_mode_rs = flag_special_mode_rs; +///////////////////// + + if (flag_special_mode_rs==0) + { + xpwm_time.disable_sync_out = 0; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_22_ON; +#endif + +// if (level_go_main==1) + project.read_all_hwp(); //800 mks + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_ON; +#endif + + if (edrk.flag_slow_in_main==0 || level_go_main==20) + project.write_all_sbus(); //5msec + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_22_OFF; +#endif + + run_edrk(); + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_ON; +#endif + +// if (at==1) +// { +// SendAll2SecondBS(); +// oscil_can.send(&oscil_can); +// at=0; +// } + + //����� �� CAN + if (disable_can==0) + CAN_may_be_send_cycle_fifo(); + + } + else + { + xpwm_time.disable_sync_out = 1; + project.read_all_pbus(); + project.read_all_hwp(); + project.write_all_sbus(); +// project.disable_int13(); + + RS232_WorkingWith(0,1,0); + } + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_23_OFF; +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_21_OFF; +#endif + + level_go_main++; + if (level_go_main>=40) + level_go_main = 0; + + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +//#pragma CODE_SECTION(get_start_ged_from_zadanie,".fast_run"); +int get_start_ged_from_zadanie(void) +{ + + // uf const + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) + { + if (edrk.zadanie.iq_fzad_rmp!=0 && edrk.zadanie.iq_kzad_rmp!=0) + return 1; + else + return 0; + } + else + // scalar oborots + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_OBOROTS) + { + if (edrk.MasterSlave==MODE_SLAVE) + { + if (edrk.zadanie.iq_Izad_rmp!=0 + && edrk.zadanie.iq_limit_power_zad_rmp!=0) + return 1; + else + return 0; + } + else + { + if (edrk.zadanie.iq_oborots_zad_hz_rmp!=0 && edrk.zadanie.iq_Izad_rmp!=0 + && edrk.zadanie.iq_power_zad_rmp!=0 && edrk.zadanie.iq_limit_power_zad_rmp!=0) + return 1; + else + return 0; + } + } + else + // scalar power + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_POWER) + { + if (edrk.zadanie.iq_oborots_zad_hz_rmp!=0 && edrk.zadanie.iq_Izad_rmp!=0 + && edrk.zadanie.iq_power_zad_rmp!=0 && edrk.zadanie.iq_limit_power_zad_rmp!=0) + return 1; + else + return 0; + } + else + // foc oborots + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS) + { + if (edrk.zadanie.iq_oborots_zad_hz_rmp!=0 && edrk.zadanie.iq_Izad_rmp!=0 + && edrk.zadanie.iq_power_zad_rmp!=0 && edrk.zadanie.iq_limit_power_zad_rmp!=0) + return 1; + else + return 0; + } + else + // foc power + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) + { + if (edrk.zadanie.iq_oborots_zad_hz_rmp!=0 && edrk.zadanie.iq_Izad_rmp!=0 + && edrk.zadanie.iq_power_zad_rmp!=0 && edrk.zadanie.iq_limit_power_zad_rmp!=0) + return 1; + else + return 0; + } + else + { + return 0; + } + +} +////////////////////////////////////////////////////////// + + +void cross_stend_automats(void) +{ + unsigned int g; + + edrk.to_shema.bits.CROSS_UMP_ON_OFF = 0; + edrk.to_shema.bits.CROSS_QTV_ON_OFF = 0; + +} + + + + +#define MAX_ERRORS_DETECT_CHANGE_ACTIVE_CONTROL 50 +void check_change_post_upravl(void) +{ + static int prev_active_post_upravl = -1, prev_active_post_upravl_another_bs = -1; + int active_post_upravl = -1, active_post_upravl_another_bs = -1; + static unsigned int count_err = 0; + + + active_post_upravl = get_code_active_post_upravl(); + active_post_upravl_another_bs = edrk.active_post_upravl_another_bs; + + + if (edrk.Status_Ready.bits.ready_final && edrk.Ready2_another_bs) + { + if ((active_post_upravl_another_bs==0 || active_post_upravl==0) && (active_post_upravl==2 || active_post_upravl_another_bs==2)) + { + // ���� �����-�� �� � ��� � ������ � ������� + edrk.errors.e9.bits.CHANGE_ACTIVE_CONTROL_TO_LOCAL_FROM_SVU |= + filter_err_count(&count_err, + MAX_ERRORS_DETECT_CHANGE_ACTIVE_CONTROL, + 1, + 0); + } + else + count_err = 0; + } + + + prev_active_post_upravl = active_post_upravl; + prev_active_post_upravl_another_bs = active_post_upravl_another_bs; + + edrk.active_post_upravl = active_post_upravl; +} + + +int get_code_active_post_upravl(void) +{ + + if (control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232]) + return 3; + else + if (control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN]) + return 4; + else + if (control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485])//(edrk.RemouteFromDISPLAY) + return 0; + else + if (control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN]) + return 5; + else + if (control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN]) + return 6; + else + if (control_station.active_control_station[CONTROL_STATION_VPU_CAN]) + return 1; + else + if (control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN]) + return 2; + else + return 10; //error +} + + + + +#define MAX_COUNT_DETECTS_ZERO_U_ZPT 5 + +void auto_detect_zero_u_zpt(void) +{ + static unsigned int old_time_u_zpt1=0, count_detects = 0, flag_detect_zero_u_zpt = 0; + + static _iq prev_uzpt1=0; + static _iq prev_uzpt2=0; + static _iq delta_u = _IQ(3.0/NORMA_ACP); + static _iq minimal_detect_u = _IQ(40.0/NORMA_ACP); + + + + if (edrk.SumSbor==0 && flag_detect_zero_u_zpt==0) + { + // ��� �����, ������ ����� ������ ���� Uzpt + if (detect_pause_sec(5,&old_time_u_zpt1)) + { + if ( filter.iqU_1_long>=minimal_detect_u || + filter.iqU_2_long>=minimal_detect_u || + (prev_uzpt1-filter.iqU_1_long)>=delta_u || + (prev_uzpt2-filter.iqU_2_long)>=delta_u ) + { + // ���������� ��� ������ + count_detects = 0; + } + else + { + if (count_detects<MAX_COUNT_DETECTS_ZERO_U_ZPT) + count_detects++; + else + { + if (flag_detect_zero_u_zpt==0) + { + if (filter.iqU_1_long<=minimal_detect_u && + filter.iqU_2_long<=minimal_detect_u) + { + analog_zero.iqU_1 = filter.iqU_1_long; + analog_zero.iqU_2 = filter.iqU_2_long; + } + } + flag_detect_zero_u_zpt = 1; + + } + + } + + prev_uzpt1 = filter.iqU_1_long; + prev_uzpt2 = filter.iqU_2_long; + } // 1 sec end + } + else + { + if (flag_detect_zero_u_zpt) + { + if (filter.iqU_1_long<-delta_u || filter.iqU_2_long<-delta_u) + { + // ������� ���� ���� ����������� ���������, ���� �� ��������� + flag_detect_zero_u_zpt = 0; + analog_zero.iqU_1 = 0; + analog_zero.iqU_2 = 0; + } + + } + count_detects = 0; + } + +} + +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +// ��� ����� ���������� ����� ������ ����� +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +void reinit_before_sbor(void) +{ + static unsigned int prev_sbor = 0; + + if (edrk.SumSbor && edrk.SumSbor!=prev_sbor ) + { + init_50hz_input_net50hz(); + init_all_limit_koeffs(); + } + prev_sbor = edrk.SumSbor; +} + +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +#define MINIMAL_POWER_TO_DISPLAY 10 // ������� 10 ��� + +#define PAUSE_COMUNICATION 100 +void run_edrk(void) +{ + // static unsigned int prev_SumSbor = 0, prev_AllStart = 0, prev_VozbudOnOff = 0, prev_SBOR_SHEMA_VPU = 0,prev_SBOR_SHEMA_RS=0, prev_SBOR_SHEMA_DISPLAY = 0; + + int ff =0; + static unsigned int filter_count_error_control_station_select_active = 0; + static int flag_enable_update_mpu = 1; + static unsigned int external_cmd_alarm_log = 0; + static int prev_enable_pwm_test_lines=0; + int power_kw_full = 0; + + float max_oborots, local_oborots, local_power, max_power; + static float float_oborots = 0, koef_p1 = 0, koef_p2 = 0, koef_p3 = 27.391304347826086956521739130435; + + static unsigned int prev_rs_a_count_recive_ok = 0; + static unsigned int pause_comunication = PAUSE_COMUNICATION; + static unsigned int time_pause_modbus_can_zadatchik_vpu = TIME_PAUSE_MODBUS_CAN_ZADATCHIK_VPU; + static unsigned int time_pause_modbus_can_ukss_setup = TIME_PAUSE_MODBUS_CAN_UKSS_SETUP; + static unsigned int time_pause_modbus_can_bs2bs = TIME_PAUSE_MODBUS_CAN_BS2BS; + static int fa_0 = 1; + static int fa_1 = 1; + static int fa_2 = 1; + + static int prev_cmd_very_slow_start = 0; + + +// static float fff = 0; + + reinit_before_sbor(); + + if (edrk.SumSbor || edrk.Status_Ready.bits.ready_final) + { + disable_flag_special_mode_rs = 1; + } + else + disable_flag_special_mode_rs = 0; + + if (f.Prepare || f.terminal_prepare) { + project.clear_errors_all_plates(); + } + +// fff = my_satur_float(fff,MAX_ZADANIE_LIMIT_POWER, MIN_ZADANIE_LIMIT_POWER, 0); + // slow_vector_update(); + + read_plane_errors(); + +// if (flag_enable_update_hmi) +// update_tables_HMI(); +// if (flag_enable_update_mpu) +// update_modbus_table(); +// modbusNetworkSharing(1); +// get_command_HMI(); + +// return; + +// i_led1_on_off(1); + if (edrk.flag_disable_pult_485==0) + { + i_led2_on_off(1); + modbusNetworkSharing(0); + + } +// i_led1_on_off(0); + +// if (ccc[0]) +// { +// i_led2_on_off(0); +// return; +// } + + if (!(detect_pause_milisec(pause_comunication, &old_time_edrk2))) + return; + + + if (edrk.get_new_data_from_hmi2) + { + get_command_HMI(); + edrk.get_new_data_from_hmi2 = 0; + } + + + + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + // ������ ��� ����������� ��� � 100 ����. + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + + + // external_cmd_alarm_log = modbus_table_can_in[11].all; + // test_send_alarm_log(external_cmd_alarm_log); + + // modbusNetworkSharing(0); + + // i_led2_on_off(1); + + modbusNetworkSharingCAN(); + + #if (ENABLE_CAN_SEND_TO_UKSS_FROM_MAIN) + // ����� � �������� + update_ukss_can(time_pause_modbus_can_zadatchik_vpu); + update_ukss_can_moment_kgnc(time_pause_modbus_can_zadatchik_vpu*3); + + + update_ukss_setup(time_pause_modbus_can_ukss_setup); + #endif + + #if (ENABLE_CAN_SEND_TO_ANOTHER_BSU_FROM_MAIN) +// ����� � �������� + update_bsu_can(time_pause_modbus_can_bs2bs); + #endif + + check_all_power_limits(); + + calc_p_water_edrk(); + calc_temper_edrk(); + calc_temper_acdrive(); + + // ������ ���� ����� + update_input_edrk(); + + detect_kvitir_from_all(); + + detect_error_all(); + + calc_limit_overheat(); + + calc_RMS_values_main(); + + update_lamp_alarm(); + + set_zadanie_u_charge(); + + reinit_protect_I_and_U_settings(); + + nagrev_auto_on_off(); + + auto_block_key_on_off(); + + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + edrk.f_rotor_hz = _IQtoF(edrk.iq_f_rotor_hz) * NORMA_FROTOR; + + + + if (edrk.Status_Ready.bits.ImitationReady2) + { +// edrk.oborots = edrk.zadanie.oborots_zad; +// koef_p1 = 54.78260869565217391304347826087/(edrk.count_bs_work+1); +// koef_p2 = 54.78260869565217391304347826087/4; + + koef_p3 = 27.39130; + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ROTOR_POWER]==0) // �� �������� + { + + if (edrk.count_bs_work==0) + max_power = my_satur_float(edrk.zadanie.limit_power_zad, MAX_ZADANIE_POWER/2, MIN_ZADANIE_POWER/2, 0); + else + max_power = my_satur_float(edrk.zadanie.limit_power_zad, MAX_ZADANIE_POWER, MIN_ZADANIE_POWER, 0); + + max_oborots = max_power/koef_p3; + if (edrk.count_bs_work==0) + max_oborots = my_satur_float(max_oborots,MAX_ZADANIE_OBOROTS_ROTOR/2,MIN_ZADANIE_OBOROTS_ROTOR/2, 0); + else + max_oborots = my_satur_float(max_oborots,MAX_ZADANIE_OBOROTS_ROTOR,MIN_ZADANIE_OBOROTS_ROTOR, 0); + + local_oborots = fast_round(_IQtoF(edrk.zadanie.iq_oborots_zad_hz)*60.0*NORMA_FROTOR); + if (local_oborots>=0) + { + if (local_oborots>max_oborots) + local_oborots = max_oborots; + } + else + { + if (local_oborots<-max_oborots) + local_oborots = -max_oborots; + } + + float_oborots = zad_intensiv(1.0, 1.0, float_oborots, local_oborots); + + edrk.oborots = float_oborots; + edrk.power_kw = edrk.oborots * koef_p3/(edrk.count_bs_work+1); + + + + +// +// max_oborots = edrk.zadanie.limit_power_zad/koef_p2; +// max_oborots = my_satur_float(max_oborots,MAX_ZADANIE_OBOROTS_ROTOR,MIN_ZADANIE_OBOROTS_ROTOR, 0); +// +// local_oborots = fast_round(_IQtoF(edrk.zadanie.rmp_oborots_imitation_rmp)*60.0*NORMA_FROTOR); +// if (local_oborots>=0) +// { +// if (local_oborots>max_oborots) +// local_oborots = max_oborots; +// } +// else +// { +// if (local_oborots<-max_oborots) +// local_oborots = -max_oborots; +// } + + } + else + { + + local_power = fast_round(_IQtoF(edrk.zadanie.iq_power_zad_rmp) * NORMA_ACP * NORMA_ACP / 1000.0); + if (edrk.count_bs_work==0) + local_power = my_satur_float(local_power, MAX_ZADANIE_POWER/2, MIN_ZADANIE_POWER/2, 0); + else + local_power = my_satur_float(local_power, MAX_ZADANIE_POWER, MIN_ZADANIE_POWER, 0); + + local_oborots = local_power/koef_p3; + float_oborots = zad_intensiv(1.0, 1.0, float_oborots, local_oborots); + edrk.oborots = float_oborots; + edrk.power_kw = local_power/(edrk.count_bs_work+1);//edrk.oborots * koef_p3; + +// local_power = fast_round(_IQtoF(edrk.zadanie.iq_power_zad_rmp) * NORMA_ACP * NORMA_ACP / 1000.0); +// local_oborots = local_power/koef_p1; + } + + +// float_oborots = zad_intensiv(0.5, 0.5, float_oborots, local_oborots); +// edrk.oborots = float_oborots; +// +// if (edrk.oborots>=0) +// edrk.power_kw = edrk.oborots * koef_p2; +// else +// edrk.power_kw = edrk.oborots * koef_p2; + +// +// +// +// if (edrk.oborots>=0) +// edrk.power_kw = edrk.oborots * koef_p; +// else +// edrk.power_kw = edrk.oborots * (+koef_p); + } + else + { + edrk.oborots = fast_round(_IQtoF(WRotor.iqWRotorSumFilter3)*60.0*NORMA_FROTOR); +// local_power = fast_round(_IQtoF(filter.PowerScalarFilter2) * NORMA_ACP * NORMA_ACP / 1000.0); +// +// if (edrk.oborots>=0) +// edrk.power_kw = local_power; +// else +// edrk.power_kw = -local_power; + + edrk.power_kw = fast_round(_IQtoF(edrk.iq_power_kw_one_filter_znak) * NORMA_ACP * NORMA_ACP / 1000.0); + } + + power_kw_full = edrk.power_kw + edrk.power_kw_another_bs; + +// if (power_kw_full < MINIMAL_POWER_TO_DISPLAY) +// edrk.power_kw_full = 0; +// else + edrk.power_kw_full = power_kw_full; + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + + + edrk.Status_Ready.bits.ready1 = get_ready_1(); + + pump_control(); + + + if (control_station_select_active()) + { + + if (filter_count_error_control_station_select_active<30) + filter_count_error_control_station_select_active++; + else + edrk.errors.e7.bits.NOT_VALID_CONTROL_STATION |= 1; + } + else + filter_count_error_control_station_select_active = 0; + + edrk.current_active_control = get_current_station_control(); + + if (edrk.current_active_control<CONTROL_STATION_LAST) + { + // ���� �������� ���� ���������� + } + + + // ��������� ��� ������ �� ���� ��������� ������ ���������� + parse_parameters_from_all_control_station(); + //�������� ������ �� ��������� ����� � ������� + load_parameters_from_active_control_station(edrk.current_active_control); + + // ���� �� slave �� ����� ������ ����� � ������� �� CAN � �������� � active_control_station + parse_data_from_master_to_alg(); + + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR]; + control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_SET_ROTOR] = ff; + control_station.array_cmd[CONTROL_STATION_VPU_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + control_station.array_cmd[CONTROL_STATION_ZADATCHIK_CAN][CONTROL_STATION_CMD_SET_ROTOR] = ff; + + ff = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER]; + control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_SET_POWER] = ff; + + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ROTOR_POWER]) + { + control_station.array_cmd[CONTROL_STATION_ZADATCHIK_CAN][CONTROL_STATION_CMD_SET_ROTOR] = 0; + control_station.array_cmd[CONTROL_STATION_VPU_CAN][CONTROL_STATION_CMD_SET_ROTOR] = 0; + } + + // ��� ������, ��� ����� ������ ������ ��, �� ������ �� ������ �������� ����������� ������� ��� ���������, + // �.�. ������� ���������� QTV � QPU �������� ���������������. +// cross_stend_automats(); + + // ��������� ������ �� ������� �� �� CAN + read_data_from_bs(); + + //��������� ���������� ������ �� �������� ����� ���������� � ��������� edrk. + parse_analog_data_from_active_control_station_to_alg(); + + // if (flag_enable_update_hmi) + // update_tables_HMI(); + if (flag_enable_update_mpu) + { + update_svu_modbus_table(); + } + + // modbusNetworkSharing(0); + + + + if (flag_enable_can_from_mpu) + { + + // write_all_data_to_mpu_485(0); + // read_all_data_from_mpu_485(0); + // write_all_data_to_mpu_can(1); + // test_rs_can_with_svu_mpu(); + } + + // + + if (edrk.test_mode) + { + return; + } + + get_sumsbor_command(); + + sbor_shema(edrk.SumSbor); + + auto_select_master_slave(); + + who_select_sync_signal(); + + check_change_post_upravl(); + + get_freq_50hz_float(); + + auto_detect_zero_u_zpt(); + + + if (detect_pause_sec(2,&old_time_edrk1)) + { + update_nPCH(); + + if (control_station.array_cmd[CONTROL_STATION_TERMINAL_RS232][CONTROL_STATION_CMD_WDOG_OFF]) + stop_wdog(); + else + start_wdog(); + + + if (rs_a.count_recive_ok != prev_rs_a_count_recive_ok) + control_station.time_detect_active[CONTROL_STATION_TERMINAL_RS232] = 0; + prev_rs_a_count_recive_ok = rs_a.count_recive_ok; + } // 1 sec end + + update_zadat4ik(); + +// update_uom(); + + calc_count_build_revers(); + + run_store_slow_logs(); + prepare_logger_pult(); + update_LoggerParams(); + + send_alarm_log_pult(); + + //////////////////////////////////////////////////////////// + // ����� �������� ������ + //////////////////////////////////////////////////////////// + update_output_edrk(); + + + read_can_error(); + + check_temper_break(); + check_breaker_ged(); + + + + + // change_ramp_zadanie + if (edrk.cmd_very_slow_start != prev_cmd_very_slow_start) + { + change_ramp_zadanie(); + } + prev_cmd_very_slow_start = edrk.cmd_very_slow_start; + + + // i_led2_on_off(0); + + + + +#if (_ENABLE_PWM_LINES_FOR_TESTS==1 \ + || _ENABLE_PWM_LINES_FOR_TESTS_ROTOR==1 \ + || _ENABLE_PWM_LINES_FOR_TESTS_PWM==1 \ + || _ENABLE_PWM_LINES_FOR_TESTS_RS \ + || _ENABLE_PWM_LINES_FOR_TESTS_SYNC \ + || _ENABLE_PWM_LINES_FOR_TESTS_GO) + + if (edrk.enable_pwm_test_lines != prev_enable_pwm_test_lines) + { + if (edrk.enable_pwm_test_lines) + pwm_test_lines_start(); + else + pwm_test_lines_stop(); + } + prev_enable_pwm_test_lines = edrk.enable_pwm_test_lines; + +#endif + + +#if (_FLOOR6==1) + if (fa_0) + { + // �������� ������� ������ �� + control_station.time_detect_active[7] = 0; + control_station.alive_control_station[7] = 1; + } + + if (fa_1) + { + control_station.time_detect_active[CONTROL_STATION_MPU_SVU_CAN] = 0; + control_station.alive_control_station[CONTROL_STATION_MPU_SVU_CAN] = 1; + } + + if (fa_2) + { + control_station.time_detect_active[CONTROL_STATION_MPU_KEY_CAN] = 0; + control_station.alive_control_station[CONTROL_STATION_MPU_KEY_CAN] = 1; + } + +#endif + + + i_led2_on_off(0); + +} + + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +void run_can_from_mpu(void) +{ + int i; + + for (i=0;i<MPU_UNIT_QUA_UNITS;i++) + mpu_can_setup.adr_detect_refresh[i] = 123 - 1; + + + flag_enable_can_from_mpu = 1; + + + +} + + + + +void update_maz_level_i_af(int n_af, unsigned int new_maz_level) +{ +#if (USE_HWP_0) + if (n_af == 0) + { + project.hwp[0].write.values[2].plus = new_maz_level; + project.hwp[0].write.values[2].minus = new_maz_level; + project.hwp[0].write.values[3].plus = new_maz_level; + project.hwp[0].write.values[3].minus = new_maz_level; + project.hwp[0].write.values[4].plus = new_maz_level; + project.hwp[0].write.values[4].minus = new_maz_level; + project.hwp[0].write.values[5].plus = new_maz_level; + project.hwp[0].write.values[5].minus = new_maz_level; + project.hwp[0].write.values[6].plus = new_maz_level; + project.hwp[0].write.values[6].minus = new_maz_level; + project.hwp[0].write.values[7].plus = new_maz_level; + project.hwp[0].write.values[7].minus = new_maz_level; + } + else + { + + } +#endif +} + + +void set_new_level_i_protect(int n_af, int level) +{ + static int i_af_protect_d = 0, prev_level_all = 0, prev_level_2 = 0; + + if (level>LEVEL_HWP_I_AF) level = LEVEL_HWP_I_AF; + if (level<0) level = 0; + + if (n_af == 0) + { + if (level != prev_level_all) + { + i_af_protect_d = convert_real_to_mv_hwp(2,level); + if (i_af_protect_d>1500) i_af_protect_d = 1500; // max 1500 mV + + update_maz_level_i_af(n_af, i_af_protect_d); + project.write_all_hwp(); + } + prev_level_all = level; + } +// else +// { +// if (level != prev_level_2) +// { +// i_af_protect_d = convert_real_to_mv_hwp(4,level); +// if (i_af_protect_d>1500) i_af_protect_d = 1500; // max 1500 mV +// +// update_maz_level_i_af(n_af, i_af_protect_d); +// project.write_all_hwp(); +// } +// prev_level_2 = level; +// +// } +} + + +void calc_count_build_revers(void) +{ + static unsigned int prev_b = 0, prev_r = 0; + + if (edrk.Status_Ready.bits.ImitationReady2) + { + detect_work_revers(((edrk.oborots>=0) ? 1 : -1), edrk.zadanie.iq_oborots_zad_hz_rmp, edrk.oborots); + } + else + detect_work_revers(WRotor.RotorDirectionSlow, edrk.zadanie.iq_oborots_zad_hz_rmp, WRotor.iqWRotorSumFilter2); + + if (edrk.count_revers != prev_r) + inc_count_revers(); + + if (edrk.count_sbor != prev_b) + inc_count_build(); + + prev_r = edrk.count_revers; + prev_b = edrk.count_sbor; + +} + + +void prepare_logger_pult(void) +{ + + edrk.pult_data.logger_params[0] = fast_round(_IQtoF(simple_scalar1.iq_decr_mzz_power_filter)*1000.0);//edrk.zadanie.oborots_zad; + edrk.pult_data.logger_params[1] = fast_round(_IQtoF(edrk.Kplus)*1000.0); + edrk.pult_data.logger_params[2] = fast_round(_IQtoF(pll1.vars.pll_Ud)*NORMA_ACP); + edrk.pult_data.logger_params[3] = fast_round(_IQtoF(edrk.f_stator)*NORMA_FROTOR*100.0); + edrk.pult_data.logger_params[4] = fast_round(_IQtoF(edrk.k_stator1)*10000.0); + edrk.pult_data.logger_params[5] = fast_round(_IQtoF(pll1.vars.pll_Uq)*NORMA_ACP); + edrk.pult_data.logger_params[6] = edrk.period_calc_pwm_int2; + edrk.pult_data.logger_params[7] = fast_round(_IQtoF(simple_scalar1.pidF.OutMax)*NORMA_ACP);//edrk.power_kw_full; + edrk.pult_data.logger_params[8] = edrk.Sbor_Mode; + edrk.pult_data.logger_params[9] = edrk.Stage_Sbor; + edrk.pult_data.logger_params[10] = fast_round(_IQtoF(edrk.Izad_out)*NORMA_ACP); + edrk.pult_data.logger_params[11] = edrk.period_calc_pwm_int1; + edrk.pult_data.logger_params[12] = fast_round(_IQtoF(simple_scalar1.pidF.Out)*NORMA_ACP); + edrk.pult_data.logger_params[13] = fast_round(_IQtoF(simple_scalar1.pidF.OutMin)*NORMA_ACP); + edrk.pult_data.logger_params[14] = fast_round(_IQtoF(simple_scalar1.pidPower.Out)*NORMA_ACP); + edrk.pult_data.logger_params[15] = fast_round(_IQtoF(simple_scalar1.pidPower.OutMax)*NORMA_ACP); + edrk.pult_data.logger_params[16] = fast_round(_IQtoF(simple_scalar1.pidF.Ref)*NORMA_FROTOR*1000.0);// //modbus_table_can_in[123].all;//���������� (�� ��������, �� ��������) + edrk.pult_data.logger_params[17] = modbus_table_can_in[124].all;//������� (��������) + edrk.pult_data.logger_params[18] = modbus_table_can_in[125].all;//�������� (��������) + edrk.pult_data.logger_params[19] = modbus_table_can_in[134].all;//����� �������� + edrk.pult_data.logger_params[20] = fast_round(_IQtoF(simple_scalar1.bpsi_curent)*NORMA_FROTOR*1000.0); + edrk.pult_data.logger_params[21] = fast_round(_IQtoF(edrk.from_uom.iq_level_value_kwt)*NORMA_ACP*NORMA_ACP/1000.0); + edrk.pult_data.logger_params[22] = fast_round(_IQtoF(simple_scalar1.iqKoefOgran)*1000.0);//fast_round(_IQtoF(rotor_22220.iqFout)*NORMA_FROTOR*1000.0); + edrk.pult_data.logger_params[23] = fast_round(_IQtoF(simple_scalar1.iqKoefOgranIzad)*1000.0); //fast_round(_IQtoF(edrk.zadanie.iq_limit_power_zad)*NORMA_ACP*NORMA_ACP/1000.0); + edrk.pult_data.logger_params[24] = fast_round(_IQtoF(edrk.all_limit_koeffs.sum_limit)*1000.0); + edrk.pult_data.logger_params[25] = fast_round(_IQtoF(edrk.all_limit_koeffs.uom_limit)*1000.0); + edrk.pult_data.logger_params[26] = fast_round(_IQtoF(edrk.all_limit_koeffs.uin_freq_limit)*1000.0); + edrk.pult_data.logger_params[27] = fast_round(_IQtoF(simple_scalar1.pidF.Fdb)*NORMA_FROTOR*1000.0); // + + +} + + +int calc_auto_moto_pump(void) +{ + volatile long sum_minutes_pump1, sum_minutes_pump2, set_delta_minutes, cur_delta_minutes; + + + sum_minutes_pump1 = 0; + if (edrk.pult_data.data_from_pult.moto[12]>=0) + sum_minutes_pump1 += edrk.pult_data.data_from_pult.moto[12] * 1440; + if (edrk.pult_data.data_from_pult.moto[3]>=0) + sum_minutes_pump1 += edrk.pult_data.data_from_pult.moto[3]; + + sum_minutes_pump2 = 0; + if (edrk.pult_data.data_from_pult.moto[13]>=0) + sum_minutes_pump2 += edrk.pult_data.data_from_pult.moto[13] * 1440; + if (edrk.pult_data.data_from_pult.moto[4]>=0) + sum_minutes_pump2 += edrk.pult_data.data_from_pult.moto[4]; + + cur_delta_minutes = sum_minutes_pump1 - sum_minutes_pump2; + + set_delta_minutes = edrk.pult_data.data_to_pult.TimeToChangePump; + + if (set_delta_minutes==0) + { + return 0; + } + + + if (cur_delta_minutes>set_delta_minutes) + { + return 2; + } + else + if (cur_delta_minutes<-set_delta_minutes) + { + return 1; + } + else + if (edrk.pult_data.data_from_pult.LastWorkPump==0) + { + if (cur_delta_minutes>0) + { + return 1; + } + else + if (cur_delta_minutes<=0) + { + return 2; + } + else + return 0; + } + else + { + if (edrk.pult_data.data_from_pult.LastWorkPump == 1) + return 1; + else + if (edrk.pult_data.data_from_pult.LastWorkPump == 2) + return 2; + else + return 0; + } +// +// +// if (cur_delta_minutes>0) +// { +// //T1>T2 +// if (_IQabs(cur_delta_minutes) >= set_delta_minutes) +// { +// // T1+delta>T2 +// return 2; +// } +// else +// return 1; +// } +// else +// { +// //T2>T1 +// if (_IQabs(cur_delta_minutes) >= set_delta_minutes) +// { +// //T2+delta>T1 +// return 1; +// } +// else +// return 2; +// } + +// if (_IQabs(cur_delta_minutes) > set_delta_minutes) +// { +// if (cur_delta_minutes>) +// return 2; +// else +// return 1; +// +// +// } +// if (cur_delta_minutes>=0) +// { +// if (_IQabs(cur_delta_minutes) > set_delta_minutes) +// return 2; +// else +// return 1; +// } +// else +// { +// if (_IQabs(cur_delta_minutes) > set_delta_minutes) +// return 1; +// else +// return 2; +// } + + + +} + + + +void read_can_error(void) +{ + EALLOW; + edrk.canes_reg = ECanaRegs.CANES.all; + edrk.canrec_reg = ECanaRegs.CANREC.all; + edrk.cantec_reg = ECanaRegs.CANTEC.all; + EDIS; + + cmd_clear_can_error(); + +} + + +void clear_can_error(void) +{ + // EALLOW; + + // ECanaRegs.CANES.all=0xffffffff; + InitCanSoft(); + + //EDIS; + +} + +void cmd_clear_can_error(void) +{ + static int prev_cmd_clear_can_error = 0; + + if (edrk.cmd_clear_can_error && prev_cmd_clear_can_error==0) + { + clear_can_error(); + } + prev_cmd_clear_can_error = edrk.cmd_clear_can_error; + +} + + +void check_temper_break(void) +{ + + if ( (edrk.break_tempers[0] > ABNORMAL_TEMPER_BREAK_INT) + || (edrk.break_tempers[1] > ABNORMAL_TEMPER_BREAK_INT) + || (edrk.break_tempers[2] > ABNORMAL_TEMPER_BREAK_INT) + || (edrk.break_tempers[3] > ABNORMAL_TEMPER_BREAK_INT) + ) + edrk.warnings.e9.bits.BREAK_TEMPER_WARNING = 1; + else + { + if ( (edrk.break_tempers[0] < ABNORMAL_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[1] < ABNORMAL_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[2] < ABNORMAL_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[3] < ABNORMAL_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + ) + edrk.warnings.e9.bits.BREAK_TEMPER_WARNING = 0; + } + + + if ( (edrk.break_tempers[0] > ALARM_TEMPER_BREAK_INT) + || (edrk.break_tempers[1] > ALARM_TEMPER_BREAK_INT) + || (edrk.break_tempers[2] > ALARM_TEMPER_BREAK_INT) + || (edrk.break_tempers[3] > ALARM_TEMPER_BREAK_INT) + ) + edrk.warnings.e9.bits.BREAK_TEMPER_ALARM = 1; + else + { + //DELTA_TEMPER_BREAK_INT + if ( (edrk.break_tempers[0] < ALARM_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[1] < ALARM_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[2] < ALARM_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + && (edrk.break_tempers[3] < ALARM_TEMPER_BREAK_INT-DELTA_TEMPER_BREAK_INT) + ) + edrk.warnings.e9.bits.BREAK_TEMPER_ALARM = 0; + } + +} + +#define TIME_FILTER_BREAKER_SIGNALS 10 + +void check_breaker_ged(void) +{ + static unsigned int count_wait_breaker = 0; + + edrk.warnings.e9.bits.BREAKER_GED_ON = filter_digital_input( edrk.warnings.e9.bits.BREAKER_GED_ON, + &count_wait_breaker, + TIME_FILTER_BREAKER_SIGNALS, + edrk.breaker_on); + +// if (edrk.breaker_on) +// edrk.warnings.e9.bits.BREAKER_GED_ON = 1; +// else +// edrk.warnings.e9.bits.BREAKER_GED_ON = 0; + +} diff --git a/Inu/Src/main/edrk_main.h b/Inu/Src/main/edrk_main.h new file mode 100644 index 0000000..435baca --- /dev/null +++ b/Inu/Src/main/edrk_main.h @@ -0,0 +1,1838 @@ + +#ifndef _EDRK_MAIN_H__ +#define _EDRK_MAIN_H__ + + +#include "IQmathLib.h" +#include "rmp_cntl_v1.h" +#include "rmp_cntl_v2.h" + +#include "alg_pll.h" + + +#define TIME_PAUSE_MODBUS_CAN_BS2BS 500 //900 //500 +#define TIME_PAUSE_MODBUS_CAN_ZADATCHIK_VPU 250 //100//100 +#define TIME_PAUSE_MODBUS_CAN_UKSS_SETUP 2500 // +#define TIME_PAUSE_MODBUS_CAN_MPU 1100 //500 +#define TIME_PAUSE_MODBUS_CAN_TERMINALS 2000 //1000 +#define TIME_PAUSE_MODBUS_CAN_OSCIL 5000 + +//#define TIME_PAUSE_MODBUS_CAN_BS2BS 100//20//500 +//#define TIME_PAUSE_MODBUS_CAN_ZADATCHIK_VPU 250//20//100 +//#define TIME_PAUSE_MODBUS_CAN_UKSS_SETUP 5000 +//#define TIME_PAUSE_MODBUS_CAN_MPU 500//20//500 +//#define TIME_PAUSE_MODBUS_CAN_TERMINALS 1000 +//#define TIME_PAUSE_MODBUS_CAN_OSCIL 5000 + + +//#define TIME_PAUSE_MODBUS_CAN_TMS2TMS_VIPR 75 //500 + + + +//#define FROM_OPENDOOR project.cds_in[1].read.pbus.data_in.bit.in15 + + +// IN0 +#define SENSOR_ROTOR_1 project.cds_in[0].read.pbus.data_in.bit.in0 // ������ ������� 1 +#define SENSOR_ROTOR_2 project.cds_in[0].read.pbus.data_in.bit.in1 // ������ ������� 2 +#define SENSOR_ROTOR_3 project.cds_in[0].read.pbus.data_in.bit.in2 // ������ ������� 3 + +#define FROM_ING_LOCAL_REMOUTE project.cds_in[0].read.pbus.data_in.bit.in3 // LOCAL=0/REMOUTE=1 �� ����� �������� +#define FROM_ING_LOCAL_KVITIR project.cds_in[0].read.pbus.data_in.bit.in4 // ������������ � ������ + +#define FROM_BSU_RAZBOR_SHEMA project.cds_in[0].read.pbus.data_in.bit.in5 // ��������� �����=0 +#define FROM_BSU_SBOR_SHEMA project.cds_in[0].read.pbus.data_in.bit.in6 // ������� �����=0 + +#define FROM_ING_RAZBOR_SHEMA project.cds_in[0].read.pbus.data_in.bit.in5 // ��������� �����=0 +#define FROM_ING_SBOR_SHEMA project.cds_in[0].read.pbus.data_in.bit.in6 // ������� �����=0 + +#define FROM_ING_OBOROTS_MINUS project.cds_in[0].read.pbus.data_in.bit.in7 // ������� ������ +#define FROM_ING_OBOROTS_PLUS project.cds_in[0].read.pbus.data_in.bit.in8 // ������� ������ + + +#define FROM_BSU_ZADA_DISPLAY project.cds_in[0].read.pbus.data_in.bit.in9 // ��������=1/�����=0 ��� +#define FROM_BSU_SVU project.cds_in[0].read.pbus.data_in.bit.in10 // ��������� ���=0/�������=1 ��� +#define FROM_SHEMA_QTV_ON_OFF ((project.cds_in[0].read.pbus.data_in.bit.in12)) + +// �� ������ ����� ������� ���, �� ������� ������ ����. +#define FROM_SVU_BLOCK_QTV project.cds_in[0].read.pbus.data_in.bit.in11 // ���������� ��� QTV �� ��� + +#define FROM_ING_ANOTHER_RASCEPITEL 1//project.cds_in[0].read.pbus.data_in.bit.in12 // ��������� ����������� ������� �� +#define FROM_SHEMA_UMP_ON_OFF project.cds_in[0].read.pbus.data_in.bit.in13 // ��������� �������� ��� �������������� �������������� + +#define FROM_SHEMA_READY_UMP project.cds_in[0].read.pbus.data_in.bit.in14 // ���������� ��� �������������� �������������� +#define FROM_ING_RASCEPITEL_ON_OFF ((project.cds_in[0].read.pbus.data_in.bit.in15)) // ��������� ����������� ��� + + + +///////////////// + +#define FROM_ING_OP_PIT_NORMA project.cds_in[1].read.pbus.data_in.bit.in0 // ��������� �������������� � ����� 0-����� +#define FROM_ING_OHLAD_UTE4KA_WATER !(project.cds_in[1].read.pbus.data_in.bit.in1) // ������ ���� // 1 - �����, 0 -������ +#define FROM_ING_SOST_ZAMKA project.cds_in[1].read.pbus.data_in.bit.in2 // ��������� ����� +#define FROM_ING_ZARYAD_ON project.cds_in[1].read.pbus.data_in.bit.in3 // ��������� ���� ���������� ������ 1-��� ������ + +#define FROM_ING_VENTIL_ON project.cds_in[1].read.pbus.data_in.bit.in4 // ����������� �������� 0-�������� +#define FROM_ING_NASOS_ON project.cds_in[1].read.pbus.data_in.bit.in5 // ��������� ����� ������� 0 - ������� +#define FROM_ING_NASOS_NORMA project.cds_in[1].read.pbus.data_in.bit.in6 // ������ � ����� 0? ����� ��������� ���� 0. +#define FROM_ING_ZAZEML_OFF project.cds_in[1].read.pbus.data_in.bit.in7 // ��������� ���������� 1-���������. +#define FROM_ING_NAGREV_ON project.cds_in[1].read.pbus.data_in.bit.in8 // ��������� ������������ 1-��������� +#define FROM_ING_BLOCK_IZOL_NORMA project.cds_in[1].read.pbus.data_in.bit.in9 // �������������� �� �������� ���� ��������. 1-������. +#define FROM_ING_VIPR_PREDOHR_NORMA project.cds_in[1].read.pbus.data_in.bit.in10 // �������������� ����������� � ����� 0 - �����. +#define FROM_ING_BLOCK_IZOL_AVARIA project.cds_in[1].read.pbus.data_in.bit.in11 // ������ �� �������� ������.�������� 0-������ +#define FROM_ALL_KNOPKA_AVARIA project.cds_in[1].read.pbus.data_in.bit.in12 // ������ ������ 1 - ������ ����. +#define FROM_ING_ZAZEML_ON project.cds_in[1].read.pbus.data_in.bit.in13 // ��������� ���������� 0-���������. + +#define FROM_ING_ANOTHER_MASTER_PCH project.cds_in[1].read.pbus.data_in.bit.in14 // ������ �� � ������ ������. + +#define FROM_ING_UPC_24V_NORMA project.cds_in[1].read.pbus.data_in.bit.in15 // 24 UPC � ����� 0-�����. + +//#define FROM_REZERV_12 project.cds_in[1].read.pbus.data_in.bit.in12 // ������ + + + + +#define TO_ING_ZARYAD_ON project.cds_out[0].write.sbus.data_out.bit.dout0 // �������� ����� +#define TO_ING_NAGREV_OFF project.cds_out[0].write.sbus.data_out.bit.dout1 // ��������� ������� +#define TO_ING_NASOS_1_ON project.cds_out[0].write.sbus.data_out.bit.dout2 // ����� 1 �������� +#define TO_ING_NASOS_2_ON project.cds_out[0].write.sbus.data_out.bit.dout3 // ����� 2 �������� +#define TO_ING_BLOCK_KEY_OFF project.cds_out[0].write.sbus.data_out.bit.dout4 // ���������� ����� ���������, ���������� �������� ������ + +#define TO_ING_RELOAD_UPC project.cds_out[0].write.sbus.data_out.bit.dout5 //5- ������������ ���������� ������� + +#define TO_SHEMA_ENABLE_QTV project.cds_out[0].write.sbus.data_out.bit.dout6 // 6 - ���������� ��������� QTV +#define TO_ING_LAMPA_ZARYAD project.cds_out[0].write.sbus.data_out.bit.dout7 //7- ������� �������� 80 ����. ��������� �������� + + + +#define MODE_QTV_UPRAVLENIE 2 // 1 - �������, 2 - ��������� + + +#if (MODE_QTV_UPRAVLENIE==1) +////////////////////////////////////////////////////////// +// QTV ��������� ������� +#define TO_SHEMA_QTV_ON_OFF project.cds_out[0].write.sbus.data_out.bit.dout8 // 8 - ��������� QTV +#endif + + +#if (MODE_QTV_UPRAVLENIE==2) +// QTV ��������� ��������� +#define TO_SHEMA_QTV_ON project.cds_out[0].write.sbus.data_out.bit.dout8 // 8 - ��������� QTV +#define TO_SHEMA_QTV_OFF project.cds_out[0].write.sbus.data_out.bit.dout9 // 9 - ���������� QTV +/////////////////////////////////////////////////////////// +#endif + +#define TO_ING_SMALL_LAMPA_AVARIA project.cds_out[0].write.sbus.data_out.bit.dout10 // ������ � ��� � ����� + +#define TO_SECOND_PCH_ALARM project.cds_out[0].write.sbus.data_out.bit.dout11 // 11 - ������ � ����. �� +#define TO_SECOND_PCH_MASTER project.cds_out[0].write.sbus.data_out.bit.dout12 // 12 - ����� - ������ � ����. �� + +#define TO_SHEMA_UMP_ON_OFF project.cds_out[0].write.sbus.data_out.bit.dout13 // 13 - �������� ��� �������������� �������������� +#define TO_ING_RASCEPITEL_OFF project.cds_out[0].write.sbus.data_out.bit.dout14// 14- ��������� ������� ��� +#define TO_ING_RASCEPITEL_ON project.cds_out[0].write.sbus.data_out.bit.dout15// 15 - �������� ������� ��� + + + +enum +{ + ALG_MODE_UF_CONST = 1, + ALG_MODE_SCALAR_OBOROTS, + ALG_MODE_SCALAR_POWER, + ALG_MODE_FOC_OBOROTS, + ALG_MODE_FOC_POWER +}; + + +enum +{ + STAGE_SBOR_STATUS_NO_STATUS = 0, + STAGE_SBOR_STATUS_FIRST, + STAGE_SBOR_STATUS_PUMP, + STAGE_SBOR_STATUS_ZARYAD, + STAGE_SBOR_STATUS_UMP_ON, + STAGE_SBOR_STATUS_QTV, + STAGE_SBOR_STATUS_UMP_OFF, + STAGE_SBOR_STATUS_RASCEPITEL_1, + STAGE_SBOR_STATUS_RASCEPITEL_2, + STAGE_SBOR_STATUS_RASCEPITEL_3, + STAGE_SBOR_STATUS_RASCEPITEL_4, + STAGE_SBOR_STATUS_WAIT_READY_ANOTHER, + STAGE_SBOR_STATUS_FINISH +}; + +/* + + + + + +#define TO_ING_KVITIR project.cds_out[0].write.sbus.data_out.bit.dout3 +#define TO_QTV_OFF project.cds_out[0].write.sbus.data_out.bit.dout4 + +#define TO_ING_VOZB_PODKLU4EN project.cds_out[0].write.sbus.data_out.bit.dout5 +#define TO_ING_VOZB_NEPODKLU4EN project.cds_out[0].write.sbus.data_out.bit.dout6 +#define TO_ING_VOZB_READY project.cds_out[0].write.sbus.data_out.bit.dout7 + + + +#define TO_ING_QTV_VLU4EN project.cds_out[0].write.sbus.data_out.bit.dout9 +#define TO_ING_QTV_READY project.cds_out[0].write.sbus.data_out.bit.dout10 +#define TO_ING_START_GED project.cds_out[0].write.sbus.data_out.bit.dout11 +#define TO_ING_SIL_BLOK_OTKL project.cds_out[0].write.sbus.data_out.bit.dout12 +#define TO_ING_SIL_BLOK_VKL project.cds_out[0].write.sbus.data_out.bit.dout13 +#define TO_ING_BLOK_VOZB_WORK project.cds_out[0].write.sbus.data_out.bit.dout15 +#define TO_ING_OSTANOV_GED project.cds_out[0].write.sbus.data_out.bit.dout14 + + + +#define FROM_ING_SIL_BLOK_VKL project.cds_in[1].read.pbus.data_in.bit.in0 +#define FROM_ING_SIL_BLOK_OTKL project.cds_in[1].read.pbus.data_in.bit.in1 +#define FROM_ING_GED_NAMAGNI4EN project.cds_in[1].read.pbus.data_in.bit.in2 +#define FROM_ING_GED_OSTANOVLEN project.cds_in[1].read.pbus.data_in.bit.in3 +#define FROM_ING_QTV_ON project.cds_in[1].read.pbus.data_in.bit.in4 +#define FROM_ING_QTV_OFF project.cds_in[1].read.pbus.data_in.bit.in5 +#define FROM_ING_VOZB_PODKLU4IT project.cds_in[1].read.pbus.data_in.bit.in6 +#define FROM_ING_VOZB_OTKLU4IT project.cds_in[1].read.pbus.data_in.bit.in7 +#define FROM_ING_VOZB_PUSK project.cds_in[1].read.pbus.data_in.bit.in8 + +*/ + +typedef struct +{ + int adc_temper_u[7]; + float real_temper_u[7]; + int real_int_temper_u[7]; + int max_real_int_temper_u; + + int adc_temper_water[2]; + float real_temper_water[2]; + int real_int_temper_water[2]; //0 - internal; 1 - external + int max_real_int_temper_water; + + int adc_temper_air[4]; + float real_temper_air[4]; + int real_int_temper_air[4]; + int max_real_int_temper_air; + int min_real_int_temper_air; + + + + +} TEMPER_EDRK; +#define TEMPER_EDRK_DEFAULT {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},0,\ + {0,0},{0,0},{0,0},0,\ + {0,0,0,0},{0,0,0,0},{0,0,0,0},0,0\ + } + + +typedef struct +{ + int adc_p_water[1]; + float real_p_water[1]; + int real_int_p_water[1]; + float filter_real_p_water[1]; + int filter_real_int_p_water[1]; + int flag_init_filter_temp[1]; + +} P_WATER_EDRK; +#define P_WATER_EDRK_DEFAULT {{0},{0},{0},{0},{0},{0}} + + + +typedef struct +{ + + struct + { + int adc_temper[6]; + float real_temper[6]; + int real_int_temper[6]; + float filter_real_temper[6]; + int filter_real_int_temper[6]; + int flag_init_filter_temp[6]; + int max_size; + int max_real_int_temper; + } winding; + + struct + { + int adc_temper[2]; + float real_temper[2]; + int real_int_temper[2]; + float filter_real_temper[2]; + int filter_real_int_temper[2]; + int flag_init_filter_temp[2]; + int max_size; + int max_real_int_temper; + } bear; + +} TEMPER_ACDRIVE; + +#define TEMPER_ACDRIVE_DEFAULT {{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},6,0},\ + {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},2,0} } +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + unsigned int all; + struct { + unsigned int U_1_MAX: 1; + unsigned int U_2_MAX: 1; + unsigned int U_1_MIN: 1; + unsigned int U_2_MIN : 1; + + unsigned int U_A1B1_MAX: 1; + unsigned int U_A2B2_MAX: 1; + unsigned int U_B1C1_MAX:1; + unsigned int U_B2C2_MAX :1; + + unsigned int U_A1B1_MIN :1; + unsigned int U_A2B2_MIN: 1; + unsigned int U_B1C1_MIN:1; + unsigned int U_B2C2_MIN :1; + + unsigned int U_IN_MAX:1; + unsigned int U_IN_MIN:1; + unsigned int I_1_MAX:1; + unsigned int I_2_MAX:1; + + } bits; + } e0; + + union { + unsigned int all; + struct { + unsigned int I_UO2_MAX: 1; + unsigned int I_UO3_MAX: 1; + unsigned int I_UO4_MAX: 1; + unsigned int I_UO5_MAX : 1; + + unsigned int I_UO6_MAX: 1; + unsigned int I_UO7_MAX: 1; + unsigned int I_BREAK_1_MAX:1; + unsigned int I_BREAK_2_MAX :1; + + unsigned int HWP_ERROR :1; + + unsigned int BLOCK_DOOR: 1; + unsigned int NO_INPUT_SYNC_SIGNAL: 1; + unsigned int NO_CONFIRM_ON_RASCEPITEL: 1; + + unsigned int ANOTHER_BS_NOT_ON_RASCEPITEL: 1; + unsigned int ANOTHER_BS_VERY_LONG_WAIT: 1; + unsigned int VERY_LONG_BOTH_READY2: 1; + unsigned int BOTH_KEYS_CHARGE_DISCHARGE: 1; + + + } bits; + } e1; + + + union { + unsigned int all; + struct { + unsigned int T_UO1_MAX:1; + unsigned int T_UO2_MAX :1; + unsigned int T_UO3_MAX :1; + unsigned int T_UO4_MAX :1; + + unsigned int T_UO5_MAX :1; + unsigned int T_UO6_MAX:1; + unsigned int T_UO7_MAX:1; + unsigned int T_WATER_EXT_MAX:1; + + unsigned int T_WATER_INT_MAX:1; + unsigned int P_WATER_INT_MAX: 1; + unsigned int P_WATER_INT_MIN: 1; + unsigned int T_AIR0_MAX :1; + + unsigned int T_AIR1_MAX :1; + unsigned int T_AIR2_MAX :1; + unsigned int T_AIR3_MAX :1; + unsigned int ERROR_RAZBOR_SHEMA :1; + + + } bits; + } e2; + + + union { + unsigned int all; + struct { + unsigned int NOT_READY_TK_0: 1; + unsigned int NOT_READY_TK_1 : 1; + unsigned int NOT_READY_TK_2: 1; + unsigned int NOT_READY_TK_3: 1; + + unsigned int NOT_READY_OUT_0:1; + unsigned int NOT_READY_OUT_1:1; + unsigned int NOT_READY_OUT_2:1; + unsigned int NOT_READY_IN_0 :1; + + unsigned int NOT_READY_IN_1 :1; + unsigned int NOT_READY_IN_2 :1; + unsigned int NOT_READY_ADC_0: 1; + unsigned int NOT_READY_ADC_1: 1; + + unsigned int NOT_READY_HWP_0: 1; + unsigned int NOT_READY_HWP_1: 1; + unsigned int NOT_READY_CONTR: 1; + unsigned int ERR_INT_PWM_LONG:1; + + + } bits; + } e3; + + + union { + unsigned int all; + struct { + + unsigned int ERR_TK_0: 1; + unsigned int ERR_TK_1: 1; + unsigned int ERR_TK_2: 1; + unsigned int ERR_TK_3: 1; + + unsigned int ERR_OUT_0:1; + unsigned int ERR_OUT_1:1; + unsigned int ERR_OUT_2:1; + unsigned int ERR_IN_0 :1; + + unsigned int ERR_IN_1 :1; + unsigned int ERR_IN_2 :1; + unsigned int ERR_ADC_0:1; + unsigned int ERR_ADC_1:1; + + unsigned int ERR_HWP_0:1; + unsigned int ERR_HWP_1:1; + unsigned int ANOTHER_BS_POWER_OFF:1; + unsigned int FAST_OPTICAL_ALARM:1; + } bits; + } e4; + + union { + unsigned int all; + struct { + + unsigned int LINE_ERR0: 1; + unsigned int LINE_HWP : 1; + unsigned int KEY_AVARIA: 1; + unsigned int PUMP_1: 1; + + unsigned int PUMP_2 : 1; + unsigned int FAN : 1; + unsigned int OP_PIT : 1; + unsigned int POWER_UPC :1; + + unsigned int UTE4KA_WATER :1; + unsigned int T_VIPR_MAX :1; + unsigned int ERROR_PRE_CHARGE_ON: 1; + unsigned int PRE_READY_PUMP: 1; + + unsigned int ERROR_GROUND_NET: 1; + unsigned int ERROR_HEAT: 1; + unsigned int ERROR_ISOLATE: 1; + unsigned int ERROR_PRED_VIPR: 1; + + + } bits; + } e5; + + union { + unsigned int all; + struct { + + unsigned int QTV_ERROR_NOT_ANSWER: 1; + unsigned int QTV_ERROR_NOT_U : 1; + unsigned int ERROR_PRE_CHARGE_U: 1; + unsigned int ERROR_PRE_CHARGE_ANSWER: 1; + + unsigned int UO2_KEYS :1; + unsigned int UO3_KEYS :1; + unsigned int UO4_KEYS :1; + unsigned int UO5_KEYS :1; + + unsigned int UO6_KEYS:1; + unsigned int UO7_KEYS:1; + unsigned int UO1_KEYS:1; + unsigned int ERR_PBUS:1; + + unsigned int ERR_SBUS:1; + unsigned int ER_DISBAL_BATT:1; + unsigned int ER_RAZBALANS_ALG:1; + unsigned int RASCEPITEL_ERROR_NOT_ANSWER:1; + + } bits; + } e6; + + union { + unsigned int all; + struct { + + unsigned int MASTER_SLAVE_SYNC: 1; + unsigned int WRITE_OPTBUS: 1; + unsigned int READ_OPTBUS: 1; + unsigned int ANOTHER_PCH_NOT_ANSWER: 1; + + unsigned int AUTO_SET_MASTER: 1; + unsigned int UMP_NOT_READY: 1; + unsigned int ERROR_SBOR_SHEMA: 1; + unsigned int NOT_VALID_CONTROL_STATION:1; + + unsigned int VERY_FAST_GO_0to1:1; + unsigned int T_ACDRIVE_WINDING_MAX:1; + unsigned int T_ACDRIVE_BEAR_MAX_DNE:1; + unsigned int SVU_BLOCK_ON_QTV:1; + + unsigned int UMP_NOT_ANSWER: 1; + unsigned int ANOTHER_RASCEPITEL_ON: 1; + unsigned int CAN2CAN_BS: 1; + unsigned int ANOTHER_BS_ALARM: 1; + + + + } bits; + } e7; + + union { + unsigned int all; + struct { + + unsigned int LOSS_OUTPUT_U1: 1; + unsigned int LOSS_OUTPUT_V1: 1; + unsigned int LOSS_OUTPUT_W1: 1; + unsigned int LOSS_OUTPUT_U2: 1; + + unsigned int LOSS_OUTPUT_V2: 1; + unsigned int LOSS_OUTPUT_W2: 1; + unsigned int LOSS_INPUT_A1B1: 1; + unsigned int LOSS_INPUT_B1C1: 1; + + unsigned int LOSS_INPUT_A2B2: 1; + unsigned int LOSS_INPUT_B2C2: 1; + unsigned int LOW_FREQ_50HZ: 1; + unsigned int U_IN_10_PROCENTS_LOW: 1; + + unsigned int U_IN_20_PROCENTS_LOW: 1; + unsigned int U_IN_20_PROCENTS_HIGH: 1; + unsigned int DISBALANCE_IM1_IM2: 1; + unsigned int WDOG_OPTICAL_BUS: 1; + + } bits; + } e8; + + union { + unsigned int all; + struct { + unsigned int T_ACDRIVE_BEAR_MAX_NE :1; + unsigned int I_GED_MAX :1; + unsigned int CHANGE_ACTIVE_CONTROL_TO_LOCAL_FROM_SVU :1; + unsigned int DISBALANCE_Uin_1 :1; + + unsigned int DISBALANCE_Uin_2 :1; + unsigned int U_IN_FREQ_NOT_NORMA :1; + unsigned int U_IN_FREQ_NOT_STABLE :1; + unsigned int ERR_PWM_WDOG :1; + + unsigned int ERR_INT_PWM_VERY_LONG : 1; + unsigned int SENSOR_ROTOR_1_BREAK : 1; + unsigned int SENSOR_ROTOR_2_BREAK : 1; + unsigned int SENSOR_ROTOR_1_2_BREAK : 1; + + unsigned int SENSOR_ROTOR_BREAK_DIRECTION : 1; + + unsigned int BREAK_TEMPER_WARNING : 1; + unsigned int BREAK_TEMPER_ALARM : 1; + unsigned int BREAKER_GED_ON : 1; + + } bits; + } e9; + union { + unsigned int all; + struct { + unsigned int WARNING_I_OUT_OVER_1_6_NOMINAL :1; + unsigned int T_BSU_Sensor_BK1 :1; + unsigned int T_BSU_Sensor_BK2 :1; + unsigned int T_ACDRIVE_WINDING_U1 :1; + unsigned int T_ACDRIVE_WINDING_V1 :1; + unsigned int T_ACDRIVE_WINDING_W1 :1; + unsigned int T_ACDRIVE_WINDING_U2 :1; + unsigned int T_ACDRIVE_WINDING_V2 :1; + unsigned int T_ACDRIVE_WINDING_W2 :1; + unsigned int res: 7; + + } bits; + } e10; + union { + unsigned int all; + struct { + unsigned int ERROR_PUMP_ON_SBOR:1; + unsigned int ERROR_RESTART_PUMP_1_ON_SBOR:1; + unsigned int ERROR_RESTART_PUMP_2_ON_SBOR:1; + unsigned int ERROR_RESTART_PUMP_ALL_ON_SBOR:1; + + unsigned int ERROR_PRED_ZARYAD:1; + unsigned int ERROR_PRED_ZARYAD_AFTER:1; + unsigned int ERROR_READY_UMP_BEFORE_QTV:1; + unsigned int ERROR_STATUS_QTV:1; + + unsigned int ERROR_UMP_ON_AFTER :1; + unsigned int ERROR_UMP_NOT_ON:1; + unsigned int ERROR_UMP_NOT_OFF :1; + unsigned int ERROR_RASCEPITEL_WAIT_CMD:1; + + unsigned int ERROR_RASCEPITEL_ON_AFTER:1; + unsigned int ERROR_DISABLE_SBOR:1; + unsigned int ERROR_VERY_LONG_SBOR:1; + unsigned int ERROR_CONTROLLER_BUS:1; +// unsigned int :1; + + } bits; + } e11; + union { + unsigned int all; + struct { + unsigned int res: 16; + + } bits; + } e12; + +} ERRORS_EDRK; + + +#define ERRORS_EDRK_DEFAULT {0,0,0,0,0,0,0,0,0,0,0,0} + +//////////////////////////////////////////////////////// + +typedef struct +{ + struct + { + unsigned int alive_can_to_another_bs; + unsigned int alive_sync_line; + unsigned int alive_sync_line_local; + unsigned int alive_opt_bus_read; + unsigned int alive_opt_bus_write; + unsigned int input_master_slave; + unsigned int input_alarm_another_bs; + unsigned int another_rascepitel; + unsigned int fast_optical_alarm; + } err_lock_signals; + struct + { + unsigned int alive_can_to_another_bs; + unsigned int alive_sync_line; + unsigned int alive_sync_line_local; + unsigned int alive_opt_bus_read; + unsigned int alive_opt_bus_write; + unsigned int input_master_slave; + unsigned int input_alarm_another_bs; + unsigned int another_rascepitel; + unsigned int fast_optical_alarm; + } err_signals; + struct + { + unsigned int alive_can_to_another_bs; + unsigned int alive_sync_line; + unsigned int alive_sync_line_local; + unsigned int alive_opt_bus_read; + unsigned int alive_opt_bus_write; + unsigned int input_master_slave; + unsigned int input_alarm_another_bs; + unsigned int another_rascepitel; + unsigned int fast_optical_alarm; + } warning_signals; + struct + { + unsigned int alive_can_to_another_bs; + unsigned int alive_sync_line; + unsigned int alive_sync_line_local; + unsigned int alive_opt_bus_read; + unsigned int alive_opt_bus_write; + unsigned int input_master_slave; + unsigned int input_alarm_another_bs; + unsigned int another_rascepitel; + unsigned int fast_optical_alarm; + } errors_count; + struct + { + unsigned int alive_can_to_another_bs; + unsigned int alive_sync_line; + unsigned int alive_sync_line_local; + unsigned int alive_opt_bus_read; + unsigned int alive_opt_bus_write; + unsigned int input_master_slave; + unsigned int input_alarm_another_bs; + unsigned int another_rascepitel; + unsigned int fast_optical_alarm; + } wait_count; + + + unsigned int sum_err; // ����� ������ + unsigned int sum_warning; // ����� �������������� + unsigned int another_bs_maybe_on; // ��� �� ������� + unsigned int another_bs_maybe_off; // ��� �� �������� + unsigned int ready1; // ������� ����������1 ���� + unsigned int ready2; // ������� ����������2 ���� + unsigned int ready3; // ���� ����� � master/slave � ����������� ��������� + unsigned int count_time_wait_ready1; // ������� �������� ���������� ���� + unsigned int count_time_wait_ready2; // ������� �������� ���������� ���� + unsigned int status; // ��� ���������, � ����� ����: �������, ���� ������, ���� ������. + + + +} MASTER_SLAVE_COM; +#define MASTER_SLAVE_COM_DEFAULT {{0,0,0,0,0,0,0,0},\ + {0,0,0,0,0,0,0,0},\ + {0,0,0,0,0,0,0,0},\ + {0,0,0,0,0,0,0,0},\ + {0,0,0,0,0,0,0,0},\ + 0,0,0,0,0,0,0,0,0} + + + +//////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////// + +typedef union { + unsigned int all; + struct { + + unsigned int master: 1; + unsigned int slave: 1; + unsigned int try_master: 1; + unsigned int try_slave: 1; + + unsigned int nothing: 1; + unsigned int sync1_2: 1; + unsigned int bus_off: 1; + unsigned int in_err: 1; + unsigned int sync_line_detect:1; + unsigned int tick:1; + + + } bits; + + } AUTO_MASTER_SLAVE_DATA; +//////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + + unsigned int ready1: 1; + unsigned int ready2: 1; + unsigned int ready3: 1; + unsigned int ready4: 1; + + unsigned int ready5: 1; + unsigned int ready6: 1; + unsigned int ready7: 1; + unsigned int ready_final: 1; + + unsigned int Batt: 1; + unsigned int ImitationReady2: 1; + unsigned int MasterSlaveActive: 1; // �������� ���� ���� master ��� slave + unsigned int preImitationReady2: 1; + + unsigned int res:4; + } bits; + } STATUS_READY; +//////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + + unsigned int ZARYAD_ON: 1; + unsigned int NAGREV_OFF: 1; + unsigned int NASOS_1_ON: 1; + unsigned int NASOS_2_ON: 1; + + unsigned int BLOCK_KEY_OFF: 1; + unsigned int RESET_BLOCK_IZOL: 1; + unsigned int SMALL_LAMPA_AVARIA: 1; + unsigned int RASCEPITEL_OFF: 1; + + unsigned int RASCEPITEL_ON: 1; + + unsigned int res:7; + } bits; + } TO_ING; +//////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int OP_PIT_NORMA : 1; + unsigned int OHLAD_UTE4KA_WATER: 1; + unsigned int RASCEPITEL_ON: 1; + unsigned int ZARYAD_ON: 1; + + unsigned int VENTIL_ON : 1; + unsigned int NASOS_ON: 1; + unsigned int NASOS_NORMA: 1; + unsigned int ZAZEML_OFF: 1; + + unsigned int NAGREV_ON: 1; + unsigned int BLOCK_IZOL_NORMA: 1; + unsigned int VIPR_PREDOHR_NORMA: 1; + unsigned int UPC_24V_NORMA: 1; + + unsigned int LOCAL_REMOUTE: 1; + unsigned int ZAZEML_ON: 1; + unsigned int ALL_KNOPKA_AVARIA: 1; + unsigned int BLOCK_IZOL_AVARIA: 1; + } bits; + } FROM_ING1; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int KEY_PLUS : 1; + unsigned int KEY_MINUS : 1; + unsigned int KEY_SBOR : 1; + unsigned int KEY_RAZBOR : 1; + + unsigned int KEY_KVITIR : 1; + unsigned int SOST_ZAMKA : 1; + + unsigned int res: 9; + + } bits; + } FROM_ING2; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int MASTER: 1; + unsigned int RASCEPITEL: 1; + unsigned int res:14; + } bits; + } FROM_SECOND_PCH; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int MASTER: 1; + unsigned int ALARM: 1; + + unsigned int res:14; + } bits; + } TO_SECOND_PCH; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int QTV_ON: 1; + unsigned int QTV_OFF: 1; + unsigned int UMP_ON_OFF: 1; + unsigned int ENABLE_QTV: 1; + unsigned int QTV_ON_OFF: 1; + unsigned int CROSS_UMP_ON_OFF: 1; + unsigned int CROSS_QTV_ON_OFF: 1; + + unsigned int res:9; + } bits; + } TO_SHEMA; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int QTV_ON_OFF: 1; + // unsigned int KNOPKA_AVARIA: 1; + unsigned int ZADA_DISPLAY : 1; + unsigned int RAZBOR_SHEMA :1 ; + unsigned int SBOR_SHEMA : 1; + // unsigned int OPENDOOR : 1; + unsigned int SVU : 1; + // unsigned int ACTIVE : 1; + unsigned int READY_UMP : 1; + unsigned int UMP_ON_OFF : 1; + unsigned int SVU_BLOCK_QTV : 1; + + // unsigned int res:10; + } bits; + } FROM_SHEMA; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int KVITIR: 1; + unsigned int PLUS: 1; + unsigned int MINUS : 1; + unsigned int PROVOROT :1 ; + + unsigned int UOM_READY_ACTIVE : 1; + unsigned int UOM_LIMIT_3 : 1; + unsigned int UOM_LIMIT_2 : 1; + unsigned int UOM_LIMIT_1 : 1; + + + unsigned int res:8; + } bits; + } FROM_ZADAT4IK; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int SBOR_SHEMA: 1; + unsigned int RAZBOR_SHEMA: 1; + unsigned int KVITIR: 1; + unsigned int ACTIVE : 1; + unsigned int res:12; + } bits; + } FROM_RS; + //////////////////////////////////////////////////////// + typedef union { + unsigned int all; + struct { + unsigned int SBOR_SHEMA: 1; + unsigned int RAZBOR_SHEMA: 1; + unsigned int KVITIR: 1; + unsigned int ACTIVE : 1; + unsigned int BLOCKED : 1; + unsigned int res:11; + } bits; + } FROM_DISPLAY; + //////////////////////////////////////////////////////// + typedef struct { + + union { + int all; + } OBOROTS1; + + + union { + int all; + } OBOROTS2; + + union { + unsigned int all; + struct { + unsigned int GOTOV1 : 1; + unsigned int GOTOV2 : 1; + unsigned int EMKOST : 1; //For 23550.3 and AVARIA moved up + unsigned int NEISPRAVNOST : 1; + unsigned int PEREGREV : 1; + unsigned int OGRAN_POWER : 1; + unsigned int AVARIA : 1; + unsigned int res:9; + } bits; + } BIG_LAMS; + + union { + unsigned int all; + struct { + unsigned int PCH1_READY1: 1; + unsigned int PCH1_SHEMA_SOBRANA: 1; + unsigned int PCH1_PODKLU4EN: 1; + unsigned int PCH1_MESTNOE: 1; + + unsigned int PCH2_READY1: 1; + unsigned int PCH2_SHEMA_SOBRANA: 1; + unsigned int PCH2_PODKLU4EN: 1; + unsigned int PCH2_MESTNOE: 1; + + unsigned int GED_PEREGREV: 1; + unsigned int PCH1_PCH2_SYNC: 1; + unsigned int GED_PEREGRUZ: 1; + unsigned int OBOROT_SVU: 1; + + unsigned int OBOROT_ZADAT: 1; + unsigned int OBOROT_MONITOR: 1; + unsigned int OBOROT_VPU: 1; + unsigned int HOD: 1; + } bits; + } APL_LAMS0; + + union { + unsigned int all; + struct { + unsigned int PCH_READY1: 1; + unsigned int PCH_SHEMA_SOBRANA: 1; + unsigned int PCH_PODKLU4EN: 1; + unsigned int PCH_MESTNOE: 1; + unsigned int reserv: 12; + } bits; + } APL_LAMS_PCH; + + } TO_ZADAT4IK; + +#define TO_ZADAT4IK_DEFAULT {0,0,0,0,0} + + + //////////////////////////////////////////////////////// + typedef struct { + + union { + int all; + } OBOROTS1; + + + union { + int all; + } OBOROTS2; + + union { + unsigned int all; + struct { + unsigned int VPU: 1; + unsigned int GOTOV2: 1; + unsigned int PODDERG_OBOROTS : 1; + unsigned int PEREGRUZKA :1 ; + unsigned int res:12; + } bits; + } BIG_LAMS; + + } TO_VPU; + +#define TO_VPU_DEFAULT {0,0,0} + + //////////////////////////////////////////////////////// + typedef struct { + + unsigned int level_value; + unsigned int ready; + unsigned int error; + unsigned int code; + _iq iq_level_value; + _iq iq_level_value_kwt; + + + + union { + unsigned int all; + struct { + unsigned int ready: 1; + unsigned int level0: 1; + unsigned int level1: 1; + unsigned int level2: 1; + unsigned int level3: 12; + } bits; + } digital_line; + + } FROM_UOM; + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// + typedef struct { + + int int_ZadanieU_Charge; + float ZadanieU_Charge; + _iq iq_ZadanieU_Charge; + _iq iq_ZadanieU_Charge_rmp; + + int int_oborots_zad; + float oborots_zad; + float oborots_zad_hz; + _iq iq_oborots_zad_hz; + _iq iq_oborots_zad_hz_rmp; + + int int_fzad; + float fzad; + _iq iq_fzad; + _iq iq_fzad_rmp; + + int int_kzad; + float kzad; + _iq iq_kzad; + _iq iq_kzad_rmp; + + int int_Izad; + float Izad; + _iq iq_Izad; + _iq iq_Izad_rmp; + + int int_power_zad; + float power_zad; + _iq iq_power_zad; + _iq iq_power_zad_rmp; + + } ZADANIE_FROM_ANOTHER_BS; + +#define ZADANIE_FROM_ANOTHER_BS_DEFAULT {\ + 0,0,0,0, 0,0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 } + + //////////////////////////////////////////////////////// + +typedef struct { + + RMP_V1 rmp_ZadanieU_Charge; + RMP_V1 rmp_fzad; + RMP_V1 rmp_k_u_disbalance; + RMP_V1 rmp_kplus_u_disbalance; + RMP_V1 rmp_Izad; + + RMP_V2 rmp_powers_zad; + + RMP_V2 rmp_limit_powers_zad; + RMP_V1 rmp_kzad; + + RMP_V2 rmp_oborots_zad_hz; + + RMP_V1 rmp_oborots_imitation; + + _iq rmp_oborots_imitation_rmp; + + + float ZadanieU_Charge; + _iq iq_ZadanieU_Charge; + _iq iq_ZadanieU_Charge_rmp; + + float oborots_zad; + + float oborots_zad_hz; + _iq iq_oborots_zad_hz; + _iq iq_oborots_zad_hz_rmp; + + float fzad; + _iq iq_fzad; + _iq iq_fzad_rmp; + + float kzad; + _iq iq_kzad; + _iq iq_kzad_rmp; + + float k_u_disbalance; + _iq iq_k_u_disbalance; + _iq iq_k_u_disbalance_rmp; + + float kplus_u_disbalance; + _iq iq_kplus_u_disbalance; + _iq iq_kplus_u_disbalance_rmp; + + float Izad; + _iq iq_Izad; + _iq iq_Izad_rmp; + + float power_zad; + _iq iq_power_zad; + _iq iq_power_zad_rmp; + + float limit_power_zad; + _iq iq_limit_power_zad; + _iq iq_limit_power_zad_rmp; + + _iq iq_set_break_level; + + float oborots_zad_no_dead_zone; + +} ZADANIE; + +#define ZADANIE_DEFAULT { RMP_V1_DEFAULTS, RMP_V1_DEFAULTS,RMP_V1_DEFAULTS,\ + RMP_V1_DEFAULTS,RMP_V1_DEFAULTS,\ + RMP_V2_DEFAULTS,\ + RMP_V2_DEFAULTS,RMP_V1_DEFAULTS,\ + RMP_V2_DEFAULTS,\ + RMP_V1_DEFAULTS,\ + 0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0 , 0,0,0, 0,0} + +typedef union { + struct { + unsigned int limit_by_temper:1; + unsigned int limit_Iout:1; + unsigned int limit_UOM:1; //���������� ����������� �������� + unsigned int limit_from_SVU:1; + unsigned int limit_from_freq:1; + unsigned int limit_from_uom_fast:1; + unsigned int limit_moment:1; + + unsigned int res:9; + } bits; + unsigned int all; +} POWER_LIMIT; + +#define POWER_LIMIT_DEFAULTS {0} + + +typedef struct { + + _iq temper_limit; + _iq power_limit; + _iq moment_limit; + _iq uin_freq_limit; + _iq uom_limit; + + _iq local_temper_limit; + _iq local_power_limit; + _iq local_moment_limit; + _iq local_uin_freq_limit; + _iq local_uom_limit; + + _iq sum_limit; + _iq local_sum_limit; + int code_status; + +} ALL_LIMIT_KOEFFS; + +#define ALL_LIMIT_KOEFFS_DEFAULTS {0,0,0,0,0, 0,0,0,0,0, 0,0,0} + +typedef struct { + _iq power_units; + _iq area; + _iq water_int; + _iq water_ext; + _iq acdrive_windings; + + _iq acdrive_bears; + _iq sum_limit; + int code_status; +} TEMPERATURE_LIMIT_KOEFFS; + +#define TEMPERATURE_LIMIT_KOEFFS_DEFAULTS {0,0,0,0,0, 0,CONST_IQ_1,0} + +#define COUNT_MOTO_PULT 18 + +typedef struct +{ + + int nPCH; + int TimeToChangePump; + + int count_revers; // ���-�� �������� + int count_build; // ���-�� ������ ���� + + int LastWorkPump; // ����� ��� ��������� ���������� ����� + + int moto[COUNT_MOTO_PULT]; + +} t_params_pult_ing_one; + +#define PARAMS_PULT_ING_ONE_DEFAULTS {-1,-1, -1,-1, 0, \ + {-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1 } } + +#define PARAMS_PULT_ING_TWO_DEFAULTS {0,0, 0,0, 0, \ + {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0 } } + +typedef struct +{ + int flagSaveDataPCH; + int flagSaveDataMoto; + int flagSaveSlowLogs; + int flagSaveParamLogs; + + int logger_params[28]; + + t_params_pult_ing_one data; + t_params_pult_ing_one data_from_pult; + t_params_pult_ing_one data_to_pult; + +// int nPCH_from_pult; +// int nPCH_to_pult; +// int nPCH; +// +// int TimeToChangePump_from_pult; +// int TimeToChangePump_to_pult; +// int TimeToChangePump; +// +// int moto_from_pult[COUNT_MOTO_PULT]; +// int mot_to_pult[COUNT_MOTO_PULT]; +// int moto[COUNT_MOTO_PULT]; +// +// int count_revers_from_pult; +// int count_revers_to_pult; + +} t_params_pult_ing; + +#define PARAMS_PULT_ING_DEFAULTS {0,0,0,0, \ + {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0}, \ + PARAMS_PULT_ING_TWO_DEFAULTS, \ + PARAMS_PULT_ING_ONE_DEFAULTS, \ + PARAMS_PULT_ING_ONE_DEFAULTS \ + } + + + + +typedef struct +{ + int log_what_memory; // �������� 0 - ��� �� ������, �� �����; + //�������� 1 - ��� ������, ���� �����; + //�������� 2 - ���� ������, ��� �����; + //�������� 3 - ���� � ������ � �����; + int kvitir; // + int sbor; + int send_log; + int pump_mode; + int sdusb;// 0 - sd, 1 usb + +} t_pult_cmd_ing; + +#define PULT_CMD_ING_DEFAULTS 0,0,0,0,0,0 + + + +//////////////////////////////////////////////////////// +typedef struct +{ + ZADANIE zadanie; + ZADANIE_FROM_ANOTHER_BS zadanie_from_another_bs; + TEMPER_EDRK temper_edrk; + P_WATER_EDRK p_water_edrk; + ERRORS_EDRK errors; + ERRORS_EDRK warnings; + TEMPER_ACDRIVE temper_acdrive; + + POWER_LIMIT power_limit; + TEMPERATURE_LIMIT_KOEFFS temper_limit_koeffs; + ALL_LIMIT_KOEFFS all_limit_koeffs; + + MASTER_SLAVE_COM ms; + + //////// + + struct { + + AUTO_MASTER_SLAVE_DATA local; // 1 + AUTO_MASTER_SLAVE_DATA prev_local;//1 + AUTO_MASTER_SLAVE_DATA remoute;//1 + AUTO_MASTER_SLAVE_DATA prev_remoute;//1 + unsigned int status; + unsigned int prev_status; + } auto_master_slave; // 6 + + + + STATUS_READY Status_Ready; //1 + + TO_ING to_ing; //1 + + FROM_ING1 from_ing1;//1 + + FROM_ING2 from_ing2;//1 + + FROM_SECOND_PCH from_second_pch;//1 + + TO_SECOND_PCH to_second_pch;//1 + + TO_SHEMA to_shema;//1 + + FROM_SHEMA from_shema;//1 + FROM_SHEMA from_shema_filter;//1 + + FROM_ZADAT4IK from_zadat4ik;//1 + + FROM_ZADAT4IK from_vpu;//1 + + FROM_RS from_rs;//1 + + FROM_RS from_can;//1 + + FROM_DISPLAY from_display;//1 + + FROM_DISPLAY from_mpu;//1 + + FROM_DISPLAY from_svu;//1 + + TO_ZADAT4IK to_zadat4ik;//5 + + + + TO_VPU to_vpu;//3 + + FROM_UOM from_uom;//7 +/////////////////////////////////////////////// + + unsigned int Discharge; + unsigned int ManualDischarge; + unsigned int NoDetectUZeroDischarge; + + unsigned int TimeSbor; + unsigned int TimeRazbor; + + unsigned int AutoStartPump; + unsigned int SumStartPump; + unsigned int ManualStartPump; + + + + unsigned int SumSbor; + + int Kvitir; + int KvitirProcess;//10 + + unsigned int prevGo; + unsigned int Go; + unsigned int GoBreak; + + unsigned int GoWait; + + int flag_wait_set_to_zero_zadanie; + int flag_block_zadanie; + int StartGEDfromControl; + int StartGEDfromZadanie; + int prevStartGEDfromZadanie; + + int StartGED; + int test_mode; + int cmd_to_qtv;//20 + int cmd_to_ump;//20 + int prepare_stop_PWM; + + int StartGEDfromSyncBus; + + + int cmd_to_rascepitel; + + int Mode_ScalarVectorUFConst; + int Mode_OborotsOrPower; + + int SelectPump1_2;//25 + + int summ_errors; + int Status_Charge; + + unsigned int Sbor_Mode; + unsigned int Razbor_Mode; + unsigned int time_wait_sbor; + + int Status_Sbor; + int Stage_Sbor; + int StatusPumpFanAll; + + int StatusPump0; + int StatusPump1; + int StatusFunAll; + int StatusPumpAll;//35 + + + int Run_Pred_Zaryad; + int Zaryad_OK; + int Rascepitel_OK; + int Run_QTV; + int Run_Rascepitel; + int Run_Rascepitel_from_RS; + int Run_UMP; + int Zaryad_UMP_Ok; + int Status_UMP_Ok; + + + int Status_QTV_Ok; + int Status_Rascepitel_Ok; + int Status_Perehod_Rascepitel; + int Final_Status_Rascepitel; + int you_can_on_rascepitel; + int RunZahvatRascepitel; + int RunUnZahvatRascepitel; + + _iq iqMAX_U_ZPT; + _iq iqMAX_U_ZPT_Global; + _iq iqMAX_U_ZPT_Predzaryad; + _iq iqMIN_U_ZPT;//50 + + _iq iqMAX_U_IN; + _iq iqMIN_U_IN; + + int SborFinishOk; + int RazborNotFinish; + + int Obmotka1; + int Obmotka2; + + _iq f_stator; + + _iq k_stator1; + _iq k_stator2;//60 + + _iq iq_f_rotor_hz; + float f_rotor_hz; + int oborots; + int rotor_direction; + int power_kw; +// _iq iq_oborots; + + _iq Izad_out; + + unsigned int period_calc_pwm_int1; + unsigned int period_calc_pwm_int2; + + unsigned int count_lost_interrupt; + unsigned int into_pwm_interrupt; + + int disable_alg_u_disbalance; + + _iq Kplus; + _iq Kminus; + + unsigned int Revers; + + _iq Uzad_max; + + _iq iq_bpsi_normal; + + _iq iq_f_provorot;//70 + + int flag_second_PCH; + int test; + + int Stop; + + int warning; + int overheat; + + unsigned int MasterSlave; + + _iq master_theta; + _iq master_Uzad; + _iq master_Iq; + _iq master_Izad; + _iq tetta_to_slave; + _iq Uzad_to_slave; + _iq Iq_to_slave; + _iq P_from_slave; + _iq P_to_master;//82 + + int flag_wait_both_ready2; + + int number_can_box_terminal_cmd; + int number_can_box_terminal_oscil; + + int Provorot; + int int_koef_ogran_power; + _iq iq_koef_ogran_power; + + int int_koef_ogran_power_another_bs; + _iq iq_koef_ogran_power_another_bs; + + int power_kw_another_bs; + _iq iq_power_kw_another_bs; + + int run_razbor_shema; + + int Ready1_another_bs; + int Ready2_another_bs; + + int ump_cmd_another_bs; + int qtv_cmd_another_bs; + + int active_post_upravl; + int active_post_upravl_another_bs; + int MasterSlave_another_bs; + int freq_50hz_1; + int freq_50hz_2; + + _iq test_rms_Iu; + _iq test_rms_Ua; +// + int disable_interrupt_pwm; + + int disable_interrupt_timer1; + int disable_interrupt_timer2; + int disable_interrupt_timer3; + int disable_interrupt_timer4; + + int disable_interrupt_sync; + + int get_new_data_from_hmi; + int flag_enable_update_hmi; + + int flag_disable_pult_485; + + int disable_rascepitel_work; + + int enable_pwm_test_lines; + int count_bs_work; + + unsigned int run_to_pwm_async; + + int power_kw_full; + + int stop_logs_rs232; + int sbor_wait_ump1; + int sbor_wait_ump2; + int flag_enable_on_ump; + + int local_ump_on_off; + int local_ump_on_off_count; + int local_ready_ump; + int local_ready_ump_count; + + t_params_pult_ing pult_data; + + int logs_rotor; + + int stop_slow_log; + int t_slow_log; + int disable_limit_power_from_svu; + int disable_uom; + int disable_break_work; + + int flag_another_bs_first_ready12; + int flag_this_bs_first_ready12; + int enter_to_pump_stage; + + int buildYear; + int buildMonth; + int buildDay; + + int errors_another_bs_from_can; + + unsigned int count_sbor; + unsigned int count_revers; + unsigned int count_run; + + int flag_slow_in_main; + + t_pult_cmd_ing pult_cmd; + + int get_new_data_from_hmi2; + + _iq iq_freq_50hz; + + int imit_limit_freq; + int imit_limit_uom; + int set_limit_uom_50; + + _iq iq_power_kw_full_znak; + _iq iq_power_kw_one_znak; + + _iq iq_power_kw_full_filter_znak; + _iq iq_power_kw_one_filter_znak; + + _iq iq_power_kw_full_abs; + _iq iq_power_kw_one_abs; + + _iq iq_power_kw_full_filter_abs; + _iq iq_power_kw_one_filter_abs; + + unsigned int sum_count_err_read_opt_bus; + + int imit_save_slow_logs; + + int imit_send_alarm_log_pult; + + int current_active_control; + + // int data_to_message2[100]; +//101 + unsigned long canes_reg; + unsigned long cantec_reg; // Transmit Error Counter + unsigned long canrec_reg; // Receive Error Counter + + int cmd_clear_can_error; + + int cmd_very_slow_start; + + int cmd_imit_low_isolation; + + + int breaker_on; + int break_tempers[4]; + + int cmd_disable_calc_km_on_slave; + + +} EDRK; + + + +#define EDRK_DEFAULT { \ + ZADANIE_DEFAULT,\ + ZADANIE_FROM_ANOTHER_BS_DEFAULT,\ + TEMPER_EDRK_DEFAULT, \ + P_WATER_EDRK_DEFAULT, \ + ERRORS_EDRK_DEFAULT, \ + ERRORS_EDRK_DEFAULT, \ + TEMPER_ACDRIVE_DEFAULT, \ + POWER_LIMIT_DEFAULTS, \ + TEMPERATURE_LIMIT_KOEFFS_DEFAULTS, \ + ALL_LIMIT_KOEFFS_DEFAULTS, \ + MASTER_SLAVE_COM_DEFAULT, \ + 0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0, \ + 0,0,0,0, \ + 0,0,0, \ + 0,0,0,0,0,0,0, \ + \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0, 0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0, \ + PARAMS_PULT_ING_DEFAULTS, \ + 0,0,0,0,0,0,0,0, \ + 0,0,0,\ + 0, 0,0,0, 0, \ + PULT_CMD_ING_DEFAULTS, 0,0, 0,0,0, 0,0,0,0, 0,0,0,0, \ + 0, 0,0, 0, 0, \ + 0,0,0, 0, 0, 0, \ + 0, {0,0,0,0}, \ + 0 \ + } + + +extern EDRK edrk; +extern PLL_REC pll1; + +//float get_sensor_ing(void); +//float get_i_vozbud(void); +//float get_zad_vozbud(void); + +//unsigned int convert_w_to_mA(float inp); + +void edrk_init(void); + + +void update_input_edrk(void); +void update_output_edrk(void); + + +//float get_amper_vozbud(void); + +//void set_amper_vozbud(float set_curr, float cur_curr); + + + +//void write_dac(int ndac, int Value); + +void run_edrk(void); + + + +void set_oborots_from_zadat4ik(void); +void get_where_oborots(void); + +//void update_errors(void); + + + + + + +//unsigned int zaryad_on_off(unsigned int flag); + + +void update_lamp_alarm(void); + + + + + + +//int get_status_temper_acdrive_winding(int nc); +//int get_status_temper_acdrive_bear(int nc); +//int get_status_temper_air(int nc); +//int get_status_temper_u(int nc); +//int get_status_temper_water(int nc); +//int get_status_p_water_max(void); +//int get_status_p_water_min(int pump_on_off); + +void detect_kvitir_from_all(void); +//void set_status_pump_fan(void); + + + +int qtv_on_off(unsigned int flag); + +///int detect_error_u_zpt(void); +//int detect_error_u_zpt_on_predzaryad(void); + +void set_zadanie_u_charge(void); + + + + + + + + + + + +void edrk_init_variables(void); + +void edrk_init_before_main(void); +void edrk_init_before_loop(void); +void edrk_go_main(void); + +int get_start_ged_from_zadanie(void); + + +//void UpdateTableSecondBS(void); + +unsigned int get_ready_1(void); + +//int detect_zaryad_ump(void); + +void cross_stend_automats(void); + + + +void get_sumsbor_command(void); + + +//unsigned int read_cmd_sbor_from_bs(void); + +//void read_data_from_bs(void); + + +void check_change_post_upravl(void); +int get_code_active_post_upravl(void); + + + +void auto_detect_zero_u_zpt(void); + +void run_can_from_mpu(void); +void set_new_level_i_protect(int n_af, int level); +void update_maz_level_i_af(int n_af, unsigned int new_maz_level); +void calc_count_build_revers(void); +int calc_auto_moto_pump(void); +void prepare_logger_pult(void); +void read_can_error(void); +void clear_can_error(void); +void cmd_clear_can_error(void); +void check_temper_break(void); +void check_breaker_ged(void); + + + + +//extern int ccc[40]; + +void reinit_before_sbor(void); +unsigned int toggle_status_lamp(unsigned int bb1, unsigned int flag); + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Inu/Src/main/f281xbmsk.h b/Inu/Src/main/f281xbmsk.h new file mode 100644 index 0000000..f9dd78f --- /dev/null +++ b/Inu/Src/main/f281xbmsk.h @@ -0,0 +1,244 @@ +/* ================================================================================== +File name: F281XBMSK.H + +Originator: Digital Control Systems Group + Texas Instruments +Description: +Header file containing handy bitmasks for setting up register values. +This file defines the bitmasks for F281X. + +Target: TMS320F281x family + +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20: Using DSP281x v. 1.00 or higher +---------------------------------------------------------------------------------- */ + +#ifndef __F281X_BMSK_H__ +#define __F281X_BMSK_H__ + +/*------------------------------------------------------------------------------ + F281X Register TxCON +------------------------------------------------------------------------------*/ +#define FREE_RUN_FLAG 0x8000 +#define SOFT_STOP_FLAG 0x4000 + +#define TIMER_STOP 0x0000 +#define TIMER_CONT_UPDN 0x0800 +#define TIMER_CONT_UP 0x1000 +#define TIMER_DIR_UPDN 0x1800 + +#define TIMER_CLK_PRESCALE_X_1 0x0000 +#define TIMER_CLK_PRESCALE_X_2 0x0100 +#define TIMER_CLK_PRESCALE_X_4 0x0200 +#define TIMER_CLK_PRESCALE_X_8 0x0300 +#define TIMER_CLK_PRESCALE_X_16 0x0400 +#define TIMER_CLK_PRESCALE_X_32 0x0500 +#define TIMER_CLK_PRESCALE_X_64 0x0600 +#define TIMER_CLK_PRESCALE_X_128 0x0700 + +#define TIMER_ENABLE_BY_OWN 0x0000 +#define TIMER_ENABLE_BY_T1 0x0080 + +#define TIMER_ENABLE 0x0040 +#define TIMER_DISABLE 0x0000 + +#define TIMER_CLOCK_SRC_INTERNAL 0x0000 +#define TIMER_CLOCK_SRC_EXTERNAL 0x0010 +#define TIMER_CLOCK_SRC_QEP 0x0030 + +#define TIMER_COMPARE_LD_ON_ZERO 0x0000 +#define TIMER_COMPARE_LD_ON_ZERO_OR_PRD 0x0004 +#define TIMER_COMPARE_LD_IMMEDIATE 0x0008 + +#define TIMER_ENABLE_COMPARE 0x0002 +#define TIMER_SELECT_T1_PERIOD 0x0001 + +/*------------------------------------------------------------------------------ + F281X Register ACTR 0x7413 BIT FIELD MASKS +------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------ +Space Vector Direction Commands +------------------------------------------------------------------------------*/ +#define SV_DIRECTION_CW 0x8000 +#define SV_DIRECTION_CCW 0x0000 + +/*------------------------------------------------------------------------------ +Space Vector Generation Vectors +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +#define SPACE_VECTOR_0 0x0000 +#define SPACE_VECTOR_1 0x1000 +#define SPACE_VECTOR_2 0x2000 +#define SPACE_VECTOR_3 0x3000 +#define SPACE_VECTOR_4 0x4000 +#define SPACE_VECTOR_5 0x5000 +#define SPACE_VECTOR_6 0x6000 +#define SPACE_VECTOR_7 0x7000 + +/*------------------------------------------------------------------------------ + Compare action definitions +------------------------------------------------------------------------------*/ +#define COMPARE6_FL 0x0000 +#define COMPARE6_AL 0x0400 +#define COMPARE6_AH 0x0800 +#define COMPARE6_FH 0x0C00 +//------------------------------------------------------------------------------ +#define COMPARE5_FL 0x0000 +#define COMPARE5_AL 0x0100 +#define COMPARE5_AH 0x0200 +#define COMPARE5_FH 0x0300 +//------------------------------------------------------------------------------ +#define COMPARE4_FL 0x0000 +#define COMPARE4_AL 0x0040 +#define COMPARE4_AH 0x0080 +#define COMPARE4_FH 0x00C0 +//------------------------------------------------------------------------------ +#define COMPARE3_FL 0x0000 +#define COMPARE3_AL 0x0010 +#define COMPARE3_AH 0x0020 +#define COMPARE3_FH 0x0030 +//------------------------------------------------------------------------------ +#define COMPARE2_FL 0x0000 +#define COMPARE2_AL 0x0004 +#define COMPARE2_AH 0x0008 +#define COMPARE2_FH 0x000C +//------------------------------------------------------------------------------ +#define COMPARE1_FL 0x0000 +#define COMPARE1_AL 0x0001 +#define COMPARE1_AH 0x0002 +#define COMPARE1_FH 0x0003 +//------------------------------------------------------------------------------ + +/*------------------------------------------------------------------------------ + F281X Register COMCONA/COMCONB +------------------------------------------------------------------------------*/ +#define CMPR_ENABLE 0x8000 +#define CMPR_LD_ON_ZERO 0x0000 +#define CMPR_LD_ON_ZERO_OR_PRD 0x2000 +#define CMPR_LD_IMMEDIATE 0x4000 +#define SVENABLE 0x1000 +#define SVDISABLE 0x0000 +#define ACTR_LD_ON_ZERO 0x0000 +#define ACTR_LD_ON_ZERO_OR_PRD 0x0400 +#define ACTR_LD_IMMEDIATE 0x0800 +#define FCOMPOE 0x0100 + +/*------------------------------------------------------------------------------ + F281X Register DBTCON +------------------------------------------------------------------------------*/ +#define DBT_VAL_0 0x0000 +#define DBT_VAL_1 0x0100 +#define DBT_VAL_2 0x0200 +#define DBT_VAL_3 0x0300 +#define DBT_VAL_4 0x0400 +#define DBT_VAL_5 0x0500 +#define DBT_VAL_6 0x0600 +#define DBT_VAL_7 0x0700 +#define DBT_VAL_8 0x0800 +#define DBT_VAL_9 0x0900 +#define DBT_VAL_10 0x0A00 +#define DBT_VAL_11 0x0B00 +#define DBT_VAL_12 0x0C00 +#define DBT_VAL_13 0x0D00 +#define DBT_VAL_14 0x0E00 +#define DBT_VAL_15 0x0F00 + +#define EDBT3_DIS 0x0000 +#define EDBT3_EN 0x0080 +#define EDBT2_DIS 0x0000 +#define EDBT2_EN 0x0040 +#define EDBT1_DIS 0x0000 +#define EDBT1_EN 0x0020 + +#define DBTPS_X32 0x0014 +#define DBTPS_X16 0x0010 +#define DBTPS_X8 0x000C +#define DBTPS_X4 0x0008 +#define DBTPS_X2 0x0004 +#define DBTPS_X1 0x0000 + +/*------------------------------------------------------------------------------ + F281X Register ADCTRL1 +------------------------------------------------------------------------------*/ +#define ADC_SUS_MODE0 0x0000 +#define ADC_SUS_MODE1 0X1000 +#define ADC_SUS_MODE2 0x2000 +#define ADC_SUS_MODE3 0X3000 +#define ADC_RESET_FLAG 0x4000 + +#define ADC_ACQ_PS_1 0x0000 +#define ADC_ACQ_PS_2 0x0100 +#define ADC_ACQ_PS_3 0x0200 +#define ADC_ACQ_PS_4 0x0300 +#define ADC_ACQ_PS_5 0x0400 +#define ADC_ACQ_PS_6 0x0500 +#define ADC_ACQ_PS_7 0x0600 +#define ADC_ACQ_PS_8 0x0700 +#define ADC_ACQ_PS_9 0x0800 +#define ADC_ACQ_PS_10 0x0900 +#define ADC_ACQ_PS_11 0x0A00 +#define ADC_ACQ_PS_12 0x0B00 +#define ADC_ACQ_PS_13 0x0C00 +#define ADC_ACQ_PS_14 0x0D00 +#define ADC_ACQ_PS_15 0x0E00 +#define ADC_ACQ_PS_16 0x0F00 + +#define ADC_CPS_1 0x0000 +#define ADC_CPS_2 0x0080 +#define ADC_CONT_RUN 0x0040 +#define ADC_SEQ_CASC 0x0010 +#define ADC_SEQ_DUAL 0x0000 + +/*------------------------------------------------------------------------------ + F281X Register ADCTRL2 +------------------------------------------------------------------------------*/ +#define ADC_EVB_SOC 0x8000 +#define ADC_RST_SEQ1 0x4000 +#define ADC_SOC_SEQ1 0x2000 + +#define ADC_INT_ENA_SEQ1 0x0800 +#define ADC_INT_MODE_SEQ1 0X0400 +#define ADC_EVA_SOC_SEQ1 0x0100 + +#define ADC_EXT_SOC_SEQ1 0x0080 +#define ADC_RST_SEQ2 0x0040 +#define ADC_SOC_SEQ2 0x0020 + +#define ADC_INT_ENA_SEQ2 0x0008 +#define ADC_INT_MODE_SEQ2 0x0004 +#define ADC_EVB_SOC_SEQ2 0x0001 + +/*------------------------------------------------------------------------------ + F281X Register ADCTRL3 +------------------------------------------------------------------------------*/ +#define ADC_RFDN 0x0080 +#define ADC_BGDN 0x0040 +#define ADC_PWDN 0x0020 + +#define ADC_CLKPS_X_1 0x0000 +#define ADC_CLKPS_X_2 0x0002 +#define ADC_CLKPS_X_4 0x0004 +#define ADC_CLKPS_X_6 0x0006 +#define ADC_CLKPS_X_8 0x0008 +#define ADC_CLKPS_X_10 0x000A +#define ADC_CLKPS_X_12 0x000C +#define ADC_CLKPS_X_14 0x000E +#define ADC_CLKPS_X_16 0x0010 +#define ADC_CLKPS_X_18 0x0012 +#define ADC_CLKPS_X_20 0x0014 +#define ADC_CLKPS_X_22 0x0016 +#define ADC_CLKPS_X_24 0x0018 +#define ADC_CLKPS_X_26 0x001A +#define ADC_CLKPS_X_28 0x001C +#define ADC_CLKPS_X_30 0x001E + +#define ADC_SMODE_SIMULTANEOUS 0x0001 +#define ADC_SMODE_SEQUENTIAL 0x0000 + +#endif // __F281X_BMSK_H__ +// EOF + + diff --git a/Inu/Src/main/f281xpwm.c b/Inu/Src/main/f281xpwm.c new file mode 100644 index 0000000..1103b7e --- /dev/null +++ b/Inu/Src/main/f281xpwm.c @@ -0,0 +1,288 @@ +/* ================================================================================== +File name: F281XPWM.C + +Originator: Digital Control Systems Group + Texas Instruments + +Description: This file contains source for the Full Compare PWM drivers for the F281x + +Target: TMS320F281x family + +===================================================================================== +History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20: Using DSP281x v. 1.00 or higher +----------------------------------------------------------------------------------*/ + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include <f281xpwm.h> + +#include "DSP281x_Ev.h" +//#include "params.h" + + +void F281X_EV1_PWM_Init(PWMGEN *p) +{ + EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 period Register + EvaRegs.T1CON.all = PWM_INIT_STATE; // Symmetrical Operation + EvaRegs.DBTCONA.all = DBTCON_INIT_STATE; // Init DBTCONA Register + EvaRegs.ACTRA.all = ACTR_INIT_STATE; // Init ACTRA Register + + EvaRegs.COMCONA.all = 0xA600; // Init COMCONA Register + + EvaRegs.CMPR1 = p->PeriodMax; // Init CMPR1 Register + EvaRegs.CMPR2 = p->PeriodMax; // Init CMPR2 Register + EvaRegs.CMPR3 = p->PeriodMax; // Init CMPR3 Register + EALLOW; // Enable EALLOW + GpioMuxRegs.GPAMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins + EDIS; // Disable EALLOW +} + + +void F281X_EV1_PWM_Update(PWMGEN *p) +{ + int16 MPeriod; + int32 Tmp; + +// Compute the timer period (Q0) from the period modulation input (Q15) + Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15 + MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvaRegs.T1PR = MPeriod; + +// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15 + EvaRegs.CMPR1 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + +// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15 + EvaRegs.CMPR2 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + +// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15 + EvaRegs.CMPR3 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) +} + + +void F281X_EV2_PWM_Init(PWMGEN *p) +{ + EvbRegs.T3PR = p->PeriodMax; // Init Timer 1 period Register + EvbRegs.T3CON.all = PWM_INIT_STATE; // Symmetrical Operation + EvbRegs.DBTCONB.all = DBTCON_INIT_STATE; // Init DBTCONA Register + EvbRegs.ACTRB.all = ACTR_INIT_STATE; // Init ACTRA Register + + EvbRegs.COMCONB.all = 0xA600; // Init COMCONA Register + + EvbRegs.CMPR4 = p->PeriodMax; // Init CMPR1 Register + EvbRegs.CMPR5 = p->PeriodMax; // Init CMPR2 Register + EvbRegs.CMPR6 = p->PeriodMax; // Init CMPR3 Register + EALLOW; // Enable EALLOW + GpioMuxRegs.GPBMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins + EDIS; // Disable EALLOW +} + + +void F281X_EV2_PWM_Update(PWMGEN *p) +{ + int16 MPeriod; + int32 Tmp; + +// Compute the timer period (Q0) from the period modulation input (Q15) + Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15 + MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvbRegs.T3PR = MPeriod; + +// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15 + EvbRegs.CMPR4 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + +// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15 + EvbRegs.CMPR5 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + +// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15 + EvbRegs.CMPR6 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + +} + + + +void F281X_EVD_PWM_Init(PWMGEND *p) +{ +//unsigned int pna=0,pnb=0; + + EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 period Register + +#ifdef DOUBLE_UPDATE_PWM + EvaRegs.T1CON.all = PWM_INIT_STATE_DOUBLE_UPADTE; // Symmetrical Operation + DOUBLE UPDATE +#else + EvaRegs.T1CON.all = PWM_INIT_STATE; // Symmetrical Operation +#endif + + EvaRegs.DBTCONA.all = DBTCON_INIT_STATE; // Init DBTCONA Register + EvaRegs.ACTRA.all = ACTR_INIT_STATE; // Init ACTRA Register + + EvaRegs.COMCONA.all = 0xa600;//0xA600; // Init COMCONA Register + + EvaRegs.CMPR1 = p->PeriodMax; // Init CMPR1 Register + EvaRegs.CMPR2 = p->PeriodMax; // Init CMPR2 Register + EvaRegs.CMPR3 = p->PeriodMax; // Init CMPR3 Register + EALLOW; // Enable EALLOW + GpioMuxRegs.GPAMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins + EDIS; // Disable EALLOW + + + EvbRegs.T3PR = p->PeriodMax; // Init Timer 1 period Register + +#ifdef DOUBLE_UPDATE_PWM + EvbRegs.T3CON.all = PWM_INIT_STATE_DOUBLE_UPADTE; // Symmetrical Operation + DOUBLE UPDATE +#else + EvbRegs.T3CON.all = PWM_INIT_STATE; // Symmetrical Operation +#endif + + EvbRegs.DBTCONB.all = DBTCON_INIT_STATE; // Init DBTCONA Register + EvbRegs.ACTRB.all = ACTR_INIT_STATE; // Init ACTRA Register + + EvbRegs.COMCONB.all = 0xa600;//0xA600; // Init COMCONA Register + + EvbRegs.CMPR4 = p->PeriodMax; // Init CMPR1 Register + EvbRegs.CMPR5 = p->PeriodMax; // Init CMPR2 Register + EvbRegs.CMPR6 = p->PeriodMax; // Init CMPR3 Register + EALLOW; // Enable EALLOW + GpioMuxRegs.GPBMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins + EDIS; // Disable EALLOW +// pna = p->ShiftPhaseA;//(p->PeriodMax); +// pnb = p->ShiftPhaseB; + + + EvaRegs.T1CNT = 0x0000; + EvbRegs.T3CNT = 0x0000; + +} + +#pragma CODE_SECTION(set_predel_dshim,".fast_run"); +int16 set_predel_dshim(int16 dshim,int16 dmin,int16 dpwm) +{ + if (dshim < dmin) + { + dshim = dmin; + } + + if (dshim > (dpwm - dmin) ) + { + dshim = (dpwm - dmin); + } + return dshim; +} + +#pragma CODE_SECTION(set_predel_dshim_max,".fast_run"); +int16 set_predel_dshim_max(int16 dshim,int16 dmin,int16 dpwm) +{ + int d2; + +/* + if (dshim < dmin) + { + return 0; + } + else + { + if (dshim > (dpwm - dmin) ) + { +// dshim = (dpwm + 1); + return (dpwm + 10); + } + else + return dshim; + + } +*/ + + + d2 = dmin/2; + + if (dshim < d2) + { + dshim = 0; + return dshim; + } + + if (dshim < dmin) + { + dshim = dmin; + return dshim; + } + + + if (dshim > (dpwm - d2) ) + { + dshim = dpwm+dmin; + return dshim; + } + + + if (dshim > (dpwm - dmin) ) + { + dshim = (dpwm - dmin); + return dshim; + } + + return dshim; + + +} + + +//#pragma CODE_SECTION(F281X_EVD_PWM_Update,".fast_run"); +void F281X_EVD_PWM_Update(PWMGEND *p) +{ + int16 MPeriod, Dshim; + int32 Tmp; + + +// Compute the timer period (Q0) from the period modulation input (Q15) + Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15 + MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvaRegs.T1PR = MPeriod; + +// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvaRegs.CMPR1 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + +// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvaRegs.CMPR2 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + +// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvaRegs.CMPR3 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + + +// Compute the timer period (Q0) from the period modulation input (Q15) +// Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15 +// MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvbRegs.T3PR = MPeriod; + +// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC4; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvbRegs.CMPR4 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + +// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC5; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvbRegs.CMPR5 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + +// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15) + Tmp = (int32)MPeriod*(int32)p->MfuncC6; // Q15 = Q0*Q15 + Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2) + EvbRegs.CMPR6 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod); + +} + diff --git a/Inu/Src/main/f281xpwm.h b/Inu/Src/main/f281xpwm.h new file mode 100644 index 0000000..bf9499f --- /dev/null +++ b/Inu/Src/main/f281xpwm.h @@ -0,0 +1,163 @@ +/* ================================================================================== +File name: F281XPWM.H + +Originator: Digital Control Systems Group + Texas Instruments +Description: +Header file containing data type and object definitions and +initializers. Also contains prototypes for the functions in F281XPWM.C. + +Target: TMS320F281x family + +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20: Using DSP281x v. 1.00 or higher +---------------------------------------------------------------------------------- */ + +#ifndef __F281X_PWM_H__ +#define __F281X_PWM_H__ + +#include <f281xbmsk.h> +//#include "DSP281x_Device.h" +/*---------------------------------------------------------------------------- +Initialization constant for the F281X Timer TxCON for PWM Generation. +Sets up the timer to run free upon emulation suspend, continuous up-down mode +prescaler 1, timer enabled. +----------------------------------------------------------------------------*/ //FREE_RUN_FLAG +#define PWM_INIT_STATE (FREE_RUN_FLAG + \ + TIMER_CONT_UPDN + \ + TIMER_CLK_PRESCALE_X_1 + \ + TIMER_ENABLE_BY_OWN + \ + TIMER_ENABLE) + +#define PWM_INIT_STATE_DOUBLE_UPADTE (FREE_RUN_FLAG + \ + TIMER_COMPARE_LD_ON_ZERO_OR_PRD + \ + TIMER_CONT_UPDN + \ + TIMER_CLK_PRESCALE_X_1 + \ + TIMER_ENABLE_BY_OWN + \ + TIMER_ENABLE) + +/*---------------------------------------------------------------------------- +Initialization constant for the F281X ACTRx register for PWM Generation. +Sets up PWM polarities. +----------------------------------------------------------------------------*/ +#define ACTR_INIT_STATE ( COMPARE1_FH + \ + COMPARE2_FH + \ + COMPARE3_FH + \ + COMPARE4_FH + \ + COMPARE5_FH + \ + COMPARE6_FH ) + +#define ACTR_ON_STATE ( COMPARE1_AL + \ + COMPARE2_AH + \ + COMPARE3_AL + \ + COMPARE4_AH + \ + COMPARE5_AL + \ + COMPARE6_AH ) + +/*---------------------------------------------------------------------------- +Initialization constant for the F281X DBTCONx register for PWM Generation. +Sets up the dead band for PWM and sets up dead band values. +----------------------------------------------------------------------------*/ +#define DBTCON_INIT_STATE ( DBT_VAL_10 + \ + EDBT3_EN + \ + EDBT2_EN + \ + EDBT1_EN + \ + DBTPS_X32 ) + + +/*----------------------------------------------------------------------------- +Define the structure of the PWM Driver Object +-----------------------------------------------------------------------------*/ +typedef struct { + Uint16 PeriodMax; // Parameter: PWM Half-Period in CPU clock cycles (Q0) + int16 MfuncPeriod; // Input: Period scaler (Q15) + int16 MfuncC1; // Input: PWM 1&2 Duty cycle ratio (Q15) + int16 MfuncC2; // Input: PWM 3&4 Duty cycle ratio (Q15) + int16 MfuncC3; // Input: PWM 5&6 Duty cycle ratio (Q15) + void (*init)(); // Pointer to the init function + void (*update)(); // Pointer to the update function + } PWMGEN ; + + +typedef struct { + Uint16 PeriodMax; // Parameter: PWM Half-Period in CPU clock cycles (Q0) + Uint16 PeriodMin; // Parameter: PWM Half-Period in CPU clock cycles (Q0) + int16 MfuncPeriod; // Input: Period scaler (Q15) + int16 MfuncC1; // Input: PWM 1&2 Duty cycle ratio (Q15) + int16 MfuncC2; // Input: PWM 3&4 Duty cycle ratio (Q15) + int16 MfuncC3; // Input: PWM 5&6 Duty cycle ratio (Q15) + int16 MfuncC4; // Input: PWM 1&2 Duty cycle ratio (Q15) + int16 MfuncC5; // Input: PWM 3&4 Duty cycle ratio (Q15) + int16 MfuncC6; // Input: PWM 5&6 Duty cycle ratio (Q15) + Uint16 ShiftPhaseA; // Parameter: PWM Half-Period in CPU clock cycles (Q0) + Uint16 ShiftPhaseB; // Parameter: PWM Half-Period in CPU clock cycles (Q0) + void (*init)(); // Pointer to the init function + void (*update)(); // Pointer to the update function + } PWMGEND ; + +/*----------------------------------------------------------------------------- +Define a PWMGEN_handle +-----------------------------------------------------------------------------*/ +typedef PWMGEN *PWMGEN_handle; +typedef PWMGEND *PWMGEND_handle; + +/*------------------------------------------------------------------------------ +Default Initializers for the F281X PWMGEN Object +------------------------------------------------------------------------------*/ +#define F281X_EV1_FC_PWM_GEN {1000, \ + 0x7FFF, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + (void (*)(Uint32))F281X_EV1_PWM_Init, \ + (void (*)(Uint32))F281X_EV1_PWM_Update \ + } + +#define F281X_EV2_FC_PWM_GEN {1000, \ + 0x7FFF, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + (void (*)(Uint32))F281X_EV2_PWM_Init, \ + (void (*)(Uint32))F281X_EV2_PWM_Update \ + } + + +#define F281X_EVD_FC_PWM_GEN {1000, \ + 0, \ + 0x7FFF, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + 0x4000, \ + 0x000, \ + 0x000, \ + (void (*)(Uint32))F281X_EVD_PWM_Init, \ + (void (*)(Uint32))F281X_EVD_PWM_Update \ + } + +#define PWMGEN1_DEFAULTS F281X_EV1_FC_PWM_GEN +#define PWMGEN2_DEFAULTS F281X_EV2_FC_PWM_GEN +#define PWMGEND_DEFAULTS F281X_EVD_FC_PWM_GEN + +/*------------------------------------------------------------------------------ + Prototypes for the functions in F281XPWM.C +------------------------------------------------------------------------------*/ +void F281X_EV1_PWM_Init(PWMGEN_handle); +void F281X_EV1_PWM_Update(PWMGEN_handle); +void F281X_EV2_PWM_Init(PWMGEN_handle); +void F281X_EV2_PWM_Update(PWMGEN_handle); + +void F281X_EVD_PWM_Init(PWMGEND_handle); +void F281X_EVD_PWM_Update(PWMGEND_handle); + +int16 set_predel_dshim_max(int16 dshim,int16 dmin,int16 dpwm); +int16 set_predel_dshim(int16 dshim,int16 dmin,int16 dpwm); + + +#endif // __F281X_PWM_H__ + diff --git a/Inu/Src/main/limit_lib.c b/Inu/Src/main/limit_lib.c new file mode 100644 index 0000000..859b644 --- /dev/null +++ b/Inu/Src/main/limit_lib.c @@ -0,0 +1,50 @@ +/* + * limit_lib.c + * + * Created on: 15 ���. 2024 �. + * Author: yura + */ + + +#include "IQmathLib.h" +#include "math_pi.h" + + + +_iq linear_decrease(float current, int alarm_level, int warnig_level) { + float delta = current - warnig_level; + float max_delta = alarm_level - warnig_level; + if (delta <= 0 || max_delta <= 0) { + return CONST_IQ_1; + } else { + if (delta>max_delta) + return 0; + else + return CONST_IQ_1 - _IQ(delta / max_delta); + } +} + + + + + + + +_iq linear_decrease_iq(_iq current, _iq alarm_level, _iq warnig_level) +{ + _iq delta = current - warnig_level; + + _iq max_delta = alarm_level - warnig_level; + + if (delta <= 0 || max_delta <= 0) { + return CONST_IQ_1; + } else { + if (delta>=max_delta) + return 0; + else + return CONST_IQ_1 - _IQdiv(delta, max_delta); + } +} + + + diff --git a/Inu/Src/main/limit_lib.h b/Inu/Src/main/limit_lib.h new file mode 100644 index 0000000..3b1e6aa --- /dev/null +++ b/Inu/Src/main/limit_lib.h @@ -0,0 +1,15 @@ +/* + * limit_lib.h + * + * Created on: 15 ���. 2024 �. + * Author: yura + */ + +#ifndef SRC_MAIN_LIMIT_LIB_H_ +#define SRC_MAIN_LIMIT_LIB_H_ + +_iq linear_decrease(float current, int alarm_level, int warnig_level); + +_iq linear_decrease_iq(_iq current, _iq alarm_level, _iq warnig_level); + +#endif /* SRC_MAIN_LIMIT_LIB_H_ */ diff --git a/Inu/Src/main/limit_power.c b/Inu/Src/main/limit_power.c new file mode 100644 index 0000000..840019f --- /dev/null +++ b/Inu/Src/main/limit_power.c @@ -0,0 +1,237 @@ +/* + * limit_power.c + * + * Created on: 15 ���. 2024 �. + * Author: yura + */ + +#include "IQmathLib.h" + +#include <adc_tools.h> +#include <detect_overload.h> +#include <edrk_main.h> +#include <params_motor.h> +#include <params_pwm24.h> +#include "mathlib.h" +#include "math_pi.h" + + +#include "limit_power.h" +#include "limit_lib.h" + +#include "pll_tools.h" + +#include "uom_tools.h" + + + + +#define KOEF_50HZ (FREQ_PWM*2.0*50.0/PI) +#define LEVEL_01HZ_IQ _IQ(10.0/KOEF_50HZ) // 0.1 HZ + +_iq level_50hz = _IQmpyI32(LEVEL_01HZ_IQ, 500); +_iq level_minimal_level_work_hz = _IQmpyI32(LEVEL_01HZ_IQ, 350); + +_iq delta_freq_test = 0; + + +//_iq level_01hz = _IQ(LEVEL_01HZ); + + +//#define LEVEL_50HZ (5000.0/KOEF_50HZ) // 50 HZ +//#define LEVEL_05HZ (50.0/KOEF_50HZ) // 50 HZ +// +//#define LEVEL_3HZ (300.0/KOEF_50HZ) // 50 HZ +//#define LEVEL_2HZ (200.0/KOEF_50HZ) // 50 HZ +//#define LEVEL_1HZ (100.0/KOEF_50HZ) // 50 HZ + + + +#define LEVEL1_FREQ_DECR 10 // 1.5 Hz �� 49.0 +#define LEVEL2_FREQ_DECR 100 // 10 Hz �� 40 +//#define LEVEL1_FREQ_DECR 15 // 1.5 Hz �� 48.5 +//#define LEVEL2_FREQ_DECR 100 // 10 Hz �� 40 + +#define PLUS_LIMIT_KOEFFS 0.0001 +#define MINUS_LIMIT_KOEFFS 0.05 + +#define MAX_COUNT_GO_UOM (FREQ_PWM*5) // 5 sec +#define SET_LIMIT_UOM 0.5 + +void calc_all_limit_koeffs(void) +{ + _iq sum_limit, delta_freq; + + static unsigned int prev_uom = 0; + static int flag_enable_go_uom = 0; + + + static _iq level1_freq_decr = _IQmpyI32(LEVEL_01HZ_IQ, LEVEL1_FREQ_DECR); + static _iq level2_freq_decr = _IQmpyI32(LEVEL_01HZ_IQ, LEVEL2_FREQ_DECR); + + static _iq iq_set_limit_uom = _IQ(SET_LIMIT_UOM); + static unsigned int count_go_uom = 0; + + static _iq iq_plus_limit_koeffs = _IQ(PLUS_LIMIT_KOEFFS); + static _iq iq_minus_limit_koeffs = _IQ(MINUS_LIMIT_KOEFFS); + + static long freq_test = 30; + //*LEVEL_01HZ_IQ; + static _iq minus_delta_freq_test = _IQdiv32(LEVEL_01HZ_IQ); // 0.1/32 + + + static int uom_test = 50; + static int prev_imit_limit_freq = 0, prev_imit_limit_uom = 0; + + static _iq iq_new_uom_level_kwt = 0; + + + update_uom(); + + // temper + edrk.all_limit_koeffs.local_temper_limit = edrk.temper_limit_koeffs.sum_limit; + + + // uin_freq + if (edrk.Status_Ready.bits.ready_final) //|| edrk.imit_limit_freq + { + + get_freq_50hz_iq(); + + // freq = LEVEL_50HZ - edrk.iq_freq_50hz; + + if (edrk.imit_limit_freq && prev_imit_limit_freq == 0) + delta_freq_test = _IQmpyI32(LEVEL_01HZ_IQ, freq_test); + + if (delta_freq_test>0) + { + if (delta_freq_test>0) + delta_freq_test -= minus_delta_freq_test; + if (delta_freq_test<0) + delta_freq_test = 0; + } + + if (edrk.iq_freq_50hz>level_minimal_level_work_hz) + { + edrk.all_limit_koeffs.local_uin_freq_limit = linear_decrease_iq( (level_50hz - edrk.iq_freq_50hz), + level2_freq_decr, level1_freq_decr); + } + else + edrk.all_limit_koeffs.local_uin_freq_limit = CONST_IQ_1; + } + else + { + edrk.all_limit_koeffs.local_uin_freq_limit = CONST_IQ_1; + } + prev_imit_limit_freq = edrk.imit_limit_freq; + + // + /// UOM + // + if (edrk.from_uom.ready || edrk.set_limit_uom_50) + { + if (edrk.set_limit_uom_50) + { + edrk.from_uom.level_value = uom_test; + } + + if (edrk.imit_limit_uom && prev_imit_limit_uom == 0) + edrk.from_uom.level_value++; + + + if (prev_uom!=edrk.from_uom.level_value && edrk.from_uom.level_value > prev_uom) + { + if (edrk.iq_power_kw_full_filter_abs > edrk.from_uom.iq_level_value_kwt) + flag_enable_go_uom = 1; + } + else + flag_enable_go_uom = 0; + + if (flag_enable_go_uom) + { + count_go_uom = MAX_COUNT_GO_UOM; + edrk.all_limit_koeffs.local_uom_limit = iq_set_limit_uom; // ���� ����� + } + + if (count_go_uom) + { + // ������ ����� + count_go_uom--; + } + else + edrk.all_limit_koeffs.local_uom_limit = CONST_IQ_1; // ������������ + + prev_uom = edrk.from_uom.level_value; + + } + else + { + + edrk.power_limit.bits.limit_from_uom_fast = 0; + edrk.all_limit_koeffs.uom_limit = CONST_IQ_1; + prev_uom = 0; + } + prev_imit_limit_uom = edrk.imit_limit_uom; + // if () + + + //// temper + edrk.all_limit_koeffs.temper_limit = zad_intensiv_q(iq_plus_limit_koeffs, iq_minus_limit_koeffs, + edrk.all_limit_koeffs.temper_limit, + edrk.all_limit_koeffs.local_temper_limit); + + edrk.power_limit.bits.limit_by_temper = (edrk.all_limit_koeffs.temper_limit<CONST_IQ_1) ? 1 : 0; + + ////// freq + edrk.all_limit_koeffs.uin_freq_limit = zad_intensiv_q(iq_plus_limit_koeffs, iq_minus_limit_koeffs, + edrk.all_limit_koeffs.uin_freq_limit, + edrk.all_limit_koeffs.local_uin_freq_limit); + + edrk.power_limit.bits.limit_from_freq = (edrk.all_limit_koeffs.uin_freq_limit<CONST_IQ_1) ? 1 : 0; + + + ///// uom + edrk.all_limit_koeffs.uom_limit = zad_intensiv_q(iq_plus_limit_koeffs, iq_minus_limit_koeffs, + edrk.all_limit_koeffs.uom_limit, + edrk.all_limit_koeffs.local_uom_limit); + + edrk.power_limit.bits.limit_from_uom_fast = (edrk.all_limit_koeffs.uom_limit<CONST_IQ_1) ? 1 : 0; + + + + + + + // sum_limit + sum_limit = edrk.all_limit_koeffs.temper_limit; + sum_limit = _IQmpy(sum_limit, edrk.all_limit_koeffs.moment_limit ); + sum_limit = _IQmpy(sum_limit, edrk.all_limit_koeffs.power_limit ); + sum_limit = _IQmpy(sum_limit, edrk.all_limit_koeffs.uin_freq_limit ); + sum_limit = _IQmpy(sum_limit, edrk.all_limit_koeffs.uom_limit ); + + edrk.all_limit_koeffs.sum_limit = sum_limit; + +} + + + + +void init_all_limit_koeffs(void) +{ + edrk.all_limit_koeffs.moment_limit = CONST_IQ_1; + edrk.all_limit_koeffs.power_limit = CONST_IQ_1; + edrk.all_limit_koeffs.temper_limit = CONST_IQ_1; + edrk.all_limit_koeffs.uin_freq_limit = CONST_IQ_1; + edrk.all_limit_koeffs.uom_limit = CONST_IQ_1; + edrk.all_limit_koeffs.sum_limit = CONST_IQ_1; + + edrk.all_limit_koeffs.local_moment_limit = CONST_IQ_1; + edrk.all_limit_koeffs.local_power_limit = CONST_IQ_1; + edrk.all_limit_koeffs.local_temper_limit = CONST_IQ_1; + edrk.all_limit_koeffs.local_uin_freq_limit = CONST_IQ_1; + edrk.all_limit_koeffs.local_uom_limit = CONST_IQ_1; + edrk.all_limit_koeffs.local_sum_limit = CONST_IQ_1; + +} + + diff --git a/Inu/Src/main/limit_power.h b/Inu/Src/main/limit_power.h new file mode 100644 index 0000000..1f27f20 --- /dev/null +++ b/Inu/Src/main/limit_power.h @@ -0,0 +1,21 @@ +/* + * limit_power.h + * + * Created on: 15 ���. 2024 �. + * Author: yura + */ + +#ifndef SRC_MAIN_LIMIT_POWER_H_ +#define SRC_MAIN_LIMIT_POWER_H_ + + + + + +void calc_all_limit_koeffs(void); +void init_all_limit_koeffs(void); + + +extern _iq level_50hz, delta_freq_test; + +#endif /* SRC_MAIN_LIMIT_POWER_H_ */ diff --git a/Inu/Src/main/logs_hmi.c b/Inu/Src/main/logs_hmi.c new file mode 100644 index 0000000..4951299 --- /dev/null +++ b/Inu/Src/main/logs_hmi.c @@ -0,0 +1,1150 @@ +/* + * logs_hmi.c + * + * Created on: 28 ���. 2024 �. + * Author: Evgeniy_Sokolov + */ +#include "log_to_memory.h" +#include <message_modbus.h> +#include <modbus_hmi.h> +#include <modbus_hmi_update.h> +#include <vector.h> + +#include "control_station.h" +#include "global_time.h" +#include "modbus_table_v2.h" +#include "RS_modbus_pult.h" +#include "DSP281x_Device.h" +#include "MemoryFunctions.h" +#include "RS_modbus_svu.h" +#include "log_params.h" +#include "logs_hmi.h" +#include "edrk_main.h" + + +#pragma DATA_SECTION(log_to_HMI, ".logs"); +t_Logs_with_modbus log_to_HMI = LOGS_WITH_MODBUS_DEFAULTS; + + +#define COUNT_FAST_DATA 300//150 +#define COUNT_SLOW_DATA 300 + + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +#define MAX_SIZE_LOGS_HMI_FULL (END_ADDRESS_LOGS - START_ADDRESS_LOG + 1) //262144 // 0x80000/2 +#define MAX_SIZE_LOGS_HMI_SMALL 10000 + +#define START_ARRAY_LOG_SEND 300 +#define END_ARRAY_LOG_SEND 899 +#define SIZE_ARRAY_LOG_SEND (END_ARRAY_LOG_SEND - START_ARRAY_LOG_SEND + 1) +#define SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE 120 + +int writeLogsArray(int flag_next) +{ + int succed = 0; + static unsigned int old_time = 0; + + static int count_write_to_modbus = 0; + static int cur_position_buf_modbus16 = 0; + + + + + + if (!rs_b.flag_LEADING) + { + + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + + if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) + { + if (log_to_HMI.flag_start_log_array_sent) + { + cur_position_buf_modbus16 = START_ARRAY_LOG_SEND; + log_to_HMI.flag_log_array_sended = 0; + } + else + { + if (flag_next) + cur_position_buf_modbus16 = cur_position_buf_modbus16 + SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE; + } + + log_to_HMI.flag_start_log_array_sent = 0; + } + + if (cur_position_buf_modbus16 >= END_ARRAY_LOG_SEND) + { + // ��� �������� ���? + cur_position_buf_modbus16 = START_ARRAY_LOG_SEND; + log_to_HMI.flag_log_array_sended = 1; + // log_to_HMI.flag_log_array_sent_process = 0; +// succed = 1; + return succed; + } + +// //����� � ������. ����������. +// if ((cur_position_buf_modbus16 > ADRESS_END_FIRST_BLOCK) && +// (cur_position_buf_modbus16 < ADRESS_START_PROTECTION_LEVELS)) { +// cur_position_buf_modbus16 = ADRESS_START_PROTECTION_LEVELS; +// } + + if ((cur_position_buf_modbus16 + SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE) > (END_ARRAY_LOG_SEND+1)) + count_write_to_modbus = END_ARRAY_LOG_SEND - cur_position_buf_modbus16 + 1; + else + count_write_to_modbus = SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE; + + log_to_HMI.n_log_array_sended = (cur_position_buf_modbus16 - START_ARRAY_LOG_SEND)/100 + 1; + log_to_HMI.flag_log_array_sent_process++;// = 1; + + ModbusRTUsend16(&rs_b, 2, + ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus16, + count_write_to_modbus); + + + + // control_station.count_error_modbus_16[CONTROL_STATION_INGETEAM_PULT_RS485]++; + + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + succed = count_write_to_modbus; + } + return succed; + + + +/* + + unsigned long i = 0; + int succed = 0; + +// int *p_log_data = (int*)LOG_START_ADRES; + + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + if (!rs_b.flag_LEADING) + { + ModbusRTUsend16(&rs_b, 2, + log_to_HMI.current_address, + log_to_HMI.count_write_to_modbus + 1); + + if (err_send_log_16 == 0) { //prev message without errors + log_to_HMI.current_address = log_to_HMI.current_address + SIZE_BUF_WRITE_LOG_TO_MODBUS16; + } + if (log_to_HMI.current_address > END_ARRAY_LOG_SEND) { + log_to_HMI.current_address = START_ARRAY_LOG_SEND; +// log_to_HMI.flag_end_of_log = 1; + log_to_HMI.flag_log_array_sent = 1; + } + if ((log_to_HMI.current_address + SIZE_BUF_WRITE_LOG_TO_MODBUS16) > END_ARRAY_LOG_SEND) { + log_to_HMI.count_write_to_modbus = END_ARRAY_LOG_SEND - log_to_HMI.current_address; + } else { + log_to_HMI.count_write_to_modbus = SIZE_BUF_WRITE_LOG_TO_MODBUS16; + } + + err_send_log_16 += 1; + succed = 1; + + } + return succed; +*/ +} + +void prepareWriteLogsArray(void) { +// log_to_HMI.start_log_address = logpar.addres_mem - logpar.count_log_params_fast_log * SIZE_ARRAY_LOG_SEND; +// log_to_HMI.start_log_address = log_params.addres_mem - log_params.BlockSizeErr * SIZE_ARRAY_LOG_SEND; + + if (log_to_HMI.send_log == 1) + log_to_HMI.start_log_address = log_params.start_address_log_slow; + if (log_to_HMI.send_log == 2) + log_to_HMI.start_log_address = log_params.start_address_log; + if (log_to_HMI.send_log == 3) + log_to_HMI.start_log_address = 0;//log_params.start_address_log; + + // - log_to_HMI.max_size_logs_hmi; + +// if (log_to_HMI.start_log_address < log_params.start_address_log) { +// log_to_HMI.start_log_address = log_params.end_address_log - (log_params.start_address_log - log_to_HMI.start_log_address); +// } +// log_to_HMI.log_address_step = SIZE_ARRAY_LOG_SEND;//log_params.BlockSizeErr; +} + + +int fillAnalogDataArrayForLogSend(void) +{ + int i, k, n;// = START_ARRAY_LOG_SEND; + int c_data = 0, lb = 0, type_log; + volatile unsigned long local_pos = 0; + +// unsigned long current_address = log_to_HMI.start_log_address;// + num_of_log; + + k = 0; + n = 0; + for (i = START_ARRAY_LOG_SEND; i <= END_ARRAY_LOG_SEND; i++) { + +// if (log_to_HMI.count_write_to_modbus > log_to_HMI.max_size_logs_hmi) +// break; + + n = log_to_HMI.count_write_to_modbus/SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE; + + if (k>=SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE) + k = 0; + + if (k==0) + modbus_table_analog_out[i].all = LOWORD(log_to_HMI.count_write_to_modbus); + else + if (k==1) + modbus_table_analog_out[i].all = LOWORD(global_time.miliseconds); + else + if (k==2) + modbus_table_analog_out[i].all = HIWORD(log_to_HMI.start_log_address); + else + if (k==3) + modbus_table_analog_out[i].all = LOWORD(log_to_HMI.start_log_address); + else + if (k==SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE-1) + modbus_table_analog_out[i].all = log_to_HMI.tick_step; + else + { + if (log_to_HMI.count_write_to_modbus > log_to_HMI.max_size_logs_hmi) + modbus_table_analog_out[i].all = 0; + else + { +// modbus_table_analog_out[i].all = LOWORD(log_to_HMI.start_log_address); // ��� ��� ����� + if (log_to_HMI.send_log==3) + { + if (log_to_HMI.start_log_address>=(COUNT_FAST_DATA*log_params.BlockSizeErr) ) + { + local_pos = log_to_HMI.max_size_logs_hmi - log_to_HMI.start_log_address;// - (COUNT_FAST_DATA*log_params.BlockSizeErr); + type_log = SLOW_LOG; + } + else + { + local_pos = log_to_HMI.max_size_logs_hmi - log_to_HMI.start_log_address - (COUNT_SLOW_DATA*log_params.BlockSizeErr); + type_log = FAST_LOG; + } + + modbus_table_analog_out[i].all = alarm_log_get_data(local_pos, type_log); + } + else + modbus_table_analog_out[i].all = ReadMemory(log_to_HMI.start_log_address); + + + + log_to_HMI.start_log_address += 1;//log_to_HMI.log_address_step; + log_to_HMI.count_write_to_modbus += 1; + + } + } + +// modbus_table_analog_out[i+1].all = HIWORD(log_to_HMI.start_log_address);//log_to_HMI.count_write_to_modbus;//ReadMemory(log_to_HMI.start_log_address); +// modbus_table_analog_out[i].all = LOWORD(global_time.miliseconds);//ReadMemory(log_to_HMI.start_log_address); +// modbus_table_analog_out[i+1].all = HIWORD(global_time.miliseconds);//log_to_HMI.count_write_to_modbus;//ReadMemory(log_to_HMI.start_log_address); + +// if (k>1 && k<SIZE_BUF_WRITE_LOGS_TO_MODBUS16_REMOUTE-1) +// { +// log_to_HMI.start_log_address += 1;//log_to_HMI.log_address_step; +// log_to_HMI.count_write_to_modbus += 1; +// +// } + + k++; + c_data += 1; + } + return c_data;// ������� ������� �������� + +// log_to_HMI.current_address = START_ARRAY_LOG_SEND; + //log_to_HMI.count_write_to_modbus += num_of_log; +} + + + + +#define START_CMD_ADR_PROGRESS_DATA 192 +#define LENGTH_CMD_PROGRESS_DATA 6 + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +#define TIME_PAUSE_STATUS_SAVE 5000 +#define MAX_WAIT_WRITE_DISCRETE 10 //10 +#define MAX_WAIT_WRITE_PROGRESS 5 + +#define TIME_PAUSE_STATUS_SAVE1 10 +#define TIME_PAUSE_STATUS_SAVE2 5000 //1000 +#define TIME_PAUSE_STATUS_SAVE3 300 // +#define TIME_PAUSE_STATUS_SAVE4 700 //30 +#define TIME_PAUSE_STATUS_SAVE5 30 +#define TIME_PAUSE_STATUS_SAVE6 500 //150 +#define TIME_PAUSE_STATUS_SAVE7 10000 //1000 +#define TIME_PAUSE_STATUS_SAVE8 6000 //1000 +#define TIME_PAUSE_STATUS_SAVE9 5000 //1000 + +//#define PLACE_STORE_LOG_PULT 2 //SD +#define PLACE_STORE_LOG_PULT 1 //USB Flash + + + + +void wdog_hmi(void) +{ + static int local_hmi_watch_dog = 0, stage = 0; + + + + + stage = !stage; + + if (stage) + { + local_hmi_watch_dog = !local_hmi_watch_dog; + setRegisterDiscreteOutput(local_hmi_watch_dog, 515); + writeSigleDiscreteDataToRemote(515); + } + else + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + +} + +int sendLogToHMI(int status_ok) +{ + int succed = 0, flag_next = 0; + unsigned int time_finish_transmitt = 0, pause_save = 0; + static int prev_send_log = 0, flag_one = 0; + static int prev_status_ok = -1; + static unsigned int count_send = 0, enable_next_step = 0; + static unsigned int time_pause_status_save = TIME_PAUSE_STATUS_SAVE, old_time_status_save = 0, + max_wait_write_discrete = MAX_WAIT_WRITE_DISCRETE, wait_write_discrete = 0, + max_wait_write_progress = MAX_WAIT_WRITE_PROGRESS, wait_write_progress = 0; + + static unsigned int time_pause_status_save1 = TIME_PAUSE_STATUS_SAVE1; + static unsigned int time_pause_status_save2 = TIME_PAUSE_STATUS_SAVE2; + static unsigned int time_pause_status_save3 = TIME_PAUSE_STATUS_SAVE3; + static unsigned int time_pause_status_save4 = TIME_PAUSE_STATUS_SAVE4; + static unsigned int time_pause_status_save5 = TIME_PAUSE_STATUS_SAVE5; + static unsigned int time_pause_status_save6 = TIME_PAUSE_STATUS_SAVE6; + static unsigned int time_pause_status_save7 = TIME_PAUSE_STATUS_SAVE7; + static unsigned int time_pause_status_save8 = TIME_PAUSE_STATUS_SAVE8; + static unsigned int time_pause_status_save9 = TIME_PAUSE_STATUS_SAVE9; + +// static unsigned int place_store_log_pult = PLACE_STORE_LOG_PULT; + + static unsigned int flag_local_sended = 0, flag_local_finish = 0; + + + + if (log_to_HMI.send_log && prev_send_log==0) + { + if (log_to_HMI.max_size_logs_hmi_small == 0) + +#if(_LOG_HMI_SMALL_TEST==1) + log_to_HMI.max_size_logs_hmi_small = MAX_SIZE_LOGS_HMI_SMALL; +#else + log_to_HMI.max_size_logs_hmi_small = (log_params.end_address_log_slow - log_params.start_address_log_slow + 1 ); //MAX_SIZE_LOGS_HMI_SMALL; +#endif + + if (log_to_HMI.max_size_logs_hmi_full == 0) + log_to_HMI.max_size_logs_hmi_full = MAX_SIZE_LOGS_HMI_FULL; + +//30007 - ����� 1 - ��� ������ �� ����������� ����, � 2 �� ������. + if (log_to_HMI.send_log == 1) + log_to_HMI.max_size_logs_hmi = log_to_HMI.max_size_logs_hmi_small; + if (log_to_HMI.send_log == 2) + log_to_HMI.max_size_logs_hmi = log_to_HMI.max_size_logs_hmi_full; + + if (log_to_HMI.send_log == 3) + log_to_HMI.max_size_logs_hmi = log_params.BlockSizeErr*(COUNT_FAST_DATA+COUNT_SLOW_DATA);// MAX_SIZE_LOGS_HMI_SMALL;//log_to_HMI.max_size_logs_hmi_full; + + + + log_to_HMI.step = -1; + enable_next_step = 1; + +// log_to_HMI.flag_data_received = 0; + log_to_HMI.count_write_to_modbus = 0; + log_to_HMI.flag_log_array_sended = 0; + log_to_HMI.log_size_sent = 0; +// log_to_HMI.current_address = 0; +// log_to_HMI.number_of_log = 0; + + log_to_HMI.progress_bar = 0; + log_to_HMI.enable_progress_bar = 1; + log_to_HMI.cleanLogs = 0; + log_to_HMI.tick_step = 0; +// log_to_HMI.tick_finish = 0; + log_to_HMI.saveLogsToSDCard = 0; + + log_to_HMI.flag_log_array_sent_process = 0; + log_to_HMI.count_sended_to_pult = 0; + log_to_HMI.ReportLogOut = log_to_HMI.send_log; + + prepareWriteLogsArray(); + + + //global_time.miliseconds = 0; + +// setRegisterDiscreteOutput(0, 522); + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; +// return 1; + } + + + + if (log_to_HMI.send_log) + { + // ������ �������� � �������� ����� �� ���� �������? + if (status_ok != prev_status_ok || prev_status_ok == -1 ) + { + + + if (enable_next_step) + { + old_time_status_save = global_time.miliseconds; + log_to_HMI.step++; + } + + if (log_to_HMI.flag_log_array_sended==0 && log_to_HMI.step==8) + { + // ������ ������� ���� ����� �� 4, �.�. �� ��� ������ ������ + log_to_HMI.step--; + flag_next = 1; + } + + + if ((time_pause_status_save4==0 && log_to_HMI.step==6) + || (time_pause_status_save5==0 && log_to_HMI.step==8) + || (time_pause_status_save6==0 && log_to_HMI.step==10)) + log_to_HMI.step++; // ������� ���� + + } + + + + + switch (log_to_HMI.step) + { + + case 0: + if (detect_pause_milisec(time_pause_status_save1,&old_time_status_save) || time_pause_status_save1 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + + } + break; + + case 1: + log_to_HMI.cleanLogs = 1;//!log_to_HMI.tick_start; + update_logs_cmd_HMI(); + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + succed = 1; + enable_next_step = 1; +// log_to_HMI.step++; + + break; + +// case 1: +// log_to_HMI.progress_bar = 100; +// log_to_HMI.enable_progress_bar = 1; +// +// update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA,LENGTH_CMD_PROGRESS_DATA); +// +// old_time_status_save = global_time.miliseconds; +//// log_to_HMI.step++; +// succed = 1; +// enable_next_step = 1; +// break; + case 2: + if (detect_pause_milisec(time_pause_status_save2,&old_time_status_save) || time_pause_status_save2 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + wdog_hmi(); + + + } + break; + +// case 2: +// if (detect_pause_milisec(time_pause_status_save,&old_time_status_save)) +// { +// succed = 1; +// enable_next_step = 1; +// } +// else +// { +// pause_save = get_delta_milisec(&old_time_status_save, 0); +// log_to_HMI.progress_bar = 100 - ((long)pause_save*100L)/(long)time_pause_status_save; +// +// if (log_to_HMI.progress_bar<50) +// log_to_HMI.tick_start = 0; +// +// if (flag_one) +// { +// update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); +// } +// else +// { +// setRegisterDiscreteOutput(hmi_watch_dog, 515); +// hmi_watch_dog = !hmi_watch_dog; +// writeSigleDiscreteDataToRemote(515); +// } +// flag_one = !flag_one; +// +// +// succed = 1; +// enable_next_step = 0; +// } +// break; + case 3: + log_to_HMI.cleanLogs = 0; + log_to_HMI.progress_bar = 0; + log_to_HMI.enable_progress_bar = 1; + log_to_HMI.count_write_to_modbus = 0; + + + update_logs_cmd_HMI(); + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + succed = 1; + enable_next_step = 1; + +// log_to_HMI.step++; + break; + + case 4: + if (detect_pause_milisec(time_pause_status_save3,&old_time_status_save) || time_pause_status_save3 == 0) + { + succed = 1; + enable_next_step = 1; + + log_to_HMI.flag_log_array_sended = 0; + // log_to_HMI.flag_log_array_sent_process = 1; + log_to_HMI.flag_start_log_array_sent = 1; + // �������� ������� + // log_to_HMI.number_of_log = SIZE_ARRAY_LOG_SEND; + log_to_HMI.tick_step++; + log_to_HMI.count_data_in_buf = fillAnalogDataArrayForLogSend(); + flag_next = 0; + + + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + } + break; + + + +// case 4: +// log_to_HMI.flag_log_array_sended = 0; +//// log_to_HMI.flag_log_array_sent_process = 1; +// log_to_HMI.flag_start_log_array_sent = 1; +// // �������� ������� +//// log_to_HMI.number_of_log = SIZE_ARRAY_LOG_SEND; +// log_to_HMI.count_data_in_buf = fillAnalogDataArrayForLogSend(); +// +// // update_logs_cmd_HMI(); +//// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); +// succed = 1; +// enable_next_step = 1; +//// log_to_HMI.step++; +// break; + + case 5: + if (wait_write_discrete<max_wait_write_discrete) + { + wait_write_discrete++; + succed = 1; + enable_next_step = 1; + } + else + { + wait_write_discrete = 0; + //update_tables_HMI_discrete(); + // update_tables_HMI_analog(); + wdog_hmi(); + +// setRegisterDiscreteOutput(hmi_watch_dog, 515); +// hmi_watch_dog = !hmi_watch_dog; +// writeSigleDiscreteDataToRemote(515); + +// writeDiscreteDataToRemote();// ��� �������� ������ + // log_to_HMI.step++; + succed = 1; + enable_next_step = 1; + } + break; + + case 6: + if (detect_pause_milisec(time_pause_status_save4,&old_time_status_save) || time_pause_status_save4 == 0) + { + succed = 1; + enable_next_step = 1; + flag_local_finish = 0; + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + + } + break; + + case 7: + // ���� ��� ����������? + if (log_to_HMI.count_data_in_buf) + { + +// if (flag_next) +// { +// if (flag_local_sended) +// { +// flag_local_finish = 1; +// flag_local_sended = 0; +// } +// else +// if (flag_local_finish) +// { +// flag_local_finish = 0; +// } +// } + + +// if (flag_local_finish) +// { +// +// if (log_to_HMI.n_log_array_sended==1) +// log_to_HMI.tick_step++; // ������� 194 ������� +// else +// if (log_to_HMI.n_log_array_sended==2) +// log_to_HMI.tick_step2++; // ������� 194 ������� +// else +// if (log_to_HMI.n_log_array_sended==3) +// log_to_HMI.tick_step3++; // ������� 194 ������� +// else +// if (log_to_HMI.n_log_array_sended==4) +// log_to_HMI.tick_step4++; // ������� 194 ������� +// else +// if (log_to_HMI.n_log_array_sended==5) +// log_to_HMI.tick_step5++; // ������� 194 ������� +// +// +// update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); +// +// flag_next = 0; +// +// } +// else + { + + // �������� � ����� ��� ������ �� ������ + writeLogsArray(flag_next);// ��� ����� ���� ����� + flag_local_sended = 1; + flag_local_finish = 0; + flag_next = 0; + } + + // ��� ����? + if (log_to_HMI.flag_log_array_sended) + { + log_to_HMI.log_size_sent = log_to_HMI.count_write_to_modbus; + log_to_HMI.count_sended_to_pult += log_to_HMI.count_data_in_buf; + } + else + { + succed = 1; + } + } + else + { + status_ok = 0; + log_to_HMI.step += 3; + } + enable_next_step = 1; + + break; + + case 8: + if (detect_pause_milisec(time_pause_status_save5,&old_time_status_save) || time_pause_status_save5 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + +// wdog_hmi(); + + + } + break; + + case 9: + + if (wait_write_progress<max_wait_write_progress) + { + wait_write_progress++; + succed = 1; + enable_next_step = 1; + } + else + { + wait_write_progress = 0; + + log_to_HMI.progress_bar = (log_to_HMI.count_write_to_modbus*100)/log_to_HMI.max_size_logs_hmi; + + update_logs_cmd_HMI(); + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + succed = 1; + enable_next_step = 1; + } + break; + + case 10: + if (detect_pause_milisec(time_pause_status_save6,&old_time_status_save) || time_pause_status_save6 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + +// wdog_hmi(); + + + } + break; + + + case 11: +// log_to_HMI.flag_log_array_sent_process = 0; + +// if (log_to_HMI.flag_log_array_sent) +// log_to_HMI.tick_step++; + + if (log_to_HMI.log_size_sent < log_to_HMI.max_size_logs_hmi) +// log_to_HMI.step++; +// else + log_to_HMI.step = 3; // �������� ������, ��� ��� log_to_HMI.max_size_logs_hmi + + status_ok = 0; + succed = 1; + enable_next_step = 1; + break; + + case 12: + if (detect_pause_milisec(time_pause_status_save7,&old_time_status_save) || time_pause_status_save7 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + + } + break; + + + case 13: + + // log_to_HMI.tick_finish = place_store_log_pult; + log_to_HMI.saveLogsToSDCard = 3;//log_to_HMI.sdusb; + log_to_HMI.progress_bar = 100; + + update_logs_cmd_HMI(); + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + +// log_to_HMI.step++; + succed = 1; + enable_next_step = 1; + break; + + case 14: + if (detect_pause_milisec(time_pause_status_save8,&old_time_status_save) || time_pause_status_save8 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + + } + break; + + case 15: + +// log_to_HMI.tick_finish = 0; + log_to_HMI.saveLogsToSDCard = 0; + + log_to_HMI.progress_bar = 0; + //log_to_HMI.enable_progress_bar = 0; + log_to_HMI.ReportLogOut = 255; + + update_logs_cmd_HMI(); + writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + + // log_to_HMI.step++; + succed = 1; + enable_next_step = 1; + break; + + case 16: + if (detect_pause_milisec(time_pause_status_save9,&old_time_status_save) || time_pause_status_save9 == 0) + { + succed = 1; + enable_next_step = 1; + } + else + { + succed = 1; + enable_next_step = 0; + + wdog_hmi(); + + + } + break; + + +// case 17: +// +// log_to_HMI.tick_finish = place_store_log_pult; +// log_to_HMI.progress_bar = 100; +// +// update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); +// +// succed = 1; +// enable_next_step = 1; +// break; +// +// case 18: +// if (detect_pause_milisec(time_pause_status_save8,&old_time_status_save)) +// { +// succed = 1; +// enable_next_step = 1; +// } +// else +// { +// succed = 1; +// enable_next_step = 0; +// +// wdog_hmi(); +// +// } +// break; +// +// case 19: +// +// log_to_HMI.tick_finish = 0; +// log_to_HMI.progress_bar = 0; +// log_to_HMI.enable_progress_bar = 0; +// +// update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); +// +// // log_to_HMI.step++; +// succed = 1; +// enable_next_step = 1; +// break; +// +// case 20: +// if (detect_pause_milisec(time_pause_status_save9,&old_time_status_save)) +// { +// succed = 1; +// enable_next_step = 1; +// } +// else +// { +// succed = 1; +// enable_next_step = 0; +// +// wdog_hmi(); +// +// } +// break; +// +// +// + + + case 17: + + log_to_HMI.ReportLogOut = 0; + update_logs_cmd_HMI(); +// writeSingleAnalogDataToRemote(START_CMD_ADR_PROGRESS_DATA, LENGTH_CMD_PROGRESS_DATA); + + log_to_HMI.send_log = 0; + log_to_HMI.enable_progress_bar = 0; + // log_to_HMI.step++; + succed = 0; + enable_next_step = 1; + break; + + + default: + break; + + } + + } + prev_send_log = log_to_HMI.send_log; + prev_status_ok = status_ok; + + + + + + +// +// +// +// if (log_to_HMI.step == 0) +// { +//// modbus_table_analog_out[3].all = log_params.BlockSizeErr;// logpar.count_log_params_fast_log; +// +// if (log_to_HMI.log_size_sent == 0 && +// (writeSingleAnalogOutputToRemote(3) == 1)) +// { +// log_to_HMI.log_size_sent = 1; +// succed = 1; +// } else if (log_to_HMI.log_size_sent == 1) { +// log_to_HMI.step = 1; +// log_to_HMI.flag_log_array_sent = 0; +// prepareWriteLogsArray(); +// fillAnalogDataArrayForLogSend(log_to_HMI.number_of_log); +// } +// } +// if (log_to_HMI.step == 1) { +// if (log_to_HMI.flag_log_array_sent == 0) { +// succed = writeLogsArray(log_to_HMI.number_of_log); +// } else { +// log_to_HMI.step = 2; +// init_timer_milisec(&time_finish_transmitt); +// } +// } +// if (log_to_HMI.step == 2) +// { +// if (detect_pause_milisec(1000, &time_finish_transmitt)) { +// setRegisterDiscreteOutput(1, 522); +// if (writeDiscreteDataToRemote() == 1) { +// log_to_HMI.step = 3; +// succed = 1; +// } +// } else { +// succed = 1; +// } +// +// } +// if (log_to_HMI.step == 3) { +// succed = readAnalogDataFromRemote(); +// if (modbus_table_analog_in[8].all == 1) { +// if (detect_pause_milisec(1000, &time_finish_transmitt)) { +// log_to_HMI.step = 4; +// } +// } else { +// init_timer_milisec(&time_finish_transmitt); +// } +// } +// if (log_to_HMI.step == 4) { +// setRegisterDiscreteOutput(0, 522); +// if (writeDiscreteDataToRemote() == 1) { +// log_to_HMI.step = 5; +// succed = 1; +// } +// } +// if (log_to_HMI.step == 5) { +// succed = readAnalogDataFromRemote(); +// if (modbus_table_analog_in[8].all == 0) { +// if (detect_pause_milisec(1000, &time_finish_transmitt) && log_to_HMI.number_of_log < (log_params.BlockSizeErr - 1)) { +// log_to_HMI.number_of_log += 1; +// fillAnalogDataArrayForLogSend(log_to_HMI.number_of_log); +// log_to_HMI.flag_log_array_sent = 0; +// log_to_HMI.step = 1; +// } else { +// succed = 1; +// } +// } +// } + +// log_to_HMI.send_log = modbus_table_analog_in[7].all; +// control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + + + return succed; +} + +#define PAUSE_AUTO_SAVE_SLOW_LOG_SECONDS 300 //120 //60 // 60 sec + +void run_store_slow_logs(void) +{ + static int prev_imit_save_slow_logs = 0, flag_auto_logs = 0; + static unsigned int pause_logs = 0; + + if (pause_logs == 0) + init_timer_sec(&pause_logs); + + flag_auto_logs = detect_pause_sec(PAUSE_AUTO_SAVE_SLOW_LOG_SECONDS, &pause_logs); + + + if ((edrk.imit_save_slow_logs && prev_imit_save_slow_logs == 0) || flag_auto_logs) + { + if (log_to_HMI.send_log == 0) + set_write_slow_logs(1); + } + else + set_write_slow_logs(0); + + prev_imit_save_slow_logs = edrk.imit_save_slow_logs; + +} + + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + +void fillLogArea() { + unsigned int value = 0; + unsigned int *p_memory = (unsigned int*)LOG_START_ADRES; + long log_size = LOG_BUFFER_SIZE; + while (log_size-- > 0) { + *(p_memory++) = value; + value += 1; +// if (log_size % 8 == 0) { +// value += 1; +// } + } +} + + + + + + +int alarm_log_get_data(unsigned long pos, int type_log) +{ + //unsigned int i,k; + static volatile unsigned long cur_adr_log, end_log, start_log, addres_mem, temp_length, delta_adr;//clog //real_length + //int *adr_finish_temp, *adr_current; + + +// real_length = al->real_points * al->oscills; + // real_adr = al->start_adr_real_logs; + + if (type_log==FAST_LOG) + { + temp_length = log_params.BlockSizeErr; + cur_adr_log = log_params.addres_mem; + end_log = log_params.end_address_log; + start_log = log_params.start_address_log; + + } + + if (type_log==SLOW_LOG) + { + temp_length = log_params.BlockSizeSlow; + cur_adr_log = log_params.addres_mem_slow; + end_log = log_params.end_address_log_slow; + start_log = log_params.start_address_log_slow; + } + + // ���� ����� � ������ + + + addres_mem = cur_adr_log - pos;//temp_length + + // �������� ����� ����? + if (addres_mem<start_log) + { + delta_adr = start_log - addres_mem ; + addres_mem = end_log - delta_adr + 1; + } + + return ReadMemory(addres_mem); + + +/* + + temp_length = al->temp_points * al->oscills; // ������� ������ ���� ��������� �� ���� + al->temp_log_ready = 0; + + + if (al->current_adr_real_log == al->start_adr_real_logs) // �� � ������, ����� ����? + return; + + adr_current = al->current_adr_real_log; // ��������� ����� ���� + adr_finish_temp = al->start_adr_temp + temp_length; // ��� ����� ���� temp + // ������ ������� � ����� adr_finish ��������� � temp_log + // � ������ ���� ��� �� �������� �� ������������ ������ � �������, ����� ��������� ������ + for (clog=0; clog<temp_length ;clog++) + { + if ( (adr_current >= al->start_adr_real_logs) ) + { + *adr_finish_temp = *adr_current; // ����������� ������ + // ���� ����� + adr_current--; + } + else + *adr_finish_temp = 0; // � ���� ������! + + // ���� ����� + adr_finish_temp--; + + // ��������������? + if (adr_current < al->start_adr_real_logs) + { + if (al->finish_adr_real_log) // ��� �������������? + adr_current = al->finish_adr_real_log; // ������� � �����. + else + adr_current = al->start_adr_real_logs - 1; + } + } + + al->temp_log_ready = 1; +*/ + +} + + + + diff --git a/Inu/Src/main/logs_hmi.h b/Inu/Src/main/logs_hmi.h new file mode 100644 index 0000000..e7637f5 --- /dev/null +++ b/Inu/Src/main/logs_hmi.h @@ -0,0 +1,86 @@ +/* + * logs_hmi.h + * + * Created on: 28 ���. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_LOGS_HMI_H_ +#define SRC_MAIN_LOGS_HMI_H_ + +#define _LOG_HMI_SMALL_TEST 0//1 + +#define PLACE_STORE_LOG_PULT_SD 1 //SD +#define PLACE_STORE_LOG_PULT_USB 2 //USB Flash + +typedef struct { + + int send_log; + +// int new_send_log_checked; + unsigned long log_size_sent; +// int flag_data_received; + + + +// unsigned int number_of_log; + unsigned long count_write_to_modbus; + +// unsigned long current_address; + unsigned long start_log_address; +// int log_address_step; + + int step; + int progress_bar; + int enable_progress_bar; + + int cleanLogs; + int tick_step; +// int tick_finish; + + int flag_log_array_sended; + int flag_start_log_array_sent; + + int flag_log_array_sent_process; + int count_data_in_buf; + unsigned long count_sended_to_pult; + + unsigned long max_size_logs_hmi; + + int tick_step2; + int tick_step3; + int tick_step4; + int tick_step5; + int n_log_array_sended; + + unsigned long max_size_logs_hmi_small; + unsigned long max_size_logs_hmi_full; + + int saveLogsToSDCard; + int ReportLogOut; + int sdusb; + +} t_Logs_with_modbus; + +#define LOGS_WITH_MODBUS_DEFAULTS {0,0,0,0,0, 0,0,0,0, 0,0,0,0,0, 0, 0,0,0,0,0, 0,0, 0,0,0} +extern t_Logs_with_modbus log_to_HMI; + + + + +#define LOG_START_ADRES 0xA0000UL +#define LOG_END_ADRES 0xF0000UL +#define LOG_BUFFER_SIZE 0x50000UL //0x100UL + +void fillLogArea(); //TODO for testing only + +int alarm_log_get_data(unsigned long pos, int type_log); + +int writeLogsArray(int flag_next); +static void prepareWriteLogsArray(void); +static int fillAnalogDataArrayForLogSend(void); +int sendLogToHMI(int status_ok); +void run_store_slow_logs(void); + + +#endif /* SRC_MAIN_LOGS_HMI_H_ */ diff --git a/Inu/Src/main/manch.h b/Inu/Src/main/manch.h new file mode 100644 index 0000000..d634beb --- /dev/null +++ b/Inu/Src/main/manch.h @@ -0,0 +1,182 @@ +#ifndef MANCH_H +#define MANCH_H + +#ifdef __cplusplus +extern "C" { +#endif + + + + +struct MANCH_READ_BITS { // bits description + Uint16 but_0:1; // 1 + Uint16 but_1:1; // 1 + Uint16 but_2:1; // 1 + Uint16 but_3:1; // 1 + Uint16 but_4:1; // 1 + Uint16 but_5:1; // 1 + Uint16 but_6:1; // 1 + Uint16 but_7:1; // 1 + Uint16 press_any_key:1; // 0 +}; + + +union MANCH_READ_REG { + Uint16 all; + struct MANCH_READ_BITS bit; +}; + + +struct MANCH_WRITE_BITS { // bits description + int number0:14; // 1 + int number1:14; // 1 + Uint16 data_control:1; // 1 + Uint16 case_line_recive2:1; // 1 + Uint16 res0:1; // 1 + Uint16 res1:1; // 1 + Uint16 set_ratio_indicator:4; // 1 + union { + Uint16 all; + struct + { + Uint16 lamp_0:1; // 1 + Uint16 lamp_1:1; // 1 + Uint16 lamp_2:1; // 1 + Uint16 lamp_3:1; // 1 + Uint16 lamp_4:1; // 1 + Uint16 lamp_5:1; // 1 + Uint16 lamp_6:1; // 1 + Uint16 lamp_7:1; // 1 + Uint16 lamp_8:1; // 1 + Uint16 lamp_9:1; // 1 + Uint16 lamp_10:1; // 1 + Uint16 lamp_11:1; // 1 + Uint16 lamp_12:1; // 1 + Uint16 lamp_13:1; // 1 + Uint16 lamp_14:1; // 1 + Uint16 lamp_15:1; // 1 + } bit; + } lamps; + union { + Uint16 all; + struct + { + Uint16 lamp_0:1; // 1 + Uint16 lamp_1:1; // 1 + Uint16 lamp_2:1; // 1 + Uint16 lamp_3:1; // 1 + Uint16 lamp_4:1; // 1 + Uint16 lamp_5:1; // 1 + Uint16 lamp_6:1; // 1 + Uint16 lamp_7:1; // 1 + Uint16 lamp_8:1; // 1 + Uint16 lamp_9:1; // 1 + Uint16 lamp_10:1; // 1 + Uint16 lamp_11:1; // 1 + Uint16 lamp_12:1; // 1 + Uint16 lamp_13:1; // 1 + Uint16 lamp_14:1; // 1 + Uint16 lamp_15:1; // 1 + } bit; + } lamps_2; + Uint16 res2:1; // 1 + Uint16 res3:1; // 1 + Uint16 set_ratio_lamp:4; // 1 + Uint16 case_line_receive1:1; +}; + +/* + +struct MANCH_WRITE1_BITS { // bits description + Uint16 number0:16; // 1 +}; + + + +struct MANCH_WRITE2_BITS { // bits description + Uint16 number1:8; // 1 + Uint16 data_control:1; // 1 + Uint16 case_line_recive2:1; // 1 + Uint16 res10:1; // 1 + Uint16 res11:1; // 1 + + Uint16 res1:6; // 1 +}; + +struct MANCH_WRITE3_BITS { // bits description + Uint16 lamp_0:1; // 1 + Uint16 lamp_1:1; // 1 + Uint16 lamp_2:1; // 1 + Uint16 lamp_3:1; // 1 + Uint16 lamp_4:1; // 1 + Uint16 lamp_5:1; // 1 + Uint16 lamp_6:1; // 1 + Uint16 lamp_7:1; // 1 + Uint16 lamp_8:1; // 1 + Uint16 lamp_9:1; // 1 + Uint16 lamp_10:1; // 1 + Uint16 lamp_11:1; // 1 + Uint16 lamp_12:1; // 1 + Uint16 lamp_13:1; // 1 + Uint16 lamp_14:1; // 1 + Uint16 lamp_15:1; // 1 +}; + + +union MANCH_WRITE1_REG { + Uint16 all; + struct MANCH_WRITE1_BITS bit; +}; + +union MANCH_WRITE2_REG { + Uint16 all; + struct MANCH_WRITE2_BITS bit; +}; + +union MANCH_WRITE3_REG { + Uint16 all; + struct MANCH_WRITE3_BITS bit; +}; + +*/ + +typedef volatile struct { // bits description + union MANCH_READ_REG reg1; +} MANCH_READ_REGS; + +/* +typedef volatile struct { // bits description + union MANCH_WRITE1_REG reg1; + union MANCH_WRITE2_REG reg2; + union MANCH_WRITE3_REG reg3; +} MANCH_WRITE_REGS; +*/ + +typedef volatile struct MANCH_WRITE_BITS MANCH_WRITE_REGS; + + + + + +extern MANCH_READ_REGS ManchReadRegs_00; +extern MANCH_READ_REGS ManchReadRegs_01; +extern MANCH_READ_REGS ManchReadRegs_02; +extern MANCH_READ_REGS ManchReadRegs_03; + +extern MANCH_WRITE_REGS ManchWriteRegs_00; +extern MANCH_WRITE_REGS ManchWriteRegs_01; + + + +void read_manch(); +int write_manch(); +void tune_manch_lines_v1(); + + +#ifdef __cplusplus +} +#endif /* extern "C" */ + + +#endif // end of MANCH_H definition + diff --git a/Inu/Src/main/master_slave.c b/Inu/Src/main/master_slave.c new file mode 100644 index 0000000..4aa4297 --- /dev/null +++ b/Inu/Src/main/master_slave.c @@ -0,0 +1,586 @@ +/* + * 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; + + } + +} + +////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/master_slave.h b/Inu/Src/main/master_slave.h new file mode 100644 index 0000000..c8ed38e --- /dev/null +++ b/Inu/Src/main/master_slave.h @@ -0,0 +1,34 @@ +/* + * master_slave.h + * + * Created on: 30 ����. 2020 �. + * Author: stud + */ + +#ifndef SRC_MASTER_SLAVE_H_ +#define SRC_MASTER_SLAVE_H_ + + +enum +{ +MODE_DONTKNOW = 1, +MODE_MASTER, +MODE_SLAVE +}; + + +////////////////////////////////////////////////////////// +#define MAX_COUNT_TRY_MASTER_BS1 200//40 //15 //5 +#define MAX_COUNT_TRY_MASTER_BS2 100//40 //15 //40 //20 +#define MAX_COUNT_WAIT_ANSWER_CONFIRM_MODE 20 + +#define MAX_COUNT_WAIT_SLAVE_TRY_MASTER 100 + + +#define SIZE_LOG_MASTER_SLAVE_STATUS 50 + +void auto_select_master_slave(void); +void clear_errors_master_slave(void); + + +#endif /* SRC_MASTER_SLAVE_H_ */ diff --git a/Inu/Src/main/message2.c b/Inu/Src/main/message2.c new file mode 100644 index 0000000..c54655c --- /dev/null +++ b/Inu/Src/main/message2.c @@ -0,0 +1,907 @@ +#include "IQmathLib.h" +#include "DSP281x_Device.h" + +#include <adc_tools.h> +#include <alg_simple_scalar.h> +#include <edrk_main.h> +#include <math.h> +#include <mathlib.h> +#include <message2.h> +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <sync_tools.h> +#include <v_rotor.h> +#include <vector.h> + +#include "control_station.h" +#include "global_time.h" +#include "vector_control.h" +#include "x_basic_types.h" +#include "xp_cds_in.h" +#include "xp_hwp.h" +#include "xp_project.h" +#include "modbus_table_v2.h" +#include "filter_v1.h" +#include "v_rotor_22220.h" +#include "log_params.h" +#include "break_regul.h" +#include "logs_hmi.h" +#include "CAN_Setup.h" +#include "params_temper_p.h" + + +void func_unpack_answer_from_TMS_RS232(CMD_TO_TMS_STRUCT *pcommand) +{ + // ����������y ����� + unsigned int DataOut; + int Data, Data1, Data2, DataAnalog1, DataAnalog2, DataAnalog3, DataAnalog4, i; + unsigned int h; + volatile unsigned char *pByte; + // static int vs11,vs12,vs1; + // static int DataCnt=0; + // int GoT,Assemble_scheme; + // static int prev_temp_Rele1=0, temp_Rele1=0, prev_temp_Rele2=0, temp_Rele2=0; + + static int flag_prev_turn_on = 0; + static int flag_prev_turn_off = 0; + static int prev_byte01_bit4 = 0; + static int prev_byte01_bit1 = 0; + static int flag_wait_revers_sbor = 1; + static int flag_wait_revers_go = 1; + + static unsigned int count_transmited = 0; + + + // ��������� ���y ������� + // ��� ��� ���� ������� ���� + + if ((sizeof(CMD_TO_TMS_STRUCT)-5)>CONTROL_STATION_MAX_RAW_DATA) + xerror(main_er_ID(2),(void *)0); + + + + // ���������� �� ������ � �����, �.�. � RS232 ������ ���� ������� + pByte = (unsigned char *)(pcommand);//->analog_data.analog1_lo; + + + pByte++; + pByte++; + + for (h=0;h<sizeof(TMS_TO_TERMINAL_STRUCT)-5;h++) + { + if (h%2) + { + control_station.raw_array_data[CONTROL_STATION_TERMINAL_RS232][h>>1].all |= ( (*pByte) << 8) & 0xff00; + } + else + control_station.raw_array_data[CONTROL_STATION_TERMINAL_RS232][h>>1].all = ( (*pByte) ) & 0x00ff; + + pByte++; + } + +} + + + +void func_pack_answer_to_TMS(TMS_TO_TERMINAL_STRUCT *reply_a) +{ + // ����������y ����� + unsigned int DataOut; + int Data1, Data2, DataAnalog1, DataAnalog2, DataAnalog3, DataAnalog4, i; + float Data; + unsigned char *pByte; + // static int vs11,vs12,vs1; + // static int DataCnt=0; + // int GoT,Assemble_scheme; + // static int prev_temp_Rele1=0, temp_Rele1=0, prev_temp_Rele2=0, temp_Rele2=0; + + static int flag_prev_turn_on = 0; + static int flag_prev_turn_off = 0; + static int prev_byte01_bit4 = 0; + static int prev_byte01_bit1 = 0; + static int flag_wait_revers_sbor = 1; + static int flag_wait_revers_go = 1; + + static unsigned int count_transmited = 0; + /* const ��������� �� ��������� ����������� ������� + ��������� �� ����� ������ */ + +// edrk.data_to_message2[1] = _IQtoF(filter.iqU_1_long)*NORMA_ACP; +// edrk.data_to_message2[2] = _IQtoF(filter.iqU_2_long)*NORMA_ACP; + + + //For instance + //reply->digit_data.byte01.byte_data = 0x43; + + + //1 + Data = _IQtoF(filter.iqU_1_long)*NORMA_ACP; + reply_a->analog_data.analog1_lo = LOBYTE(Data); + reply_a->analog_data.analog1_hi = HIBYTE(Data); + //2 + Data = _IQtoF(filter.iqU_2_long)*NORMA_ACP;//(project.adc[0].read.pbus.adc_value[1] - 2330)/4096*3.0/62.2*1000.0; + reply_a->analog_data.analog2_lo = LOBYTE(Data); + reply_a->analog_data.analog2_hi = HIBYTE(Data); + + //3 + Data = _IQtoF(filter.iqUin_m1)*NORMA_ACP;//(project.adc[0].read.pbus.adc_value[2] - 2330)/4096*3.0/62.2*1000.0; + reply_a->analog_data.analog3_lo = LOBYTE(Data); + reply_a->analog_data.analog3_hi = HIBYTE(Data); + +//4 +// Data = edrk.Status_Sbor;//_IQtoF(filter.iqUin_m2)*NORMA_ACP;//(project.adc[0].read.pbus.adc_value[3] - 2330)/4096*3.0/62.2*1000.0; + Data = _IQtoF(filter.iqUin_m2)*NORMA_ACP;//(project.adc[0].read.pbus.adc_value[3] - 2330)/4096*3.0/62.2*1000.0; +// Data = (_IQtoF((filter.Power) * 9000.0)); //�������� ��������� ������� ��� + reply_a->analog_data.analog4_lo = LOBYTE(Data); + reply_a->analog_data.analog4_hi = HIBYTE(Data); + +//5 + Data = edrk.power_kw; //�������� ��������� ������� ��� +// Data = (_IQtoF((analog.Power) * 9000.0)); //�������� ��������� ������� ��� + //_IQtoF(analog.iqIin_1)*NORMA_ACP;//project.adc[0].read.pbus.adc_value[0]; + reply_a->analog_data.analog5_lo = LOBYTE(Data); + reply_a->analog_data.analog5_hi = HIBYTE(Data); + + Data = _IQtoF(analog.iqIin_sum)*NORMA_ACP;//project.adc[0].read.pbus.adc_value[1]; + reply_a->analog_data.analog6_lo = LOBYTE(Data); + reply_a->analog_data.analog6_hi = HIBYTE(Data); + + + Data = _IQtoF(filter.iqIm_1)*NORMA_ACP;//project.adc[0].read.pbus.adc_value[2]; + reply_a->analog_data.analog7_lo = LOBYTE(Data); + reply_a->analog_data.analog7_hi = HIBYTE(Data); + + Data = _IQtoF(filter.iqIm_2)*NORMA_ACP;//project.adc[0].read.pbus.adc_value[3]; + reply_a->analog_data.analog8_lo = LOBYTE(Data); + reply_a->analog_data.analog8_hi = HIBYTE(Data); + + Data = (int)(edrk.temper_edrk.max_real_int_temper_u); + reply_a->analog_data.analog9_lo = LOBYTE(Data); + reply_a->analog_data.analog9_hi = HIBYTE(Data); + + Data = (int) (edrk.temper_edrk.max_real_int_temper_water); + reply_a->analog_data.analog10_lo = LOBYTE(Data); + reply_a->analog_data.analog10_hi = HIBYTE(Data); + + Data = (int) (edrk.p_water_edrk.filter_real_int_p_water[0]); + reply_a->analog_data.analog11_lo = LOBYTE(Data); + reply_a->analog_data.analog11_hi = HIBYTE(Data); + + Data = (int) (edrk.temper_edrk.max_real_int_temper_air);//_IQtoF(edrk.f_stator)*F_STATOR_MAX;// + reply_a->analog_data.analog12_lo = LOBYTE(Data); + reply_a->analog_data.analog12_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.zadanie.iq_ZadanieU_Charge_rmp)*NORMA_ACP);//edrk.I_zad_vozbud;// + reply_a->analog_data.analog13_lo = LOBYTE(Data); + reply_a->analog_data.analog13_hi = HIBYTE(Data); + + Data = edrk.zadanie.oborots_zad;//edrk.I_zad_vozbud_exp;// + reply_a->analog_data.analog14_lo = LOBYTE(Data); + reply_a->analog_data.analog14_hi = HIBYTE(Data); + + Data = edrk.zadanie.power_zad;//edrk.I_cur_vozbud;// + reply_a->analog_data.analog15_lo = LOBYTE(Data); + reply_a->analog_data.analog15_hi = HIBYTE(Data); + + Data = edrk.zadanie.Izad;//edrk.I_cur_vozbud_exp;// + reply_a->analog_data.analog16_lo = LOBYTE(Data); + reply_a->analog_data.analog16_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.Kplus)*1000.0);//edrk.W_zad_mA;// + reply_a->analog_data.analog17_lo = LOBYTE(Data); + reply_a->analog_data.analog17_hi = HIBYTE(Data); + +Data = fast_round(edrk.freq_50hz_1/10.0);//edrk.Zadanie2VozbudING;// + reply_a->analog_data.analog18_lo = LOBYTE(Data); + reply_a->analog_data.analog18_hi = HIBYTE(Data); + +Data =fast_round(_IQtoF(edrk.f_stator)*NORMA_FROTOR*100.0);// 0;//edrk.Zadanie2VozbudMY;// + reply_a->analog_data.analog19_lo = LOBYTE(Data); + reply_a->analog_data.analog19_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(edrk.k_stator1)*10000.0);// edrk.W_from_all; + reply_a->analog_data.analog20_lo = LOBYTE(Data); + reply_a->analog_data.analog20_hi = HIBYTE(Data); + +Data = _IQtoF(vect_control.iqId1)*NORMA_ACP;//0;//_IQtoF(edrk.test_rms_Iu)*NORMA_ACP; //fast_round(_IQtoF(WRotor.iqWRotorImpulses1)*NORMA_FROTOR*1000.0);// edrk.W_from_DISPLAY; + reply_a->analog_data.analog21_lo = LOBYTE(Data); + reply_a->analog_data.analog21_hi = HIBYTE(Data); + +Data = _IQtoF(vect_control.iqIq1)*NORMA_ACP;// 0;//_IQtoF(edrk.test_rms_Ua)*NORMA_ACP;// fast_round(_IQtoF(WRotor.iqWRotorImpulses2)*NORMA_FROTOR*1000.0);//600.0*1000000000.0/WRotor.iqWRotorImpulses1;//edrk.W_from_SVU; + reply_a->analog_data.analog22_lo = LOBYTE(Data); + reply_a->analog_data.analog22_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorSumFilter3)*NORMA_FROTOR*100.0*60.0);//edrk.oborots;//fast_round(_IQtoF(WRotorPBus.iqAngle1F)*360.0);//600.0*1000000000.0/WRotor.iqWRotorImpulses2;//edrk.W_from_ZADAT4IK; +Data = _IQtoF(WRotor.iqWRotorSumFilter) * NORMA_FROTOR*600.0;//edrk.oborots; + reply_a->analog_data.analog23_lo = LOBYTE(Data); + reply_a->analog_data.analog23_hi = HIBYTE(Data); + +Data = fast_round(edrk.f_rotor_hz*100.0);//fast_round(_IQtoF(WRotorPBus.iqAngle2F)*360.0);//; + reply_a->analog_data.analog24_lo = LOBYTE(Data); + reply_a->analog_data.analog24_hi = HIBYTE(Data); + +//Data = _IQtoF(edrk.k_stator1)*10000;//; +Data = edrk.period_calc_pwm_int2;//fast_round(_IQtoF(rotor_22220.iqFdirty)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog25_lo = LOBYTE(Data); + reply_a->analog_data.analog25_hi = HIBYTE(Data); + +Data = edrk.power_kw_full; //�������� ��������� ������� ��� +//fast_round(_IQtoF(WRotor.iqWRotorCalcBeforeRegul2)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog26_lo = LOBYTE(Data); + reply_a->analog_data.analog26_hi = HIBYTE(Data); + +Data = edrk.Sbor_Mode;//fast_round(_IQtoF(WRotorPBus.iqWRotorCalcBeforeRegul1)*NORMA_FROTOR*1000.0);//edrk.count_lost_interrupt; + reply_a->analog_data.analog27_lo = LOBYTE(Data); + reply_a->analog_data.analog27_hi = HIBYTE(Data); + +Data = edrk.Stage_Sbor;// fast_round(_IQtoF(WRotorPBus.iqWRotorCalcBeforeRegul2)*NORMA_FROTOR*1000.0);; + reply_a->analog_data.analog28_lo = LOBYTE(Data); + reply_a->analog_data.analog28_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(edrk.Izad_out)*NORMA_ACP);//edrk.I_zad_vozbud;//; + reply_a->analog_data.analog29_lo = LOBYTE(Data); + reply_a->analog_data.analog29_hi = HIBYTE(Data); + +Data = edrk.period_calc_pwm_int1; + reply_a->analog_data.analog30_lo = LOBYTE(Data); + reply_a->analog_data.analog30_hi = HIBYTE(Data); + + Data = (int)edrk.temper_acdrive.winding.max_real_int_temper; + reply_a->analog_data.analog31_lo = LOBYTE(Data); + reply_a->analog_data.analog31_hi = HIBYTE(Data); + Data = (int)edrk.temper_acdrive.bear.max_real_int_temper; + reply_a->analog_data.analog32_lo = LOBYTE(Data); + reply_a->analog_data.analog32_hi = HIBYTE(Data); + + + + Data = (int)(edrk.temper_edrk.real_int_temper_u[0]); + reply_a->analog_data.analog33_lo = LOBYTE(Data); + reply_a->analog_data.analog33_hi = HIBYTE(Data); + + Data = (int)(edrk.temper_edrk.real_int_temper_u[1]); + reply_a->analog_data.analog34_lo = LOBYTE(Data); + reply_a->analog_data.analog34_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_u[2]); + reply_a->analog_data.analog35_lo = LOBYTE(Data); + reply_a->analog_data.analog35_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_u[3]); + reply_a->analog_data.analog36_lo = LOBYTE(Data); + reply_a->analog_data.analog36_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_u[4]); + reply_a->analog_data.analog37_lo = LOBYTE(Data); + reply_a->analog_data.analog37_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_u[5]); + reply_a->analog_data.analog38_lo = LOBYTE(Data); + reply_a->analog_data.analog38_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_u[6]); + reply_a->analog_data.analog39_lo = LOBYTE(Data); + reply_a->analog_data.analog39_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_air[0]); + reply_a->analog_data.analog40_lo = LOBYTE(Data); + reply_a->analog_data.analog40_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_air[1]); + reply_a->analog_data.analog41_lo = LOBYTE(Data); + reply_a->analog_data.analog41_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_air[2]); + reply_a->analog_data.analog42_lo = LOBYTE(Data); + reply_a->analog_data.analog42_hi = HIBYTE(Data); + + Data = (int)(edrk.temper_edrk.real_int_temper_air[3]); + reply_a->analog_data.analog43_lo = LOBYTE(Data); + reply_a->analog_data.analog43_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_water[0]); // external + reply_a->analog_data.analog44_lo = LOBYTE(Data); + reply_a->analog_data.analog44_hi = HIBYTE(Data); + Data = (int)(edrk.temper_edrk.real_int_temper_water[1]); // internal + reply_a->analog_data.analog45_lo = LOBYTE(Data); + reply_a->analog_data.analog45_hi = HIBYTE(Data); + + + Data = fast_round(_IQtoF(simple_scalar1.pidF.OutMax)*NORMA_ACP);//edrk.auto_master_slave.prev_status;//fast_round(_IQtoF(edrk.zadanie.iq_ZadanieU_Charge_rmp)*NORMA_ACP); + reply_a->analog_data.analog46_lo = LOBYTE(Data); + reply_a->analog_data.analog46_hi = HIBYTE(Data); + + + Data = fast_round(_IQtoF(edrk.zadanie.iq_Izad_rmp)*NORMA_ACP); + reply_a->analog_data.analog47_lo = LOBYTE(Data); + reply_a->analog_data.analog47_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(edrk.zadanie.iq_fzad_rmp)*NORMA_FROTOR*100.0); + reply_a->analog_data.analog48_lo = LOBYTE(Data); + reply_a->analog_data.analog48_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(edrk.zadanie.iq_kzad_rmp)*10000.0); + reply_a->analog_data.analog49_lo = LOBYTE(Data); + reply_a->analog_data.analog49_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(edrk.zadanie.iq_oborots_zad_hz_rmp)*NORMA_FROTOR*60.0); + reply_a->analog_data.analog50_lo = LOBYTE(Data); + reply_a->analog_data.analog50_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.zadanie.iq_power_zad_rmp)*NORMA_ACP*NORMA_ACP/1000.0); + reply_a->analog_data.analog51_lo = LOBYTE(Data); + reply_a->analog_data.analog51_hi = HIBYTE(Data); + + Data = _IQtoF(vect_control.iqId2)*NORMA_ACP;//0;//fast_round( _IQtoF(edrk.zadanie.iq_k_u_disbalance_rmp)*100.0); + reply_a->analog_data.analog52_lo = LOBYTE(Data); + reply_a->analog_data.analog52_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.zadanie.iq_limit_power_zad_rmp)*NORMA_ACP*NORMA_ACP/1000.0); + reply_a->analog_data.analog53_lo = LOBYTE(Data); + reply_a->analog_data.analog53_hi = HIBYTE(Data); + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) { + Data = fast_round(_IQtoF(turns.pidFvect.Out)*NORMA_ACP); + reply_a->analog_data.analog54_lo = LOBYTE(Data); + reply_a->analog_data.analog54_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(turns.pidFvect.OutMax)*NORMA_ACP); + reply_a->analog_data.analog55_lo = LOBYTE(Data); + reply_a->analog_data.analog55_hi = HIBYTE(Data); + Data =fast_round(_IQtoF(power.pidP.Out)*NORMA_ACP); + reply_a->analog_data.analog56_lo = LOBYTE(Data); + reply_a->analog_data.analog56_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(power.pidP.OutMax)*NORMA_ACP); + } else { + Data = fast_round(_IQtoF(simple_scalar1.pidF.Out)*NORMA_ACP); + reply_a->analog_data.analog54_lo = LOBYTE(Data); + reply_a->analog_data.analog54_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(simple_scalar1.pidF.OutMin)*NORMA_ACP); + reply_a->analog_data.analog55_lo = LOBYTE(Data); + reply_a->analog_data.analog55_hi = HIBYTE(Data); + Data =fast_round(_IQtoF(simple_scalar1.pidPower.Out)*NORMA_ACP); + reply_a->analog_data.analog56_lo = LOBYTE(Data); + reply_a->analog_data.analog56_hi = HIBYTE(Data); + Data = fast_round(_IQtoF(simple_scalar1.pidPower.OutMax)*NORMA_ACP); + } + + reply_a->analog_data.analog57_lo = LOBYTE(Data); + reply_a->analog_data.analog57_hi = HIBYTE(Data); + + + + Data = fast_round(_IQtoF(simple_scalar1.Izad)*NORMA_ACP); + reply_a->analog_data.analog58_lo = LOBYTE(Data); + reply_a->analog_data.analog58_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.master_Iq)*NORMA_ACP); + reply_a->analog_data.analog59_lo = LOBYTE(Data); + reply_a->analog_data.analog59_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.mzz_zad_in2)*NORMA_ACP);//count_transmited++; + reply_a->analog_data.analog60_lo = LOBYTE(Data); + reply_a->analog_data.analog60_hi = HIBYTE(Data); +// + Data = modbus_table_can_in[123].all;//���������� (�� ��������, �� ��������) + reply_a->analog_data.analog61_lo = LOBYTE(Data); + reply_a->analog_data.analog61_hi = HIBYTE(Data); + + Data = modbus_table_can_in[124].all;//������� (��������) + reply_a->analog_data.analog62_lo = LOBYTE(Data); + reply_a->analog_data.analog62_hi = HIBYTE(Data); + + Data = modbus_table_can_in[125].all;//�������� (��������) + reply_a->analog_data.analog63_lo = LOBYTE(Data); + reply_a->analog_data.analog63_hi = HIBYTE(Data); + + Data = modbus_table_can_in[134].all;//����� �������� + reply_a->analog_data.analog64_lo = LOBYTE(Data); + reply_a->analog_data.analog64_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidPower.SatErr)*NORMA_ACP);//project.cds_tk[3].optical_data_in.local_count_error; + reply_a->analog_data.analog65_lo = LOBYTE(Data); + reply_a->analog_data.analog65_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidPower.Fdb)*NORMA_ACP*NORMA_ACP/1000.0);//project.cds_tk[3].optical_data_out.local_count_error; + reply_a->analog_data.analog66_lo = LOBYTE(Data); + reply_a->analog_data.analog66_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidPower.Ref)*NORMA_ACP*NORMA_ACP/1000.0);//////optical_read_data.count_error_wdog; + reply_a->analog_data.analog67_lo = LOBYTE(Data); + reply_a->analog_data.analog67_hi = HIBYTE(Data); + + + Data = fast_round(_IQtoF(simple_scalar1.pidPower.Up)*NORMA_ACP);//edrk.auto_master_slave.status;//fast_round(_IQtoF(edrk.zadanie.iq_kplus_u_disbalance_rmp)*1000.0); + reply_a->analog_data.analog68_lo = LOBYTE(Data); + reply_a->analog_data.analog68_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(pll1.vars.pll_Uq)*NORMA_ACP); + reply_a->analog_data.analog69_lo = LOBYTE(Data); + reply_a->analog_data.analog69_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(pll1.vars.pll_Ud)*NORMA_ACP); + reply_a->analog_data.analog70_lo = LOBYTE(Data); + reply_a->analog_data.analog70_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(simple_scalar1.bpsi_curent)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog71_lo = LOBYTE(Data); + reply_a->analog_data.analog71_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(WRotor.iqWRotorSumFilter2)*NORMA_FROTOR*1000.0); //iqFlong + reply_a->analog_data.analog72_lo = LOBYTE(Data); + reply_a->analog_data.analog72_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorCalc1)*NORMA_FROTOR*1000.0); +Data = fast_round(_IQtoF(edrk.from_uom.iq_level_value_kwt)*NORMA_ACP*NORMA_ACP/1000.0);// ;//edrk.from_uom.level_value;//fast_round(_IQtoF(rotor_22220.iqFdirty)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog73_lo = LOBYTE(Data); + reply_a->analog_data.analog73_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorCalc2)*NORMA_FROTOR*1000.0); +Data = _IQtoF(vect_control.iqIq2)*NORMA_ACP;//0;//fast_round(_IQtoF(rotor_22220.iqF)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog74_lo = LOBYTE(Data); + reply_a->analog_data.analog74_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorImpulsesBeforeRegul1)*NORMA_FROTOR*1000.0);// edrk.W_from_DISPLAY; +Data = fast_round(_IQtoF(WRotor.iqWRotorSumFilter)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog75_lo = LOBYTE(Data); + reply_a->analog_data.analog75_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorImpulsesBeforeRegul2)*NORMA_FROTOR*1000.0);//600.0*1000000000.0/WRotor.iqWRotorImpulses1;//edrk.W_from_SVU; +Data = fast_round(_IQtoF(simple_scalar1.mzz_zad_int)*NORMA_ACP);//;//0;//fast_round(_IQtoF(rotor_22220.iqFlong)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog76_lo = LOBYTE(Data); + reply_a->analog_data.analog76_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorImpulses1)*NORMA_FROTOR*1000.0);// edrk.W_from_DISPLAY; + Data = _IQtoF(simple_scalar1.Izad)*NORMA_ACP_RMS;// 0;//fast_round(_IQtoF(WRotor.iqWRotorSumRamp)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog77_lo = LOBYTE(Data); + reply_a->analog_data.analog77_hi = HIBYTE(Data); + +//Data = fast_round(_IQtoF(WRotor.iqWRotorImpulses2)*NORMA_FROTOR*1000.0);//600.0*1000000000.0/WRotor.iqWRotorImpulses1;//edrk.W_from_SVU; + Data = WRotor.RotorDirectionSlow; + reply_a->analog_data.analog78_lo = LOBYTE(Data); + reply_a->analog_data.analog78_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(simple_scalar1.iqKoefOgran)*1000.0);//0;//fast_round(_IQtoF(WRotor.iqWRotorSum)*NORMA_FROTOR*1000.0);// edrk.W_from_DISPLAY; + reply_a->analog_data.analog79_lo = LOBYTE(Data); + reply_a->analog_data.analog79_hi = HIBYTE(Data); + +Data = fast_round(_IQtoF(simple_scalar1.iqKoefOgranIzad)*1000.0);//0;//fast_round(_IQtoF(WRotor.iqWRotorSumFilter)*NORMA_FROTOR*1000.0);//600.0*1000000000.0/WRotor.iqWRotorImpulses1;//edrk.W_from_SVU; + reply_a->analog_data.analog80_lo = LOBYTE(Data); + reply_a->analog_data.analog80_hi = HIBYTE(Data); + + Data = log_params.cur_volume_of_slow_log;//edrk.power_kw_full; //�������� ��������� ������� ��� +// Data = (_IQtoF((analog.Power) * 9000.0)); //�������� ��������� ������� ��� + //_IQtoF(analog.iqIin_1)*NORMA_ACP;//project.adc[0].read.pbus.adc_value[0]; + reply_a->analog_data.analog81_lo = LOBYTE(Data); + reply_a->analog_data.analog81_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.zadanie.iq_limit_power_zad)*NORMA_ACP*NORMA_ACP/1000.0); + reply_a->analog_data.analog82_lo = LOBYTE(Data); + reply_a->analog_data.analog82_hi = HIBYTE(Data); + + Data = break_result_1;//fast_round(_IQtoF(WRotor.iqWRotorSumFilter3)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog83_lo = LOBYTE(Data); + reply_a->analog_data.analog83_hi = HIBYTE(Data); + + Data = break_result_2;//WRotorPBus.RotorDirectionInstant; + reply_a->analog_data.analog84_lo = LOBYTE(Data); + reply_a->analog_data.analog84_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.all_limit_koeffs.sum_limit)*1000.0);//WRotorPBus.RotorDirectionCount; + reply_a->analog_data.analog85_lo = LOBYTE(Data); + reply_a->analog_data.analog85_hi = HIBYTE(Data); + + + Data = fast_round(_IQtoF(edrk.all_limit_koeffs.uom_limit)*1000.0);//WRotorPBus.RotorDirectionSlow2; + reply_a->analog_data.analog86_lo = LOBYTE(Data); + reply_a->analog_data.analog86_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(edrk.all_limit_koeffs.uin_freq_limit)*1000.0);//fast_round(_IQtoF(WRotor.iqWRotorSumRamp)*NORMA_FROTOR*1000.0); + reply_a->analog_data.analog87_lo = LOBYTE(Data); + reply_a->analog_data.analog87_hi = HIBYTE(Data); + + Data = _IQtoF(simple_scalar1.Im_regul)*NORMA_ACP_RMS;//(edrk.cantec_reg & 0xff);//edrk.pult_data.TimeToChangePump_from_pult;//0;//fast_round(_IQtoF(WRotor.iqWRotorCalc1Ramp)*NORMA_FROTOR*1000.0);;//WRotor.iqWRotorCalc1Ramp + reply_a->analog_data.analog88_lo = LOBYTE(Data); + reply_a->analog_data.analog88_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidPower.Ui)*NORMA_ACP);//(edrk.canrec_reg & 0xff);;//edrk.pult_data.nPCH_from_pult;//0;//fast_round(_IQtoF(WRotor.iqWRotorCalc2Ramp)*NORMA_FROTOR*1000.0);; + reply_a->analog_data.analog89_lo = LOBYTE(Data); + reply_a->analog_data.analog89_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidF.Fdb)*NORMA_FROTOR*1000.0);//(((unsigned long)edrk.canes_reg>>16) & 0x01ff); + reply_a->analog_data.analog90_lo = LOBYTE(Data); + reply_a->analog_data.analog90_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidF.Ref)*NORMA_FROTOR*1000.0);//(((unsigned long)edrk.canes_reg) & 0x3f); + reply_a->analog_data.analog91_lo = LOBYTE(Data); + reply_a->analog_data.analog91_hi = HIBYTE(Data); + + + Data = fast_round(_IQtoF(simple_scalar1.pidF.SatErr)*NORMA_ACP);//CanBusOffError;//0; + reply_a->analog_data.analog92_lo = LOBYTE(Data); + reply_a->analog_data.analog92_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidF.Ui)*NORMA_ACP);//CanTimeOutErrorTR;//0; + reply_a->analog_data.analog93_lo = LOBYTE(Data); + reply_a->analog_data.analog93_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.pidF.Up)*NORMA_ACP);//0; + reply_a->analog_data.analog94_lo = LOBYTE(Data); + reply_a->analog_data.analog94_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.iq_decr_mzz_power)*1000.0);//0;//simple_scalar1.k_ogr_n + reply_a->analog_data.analog95_lo = LOBYTE(Data); + reply_a->analog_data.analog95_hi = HIBYTE(Data); + + Data = fast_round(_IQtoF(simple_scalar1.iq_decr_mzz_power_filter)*1000.0);//fast_round(_IQtoF(edrk.zadanie.rmp_oborots_zad_hz.PosRampPlus1)*NORMA_FROTOR*60.0*450.0*1000.0); + reply_a->analog_data.analog96_lo = LOBYTE(Data); + reply_a->analog_data.analog96_hi = HIBYTE(Data); + +// Data = 0; +// reply_a->analog_data.analog97_lo = LOBYTE(Data); +// reply_a->analog_data.analog97_hi = HIBYTE(Data); + + + + pByte = &reply_a->digit_data.byte01.byte_data; + for (i = 0; i < 59; i++) //zero all dig data + { + *(pByte + i) = 0; + } + + +// reply->digit_data.byte01.byte_data = project.cds_in[1].read.pbus.data_in.all & 0xff; +// reply->digit_data.byte02.byte_data = (project.cds_in[1].read.pbus.data_in.all >> 8) & 0xff; + + reply_a->digit_data.byte01.byte_data = edrk.errors.e0.all & 0xff; + reply_a->digit_data.byte02.byte_data = (edrk.errors.e0.all >> 8) & 0xff; + + reply_a->digit_data.byte03.byte_data = edrk.errors.e1.all & 0xff; + reply_a->digit_data.byte04.byte_data = (edrk.errors.e1.all >> 8) & 0xff; + + reply_a->digit_data.byte05.byte_data = edrk.errors.e2.all & 0xff; + reply_a->digit_data.byte06.byte_data = (edrk.errors.e2.all >> 8) & 0xff; + + reply_a->digit_data.byte07.byte_data = edrk.errors.e3.all & 0xff; + reply_a->digit_data.byte08.byte_data = (edrk.errors.e3.all >> 8) & 0xff; + + reply_a->digit_data.byte09.byte_data = edrk.errors.e4.all & 0xff; + reply_a->digit_data.byte10.byte_data = (edrk.errors.e4.all >> 8) & 0xff; + + reply_a->digit_data.byte11.byte_data = edrk.errors.e5.all & 0xff; + reply_a->digit_data.byte12.byte_data = (edrk.errors.e5.all >> 8) & 0xff; + +//13 + if (edrk.Status_Perehod_Rascepitel) + reply_a->digit_data.byte13.bit_data.bit1 = 1; + else + reply_a->digit_data.byte13.bit_data.bit1 = 0; + + if (edrk.Status_Rascepitel_Ok) + reply_a->digit_data.byte13.bit_data.bit0 = 1; + else + reply_a->digit_data.byte13.bit_data.bit0 = 0; + + reply_a->digit_data.byte13.bit_data.bit2 = edrk.from_second_pch.bits.MASTER; + reply_a->digit_data.byte13.bit_data.bit3 = edrk.from_second_pch.bits.RASCEPITEL; + + reply_a->digit_data.byte13.bit_data.bit4 = edrk.warning; + reply_a->digit_data.byte13.bit_data.bit5 = edrk.overheat; + reply_a->digit_data.byte13.bit_data.bit6 = edrk.summ_errors; + reply_a->digit_data.byte13.bit_data.bit7 = edrk.Status_Ready.bits.ready_final; + + +// reply_a->digit_data.byte13.byte_data = edrk.errors.e6.all & 0xff; +// reply->digit_data.byte14.byte_data = (edrk.errors.e6.all >> 8) & 0xff; +/* + reply->digit_data.byte15.byte_data = edrk.errors.e7.all & 0xff; + reply->digit_data.byte16.byte_data = (edrk.errors.e7.all >> 8) & 0xff; + + reply->digit_data.byte17.byte_data = edrk.errors.e8.all & 0xff; + reply->digit_data.byte18.byte_data = (edrk.errors.e8.all >> 8) & 0xff; +*/ +//IN2 + reply_a->digit_data.byte14.byte_data = edrk.from_ing1.all & 0xff;// project.cds_in[1].read.pbus.data_in.all & 0xFF; + reply_a->digit_data.byte15.byte_data = (edrk.from_ing1.all >> 8) & 0xFF;//(project.cds_in[1].read.pbus.data_in.all >> 8) & 0xFF; + +// status plates + reply_a->digit_data.byte16.bit_data.bit0 = !(project.hwp[0].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; + reply_a->digit_data.byte16.bit_data.bit1 = !(project.adc[0].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; + reply_a->digit_data.byte16.bit_data.bit2 = !(project.adc[1].status == component_Ready); + reply_a->digit_data.byte16.bit_data.bit3 = !(project.cds_in[0].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneIN0_IsReady; + reply_a->digit_data.byte16.bit_data.bit4 = !(project.cds_in[1].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneIN1_IsReady; +// reply_ans->digit_data.byte21.bit_data.bit5 = !project.cds_in[2].status;//XProject_balzam.IsReady_reg.bit.XPlaneIN2_IsReady; + reply_a->digit_data.byte16.bit_data.bit5 = !(project.cds_out[0].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneOUT0_IsReady; +// reply_ans->digit_data.byte21.bit_data.bit7 = !project.cds_out[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneOUT1_IsReady; +// reply_ans->digit_data.byte22.bit_data.bit0 = !project.cds_out[2].status;//XProject_balzam.IsReady_reg.bit.XPlaneOUT2_IsReady; + reply_a->digit_data.byte16.bit_data.bit6 = !(project.cds_tk[0].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneTK0_IsReady; + reply_a->digit_data.byte16.bit_data.bit7 = !(project.cds_tk[1].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneTK1_IsReady; + reply_a->digit_data.byte17.bit_data.bit0 = !(project.cds_tk[2].status == component_Ready);//XProject_balzam.IsReady_reg.bit.XPlaneTK2_IsReady; + reply_a->digit_data.byte17.bit_data.bit1 = !(project.cds_tk[3].status == component_Ready);//!XProject_balzam.IsReady_reg.bit.XPlaneTK3_IsReady; +// reply_ans->digit_data.byte22.bit_data.bit5 = !project.adc[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; + + +//IN1 + reply_a->digit_data.byte17.bit_data.bit2 = project.cds_in[0].read.pbus.data_in.bit.in0; + reply_a->digit_data.byte17.bit_data.bit3 = project.cds_in[0].read.pbus.data_in.bit.in1; + reply_a->digit_data.byte17.bit_data.bit4 = project.cds_in[0].read.pbus.data_in.bit.in2; + reply_a->digit_data.byte17.bit_data.bit5 = project.cds_in[0].read.pbus.data_in.bit.in3; + reply_a->digit_data.byte17.bit_data.bit6 = project.cds_in[0].read.pbus.data_in.bit.in4; + + reply_a->digit_data.byte17.bit_data.bit7 = project.cds_in[0].read.pbus.data_in.bit.in8; + + reply_a->digit_data.byte18.bit_data.bit0 = project.cds_in[0].read.pbus.data_in.bit.in9; + reply_a->digit_data.byte18.bit_data.bit1 = project.cds_in[0].read.pbus.data_in.bit.in10; + reply_a->digit_data.byte18.bit_data.bit2 = project.cds_in[0].read.pbus.data_in.bit.in11; + + +//out + reply_a->digit_data.byte18.bit_data.bit3 = edrk.to_ing.bits.ZARYAD_ON;// project.cds_out[0].write.sbus.data_out.bit.dout0; + + reply_a->digit_data.byte18.bit_data.bit4 = edrk.to_ing.bits.NAGREV_OFF;//project.cds_out[0].write.sbus.data_out.bit.dout1; + reply_a->digit_data.byte18.bit_data.bit5 = edrk.to_ing.bits.NASOS_1_ON;//project.cds_out[0].write.sbus.data_out.bit.dout2; + reply_a->digit_data.byte18.bit_data.bit6 = edrk.to_ing.bits.NASOS_2_ON;//project.cds_out[0].write.sbus.data_out.bit.dout3; + reply_a->digit_data.byte18.bit_data.bit7 = edrk.to_ing.bits.BLOCK_KEY_OFF;//project.cds _out[0].write.sbus.data_out.bit.dout4; + reply_a->digit_data.byte19.bit_data.bit0 = (edrk.to_shema.bits.UMP_ON_OFF || edrk.to_shema.bits.CROSS_UMP_ON_OFF);//project.cds_out[0].write.sbus.data_out.bit.dout5; + reply_a->digit_data.byte19.bit_data.bit1 = edrk.to_shema.bits.QTV_ON || edrk.to_shema.bits.QTV_ON_OFF || edrk.to_shema.bits.CROSS_QTV_ON_OFF;//project.cds_out[0].write.sbus.data_out.bit.dout6; + reply_a->digit_data.byte19.bit_data.bit2 = edrk.to_shema.bits.QTV_OFF;//project.cds_out[0].write.sbus.data_out.bit.dout7; + + reply_a->digit_data.byte19.bit_data.bit3 = edrk.to_ing.bits.RASCEPITEL_OFF; + reply_a->digit_data.byte19.bit_data.bit4 = edrk.to_ing.bits.RASCEPITEL_ON; + reply_a->digit_data.byte19.bit_data.bit5 = sync_data.local_flag_sync_1_2;// + reply_a->digit_data.byte19.bit_data.bit6 = edrk.flag_second_PCH;// + reply_a->digit_data.byte19.bit_data.bit7 = edrk.to_ing.bits.SMALL_LAMPA_AVARIA; //project.cds_out[0].write.sbus.data_out.bit.dout15; + +//20 + reply_a->digit_data.byte20.bit_data.bit0 = edrk.SumSbor; + + reply_a->digit_data.byte20.bit_data.bit1 = edrk.Status_Ready.bits.ready1; + reply_a->digit_data.byte20.bit_data.bit2 = edrk.Status_Ready.bits.ready2; + reply_a->digit_data.byte20.bit_data.bit3 = edrk.Status_Ready.bits.ready3; + reply_a->digit_data.byte20.bit_data.bit4 = edrk.Status_Ready.bits.ready4; + reply_a->digit_data.byte20.bit_data.bit5 = edrk.Status_Ready.bits.ready5; + reply_a->digit_data.byte20.bit_data.bit6 = edrk.Status_Charge; + reply_a->digit_data.byte20.bit_data.bit7 = edrk.Zaryad_OK; + + reply_a->digit_data.byte21.byte_data = edrk.errors.e6.all & 0xff; + reply_a->digit_data.byte22.byte_data = (edrk.errors.e6.all >> 8) & 0xff; + +// reply_a->digit_data.byte21.bit_data.bit0 = edrk.errors.e6.bits.UO6_KEYS; +// reply_a->digit_data.byte21.bit_data.bit1 = edrk.errors.e6.bits.UO7_KEYS; +// reply_a->digit_data.byte21.bit_data.bit2 = edrk.errors.e6.bits.UO1_KEYS; +// reply_a->digit_data.byte21.bit_data.bit3 = edrk.errors.e6.bits.ERR_PBUS; +// reply_a->digit_data.byte21.bit_data.bit4 = edrk.errors.e6.bits.ERR_SBUS; +// reply_a->digit_data.byte21.bit_data.bit5 = edrk.errors.e6.bits.ER_DISBAL_BATT; +// reply_a->digit_data.byte21.bit_data.bit6 = edrk.errors.e6.bits.ER_RAZBALANS_ALG; +// reply_a->digit_data.byte21.bit_data.bit7 = edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER; + + + reply_a->digit_data.byte23.byte_data = edrk.errors.e7.all & 0xff; + reply_a->digit_data.byte24.byte_data = (edrk.errors.e7.all >> 8) & 0xff; + + + + // hwp + reply_a->digit_data.byte25.byte_data = project.hwp[0].read.comp_s.plus.all & 0xff; + reply_a->digit_data.byte26.byte_data = (project.hwp[0].read.comp_s.plus.all >> 8) & 0xff; + + reply_a->digit_data.byte27.byte_data = project.hwp[0].read.comp_s.minus.all & 0xff; + reply_a->digit_data.byte28.byte_data = (project.hwp[0].read.comp_s.minus.all >> 8) & 0xff; + + + reply_a->digit_data.byte29.bit_data.bit0 = control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232]; + reply_a->digit_data.byte29.bit_data.bit1 = control_station.active_control_station[CONTROL_STATION_TERMINAL_CAN]; + reply_a->digit_data.byte29.bit_data.bit2 = control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]; + reply_a->digit_data.byte29.bit_data.bit3 = control_station.active_control_station[CONTROL_STATION_MPU_SVU_CAN]; + reply_a->digit_data.byte29.bit_data.bit4 = control_station.active_control_station[CONTROL_STATION_MPU_KEY_CAN]; + reply_a->digit_data.byte29.bit_data.bit5 = control_station.active_control_station[CONTROL_STATION_MPU_SVU_RS485]; + reply_a->digit_data.byte29.bit_data.bit6 = control_station.active_control_station[CONTROL_STATION_MPU_KEY_RS485]; + reply_a->digit_data.byte29.bit_data.bit7 = control_station.active_control_station[CONTROL_STATION_ZADATCHIK_CAN]; + + reply_a->digit_data.byte30.bit_data.bit0 = control_station.alive_control_station[CONTROL_STATION_TERMINAL_RS232]; + reply_a->digit_data.byte30.bit_data.bit1 = control_station.alive_control_station[CONTROL_STATION_TERMINAL_CAN]; + reply_a->digit_data.byte30.bit_data.bit2 = control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]; + reply_a->digit_data.byte30.bit_data.bit3 = control_station.alive_control_station[CONTROL_STATION_MPU_SVU_CAN]; + reply_a->digit_data.byte30.bit_data.bit4 = control_station.alive_control_station[CONTROL_STATION_MPU_KEY_CAN]; + reply_a->digit_data.byte30.bit_data.bit5 = control_station.alive_control_station[CONTROL_STATION_MPU_SVU_RS485]; + reply_a->digit_data.byte30.bit_data.bit6 = control_station.alive_control_station[CONTROL_STATION_MPU_KEY_RS485]; + reply_a->digit_data.byte30.bit_data.bit7 = control_station.alive_control_station[CONTROL_STATION_ZADATCHIK_CAN]; + + + reply_a->digit_data.byte31.byte_data = optical_read_data.data.cmd.all & 0xff; + reply_a->digit_data.byte32.byte_data = (optical_read_data.data.cmd.all >> 8) & 0xff; + + reply_a->digit_data.byte33.byte_data = optical_write_data.data.cmd.all & 0xff; + reply_a->digit_data.byte34.byte_data = (optical_write_data.data.cmd.all >> 8) & 0xff; + + reply_a->digit_data.byte35.bit_data.bit0 = control_station.alive_control_station[CONTROL_STATION_VPU_CAN]; + reply_a->digit_data.byte35.bit_data.bit1 = control_station.active_control_station[CONTROL_STATION_VPU_CAN]; + + reply_a->digit_data.byte35.bit_data.bit2 = edrk.auto_master_slave.local.bits.master; + reply_a->digit_data.byte35.bit_data.bit3 = edrk.auto_master_slave.local.bits.slave; + reply_a->digit_data.byte35.bit_data.bit4 = edrk.auto_master_slave.local.bits.try_master; + + reply_a->digit_data.byte35.bit_data.bit5 = edrk.auto_master_slave.remoute.bits.master; + reply_a->digit_data.byte35.bit_data.bit6 = edrk.auto_master_slave.remoute.bits.slave; + reply_a->digit_data.byte35.bit_data.bit7 = edrk.auto_master_slave.remoute.bits.try_master; + + reply_a->digit_data.byte36.bit_data.bit0 = edrk.Status_Ready.bits.MasterSlaveActive; + reply_a->digit_data.byte36.bit_data.bit1 = edrk.ms.ready1; + reply_a->digit_data.byte36.bit_data.bit2 = edrk.ms.ready2; + reply_a->digit_data.byte36.bit_data.bit3 = edrk.flag_wait_both_ready2; + reply_a->digit_data.byte36.bit_data.bit4 = edrk.Ready1_another_bs; + reply_a->digit_data.byte36.bit_data.bit5 = edrk.Ready2_another_bs; + reply_a->digit_data.byte36.bit_data.bit6 = edrk.flag_another_bs_first_ready12; + reply_a->digit_data.byte36.bit_data.bit7 = edrk.flag_this_bs_first_ready12; + + + + + reply_a->digit_data.byte37.byte_data = edrk.errors.e8.all & 0xff; + reply_a->digit_data.byte38.byte_data = (edrk.errors.e8.all >> 8) & 0xff; + + reply_a->digit_data.byte39.bit_data.bit0 = edrk.RazborNotFinish; + reply_a->digit_data.byte39.bit_data.bit1 = edrk.RunZahvatRascepitel; + reply_a->digit_data.byte39.bit_data.bit2 = edrk.RunUnZahvatRascepitel; + reply_a->digit_data.byte39.bit_data.bit3 = edrk.Run_Rascepitel; + reply_a->digit_data.byte39.bit_data.bit4 = edrk.ms.ready3; + + reply_a->digit_data.byte39.bit_data.bit5 = edrk.StartGEDfromZadanie; + reply_a->digit_data.byte39.bit_data.bit6 = edrk.flag_wait_set_to_zero_zadanie; + reply_a->digit_data.byte39.bit_data.bit7 = edrk.flag_block_zadanie; + reply_a->digit_data.byte40.bit_data.bit0 = edrk.you_can_on_rascepitel; + reply_a->digit_data.byte40.bit_data.bit1 = edrk.StartGEDfromControl; + reply_a->digit_data.byte40.bit_data.bit2 = edrk.StartGED; + reply_a->digit_data.byte40.bit_data.bit3 = edrk.GoWait; + + reply_a->digit_data.byte40.bit_data.bit4 = edrk.stop_logs_rs232; + reply_a->digit_data.byte40.bit_data.bit5 = edrk.stop_slow_log; + + reply_a->digit_data.byte40.bit_data.bit6 = edrk.disable_limit_power_from_svu; + reply_a->digit_data.byte40.bit_data.bit7 = edrk.disable_uom; + + reply_a->digit_data.byte41.byte_data = edrk.errors.e9.all & 0xff; + reply_a->digit_data.byte42.byte_data = (edrk.errors.e9.all >> 8) & 0xff; + + reply_a->digit_data.byte43.byte_data = edrk.errors.e10.all & 0xff; + reply_a->digit_data.byte44.byte_data = (edrk.errors.e10.all >> 8) & 0xff; + + reply_a->digit_data.byte45.byte_data = edrk.errors.e11.all & 0xff; + reply_a->digit_data.byte46.byte_data = (edrk.errors.e11.all >> 8) & 0xff; + + reply_a->digit_data.byte47.byte_data = edrk.errors.e12.all & 0xff; + reply_a->digit_data.byte48.byte_data = (edrk.errors.e12.all >> 8) & 0xff; + + +// reply_a->digit_data.byte49.byte_data = 0; +// reply_a->digit_data.byte50.byte_data = 0; + // reply_a->digit_data.byte49.byte_data = 0; + + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.ALL_KNOPKA_AVARIA; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.BLOCK_IZOL_AVARIA; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.BLOCK_IZOL_NORMA; + reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.LOCAL_REMOUTE; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.NAGREV_ON = !FROM_ING_NAGREV_ON; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.NASOS_NORMA = !FROM_ING_NASOS_NORMA; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.NASOS_ON = !FROM_ING_NASOS_ON; + // reply_a->digit_data.byte49.bit_data.bit0 = edrk.from_ing1.bits.OHLAD_UTE4KA_WATER = !FROM_ING_OHLAD_UTE4KA_WATER; + // edrk.from_ing1.bits.UPC_24V_NORMA = !FROM_ING_UPC_24V_NORMA; + //edrk.from_ing1.bits.OP_PIT_NORMA = !FROM_ING_OP_PIT_NORMA; + //edrk.from_ing1.bits.VENTIL_ON = !FROM_ING_VENTIL_ON; + // edrk.from_ing1.bits.VIPR_PREDOHR_NORMA = !FROM_ING_VIPR_PREDOHR_NORMA; + + // edrk.from_ing1.bits.ZARYAD_ON = !FROM_ING_ZARYAD_ON; + // edrk.from_ing1.bits.ZAZEML_OFF = !FROM_ING_ZAZEML_OFF; + // edrk.from_ing1.bits.ZAZEML_ON = !FROM_ING_ZAZEML_ON; + + reply_a->digit_data.byte49.bit_data.bit1 = edrk.from_ing2.bits.KEY_MINUS; + reply_a->digit_data.byte49.bit_data.bit2 = edrk.from_ing2.bits.KEY_PLUS; + reply_a->digit_data.byte49.bit_data.bit3 = edrk.from_ing2.bits.KEY_KVITIR; + + reply_a->digit_data.byte49.bit_data.bit4 = edrk.from_ing2.bits.KEY_SBOR; + reply_a->digit_data.byte49.bit_data.bit5 = edrk.from_ing2.bits.KEY_RAZBOR; + + // edrk.from_ing1.bits.RASCEPITEL_ON = FROM_ING_RASCEPITEL_ON_OFF; + + reply_a->digit_data.byte49.bit_data.bit6 = edrk.from_ing2.bits.SOST_ZAMKA; + reply_a->digit_data.byte49.bit_data.bit7 = edrk.from_shema_filter.bits.RAZBOR_SHEMA; + // + reply_a->digit_data.byte50.bit_data.bit0 = edrk.from_shema_filter.bits.SBOR_SHEMA; + + reply_a->digit_data.byte50.bit_data.bit1 = edrk.from_shema_filter.bits.ZADA_DISPLAY; + reply_a->digit_data.byte50.bit_data.bit2 = edrk.from_shema_filter.bits.SVU; + // edrk.from_shema.bits.KNOPKA_AVARIA = FROM_ALL_KNOPKA_AVARIA; + reply_a->digit_data.byte50.bit_data.bit3 = edrk.from_shema.bits.QTV_ON_OFF; + reply_a->digit_data.byte50.bit_data.bit4 = edrk.from_shema_filter.bits.UMP_ON_OFF; + reply_a->digit_data.byte50.bit_data.bit5 = edrk.from_shema_filter.bits.READY_UMP; + reply_a->digit_data.byte50.bit_data.bit6 = edrk.from_shema.bits.SVU_BLOCK_QTV; + reply_a->digit_data.byte50.bit_data.bit7 = edrk.errors_another_bs_from_can; + + + // reply_a->digit_data.byte44.byte_data = 0; + + + reply_a->digit_data.byte51.bit_data.bit0 = inc_sensor.break_sensor1; + reply_a->digit_data.byte51.bit_data.bit1 = inc_sensor.break_sensor2; + reply_a->digit_data.byte51.bit_data.bit2 = pll1.output.flag_find_pll; + reply_a->digit_data.byte51.bit_data.bit3 = log_params.stop_log_slow; + reply_a->digit_data.byte51.bit_data.bit4 = log_params.stop_log_level_1; + reply_a->digit_data.byte51.bit_data.bit5 = log_params.stop_log_level_2; + reply_a->digit_data.byte51.bit_data.bit6 = log_params.stop_log_slow_level_1; + reply_a->digit_data.byte51.bit_data.bit7 = log_params.stop_log_slow_level_2; + + + + reply_a->digit_data.byte52.bit_data.bit0 = edrk.from_zadat4ik.bits.KVITIR; + reply_a->digit_data.byte52.bit_data.bit1 = edrk.from_zadat4ik.bits.PLUS; + reply_a->digit_data.byte52.bit_data.bit2 = edrk.from_zadat4ik.bits.MINUS; + reply_a->digit_data.byte52.bit_data.bit3 = edrk.from_zadat4ik.bits.PROVOROT; + reply_a->digit_data.byte52.bit_data.bit4 = edrk.from_zadat4ik.bits.UOM_READY_ACTIVE; + reply_a->digit_data.byte52.bit_data.bit5 = edrk.from_zadat4ik.bits.UOM_LIMIT_3; + reply_a->digit_data.byte52.bit_data.bit6 = edrk.from_zadat4ik.bits.UOM_LIMIT_2; + reply_a->digit_data.byte52.bit_data.bit7 = edrk.from_zadat4ik.bits.UOM_LIMIT_1; + + + + reply_a->digit_data.byte53.bit_data.bit0 = edrk.Run_UMP; + reply_a->digit_data.byte53.bit_data.bit1 = edrk.Status_UMP_Ok; + reply_a->digit_data.byte53.bit_data.bit2 = edrk.Zaryad_UMP_Ok; + reply_a->digit_data.byte53.bit_data.bit3 = edrk.cmd_to_ump; + reply_a->digit_data.byte53.bit_data.bit4 = edrk.sbor_wait_ump1; + reply_a->digit_data.byte53.bit_data.bit5 = edrk.sbor_wait_ump2; + reply_a->digit_data.byte53.bit_data.bit6 = edrk.flag_enable_on_ump; + + reply_a->digit_data.byte53.bit_data.bit7 = edrk.local_ump_on_off; + reply_a->digit_data.byte54.bit_data.bit0 = edrk.local_ready_ump; + +/// + reply_a->digit_data.byte54.bit_data.bit1 = (modbus_table_can_in[128].all) ? 1 : 0; //cmd_local_charge PCH 0 + reply_a->digit_data.byte54.bit_data.bit2 = (modbus_table_can_in[131].all) ? 1 : 0; //cmd_local_uncharge PCH 0 + + reply_a->digit_data.byte54.bit_data.bit3 = (modbus_table_can_in[129].all) ? 1 : 0; //cmd_local_charge PCH 1 + reply_a->digit_data.byte54.bit_data.bit4 = (modbus_table_can_in[132].all) ? 1 : 0; //cmd_local_uncharge PCH 1 + + reply_a->digit_data.byte54.bit_data.bit5 = edrk.from_shema_filter.bits.UMP_ON_OFF; + reply_a->digit_data.byte54.bit_data.bit6 = edrk.SumSbor; + + reply_a->digit_data.byte55.bit_data.bit0 = edrk.power_limit.bits.limit_Iout; + reply_a->digit_data.byte55.bit_data.bit1 = edrk.power_limit.bits.limit_UOM; + reply_a->digit_data.byte55.bit_data.bit2 = edrk.power_limit.bits.limit_by_temper; + reply_a->digit_data.byte55.bit_data.bit3 = edrk.power_limit.bits.limit_from_SVU; + reply_a->digit_data.byte55.bit_data.bit4 = edrk.power_limit.bits.limit_from_uom_fast; + reply_a->digit_data.byte55.bit_data.bit5 = edrk.power_limit.bits.limit_from_freq; + reply_a->digit_data.byte55.bit_data.bit6 = edrk.power_limit.bits.limit_moment; + reply_a->digit_data.byte55.bit_data.bit7 = simple_scalar1.flag_decr_mzz_power; + + + reply_a->digit_data.byte56.bit_data.bit0 = (edrk.pult_cmd.log_what_memory & 0x1) ? 1 : 0; + reply_a->digit_data.byte56.bit_data.bit1 = (edrk.pult_cmd.log_what_memory & 0x2) ? 1 : 0; + + reply_a->digit_data.byte56.bit_data.bit2 = edrk.pult_data.flagSaveDataMoto ? 1 : 0; + + reply_a->digit_data.byte56.bit_data.bit3 = (edrk.pult_data.flagSaveSlowLogs) ? 1 : 0; + reply_a->digit_data.byte56.bit_data.bit4 = edrk.pult_cmd.send_log ? 1 : 0; + + reply_a->digit_data.byte56.bit_data.bit5 = (log_to_HMI.send_log==1) ? 1 : 0; + reply_a->digit_data.byte56.bit_data.bit6 = (log_to_HMI.send_log==2) ? 1 : 0; + reply_a->digit_data.byte56.bit_data.bit7 = (log_to_HMI.send_log==3) ? 1 : 0; + +// + reply_a->digit_data.byte57.bit_data.bit0 = (edrk.break_tempers[0] > ABNORMAL_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit1 = (edrk.break_tempers[1] > ABNORMAL_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit2 = (edrk.break_tempers[2] > ABNORMAL_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit3 = (edrk.break_tempers[3] > ABNORMAL_TEMPER_BREAK_INT) ? 1 : 0; + + reply_a->digit_data.byte57.bit_data.bit4 = (edrk.break_tempers[0] > ALARM_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit5 = (edrk.break_tempers[1] > ALARM_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit6 = (edrk.break_tempers[2] > ALARM_TEMPER_BREAK_INT) ? 1 : 0; + reply_a->digit_data.byte57.bit_data.bit7 = (edrk.break_tempers[3] > ALARM_TEMPER_BREAK_INT) ? 1 : 0; + + reply_a->digit_data.byte58.bit_data.bit0 = (edrk.breaker_on==1) ? 1 : 0; + + reply_a->digit_data.byte58.bit_data.bit1 = edrk.warnings.e9.bits.BREAK_TEMPER_WARNING; + reply_a->digit_data.byte58.bit_data.bit2 = edrk.warnings.e9.bits.BREAK_TEMPER_ALARM; + reply_a->digit_data.byte58.bit_data.bit3 = edrk.warnings.e9.bits.BREAKER_GED_ON; + + + +// reply_a->digit_data.byte57.byte_data = 0;//(((unsigned long)edrk.canes_reg>>16) & 0x0ff); +// reply_a->digit_data.byte58.byte_data = 0;//(((unsigned long)edrk.canes_reg) & 0x3f); + reply_a->digit_data.byte59.byte_data = 0;//(((unsigned long)edrk.canes_reg>>24) & 0x1); + reply_a->digit_data.byte60.byte_data = 0; + + + + + return; +} + + diff --git a/Inu/Src/main/message2.h b/Inu/Src/main/message2.h new file mode 100644 index 0000000..0f93c42 --- /dev/null +++ b/Inu/Src/main/message2.h @@ -0,0 +1,33 @@ +//////////////////////////////////////////// +// message.h +// +// ��������� ��������� �����: +// 1. ������������ ��������������y +// 2. �������������� ������������ +// 3. ������������ �������� �����y +// +// ������ ���� ����� ���� ����������� ��� +// ������y��� ��������� ��y ���������y �� ������ +// ����������. � ��������� �� INTEL 386SX Octagon +// � �� TMS320C32 Texas Instruments. +// �������� ������ ����� ���������������� ��������� +// ���������� ��������. +// � ������ ����� ��������� ��� ��y ������������ ������ +// unsigned char = 8 ��� +// �� TMS320C32 unsigned char = 32 ���, �� �����������y +// ������ ������� 8 ���. +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// ������ �������� ������� �������� �������� �� ������ +// ���������� � ����������� �� ������ �����������y +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//////////////////////////////////////////// + +#ifndef MESSAGE_H +#define MESSAGE_H + +#include "RS_Function_terminal.h" + +//void func_fill_answer_to_TMS(TMS_TO_TERMINAL_STRUCT* reply_ans, CMD_TO_TMS_STRUCT* pcommand); +void func_pack_answer_to_TMS(TMS_TO_TERMINAL_STRUCT* reply_a); +void func_unpack_answer_from_TMS_RS232(CMD_TO_TMS_STRUCT* pcommand); +#endif //MESSAGE_H diff --git a/Inu/Src/main/message2can.c b/Inu/Src/main/message2can.c new file mode 100644 index 0000000..5b0a883 --- /dev/null +++ b/Inu/Src/main/message2can.c @@ -0,0 +1,278 @@ +/* + * message2can.c + * + * Created on: 3 ���. 2020 �. + * Author: Yura + */ +#include <adc_tools.h> +#include <edrk_main.h> +#include <message2can.h> +#include <params.h> +#include <params_norma.h> +#include <v_rotor.h> +#include <vector.h> + +#include "control_station.h" +#include "CAN_Setup.h" +#include "global_time.h" +#include "IQmathLib.h" +#include "DSP281x_Device.h" +#include "x_basic_types.h" +#include "xp_cds_in.h" +#include "xp_hwp.h" +#include "xp_project.h" + + +void detecting_cmd_from_can(void) +{ + + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_CAN]) + { + func_unpack_answer_from_TMS_CAN((TERMINAL_UNITES_STRUCT_handle)&TerminalUnites[edrk.number_can_box_terminal_cmd][0]); + } + +} + + +void func_unpack_answer_from_TMS_CAN(TERMINAL_UNITES_STRUCT_handle unites_t) +{ + // ����������y ����� + unsigned int DataOut,h; + int Data, Data1, Data2, DataAnalog1, DataAnalog2, DataAnalog3, DataAnalog4,DataAnalog5,DataAnalog6, i; + unsigned char *pByte; + // static int vs11,vs12,vs1; + // static int DataCnt=0; + // int GoT,Assemble_scheme; + // static int prev_temp_Rele1=0, temp_Rele1=0, prev_temp_Rele2=0, temp_Rele2=0; + + static int flag_prev_turn_on = 0; + static int flag_prev_turn_off = 0; + static int prev_byte01_bit4 = 0; + static int prev_byte01_bit1 = 0; + static int flag_wait_revers_sbor = 1; + static int flag_wait_revers_go = 1; + + static unsigned int count_transmited = 0; + + + // + + if (TERMINAL_UNIT_LEN>CONTROL_STATION_MAX_RAW_DATA) + xerror(main_er_ID(2),(void *)0); + + + + // ���������� �� ������ � �����, �.�. � RS232 ������ ���� ������� + // pByte = (unsigned char *)(pcommand);//->analog_data.analog1_lo; + + for (h=0;h<TERMINAL_UNIT_LEN;h++) + { + control_station.raw_array_data[CONTROL_STATION_TERMINAL_CAN][h].all = unites_t->buf[h].all; + } + + /* + + if (control_station.alive_control_station[CONTROL_STATION_TERMINAL_CAN]==0) + { + edrk.from_can.bits.ACTIVE = 0; + return; + } + + if ((control_station.active_control_station[CONTROL_STATION_TERMINAL_RS232]==1)) + { + edrk.from_can.bits.ACTIVE = 0; + return; + } + + // unites_t->buf[0].bits.bit0 + + edrk.test_mode = 0; + + edrk.from_can.bits.ACTIVE = unites_t->buf[6].bits.bit3; + + if (edrk.from_can.bits.ACTIVE==0) + return; + +// f.RScount = SECOND * 3; + + // unites_t-> +// StartGED + + if (edrk.summ_errors) + { + flag_wait_revers_go = 1; + } + + if (flag_wait_revers_go==1) + edrk.StartGEDRS = 0; + if (unites_t->buf[6].bits.bit0 && flag_wait_revers_go) + edrk.StartGEDRS = 0; + if (unites_t->buf[6].bits.bit0==0) + edrk.StartGEDRS = 0; + if (unites_t->buf[6].bits.bit0==0 && flag_wait_revers_go) + flag_wait_revers_go = 0; + if (unites_t->buf[6].bits.bit0==1 && flag_wait_revers_go==0) + edrk.StartGEDRS = 1; + +// edrk.StartGEDRS = pcommand->digit_data.Byte01.bit_data.bit0; + +// end StartGED + + + edrk.Mode_UFConst = unites_t->buf[6].bits.bit2; + + +//////////////// + + if (unites_t->buf[6].bits.bit1 && prev_byte01_bit1==0) + edrk.KvitirRS = 1; + + prev_byte01_bit1 = unites_t->buf[6].bits.bit1; + + +// edrk.from_rs.bits.RAZBOR_SHEMA = pcommand->digit_data.Byte01.bit_data.bit5; + + + +// SBOR SHEMA + if (edrk.summ_errors) + { + flag_wait_revers_sbor = 1; + } + + if (flag_wait_revers_sbor==1) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (unites_t->buf[6].bits.bit4 && flag_wait_revers_sbor) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (unites_t->buf[6].bits.bit4==0) + edrk.from_can.bits.SBOR_SHEMA = 0; + + if (unites_t->buf[6].bits.bit4==0 && flag_wait_revers_sbor) + flag_wait_revers_sbor = 0; + + if (unites_t->buf[6].bits.bit4==1 && flag_wait_revers_sbor==0) + edrk.from_can.bits.SBOR_SHEMA = unites_t->buf[6].bits.bit4; + + prev_byte01_bit4 = unites_t->buf[6].bits.bit4; + +// end SBOR SHEMA + + + +// if (edrk.from_rs.bits.RAZBOR_SHEMA) + // edrk.from_rs.bits.SBOR_SHEMA = 0; + + //edrk.SborRS = pcommand->digit_data.Byte01.bit_data.bit4; + + + edrk.SelectPump0_1 = unites_t->buf[6].bits.bit6; + edrk.DirectOUT = unites_t->buf[6].bits.bit7; + + edrk.DirectNagrevOff = unites_t->buf[6].bits.bit8; + edrk.DirectBlockKeyOff = unites_t->buf[6].bits.bit9; + edrk.DirectPumpON = unites_t->buf[6].bits.bit10; + edrk.DirectZaryadOn = unites_t->buf[6].bits.bit11; + +#ifdef STENDD + + // edrk.to_shema.bits.QTV_ON = pcommand->digit_data.Byte02.bit_data.bit3; + +#endif + + edrk.Status_Ready.bits.ImitationReady2 = unites_t->buf[6].bits.bit12; + + edrk.SetSpeed = unites_t->buf[6].bits.bit13; + + + +// edrk.RemouteFromRS = pcommand->digit_data.Byte01.bit_data.bit3; + + + + +// edrk.VozbudOnOffFromRS = pcommand->digit_data.Byte01.bit_data.bit1; +// edrk.enable_set_vozbud = pcommand->digit_data.Byte01.bit_data.bit1; +// edrk.SborRS = pcommand->digit_data.Byte01.bit_data.bit2; +// edrk.RazborRS = pcommand->digit_data.Byte01.bit_data.bit3; +// edrk.DirectOUT = pcommand->digit_data.Byte01.bit_data.bit4; + +// edrk.StartGED = pcommand->digit_data.Byte01.bit_data.bit6; + + +// f.flag_distance = pcommand->digit_data.Byte01.bit_data.bit6; +// f.Set_power = pcommand->digit_data.Byte01.bit_data.bit7; + + f.Obmotka1 = unites_t->buf[6].bits.bit15; + f.Obmotka2 = unites_t->buf[7].bits.bit0; + + edrk.disable_alg_u_disbalance = unites_t->buf[7].bits.bit1; + + // f.Down50 = pcommand->digit_data.Byte02.bit_data.bit2; +// f.Up50 = pcommand->digit_data.Byte02.bit_data.bit3; +// f.Ciclelog = pcommand->digit_data.Byte02.bit_data.bit4; + + // if (SPEED_SELECT_ZADAT==1) +// f.Provorot = pcommand->digit_data.Byte02.bit_data.bit5; + + +// Data1 = pcommand->analog_data.analog1_hi; +// Data2 = pcommand->analog_data.analog1_lo; +// Data = (Data2 + Data1 * 256); +// if (Data > 32767) +// Data = Data - 65536; + DataAnalog1 = unites_t->buf[0].all; + +// Data1 = pcommand->analog_data.analog2_hi; +// Data2 = pcommand->analog_data.analog2_lo; +// Data = (Data2 + Data1 * 256); +// if (Data > 32767) +// Data = Data - 65536; + DataAnalog2 = unites_t->buf[1].all; + +// Data1 = pcommand->analog_data.analog3_hi; +// Data2 = pcommand->analog_data.analog3_lo; +// Data = (Data2 + Data1 * 256); +// if (Data > 32767) +// Data = Data - 65536; + DataAnalog3 = unites_t->buf[2].all; + +// Data1 = pcommand->analog_data.analog4_hi; +// Data2 = pcommand->analog_data.analog4_lo; +// Data = (Data2 + Data1 * 256); +// if (Data > 32767) +// Data = Data - 65536; + DataAnalog4 = unites_t->buf[3].all; + DataAnalog5 = unites_t->buf[4].all; + DataAnalog6 = unites_t->buf[5].all; + + + edrk.W_from_RS = DataAnalog1; + edrk.I_zad_vozb_add_from_RS = 0;//DataAnalog4; + + + if (!edrk.SetSpeed) + { + if (DataAnalog3<0) + edrk.ZadanieU_Charge_RS = 0; + else + edrk.ZadanieU_Charge_RS = DataAnalog3; + } + + if (edrk.SetSpeed) + { + edrk.fzad = DataAnalog1/100.0; + edrk.kzad = DataAnalog2/10000.0; + edrk.k_u_disbalance = _IQ(DataAnalog4/100.0); + edrk.kplus_u_disbalance = _IQ(DataAnalog3/1000.0); + + } +*/ + return; +} + + + + + diff --git a/Inu/Src/main/message2can.h b/Inu/Src/main/message2can.h new file mode 100644 index 0000000..14ad7da --- /dev/null +++ b/Inu/Src/main/message2can.h @@ -0,0 +1,18 @@ +/* + * message2can.h + * + * Created on: 3 ���. 2020 �. + * Author: Yura + */ + +#ifndef SRC_MAIN_MESSAGE2CAN_H_ +#define SRC_MAIN_MESSAGE2CAN_H_ + +#include "CAN_Setup.h" + +void func_unpack_answer_from_TMS_CAN(TERMINAL_UNITES_STRUCT_handle); +void detecting_cmd_from_can(void); + + + +#endif /* SRC_MAIN_MESSAGE2CAN_H_ */ diff --git a/Inu/Src/main/message2test.c b/Inu/Src/main/message2test.c new file mode 100644 index 0000000..fbcff9e --- /dev/null +++ b/Inu/Src/main/message2test.c @@ -0,0 +1,678 @@ +#include <adc_tools.h> +#include <edrk_main.h> +#include <message2test.h> +#include <params.h> +#include <sync_tools.h> +#include <tk_Test.h> +#include <vector.h> + +#include "CAN_Setup.h" +#include "IQmathLib.h" +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "RS_Functions.h" +#include "xp_project.h" + +#include "x_wdog.h" +#include "params_hwp.h" +#include "detect_errors.h" + + +//XilinxV2 + + +void func_fill_answer_to_TMS_test(TMS_TO_TERMINAL_TEST_ALL_STRUCT* reply_ans, CMD_TO_TMS_TEST_ALL_STRUCT* pcommand) +{ + // ���������y ����� + unsigned int crc, DataOut, sinusImpulse, doubleImpulse,adc_plate; + int Data,Data1,Data2/*,bitt, DataAnalog1, DataAnalog2*/, tk0,tk1,tk2,tk3,period1,period2, period3; + + //static int vs11,vs12,vs1; + static int prev_Go = 0; + static int prev_Prepare = 0; + + static int flag_prev_turn_on = 0; + static int flag_prev_turn_off = 0; + static int flag_prev_lamp_on_off = 0; + static int soft_off_enable = 0, soft_on_enable = 0; + static float tk_time_soft_off = 0; + static unsigned long tk_time_soft_off_d = 0; + static unsigned int i_af_protect_a = 0, i_af_protect_d = 0; + int enable_line_err = 0, disable_tk_soft_off, disable_protect_tk_soft_off; + + + stop_wdog(); + + edrk.test_mode = 1; + // const ��������� �� ��������� ����������� ������� + // ��������� �� ����� ������ + +// TMS_TO_TERMINAL_TEST_ALL_STRUCT* const pcommand = ((TMS_TO_TERMINAL_TEST_ALL_STRUCT*)reply); + + // -�������� ���y ������� + // ?�� ��� ���� ������� ���� + +// f.RScount = SECOND*3; + + f.terminal_prepare = pcommand->digit_data.byte05.bit_data.bit1; + soft_off_enable = pcommand->digit_data.byte06.bit_data.bit0; + soft_on_enable = pcommand->digit_data.byte06.bit_data.bit1; +// edrk.direct_write_out = pcommand->digit_data.byte06.bit_data.bit2; + + disable_tk_soft_off = pcommand->digit_data.byte06.bit_data.bit3; + disable_protect_tk_soft_off = pcommand->digit_data.byte06.bit_data.bit4; + + enable_line_err = pcommand->digit_data.byte06.bit_data.bit5; + + // �������� ��� ������ + +#if (CHECK_IN_OUT_TERMINAL==1) + +#if(C_cds_out_number>=1) + project.cds_out[0].write.sbus.data_out.all = ~(pcommand->digit_data.byte07.byte_data | ((pcommand->digit_data.byte08.byte_data) << 8)); +#endif +#if(C_cds_out_number>=2) + project.cds_out[1].write.sbus.data_out.all = ~(pcommand->digit_data.byte09.byte_data | ((pcommand->digit_data.byte10.byte_data) << 8)); +#endif +#if(C_cds_out_number>=3) + project.cds_out[2].write.sbus.data_out.all = ~(pcommand->digit_data.byte11.byte_data | ((pcommand->digit_data.byte12.byte_data) << 8)); +#endif + +#endif //CHECK_IN_OUT + + if (pcommand->digit_data.byte05.bit_data.bit1 == 1) + { + + //xreset_error_all(); + } + + + +// write_dig_out(); + + //calc_norm_ADC(0); + calc_norm_ADC_0(1); + calc_norm_ADC_1(1); + + // �������� ������ + tk0 = (pcommand->digit_data.byte01.byte_data); + tk1 = (pcommand->digit_data.byte02.byte_data); + tk2 = (pcommand->digit_data.byte03.byte_data); + tk3 = (pcommand->digit_data.byte04.byte_data); + + Data1 = pcommand->analog_data.analog1_hi; + Data2 = pcommand->analog_data.analog1_lo; + Data = (Data2 + Data1*256); + period1 = Data; + + Data1 = pcommand->analog_data.analog2_hi; + Data2 = pcommand->analog_data.analog2_lo; + Data = (Data2 + Data1*256); + period2 = Data; + + Data1 = pcommand->analog_data.analog3_hi; + Data2 = pcommand->analog_data.analog3_lo; + Data = (Data2 + Data1*256); + period3 = Data; + + Data1 = pcommand->analog_data.analog4_hi; + Data2 = pcommand->analog_data.analog4_lo; + Data = (Data2 + Data1*256); + // Data = 200; + tk_time_soft_off = Data*100.0; // mks*10->ns + if (tk_time_soft_off>1300000.0) + tk_time_soft_off = 1300000.0; + tk_time_soft_off_d = (unsigned long)(tk_time_soft_off / DIV_TIME_TK_SOFT_OFF); + + if (tk_time_soft_off_d>65535) + tk_time_soft_off_d = 65535; + + + Data1 = pcommand->analog_data.analog5_hi; + Data2 = pcommand->analog_data.analog5_lo; + Data = (Data2 + Data1*256); + i_af_protect_a = Data; + + if (i_af_protect_a>LEVEL_HWP_I_AF) i_af_protect_a = LEVEL_HWP_I_AF; + if (i_af_protect_a<10) i_af_protect_a = 10; + i_af_protect_d = convert_real_to_mv_hwp(4,i_af_protect_a); + if (i_af_protect_d>1500) i_af_protect_d = 1500; // max 1500 mV + + update_maz_level_i_af(0, i_af_protect_d); + project.read_all_hwp(); + + + + if(pcommand->digit_data.byte05.bit_data.bit3 == 1) + doubleImpulse = 1; + else + doubleImpulse = 0; + + if(pcommand->digit_data.byte05.bit_data.bit5 == 1) + sinusImpulse = 1; + else + sinusImpulse = 0; + + if ((pcommand->digit_data.byte05.bit_data.bit0 == 1) && (prev_Go == 0)) + { + if (pcommand->digit_data.byte05.bit_data.bit2 == 1) // ��� ���� �������� �������������� ���� ������������ + { + update_maz_level_i_af(0, 1500); + project.write_all_hwp(); + clear_errors(); + project.clear_errors_all_plates(); + update_maz_level_i_af(0, i_af_protect_d); + project.write_all_hwp(); + + } + + +// test_tk_ak_one_impulse( tk0, tk1, tk2, tk3, period1, period2); +#if (USE_TK_0) + project.cds_tk[0].write.sbus.protect_error.bit.enable_soft_disconnect = !disable_tk_soft_off; + project.cds_tk[0].write.sbus.protect_error.bit.detect_soft_disconnect = !disable_protect_tk_soft_off; + project.cds_tk[0].write.sbus.protect_error.bit.enable_line_err = enable_line_err; + project.cds_tk[0].write.sbus.time_after_err = tk_time_soft_off_d;//(int)(tk_time_soft_off / DIV_TIME_TK_SOFT_OFF); +#endif +#if (USE_TK_1) + project.cds_tk[1].write.sbus.protect_error.bit.enable_soft_disconnect = !disable_tk_soft_off; + project.cds_tk[1].write.sbus.protect_error.bit.detect_soft_disconnect = !disable_protect_tk_soft_off; + project.cds_tk[1].write.sbus.protect_error.bit.enable_line_err = enable_line_err; + project.cds_tk[1].write.sbus.time_after_err = tk_time_soft_off_d;//(int)(tk_time_soft_off / DIV_TIME_TK_SOFT_OFF); +#endif +#if (USE_TK_3) + project.cds_tk[3].write.sbus.protect_error.bit.enable_soft_disconnect = !disable_tk_soft_off; + project.cds_tk[3].write.sbus.protect_error.bit.detect_soft_disconnect = !disable_protect_tk_soft_off; + project.cds_tk[3].write.sbus.protect_error.bit.enable_line_err = enable_line_err; + project.cds_tk[3].write.sbus.time_after_err = tk_time_soft_off_d;//(int)(tk_time_soft_off / DIV_TIME_TK_SOFT_OFF); +#endif + + + project.write_all_sbus(); + project.write_all_hwp(); + + test_tk_ak_one_impulse( tk0, tk1, tk2, tk3, period1, period2, period3, doubleImpulse, sinusImpulse, soft_off_enable, soft_on_enable); + } + + if ((pcommand->digit_data.byte05.bit_data.bit0 == 1) && + (pcommand->digit_data.byte05.bit_data.bit3 == 1) && (prev_Go == 0)) + { +// test_tk_ak_sinus_period( tk0, tk1, tk2, tk3, period1, period2); + } + prev_Go = pcommand->digit_data.byte05.bit_data.bit0; + + f.Prepare = pcommand->digit_data.byte05.bit_data.bit1; + if (pcommand->digit_data.byte05.bit_data.bit1 != prev_Prepare) + { + if (pcommand->digit_data.byte05.bit_data.bit1==1) + { + stop_wdog(); + update_maz_level_i_af(0, 1500); + project.write_all_hwp(); + clear_errors(); + project.clear_errors_all_plates(); + update_maz_level_i_af(0, i_af_protect_d); + project.write_all_hwp(); + } + } + prev_Prepare = pcommand->digit_data.byte05.bit_data.bit1; + + if (pcommand->digit_data.byte05.bit_data.bit2 == 1) + { + + prev_Go = 0; // ��������� Go + } + +// break_all_on_off(pcommand->digit_data.byte05.bit_data.bit5); + +/* + if (pcommand->digit_data.byte05.bit_data.bit5 != flag_prev_turn_off) //turn off + { + if(pcommand->digit_data.byte05.bit_data.bit5 == 1) + { + project.cds_out[0].fpga.Write.Dout.bit.dout2 = 1; + project.cds_out[0].fpga.Write.Dout.bit.dout12 = 1; + cds_out_all(cds_out_WriteAll); + pause_1000(100000); + pause_1000(100000); + pause_1000(100000); + pause_1000(100000); + project.cds_out[0].fpga.Write.Dout.bit.dout2 = 0; + project.cds_out[0].fpga.Write.Dout.bit.dout12 = 0; + cds_out_all(cds_out_WriteAll); + //f.Ready2 = 0; + f.On_Power_QTV = 0; + edrk.Go = 0; + + } + + flag_prev_turn_off = pcommand->digit_data.byte05.bit_data.bit5; + cds_out_all(cds_out_WriteAll); + + } + if ((pcommand->digit_data.byte05.bit_data.bit6 != flag_prev_turn_on) && !f.Stop && +// ((filter.iqU_1_long > 11184810) || (filter.iqU_3_long > 11184810))) //turn_on + ((filter.iqU_1_long > 5590240) || (filter.iqU_3_long > 5590240))) + { + if(pcommand->digit_data.byte05.bit_data.bit6 == 1) + { + project.cds_out[0].fpga.Write.Dout.bit.dout7 = 0; + cds_out_all(cds_out_WriteAll); + pause_1000(100000); + pause_1000(100000); + pause_1000(100000); + pause_1000(100000); + pause_1000(100000); + project.cds_out[0].fpga.Write.Dout.bit.dout7 = 1; + cds_out_all(cds_out_WriteAll); + //f.Ready2 = 1; + f.On_Power_QTV = 1; + } + + flag_prev_turn_on = pcommand->digit_data.byte05.bit_data.bit6; + cds_out_all(cds_out_WriteAll); + + } + if(project.cds_in[1].fpga.input_new.ChanalsPtr.ChanalPtr[7].rd_status != flag_prev_lamp_on_off) //turnig on lamp when power is on + { + if(project.cds_in[1].fpga.input_new.ChanalsPtr.ChanalPtr[7].rd_status == 1) + { + project.cds_out[1].fpga.Write.Dout.bit.dout1 = 0; + cds_out_all(cds_out_WriteAll); + } + else + { + project.cds_out[1].fpga.Write.Dout.bit.dout1 = 1; + cds_out_all(cds_out_WriteAll); + } + flag_prev_lamp_on_off = project.cds_in[1].fpga.input_new.ChanalsPtr.ChanalPtr[7].rd_status; + } + + +*/ + +// run_break = pcommand->digit_data.byte05.bit_data.bit4; + + + if (pcommand->digit_data.byte05.bit_data.bit4 == 1) + { + adc_plate = 1; + + } + else + adc_plate = 0; + + if (pcommand->digit_data.byte05.bit_data.bit6 == 1) + i_sync_pin_on(); + else + i_sync_pin_off(); + + + + Data = project.adc[adc_plate].read.pbus.adc_value[0];//InternalADC[0];//0;//ADC_sf[0];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog1_lo=LOBYTE(Data); + reply_test_all.analog_data.analog1_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[1];// InternalADC[1];//0;//ADC_sf[1];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog2_lo=LOBYTE(Data); + reply_test_all.analog_data.analog2_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[2];// InternalADC[2];//0;//ADC_sf[2];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog3_lo=LOBYTE(Data); + reply_test_all.analog_data.analog3_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[3];// InternalADC[3];//0;//ADC_sf[3];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog4_lo=LOBYTE(Data); + reply_test_all.analog_data.analog4_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[4];// InternalADC[4];//0;//ADC_sf[4];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog5_lo=LOBYTE(Data); + reply_test_all.analog_data.analog5_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[5];// InternalADC[5];//0;//ADC_sf[5];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog6_lo=LOBYTE(Data); + reply_test_all.analog_data.analog6_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[6];// InternalADC[6];//0;//ADC_sf[6];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog7_lo=LOBYTE(Data); + reply_test_all.analog_data.analog7_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[7];//InternalADC[7];//0;//ADC_sf[7];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog8_lo=LOBYTE(Data); + reply_test_all.analog_data.analog8_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[8];//InternalADC[8];//0;//ADC_sf[8];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog9_lo=LOBYTE(Data); + reply_test_all.analog_data.analog9_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[9];//InternalADC[9];//0;//ADC_sf[9];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog10_lo=LOBYTE(Data); + reply_test_all.analog_data.analog10_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[10];//InternalADC[10];//0;//ADC_sf[10];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog11_lo=LOBYTE(Data); + reply_test_all.analog_data.analog11_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[11];//InternalADC[11];//0;//ADC_sf[11];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog12_lo=LOBYTE(Data); + reply_test_all.analog_data.analog12_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[12];//InternalADC[12];//0;//ADC_sf[12];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog13_lo=LOBYTE(Data); + reply_test_all.analog_data.analog13_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[13];//InternalADC[13];//0;//ADC_sf[13];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog14_lo=LOBYTE(Data); + reply_test_all.analog_data.analog14_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[14];//InternalADC[14];//0;//ADC_sf[14];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog15_lo=LOBYTE(Data); + reply_test_all.analog_data.analog15_hi=HIBYTE(Data); + + Data = project.adc[adc_plate].read.pbus.adc_value[15];//InternalADC[15];//0;//ADC_sf[15];//_IQtoF(analog.iqIa1_1_fir_n)*2000.0;// + reply_test_all.analog_data.analog16_lo=LOBYTE(Data); + reply_test_all.analog_data.analog16_hi=HIBYTE(Data); + + + Data = _IQtoF(analog.iqU_1) * NORMA_ACP; + reply_ans->analog_data.analog17_lo=LOBYTE(Data); + reply_ans->analog_data.analog17_hi=HIBYTE(Data); + + Data = _IQtoF(analog.iqU_2) * NORMA_ACP; + reply_ans->analog_data.analog18_lo=LOBYTE(Data); + reply_ans->analog_data.analog18_hi=HIBYTE(Data); + + Data = project.cds_tk[0].read.sbus.time_err_tk_all.bit.tk_3210; + reply_ans->analog_data.analog19_lo=LOBYTE(Data); + reply_ans->analog_data.analog19_hi=HIBYTE(Data); + + Data = project.cds_tk[0].read.sbus.time_err_tk_all.bit.tk_7654; + reply_ans->analog_data.analog20_lo=LOBYTE(Data); + reply_ans->analog_data.analog20_hi=HIBYTE(Data); + + Data = project.cds_tk[1].read.sbus.time_err_tk_all.bit.tk_3210; + reply_ans->analog_data.analog21_lo=LOBYTE(Data); + reply_ans->analog_data.analog21_hi=HIBYTE(Data); + + Data = project.cds_tk[1].read.sbus.time_err_tk_all.bit.tk_7654; + reply_ans->analog_data.analog22_lo=LOBYTE(Data); + reply_ans->analog_data.analog22_hi=HIBYTE(Data); + + Data = project.cds_tk[2].read.sbus.time_err_tk_all.bit.tk_3210; + reply_ans->analog_data.analog23_lo=LOBYTE(Data); + reply_ans->analog_data.analog23_hi=HIBYTE(Data); + + Data = project.cds_tk[2].read.sbus.time_err_tk_all.bit.tk_7654; + reply_ans->analog_data.analog24_lo=LOBYTE(Data); + reply_ans->analog_data.analog24_hi=HIBYTE(Data); + +// Data = project.cds_tk[3].read.sbus.time_err_tk_all.bit.tk_3210; +// reply_ans->analog_data.analog25_lo=LOBYTE(Data); +// reply_ans->analog_data.analog25_hi=HIBYTE(Data); +// +// Data = project.cds_tk[3].read.sbus.time_err_tk_all.bit.tk_7654; +// reply_ans->analog_data.analog26_lo=LOBYTE(Data); +// reply_ans->analog_data.analog26_hi=HIBYTE(Data); + +reply_ans->digit_data.byte01.byte_data = 0; +reply_ans->digit_data.byte02.byte_data = 0; +reply_ans->digit_data.byte03.byte_data = 0; +reply_ans->digit_data.byte04.byte_data = 0; +reply_ans->digit_data.byte05.byte_data = 0; +reply_ans->digit_data.byte06.byte_data = 0; +reply_ans->digit_data.byte07.byte_data = 0; +reply_ans->digit_data.byte08.byte_data = 0; +reply_ans->digit_data.byte09.byte_data = 0; +reply_ans->digit_data.byte10.byte_data = 0; +reply_ans->digit_data.byte11.byte_data = 0; +reply_ans->digit_data.byte12.byte_data = 0; +reply_ans->digit_data.byte13.byte_data = 0; +reply_ans->digit_data.byte14.byte_data = 0; +reply_ans->digit_data.byte15.byte_data = 0; +reply_ans->digit_data.byte16.byte_data = 0; +reply_ans->digit_data.byte17.byte_data = 0; +reply_ans->digit_data.byte18.byte_data = 0; +reply_ans->digit_data.byte19.byte_data = 0; +reply_ans->digit_data.byte20.byte_data = 0; +reply_ans->digit_data.byte21.byte_data = 0; +reply_ans->digit_data.byte22.byte_data = 0; +reply_ans->digit_data.byte23.byte_data = 0; +reply_ans->digit_data.byte24.byte_data = 0; + + + reply_ans->digit_data.byte01.bit_data.bit0 = project.cds_tk[0].read.sbus.current_status_error.bit.err0_local; + reply_ans->digit_data.byte01.bit_data.bit1 = project.cds_tk[1].read.sbus.current_status_error.bit.err0_local; + reply_ans->digit_data.byte01.bit_data.bit2 = project.cds_tk[2].read.sbus.current_status_error.bit.err0_local; + reply_ans->digit_data.byte01.bit_data.bit3 = project.cds_tk[3].read.sbus.current_status_error.bit.err0_local; + + reply_ans->digit_data.byte01.bit_data.bit4 = project.cds_tk[0].read.sbus.current_status_error.bit.err_power; + reply_ans->digit_data.byte01.bit_data.bit5 = project.cds_tk[1].read.sbus.current_status_error.bit.err_power; + reply_ans->digit_data.byte01.bit_data.bit6 = project.cds_tk[2].read.sbus.current_status_error.bit.err_power; + reply_ans->digit_data.byte01.bit_data.bit7 = project.cds_tk[3].read.sbus.current_status_error.bit.err_power; + + reply_ans->digit_data.byte02.bit_data.bit0 = project.cds_in[0].read.sbus.current_status_error.bit.err_power; + reply_ans->digit_data.byte02.bit_data.bit1 = project.cds_in[1].read.sbus.current_status_error.bit.err_power; +#if(C_cds_in_number>=3) + reply_ans->digit_data.byte02.bit_data.bit2 = project.cds_in[2].read.sbus.current_status_error.bit.err_power; +#endif + reply_ans->digit_data.byte02.bit_data.bit3 = project.cds_out[0].read.sbus.current_status_error.bit.err_power; + + reply_ans->digit_data.byte02.bit_data.bit4 = project.cds_out[1].read.sbus.current_status_error.bit.err_power; + reply_ans->digit_data.byte02.bit_data.bit5 = 0; + reply_ans->digit_data.byte02.bit_data.bit6 = project.cds_tk[0].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte02.bit_data.bit7 = project.cds_tk[1].read.sbus.current_status_error.bit.err_switch; + + reply_ans->digit_data.byte03.bit_data.bit0 = project.cds_tk[2].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte03.bit_data.bit1 = project.cds_tk[3].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte03.bit_data.bit2 = project.cds_in[0].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte03.bit_data.bit3 = project.cds_in[1].read.sbus.current_status_error.bit.err_switch; + + +#if(C_cds_in_number>=3) + reply_ans->digit_data.byte03.bit_data.bit4 = project.cds_in[2].read.sbus.current_status_error.bit.err_switch; +#endif + reply_ans->digit_data.byte03.bit_data.bit5 = project.cds_out[0].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte03.bit_data.bit6 = project.cds_out[1].read.sbus.current_status_error.bit.err_switch; + reply_ans->digit_data.byte03.bit_data.bit7 = 0; + + //TK0 acknolege-current + reply_ans->digit_data.byte04.byte_data = project.cds_tk[0].read.sbus.status_protect_current_ack.all & 0xFF; + reply_ans->digit_data.byte05.byte_data = (project.cds_tk[0].read.sbus.status_protect_current_ack.all >> 8) & 0xFF; + + //TK1 acknolege-current + reply_ans->digit_data.byte06.byte_data = project.cds_tk[1].read.sbus.status_protect_current_ack.all & 0xFF; + reply_ans->digit_data.byte07.byte_data = (project.cds_tk[1].read.sbus.status_protect_current_ack.all >> 8) & 0xFF; + + //TK2 acknolege-current + reply_ans->digit_data.byte08.byte_data = project.cds_tk[2].read.sbus.status_protect_current_ack.all & 0xFF; + reply_ans->digit_data.byte09.byte_data = (project.cds_tk[2].read.sbus.status_protect_current_ack.all >> 8) & 0xFF; + + //TK3 acknolege-current + reply_ans->digit_data.byte10.byte_data = project.cds_tk[3].read.sbus.status_protect_current_ack.all & 0xFF; + reply_ans->digit_data.byte11.byte_data = (project.cds_tk[3].read.sbus.status_protect_current_ack.all >> 8) & 0xFF; + + +//IN1 + reply_ans->digit_data.byte13.byte_data = project.cds_in[0].read.pbus.data_in.all & 0xFF; + reply_ans->digit_data.byte14.byte_data = (project.cds_in[0].read.pbus.data_in.all >> 8) & 0xFF; + +//IN2 + reply_ans->digit_data.byte15.byte_data = project.cds_in[1].read.pbus.data_in.all & 0xFF; + reply_ans->digit_data.byte16.byte_data = (project.cds_in[1].read.pbus.data_in.all >> 8) & 0xFF; + +//IN3 +#if(C_cds_in_number>=3) + reply_ans->digit_data.byte17.byte_data = project.cds_in[2].read.pbus.data_in.all & 0xFF; + reply_ans->digit_data.byte18.byte_data = (project.cds_in[2].read.pbus.data_in.all >> 8) & 0xFF; +#endif + + reply_ans->digit_data.byte19.bit_data.bit0 = get_status_sync_line();//CAN_timeout[UKSS1_CAN_DEVICE]; + //reply.digit_data.byte21.bit_data.bit1 = CAN_timeout[UKSS4_CAN_DEVICE]; + reply_ans->digit_data.byte19.bit_data.bit2 = 0;// CAN_timeout[UKSS2_CAN_DEVICE]; + reply_ans->digit_data.byte19.bit_data.bit3 = 0;// CAN_timeout[UKSS3_CAN_DEVICE]; + reply_ans->digit_data.byte19.bit_data.bit4 = CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,ZADATCHIK_CAN)]; + //reply_test_all.digit_data.byte19.bit_data.bit5 = CAN_timeout[VPU2_CAN_DEVICE]; + reply_ans->digit_data.byte19.bit_data.bit6 = CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,UMU_CAN_DEVICE)]; + //reply.digit_data.byte21.bit_data.bit7 = CAN_timeout[VPU1_CAN_DEVICE]; + + reply_ans->digit_data.byte20.bit_data.bit0 = project.controller.read.errors.bit.er0_out; + reply_ans->digit_data.byte20.bit_data.bit1 = project.controller.read.errors.bit.er0_trig; + reply_ans->digit_data.byte20.bit_data.bit2 = project.controller.read.errors.bit.errHWP; + reply_ans->digit_data.byte20.bit_data.bit3 = project.controller.read.errors.bit.errHWP_trig; + reply_ans->digit_data.byte20.bit_data.bit4 = project.controller.read.errors.bit.error_pbus; + reply_ans->digit_data.byte20.bit_data.bit5 = project.controller.read.errors.bit.pwm_wdog; + reply_ans->digit_data.byte20.bit_data.bit6 = project.controller.read.errors.bit.status_er0; +// reply_ans->digit_data.byte20.bit_data.bit0 = project.controller.read.errors.bit.er0_out; +// reply_ans->digit_data.byte20.bit_data.bit0 = CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,VPU_CAN)]; +// reply_ans->digit_data.byte20.bit_data.bit1 = CAN_timeout[get_real_in_mbox(MPU_TYPE_BOX,0)]; + reply_ans->digit_data.byte20.bit_data.bit2 = 0;//READY_UKSS_6; + reply_ans->digit_data.byte20.bit_data.bit3 = 0;//READY_UKSS_7; + reply_ans->digit_data.byte20.bit_data.bit4 = 0;//READY_UKSS_8; + //reply_test_all.digit_data.byte20.bit_data.bit5 = READY_UKSS_1; + //reply_test_all.digit_data.byte20.bit_data.bit6 = READY_UKSS_2; + //reply_test_all.digit_data.byte20.bit_data.bit7 = READY_UKSS_3; + + + + reply_ans->digit_data.byte21.bit_data.bit0 = !project.hwp[0].status;//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; + reply_ans->digit_data.byte21.bit_data.bit2 = !project.adc[0].status;//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; +#if(C_cds_in_number>=1) + reply_ans->digit_data.byte21.bit_data.bit3 = !project.cds_in[0].status;//XProject_balzam.IsReady_reg.bit.XPlaneIN0_IsReady; +#endif +#if(C_cds_in_number>=2) + reply_ans->digit_data.byte21.bit_data.bit4 = !project.cds_in[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneIN1_IsReady; +#endif +#if(C_cds_in_number>=3) + reply_ans->digit_data.byte21.bit_data.bit5 = !project.cds_in[2].status;//XProject_balzam.IsReady_reg.bit.XPlaneIN2_IsReady; +#endif + +#if(C_cds_out_number>=1) + reply_ans->digit_data.byte21.bit_data.bit6 = !project.cds_out[0].status;//XProject_balzam.IsReady_reg.bit.XPlaneOUT0_IsReady; +#endif +#if(C_cds_out_number>=2) + reply_ans->digit_data.byte21.bit_data.bit7 = !project.cds_out[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneOUT1_IsReady; +#endif +#if(C_cds_out_number>=3) + reply_ans->digit_data.byte22.bit_data.bit0 = !project.cds_out[2].status;//XProject_balzam.IsReady_reg.bit.XPlaneOUT2_IsReady; +#endif + + + reply_ans->digit_data.byte22.bit_data.bit1 = !project.cds_tk[0].status;//XProject_balzam.IsReady_reg.bit.XPlaneTK0_IsReady; + reply_ans->digit_data.byte22.bit_data.bit2 = !project.cds_tk[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneTK1_IsReady; + reply_ans->digit_data.byte22.bit_data.bit3 = !project.cds_tk[2].status;//XProject_balzam.IsReady_reg.bit.XPlaneTK2_IsReady; + reply_ans->digit_data.byte22.bit_data.bit4 = !project.cds_tk[3].status;//!XProject_balzam.IsReady_reg.bit.XPlaneTK3_IsReady; + reply_ans->digit_data.byte22.bit_data.bit5 = !project.adc[1].status;//XProject_balzam.IsReady_reg.bit.XPlaneHWP_Chanals_IsReady; + + reply_ans->digit_data.byte23.byte_data=project.hwp[0].read.comp_s.minus.all & 0x00ff; + reply_ans->digit_data.byte24.byte_data=((project.hwp[0].read.comp_s.minus.all >> 8) & 0x00ff); + + reply_ans->digit_data.byte23.byte_data|=project.hwp[0].read.comp_s.plus.all & 0x00ff; + reply_ans->digit_data.byte24.byte_data|=((project.hwp[0].read.comp_s.plus.all >> 8) & 0x00ff); + +#if (USE_TK_0) + if (project.cds_tk[0].useit) + { +// reply_ans->digit_data.byte22.bit_data.bit0 = project.cds_tk[0].read.sbus.lock_status_error.bit.err0_in; + reply_ans->digit_data.byte25.bit_data.bit0 = project.cds_tk[0].read.sbus.lock_status_error.bit.err_hwp; + reply_ans->digit_data.byte25.bit_data.bit1 = project.cds_tk[0].read.sbus.lock_status_error.bit.err0_local; + reply_ans->digit_data.byte25.bit_data.bit2 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + reply_ans->digit_data.byte25.bit_data.bit3 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + reply_ans->digit_data.byte25.bit_data.bit4 = project.cds_tk[0].read.sbus.lock_status_error.bit.line_err_keys_7654; + reply_ans->digit_data.byte25.bit_data.bit5 = project.cds_tk[0].read.sbus.lock_status_error.bit.line_err_keys_3210; + reply_ans->digit_data.byte25.bit_data.bit6 = project.cds_tk[0].read.sbus.lock_status_error.bit.ErrorSoftShutdownFromErr0; + reply_ans->digit_data.byte25.bit_data.bit7 = project.cds_tk[0].read.sbus.lock_status_error.bit.ErrorSoftShutdownForbidComb; + } + else + reply_ans->digit_data.byte25.byte_data = 0; + +#else + reply_ans->digit_data.byte25.byte_data = 0; +#endif + +#if (USE_TK_1) + if (project.cds_tk[1].useit) + { + reply_ans->digit_data.byte26.bit_data.bit0 = project.cds_tk[1].read.sbus.lock_status_error.bit.err_hwp; + reply_ans->digit_data.byte26.bit_data.bit1 = project.cds_tk[1].read.sbus.lock_status_error.bit.err0_local; + reply_ans->digit_data.byte26.bit_data.bit2 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + reply_ans->digit_data.byte26.bit_data.bit3 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + reply_ans->digit_data.byte26.bit_data.bit4 = project.cds_tk[1].read.sbus.lock_status_error.bit.line_err_keys_7654; + reply_ans->digit_data.byte26.bit_data.bit5 = project.cds_tk[1].read.sbus.lock_status_error.bit.line_err_keys_3210; + reply_ans->digit_data.byte26.bit_data.bit6 = project.cds_tk[1].read.sbus.lock_status_error.bit.ErrorSoftShutdownFromErr0; + reply_ans->digit_data.byte26.bit_data.bit7 = project.cds_tk[1].read.sbus.lock_status_error.bit.ErrorSoftShutdownForbidComb; + } + else + reply_ans->digit_data.byte26.byte_data = 0; +#else + reply_ans->digit_data.byte26.byte_data = 0; +#endif + +#if (USE_TK_2) + if (project.cds_tk[2].useit) + { + reply_ans->digit_data.byte27.bit_data.bit0 = project.cds_tk[2].read.sbus.lock_status_error.bit.err_hwp; + reply_ans->digit_data.byte27.bit_data.bit1 = project.cds_tk[2].read.sbus.lock_status_error.bit.err0_local; + reply_ans->digit_data.byte27.bit_data.bit2 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + reply_ans->digit_data.byte27.bit_data.bit3 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + reply_ans->digit_data.byte27.bit_data.bit4 = project.cds_tk[2].read.sbus.lock_status_error.bit.line_err_keys_7654; + reply_ans->digit_data.byte27.bit_data.bit5 = project.cds_tk[2].read.sbus.lock_status_error.bit.line_err_keys_3210; + reply_ans->digit_data.byte27.bit_data.bit6 = project.cds_tk[2].read.sbus.lock_status_error.bit.ErrorSoftShutdownFromErr0; + reply_ans->digit_data.byte27.bit_data.bit7 = project.cds_tk[2].read.sbus.lock_status_error.bit.ErrorSoftShutdownForbidComb; + } + else + reply_ans->digit_data.byte27.byte_data = 0; +#else + reply_ans->digit_data.byte27.byte_data = 0; +#endif + +#if (USE_TK_3) + if (project.cds_tk[3].useit) + { + reply_ans->digit_data.byte28.bit_data.bit0 = project.cds_tk[3].read.sbus.lock_status_error.bit.err_hwp; + reply_ans->digit_data.byte28.bit_data.bit1 = project.cds_tk[3].read.sbus.lock_status_error.bit.err0_local; + reply_ans->digit_data.byte28.bit_data.bit2 = project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + reply_ans->digit_data.byte28.bit_data.bit3 = project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + reply_ans->digit_data.byte28.bit_data.bit4 = project.cds_tk[3].read.sbus.lock_status_error.bit.line_err_keys_7654; + reply_ans->digit_data.byte28.bit_data.bit5 = project.cds_tk[3].read.sbus.lock_status_error.bit.line_err_keys_3210; + reply_ans->digit_data.byte28.bit_data.bit6 = project.cds_tk[3].read.sbus.lock_status_error.bit.ErrorSoftShutdownFromErr0; + reply_ans->digit_data.byte28.bit_data.bit7 = project.cds_tk[3].read.sbus.lock_status_error.bit.ErrorSoftShutdownForbidComb; + } + else + reply_ans->digit_data.byte28.byte_data = 0; +#else + reply_ans->digit_data.byte28.byte_data = 0; +#endif + + +/* + +//IN1 ready + reply_ans->digit_data.byte21.byte_data = project.cds_in[0].read.pbus.ready_in.all & 0xFF; + reply_ans->digit_data.byte22.byte_data = (project.cds_in[0].read.pbus.ready_in.all >> 8) & 0xFF; + +//TK0 acknolege-current + reply_ans->digit_data.byte23.byte_data = project.cds_tk[0].read.sbus.status_protect_current_ack.all & 0xFF; + reply_ans->digit_data.byte24.byte_data = (project.cds_tk[0].read.sbus.status_protect_current_ack.all >> 8) & 0xFF; +*/ + return; +} + + + + + + + + + + + + + + + + + + + + + diff --git a/Inu/Src/main/message2test.h b/Inu/Src/main/message2test.h new file mode 100644 index 0000000..3f1406c --- /dev/null +++ b/Inu/Src/main/message2test.h @@ -0,0 +1,33 @@ +//////////////////////////////////////////// +// message.h +// +// ��������� ��������� �����: +// 1. ������������ ��������������y +// 2. �������������� ������������ +// 3. ������������ �������� �����y +// +// ������ ���� ����� ���� ����������� ��� +// ������y��� ��������� ��y ���������y �� ������ +// ����������. � ��������� �� INTEL 386SX Octagon +// � �� TMS320C32 Texas Instruments. +// �������� ������ ����� ���������������� ��������� +// ���������� ��������. +// � ������ ����� ��������� ��� ��y ������������ ������ +// unsigned char = 8 ��� +// �� TMS320C32 unsigned char = 32 ���, �� �����������y +// ������ ������� 8 ���. +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// ������ �������� ������� �������� �������� �� ������ +// ���������� � ����������� �� ������ �����������y +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//////////////////////////////////////////// + +#ifndef MESSAGE_TEST_H +#define MESSAGE_TEST_H + +#include "RS_Function_terminal.h" + +void func_fill_answer_to_TMS_test(TMS_TO_TERMINAL_TEST_ALL_STRUCT* reply_ans, CMD_TO_TMS_TEST_ALL_STRUCT* pcommand); + + +#endif //MESSAGE_H diff --git a/Inu/Src/main/message_modbus.c b/Inu/Src/main/message_modbus.c new file mode 100644 index 0000000..024db30 --- /dev/null +++ b/Inu/Src/main/message_modbus.c @@ -0,0 +1,897 @@ +#include <message_modbus.h> +#include <message_terminals_can.h> +#include <message2.h> +#include <modbus_hmi.h> +#include <project.h> +#include <vector.h> +#include <modbus_hmi_update.h> +#include "CAN_Setup.h" +#include "global_time.h" +#include "modbus_table_v2.h" +#include "oscil_can.h" +#include "RS_modbus_pult.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "CRC_Functions.h" +#include "RS_Function_terminal.h" +#include "RS_modbus_svu.h" +#include "TuneUpPlane.h" +#if (USE_CONTROL_STATION==1) +#include "control_station.h" +#endif +#include <message2can.h> +#include <edrk_main.h> + +#include "pwm_test_lines.h" +#include "params.h" +#include "logs_hmi.h" + + +//#include "can_setup_21300.h" +//#include "modbus_can.h" + +//static int err_modbus3=1; +//static int err_modbus16=1; +//static int cmd_3_or_16=0; + +int enable_can = 0; + +void write_all_data_to_mpu_485(int run_force) +{ + static unsigned int time_tick_modbus = 0; + static unsigned int old_PWM_ticks = 0; + static int count_write_to_modbus = 0; + static int cur_position_buf_modbus16 = 0; + + if (global_time.pwm_tics != old_PWM_ticks) + { + if (global_time.pwm_tics > old_PWM_ticks) + time_tick_modbus = time_tick_modbus + (global_time.pwm_tics - old_PWM_ticks); + else + time_tick_modbus++; + } + + if (time_tick_modbus > TIME_PAUSE_MODBUS_MPU) + { + // pause_1000() + + time_tick_modbus = 0; + pause_1000(10); + // SendCommandModbus3(&rs_b, 0x1, 0xc012,1); + // rs_b.flag_LEADING = 0; + if (!rs_b.flag_LEADING) + { + time_tick_modbus = 0; + //Fast answer to SVU when command changed + // if (flag_send_answer_rs) { + // flag_send_answer_rs = 0; + // err_modbus16++; + // SendCommandModbus16(&rs_b,1,210,SIZE_BUF_WRITE_TO_MODBUS16); + // return; + // } + if (err_modbus16 == 0) + cur_position_buf_modbus16 = cur_position_buf_modbus16 + SIZE_BUF_WRITE_TO_MODBUS16_VPU; + + if (cur_position_buf_modbus16 >= SIZE_MODBUS_TABLE) + cur_position_buf_modbus16 = 0; + + if ((cur_position_buf_modbus16 + SIZE_BUF_WRITE_TO_MODBUS16_VPU) > SIZE_MODBUS_TABLE) + count_write_to_modbus = SIZE_MODBUS_TABLE - cur_position_buf_modbus16; + else + count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16_VPU; + + // count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16_VPU; + // cur_position_buf_modbus=0; + + err_modbus16++; + + if (err_modbus16 > MAX_COUNT_ERROR_FROM_RS_MPU) + f.RS_MPU_ERROR = 1; + + ModbusRTUsend16(&rs_b, 1, + ADR_MODBUS_TABLE + cur_position_buf_modbus16, + count_write_to_modbus); + // SendCommandModbus16(&rs_b,1,ADR_MODBUS_TABLE+cur_position_buf_modbus16,count_write_to_modbus); + // SendCommandModbus16(&rs_b,1,1,30); + + // + // SendCommandModbus16(&rs_b,1,0xc001,0x64); + // err_modbus + } + } +} + +void read_all_data_from_mpu_485(int run_force) +{ + static unsigned int time_tick_modbus = 0; + static unsigned int old_PWM_ticks = 0; + static unsigned int count_write_to_modbus = 0; + static int cur_position_buf_modbus3 = 0; + + if (global_time.pwm_tics != old_PWM_ticks) + { + if (global_time.pwm_tics > old_PWM_ticks) + time_tick_modbus = time_tick_modbus + (global_time.pwm_tics - old_PWM_ticks); + else + time_tick_modbus++; + } + + old_PWM_ticks = global_time.pwm_tics; + + if (TIME_PAUSE_MODBUS_MPU < time_tick_modbus) + { + // pause_1000() + + pause_1000(10); + // SendCommandModbus3(&rs_b, 0x1, 0xc012,1); + //rs_b.flag_LEADING = 0; + if (!rs_b.flag_LEADING) + { + time_tick_modbus = 0; + + if (err_modbus3 == 0) + cur_position_buf_modbus3 = cur_position_buf_modbus3 + SIZE_BUF_WRITE_TO_MODBUS16_VPU; + + if (cur_position_buf_modbus3 >= SIZE_MODBUS_TABLE) + cur_position_buf_modbus3 = 0; + + if ((cur_position_buf_modbus3 + SIZE_BUF_WRITE_TO_MODBUS16_VPU) > SIZE_MODBUS_TABLE) + count_write_to_modbus = SIZE_MODBUS_TABLE - cur_position_buf_modbus3; + else + count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16_VPU; + + // count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16_VPU; + // cur_position_buf_modbus=0; + + err_modbus3++; + + if (err_modbus3 > MAX_COUNT_ERROR_FROM_RS_MPU) + f.RS_MPU_ERROR = 1; + + // SendCommandModbus3(&rs_b,1,ADR_MODBUS_TABLE+cur_position_buf_modbus3,count_write_to_modbus); + ModbusRTUsend3(&rs_b, 1, + ADR_MODBUS_TABLE + cur_position_buf_modbus3, + count_write_to_modbus); + } + } + + // time_tick_modbus++; +} + +void write_all_data_to_mpu_can(int run_force, unsigned int pause) +{ +// static int time_tick_modbus_can = 0; + static unsigned int old_time = 0; + static int count_write_to_modbus_can = 0; +// static int time_send_to_can = 0; + // static unsigned int counter_max_I = 0, counter_max_M = 0; + + static int cur_position_buf_modbus16_can = 0, prev_send_to_can = 0; + int real_mbox; + unsigned int i; + + real_mbox = get_real_out_mbox(MPU_TYPE_BOX, edrk.flag_second_PCH); + + if (prev_send_to_can && CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF)==0) + { + old_time = (unsigned int)global_time.miliseconds; + return; + } + prev_send_to_can = 0; + + if (!detect_pause_milisec(pause,&old_time)) + return; + + +// +// +// if (cmd_3_or_16 == 1 || run_force) +// { +// +// if (global_time.pwm_tics != old_PWM_ticks) +// { +// if (global_time.pwm_tics > old_PWM_ticks) +// time_tick_modbus_can = time_tick_modbus_can + (global_time.pwm_tics - old_PWM_ticks); +// else +// time_tick_modbus_can++; +// } +// +// old_PWM_ticks = global_time.pwm_tics; +// } +// else +// { +// old_PWM_ticks = global_time.pwm_tics; +// return; +// } +// +// +// +// if (CAN_cycle_free(real_mbox)) +// { +// if (time_send_to_can == 0) +// time_send_to_can = time_tick_modbus_can; +// +// // time_tick_modbus_can=0; +// +// } + // if(f.Prepare && CAN_cycle_free(real_mbox)) + // { + // CAN_cycle_send( MPU_TYPE_BOX, 0, 198, &modbus_table_can_out[197].all, 1); + // } + + +// if (time_tick_modbus_can > TIME_PAUSE_MODBUS_CAN) +// { +// time_tick_modbus_can = 0; +// time_send_to_can = 0; +// // pause_1000(300); + + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + ///////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////////////////// + + + if (cur_position_buf_modbus16_can >= SIZE_MODBUS_TABLE) + { + cur_position_buf_modbus16_can = 0; + // modbus_table_can_out[ADR_CAN_TEST_PLUS_ONE].all++; + } + + // ��������� �� ��������� ������ ����� ������� �������� ����� ������� ����� ������ �� �������� �� ����� �������� + if (cur_position_buf_modbus16_can == 0) + { + for (i=0;i<SIZE_MODBUS_TABLE;i++) + modbus_table_can_out_temp[i] = modbus_table_can_out[i]; + } + + if ((cur_position_buf_modbus16_can + SIZE_BUF_WRITE_TO_MODBUS16_CAN) >= SIZE_MODBUS_TABLE) + count_write_to_modbus_can = SIZE_MODBUS_TABLE - cur_position_buf_modbus16_can; + else + count_write_to_modbus_can = SIZE_BUF_WRITE_TO_MODBUS16_CAN; + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + // modbus_table_can_out[0x124].all++; + // CAN_cycle_send(MPU_CAN_DEVICE, cur_position_buf_modbus16_can+1, &modbus_table_can_out[cur_position_buf_modbus16_can].all, count_write_to_modbus_can); + + CAN_cycle_send( + MPU_TYPE_BOX, + edrk.flag_second_PCH, + cur_position_buf_modbus16_can + 1, +// &modbus_table_can_out[cur_position_buf_modbus16_can].all, + &modbus_table_can_out_temp[cur_position_buf_modbus16_can].all, + count_write_to_modbus_can, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL); + + cur_position_buf_modbus16_can = cur_position_buf_modbus16_can + SIZE_BUF_WRITE_TO_MODBUS16_CAN; + } + } + +// } + +} + +//void test_rs_can_with_svu_mpu() +//{ +// int test_a, test_b; +// +// test_a = test_rs_live(&rs_a); +// test_b = test_rs_live(&rs_b); +// +// if (test_a == 0 && test_b == 0 && f.status_MODE_WORK_SVU == 0) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// if (test_can_live_mpu() == 0) +// { +// // if (f.cmd_to_go == 0) f.cmd_to_go = ERROR_CMD_GO_1; +// edrk.Go = 0; /* ��������� */ +// } +// } +// +// if (test_a == 0 && test_b == 0 && f.status_MODE_WORK_MPU == 0 /*&& f.status_SPEED_SELECT_KEY==0*/) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// if (test_can_live_mpu() == 0) +// { +// // if (f.cmd_to_go == 0) f.cmd_to_go = ERROR_CMD_GO_2; +// edrk.Go = 0; /* ��������� */ +// } +// } +// +// if (test_a == 2) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// // edrk.Go=0; /* ��������� */ +// resetup_rs(&rs_a); +// } +// +// if (test_b == 2) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// resetup_rs(&rs_b); +//// flag_waiting_answer = 0; //���������, ����� ����� ������� �� ��������� ������, +// //���� ���� slave ����, ������ ����� ��������. +// } +// +// if (test_b == 5) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// resetup_rs(&rs_b); +//// flag_waiting_answer = 0; //���������, ����� ����� ������� �� ��������� ������, +// //���� ���� slave ����, ������ ����� ��������. +// } +// +// if (test_a == 4 && test_b == 4) //TODO: && SPEED_SELECT_REMOTE==1) +// { +// // ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 +// if (test_can_live_mpu() == 0) +// { +// // if (f.cmd_to_go == 0) f.cmd_to_go = ERROR_CMD_GO_3; +// edrk.Go = 0; // ��������� +// } +// resetup_mpu_rs(&rs_a); +// resetup_mpu_rs(&rs_b); +//// flag_waiting_answer = 0; +// } +// +// if (test_a == 4 && test_b == 4) //TOD: && SPEED_SELECT_REMOTE==0) +// { +// // ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 +// // if (test_can_live_mpu()==0) +// +// // test_can_live_terminal // +// +// { +// // if (f.cmd_to_go == 0) f.cmd_to_go = ERROR_CMD_GO_20; +// edrk.Go = 0; // ��������� +// } +// resetup_mpu_rs(&rs_a); +// resetup_mpu_rs(&rs_b); +// } +// +// if (test_a == 0 && f.status_MODE_WORK_MPU == 0) // && SPEED_SELECT_REMOTE==0) +// { +// /* ���� ����� �� �������� �� ���������� ��������� � ��������� ������������ RS232 */ +// // if (test_can_live_mpu()==0) +// // if (f.cmd_to_go == 0) f.cmd_to_go = ERROR_CMD_GO_4; +// edrk.Go = 0; /* ��������� */ +// } +// +// // if (CAN_timeout[]==1) +// // f.CAN_MPU_ERROR=CAN_timeout[MPU_CAN_DEVICE]; +//} + + + +#define TIME_REINIT_PULT_INGETEAM 5 + + +void test_alive_pult_485(void) +{ + static unsigned int time_pause = 0, old_time = 0; + +// +// if (control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active_resend_485[CONTROL_STATION_INGETEAM_PULT_RS485]) +// { +// resetup_mpu_rs(&rs_b); +// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// } +/* + if (control_station.time_detect_active[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active_resend_485[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + resetup_mpu_rs(&rs_b); + control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + // control_station.time_detect_active[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + } +*/ + +// if (control_station.time_detect_active[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active[CONTROL_STATION_INGETEAM_PULT_RS485]) +// { +// resetup_mpu_rs(&rs_b); +// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// control_station.time_detect_active[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// } + + +/* + if (!detect_pause_milisec(CONTROL_STATION_TIME_WAIT,&old_time)) + return; + + time_pause++; + + if (time_pause>=TIME_REINIT_PULT_INGETEAM) + { + flag_waiting_answer = 0; //���������, ����� ����� ������� �� ��������� ������ + } +*/ + +} + + +#define MAX_COUNT_WORK_IN_LOG 150 + + +int modbusNetworkSharing(int flag_update_only_hmi) +{ + static unsigned int old_time = 0 , old_time_refresh = 0, time_pause = TIME_PAUSE_MODBUS_REMOUTE; + static unsigned int old_time_status_3 = 0, time_pause_status_3 = 500; + int final_code=0; + static unsigned int status=0; + static int numberInT=0, enable_send_cmd = 0; + + static int run_pause = 1, flag_next = 0, prev_flag_next = 0; + static int last_ok_cmd=0; + static int flag_only_one_cmd=0; + static int status_ok = 1, status_err = 0, flag_work_rs_send_log = 0, count_free = 0, count_work_in_log = 0; + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_20_ON; +#endif + + RS232_WorkingWith(0,1,0); + + // ��� ��� ������-����� ��� ������� �������� + // control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + + control_station_test_alive_all_control(); + + // if (detect_pause_milisec(100,&old_time_refresh)) + control_station.update_timers(&control_station); + + detecting_cmd_from_can(); + + // test_rs_can_with_svu_mpu(); +// test_alive_pult_485(); + + + // if (rs_b.RS_DataSended==0 && rs_b.RS_DataReadyAnswerAnalyze==0) + // status = 0; + + control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = rs_b.RS_DataSended; + + final_code = 0; + + + switch(status) + { + case 0: + + old_time = global_time.miliseconds; + status = 1; + if (time_pause==0) + status = 2; + + break; + case 1: + // if (numberInT==0) + // { + if (detect_pause_milisec(time_pause,&old_time)) + status = 2; + // } + // else + // status = 2; + + break; + case 2: + enable_send_cmd = 1; + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + status = 3; + old_time_status_3 = global_time.miliseconds; + + break; + case 3: + // // ���� �� � �������� ����� � ��� ������ ������� ��� ������ �� rs485 + // if (flag_work_rs_send_log) + // { + // status = 0; + // status_ok++; + // if (status_ok<0) status_ok=1; + // } + + // �� ���� ������� �� rs485 ������ � ������ ��� ������! + if (rs_b.RS_DataWillSend2 == 0 && enable_send_cmd == 0) + { + status = 0; + status_ok++; + count_free++; + } + else + if (rs_b.RS_DataReadyAnswerAnalyze) + { +// i_led2_on_off(0); + + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + control_station.count_ok_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; + rs_b.RS_DataReadyAnswerAnalyze = 0; + rs_b.RS_DataWillSend2 = 0; + status = 0; + + if (last_ok_cmd==4) // ������ readAnalogDataFromRemote() �� ���� + { + edrk.get_new_data_from_hmi = 1;// ����� ������� ������? + edrk.get_new_data_from_hmi2 = 1;// ����� ������� ������? + } + final_code = last_ok_cmd;//numberInT+1; + + //status_err = 0; + status_ok++; + } + else + { + if ( (control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active_resend_485[CONTROL_STATION_INGETEAM_PULT_RS485]) + || (detect_pause_milisec(time_pause_status_3,&old_time_status_3)) ) + { + resetup_mpu_rs(&rs_b); + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + rs_b.RS_DataWillSend2 = 0; + status = 0; + control_station.count_error_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; + status_err++;// = 1; + } + + } + + if (status_ok<0) status_ok=1; + + break; + case 4: + + break; + case 5: + + break; + case 6: + + break; + default: + break; + + + + } + +/* + if (status==0) + { + old_time = global_time.miliseconds; + status = 1; + if (time_pause==0) + status = 2; + } + + if (status==1) + { +// if (numberInT==0) +// { + if (detect_pause_milisec(time_pause,&old_time)) + status = 2; +// } +// else +// status = 2; + } + + if (status==2) + { + enable_send_cmd = 1; + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + status = 3; + old_time_status_3 = global_time.miliseconds; + } + + if (status==3) + { + if (rs_b.RS_DataWillSend2 == 0) + { + + count_free++; + + } + + // ���� �� � �������� ����� � ��� ������ ������� ��� ������ �� rs485 + if (flag_work_rs_send_log) + { + status = 0; + status_ok++; + if (status_ok<0) status_ok=1; + } + + if (rs_b.RS_DataReadyAnswerAnalyze) + { +// i_led2_on_off(0); + + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + control_station.count_ok_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; + rs_b.RS_DataReadyAnswerAnalyze = 0; + rs_b.RS_DataWillSend2 = 0; + status = 0; + + if (last_ok_cmd==4) // ������ readAnalogDataFromRemote() �� ���� + edrk.get_new_data_from_hmi = 1;// ����� ������� ������? + final_code = last_ok_cmd;//numberInT+1; + + //status_err = 0; + status_ok++; + if (status_ok<0) status_ok=1; + } + else + { + if ( (control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active_resend_485[CONTROL_STATION_INGETEAM_PULT_RS485]) + || (detect_pause_milisec(time_pause_status_3,&old_time_status_3)) ) + { + resetup_mpu_rs(&rs_b); + control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; + rs_b.RS_DataWillSend2 = 0; + status = 0; + control_station.count_error_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; + status_err++;// = 1; + } + + } + + } +*/ +// switch (status) +// { +// case 0 : status = 1; +// break; +// +// case 1 : old_time = global_time.miliseconds; +// status = 2; +// break; +// +// case 2 : +// if (run_pause) +// { +// status = 3; +// run_pause = 0; +// } +// if (detect_pause_milisec(time_pause,&old_time)) +// status = 3; +// break; +// +// case 3 : +// enable_send_cmd = 1; +//// control_station.count_error_modbus_15[CONTROL_STATION_INGETEAM_PULT_RS485]++; +// control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// status = 4; +// break; +// +// +// case 4 : +// if (rs_b.RS_DataReadyAnswerAnalyze) +// { +// control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// control_station.count_ok_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; +// rs_b.RS_DataReadyAnswerAnalyze = 0; +// status = 1; +// final_code = numberInT+1; +// } +// else +// { +// if (control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485]>control_station.setup_time_detect_active_resend_485[CONTROL_STATION_INGETEAM_PULT_RS485]) +// { +// resetup_mpu_rs(&rs_b); +// control_station.time_detect_answer_485[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// status = 1; +// control_station.count_error_modbus[CONTROL_STATION_INGETEAM_PULT_RS485]++; +// } +// } +// break; +// +// +// case 5 : break; +// +// +// case 6 : break; +// +// default : break; +// } + + +// +// +// if (control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] == 1) +// { +// if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0 && prev_flag_waiting_answer == 1) +// { +// old_time = global_time.miliseconds; +// } +// +// if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) +// { +// if (detect_pause_milisec(time_pause,&old_time)) +// { +// control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 0; +// } +// +// } +// } +// prev_flag_waiting_answer = control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485]; +// +// +// if (control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] == 0 && +// control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0 ) +// { +// enable_send_cmd = 1; +//// numberInT++; +//// if (numberInT>3) +//// numberInT = 1; +// } +// + + +// ��� �������� ��� ����� ������ + if (flag_only_one_cmd) + numberInT=flag_only_one_cmd-1; +// + + + if (enable_send_cmd +// && (log_to_HMI.send_log == 0) + ) + { +//i_led2_on_off(1); + last_ok_cmd = numberInT; + switch (numberInT) + { + + case 0: + + if ((flag_update_only_hmi==0) && (edrk.flag_enable_update_hmi)) + update_tables_HMI_discrete(); + + writeDiscreteDataToRemote(); + edrk.test++; + + numberInT++; + enable_send_cmd = 0; + break; + + case 1: + + if ((flag_update_only_hmi==0) && (edrk.flag_enable_update_hmi)) +// if (edrk.flag_enable_update_hmi) + update_tables_HMI_analog(); + + writeAnalogDataToRemote(); // 1 ����� ������� + +// if (flag_update_only_hmi==1) +// // ���������� ���� ������� +// numberInT = 0; +// else + numberInT++; + + enable_send_cmd = 0; + break; + + case 2: + +// if (edrk.flag_enable_update_hmi) +// update_tables_HMI_analog(); + + writeAnalogDataToRemote(); // 2 ����� ������� + +// if (flag_update_only_hmi==1) +// // ���������� ���� ������� +// numberInT = 0; +// else + numberInT++; + + enable_send_cmd = 0; + break; + + + case 3: + readAnalogDataFromRemote(); // 1 ����� + numberInT++; + enable_send_cmd = 0; + break; + + case 4: + readAnalogDataFromRemote(); // 2 ����� + + if (log_to_HMI.send_log) + { + numberInT++; + } + else + // ���������� ���� ������� + numberInT = 0; + + enable_send_cmd = 0; + count_work_in_log = 0; // ���������� ��� ����� + break; + + case 5: + if (log_to_HMI.send_log) + { + time_pause = 2; + // ccc[0] = 1; + flag_work_rs_send_log = !sendLogToHMI(status_ok); + edrk.flag_slow_in_main = 1; + enable_send_cmd = 0; + + if (count_work_in_log>MAX_COUNT_WORK_IN_LOG) + { + count_work_in_log = 0; + numberInT = 0; // ��������� ������ ���� + + } + else + { + count_work_in_log++; + // �������� � ���� ����� ����� + } + + } + else + { + time_pause = TIME_PAUSE_MODBUS_REMOUTE; + // ccc[0] = 0; + numberInT = 0; + enable_send_cmd = 0; + edrk.flag_slow_in_main = 0; + } + break; + + + default: + enable_send_cmd = 0; + break; + } + + +//i_led2_on_off(0); + + } + //sendLogToHMI(); + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_RS) + PWM_LINES_TK_20_OFF; +#endif + + if (flag_update_only_hmi) + return final_code; + + + return 0; +} + + + +int modbusNetworkSharingCAN(void) +{ +// static unsigned int old_time1 = 0 , time_pause1 = TIME_PAUSE_NETWORK_CAN1; +// static unsigned int old_time2 = 0 , time_pause2 = TIME_PAUSE_NETWORK_CAN2; +// static unsigned int old_time3 = 0 , time_pause3 = TIME_PAUSE_NETWORK_CAN3; + static unsigned int time_pause_modbus_can_terminals = TIME_PAUSE_MODBUS_CAN_TERMINALS; + + + +#if (ENABLE_CAN_SEND_TO_MPU_FROM_MAIN) +// if (detect_pause_milisec(time_pause1,&old_time1)) + static unsigned int time_pause_modbus_can_mpu = TIME_PAUSE_MODBUS_CAN_MPU; + write_all_data_to_mpu_can(1, time_pause_modbus_can_mpu); +#endif + +#if (ENABLE_CAN_SEND_TO_TERMINAL_FROM_MAIN) +// if (detect_pause_milisec(time_pause2,&old_time2)) + write_all_data_to_terminals_can(1, time_pause_modbus_can_terminals); +#endif + + +#if (ENABLE_CAN_SEND_TO_TERMINAL_OSCIL) +// if (detect_pause_milisec(time_pause3,&old_time3)) + oscil_can.pause_can = TIME_PAUSE_MODBUS_CAN_OSCIL; + oscil_can.send(&oscil_can); +#endif + + return 0; +} + diff --git a/Inu/Src/main/message_modbus.h b/Inu/Src/main/message_modbus.h new file mode 100644 index 0000000..971e5a9 --- /dev/null +++ b/Inu/Src/main/message_modbus.h @@ -0,0 +1,61 @@ + +#ifndef _MESSAGE_MODBUS_H +#define _MESSAGE_MODBUS_H + + + +// void ReceiveCommandModbus3(RS_DATA *rs_arr); +// void ReceiveCommandModbus16(RS_DATA *rs_arr); +// void ReceiveCommandModbus15(RS_DATA *rs_arr); + +// void SendCommandModbus3(RS_DATA *rs_arr,int adr_contr, unsigned int adr_start,unsigned int count_word); +// void SendCommandModbus16(RS_DATA *rs_arr,int adr_contr, unsigned int adr_start,unsigned int count_word); + +// void ReceiveAnswerCommandModbus16(RS_DATA *rs_arr); +// void ReceiveAnswerCommandModbus3(RS_DATA *rs_arr); + +#define TIME_PAUSE_MODBUS_MPU 250 //100//500 +#define TIME_PAUSE_MODBUS_REMOUTE 20 //100 //500 + +#define TIME_PAUSE_NETWORK_CAN1 444 //500 +#define TIME_PAUSE_NETWORK_CAN2 990 //500 +#define TIME_PAUSE_NETWORK_CAN3 1855 //500 + +//#define START_ADR_ARR 0xc000 +//#define LENGTH_ADR_ARR 0x100 +//#define SIZE_MODBUS_TABLE_DISCRETE_REMOUTE 36 // = 576/16 +#define SIZE_BUF_WRITE_TO_MODBUS1_REMOUTE SIZE_MODBUS_TABLE_DISCRET_REMOUTE // SIZE_MODBUS_TABLE_DISCRET_BITS //576 //��� ������� ������� ������ 3 ���� modbus ��������� ������� ��� �� ���������� ������ �������. +#define SIZE_BUF_WRITE_TO_MODBUS15_REMOUTE SIZE_MODBUS_TABLE_DISCRET_REMOUTE //SIZE_MODBUS_TABLE_DISCRET_BITS //576 //96 + + +#define SIZE_BUF_WRITE_TO_MODBUS16_VPU 100 // + +#define SIZE_BUF_WRITE_TO_MODBUS16_REMOUTE 120 //100 // ��������, ������ � ����� ������� ������.����� ������ ���, �� ������ SIZE_ANALOG_DATA_REMOUTE +#define SIZE_ANALOG_DATA_REMOUTE 240 //165 // ��������, ������ ������ �� ���������� ����� ������ ��� + + +#define SIZE_BUF_READ_FROM_MODBUS16_REMOUTE 120 //20//36 // �����, ������ � ����� ������� ������.����� ������ ���, �� ������ SIZE_ANALOG_DATA_FROM_MODBUS16_REMOUTE +#define SIZE_ANALOG_DATA_FROM_MODBUS16_REMOUTE SIZE_ANALOG_DATA_REMOUTE //20//36 // �����, ������ ������ �� ���������� ����� ������ ��� + + +#define SIZE_BUF_WRITE_TO_MODBUS16_CAN 100 //10 //1000//400//04.04.2012 //100// //800 +#define START_LOG_MODBUS16_ADRES 100 +#define SIZE_BUF_WRITE_LOG_TO_MODBUS16 120 +//#define SIZE_ANALOG_DATA 61 + + +#define MAX_COUNT_ERROR_FROM_RS_MPU 10 + +//void test_rs_can_with_svu_mpu(); +void write_all_data_to_mpu_can(int run_force, unsigned int pause); +void read_all_data_from_mpu_485(int run_force); +void write_all_data_to_mpu_485(int run_force); +extern int enable_can; + +int modbusNetworkSharing(int flag_update_only_hmi); +int modbusNetworkSharingCAN(void); + + + +#endif //_MESSAGE_MODBUS_H + diff --git a/Inu/Src/main/message_terminals_can.c b/Inu/Src/main/message_terminals_can.c new file mode 100644 index 0000000..c21892a --- /dev/null +++ b/Inu/Src/main/message_terminals_can.c @@ -0,0 +1,128 @@ +/* + * message_terminals_can.c + * + * Created on: 15 ��� 2020 �. + * Author: yura + */ +#include <edrk_main.h> +#include <message_modbus.h> +#include <message2.h> +#include <vector.h> + +#include "CAN_Setup.h" +#include "global_time.h" +#include "modbus_table_v2.h" +#include "oscil_can.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "CRC_Functions.h" +#include "RS_Function_terminal.h" +#include "TuneUpPlane.h" +#include "control_station.h" + + + +#define TERMINALS_CAN_TIME_WAIT 500 // ������ �������� ������ � ���������� +#pragma DATA_SECTION(buf_message_can_cmd,".slow_vars") +int buf_message_can_cmd[sizeof(CMD_TO_TMS_STRUCT)+10]; +#pragma DATA_SECTION(buf_message_can_data,".slow_vars") +int buf_message_can_data[sizeof(TMS_TO_TERMINAL_STRUCT)+10]; +#pragma DATA_SECTION(buf_message_can_data2,".slow_vars") +int buf_message_can_data2[sizeof(TMS_TO_TERMINAL_STRUCT)+10]; + +int *p_buf_message_can_data3; + + +void write_all_data_to_terminals_can(int run_force, unsigned int pause) +{ + static unsigned int old_time = 0; + static unsigned int send_time = 0; + static int prev_send_to_can = 0; + + static int count_sends = 0; + + unsigned long old_t; + unsigned int i; + int real_mbox; + CMD_TO_TMS_STRUCT* pcommand = (CMD_TO_TMS_STRUCT *)(buf_message_can_cmd); + + + real_mbox = get_real_out_mbox(TERMINAL_TYPE_BOX, edrk.number_can_box_terminal_cmd); + + // ���� ������� �� �������� ������� � ��� ��� �� ����, ����� ���������� ������� ������� ����� ����� ���������, + // �.�. TERMINALS_CAN_TIME_WAIT ����� ������ �������� ������� � ����� �������. + if (prev_send_to_can && CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF)==0) + { + old_time = (unsigned int)global_time.miliseconds; + return; + } + prev_send_to_can = 0; + + if (!detect_pause_milisec(pause,&old_time)) + return; + + + //func_fill_answer_to_TMS(&reply, pcommand); + func_pack_answer_to_TMS(&reply); + + *(TMS_TO_TERMINAL_STRUCT*)buf_message_can_data2 = reply; // ���������� ������ ���������� + + + + // reply.digit_data.byte01.byte_data = send_time; +/* reply.digit_data.byte02.byte_data = 0x66; + reply.analog_data.analog60_hi = 0x33; + reply.analog_data.analog60_lo = 0x44; +*/ + reply.analog_data.analog58_hi = HIBYTE((unsigned int)control_station.raw_array_data[CONTROL_STATION_TERMINAL_CAN][0].all); + reply.analog_data.analog58_lo = LOBYTE((unsigned int)control_station.raw_array_data[CONTROL_STATION_TERMINAL_CAN][0].all); + +// control_station.raw_array_data[CONTROL_STATION_TERMINAL_CAN][0].all + + reply.analog_data.analog59_hi = HIBYTE((unsigned int)global_time.miliseconds); + reply.analog_data.analog59_lo = LOBYTE((unsigned int)global_time.miliseconds); + + reply.analog_data.analog60_hi = HIBYTE(count_sends); + reply.analog_data.analog60_lo = LOBYTE(count_sends); + count_sends++; + if (count_sends>32768) count_sends=0; + +// reply.analog_data.analog1_hi = HIBYTE(send_time); + // reply.analog_data.analog1_lo = LOBYTE(send_time); + +// reply.analog_data.analog2_hi = HIBYTE(oscil_can.timer_send); +// reply.analog_data.analog2_lo = LOBYTE(oscil_can.timer_send); + + p_buf_message_can_data3 = (int *)&reply.digit_data; + + + for (i=0;i<sizeof(TMS_TO_TERMINAL_STRUCT)-5;i++) + { + + if (i%2) + { + buf_message_can_data[i>>1] |= ( (*p_buf_message_can_data3++) << 8) & 0xff00; + } + else + buf_message_can_data[i>>1] = ( (*p_buf_message_can_data3++) ) & 0x00ff; + + } + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + + old_t = global_time.microseconds; + CAN_cycle_send( + TERMINAL_TYPE_BOX, + edrk.number_can_box_terminal_cmd, + 0, + &buf_message_can_data[0], ((sizeof(TMS_TO_TERMINAL_STRUCT)-5)>>1), CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL); + + prev_send_to_can = 1; + + + send_time = (global_time.microseconds - old_t)/100; + } + + +} diff --git a/Inu/Src/main/message_terminals_can.h b/Inu/Src/main/message_terminals_can.h new file mode 100644 index 0000000..90cf1c6 --- /dev/null +++ b/Inu/Src/main/message_terminals_can.h @@ -0,0 +1,15 @@ +/* + * message_terminals_can.h + * + * Created on: 22 ��� 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_MESSAGE_TERMINALS_CAN_H_ +#define SRC_MAIN_MESSAGE_TERMINALS_CAN_H_ + +void write_all_data_to_terminals_can(int run_force, unsigned int pause); + + + +#endif /* SRC_MAIN_MESSAGE_TERMINALS_CAN_H_ */ diff --git a/Inu/Src/main/modbus_hmi.c b/Inu/Src/main/modbus_hmi.c new file mode 100644 index 0000000..f28cb25 --- /dev/null +++ b/Inu/Src/main/modbus_hmi.c @@ -0,0 +1,393 @@ +#include "log_to_memory.h" +#include <message_modbus.h> +#include <modbus_hmi.h> +#include <modbus_hmi_update.h> +#include <vector.h> + +#include "control_station.h" +#include "global_time.h" +#include "modbus_table_v2.h" +#include "RS_modbus_pult.h" +#include "DSP281x_Device.h" +#include "MemoryFunctions.h" +#include "RS_modbus_svu.h" +#include "log_params.h" + + +#pragma DATA_SECTION(modbus_table_discret_in,".logs"); +MODBUS_REG_STRUCT modbus_table_discret_in[SIZE_MODBUS_TABLE_DISCRET_REMOUTE]; //registers 10001-19999 modbus RTU + +#pragma DATA_SECTION(modbus_table_discret_out,".logs"); +MODBUS_REG_STRUCT modbus_table_discret_out[SIZE_MODBUS_TABLE_DISCRET_REMOUTE]; //registers 1-9999 modbus RTU + +#pragma DATA_SECTION(modbus_table_analog_in, ".logs"); +MODBUS_REG_STRUCT modbus_table_analog_in[SIZE_MODBUS_ANALOG_REMOUTE]; //registers 30001-39999 modbus RTU + +#pragma DATA_SECTION(modbus_table_analog_out, ".logs"); +//MODBUS_REG_STRUCT modbus_table_analog_out[700]; //registers 40001-49999 modbus RTU +MODBUS_REG_STRUCT modbus_table_analog_out[SIZE_MODBUS_ANALOG_REMOUTE]; //registers 40001-49999 modbus RTU + +//#pragma DATA_SECTION(modbus_table_analog_out2, ".logs"); +//MODBUS_REG_STRUCT modbus_table_analog_out[700]; //registers 40001-49999 modbus RTU +//MODBUS_REG_STRUCT modbus_table_analog_out2[SIZE_MODBUS_ANALOG_REMOUTE]; //registers 40001-49999 modbus RTU + + +//unsigned int flag_waiting_answer = 1; +//unsigned int flag_message_sent = 0; + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +void clear_table_remoute(void) +{ + int i; + + for (i=0;i<SIZE_MODBUS_TABLE_DISCRET_REMOUTE;i++) + { + modbus_table_discret_in[i].all = 0; + modbus_table_discret_out[i].all = 0; + } + + for (i=0;i<SIZE_MODBUS_ANALOG_REMOUTE;i++) + { + modbus_table_analog_in[i].all = 0; + modbus_table_analog_out[i].all = 0; + //modbus_table_analog_out2[i].all = 0; + } + + + + +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + +void setRegisterDiscreteOutput(int value, int adres) +{ + int word_number = 0; + int bit_number = 0; + + if (adres >= 0 && adres < SIZE_MODBUS_TABLE_DISCRET_BITS) + { +// word_number = (adres % 16 == 0) && (adres != 0) ? adres / 16 + 1 : +// adres / 16; + word_number = (adres % 16 == 0) && (adres != 0) ? adres / 16 : + adres / 16; + bit_number = adres % 16; + + if (word_number<SIZE_MODBUS_TABLE_DISCRET_REMOUTE) + { + if (value) + modbus_table_discret_out[word_number].all |= 1 << bit_number; + else + modbus_table_discret_out[word_number].all &= ~(1 << bit_number); + } + } +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int getRegisterDiscreteOutput(int adres) { + int word_number = 0; + int bit_number = 0; + + if (adres >= 0 && adres < SIZE_MODBUS_TABLE_DISCRET_BITS) { + word_number = adres / 16; + bit_number = adres % 16; + return (modbus_table_discret_out[word_number].all >> bit_number) & 1; + } + + return 0; +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int readDiscreteOutputsFromRemote() +{ + int succed = 0; + static unsigned int time_tick_modbus = 0; + static unsigned int old_PWM_ticks = 0; + static unsigned int count_write_to_modbus = 0; + static int cur_position_buf_modbus1 = 0; + + ModbusRTUsetDiscretDataArray(modbus_table_discret_out, modbus_table_discret_out); + +// if (global_time.pwm_tics != old_PWM_ticks) +// { +// if (global_time.pwm_tics > old_PWM_ticks) +// time_tick_modbus = time_tick_modbus + (global_time.pwm_tics - old_PWM_ticks); +// else +// time_tick_modbus++; +// } +// old_PWM_ticks = global_time.pwm_tics; +// if (TIME_PAUSE_MODBUS < time_tick_modbus) +// { + if (!rs_b.flag_LEADING) + { +// time_tick_modbus = 0; + + if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) + cur_position_buf_modbus1 = cur_position_buf_modbus1 + SIZE_BUF_WRITE_TO_MODBUS1_REMOUTE; + + if (cur_position_buf_modbus1 >= SIZE_MODBUS_TABLE_DISCRET_REMOUTE) + cur_position_buf_modbus1 = 0; + + if ((cur_position_buf_modbus1 + SIZE_BUF_WRITE_TO_MODBUS1_REMOUTE) > SIZE_MODBUS_TABLE_DISCRET_REMOUTE) + count_write_to_modbus = SIZE_MODBUS_TABLE_DISCRET_REMOUTE - cur_position_buf_modbus1; + else + count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS1_REMOUTE; + + ModbusRTUsend1(&rs_b, 2, + ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus1, + count_write_to_modbus); + succed = 1; + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + } +// } + return succed; +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int writeSigleDiscreteDataToRemote(unsigned int adres) +{ + ModbusRTUsetDiscretDataArray(modbus_table_discret_out, modbus_table_discret_out); + if (!rs_b.flag_LEADING && !control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] && + (adres < SIZE_MODBUS_TABLE_DISCRET_BITS)) { + ModbusRTUsend5(&rs_b, 2, ADR_MODBUS_TABLE_REMOUTE + adres); + return 1; + } + return 0; +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int writeSingleAnalogOutputToRemote(unsigned int adres) +{ + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + if (!rs_b.flag_LEADING && !control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] && + (adres < SIZE_MODBUS_ANALOG_REMOUTE)) { + ModbusRTUsend6(&rs_b, 2, ADR_MODBUS_TABLE_REMOUTE + adres); + return 1; + } + return 0; +} + + + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int writeDiscreteDataToRemote() +{ + int succed = 0; + static unsigned int old_time = 0; + + static unsigned int count_write_to_modbus = 0; + static int cur_position_buf_modbus15 = 0; + + //ModbusRTUsetDiscretDataArray(modbus_table_discret_out, modbus_table_discret_out); + ModbusRTUsetDiscretDataArray(modbus_table_discret_in, modbus_table_discret_out); + + + if (!rs_b.flag_LEADING) + { + +// if (rs_b.RS_DataReadyAnswerAnalyze) +// { +// cur_position_buf_modbus15 += SIZE_BUF_WRITE_TO_MODBUS15_REMOUTE; +// } + + if (cur_position_buf_modbus15 >= (SIZE_MODBUS_TABLE_DISCRET_REMOUTE)) + cur_position_buf_modbus15 = 0; + + if ((cur_position_buf_modbus15 + SIZE_BUF_WRITE_TO_MODBUS15_REMOUTE) > (SIZE_MODBUS_TABLE_DISCRET_REMOUTE)) + count_write_to_modbus = SIZE_MODBUS_TABLE_DISCRET_REMOUTE - cur_position_buf_modbus15; + else + count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS15_REMOUTE; + + // count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16; + // cur_position_buf_modbus=0; + + ModbusRTUsend15(&rs_b, 2, ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus15*16, + count_write_to_modbus*16); +// ModbusRTUsend15(&rs_a, 2, ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus15*16, +// count_write_to_modbus*16); + + cur_position_buf_modbus15 += SIZE_BUF_WRITE_TO_MODBUS15_REMOUTE; + + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + // control_station.count_error_modbus_15[CONTROL_STATION_INGETEAM_PULT_RS485]++; + + // hmi_watch_dog = !hmi_watch_dog; //was transmitted, need to change + succed = 1; + + } + return succed; +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +#define ADRESS_END_FIRST_BLOCK 20 +#define ADRESS_START_PROTECTION_LEVELS 91 + +int readAnalogDataFromRemote() +{ + int succed = 0; + static unsigned int old_time = 0; + + static unsigned int count_write_to_modbus = 0; + static int cur_position_buf_modbus3 = 0, size_buf = SIZE_BUF_READ_FROM_MODBUS16_REMOUTE; + + + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + + + + if (!rs_b.flag_LEADING) + { + + if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) + cur_position_buf_modbus3 = cur_position_buf_modbus3 + size_buf; + + if (cur_position_buf_modbus3 >= SIZE_ANALOG_DATA_FROM_MODBUS16_REMOUTE) + cur_position_buf_modbus3 = 0; + //����� � ������. ����������. + if ((cur_position_buf_modbus3 > ADRESS_END_FIRST_BLOCK) && + (cur_position_buf_modbus3 < ADRESS_START_PROTECTION_LEVELS)) { + cur_position_buf_modbus3 = ADRESS_START_PROTECTION_LEVELS; + } + if((cur_position_buf_modbus3 < ADRESS_END_FIRST_BLOCK) && + (cur_position_buf_modbus3 + size_buf) > ADRESS_END_FIRST_BLOCK) { + count_write_to_modbus = ADRESS_END_FIRST_BLOCK - cur_position_buf_modbus3; + } + + if ((cur_position_buf_modbus3 + size_buf) > SIZE_ANALOG_DATA_FROM_MODBUS16_REMOUTE) + count_write_to_modbus = SIZE_ANALOG_DATA_FROM_MODBUS16_REMOUTE - cur_position_buf_modbus3; + else + count_write_to_modbus = size_buf; + + // count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16; + // cur_position_buf_modbus=0; + + + // SendCommandModbus3(&rs_b,1,ADR_MODBUS_TABLE+cur_position_buf_modbus3,count_write_to_modbus); + ModbusRTUsend4(&rs_b, 2, + ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus3, + count_write_to_modbus); + // control_station.count_error_modbus_4[CONTROL_STATION_INGETEAM_PULT_RS485]++; + + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + succed = 1; + } + return succed; +} + + +int writeSingleAnalogDataToRemote(int from_adr, int count_wr) +{ + int succed = 0; + static unsigned int old_time = 0; + + static int count_write_to_modbus = 0; + static int cur_position_buf_modbus16 = 0; + + + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + + + if (!rs_b.flag_LEADING) + { + cur_position_buf_modbus16 = from_adr; + +// if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) +// cur_position_buf_modbus16 = cur_position_buf_modbus16 + SIZE_BUF_WRITE_TO_MODBUS16_REMOUTE; +// +// if (cur_position_buf_modbus16 >= SIZE_ANALOG_DATA_REMOUTE) +// cur_position_buf_modbus16 = 0; + +// //����� � ������. ����������. +// if ((cur_position_buf_modbus16 > ADRESS_END_FIRST_BLOCK) && +// (cur_position_buf_modbus16 < ADRESS_START_PROTECTION_LEVELS)) { +// cur_position_buf_modbus16 = ADRESS_START_PROTECTION_LEVELS; +// } + + if ((cur_position_buf_modbus16 + count_wr) > SIZE_ANALOG_DATA_REMOUTE) + count_write_to_modbus = SIZE_ANALOG_DATA_REMOUTE - cur_position_buf_modbus16; + else + count_write_to_modbus = count_wr; + + ModbusRTUsend16(&rs_b, 2, + ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus16, + count_write_to_modbus); + + succed = 1; + } + return succed; +} + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +int writeAnalogDataToRemote() +{ + int succed = 0; + static unsigned int old_time = 0; + + static int count_write_to_modbus = 0; + static int cur_position_buf_modbus16 = 0; + + + ModbusRTUsetDataArrays(modbus_table_analog_in, modbus_table_analog_out); + + + if (!rs_b.flag_LEADING) + { + if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485] == 0) + cur_position_buf_modbus16 = cur_position_buf_modbus16 + SIZE_BUF_WRITE_TO_MODBUS16_REMOUTE; + + if (cur_position_buf_modbus16 >= SIZE_ANALOG_DATA_REMOUTE) + cur_position_buf_modbus16 = 0; + +// //����� � ������. ����������. +// if ((cur_position_buf_modbus16 > ADRESS_END_FIRST_BLOCK) && +// (cur_position_buf_modbus16 < ADRESS_START_PROTECTION_LEVELS)) { +// cur_position_buf_modbus16 = ADRESS_START_PROTECTION_LEVELS; +// } + + if ((cur_position_buf_modbus16 + SIZE_BUF_WRITE_TO_MODBUS16_REMOUTE) > SIZE_ANALOG_DATA_REMOUTE) + count_write_to_modbus = SIZE_ANALOG_DATA_REMOUTE - cur_position_buf_modbus16; + else + count_write_to_modbus = SIZE_BUF_WRITE_TO_MODBUS16_REMOUTE; + + ModbusRTUsend16(&rs_b, 2, + ADR_MODBUS_TABLE_REMOUTE + cur_position_buf_modbus16, + count_write_to_modbus); + // control_station.count_error_modbus_16[CONTROL_STATION_INGETEAM_PULT_RS485]++; + + // control_station.flag_message_sent[CONTROL_STATION_INGETEAM_PULT_RS485] = 1; + succed = 1; + } + return succed; +} + + + + + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + + + diff --git a/Inu/Src/main/modbus_hmi.h b/Inu/Src/main/modbus_hmi.h new file mode 100644 index 0000000..887b537 --- /dev/null +++ b/Inu/Src/main/modbus_hmi.h @@ -0,0 +1,39 @@ +#ifndef _MODBUS_HMI +#define _MODBUS_HMI + +#include "modbus_struct.h" + + +int readDiscreteOutputsFromRemote(); +int writeSigleDiscreteDataToRemote(unsigned int adres); +int writeSingleAnalogOutputToRemote(unsigned int adres); +int writeDiscreteDataToRemote(); +int readAnalogDataFromRemote(); +int writeAnalogDataToRemote(); +int writeSingleAnalogDataToRemote(int from_adr, int count_wr); + +void setRegisterDiscreteOutput(int value, int adres); +int getRegisterDiscreteOutput(int adres); + + + + +void clear_table_remoute(void); // clear table + +#define ADRES_LOG_REGISTERS 100 + + +#define SIZE_MODBUS_TABLE_DISCRET_REMOUTE 36 +#define SIZE_MODBUS_TABLE_DISCRET_BITS (SIZE_MODBUS_TABLE_DISCRET_REMOUTE * 16) +#define SIZE_MODBUS_ANALOG_REMOUTE 900 + + +extern MODBUS_REG_STRUCT modbus_table_analog_in[SIZE_MODBUS_ANALOG_REMOUTE]; +extern MODBUS_REG_STRUCT modbus_table_analog_out[SIZE_MODBUS_ANALOG_REMOUTE]; +extern MODBUS_REG_STRUCT modbus_table_discret_in[SIZE_MODBUS_TABLE_DISCRET_REMOUTE]; +extern MODBUS_REG_STRUCT modbus_table_discret_out[SIZE_MODBUS_TABLE_DISCRET_REMOUTE]; + +//extern unsigned int flag_waiting_answer; +//extern unsigned int flag_message_sent; + +#endif //_MODBUS_HMI diff --git a/Inu/Src/main/modbus_hmi_read.c b/Inu/Src/main/modbus_hmi_read.c new file mode 100644 index 0000000..9718943 --- /dev/null +++ b/Inu/Src/main/modbus_hmi_read.c @@ -0,0 +1,222 @@ +/* + * modbus_hmi_read.c + * + * Created on: 21 ���. 2020 �. + * Author: star + */ +#include <adc_tools.h> +#include <edrk_main.h> +#include <modbus_hmi.h> +#include <modbus_hmi_read.h> +#include <protect_levels.h> + + +#define DELTA_ABNORMAL_P_WATER_MIN 50 +#define DELTA_ABNORMAL_P_WATER_MAX 100 + +void parse_protect_levels_HMI() { + + if (modbus_table_analog_in[91].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_U1 = modbus_table_analog_in[91].all * 10; + } + if(modbus_table_analog_in[92].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_V1 = modbus_table_analog_in[92].all * 10; + } + if(modbus_table_analog_in[93].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_W1 = modbus_table_analog_in[93].all * 10; + } + if (modbus_table_analog_in[94].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_U2 = modbus_table_analog_in[94].all * 10; + } + if (modbus_table_analog_in[95].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_V2 = modbus_table_analog_in[95].all * 10; + } + if (modbus_table_analog_in[96].all > 0) { + protect_levels.abnormal_temper_acdrive_winding_W2 = modbus_table_analog_in[96].all * 10; + } + if (modbus_table_analog_in[97].all > 0) { + protect_levels.abnormal_temper_acdrive_bear_DNE = modbus_table_analog_in[97].all * 10; + } + if(modbus_table_analog_in[98].all > 0) { + protect_levels.abnormal_temper_acdrive_bear_NE = modbus_table_analog_in[98].all * 10; + } + + if (modbus_table_analog_in[99].all > 0) { + protect_levels.alarm_temper_acdrive_winding_U1 = modbus_table_analog_in[99].all * 10; + } + if (modbus_table_analog_in[100].all > 0) { + protect_levels.alarm_temper_acdrive_winding_V1 = modbus_table_analog_in[100].all * 10; + } + if (modbus_table_analog_in[101].all > 0) { + protect_levels.alarm_temper_acdrive_winding_W1 = modbus_table_analog_in[101].all * 10; + } + if (modbus_table_analog_in[102].all > 0) { + protect_levels.alarm_temper_acdrive_winding_U2 = modbus_table_analog_in[102].all * 10; + } + if (modbus_table_analog_in[103].all > 0) { + protect_levels.alarm_temper_acdrive_winding_V2 = modbus_table_analog_in[103].all * 10; + } + if (modbus_table_analog_in[104].all > 0) { + protect_levels.alarm_temper_acdrive_winding_W2 = modbus_table_analog_in[104].all * 10; + } + if (modbus_table_analog_in[105].all > 0) { + protect_levels.alarm_temper_acdrive_bear_DNE = modbus_table_analog_in[105].all * 10; + } + if (modbus_table_analog_in[106].all > 0) { + protect_levels.alarm_temper_acdrive_bear_NE = modbus_table_analog_in[106].all * 10; + } + + if (modbus_table_analog_in[107].all > 0) { + protect_levels.abnormal_temper_u_01 = modbus_table_analog_in[107].all * 10; + } + if (modbus_table_analog_in[108].all > 0) { + protect_levels.abnormal_temper_u_02 = modbus_table_analog_in[108].all * 10; + } + if (modbus_table_analog_in[109].all > 0) { + protect_levels.abnormal_temper_u_03 = modbus_table_analog_in[109].all * 10; + } + if (modbus_table_analog_in[110].all > 0) { + protect_levels.abnormal_temper_u_04 = modbus_table_analog_in[110].all * 10; + } + if (modbus_table_analog_in[111].all > 0) { + protect_levels.abnormal_temper_u_05 = modbus_table_analog_in[111].all * 10; + } + if (modbus_table_analog_in[112].all > 0) { + protect_levels.abnormal_temper_u_06 = modbus_table_analog_in[112].all * 10; + } + if (modbus_table_analog_in[113].all > 0) { + protect_levels.abnormal_temper_u_07 = modbus_table_analog_in[113].all * 10; + } + if (modbus_table_analog_in[114].all > 0) { + protect_levels.alarm_temper_u_01 = modbus_table_analog_in[114].all * 10; + } + if (modbus_table_analog_in[115].all > 0) { + protect_levels.alarm_temper_u_02 = modbus_table_analog_in[115].all * 10; + } + if (modbus_table_analog_in[116].all > 0) { + protect_levels.alarm_temper_u_03 = modbus_table_analog_in[116].all * 10; + } + if (modbus_table_analog_in[117].all > 0) { + protect_levels.alarm_temper_u_04 = modbus_table_analog_in[117].all * 10; + } + if (modbus_table_analog_in[118].all > 0) { + protect_levels.alarm_temper_u_05 = modbus_table_analog_in[118].all * 10; + } + if (modbus_table_analog_in[119].all > 0) { + protect_levels.alarm_temper_u_06 = modbus_table_analog_in[119].all * 10; + } + if (modbus_table_analog_in[120].all > 0) { + protect_levels.alarm_temper_u_07 = modbus_table_analog_in[120].all * 10; + } + + if (modbus_table_analog_in[123].all > 0) { + protect_levels.abnormal_temper_water_int = modbus_table_analog_in[123].all * 10; + } + if (modbus_table_analog_in[124].all > 0) { + protect_levels.abnormal_temper_water_ext = modbus_table_analog_in[124].all * 10; + } + if (modbus_table_analog_in[125].all > 0) { + protect_levels.alarm_p_water_min_int = modbus_table_analog_in[125].all * 10; + protect_levels.abnormal_p_water_min_int = protect_levels.alarm_p_water_min_int + DELTA_ABNORMAL_P_WATER_MIN; + } + if (modbus_table_analog_in[126].all > 0) { + protect_levels.alarm_temper_water_int = modbus_table_analog_in[126].all * 10; + } + if (modbus_table_analog_in[127].all > 0) { + protect_levels.alarm_temper_water_ext = modbus_table_analog_in[127].all * 10; + } + if (modbus_table_analog_in[128].all > 0) { + protect_levels.alarm_p_water_max_int = modbus_table_analog_in[128].all * 10; + protect_levels.abnormal_p_water_max_int = protect_levels.alarm_p_water_max_int - DELTA_ABNORMAL_P_WATER_MAX; + } + + if (modbus_table_analog_in[129].all > 0) { + protect_levels.abnormal_temper_air_int_01 = modbus_table_analog_in[129].all * 10; + } + if (modbus_table_analog_in[130].all > 0) { + protect_levels.abnormal_temper_air_int_02 = modbus_table_analog_in[130].all * 10; + } + if (modbus_table_analog_in[131].all > 0) { + protect_levels.abnormal_temper_air_int_03 = modbus_table_analog_in[131].all * 10; + } + if (modbus_table_analog_in[132].all > 0) { + protect_levels.abnormal_temper_air_int_04 = modbus_table_analog_in[132].all * 10; + } + if (modbus_table_analog_in[133].all > 0) { + protect_levels.alarm_temper_air_int_01 = modbus_table_analog_in[133].all * 10; + } + if (modbus_table_analog_in[134].all > 0) { + protect_levels.alarm_temper_air_int_02 = modbus_table_analog_in[134].all * 10; + } + if (modbus_table_analog_in[135].all > 0) { + protect_levels.alarm_temper_air_int_03 = modbus_table_analog_in[135].all * 10; + } + if (modbus_table_analog_in[136].all > 0) { + protect_levels.alarm_temper_air_int_04 = modbus_table_analog_in[136].all * 10; + } + + if (modbus_table_analog_in[137].all > 0) { + edrk.iqMIN_U_IN = _IQ(((float)modbus_table_analog_in[137].all) / NORMA_ACP); + } + if (modbus_table_analog_in[138].all > 0) { + edrk.iqMIN_U_IN = _IQ(((float)modbus_table_analog_in[138].all) / NORMA_ACP); + } + + if (modbus_table_analog_in[139].all > 0) { + edrk.iqMIN_U_ZPT = _IQ(((float)modbus_table_analog_in[139].all) / NORMA_ACP); + } + if (modbus_table_analog_in[140].all > 0) { + edrk.iqMIN_U_ZPT = _IQ(((float)modbus_table_analog_in[140].all) / NORMA_ACP); + } + + if (modbus_table_analog_in[142].all > 0) { + edrk.iqMAX_U_IN = _IQ(((float)modbus_table_analog_in[142].all) / NORMA_ACP); + } + if (modbus_table_analog_in[143].all > 0) { + edrk.iqMAX_U_IN = _IQ(((float)modbus_table_analog_in[143].all) / NORMA_ACP); + } + + if (modbus_table_analog_in[144].all > 0) { + edrk.iqMAX_U_ZPT = _IQ(((float)modbus_table_analog_in[144].all) / NORMA_ACP); + } + if (modbus_table_analog_in[145].all > 0) { + edrk.iqMAX_U_ZPT = _IQ(((float)modbus_table_analog_in[145].all) / NORMA_ACP); + } + + if (modbus_table_analog_in[146].all > 0) { + protect_levels.alarm_Izpt_max = modbus_table_analog_in[146].all; + } + + if (modbus_table_analog_in[155].all > 0) { + protect_levels.alarm_Imax_U01 = modbus_table_analog_in[155].all; + } + if (modbus_table_analog_in[156].all > 0) { + protect_levels.alarm_Imax_U02 = modbus_table_analog_in[156].all; + } + if (modbus_table_analog_in[157].all > 0) { + protect_levels.alarm_Imax_U03 = modbus_table_analog_in[157].all; + } + if (modbus_table_analog_in[158].all > 0) { + protect_levels.alarm_Imax_U04 = modbus_table_analog_in[158].all; + } + if (modbus_table_analog_in[159].all > 0) { + protect_levels.alarm_Imax_U05 = modbus_table_analog_in[159].all; + } + if (modbus_table_analog_in[160].all > 0) { + protect_levels.alarm_Imax_U06 = modbus_table_analog_in[160].all; + } + if (modbus_table_analog_in[161].all > 0) { + protect_levels.alarm_Imax_U07 = modbus_table_analog_in[161].all; + } + if (modbus_table_analog_in[162].all > 0) { + protect_levels.alarm_Iged_max = modbus_table_analog_in[162].all; + } + + + + + +} + + + diff --git a/Inu/Src/main/modbus_hmi_read.h b/Inu/Src/main/modbus_hmi_read.h new file mode 100644 index 0000000..7f3e0db --- /dev/null +++ b/Inu/Src/main/modbus_hmi_read.h @@ -0,0 +1,15 @@ +/* + * modbus_hmi_read.h + * + * Created on: 21 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_MODBUS_HMI_READ_H_ +#define SRC_MAIN_MODBUS_HMI_READ_H_ + + +void parse_protect_levels_HMI(void); + + +#endif /* SRC_MAIN_MODBUS_HMI_READ_H_ */ diff --git a/Inu/Src/main/modbus_hmi_update.c b/Inu/Src/main/modbus_hmi_update.c new file mode 100644 index 0000000..7c1e83c --- /dev/null +++ b/Inu/Src/main/modbus_hmi_update.c @@ -0,0 +1,2022 @@ +#include <adc_tools.h> +#include <detect_errors_adc.h> +#include <edrk_main.h> +#include <math.h> +#include <message_modbus.h> +#include <modbus_hmi.h> +#include <modbus_hmi_read.h> +#include <modbus_hmi_update.h> +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <project.h> +#include <protect_levels.h> +#include <pump_control.h> +#include <v_rotor.h> +#include <vector.h> +#include "edrk_main.h" +#include "global_time.h" +#include "control_station.h" +#include "CAN_Setup.h" +#include "global_time.h" +#include "RS_Functions.h" +#include "mathlib.h" +#include "logs_hmi.h" +#include "detect_errors.h" +/* +#include "mathlib.h" +#include <math.h> +#include "IQmathLib.h" +*/ +int hmi_watch_dog = 0; +int prev_kvitir = 0; +int prev_sbor = 0; +int kvitir1 = 0; +int sbor1 = 0; +int razbor1 = 0; + +//30001 ResetErrors command to controller to reset errors 1-reset +//30002 SchemeAssemble Command to change scheme state 0-scheme dissasemble 1- assemble +//30003 IsPowerSetMode 0-control enigine by turnovers, 1- by power +//30004 SpecifiedPower Power set by user +//30005 SpecifiedTurnovers Turnovers set by user + +//30006 UserValueUpdated command to controller to update set value 1-ative + +//30007 ReportGet Command to get report 1-get 0- nothinhg +//30008 ReportArraySaved Sets to 1 when HMI is ready to get array(part of report) +//30009 PumpsControlMode Pumps Control mode. 0 = auto, 1= pump 1, 2= pump 2 + +//30010 MotoHoursPanel �������� ������� (������) +//30011 MotoHoursFan1 �������� ������ ������������ 1 (������) +//30012 MotoHoursFan2 �������� ������ ������������ 2 (������) +//30013 MotoHoursPump1 �������� ��������� ������ (������) +//30014 MotoHoursPump2 �������� ���������� ������ (������) +//30015 MotoHoursInvertorCharged �������� � ��������� ""������� ����� �������"" (������) +//30016 MotoHoursInvertorGo �������� � ��������� ""���"" (������) +//30017 MotoHoursInvertorGoFault �������� � ��������� ""��� � ��������������"" (������) +//30018 MotoHoursInvertorAlarm �������� � ��������� ""������"" (������) + +#define COUNT_ANALOG_DATA_FROM_INGETEAM SIZE_ANALOG_DATA_REMOUTE //(18+1) +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +void func_unpack_answer_from_Ingeteam(unsigned int cc) +{ + // ����������y ����� + unsigned int DataOut; + int Data, Data1, Data2, DataAnalog1, DataAnalog2, DataAnalog3, DataAnalog4, i; + unsigned int h; + volatile unsigned char *pByte; + // static int vs11,vs12,vs1; + // static int DataCnt=0; + // int GoT,Assemble_scheme; + // static int prev_temp_Rele1=0, temp_Rele1=0, prev_temp_Rele2=0, temp_Rele2=0; + + static int flag_prev_turn_on = 0; + static int flag_prev_turn_off = 0; + static int prev_byte01_bit4 = 0; + static int prev_byte01_bit1 = 0; + static int flag_wait_revers_sbor = 1; + static int flag_wait_revers_go = 1; + + static unsigned int count_transmited = 0; + + + // ��������� ���y ������� + // ��� ��� ���� ������� ���� + + if (COUNT_ANALOG_DATA_FROM_INGETEAM > CONTROL_STATION_MAX_RAW_DATA) + xerror(main_er_ID(2),(void *)0); + + for (h=1;h<COUNT_ANALOG_DATA_FROM_INGETEAM;h++) + control_station.raw_array_data[cc][h].all = modbus_table_analog_in[h].all; + + +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + +void get_command_HMI(void) +{ + + int i; + static int prev_send_log = -1; + + ///////////////// + ///////////////// + ///////////////// + + edrk.pult_cmd.kvitir = modbus_table_analog_in[1].all; + edrk.pult_cmd.sbor = modbus_table_analog_in[2].all; + edrk.pult_cmd.send_log = modbus_table_analog_in[7].all; + edrk.pult_cmd.pump_mode = modbus_table_analog_in[9].all; + + + // mode_pump = modbus_table_analog_in[9].all; + // 0 - auto on - rand pump + // 1 - auto on 1 pump + // 2 - auto on 2 pump + // 3 - manual on 1 pump + // 4 - manual on 2 pump + ////////////////////// + pumps.pump1_engine_minutes = modbus_table_analog_in[13].all; + pumps.pump2_engine_minutes = modbus_table_analog_in[14].all; + + + edrk.pult_data.data_from_pult.nPCH = modbus_table_analog_in[34].all; + edrk.pult_data.data_from_pult.TimeToChangePump = modbus_table_analog_in[164].all; + + edrk.pult_data.data_from_pult.count_build = modbus_table_analog_in[31].all; + edrk.pult_data.data_from_pult.count_revers = modbus_table_analog_in[32].all; + + edrk.pult_data.data_from_pult.LastWorkPump = modbus_table_analog_in[36].all; + + // + //������ ����� � ������ ����� ������ � �������� 30033: + //�������� 0 - ��� �� ������, �� �����; + //�������� 1 - ��� ������, ���� �����; + //�������� 2 - ���� ������, ��� �����; + //�������� 3 - ���� � ������ � �����; + + edrk.pult_cmd.log_what_memory = modbus_table_analog_in[33].all; + + + edrk.pult_cmd.sdusb = modbus_table_analog_in[35].all; + + + //moto + for (i=0;i<COUNT_MOTO_PULT;i++) + edrk.pult_data.data_from_pult.moto[i] = modbus_table_analog_in[10+i].all; + + + ///////////////// + ///////////////// + ///////////////// + ///////////////// + ///////////////// + + if (edrk.pult_cmd.kvitir == 1) + { + if (prev_kvitir==0) + kvitir1 = 1; + } + else + kvitir1 = 0; + +// edrk.KvitirDISPLAY = kvitir1; +// edrk.from_display.bits.KVITIR = kvitir1; + + control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_CHECKBACK] = kvitir1; + + prev_kvitir = edrk.pult_cmd.kvitir; + + + ///////////////// + ///////////////// + ///////////////// + ///////////////// + ///////////////// + ///////////////// + + if (edrk.pult_cmd.sbor == 1) + { + if (prev_sbor==0) + { + sbor1 = 1; + } + razbor1 = 0; + } + else + { + if (prev_sbor==1) + { + razbor1 = 1; + } + sbor1 = 0; + + } + edrk.from_display.bits.SBOR_SHEMA = sbor1; +// edrk.from_display.bits.RAZBOR_SHEMA = razbor1; + prev_sbor = edrk.pult_cmd.sbor; + + ///////////////// + ///////////////// + ///////////////// + ///////////////// + + if (prev_send_log>=0 && prev_send_log != edrk.pult_cmd.send_log) + { + if (edrk.pult_cmd.send_log) + log_to_HMI.send_log = edrk.pult_cmd.send_log; + + log_to_HMI.sdusb = edrk.pult_cmd.sdusb; + + } +// else +// log_to_HMI.send_log = 0; + + prev_send_log = edrk.pult_cmd.send_log; + + ///////////////// + ///////////////// + ///////////////// + + control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MODE_PUMP] = edrk.pult_cmd.pump_mode; + + +// +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_PUMP] = modbus_table_analog_in[188].all; +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_QTV] = modbus_table_analog_in[189].all; +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_DISABLE_ON_UMP] = modbus_table_analog_in[190].all; +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_ENABLE_ON_CHARGE] = modbus_table_analog_in[191].all; +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_MANUAL_DISCHARGE] = modbus_table_analog_in[180].all; +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_GO] = !modbus_table_analog_in[192].all; +// +// control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_] = modbus_table_analog_in[188].all; + + ///////////////// + ///////////////// + ///////////////// + ///////////////// + + parse_protect_levels_HMI(); + +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + +int update_progress_load_hmi(int proc_load) +{ + static unsigned int old_time_5 = 0; + volatile int perc_load=0, final_code = 0, c_l = 0; + +// return 0; + + update_tables_HMI_on_inited(proc_load); + + + old_time_5 = global_time.miliseconds; + do + { + + if (final_code >= 4) + { + return 1; + } + +// if (control_station.flag_waiting_answer[CONTROL_STATION_INGETEAM_PULT_RS485]==0) +// final_code = modbusNetworkSharing(0); +// else + final_code = modbusNetworkSharing(1); + +// RS232_WorkingWith(0,1,0); + + } + while (detect_pause_milisec(1500, &old_time_5)==0);//(100,&old_time)); + + return 0; + + + +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + + +void update_tables_HMI_on_inited(int perc_load) +{ + Inverter_state state; + static int nn=0, ss=0; + static int prev_edrk_KVITIR=0; + int i,status; + +// log_to_HMI.send_log = modbus_table_analog_in[7].all; + //setRegisterDiscreteOutput(log_to_HMI.flag_log_array_ready_sent, 310); + + // LoadMode Read 00544 00544 ����� �������� ������������ ����������� + setRegisterDiscreteOutput(0, 544);// + + // Loading ReadWrite 30088 40088 ����������� �������� 0-10 + modbus_table_analog_out[88].all = perc_load; + + // ��� �������� ������ ������ + modbus_table_analog_out[4].all++; + + + // build version + modbus_table_analog_out[219].all = edrk.buildYear; + modbus_table_analog_out[220].all = edrk.buildMonth; + modbus_table_analog_out[221].all = edrk.buildDay; + + +} + +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +void update_tables_HMI_discrete(void) +{ + int real_box; + // ��� ���� ������������ ���������!!! + // if (edrk.from_display.bits.KVITIR) + // setRegisterDiscreteOutput(edrk.from_display.bits.KVITIR, 301); + setRegisterDiscreteOutput(control_station.array_cmd[CONTROL_STATION_INGETEAM_PULT_RS485][CONTROL_STATION_CMD_CHECKBACK], 513); + // prev_edrk_KVITIR = edrk.from_display.bits.KVITIR; + ///// + + //setRegisterDiscreteOutput(edrk.RemouteFromDISPLAY, 302); + setRegisterDiscreteOutput(control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485], 514); + + setRegisterDiscreteOutput(hmi_watch_dog, 515); + + + setRegisterDiscreteOutput(edrk.StatusFunAll, 516); + setRegisterDiscreteOutput(edrk.StatusFunAll, 517); + + setRegisterDiscreteOutput(edrk.StatusPump0, 518); + setRegisterDiscreteOutput(edrk.StatusPump1, 519); + + setRegisterDiscreteOutput(edrk.from_shema_filter.bits.SVU,524); + setRegisterDiscreteOutput(edrk.from_shema_filter.bits.ZADA_DISPLAY,525); + // �������_�������������_����������_�� Read 00523 + // �������_�������������_����������_��� Read 00524 + // �������_��������_����� Read 00525 + + + setRegisterDiscreteOutput(edrk.from_ing1.bits.OHLAD_UTE4KA_WATER, 526);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.NASOS_NORMA, 527);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.OP_PIT_NORMA, 528);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.UPC_24V_NORMA, 529);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.ALL_KNOPKA_AVARIA, 530);// + setRegisterDiscreteOutput(edrk.SumSbor, 531);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.ZARYAD_ON, 532);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.VIPR_PREDOHR_NORMA, 533);// + setRegisterDiscreteOutput(!edrk.temper_limit_koeffs.code_status, 534);// + // setRegisterDiscreteOutput(1, 331);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.ZAZEML_ON, 535);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.NAGREV_ON, 536);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.BLOCK_IZOL_NORMA, 537);// + setRegisterDiscreteOutput(edrk.from_ing1.bits.BLOCK_IZOL_AVARIA, 538);// + + ////////////// + // schemeStateOnController ReadWrite 00539 00539 ��������� ����� �� ����������� 0 - ���������, 1-������� + // StateAnotherPowerChannel Read 00540 00540 ��������� ������� �������� ������: 0 - ��� ������, 1 ������ + // InterfaceOpticalBus Read 00541 00541 ��������� ���������� ����: 0 - ��� ������, 1 - ���� ����� + // StateDriver Read 00542 00542 ��������� �������: 0 - �� ��������� � ������� ���, 1 - ��������� � ������� ��� + // NumberPowerChannel Read 00543 00543 ����� �������� ������: 0 - ������, 1 - ������ + + + setRegisterDiscreteOutput(edrk.Status_Ready.bits.ready_final, 539); + setRegisterDiscreteOutput(edrk.errors.e7.bits.ANOTHER_BS_ALARM, 540); + setRegisterDiscreteOutput(optical_read_data.status == 1 && optical_write_data.status == 1 ? 1 : 0, 541); + setRegisterDiscreteOutput(edrk.Status_Rascepitel_Ok, 542); + + if (edrk.flag_second_PCH==0) + setRegisterDiscreteOutput(0, 543); + else + setRegisterDiscreteOutput(1, 543); + + // LoadMode Read 00544 00544 ����� �������� ������������ ����������� + setRegisterDiscreteOutput(1, 544); // + + // Loading ReadWrite 30088 40088 ����������� �������� 0-10 + + setRegisterDiscreteOutput(control_station.active_array_cmd[CONTROL_STATION_CMD_BLOCK_BS] + || edrk.from_shema.bits.SVU_BLOCK_QTV, 545); + ////////////// + + + + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_ack, 17);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_ack, 18);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_ack, 19);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_ack, 20);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_ack, 21);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_ack, 22);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_ack, 23);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_ack, 24);// + + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_ack, 25);// + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_ack, 26);// + ///////////////////// + if (edrk.flag_second_PCH==0) + setRegisterDiscreteOutput(edrk.errors.e4.bits.ANOTHER_BS_POWER_OFF, 27); + else + setRegisterDiscreteOutput(edrk.errors.e4.bits.ANOTHER_BS_POWER_OFF, 28); + + + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_current, 33);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_current, 34);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_current, 35);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_current, 36);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_current, 37);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_current, 38);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_current, 39);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_current, 40);// + + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_current, 41);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_current, 42);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_current, 43);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_current, 44);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_current, 45);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_current, 46);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_current, 47);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_current, 48);// + + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_current, 49);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_current, 50);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_current, 51);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_current, 52);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_current, 53);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_current, 54);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_current, 55);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_current, 56);// + + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_current, 57);// + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_current, 58);// + ////////////////////////// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 65);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 66);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 67);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 68);// + + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 69);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 70);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 71);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 72);// + + + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 73);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 74);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 75);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 76);// + + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 77);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 78);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 79);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 80);// + + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 81);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 82);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 83);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 84);// + + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 85);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 86);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 87);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654, 88);// + + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 89);// + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_3210, 90);// + + ///////////////// + + + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_TK_0, 97);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_TK_1, 98);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_TK_2, 99);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_TK_3, 100);// + + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_IN_0, 101);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_IN_1, 102);// + + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_OUT_0, 103);// + // setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_OUT_1, 105);// + + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_ADC_0, 104);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_HWP_0, 105);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_ADC_1, 106);// + + setRegisterDiscreteOutput(edrk.errors.e3.bits.NOT_READY_CONTR, 107);// + + + /////////////////// + + + setRegisterDiscreteOutput(edrk.errors.e5.bits.KEY_AVARIA, 113);// + + setRegisterDiscreteOutput(edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER, 114); + setRegisterDiscreteOutput(edrk.errors.e7.bits.SVU_BLOCK_ON_QTV + || control_station.active_array_cmd[CONTROL_STATION_CMD_BLOCK_BS], 115); + setRegisterDiscreteOutput(edrk.errors.e7.bits.UMP_NOT_ANSWER, 116); + setRegisterDiscreteOutput(edrk.errors.e7.bits.UMP_NOT_READY, 117); + setRegisterDiscreteOutput(edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER, 118); + setRegisterDiscreteOutput(edrk.errors.e7.bits.ANOTHER_RASCEPITEL_ON, 119); + + setRegisterDiscreteOutput(edrk.errors.e7.bits.AUTO_SET_MASTER, 120); + setRegisterDiscreteOutput(edrk.errors.e7.bits.ANOTHER_PCH_NOT_ANSWER, 121); + setRegisterDiscreteOutput(edrk.errors.e8.bits.WDOG_OPTICAL_BUS, 122); + setRegisterDiscreteOutput(edrk.errors.e2.bits.ERROR_RAZBOR_SHEMA, 123); + + setRegisterDiscreteOutput(edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL, 124); + + setRegisterDiscreteOutput(edrk.errors.e1.bits.ANOTHER_BS_NOT_ON_RASCEPITEL, 125); + setRegisterDiscreteOutput(edrk.errors.e1.bits.ANOTHER_BS_VERY_LONG_WAIT, 126); + setRegisterDiscreteOutput(edrk.errors.e1.bits.VERY_LONG_BOTH_READY2, 127); + setRegisterDiscreteOutput(edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE, 128); + + // setRegisterDiscreteOutput(edrk.errors.e5.bits.OP_PIT, 115);// + // setRegisterDiscreteOutput(edrk.errors.e5.bits.POWER_UPC, 116);// + /////////////////// + + setRegisterDiscreteOutput(!control_station.alive_control_station[CONTROL_STATION_ZADATCHIK_CAN], 129); + setRegisterDiscreteOutput(!control_station.alive_control_station[CONTROL_STATION_MPU_SVU_CAN], 130); + // setRegisterDiscreteOutput(CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,UMU_CAN_DEVICE)], 131); �������� �� ����� + real_box = get_real_in_mbox(UNITS_TYPE_BOX,BKSSD_CAN_DEVICE); + if (real_box != -1) + setRegisterDiscreteOutput(CAN_timeout[real_box], 132); + + real_box = get_real_in_mbox(UNITS_TYPE_BOX,VPU_CAN); + if (real_box != -1) + setRegisterDiscreteOutput(CAN_timeout[real_box], 133); + real_box = get_real_in_mbox(UNITS_TYPE_BOX,ANOTHER_BSU1_CAN_DEVICE); + if (real_box != -1) + setRegisterDiscreteOutput(CAN_timeout[real_box], 134); + setRegisterDiscreteOutput(edrk.errors.e7.bits.CAN2CAN_BS, 135); + + + if (edrk.flag_second_PCH==0) + setRegisterDiscreteOutput(edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF, 137); + else + setRegisterDiscreteOutput(edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF, 136); + + setRegisterDiscreteOutput(edrk.errors.e7.bits.ANOTHER_BS_ALARM, 138); // ; edrk.errors.e4.bits.FAST_OPTICAL_ALARM + setRegisterDiscreteOutput(edrk.warnings.e7.bits.ANOTHER_BS_ALARM, 139);// ; edrk.warnings.e4.bits.FAST_OPTICAL_ALARM + + setRegisterDiscreteOutput(edrk.warnings.e7.bits.UMP_NOT_READY, 140); + + setRegisterDiscreteOutput(edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK, 141); + setRegisterDiscreteOutput(edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK, 142); + + setRegisterDiscreteOutput(edrk.errors.e9.bits.SENSOR_ROTOR_1_2_BREAK, 143); + + + + /// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_ack, 145);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_ack, 146);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_ack, 147);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_ack, 148);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_ack, 149);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_ack, 150);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_ack, 151);// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_ack, 152);// + + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_ack, 153);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_ack, 154);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_ack, 155);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_ack, 156);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_ack, 157);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_ack, 158);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_ack, 159);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_ack, 160);// + + + + + // setRegisterDiscreteOutput(edrk.errors.e5.bits.KEY_AVARIA, 243);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.OP_PIT, 161);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.UTE4KA_WATER, 162);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.BLOCK_DOOR, 163);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON, 164);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.FAN, 165);// + + setRegisterDiscreteOutput(edrk.errors.e5.bits.PUMP_1, 166);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.PRE_READY_PUMP, 167);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_HEAT, 168);// + + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_PRED_VIPR, 170);// + + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_ISOLATE, 171);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.POWER_UPC, 172);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_GROUND_NET, 173);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.PUMP_2, 174);// + setRegisterDiscreteOutput(edrk.warnings.e5.bits.ERROR_ISOLATE, 175);// + setRegisterDiscreteOutput(edrk.warnings.e5.bits.PRE_READY_PUMP, 176);// + + + /////////////////// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_1_MAX, 177);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_2_MAX, 178);// + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_1_MIN, 179);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_2_MIN, 180);// + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_A1B1_MAX, 181);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_A2B2_MAX, 182);// + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_B1C1_MAX, 183);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_B2C2_MAX, 184);// + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_A1B1_MIN, 185);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_A2B2_MIN, 186);// + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_B1C1_MIN, 187);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_B2C2_MIN, 188);// + + + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_IN_MAX, 189);// + setRegisterDiscreteOutput(edrk.errors.e0.bits.U_IN_MIN, 190);// + + // setRegisterDiscreteOutput(edrk.errors.e0.bits.I_1_MAX, 191);// + // setRegisterDiscreteOutput(edrk.errors.e0.bits.I_2_MAX, 192);// + + + ////////////// + + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO2_MAX, 193);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO3_MAX, 194);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO4_MAX, 195);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO5_MAX, 196);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO6_MAX, 197);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_UO7_MAX, 198);// + + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_BREAK_1_MAX, 199);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.I_BREAK_2_MAX, 200);// + + // setRegisterDiscreteOutput(edrk.errors.e1.bits.HWP_ERROR, 201);// + //////////////////// + + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_AIR0_MAX, 203);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_AIR1_MAX, 204);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_AIR2_MAX, 205);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_AIR3_MAX, 206);// + + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_by_temper, 207);// + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_from_freq, 211);// + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_from_uom_fast, 212);// + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_from_SVU, 213);// + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_moment, 214);// + setRegisterDiscreteOutput(edrk.power_limit.bits.limit_Iout, 216);// + + //////////////////// + setRegisterDiscreteOutput(edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON, 209);// + setRegisterDiscreteOutput(edrk.errors.e7.bits.ERROR_SBOR_SHEMA, 210);// + + ///////////////////// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch0, 225);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch1, 226);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch2, 227);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch3, 228);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch4, 229);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch5, 230);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch6, 231);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch7, 232);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch8, 234);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch10, 235);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch11, 236);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch12, 237);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch13, 238);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch14, 239);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.plus.bit.ch15, 240);// + + + //////////////////// + setRegisterDiscreteOutput(edrk.errors.e5.bits.LINE_ERR0, 241);// + setRegisterDiscreteOutput(edrk.errors.e5.bits.LINE_HWP, 242);// + //////////////////// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch2, 243);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch3, 244);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch4, 245);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch5, 246);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch6, 247);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch7, 248);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch8, 250);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch10, 251);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch11, 252);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch12, 253);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch13, 254);// + + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch14, 255);// + setRegisterDiscreteOutput(project.hwp[0].read.comp_s.minus.bit.ch15, 256);// + + + + //////////////////// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_INPUT_A1B1, 257);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_INPUT_B1C1, 258);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_INPUT_A2B2, 259);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_INPUT_B2C2, 260);// + + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOW_FREQ_50HZ, 261);// + setRegisterDiscreteOutput(edrk.warnings.e8.bits.LOW_FREQ_50HZ, 262);// + + setRegisterDiscreteOutput(edrk.errors.e7.bits.READ_OPTBUS || edrk.errors.e7.bits.WRITE_OPTBUS, 263);// + setRegisterDiscreteOutput(edrk.errors.e7.bits.MASTER_SLAVE_SYNC, 264); // + + setRegisterDiscreteOutput(edrk.errors.e6.bits.ERR_SBUS, 265);// + setRegisterDiscreteOutput(edrk.errors.e6.bits.ERR_PBUS, 266);// + + setRegisterDiscreteOutput(edrk.errors.e6.bits.ER_DISBAL_BATT, 267);// + + setRegisterDiscreteOutput(edrk.errors.e6.bits.QTV_ERROR_NOT_U, 268);// + setRegisterDiscreteOutput(edrk.errors.e6.bits.ERROR_PRE_CHARGE_U, 269);// + + setRegisterDiscreteOutput(edrk.errors.e8.bits.U_IN_20_PROCENTS_HIGH, 270);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.U_IN_10_PROCENTS_LOW, 271);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.U_IN_20_PROCENTS_LOW, 272);// + + + //////////////// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.err_power, 273);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.err_power, 274);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.err_power, 275);// + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.lock_status_error.bit.err_power, 276);// + setRegisterDiscreteOutput(project.cds_in[0].read.sbus.lock_status_error.bit.err_power, 277);// + setRegisterDiscreteOutput(project.cds_in[1].read.sbus.lock_status_error.bit.err_power, 278);// + setRegisterDiscreteOutput(project.cds_out[0].read.sbus.lock_status_error.bit.err_power, 279);// + + + setRegisterDiscreteOutput(edrk.errors.e7.bits.NOT_VALID_CONTROL_STATION, 280);// + + //////////////// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_U1, 281);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_V1, 282);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_W1, 283);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_U2, 284);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_V2, 285);// + setRegisterDiscreteOutput(edrk.errors.e8.bits.LOSS_OUTPUT_W2, 286);// + + setRegisterDiscreteOutput(edrk.errors.e8.bits.DISBALANCE_IM1_IM2, 287);// + setRegisterDiscreteOutput(edrk.errors.e7.bits.VERY_FAST_GO_0to1, 288);// + + //////////////// + setRegisterDiscreteOutput(project.cds_tk[0].read.sbus.lock_status_error.bit.err_switch, 289);// + setRegisterDiscreteOutput(project.cds_tk[1].read.sbus.lock_status_error.bit.err_switch, 290);// + setRegisterDiscreteOutput(project.cds_tk[2].read.sbus.lock_status_error.bit.err_switch, 291);// + setRegisterDiscreteOutput(project.cds_tk[3].read.sbus.lock_status_error.bit.err_switch, 292);// + setRegisterDiscreteOutput(project.cds_in[0].read.sbus.lock_status_error.bit.err_switch, 293);// + setRegisterDiscreteOutput(project.cds_in[1].read.sbus.lock_status_error.bit.err_switch, 294);// + setRegisterDiscreteOutput(project.cds_out[0].read.sbus.lock_status_error.bit.err_switch, 295);// + + setRegisterDiscreteOutput(project.adc[0].read.sbus.lock_status_error.bit.err_switch, 296);// + setRegisterDiscreteOutput(project.adc[1].read.sbus.lock_status_error.bit.err_switch, 298);// + + //////////////// + + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO1_MAX, 305);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO2_MAX, 306);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO3_MAX, 307);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO4_MAX, 308);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO5_MAX, 309);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO6_MAX, 310);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_UO7_MAX, 311);// + + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO1_MAX, 312);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO2_MAX, 313);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO3_MAX, 314);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO4_MAX, 315);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO5_MAX, 316);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO6_MAX, 317);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_UO7_MAX, 318);// + + + + + ///////////////////// + + setRegisterDiscreteOutput(edrk.warnings.e7.bits.READ_OPTBUS || edrk.warnings.e7.bits.WRITE_OPTBUS, 321);// + setRegisterDiscreteOutput(edrk.warnings.e7.bits.MASTER_SLAVE_SYNC, 322);// + + setRegisterDiscreteOutput(edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER, 323);// + + setRegisterDiscreteOutput(edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL, 324);// + setRegisterDiscreteOutput(edrk.errors.e1.bits.NO_INPUT_SYNC_SIGNAL, 325);// + setRegisterDiscreteOutput(edrk.errors.e3.bits.ERR_INT_PWM_LONG + || edrk.errors.e9.bits.ERR_PWM_WDOG + || edrk.errors.e9.bits.ERR_INT_PWM_VERY_LONG, 326);// + + setRegisterDiscreteOutput(edrk.errors.e5.bits.T_VIPR_MAX, 336); + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_AIR0_MAX, 337); + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_AIR1_MAX, 338); + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_AIR2_MAX, 339); + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_AIR3_MAX, 340); + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_BSU_Sensor_BK1, 341); + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_BSU_Sensor_BK1, 342); + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_BSU_Sensor_BK2, 343); + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_BSU_Sensor_BK2, 344); + ////// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_WATER_EXT_MAX, 345);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.T_WATER_INT_MAX, 346);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_WATER_EXT_MAX, 347);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.T_WATER_INT_MAX, 348);// + + setRegisterDiscreteOutput(edrk.errors.e7.bits.T_ACDRIVE_BEAR_MAX_DNE, 349);// + setRegisterDiscreteOutput(edrk.errors.e9.bits.T_ACDRIVE_BEAR_MAX_NE, 350);// + setRegisterDiscreteOutput(edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE, 351);// + setRegisterDiscreteOutput(edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE, 352);// + + ////////////// + + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_U1, 353);// + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_V1, 354);// + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_W1, 355);// + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_U2, 356);// + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_V2, 357);// + setRegisterDiscreteOutput(edrk.errors.e10.bits.T_ACDRIVE_WINDING_W2, 358);// + + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1, 359);// + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1, 360);// + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1, 361);// + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2, 362);// + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2, 363);// + setRegisterDiscreteOutput(edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2, 364);// + + //////////////////// + + setRegisterDiscreteOutput(edrk.errors.e2.bits.P_WATER_INT_MAX, 369);// + setRegisterDiscreteOutput(edrk.errors.e2.bits.P_WATER_INT_MIN, 370);// + + setRegisterDiscreteOutput(edrk.warnings.e2.bits.P_WATER_INT_MAX, 371);// + setRegisterDiscreteOutput(edrk.warnings.e2.bits.P_WATER_INT_MIN, 372);// + setRegisterDiscreteOutput(edrk.warnings.e5.bits.PUMP_1, 373);// + setRegisterDiscreteOutput(edrk.warnings.e5.bits.PUMP_2, 374);// + + + + //// + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_PUMP_ON_SBOR, 385); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_RESTART_PUMP_1_ON_SBOR, 386); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_RESTART_PUMP_2_ON_SBOR, 387); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_RESTART_PUMP_ALL_ON_SBOR, 388); + + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_PRED_ZARYAD, 389); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_PRED_ZARYAD_AFTER, 390); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_READY_UMP_BEFORE_QTV, 391); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_STATUS_QTV, 392); + + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_UMP_ON_AFTER, 393); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_UMP_NOT_ON, 394); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_UMP_NOT_OFF, 395); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_RASCEPITEL_WAIT_CMD, 396); + + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_RASCEPITEL_ON_AFTER, 397); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_DISABLE_SBOR, 398); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_VERY_LONG_SBOR, 399); + setRegisterDiscreteOutput(edrk.errors.e11.bits.ERROR_CONTROLLER_BUS, 400); + + setRegisterDiscreteOutput(edrk.warnings.e9.bits.BREAK_TEMPER_WARNING, 417);// + setRegisterDiscreteOutput(edrk.warnings.e9.bits.BREAK_TEMPER_ALARM, 418);// + setRegisterDiscreteOutput(edrk.warnings.e9.bits.BREAKER_GED_ON, 419);// + + ////////////////// + + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER || + edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_POWER) { + setRegisterDiscreteOutput(1, 520); + } else { + setRegisterDiscreteOutput(0, 520); + } + // setRegisterDiscreteOutput(TODO ���������� ���, 546);// + setRegisterDiscreteOutput(!edrk.from_ing1.bits.UPC_24V_NORMA, 546);// + setRegisterDiscreteOutput(edrk.from_ing2.bits.SOST_ZAMKA, 547);// + setRegisterDiscreteOutput(edrk.from_shema_filter.bits.READY_UMP, 548);// + + + //////////////// + + +} + + + +void update_tables_HMI_analog(void) +{ + int power_kw_full; + int power_kw; + int oborots; + + Inverter_state state; + static int nn=0, ss=0, pl = 0; +// static int prev_edrk_KVITIR=0; + int i,status; +// static int check = 0; + + hmi_watch_dog = !hmi_watch_dog; //was transmitted, need to change + + //log_to_HMI.send_log = modbus_table_analog_in[7].all; + //setRegisterDiscreteOutput(log_to_HMI.flag_log_array_ready_sent, 310); + +// setRegisterDiscreteOutput(ss, nn); + + // ��� �������� ������ ������ + modbus_table_analog_out[4].all++;// = ++check; +// test +// setRegisterDiscreteOutput(1, 293); +// setRegisterDiscreteOutput(1, 294); + + + + + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + if (edrk.summ_errors) + { + modbus_table_analog_out[1].all = 6; // ������ + modbus_table_analog_out[2].all = 3; // red + } + else + { + + if (edrk.SumSbor || edrk.Status_Ready.bits.ImitationReady2) + { + if (edrk.Status_Ready.bits.ready_final) + { + //modbus_table_analog_out[2].all = 1; // green + if (edrk.Go) + { + modbus_table_analog_out[1].all = 3; // ��� + if (edrk.Provorot) + modbus_table_analog_out[1].all = 12; // �������� = 11 + + } + else + modbus_table_analog_out[1].all = 2; // ready2 + } + else + modbus_table_analog_out[1].all = 4; // building + } + else + { + if (edrk.Status_Ready.bits.ready1) + modbus_table_analog_out[1].all = 1; // ready1 + else + modbus_table_analog_out[1].all = 0; // waiting + } + + if (edrk.RazborNotFinish) + modbus_table_analog_out[1].all = 11; // ������ + + if (edrk.Status_Perehod_Rascepitel==1 && edrk.cmd_to_rascepitel==1) + modbus_table_analog_out[1].all = 7; // ����������� ������� + + if (edrk.Status_Perehod_Rascepitel==1 && edrk.cmd_to_rascepitel==0) + modbus_table_analog_out[1].all = 8; // ���������� ������� + + if (edrk.RunZahvatRascepitel) + modbus_table_analog_out[1].all = 9; // ������ �� ����������� = 9 + if (edrk.RunUnZahvatRascepitel) + modbus_table_analog_out[1].all = 10; // ������ �� ���������� = 10 + + // + //modbus_table_analog_out[1].all = 5; // ������������� + + if (modbus_table_analog_out[1].all == 1) + modbus_table_analog_out[2].all = 0; // gray + else + if (modbus_table_analog_out[1].all == 3 || + modbus_table_analog_out[1].all == 12 || + modbus_table_analog_out[1].all == 2) + modbus_table_analog_out[2].all = 1; // green + else + { + if (modbus_table_analog_out[2].all==0) + modbus_table_analog_out[2].all = 1; // green + else + modbus_table_analog_out[2].all = 0; // gray + } + + } + + + + + if (edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER || edrk.errors.e6.bits.QTV_ERROR_NOT_U) + { + modbus_table_analog_out[10].all = 3; + modbus_table_analog_out[11].all = 3; + } + else + { + if (edrk.from_shema_filter.bits.QTV_ON_OFF) + { + modbus_table_analog_out[10].all = 1; + modbus_table_analog_out[11].all = 1; + } + else + { + modbus_table_analog_out[10].all = 0; + modbus_table_analog_out[11].all = 0; + } + } + + + if (edrk.from_ing1.bits.VIPR_PREDOHR_NORMA==1) + { + if (edrk.from_shema_filter.bits.QTV_ON_OFF==1) + modbus_table_analog_out[12].all = 1; + else + modbus_table_analog_out[12].all = 0; + } + else + modbus_table_analog_out[12].all = 3; + + + if (edrk.errors.e6.bits.UO1_KEYS || edrk.errors.e1.bits.I_BREAK_1_MAX || edrk.errors.e1.bits.I_BREAK_2_MAX || edrk.errors.e2.bits.T_UO1_MAX) + modbus_table_analog_out[13].all = 3; + else + if (edrk.warnings.e2.bits.T_UO1_MAX) + modbus_table_analog_out[13].all = 2; + else + modbus_table_analog_out[13].all = 1; + + if (edrk.errors.e6.bits.UO2_KEYS || edrk.errors.e1.bits.I_UO2_MAX || edrk.errors.e2.bits.T_UO2_MAX) + modbus_table_analog_out[14].all = 3; + else + if (edrk.warnings.e2.bits.T_UO2_MAX) + modbus_table_analog_out[14].all = 2; + else + modbus_table_analog_out[14].all = 1; + + if (edrk.errors.e6.bits.UO3_KEYS || edrk.errors.e1.bits.I_UO3_MAX || edrk.errors.e2.bits.T_UO3_MAX) + modbus_table_analog_out[15].all = 3; + else + if (edrk.warnings.e2.bits.T_UO3_MAX) + modbus_table_analog_out[15].all = 2; + else + modbus_table_analog_out[15].all = 1; + + if (edrk.errors.e6.bits.UO4_KEYS || edrk.errors.e1.bits.I_UO4_MAX || edrk.errors.e2.bits.T_UO4_MAX) + modbus_table_analog_out[16].all = 3; + else + if (edrk.warnings.e2.bits.T_UO4_MAX) + modbus_table_analog_out[16].all = 2; + else + modbus_table_analog_out[16].all = 1; + + if (edrk.errors.e6.bits.UO5_KEYS || edrk.errors.e1.bits.I_UO5_MAX || edrk.errors.e2.bits.T_UO5_MAX) + modbus_table_analog_out[17].all = 3; + else + if (edrk.warnings.e2.bits.T_UO5_MAX) + modbus_table_analog_out[17].all = 2; + else + modbus_table_analog_out[17].all = 1; + + if (edrk.errors.e6.bits.UO6_KEYS || edrk.errors.e1.bits.I_UO6_MAX || edrk.errors.e2.bits.T_UO6_MAX) + modbus_table_analog_out[18].all = 3; + else + if (edrk.warnings.e2.bits.T_UO6_MAX) + modbus_table_analog_out[18].all = 2; + else + modbus_table_analog_out[18].all = 1; + + if (edrk.errors.e6.bits.UO7_KEYS || edrk.errors.e1.bits.I_UO7_MAX || edrk.errors.e2.bits.T_UO7_MAX) + modbus_table_analog_out[19].all = 3; + else + if (edrk.warnings.e2.bits.T_UO7_MAX) + modbus_table_analog_out[19].all = 2; + else + modbus_table_analog_out[19].all = 1; + + + // motor_state + if (edrk.errors.e10.bits.T_ACDRIVE_WINDING_U1 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_V1 || + edrk.errors.e10.bits.T_ACDRIVE_WINDING_W1 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_U2 || + edrk.errors.e10.bits.T_ACDRIVE_WINDING_V2 || edrk.errors.e10.bits.T_ACDRIVE_WINDING_W2 || + edrk.errors.e7.bits.T_ACDRIVE_BEAR_MAX_DNE || edrk.errors.e9.bits.T_ACDRIVE_BEAR_MAX_NE) { + modbus_table_analog_out[20].all = 3; + } else if (edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1 || + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2 || + edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2 || edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2 || + edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE || edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE + || edrk.power_limit.all + ) { + modbus_table_analog_out[20].all = 2; + } else { + modbus_table_analog_out[20].all = 1; + } + + + // ump state + if (edrk.from_ing1.bits.ZARYAD_ON || edrk.from_shema_filter.bits.UMP_ON_OFF) + { + modbus_table_analog_out[21].all = 1; //green + } + else + { + if (edrk.errors.e7.bits.ERROR_SBOR_SHEMA || edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON || + edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER || edrk.errors.e6.bits.ERROR_PRE_CHARGE_U || edrk.errors.e7.bits.UMP_NOT_READY) + modbus_table_analog_out[21].all = 3; // alarm + else + if (edrk.warnings.e7.bits.UMP_NOT_READY) + modbus_table_analog_out[21].all = 2; //fault + else + { + if (edrk.Stage_Sbor == STAGE_SBOR_STATUS_UMP_ON && edrk.SumSbor) + { + if (modbus_table_analog_out[21].all==0) + modbus_table_analog_out[21].all = 1; //green + else + modbus_table_analog_out[21].all = 0; //gray + } + else + modbus_table_analog_out[21].all = 0; + } + } + + + modbus_table_analog_out[30].all = fast_round_with_limiter(_IQtoF(filter.iqUin_m1)*NORMA_ACP/1.41, LIMITER_U_I_PULT); + modbus_table_analog_out[31].all = fast_round_with_limiter(_IQtoF(filter.iqUin_m2)*NORMA_ACP/1.41, LIMITER_U_I_PULT); + +// if (edrk.Status_Ready.bits.ready_final==0) +// { +// modbus_table_analog_out[32].all = edrk.Stage_Sbor; +// modbus_table_analog_out[33].all = edrk.Sbor_Mode;//_IQtoF(analog.iqIin_1)*NORMA_ACP; +// } +// else +// { + modbus_table_analog_out[32].all = fast_round_with_limiter(_IQtoF(analog.iqIin_1)*NORMA_ACP, LIMITER_U_I_PULT); + modbus_table_analog_out[33].all = fast_round_with_limiter(_IQtoF(analog.iqIin_2)*NORMA_ACP, LIMITER_U_I_PULT); +// } + + +// modbus_table_analog_out[34].all = _IQtoF(filter.iqU_1_long)*NORMA_ACP; + modbus_table_analog_out[35].all = fast_round_with_limiter(_IQtoF(filter.iqU_2_long)*NORMA_ACP, LIMITER_U_I_PULT); + modbus_table_analog_out[34].all = fast_round_with_limiter(_IQtoF(filter.iqU_1_long)*NORMA_ACP, LIMITER_U_I_PULT); + + modbus_table_analog_out[36].all = fast_round_with_limiter(_IQtoF(analog.iqIbreak_1+analog.iqIbreak_2)*NORMA_ACP, LIMITER_U_I_PULT);//Ibreak + + + +// modbus_table_analog_out[37].all = fast_round(_IQtoF(analog.iqIu_1_rms)*NORMA_ACP); +// modbus_table_analog_out[38].all = fast_round(_IQtoF(analog.iqIv_1_rms)*NORMA_ACP); +// modbus_table_analog_out[39].all = fast_round(_IQtoF(analog.iqIw_1_rms)*NORMA_ACP); +// +// modbus_table_analog_out[40].all = fast_round(_IQtoF(analog.iqIu_2_rms)*NORMA_ACP); +// modbus_table_analog_out[41].all = fast_round(_IQtoF(analog.iqIv_2_rms)*NORMA_ACP); +// modbus_table_analog_out[42].all = fast_round(_IQtoF(analog.iqIw_2_rms)*NORMA_ACP); + + modbus_table_analog_out[37].all = //fast_round(_IQtoF(filter.iqIm_1)*NORMA_ACP_RMS); + modbus_table_analog_out[38].all = //fast_round(_IQtoF(filter.iqIm_1)*NORMA_ACP_RMS); + modbus_table_analog_out[39].all = fast_round_with_limiter(_IQtoF(filter.iqIm_1)*NORMA_ACP_RMS, LIMITER_U_I_PULT); + + modbus_table_analog_out[40].all = //fast_round(_IQtoF(filter.iqIm_2)*NORMA_ACP_RMS); + modbus_table_analog_out[41].all = //fast_round(_IQtoF(filter.iqIm_2)*NORMA_ACP_RMS); + modbus_table_analog_out[42].all = fast_round_with_limiter(_IQtoF(filter.iqIm_2)*NORMA_ACP_RMS, LIMITER_U_I_PULT); + +// if (edrk.flag_second_PCH == 0) { +// modbus_table_analog_out[43].all = modbus_table_analog_out[44].all = fast_round(_IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP_RMS); +// //modbus_table_analog_out[44].all = fast_round(_IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP_RMS); +// } else { +// modbus_table_analog_out[43].all = modbus_table_analog_out[44].all = fast_round(_IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP_RMS); +// //modbus_table_analog_out[44].all = fast_round(_IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP_RMS); +// } + modbus_table_analog_out[43].all = modbus_table_analog_out[44].all = fast_round_with_limiter(_IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP_RMS, LIMITER_U_I_PULT); + + modbus_table_analog_out[45].all = 0; //edrk.I_zad_vozbud_exp; + +// modbus_table_analog_out[4].all = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_ROTOR]; +// modbus_table_analog_out[5].all = control_station.active_array_cmd[CONTROL_STATION_CMD_SET_POWER]; + + +//#if (_FLOOR6__) +// power_kw_full = edrk.power_kw_full; +// power_kw = edrk.power_kw; +// oborots = edrk.oborots; +// +// if (edrk.oborots) +// oborots = edrk.oborots; +// else +// oborots = edrk.zadanie.oborots_zad; +// +// +// if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_SCALAR_OBOROTS +// || (edrk.Mode_ScalarVectorUFConst==ALG_MODE_FOC_OBOROTS) +// || (edrk.Mode_ScalarVectorUFConst==ALG_MODE_UF_CONST) +// ) // oborots +// { +// power_kw_full = (edrk.zadanie.oborots_zad)*50; +// power_kw = (edrk.zadanie.oborots_zad)*25; +// } +// else +// { +// oborots = edrk.zadanie.power_zad/25; +//// modbus_table_analog_out[48].all = abs(edrk.zadanie.power_zad); +// } +// +// +// +// +// +//#else + power_kw_full = fast_round_with_limiter(edrk.power_kw_full, LIMITER_U_I_PULT); + power_kw = edrk.power_kw; + oborots = edrk.oborots; +//#endif + + + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_UF_CONST) // UFCONST + { + modbus_table_analog_out[47].all = 0;//fast_round(edrk.zadanie.fzad*100.0); //������� ��������� �������� + modbus_table_analog_out[46].all = 0; //�������� ��������� �������� + } + else + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_SCALAR_OBOROTS) // scalar oborots + { + modbus_table_analog_out[47].all = edrk.zadanie.oborots_zad; //������� ��������� �������� + + if (oborots>=0) + modbus_table_analog_out[46].all = power_kw_full; //�������� ���� ������� ��������� + else + modbus_table_analog_out[46].all = -power_kw_full; //�������� ��������� �������� + + } + else + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_SCALAR_POWER) // scalar power + { + modbus_table_analog_out[47].all = oborots; //������� ��������� �������� + modbus_table_analog_out[46].all = edrk.zadanie.power_zad; //�������� ��������� �������� + + } + else + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_FOC_OBOROTS) // foc oborots + { + modbus_table_analog_out[47].all = edrk.zadanie.oborots_zad; //������� ��������� �������� + + if (oborots>=0) + modbus_table_analog_out[46].all = power_kw_full; //�������� ���� ������� ��������� + else + modbus_table_analog_out[46].all = -power_kw_full; //�������� ��������� �������� + +// modbus_table_analog_out[46].all = 0; //�������� ��������� �������� + + } + else + if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_FOC_POWER) // foc power + { + modbus_table_analog_out[47].all = oborots; //������� ��������� �������� + modbus_table_analog_out[46].all = edrk.zadanie.power_zad; //�������� ��������� �������� + + } + else + { + modbus_table_analog_out[46].all = 0;//-1; //�������� ��������� �������� + modbus_table_analog_out[47].all = 0;//-1; //������� ��������� �������� + } + + + + + +//#if (_FLOOR6___) +// if (edrk.Mode_ScalarVectorUFConst==ALG_MODE_SCALAR_OBOROTS +// || (edrk.Mode_ScalarVectorUFConst==ALG_MODE_FOC_OBOROTS) +// || (edrk.Mode_ScalarVectorUFConst==ALG_MODE_UF_CONST) +// ) // oborots +// { +// // �������� �������� ��� ����� +// if (edrk.oborots == 0) +// { +// if (edrk.zadanie.oborots_zad>0) +// modbus_table_analog_out[49].all = edrk.zadanie.oborots_zad - 1; +// else if (edrk.zadanie.oborots_zad<0) +// modbus_table_analog_out[49].all = edrk.zadanie.oborots_zad + 1; +// else +// modbus_table_analog_out[49].all = 0; +// +// } +// else +// { +// modbus_table_analog_out[49].all = edrk.oborots; // ������� ������� +// } +// +// if (edrk.zadanie.oborots_zad<0) +// modbus_table_analog_out[48].all = -(edrk.zadanie.oborots_zad)*25; //�������� ��������� ������� ��� +// else +// modbus_table_analog_out[48].all = (edrk.zadanie.oborots_zad)*25; //�������� ��������� ������� ��� +// +// } +// else +// { +// modbus_table_analog_out[49].all = edrk.zadanie.power_zad/25; +// modbus_table_analog_out[48].all = abs(edrk.zadanie.power_zad); +// } +// +// modbus_table_analog_out[5].all = abs(power_kw*2);//power_kw_full; //�������� ���� ������� ��������� +//#else + + modbus_table_analog_out[48].all = abs(power_kw); //�������� ��������� ������� ��� + modbus_table_analog_out[49].all = oborots; // ������� ������� + modbus_table_analog_out[5].all = abs(power_kw_full); //�������� ���� ������� ��������� + modbus_table_analog_out[6].all = fast_round(_IQtoF(edrk.zadanie.iq_limit_power_zad_rmp)*NORMA_ACP*NORMA_ACP/1000.0);//abs(power_kw_full); //�������� ���� ������� ��������� +//#endif + + + // modbus_table_analog_out[48].all = fast_round(_IQtoF((filter.Power) * NORMA_ACP * NORMA_ACP) / 1000.0); //�������� ��������� ������� ��� + + for (i=0;i<2;i++) + modbus_table_analog_out[50+i].all = fast_round_with_delta(modbus_table_analog_out[50+i].all, edrk.temper_edrk.real_int_temper_water[i]/10.0, 1); + + + modbus_table_analog_out[52].all = fast_round_with_delta(modbus_table_analog_out[52].all, edrk.p_water_edrk.filter_real_int_p_water[0]/10.0, 1); + + for (i=0;i<6;i++) + modbus_table_analog_out[53+i].all = fast_round_with_delta(modbus_table_analog_out[53+i].all, edrk.temper_edrk.real_int_temper_u[1+i]/10.0, 1); + + modbus_table_analog_out[59].all = fast_round_with_delta(modbus_table_analog_out[59].all, edrk.temper_edrk.real_int_temper_u[0]/10.0, 1); + + for (i=0;i<4;i++) + modbus_table_analog_out[60+i].all = fast_round_with_delta(modbus_table_analog_out[60+i].all, edrk.temper_edrk.real_int_temper_air[i]/10.0, 1); + + modbus_table_analog_out[8].all = fast_round_with_delta(modbus_table_analog_out[8].all, edrk.temper_edrk.max_real_int_temper_u/10.0, 1); + + if (edrk.errors.e2.bits.T_AIR0_MAX) + modbus_table_analog_out[64].all = 3; + else + if (edrk.warnings.e2.bits.T_AIR0_MAX) + modbus_table_analog_out[64].all = 2; + else + modbus_table_analog_out[64].all = 1; + + if (edrk.errors.e2.bits.T_AIR1_MAX) + modbus_table_analog_out[65].all = 3; + else + if (edrk.warnings.e2.bits.T_AIR1_MAX) + modbus_table_analog_out[65].all = 2; + else + modbus_table_analog_out[65].all = 1; + + if (edrk.errors.e2.bits.T_AIR2_MAX) + modbus_table_analog_out[66].all = 3; + else + if (edrk.warnings.e2.bits.T_AIR2_MAX) + modbus_table_analog_out[66].all = 2; + else + modbus_table_analog_out[66].all = 1; + + if (edrk.errors.e2.bits.T_AIR3_MAX) + modbus_table_analog_out[67].all = 3; + else + if (edrk.warnings.e2.bits.T_AIR3_MAX) + modbus_table_analog_out[67].all = 2; + else + modbus_table_analog_out[67].all = 1; + + + + if (edrk.auto_master_slave.local.bits.master) + modbus_table_analog_out[68].all = 0; // master salve + else + if (edrk.auto_master_slave.local.bits.slave) + modbus_table_analog_out[68].all = 1; // master salve + else + if (edrk.auto_master_slave.local.bits.try_master) + modbus_table_analog_out[68].all = 3; // master salve + else + if (edrk.errors.e7.bits.AUTO_SET_MASTER) + modbus_table_analog_out[68].all = 4; // master salve + else + modbus_table_analog_out[68].all = 2; // master salve + + for (i=0;i<6;i++) + modbus_table_analog_out[69+i].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[0+i]); + + modbus_table_analog_out[9].all = fast_round(edrk.temper_acdrive.winding.max_real_int_temper/10.0); + + modbus_table_analog_out[75].all = fast_round(edrk.temper_acdrive.bear.filter_real_temper[0]); + modbus_table_analog_out[76].all = fast_round(edrk.temper_acdrive.bear.filter_real_temper[1]); + + modbus_table_analog_out[23].all = fast_round(edrk.temper_acdrive.bear.max_real_int_temper/10.0); + + for (i=0;i<6;i++) + { + status = get_status_temper_acdrive_winding(i); + if (status==4) + modbus_table_analog_out[77+i].all = 3; + if (status==2) + modbus_table_analog_out[77+i].all = 2; + if (status==1) + modbus_table_analog_out[77+i].all = 1; + } + + for (i=0;i<2;i++) + { + status = get_status_temper_acdrive_bear(i); + if (status==4) + modbus_table_analog_out[83+i].all = 3; + if (status==2) + modbus_table_analog_out[83+i].all = 2; + if (status==1) + modbus_table_analog_out[83+i].all = 1; + } + + +//UOM + modbus_table_analog_out[85].all = edrk.from_uom.level_value; + + if (edrk.from_uom.ready==1) + { + if (edrk.from_uom.error) + modbus_table_analog_out[86].all = 1; // ������� + else + { + if (edrk.from_uom.level_value==0) + modbus_table_analog_out[86].all = 2; // ������� + else + { + if (edrk.power_limit.bits.limit_UOM || edrk.power_limit.bits.limit_from_uom_fast) + { + // ������� ������-����� + if (modbus_table_analog_out[86].all==0) + modbus_table_analog_out[86].all = 3; //������ + else + modbus_table_analog_out[86].all = 0; //gray + } + else + modbus_table_analog_out[86].all = 3; + + //modbus_table_analog_out[86].all = 3; // ������ + } + } + } + else + modbus_table_analog_out[86].all = 0; // ����� + + +// active control station +// CONTROL_STATION_TERMINAL_RS232 = 0, - +// CONTROL_STATION_TERMINAL_CAN, - +// +// CONTROL_STATION_INGETEAM_PULT_RS485, - +// CONTROL_STATION_MPU_SVU_CAN, +// CONTROL_STATION_MPU_KEY_CAN, +// CONTROL_STATION_MPU_SVU_RS485, +// CONTROL_STATION_MPU_KEY_RS485, +// CONTROL_STATION_ZADATCHIK_CAN, +// CONTROL_STATION_VPU_CAN, + + modbus_table_analog_out[87].all = edrk.active_post_upravl; + + + // load procents + modbus_table_analog_out[88].all = 0; //error + + // 0- �����, �������, ������, ������� - ���� ����� ���������� ��. [87]. + if (modbus_table_analog_out[87].all == 10) + modbus_table_analog_out[89].all = 3; //red + else + modbus_table_analog_out[89].all = 1; //no error + + ///////////////////////////// + ///////////////////////////// + if (edrk.warnings.e7.bits.READ_OPTBUS + && edrk.warnings.e7.bits.WRITE_OPTBUS + && edrk.warnings.e7.bits.MASTER_SLAVE_SYNC) + modbus_table_analog_out[90].all = 2; //warning + else + if (edrk.errors.e7.bits.READ_OPTBUS + || edrk.errors.e7.bits.WRITE_OPTBUS + || edrk.errors.e7.bits.MASTER_SLAVE_SYNC + || edrk.errors.e1.bits.NO_INPUT_SYNC_SIGNAL) + modbus_table_analog_out[90].all = 3; //error + else + if (edrk.warnings.e7.bits.READ_OPTBUS + || edrk.warnings.e7.bits.WRITE_OPTBUS + || edrk.warnings.e7.bits.MASTER_SLAVE_SYNC + || edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL) + modbus_table_analog_out[90].all = 5; //warning + else + if (edrk.ms.ready1==0) + modbus_table_analog_out[90].all = 1; //find + else + modbus_table_analog_out[90].all = 0; //ok + + modbus_table_analog_out[91].all = protect_levels.abnormal_temper_acdrive_winding_U1 / 10; + modbus_table_analog_out[92].all = protect_levels.abnormal_temper_acdrive_winding_V1 / 10; + modbus_table_analog_out[93].all = protect_levels.abnormal_temper_acdrive_winding_W1 / 10; + modbus_table_analog_out[94].all = protect_levels.abnormal_temper_acdrive_winding_U2 / 10; + modbus_table_analog_out[95].all = protect_levels.abnormal_temper_acdrive_winding_V2 / 10; + modbus_table_analog_out[96].all = protect_levels.abnormal_temper_acdrive_winding_W2 / 10; + modbus_table_analog_out[97].all = protect_levels.abnormal_temper_acdrive_bear_DNE / 10; + modbus_table_analog_out[98].all = protect_levels.abnormal_temper_acdrive_bear_NE / 10; + + modbus_table_analog_out[99].all = protect_levels.alarm_temper_acdrive_winding_U1 / 10; + modbus_table_analog_out[100].all = protect_levels.alarm_temper_acdrive_winding_V1 / 10; + modbus_table_analog_out[101].all = protect_levels.alarm_temper_acdrive_winding_W1 / 10; + modbus_table_analog_out[102].all = protect_levels.alarm_temper_acdrive_winding_U2 / 10; + modbus_table_analog_out[103].all = protect_levels.alarm_temper_acdrive_winding_V2 / 10; + modbus_table_analog_out[104].all = protect_levels.alarm_temper_acdrive_winding_W2 / 10; + modbus_table_analog_out[105].all = protect_levels.alarm_temper_acdrive_bear_DNE / 10; + modbus_table_analog_out[106].all = protect_levels.alarm_temper_acdrive_bear_NE / 10; + + modbus_table_analog_out[107].all = protect_levels.abnormal_temper_u_01 / 10; + modbus_table_analog_out[108].all = protect_levels.abnormal_temper_u_02 / 10; + modbus_table_analog_out[109].all = protect_levels.abnormal_temper_u_03 / 10; + modbus_table_analog_out[110].all = protect_levels.abnormal_temper_u_04 / 10; + modbus_table_analog_out[111].all = protect_levels.abnormal_temper_u_05 / 10; + modbus_table_analog_out[112].all = protect_levels.abnormal_temper_u_06 / 10; + modbus_table_analog_out[113].all = protect_levels.abnormal_temper_u_07 / 10; + modbus_table_analog_out[114].all = protect_levels.alarm_temper_u_01 / 10; + modbus_table_analog_out[115].all = protect_levels.alarm_temper_u_02 / 10; + modbus_table_analog_out[116].all = protect_levels.alarm_temper_u_03 / 10; + modbus_table_analog_out[117].all = protect_levels.alarm_temper_u_04 / 10; + modbus_table_analog_out[118].all = protect_levels.alarm_temper_u_05 / 10; + modbus_table_analog_out[119].all = protect_levels.alarm_temper_u_06 / 10; + modbus_table_analog_out[120].all = protect_levels.alarm_temper_u_07 / 10; + + modbus_table_analog_out[123].all = protect_levels.abnormal_temper_water_int / 10; + modbus_table_analog_out[124].all = protect_levels.abnormal_temper_water_ext / 10; + modbus_table_analog_out[125].all = protect_levels.alarm_p_water_min_int / 10; + modbus_table_analog_out[126].all = protect_levels.alarm_temper_water_int / 10; + modbus_table_analog_out[127].all = protect_levels.alarm_temper_water_ext / 10; + modbus_table_analog_out[128].all = protect_levels.alarm_p_water_max_int / 10; + + modbus_table_analog_out[129].all = protect_levels.abnormal_temper_air_int_01 / 10; + modbus_table_analog_out[130].all = protect_levels.abnormal_temper_air_int_02 / 10; + modbus_table_analog_out[131].all = protect_levels.abnormal_temper_air_int_03 / 10; + modbus_table_analog_out[132].all = protect_levels.abnormal_temper_air_int_04 / 10; + modbus_table_analog_out[133].all = protect_levels.alarm_temper_air_int_01 / 10; + modbus_table_analog_out[134].all = protect_levels.alarm_temper_air_int_02 / 10; + modbus_table_analog_out[135].all = protect_levels.alarm_temper_air_int_03 / 10; + modbus_table_analog_out[136].all = protect_levels.alarm_temper_air_int_04 / 10; + +// toControllerAlarmMinUlineA1B1C1 30137 +// toControllerAlarmMinUlineA2B2C2 30138 +// toControllerAlarmMinUdcUP 30139 +// toControllerAlarmMinUdcDOWN 30140 +// toControllerAlarmMaxUlineA1B1C1 30142 +// toControllerAlarmMaxUlineA2B2C2 30143 +// toControllerAlarmMaxUdcUP 30144 +// toControllerAlarmMaxUdcDOWN 30145 + + modbus_table_analog_out[137].all = _IQtoF(analog_protect.in_voltage[0].setup.levels.iqNominal_minus20) * NORMA_ACP;//_IQtoF(edrk.iqMIN_U_IN) * NORMA_ACP; + modbus_table_analog_out[138].all = _IQtoF(analog_protect.in_voltage[1].setup.levels.iqNominal_minus20) * NORMA_ACP; + + modbus_table_analog_out[139].all = _IQtoF(edrk.iqMIN_U_ZPT) * NORMA_ACP; + modbus_table_analog_out[140].all = _IQtoF(edrk.iqMIN_U_ZPT) * NORMA_ACP; + + modbus_table_analog_out[142].all = _IQtoF(analog_protect.in_voltage[0].setup.levels.iqNominal_plus20) * NORMA_ACP; + modbus_table_analog_out[143].all = _IQtoF(analog_protect.in_voltage[1].setup.levels.iqNominal_plus20) * NORMA_ACP; + +// modbus_table_analog_out[141].all = //_IQtoF(edrk.iqMAX_U_IN) * NORMA_ACP; +// modbus_table_analog_out[140].all = _IQtoF(edrk.iqMAX_U_IN) * NORMA_ACP; + + modbus_table_analog_out[144].all = _IQtoF(edrk.iqMAX_U_ZPT) * NORMA_ACP; + modbus_table_analog_out[145].all = _IQtoF(edrk.iqMAX_U_ZPT) * NORMA_ACP; + + modbus_table_analog_out[146].all = protect_levels.alarm_Izpt_max; + + modbus_table_analog_out[155].all = protect_levels.alarm_Imax_U01; + modbus_table_analog_out[156].all = protect_levels.alarm_Imax_U02; + modbus_table_analog_out[157].all = protect_levels.alarm_Imax_U03; + modbus_table_analog_out[158].all = protect_levels.alarm_Imax_U04; + modbus_table_analog_out[159].all = protect_levels.alarm_Imax_U05; + modbus_table_analog_out[160].all = protect_levels.alarm_Imax_U06; + modbus_table_analog_out[161].all = protect_levels.alarm_Imax_U07; + modbus_table_analog_out[162].all = protect_levels.alarm_Iged_max; + + + // save nPCH TimeToChangePump + modbus_table_analog_out[163].all = edrk.pult_data.data_to_pult.nPCH; + modbus_table_analog_out[154].all = edrk.pult_data.data_to_pult.TimeToChangePump; + + modbus_table_analog_out[222].all = edrk.pult_data.data_to_pult.count_build; + modbus_table_analog_out[223].all = edrk.pult_data.data_to_pult.count_revers; + + + + modbus_table_analog_out[197].all = edrk.pult_data.flagSaveDataPCH; + + + + + // build version + modbus_table_analog_out[219].all = edrk.buildYear; + modbus_table_analog_out[220].all = edrk.buildMonth; + modbus_table_analog_out[221].all = edrk.buildDay; + + //moto + for (i=0;i<COUNT_MOTO_PULT;i++) + modbus_table_analog_out[i+201].all = edrk.pult_data.data_to_pult.moto[i]; + + modbus_table_analog_out[200].all = edrk.pult_data.flagSaveDataMoto; + modbus_table_analog_out[198].all = edrk.pult_data.flagSaveSlowLogs; +// modbus_table_analog_out[198].all = edrk.pult_data.flagSaveParamLogs; + + modbus_table_analog_out[7].all = edrk.freq_50hz_1; + + + //////////////// log//// + update_logs_cmd_HMI(); + +/* +���������� ��������� � ����������� � ������ ��������. +��� �������� ������ �� � ��������� 30010-30027 �������� +�������������������� �������� FFFF. +�������� �������� �� ���������� �������� ����� + ��������� �������: �������� � �������� 40701-40718 ������, � + ����� ��������� ������� � ������� 40700. ������ ����������, + ����������� �� �������� "��������" � ������� ������� � �������� 30010-30027. + */ +// if () + +} + + +/* + * 40194 - ��������� ������ ������ �� ��������� 40300-40399 � ����� LOGS1; +40224 - ��������� ������ ������ �� ��������� 40400-40499 � ����� LOGS2; +40225 - ��������� ������ ������ �� ��������� 40500-40599 � ����� LOGS3; +40226 - ��������� ������ ������ �� ��������� 40600-40699 � ����� LOGS4; +40227 - ��������� ������ ������ �� ��������� 40700-40799 � ����� LOGS5; + */ + +void update_LoggerParams(void) +{ + int i; + + for (i=0;i<28;i++) + { + modbus_table_analog_out[164+i].all = edrk.pult_data.logger_params[i]; + } + + +} + + +void update_logs_cmd_HMI(void) +{ + modbus_table_analog_out[192].all = log_to_HMI.enable_progress_bar; // stateLogsReport + modbus_table_analog_out[193].all = log_to_HMI.progress_bar; // controlProgressBar + modbus_table_analog_out[194].all = log_to_HMI.ReportLogOut; // ReportGetOut + modbus_table_analog_out[195].all = log_to_HMI.cleanLogs; // cleanLogs == 1 + modbus_table_analog_out[196].all = log_to_HMI.saveLogsToSDCard; // saveLogsToSDCard 1-SD 2-USB + +// modbus_table_analog_out[224].all = log_to_HMI.tick_step2; +// modbus_table_analog_out[225].all = log_to_HMI.tick_step3; +// modbus_table_analog_out[226].all = log_to_HMI.tick_step4; +// modbus_table_analog_out[227].all = log_to_HMI.tick_step5; + + +} + +void update_tables_HMI(void) +{ + update_tables_HMI_analog(); + update_tables_HMI_discrete(); +} + + +void setStateHMI(Inverter_state state) { + switch (state) { + case state_ready1: + modbus_table_analog_out[1].all = 1; + modbus_table_analog_out[2].all = 1; + break; + case state_ready2: + modbus_table_analog_out[1].all = 2; + modbus_table_analog_out[2].all = 1; + break; + case state_go: + modbus_table_analog_out[1].all = 3; + modbus_table_analog_out[2].all = 1; + break; + case state_assemble: + modbus_table_analog_out[1].all = 4; + modbus_table_analog_out[2].all = 1; + break; + case state_fault: + modbus_table_analog_out[1].all = 5; + modbus_table_analog_out[2].all = 2; + break; + case state_accident: + modbus_table_analog_out[1].all = 6; + modbus_table_analog_out[2].all = 3; + break; + default: + modbus_table_analog_out[1].all = 0; + modbus_table_analog_out[2].all = 0; + + }; +} +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// + +void setElementsColorsHMI(Inverter_state state) { + int i = 10; + if ((state == state_not_init) || (state == state_ready1)) { + //All grey + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 0; + } + } else if (state == state_assemble) { + //UMP + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 0; + } + modbus_table_analog_out[21].all = 1; + } else if (state == state_ready2) { + //All green + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 0; + } + modbus_table_analog_out[10].all = 1; + modbus_table_analog_out[11].all = 1; + modbus_table_analog_out[12].all = 1; + } else if (state == state_go) { + //Almost all + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 1; + } + modbus_table_analog_out[21].all = 0; + } else if (state == state_fault) { + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 2; + } + } else if (state == state_accident) { + for (i = 10; i <= 22; ++i) { + modbus_table_analog_out[i].all = 3; + } + } +} +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +/////////////////////////////////////////////////// +/// +/////////////////////////////////////////////////// +void inc_count_build(void) +{ + // edrk.pult_data.data.count_build = edrk.pult_data.data_from_pult.moto[21]; + + edrk.pult_data.data.count_build++; + if (edrk.pult_data.data.count_build>32760) + edrk.pult_data.data.count_build = 1; + + // edrk.pult_data.data_to_pult.count_build = edrk.pult_data.data.count_build; + // edrk.pult_data.data_to_pult.moto[21] = edrk.pult_data.data_to_pult.count_build; +} + + + +void inc_count_revers(void) +{ +// edrk.pult_data.data.count_revers = edrk.pult_data.data_from_pult.moto[22]; + + edrk.pult_data.data.count_revers++; + if (edrk.pult_data.data.count_revers>32760) + edrk.pult_data.data.count_revers = 1; + +// edrk.pult_data.data_to_pult.count_revers = edrk.pult_data.data.count_revers; + // edrk.pult_data.data_to_pult.moto[22] = edrk.pult_data.data_to_pult.count_revers + +} + + +void update_nPCH(void) +{ + + static int pause_w = 5, first_run = 1; // 10 ��� �������� �� ����� ������ �� ������ + int flag_1 = 0, flag_2 = 0, i; + static int prev_active = 0; + + if (control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]==0) + { + pause_w = 5; + } + + if (pause_w > 1) + { + pause_w--; +// if (edrk.pult_data.nPCH_from_pult) +// if (pause_w > 1) +// pause_w = 1; + prev_active = control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]; + return; + } + + // �������� �� -1 � ������ + // ���� � ������ -1 � �� ������ �����������, ������ ���� ��� �������� + // ����� ���������� �� ��� � ������ + if (pause_w==1 && first_run) + { + //����� �� + if (edrk.pult_data.data_from_pult.nPCH==-1) // ��� ����� + { + edrk.pult_data.data_to_pult.nPCH = edrk.pult_data.data.nPCH = 0; + } + else + edrk.pult_data.data_to_pult.nPCH = edrk.pult_data.data.nPCH = edrk.pult_data.data_from_pult.nPCH; + + //�������� ������������ � ������ �� ����� + if (edrk.pult_data.data_from_pult.TimeToChangePump == -1) // ��� ����� + edrk.pult_data.data_to_pult.TimeToChangePump = edrk.pult_data.data.TimeToChangePump = 0; + else + edrk.pult_data.data_to_pult.TimeToChangePump = edrk.pult_data.data.TimeToChangePump = edrk.pult_data.data_from_pult.TimeToChangePump; + + //�������� + ������ + ���-�� ������ + for (i=0;i<COUNT_MOTO_PULT;i++) + { + if (edrk.pult_data.data_from_pult.moto[i] == -1) // ��� ����� + edrk.pult_data.data_to_pult.moto[i] = edrk.pult_data.data.moto[i] = 0; + else + edrk.pult_data.data_to_pult.moto[i] = edrk.pult_data.data.moto[i] = edrk.pult_data.data_from_pult.moto[i]; + } + + // count_build + if (edrk.pult_data.data_from_pult.count_build==-1) // ��� ����� + { + edrk.pult_data.data_to_pult.count_build = edrk.pult_data.data.count_build = 0; + } + else + edrk.pult_data.data_to_pult.count_build = edrk.pult_data.data.count_build = edrk.pult_data.data_from_pult.count_build; + + // count_revers + if (edrk.pult_data.data_from_pult.count_revers == -1) // ��� ����� + { + edrk.pult_data.data_to_pult.count_revers = edrk.pult_data.data.count_revers = 0; + } + else + edrk.pult_data.data_to_pult.count_revers = edrk.pult_data.data.count_revers = edrk.pult_data.data_from_pult.count_revers; + + // + pause_w = 0; + first_run = 0; + } + + //����� �� + // ����� ��������� �� ������ + if (edrk.pult_data.data_from_pult.nPCH != edrk.pult_data.data.nPCH && edrk.pult_data.data_from_pult.nPCH>=0) + { + edrk.pult_data.data_to_pult.nPCH = edrk.pult_data.data_from_pult.nPCH; + flag_1 = 1; + edrk.pult_data.data.nPCH = edrk.pult_data.data_from_pult.nPCH; + } + + // ��� ����� ����� -1 ������ �� ������� �������� + if (edrk.pult_data.data_from_pult.nPCH != edrk.pult_data.data.nPCH && edrk.pult_data.data_from_pult.nPCH == -1) + { + edrk.pult_data.data_to_pult.nPCH = edrk.pult_data.data.nPCH; + flag_1 = 1; + } + + + //�������� ������������ � ������ �� ����� + // ����� ��������� �� ������ + if (edrk.pult_data.data_from_pult.TimeToChangePump != edrk.pult_data.data.TimeToChangePump + && edrk.pult_data.data_from_pult.TimeToChangePump >= 0) + { + edrk.pult_data.data_to_pult.TimeToChangePump = edrk.pult_data.data_from_pult.TimeToChangePump; + flag_1 = 1; + edrk.pult_data.data.TimeToChangePump = edrk.pult_data.data_from_pult.TimeToChangePump; + } + + // ��� ����� ����� -1 ������ �� ������� �������� + if (edrk.pult_data.data_from_pult.TimeToChangePump != edrk.pult_data.data.TimeToChangePump + && edrk.pult_data.data_from_pult.TimeToChangePump == -1) + { + edrk.pult_data.data_to_pult.TimeToChangePump = edrk.pult_data.data.TimeToChangePump; + flag_1 = 1; + } + + // build + // ��� ����� ����� -1 ������ �� ������� �������� + if (edrk.pult_data.data_from_pult.count_build != edrk.pult_data.data.count_build + && edrk.pult_data.data_from_pult.count_build == -1) + { + edrk.pult_data.data_to_pult.count_build = edrk.pult_data.data.count_build; + flag_1 = 1; + } + + if (edrk.pult_data.data_from_pult.count_build != edrk.pult_data.data.count_build) + { + edrk.pult_data.data_to_pult.count_build = edrk.pult_data.data.count_build; + flag_1 = 1; + } + + // revers + // ��� ����� ����� -1 ������ �� ������� �������� + if (edrk.pult_data.data_from_pult.count_revers != edrk.pult_data.data.count_revers + && edrk.pult_data.data_from_pult.count_revers == -1) + { + edrk.pult_data.data_to_pult.count_revers = edrk.pult_data.data.count_revers; + flag_1 = 1; + } + + if (edrk.pult_data.data_from_pult.count_revers != edrk.pult_data.data.count_revers ) + { + edrk.pult_data.data_to_pult.count_revers = edrk.pult_data.data.count_revers; + flag_1 = 1; + } + // ���� ������� ��������� + edrk.pult_data.flagSaveDataPCH = flag_1; + + + // moto + for (i=0;i<COUNT_MOTO_PULT;i++) + { + // ��� ����� ����� -1 ������ �� ������� �������� + if (edrk.pult_data.data_from_pult.moto[i] == -1) + flag_2 = 1; + else + edrk.pult_data.data.moto[i] = edrk.pult_data.data_from_pult.moto[i]; + } + + // ���� ���� ���� -1 � ������, ������ ��� ����� ��������, ��������� ��� ������ + if (flag_2) + { + for (i=0;i<COUNT_MOTO_PULT;i++) + { + edrk.pult_data.data_to_pult.moto[i] = edrk.pult_data.data.moto[i]; + } + } + + // ���� ������� ��������� + edrk.pult_data.flagSaveDataMoto = flag_2; + + + + + + + prev_active = control_station.alive_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]; + +} + + +#define COUNT_WAIT_SAVE_LOG 3000 + +void set_write_slow_logs(int cmd) +{ + static int prev_cmd = 0, flag_wait = 0, flag_clear = 0; + static unsigned int time_wait_save_log = 0, time_wait_clear_log = 0; + int to_store = 0; + + if (edrk.pult_cmd.log_what_memory == 3) + to_store = 3; + else + if (edrk.pult_cmd.log_what_memory >= 2) + to_store = 2; + else + if (edrk.pult_cmd.log_what_memory >= 1) + to_store = 1; + else + to_store = 0; + + //40198 - ���������� ���������� ������� (�������������� �����) �� ������ (2), �� ����� (1), �� �����+usb (3) + if (prev_cmd == 0 && cmd && to_store && flag_wait == 0) + { + edrk.pult_data.flagSaveSlowLogs = to_store; + flag_wait = 1; + time_wait_save_log = global_time.miliseconds; + } + + + if (flag_wait) + { + if (detect_pause_milisec(COUNT_WAIT_SAVE_LOG, &time_wait_save_log)) + { + flag_wait = 0; + flag_clear = 1; // ���� ������� �� �������� + edrk.pult_data.flagSaveSlowLogs = 0; + time_wait_clear_log = global_time.miliseconds; + } + + } + else + { + + } + + + + + if (flag_clear) // ������� + { + edrk.pult_data.flagSaveSlowLogs = 100; + if (detect_pause_milisec(COUNT_WAIT_SAVE_LOG, &time_wait_clear_log)) + { + flag_wait = 0; + flag_clear = 0; + edrk.pult_data.flagSaveSlowLogs = 0; + } + + } + + //������ ����� � ������ ����� ������ � �������� 30033: + +// �������� 0 - ��� �� ������, �� �����; +// �������� 1 - ��� ������, ���� �����; +// �������� 2 - ���� ������, ��� �����; +// �������� 3 - ���� � ������ � �����; +} + diff --git a/Inu/Src/main/modbus_hmi_update.h b/Inu/Src/main/modbus_hmi_update.h new file mode 100644 index 0000000..3ed0c05 --- /dev/null +++ b/Inu/Src/main/modbus_hmi_update.h @@ -0,0 +1,39 @@ +#ifndef _HMI_UPDATE +#define _HMI_UPDATE + + +#define LIMITER_U_I_PULT 5.0 //10.0 + + +typedef enum { + state_not_init = 0, state_ready1 = 1, state_ready2, state_go, state_assemble, state_fault, state_accident +} Inverter_state; + +void update_tables_HMI(void); +void update_logs_cmd_HMI(void); +void update_tables_HMI_on_inited(int perc_load); + +void update_tables_HMI_analog(void); +void update_tables_HMI_discrete(void); + +int update_progress_load_hmi(int proc_load); + +void setStateHMI(Inverter_state state); +void setElementsColorsHMI(Inverter_state state); + +void get_command_HMI(void); +void func_unpack_answer_from_Ingeteam(unsigned int cc); + +extern int hmi_watch_dog; + +void update_nPCH(void); + +void inc_count_build(void); +void inc_count_revers(void); + +void set_write_slow_logs(int cmd); + +void update_LoggerParams(void); + + +#endif //_HMI_UPDATE diff --git a/Inu/Src/main/modbus_svu_update.c b/Inu/Src/main/modbus_svu_update.c new file mode 100644 index 0000000..d9e6fe2 --- /dev/null +++ b/Inu/Src/main/modbus_svu_update.c @@ -0,0 +1,710 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File + +#include <adc_tools.h> +#include <control_station_project.h> +#include <detect_errors_adc.h> +#include <edrk_main.h> +#include <master_slave.h> +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <protect_levels.h> +#include <v_rotor.h> +#include <v_rotor.h> +#include "math.h" +#include "control_station.h" +#include "CAN_Setup.h" +#include "modbus_table_v2.h" +#include "mathlib.h" + +void update_errors_to_svu(void); +void update_protect_levels_to_MPU(void); + +void update_svu_modbus_table(void) +{ + int current_active_control; + + modbus_table_can_out[0].all = edrk.Stop ? 7 : +// edrk.Provorot ? 6 : + edrk.Go ? 5 : + edrk.Status_Ready.bits.ready_final ? 4 : + edrk.to_ing.bits.RASCEPITEL_ON ? 3 : + edrk.SumSbor ? 2 : + edrk.Status_Ready.bits.ready1 ? 1 : 0; + modbus_table_can_out[1].all = edrk.warning; + modbus_table_can_out[2].all = edrk.overheat; +// modbus_table_can_out[3].all = ����������� �������� ���; +// modbus_table_can_out[4].all = ���������� ���; + modbus_table_can_out[5].all = edrk.Status_Ready.bits.Batt; + modbus_table_can_out[6].all = edrk.from_ing1.bits.UPC_24V_NORMA | edrk.from_ing1.bits.OP_PIT_NORMA ? 0 : 1; + modbus_table_can_out[7].all = WRotor.RotorDirectionSlow >= 0 ? 0 : 1; + modbus_table_can_out[8].all = edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER || + edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_POWER ? 1 : 0; + current_active_control = get_current_station_control(); + modbus_table_can_out[9].all = current_active_control == CONTROL_STATION_INGETEAM_PULT_RS485 ? 1 : + current_active_control == CONTROL_STATION_MPU_KEY_CAN || current_active_control == CONTROL_STATION_MPU_KEY_RS485 ? 2 : + current_active_control == CONTROL_STATION_ZADATCHIK_CAN ? 3 : + current_active_control == CONTROL_STATION_VPU_CAN ? 4 : + current_active_control == CONTROL_STATION_MPU_SVU_CAN || current_active_control == CONTROL_STATION_MPU_SVU_RS485 ? 5 : + 0; + modbus_table_can_out[10].all = edrk.errors.e2.bits.T_UO1_MAX || edrk.errors.e6.bits.UO1_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO1_MAX ? 2 : 1; + modbus_table_can_out[11].all = edrk.errors.e2.bits.T_UO2_MAX || edrk.errors.e6.bits.UO2_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO2_MAX ? 2 : 1; + modbus_table_can_out[12].all = edrk.errors.e2.bits.T_UO3_MAX || edrk.errors.e6.bits.UO3_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO3_MAX ? 2 : 1; + modbus_table_can_out[13].all = edrk.errors.e2.bits.T_UO4_MAX || edrk.errors.e6.bits.UO4_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO4_MAX ? 2 : 1; + modbus_table_can_out[14].all = edrk.errors.e2.bits.T_UO5_MAX || edrk.errors.e6.bits.UO5_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO5_MAX ? 2 : 1; + modbus_table_can_out[15].all = edrk.errors.e2.bits.T_UO6_MAX || edrk.errors.e6.bits.UO6_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO6_MAX ? 2 : 1; + modbus_table_can_out[16].all = edrk.errors.e2.bits.T_UO7_MAX || edrk.errors.e6.bits.UO7_KEYS ? 3 : + edrk.warnings.e2.bits.T_UO7_MAX ? 2 : 1; + modbus_table_can_out[17].all = edrk.Status_QTV_Ok;// edrk.from_shema.bits.QTV_ON_OFF; + modbus_table_can_out[18].all = edrk.from_svu.bits.BLOCKED; + modbus_table_can_out[19].all = edrk.from_shema_filter.bits.UMP_ON_OFF; + modbus_table_can_out[20].all = edrk.from_shema_filter.bits.READY_UMP; + modbus_table_can_out[21].all = edrk.from_ing1.bits.RASCEPITEL_ON; + modbus_table_can_out[22].all = edrk.from_ing1.bits.UPC_24V_NORMA; + modbus_table_can_out[23].all = edrk.from_ing1.bits.OHLAD_UTE4KA_WATER; + modbus_table_can_out[24].all = edrk.from_ing2.bits.SOST_ZAMKA; + modbus_table_can_out[25].all = edrk.from_ing1.bits.ZARYAD_ON | edrk.from_shema_filter.bits.UMP_ON_OFF; //������, ������ �� ����������� ��� �� �����, ������� ��� �������������� + modbus_table_can_out[26].all = edrk.from_ing1.bits.VENTIL_ON; + modbus_table_can_out[27].all = edrk.to_ing.bits.NASOS_1_ON == 1 && edrk.from_ing1.bits.NASOS_ON == 1 ? 1 : 0; + modbus_table_can_out[28].all = edrk.to_ing.bits.NASOS_2_ON == 1 && edrk.from_ing1.bits.NASOS_ON == 1 ? 1 : 0; + modbus_table_can_out[29].all = edrk.from_ing1.bits.NASOS_NORMA; + modbus_table_can_out[30].all = edrk.from_ing1.bits.ZAZEML_ON; + modbus_table_can_out[31].all = edrk.from_ing1.bits.NAGREV_ON; + modbus_table_can_out[32].all = edrk.from_ing1.bits.BLOCK_IZOL_NORMA == 1 ? 1 : 0; + modbus_table_can_out[33].all = edrk.errors.e5.bits.ERROR_ISOLATE == 0 && edrk.from_ing1.bits.BLOCK_IZOL_NORMA == 1 ? 0 : 1; + modbus_table_can_out[34].all = edrk.from_ing1.bits.ALL_KNOPKA_AVARIA; + + if (edrk.MasterSlave == MODE_MASTER) + modbus_table_can_out[35].all = 1; + else + if (edrk.MasterSlave == MODE_SLAVE) + modbus_table_can_out[35].all = 0; + else + modbus_table_can_out[35].all = 2; // MODE_DONTKNOW + +// modbus_table_can_out[35].all = edrk.MasterSlave == MODE_MASTER ? 1 : 0; + modbus_table_can_out[36].all = edrk.from_ing1.bits.OP_PIT_NORMA & edrk.from_ing1.bits.UPC_24V_NORMA; + modbus_table_can_out[37].all = optical_read_data.status == 1 && optical_write_data.status == 1 ? 1 : 0; + modbus_table_can_out[38].all = edrk.warnings.e7.bits.MASTER_SLAVE_SYNC == 0 ? 1 : 0; + modbus_table_can_out[39].all = fast_round(_IQtoF(filter.iqIm) * NORMA_ACP); + modbus_table_can_out[40].all = fast_round(_IQtoF(filter.iqIin_sum) * NORMA_ACP); + modbus_table_can_out[41].all = fast_round(_IQtoF(filter.iqU_1_long + filter.iqU_2_long) * NORMA_ACP); + + if (filter.iqUin_m1>=filter.iqUin_m2) + modbus_table_can_out[42].all = fast_round(_IQtoF(filter.iqUin_m1) * NORMA_ACP / 1.41); + else + modbus_table_can_out[42].all = fast_round(_IQtoF(filter.iqUin_m2) * NORMA_ACP / 1.41); + + modbus_table_can_out[43].all = fast_round(_IQtoF(filter.iqU_1_long) * NORMA_ACP); + modbus_table_can_out[44].all = fast_round(_IQtoF(filter.iqU_2_long) * NORMA_ACP); + modbus_table_can_out[45].all = fast_round(_IQtoF(filter.iqIm_1) * NORMA_ACP / 1.41); + modbus_table_can_out[46].all = fast_round(_IQtoF(filter.iqIm_1) * NORMA_ACP / 1.41); + modbus_table_can_out[47].all = fast_round(_IQtoF(filter.iqIm_1) * NORMA_ACP / 1.41); + modbus_table_can_out[48].all = fast_round(_IQtoF(filter.iqIm_2) * NORMA_ACP / 1.41); + modbus_table_can_out[49].all = fast_round(_IQtoF(filter.iqIm_2) * NORMA_ACP / 1.41); + modbus_table_can_out[50].all = fast_round(_IQtoF(filter.iqIm_2) * NORMA_ACP / 1.41); + modbus_table_can_out[51].all = fast_round(_IQtoF(filter.iqIin_sum) * NORMA_ACP); +// modbus_table_can_out[52].all = Uvh rms +// modbus_table_can_out[53].all = +// modbus_table_can_out[54].all = +// modbus_table_can_out[55].all = + modbus_table_can_out[56].all = _IQtoF(analog.iqIbreak_1) * NORMA_ACP; + modbus_table_can_out[57].all = _IQtoF(analog.iqIbreak_2) * NORMA_ACP; + + //Temperatures + modbus_table_can_out[58].all = fast_round(edrk.temper_edrk.real_temper_u[0]); + modbus_table_can_out[59].all = fast_round(edrk.temper_edrk.real_temper_u[1]); + modbus_table_can_out[60].all = fast_round(edrk.temper_edrk.real_temper_u[2]); + modbus_table_can_out[61].all = fast_round(edrk.temper_edrk.real_temper_u[3]); + modbus_table_can_out[62].all = fast_round(edrk.temper_edrk.real_temper_u[4]); + modbus_table_can_out[63].all = fast_round(edrk.temper_edrk.real_temper_u[5]); + modbus_table_can_out[64].all = fast_round(edrk.temper_edrk.real_temper_u[6]); + modbus_table_can_out[65].all = fast_round(edrk.temper_edrk.real_temper_water[1]); + modbus_table_can_out[66].all = fast_round(edrk.temper_edrk.real_temper_water[0]); + modbus_table_can_out[67].all = fast_round(edrk.temper_edrk.real_temper_air[0]); + modbus_table_can_out[68].all = fast_round(edrk.temper_edrk.real_temper_air[1]); + modbus_table_can_out[69].all = fast_round(edrk.temper_edrk.real_temper_air[2]); + modbus_table_can_out[70].all = fast_round(edrk.temper_edrk.real_temper_air[3]); + + modbus_table_can_out[71].all = fast_round(edrk.p_water_edrk.real_p_water[0]); + + modbus_table_can_out[72].all = fast_round(_IQtoF(edrk.zadanie.iq_oborots_zad_hz_rmp) * NORMA_FROTOR * 60); + modbus_table_can_out[73].all = edrk.oborots;// fast_round(_IQtoF(WRotor.iqWRotorSumFilter3) * NORMA_FROTOR * 60); + modbus_table_can_out[74].all = edrk.oborots;//fast_round(_IQtoF(WRotor.iqWRotorSumFilter3) * NORMA_FROTOR * 60); //Sensor 1 + modbus_table_can_out[75].all = edrk.oborots;//fast_round(_IQtoF(WRotor.iqWRotorSumFilter3) * NORMA_FROTOR * 60); //Sensor 1 + + modbus_table_can_out[76].all = fast_round(_IQtoF(edrk.zadanie.iq_power_zad_rmp) * NORMA_ACP * NORMA_ACP / 1000.0); + modbus_table_can_out[77].all = fabs(edrk.power_kw);// fast_round(_IQtoF(filter.PowerScalar) * NORMA_ACP* NORMA_ACP / 1000.0); + + modbus_table_can_out[78].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[0]); + modbus_table_can_out[79].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[1]); + modbus_table_can_out[80].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[2]); + modbus_table_can_out[81].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[3]); + modbus_table_can_out[82].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[4]); + modbus_table_can_out[83].all = fast_round(edrk.temper_acdrive.winding.filter_real_temper[5]); + modbus_table_can_out[84].all = fast_round(edrk.temper_acdrive.bear.filter_real_temper[0]); //��������� ������� TODO: ��������� ������������ + modbus_table_can_out[85].all = fast_round(edrk.temper_acdrive.bear.filter_real_temper[1]); //����������� ������� + + modbus_table_can_out[86].all = Unites[UMU_CAN_DEVICE][24]; + modbus_table_can_out[87].all = Unites[UMU_CAN_DEVICE][25]; + modbus_table_can_out[88].all = Unites[UMU_CAN_DEVICE][28]; + modbus_table_can_out[89].all = Unites[UMU_CAN_DEVICE][29]; + modbus_table_can_out[90].all = Unites[UMU_CAN_DEVICE][34]; + modbus_table_can_out[91].all = Unites[UMU_CAN_DEVICE][35]; + modbus_table_can_out[92].all = Unites[UMU_CAN_DEVICE][34]; //����������, ��� � ���� + modbus_table_can_out[93].all = Unites[UMU_CAN_DEVICE][35]; //����������, ��� � ���� + + modbus_table_can_out[94].all = edrk.warnings.e2.bits.T_UO1_MAX | edrk.warnings.e2.bits.T_UO2_MAX | + edrk.warnings.e2.bits.T_UO3_MAX | edrk.warnings.e2.bits.T_UO4_MAX | + edrk.warnings.e2.bits.T_UO5_MAX | edrk.warnings.e2.bits.T_UO6_MAX | + edrk.warnings.e2.bits.T_UO7_MAX; + modbus_table_can_out[95].all = edrk.errors.e2.bits.T_UO1_MAX | edrk.errors.e2.bits.T_UO2_MAX | + edrk.errors.e2.bits.T_UO3_MAX | edrk.errors.e2.bits.T_UO4_MAX | + edrk.errors.e2.bits.T_UO5_MAX | edrk.errors.e2.bits.T_UO6_MAX | + edrk.errors.e2.bits.T_UO7_MAX; + modbus_table_can_out[96].all = edrk.warnings.e2.bits.T_AIR0_MAX | edrk.warnings.e2.bits.T_AIR1_MAX | + edrk.warnings.e2.bits.T_AIR2_MAX | edrk.warnings.e2.bits.T_AIR3_MAX; + modbus_table_can_out[97].all = edrk.errors.e2.bits.T_AIR0_MAX | edrk.errors.e2.bits.T_AIR1_MAX | + edrk.errors.e2.bits.T_AIR2_MAX | edrk.errors.e2.bits.T_AIR3_MAX; + modbus_table_can_out[98].all = edrk.warnings.e2.bits.T_WATER_EXT_MAX; + modbus_table_can_out[99].all = edrk.errors.e2.bits.T_WATER_EXT_MAX; + modbus_table_can_out[100].all = edrk.warnings.e2.bits.T_WATER_INT_MAX; + modbus_table_can_out[101].all = edrk.errors.e2.bits.T_WATER_INT_MAX; + + modbus_table_can_out[102].all = edrk.warnings.e2.bits.P_WATER_INT_MAX; + modbus_table_can_out[103].all = edrk.errors.e2.bits.P_WATER_INT_MAX; + modbus_table_can_out[104].all = edrk.warnings.e2.bits.P_WATER_INT_MIN; + modbus_table_can_out[105].all = edrk.errors.e2.bits.P_WATER_INT_MIN; + + modbus_table_can_out[106].all = edrk.warnings.e7.bits.T_ACDRIVE_WINDING_MAX; + modbus_table_can_out[107].all = edrk.errors.e7.bits.T_ACDRIVE_WINDING_MAX; + modbus_table_can_out[108].all = edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE; //����������� ���������� + modbus_table_can_out[109].all = edrk.errors.e7.bits.T_ACDRIVE_BEAR_MAX_DNE; + modbus_table_can_out[110].all = edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE; //��������� ��������� � �� ��������� + modbus_table_can_out[111].all = edrk.errors.e9.bits.T_ACDRIVE_BEAR_MAX_NE; + + modbus_table_can_out[112].all = edrk.warnings.e9.bits.I_GED_MAX; + modbus_table_can_out[113].all = edrk.errors.e1.bits.I_UO2_MAX | edrk.errors.e1.bits.I_UO3_MAX | + edrk.errors.e1.bits.I_UO4_MAX | edrk.errors.e1.bits.I_UO5_MAX | + edrk.errors.e1.bits.I_UO6_MAX | edrk.errors.e1.bits.I_UO7_MAX; //TODO add adc errors + modbus_table_can_out[114].all = edrk.errors.e0.bits.I_1_MAX | edrk.errors.e0.bits.I_2_MAX; + modbus_table_can_out[115].all = edrk.errors.e0.bits.U_1_MAX | edrk.errors.e0.bits.U_2_MAX; + modbus_table_can_out[116].all = edrk.warnings.e0.bits.U_IN_MIN; + modbus_table_can_out[117].all = edrk.errors.e0.bits.U_IN_MIN; + modbus_table_can_out[118].all = edrk.warnings.e0.bits.U_IN_MAX; + modbus_table_can_out[119].all = edrk.errors.e0.bits.U_IN_MAX; + modbus_table_can_out[120].all = edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK; //TODO ������������� ������� �������� + modbus_table_can_out[121].all = edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK; //TODO ���������� ���������� �������� + modbus_table_can_out[122].all = edrk.Kvitir; + + + modbus_table_can_out[137].all = edrk.pult_data.data_from_pult.moto[15]; + modbus_table_can_out[138].all = edrk.pult_data.data_from_pult.moto[6]; + + update_errors_to_svu(); + update_protect_levels_to_MPU(); + + copy_from_can_out_to_rs_out(); + +} + +#define MPU_ADRESS_CMD_START 122 // � ��� -1 ������������ ���14, 122 ������������� 123 � ���14 +#define MPU_ADRESS_CMD_END 144 //138 // + +#if (MPU_ADRESS_CMD_END>=SIZE_MODBUS_TABLE) +#define MPU_ADRESS_CMD_END (SIZE_MODBUS_TABLE-1) +#endif + + +#if (MPU_ADRESS_CMD_END - MPU_ADRESS_CMD_START +1 )>CONTROL_STATION_MAX_RAW_DATA +#define MPU_LENGTH_CMD CONTROL_STATION_MAX_RAW_DATA +#else +#define MPU_LENGTH_CMD (MPU_ADRESS_CMD_END - MPU_ADRESS_CMD_START + 1) +#endif +///////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////// + +void unpack_answer_from_MPU_SVU_CAN_filter(unsigned int cc) +{ + unsigned int i = 0, j = 0, k, max_data; + + for (i = 0; i < MPU_LENGTH_CMD; i++) + { + max_data = 0;//control_station.raw_array_data_temp[cc][i][0].all; + //min_data = 0;//control_station.raw_array_data_temp[cc][i][0].all; + + for (j=0; j<CONTROL_STATION_MAX_RAW_DATA_TEMP; j++) + { + if (control_station.raw_array_data_temp[cc][i][j].all > max_data) + max_data = control_station.raw_array_data_temp[cc][i][j].all; + } + + control_station.raw_array_data[cc][i].all = max_data; + + } + +} + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + + +void unpack_answer_from_MPU_SVU_CAN(unsigned int cc) { + int i = 0, j = 0, k; +// static unsigned int prev_CAN_count_cycle_input_units = 0; + + if (control_station.prev_CAN_count_cycle_input_units[cc] != mpu_can_setup.CAN_count_cycle_input_units[0]) + { + k = control_station.count_raw_array_data_temp[cc]; + for (i = 0, j = 0; i < MPU_LENGTH_CMD && j < CONTROL_STATION_MAX_RAW_DATA; i++, j++) + { + control_station.raw_array_data_temp[cc][j][k].all = modbus_table_can_in[MPU_ADRESS_CMD_START+i].all; + } + + control_station.count_raw_array_data_temp[cc]++; + if (control_station.count_raw_array_data_temp[cc]>=CONTROL_STATION_MAX_RAW_DATA_TEMP) + control_station.count_raw_array_data_temp[cc] = 0; + + control_station.prev_CAN_count_cycle_input_units[cc] = mpu_can_setup.CAN_count_cycle_input_units[0]; + } + + +// for (i = ADRESS_CMD_START, j = 0; i < SIZE_MODBUS_TABLE && j < CONTROL_STATION_MAX_RAW_DATA; i++, j++) +// { +// control_station.raw_array_data[cc][j].all = modbus_table_can_in[i].all; +// } + + unpack_answer_from_MPU_SVU_CAN_filter(cc); + +} + +void unpack_answer_from_MPU_SVU_RS(unsigned int cc) { + int i = 0, j = 0; + for (i = MPU_ADRESS_CMD_START, j = 0; i < SIZE_MODBUS_TABLE && j < CONTROL_STATION_MAX_RAW_DATA; i++, j++) + control_station.raw_array_data[cc][j].all = modbus_table_rs_in[i].all; +} + +void update_errors_to_svu() { + modbus_table_can_out[208].bit.bit0 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_ack; + modbus_table_can_out[208].bit.bit1 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_ack; + modbus_table_can_out[208].bit.bit2 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_ack; + modbus_table_can_out[208].bit.bit3 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_ack; + modbus_table_can_out[208].bit.bit4 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_ack; + modbus_table_can_out[208].bit.bit5 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_ack; + modbus_table_can_out[208].bit.bit6 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_ack; + modbus_table_can_out[208].bit.bit7 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_ack; + + modbus_table_can_out[208].bit.bit8 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_ack; + modbus_table_can_out[208].bit.bit9 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_ack; + modbus_table_can_out[208].bit.bit10 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_ack; + modbus_table_can_out[208].bit.bit11 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_ack; + modbus_table_can_out[208].bit.bit12 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_ack; + modbus_table_can_out[208].bit.bit13 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_ack; + modbus_table_can_out[208].bit.bit14 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_ack; + modbus_table_can_out[208].bit.bit15 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_ack; + + modbus_table_can_out[200].bit.bit0 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_ack; + modbus_table_can_out[200].bit.bit1 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_ack; + modbus_table_can_out[200].bit.bit2 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_ack; + modbus_table_can_out[200].bit.bit3 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_ack; + modbus_table_can_out[200].bit.bit4 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_ack; + modbus_table_can_out[200].bit.bit5 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_ack; + modbus_table_can_out[200].bit.bit6 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_ack; + modbus_table_can_out[200].bit.bit7 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_ack; + modbus_table_can_out[200].bit.bit8 = project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_ack; + modbus_table_can_out[200].bit.bit9 = project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_ack; + + if (edrk.flag_second_PCH == 1) { + modbus_table_can_out[200].bit.bit10 = edrk.errors.e4.bits.ANOTHER_BS_POWER_OFF; + } else { + modbus_table_can_out[200].bit.bit11 = edrk.errors.e4.bits.ANOTHER_BS_POWER_OFF; + } + + modbus_table_can_out[201].bit.bit0 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk0_current; + modbus_table_can_out[201].bit.bit1 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk1_current; + modbus_table_can_out[201].bit.bit2 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk2_current; + modbus_table_can_out[201].bit.bit3 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk3_current; + modbus_table_can_out[201].bit.bit4 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk4_current; + modbus_table_can_out[201].bit.bit5 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk5_current; + modbus_table_can_out[201].bit.bit6 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk6_current; + modbus_table_can_out[201].bit.bit7 = project.cds_tk[0].read.sbus.status_protect_current_ack.bit.tk7_current; + modbus_table_can_out[201].bit.bit8 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk0_current; + modbus_table_can_out[201].bit.bit9 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk1_current; + modbus_table_can_out[201].bit.bit10 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk2_current; + modbus_table_can_out[201].bit.bit11 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk3_current; + modbus_table_can_out[201].bit.bit12 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk4_current; + modbus_table_can_out[201].bit.bit13 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk5_current; + modbus_table_can_out[201].bit.bit14 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk6_current; + modbus_table_can_out[201].bit.bit15 = project.cds_tk[1].read.sbus.status_protect_current_ack.bit.tk7_current; + + modbus_table_can_out[202].bit.bit0 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk0_current; + modbus_table_can_out[202].bit.bit1 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk1_current; + modbus_table_can_out[202].bit.bit2 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk2_current; + modbus_table_can_out[202].bit.bit3 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk3_current; + modbus_table_can_out[202].bit.bit4 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk4_current; + modbus_table_can_out[202].bit.bit5 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk5_current; + modbus_table_can_out[202].bit.bit6 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk6_current; + modbus_table_can_out[202].bit.bit7 = project.cds_tk[2].read.sbus.status_protect_current_ack.bit.tk7_current; + modbus_table_can_out[202].bit.bit8 = project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk0_current; + modbus_table_can_out[202].bit.bit9 = project.cds_tk[3].read.sbus.status_protect_current_ack.bit.tk1_current; + + modbus_table_can_out[203].bit.bit0 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit1 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit2 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit3 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit4 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit5 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit6 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit7 = project.cds_tk[0].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit8 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit9 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit10 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit11 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[203].bit.bit12 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit13 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit14 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[203].bit.bit15 = project.cds_tk[1].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + + modbus_table_can_out[204].bit.bit0 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[204].bit.bit1 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[204].bit.bit2 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[204].bit.bit3 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[204].bit.bit4 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[204].bit.bit5 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[204].bit.bit6 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[204].bit.bit7 = project.cds_tk[2].read.sbus.lock_status_error.bit.mintime_err_keys_7654; + modbus_table_can_out[204].bit.bit8 = project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + modbus_table_can_out[204].bit.bit9 = project.cds_tk[3].read.sbus.lock_status_error.bit.mintime_err_keys_3210; + + modbus_table_can_out[205].bit.bit0 = edrk.errors.e3.bits.NOT_READY_TK_0; + modbus_table_can_out[205].bit.bit1 = edrk.errors.e3.bits.NOT_READY_TK_1; + modbus_table_can_out[205].bit.bit2 = edrk.errors.e3.bits.NOT_READY_TK_2; + modbus_table_can_out[205].bit.bit3 = edrk.errors.e3.bits.NOT_READY_TK_3; + modbus_table_can_out[205].bit.bit4 = edrk.errors.e3.bits.NOT_READY_IN_0; + modbus_table_can_out[205].bit.bit5 = edrk.errors.e3.bits.NOT_READY_IN_1; + modbus_table_can_out[205].bit.bit6 = edrk.errors.e3.bits.NOT_READY_OUT_0; + modbus_table_can_out[205].bit.bit7 = edrk.errors.e3.bits.NOT_READY_ADC_0; + modbus_table_can_out[205].bit.bit8 = edrk.errors.e3.bits.NOT_READY_HWP_0; + modbus_table_can_out[205].bit.bit9 = edrk.errors.e3.bits.NOT_READY_ADC_1; + modbus_table_can_out[205].bit.bit10 = edrk.errors.e3.bits.NOT_READY_CONTR; + + modbus_table_can_out[206].bit.bit0 = edrk.errors.e5.bits.KEY_AVARIA; + modbus_table_can_out[206].bit.bit1 = edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER; + modbus_table_can_out[206].bit.bit2 = edrk.errors.e7.bits.SVU_BLOCK_ON_QTV; + modbus_table_can_out[206].bit.bit3 = edrk.errors.e7.bits.UMP_NOT_ANSWER; + modbus_table_can_out[206].bit.bit4 = edrk.errors.e7.bits.UMP_NOT_READY; + modbus_table_can_out[206].bit.bit5 = edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER; + modbus_table_can_out[206].bit.bit6 = edrk.errors.e7.bits.ANOTHER_RASCEPITEL_ON; + modbus_table_can_out[206].bit.bit7 = edrk.warnings.e7.bits.AUTO_SET_MASTER; + modbus_table_can_out[206].bit.bit8 = edrk.errors.e7.bits.ANOTHER_PCH_NOT_ANSWER; + modbus_table_can_out[206].bit.bit9 = edrk.errors.e8.bits.WDOG_OPTICAL_BUS; + modbus_table_can_out[206].bit.bit10 = edrk.errors.e6.bits.QTV_ERROR_NOT_ANSWER; //��� ������������� �� ���������� �������� �������� ���� + modbus_table_can_out[206].bit.bit11 = edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL; //��� ���������� �� ������� �� �� ����������� ����������� + modbus_table_can_out[206].bit.bit12 = edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER; + modbus_table_can_out[206].bit.bit13 = edrk.errors.e1.bits.ANOTHER_BS_VERY_LONG_WAIT; + modbus_table_can_out[206].bit.bit14 = edrk.errors.e1.bits.VERY_LONG_BOTH_READY2; + modbus_table_can_out[206].bit.bit15 = edrk.errors.e1.bits.BOTH_KEYS_CHARGE_DISCHARGE; + + + modbus_table_can_out[207].bit.bit0 = !control_station.alive_control_station[CONTROL_STATION_ZADATCHIK_CAN]; + modbus_table_can_out[207].bit.bit1 = !control_station.alive_control_station[CONTROL_STATION_MPU_SVU_CAN]; + modbus_table_can_out[207].bit.bit2 = 0;// CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,UMU_CAN_DEVICE)]; �������� �� ����� + modbus_table_can_out[207].bit.bit3 = CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,BKSSD_CAN_DEVICE)]; + modbus_table_can_out[207].bit.bit4 = CAN_timeout[get_real_in_mbox(UNITS_TYPE_BOX,VPU_CAN)]; + modbus_table_can_out[207].bit.bit5 = edrk.warnings.e7.bits.CAN2CAN_BS; + modbus_table_can_out[207].bit.bit6 = edrk.errors.e7.bits.CAN2CAN_BS; + + if (edrk.flag_second_PCH == 1) { + modbus_table_can_out[207].bit.bit7 = edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF; + } else { + modbus_table_can_out[207].bit.bit8 = edrk.warnings.e4.bits.ANOTHER_BS_POWER_OFF; + } + modbus_table_can_out[207].bit.bit9 = edrk.errors.e7.bits.ANOTHER_BS_ALARM; //��������� ���������� ������� �� (���������� �����) + modbus_table_can_out[207].bit.bit10 = edrk.warnings.e7.bits.READ_OPTBUS; //��� ������������� ����������������� ����������� ������ �� ������� �� ��� ���������� ���������� + + modbus_table_can_out[209].bit.bit0 = edrk.errors.e5.bits.OP_PIT; + modbus_table_can_out[209].bit.bit1 = edrk.errors.e5.bits.UTE4KA_WATER; + modbus_table_can_out[209].bit.bit2 = edrk.errors.e1.bits.BLOCK_DOOR; + modbus_table_can_out[209].bit.bit3 = edrk.errors.e7.bits.UMP_NOT_READY; + modbus_table_can_out[209].bit.bit4 = edrk.errors.e5.bits.FAN; + modbus_table_can_out[209].bit.bit5 = edrk.errors.e5.bits.PUMP_1; + modbus_table_can_out[209].bit.bit6 = edrk.errors.e5.bits.PRE_READY_PUMP; + modbus_table_can_out[209].bit.bit7 = edrk.errors.e5.bits.ERROR_HEAT; + modbus_table_can_out[209].bit.bit8 = edrk.warnings.e5.bits.ERROR_ISOLATE; + modbus_table_can_out[209].bit.bit9 = edrk.errors.e5.bits.ERROR_PRED_VIPR; + modbus_table_can_out[209].bit.bit10 = edrk.errors.e5.bits.ERROR_ISOLATE; + modbus_table_can_out[209].bit.bit11 = edrk.errors.e5.bits.POWER_UPC; + modbus_table_can_out[209].bit.bit12 = edrk.errors.e5.bits.ERROR_GROUND_NET; + modbus_table_can_out[209].bit.bit13 = edrk.errors.e5.bits.PUMP_2; + modbus_table_can_out[209].bit.bit14 = edrk.from_ing1.bits.BLOCK_IZOL_NORMA ? 0 : 1; + + modbus_table_can_out[210].bit.bit0 = edrk.errors.e0.bits.U_1_MAX; + modbus_table_can_out[210].bit.bit1 = edrk.errors.e0.bits.U_2_MAX; + modbus_table_can_out[210].bit.bit2 = edrk.errors.e0.bits.U_1_MIN; + modbus_table_can_out[210].bit.bit3 = edrk.errors.e0.bits.U_2_MIN; + modbus_table_can_out[210].bit.bit4 = edrk.errors.e0.bits.U_A1B1_MAX; + modbus_table_can_out[210].bit.bit5 = edrk.errors.e0.bits.U_A2B2_MAX; + modbus_table_can_out[210].bit.bit6 = edrk.errors.e0.bits.U_B1C1_MAX; + modbus_table_can_out[210].bit.bit7 = edrk.errors.e0.bits.U_B2C2_MAX; + modbus_table_can_out[210].bit.bit8 = edrk.errors.e0.bits.U_A1B1_MIN; + modbus_table_can_out[210].bit.bit9 = edrk.errors.e0.bits.U_A2B2_MIN; + modbus_table_can_out[210].bit.bit10 = edrk.errors.e0.bits.U_B1C1_MIN; + modbus_table_can_out[210].bit.bit11 = edrk.errors.e0.bits.U_B2C2_MIN; + modbus_table_can_out[210].bit.bit12 = edrk.errors.e0.bits.U_IN_MAX; + modbus_table_can_out[210].bit.bit13 = edrk.errors.e0.bits.U_IN_MIN; + + modbus_table_can_out[211].bit.bit0 = edrk.errors.e1.bits.I_UO2_MAX; + modbus_table_can_out[211].bit.bit1 = edrk.errors.e1.bits.I_UO3_MAX; + modbus_table_can_out[211].bit.bit2 = edrk.errors.e1.bits.I_UO4_MAX; + modbus_table_can_out[211].bit.bit3 = edrk.errors.e1.bits.I_UO5_MAX; + modbus_table_can_out[211].bit.bit4 = edrk.errors.e1.bits.I_UO6_MAX; + modbus_table_can_out[211].bit.bit5 = edrk.errors.e1.bits.I_UO7_MAX; + modbus_table_can_out[211].bit.bit6 = edrk.errors.e1.bits.I_BREAK_1_MAX; + modbus_table_can_out[211].bit.bit7 = edrk.errors.e1.bits.I_BREAK_2_MAX; + modbus_table_can_out[211].bit.bit8 = edrk.errors.e0.bits.I_1_MAX; + modbus_table_can_out[211].bit.bit9 = edrk.errors.e0.bits.I_1_MAX; + + modbus_table_can_out[211].bit.bit10 = edrk.warnings.e2.bits.T_AIR0_MAX; + modbus_table_can_out[211].bit.bit11 = edrk.warnings.e2.bits.T_AIR1_MAX; + modbus_table_can_out[211].bit.bit12 = edrk.warnings.e2.bits.T_AIR2_MAX; + modbus_table_can_out[211].bit.bit13 = edrk.warnings.e2.bits.T_AIR3_MAX; + + if (edrk.power_limit.all) + modbus_table_can_out[211].bit.bit14 = 1; + else + modbus_table_can_out[211].bit.bit14 = 0; + + modbus_table_can_out[211].bit.bit15 = edrk.warnings.e10.bits.WARNING_I_OUT_OVER_1_6_NOMINAL; + + modbus_table_can_out[212].bit.bit0 = edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON; + modbus_table_can_out[212].bit.bit1 = edrk.errors.e7.bits.ERROR_SBOR_SHEMA; + + + + + modbus_table_can_out[213].bit.bit0 = project.hwp[0].read.comp_s.plus.bit.ch0; + modbus_table_can_out[213].bit.bit1 = project.hwp[0].read.comp_s.plus.bit.ch1; + modbus_table_can_out[213].bit.bit2 = project.hwp[0].read.comp_s.plus.bit.ch2; + modbus_table_can_out[213].bit.bit3 = project.hwp[0].read.comp_s.plus.bit.ch3; + modbus_table_can_out[213].bit.bit4 = project.hwp[0].read.comp_s.plus.bit.ch4; + modbus_table_can_out[213].bit.bit5 = project.hwp[0].read.comp_s.plus.bit.ch5; + modbus_table_can_out[213].bit.bit6 = project.hwp[0].read.comp_s.plus.bit.ch6; + modbus_table_can_out[213].bit.bit7 = project.hwp[0].read.comp_s.plus.bit.ch7; + modbus_table_can_out[213].bit.bit8 = 0; + modbus_table_can_out[213].bit.bit9 = project.hwp[0].read.comp_s.plus.bit.ch9; + modbus_table_can_out[213].bit.bit10 = project.hwp[0].read.comp_s.plus.bit.ch10; + modbus_table_can_out[213].bit.bit11 = project.hwp[0].read.comp_s.plus.bit.ch11; + modbus_table_can_out[213].bit.bit12 = project.hwp[0].read.comp_s.plus.bit.ch12; + modbus_table_can_out[213].bit.bit13 = project.hwp[0].read.comp_s.plus.bit.ch13; + modbus_table_can_out[213].bit.bit14 = project.hwp[0].read.comp_s.plus.bit.ch14; + modbus_table_can_out[213].bit.bit15 = project.hwp[0].read.comp_s.plus.bit.ch15; + + modbus_table_can_out[214].bit.bit0 = edrk.errors.e5.bits.LINE_ERR0; + modbus_table_can_out[214].bit.bit1 = edrk.errors.e5.bits.LINE_HWP; + modbus_table_can_out[214].bit.bit2 = project.hwp[0].read.comp_s.minus.bit.ch2; + modbus_table_can_out[214].bit.bit3 = project.hwp[0].read.comp_s.minus.bit.ch3; + modbus_table_can_out[214].bit.bit4 = project.hwp[0].read.comp_s.minus.bit.ch4; + modbus_table_can_out[214].bit.bit5 = project.hwp[0].read.comp_s.minus.bit.ch5; + modbus_table_can_out[214].bit.bit6 = project.hwp[0].read.comp_s.minus.bit.ch6; + modbus_table_can_out[214].bit.bit7 = project.hwp[0].read.comp_s.minus.bit.ch7; + modbus_table_can_out[214].bit.bit8 = 0; + modbus_table_can_out[214].bit.bit9 = project.hwp[0].read.comp_s.minus.bit.ch9; + modbus_table_can_out[214].bit.bit10 = project.hwp[0].read.comp_s.minus.bit.ch10; + modbus_table_can_out[214].bit.bit11 = project.hwp[0].read.comp_s.minus.bit.ch11; + modbus_table_can_out[214].bit.bit12 = project.hwp[0].read.comp_s.minus.bit.ch12; + modbus_table_can_out[214].bit.bit13 = project.hwp[0].read.comp_s.minus.bit.ch13; + modbus_table_can_out[214].bit.bit14 = project.hwp[0].read.comp_s.minus.bit.ch14; + modbus_table_can_out[214].bit.bit15 = project.hwp[0].read.comp_s.minus.bit.ch15; + + modbus_table_can_out[215].bit.bit0 = edrk.errors.e8.bits.LOSS_INPUT_A1B1 | edrk.errors.e9.bits.DISBALANCE_Uin_1; //TODO: ������ ����� ��������� + modbus_table_can_out[215].bit.bit1 = edrk.errors.e8.bits.LOSS_INPUT_B1C1 | edrk.errors.e9.bits.DISBALANCE_Uin_1; + modbus_table_can_out[215].bit.bit2 = edrk.errors.e8.bits.LOSS_INPUT_A2B2 | edrk.errors.e9.bits.DISBALANCE_Uin_2; + modbus_table_can_out[215].bit.bit3 = edrk.errors.e8.bits.LOSS_INPUT_B2C2 | edrk.errors.e9.bits.DISBALANCE_Uin_2; + modbus_table_can_out[215].bit.bit4 = edrk.errors.e9.bits.U_IN_FREQ_NOT_NORMA; + modbus_table_can_out[215].bit.bit5 = edrk.errors.e9.bits.U_IN_FREQ_NOT_STABLE; + modbus_table_can_out[215].bit.bit6 = edrk.errors.e7.bits.READ_OPTBUS | edrk.errors.e7.bits.WRITE_OPTBUS; + modbus_table_can_out[215].bit.bit7 = edrk.errors.e7.bits.MASTER_SLAVE_SYNC; + modbus_table_can_out[215].bit.bit8 = project.controller.read.errors_buses.bit.err_sbus; + modbus_table_can_out[215].bit.bit9 = project.controller.read.errors.bit.error_pbus || project.controller.read.errors_buses.bit.slave_addr_error + || project.controller.read.errors_buses.bit.count_error_pbus; + modbus_table_can_out[215].bit.bit10 = edrk.errors.e6.bits.ER_DISBAL_BATT; + modbus_table_can_out[215].bit.bit11 = edrk.errors.e6.bits.QTV_ERROR_NOT_U; + modbus_table_can_out[215].bit.bit12 = edrk.errors.e6.bits.ERROR_PRE_CHARGE_U; + modbus_table_can_out[215].bit.bit13 = edrk.errors.e8.bits.U_IN_20_PROCENTS_HIGH; + modbus_table_can_out[215].bit.bit14 = edrk.errors.e8.bits.U_IN_10_PROCENTS_LOW; + modbus_table_can_out[215].bit.bit15 = edrk.errors.e8.bits.U_IN_20_PROCENTS_LOW; + + modbus_table_can_out[216].bit.bit0 = project.cds_tk[0].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit1 = project.cds_tk[1].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit2 = project.cds_tk[2].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit3 = project.cds_tk[3].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit4 = project.cds_in[0].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit5 = project.cds_in[1].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit6 = project.cds_out[0].read.sbus.lock_status_error.bit.err_power; + modbus_table_can_out[216].bit.bit7 = edrk.errors.e7.bits.NOT_VALID_CONTROL_STATION; + modbus_table_can_out[216].bit.bit8 = edrk.errors.e8.bits.LOSS_OUTPUT_U1; + modbus_table_can_out[216].bit.bit9 = edrk.errors.e8.bits.LOSS_OUTPUT_V1; + modbus_table_can_out[216].bit.bit10 = edrk.errors.e8.bits.LOSS_OUTPUT_W1; + modbus_table_can_out[216].bit.bit11 = edrk.errors.e8.bits.LOSS_OUTPUT_U2; + modbus_table_can_out[216].bit.bit12 = edrk.errors.e8.bits.LOSS_OUTPUT_V2; + modbus_table_can_out[216].bit.bit13 = edrk.errors.e8.bits.LOSS_OUTPUT_W2; + modbus_table_can_out[216].bit.bit14 = edrk.errors.e8.bits.DISBALANCE_IM1_IM2; + modbus_table_can_out[216].bit.bit15 = edrk.errors.e7.bits.VERY_FAST_GO_0to1; + + modbus_table_can_out[217].bit.bit0 = project.cds_tk[0].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit1 = project.cds_tk[1].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit2 = project.cds_tk[2].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit3 = project.cds_tk[3].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit4 = project.cds_in[0].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit5 = project.cds_in[1].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit6 = project.cds_out[0].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit7 = project.adc[0].read.sbus.lock_status_error.bit.err_switch; + modbus_table_can_out[217].bit.bit8 = 0; + modbus_table_can_out[217].bit.bit9 = project.adc[1].read.sbus.lock_status_error.bit.err_switch; + + modbus_table_can_out[218].bit.bit0 = edrk.warnings.e2.bits.T_UO1_MAX; + modbus_table_can_out[218].bit.bit1 = edrk.warnings.e2.bits.T_UO2_MAX; + modbus_table_can_out[218].bit.bit2 = edrk.warnings.e2.bits.T_UO3_MAX; + modbus_table_can_out[218].bit.bit3 = edrk.warnings.e2.bits.T_UO4_MAX; + modbus_table_can_out[218].bit.bit4 = edrk.warnings.e2.bits.T_UO5_MAX; + modbus_table_can_out[218].bit.bit5 = edrk.warnings.e2.bits.T_UO6_MAX; + modbus_table_can_out[218].bit.bit6 = edrk.warnings.e2.bits.T_UO7_MAX; + modbus_table_can_out[218].bit.bit7 = edrk.errors.e2.bits.T_UO1_MAX; + modbus_table_can_out[218].bit.bit8 = edrk.errors.e2.bits.T_UO2_MAX; + modbus_table_can_out[218].bit.bit9 = edrk.errors.e2.bits.T_UO3_MAX; + modbus_table_can_out[218].bit.bit10 = edrk.errors.e2.bits.T_UO4_MAX; + modbus_table_can_out[218].bit.bit11 = edrk.errors.e2.bits.T_UO5_MAX; + modbus_table_can_out[218].bit.bit12 = edrk.errors.e2.bits.T_UO6_MAX; + modbus_table_can_out[218].bit.bit13 = edrk.errors.e2.bits.T_UO7_MAX; + + modbus_table_can_out[219].bit.bit0 = edrk.warnings.e7.bits.READ_OPTBUS | edrk.warnings.e7.bits.WRITE_OPTBUS; + modbus_table_can_out[219].bit.bit1 = edrk.warnings.e7.bits.MASTER_SLAVE_SYNC; + modbus_table_can_out[219].bit.bit2 = edrk.errors.e6.bits.ERROR_PRE_CHARGE_ANSWER; + modbus_table_can_out[219].bit.bit3 = edrk.warnings.e1.bits.NO_INPUT_SYNC_SIGNAL; + modbus_table_can_out[219].bit.bit4 = edrk.errors.e1.bits.NO_INPUT_SYNC_SIGNAL; + modbus_table_can_out[219].bit.bit5 = edrk.errors.e3.bits.ERR_INT_PWM_LONG + || edrk.errors.e9.bits.ERR_PWM_WDOG + || edrk.errors.e9.bits.ERR_INT_PWM_VERY_LONG; + modbus_table_can_out[219].bit.bit15 = edrk.errors.e5.bits.T_VIPR_MAX; + + modbus_table_can_out[220].bit.bit0 = edrk.errors.e2.bits.T_AIR0_MAX; + modbus_table_can_out[220].bit.bit1 = edrk.errors.e2.bits.T_AIR1_MAX; + modbus_table_can_out[220].bit.bit2 = edrk.errors.e2.bits.T_AIR2_MAX; + modbus_table_can_out[220].bit.bit3 = edrk.errors.e2.bits.T_AIR3_MAX; + modbus_table_can_out[220].bit.bit4 = edrk.warnings.e10.bits.T_BSU_Sensor_BK1; + modbus_table_can_out[220].bit.bit5 = edrk.errors.e10.bits.T_BSU_Sensor_BK1; + modbus_table_can_out[220].bit.bit6 = edrk.warnings.e10.bits.T_BSU_Sensor_BK2; + modbus_table_can_out[220].bit.bit7 = edrk.errors.e10.bits.T_BSU_Sensor_BK2; + + modbus_table_can_out[220].bit.bit8 = edrk.errors.e2.bits.T_WATER_EXT_MAX; + modbus_table_can_out[220].bit.bit9 = edrk.errors.e2.bits.T_WATER_INT_MAX; + modbus_table_can_out[220].bit.bit10 = edrk.warnings.e2.bits.T_WATER_EXT_MAX; + modbus_table_can_out[220].bit.bit11 = edrk.warnings.e2.bits.T_WATER_INT_MAX; + + modbus_table_can_out[220].bit.bit12 = edrk.errors.e7.bits.T_ACDRIVE_BEAR_MAX_DNE; + modbus_table_can_out[220].bit.bit13 = edrk.errors.e9.bits.T_ACDRIVE_BEAR_MAX_NE; + modbus_table_can_out[220].bit.bit14 = edrk.warnings.e7.bits.T_ACDRIVE_BEAR_MAX_DNE; + modbus_table_can_out[220].bit.bit15 = edrk.warnings.e9.bits.T_ACDRIVE_BEAR_MAX_NE; + + modbus_table_can_out[221].bit.bit0 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_U1; + modbus_table_can_out[221].bit.bit1 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_V1; + modbus_table_can_out[221].bit.bit2 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_W1; + modbus_table_can_out[221].bit.bit3 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_U2; + modbus_table_can_out[221].bit.bit4 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_V2; + modbus_table_can_out[221].bit.bit5 = edrk.errors.e10.bits.T_ACDRIVE_WINDING_W2; + modbus_table_can_out[221].bit.bit6 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U1; + modbus_table_can_out[221].bit.bit7 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V1; + modbus_table_can_out[221].bit.bit8 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W1; + modbus_table_can_out[221].bit.bit9 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_U2; + modbus_table_can_out[221].bit.bit10 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_V2; + modbus_table_can_out[221].bit.bit11 = edrk.warnings.e10.bits.T_ACDRIVE_WINDING_W2; + + modbus_table_can_out[222].bit.bit0 = edrk.errors.e2.bits.P_WATER_INT_MAX; + modbus_table_can_out[222].bit.bit1 = edrk.errors.e2.bits.P_WATER_INT_MIN; + modbus_table_can_out[222].bit.bit2 = edrk.warnings.e2.bits.P_WATER_INT_MAX; + modbus_table_can_out[222].bit.bit3 = edrk.warnings.e2.bits.P_WATER_INT_MIN; + + + modbus_table_can_out[223].all = edrk.errors.e11.all; + + + +} + +void update_protect_levels_to_MPU() { + modbus_table_can_out[139].all = protect_levels.abnormal_temper_acdrive_winding_U1 / 10; + modbus_table_can_out[140].all = protect_levels.abnormal_temper_acdrive_winding_V1 / 10; + modbus_table_can_out[141].all = protect_levels.abnormal_temper_acdrive_winding_W1 / 10; + modbus_table_can_out[142].all = protect_levels.abnormal_temper_acdrive_winding_U2 / 10; + modbus_table_can_out[143].all = protect_levels.abnormal_temper_acdrive_winding_V2 / 10; + modbus_table_can_out[144].all = protect_levels.abnormal_temper_acdrive_winding_W2 / 10; + modbus_table_can_out[145].all = protect_levels.abnormal_temper_acdrive_bear_DNE / 10; + modbus_table_can_out[146].all = protect_levels.abnormal_temper_acdrive_bear_NE / 10; + + modbus_table_can_out[147].all = protect_levels.alarm_temper_acdrive_winding_U1 / 10; + modbus_table_can_out[148].all = protect_levels.alarm_temper_acdrive_winding_V1 / 10; + modbus_table_can_out[149].all = protect_levels.alarm_temper_acdrive_winding_W1 / 10; + modbus_table_can_out[150].all = protect_levels.alarm_temper_acdrive_winding_U2 / 10; + modbus_table_can_out[151].all = protect_levels.alarm_temper_acdrive_winding_V2 / 10; + modbus_table_can_out[152].all = protect_levels.alarm_temper_acdrive_winding_W2 / 10; + modbus_table_can_out[153].all = protect_levels.alarm_temper_acdrive_bear_DNE / 10; + modbus_table_can_out[154].all = protect_levels.alarm_temper_acdrive_bear_NE / 10; + + modbus_table_can_out[155].all = protect_levels.abnormal_temper_u_01 / 10; + modbus_table_can_out[156].all = protect_levels.abnormal_temper_u_02 / 10; + modbus_table_can_out[157].all = protect_levels.abnormal_temper_u_03 / 10; + modbus_table_can_out[158].all = protect_levels.abnormal_temper_u_04 / 10; + modbus_table_can_out[159].all = protect_levels.abnormal_temper_u_05 / 10; + modbus_table_can_out[160].all = protect_levels.abnormal_temper_u_06 / 10; + modbus_table_can_out[161].all = protect_levels.abnormal_temper_u_07 / 10; + modbus_table_can_out[162].all = protect_levels.alarm_temper_u_01 / 10; + modbus_table_can_out[163].all = protect_levels.alarm_temper_u_02 / 10; + modbus_table_can_out[164].all = protect_levels.alarm_temper_u_03 / 10; + modbus_table_can_out[165].all = protect_levels.alarm_temper_u_04 / 10; + modbus_table_can_out[166].all = protect_levels.alarm_temper_u_05 / 10; + modbus_table_can_out[167].all = protect_levels.alarm_temper_u_06 / 10; + modbus_table_can_out[168].all = protect_levels.alarm_temper_u_07 / 10; + + modbus_table_can_out[169].all = protect_levels.abnormal_temper_water_ext / 10; + modbus_table_can_out[170].all = protect_levels.abnormal_temper_water_int / 10; + modbus_table_can_out[171].all = protect_levels.alarm_p_water_min_int / 100; + modbus_table_can_out[172].all = protect_levels.alarm_temper_water_int / 10; + modbus_table_can_out[173].all = protect_levels.alarm_temper_water_ext / 10; + modbus_table_can_out[174].all = protect_levels.alarm_p_water_max_int / 100; + + modbus_table_can_out[175].all = protect_levels.abnormal_temper_air_int_01 / 10; + modbus_table_can_out[176].all = protect_levels.abnormal_temper_air_int_02 / 10; + modbus_table_can_out[177].all = protect_levels.abnormal_temper_air_int_03 / 10; + modbus_table_can_out[178].all = protect_levels.abnormal_temper_air_int_04 / 10; + modbus_table_can_out[179].all = protect_levels.alarm_temper_air_int_01 / 10; + modbus_table_can_out[180].all = protect_levels.alarm_temper_air_int_02 / 10; + modbus_table_can_out[181].all = protect_levels.alarm_temper_air_int_03 / 10; + modbus_table_can_out[182].all = protect_levels.alarm_temper_air_int_04 / 10; + + modbus_table_can_out[183].all = _IQtoF(analog_protect.in_voltage[0].setup.levels.iqNominal_minus20) * NORMA_ACP;//_IQtoF(edrk.iqMIN_U_IN) * NORMA_ACP; + modbus_table_can_out[184].all = _IQtoF(analog_protect.in_voltage[1].setup.levels.iqNominal_minus20) * NORMA_ACP; + modbus_table_can_out[185].all = _IQtoF(analog_protect.in_voltage[0].setup.levels.iqNominal_plus20) * NORMA_ACP;//_IQtoF(edrk.iqMIN_U_ZPT) * NORMA_ACP; + modbus_table_can_out[186].all = _IQtoF(analog_protect.in_voltage[1].setup.levels.iqNominal_plus20) * NORMA_ACP; + modbus_table_can_out[187].all = //_IQtoF(edrk.iqMAX_U_IN) * NORMA_ACP; + modbus_table_can_out[188].all = _IQtoF(edrk.iqMAX_U_IN) * NORMA_ACP; + modbus_table_can_out[189].all = //_IQtoF(edrk.iqMAX_U_ZPT) * NORMA_ACP; + modbus_table_can_out[190].all = _IQtoF(edrk.iqMAX_U_ZPT) * NORMA_ACP; + + modbus_table_can_out[191].all = protect_levels.alarm_Izpt_max; + + modbus_table_can_out[192].all = protect_levels.alarm_Imax_U01; + modbus_table_can_out[193].all = protect_levels.alarm_Imax_U02; + modbus_table_can_out[194].all = protect_levels.alarm_Imax_U03; + modbus_table_can_out[195].all = protect_levels.alarm_Imax_U04; + modbus_table_can_out[196].all = protect_levels.alarm_Imax_U05; + modbus_table_can_out[197].all = protect_levels.alarm_Imax_U06; + modbus_table_can_out[198].all = protect_levels.alarm_Imax_U07; + modbus_table_can_out[199].all = protect_levels.alarm_Iged_max; +} diff --git a/Inu/Src/main/modbus_svu_update.h b/Inu/Src/main/modbus_svu_update.h new file mode 100644 index 0000000..d58d103 --- /dev/null +++ b/Inu/Src/main/modbus_svu_update.h @@ -0,0 +1,17 @@ +/* + * modbus_update_table.h + * + * Created on: 4 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_MODBUS_SVU_UPDATE_H_ +#define SRC_MAIN_MODBUS_SVU_UPDATE_H_ + + + +void update_svu_modbus_table(void); +void unpack_answer_from_MPU_SVU_CAN(unsigned int cc); +void unpack_answer_from_MPU_SVU_RS(unsigned int cc); + +#endif /* SRC_MAIN_MODBUS_SVU_UPDATE_H_ */ diff --git a/Inu/Src/main/not_use/log_to_mem.c b/Inu/Src/main/not_use/log_to_mem.c new file mode 100644 index 0000000..8a5c223 --- /dev/null +++ b/Inu/Src/main/not_use/log_to_mem.c @@ -0,0 +1,249 @@ +/****************************************************************/ +/* TMS320C32 */ +/* ====== BIOS, �����, ����� ====== */ +/* ���� ��� (�) 1998-2001�. */ +/****************************************************************/ +/* log_to_mem.c + **************************************************************** + * ������ ����� � ���y�� * + ****************************************************************/ + +#include <log_to_mem.h> + +#include "MemoryFunctions.h" + + +// ���������� ������������ ������ � ���� ������ +// ���������� �� �/� logs_data(), write_to_mem � clear_mem +// ��������� ����� ���y�� ��y ������ ����� (��. �/� write_to_mem) +//#pragma DATA_SECTION(count_mem,".fast_vars"); +//static long count_mem = START_ADDRESS_LOG; + +#pragma DATA_SECTION(count_mem_slow,".fast_vars"); +static long count_mem_slow = START_ADDRESS_LOG_SLOW; + + +// ��y��������� ��������� �������� ����� ���y��� ������ +// ���������y ��� ������ ����������� ������ +int hb_logs_data = 0; +#pragma DATA_SECTION(stop_log,".fast_vars"); +int stop_log = 0; +int stop_log_slow = 0; + + +#pragma DATA_SECTION(logpar,".fast_vars"); +LOGSPARAMS logpar = LOGSPARAMS_DEFAULTS; + +#pragma DATA_SECTION(no_write,".fast_vars"); +int no_write = 0; // ����, ����� �� ������ (���� ���) +#pragma DATA_SECTION(no_write_slow,".fast_vars"); +int no_write_slow = 0; // ����, ����� �� ������ (���� ���) + +#pragma CODE_SECTION(clear_logpar,".fast_run"); +void clear_logpar() +{ + int i; + for(i=0;i<SIZE_LOGS_ARRAY;i++) + logpar.logs[i] = 0; +} + +// ������ ���� ������� ������ ��������� � ���y��, ��� ���� ����� +#pragma CODE_SECTION(write_to_mem,".fast_run"); +void write_to_mem(int tlog,int DataM) +{ +// int DataT; + + if (tlog==FAST_LOG) + { + if (no_write) return; + + if (logpar.stop_log_level_1) return; + + if (logpar.addres_mem >= END_ADDRESS_LOG) logpar.addres_mem = END_ADDRESS_LOG; + + i_WriteMemory(logpar.addres_mem,DataM); + // *(int *)logpar.count_mem = ((DataM & 0xFFFF) ); + logpar.addres_mem++; + } + + if (tlog==SLOW_LOG) + { + if (no_write_slow) return; + + if (logpar.stop_log_slow_level_1) return; + + if (count_mem_slow >= END_ADDRESS_LOG_SLOW) count_mem_slow = END_ADDRESS_LOG_SLOW; + + i_WriteMemory(count_mem_slow,DataM); + // *(int *)logpar.count_mem = ((DataM & 0xFFFF) ); + count_mem_slow++; + } + + + + +} + + +#pragma CODE_SECTION(test_mem_limit,".fast_run"); +void test_mem_limit(int tlog,int ciclelog) +{ + if (tlog==FAST_LOG) + { + if( logpar.addres_mem >= (END_ADDRESS_LOG - LENGTH_HAZARD)) + { + logpar.real_finish_addres_mem = logpar.addres_mem; + + if (ciclelog==1) + { + stop_log = 0; + logpar.stop_log_level_1=0; + logpar.addres_mem = START_ADDRESS_LOG; + } + else + { + stop_log = 1; + logpar.stop_log_level_1=1; + } + } + + if( logpar.addres_mem >= (END_ADDRESS_LOG_LEVEL_2)) + { + logpar.stop_log_level_2=1; + } + else + { + logpar.stop_log_level_2=0; + } + + if( logpar.addres_mem >= (END_ADDRESS_LOG_LEVEL_3)) + { + logpar.stop_log_level_3=1; + } + else + { + logpar.stop_log_level_3=0; + } + } + else + { + if (tlog==SLOW_LOG) + { + if (ciclelog==1) + { + logpar.stop_log_slow_level_1=0; + } + + if( count_mem_slow >= (END_ADDRESS_LOG_SLOW - LENGTH_HAZARD)) + { + if (ciclelog==1) + { + stop_log_slow = 0; + logpar.stop_log_slow_level_1=0; + count_mem_slow = START_ADDRESS_LOG_SLOW; + } + else + { + stop_log_slow = 1; + logpar.stop_log_slow_level_1=1; + } + } + + if( count_mem_slow >= (END_ADDRESS_LOG_SLOW_LEVEL_2)) + { + logpar.stop_log_slow_level_2=1; + } + else + { + logpar.stop_log_slow_level_2=0; + } + + if( count_mem_slow >= (END_ADDRESS_LOG_SLOW_LEVEL_3)) + { + logpar.stop_log_slow_level_3=1; + } + else + { + logpar.stop_log_slow_level_3=0; + } + } + } +} + + + +// �������� ���y��, ��� ���� ����� +void clear_mem(int tlog) +{ + if (tlog==FAST_LOG) + { + logpar.real_finish_addres_mem = 0; + + for (logpar.addres_mem=START_ADDRESS_LOG; logpar.addres_mem<END_ADDRESS_LOG; logpar.addres_mem++)//END_ADDRESS_LOG; logpar.count_mem++) + i_WriteMemory(logpar.addres_mem,0x0); + + logpar.addres_mem = START_ADDRESS_LOG; + hb_logs_data = 0; + stop_log = 0; + + logpar.stop_log_level_1=0; + logpar.stop_log_level_2=0; + logpar.stop_log_level_3=0; + logpar.start_write_fast_log = 1; + } + + if (tlog==SLOW_LOG) + { + + for (count_mem_slow=START_ADDRESS_LOG_SLOW; count_mem_slow<END_ADDRESS_LOG_SLOW; count_mem_slow++) + i_WriteMemory(count_mem_slow,0x0); + + count_mem_slow = START_ADDRESS_LOG_SLOW; + hb_logs_data = 0; + stop_log_slow = 0; + + logpar.stop_log_slow_level_1=0; + logpar.stop_log_slow_level_2=0; + logpar.stop_log_slow_level_3=0; + } + +} + + + +// ����������� ������� ����� � ������ +void set_start_mem(int tlog) +{ + + if (tlog==FAST_LOG) + { + + logpar.real_finish_addres_mem = 0; + logpar.addres_mem = START_ADDRESS_LOG; + hb_logs_data = 0; + stop_log = 0; + + logpar.stop_log_level_1=0; + logpar.stop_log_level_2=0; + logpar.stop_log_level_3=0; + } + + + if (tlog==SLOW_LOG) + { + + count_mem_slow = START_ADDRESS_LOG_SLOW; + hb_logs_data = 0; + stop_log_slow = 0; + + logpar.stop_log_slow_level_1=0; + logpar.stop_log_slow_level_2=0; + logpar.stop_log_slow_level_3=0; + } + + +} + +void get_log_params_count(void) { + logpar.count_log_params_fast_log = logpar.addres_mem - START_ADDRESS_LOG; +} diff --git a/Inu/Src/main/not_use/log_to_mem.h b/Inu/Src/main/not_use/log_to_mem.h new file mode 100644 index 0000000..0b0fdcd --- /dev/null +++ b/Inu/Src/main/not_use/log_to_mem.h @@ -0,0 +1,201 @@ +/****************************************************************/ +/* TMS320C32 */ +/* ====== BIOS, �����, ����� ====== */ +/* ���� ��� (�) 1998-2001�. */ +/****************************************************************/ +/* log_to_mem.h + **************************************************************** + * ������ ����� � ���y�� * + ****************************************************************/ + +#ifndef _LOG_TO_MEM +#define _LOG_TO_MEM + + +#define SLOW_LOG 1 +#define FAST_LOG 0 + +#define SIZE_LOGS_ARRAY 90 + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + int stop_log_level_1; + int stop_log_level_2; + int stop_log_level_3; + + int stop_log_slow_level_1; + int stop_log_slow_level_2; + int stop_log_slow_level_3; + + int logs[SIZE_LOGS_ARRAY]; + +// int log1; +// int log2; +// int log3; +// int log4; +// int log5; +// int log6; +// int log7; +// int log8; +// int log9; +// int log10; +// int log11; +// int log12; +// int log13; +// int log14; +// int log15; +// int log16; +// int log17; +// int log18; +// int log19; +// int log20; +// +// int log21; +// int log22; +// int log23; +// int log24; +// int log25; +// int log26; +// int log27; +// int log28; +// int log29; +// int log30; +// +// int log31; +// int log32; +// int log33; +// int log34; +// int log35; +// int log36; +// int log37; +// int log38; +// int log39; +// int log40; +// +// int log41; +// int log42; +// int log43; +// int log44; +// int log45; +// int log46; +// int log47; +// int log48; +// int log49; +// int log50; +// +// int log51; +// int log52; +// int log53; +// int log54; +// int log55; +// int log56; +// int log57; +// int log58; +// int log59; +// int log60; +// +// int log61; +// int log62; +// int log63; +// int log64; +// int log65; +// int log66; +// int log67; +// int log68; +// int log69; +// int log70; +// +// int log71; +// int log72; +// int log73; +// int log74; +// int log75; +// +// int log76; +// int log77; +// int log78; +// int log79; +// int log80; +// int log81; +// int log82; +// int log83; +// int log84; +// int log85; +// +// int log86; +// int log87; +// int log88; +// int log89; +// int log90; + +// long addres_mem; //����� ���y�� ��y ������ ����� +// +// int count_log_params_fast_log; //���������� ������������ � ��� ���������� +// int start_write_fast_log; //������ ������ ����, ��� ����������� count_log_params_fast_log +// long real_finish_addres_mem; //����� ���y�� ��y ������ ����� +} LOGSPARAMS; + +#define LOGSPARAMS_DEFAULTS { 0,0,0, 0,0,0, \ + {0} \ + } + + + +/* ����������y ��y ������ ������� */ +#define START_ADDRESS_LOG 0x0a0000 +#define END_ADDRESS_LOG 0x0bf000 + +//#define START_ADDRESS_LOG 0xa0000 /* 0x904000 */ +//#define END_ADDRESS_LOG 0x0cf000 /* 0x90a000 */ + + +#define END_ADDRESS_LOG_LEVEL_2 0xa8000 +#define END_ADDRESS_LOG_LEVEL_3 0xb0000 + +#define START_ADDRESS_LOG_SLOW 0x0d0000 /* 0x904000 */ +#define END_ADDRESS_LOG_SLOW 0x0ef000 /* 0x90a000 */ +#define END_ADDRESS_LOG_SLOW_LEVEL_2 0xdb000 +#define END_ADDRESS_LOG_SLOW_LEVEL_3 0xe5000 + + + +#define LENGTH_HAZARD 100 +#define COUNT_SAVE_LOG_OFF 500 + + +/* �� ��������� ������� ����� */ +#define NO_ROTATE_LOG 0 + +extern int no_write; // ����, ����� �� ������ (���� ���) +extern int stop_log; // ���� ������������ + + +/* ������ ���� ������� ������ ��������� � ���y��, ��� ���� ����� */ +void write_to_mem(int tlog,int DataM); +void write_to_mem_a(int DataM); + +void start_write_acp(int Data1, int Data2, int Data3, int Data4, int Data5); + +/* �������� ������� ���y�� ��y ����� */ +void test_mem_limit(int tlog,int ciclelog); +void test_mem_limit_a(void); +void set_start_mem(int tlog); +void get_log_params_count(void); + +/* ������� ���y�� (���������) */ +void clear_mem(int tlog); + +//������� ����� logpar.logNN +void clear_logpar(); + +extern LOGSPARAMS logpar; + +#ifdef __cplusplus + } +#endif + +#endif /* _LOG_TO_MEM */ diff --git a/Inu/Src/main/optical_bus.c b/Inu/Src/main/optical_bus.c new file mode 100644 index 0000000..22ae162 --- /dev/null +++ b/Inu/Src/main/optical_bus.c @@ -0,0 +1,413 @@ +/* + * optical_bus.h.c + * + * Created on: 18 ���. 2020 �. + * Author: stud + */ + +#include <adc_tools.h> +#include <edrk_main.h> +#include <optical_bus.h> +#include <params.h> +#include <sync_tools.h> +#include <vector.h> + +#include "IQmathLib.h" +#include "xp_project.h" + + +OPTICAL_BUS_DATA optical_write_data = OPTICAL_BUS_DATA_DEFAULT; +OPTICAL_BUS_DATA optical_read_data = OPTICAL_BUS_DATA_DEFAULT; + +void parse_task_from_optical_bus(void); + + +#pragma CODE_SECTION(optical_bus_update_data_write,".fast_run"); +void optical_bus_update_data_write(void) +{ + + optical_write_data.data.cmd.bit.alarm = edrk.summ_errors; + + optical_write_data.data.cmd.bit.master = edrk.auto_master_slave.local.bits.master; + optical_write_data.data.cmd.bit.slave = edrk.auto_master_slave.local.bits.slave; + optical_write_data.data.cmd.bit.maybe_master = edrk.auto_master_slave.local.bits.try_master; + + +// optical_write_data.cmd.bit.controlMode = ; + +// optical_write_data.cmd.bit.err_optbus = +// optical_write_data.cmd.bit.master = +// optical_write_data.cmd.bit.maybe_master = +// optical_write_data.cmd.bit.pwm_status = +// + + if (edrk.Status_Rascepitel_Ok==0) + { + if (edrk.RunZahvatRascepitel) + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_REQUEST_AND_THIS_OFF;// 10 - ������ �� ���������, ���� �������� + else + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_OFF;//00 - ����� �������� �����������, ���� �������� + } + else + { + + if (edrk.Status_Ready.bits.ready_final==0) // ����� ��������� + { + if (edrk.RunUnZahvatRascepitel) + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_REQUEST_AND_THIS_OFF;// 10 - ������ �� ����������, ���� ������� + else + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON;// 01 - ����� �������� �����������, ���� ������� + } + else + { + if (edrk.you_can_on_rascepitel==0) + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_DISABLE_THIS_ON; // 11 - ������ ����������� �����������, ���� ������� + else + optical_write_data.data.cmd.bit.rascepitel_cmd = CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON; // 01 - ����� �������� �����������, ���� ������� + } + } + + if (edrk.Status_Ready.bits.ready7 || (edrk.Status_Ready.bits.ready5 && edrk.Status_Ready.bits.ImitationReady2) ) + optical_write_data.data.cmd.bit.ready_cmd = CODE_READY_CMD_READY2; + else + if (edrk.SumSbor) + optical_write_data.data.cmd.bit.ready_cmd = CODE_READY_CMD_READY1TO2; + else + optical_write_data.data.cmd.bit.ready_cmd = CODE_READY_CMD_READY1; + +// optical_write_data.cmd.bit.ready_to_go = +// optical_write_data.cmd.bit.slave = +// +// optical_write_data.cmd.bit.start_pwm = + optical_write_data.data.cmd.bit.statusQTV = edrk.from_shema_filter.bits.QTV_ON_OFF; +// optical_write_data.cmd.bit.stop_pwm = + + optical_write_data.data.cmd.bit.sync_1_2 = sync_data.local_flag_sync_1_2; + optical_write_data.data.cmd.bit.sync_line_detect = !sync_data.timeout_sync_signal; + +// optical_write_data.data1 = f.Mode == 1 ? f.fzad * 60.0 + 0.5 : +// f.Mode == 2 ? f.p_zad / 1000.0 : +// 0; +// optical_write_data.data2 = rotor.direct_rotor == -1 ? -_IQtoIQ15(rotor.iqFout) : +// _IQtoIQ15(rotor.iqFout); +// optical_write_data.data3 = _IQtoIQ15(analog.iqIq_zadan); +// optical_write_data.data4.bit.controlMode = f.Mode == 2 ? 1 : 0; +// optical_write_data.data4.bit.leading_ready = f.Ready2 && (f.Mode == 1 || f.Mode == 2) ? 1 : 0; +// optical_write_data.data4.bit.leading_Go = edrk.Go; + + + +} + + + +#pragma CODE_SECTION(optical_bus_write,".fast_run"); +void optical_bus_write(void) +{ +#if(USE_TK_3) + // check error write PBUS OPTICAL BUS + project.cds_tk[3].optical_bus_check_error_write(&project.cds_tk[3]); + + // write data to OPTICAL BUS + project.cds_tk[3].optical_data_out.buf[0] = optical_write_data.data.pzad_or_wzad; + project.cds_tk[3].optical_data_out.buf[1] = optical_write_data.data.angle_pwm; + project.cds_tk[3].optical_data_out.buf[2] = optical_write_data.data.iq_zad_i_zad; + project.cds_tk[3].optical_data_out.buf[3] = optical_write_data.data.cmd.all; + + optical_write_data.status = 1; + + + project.cds_tk[3].optical_bus_write_data(&project.cds_tk[3]); +#endif +} + + + + + +#pragma CODE_SECTION(optical_bus_read_old,".fast_run"); +void optical_bus_read_old(void) +{ + +// // check error write PBUS OPTICAL BUS +// project.cds_tk[3].optical_bus_check_error_write(&project.cds_tk[3]); +//// read data from OPTICAL BUS +// project.cds_tk[3].read_pbus(&project.cds_tk[3]); +// // check error read PBUS OPTICAL BUS +// project.cds_tk[3].optical_bus_check_error_read(&project.cds_tk[3]); +// +// +// if (project.cds_tk[3].optical_data_in.new_data_ready) +// { +// if (project.cds_tk[3].optical_data_in.overfull_new_data) +// optical_read_data.overfull_data++; +// +// optical_read_data.raw.pzad_or_wzad = (int)project.cds_tk[3].optical_data_in.buf[0]; +// optical_read_data.raw.angle_pwm = (int)project.cds_tk[3].optical_data_in.buf[1]; +// optical_read_data.raw.iq_zad = (int)project.cds_tk[3].optical_data_in.buf[2]; +// optical_read_data.raw.cmd.all = project.cds_tk[3].optical_data_in.buf[3]; +// +// +// optical_read_data.data.pzad_or_wzad = optical_read_data.raw.pzad_or_wzad; +// optical_read_data.data.angle_pwm = optical_read_data.raw.angle_pwm ; +// optical_read_data.data.iq_zad = optical_read_data.raw.iq_zad; +// optical_read_data.data.cmd.all = optical_read_data.raw.cmd.all; +// +// optical_read_data.code_status.bit.ready = 1; +// optical_read_data.code_status.bit.recive_error = 0; +// optical_read_data.code_status.bit.overfull = 0; +// optical_read_data.code_status.bit.timeout = 0; +// optical_read_data.code_status.bit.wait = 0; +// +// project.cds_tk[3].optical_data_in.new_data_ready = 0; +// +// return (optical_read_data.code_status); +// +// } +// else +// { +// +// if (project.cds_tk[3].optical_data_in.ready == 1) +// { +// optical_read_data.code_status.bit.ready = 0; +// +// if (project.cds_tk[3].optical_data_in.raw_local_error) +// optical_read_data.code_status.bit.recive_error = 1; +// else +// optical_read_data.code_status.bit.recive_error = 0; +// +// optical_read_data.code_status.bit.overfull = 0; +// optical_read_data.code_status.bit.timeout = 0; +// optical_read_data.code_status.bit.wait = 1; +// +// return (optical_read_data.code_status); +// } +// +// } +// +// +// if (project.cds_tk[3].optical_data_out.ready == 0) { +// +// project.cds_tk[3].optical_data_out.error_not_ready_count += 1; +// +//// optical_read_data.code_status.bit.ready = 0; +// optical_read_data.code_status.bit.send_error = 1; +//// optical_read_data.code_status.bit.overfull = 0; +//// optical_read_data.code_status.bit.timeout = 0; +//// optical_read_data.code_status.bit.wait = 0; +// +//// optical_write_data.status = 2; +//// return (optical_read_data.code_status); +// } +// else +// optical_read_data.code_status.bit.send_error = 0; +// +// +// if (project.cds_tk[3].optical_data_in.ready == 0) { +// +//// f.read_task_from_optical_bus = 0; +// project.cds_tk[3].optical_data_in.error_not_ready_count += 1; +// +// optical_read_data.code_status.bit.ready = 0; +// // optical_read_data.code_status.bit.send_error = 0; +// //optical_read_data.code_status.bit.recive_error = 1; +// optical_read_data.code_status.bit.overfull = 0; +// optical_read_data.code_status.bit.timeout = 1; +// optical_read_data.code_status.bit.wait = 0; +// +// optical_read_data.data.pzad_or_wzad = 0; +// optical_read_data.data.angle_pwm = 0; +// optical_read_data.data.iq_zad = 0; +// optical_read_data.data.cmd.all = 0; +// +// // optical_read_data.status = 2; +// +// // return (project.cds_tk[3].optical_data_in.raw_local_error); +// } +// else +// { +// +// +// +// } +// +// return (optical_read_data.code_status); +// +// +//// optical_read_data.status = 1; +// +// // return (project.cds_tk[3].optical_data_in.raw_local_error); +// +//// if (f.flag_leading == 0 && f.flag_distance && f.Ready1){ +//// parse_task_from_optical_bus(); +//// } else { +//// f.read_task_from_optical_bus = 0; +//// } +//// rotor.iqFrotFromOptica = _IQ15toIQ(optical_read_data.data2); //Frot +//// analog.iqIq_zad_from_optica = _IQ15toIQ(optical_read_data.data3); + +} + + +#pragma CODE_SECTION(optical_bus_read,".fast_run"); +void optical_bus_read(void) +{ + + // check error write PBUS OPTICAL BUS +// project.cds_tk[3].optical_bus_check_error_write(&project.cds_tk[3]); +// read data from OPTICAL BUS +#if(USE_TK_3) + project.cds_tk[3].read_pbus(&project.cds_tk[3]); +#endif + + return; +} + +#pragma CODE_SECTION(optical_bus_read_clear_count_error,".fast_run"); +void optical_bus_read_clear_count_error(void) +{ +#if(USE_TK_3) + project.cds_tk[3].optical_data_in.local_count_error = 0; +#endif + + return; +} + + + +#pragma CODE_SECTION(optical_bus_get_status_and_read,".fast_run"); +STATUS_DATA_READ_OPT_BUS optical_bus_get_status_and_read(void) +{ + STATUS_DATA_READ_OPT_BUS status_read; + // check error write PBUS OPTICAL BUS + // project.cds_tk[3].optical_bus_check_error_write(&project.cds_tk[3]); +// read data from OPTICAL BUS +// project.cds_tk[3].read_pbus(&project.cds_tk[3]); + +#if(USE_TK_3) + // check error read PBUS OPTICAL BUS + project.cds_tk[3].optical_bus_check_error_read(&project.cds_tk[3]); + + status_read.all = project.cds_tk[3].optical_data_in.status_read.all; + + project.cds_tk[3].optical_data_in.prev_status_read.all = status_read.all; + project.cds_tk[3].optical_data_in.status_read.all = 0; + + optical_read_data.status = project.cds_tk[3].optical_data_in.ready; + + + if (status_read.bit.new_data_ready) + { + if (status_read.bit.overfull_new_data) + optical_read_data.overfull_data++; + + optical_read_data.raw.pzad_or_wzad = (int)project.cds_tk[3].optical_data_in.buf[0]; + optical_read_data.raw.angle_pwm = (int)project.cds_tk[3].optical_data_in.buf[1]; + optical_read_data.raw.iq_zad_i_zad = (int)project.cds_tk[3].optical_data_in.buf[2]; + optical_read_data.raw.cmd.all = project.cds_tk[3].optical_data_in.buf[3]; + + + optical_read_data.data.pzad_or_wzad = optical_read_data.raw.pzad_or_wzad; + optical_read_data.data.angle_pwm = optical_read_data.raw.angle_pwm ; + optical_read_data.data.iq_zad_i_zad = optical_read_data.raw.iq_zad_i_zad; + optical_read_data.data.cmd.all = optical_read_data.raw.cmd.all; + + + return (status_read); // �� �������� ������ + + } + else + { + // ��� ������? + // �������� � ���������� optical_bus, � �� ���! + +// optical_read_data.data.pzad_or_wzad = 0; +// optical_read_data.data.angle_pwm = 0; +// optical_read_data.data.iq_zad_i_zad = 0; +// optical_read_data.data.cmd.all = 0; + + + + } +#else + status_read.all = 0; +#endif + return status_read; //��� ������ ��� ������ + +} + + + + +void parse_task_from_optical_bus(void) { + + // if (optical_read_data.data4.bit.leading_ready == 1) { +// f.read_task_from_optical_bus = 1; +// f.Mode = optical_read_data.data4.bit.controlMode == 0 ? 1 : 2; +// if (f.Mode == 1) { +// f.fzad = (float)optical_read_data.data1 / 60.0; +// f.iq_fzad = _IQ(f.fzad / NORMA_FROTOR); +// limit_mzz_zad_turns(); +// } +// if (f.Mode == 2) { +// f.p_zad = (float)optical_read_data.data1 * 1000.0; +// f.iq_p_zad = _IQ(f.p_zad/NORMA_ACP/NORMA_ACP); +// // +// if (f.iq_p_zad > f.iq_p_limit_zad) { f.iq_p_zad = f.iq_p_limit_zad;} +// if (f.iq_p_zad < -f.iq_p_limit_zad) { f.iq_p_zad = -f.iq_p_limit_zad;} +// +// limit_mzz_zad_power(); +// } + +// if (f.Ready1 && f.Ready2) { +// if (((f.Mode == 1 && f.fzad != 0) || (f.Mode == 2 && f.p_zad != 0)) +// && (!f.Is_Blocked || (f.Is_Blocked && edrk.Go)) +// && (f.rotor_stopped == 0) +//// && (faults.faults5.bit.rotor_stopped == 0) +// //&& (optical_read_data.data4.bit.leading_Go == 1) +// ){ +// edrk.Go = 1; +// } else { +// if (edrk.Go) { +// f.p_zad = 0; +// f.fzad = 0; +// f.iq_fzad = 0; +// f.iq_p_zad = 0; +// if(f.Mode == 1) +// { +// if(a.iqk < 1677722 || rotor.iqFout < 48210 //1677722 ~ 0.1 ����������� 503316 = 3% 838860 = 5% +// || (analog.iqIm_1 < 1677721 && analog.iqIm_2 < 1677721)) //1677721 ~ 300A +// { +// edrk.Go = 0; +// f.iq_fzad = 0; +// } +// +// } +// if(edrk.Go && f.Mode == 2) +// { +// if(analog.iqW < 186413) +// { +// if(a.iqk < 1677722 || //1677722 ~ 0.1 ����������� +// (analog.iqIm_1 < 1677721 && analog.iqIm_2 < 1677721)) //1677721 ~ 300A +// { +// edrk.Go = 0; +// } +// } +// } +// +// } else { +// f.iq_mzz_zad = _IQ(500.0/NORMA_MZZ); +// } +// } +// } else { +// edrk.Go = 0; +// } + + + // _IQ15toIQ(optical_read_data.data3); //Iq_zad +// } else { + // f.read_task_from_optical_bus = 0; +// } + +} + diff --git a/Inu/Src/main/optical_bus.h b/Inu/Src/main/optical_bus.h new file mode 100644 index 0000000..ce30d7c --- /dev/null +++ b/Inu/Src/main/optical_bus.h @@ -0,0 +1,109 @@ +/* + * optical_bus.h + * + * Created on: 18 ���. 2020 �. + * Author: stud + */ + +#ifndef SRC_MAIN_OPTICAL_BUS_H_ +#define SRC_MAIN_OPTICAL_BUS_H_ + +#include "xp_cds_tk_23550.h" + +enum +{ +CODE_READY_CMD_NOT_READY=0, //// 0 - not ready +CODE_READY_CMD_READY1, //1-ready1 +CODE_READY_CMD_READY1TO2, //2-ready1to2 +CODE_READY_CMD_READY2 //3 -ready2 +}; + +enum +{ + CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_OFF=0, //0 - ����� �������� �����������, ���� �������� + CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON, // 1 - ����� �������� �����������, ���� ������� + CODE_RASCEPITEL_CMD_REQUEST_AND_THIS_OFF, // 2 - ������ �� ���������, ���� �������� + CODE_RASCEPITEL_CMD_DISABLE_THIS_ON // 3 - ������ ����������� �����������, ���� ������� +}; + + + typedef union { + struct { + unsigned int wdog_tick :1; //�������� 0_1_0 � �.�. + unsigned int statusQTV :1; //1-QTV On, QTV - off + unsigned int master :1; // 1 -Master, 0 - not Master + unsigned int slave :1; // 1 -Slave, 0 - not Slave + + unsigned int sync_line_detect :1; // 1 - yes, 0 - no ������������ ����������� + unsigned int sync_1_2 :1; // 1 - yes, 0 - no ���� ������������� ����� �� + unsigned int alarm :1; // 1 - yes, 0 - no ������ + unsigned int ready_cmd :2; // 00 - not ready,01-ready1,10-ready1to2, 11 -ready2 + + unsigned int prepare_stop_PWM :1; // 0 - regul turns; 1 - power ����� ������ +// unsigned int ready_to_go :1; // 1 - yes, 0 - no ����� �������, ������ ������ ��� + unsigned int start_pwm :1; // 1 - yes, 0 - no ���� ������� �� ������ ���� + unsigned int stop_pwm :1; // 1 - yes, 0 - no ���� ������� �� ���� ���� + + unsigned int pwm_status :1; // 1 -On, 0 - Off ������� �������� ���� +// unsigned int can_on_rascepitel :1; // 1 - yes, 0 - no ����� ���������� ����������� + unsigned int maybe_master :1; // 1 - yes, 0 - no ������ �� ������ ������ Master + unsigned int rascepitel_cmd :2; // + // 00 - ����� �������� �����������, ���� �������� + // 01 - ����� �������� �����������, ���� ������� + // 10 - ������ �� ���������, ���� �������� + // 11 - ������ ����������� �����������, ���� ������� + } bit; + unsigned int all; + } OPTICAL_BUS_DATA_LOW_CMD; + + +// typedef union { +// struct { +// unsigned int ready :1; // ������ ������ +// unsigned int overfull :1; //������ �������� +// unsigned int recive_error :1; //������ ������ � ������� +// unsigned int send_error :1; //������ ���� � ������� +// unsigned int wait :1; //������ ��������� +// unsigned int timeout :1; //������ ����� �� ���� +// } bit; +// unsigned int all; +// } OPTICAL_BUS_CODE_STATUS; + + +typedef struct { + int pzad_or_wzad; //given turns or power, depends on controlMode; + int angle_pwm; //current rotor turns + int iq_zad_i_zad; // Iq_zadan or Izad + OPTICAL_BUS_DATA_LOW_CMD cmd; +} OPTICAL_BUS_DATA_LOW; + +typedef struct { + OPTICAL_BUS_DATA_LOW raw; + OPTICAL_BUS_DATA_LOW data; + unsigned int status; + unsigned int overfull_data; + unsigned int timer; + unsigned int flag_clear; + unsigned int data_was_update_between_pwm_int; + unsigned int error_wdog; + unsigned int count_error_wdog; + unsigned int count_read_optical_bus_old_data; // ������� ������� ������� ������ �� ����������� + + +// OPTICAL_BUS_CODE_STATUS code_status; +} OPTICAL_BUS_DATA; + + +#define OPTICAL_BUS_DATA_DEFAULT {{0,0,0,0},{0,0,0,0},0,0,0,0,0,0,0,0} + +extern OPTICAL_BUS_DATA optical_write_data; +extern OPTICAL_BUS_DATA optical_read_data; + + +void optical_bus_read(void); +STATUS_DATA_READ_OPT_BUS optical_bus_get_status_and_read(void); +void optical_bus_write(void); +void optical_bus_read_clear_count_error(void); +void optical_bus_update_data_write(void); + +#endif /* SRC_MAIN_OPTICAL_BUS_H_ */ diff --git a/Inu/Src/main/optical_bus_tools.c b/Inu/Src/main/optical_bus_tools.c new file mode 100644 index 0000000..431ade9 --- /dev/null +++ b/Inu/Src/main/optical_bus_tools.c @@ -0,0 +1,791 @@ +/* + * optical_bus_tools.c + * + * Created on: 19 ���. 2024 �. + * Author: user + */ +#include <adc_tools.h> +#include <alg_simple_scalar.h> +#include <alg_uf_const.h> +#include <break_regul.h> +#include <edrk_main.h> +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include <project.h> +#include <v_pwm24_v2.h> +#include <v_rotor.h> +#include <vector.h> +#include "global_time.h" +#include "IQmathLib.h" +#include "oscil_can.h" +#include "uf_alg_ing.h" +#include "MemoryFunctions.h" +#include "RS_Functions.h" +#include "v_rotor_22220.h" +#include "log_to_memory.h" +#include "log_params.h" + + + + + +/////////////////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(optical_bus_read_write_interrupt,".fast_run2"); +void optical_bus_read_write_interrupt(void) +{ + + + static unsigned int prev_error_read = 0, count_read_optical_bus_error = 0, count_read_optical_bus_old_data = 0; + static unsigned int max_count_read_old_data_optical_bus = 15; + static unsigned int flag_disable_resend = 0; + static unsigned int count_resend = 0, cc=0; +// static STATUS_DATA_READ_OPT_BUS buf_status[10]; + static STATUS_DATA_READ_OPT_BUS optbus_status; + static unsigned int tt=0; + static unsigned int cmd_wdog_sbus = 0, count_wait_wdog_sbus = 0, wdog_sbus = 0; + static int prepare_time = 0; + + + static unsigned int t_finish_optbus = 14, t_read_optbus = 6, t_write_optbus = 10, max_count_read_error_optical_bus = 15, max_count_read_wdog_optical_bus = 48; + static int cmd_optbus = 0; + + static int flag_enable_read=0, flag_finish_read = 0, flag_enable_write = 0, flag_finish_write = 0, count_wait_write = 0; + + if (prepare_time==0) + { + if (edrk.flag_second_PCH==0) + { + t_read_optbus = 6; + t_write_optbus = 8; + t_finish_optbus = 20; + } + + if (edrk.flag_second_PCH==1) + { + t_read_optbus = 12; + t_write_optbus = 14; + t_finish_optbus = 10; + } + prepare_time = 1; + } + + if (flag_special_mode_rs==1) + return; + + if (edrk.KvitirProcess) + return; + + if (edrk.disable_interrupt_timer2) + return; + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_17_ON; +#endif + +//i_led2_on_off(1); + + +//#if (ENABLE_LOG_INTERRUPTS) +// add_log_interrupts(2); +//#endif + + +// pause_1000(100); + if (optical_read_data.flag_clear) + { + // stage_1 = 0; + optical_read_data.timer = 0; + optical_read_data.flag_clear = 0; + optical_read_data.error_wdog = 0; +// count_wait_wdog_sbus = 0; + +// if (optical_read_data.data_was_update_between_pwm_int==0) +// sum_count_err_read_opt_bus++; +// +// optical_read_data.data_was_update_between_pwm_int = 0; + + // optical_read_data.data_was_update_between_pwm_int = 0; + cc = 0; + prev_error_read = 0; + } + + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + if (optical_read_data.timer==0) + { + PWM_LINES_TK_16_ON; + } + else + { + PWM_LINES_TK_16_OFF; + } +#endif + + + +// else + optical_read_data.timer++; + +// if (edrk.into_pwm_interrupt==1) +// { +// if (optical_read_data.timer>=2) +// { +// optical_read_data.timer--; +// optical_read_data.timer--; +// } +// flag_disable_resend = 0; +// count_resend = 0; +// +// } + +// +// +// +// if (stage_1==0) +// tt = t1; +// +// if (stage_1==1) +// tt = t2; + + if (edrk.ms.another_bs_maybe_on==1 && edrk.flag_second_PCH==0 /*edrk.auto_master_slave.local.bits.master*/ ) + { + + if (optical_read_data.data.cmd.bit.wdog_tick) + { + // i_led1_on(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_21_ON; +#endif + } + else + { + // i_led1_off(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_21_OFF; +#endif + + } + + optical_write_data.data.cmd.bit.wdog_tick = optical_read_data.data.cmd.bit.wdog_tick; + + if (optical_write_data.data.cmd.bit.wdog_tick) + { + // i_led2_on(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_22_ON; +#endif + + } + else + { + // i_led2_off(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_22_OFF; +#endif + } + + + + } + + + if (edrk.ms.another_bs_maybe_on==1 && edrk.flag_second_PCH==1 /*edrk.auto_master_slave.local.bits.slave*/ ) + { + + if (optical_write_data.data.cmd.bit.wdog_tick) + { + // i_led2_on(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_22_ON; +#endif + + } + else + { + // i_led2_off(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_22_OFF; +#endif + } + + + + if (optical_read_data.data.cmd.bit.wdog_tick) + { + // i_led1_on(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_21_ON; +#endif + } + else + { + // i_led1_off(); +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_21_OFF; +#endif + } + + + + + // ����� + optical_write_data.data.cmd.bit.wdog_tick = wdog_sbus; + if (cmd_wdog_sbus==0) + { +// optical_write_data.data.cmd.bit.wdog_tick = wdog_sbus; + count_wait_wdog_sbus = 0; + cmd_wdog_sbus++; + } + else + // ���� ������������� + if (cmd_wdog_sbus==1) + { + if (optical_read_data.data.cmd.bit.wdog_tick == wdog_sbus) //&& prev_error_read==0 + { + // result_code_wdog_sbus = 1; + optical_read_data.count_error_wdog = count_wait_wdog_sbus; + count_wait_wdog_sbus = 0; + wdog_sbus = !wdog_sbus; + cmd_wdog_sbus = 0; + } + else + { + if (count_wait_wdog_sbus<max_count_read_wdog_optical_bus ) //6 + { + count_wait_wdog_sbus++; + } + else + { + if (optical_read_data.error_wdog==0) + { + // �� ���� ������ � ����� ����! + +// i_led2_toggle(); +// pause_1000(10); +// i_led2_toggle(); +// pause_1000(10); + } + // if (optical_read_data.data.cmd.bit.alarm==0) // ���� ���! + optical_read_data.error_wdog = 1; // ���� ������ + + } + + + } + } + + + } + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + +// if (count_wait_wdog_sbus==0) +// { +// PWM_LINES_TK_16_ON; +// } +// else +// { +// PWM_LINES_TK_16_OFF; +// } + + +#endif + + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + if (optical_read_data.error_wdog) + { + PWM_LINES_TK_23_ON; + PWM_LINES_TK_23_ON; + } + else + { + PWM_LINES_TK_23_OFF; + } +#endif + + + +#define TIME_WAIT_CMD_WRITE 5 // ������� ����� ���� ������ �� ���������, ����� ����� ����� ����������� ��������� ������ +if (edrk.flag_second_PCH==1) +{ + switch (cmd_optbus) + { + case 0 : if (optical_read_data.timer==t_read_optbus) + cmd_optbus = 1; + break; + case 1: flag_enable_read = 1; + flag_finish_read = 0; + flag_enable_write = 0; + flag_finish_write = 0; + count_wait_write = 0; + cmd_optbus = 2; + break; + + case 2: if (flag_finish_read) + { + flag_enable_write = 1; + count_wait_write = TIME_WAIT_CMD_WRITE; + cmd_optbus = 3; + } + break; + + case 3: if (flag_enable_write==0) + { + if (count_wait_write) + { + count_wait_write--; + } + else + cmd_optbus = 4; + } + break; + + case 4: if (optical_read_data.timer>=t_finish_optbus) + cmd_optbus = 1; + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + default: + break; + } +} + + + +if (edrk.flag_second_PCH==0) +{ + switch (cmd_optbus) + { + case 0 : if (optical_read_data.timer==t_write_optbus) + cmd_optbus = 1; + break; + + case 1: flag_enable_read = 0; + flag_finish_read = 0; + flag_enable_write = 1; + flag_finish_write = 0; + count_wait_write = TIME_WAIT_CMD_WRITE; + cmd_optbus = 2; + break; + + case 2: if (flag_enable_write==0) + { + if (count_wait_write) + { + count_wait_write--; + } + else + cmd_optbus = 3; + } + break; + case 3: flag_enable_read = 1; + flag_finish_read = 0; + flag_enable_write = 0; + flag_finish_write = 0; + count_wait_write = 0; + cmd_optbus = 4; + break; + + case 4: if (flag_finish_read) + { + //flag_enable_write = 1; + //count_wait_write = 2; + //cmd_optbus = 2; + flag_enable_read = 0; + flag_finish_read = 0; + flag_enable_write = 1; + flag_finish_write = 0; + count_wait_write = TIME_WAIT_CMD_WRITE; + cmd_optbus = 2; // ������ case 5: � case 1: + } + break; + + case 5: if (optical_read_data.timer>=t_finish_optbus) + cmd_optbus = 1; + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + default: + break; + } +} +// if (optical_read_data.timer==t_read_optbus) +// flag_run_cycle = 1; +// +// if (flag_run_cycle==t_read_optbus) +// { +// flag_enable_read = 1; +// flag_finish_read = 0; +// flag_enable_write = 0; +// flag_finish_write = 0; +// flag_run_cycle = 0; +// } +// +// +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_18_OFF; +#endif + + if (flag_enable_read) + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_19_ON; +#endif + +#if(USE_TK_3) + project.cds_tk[3].read_pbus(&project.cds_tk[3]); +#endif + optbus_status = optical_bus_get_status_and_read(); + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_19_OFF; +#endif + cc++; + + if (optbus_status.bit.new_data_ready) + { + + prev_error_read = 0; + optical_read_data.count_read_optical_bus_old_data = 0; + + if (optical_read_data.data_was_update_between_pwm_int<10000) + optical_read_data.data_was_update_between_pwm_int += 1; + + count_read_optical_bus_error = 0; + flag_finish_read = 1; + flag_enable_read = 0; + } + + if (optbus_status.bit.receiver_error || optbus_status.bit.bad_status12 ) + { + + prev_error_read = 1; + + if (count_read_optical_bus_error<=max_count_read_error_optical_bus) + count_read_optical_bus_error++; + else + { + optical_read_data.data.pzad_or_wzad = 0; + optical_read_data.data.angle_pwm = 0; + optical_read_data.data.iq_zad_i_zad = 0; + optical_read_data.data.cmd.all = 0; + flag_finish_read = 1; + } + } + + + if (optbus_status.bit.old_data) + { + +// prev_error_read = 1; + + flag_finish_read = 1; + + if (optical_read_data.count_read_optical_bus_old_data<=max_count_read_old_data_optical_bus) + optical_read_data.count_read_optical_bus_old_data++; + else + { + optical_read_data.data.pzad_or_wzad = 0; + optical_read_data.data.angle_pwm = 0; + optical_read_data.data.iq_zad_i_zad = 0; + optical_read_data.data.cmd.all = 0; + } + } + + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + if (optbus_status.bit.new_data_ready) + { + PWM_LINES_TK_18_ON; + } +#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + if (optbus_status.bit.receiver_busy || optbus_status.bit.receiver_error || optbus_status.bit.bad_status12) + { + // PWM_LINES_TK_16_ON; + } +#endif + + } + +// +// +// if (flag_finish_read) +// { +// flag_enable_write = 1; +// count_wait_write = 10; +// } + + + if (flag_enable_write) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_20_ON; +#endif +#if(_ENABLE_PWM_LINES_FOR_TESTS) + static unsigned int ccc = 0; + ccc++; + optical_write_data.data.angle_pwm = ccc; +#endif + optical_bus_write(); + + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_20_OFF; +#endif + flag_enable_write = 0; + } +// +// if (count_wait_write) +// { +// count_wait_write--; +// } +// else +// flag_finish_write = 1; +// +// +// +//// read +// +// if (optical_read_data.timer==(t_read_optbus-1)) +// prev_error_read = 1; +// else +// if (optical_read_data.timer==t_read_optbus || prev_error_read==1) +// { +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_18_OFF; +//#endif +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_19_ON; +//#endif +// +// project.cds_tk[3].read_pbus(&project.cds_tk[3]); +// +// optbus_status = optical_bus_get_status_and_read(); +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_19_OFF; +//#endif +// cc++; +// +// if (optbus_status.bit.new_data_ready) +// { +// +// prev_error_read = 0; +// +// if (optical_read_data.data_was_update_between_pwm_int<10000) +// optical_read_data.data_was_update_between_pwm_int += 1; +// +// count_read_optical_bus_error = 0; +// } +// +// if (optbus_status.bit.receiver_error || optbus_status.bit.bad_status12 ) +// { +// +// prev_error_read = 1; +// +// if (count_read_optical_bus_error<=max_count_read_error_optical_bus) +// count_read_optical_bus_error++; +// else +// { +// optical_read_data.data.pzad_or_wzad = 0; +// optical_read_data.data.angle_pwm = 0; +// optical_read_data.data.iq_zad_i_zad = 0; +//// optical_read_data.data.cmd.all = 0x40; // ��������! alarm = 1 +// optical_read_data.data.cmd.all = 0; +// } +// } +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// if (optbus_status.bit.new_data_ready) +// { +// PWM_LINES_TK_18_ON; +// } +//#endif +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// if (optbus_status.bit.receiver_busy || optbus_status.bit.receiver_error || optbus_status.bit.bad_status12) +// { +// // PWM_LINES_TK_16_ON; +// } +//#endif +// +// } +// +// +// +// +//// write +// +// if (optical_read_data.timer==t_write_optbus) +// { +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_20_ON; +//#endif +// +// optical_bus_write(); +// +// +//#if(_ENABLE_PWM_LINES_FOR_TESTS) +// PWM_LINES_TK_20_OFF; +//#endif +// } + + + +// finish + +// if (optical_read_data.timer>=t_finish_optbus) +// { +// optical_read_data.timer = 0; +// } + +// if (prev_error_read==0) +// i_led2_off(); + + +// if (optical_read_data.timer==t2) +// { +// +// // if (edrk.flag_second_PCH==0) +// stage_2 = 1; +// // else +// // stage_1 = 1; +// +// optical_read_data.timer = 0; +// } + +// if (optical_read_data.timer>=t3) +// { +// optical_read_data.timer = 0; +// } + + + + + +// +// if (stage_1==2 && prev_stage1!=stage_1) +// { +// // i_led2_on(); +//// if (flag_disable_resend==0) +//// { +// // if (edrk.ms.another_bs_maybe_on==1 && (edrk.auto_master_slave.local.bits.master ) ) +// +// // if (edrk.flag_second_PCH==0) +// { +// i_led2_on(); +// i_led2_off(); +// i_led2_on(); +// +// optical_bus_write(); +// } +//// else +//// { +//// i_led2_on(); +//// +//// optical_bus_read(); +//// optbus_status = optical_bus_get_status_and_read(); +//// buf_status[cc] = optbus_status; +//// cc++; +//// +//// if (optbus_status.bit.new_data_ready) +//// optical_read_data.data_was_update_between_pwm_int = 1; +//// +//// if (optbus_status.bit.receiver_busy || optbus_status.bit.receiver_error || optbus_status.bit.bad_status12 +//// ) +//// { +//// i_led1_on(); +//// i_led1_off(); +//// +//// } +//// +//// } +// stage_1 = 0; +// } + +// if (stage_1==1 && prev_stage1!=stage_1) +// { +// +//// if (edrk.flag_second_PCH==1) +//// { +//// i_led2_on(); +//// i_led2_off(); +//// i_led2_on(); +//// +//// optical_bus_write(); +//// } +//// else +// // { +// i_led2_on(); +// +// optical_bus_read(); +// optbus_status = optical_bus_get_status_and_read(); +// buf_status[cc] = optbus_status; +// cc++; +// +// if (optbus_status.bit.new_data_ready) +// optical_read_data.data_was_update_between_pwm_int = 1; +// +// if (optbus_status.bit.receiver_busy || optbus_status.bit.receiver_error || optbus_status.bit.bad_status12 +// ) +// { +// i_led1_on(); +// i_led1_off(); +// +// } +// +// // } +// +// +// // stage_1 = 0; +// } + + // prev_stage1 = stage_1; + // } +// if (edrk.flag_second_PCH==1) +// { +// i_led2_off(); +// } + +//i_led2_on_off(0); + +//#if (ENABLE_LOG_INTERRUPTS) +// add_log_interrupts(102); +//#endif + +#if(_ENABLE_PWM_LINES_FOR_TESTS) + PWM_LINES_TK_17_OFF; +#endif + + +} +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + diff --git a/Inu/Src/main/optical_bus_tools.h b/Inu/Src/main/optical_bus_tools.h new file mode 100644 index 0000000..89c6bc6 --- /dev/null +++ b/Inu/Src/main/optical_bus_tools.h @@ -0,0 +1,14 @@ +/* + * optical_bus_tools.h + * + * Created on: 19 ���. 2024 �. + * Author: user + */ + +#ifndef SRC_MAIN_OPTICAL_BUS_TOOLS_H_ +#define SRC_MAIN_OPTICAL_BUS_TOOLS_H_ + +void optical_bus_read_write_interrupt(void); + + +#endif /* SRC_MAIN_OPTICAL_BUS_TOOLS_H_ */ diff --git a/Inu/Src/main/overheat_limit.c b/Inu/Src/main/overheat_limit.c new file mode 100644 index 0000000..e2c2720 --- /dev/null +++ b/Inu/Src/main/overheat_limit.c @@ -0,0 +1,80 @@ +/* + * overheat_limit.c + * + * Created on: 17 ���. 2020 �. + * Author: star + */ + +#include <edrk_main.h> +#include <overheat_limit.h> +#include <params_temper_p.h> +#include <protect_levels.h> + +#include "IQmathLib.h" +#include "math_pi.h" +#include "limit_lib.h" + + +TEMPERATURE_LIMIT_KOEFFS temper_limit_koeffs = TEMPERATURE_LIMIT_KOEFFS_DEFAULTS; + +void calc_limit_overheat() +{ + int *p_alarm, *p_abnormal; + _iq sum_limit = CONST_IQ_1; + _iq val; + int i = 0; + + p_alarm = &protect_levels.alarm_temper_u_01; + p_abnormal = &protect_levels.abnormal_temper_u_01; + edrk.temper_limit_koeffs.power_units = CONST_IQ_1; + for (i = 0; i < 7; i++) { + val = linear_decrease(edrk.temper_edrk.real_int_temper_u[i], + *(p_alarm + i), *(p_abnormal + i)); + edrk.temper_limit_koeffs.power_units = _IQmpy(val, edrk.temper_limit_koeffs.power_units); + } + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.power_units); + + p_alarm = &protect_levels.alarm_temper_air_int_01; + p_abnormal = &protect_levels.abnormal_temper_air_int_01; + edrk.temper_limit_koeffs.area = CONST_IQ_1; + for (i = 0; i < 4; i++) { + val = linear_decrease(edrk.temper_edrk.real_int_temper_air[i], + *(p_alarm + i), *(p_abnormal + i)); + edrk.temper_limit_koeffs.area = _IQmpy(val, edrk.temper_limit_koeffs.area); + } + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.area); + + edrk.temper_limit_koeffs.water_int = linear_decrease(edrk.temper_edrk.real_temper_water[0] * 10.0, + protect_levels.alarm_temper_water_int, protect_levels.abnormal_temper_water_int); + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.water_int); + + edrk.temper_limit_koeffs.water_ext = linear_decrease(edrk.temper_edrk.real_temper_water[1] * 10.0, + protect_levels.alarm_temper_water_ext, protect_levels.abnormal_temper_water_ext); + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.water_ext); + + + p_alarm = &protect_levels.alarm_temper_acdrive_winding_U1; + p_abnormal = &protect_levels.abnormal_temper_acdrive_winding_U1; + edrk.temper_limit_koeffs.acdrive_windings = CONST_IQ_1; + for (i = 0; i < 6; i++) { + val = linear_decrease(edrk.temper_acdrive.winding.real_int_temper[i], + *(p_alarm + i), *(p_abnormal + i)); + edrk.temper_limit_koeffs.acdrive_windings = _IQmpy(val, edrk.temper_limit_koeffs.acdrive_windings); + } + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.acdrive_windings); + + edrk.temper_limit_koeffs.acdrive_bears = linear_decrease(edrk.temper_acdrive.bear.real_int_temper[0], + protect_levels.alarm_temper_acdrive_bear_DNE, protect_levels.abnormal_temper_acdrive_bear_DNE); + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.acdrive_bears); + edrk.temper_limit_koeffs.acdrive_bears = linear_decrease(edrk.temper_acdrive.bear.real_int_temper[1], + protect_levels.alarm_temper_acdrive_bear_NE, protect_levels.abnormal_temper_acdrive_bear_NE); + sum_limit = _IQmpy(sum_limit,edrk.temper_limit_koeffs.acdrive_bears); + + edrk.temper_limit_koeffs.sum_limit = sum_limit; + + if (edrk.temper_limit_koeffs.sum_limit < (CONST_IQ_1 - 1000)) + edrk.temper_limit_koeffs.code_status = 1; + else + edrk.temper_limit_koeffs.code_status = 0; + +} diff --git a/Inu/Src/main/overheat_limit.h b/Inu/Src/main/overheat_limit.h new file mode 100644 index 0000000..dc1199d --- /dev/null +++ b/Inu/Src/main/overheat_limit.h @@ -0,0 +1,13 @@ +/* + * overheat_limit.h + * + * Created on: 17 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_OVERHEAT_LIMIT_H_ +#define SRC_MAIN_OVERHEAT_LIMIT_H_ + +void calc_limit_overheat(); + +#endif /* SRC_MAIN_OVERHEAT_LIMIT_H_ */ diff --git a/Inu/Src/main/params.h b/Inu/Src/main/params.h new file mode 100644 index 0000000..7abc592 --- /dev/null +++ b/Inu/Src/main/params.h @@ -0,0 +1,182 @@ +#ifndef _PARAMS +#define _PARAMS + + +#if(_FLOOR6) + + +#define _ENABLE_PWM_LINES_FOR_TESTS 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_ROTOR 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_PWM 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_RS 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_SYNC 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_GO 0//1 + +#else + +#define _ENABLE_PWM_LINES_FOR_TESTS 0 +#define _ENABLE_PWM_LINES_FOR_TESTS_ROTOR 0 +#define _ENABLE_PWM_LINES_FOR_TESTS_PWM 0 +#define _ENABLE_PWM_LINES_FOR_TESTS_RS 0 +#define _ENABLE_PWM_LINES_FOR_TESTS_SYNC 0//1 +#define _ENABLE_PWM_LINES_FOR_TESTS_GO 0//1 +#endif + + +#if(_FLOOR6) +#define MODE_DISABLE_ENABLE_WDOG 1 // 0 - wdog ��������, 1 - �������� +#else +#define MODE_DISABLE_ENABLE_WDOG 0 // 0 - wdog ��������, 1 - �������� +#endif + + + + + + +#define CHECK_IN_OUT_TERMINAL 1 + +#define WORK_ON_STEND_D 0//1 + + + +//////////////////////////////////////////////////////////////////// +#ifndef MODE_DISABLE_ENABLE_WDOG +#define MODE_DISABLE_ENABLE_WDOG 0 +#endif + + +#ifndef CHECK_IN_OUT_TERMINAL +#define CHECK_IN_OUT_TERMINAL 0 +#endif + +#ifndef WORK_ON_STEND_D +#define WORK_ON_STEND_D 0 +#endif + + + +/*************************************************************************************/ +//#define BAN_ROTOR_REVERS_DIRECT 1 + +//#define TIME_PAUSE_ZADATCHIK 750//500 + +//#define TIME_SET_LINE_RELAY_FAN 3000 // ����� ������ �������� �� ���� ��������� ���������� ����������� +//#define LEVEL_FAN_ON_TEMPER_ACDRIVE 1400 //������� ��������� ����������� ���������� ��������� +//#define LEVEL_FAN_OFF_TEMPER_ACDRIVE 1200 //������� ���������� ����������� ���������� ��������� +//(������ ���� ������ LEVEL_FAN_ON_TEMPER_ACDRIVE � ������� �� ���������� ~20 �������� ) +//#define TIME_SET_LINE_RELAY_FAN 3000 //����� ������ �������� �� ���� ��������� ���������� ����������� + +/* +#define MAX_TIME_DIRECT_ROTOR 5000 // ����. �������� �������� �� ����������� ����������� �������� +#define MIN_TIME_DIRECT_ROTOR -5000 // ����������� �������� �������� �� ����������� ����������� �������� + +#define LEVEL_FORWARD_TIME_DIRECT_ROTOR 4000 // �������� �������� ������� ��������� ��� ����������� ������ +#define LEVEL_BACK_TIME_DIRECT_ROTOR -4000 // �������� �������� ������� ��������� ��� ����������� ����� + +#define MAX_TIME_ERROR_ROTOR 5000 // ����. �������� �������� �� ����������� ������������� ������������ �������� +#define MIN_TIME_ERROR_ROTOR 0 // ���. �������� �������� �� ����������� ������������� ������������ �������� + + +#define LEVEL_ON_ERROR_ROTOR 4000 // �������� �������� ������� ��������� ��� ����������� ������������ � ������� +#define LEVEL_OFF_ERROR_ROTOR 1000 // �������� �������� ������� ��������� ��� ����������� ������������ ��� ������� +*/ + + +/* +#define PID_KP_IM 0.018 //0.036 //0.018 //0.18 //0.095 // PID Kp +#define PID_KI_IM 0.08 // 0.008 // PID Ki +#define PID_KD_IM 0.0000 //100 // PID Kd +#define PID_KC_IM 0.09 // PID Kc + + +#define PID_KP_F 12//26//12 //40 //20 //12 //20 //60.0 //20.0 //0.095 // PID Kp +#define PID_KI_F 0.00010 // 0.008 // PID Ki +#define PID_KD_F 0.000 //100 PID Kd +#define PID_KC_F 0.005 // PID Kc +//#define PID_KC_F 0.000 // PID Kc + +#define ADD_KP_DF (1000.0/NORMA_MZZ)//(500.0/NORMA_MZZ)//(50.0/NORMA_MZZ) +#define ADD_KI_DF (2000.0/NORMA_MZZ)//(1000.0/NORMA_MZZ)//(100.0/NORMA_MZZ) +#define MAX_DELTA_pidF 2.0 +#define MIN_MZZ_FOR_DF 1761607 //(210/NORMA_MZZ) +*/ + +/* +#define Im_PREDEL 600 // ���������� ������ ��� ��� ������ �� ���� +#define I_OUT_PREDEL -20 // ���������� ���. ��� ����������y ��� ������ �� ���� +#define U_IN_PREDEL 500 // ���������� ������������ ������� ����y����� ��� ������ �� ���� + +#define IQ_NORMAL_CHARGE_UD_MAX 12163481 // 1450 V //13002342 // 1550 //_IQtoF(filter.iqU_1_long)*NORMA_ACP +#define IQ_NORMAL_CHARGE_UD_MIN 10066329 // 1200 V + + +#define U_D_MAX_ERROR_GLOBAL 17616076 // 2100 V //17196646 //2050V // 16777216 //2000V/2000*2^24 +#define U_D_MAX_ERROR 16777216 // 2000V //16357785 //1950V //15938355 //1900V/2000*2^24 + +//#define U_D_NORMA_MIN 3774873 // 450 V // 13421772 // 450 V 22.05.08 //1600V/2000*2^24 +//#define U_D_NORMA_MAX 15518924 // //15099494 //1850V/2000*2^24 + +#define U_D_MIN_ERROR 10905190 // 1300V/2000*2^24 + +#define I_IN_MAX_ERROR_GLOBAL 18454937 // 2200 A //16777216 //2000 A // 13421772 //1600 A //10905190 //1300 // 900A + +#define KOEFF_WROTOR_FILTER_SPARTAN 7//8 +#define MAX_DELTA_WROTOR_S_1_2 1 + +#define ENABLE_I_HDW_PROTECT_ON_GLOBAL 1 // ��������� ��������� ������� �������� �� ���������� ������� ������ + +#define TIME_WAIT_CHARGE 2000 //5000 // 10000 +#define TIME_WAIT_CHARGE_OUT 15000 //15000 +#define TIME_SET_LINE_RELAY 10000 +#define TIME_SET_LINE_RELAY5 3000 +#define TIME_WAIT_LEVEL_QPU2 3000 +*/ + + +/* +///--------------------------- 22220 paremetrs -------------------///////// + +//////////////////////////////////////////////////////////////// +// Loaded capasitors level +#define V_CAPASITORS_LOADED_IQ 11184810 //13421772 ~ 2400V // 11184810 ~ 2000V +#define V_NOMINAL 15099494 //15099494 ~ 2700V + +// Level of nominal currents +#define I_OUT_NOMINAL_IQ 10066329 //8388608 ~ 1500A //5592405 ~ 1000A // 10066329 ~ 1800A + //11184811 ~ 2000A // 12482249 ~ 2232A // 6710886 ~ 1200A +#define I_ZPT_NOMINAL_IQ 6123683 //1095A + + + +#define NORMA_MZZ 3000 //5000 +//#define NORMA_ACP 3000 +#define DISABLE_TEST_TKAK_ON_START 1 +//#define MOTOR_STEND 1 + + +//#define FREQ_PWM 350 //401 //379 + +#ifdef MOTOR_STEND +#define POLUS 4 // ����� ��� ������� + +#define BPSI_NORMAL 0.9//0.7 //Hz +#define MAX_FZAD_FROM_SU 16.7 // ����������� �������� �������� ������� � ������ �� �� +#define MAX_FZAD_FROM_SU_OBOROT 1100 + +#else +#define POLUS 6 // ����� ��� ������� +#define BPSI_NORMAL 0.9 //Hz +#define MAX_FZAD_FROM_SU 16.7 // ����������� �������� �������� ������� � ������ �� �� +#define MAX_FZAD_FROM_SU_OBOROT 1650 +#define COS_FI 0.83 + +#endif +*/ + +#define KOEF_TEMPER_DECR_MZZ 2.0 + +#endif + + + diff --git a/Inu/Src/main/params_alg.h b/Inu/Src/main/params_alg.h new file mode 100644 index 0000000..8529a80 --- /dev/null +++ b/Inu/Src/main/params_alg.h @@ -0,0 +1,218 @@ +/* + * params_alg.h + * + * Created on: 26 ���. 2020 �. + * Author: Yura + */ + +#ifndef SRC_MAIN_PARAMS_ALG_H_ +#define SRC_MAIN_PARAMS_ALG_H_ + +// ������� ������� �� �� ������, ����� � ������� +#define DISABLE_CALC_KM_ON_SLAVE 0//1 + +#define DISABLE_WORK_BREAK 0 // ��������� ������ � ���������� + +#define SENSOR_ALG_22220 1 +#define SENSOR_ALG_23550 2 + + +#define SENSOR_ALG SENSOR_ALG_22220 +//#define SENSOR_ALG SENSOR_ALG_23550 + + +#define NOMINAL_U_ZARYAD 2520 // ������� ���������� ������ ��� +#define NOMINAL_U_BREAK_LEVEL 2580 // ������ ������ ��������� + IQ_DELTA_U_START_RECUP=100V +#define NOMINAL_SET_IZAD 910 // ��� �� ����� +#define NOMINAL_SET_K_U_DISBALANCE 40//20 // ������� � ���������� ���������� ����. �������� ����� �� ����������, ���� >0 ���� ������� �������� +#define NOMINAL_SET_LIMIT_POWER 6300 // ����� �������� �� ����� + + + + + +/////////////////////////////////////////////////////////////// +#define U_D_MAX_ERROR_GLOBAL IQ_I_U_VALUE_PLUS_2850 //U_D_MAX_ERROR_GLOBAL_2850 + +#define MAX_U_PROC_SMALL 2.5 //1.4 +#define MAX_U_PROC 1.1 //1.11 //1.4 +#define MIN_U_PROC 0.8 //0.7 + +#define ADD_U_MAX_GLOBAL 200.0 //V ��������� ��������� ������� GLOBAL ������������ ZadanieU_Charge +#define ADD_U_MAX_GLOBAL_SMALL 500.0 //V ��������� ��������� ������� GLOBAL ������������ ZadanieU_Charge +#define LEVEL_DETECT_U_SMALL 1000.0 //V ��������� ��������� ������� GLOBAL ������������ ZadanieU_Charge + +#define KOEF_IM_ON_TORMOG 0.65// 0.75 // �� ������� ��������� ��������� �������� ��� ���������� +#define KOEF_IM_ON_TORMOG_WITH_MAX_TEMPER_BREAK 0.1// � ���������� �������� �� ������� ��������� ��������� �������� ��� ���������� + +/////////////////////////////////////////////////////////////// + + +#define MZZ_ADD_1 0.5 // 0.25 //0.5 ������������ ������ ������� �� 1 ���� +#define MZZ_ADD_2 0.15 ///0.1 //0.05 //0.1 ������������ ������ ������� �� 1 ���� +#define MZZ_ADD_3 0.25 //0.05 ///0.1 //0.05 //0.1 ������������ ������ ������� �� 1 ���� + +#define FZAD_ADD_MAX 0.08 //0.005 //0.08 ������������ ������ fzad �� 1 ���� +#define FZAD_DEC 0.0004 //������������ ����� fzad �� 1 ���� + +#define POWERZAD_ADD_MAX 0.08 //0.005 //0.08 ������������ ������ fzad �� 1 ���� +#define POWERZAD_DEC 0.0004 //������������ ����� fzad �� 1 ���� + +#define POLUS 6 //6 // ����� ��� ������� +#define BPSI_NORMAL 0.22 //0.3 // ���������� ��������� +#define BPSI_MAXIMAL 0.35 //0.3 // ���������� ��������� +#define BPSI_MINIMAL 0.05 //0.3 // ���������� ��������� +#define PROVOROT_F_HZ 0.2 // �������� +#define PROVOROT_OBOROTS 10 // �������� + + +#define ADD_KP_DF (1000.0/NORMA_MZZ)//(500.0/NORMA_MZZ)//(50.0/NORMA_MZZ) +#define ADD_KI_DF (2000.0/NORMA_MZZ)//(1000.0/NORMA_MZZ)//(100.0/NORMA_MZZ) + +#define ADD_KP_DPOWER (1000.0/NORMA_MZZ)//(500.0/NORMA_MZZ)//(50.0/NORMA_MZZ) +#define ADD_KI_DPOWER (2000.0/NORMA_MZZ)//(1000.0/NORMA_MZZ)//(100.0/NORMA_MZZ) + +#define MIN_MZZ_FOR_DF 210 +#define MIN_MZZ_FOR_DPOWER 210 + + +//////////////////// + + +#define PID_KP_IM 0.036 //0.018 //0.0013// 0.018 //0.036 //0.018 //0.18 //0.095 // PID Kp +#define PID_KI_IM 0.32 // 0.16 //0.32 //0.16 //0.08//0.8//0.025 //0.08 // PID Ki +#define PID_KD_IM 0.0000 //*100 // PID Kd +#define PID_KC_IM 0.09 // PID Kc + + +#define PID_KP_F 12.0//6.0//12.0 //6.0 //18 //12//6//26//12 //40 //20 //12 //20 //60.0 //20.0 //0.095 // PID Kp +#define PID_KI_F 0.00020 //0.00010 // 0.008 // PID Ki +//#define PID_KI_F 0.00030 //0.00010 // 0.008 // PID Ki +#define PID_KD_F 0.000 //*100 PID Kd +#define PID_KC_F 0.00005//0.005 // PID Kc +//#define PID_KC_F 0.000 // PID Kc + +#define PID_KP_POWER 9//3//26//12 //40 //20 //12 //20 //60.0 //20.0 //0.095 // PID Kp +//#define PID_KI_F 0.00020 //0.00010 // 0.008 // PID Ki +#define PID_KI_POWER 0.00030 //0.00010 // 0.008 // PID Ki +#define PID_KD_POWER 0.000 //*100 PID Kd +#define PID_KC_POWER 0.0001 // PID Kc + + + +/////////////////// +// ����. k ���������� ������������ + +#define K_STATOR_MAX 0.93 // 0.91 // ��� DEF_PERIOD_MIN_MKS = 60 ��� +#define K_STATOR_MIN 0.020 // 0.91 // ��� DEF_PERIOD_MIN_MKS = 60 ��� + +//#define K_STATOR_MAX 0.89 //��� DEF_PERIOD_MIN_MKS = 80 ��� + + + + +#define MAX_ZADANIE_I_VOZBUD 200.0 // A + +#define MAX_ZADANIE_U_CHARGE 2800.0//1500.0 //V +//#define MAX_ZADANIE_F_ROTOR 70 + +#define MAX_ZADANIE_OBOROTS_ROTOR 230.0 //340 //240 1000 //260.0 // +/- ob/min +#define MIN_ZADANIE_OBOROTS_ROTOR -230.0 //-180.0 //-230.0 // 1000 //260.0 // +/- ob/min + +#define MAX_1_ZADANIE_OBOROTS_ROTOR 120.0 //340 //240 1000 //260.0 // +/- ob/min +#define MIN_1_ZADANIE_OBOROTS_ROTOR -90.0 //-230.0 // 1000 //260.0 // +/- ob/min + + +#define DEAD_ZONE_ZADANIE_OBOROTS_ROTOR 10.0 + +#define MAX_ZADANIE_I_M 950.0// 1000.0 //750.0 // A + +#define MAX_ZADANIE_POWER 6300.0 // kWt +#define MIN_ZADANIE_POWER -6300.0 // kWt + +#define MAX_1_ZADANIE_POWER 3000.0 // kWt +#define MIN_1_ZADANIE_POWER -3000.0 // kWt + + +#define SUPER_MAX_ZADANIE_LIMIT_POWER 6500.0 // kWt + +#define MAX_ZADANIE_LIMIT_POWER 6300.0 // kWt +#define MAX_1_ZADANIE_LIMIT_POWER 2000.0 // kWt + +#define MIN_ZADANIE_LIMIT_POWER 100.0 // kWt +#define MIN_ZADANIE_LIMIT_POWER_FROM_SVU 50.0 // kWt +#define POWER_ZAPAS_FOR_UOM 5 //50 // ��� ����� ��� ��� + +#define DEAD_ZONE_ZADANIE_POWER 50.0 // kWt +#define DEAD_ZONE_ZADANIE_LIMIT_POWER 50.0 // kWt + + + +#define MAX_ZADANIE_K_M K_STATOR_MAX // A +#define MAX_ZADANIE_F 30.0 // Hz +#define MIN_ZADANIE_F -30.0 //60.0 // Hz + + +#define MAX_ZADANIE_K_U_DISBALANCE 2.0 //1.0 // k +#define MAX_ZADANIE_KPLUS_U_DISBALANCE 1.0 // k + + + +#define T_NARAST_ZADANIE_F 5.0 // sec +#define T_NARAST_ZADANIE_OBOROTS_ROTOR 80.0 //20.0 //30.0 //15.0 // sec + +#define T1_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS 80.0 //20.0 //30.0 //15.0 // sec +#define T1_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS 40.0 //20.0 //30.0 //15.0 // sec + +#define T2_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS 80.0 //160.0 //20.0 //30.0 //15.0 // sec +#define T2_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS 40.0 //20.0 //30.0 //15.0 // sec + +#define T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS 600.0 //160.0 //20.0 //30.0 //15.0 // sec +#define T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS 600.0 //20.0 //30.0 //15.0 // sec + + + +#define T_NARAST_ZADANIE_K_M 15.0 // sec +#define T_NARAST_ZADANIE_I_M 15.0 // sec + +#define T1_NARAST_ZADANIE_POWER_PLUS 80.0 //30.0 // sec +#define T1_NARAST_ZADANIE_POWER_MINUS 30.0 //30.0 // sec +#define T2_NARAST_ZADANIE_POWER_PLUS 80.0 //30.0 // sec +#define T2_NARAST_ZADANIE_POWER_MINUS 30.0 //30.0 // sec + +#define T_NARAST_ZADANIE_LIMIT_POWER 5.0 //30.0 // sec + +#define T1_NARAST_ZADANIE_LIMIT_POWER_PLUS 30.0 //30.0 // sec +#define T1_NARAST_ZADANIE_LIMIT_POWER_MINUS 5.0 //30.0 // sec +#define T2_NARAST_ZADANIE_LIMIT_POWER_PLUS 80.0 //30.0 // sec +#define T2_NARAST_ZADANIE_LIMIT_POWER_MINUS 5.0 //30.0 // sec + + +#define T_NARAST_ZADANIE_U_CHARGE 2.0 // sec +#define T_NARAST_ZADANIE_K_U_DISBALANCE 15.0 // sec +#define T_NARAST_ZADANIE_KPLUS_U_DISBALANCE 15.0 // sec + +#define T_NARAST_ZADANIE_IMITATION_OBOROTS_ROTOR 30.0 // sec + + + + + + +#define ENABLE_DECR_MZZ_POWER_IZAD 1 +// ����� �������� ��� ������� �������� �� ��� +#define POWER_AIN_100KW 186413 + +#define DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF (3*POWER_AIN_100KW) // 300 kW // 559240 //300 ���//186413 //100kW // iqP = P (W) /3000/3000 * 2^24 // +#define MIN_DELTA_LEVEL_POWER_AIN_DECR_MZZ_DEF (5*POWER_AIN_100KW) // 500 kW +#define SMEWENIE_LEVEL_POWER_AIN_DECR_MZZ_DEF 0 //(1*POWER_AIN_100KW) // 100 kW + +// �������� �� 1 - ������ ������ �� 0 - ��� ����������� +#define MAX_KOEF_OGRAN_POWER_LIMIT CONST_IQ_05 // 0.5 +#define EXP_FILTER_KOEF_OGRAN_POWER_LIMIT 4.40//2.22 // � �������� + + + + + +#endif /* SRC_MAIN_PARAMS_ALG_H_ */ diff --git a/Inu/Src/main/params_bsu.h b/Inu/Src/main/params_bsu.h new file mode 100644 index 0000000..a58cc2c --- /dev/null +++ b/Inu/Src/main/params_bsu.h @@ -0,0 +1,123 @@ +/* + * params_bsu.h + * + * Created on: 14 ����. 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_PARAMS_BSU_H_ +#define SRC_MAIN_PARAMS_BSU_H_ + +#include "iq_values_norma_f.h" +#include "iq_values_norma_iu.h" +#include "iq_values_norma_oborot.h" + + + +#define TKAK_23550 1 +#define TKAK_EDRK 2 + + +#define TKAK_VERSION TKAK_23550 +//#define TKAK_VERSION TKAK_EDRK + + +// ��� 23550_sp2 +#define TK_DEAD_TIME_NS 25000 //25.0 //40.0 +#define TK_ACKN_TIME_NS 2200 +#define TK_MIN_TIME_NS 25000 //80.0 //35.0 // 15.0 //40.0 +#define TK_SOFT_OFF_TIME_NS 20000 //25.0 //40.0 + +#define DIV_TIME_TK_SOFT_OFF 20 // 20 nsec -> 1 bit +#define DIV_TIME_TK_DEAD 640 //0.16 // 160 nsec -> 1 bit +#define DIV_TIME_TK_MIN 640 //0.16 // 160 nsec -> 1 bit + +#define DIV_TIME_TK_ACKN 20 // 20 nsec -> 1 bit + + +// ��� ���� sp2 + +#define TK_DEAD_TIME_MKS 25.0 //40.0 +#define TK_ACKN_TIME_MKS 2.2 +#define TK_MIN_TIME_MKS 25.0 // 15.0 //40.0 +#define DIV_TIME_TK 0.4 // 0.16 + + +#define MAX_READ_SBUS 1 //10 + + +#if (_FLOOR6==1) +// tkak +#define TKAK0_OFF_PROTECT 1 +#define TKAK1_OFF_PROTECT 1 +#define TKAK2_OFF_PROTECT 1 +#define TKAK3_OFF_PROTECT 1 +#define IN0_OFF_PROTECT 1 +#define IN1_OFF_PROTECT 1 +#define OUT0_OFF_PROTECT 1 + +#else +// tkak +#define TKAK0_OFF_PROTECT 0 +#define TKAK1_OFF_PROTECT 0 +#define TKAK2_OFF_PROTECT 0 +#define TKAK3_OFF_PROTECT 0 +#define IN0_OFF_PROTECT 0 +#define IN1_OFF_PROTECT 0 +#define OUT0_OFF_PROTECT 0 +#endif + +// ������ �� ����� ���� �� ������ +#define TK_DISABLE_OUTPUT_A1 0 +#define TK_DISABLE_OUTPUT_B1 0 +#define TK_DISABLE_OUTPUT_C1 0 + +#define TK_DISABLE_OUTPUT_A2 0 +#define TK_DISABLE_OUTPUT_B2 0 +#define TK_DISABLE_OUTPUT_C2 0 + +////////////////////// + +#define ENABLE_ROTOR_SENSOR_ZERO_SIGNAL 0 +#define ENABLE_ROTOR_SENSOR_1_PM67 1 +#define ENABLE_ROTOR_SENSOR_2_PM67 0 + +#define ENABLE_ROTOR_SENSOR_1_PBUS 0//1 +#define ENABLE_ROTOR_SENSOR_2_PBUS 0//1 + + +#if (ENABLE_ROTOR_SENSOR_1_PM67==1 && ENABLE_ROTOR_SENSOR_2_PM67==0) +// ������� 1-�� ������� �� ���� 2-�� +#define ENABLE_COMBO_SENSOR_1_TO_2 1 +#define ENABLE_COMBO_SENSOR_2_TO_1 0 +#endif + +#if (ENABLE_ROTOR_SENSOR_1_PM67==0 && ENABLE_ROTOR_SENSOR_2_PM67==1) +// ������� 2-�� ������� �� ���� 1-�� +#define ENABLE_COMBO_SENSOR_2_TO_1 1 +#define ENABLE_COMBO_SENSOR_1_TO_2 0 +#endif + + + +#if (ENABLE_ROTOR_SENSOR_1_PM67==1 && ENABLE_ROTOR_SENSOR_2_PM67==1) + +#define ENABLE_COMBO_SENSOR_1 0 +#define ENABLE_COMBO_SENSOR_1 0 + +#endif + + +#define ROTOR_SENSOR_IMPULSES_PER_ROTATE 4096 // 1024 // ���-�� ��������� �� 1 ������ � ������� + + + + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// + + + +#endif /* SRC_MAIN_PARAMS_BSU_H_ */ diff --git a/Inu/Src/main/params_hwp.h b/Inu/Src/main/params_hwp.h new file mode 100644 index 0000000..d3ebed4 --- /dev/null +++ b/Inu/Src/main/params_hwp.h @@ -0,0 +1,9 @@ + + +#define LEVEL_HWP_U_ZPT 2900 //2800 // V 0-2900 V +#define LEVEL_HWP_I_AF 800 //700 // A 0-450A +#define LEVEL_HWP_I_ZPT 1600 // A 0-2000?? +#define LEVEL_HWP_U_ABC 3100 //2900 //2800 // V 0-2000V +#define LEVEL_HWP_I_BREAK 900 //750 // A 0-2000A + +#define convert_real_to_mv_hwp(nc,value) ((float)value*(float)R_ADC[0][nc]/(float)K_LEM_ADC[0][nc]*10.0) diff --git a/Inu/Src/main/params_motor.h b/Inu/Src/main/params_motor.h new file mode 100644 index 0000000..1e8c030 --- /dev/null +++ b/Inu/Src/main/params_motor.h @@ -0,0 +1,59 @@ +/* + * params_motor.h + * + * Created on: 14 ����. 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_PARAMS_MOTOR_H_ +#define SRC_MAIN_PARAMS_MOTOR_H_ + + + +#define SDVIG_OBMOTKI_ZERO 1 +#define SDVIG_OBMOTKI_30_PLUS 2 +#define SDVIG_OBMOTKI_30_MINUS 3 + + +#define SETUP_SDVIG_OBMOTKI SDVIG_OBMOTKI_ZERO //SDVIG_OBMOTKI_ZERO +//#define SETUP_SDVIG_OBMOTKI SDVIG_OBMOTKI_30_PLUS //SDVIG_OBMOTKI_ZERO + +#define COS_FI 0.87 +// Level of nominal currents +#define I_OUT_NOMINAL_IQ 5033164// 900 A //8388608 ~ 1500A //5592405 ~ 1000A // 10066329 ~ 1800A + //11184811 ~ 2000A // 12482249 ~ 2232A // 6710886 ~ 1200A +#define I_OUT_NOMINAL 900 + +#define MOTOR_CURRENT_NOMINAL 650.0 //930.0 +#define MOTOR_CURRENT_MAX 900.00 //1489.0 + + + + +#define P_NOMINAL 6300 //KWt +#define WROT_NOMINAL 180.0 +#define WROT_MAX 530.0 +#define FROT_NOMINAL (WROT_NOMINAL / 60.0) +#define FROT_MAX (WROT_MAX / 60.0) + +//#define REVERS_ON_CLOCK 1 // 0 // 1- �� ������� .. 0 - ������ ������� + + + +//#define WORK_TWICE 0 /* �������� � ����y ��������� */ + + +//#define MAX_ZAD_OBOROTS 200 + +#define L_SIGMA_S 0.0001467 +#define L_SIGMA_R 0.00000923 +#define L_M 0.00421 +#define R_STATOR 0.002 +#define R_ROTOR_SHTRIH 0.0021 +#define SLIP_NOM 0.006 +#define R_ROTOR (R_ROTOR_SHTRIH / SLIP_NOM) +#define F_STATOR_NOM 50.0 + + + +#endif /* SRC_MAIN_PARAMS_MOTOR_H_ */ diff --git a/Inu/Src/main/params_norma.h b/Inu/Src/main/params_norma.h new file mode 100644 index 0000000..9c3e790 --- /dev/null +++ b/Inu/Src/main/params_norma.h @@ -0,0 +1,70 @@ +/* + * params_norma.h + * + * Created on: 14 ����. 2020 �. + * Author: yura + */ + +#ifndef _PARAMS_NORMA_H_ +#define _PARAMS_NORMA_H_ + + +//////////////////////////////////////////////////// +#define NORMA_FROTOR_INT 20 +#define NORMA_ACP_INT 3000 +#define NORMA_ANGLE 360 +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +//#define NORMA_FROTOR 20.0 +//#define NORMA_ACP 3000.0 + +#define NORMA_FROTOR ((float)NORMA_FROTOR_INT) +#define NORMA_ACP ((float)NORMA_ACP_INT) + + +#define NORMA_MZZ_INT NORMA_ACP_INT +#define NORMA_MZZ ((float)NORMA_MZZ_INT) + +#define NORMA_I_U_INT NORMA_MZZ_INT + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// + +//#define F_STATOR_MAX NORMA_FROTOR // ����. �������� ���������� ������������ + + + + +#define NORMA_ACP_P 100.0 + +#define NORMA_ACP_RMS 2127.66 + +#define NORMA_ACP_TEMPER_MILL_AMP 100.0 // + +#ifndef PROJECT_SHIP +#error �� ���������� PROJECT_SHIP � predifine Name +#else + + +#if (PROJECT_SHIP == 1) +#define NORMA_ACP_TEMPER 100.0 // ��� 23550.1 +#endif + + +#if (PROJECT_SHIP == 2) +#define NORMA_ACP_TEMPER 200.0 // ��� 23550.3 +#endif + +#if (PROJECT_SHIP== 3) +#define NORMA_ACP_TEMPER 200.0 // ��� 23550.3 + +#endif + + +#endif + + + + +#endif /* _PARAMS_NORMA_H_ */ diff --git a/Inu/Src/main/params_protect_adc.h b/Inu/Src/main/params_protect_adc.h new file mode 100644 index 0000000..b5772bd --- /dev/null +++ b/Inu/Src/main/params_protect_adc.h @@ -0,0 +1,25 @@ +/* + * params_protect_adc.h + * + * Created on: 8 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_PARAMS_PROTECT_ADC_H_ +#define SRC_MAIN_PARAMS_PROTECT_ADC_H_ +#include <params_motor.h> +#include <params_hwp.h> + + +#define LEVEL_ADC_I_AF LEVEL_HWP_I_AF // A 0-450A +#define LEVEL_ADC_I_ZPT LEVEL_HWP_I_ZPT // A 0-2000?? +//#define LEVEL_ADC_U_ABC 1000 // V 0-2000V +#define LEVEL_ADC_I_BREAK LEVEL_HWP_I_BREAK // A 0-2000A +#define LEVEL_ADC_U_ZPT_MAX LEVEL_HWP_U_ZPT +#define LEVEL_ADC_U_ZPT_MIN 1800 +#define LEVEL_ADC_U_IN_MAX LEVEL_HWP_U_ABC +#define LEVEL_ADC_U_IN_MIN 1380 +#define LEVEL_ADC_I_OUT_MAX I_OUT_NOMINAL //(I_OUT_NOMINAL * 1.9) + + +#endif /* SRC_MAIN_PARAMS_PROTECT_ADC_H_ */ diff --git a/Inu/Src/main/params_pwm24.h b/Inu/Src/main/params_pwm24.h new file mode 100644 index 0000000..a2571a6 --- /dev/null +++ b/Inu/Src/main/params_pwm24.h @@ -0,0 +1,48 @@ +/* + * params_pwm24.h + * + * Created on: 14 ����. 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_PARAMS_PWM24_H_ +#define SRC_MAIN_PARAMS_PWM24_H_ + +/////////////////////////////////////////////////////// +#if (_SIMULATE_AC==1) +#define FREQ_PWM 100 //450 //800 /* ������� ���� */ //3138 // 2360//2477 // +#else +#define FREQ_PWM 450 //800 /* ������� ���� */ //3138 // 2360//2477 // +#endif + +#define DEF_PERIOD_MIN_MKS 60 // 80 //60 // ����� ����������� ����� ������ ����� = 2*TK_MIN_TIME_MKS = 30 � ������� + // + TK_DEAD_TIME_MKS + 5mks ����� = 60 +#define DEF_PERIOD_MIN_BR_XTICS 165 + +///////////////// + + + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + + +//#define PWN_COUNT_RUN_PER_INTERRUPT PWM_ONE_INTERRUPT_RUN // ���� ���������� �� ������ ���� +#define PWN_COUNT_RUN_PER_INTERRUPT PWM_TWICE_INTERRUPT_RUN // ��� ���������� �� ������ ���� + + + + + +/////////////////////////// +#define FREQ_INTERNAL_GENERATOR_XILINX_TMS 1875000 // ���������� ������� ���������� � ��� ���������� �� ��67 + + +////////////////////// + + + + + +#endif /* SRC_MAIN_PARAMS_PWM24_H_ */ diff --git a/Inu/Src/main/params_temper_p.h b/Inu/Src/main/params_temper_p.h new file mode 100644 index 0000000..2864649 --- /dev/null +++ b/Inu/Src/main/params_temper_p.h @@ -0,0 +1,58 @@ + +#define INDEX_T_WATER_EXT 0 +#define INDEX_T_WATER_INT 1 + + +#define ALARM_TEMPER_BREAK_INT 1100 +#define ABNORMAL_TEMPER_BREAK_INT 900 +#define DELTA_TEMPER_BREAK_INT 20 + + + + +// koef to svu +#define K_TEMPER_TO_SVU 10.0 +#define K_P_WATER_TO_SVU 100.0 + + + +// T UO1_7 +#define ALARM_TEMPER_AF 400 +#define ABNORMAL_TEMPER_AF 350 + + +// T water INT EXT +#define ALARM_TEMPER_WATER_INT 400 +#define ABNORMAL_TEMPER_WATER_INT 350 + + +#define ALARM_TEMPER_WATER_EXT 400 +#define ABNORMAL_TEMPER_WATER_EXT 350 + + +// P water max +#define ALARM_P_WATER_MAX_INT 600 +#define ABNORMAL_P_WATER_MAX_INT 500 + +// P water min +#define ALARM_P_WATER_MIN_INT 150//300 +#define ABNORMAL_P_WATER_MIN_INT 180//320 + +#define ALARM_P_WATER_MIN_INT_ON_OFF_PUMP 60// 110 +#define ABNORMAL_P_WATER_MIN_INT_ON_OFF_PUMP 110// 130 + + +// air +#define ALARM_TEMPER_AIR_INT 450 +#define ABNORMAL_TEMPER_AIR_INT 400 + +//ac drive +#define ALARM_TEMPER_ACDRIVE_WINDING 1300 +#define ABNORMAL_TEMPER_ACDRIVE_WINDING 1200 + +#define ALARM_TEMPER_ACDRIVE_BEAR 900 +#define ABNORMAL_TEMPER_ACDRIVE_BEAR 800 + +#define ALARM_TEMPER_BSU 600 +#define ABNORMAL_TEMPER_BSU 500 + diff --git a/Inu/Src/main/pll_tools.c b/Inu/Src/main/pll_tools.c new file mode 100644 index 0000000..decc342 --- /dev/null +++ b/Inu/Src/main/pll_tools.c @@ -0,0 +1,105 @@ +/* + * pll_tools.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 "adc_tools.h" +#include "limit_power.h" +#include "pll_tools.h" + + +//#pragma DATA_SECTION(pll1, ".slow_vars") +PLL_REC pll1 = PLL_REC_DEFAULT; + + + +void init_50hz_input_net50hz(void) +{ + + //1. ������������� + + pll1.setup.freq_run_pll = (FREQ_RUN_PLL); // ������� ������� ������� ��. + pll1.setup.rotation_u_cba = 0;//0;//1; // ����������� ���: 0 - ���������� A-B-C, 1 - ������������ A-C-B + + pll1.init(&pll1); // ������ � ������������� ���������� ���������� + + // ����� ������������� + +} + +void calc_pll_50hz(void) +{ + + // �������� ������ � ��������. + pll1.input.Input_U_AB = analog.iqUin_A1B1; + pll1.input.Input_U_BC = analog.iqUin_B1C1; + pll1.input.Input_U_CA = analog.iqUin_C1A1; + + // ������, ��������� � �������� ��������� � setup.freq_run_pll + pll1.calc_pll(&pll1); +// ����� ������� + + +} + + +void get_freq_50hz_float(void) +{ + float int_delta_freq_test; + // 3. ��������� ������ � ���������� ����. + + // ��������� ������ � �������� ���� � ��*100. + // ����� �������� ���� - ������ ��� ��������� ������. + pll1.get_freq_float(&pll1); + + if (edrk.Status_Ready.bits.preImitationReady2) + edrk.freq_50hz_1 = 5001; + else + edrk.freq_50hz_1 = pll1.output.int_freq_net; + + if (delta_freq_test>0) + { + int_delta_freq_test = _IQtoF( delta_freq_test) * pll1.setup.freq_run_pll / PI * 50.00; // freq*100 + edrk.freq_50hz_1 -= int_delta_freq_test; + } + + // + + +} + +void get_freq_50hz_iq(void) +{ + + // 3. ��������� ������ � ���������� ����. + + // ��������� ������ � �������� ���� � ��*100. + // ����� �������� ���� - ������ ��� ��������� ������. + pll1.get_freq_iq(&pll1); + + if (edrk.Status_Ready.bits.preImitationReady2) + edrk.iq_freq_50hz = level_50hz; + else + edrk.iq_freq_50hz = pll1.output.iq_freq_net; + + if (delta_freq_test>0) + edrk.iq_freq_50hz -= delta_freq_test; + + // + + +} + diff --git a/Inu/Src/main/pll_tools.h b/Inu/Src/main/pll_tools.h new file mode 100644 index 0000000..1659e90 --- /dev/null +++ b/Inu/Src/main/pll_tools.h @@ -0,0 +1,22 @@ +/* + * pll_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_PLL_TOOLS_H_ +#define SRC_MAIN_PLL_TOOLS_H_ + + +#define FREQ_RUN_PLL (2*FREQ_PWM) + + +void get_freq_50hz_float(void); +void get_freq_50hz_iq(void); +void calc_pll_50hz(void); +void init_50hz_input_net50hz(void); + +extern PLL_REC pll1; + +#endif /* SRC_MAIN_PLL_TOOLS_H_ */ diff --git a/Inu/Src/main/project.c b/Inu/Src/main/project.c new file mode 100644 index 0000000..a8fcec9 --- /dev/null +++ b/Inu/Src/main/project.c @@ -0,0 +1,1049 @@ +#include <adc_tools.h> +#include <params_bsu.h> +#include <params_hwp.h> + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" +#include "xp_cds_in.h" +#include "xp_cds_out.h" +#include "xp_cds_rs.h" +#include "xp_cds_tk.h" +#include "xp_cds_tk_balzam.h" +#include "xp_project.h" + + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + + + + + + + +void tkak_init_plate(int k, int tkak0_off_protect, int tk_disable_output_a, int tk_disable_output_b) +{ + unsigned int t_ticks; + //tkak 0 + project.cds_tk[k].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + + + if (k==3) + { +// project.cds_tk[k].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + // ��� � ��� ������ ��������� + if (tkak0_off_protect==1) + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0x0000; // only break ack+cur + else + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0x0303; // only break ack+cur + +// project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x0003; // optical bus+break + project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x00cf; // optical bus+break + +#if (TKAK_VERSION==TKAK_EDRK) + project.cds_tk[k].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[k].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[k].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); +#endif + +#if (TKAK_VERSION==TKAK_23550) + project.cds_tk[k].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_NS/1000.0 / 0.02); + project.cds_tk[k].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_NS/1000.0 / DIV_TIME_TK); + project.cds_tk[k].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_NS/1000.0 / DIV_TIME_TK); +#endif + } + else + { + project.cds_tk[k].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + + if (tk_disable_output_a==1 && tk_disable_output_b==1) + { + project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x0000; //mask key 1-use key,0-not use key + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0xff00; // cur+ack 1-on protect. + } + else + if (tk_disable_output_a==0 && tk_disable_output_b==1) + { + project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x000f; //mask key 1-use key,0-not use key + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0x0f0f; // cur+ack 1-on protect. + } + else + if (tk_disable_output_a==1 && tk_disable_output_b==0) + { + project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x00f0; //mask key 1-use key,0-not use key + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0xf0f0; // cur+ack 1-on protect. + } + else + if (tk_disable_output_a==0 && tk_disable_output_b==0) + { + project.cds_tk[k].write.sbus.mask_tk_out_40pin.all = 0x00ff; //mask key 1-use key,0-not use key + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0xffff; // cur+ack 1-on protect. + } + + if (tkak0_off_protect==1) + project.cds_tk[k].write.sbus.mask_protect_tk.all = 0x0000; // cur+ack 1-on protect. + + +#if (TKAK_VERSION==TKAK_EDRK) + project.cds_tk[k].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[k].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[k].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); +#endif + + +#if (TKAK_VERSION==TKAK_23550) + + +// TK_ACKN_TIME_NS + + t_ticks = (unsigned int)(TK_ACKN_TIME_NS / DIV_TIME_TK_ACKN); + +#if (TK_ACKN_TIME_NS>(DIV_TIME_TK_ACKN*255)) +#error "TK_ACKN_TIME_NS ���� �������!" +#endif + project.cds_tk[k].write.sbus.ack_time.bit.time = (unsigned int)t_ticks; + + +// TK_MIN_TIME_NS + + t_ticks = (unsigned int)(TK_MIN_TIME_NS / DIV_TIME_TK_MIN); + +#if (TK_MIN_TIME_NS>(DIV_TIME_TK_MIN*255)) +#error "TK_MIN_TIME_NS ���� �������!" +#endif + + project.cds_tk[k].write.sbus.dead_min_time.bit.mintime = (unsigned int)t_ticks; + + +//TK_DEAD_TIME_NS + + // ����������� �������� ��� dead_time = 5 ���, ������ - ���������� ��� ����� 5 ��� + t_ticks = (unsigned int)(TK_DEAD_TIME_NS / DIV_TIME_TK_DEAD); + +#if (TK_DEAD_TIME_NS>(DIV_TIME_TK_DEAD*255)) +#error "TK_DEAD_TIME_MKS ���� �������!" +#endif + project.cds_tk[k].write.sbus.dead_min_time.bit.deadtime = (unsigned int)(t_ticks); + + +// TK_SOFT_OFF_TIME_NS + + t_ticks = (unsigned int)(TK_SOFT_OFF_TIME_NS / DIV_TIME_TK_SOFT_OFF); + +#if (TK_SOFT_OFF_TIME_NS>(DIV_TIME_TK_SOFT_OFF*65535)) +#error "TK_SOFT_OFF_TIME_MKS ���� �������!" +#endif + project.cds_tk[k].write.sbus.time_after_err = (unsigned int)t_ticks; + +#endif + + + + + project.cds_tk[k].write.sbus.protect_error.bit.enable_soft_disconnect = 1; + project.cds_tk[k].write.sbus.protect_error.bit.detect_soft_disconnect = 0;//1; + + } + + if (tkak0_off_protect==1) + { + project.cds_tk[k].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_tk[k].write.sbus.protect_error.bit.enable_err_switch = 0; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err_mintime = 0; + project.cds_tk[k].write.sbus.protect_error.bit.enable_line_err = 0; + project.cds_tk[k].write.sbus.protect_error.bit.enable_soft_disconnect = 0; + project.cds_tk[k].write.sbus.protect_error.bit.detect_soft_disconnect = 0; + } + else + { + + project.cds_tk[k].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_tk[k].write.sbus.protect_error.bit.disable_err_mintime = 1; + project.cds_tk[k].write.sbus.protect_error.bit.enable_line_err = 1;//1;//0;//1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_tk[k].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_tk[k].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_tk[k].write.sbus.protect_error.bit.enable_err_switch = 1; + } + + +} + + +//////////////////////////////////////////////////////////////// +// ������ ��������� � �������. ����� � HWP +//////////////////////////////////////////////////////////////// +void project_prepare_config(void) +{ + int k = 0; +// write here setup for all plates +// +// +// +// ... +// project.cds_tk[0].write.sbus.ack_time.bit.delay = ...; + + + + +////////////////////////////////////////////////////////////////// +/// +// �������� ��� ��������� � ���� PBUS +///////////////////////////////////////////////////////////////// + +#if (USE_IN_0) + project.cds_in[0].type_plate = cds_in_type_in_1; +////////////////////////////////////////////////////////////////// +// �������� ����� ������ �� ����� �������� � PBUS IN0 sensors +// + project.cds_in[0].setup_pbus.use_reg_in_pbus.all = 0; +//DataFromIn + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg0 = 1; // use +//Gotov + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg1 = 1; // use +//Direction + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg2 = 1; // use + +//#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) +// sensor1 +//SpeedS1_cnt + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg3 = 1; // use +//SpeedS1_cnt90 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg4 = 1; // use +//#endif + +//#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) +// sensor2 +//SpeedS2_cnt + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg5 = 1; // use +//SpeedS2_cnt90 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg6 = 1; // use +//#endif + +//#if (TYPE_CDS_XILINX_IN_0==TYPE_CDS_XILINX_SP2) +// if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP2) +//is Channel Alive +// project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg13 = 1; // use +//#endif + + + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + + #if (ENABLE_ROTOR_SENSOR_1_PBUS==1) + //Time since zero point S1 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg7 = 1; // use + // Impulses since zero point Rising S1 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg8 = 1; // use + //Impulses since zero point Falling S1 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg9 = 1; // use + #endif + + + #if (ENABLE_ROTOR_SENSOR_2_PBUS==1) + //Time since zero point S2 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg10 = 1; // use + // Impulses since zero point Rising S2 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg11 = 1; // use + //Impulses since zero point Falling S2 + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg12 = 1; // use + #endif + + //is Channel Alive + project.cds_in[0].setup_pbus.use_reg_in_pbus.bit.reg13 = 1; // use + + } + project.cds_in[0].status_serial_bus.max_read_error = MAX_READ_SBUS; + + +#endif + + +#if (USE_IN_1) + project.cds_in[1].type_plate = cds_in_type_in_2; +// IN1 + project.cds_in[1].setup_pbus.use_reg_in_pbus.all = 0; + project.cds_in[1].setup_pbus.use_reg_in_pbus.bit.reg0 = 1; // use + project.cds_in[1].setup_pbus.use_reg_in_pbus.bit.reg1 = 0; // not use + project.cds_in[1].setup_pbus.use_reg_in_pbus.bit.reg2 = 0; // not use + + project.cds_in[1].status_serial_bus.max_read_error = MAX_READ_SBUS; + +#endif + +#if (USE_IN_2) + project.cds_in[2].type_plate = cds_in_type_in_2; +// IN2 + project.cds_in[2].setup_pbus.use_reg_in_pbus.all = 0; + project.cds_in[2].setup_pbus.use_reg_in_pbus.bit.reg0 = 1; // use + project.cds_in[2].setup_pbus.use_reg_in_pbus.bit.reg1 = 0; // not use + project.cds_in[2].setup_pbus.use_reg_in_pbus.bit.reg2 = 0; // not use + project.cds_in[2].status_serial_bus.max_read_error = MAX_READ_SBUS; + +#endif + +#if (USE_ROT_1) +// CDS_RS + project.cds_rs[0].setup_pbus.use_reg_in_pbus.all = 0xffff; // use all 16 +#endif + +#if (USE_ADC_0) +//ADC0 + project.adc[0].setup_pbus.use_reg_in_pbus.all = 0xffff; // use all 16 + ///////////////////////////////////////////////////////////////////////////// + // SERIAL_BUS Timing setup + ///////////////////////////////////////////////////////////////////////////// + project.adc[0].status_serial_bus.max_read_error = 2;//MAX_READ_SBUS; + project.adc[0].status_serial_bus.max_write_error = 2;//MAX_READ_SBUS; +#endif + +#if (USE_ADC_1) +//ADC1 + project.adc[1].setup_pbus.use_reg_in_pbus.all = 0xffff; // use all 16 + ///////////////////////////////////////////////////////////////////////////// + // SERIAL_BUS Timing setup + ///////////////////////////////////////////////////////////////////////////// + project.adc[1].status_serial_bus.max_read_error = 2;//MAX_READ_SBUS; + project.adc[1].status_serial_bus.max_write_error = 2;//MAX_READ_SBUS; + +#endif + +#if (USE_ADC_2) +//ADC1 + project.adc[1].setup_pbus.use_reg_in_pbus.all = 0xffff; // use all 16 + ///////////////////////////////////////////////////////////////////////////// + // SERIAL_BUS Timing setup + ///////////////////////////////////////////////////////////////////////////// + + project.adc[1].status_serial_bus.max_read_error = 2;//MAX_READ_SBUS; + project.adc[1].status_serial_bus.max_write_error = 2;//MAX_READ_SBUS; + +#endif + + + +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// + +#if (USE_TK_0) + tkak_init_plate(0, TKAK0_OFF_PROTECT, TK_DISABLE_OUTPUT_A1, TK_DISABLE_OUTPUT_B1); +#endif +#if (USE_TK_1) + tkak_init_plate(1, TKAK1_OFF_PROTECT, TK_DISABLE_OUTPUT_C1, TK_DISABLE_OUTPUT_A2); +#endif +#if (USE_TK_2) + tkak_init_plate(2, TKAK2_OFF_PROTECT, TK_DISABLE_OUTPUT_B2, TK_DISABLE_OUTPUT_C2); +#endif + +#if (USE_TK_3) + tkak_init_plate(3, TKAK3_OFF_PROTECT, 0, 0); +#endif + +/* +#if (USE_TK_0) +//tkak 0 + project.cds_tk[0].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + project.cds_tk[0].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + +#if (TK_DISABLE_OUTPUT_A1==1 && TK_DISABLE_OUTPUT_B1==1) + project.cds_tk[0].write.sbus.mask_tk_out_40pin.all = 0x0000; //mask key 1-use key,0-not use key + project.cds_tk[0].write.sbus.mask_protect_tk.all = 0xff00; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_A1==0 && TK_DISABLE_OUTPUT_B1==1) + project.cds_tk[0].write.sbus.mask_tk_out_40pin.all = 0x000f; //mask key 1-use key,0-not use key + project.cds_tk[0].write.sbus.mask_protect_tk.all = 0xff0f; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_A1==1 && TK_DISABLE_OUTPUT_B1==0) + project.cds_tk[0].write.sbus.mask_tk_out_40pin.all = 0x00f0; //mask key 1-use key,0-not use key + project.cds_tk[0].write.sbus.mask_protect_tk.all = 0xfff0; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_A1==0 && TK_DISABLE_OUTPUT_B1==0) + project.cds_tk[0].write.sbus.mask_tk_out_40pin.all = 0x00ff; //mask key 1-use key,0-not use key + project.cds_tk[0].write.sbus.mask_protect_tk.all = 0xffff; // cur+ack 1-on protect. +#endif +#endif +#endif +#endif + +#if (TKAK0_OFF_PROTECT==1) + project.cds_tk[0].write.sbus.mask_protect_tk.all = 0x0000; // cur+ack 1-on protect. +#endif + + + project.cds_tk[0].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[0].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[0].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); + + + +#if (TKAK0_OFF_PROTECT==1) + project.cds_tk[0].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_tk[0].write.sbus.protect_error.bit.enable_err_switch = 0; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err_mintime = 0; + project.cds_tk[0].write.sbus.protect_error.bit.enable_line_err = 0; +#else + + + project.cds_tk[0].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_tk[0].write.sbus.protect_error.bit.disable_err_mintime = 1; + project.cds_tk[0].write.sbus.protect_error.bit.enable_line_err = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_tk[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_tk[0].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_tk[0].write.sbus.protect_error.bit.enable_err_switch = 1; + + +#endif + + +#endif + + +#if (USE_TK_1) +////////////////////////////////////////////////////////////// +// tkak1 + project.cds_tk[1].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + project.cds_tk[1].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + + +#if (TK_DISABLE_OUTPUT_C1==1 && TK_DISABLE_OUTPUT_A2==1) + project.cds_tk[1].write.sbus.mask_tk_out_40pin.all = 0x0000; //mask key 1-use key,0-not use key + project.cds_tk[1].write.sbus.mask_protect_tk.all = 0xff00; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_C1==0 && TK_DISABLE_OUTPUT_A2==1) + project.cds_tk[1].write.sbus.mask_tk_out_40pin.all = 0x000f; //mask key 1-use key,0-not use key + project.cds_tk[1].write.sbus.mask_protect_tk.all = 0xff0f; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_C1==1 && TK_DISABLE_OUTPUT_A2==0) + project.cds_tk[1].write.sbus.mask_tk_out_40pin.all = 0x00f0; //mask key 1-use key,0-not use key + project.cds_tk[1].write.sbus.mask_protect_tk.all = 0xfff0; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_C1==0 && TK_DISABLE_OUTPUT_A2==0) + project.cds_tk[1].write.sbus.mask_tk_out_40pin.all = 0x00ff; //mask key 1-use key,0-not use key + project.cds_tk[1].write.sbus.mask_protect_tk.all = 0xffff; // cur+ack 1-on protect. +#endif +#endif +#endif +#endif + + +#if (TKAK1_OFF_PROTECT==1) + project.cds_tk[1].write.sbus.mask_protect_tk.all = 0x0000; // cur+ack 1-on protect. +#endif + + project.cds_tk[1].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[1].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[1].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); + +#if (TKAK1_OFF_PROTECT==1) + project.cds_tk[1].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_tk[1].write.sbus.protect_error.bit.enable_err_switch = 0; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err_mintime = 0; + project.cds_tk[1].write.sbus.protect_error.bit.enable_line_err = 0; +#else + + project.cds_tk[1].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_tk[1].write.sbus.protect_error.bit.disable_err_mintime = 1; + project.cds_tk[1].write.sbus.protect_error.bit.enable_line_err = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_tk[1].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_tk[1].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_tk[1].write.sbus.protect_error.bit.enable_err_switch = 1; + +#endif + +#endif + + +#if (USE_TK_2) +////////////////////////////////////////////////////////////// +// tkak2 + project.cds_tk[2].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + project.cds_tk[2].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + +#if (TK_DISABLE_OUTPUT_B2==1 && TK_DISABLE_OUTPUT_C2==1) + project.cds_tk[2].write.sbus.mask_tk_out_40pin.all = 0x0000; //mask key 1-use key,0-not use key + project.cds_tk[2].write.sbus.mask_protect_tk.all = 0xff00; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_B2==0 && TK_DISABLE_OUTPUT_C2==1) + project.cds_tk[2].write.sbus.mask_tk_out_40pin.all = 0x000f; //mask key 1-use key,0-not use key + project.cds_tk[2].write.sbus.mask_protect_tk.all = 0xff0f; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_B2==1 && TK_DISABLE_OUTPUT_C2==0) + project.cds_tk[2].write.sbus.mask_tk_out_40pin.all = 0x00f0; //mask key 1-use key,0-not use key + project.cds_tk[2].write.sbus.mask_protect_tk.all = 0xfff0; // cur+ack 1-on protect. +#else +#if (TK_DISABLE_OUTPUT_B2==0 && TK_DISABLE_OUTPUT_C2==0) + project.cds_tk[2].write.sbus.mask_tk_out_40pin.all = 0x00ff; //mask key 1-use key,0-not use key + project.cds_tk[2].write.sbus.mask_protect_tk.all = 0xffff; // cur+ack 1-on protect. +#endif +#endif +#endif +#endif + +#if (TKAK1_OFF_PROTECT==1) + project.cds_tk[2].write.sbus.mask_protect_tk.all = 0x0000; // cur+ack 1-on protect. +#endif + + + project.cds_tk[2].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[2].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[2].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); + +#if (TKAK2_OFF_PROTECT==1) + + project.cds_tk[2].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_tk[2].write.sbus.protect_error.bit.enable_err_switch = 0; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err_mintime = 0; + project.cds_tk[2].write.sbus.protect_error.bit.enable_line_err = 0; + +#else + + project.cds_tk[2].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_tk[2].write.sbus.protect_error.bit.disable_err_mintime = 1; + project.cds_tk[2].write.sbus.protect_error.bit.enable_line_err = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_tk[2].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_tk[2].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_tk[2].write.sbus.protect_error.bit.enable_err_switch = 1; + +#endif + +#endif + + + +#if (USE_TK_3) +////////////////////////////////////////////////////////////// + +// ��� � ��� ������ ��������� + project.cds_tk[3].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup +// project.cds_tk[3].setup_pbus.use_reg_in_pbus.all = 0x0; // PBUS all off + +#if (TKAK3_OFF_PROTECT==1) + project.cds_tk[3].write.sbus.mask_protect_tk.all = 0x0000; // only break ack+cur +#else + project.cds_tk[3].write.sbus.mask_protect_tk.all = 0x0303; // only break ack+cur +#endif + project.cds_tk[3].write.sbus.mask_tk_out_40pin.all = 0x00cf; // optical bus+break + + project.cds_tk[3].write.sbus.ack_time.bit.time = (int)(TK_ACKN_TIME_MKS / 0.02); + project.cds_tk[3].write.sbus.dead_min_time.bit.mintime = (int)(TK_MIN_TIME_MKS / DIV_TIME_TK); + project.cds_tk[3].write.sbus.dead_min_time.bit.deadtime = (int)(TK_DEAD_TIME_MKS / DIV_TIME_TK); + + +#if (TKAK3_OFF_PROTECT==1) + + project.cds_tk[3].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_tk[3].write.sbus.protect_error.bit.enable_err_switch = 0; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err_mintime = 0; + project.cds_tk[3].write.sbus.protect_error.bit.enable_line_err = 0; + +#else + + project.cds_tk[3].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_tk[3].write.sbus.protect_error.bit.disable_err_mintime = 1; + project.cds_tk[3].write.sbus.protect_error.bit.enable_line_err = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_tk[3].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_tk[3].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_tk[3].write.sbus.protect_error.bit.enable_err_switch = 1; + + +#endif + +#endif +*/ +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// + +// Out plane setup + + +#if (USE_OUT_0) +////////////////////////////////////////////////////////////// +// out0 + + project.cds_out[0].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + + + +#if (OUT0_OFF_PROTECT==1) + + project.cds_out[0].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_out[0].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_out[0].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_out[0].write.sbus.protect_error.bit.enable_err_switch = 0; + +#else + + project.cds_out[0].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_out[0].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_out[0].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_out[0].write.sbus.protect_error.bit.enable_err_switch = 1; + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_out[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_out[0].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_out[0].write.sbus.protect_error.bit.enable_err_switch = 1; + +#endif + + project.cds_out[0].write.sbus.enable_protect_out.all = 0x0000; + + +// ���������� ����������� �������� �� ����� OUT ��� ������������� �������� ERR + project.cds_out[0].write.sbus.enable_protect_out.bit.dout0 = 1; // ��� ���. ����� + project.cds_out[0].write.sbus.enable_protect_out.bit.dout6 = 1; // 6 - ���������� ��������� QTV +// project.cds_out[0].write.sbus.enable_protect_out.bit.dout7 = 1; // QTV OFF + project.cds_out[0].write.sbus.enable_protect_out.bit.dout8 = 1; // 8 - ��������� QTV + project.cds_out[0].write.sbus.enable_protect_out.bit.dout13 = 1; // 13 - �������� ��� �������������� �������������� + +#endif + +#if (USE_OUT_1) + +// out1 + project.cds_out[1].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + +#if (OUT1_OFF_PROTECT==1) + + project.cds_out[1].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_out[1].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_out[1].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_out[1].write.sbus.protect_error.bit.enable_err_switch = 0; + +#else + project.cds_out[1].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_out[1].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_out[1].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_out[1].write.sbus.protect_error.bit.enable_err_switch = 1; + + + project.cds_out[1].write.sbus.protect_error.bit.enable_err_power = 1; + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_out[1].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_out[1].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_out[1].write.sbus.protect_error.bit.enable_err_switch = 1; +#endif + + project.cds_out[1].write.sbus.enable_protect_out.all = 0x0000; + +#endif + +#if (USE_OUT_2) + +//out2 + project.cds_out[2].status_serial_bus.max_read_error = MAX_READ_SBUS;// SERIAL_BUS Timing setup + + + project.cds_out[2].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_out[2].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_out[2].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_out[2].write.sbus.protect_error.bit.enable_err_switch = 1; + + + project.cds_out[2].write.sbus.protect_error.bit.enable_err_power = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_out[2].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_out[2].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_out[2].write.sbus.protect_error.bit.enable_err_switch = 1; + + project.cds_out[2].write.sbus.enable_protect_out.all = 0x0000; + +#endif + +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +///////////// + +#if (USE_IN_0) + +///////////////////////////////////////////////////////////////////// +// setup incremental sensor rotor +///////////////////////////////////////////////////////////////////// +// ����� ������������� ��� �������� �������� �� ����� ������ +// 1 - 20ns 0 - 2us. + project.cds_in[0].write.sbus.enabled_channels.bit.discret = 0; + + +// ��������� ������ ���� ������ �� ����� In0- ����� ����, In1-������, In2-������90����. +// ������� ��������� ������ ������ ��� ������, ���� �� ������ �� ���� ��67 ��� ������, �� +// ������ ������� In1-������, In2-������90����. � ���������� ��� ������� ������� + + project.cds_in[0].write.sbus.enabled_channels.bit.sens_1_direct_ch = 1; //1 + project.cds_in[0].write.sbus.enabled_channels.bit.sens_1_direct_ch_90deg = 1; //0 + project.cds_in[0].write.sbus.enabled_channels.bit.sens_1_inv_ch = 0; + project.cds_in[0].write.sbus.enabled_channels.bit.sens_1_inv_ch_90deg = 0; + + project.cds_in[0].write.sbus.enabled_channels.bit.sens_2_direct_ch = 1; + project.cds_in[0].write.sbus.enabled_channels.bit.sens_2_direct_ch_90deg = 1; + project.cds_in[0].write.sbus.enabled_channels.bit.sens_2_inv_ch = 0; + project.cds_in[0].write.sbus.enabled_channels.bit.sens_2_inv_ch_90deg = 0; + +// ������ ������ In1-������, In2-������90����. +// �� �������������� ����� 0xf + project.cds_in[0].write.sbus.first_sensor.bit.direct_ch = 0x0; // in2 + project.cds_in[0].write.sbus.first_sensor.bit.direct_ch_90deg = 0x1; // in1 +// ��� ��������� + project.cds_in[0].write.sbus.first_sensor.bit.inv_ch = 0x0f; // in0 + project.cds_in[0].write.sbus.first_sensor.bit.inv_ch_90deg = 0x0f; // in0 + +// ��� �� ������, �� � ����������� In2-������, In1-������90����. + project.cds_in[0].write.sbus.second_sensor.bit.direct_ch = 0x01; // in0 + project.cds_in[0].write.sbus.second_sensor.bit.direct_ch_90deg = 0x00; // in1 +// ��� ��������� + project.cds_in[0].write.sbus.second_sensor.bit.inv_ch = 0x0f; // in0 + project.cds_in[0].write.sbus.second_sensor.bit.inv_ch_90deg = 0x0f; // in0 +// ����� ���� + project.cds_in[0].write.sbus.zero_sensors.bit.for_sensor1 = 0x02; // + project.cds_in[0].write.sbus.zero_sensors.bit.for_sensor2 = 0x0f; // +// �������� ������ ���� ������ ���� + project.cds_in[0].write.sbus.zero_sensors.bit.enable_sensor1 = 1; + project.cds_in[0].write.sbus.zero_sensors.bit.enable_sensor2 = 0; + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// + +// In plane setup +//in0 + +#if (IN0_OFF_PROTECT==1) + + project.cds_in[0].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_in[0].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_in[0].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_in[0].write.sbus.protect_error.bit.enable_err_switch = 0; + +#else + + project.cds_in[0].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_in[0].write.sbus.protect_error.bit.disable_err_hwp = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + project.cds_in[0].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_in[0].write.sbus.protect_error.bit.enable_err_switch = 0; + } + else + { + project.cds_in[0].write.sbus.protect_error.bit.enable_err_power = 1; + project.cds_in[0].write.sbus.protect_error.bit.enable_err_switch = 1; + } + +#endif + + +#endif + + +#if (USE_IN_1) + +// in1 + +#if (IN1_OFF_PROTECT==1) + + project.cds_in[1].write.sbus.protect_error.bit.disable_err0_in = 0; + project.cds_in[1].write.sbus.protect_error.bit.disable_err_hwp = 0; + project.cds_in[1].write.sbus.protect_error.bit.enable_err_power = 0; + project.cds_in[1].write.sbus.protect_error.bit.enable_err_switch = 0; + +#else + + + project.cds_in[1].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_in[1].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_in[1].write.sbus.protect_error.bit.enable_err_power = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_in[1].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_in[1].write.sbus.protect_error.bit.enable_err_switch = 0; + else + project.cds_in[1].write.sbus.protect_error.bit.enable_err_switch = 1; + +#endif + +#endif + + + +#if (USE_IN_2) + +// in2 + project.cds_in[2].write.sbus.protect_error.bit.disable_err0_in = 1; + project.cds_in[2].write.sbus.protect_error.bit.disable_err_hwp = 1; + project.cds_in[2].write.sbus.protect_error.bit.enable_err_power = 1; + + // �� ������ ���������� ������ ����� ������� ���! ����� ��������! + if (project.cds_in[2].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + project.cds_in[2].write.sbus.protect_error.bit.enable_err_switch = 0; + + else + project.cds_in[2].write.sbus.protect_error.bit.enable_err_switch = 1; + + +#endif + +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +#if (USE_HWP_0) + + // HWP setup +// project.hwp[0].write.HWP_Speed = MODE_HWP_SPEED_AUTO;//MODE_HWP_SPEED_NORMAL;// MODE_HWP_SPEED_AUTO; // MODE_HWP_SPEED_SLOW;//MODE_HWP_SPEED_NORMAL;// MODE_HWP_SPEED_SLOW; + + project.hwp[0].write.test_all_channel = 1; + + project.hwp[0].write.use_channel.minus.all = 0xfffc; + project.hwp[0].write.use_channel.plus.all = 0xffff; + +/* + project.hwp[0].write.use_channel.plus.bit.ch0 = 1; + + project.hwp[0].write.use_channel.minus.bit.ch5 = 1; + project.hwp[0].write.use_channel.plus.bit.ch5 = 1; + + project.hwp[0].write.use_channel.minus.bit.ch11 = 1; + project.hwp[0].write.use_channel.plus.bit.ch11 = 1; + +*/ + + project.hwp[0].write.values[0].plus = convert_real_to_mv_hwp(0,LEVEL_HWP_U_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[0].minus = convert_real_to_mv_hwp(0,LEVEL_HWP_U_ZPT); + + project.hwp[0].write.values[1].plus = convert_real_to_mv_hwp(1,LEVEL_HWP_U_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[1].minus = convert_real_to_mv_hwp(1,LEVEL_HWP_U_ZPT); + + project.hwp[0].write.values[2].plus = convert_real_to_mv_hwp(2,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[2].minus = convert_real_to_mv_hwp(2,LEVEL_HWP_I_AF); + project.hwp[0].write.values[3].plus = convert_real_to_mv_hwp(3,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[3].minus = convert_real_to_mv_hwp(3,LEVEL_HWP_I_AF); + project.hwp[0].write.values[4].plus = convert_real_to_mv_hwp(4,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[4].minus = convert_real_to_mv_hwp(4,LEVEL_HWP_I_AF); + project.hwp[0].write.values[5].plus = convert_real_to_mv_hwp(5,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[5].minus = convert_real_to_mv_hwp(5,LEVEL_HWP_I_AF); + project.hwp[0].write.values[6].plus = convert_real_to_mv_hwp(6,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[6].minus = convert_real_to_mv_hwp(6,LEVEL_HWP_I_AF); + project.hwp[0].write.values[7].plus = convert_real_to_mv_hwp(7,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[7].minus = convert_real_to_mv_hwp(7,LEVEL_HWP_I_AF); + + project.hwp[0].write.values[8].plus = convert_real_to_mv_hwp(8,LEVEL_HWP_I_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[8].minus = convert_real_to_mv_hwp(8,LEVEL_HWP_I_ZPT); + project.hwp[0].write.values[9].plus = convert_real_to_mv_hwp(9,LEVEL_HWP_I_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[9].minus = convert_real_to_mv_hwp(9,LEVEL_HWP_I_ZPT); + + project.hwp[0].write.use_channel.minus.bit.ch9 = 0; + project.hwp[0].write.use_channel.plus.bit.ch9 = 0; + + project.hwp[0].write.values[10].plus = convert_real_to_mv_hwp(10,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[10].minus = convert_real_to_mv_hwp(10,LEVEL_HWP_U_ABC); + project.hwp[0].write.values[11].plus = convert_real_to_mv_hwp(11,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[11].minus = convert_real_to_mv_hwp(11,LEVEL_HWP_U_ABC); + project.hwp[0].write.values[12].plus = convert_real_to_mv_hwp(12,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[12].minus = convert_real_to_mv_hwp(12,LEVEL_HWP_U_ABC); + project.hwp[0].write.values[13].plus = convert_real_to_mv_hwp(13,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[13].minus = convert_real_to_mv_hwp(13,LEVEL_HWP_U_ABC); + + + project.hwp[0].write.values[14].plus = convert_real_to_mv_hwp(14,LEVEL_HWP_I_BREAK); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[14].minus = convert_real_to_mv_hwp(14,LEVEL_HWP_I_BREAK); + project.hwp[0].write.values[15].plus = convert_real_to_mv_hwp(15,LEVEL_HWP_I_BREAK); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[0].write.values[15].minus = convert_real_to_mv_hwp(15,LEVEL_HWP_I_BREAK); +#endif +////////////////////////////////////////////////////////////// +#if (USE_HWP_1) + + // HWP setup + // project.hwp[1].write.HWP_Speed = MODE_HWP_SPEED_AUTO;//MODE_HWP_SPEED_NORMAL;// MODE_HWP_SPEED_SLOW; + project.hwp[1].write.test_all_channel = 1; + + project.hwp[1].write.use_channel.minus.all = 0xfffc; + project.hwp[1].write.use_channel.plus.all = 0xffff; + + + project.hwp[1].write.values[0].plus = convert_real_to_mv_hwp(0,LEVEL_HWP_U_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[0].minus = convert_real_to_mv_hwp(0,LEVEL_HWP_U_ZPT); + + project.hwp[1].write.values[1].plus = convert_real_to_mv_hwp(1,LEVEL_HWP_U_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[1].minus = convert_real_to_mv_hwp(1,LEVEL_HWP_U_ZPT); + + project.hwp[1].write.values[2].plus = convert_real_to_mv_hwp(2,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[2].minus = convert_real_to_mv_hwp(2,LEVEL_HWP_I_AF); + project.hwp[1].write.values[3].plus = convert_real_to_mv_hwp(3,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[3].minus = convert_real_to_mv_hwp(3,LEVEL_HWP_I_AF); + project.hwp[1].write.values[4].plus = convert_real_to_mv_hwp(4,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[4].minus = convert_real_to_mv_hwp(4,LEVEL_HWP_I_AF); + project.hwp[1].write.values[5].plus = convert_real_to_mv_hwp(5,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[5].minus = convert_real_to_mv_hwp(5,LEVEL_HWP_I_AF); + project.hwp[1].write.values[6].plus = convert_real_to_mv_hwp(6,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[6].minus = convert_real_to_mv_hwp(6,LEVEL_HWP_I_AF); + project.hwp[1].write.values[7].plus = convert_real_to_mv_hwp(7,LEVEL_HWP_I_AF); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[7].minus = convert_real_to_mv_hwp(7,LEVEL_HWP_I_AF); + + project.hwp[1].write.values[8].plus = convert_real_to_mv_hwp(8,LEVEL_HWP_I_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[8].minus = convert_real_to_mv_hwp(8,LEVEL_HWP_I_ZPT); + project.hwp[1].write.values[9].plus = convert_real_to_mv_hwp(9,LEVEL_HWP_I_ZPT); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[9].minus = convert_real_to_mv_hwp(9,LEVEL_HWP_I_ZPT); + + + project.hwp[1].write.values[10].plus = convert_real_to_mv_hwp(10,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[10].minus = convert_real_to_mv_hwp(10,LEVEL_HWP_U_ABC); + project.hwp[1].write.values[11].plus = convert_real_to_mv_hwp(11,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[11].minus = convert_real_to_mv_hwp(11,LEVEL_HWP_U_ABC); + project.hwp[1].write.values[12].plus = convert_real_to_mv_hwp(12,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[12].minus = convert_real_to_mv_hwp(12,LEVEL_HWP_U_ABC); + project.hwp[1].write.values[13].plus = convert_real_to_mv_hwp(13,LEVEL_HWP_U_ABC); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[13].minus = convert_real_to_mv_hwp(13,LEVEL_HWP_U_ABC); + + + project.hwp[1].write.values[14].plus = convert_real_to_mv_hwp(14,LEVEL_HWP_I_BREAK); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[14].minus = convert_real_to_mv_hwp(14,LEVEL_HWP_I_BREAK); + project.hwp[1].write.values[15].plus = convert_real_to_mv_hwp(15,LEVEL_HWP_I_BREAK); //Uzpt1 //2 3000V - 845; 3977V - 1120; 2800V - 789; 2600V - 732 + project.hwp[1].write.values[15].minus = convert_real_to_mv_hwp(15,LEVEL_HWP_I_BREAK); + #endif + + +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// + //Incremental sensor_init +#if (ENABLE_ROTOR_SENSOR_1_PM67==1) + inc_sensor.use_sensor1 = 1; +#else + inc_sensor.use_sensor1 = 0; +#endif + +#if (ENABLE_ROTOR_SENSOR_2_PM67==1) + inc_sensor.use_sensor2 = 1; +#else + inc_sensor.use_sensor2 = 0; +#endif + + +#if (ENABLE_COMBO_SENSOR_1_TO_2==1) + inc_sensor.use_sensor2 = 1; +#endif +#if (ENABLE_COMBO_SENSOR_2_TO_1==1) + inc_sensor.use_sensor1 = 1; +#endif + + + inc_sensor.pm67regs.write_comand_reg.bit.set_sampling_time = SAMPLING_TIME_MS; +// 23550 +// inc_sensor.pm67regs.write_comand_reg.bit.filter_sensitivity = 5; //0x0; //�� 170 ��.��� +// 22220 + inc_sensor.pm67regs.write_comand_reg.bit.filter_sensitivity = 300;//5; //0x0; //�� 170 ��.��� + + + + inc_sensor.set(&inc_sensor); + + //Rotation sensor_init +/* + rotation_sensor.in_plane.cds_in = &project.cds_in[0]; + rotation_sensor.use_sensor1 = 1; + rotation_sensor.use_sensor2 = 1; + rotation_sensor.use_angle_plane = 0; + + + + + rotation_sensor.in_plane.write.sbus.enabled_channels.bit.sens_1_direct_ch =1; + rotation_sensor.in_plane.write.sbus.enabled_channels.bit.sens_2_direct_ch_90deg =1; + +// rotation_sensor.in_plane.write.sbus.enabled_channels.bit.sens_1_direct_ch_90deg = 1; + +// rotation_sensor.in_plane.write.sbus.enabled_channels.bit.sens_2_direct_ch = 1; +// rotation_sensor.in_plane.write.sbus.enabled_channels.bit.sens_2_direct_ch_90deg = 1; + + rotation_sensor.in_plane.write.sbus.first_sensor_inputs.bit.direct_ch = 0; +// rotation_sensor.in_plane.write.sbus.first_sensor_inputs.bit.direct_ch_90deg = 1; + +// rotation_sensor.in_plane.write.sbus.second_sensor_inputs.bit.direct_ch = 3; + rotation_sensor.in_plane.write.sbus.second_sensor_inputs.bit.direct_ch_90deg = 1; + + + + + + + rotation_sensor.in_plane.write.regs.comand_reg.bit.set_sampling_time = SAMPLING_TIME_MS; + rotation_sensor.in_plane.write.regs.comand_reg.bit.filter_sensitivity = 0xF; //�� 170 ��.��� + +*/ + + + + + //filter 1 ~ 20nsec + /* rotation_sensor.rotation_plane.cds_rs = &project.cds_rs[0]; + rotation_sensor.rotation_plane.write.sbus.config.all = 0; + rotation_sensor.rotation_plane.write.sbus.config.bit.channel1_enable = 1; + rotation_sensor.rotation_plane.write.sbus.config.bit.plane_is_master = 1; + rotation_sensor.rotation_plane.write.sbus.config.bit.survey_time = 49; + rotation_sensor.rotation_plane.write.sbus.config.bit.transmition_speed = TS250; + */ +// rotation_sensor.set(&rotation_sensor); + + if (project.controller.status != component_Ready) + return; + +// project.load_cfg_to_plates(); + +} + + + diff --git a/Inu/Src/main/project.h b/Inu/Src/main/project.h new file mode 100644 index 0000000..32dba9a --- /dev/null +++ b/Inu/Src/main/project.h @@ -0,0 +1,74 @@ +#ifndef PROJECT_H +#define PROJECT_H + + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_GlobalPrototypes.h" +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" +#include "DSP281x_Ev.h" // DSP281x Examples Include File +#include "MemoryFunctions.h" +#include "Spartan2E_Adr.h" +#include "Spartan2E_Functions.h" +#include "TuneUpPlane.h" +#include "x_parallel_bus.h" +#include "x_serial_bus.h" +#include "xerror.h" +#include "xp_adc.h" +#include "xp_cds_in.h" +#include "xp_cds_out.h" +#include "xp_cds_tk.h" +#include "xp_controller.h" +#include "xp_hwp.h" +#include "xp_project.h" +#include "xPeriphSP6_loader.h" +//#include "xp_omega.h" +//#include "xp_dispatcher.h" + +//#include "x_error_buffer.h" + +//#include "x_project_plane.h" + +/* Define this macros to add to project files, contaning code */ +/* communicating with test terminal by RS232 */ +#define USE_TEST_TERMINAL 1 + +/* Define this macros to add to project files, contaning code */ +/* communicating with SVO and MPU by RS, using modbus protokol */ +#define USE_MODBUS_TABLE_SVU 1 + +/* Define this macros to add to project files, contaning code */ +/* communicating with Ingeteam Pult by RS, using modbus protocol */ +#define USE_MODBUS_TABLE_PULT 1 + + +// ���������� control_station.c � control_station.h +#define USE_CONTROL_STATION 1 + + + + + +///////////////////////////////////////////////////////////////// +#ifndef USE_CONTROL_STATION +#define USE_CONTROL_STATION 0 +#endif + +#ifndef USE_TEST_TERMINAL +#define USE_TEST_TERMINAL 0 +#endif + +#ifndef USE_MODBUS_TABLE_SVU +#define USE_MODBUS_TABLE_SVU 0 +#endif + +#ifndef USE_MODBUS_TABLE_PULT +#define USE_MODBUS_TABLE_PULT 0 +#endif +//////////////////////////////////////////////////////////////// +// ������ ��������� � �������. ����� � HWP +//////////////////////////////////////////////////////////////// +void project_prepare_config(void); + + +#endif // end PROJECT_H diff --git a/Inu/Src/main/project_setup.h b/Inu/Src/main/project_setup.h new file mode 100644 index 0000000..4f3ec93 --- /dev/null +++ b/Inu/Src/main/project_setup.h @@ -0,0 +1,414 @@ +#ifndef PROJECT_SETUP_H +#define PROJECT_SETUP_H + +/* + + ���������� ��������� ��� ����� ���� � myXilinx + � ����������� �� C_PROJECT_TYPE ���������� ���� + + project_setup.h ������ ������ � ����� /main/ + �.�. ��� /myXilinx/ + �.�. �� ��� ������� ������� �� ������ ���� ��������! +*/ + +/*------------------------------------------------------------------------------ + Project type +------------------------------------------------------------------------------*/ +// ��� ��������� ������� +///////////////////////////////////////////////////////////////////////////// +#define PROJECT_22220 10 +#define PROJECT_21300 11 +#define PROJECT_21180 12 +#define PROJECT_BALZAM 13 +#define PROJECT_23470 14 +#define PROJECT_23550 15 +#define PROJECT_10510 16 + + +#define PROJECT_STEND_D PROJECT_BALZAM + +/////////////////////////////////////////////// +// �������� ������ ������ +/////////////////////////////////////////////// + +//#define C_PROJECT_TYPE PROJECT_21180 +//#define C_PROJECT_TYPE PROJECT_21300 +//#define C_PROJECT_TYPE PROJECT_22220 +//#define C_PROJECT_TYPE PROJECT_BALZAM +//#define C_PROJECT_TYPE PROJECT_23470 +//#define C_PROJECT_TYPE PROJECT_STEND_D + +#define C_PROJECT_TYPE PROJECT_23550 +//#define C_PROJECT_TYPE PROJECT_10510 + +// ��������� ��������� RS232 +#define RS232_SPEED_A 57600//115200//57600 +#define RS232_SPEED_B 57600//115200//57600// + +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +// ��������� ���� ���� +/////////////////////////////////////////////////////////////////////////////////// + +#if (C_PROJECT_TYPE==PROJECT_23550 || C_PROJECT_TYPE==PROJECT_BALZAM) +#define XPWMGEN 1 // ��� �� xilinx 24 +#define TMSPWMGEN 0 // ��� �� tms +#else +#define XPWMGEN 0 // ��� �� xilinx 24 +#define TMSPWMGEN 1 // ��� �� tms +#endif + + +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// + +#if (TMSPWMGEN==1) && (XPWMGEN==1) + #error "������ ��������� �������. ������� ��� ���� ����!!!" + +#endif + + +#if (TMSPWMGEN==1) + +#else //TMSPWMGEN + +#if (XPWMGEN==1) +#else + + #error "������ ��������� �������. �� ������ ��� ����!!!" + +#endif //XPWMGEN +#endif //TMSPWMGEN + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +///////////////////////////////////////////////// +// ��������� ���������� ���� ��� ������� +//////////////////////////////////////////////// +///////////////////////////////////////////////// +#if (_FLOOR6==0) +#define USE_ADC_0 1 +#define USE_ADC_1 1 +////#define USE_ADC_2 1 +// +#define USE_IN_0 1 + +#define USE_IN_1 1 +//////#define USE_IN_2 1 +//// +#define USE_OUT_0 1 +//////#define USE_OUT_1 1 +//////#define USE_OUT_2 1 +//// +//// +#define USE_TK_0 1 +#define USE_TK_1 1 +//// +#define USE_TK_2 1 +#define USE_TK_3 1 +//// +//////#define USE_TK_4 1 +//////#define USE_TK_5 1 +//////#define USE_TK_6 1 +//////#define USE_TK_7 1 +//// +#define USE_HWP_0 1 +////#define USE_HWP_1 1 +//////#define USE_HWP_2 1 +//// +//////#define USE_ROT_1 1 + +#else + +#if (_FLOOR6_ADD==1) + +#define USE_ADC_0 1 +#define USE_ADC_1 1 +////// +#define USE_IN_0 1 +//// +//#define USE_IN_1 1 +//////// +//#define USE_OUT_0 1 +//////// +//////// +#define USE_TK_0 1 +#define USE_TK_1 1 +////// +#define USE_TK_2 1 +#define USE_TK_3 1 + +//#define USE_HWP_0 1 + + +#else + +#define USE_ADC_0 1 +#define USE_ADC_1 1 +//// +#define USE_IN_0 1 +// +#define USE_IN_1 1 +////// +#define USE_OUT_0 1 +////// +////// +#define USE_TK_0 1 +#define USE_TK_1 1 +//// +#define USE_TK_2 1 +#define USE_TK_3 1 + +#define USE_HWP_0 1 +#define USE_HWP_1 1 + +#endif + +#endif + + +//////////////////////////////////////////////// +// ��������� ���� ���� SP2 ��� SP6 +//////////////////////////////////////////////// +//////////////////////////////////////////////// +//////////////////////////////////////////////// + +#define TYPE_CDS_XILINX_IN_0 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_IN_1 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_IN_2 TYPE_CDS_XILINX_SP2 + +#define TYPE_CDS_XILINX_OUT_0 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_OUT_1 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_OUT_2 TYPE_CDS_XILINX_SP2 + +#define TYPE_CDS_XILINX_TK_0 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_1 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_2 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_3 TYPE_CDS_XILINX_SP6 +#define TYPE_CDS_XILINX_TK_4 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_5 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_6 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_TK_7 TYPE_CDS_XILINX_SP2 + +#define TYPE_CDS_XILINX_ADC_0 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_ADC_1 TYPE_CDS_XILINX_SP2 +#define TYPE_CDS_XILINX_ADC_2 TYPE_CDS_XILINX_SP2 + +#define TYPE_CDS_XILINX_RS_0 TYPE_CDS_XILINX_SP2 + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +//////////////////////////////////////////////// + +//#define TYPE_CDS_XILINX_HWP_0_1 MODE_HWP_SPEED_SLOW + +#ifndef USE_ADC_0 +#define USE_ADC_0 0 +#endif + +#ifndef USE_ADC_1 +#define USE_ADC_1 0 +#endif + +#ifndef USE_ADC_2 +#define USE_ADC_2 0 +#endif + + +#ifndef USE_IN_0 +#define USE_IN_0 0 +#endif + +#ifndef USE_IN_1 +#define USE_IN_1 0 +#endif + +#ifndef USE_IN_2 +#define USE_IN_2 0 +#endif + + +#ifndef USE_OUT_0 +#define USE_OUT_0 0 +#endif + +#ifndef USE_OUT_1 +#define USE_OUT_1 0 +#endif + +#ifndef USE_OUT_2 +#define USE_OUT_2 0 +#endif + + + +#ifndef USE_TK_0 +#define USE_TK_0 0 +#endif + +#ifndef USE_TK_1 +#define USE_TK_1 0 +#endif + + +// +#ifndef USE_TK_2 +#define USE_TK_2 0 +#endif + +#ifndef USE_TK_3 +#define USE_TK_3 0 +#endif + + +#ifndef USE_TK_4 +#define USE_TK_4 0 +#endif + +#ifndef USE_TK_5 +#define USE_TK_5 0 +#endif + +#ifndef USE_TK_6 +#define USE_TK_6 0 +#endif + +#ifndef USE_TK_7 +#define USE_TK_7 0 +#endif + + +#ifndef USE_HWP_0 +#define USE_HWP_0 0 +#endif + +#ifndef USE_HWP_1 +#define USE_HWP_1 0 +#endif + +#ifndef USE_HWP_2 +#define USE_HWP_2 0 +#endif + + +#ifndef USE_ROT_1 +#define USE_ROT_1 0 +#endif + + + +//////////////////////////////////////////////// +// ������������� ���� ������� ���� � ������� +//////////////////////////////////////////////// +#if (USE_HWP_2==1) +#define MAX_COUNT_PLATES_HWP 3 +#else +#if (USE_HWP_1==1) +#define MAX_COUNT_PLATES_HWP 2 +#else +#define MAX_COUNT_PLATES_HWP 1 +#endif +#endif +//////////////////////////////////////////////// + +#if (USE_TK_7==1) +#define MAX_COUNT_PLATES_CDS_TK 8 +#else +#if (USE_TK_6==1) +#define MAX_COUNT_PLATES_CDS_TK 7 +#else +#if (USE_TK_5==1) +#define MAX_COUNT_PLATES_CDS_TK 6 +#else +#if (USE_TK_4==1) +#define MAX_COUNT_PLATES_CDS_TK 5 +#else +#if (USE_TK_3==1) +#define MAX_COUNT_PLATES_CDS_TK 4 +#else +#if (USE_TK_2==1) +#define MAX_COUNT_PLATES_CDS_TK 3 +#else +#if (USE_TK_1==1) +#define MAX_COUNT_PLATES_CDS_TK 2 +#else +#if (USE_TK_0==1) +#define MAX_COUNT_PLATES_CDS_TK 1 +#else +#define MAX_COUNT_PLATES_CDS_TK 1 + +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +//////////////////////////////////////////////// + +#if (USE_ADC_2==1) +#define MAX_COUNT_PLATES_ADC 3 +#else +#if (USE_ADC_1==1) +#define MAX_COUNT_PLATES_ADC 2 +#else +#if (USE_ADC_0==1) +#define MAX_COUNT_PLATES_ADC 1 +#else +#define MAX_COUNT_PLATES_ADC 1 +#endif +#endif +#endif + + +//////////////////////////////////////////////// +#if (USE_OUT_2==1) +#define MAX_COUNT_PLATES_OUT 3 +#else +#if (USE_OUT_1==1) +#define MAX_COUNT_PLATES_OUT 2 +#else +#if (USE_OUT_0==1) +#define MAX_COUNT_PLATES_OUT 1 +#else +#define MAX_COUNT_PLATES_OUT 1 +#endif +#endif +#endif + + +//////////////////////////////////////////////// +//////////////////////////////////////////////// +#if (USE_IN_2==1) +#define MAX_COUNT_PLATES_IN 3 +#else +#if (USE_IN_1==1) +#define MAX_COUNT_PLATES_IN 2 +#else +#if (USE_IN_0==1) +#define MAX_COUNT_PLATES_IN 1 +#else +#define MAX_COUNT_PLATES_IN 1 +#endif +#endif +#endif + + +//////////////////////////////////////////////// + + +#if (USE_ROT_1==1) +#define MAX_COUNT_PLATES_CDS_RS 1 +#else +#define MAX_COUNT_PLATES_CDS_RS 0 +#endif + +//////////////////////////////////////////////// + + +#include <params_bsu.h> + +#endif // end PROJECT_SETUP_H + diff --git a/Inu/Src/main/protect_levels.h b/Inu/Src/main/protect_levels.h new file mode 100644 index 0000000..b9bf78f --- /dev/null +++ b/Inu/Src/main/protect_levels.h @@ -0,0 +1,119 @@ +/* + * params_protect.h + * + * Created on: 17 ���. 2020 �. + * Author: star + */ + +#ifndef SRC_MAIN_PROTECT_LEVELS_H_ +#define SRC_MAIN_PROTECT_LEVELS_H_ + +#include <params_protect_adc.h> + +typedef struct { + + int alarm_temper_u_01; + int alarm_temper_u_02; + int alarm_temper_u_03; + int alarm_temper_u_04; + int alarm_temper_u_05; + int alarm_temper_u_06; + int alarm_temper_u_07; + + int abnormal_temper_u_01; + int abnormal_temper_u_02; + int abnormal_temper_u_03; + int abnormal_temper_u_04; + int abnormal_temper_u_05; + int abnormal_temper_u_06; + int abnormal_temper_u_07; + + int alarm_temper_water_int; + int abnormal_temper_water_int; + + int alarm_temper_water_ext; + int abnormal_temper_water_ext; + + int alarm_p_water_max_int; + int abnormal_p_water_max_int; + + int alarm_p_water_min_int; + int abnormal_p_water_min_int; + + int alarm_temper_air_int_01; + int alarm_temper_air_int_02; + int alarm_temper_air_int_03; + int alarm_temper_air_int_04; + + int abnormal_temper_air_int_01; + int abnormal_temper_air_int_02; + int abnormal_temper_air_int_03; + int abnormal_temper_air_int_04; + + int alarm_temper_acdrive_winding_U1; + int alarm_temper_acdrive_winding_V1; + int alarm_temper_acdrive_winding_W1; + int alarm_temper_acdrive_winding_U2; + int alarm_temper_acdrive_winding_V2; + int alarm_temper_acdrive_winding_W2; + + int abnormal_temper_acdrive_winding_U1; + int abnormal_temper_acdrive_winding_V1; + int abnormal_temper_acdrive_winding_W1; + int abnormal_temper_acdrive_winding_U2; + int abnormal_temper_acdrive_winding_V2; + int abnormal_temper_acdrive_winding_W2; + + int alarm_temper_acdrive_bear_DNE; + int alarm_temper_acdrive_bear_NE; + int abnormal_temper_acdrive_bear_DNE; + int abnormal_temper_acdrive_bear_NE; + + int alarm_Uin_max_Up; + int alarm_Uin_max_Down; + int alarm_Uin_min_Up; + int alarm_Uin_min_Down; + + int alarm_Udc_max_Up; + int alarm_Udc_max_Down; + int alarm_Udc_min_Up; + int alarm_Udc_min_Down; + int alarm_Izpt_max; + + int alarm_Imax_U01; + int alarm_Imax_U02; + int alarm_Imax_U03; + int alarm_Imax_U04; + int alarm_Imax_U05; + int alarm_Imax_U06; + int alarm_Imax_U07; + + int alarm_Iged_max; + +} PROTECT_LEVELS; + +#define PROTECT_LEVELS_DEFAULTS {ALARM_TEMPER_AF,ALARM_TEMPER_AF,ALARM_TEMPER_AF,\ + ALARM_TEMPER_AF,ALARM_TEMPER_AF,ALARM_TEMPER_AF,ALARM_TEMPER_AF,\ + ABNORMAL_TEMPER_AF,ABNORMAL_TEMPER_AF,ABNORMAL_TEMPER_AF,ABNORMAL_TEMPER_AF,\ + ABNORMAL_TEMPER_AF,ABNORMAL_TEMPER_AF,ABNORMAL_TEMPER_AF,\ + ALARM_TEMPER_WATER_INT,ABNORMAL_TEMPER_WATER_INT,\ + ALARM_TEMPER_WATER_EXT,ABNORMAL_TEMPER_WATER_EXT,\ + ALARM_P_WATER_MAX_INT,ABNORMAL_P_WATER_MAX_INT,\ + ALARM_P_WATER_MIN_INT,ABNORMAL_P_WATER_MIN_INT,\ + ALARM_TEMPER_AIR_INT,ALARM_TEMPER_AIR_INT,ALARM_TEMPER_AIR_INT,ALARM_TEMPER_AIR_INT,\ + ABNORMAL_TEMPER_AIR_INT,ABNORMAL_TEMPER_AIR_INT,ABNORMAL_TEMPER_AIR_INT,ABNORMAL_TEMPER_AIR_INT,\ + ALARM_TEMPER_ACDRIVE_WINDING,ALARM_TEMPER_ACDRIVE_WINDING,ALARM_TEMPER_ACDRIVE_WINDING,\ + ALARM_TEMPER_ACDRIVE_WINDING,ALARM_TEMPER_ACDRIVE_WINDING,ALARM_TEMPER_ACDRIVE_WINDING,\ + ABNORMAL_TEMPER_ACDRIVE_WINDING,ABNORMAL_TEMPER_ACDRIVE_WINDING,ABNORMAL_TEMPER_ACDRIVE_WINDING,\ + ABNORMAL_TEMPER_ACDRIVE_WINDING,ABNORMAL_TEMPER_ACDRIVE_WINDING,ABNORMAL_TEMPER_ACDRIVE_WINDING,\ + ALARM_TEMPER_ACDRIVE_BEAR,ALARM_TEMPER_ACDRIVE_BEAR,\ + ABNORMAL_TEMPER_ACDRIVE_BEAR,ABNORMAL_TEMPER_ACDRIVE_BEAR,\ + LEVEL_ADC_U_IN_MAX,LEVEL_ADC_U_IN_MAX, LEVEL_ADC_U_IN_MIN,LEVEL_ADC_U_IN_MIN,\ + LEVEL_ADC_U_ZPT_MAX,LEVEL_ADC_U_ZPT_MAX,LEVEL_ADC_U_ZPT_MIN,LEVEL_ADC_U_ZPT_MIN,\ + LEVEL_ADC_I_ZPT,\ + LEVEL_ADC_I_BREAK, LEVEL_ADC_I_AF,LEVEL_ADC_I_AF,LEVEL_ADC_I_AF,LEVEL_ADC_I_AF,LEVEL_ADC_I_AF,LEVEL_ADC_I_AF,\ + LEVEL_ADC_I_OUT_MAX} + +extern PROTECT_LEVELS protect_levels; + +#endif /* SRC_MAIN_PROTECT_LEVELS_H_ */ diff --git a/Inu/Src/main/pump_control.c b/Inu/Src/main/pump_control.c new file mode 100644 index 0000000..212473c --- /dev/null +++ b/Inu/Src/main/pump_control.c @@ -0,0 +1,255 @@ +/* + * pump_management.c + * + * Created on: 28 ���. 2020 �. + * Author: stud + */ + +#include <edrk_main.h> +#include <pump_control.h> + +#include "control_station.h" +#include "digital_filters.h" +#include "sbor_shema.h" + +#pragma DATA_SECTION(pumps, ".slow_vars") +PUMP_CONTROL pumps = PUMP_CONTROL_DEFAULTS; + +void turn_on_nasos_1_2(unsigned int without_time_wait); +int select_pump(void); + +void pump_control(void) +{ + unsigned int pump_off_without_time_wait; + + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 0) + { +// edrk.SelectPump1_2 = 0; + pumps.SelectedPump1_2 = 0; + edrk.ManualStartPump = 0; + // edrk.AutoStartPump = 1; + pump_off_without_time_wait = 0; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 1) + { +// edrk.SelectPump1_2 = 1; + pumps.SelectedPump1_2 = 1; + edrk.ManualStartPump = 0; + // edrk.AutoStartPump = 1; + pump_off_without_time_wait = 0; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 2) + { +// edrk.SelectPump1_2 = 2; + pumps.SelectedPump1_2 = 2; + edrk.ManualStartPump = 0; + // edrk.AutoStartPump = 1; + pump_off_without_time_wait = 0; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 3) + { +// edrk.SelectPump1_2 = 1; + pumps.SelectedPump1_2 = 1; + edrk.ManualStartPump = 1; + edrk.AutoStartPump = 0; + pump_off_without_time_wait = 1; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 4) + { +// edrk.SelectPump1_2 = 2; + pumps.SelectedPump1_2 = 2; + edrk.ManualStartPump = 1; + edrk.AutoStartPump = 0; + pump_off_without_time_wait = 1; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 5) + { +// edrk.SelectPump1_2 = 0; + pumps.SelectedPump1_2 = 0; + edrk.ManualStartPump = 0; + edrk.AutoStartPump = 0; + pump_off_without_time_wait = 1; + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MODE_PUMP] == 6) + { +// edrk.SelectPump1_2 = 1; + pumps.SelectedPump1_2 = 0; + edrk.ManualStartPump = 1; + edrk.AutoStartPump = 0; + pump_off_without_time_wait = 1; + } + + edrk.SumStartPump = edrk.AutoStartPump || edrk.ManualStartPump; + + turn_on_nasos_1_2(pump_off_without_time_wait); + + set_status_pump_fan(); + +} + + +#define TIME_WAIT_PUMP_ON 30 //3 sec +#define TIME_WAIT_ALL_PUMP_OFF 600 //30 sec + +/////////////////////////////////////////////// +void turn_on_nasos_1_2(unsigned int without_time_wait) +{ +static unsigned int time_wait_on_pump1=0; +static unsigned int time_wait_on_pump2=0; + +static unsigned int time_wait_off_all_pump1=0; +static unsigned int time_wait_off_all_pump2=0; + +static unsigned int prev_without_time_wait = 0; + + + +int cmd_p1 = 0, + cmd_p2 = 0, + add_cmd_without_time_wait1 = 0, + add_cmd_without_time_wait2 = 0; + +int fast_stop_pump=0; + + +// if () +//(prev_start_nasos!=edrk.StartPump) && + + + cmd_p1 = 0; + cmd_p2 = 0; + + fast_stop_pump = ( edrk.errors.e5.bits.ERROR_ISOLATE || edrk.errors.e5.bits.FAN || + edrk.errors.e5.bits.PRE_READY_PUMP || edrk.errors.e5.bits.UTE4KA_WATER || edrk.errors.e2.bits.P_WATER_INT_MIN || + edrk.errors.e2.bits.P_WATER_INT_MAX || edrk.errors.e5.bits.PUMP_1 || edrk.errors.e5.bits.PUMP_2); + + if ( edrk.SumStartPump==1 && edrk.errors.e5.bits.PRE_READY_PUMP == 0 && fast_stop_pump==0) + { + if (pumps.SelectedPump1_2 == 0 /*&& edrk.ManualStartPump == 0*/) + { + //����� ������ ������ �� ������������ ������� + switch (select_pump()) { + case 1: + cmd_p1 = 1; + cmd_p2 = 0; + break; + case 2: + cmd_p1 = 0; + cmd_p2 = 1; + break; + default: + cmd_p1 = 0; + cmd_p2 = 0; + } + pumps.lock_pump = 1; + } else + if (pumps.SelectedPump1_2==1 && edrk.errors.e5.bits.PUMP_1==0) + cmd_p1 = 1; + else if (pumps.SelectedPump1_2==2 && edrk.errors.e5.bits.PUMP_2==0) + cmd_p2 = 1; + } + else + { + cmd_p1 = 0; + cmd_p2 = 0; + } + + + if (cmd_p1) + { + edrk.SelectPump1_2 = 1; + if (pause_detect_error(&time_wait_on_pump1,TIME_WAIT_PUMP_ON,1)) + { + edrk.to_ing.bits.NASOS_1_ON = 1; + time_wait_off_all_pump1 = 0; + } + } + else + { + time_wait_on_pump1 = 0; + + if (without_time_wait==0 && prev_without_time_wait != without_time_wait) + add_cmd_without_time_wait1 = 1; + + if (cmd_p1!=cmd_p2 || fast_stop_pump || without_time_wait || add_cmd_without_time_wait1) { + edrk.to_ing.bits.NASOS_1_ON = 0; + } + else + { + if (pause_detect_error(&time_wait_off_all_pump1,TIME_WAIT_ALL_PUMP_OFF,1)) { + edrk.to_ing.bits.NASOS_1_ON = 0; + } + } + + } + + + if (cmd_p2) + { + edrk.SelectPump1_2 = 2; + if (pause_detect_error(&time_wait_on_pump2,TIME_WAIT_PUMP_ON,1)) + { + edrk.to_ing.bits.NASOS_2_ON = 1; + time_wait_off_all_pump2 = 0; + } + } + else + { + time_wait_on_pump2 = 0; + + if (without_time_wait==0 && prev_without_time_wait != without_time_wait) + add_cmd_without_time_wait2 = 1; + + if (cmd_p1!=cmd_p2 || fast_stop_pump || without_time_wait || add_cmd_without_time_wait2) { + edrk.to_ing.bits.NASOS_2_ON = 0; + } + else + { + if (pause_detect_error(&time_wait_off_all_pump2,TIME_WAIT_ALL_PUMP_OFF,1)) { + edrk.to_ing.bits.NASOS_2_ON = 0; + } + } + } + + if (edrk.to_ing.bits.NASOS_1_ON == 0 && edrk.to_ing.bits.NASOS_2_ON == 0) { + pumps.lock_pump = 0; + } + + prev_without_time_wait = without_time_wait; + +} + +int select_pump() { + int p_n = 0; + if (pumps.lock_pump == 0) { + + p_n = calc_auto_moto_pump(); + if (p_n == 0) + p_n = 1; +// if (pumps.pump1_engine_minutes > pumps.pump2_engine_minutes) { +// p_n = 2; +// } else { +// p_n = 1; +// } + + } else { + p_n = edrk.SelectPump1_2; + } + if ((edrk.errors.e5.bits.PUMP_1 == 1) && (edrk.errors.e5.bits.PUMP_2 == 1)) { + p_n = 0; + } + if (p_n == 1 && edrk.warnings.e5.bits.PUMP_1 == 1) { + p_n = 2; + } + if (p_n == 2 && edrk.warnings.e5.bits.PUMP_2 == 1) { + p_n = 1; + } + return p_n; +} diff --git a/Inu/Src/main/pump_control.h b/Inu/Src/main/pump_control.h new file mode 100644 index 0000000..92a5931 --- /dev/null +++ b/Inu/Src/main/pump_control.h @@ -0,0 +1,27 @@ +/* + * pump_management.h + * + * Created on: 28 ���. 2020 �. + * Author: stud + */ + +#ifndef SRC_MAIN_PUMP_CONTROL_H_ +#define SRC_MAIN_PUMP_CONTROL_H_ + +typedef struct { + int pump1_engine_minutes; + int pump2_engine_minutes; + int time_switch_minuts; + int SelectedPump1_2; + int lock_pump; +} PUMP_CONTROL; + +#define PUMP_CONTROL_DEFAULTS {0,0,5,0,0} + +extern PUMP_CONTROL pumps; + +void pump_control(void); + + + +#endif /* SRC_MAIN_PUMP_CONTROL_H_ */ diff --git a/Inu/Src/main/pwm_logs.c b/Inu/Src/main/pwm_logs.c new file mode 100644 index 0000000..42ca3e7 --- /dev/null +++ b/Inu/Src/main/pwm_logs.c @@ -0,0 +1,476 @@ +/* + * pwm_logs.c + * + * Created on: 19 ���. 2024 �. + * Author: user + */ +#include <adc_tools.h> +#include <alg_simple_scalar.h> +#include <alg_uf_const.h> +#include <break_regul.h> +#include <edrk_main.h> +#include <optical_bus.h> +#include <params.h> +#include <params_norma.h> +#include <params_pwm24.h> +#include <project.h> +#include <v_pwm24_v2.h> +#include <v_rotor.h> +#include <vector.h> +#include "global_time.h" +#include "IQmathLib.h" +#include "oscil_can.h" +#include "uf_alg_ing.h" +#include "MemoryFunctions.h" +#include "RS_Functions.h" +#include "v_rotor_22220.h" +#include "log_to_memory.h" +#include "log_params.h" +#include "logs_hmi.h" +#include "vector_control.h" + + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +#pragma CODE_SECTION(prepare_data_to_logs,".fast_run"); +unsigned int prepare_data_to_logs(void) +{ + logsdata.logs[0] = (int16) global_time.total_seconds10full;// = 0;//(int16)(_IQtoIQ15(Izad)); + logsdata.logs[1] = (int16) _IQtoIQ15(analog.iqIu_1); + logsdata.logs[2] = (int16) _IQtoIQ15(analog.iqIv_1); + logsdata.logs[3] = (int16) _IQtoIQ15(analog.iqIw_1); + + logsdata.logs[4] = (int16) _IQtoIQ15(analog.iqIu_2); + logsdata.logs[5] = (int16) _IQtoIQ15(analog.iqIv_2); + logsdata.logs[6] = (int16) _IQtoIQ15(analog.iqIw_2); + + logsdata.logs[7] = (int16) _IQtoIQ15(analog.iqUin_A1B1);// (int16) _IQtoIQ15(analog.iqUin_m1); + logsdata.logs[8] = (int16) _IQtoIQ15(analog.iqUin_A2B2);// (int16) _IQtoIQ15(analog.iqUin_m2); + + + logsdata.logs[9] = (int16) _IQtoIQ15(analog.iqU_1); + logsdata.logs[10] = (int16) _IQtoIQ15(analog.iqU_2);//11 + + logsdata.logs[11] = (int16) _IQtoIQ15(analog.iqIin_1); + logsdata.logs[12] = (int16) _IQtoIQ15(analog.iqIin_2); + + logsdata.logs[13] = (int16) _IQtoIQ15(analog.iqIm_1); + logsdata.logs[14] = (int16) _IQtoIQ15(analog.iqIm_2); + + logsdata.logs[15] = (int16) _IQtoIQ15(analog.iqIbreak_1);//(int16) _IQtoIQ15(filter.iqU_1_long); + logsdata.logs[16] = (int16) _IQtoIQ15(analog.iqIbreak_2);//(int16) _IQtoIQ15(filter.iqU_2_long); + + + logsdata.logs[17] = (int16)svgen_pwm24_1.Ta_0; + logsdata.logs[18] = (int16)svgen_pwm24_1.Ta_1; + logsdata.logs[19] = (int16)break_result_1; + logsdata.logs[20] = (int16)break_result_2; +// logpar.log21 = (int16)svgen_pwm24_1.Tb_1; +// logpar.log22 = (int16)svgen_pwm24_1.Tc_0; +// logpar.log23 = (int16)svgen_pwm24_1.Tc_1; //23 + + logsdata.logs[21] = (int16)(_IQtoIQ14(edrk.iq_power_kw_full_znak));// edrk.from_uom.iq_level_value_kwt + //(int16) _IQtoIQ15(rotor_22220.iqFdirty); + // + + logsdata.logs[22] = (int16) _IQtoIQ15(WRotor.iqWRotorSumFilter2); + logsdata.logs[23] = (int16) _IQtoIQ15(WRotor.iqWRotorSumFilter);//WRotor.iqWRotorSumFilter WRotor.iqWRotorSum + logsdata.logs[24] = (int16) _IQtoIQ15(simple_scalar1.iq_decr_mzz_power);//WRotor.iqWRotorSumFilter2 WRotor.iqWRotorSumFilter3 + + logsdata.logs[25] = (int16) edrk.from_uom.level_value;// (int16) _IQtoIQ15(WRotor.iqWRotorSumFilter); +// logpar.log25 = (int16) _IQtoIQ15(WRotor.iqWRotorSumFilter); +// logsdata.logs[25] = (int16) _IQtoIQ15(WRotor.iqWRotorSum); + + logsdata.logs[26] = (int16) edrk.power_limit.all;//_IQtoIQ15(pll1.vars.pll_Uq); + logsdata.logs[27] = (int16)(_IQtoIQ14(edrk.zadanie.iq_limit_power_zad));//(int16) _IQtoIQ15(pll1.vars.pll_Ud);//28 + + logsdata.logs[28] = (int16) _IQtoIQ12(edrk.master_theta);//29 + logsdata.logs[29] = (int16) _IQtoIQ15(edrk.master_Uzad);//30 + logsdata.logs[30] = (int16) _IQtoIQ14(edrk.f_stator); + logsdata.logs[31] = (int16) _IQtoIQ12(edrk.k_stator1); + + logsdata.logs[32] = optical_read_data.data.cmd.all; + logsdata.logs[33] = optical_read_data.data.pzad_or_wzad; + logsdata.logs[34] = optical_read_data.data.angle_pwm; + logsdata.logs[35] = optical_read_data.data.iq_zad_i_zad; + + logsdata.logs[36] = optical_write_data.data.cmd.all; + logsdata.logs[37] = optical_write_data.data.angle_pwm; + logsdata.logs[38] = optical_write_data.data.pzad_or_wzad; + logsdata.logs[39] = optical_write_data.data.iq_zad_i_zad; + + ///////////// + logsdata.logs[40] = (int16)(_IQtoIQ15(simple_scalar1.Izad)); + logsdata.logs[41] = (int16)(_IQtoIQ15(simple_scalar1.mzz_zad_in2));//(int16)(_IQtoIQ15(Uze_t1)); + logsdata.logs[42] = (int16)(_IQtoIQ15(simple_scalar1.pidF.OutMax)); + logsdata.logs[43] = (int16)(_IQtoIQ15(simple_scalar1.mzz_zad_int)); + logsdata.logs[44] = (int16)(_IQtoIQ15(simple_scalar1.Izad_from_master)); + + logsdata.logs[45] = (int16)(_IQtoIQ14(simple_scalar1.pidF.Fdb)); + logsdata.logs[46] = (int16)(_IQtoIQ14(simple_scalar1.pidF.Ref)); + logsdata.logs[47] = (int16)(_IQtoIQ14(simple_scalar1.pidF.Ui)); + logsdata.logs[48] = (int16)(_IQtoIQ14(simple_scalar1.pidF.Up)); + logsdata.logs[49] = (int16)(_IQtoIQ14(simple_scalar1.pidF.SatErr)); + logsdata.logs[50] = (int16)(_IQtoIQ14(simple_scalar1.pidF.Out)); + + logsdata.logs[51] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.Fdb)); + logsdata.logs[52] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.Ref)); + logsdata.logs[53] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.Ui)); + logsdata.logs[54] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.Up)); + logsdata.logs[55] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.SatErr)); + logsdata.logs[56] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.Out)); + + logsdata.logs[57] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.Fdb)); + logsdata.logs[58] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.Ref)); + logsdata.logs[59] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.Ui)); + logsdata.logs[60] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.Up)); + logsdata.logs[61] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.SatErr)); + logsdata.logs[62] = (int16)(_IQtoIQ15(simple_scalar1.pidIm1.Out)); + logsdata.logs[63] = (int16)(_IQtoIQ12(simple_scalar1.Uze_t1)); + + logsdata.logs[64] = (int16)(_IQtoIQ15(simple_scalar1.bpsi_curent)); + + logsdata.logs[65] = (int16)(_IQtoIQ14(simple_scalar1.iqKoefOgran)); + + logsdata.logs[66] = (int16)(_IQtoIQ14(simple_scalar1.Fz)); + logsdata.logs[67] = (int16) (_IQtoIQ15(simple_scalar1.iq_decr_mzz_power_filter));//rotor_22220.direct_rotor + + logsdata.logs[68] = (int16)(_IQtoIQ14(simple_scalar1.pidF.OutMin));//(int16)edrk.Status_Sbor; + logsdata.logs[69] = (int16)(_IQtoIQ14(simple_scalar1.pidPower.OutMax));//(int16)edrk.Stage_Sbor; + logsdata.logs[70] = (int16)(_IQtoIQ14(filter.iqUin_m1));//(int16)edrk.Sbor_Mode; + + logsdata.logs[71] = (int16)edrk.from_shema.all; + logsdata.logs[72] = (int16)(_IQtoIQ15(simple_scalar1.iqKoefOgranIzad));//(int16)edrk.from_shema_filter.all; +// + logsdata.logs[73] = (int16)(_IQtoIQ14(filter.iqUin_m2));//simple_scalar1.direction; + logsdata.logs[74] = (int16)(_IQtoIQ14(edrk.iq_power_kw_full_filter_znak));// + logsdata.logs[75] = (int16)(_IQtoIQ15(edrk.iq_freq_50hz));//edrk.iq_freq_50hz + logsdata.logs[76] = (int16)(_IQtoIQ15(simple_scalar1.mzz_zad_in1)); + + + + // can regs +// logsdata.logs[77] = (int16)(((unsigned long)edrk.canes_reg >> 16) & 0x1ff); +// logsdata.logs[78] = (int16)((unsigned long)edrk.canes_reg & 0x3f); +// +// logsdata.logs[79] = (int16)(edrk.cantec_reg & 0xff); +// logsdata.logs[80] = (int16)(edrk.canrec_reg & 0xff); + + logsdata.logs[77] = (int16)(_IQtoIQ14(uf_alg.Ud)); + logsdata.logs[78] = (int16)(_IQtoIQ14(uf_alg.Uq)); + logsdata.logs[79] = (int16)(_IQtoIQ14(edrk.all_limit_koeffs.uom_limit));//edrk.MasterSlave; + + logsdata.logs[80] = (int16)(_IQtoIQ14(edrk.Kplus)); + +// logsdata.logs[65] = (int16)(_IQtoIQ14(edrk.all_limit_koeffs.temper_limit)); + logsdata.logs[81] = (int16)(_IQtoIQ14(edrk.all_limit_koeffs.uin_freq_limit)); + + logsdata.logs[82] = (int16)(_IQtoIQ14(uf_alg.svgen_dq_Ta)); + logsdata.logs[83] = (int16)(_IQtoIQ14(uf_alg.svgen_dq_Tb)); + logsdata.logs[84] = (int16)(_IQtoIQ14(uf_alg.svgen_dq_Tc)); + + // uf_alg.tetta_bs + + // logsdata.logs[64] = (int16)(_IQtoIQ15()); + +// logsdata.logs[64] = (int16)(_IQtoIQ15()); + + logsdata.logs[85] = edrk.from_uom.digital_line.all; +// logsdata.logs[75] = edrk.errors.e2.all; +// logsdata.logs[76] = edrk.errors.e3.all; +// logsdata.logs[77] = edrk.errors.e4.all; +// logsdata.logs[78] = edrk.errors.e5.all; +// logsdata.logs[79] = edrk.errors.e6.all; +// logsdata.logs[80] = edrk.errors.e7.all; +// + + + + +// logsdata.logs[67] = (int16) _IQtoIQ15(WRotor.iqWRotorCalcBeforeRegul1); +// logsdata.logs[68] = (int16) _IQtoIQ15(WRotor.iqWRotorCalcBeforeRegul2); +// logsdata.logs[69] = (int16) _IQtoIQ15(WRotor.iqWRotorCalc1); + +// logsdata.logs[24] = (int16) _IQtoIQ15(WRotor.iqWRotorCalc2); + +// logsdata.logs[70] = (int16) _IQtoIQ15(WRotor.iqWRotorSumRamp); + +// logsdata.logs[72] = (int16) (WRotorPBus.RotorDirectionSlow); + // logsdata.logs[73] = (int16) (WRotorPBus.RotorDirectionSlow2); + // logsdata.logs[74] = (int16) (WRotorPBus.RotorDirectionInstant); //(int16) (WRotorPBus.); + +// logsdata.logs[75] = (int16) (WRotor.iqTimeSensor1); +// logsdata.logs[76] = (int16) (WRotor.iqTimeSensor2); +// +// logsdata.logs[77] = (int16) _IQtoIQ15(WRotor.iqWRotorCalc1Ramp); +// logsdata.logs[78] = (int16) _IQtoIQ15(WRotor.iqWRotorCalc2Ramp); +// +// logsdata.logs[79] = (int16) _IQtoIQ15(WRotor.iqPrevWRotorCalc1); +// logsdata.logs[80] = (int16) _IQtoIQ15(WRotor.iqPrevWRotorCalc2); + +// logsdata.logs[81] = (int16) modbus_table_can_in[124].all;//������� (��������); +// logsdata.logs[82] = (int16) modbus_table_can_in[134].all;//����� �������� +// logsdata.logs[83] = (int16) modbus_table_can_in[125].all;//�������� (��������) +// +// logsdata.logs[84] = (int16) project.cds_in[0].read.pbus.data_in.all; +// logsdata.logs[85] = (int16) project.cds_in[1].read.pbus.data_in.all; + + logsdata.logs[86] = (int16) _IQtoIQ15(vect_control.iqId1); + logsdata.logs[87] = (int16) _IQtoIQ15(vect_control.iqIq1); + + logsdata.logs[88] = (int16) _IQtoIQ15(vect_control.iqId2); + logsdata.logs[89] = (int16) _IQtoIQ15(vect_control.iqIq2); + logsdata.logs[90] = 0; + + return 90; +} + + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +#define PAUSE_SLOW_LOG 20 + +void save_slow_logs(int run, int t_slow) +{ + static int c_step=0; +// static int c_all = (FREQ_PWM>>2); // ��� � 0,125 � + static int c_all = (FREQ_PWM>>1); // ��� � 0,250 � + + static int prev_run=0; + static unsigned int c_pause=0; + + if (rs_a.RS_PrevCmd==CMD_RS232_UPLOAD) + return; + + if (run==0 && c_pause>=PAUSE_SLOW_LOG) + return; + + c_all = (FREQ_PWM>>(1+t_slow)); + + if (c_all<2) + c_all = 2; + + + if (c_step>=c_all) + { + test_mem_limit(SLOW_LOG, 1); + + // prepare_data_to_logs(); + + getSlowLogs(1); + c_step = 0; + + if (run==1) + c_pause = 0; + else + { + if (c_pause<PAUSE_SLOW_LOG) + c_pause++; + } + } + else + c_step++; + + + prev_run = run; +} + + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// +#pragma CODE_SECTION(run_write_logs,".fast_run"); +void run_write_logs(void) +{ + static unsigned int count_step_run = 0; + static int count_step=0, prevGo=0; + static int log_saved_to_const_mem = 1; + int i_log, local_enable_slow_log; + + + prepare_data_to_logs(); + + if(edrk.Go == 1) + { + if (edrk.Go != prevGo) + { + // clear_mem(FAST_LOG); + // count_start_impuls = 0; + count_step = 0; +// count_step_ram_off = COUNT_SAVE_LOG_OFF; + count_step_run = 0; + } + } + + prevGo = edrk.Go; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_23_ON; +#endif + +/* + +// if (oscil_can.enable_rewrite && oscil_can.global_enable) + + if (oscil_can.enable_rewrite) + { + + if (edrk.Go) + oscil_can.status_pwm = 1; + else + oscil_can.status_pwm = 0; + + + if ( (edrk.Stop == 0) && (project.controller.read.errors.all==0) ) + oscil_can.status_error = 0; + else + oscil_can.status_error = 1; + + oscil_can.oscil_buffer[0][oscil_can.current_position] = global_time.pwm_tics; +// if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) { + oscil_can.oscil_buffer[1][oscil_can.current_position] = (int16) _IQtoIQ15(filter.iqU_1_long);//xpwm_time.Ta0_0; //(int16) _IQtoIQ15(turns.pidFvect.Ui); + oscil_can.oscil_buffer[2][oscil_can.current_position] = (int16) _IQtoIQ15(filter.iqU_2_long);//xpwm_time.Ta0_1; //(int16) _IQtoIQ15(turns.pidFvect.Up); + oscil_can.oscil_buffer[3][oscil_can.current_position] = (int16) _IQtoIQ15(turns.pidFvect.Out); + oscil_can.oscil_buffer[4][oscil_can.current_position] = (int16) _IQtoIQ15(turns.pidFvect.OutMax); + oscil_can.oscil_buffer[5][oscil_can.current_position] = (int16) _IQtoIQ15(power.pidP.Out); + oscil_can.oscil_buffer[6][oscil_can.current_position] = (int16) _IQtoIQ15(power.pidP.OutMax); +// } else { +// oscil_can.oscil_buffer[1][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidF.Ui); // count_updated_sbus;//xpwm_time.Ta0_0; +// oscil_can.oscil_buffer[2][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidF.Up); +// oscil_can.oscil_buffer[3][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidF.Out);//xpwm_time.Tb0_0; +// oscil_can.oscil_buffer[4][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidF.OutMax);//xpwm_time.Tb0_1; +// oscil_can.oscil_buffer[5][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidPower.Out);//xpwm_time.Tc0_0; +// oscil_can.oscil_buffer[6][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidPower.OutMax); //xpwm_time.Tc0_1; +// } + + + oscil_can.oscil_buffer[7][oscil_can.current_position] = (int16) _IQtoIQ15(edrk.master_Uzad) ; + oscil_can.oscil_buffer[8][oscil_can.current_position] = (int16) _IQtoIQ12(edrk.master_theta);//global_time.microseconds; + + oscil_can.oscil_buffer[9][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIu_1); + oscil_can.oscil_buffer[10][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIv_1); + oscil_can.oscil_buffer[11][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIw_1); + + oscil_can.oscil_buffer[12][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIu_2); + oscil_can.oscil_buffer[13][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIv_2); + oscil_can.oscil_buffer[14][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIw_2); + + oscil_can.oscil_buffer[15][oscil_can.current_position] = (int16) _IQtoIQ15(turns.Fzad_rmp); //(int16) _IQtoIQ15(analog.iqU_1); + oscil_can.oscil_buffer[16][oscil_can.current_position] = (int16) _IQtoIQ15(WRotor.iqWRotorCalcBeforeRegul1);//(int16) _IQtoIQ15(analog.iqU_2); + +// oscil_can.oscil_buffer[17][oscil_can.current_position] = 0; + + oscil_can.oscil_buffer[18][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqIin_2); + oscil_can.oscil_buffer[19][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqUdCompensation); + oscil_can.oscil_buffer[20][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqUqCompensation); + + oscil_can.oscil_buffer[21][oscil_can.current_position] = (int16) _IQtoIQ15(edrk.f_stator); + oscil_can.oscil_buffer[22][oscil_can.current_position] = (int16) _IQtoIQ12(edrk.k_stator1); + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER) { + oscil_can.oscil_buffer[17][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqPvsi1 + vect_control.iqPvsi2); + oscil_can.oscil_buffer[23][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqId1);//(int16) _IQtoIQ15(WRotorPBus.iqAngle1F); + oscil_can.oscil_buffer[24][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqIq1);//(int16) _IQtoIQ15(WRotorPBus.iqAngle2F); + oscil_can.oscil_buffer[25][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.iqFsl); + oscil_can.oscil_buffer[26][oscil_can.current_position] = (int16) _IQtoIQ15(turns.mzz_zad_int); + oscil_can.oscil_buffer[27][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.pidD1.Out);//(int16) _IQtoIQ15(WRotorPBus.iqWRotorCalcBeforeRegul1); + oscil_can.oscil_buffer[28][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.pidQ1.Out); + oscil_can.oscil_buffer[29][oscil_can.current_position] = (int16) _IQtoIQ15(vect_control.pidD1.Ref); + } else { + oscil_can.oscil_buffer[17][oscil_can.current_position] = (int16) _IQtoIQ15(analog.PowerScalar); + oscil_can.oscil_buffer[23][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidIm1.Ui); // count_updated_sbus;//xpwm_time.Ta0_0; + oscil_can.oscil_buffer[24][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidIm1.Up); + oscil_can.oscil_buffer[25][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.pidIm1.Out); + oscil_can.oscil_buffer[26][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.mzz_zad_int);//(int16) _IQtoIQ15(WRotor.iqWRotorCalcBeforeRegul1); + oscil_can.oscil_buffer[27][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.Im_regul);//(int16) _IQtoIQ15(WRotorPBus.iqWRotorCalcBeforeRegul1); + oscil_can.oscil_buffer[28][oscil_can.current_position] = (int16) _IQtoIQ15(edrk.Kplus); + oscil_can.oscil_buffer[29][oscil_can.current_position] = (int16) _IQtoIQ15(filter.iqIm); + } + + +// oscil_can.oscil_buffer[23][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.Izad);//(int16) _IQtoIQ15(WRotorPBus.iqAngle1F); +// oscil_can.oscil_buffer[24][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.Izad_from_master);//(int16) _IQtoIQ15(WRotorPBus.iqAngle2F); +// oscil_can.oscil_buffer[25][oscil_can.current_position] = (int16) _IQtoIQ15(simple_scalar1.mzz_zad);//(int16) _IQtoIQ15(WRotor.iqWRotorImpulses1); + + + + oscil_can.oscil_buffer[30][oscil_can.current_position] = (int16) _IQtoIQ12(edrk.master_theta);//_IQtoIQ15(edrk.Uzad_to_slave); + oscil_can.oscil_buffer[31][oscil_can.current_position] = (int16) _IQtoIQ12(edrk.tetta_to_slave); + + +// oscil_can.oscil_buffer[26][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_m1); +// oscil_can.oscil_buffer[27][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_m2); +// +// oscil_can.oscil_buffer[28][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_A1B1); +// oscil_can.oscil_buffer[29][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_B1C1); +// oscil_can.oscil_buffer[30][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_A2B2); +// oscil_can.oscil_buffer[31][oscil_can.current_position] = (int16) _IQtoIQ15(analog.iqUin_B2C2); + + + oscil_can.set_next_position(&oscil_can); + } +*/ + + + // if ((m.m2.bit.LatchCrashError == 0) && (edrk.stop_logs_rs232 == 0))// && (edrk.Go == 1)) + if ( (edrk.stop_logs_rs232 == 0) && f.flag_record_log)// && (edrk.Go == 1)) + { + test_mem_limit(FAST_LOG, !f.Ciclelog); + + count_step++; + + if (count_step >= 1)//1 + { + count_step_run++; + // i_led1_on_off(1); +// write_to_mem(FAST_LOG, (int16)count_step_run); + + getFastLogs(!f.Ciclelog); +// for (i_log=0;i_log<72;i_log++) +// write_to_mem(FAST_LOG, (int16) logsdata.logs[i_log]); + +// write_to_mem(FAST_LOG, (int16) logpar.log85); + + + +// if (logpar.start_write_fast_log) { +// get_log_params_count(); +// logpar.start_write_fast_log = 0; +// } + count_step = 0; + } + } + else { + if (f.Stop && log_params.log_saved_to_const_mem == 0) { + log_params.copy_log_to_const_memory = 1; + log_params.log_saved_to_const_mem = 1; + f.flag_send_alarm_log_to_MPU = 1; + } + } + + +#if(_ENABLE_PWM_LINES_FOR_TESTS_PWM) + PWM_LINES_TK_23_OFF; +#endif + + if (filter.iqU_1_long>edrk.iqMIN_U_ZPT || filter.iqU_2_long>edrk.iqMIN_U_ZPT) + local_enable_slow_log = 1; + else + local_enable_slow_log = 0; + + if (edrk.stop_logs_rs232 == 0 && edrk.stop_slow_log ==0 && log_to_HMI.send_log == 0) + save_slow_logs(edrk.Go || (local_enable_slow_log && edrk.Status_Ready.bits.ready_final==0), edrk.t_slow_log); +} +////////////////////////////////////////////////////////////////// + + + + diff --git a/Inu/Src/main/pwm_logs.h b/Inu/Src/main/pwm_logs.h new file mode 100644 index 0000000..8eb5f07 --- /dev/null +++ b/Inu/Src/main/pwm_logs.h @@ -0,0 +1,16 @@ +/* + * pwm_logs.h + * + * Created on: 19 ���. 2024 �. + * Author: user + */ + +#ifndef SRC_MAIN_PWM_LOGS_H_ +#define SRC_MAIN_PWM_LOGS_H_ + +unsigned int prepare_data_to_logs(void); +void save_slow_logs(int run, int t_slow); +void run_write_logs(void); + + +#endif /* SRC_MAIN_PWM_LOGS_H_ */ diff --git a/Inu/Src/main/pwm_test_lines.c b/Inu/Src/main/pwm_test_lines.c new file mode 100644 index 0000000..ef24f64 --- /dev/null +++ b/Inu/Src/main/pwm_test_lines.c @@ -0,0 +1,36 @@ + +#include <281xEvTimersInit.h> +#include <project_setup.h> +#include <PWMTMSHandle.h> + +#include "DSP281x_Device.h" +#include "MemoryFunctions.h" +#include "Spartan2E_Adr.h" +#include "x_wdog.h" + +#include <edrk_main.h> + +unsigned int cmd_pwm_test_lines = 0xffff; + +void pwm_test_lines_start(void) +{ + cmd_pwm_test_lines = 0xffff; + +// i_WriteMemory(ADR_TK_MASK_1, 0); + i_WriteMemory(ADR_PWM_DIRECT2,0xffff); +// i_WriteMemory(ADR_PWM_DRIVE_MODE, 3); // on direct tk lines +// i_WriteMemory(ADR_PWM_DIRECT2,0xffff); + + i_WriteMemory(ADR_TK_MASK_1, 0x0); //Turn on additional 16 tk lines +} + +void pwm_test_lines_stop(void) +{ + cmd_pwm_test_lines = 0xffff; + + i_WriteMemory(ADR_TK_MASK_1, 0xffff); //Turn off additional 16 tk lines + i_WriteMemory(ADR_PWM_DIRECT2,0xffff); + +// i_WriteMemory(ADR_PWM_DRIVE_MODE, 0); // off direct tk lines +} + diff --git a/Inu/Src/main/pwm_test_lines.h b/Inu/Src/main/pwm_test_lines.h new file mode 100644 index 0000000..d411550 --- /dev/null +++ b/Inu/Src/main/pwm_test_lines.h @@ -0,0 +1,63 @@ + + + + + + +extern unsigned int cmd_pwm_test_lines; + +#define PWM_LINES_TK_16_OFF {cmd_pwm_test_lines &= 0xfffe; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_16_ON {cmd_pwm_test_lines |= 0x0001; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_17_OFF {cmd_pwm_test_lines &= 0xfffd; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_17_ON {cmd_pwm_test_lines |= 0x0002; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_18_OFF {cmd_pwm_test_lines &= 0xfffb; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_18_ON {cmd_pwm_test_lines |= 0x0004; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_19_OFF {cmd_pwm_test_lines &= 0xfff7; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_19_ON {cmd_pwm_test_lines |= 0x0008; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//// +#define PWM_LINES_TK_20_OFF {cmd_pwm_test_lines &= 0xffef; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_20_ON {cmd_pwm_test_lines |= 0x0010; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_21_OFF {cmd_pwm_test_lines &= 0xffdf; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_21_ON {cmd_pwm_test_lines |= 0x0020; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_22_OFF {cmd_pwm_test_lines &= 0xffbf; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_22_ON {cmd_pwm_test_lines |= 0x0040; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} + +#define PWM_LINES_TK_23_OFF {cmd_pwm_test_lines &= 0xff7f; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +#define PWM_LINES_TK_23_ON {cmd_pwm_test_lines |= 0x0080; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +////// +//#define PWM_LINES_TK_24_ON {cmd_pwm_test_lines &= 0xfeff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_24_OFF {cmd_pwm_test_lines |= 0x0100; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_25_ON {cmd_pwm_test_lines &= 0xfdff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_25_OFF {cmd_pwm_test_lines |= 0x0200; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_26_ON {cmd_pwm_test_lines &= 0xfbff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_26_OFF {cmd_pwm_test_lines |= 0x0400; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_27_ON {cmd_pwm_test_lines &= 0xf7ff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_27_OFF {cmd_pwm_test_lines |= 0x0800; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +////// +//#define PWM_LINES_TK_28_ON {cmd_pwm_test_lines &= 0xefff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_28_OFF {cmd_pwm_test_lines |= 0x1000; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_29_ON {cmd_pwm_test_lines &= 0xdfff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_29_OFF {cmd_pwm_test_lines |= 0x2000; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_30_ON {cmd_pwm_test_lines &= 0xbfff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_30_OFF {cmd_pwm_test_lines |= 0x4000; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +// +//#define PWM_LINES_TK_31_ON {cmd_pwm_test_lines &= 0x7fff; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//#define PWM_LINES_TK_31_OFF {cmd_pwm_test_lines |= 0x8000; i_WriteMemory(ADR_PWM_DIRECT2, cmd_pwm_test_lines);} +//// + + + + +///////////////////////////////////////// +void pwm_test_lines_start(void); +void pwm_test_lines_stop(void); diff --git a/Inu/Src/main/ramp_zadanie_tools.c b/Inu/Src/main/ramp_zadanie_tools.c new file mode 100644 index 0000000..61a6689 --- /dev/null +++ b/Inu/Src/main/ramp_zadanie_tools.c @@ -0,0 +1,417 @@ +/* + * ramp_zadanie_tools.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 "ramp_zadanie_tools.h" +#include "v_rotor.h" + + + +void change_ramp_zadanie(void) +{ + _iq rampafloat, rampafloat_plus, rampafloat_minus; + + if (edrk.cmd_very_slow_start) + { + rampafloat_plus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS)); + edrk.zadanie.rmp_oborots_zad_hz.PosRampPlus1 = rampafloat_plus; + edrk.zadanie.rmp_oborots_zad_hz.PosRampMinus1 = -rampafloat_minus; + + edrk.zadanie.rmp_oborots_zad_hz.NegRampPlus1 = rampafloat_minus; + edrk.zadanie.rmp_oborots_zad_hz.NegRampMinus1 = -rampafloat_plus; + +// rampafloat_plus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS)); +// rampafloat_minus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_SLOW_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS)); + edrk.zadanie.rmp_oborots_zad_hz.PosRampPlus2 = rampafloat_plus; + edrk.zadanie.rmp_oborots_zad_hz.PosRampMinus2 = -rampafloat_minus; + + edrk.zadanie.rmp_oborots_zad_hz.NegRampPlus2 = rampafloat_minus; + edrk.zadanie.rmp_oborots_zad_hz.NegRampMinus2 = -rampafloat_plus; + } + else + { + rampafloat_plus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS)); + edrk.zadanie.rmp_oborots_zad_hz.PosRampPlus1 = rampafloat_plus; + edrk.zadanie.rmp_oborots_zad_hz.PosRampMinus1 = -rampafloat_minus; + + edrk.zadanie.rmp_oborots_zad_hz.NegRampPlus1 = rampafloat_minus; + edrk.zadanie.rmp_oborots_zad_hz.NegRampMinus1 = -rampafloat_plus; + + rampafloat_plus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_OBOROTS_ROTOR_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_OBOROTS_ROTOR_MINUS)); + edrk.zadanie.rmp_oborots_zad_hz.PosRampPlus2 = rampafloat_plus; + edrk.zadanie.rmp_oborots_zad_hz.PosRampMinus2 = -rampafloat_minus; + + edrk.zadanie.rmp_oborots_zad_hz.NegRampPlus2 = rampafloat_minus; + edrk.zadanie.rmp_oborots_zad_hz.NegRampMinus2 = -rampafloat_plus; + + } + +} + +void init_ramp_all_zadanie(void) +{ + _iq rampafloat, rampafloat_plus, rampafloat_minus; + +//rmp_oborots_imitation + edrk.zadanie.rmp_oborots_imitation.RampLowLimit = _IQ(MIN_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); + edrk.zadanie.rmp_oborots_imitation.RampHighLimit = _IQ(MAX_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); + rampafloat = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_IMITATION_OBOROTS_ROTOR)); + edrk.zadanie.rmp_oborots_imitation.RampPlus = rampafloat; + edrk.zadanie.rmp_oborots_imitation.RampMinus = -rampafloat; + + edrk.zadanie.rmp_oborots_imitation.Out = 0; + edrk.zadanie.rmp_oborots_imitation.DesiredInput = 0; + +// rmp_fzad + edrk.zadanie.rmp_fzad.RampLowLimit = _IQ(-MAX_ZADANIE_F/NORMA_FROTOR); //0 + edrk.zadanie.rmp_fzad.RampHighLimit = _IQ(MAX_ZADANIE_F/NORMA_FROTOR); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_F)); + rampafloat = _IQ((MAX_ZADANIE_F/NORMA_FROTOR)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_F)); + edrk.zadanie.rmp_fzad.RampPlus = rampafloat; + edrk.zadanie.rmp_fzad.RampMinus = -rampafloat; + + edrk.zadanie.rmp_fzad.DesiredInput = 0; + edrk.zadanie.rmp_fzad.Out = 0; + +// rmp_oborots_hz + edrk.zadanie.rmp_oborots_zad_hz.RampLowLimit = _IQ(MIN_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); //0 + edrk.zadanie.rmp_oborots_zad_hz.RampHighLimit = _IQ(MAX_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); + + edrk.zadanie.rmp_oborots_zad_hz.RampLowLimit1 = _IQ(MIN_1_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); //0 + edrk.zadanie.rmp_oborots_zad_hz.RampHighLimit1 = _IQ(MAX_1_ZADANIE_OBOROTS_ROTOR/60.0/NORMA_FROTOR); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_OBOROTS_ROTOR)); +// rampafloat = _IQ((MAX_ZADANIE_OBOROTS_ROTOR/NORMA_FROTOR/60.0)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_OBOROTS_ROTOR)); +// edrk.zadanie.rmp_oborots_zad_hz.RampPlus = rampafloat; +// edrk.zadanie.rmp_oborots_zad_hz.RampMinus = -rampafloat; + + change_ramp_zadanie(); + + edrk.zadanie.rmp_oborots_zad_hz.DesiredInput = 0; + edrk.zadanie.rmp_oborots_zad_hz.Out = 0; + + +// + edrk.zadanie.rmp_Izad.RampLowLimit = _IQ(0); //0 + edrk.zadanie.rmp_Izad.RampHighLimit = _IQ(MAX_ZADANIE_I_M/NORMA_ACP); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_I_M)); + rampafloat = _IQ((MAX_ZADANIE_I_M/NORMA_ACP)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_I_M)); + edrk.zadanie.rmp_Izad.RampPlus = rampafloat; + edrk.zadanie.rmp_Izad.RampMinus = -rampafloat; + + edrk.zadanie.rmp_Izad.DesiredInput = 0; + edrk.zadanie.rmp_Izad.Out = 0; + +// + edrk.zadanie.rmp_ZadanieU_Charge.RampLowLimit = _IQ(0); //0 + edrk.zadanie.rmp_ZadanieU_Charge.RampHighLimit = _IQ(MAX_ZADANIE_U_CHARGE/NORMA_ACP); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_U_CHARGE)); + rampafloat = _IQ((MAX_ZADANIE_U_CHARGE/NORMA_ACP)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_U_CHARGE)); + edrk.zadanie.rmp_ZadanieU_Charge.RampPlus = rampafloat; + edrk.zadanie.rmp_ZadanieU_Charge.RampMinus = -rampafloat; + + edrk.zadanie.rmp_ZadanieU_Charge.DesiredInput = _IQ(NOMINAL_U_ZARYAD/NORMA_ACP); + edrk.zadanie.rmp_ZadanieU_Charge.Out = _IQ(NOMINAL_U_ZARYAD/NORMA_ACP); + + + +// + edrk.zadanie.rmp_k_u_disbalance.RampLowLimit = _IQ(0); //0 + edrk.zadanie.rmp_k_u_disbalance.RampHighLimit = _IQ(MAX_ZADANIE_K_U_DISBALANCE); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_K_U_DISBALANCE)); + rampafloat = _IQ((MAX_ZADANIE_K_U_DISBALANCE)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_K_U_DISBALANCE)); + edrk.zadanie.rmp_k_u_disbalance.RampPlus = rampafloat; + edrk.zadanie.rmp_k_u_disbalance.RampMinus = -rampafloat; + + edrk.zadanie.rmp_k_u_disbalance.DesiredInput = 0; + edrk.zadanie.rmp_k_u_disbalance.Out = 0; + + +// + edrk.zadanie.rmp_kplus_u_disbalance.RampLowLimit = _IQ(0); //0 + edrk.zadanie.rmp_kplus_u_disbalance.RampHighLimit = _IQ(MAX_ZADANIE_KPLUS_U_DISBALANCE); + +// rampafloat = _IQ(1.0/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_KPLUS_U_DISBALANCE)); + rampafloat = _IQ((MAX_ZADANIE_KPLUS_U_DISBALANCE)/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_KPLUS_U_DISBALANCE)); + edrk.zadanie.rmp_kplus_u_disbalance.RampPlus = rampafloat; + edrk.zadanie.rmp_kplus_u_disbalance.RampMinus = -rampafloat; + + edrk.zadanie.rmp_kplus_u_disbalance.DesiredInput = 0; + edrk.zadanie.rmp_kplus_u_disbalance.Out = 0; + + + +// + edrk.zadanie.rmp_kzad.RampLowLimit = _IQ(0); //0 + edrk.zadanie.rmp_kzad.RampHighLimit = _IQ(MAX_ZADANIE_K_M); + +// rampafloat = _IQ(1.0/(2.0*FREQ_PWM*T_NARAST_ZADANIE_K_M)); + rampafloat = _IQ((MAX_ZADANIE_K_M)/(2.0*FREQ_PWM*T_NARAST_ZADANIE_K_M)); + edrk.zadanie.rmp_kzad.RampPlus = rampafloat; + edrk.zadanie.rmp_kzad.RampMinus = -rampafloat; + + edrk.zadanie.rmp_kzad.DesiredInput = 0; + edrk.zadanie.rmp_kzad.Out = 0; + + +// + edrk.zadanie.rmp_powers_zad.RampLowLimit = _IQ(MIN_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); //0 + edrk.zadanie.rmp_powers_zad.RampHighLimit = _IQ(MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + + edrk.zadanie.rmp_powers_zad.RampLowLimit1 = _IQ(MIN_1_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + edrk.zadanie.rmp_powers_zad.RampHighLimit1 = _IQ(MAX_1_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + +// rampafloat = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_POWER)); +// edrk.zadanie.rmp_powers_zad.RampPlus = rampafloat; +// edrk.zadanie.rmp_powers_zad.RampMinus = -rampafloat; + + +//// + rampafloat_plus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_POWER_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_POWER_MINUS)); + + edrk.zadanie.rmp_powers_zad.PosRampPlus1 = rampafloat_plus; + edrk.zadanie.rmp_powers_zad.PosRampMinus1 = -rampafloat_minus; + + edrk.zadanie.rmp_powers_zad.NegRampPlus1 = rampafloat_minus; + edrk.zadanie.rmp_powers_zad.NegRampMinus1 = -rampafloat_plus; + + rampafloat_plus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_POWER_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_POWER_MINUS)); + + edrk.zadanie.rmp_powers_zad.PosRampPlus2 = rampafloat_plus; + edrk.zadanie.rmp_powers_zad.PosRampMinus2 = -rampafloat_minus; + + edrk.zadanie.rmp_powers_zad.NegRampPlus2 = rampafloat_minus; + edrk.zadanie.rmp_powers_zad.NegRampMinus2 = -rampafloat_plus; + +//// + + edrk.zadanie.rmp_powers_zad.DesiredInput = 0; + edrk.zadanie.rmp_powers_zad.Out = 0; + +// + + edrk.zadanie.rmp_limit_powers_zad.RampLowLimit = 0;//_IQ(0); //0 + edrk.zadanie.rmp_limit_powers_zad.RampHighLimit = _IQ(SUPER_MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + + edrk.zadanie.rmp_limit_powers_zad.RampLowLimit1 = 0; + edrk.zadanie.rmp_limit_powers_zad.RampHighLimit1 = _IQ(MAX_1_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + + rampafloat_plus = _IQ((SUPER_MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_LIMIT_POWER_PLUS)); + rampafloat_minus = _IQ((SUPER_MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T1_NARAST_ZADANIE_LIMIT_POWER_MINUS)); + + edrk.zadanie.rmp_limit_powers_zad.PosRampPlus1 = rampafloat_plus; + edrk.zadanie.rmp_limit_powers_zad.PosRampMinus1 = -rampafloat_minus; + + edrk.zadanie.rmp_limit_powers_zad.NegRampPlus1 = rampafloat_minus; + edrk.zadanie.rmp_limit_powers_zad.NegRampMinus1 = -rampafloat_plus; + + rampafloat_plus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_POWER_PLUS)); + rampafloat_minus = _IQ((MAX_ZADANIE_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T2_NARAST_ZADANIE_POWER_MINUS)); + + edrk.zadanie.rmp_limit_powers_zad.PosRampPlus2 = rampafloat_plus; + edrk.zadanie.rmp_limit_powers_zad.PosRampMinus2 = -rampafloat_minus; + + edrk.zadanie.rmp_limit_powers_zad.NegRampPlus2 = rampafloat_minus; + edrk.zadanie.rmp_limit_powers_zad.NegRampMinus2 = -rampafloat_plus; + +// rampafloat = _IQ((MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ))/(FREQ_RUN_RAMP*T_NARAST_ZADANIE_LIMIT_POWER)); + +// edrk.zadanie.rmp_limit_powers_zad.RampPlus = rampafloat; +// edrk.zadanie.rmp_limit_powers_zad.RampMinus = -rampafloat; + + edrk.zadanie.rmp_limit_powers_zad.DesiredInput = 0; + edrk.zadanie.rmp_limit_powers_zad.Out = 0; + +// + + +} + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +#pragma CODE_SECTION(ramp_all_zadanie,".fast_run"); +void load_current_ramp_oborots_power(void) +{ + int mode=0; + static int prev_mode = 0; + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_OBOROTS || + edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_OBOROTS) + mode = 1; + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_FOC_POWER || + edrk.Mode_ScalarVectorUFConst == ALG_MODE_SCALAR_POWER) + mode = 2; + + if (mode==1 && prev_mode==2) + { + // ���� ��������, � ����� ������� + edrk.zadanie.rmp_oborots_zad_hz.Out = WRotor.iqWRotorSumFilter3; + //edrk.zadanie.iq_oborots_zad_hz = WRotor.iqWRotorSumFilter3; + } + + + if (mode==2 && prev_mode==1) + { + // ���� �������, � ����� �������� + edrk.zadanie.rmp_powers_zad.Out = edrk.iq_power_kw_one_filter_znak;//filter.PowerScalarFilter2; + } + + prev_mode = mode; + +} +////////////////////////////////////////////////////////// +#pragma CODE_SECTION(ramp_all_zadanie,".fast_run"); +void ramp_all_zadanie(int flag_set_zero) +{ + +// if (edrk.Status_Ready.bits.ImitationReady2) + { + edrk.zadanie.rmp_oborots_imitation.DesiredInput = edrk.zadanie.iq_oborots_zad_hz; + edrk.zadanie.rmp_oborots_imitation.calc(&edrk.zadanie.rmp_oborots_imitation); + edrk.zadanie.rmp_oborots_imitation_rmp = edrk.zadanie.rmp_oborots_imitation.Out; + } + ////////////////////////////////////////////// + if (flag_set_zero==0) + edrk.zadanie.rmp_Izad.DesiredInput = edrk.zadanie.iq_Izad; + else + if (flag_set_zero==2) + { + edrk.zadanie.rmp_Izad.DesiredInput = 0; + edrk.zadanie.rmp_Izad.Out = 0; + } + else + edrk.zadanie.rmp_Izad.DesiredInput = 0; + + edrk.zadanie.rmp_Izad.calc(&edrk.zadanie.rmp_Izad); + edrk.zadanie.iq_Izad_rmp = edrk.zadanie.rmp_Izad.Out; + ////////////////////////////////////////////// + edrk.zadanie.rmp_ZadanieU_Charge.DesiredInput = edrk.zadanie.iq_ZadanieU_Charge; + edrk.zadanie.rmp_ZadanieU_Charge.calc(&edrk.zadanie.rmp_ZadanieU_Charge); + edrk.zadanie.iq_ZadanieU_Charge_rmp = edrk.zadanie.rmp_ZadanieU_Charge.Out; + ////////////////////////////////////////////// + if (flag_set_zero==0) + edrk.zadanie.rmp_fzad.DesiredInput = edrk.zadanie.iq_fzad; + else + if (flag_set_zero==2) + { + edrk.zadanie.rmp_fzad.DesiredInput = 0; + edrk.zadanie.rmp_fzad.Out = 0; + } + else + edrk.zadanie.rmp_fzad.DesiredInput = 0; + + edrk.zadanie.rmp_fzad.calc(&edrk.zadanie.rmp_fzad); + edrk.zadanie.iq_fzad_rmp = edrk.zadanie.rmp_fzad.Out; + ////////////////////////////////////////////// + edrk.zadanie.rmp_k_u_disbalance.DesiredInput = edrk.zadanie.iq_k_u_disbalance; + edrk.zadanie.rmp_k_u_disbalance.calc(&edrk.zadanie.rmp_k_u_disbalance); + edrk.zadanie.iq_k_u_disbalance_rmp = edrk.zadanie.rmp_k_u_disbalance.Out; + ////////////////////////////////////////////// + edrk.zadanie.rmp_kplus_u_disbalance.DesiredInput = edrk.zadanie.iq_kplus_u_disbalance; + edrk.zadanie.rmp_kplus_u_disbalance.calc(&edrk.zadanie.rmp_kplus_u_disbalance); + edrk.zadanie.iq_kplus_u_disbalance_rmp = edrk.zadanie.rmp_kplus_u_disbalance.Out; + ////////////////////////////////////////////// + if (flag_set_zero==0) + edrk.zadanie.rmp_kzad.DesiredInput = edrk.zadanie.iq_kzad; + else + if (flag_set_zero==2) + { + edrk.zadanie.rmp_kzad.DesiredInput = 0; + edrk.zadanie.rmp_kzad.Out = 0; + } + else + edrk.zadanie.rmp_kzad.DesiredInput = 0; + edrk.zadanie.rmp_kzad.calc(&edrk.zadanie.rmp_kzad); + edrk.zadanie.iq_kzad_rmp = edrk.zadanie.rmp_kzad.Out; + ////////////////////////////////////////////// + if (flag_set_zero==0) + edrk.zadanie.rmp_oborots_zad_hz.DesiredInput = edrk.zadanie.iq_oborots_zad_hz; + else + if (flag_set_zero==2) + { + edrk.zadanie.rmp_oborots_zad_hz.DesiredInput = 0; + edrk.zadanie.rmp_oborots_zad_hz.Out = 0; + } + else + edrk.zadanie.rmp_oborots_zad_hz.DesiredInput = 0; + + edrk.zadanie.rmp_oborots_zad_hz.calc(&edrk.zadanie.rmp_oborots_zad_hz); + edrk.zadanie.iq_oborots_zad_hz_rmp = edrk.zadanie.rmp_oborots_zad_hz.Out; + + ////////////////////////////////////////////// +// if (flag_set_zero==0) +// edrk.zadanie.rmp_limit_powers_zad.DesiredInput = edrk.zadanie.iq_limit_power_zad; +// else +// if (flag_set_zero==2) +// { +// edrk.zadanie.rmp_limit_powers_zad.DesiredInput = 0; +// edrk.zadanie.rmp_limit_powers_zad.Out = 0; +// } +// else +// edrk.zadanie.rmp_limit_powers_zad.DesiredInput = 0; + + edrk.zadanie.rmp_limit_powers_zad.DesiredInput = edrk.zadanie.iq_limit_power_zad; + edrk.zadanie.rmp_limit_powers_zad.calc(&edrk.zadanie.rmp_limit_powers_zad); + edrk.zadanie.iq_limit_power_zad_rmp = edrk.zadanie.rmp_limit_powers_zad.Out; + + + + ////////////////////////////////////////////// + if (flag_set_zero==0) + { + if (edrk.zadanie.iq_power_zad>=0) + { + if (edrk.zadanie.iq_power_zad>edrk.zadanie.iq_limit_power_zad_rmp) + edrk.zadanie.rmp_powers_zad.DesiredInput = edrk.zadanie.iq_limit_power_zad_rmp; + else + edrk.zadanie.rmp_powers_zad.DesiredInput = edrk.zadanie.iq_power_zad; + } + else + { + if (edrk.zadanie.iq_power_zad<-edrk.zadanie.iq_limit_power_zad_rmp) + edrk.zadanie.rmp_powers_zad.DesiredInput = -edrk.zadanie.iq_limit_power_zad_rmp; + else + edrk.zadanie.rmp_powers_zad.DesiredInput = edrk.zadanie.iq_power_zad; + } + + } + else + if (flag_set_zero==2) + { + edrk.zadanie.rmp_powers_zad.DesiredInput = 0; + edrk.zadanie.rmp_powers_zad.Out = 0; + } + else + edrk.zadanie.rmp_powers_zad.DesiredInput = 0; + + edrk.zadanie.rmp_powers_zad.calc(&edrk.zadanie.rmp_powers_zad); + edrk.zadanie.iq_power_zad_rmp = edrk.zadanie.rmp_powers_zad.Out; + +} + +////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/ramp_zadanie_tools.h b/Inu/Src/main/ramp_zadanie_tools.h new file mode 100644 index 0000000..c90acb6 --- /dev/null +++ b/Inu/Src/main/ramp_zadanie_tools.h @@ -0,0 +1,20 @@ +/* + * ramp_zadanie_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_RAMP_ZADANIE_TOOLS_H_ +#define SRC_MAIN_RAMP_ZADANIE_TOOLS_H_ + +#define FREQ_RUN_RAMP FREQ_PWM // (2.0*FREQ_PWM) + + +void ramp_all_zadanie(int flag_set_zero); +void change_ramp_zadanie(void); +void init_ramp_all_zadanie(void); +void load_current_ramp_oborots_power(void); + + +#endif /* SRC_MAIN_RAMP_ZADANIE_TOOLS_H_ */ diff --git a/Inu/Src/main/sbor_shema.c b/Inu/Src/main/sbor_shema.c new file mode 100644 index 0000000..7157fd1 --- /dev/null +++ b/Inu/Src/main/sbor_shema.c @@ -0,0 +1,1764 @@ +/* + * sbor_shema.c + * + * Created on: 18 ����. 2021 �. + * Author: stud + */ +#include "sbor_shema.h" +#include "IQmathLib.h" +#include "edrk_main.h" +#include "optical_bus.h" +#include "adc_tools.h" +#include "control_station.h" +#include "control_station_project.h" +#include "digital_filters.h" +#include "detect_errors.h" + +#define RASCEPITEL_MANUAL_ALWAYS_ON 0//1 +/////////////////////////////////////////////// +/////////////////////////////////////////////// +//#define IQ_MINIMAL_DELTA_RUN_CHARGE_1 559240 //100V +//#define IQ_MINIMAL_DELTA_RUN_CHARGE_2 1118480 //200V + +//#define IQ_MINIMAL_DELTA_RUN_CHARGE 279620 // 50V +#define IQ_MINIMAL_DELTA_RUN_CHARGE_1 1118480// 200 V ///279620 // 50V +#define IQ_MINIMAL_DELTA_RUN_CHARGE_2 1118480// 200 V //279620 // 50V + +#define IQ_MINIMAL_DELTA_RUN_WORK 2796202 // 500V // 2236960 // 400V // 1677720 // 300 V // 559240 // 100V + +#define IQ_MINIMAL_ZAD_U_CHARGE 55924 // 10V +#define IQ_MAXIMAL_ZAD_U_CHARGE 14596177 // 2610V +#define IQ_MINIMAL_DELTA_RUN_CHARGE2 139810 //25 V +#define TIME_WAIT_CHARGE_ON 300 //30 sec +#define TIME_PAUSE_U_RISE 30 // 1 sec + +#define IQ_MINIMAL_RISE_U 55924 // 10V + +unsigned int zaryad_on_off(unsigned int flag) +{ + static int restart_charge=0, batt_ok = 0; + static unsigned int time_wait_on_charge=0; + static unsigned int time_pause_detect_u_rise=0; + + static _iq prev_U1=0, prev_U2 = 0; + + batt_ok = 0; +// �������� �� ������ - ������!!! + if (_IQabs(filter.iqU_1_long-filter.iqU_2_long)>IQ_MINIMAL_DELTA_RUN_WORK) + { +// edrk.errors.e6.bits.ERROR_PRE_CHARGE_U |= 1; + edrk.errors.e6.bits.ER_DISBAL_BATT |= 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + batt_ok = 0; + } + + if (flag && edrk.summ_errors==0 && edrk.errors.e6.bits.ERROR_PRE_CHARGE_U==0 && edrk.errors.e6.bits.ER_DISBAL_BATT==0 ) + { +// ��� �������!!! + if ((edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_ZAD_U_CHARGE) <= 0) + { + edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON |= 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + return 0; + } + // ������� �������!!! + + if ((IQ_MAXIMAL_ZAD_U_CHARGE - edrk.zadanie.iq_ZadanieU_Charge) < 0) + { + edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON |= 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + return 0; + } + +// ���� �������� �� ������ + if (_IQabs(filter.iqU_1_long-filter.iqU_2_long)>IQ_MINIMAL_DELTA_RUN_WORK) //IQ_MINIMAL_DELTA_RUN_CHARGE_1 + { + edrk.errors.e6.bits.ER_DISBAL_BATT |= 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + return 0; + } + + if (restart_charge == 0) + { + + // ����� ����� � ���� ��������, ��������� + if ( edrk.from_ing1.bits.ZARYAD_ON && + (filter.iqU_1_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_1) + || filter.iqU_2_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_1)) + ) + { + restart_charge = 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + } + else + { + //TODO !!! �� ���� ��������� ���������� if. �������? + if ( edrk.from_ing1.bits.ZARYAD_ON==0 && + (filter.iqU_1_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2) + || filter.iqU_2_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) ) + { + restart_charge = 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + } + else + { + // ����� ������ �������, ��������. + if ( (filter.iqU_1_long<(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + && (filter.iqU_2_long<(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) ) + edrk.to_ing.bits.ZARYAD_ON = 1; + + } + + } + + if (pause_detect_error(&time_pause_detect_u_rise,TIME_PAUSE_U_RISE,1)) + { + time_pause_detect_u_rise = 0; + + if (((filter.iqU_1_long-prev_U1)>=IQ_MINIMAL_RISE_U) || + ((filter.iqU_2_long-prev_U2)>=IQ_MINIMAL_RISE_U) ) + time_wait_on_charge = 0; + + + prev_U1 = filter.iqU_1_long; + prev_U2 = filter.iqU_2_long; + } + + + // �� ��������� ������!!! + if (pause_detect_error(&time_wait_on_charge,TIME_WAIT_CHARGE_ON,1)) + edrk.errors.e6.bits.ERROR_PRE_CHARGE_U |= 1; +/* + + if (filter.iqU_1_long>=(edrk.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE2) + || filter.iqU_2_long>=(edrk.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE2)) + { + restart_charge = 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + } + else + { + // ���� �������� �� ������ + if (_IQabs(filter.iqU_1_long-filter.iqU_2_long)>IQ_MINIMAL_DELTA_RUN_CHARGE) + edrk.errors.e6.bits.ER_DISBAL_BATT |= 1; + + // ����� ������ �������, ��������. + if ( (filter.iqU_1_long<(edrk.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE)) + || (filter.iqU_2_long<(edrk.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE)) ) + edrk.to_ing.bits.ZARYAD_ON = 1; + + if ( (filter.iqU_1_long>=(edrk.iq_ZadanieU_Charge)) + && (filter.iqU_2_long>=(edrk.iq_ZadanieU_Charge)) ) + { + restart_charge = 1; + edrk.to_ing.bits.ZARYAD_ON = 0; + } + } +*/ + + } + else//restart_charge==0 + { + // ������-�� ����� ���� ������!!! + if ( (filter.iqU_1_long<(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + || (filter.iqU_2_long<(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) ) + edrk.errors.e6.bits.ERROR_PRE_CHARGE_U |= 1; + + } //restart_charge==0 + } + else // flag==1 + { + restart_charge = 0; + edrk.to_ing.bits.ZARYAD_ON = 0; + time_wait_on_charge = 0; + prev_U1 = filter.iqU_1_long; + prev_U2 = filter.iqU_2_long; + } + + if ( (filter.iqU_1_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + && (filter.iqU_2_long>=(edrk.zadanie.iq_ZadanieU_Charge-IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + && (_IQabs(filter.iqU_1_long-filter.iqU_2_long)<IQ_MINIMAL_DELTA_RUN_WORK) + && (filter.iqU_1_long<=(edrk.zadanie.iq_ZadanieU_Charge+IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + && (filter.iqU_2_long<=(edrk.zadanie.iq_ZadanieU_Charge+IQ_MINIMAL_DELTA_RUN_CHARGE_2)) + && edrk.to_ing.bits.ZARYAD_ON==0 + && edrk.from_ing1.bits.ZARYAD_ON==0 + && edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON==0 + && edrk.errors.e6.bits.ERROR_PRE_CHARGE_U==0 + ) + batt_ok = 1; + +// return (restart_charge && edrk.errors.e5.bits.ERROR_PRE_CHARGE_ON==0 && edrk.errors.e6.bits.ERROR_PRE_CHARGE_U==0); + return batt_ok; + +} + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void set_status_pump_fan(void) +{ + + if (edrk.from_ing1.bits.VENTIL_ON==1) + edrk.StatusFunAll = 1; + else + edrk.StatusFunAll = 0; + +/* + if ((edrk.from_ing.bits.NASOS_NORMA == 1) && + edrk.StartPump && edrk.errors.e5.bits.PRE_READY_PUMP == 0 && + (edrk.to_ing.bits.NASOS_1_ON || edrk.to_ing.bits.NASOS_2_ON) && + (edrk.errors.e5.bits.PUMP_1==0) && (edrk.errors.e5.bits.PUMP_2==0) && + edrk.errors.e2.bits.P_WATER_INT_MAX==0 && edrk.errors.e2.bits.P_WATER_INT_MIN==0) +*/ + if ( + (edrk.from_ing1.bits.NASOS_NORMA == 1) && + (edrk.to_ing.bits.NASOS_1_ON || edrk.to_ing.bits.NASOS_2_ON) && + edrk.from_ing1.bits.NASOS_ON && edrk.errors.e5.bits.PRE_READY_PUMP == 0 && + (edrk.errors.e5.bits.PUMP_1==0) && (edrk.errors.e5.bits.PUMP_2==0) + ) + { + if (edrk.to_ing.bits.NASOS_1_ON) + edrk.StatusPump0 = 1; + else + edrk.StatusPump0 = 0; + + if (edrk.to_ing.bits.NASOS_2_ON) + edrk.StatusPump1 = 1; + else + edrk.StatusPump1 = 0; + + edrk.StatusPumpAll = 1; + + + + } + else + { + + edrk.StatusPump0 = 0; + edrk.StatusPump1 = 0; + + edrk.StatusPumpAll = 0; + } + + + if (edrk.StatusFunAll && edrk.StatusPumpAll) + edrk.StatusPumpFanAll = 1; + else + { + // ���� ���� ������ ����� ������� �� ����������, �� ��������� ��������� ������� � ������������. + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_PUMP]) + edrk.StatusPumpFanAll = 1; + else + { + edrk.StatusPumpFanAll = 0; + } + } + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// +int detect_zaryad_ump(void) +{ + if (edrk.from_shema_filter.bits.UMP_ON_OFF==1) + { + if ( (filter.iqUin_m1>=edrk.iqMIN_U_IN) + && (filter.iqUin_m2>=edrk.iqMIN_U_IN) + && (filter.iqUin_m1<=edrk.iqMAX_U_IN) + && (filter.iqUin_m2<=edrk.iqMAX_U_IN) ) + return 1; + else + return 0; + + } + else + return 0; +} +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +#define TIME_WAIT_SBOR 8500 +#define TIME_WAIT_ANSWER_NASOS 500 +#define TIME_WAIT_OK_NASOS 50 + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +void sbor_shema_pusk_nasos(unsigned int t_start, unsigned int t_finish) +{ + static unsigned int time_error_nasos = 0; + static unsigned int time_ok_nasos = 0; + + int status_pump, status_pump_long; + + // ���� ������ + if (edrk.Sbor_Mode == t_start) + { + edrk.enter_to_pump_stage = 1; + // �������� �������������� �� �������, �������� � �� ��������� ���! + edrk.warnings.e5.bits.PUMP_1 = edrk.warnings.e5.bits.PUMP_2 = 0; + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_PUMP]==0) + edrk.AutoStartPump = 1; + + time_error_nasos = 0; + time_ok_nasos = 0; + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_PUMP]==1) + edrk.Sbor_Mode = t_finish; // �������� ���������� ����� ������ + } + + // ���� ����� ������ + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_PUMP; + + status_pump = get_status_p_water_min(edrk.StatusPumpFanAll); + +/* if (status & 4) + edrk.errors.e2.bits.P_WATER_INT_MIN |= 1; + if (status==2) + edrk.warnings.e2.bits.P_WATER_INT_MIN = 1; + if (status==1) + edrk.warnings.e2.bits.P_WATER_INT_MIN = 0; +*/ + + // ���� ��������� ����� ���� ������ ����� � ���������� ��������� status_pump == 1 + if (status_pump) + { + if (pause_detect_error(&time_ok_nasos,TIME_WAIT_OK_NASOS,1)) + { + status_pump_long = 1; + } + } + else + { + time_ok_nasos = 0; + status_pump_long = 0; + } + + + if (edrk.StatusPumpFanAll && status_pump==1) // ���� ����� ������ � �������� + { + edrk.Sbor_Mode = t_finish; + } + + // ����� �� ��������, ������� ������ + if (edrk.Sbor_Mode==(t_start + ((t_finish-t_start)>>1) )) + { + + + } + + // ����� �� ��������, ������ + if (edrk.Sbor_Mode==(t_finish-1)) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_PUMP_ON_SBOR |= 1; + edrk.Status_Sbor = 2; + edrk.AutoStartPump = 0; + } + + } +// ������ ��� ����� ������� ������ + if (edrk.Sbor_Mode>t_finish) + { + if (edrk.StatusPumpFanAll==0) + { + // ����� ���������� ����� + if (edrk.SelectPump1_2==1) + { + // �� ���� � ���������� ������ 1 + // ���� ��������� ����� ���� ������������� ����� + if (pause_detect_error(&time_error_nasos,TIME_WAIT_ANSWER_NASOS,1)) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_RESTART_PUMP_1_ON_SBOR |= 1; + edrk.Status_Sbor = 102; + edrk.AutoStartPump = 0; + } + } + else + if (edrk.SelectPump1_2==2) + { + // �� ���� � ���������� ������ 2 + // ���� ��������� ����� ���� ������������� ����� + if (pause_detect_error(&time_error_nasos,TIME_WAIT_ANSWER_NASOS,1)) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_RESTART_PUMP_1_ON_SBOR |= 1; + edrk.Status_Sbor = 102; + edrk.AutoStartPump = 0; + } + } + else + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_RESTART_PUMP_ALL_ON_SBOR |= 1; + edrk.Status_Sbor = 102; + edrk.AutoStartPump = 0; + } + } + else + time_error_nasos = 0; + + } +} + +void sbor_shema_pusk_zaryad(unsigned int t_start, unsigned int t_finish) +{ + ///////////////////////////////////// + // ������ ������ ����������� + if (edrk.Sbor_Mode == t_start) + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ENABLE_ON_CHARGE]==1) + edrk.Run_Pred_Zaryad = 1; // ������ ����������! + } + + // ���� ���������� ������ ���������� + // ��� ��������� ������ ��� ��������� ������ + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Status_Charge || (control_station.active_array_cmd[CONTROL_STATION_CMD_ENABLE_ON_CHARGE]==0)) + && edrk.from_ing1.bits.ZARYAD_ON==0 && edrk.StatusPumpFanAll) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_ZARYAD; + if ((edrk.Status_Charge || (control_station.active_array_cmd[CONTROL_STATION_CMD_ENABLE_ON_CHARGE]==0)) + && edrk.from_ing1.bits.ZARYAD_ON==0 && edrk.StatusPumpFanAll) + { + edrk.Zaryad_OK = 1; + edrk.Run_Pred_Zaryad = 0; + edrk.Sbor_Mode = t_finish; + } + + // ��� ������, ������ + if (edrk.Sbor_Mode==(t_finish-1)) + { + edrk.Run_Pred_Zaryad = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_PRED_ZARYAD |= 1; + edrk.Status_Sbor = 4; + } + + } + + if (edrk.Sbor_Mode>t_finish) + { + if (edrk.Zaryad_OK==0 || edrk.from_ing1.bits.ZARYAD_ON==1 ) + { + edrk.Run_Pred_Zaryad = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_PRED_ZARYAD_AFTER |= 1; + edrk.Status_Sbor = 104; + } + } + +} +void sbor_shema_pusk_ump(unsigned int t_start, unsigned int t_finish) +{ + static int enable_run_ump=0; + // �������� UMP + if (edrk.Sbor_Mode==t_start && edrk.Zaryad_OK == 1) + { + // edrk.Run_UMP = 1; + enable_run_ump = 0; + } + + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish) + { + + if (enable_run_ump==0) + { + if (edrk.from_shema_filter.bits.READY_UMP==1 + || control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_UMP]==1) + { + edrk.Run_UMP = 1; + enable_run_ump = 1; + } + } + + edrk.Stage_Sbor = STAGE_SBOR_STATUS_UMP_ON; + if (edrk.Zaryad_OK == 1 && edrk.Status_UMP_Ok==1 && edrk.Zaryad_UMP_Ok==1) + edrk.Sbor_Mode = t_finish; + + // ��� ������, ������ + if (edrk.Sbor_Mode==(t_finish-1)) + { + edrk.Run_UMP = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_UMP_NOT_ON |= 1; + edrk.Status_Sbor = 5; + } + + } + + +// if (edrk.Sbor_Mode>t_finish && (edrk.Zaryad_OK == 0 || edrk.Status_UMP_Ok==0)) +// { +// +// edrk.Run_UMP = 0; +// edrk.Run_Pred_Zaryad = 0; +// edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; +// edrk.errors.e7.bits.UMP_NOT_ANSWER |= 1; +// edrk.Run_QTV = 0; +// edrk.Status_Sbor = 105; +// } + + +} + +void sbor_shema_pusk_qtv(unsigned int t_start, unsigned int t_finish) +{ + if (edrk.Sbor_Mode==t_start && edrk.Zaryad_OK == 1 && edrk.Status_UMP_Ok) + { + edrk.Run_QTV = 1; + } + + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish ) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_QTV; + if ((edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 && edrk.Status_UMP_Ok)) + edrk.Sbor_Mode = t_finish; + + if (edrk.Sbor_Mode==(t_finish-1) && edrk.Status_UMP_Ok==0) + { + edrk.Run_QTV = 0; + edrk.Run_UMP = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_READY_UMP_BEFORE_QTV |= 1; + edrk.Status_Sbor = 6; + } + } + + + if (edrk.Sbor_Mode>t_finish) + { + if (edrk.Zaryad_OK == 0 || edrk.Status_QTV_Ok==0) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_STATUS_QTV |= 1; + edrk.Run_QTV = 0; + edrk.Status_Sbor = 106; + } + + } + +} + +void sbor_shema_stop_ump(unsigned int t_start, unsigned int t_finish) +{ + // �������� UMP + if (edrk.Sbor_Mode==t_start && edrk.Status_QTV_Ok == 1) + { + edrk.Run_UMP = 0; + } + + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish) + { + + edrk.Stage_Sbor = STAGE_SBOR_STATUS_UMP_OFF; + if (edrk.Status_UMP_Ok==0) + edrk.Sbor_Mode = t_finish; + + // ��� ������, ������ + if (edrk.Sbor_Mode==(t_finish-1)) + { + edrk.Run_UMP = 0; + edrk.Run_QTV = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; +// edrk.errors.e7.bits.UMP_NOT_ANSWER |= 1; + edrk.errors.e11.bits.ERROR_UMP_NOT_OFF |= 1; + edrk.Status_Sbor = 7; + } + + } + + + if (edrk.Sbor_Mode>t_finish && edrk.Status_UMP_Ok==1) + { + + edrk.Run_UMP = 0; + edrk.Run_Pred_Zaryad = 0; + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_UMP_ON_AFTER |= 1; + edrk.Run_QTV = 0; + edrk.Status_Sbor = 107; + } + + +} + + +void sbor_shema_rascepitel_level_1(unsigned int t_start, unsigned int t_finish) +{ + +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + if (edrk.Sbor_Mode==t_start && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 )) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_1; + // ���� ������ �� �� ������, �������� ����������� + if (optical_read_data.data.cmd.bit.ready_cmd != CODE_READY_CMD_READY2 ) + { + edrk.Run_Rascepitel = 1; + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + else + edrk.RunZahvatRascepitel = 1; // ������ ������ �� �������� ������� � ��������� ����������� ����������� + } + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) + && edrk.RunZahvatRascepitel && edrk.Run_Rascepitel==0) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_1; + // ���� ������ �� �� ������, �������� ����������� + // ������ �� ������� ������� ���� ��� ���� � ���� ��� ���� ��� + if (optical_read_data.data.cmd.bit.rascepitel_cmd == CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // 01 - ����� �������� �����������, ���� ������� + { + edrk.Run_Rascepitel = 1; + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + } + +#else + + + if (edrk.Sbor_Mode==t_start && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) && edrk.Status_Rascepitel_Ok==0) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_1; + // ���� ������ �� �� ������, �������� ����������� + if (optical_read_data.data.cmd.bit.ready_cmd != CODE_READY_CMD_READY2 ) + { + edrk.Run_Rascepitel = 1; + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + else + edrk.RunZahvatRascepitel = 1; // ������ ������ �� �������� ������� � ��������� ����������� ����������� + } +// + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) + && edrk.RunZahvatRascepitel && edrk.Status_Rascepitel_Ok==0 && edrk.Run_Rascepitel==0) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_1; + // ���� ������ �� �� ������, �������� ����������� + // ������ �� ������� ������� ���� ��� ���� � ���� ��� ���� ��� + if (optical_read_data.data.cmd.bit.rascepitel_cmd == CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // 01 - ����� �������� �����������, ���� ������� + { + edrk.Run_Rascepitel = 1; + edrk.Sbor_Mode = t_finish; // ������������ ������ + + } + } +#endif + + if (edrk.Sbor_Mode>t_finish) + { + if (edrk.Run_Rascepitel==0) + { + // �� ��������� ������� �� ��������� ������ ����������� + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_RASCEPITEL_WAIT_CMD |= 1; + edrk.Run_QTV = 0; + + edrk.Status_Sbor = 108; + // �� ��������� ������������� �� ������� + if (edrk.RunZahvatRascepitel) + edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL |= 1; + + edrk.RunZahvatRascepitel = 0; + edrk.Run_Rascepitel = 0; + } + } + +} + +void sbor_shema_rascepitel_level_2(unsigned int t_start, unsigned int t_finish) +{ + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_2; +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + edrk.Sbor_Mode = t_finish; // ������������ ������ +#else + + if ( (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) + && edrk.Status_Rascepitel_Ok==1 && edrk.Run_Rascepitel==1) + { + // ��������� ��������� ����������� � �������� ������ + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + + if (edrk.Sbor_Mode==(t_finish-1) && edrk.Status_Rascepitel_Ok==0 && edrk.Run_Rascepitel==1) + { + // �� ��������� ������������� �� ��������� ������ ����������� + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.Run_QTV = 0; + edrk.Status_Sbor = 9; + edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER |= 1; + edrk.RunZahvatRascepitel = 0; + edrk.Run_Rascepitel = 0; + } +#endif + + } + + if (edrk.Sbor_Mode>t_finish && edrk.Status_Rascepitel_Ok==0) + { + // ����������� ����������, � �� ������ ��� + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.Run_QTV = 0; + edrk.Status_Sbor = 109; +// edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER |= 1; + edrk.errors.e11.bits.ERROR_RASCEPITEL_ON_AFTER |= 1; + edrk.RunZahvatRascepitel = 0; + edrk.Run_Rascepitel = 0; + + + } + + + // + // �� ������� edrk.RunZahvatRascepitel ������ ��� �� �������� ������� � ����������� ����������� ��������� ����������� + + +// +// if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) +// && edrk.Status_Rascepitel_Ok==1 && edrk.Run_Rascepitel==1) +// { +// // ��������� ��������� ����������� � �������� ������ +// edrk.Sbor_Mode = t_finish; // ������������ ������ +// } +// +//// +// // �� ������� edrk.RunZahvatRascepitel ������ ��� �� �������� ������� � ����������� ����������� ��������� ����������� +// if (edrk.Sbor_Mode==(t_finish-1) && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 ) +// && edrk.RunZahvatRascepitel && edrk.Status_Rascepitel_Ok==0 && edrk.Run_Rascepitel==0) +// { +// // +//// if (optical_read_data.data.cmd.bit.rascepitel_cmd != CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // 01 - ����� �������� �����������, ���� ������� +// { +// // �� ��������� ������������� �� ��������� ������ ����������� +// edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; +// edrk.Run_QTV = 0; +// edrk.Status_Sbor = 8; +// edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL |= 1; +// edrk.RunZahvatRascepitel = 0; +// edrk.Run_Rascepitel = 0; +//// edrk.Run_Rascepitel = 0; +// } +// } + +} +void sbor_shema_rascepitel_level_3(unsigned int t_start, unsigned int t_finish) +{ + + // ��� ���� ��������� ����������� + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_3; + if (edrk.Status_Rascepitel_Ok==1) + { + // ����������� ���������! + // ����� ������������� � ����� + edrk.Sbor_Mode = t_finish; // ������������ ������ + edrk.RunZahvatRascepitel = 0; + } +// edrk.Run_Rascepitel = 1; + } + +// if (edrk.Sbor_Mode==(t_finish-1) && (edrk.Zaryad_OK == 0 || edrk.Status_QTV_Ok==0 || edrk.Status_Rascepitel_Ok==0)) +// { +// edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; +// edrk.Run_QTV = 0; +//// edrk.Run_Rascepitel = 0; +// edrk.RunZahvatRascepitel = 0; +// edrk.Status_Sbor = 10; +// edrk.Run_Rascepitel = 0; +// +// } +} + +void sbor_shema_rascepitel_level_4(unsigned int t_start, unsigned int t_finish) +{ + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 && edrk.Status_Rascepitel_Ok)) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_RASCEPITEL_4; + if (optical_read_data.data.cmd.bit.ready_cmd==CODE_READY_CMD_READY1TO2) // ��� �� ���������� ��� + { + // ������� ������� ������� �� + // �� ����������� ��� ���������. + if (optical_read_data.data.cmd.bit.rascepitel_cmd == CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON) + edrk.Sbor_Mode = t_finish; // ������������ ������ + + } + else + { + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + } + +// if (edrk.Sbor_Mode>t_finish) +// { +// if (edrk.Status_Rascepitel_Ok==0) +// { +// edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; +// edrk.Run_QTV = 0; +// edrk.RunZahvatRascepitel = 0; +// edrk.Status_Sbor = 9; +// edrk.Run_Rascepitel = 0; +// +// } +// +// } + +} + +void sbor_shema_wait_ready_another(unsigned int t_start, unsigned int t_finish) +{ + + if (edrk.Sbor_Mode>t_start && edrk.Sbor_Mode<t_finish && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 && edrk.Status_Rascepitel_Ok)) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_WAIT_READY_ANOTHER; + if (optical_read_data.data.cmd.bit.ready_cmd!=CODE_READY_CMD_READY1TO2) + { + edrk.Sbor_Mode = t_finish; // ������������ ������ + } + + if (edrk.Sbor_Mode==(t_finish-1) && optical_read_data.data.cmd.bit.ready_cmd==CODE_READY_CMD_READY1TO2) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e1.bits.ANOTHER_BS_VERY_LONG_WAIT |= 1; + edrk.Run_QTV = 0; +// edrk.Run_Rascepitel = 0; + edrk.RunZahvatRascepitel = 0; + edrk.Status_Sbor = 11; + edrk.Run_Rascepitel = 0; + } + + } + +} + +void sbor_shema_wait_finish(unsigned int t_start, unsigned int t_finish) +{ + if (edrk.Sbor_Mode>t_start && (edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 && edrk.Status_Rascepitel_Ok)) + { + edrk.Stage_Sbor = STAGE_SBOR_STATUS_FINISH; + edrk.SborFinishOk = 1; + // allow_discharge = 1; + } + + + if (edrk.Sbor_Mode>t_finish && (edrk.SborFinishOk) ) + { + edrk.time_wait_sbor = 0; + } + else + edrk.Sbor_Mode++; + +} + + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +#define TIME_WAIT_RELE_UMP_ON 20 //2 sec +#define TIME_WAIT_RELE_UMP_OFF 20 //2 sec + +#define TIME_WAIT_ANSWER_UMP_ON 150 //15 sec +#define TIME_WAIT_ANSWER_UMP_OFF 40 //4 sec + +#define TIME_PAUSE_AFTER_GET_READY_UMP 50 // 5 sec + +/////////////////////////////////////////////// +int ump_on_off(unsigned int flag) +{ +static unsigned int time_wait_rele_on_ump=0; +static unsigned int time_wait_rele_off_ump=0; +static unsigned int time_wait_answer_on_ump=0; +static unsigned int time_wait_answer_off_ump=0; + + +int cmd_ump=0;//,cmd_p2=0; +static int UMP_Ok = 0; +static int prev_error = 0, count_ready_upm = 0; //, flag_enable_on_ump = 0; + + + cmd_ump = 0; +// cmd_p2 = 0; + + if ( flag==1 && edrk.summ_errors==0) + { + cmd_ump = 1; + } + else + { + cmd_ump = 0; + } + + + + edrk.cmd_to_ump = cmd_ump; + + + if (cmd_ump) + { + +// if ((pause_detect_error(&time_wait_rele_on_qtv,TIME_WAIT_RELE_UMP_ON,1)==0) && edrk.from_shema.bits.UMP_ON_OFF==0) +// { +// edrk.to_shema.bits.QTV_ON_OFF = 1; +// } +// else + + // ���� ����������! + if (edrk.from_shema_filter.bits.READY_UMP == 1) + { + // ���� �������� TIME_PAUSE_AFTER_GET_READY_UMP + if (count_ready_upm<TIME_PAUSE_AFTER_GET_READY_UMP) + count_ready_upm++; + else + edrk.flag_enable_on_ump = 1; + } + else + count_ready_upm = 0; + + + if (edrk.flag_enable_on_ump) + { + edrk.sbor_wait_ump2 = 1; + edrk.to_shema.bits.UMP_ON_OFF = 1; + + if (pause_detect_error(&time_wait_answer_on_ump, TIME_WAIT_ANSWER_UMP_ON, 1)==0) + { + edrk.sbor_wait_ump1 = 1; + if (edrk.from_shema_filter.bits.UMP_ON_OFF==1) + UMP_Ok = 1; + } + else + { + edrk.sbor_wait_ump1 = 0; + if (edrk.from_shema_filter.bits.UMP_ON_OFF==0) + { + edrk.errors.e7.bits.UMP_NOT_ANSWER |= 1; + UMP_Ok = 0; + } + + } + } + else + { + edrk.sbor_wait_ump2 = 0; + } + + + time_wait_rele_off_ump = 0; + time_wait_answer_off_ump = 0; + } + else + { + count_ready_upm = 0; + UMP_Ok = 0; + time_wait_rele_on_ump = 0; + time_wait_answer_on_ump = 0; + + edrk.to_shema.bits.UMP_ON_OFF = 0; + + edrk.flag_enable_on_ump = 0; + + edrk.sbor_wait_ump2 = 0; + + if (pause_detect_error(&time_wait_answer_off_ump, TIME_WAIT_ANSWER_UMP_OFF, 1)==0) + { + edrk.sbor_wait_ump1 = 1; + } + else + { + edrk.sbor_wait_ump1 = 0; +// ��������� ������ ��� UMP ����� ���������!!! + if (edrk.from_shema_filter.bits.UMP_ON_OFF==1) + edrk.errors.e7.bits.UMP_NOT_ANSWER |= 1; + } + + + if (prev_error!=edrk.summ_errors && edrk.summ_errors) + { + if (pause_detect_error(&time_wait_rele_off_ump,TIME_WAIT_RELE_UMP_OFF,1)==1) + time_wait_rele_off_ump = 0; + } + + } + + prev_error = edrk.summ_errors; + + return (UMP_Ok); + + +} +/////////////////////////////////////////////// +/////////////////////////////////////////////// + +/////////////////////////////////////////////// +#define TIME_WAIT_RELE_RASCEPITEL_ON 10 //2 sec +#define TIME_WAIT_RELE_RASCEPITEL_OFF 10 //2 sec + +#define TIME_WAIT_ANSWER_RASCEPITEL_ON 100 //15 sec +#define TIME_WAIT_ANSWER_RASCEPITEL_ON_BS1 100 //15 sec +#define TIME_WAIT_ANSWER_RASCEPITEL_ON_BS2 150 //15 sec +#define TIME_WAIT_ANSWER_RASCEPITEL_OFF 100 //15 sec + +#define TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF 50 //5 sec +#define TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF_BS1 50 //5 sec +#define TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF_BS2 100 //7.5 sec +#define TIME_WAIT_PEREHOD_SOST_ON_OFF 100 //15 sec + + +/////////////////////////////////////////////// +void rascepitel_on_off(unsigned int flag, int *status_perehod, int *status_on_off, int *final_status_on_off) +{ +static unsigned int time_wait_rele_on=0; +static unsigned int time_wait_rele_off=0; +static unsigned int time_wait_answer_on=0; +static unsigned int time_wait_answer_off=0; + +static unsigned int time_wait_level_on=0; +static unsigned int time_wait_level_off=0; + +static unsigned int time_wait_perehod_sost=0; + + + +int cmd_rele=0, r;//,cmd_p2=0; +static int Rele_Ok = 0, filter_sost_rascepitel = 0; +static int prev_error = 0, perehod_sost = 0, flag_wait_break_perehod_sost = 0, prev_cmd_rele = 0; + + + cmd_rele = 0; +// cmd_p2 = 0; + + if ( flag==1 && edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER == 0) + { + cmd_rele = 1; + } + else + { + cmd_rele = 0; + } + + + + edrk.cmd_to_rascepitel = cmd_rele; + + + if (cmd_rele) + { + if (perehod_sost && cmd_rele!=prev_cmd_rele && flag_wait_break_perehod_sost==0) + { + + flag_wait_break_perehod_sost = 1; + time_wait_perehod_sost = 0; + } + + edrk.to_ing.bits.RASCEPITEL_OFF = 0; + + if (flag_wait_break_perehod_sost) + { + if (pause_detect_error(&time_wait_perehod_sost,TIME_WAIT_PEREHOD_SOST_ON_OFF,1)==1) + flag_wait_break_perehod_sost = 0; + } + + if (flag_wait_break_perehod_sost==0) + { + if ((pause_detect_error(&time_wait_rele_on,TIME_WAIT_RELE_RASCEPITEL_ON,1)==0)/* && edrk.from_ing1.bits.RASCEPITEL_ON==0*/) + { + perehod_sost = 1; + edrk.to_ing.bits.RASCEPITEL_ON = 1; + } + else + edrk.to_ing.bits.RASCEPITEL_ON = 0; + + if (edrk.flag_second_PCH==0) + r = pause_detect_error(&time_wait_answer_on,TIME_WAIT_ANSWER_RASCEPITEL_ON_BS1,1); + else + if (edrk.flag_second_PCH==1) + r = pause_detect_error(&time_wait_answer_on,TIME_WAIT_ANSWER_RASCEPITEL_ON_BS2,1); + else + r = 0; + + if (r==0) + { + + } + else + { + if (edrk.from_ing1.bits.RASCEPITEL_ON==1) + Rele_Ok = 1; + +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + Rele_Ok = 1; +#else + if (edrk.from_ing1.bits.RASCEPITEL_ON==0) + { + edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER |= 1; + Rele_Ok = 0; + } +#endif + perehod_sost = 0; + } + + time_wait_rele_off = 0; + time_wait_answer_off = 0; + } + } + else + { + Rele_Ok = 0; + time_wait_rele_on = 0; + time_wait_answer_on = 0; + + if (perehod_sost && cmd_rele!=prev_cmd_rele && flag_wait_break_perehod_sost==0) + { + flag_wait_break_perehod_sost = 1; + time_wait_perehod_sost = 0; + } + + edrk.to_ing.bits.RASCEPITEL_ON = 0; + + if (flag_wait_break_perehod_sost) + { + if (pause_detect_error(&time_wait_perehod_sost,TIME_WAIT_PEREHOD_SOST_ON_OFF,1)==1) + flag_wait_break_perehod_sost = 0; + } + + if (flag_wait_break_perehod_sost==0) + { + + if (pause_detect_error(&time_wait_rele_off,TIME_WAIT_RELE_RASCEPITEL_OFF,1)==0/* && edrk.from_ing1.bits.RASCEPITEL_ON==1*/) + { + edrk.to_ing.bits.RASCEPITEL_OFF = 1; + perehod_sost = 1; + } + else + edrk.to_ing.bits.RASCEPITEL_OFF = 0; + + + if (pause_detect_error(&time_wait_answer_off,TIME_WAIT_ANSWER_RASCEPITEL_OFF,1)==0) + { + + } + else + { + +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + +#else + if (edrk.from_ing1.bits.RASCEPITEL_ON == 1) + edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER |= 1; +#endif + perehod_sost = 0; + + } + + } + + +// if (prev_error!=edrk.summ_errors && edrk.summ_errors) +// { +// if (pause_detect_error(&time_wait_rele_off,TIME_WAIT_RELE_RASCEPITEL_OFF,1)==1) +// time_wait_rele_off = 0; +// } + + + } + + + + if (edrk.from_ing1.bits.RASCEPITEL_ON==1) + { + time_wait_level_off = 0; + if (edrk.flag_second_PCH==0) + { + if (pause_detect_error(&time_wait_level_on,TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF_BS1,1)==1) + filter_sost_rascepitel = 1; + } + else + { + if (pause_detect_error(&time_wait_level_on,TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF_BS2,1)==1) + filter_sost_rascepitel = 1; + } + + } + else + { + time_wait_level_on = 0; + if (pause_detect_error(&time_wait_level_off,TIME_WAIT_LEVEL_RASCEPITEL_ON_OFF,1)==1) + filter_sost_rascepitel = 0; + } + + prev_error = edrk.summ_errors; + prev_cmd_rele = cmd_rele; + + + *status_perehod = perehod_sost; + + if (filter_sost_rascepitel && perehod_sost==0 ) + *final_status_on_off = 1; +// *status_on_off = 1; + + if (filter_sost_rascepitel==0 && perehod_sost==0 ) + *final_status_on_off = 0; + + *status_on_off = filter_sost_rascepitel; + + // if (perehod_sost==1) + // *status_on_off = 2; + + return; + +} +/////////////////////////////////////////////// + + + +unsigned int sbor_shema(int mode) +{ + +// static unsigned int time_wait_sbor = 0; + static int prev_ready_final = 0; + static unsigned int time_wait_razbor = 0; + static unsigned int allow_discharge = 0, may_be_discharge=0; + int enable_sbor; + static unsigned int t1,t2, delta_t, first_run = 1, add_t1 = 0; +// static int Run_Pred_Zaryad; + + + enable_sbor = (edrk.zadanie.ZadanieU_Charge>10) && edrk.Status_Ready.bits.ready1; + + if (mode && edrk.summ_errors==0 && enable_sbor==0) + { + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_DISABLE_SBOR |= 1; + // ������ + edrk.AutoStartPump = 0; + edrk.Sbor_Mode = 0; + edrk.Razbor_Mode = 0; + edrk.time_wait_sbor = 0; + time_wait_razbor = 0; + + edrk.Run_Pred_Zaryad = 0; + edrk.Zaryad_OK = 0; + edrk.Run_QTV = 0; + edrk.Run_UMP = 0; + edrk.SborFinishOk = 0; + edrk.RunZahvatRascepitel = 0; + +// edrk.Run_Rascepitel = 0; + + edrk.Status_Sbor = 1; + first_run = 1; + edrk.enter_to_pump_stage = 0; + return (edrk.Sbor_Mode); + } + +// ���� ����� + if (mode && edrk.summ_errors==0 && enable_sbor) + { + + if (pause_detect_error(&edrk.time_wait_sbor,TIME_WAIT_SBOR,1)) + { +// if (edrk.SborFinishOk==0) + edrk.errors.e7.bits.ERROR_SBOR_SHEMA |= 1; + edrk.errors.e11.bits.ERROR_VERY_LONG_SBOR |= 1; + } + + if (first_run) + { + if (edrk.flag_another_bs_first_ready12==1 && edrk.flag_this_bs_first_ready12==0) + { + // ������ �� ��� ����������? + add_t1 = 80; // �������� 12 ��� + } + else + if (edrk.flag_another_bs_first_ready12==0 && edrk.flag_this_bs_first_ready12==1) + { + // ������ �� �� ����������? + add_t1 = 5; // �������� 1 ��� + } + else + if (edrk.flag_this_bs_first_ready12==0 && edrk.flag_another_bs_first_ready12==0) + { + // ��� ��������� ��� ��������� + if (edrk.flag_second_PCH == 1) + add_t1 = 120; // �������� 18 ��� + else + add_t1 = 80; // �������� 7 ��� + } + + + + +// if (optical_read_data.data.cmd.bit.ready_cmd==CODE_READY_CMD_READY1TO2 && edrk.flag_second_PCH == 1) +// { +// // ������ �� ��� ����������? +// add_t1 = 150; // �������� 15 ��� +// } +// else +// { +// if (edrk.flag_second_PCH == 0) +// add_t1 = 0; +// else +// add_t1 = 70; // �������� 7 ��� +// } + + first_run = 0; + } + + // ���� ������ + t1 = 10 + add_t1; + delta_t = 300;//200; + t2 = t1 + delta_t; + sbor_shema_pusk_nasos(t1,t2);//350 + + t1 = t2+30;//380 + delta_t = 700; + t2 = t1 + delta_t; + sbor_shema_pusk_zaryad(t1,t2);//1080 + + t1 = t2+10;//1090 + delta_t = 750+750+300+600;//2400 ����� ���� ����� ��� ����� �� ������ �� + t2 = t1 + delta_t; + sbor_shema_pusk_ump(t1,t2);//3490 + + t1 = t2+30; //3520 ���� 3 ��� ��� + delta_t = 200; + t2 = t1 + delta_t; + sbor_shema_pusk_qtv(t1,t2);//3720 + + t1 = t2; + delta_t = 150; + t2 = t1 + delta_t; + sbor_shema_stop_ump(t1,t2);//3870 + + // ���� ���� �� �� ������, �� ��������� ���� ����������� ����������� � ������� �� tfinish + // ����� ���� ������ � ���� �� tstart �� tfinish ���������� �� ����������� ����������� � ����� ��������� ��� ����������� + // � ����� ������ ���� ������ �� ��������� ����������� ����� ������! + t1 = t2; + delta_t = 250; + t2 = t1 + delta_t; + sbor_shema_rascepitel_level_1(t1,t2);//4120 + + // ���� ��������� ����������� �� tfinish + // ��� �� tfinish ���� ������������� ������� + t1 = t2; + delta_t = 300; + t2 = t1 + delta_t; + sbor_shema_rascepitel_level_2(t1,t2);//4420 + + t1 = t2; + delta_t = 200; + t2 = t1 + delta_t; + sbor_shema_rascepitel_level_3(t1,t2);//4620 + + // ��� ����������� ���������, �� ������ �� ���� ����������, ������� ��� ���� ���� �� ������� ���� ����������� + // ����� ����� tfinish + t1 = t2; + delta_t = 300; + t2 = t1 + delta_t; + sbor_shema_rascepitel_level_4(t1,t2);//4920 + + // ���� �� tfinish ������������� ��������� ����� �� ������� �� + // ���� �� ���������, �� ������ + t1 = t2; + delta_t = 1800; + t2 = t1 + delta_t; + sbor_shema_wait_ready_another(t1,t2);//6720 + + t1 = t2; + delta_t = 50; + t2 = t1 + delta_t; + sbor_shema_wait_finish(t1,t2);//6770 + + edrk.Razbor_Mode = 0; + edrk.RazborNotFinish = 0; + edrk.RunUnZahvatRascepitel = 0; + + if (edrk.Zaryad_OK) + may_be_discharge = 1; + + } + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // ������ ����� + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + else + { + first_run = 1; + edrk.enter_to_pump_stage = 0; + // ������ ����� + if (edrk.Razbor_Mode==0) + edrk.RazborNotFinish = 1; + + if (edrk.Status_QTV_Ok==0 && edrk.Status_UMP_Ok==0 && may_be_discharge && edrk.Razbor_Mode>100) + { + allow_discharge = 1; + may_be_discharge = 0; + } + + edrk.AutoStartPump = 0; + edrk.Sbor_Mode = 0; + edrk.time_wait_sbor = 0; + edrk.Zaryad_OK = 0; + edrk.Run_QTV = 0; + edrk.Run_UMP = 0; + edrk.SborFinishOk = 0; + edrk.Run_Pred_Zaryad = 0; + edrk.RunZahvatRascepitel = 0; + + if (edrk.Razbor_Mode==10 && edrk.Status_QTV_Ok==1) + { + // + edrk.errors.e2.bits.ERROR_RAZBOR_SHEMA |= 1; + + } + + if (edrk.Run_Rascepitel && edrk.Razbor_Mode==20 && edrk.Status_QTV_Ok==0 && edrk.Status_Rascepitel_Ok==0) + { + // �� ����������� ���� ������ ������� �� ��������, �� �� �� ������ ������-��, �� � ����� + edrk.Run_Rascepitel = 0; + edrk.Razbor_Mode=1000; // ������������ � ����� ������� + } + + + + if (edrk.Run_Rascepitel && edrk.Razbor_Mode==30 && edrk.Status_QTV_Ok==0 && edrk.Status_Rascepitel_Ok==1) + { + // ���� ������ �� �� ������, ��������� ����������� ��� ������ �������� + if (optical_read_data.data.cmd.bit.ready_cmd != CODE_READY_CMD_READY2 ) + edrk.Run_Rascepitel = 0; + else + edrk.RunUnZahvatRascepitel = 1; // ������ ������ �� ������������ + } + + + + if (edrk.Razbor_Mode>40 && edrk.Razbor_Mode<390 && (edrk.Status_QTV_Ok==0) + && edrk.RunUnZahvatRascepitel && edrk.Status_Rascepitel_Ok==1) + { + // ���� ������ �� �� ������, ��������� ����������� + // ������ �� ������� ������� ���� ��� ���� � ���� ��� ���� ��� + if (optical_read_data.data.cmd.bit.rascepitel_cmd == CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // 01 - ����� ��������� �����������, ���� ������� + { + edrk.Run_Rascepitel = 0; + edrk.RunUnZahvatRascepitel = 0; + edrk.Razbor_Mode = 390; + } + } + + + + // ���� ����������� ��������, �� ����� ���� � ����� + if (edrk.Razbor_Mode>40 && edrk.Razbor_Mode<600 && (edrk.Status_QTV_Ok==0) + && edrk.RunUnZahvatRascepitel==0 && edrk.Run_Rascepitel==0) + { + if (edrk.Status_Rascepitel_Ok == 0 ) + { + edrk.Razbor_Mode = 600; + } + } + + + + if (edrk.Razbor_Mode>390 && (edrk.Status_QTV_Ok==0) + && edrk.RunUnZahvatRascepitel && edrk.Status_Rascepitel_Ok==1 && edrk.Run_Rascepitel) + { + if (optical_read_data.data.cmd.bit.rascepitel_cmd != CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // �� ��������� ������������ ����������� ���������� ����������� ������ + { + edrk.RunUnZahvatRascepitel = 0; + edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL |= 1; + edrk.errors.e2.bits.ERROR_RAZBOR_SHEMA |= 1; + } + + } + + + + + +// +// if (edrk.Razbor_Mode==400 && (edrk.Status_QTV_Ok==0) +// && edrk.RunUnZahvatRascepitel && edrk.Status_Rascepitel_Ok==1) +// { +// // ���� ������ �� �� ������, ��������� ����������� +// // ������ �� ������� ������� ���� ��� ���� � ���� ��� ���� ��� +// if (optical_read_data.data.cmd.bit.rascepitel_cmd != CODE_RASCEPITEL_CMD_ENABLE_ON_AND_THIS_ON ) // 01 - ����� ��������� �����������, ���� ������� +// { +//// edrk.Run_Rascepitel = 0; +// edrk.RunUnZahvatRascepitel = 0; +// edrk.errors.e1.bits.NO_CONFIRM_ON_RASCEPITEL |= 1; +// edrk.errors.e2.bits.ERROR_RAZBOR_SHEMA |= 1; +// +// } +// } +// + + + + + if (edrk.Razbor_Mode==600 && edrk.Status_QTV_Ok==0 + && edrk.Run_Rascepitel == 0 + && edrk.Status_Rascepitel_Ok==1 ) + { +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + +#else + // ����������� �� ����������! + if (edrk.Run_Rascepitel_from_RS==0) // � ��� ������� ���������� �� rs232? + { + edrk.errors.e6.bits.RASCEPITEL_ERROR_NOT_ANSWER |= 1; + edrk.errors.e2.bits.ERROR_RAZBOR_SHEMA |= 1; + } +#endif + } + +#if(RASCEPITEL_MANUAL_ALWAYS_ON==1) + + edrk.RazborNotFinish = 0; + edrk.RunUnZahvatRascepitel = 0; + edrk.Razbor_Mode=650; // ������������ � ����� ������� + + +#else + + // ��� ��, ��� �����������, ������ �������� + if (edrk.Run_Rascepitel==0 && edrk.Razbor_Mode>20 && edrk.Status_QTV_Ok==0 && (edrk.Status_Rascepitel_Ok==0 || edrk.Run_Rascepitel_from_RS==1) ) + { + edrk.RazborNotFinish = 0; + edrk.RunUnZahvatRascepitel = 0; + edrk.Razbor_Mode=650; // ������������ � ����� ������� + } +#endif + +// edrk.Run_Rascepitel = 0; + + if (edrk.Razbor_Mode>650) + { + time_wait_razbor = 0; + } + else + edrk.Razbor_Mode++; + + } + + + if (edrk.errors.e7.bits.ERROR_SBOR_SHEMA) + { + // ������ + edrk.AutoStartPump = 0; + edrk.Sbor_Mode = 0; + edrk.Run_Pred_Zaryad = 0; + edrk.time_wait_sbor = 0; + edrk.Zaryad_OK = 0; + edrk.Run_QTV = 0; + edrk.Run_UMP = 0; + edrk.SborFinishOk = 0; + edrk.RunZahvatRascepitel = 0; +// edrk.Run_Rascepitel = 0; // ��������� �����������, ���� �������� � ������ ��� ������???? + + } + + + ////////////////////////////////////// + ////////////////////////////////////// + + edrk.Status_Charge = zaryad_on_off(edrk.Run_Pred_Zaryad); + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_UMP]==1 || edrk.Status_Ready.bits.ImitationReady2) + { + edrk.Status_UMP_Ok = edrk.Run_UMP; + edrk.Zaryad_UMP_Ok = 1; + edrk.to_shema.bits.UMP_ON_OFF = 0; + } + else + { + edrk.Status_UMP_Ok = ump_on_off(edrk.Run_UMP); + edrk.Zaryad_UMP_Ok = detect_zaryad_ump(); + } + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_DISABLE_ON_QTV]==1 || edrk.Status_Ready.bits.ImitationReady2) + { + edrk.Status_QTV_Ok = edrk.Run_QTV; + edrk.to_shema.bits.QTV_ON_OFF = 0; + edrk.to_shema.bits.QTV_ON = 0; + } + else + edrk.Status_QTV_Ok = qtv_on_off(edrk.Run_QTV); + + rascepitel_on_off ( edrk.Run_Rascepitel || edrk.Run_Rascepitel_from_RS, + &edrk.Status_Perehod_Rascepitel, + &edrk.Status_Rascepitel_Ok, + &edrk.Final_Status_Rascepitel + ); + + + ////////////////////////////////////// + ////////////////////////////////////// + + + + + + + ////////////////////////////////////// + ////////////////////////////////////// + + + if (control_station.active_array_cmd[CONTROL_STATION_CMD_MANUAL_DISCHARGE]==1 && edrk.SborFinishOk==0) + edrk.ManualDischarge = 1; + else + edrk.ManualDischarge = 0; + + if (allow_discharge && edrk.SborFinishOk == 0) + { + edrk.Discharge = 1; + allow_discharge = 0; + } + + + if ( edrk.Zaryad_OK == 1 && edrk.Status_QTV_Ok==1 && edrk.Status_Rascepitel_Ok) + edrk.Status_Ready.bits.ready7 = 1; + else + edrk.Status_Ready.bits.ready7 = 0; + +// if (edrk.StatusPumpFanAll) +// edrk.Status_Ready.bits.ready1 = 1; +// else +// edrk.Status_Ready.bits.ready1 = 0; + + if (edrk.Run_Pred_Zaryad) + edrk.Status_Ready.bits.ready2 = 1; + else + edrk.Status_Ready.bits.ready2 = 0; + + if (edrk.Zaryad_OK) + edrk.Status_Ready.bits.ready3 = 1; + else + edrk.Status_Ready.bits.ready3 = 0; + + if (edrk.Status_QTV_Ok) + edrk.Status_Ready.bits.ready4 = 1; + else + edrk.Status_Ready.bits.ready4 = 0; + + if (edrk.SborFinishOk || edrk.Status_Ready.bits.ImitationReady2==1) + edrk.Status_Ready.bits.ready5 = 1; + else + edrk.Status_Ready.bits.ready5 = 0; + + if (edrk.ms.ready3 || edrk.ms.another_bs_maybe_on==0) + edrk.Status_Ready.bits.ready6 = 1; + else + edrk.Status_Ready.bits.ready6 = 0; + + + if (edrk.Status_Ready.bits.ready5==1 && edrk.Status_Ready.bits.ready6==1 && edrk.Status_Ready.bits.MasterSlaveActive) + { + if (edrk.Status_Ready.bits.ImitationReady2) + edrk.Status_Ready.bits.preImitationReady2 = 1; + edrk.Status_Ready.bits.ready_final = 1; + } + else + { + edrk.Status_Ready.bits.ready_final = 0; + edrk.Status_Ready.bits.preImitationReady2 = 0; + } + + if (edrk.Status_Ready.bits.ready_final && prev_ready_final==0) + edrk.count_sbor++; + + prev_ready_final = edrk.Status_Ready.bits.ready_final; + + return (edrk.Sbor_Mode); +} + + + + + +unsigned int imit_signals_rascepitel(unsigned int *counter, unsigned int max_pause, unsigned int s, unsigned int cmd_clear) +{ + if (cmd_clear==1) + { + (*counter) = 0; + return 0; + } + + if (s) + { + if ((*counter)>=max_pause) + return 1; + else + (*counter)++; + + return 0; + } + + if (s==0) + { + if ((*counter)==0) + return 0; + else + (*counter)--; + + return 1; + } + return 0; +} + + +#define TIME_WAIT_OFF_BLOCK_KEY 100 +void auto_block_key_on_off(void) +{ + static unsigned int count_err = TIME_WAIT_OFF_BLOCK_KEY; + + if (edrk.SumSbor && edrk.enter_to_pump_stage) + { + edrk.Status_Ready.bits.Batt = 1; + edrk.to_ing.bits.BLOCK_KEY_OFF = 0; + count_err = 0; + } + + if (filter.iqU_1_long >= U_LEVEL_ON_BLOCK_KEY || filter.iqU_2_long >= U_LEVEL_ON_BLOCK_KEY) + { + edrk.Status_Ready.bits.Batt = 1; + edrk.to_ing.bits.BLOCK_KEY_OFF = 0; + count_err = 0; + } + + if (filter.iqU_1_long <= U_LEVEL_OFF_BLOCK_KEY && filter.iqU_2_long <= U_LEVEL_OFF_BLOCK_KEY && edrk.SumSbor==0) + { + if (pause_detect_error(&count_err,TIME_WAIT_OFF_BLOCK_KEY,1)) + { + edrk.to_ing.bits.BLOCK_KEY_OFF = 1; + edrk.Status_Ready.bits.Batt = 0; + } + } + else + count_err = 0; + + +} + + +/////////////////////////////////////////////// + + diff --git a/Inu/Src/main/sbor_shema.h b/Inu/Src/main/sbor_shema.h new file mode 100644 index 0000000..fdde9ff --- /dev/null +++ b/Inu/Src/main/sbor_shema.h @@ -0,0 +1,24 @@ +/* + * sbor_shema.h + * + * Created on: 18 ����. 2021 �. + * Author: stud + */ + +#ifndef SRC_MAIN_SBOR_SHEMA_H_ +#define SRC_MAIN_SBOR_SHEMA_H_ + + +#define U_LEVEL_ON_BLOCK_KEY 559240 // 100V +#define U_LEVEL_OFF_BLOCK_KEY 279620 // 50V + +unsigned int sbor_shema(int mode); +void rascepitel_on_off(unsigned int flag, int *status_perehod, int *status_on_off, int *final_status_on_off); +void auto_block_key_on_off(void); + +unsigned int imit_signals_rascepitel(unsigned int *counter, unsigned int max_pause, unsigned int s, unsigned int cmd_clear); +void set_status_pump_fan(void); + + + +#endif /* SRC_MAIN_SBOR_SHEMA_H_ */ diff --git a/Inu/Src/main/sim_model.c b/Inu/Src/main/sim_model.c new file mode 100644 index 0000000..a84fa72 --- /dev/null +++ b/Inu/Src/main/sim_model.c @@ -0,0 +1,222 @@ +/* + * sim_model.c + * + * Created on: 30 ���. 2024 �. + * Author: yura + */ + +#if (_SIMULATE_AC==1) + +#ifdef __TI_COMPILER_VERSION__ +#pragma SET_DATA_SECTION(".slow_vars") +#endif + +//#include "math.h" + + +#include "V_MotorModel.h" +//#include "V_MotorParams.h" +//#include <V_IQmath.h> +#include "IQmathLib.h" +//#include "main.h" + +#include "v_pwm24_v2.h" +#include "edrk_main.h" +#include "params_norma.h" +#include "adc_tools.h" +#include "filter_v1.h" +#include "mathlib.h" +#include "v_rotor_22220.h" + +//������ ����������������� ��� ������� � ������ ���������� +//#pragma DATA_SECTION(sim_model, ".slow_vars") +TMotorModel sim_model = MOTOR_MODEL_DEFAULTS; + + + +void sim_model_init(void) +{ + + //model.motorInternals.udc = 540; //�������� ����� ������� �������� + + sim_model.motorInternals.udc = 540; //�������� ����� ������� �������� + sim_model.tpr = svgen_pwm24_1.Tclosed_high;//450; //������ ������� ��� + sim_model.cmpr0 = svgen_pwm24_1.Tclosed_high/2; + sim_model.cmpr1 = svgen_pwm24_1.Tclosed_high/2; + sim_model.cmpr2 = svgen_pwm24_1.Tclosed_high/2; + sim_model.cmpr3 = svgen_pwm24_1.Tclosed_high/2; + + + sim_model.MotorParametersNum = 10;// + sim_model.dt = 0;//_IQ4mpy(_IQ4(150 / 4), pwm.DeadBand >> 20) >> 4; //�������� �������� ������� + + //����� ������� ������������� ������ ��������� + sim_model.Init(&sim_model); //������ ��������� + + + + sim_model.Init(&sim_model); + +} + +void sim_model_execute(void) +{ + //�������� ������� ����������� �������� ��� � ������ + sim_model.cmpr0 = svgen_pwm24_1.Ta_imp/2 + svgen_pwm24_1.Tclosed_high/2;//PWM0->CMPA_bit.CMPA; + sim_model.cmpr1 = svgen_pwm24_1.Tb_imp/2 + svgen_pwm24_1.Tclosed_high/2;//PWM1->CMPA_bit.CMPA; + sim_model.cmpr2 = svgen_pwm24_1.Tc_imp/2 + svgen_pwm24_1.Tclosed_high/2;;//PWM2->CMPA_bit.CMPA; + + sim_model.InvertorEna = edrk.Go;//���� ���������� ������ ��������� + + //����� ������� ��������� ������� ������ ��������� + sim_model.Execute(&sim_model); + +} + + +void calc_norm_ADC_0_sim(int run_norma) +{ + _iq a1,a2,a3; + +#if (1) + +#if (_FLOOR6) + analog.iqU_1 = _IQ(sim_model.motorInternals.udc/NORMA_ACP/2.0);// iq_norm_ADC[0][0] - analog_zero.iqU_1 + analog.iqU_1_imit; + analog.iqU_2 = analog.iqU_1;//iq_norm_ADC[0][1] - analog_zero.iqU_2 + analog.iqU_1_imit; +#else + analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1; + analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2; +#endif + + analog.iqIu_1 = _IQ(sim_model.motorInternals.isPhaseA/NORMA_ACP/2.0); + analog.iqIv_1 = _IQ(sim_model.motorInternals.isPhaseB/NORMA_ACP/2.0); + analog.iqIw_1 = _IQ(sim_model.motorInternals.isPhaseC/NORMA_ACP/2.0); + + analog.iqIu_2 = analog.iqIu_1; + analog.iqIv_2 = analog.iqIv_1; + analog.iqIw_2 = analog.iqIw_1; + + analog.iqIin_1 = 0;//_IQ(sim_model.motorInternals.power/sim_model.motorInternals.udc/NORMA_ACP/2.0); //-iq_norm_ADC[0][9]; // ������ ���������� + analog.iqIin_2 = analog.iqIin_1;//-iq_norm_ADC[0][9]; // ������ ���������� + + analog.iqUin_A1B1 = 0;//iq_norm_ADC[0][10]; + +// ��� �������� ����������� �������� 23550.1 ����� ���������� - �� ����� +// 23550.1 + + analog.iqUin_B1C1 = 0;//iq_norm_ADC[0][11]; // 23550.1 + analog.iqUin_A2B2 = 0;//iq_norm_ADC[0][12]; // 23550.1 + +// 23550.3 bs1 bs2 + +// analog.iqUin_B1C1 = iq_norm_ADC[0][12]; // 23550.3 +// analog.iqUin_A2B2 = iq_norm_ADC[0][11]; // 23550.3 +// + analog.iqUin_B2C2 = 0;//iq_norm_ADC[0][13]; + + analog.iqIbreak_1 = 0;//iq_norm_ADC[0][14]; + analog.iqIbreak_2 = 0;//iq_norm_ADC[0][15]; + +#else + analog.iqU_1 = analog.iqIu_1 = analog.iqIu_2 = analog.iqIv_1 = analog.iqIv_2 = + analog.iqIw_1 = analog.iqIw_2 = analog.iqIin_1 = analog.iqIin_2 = analog.iqUin_A1B1 = + analog.iqUin_B1C1 = analog.iqUin_A2B2 = analog.iqUin_B2C2 = analog.iqIbreak_1 = analog.iqIbreak_2 + = 0; +#endif + + analog.iqUin_C1A1 = -(analog.iqUin_A1B1 + analog.iqUin_B1C1); + analog.iqUin_C2A2 = -(analog.iqUin_A2B2 + analog.iqUin_B2C2); + + + + filter.iqU_1_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_1_long, analog.iqU_1); + filter.iqU_2_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_2_long, analog.iqU_2); + + +// analog.iqU_1_fast = filter_U1_3point(analog.iqU_1_fast); + filter.iqU_1_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_1_fast, analog.iqU_1); + filter.iqU_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_2_fast, analog.iqU_2); + + +// filter.iqUzpt_2_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqUzpt_2_2_fast, analog.iqUzpt_2_2); + + + +//15 + + + analog.iqIm_1 = im_calc(analog.iqIu_1, analog.iqIv_1, analog.iqIw_1); + analog.iqIm_2 = im_calc(analog.iqIu_2, analog.iqIv_2, analog.iqIw_2); + + analog.iqIu = analog.iqIu_1+analog.iqIu_2; + analog.iqIv = analog.iqIv_1+analog.iqIv_2; + analog.iqIw = analog.iqIw_1+analog.iqIw_2; + + analog.iqIm = im_calc(analog.iqIu, analog.iqIv, analog.iqIw); + + + analog.iqIin_sum = analog.iqIin_1+analog.iqIin_2; + +// analog.iqIm_3 = im_calc(analog.iqIa1_1_fir_n+analog.iqIa2_1_fir_n, analog.iqIb1_1_fir_n+analog.iqIb2_1_fir_n, analog.iqIc1_1_fir_n+analog.iqIc2_1_fir_n); + + analog.iqUin_m1 = im_calc(analog.iqUin_A1B1, analog.iqUin_B1C1, analog.iqUin_C1A1); + analog.iqUin_m2 = im_calc(analog.iqUin_A2B2, analog.iqUin_B2C2, analog.iqUin_C2A2); + +// analog.iqUin_m2 = im_calc(analog.UinA2, analog.UinB2, analog.UinC2); + + filter.iqUin_m1 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m1, analog.iqUin_m1); + filter.iqUin_m2 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m2, analog.iqUin_m2); + + + +// i_led1_on_off(0); +// i_led1_on_off(1); + +//1 + + filter.iqIm_1 = exp_regul_iq(koef_Im_filter, filter.iqIm_1, analog.iqIm_1); + filter.iqIm_2 = exp_regul_iq(koef_Im_filter, filter.iqIm_2, analog.iqIm_2); + filter.iqIm = exp_regul_iq(koef_Im_filter, filter.iqIm, analog.iqIm); + + filter.iqIin_sum = exp_regul_iq(koef_Im_filter, filter.iqIin_sum, analog.iqIin_sum); + +//3 +// filter_batter2_Iin.InpVarCurr = (analog.iqIin_1)-ZERO_I_IN; + // filter_batter2_Iin.calc(&filter_batter2_Iin); + +// filter.iqIin = _IQmpy(filter_batter2_Iin.Out,_IQ_09); + + + filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); + filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); + + a1 = analog.iqU_1+analog.iqU_2; + a2 = analog.iqIin_1; + a3 = _IQmpy(a1,a2); + analog.PowerScalar = a3; +// filter.Power = analog.iqU_1+analog.iqU_2; + filter.PowerScalar = exp_regul_iq(koef_Power_filter, filter.PowerScalar, analog.PowerScalar); + filter.PowerScalarFilter2 = exp_regul_iq(koef_Power_filter2, filter.PowerScalarFilter2, filter.PowerScalar); + +} + + + +void calc_rotors_sim(void) +{ + rotor_22220.direct_rotor = 1; + rotor_22220.iqF = _IQ(sim_model.motorInternals.omega_rpm/60.0/NORMA_FROTOR); + + + rotor_22220.iqFout = exp_regul_iq(koef_Wout_filter, rotor_22220.iqFout, rotor_22220.iqF); + rotor_22220.iqFlong = exp_regul_iq(koef_Wout_filter_long, rotor_22220.iqFlong, rotor_22220.iqF); + +} + + + +//#ifdef __TI_COMPILER_VERSION__ +//#pragma RESET_DATA_SECTION +//#endif + +#endif diff --git a/Inu/Src/main/sim_model.h b/Inu/Src/main/sim_model.h new file mode 100644 index 0000000..9a27c91 --- /dev/null +++ b/Inu/Src/main/sim_model.h @@ -0,0 +1,21 @@ +/* + * sim_model.h + * + * Created on: 30 ���. 2024 �. + * Author: yura + */ + +#ifndef SRC_MAIN_SIM_MODEL_H_ +#define SRC_MAIN_SIM_MODEL_H_ + +#include "V_MotorModel.h" + +void sim_model_init(void); +void sim_model_execute(void); +void calc_norm_ADC_0_sim(int run_norma); +void calc_rotors_sim(void); + + +extern TMotorModel sim_model; + +#endif /* SRC_MAIN_SIM_MODEL_H_ */ diff --git a/Inu/Src/main/sync_tools.c b/Inu/Src/main/sync_tools.c new file mode 100644 index 0000000..ee9ee9d --- /dev/null +++ b/Inu/Src/main/sync_tools.c @@ -0,0 +1,520 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File + +#include <params.h> +#include <sync_tools.h> +#include <vector.h> + +#include "big_dsp_module.h" +#include "MemoryFunctions.h" +#include "Spartan2E_Adr.h" +#include "Spartan2E_Functions.h" +#include "TuneUpPlane.h" +#include "pwm_test_lines.h" +#include "xp_write_xpwm_time.h" +#include "profile_interrupt.h" + +#include "edrk_main.h" +#define SIZE_SYNC_BUF 20 + +//#pragma DATA_SECTION(logbuf_sync1,".fa"); +unsigned int logbuf_sync1[SIZE_SYNC_BUF]; +unsigned int c_logbuf_sync1=0; + +//unsigned int capnum0; +//unsigned int capnum1; +//unsigned int capnum2; +//unsigned int capnum3; + +int delta_capnum = 0; +int delta_error = 0; +//int level_find_sync_zero = LEVEL_FIND_SYNC_ZERO; +unsigned int temp; + +unsigned int count_error_sync = 0; + +unsigned int count_timeout_sync = 0; +//unsigned int enable_profile_led1_sync = 1; +//unsigned int enable_profile_led2_sync = 0; + +SYNC_TOOLS_DATA sync_data=SYNC_TOOLS_DATA_DEFAULT; + + +#pragma CODE_SECTION(calculate_sync_detected,".fast_run2"); +void calculate_sync_detected(void) +{ + + + +// if (capnum0 > 1000) { +// return; +// } +// sync_data.level_find_sync_zero = LEVEL_FIND_SYNC_ZERO; + + delta_capnum = sync_data.capnum0 - sync_data.capnum1; + + if (delta_capnum > 0) //������ + { + sync_data.pwm_freq_plus_minus_zero = -1;//1; + + if (count_error_sync < MAX_COUNT_ERROR_SYNC) { + count_error_sync++; + count_error_sync++; + count_error_sync++; + } else + sync_data.local_flag_sync_1_2 = 0; + } + else + if (delta_capnum < 0) //����� + { + + if (sync_data.capnum0 > sync_data.level_find_sync_zero) + { + delta_error = sync_data.capnum0 - sync_data.level_find_sync_zero; + + if (delta_error > 50) { + if (count_error_sync < MAX_COUNT_ERROR_SYNC) { + count_error_sync++; + count_error_sync++; + count_error_sync++; + } else + sync_data.local_flag_sync_1_2 = 0; + } else { + if (count_error_sync > 0) { + count_error_sync--; + } + if (count_error_sync == 0) + sync_data.local_flag_sync_1_2 = 1; + } + sync_data.pwm_freq_plus_minus_zero = 1; + } + else + if (sync_data.capnum0 < sync_data.level_find_sync_zero) + { + + delta_error = sync_data.level_find_sync_zero - sync_data.capnum0; + + if (delta_error > 50) { + if (count_error_sync < MAX_COUNT_ERROR_SYNC) { + count_error_sync++; + count_error_sync++; + count_error_sync++; + } else + sync_data.local_flag_sync_1_2 = 0; + } else { + if (count_error_sync > 0) { + count_error_sync--; + } + if (count_error_sync == 0) + sync_data.local_flag_sync_1_2 = 1; + } + + sync_data.pwm_freq_plus_minus_zero = -1; + + } + else + { + sync_data.pwm_freq_plus_minus_zero = 0; + sync_data.local_flag_sync_1_2 = 1; + count_error_sync = 0; + } + } else + sync_data.pwm_freq_plus_minus_zero = 0; + + sync_data.delta_error_sync = delta_error; + sync_data.delta_capnum = sync_data.capnum0 - sync_data.level_find_sync_zero; //delta_capnum; + sync_data.count_error_sync = count_error_sync; + + +} + + +#pragma CODE_SECTION(sync_detected,".fast_run2"); +void sync_detected(void) +{ + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_18_ON; +#endif + + sync_data.latch_interrupt = 1; + // stop_sync_interrupt(); + + + // i_led2_on_off(1); + + // //Enable more interrupts from this capture + // EvbRegs.EVBIMRC.bit.CAP6INT = 0; + + // if (edrk.disable_interrupt_sync==0) + + +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// sync_data.capnum0 = ReadMemory(ADR_SAW_VALUE); + +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// sync_data.capnum0 = ReadMemory(ADR_SAW_VALUE); + + // pause_1000(1); + + WriteMemory(ADR_SAW_REQUEST, 0x8000); + sync_data.capnum1 = ReadMemory(ADR_SAW_VALUE); + + WriteMemory(ADR_SAW_REQUEST, 0x8000); + sync_data.capnum1 = ReadMemory(ADR_SAW_VALUE); + + sync_data.count_timeout_sync = 0; + sync_data.timeout_sync_signal = 0; + + logbuf_sync1[c_logbuf_sync1++] = sync_data.capnum0; +// logbuf_sync1[c_logbuf_sync1++] = sync_data.capnum1; + + if (c_logbuf_sync1==SIZE_SYNC_BUF) + c_logbuf_sync1=0; + + + if (sync_data.count_pause_ready < MAX_COUNT_PAUSE_READY) { + sync_data.count_pause_ready++; + sync_data.count_pause_ready++; + } else + sync_data.sync_ready = 1; + +//////////////////////////////////// + + // calculate_sync_detected(); + + + +// sync_data.capnum0 = capnum0; + + + + // + // stop_sync_interrupt(); + // EvbRegs.EVBIFRC.all = BIT2; + // + + + // // Acknowledge interrupt to receive more interrupts from PIE group 5 + // PieCtrlRegs.PIEACK.all = PIEACK_GROUP5; + + // if (edrk.disable_interrupt_sync==0) + // { + //// //Enable more interrupts from this capture + //// EvbRegs.EVBIMRC.bit.CAP6INT = 1; + //// + //// //use mask to clear EVAIFRA register + //// EvbRegs.EVBIFRC.bit.CAP6INT = 1; + // } + + //Enable more interrupts from this capture +// EvbRegs.EVBIMRC.bit.CAP6INT = 1; + + //use mask to clear EVAIFRA register +// EvbRegs.EVBIFRC.bit.CAP6INT = 1; + + + + + // DINT; + // PieCtrlRegs.PIEIER5.all = TempPIEIER; + + // return; + + + + // IER &= ~(M_INT5); + + //Enable more interrupts from this capture + // EvbRegs.EVBIMRC.bit.CAP6INT = 1; + + // Note: To be safe, use a mask value to write to the entire + // EVAIFRA register. Writing to one bit will cause a read-modify-write + // operation that may have the result of writing 1's to clear + // bits other then those intended. + //use mask to clear EVAIFRA register + // EvbRegs.EVBIFRC.bit.CAP6INT = 1; + // EvbRegs.EVBIFRC.all = BIT2; + + // IER &= ~(M_INT5); + + + // asm(" NOP;"); + + // i_led2_on_off(0); + + + // start_sync_interrupt(); + // EvbRegs.EVBIMRC.bit.CAP6INT = 1; + // Clear CAPINT6 interrupt flag + + // Acknowledge interrupt to receive more interrupts from PIE group 5 + // PieCtrlRegs.PIEACK.all = PIEACK_GROUP5; + + sync_data.count_interrupts++; + +#if(_ENABLE_PWM_LINES_FOR_TESTS_SYNC) + PWM_LINES_TK_18_OFF; +#endif + +} + + +//static long k_3=50; + +#pragma CODE_SECTION(Sync_handler,".fast_run2"); +interrupt void Sync_handler(void) { + + // Set interrupt priority: + volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER5.all; + IER |= M_INT5; + IER &= MINT5; // Set "global" priority + PieCtrlRegs.PIEIER5.all &= MG57; // Set "group" priority + PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts + + WriteMemory(ADR_SAW_REQUEST, 0x8000); + sync_data.capnum0 = ReadMemory(ADR_SAW_VALUE); + + stop_sync_interrupt_local(); // ��������� ����������, �������� �� �� �������, ���� �������� �������� ��� ������ ������. + + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.sync) + i_led1_on_off_special(1); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.sync) + i_led2_on_off_special(1); +#endif + + EINT; + +// i_led2_on_off(1); + + // Insert ISR Code here....... + sync_detected(); +// pause_1000(k_3); + // Next line for debug only (remove after inserting ISR Code): + //ESTOP0; + +// i_led2_on_off(0); + + // Enable more interrupts from this timer +// EvbRegs.EVBIMRC.bit.CAP6INT = 1; + // Note: To be safe, use a mask value to write to the entire + // EVBIFRA register. Writing to one bit will cause a read-modify-write + // operation that may have the result of writing 1's to clear + // bits other then those intended. + EvbRegs.EVBIFRC.all = BIT2; + // Acknowledge interrupt to recieve more interrupts from PIE group 5 +// PieCtrlRegs.PIEACK.all |= PIEACK_GROUP5; + + // Restore registers saved: + DINT; + PieCtrlRegs.PIEIER5.all = TempPIEIER; + +#if (_ENABLE_INTERRUPT_PROFILE_LED1) + if (profile_interrupt.for_led1.bits.sync) + i_led1_on_off_special(0); +#endif +#if (_ENABLE_INTERRUPT_PROFILE_LED2) + if (profile_interrupt.for_led2.bits.sync) + i_led2_on_off_special(0); +#endif + + +} + +void setup_sync_int(void) { + +// return; + +// EALLOW; + + if (edrk.flag_second_PCH==1) + sync_data.level_find_sync_zero = xpwm_time.pwm_tics+5; + else + sync_data.level_find_sync_zero = LEVEL_FIND_SYNC_ZERO; + + sync_data.timeout_sync_signal = 0; + sync_data.count_timeout_sync = 0; + +// sync_data.what_main_pch = 1; // ������ �� +// sync_data.what_main_pch = 2; // ������ �� + sync_data.what_main_pch = 0; // ����� �� + + + +///////////////////////////////////////////// + +// EvbRegs.EVBIFRC.bit.CAP6INT = 1; //Resets flag EVB Interrupt Flag Register + EvbRegs.EVBIFRC.all = BIT2; //Resets flag EVB Interrupt Flag Register + EvbRegs.EVBIMRC.bit.CAP6INT = 0; //1 //SET flag EVB Interrupt Mask Register C + // CAP6INT ENABLE + //0 Disable + //1 Enable + + +///////////////////////////////////////////// + EvbRegs.T4PR = 0xFFFF; //Set timer period + EvbRegs.T4CNT = 0; // Clear timer counter + + EvbRegs.T4CON.all = 0; // Disable timer + EvbRegs.T4CON.bit.FREE = 1; // FREE/SOFT, 00 = stop immediately on emulator suspend + EvbRegs.T4CON.bit.SOFT = 0; + EvbRegs.T4CON.bit.TMODE = 2; //TMODEx, 10 = continuous-up count mode + EvbRegs.T4CON.bit.TPS = 0; //TPSx, 111 = x/1 prescaler + EvbRegs.T4CON.bit.TENABLE = 0; // TENABLE, 1 = enable timer + EvbRegs.T4CON.bit.TCLKS10 = 0; //TCLKS, 00 = HSPCLK is clock source + EvbRegs.T4CON.bit.TCLD10 = 0; //Timer compare register reload condition, 00 When counter is 0 + EvbRegs.T4CON.bit.TECMPR = 1; // TECMPR, 1 = Enable timer compare operation + EvbRegs.T4CON.bit.SET3PR = 0; // SELT3PR: 0 - Use own period register + + +//////////////////////////////////////////////////// + EvbRegs.CAPCONB.all = 0; // Clear + + EvbRegs.CAPCONB.bit.CAP6EDGE = 2; //3:2 Edge Detection for Unit 6 + //Edge detection control for Capture Unit 6. +// 00 No detection +// 01 Detects rising edge +// 10 Detects falling edge +// 11 Detects both edges + + EvbRegs.CAPCONB.bit.CAP6TSEL = 0; // GP Timer selection for Unit 6 +// GP timer selection for Capture Units 4 and 5 +// 0 Selects GP timer 4 +// 1 Selects GP timer 3 + EvbRegs.CAPFIFOB.bit.CAP6FIFO = 0; //CAP6 FIFO status + EvbRegs.CAPCONB.bit.CAP6EN = 1; //Enables Capture Unit 6 +///////////////////////////////////////// + + + EALLOW; + PieVectTable.CAPINT6 = &Sync_handler; //?CAP????????????????? + EDIS; + + + PieCtrlRegs.PIEIER5.bit.INTx7 = 1; + + + +} + +void start_sync_interrupt(void) +{ + EvbRegs.EVBIFRC.all = BIT2; //Resets flag EVB Interrupt Flag Register + + IER |= M_INT5; // @suppress("Symbol is not resolved") +// PieCtrlRegs.PIEIER5.bit.INTx7 = 1; + + EvbRegs.EVBIMRC.bit.CAP6INT = 1; //SET flag EVB Interrupt Mask Register C + // //use mask to clear EVAIFRA register +// PieCtrlRegs.PIEACK.all |= PIEACK_GROUP5; + sync_data.latch_interrupt = 0; + sync_data.enabled_interrupt = 1; + +} + +void stop_sync_interrupt(void) +{ + sync_data.latch_interrupt = 0; + sync_data.enabled_interrupt = 0; + + IER &= ~(M_INT5); // @suppress("Symbol is not resolved") +// PieCtrlRegs.PIEIER5.bit.INTx7 = 0; + EvbRegs.EVBIMRC.bit.CAP6INT = 0; //SET flag EVB Interrupt Mask Register C + EvbRegs.EVBIFRC.all = BIT2; //Resets flag EVB Interrupt Flag Register +// PieCtrlRegs.PIEACK.all |= PIEACK_GROUP5; +} + +void stop_sync_interrupt_local(void) +{ + sync_data.latch_interrupt = 0; + + IER &= ~(M_INT5); // @suppress("Symbol is not resolved") + EvbRegs.EVBIMRC.bit.CAP6INT = 0; //SET flag EVB Interrupt Mask Register C + EvbRegs.EVBIFRC.all = BIT2; //Resets flag EVB Interrupt Flag Register +} + + +void setup_sync_line(void) { + + // output + EALLOW; + GpioMuxRegs.GPBMUX.bit.TCLKINB_GPIOB12 = 0; + GpioMuxRegs.GPBDIR.bit.GPIOB12 = 1; + EDIS; + + //input + EALLOW; + GpioMuxRegs.GPBMUX.bit.CAP6QI2_GPIOB10 = 1;// Configure as CAP6 +// GpioMuxRegs.GPBDIR.bit.GPIOB10 = 1; + EDIS; + +} + +#pragma CODE_SECTION(sync_inc_error,".fast_run"); +void sync_inc_error(void) +{ + + + if (sync_data.count_pause_ready > 0) { + sync_data.count_pause_ready--; + } else + sync_data.sync_ready = 0; + + + if (sync_data.count_timeout_sync < MAX_COUNT_TIMEOUT_SYNC) + { + sync_data.count_timeout_sync++; + } + else + { + sync_data.timeout_sync_signal = 1; + sync_data.count_pause_ready = 0; + sync_data.local_flag_sync_1_2 = 0; + } + + + if (count_error_sync < MAX_COUNT_ERROR_SYNC) { + count_error_sync++; + } else + sync_data.local_flag_sync_1_2 = 0; +} + +void clear_sync_error(void) +{ + sync_data.count_timeout_sync = 0; + sync_data.timeout_sync_signal = 0; +} + + +int get_status_sync_line(void) +{ + return !GpioDataRegs.GPBDAT.bit.GPIOB10; +} + +//int index_sync_ar = 0; +// +// +//void write_sync_logs(void) +//{ +// static int c=0; +// return; +// +//// logbuf1[index_filter_ar]=active_rect1.Id;//EvaRegs.CMPR1;//(active_rect1.pll_Ud);//svgenDQ.Wt; +//// logbuf2[index_filter_ar]=active_rect1.Iq;//EvaRegs.CMPR2;//filter.iqU_1_long;// (active_rect1.pll_Uq);//Iq; +//// logbuf3[index_filter_ar]=EvaRegs.CMPR1;//active_rect1.SetUzpt;////(active_rect1.Tetta);//abc_to_dq.Ud; +// +// index_sync_ar++; +// if (index_sync_ar>=SIZE_SYNC_BUF) +// { +// index_sync_ar=0; +// c++; +// if (c>=10) +// c=0; +// } +// +//} diff --git a/Inu/Src/main/sync_tools.h b/Inu/Src/main/sync_tools.h new file mode 100644 index 0000000..e41ee87 --- /dev/null +++ b/Inu/Src/main/sync_tools.h @@ -0,0 +1,113 @@ + + +#define LEVEL_FIND_SYNC_ZERO 10 //74 //24 +#define MAX_COUNT_ERROR_SYNC 100 +#define MAX_COUNT_TIMEOUT_SYNC 100 +#define MAX_COUNT_PAUSE_READY 100 + + + + + + + +typedef struct { + //Sync vals + int pwm_freq_plus_minus_zero; + int disable_sync; + int sync_ready; + unsigned int level_find_sync_zero; + + int delta_error_sync; + int delta_capnum; + int count_error_sync; + unsigned int capnum0; + unsigned int capnum1; + + int PWMcounterVal; + int local_flag_sync_1_2; + int global_flag_sync_1_2; + int timeout_sync_signal; + + unsigned int count_timeout_sync; + unsigned int count_pause_ready; + int enable_do_sync; + int latch_interrupt; + int enabled_interrupt; + unsigned int count_interrupts; + unsigned int what_main_pch; + + + +// int pzad_or_wzad; //given turns or power, depends on controlMode; +// int angle_pwm; //current rotor turns +// int iq_zad; // Iq_zadan +// union { +// struct { +// unsigned int wdog_tick :1; //�������� 0_1_0 � �.�. +// unsigned int statusQTV :1; //1-QTV On, QTV - off +// unsigned int master :1; // 1 -Master, 0 - not Master +// unsigned int slave :1; // 1 -Slave, 0 - not Slave +// +// unsigned int sync_1_2 :1; // 1 - yes, 0 - no ������������ ����������� +// unsigned int alarm :1; // 1 - yes, 0 - no ������ +// unsigned int ready_cmd :2; // 00 - not ready,01-ready1,10-ready1to2, 11 -ready2 +// +// unsigned int controlMode :1; // 0 - regul turns; 1 - power ����� ������ +// unsigned int ready_to_go :1; // 1 - yes, 0 - no ����� �������, ������ ������ ��� +// unsigned int start_pwm :1; // 1 - yes, 0 - no ���� ������� �� ������ ���� +// unsigned int stop_pwm :1; // 1 - yes, 0 - no ���� ������� �� ���� ���� +// +// unsigned int pwm_status :1; // 1 -On, 0 - Off ������� �������� ���� +// unsigned int err_optbus :1; // 1 - yes, 0 - no ���� optbus ���������� +// unsigned int maybe_master :1; // 1 - yes, 0 - no ������ �� ������ ������ Master +// unsigned int rascepitel :1; // 1 - yes, 0 - no ��������� ����������� +// +//// unsigned int leading_ready :1; //1 - second inverter ready to work or in work +//// unsigned int leading_Go :1; +// } bit; +// unsigned int all; +// } cmd; +} SYNC_TOOLS_DATA; + +#define SYNC_TOOLS_DATA_DEFAULT {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + +extern SYNC_TOOLS_DATA sync_data; + + + + +void setup_sync_line(void); +void sync_inc_error(void); +void setup_sync_int(void); +void start_sync_interrupt(void); +void stop_sync_interrupt(void); +void stop_sync_interrupt_local(void); + + +int get_status_sync_line(void); + +void clear_sync_error(void); + +void Sync_alg(void); +void calculate_sync_detected(void); + + + + +inline void i_sync_pin_on() +{ + EALLOW; + GpioDataRegs.GPBSET.bit.GPIOB12 = 1; + EDIS; +} + + +inline void i_sync_pin_off() +{ + EALLOW; + GpioDataRegs.GPBCLEAR.bit.GPIOB12 = 1; + EDIS; +} + + diff --git a/Inu/Src/main/synhro_tools.c b/Inu/Src/main/synhro_tools.c new file mode 100644 index 0000000..47bbc5e --- /dev/null +++ b/Inu/Src/main/synhro_tools.c @@ -0,0 +1,144 @@ +/* + * synhro_tools.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 "sync_tools.h" + +////////////////////////////////////////////////////////// +unsigned int wait_synhro_optical_bus(void) +{ + static unsigned int cmd = 0; + static unsigned int count_wait_synhro = 0; + + +// +// switch(cmd) +// { +// 0 : if (optical_read_data.data.cmd.bit.wdog_tick == 0) +// cmd = 1; +// +// break; +// +// 1 : optical_write_data.data.cmd.bit.wdog_tick = 1; +// break; +// +// +// default: break +// } + + + + return 0; +} + +////////////////////////////////////////////////////////// +void clear_wait_synhro_optical_bus(void) +{ + + // optical_read_data.data.cmd.bit.wdog_tick = 0; + // optical_write_data.data.cmd.bit.wdog_tick = 0; + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +void who_select_sync_signal(void) +{ + + if (sync_data.what_main_pch) + { + if (sync_data.what_main_pch==2) + { + // ������������� ������ !!! + if (edrk.flag_second_PCH) + sync_data.enable_do_sync = 1; + else + sync_data.enable_do_sync = 0; + return; + } + + if (sync_data.what_main_pch==1) + { + // ������������� ������ !!! + if (edrk.flag_second_PCH) + sync_data.enable_do_sync = 0; + else + sync_data.enable_do_sync = 1; + return; + } + + } + +// if (optical_read_data.status == 1) + sync_data.global_flag_sync_1_2 = (sync_data.local_flag_sync_1_2 || optical_read_data.data.cmd.bit.sync_1_2); +// else + // sync_data.global_flag_sync_1_2 = (sync_data.local_flag_sync_1_2); + + + if (sync_data.timeout_sync_signal && optical_read_data.data.cmd.bit.sync_line_detect) + { + // ���� �� �� ��������� ������, � ������ ���������, ������ �� ���� ��������� ������������� + // ���������������� ��� ���� ���. + + sync_data.enable_do_sync = 0; + + return; + } + + if (sync_data.timeout_sync_signal==0 && optical_read_data.data.cmd.bit.sync_line_detect==0) + { + // ���� �� ��������� ������, � ������ �� ���������, ������ �� ���� ������������� �������� ������������� + // ���������������� ���� ���� ���. + + sync_data.enable_do_sync = 1; + + return; + } + + if (sync_data.sync_ready && sync_data.timeout_sync_signal==0 && optical_read_data.data.cmd.bit.sync_line_detect) + { + + + if (optical_read_data.data.cmd.bit.sync_1_2 && sync_data.enable_do_sync==0) + { + // ��� ���� �������, ������ �� ���� ��� ������� � �� ��� ��� ������ + + } + else + if (optical_read_data.data.cmd.bit.sync_1_2 && sync_data.enable_do_sync==1) + { + // ��� ���� �������, ������ �� ���� ��� ������� � �� �� ��� ��� ������, � �� ��� + + } + else + { + // ��� �������������, ������ �������� ��� ��� ����� ������ � �������� + // ���� �� ��������� ������ � ������ ���������, ������ ������������� + // ���������� � ����������� �� ������ ��. + if (edrk.flag_second_PCH==0) + sync_data.enable_do_sync = 1; + else + sync_data.enable_do_sync = 0; + } + return; + } + +} + +////////////////////////////////////////////////////////// + diff --git a/Inu/Src/main/synhro_tools.h b/Inu/Src/main/synhro_tools.h new file mode 100644 index 0000000..e6de9f1 --- /dev/null +++ b/Inu/Src/main/synhro_tools.h @@ -0,0 +1,19 @@ +/* + * synhro_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_SYNHRO_TOOLS_H_ +#define SRC_MAIN_SYNHRO_TOOLS_H_ + +void who_select_sync_signal(void); + +void clear_wait_synhro_optical_bus(void); + +unsigned int wait_synhro_optical_bus(void); +void clear_wait_synhro_optical_bus(void); + + +#endif /* SRC_MAIN_SYNHRO_TOOLS_H_ */ diff --git a/Inu/Src/main/temper_p_tools.c b/Inu/Src/main/temper_p_tools.c new file mode 100644 index 0000000..c6a773a --- /dev/null +++ b/Inu/Src/main/temper_p_tools.c @@ -0,0 +1,77 @@ +/* + * temper_p_tools.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 "adc_tools.h" + +#include "temper_p_tools.h" +/////////////////////////////////////////////// +void nagrev_auto_on_off(void) +{ + //min_real_int_temper_air + +// if (edrk.temper_edrk.max_real_int_temper_water<TEMPER_NAGREF_ON) +// edrk.to_ing.bits.NAGREV_OFF = 0; +// +// if (edrk.temper_edrk.max_real_int_temper_water>TEMPER_NAGREF_OFF) +// edrk.to_ing.bits.NAGREV_OFF = 1; + + if (edrk.temper_edrk.min_real_int_temper_air<TEMPER_NAGREF_ON_1 && edrk.temper_edrk.max_real_int_temper_air<TEMPER_NAGREF_ON_2) + edrk.to_ing.bits.NAGREV_OFF = 0; + + if (edrk.temper_edrk.min_real_int_temper_air>TEMPER_NAGREF_OFF_1 || edrk.temper_edrk.max_real_int_temper_air>TEMPER_NAGREF_OFF_2) + edrk.to_ing.bits.NAGREV_OFF = 1; + +} +/////////////////////////////////////////////// + + + +//#define koef_P_Water_filter 1600000 //0.095367431640625 +void calc_p_water_edrk(void) +{ + _iq iqtain,iq_temp; + static _iq koef_P_Water_filter = _IQ (0.1/2.0); // 5 ��� ������ + + edrk.p_water_edrk.adc_p_water[0] = ADC_f[1][14]; + + edrk.p_water_edrk.real_p_water[0] = (_IQtoF(analog.P_Water_internal) * NORMA_ACP_P - 4.0) / 1.6; + edrk.p_water_edrk.real_int_p_water[0] = edrk.p_water_edrk.real_p_water[0] * K_P_WATER_TO_SVU; + + + iqtain = _IQ(edrk.p_water_edrk.real_p_water[0]/100.0); + iq_temp = _IQ(edrk.p_water_edrk.filter_real_p_water[0]/100.0); + + if (edrk.p_water_edrk.flag_init_filter_temp[0]==0) + { + iq_temp = iqtain; + edrk.p_water_edrk.flag_init_filter_temp[0]=1; + } + +// iq_temp_engine[i] = exp_regul_iq(koef_Temper_ENGINE_filter, iq_temp_engine[i], iqtain); + + iq_temp += _IQmpy( (iqtain-iq_temp), koef_P_Water_filter); + edrk.p_water_edrk.filter_real_p_water[0] = _IQtoF(iq_temp)*100.0; + edrk.p_water_edrk.filter_real_int_p_water[0] = edrk.p_water_edrk.filter_real_p_water[0]*K_P_WATER_TO_SVU; + + + +} + +////////////////////////////////////////////////////////// + diff --git a/Inu/Src/main/temper_p_tools.h b/Inu/Src/main/temper_p_tools.h new file mode 100644 index 0000000..d99cb89 --- /dev/null +++ b/Inu/Src/main/temper_p_tools.h @@ -0,0 +1,22 @@ +/* + * temper_p_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_TEMPER_P_TOOLS_H_ +#define SRC_MAIN_TEMPER_P_TOOLS_H_ + + +#define TEMPER_NAGREF_ON_1 120 +#define TEMPER_NAGREF_ON_2 200 + +#define TEMPER_NAGREF_OFF_1 170 +#define TEMPER_NAGREF_OFF_2 250 + +void nagrev_auto_on_off(void); +void calc_p_water_edrk(void); + + +#endif /* SRC_MAIN_TEMPER_P_TOOLS_H_ */ diff --git a/Inu/Src/main/tk_Test.c b/Inu/Src/main/tk_Test.c new file mode 100644 index 0000000..fd5cc61 --- /dev/null +++ b/Inu/Src/main/tk_Test.c @@ -0,0 +1,369 @@ + +#include <281xEvTimersInit.h> +#include <project_setup.h> +#include <PWMTMSHandle.h> + +#include "DSP281x_Device.h" +#include "MemoryFunctions.h" +#include "Spartan2E_Adr.h" +#include "x_wdog.h" +#include "project.h" + +#pragma CODE_SECTION(pause_10,".fast_run"); +void pause_10(unsigned long t) +{ + unsigned long i; + + for (i = 0; i < t; i++) + { + asm(" NOP"); + } +} + + +void test_impulse(unsigned int impulse_channel,long impulse_time) +{ + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel); + pause_10(impulse_time); + i_WriteMemory(ADR_PWM_DIRECT,0xffff); +} + +#pragma CODE_SECTION(test_double_impulse,".fast_run"); +void test_double_impulse(unsigned int impulse_channel_1,unsigned int impulse_channel_2,long impulse_time,long middle_impulse_time,long last_impulse_time, int soft_off_enable, int soft_on_enable) +{ + project.disable_all_interrupt(); +// i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); +// pause_10(middle_impulse_time); + + if (soft_on_enable) + { + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); + pause_10(last_impulse_time); + } + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_1); +// pause_10(impulse_time); + pause_10(impulse_time); + + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); + pause_10(middle_impulse_time); + + i_WriteMemory(ADR_PWM_DIRECT, impulse_channel_1); + pause_10(last_impulse_time); + + if (soft_off_enable) + { + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); + pause_10(last_impulse_time); + } + + i_WriteMemory(ADR_PWM_DIRECT,0xffff); + + project.enable_all_interrupt(); +} + +void test_sin_impulse(unsigned int impulse_channel_1,unsigned int impulse_channel_2, unsigned int impulse_channel_3, long impulse_time,long middle_impulse_time) +{ + project.disable_all_interrupt(); + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); + pause_10(middle_impulse_time); + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_1); + pause_10(impulse_time); + + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_2); + pause_10(middle_impulse_time); + + i_WriteMemory(ADR_PWM_DIRECT,impulse_channel_3); + pause_10(impulse_time); + i_WriteMemory(ADR_PWM_DIRECT,0xffff); + + project.enable_all_interrupt(); +} + + +void test_tk_ak_one_impulse(int tk0, int tk1, int tk2, int tk3, int period, int periodMiddle, int periodLast, int doubleImpulse, int sinImpulse, int soft_off_enable, int soft_on_enable) +{ + long p2 = 0, pM = 0, pL = 0; + float pf; + unsigned int tk0_0 = 0, tk0_1 = 0, tk0_2 = 0, tk0_3 = 0, tk0_4 = 0, tk0_5 = 0, tk0_6 = 0, tk0_7 = 0; + unsigned int tk1_0 = 0, tk1_1 = 0, tk1_2 = 0, tk1_3 = 0, tk1_4 = 0, tk1_5 = 0, tk1_6 = 0, tk1_7 = 0; + unsigned int tk2_0 = 0, tk2_1 = 0, tk2_2 = 0, tk2_3 = 0, tk2_4 = 0, tk2_5 = 0, tk2_6 = 0, tk2_7 = 0; + unsigned int tk3_0 = 0, tk3_1 = 0, tk3_2 = 0, tk3_3 = 0, tk3_4 = 0, tk3_5 = 0, tk3_6 = 0, tk3_7 = 0; + unsigned int break1 = 0, break2 = 0, break3 = 0, break4 = 0,key0 = 0, key1 = 0, key2 = 0, key3 = 0, key4 = 0, key5 = 0, key6 = 0, key7 = 0, key8 = 0,key9 = 0,key10 = 0,key11 = 0; + unsigned int Dkey0 = 0xffff, Dkey1 = 0xffff, Dkey2 = 0xffff; + unsigned int currentPWMMode1, currentPWMMode0, currPWMPeriod; + + + ////��������� ��� ����������� ////////// +#if (XPWMGEN==1) + i_WriteMemory(ADR_PWM_DRIVE_MODE, 3); +// pause_1000(100000L); + i_WriteMemory(ADR_PWM_DIRECT,0xffff); + i_WriteMemory(ADR_TK_MASK_0, 0); + +#endif + stop_eva_timer2(); + IER &= ~M_INT9; //stop CAN + //////////////////////////////////// + + if (period<=1) + period=1; + if (period>=1000) + period=1000; + pf = (float)(period) *11.724;/// 2.8328173374613003095975232198142;//(periodMiddle)*12; + p2 = pf; +// p2=(period) * 19 / 10;//(period)*12; + + if (periodMiddle<=1) + periodMiddle=1; + if (periodMiddle>=1000) + periodMiddle=1000; +// pM=(periodMiddle) * 19 / 10;//(periodMiddle)*12; + pf = (float)(periodMiddle)*11.724;// / 2.8328173374613003095975232198142;//(periodMiddle)*12; + pM = pf; + + if (periodLast<=1) + periodLast=1; + if (periodLast>=1000) + periodLast=1000; +// pM=(periodMiddle) * 19 / 10;//(periodMiddle)*12; + pf = (float)(periodLast)*11.724;// / 2.8328173374613003095975232198142;//(periodMiddle)*12; + pL = pf; + + + + tk0_0 = (tk0 >> 0) & 0x1; + tk0_1 = (tk0 >> 1) & 0x1; + tk0_2 = (tk0 >> 2) & 0x1; + tk0_3 = (tk0 >> 3) & 0x1; + tk0_4 = (tk0 >> 4) & 0x1; + tk0_5 = (tk0 >> 5) & 0x1; + tk0_6 = (tk0 >> 6) & 0x1; + tk0_7 = (tk0 >> 7) & 0x1; + + tk1_0 = (tk1 >> 0) & 0x1; + tk1_1 = (tk1 >> 1) & 0x1; + tk1_2 = (tk1 >> 2) & 0x1; + tk1_3 = (tk1 >> 3) & 0x1; + tk1_4 = (tk1 >> 4) & 0x1; + tk1_5 = (tk1 >> 5) & 0x1; + tk1_6 = (tk1 >> 6) & 0x1; + tk1_7 = (tk1 >> 7) & 0x1; + + tk2_0 = (tk2 >> 0) & 0x1; + tk2_1 = (tk2 >> 1) & 0x1; + tk2_2 = (tk2 >> 2) & 0x1; + tk2_3 = (tk2 >> 3) & 0x1; + tk2_4 = (tk2 >> 4) & 0x1; + tk2_5 = (tk2 >> 5) & 0x1; + tk2_6 = (tk2 >> 6) & 0x1; + tk2_7 = (tk2 >> 7) & 0x1; + + tk3_0 = (tk3 >> 0) & 0x1; + tk3_1 = (tk3 >> 1) & 0x1; + tk3_2 = (tk3 >> 2) & 0x1; + tk3_3 = (tk3 >> 3) & 0x1; + tk3_4 = (tk3 >> 4) & 0x1; + tk3_5 = (tk3 >> 5) & 0x1; + tk3_6 = (tk3 >> 6) & 0x1; + tk3_7 = (tk3 >> 7) & 0x1; + + if(doubleImpulse) + { + if(tk0_0 && tk0_7){ + Dkey0 = 0xfff6; + Dkey1 = 0xfff0; + } + else if(tk0_4 && tk0_3){ + Dkey0 = 0xfff9; + Dkey1 = 0xfff0; + } + else if(tk1_3 && tk0_0){ + Dkey0 = 0xffde; + Dkey1 = 0xffcc; + } + else if(tk1_0 && tk0_3){ + Dkey0 = 0xffed; + Dkey1 = 0xffcc; + } + else if(tk0_4 && tk1_3){ + Dkey0 = 0xffdb; + Dkey1 = 0xffc3; + } + else if(tk0_7 && tk1_0){ + Dkey0 = 0xffe7; + Dkey1 = 0xffc3; + }///// + else if(tk1_4 && tk2_3){ + Dkey0 = 0xFDBF; + Dkey1 = 0xFC3F; + } + else if(tk1_7 && tk2_0){ + Dkey0 = 0xFE7F; + Dkey1 = 0xFC3F; + } + else if(tk1_4 && tk2_7){ + Dkey0 = 0xF7BF; + Dkey1 = 0xF33F; + } + else if(tk1_7 && tk2_4){ + Dkey0 = 0xFB7F; + Dkey1 = 0xF33F; + } + else if(tk2_0 && tk2_7){ + Dkey0 = 0xF6FF; + Dkey1 = 0xF0FF; + } + else if(tk2_3 && tk2_4){ + Dkey0 = 0xF9FF; + Dkey1 = 0xF0FF; + } + else if (tk0_0){ + Dkey0 = 0xfffe; + Dkey1 = 0xfffc; + } + else if (tk0_3){ + Dkey0 = 0xfffd; + Dkey1 = 0xfffc; + } + else if (tk0_4){ + Dkey0 = 0xfffb; + Dkey1 = 0xfff3; + } + else if (tk0_7){ + Dkey0 = 0xfff7; + Dkey1 = 0xfff3; + } + else if (tk1_0){ + Dkey0 = 0xffef; + Dkey1 = 0xffcf; + } + else if (tk1_3){ + Dkey0 = 0xffdf; + Dkey1 = 0xffcf; + } + else if (tk1_4){ + Dkey0 = 0xffbf; + Dkey1 = 0xff3f; + } + else if (tk1_7){ + Dkey0 = 0xff7f; + Dkey1 = 0xff3f; + } + else if (tk2_0){ + Dkey0 = 0xfeff; + Dkey1 = 0xfcff; + } + else if (tk2_3){ + Dkey0 = 0xfdff; + Dkey1 = 0xfcff; + } + else if (tk2_4){ + Dkey0 = 0xfbff; + Dkey1 = 0xf3ff; + } + else if (tk2_7){ + Dkey0 = 0xf7ff; + Dkey1 = 0xf3ff; + } + + } + else if(sinImpulse) + { + if(tk0_0){ + Dkey0 = 0xfff6; + Dkey1 = 0xfff0; + Dkey2 = 0xfff9; + } + else if(tk0_7){ + Dkey0 = 0xfff9; + Dkey1 = 0xfff0; + Dkey2 = 0xfff6; + } + else if(tk1_0){ + Dkey0 = 0xffde; + Dkey1 = 0xffcc; + Dkey2 = 0xffed; + } + else if(tk0_4){ + Dkey0 = 0xffed; + Dkey1 = 0xffcc; + Dkey2 = 0xffde; + } + else if(tk1_4){ + Dkey0 = 0xffdb; + Dkey1 = 0xffc3; + Dkey2 = 0xffe7; + } + else if(tk1_7){ + Dkey0 = 0xffe7; + Dkey1 = 0xffc3; + Dkey2 = 0xffdb; + } + } + else + { + key0 = !(((tk0_0 == 1) && (tk0_1 == 1) && (tk0_2 == 0) && (tk0_3 == 0)) || + ((tk0_0 == 0) && (tk0_1 == 1) && (tk0_2 == 1) && (tk0_3 == 0))); + + key1 = !(((tk0_0 == 0) && (tk0_1 == 1) && (tk0_2 == 1) && (tk0_3 == 0)) || + ((tk0_0 == 0) && (tk0_1 == 0) && (tk0_2 == 1) && (tk0_3 == 1))); + + key2 = !(((tk0_4 == 1) && (tk0_5 == 1) && (tk0_6 == 0) && (tk0_7 == 0)) || + ((tk0_4 == 0) && (tk0_5 == 1) && (tk0_6 == 1) && (tk0_7 == 0))); + + key3 = !(((tk0_4 == 0) && (tk0_5 == 1) && (tk0_6 == 1) && (tk0_7 == 0)) || + ((tk0_4 == 0) && (tk0_5 == 0) && (tk0_6 == 1) && (tk0_7 == 1))); + + key4 = !(((tk1_0 == 1) && (tk1_1 == 1) && (tk1_2 == 0) && (tk1_3 == 0)) || + ((tk1_0 == 0) && (tk1_1 == 1) && (tk1_2 == 1) && (tk1_3 == 0))); + + key5 = !(((tk1_0 == 0) && (tk1_1 == 1) && (tk1_2 == 1) && (tk1_3 == 0)) || + ((tk1_0 == 0) && (tk1_1 == 0) && (tk1_2 == 1) && (tk1_3 == 1))); + + key6 = !(((tk1_4 == 1) && (tk1_5 == 1) && (tk1_6 == 0) && (tk1_7 == 0)) || + ((tk1_4 == 0) && (tk1_5 == 1) && (tk1_6 == 1) && (tk1_7 == 0))); + + key7 = !(((tk1_4 == 0) && (tk1_5 == 1) && (tk1_6 == 1) && (tk1_7 == 0)) || + ((tk1_4 == 0) && (tk1_5 == 0) && (tk1_6 == 1) && (tk1_7 == 1))); + + key8 = !(((tk2_0 == 1) && (tk2_1 == 1) && (tk2_2 == 0) && (tk2_3 == 0)) || + ((tk2_0 == 0) && (tk2_1 == 1) && (tk2_2 == 1) && (tk2_3 == 0))); + + key9 =!(((tk2_0 == 0) && (tk2_1 == 1) && (tk2_2 == 1) && (tk2_3 == 0)) || + ((tk2_0 == 0) && (tk2_1 == 0) && (tk2_2 == 1) && (tk2_3 == 1))); + + key10 = !(((tk2_4 == 1) && (tk2_5 == 1) && (tk2_6 == 0) && (tk2_7 == 0)) || + ((tk2_4 == 0) && (tk2_5 == 1) && (tk2_6 == 1) && (tk2_7 == 0))); + + key11 = !(((tk2_4 == 0) && (tk2_5 == 1) && (tk2_6 == 1) && (tk2_7 == 0)) || + ((tk2_4 == 0) && (tk2_5 == 0) && (tk2_6 == 1) && (tk2_7 == 1))); + + break1 = !tk3_1; + break2 = !tk3_2; + break3 = !tk3_3; + break4 = !tk3_4; + + Dkey0 &= ((break4 << 15)|(break3 << 14)|(break2 << 13)|(break1 << 12)| (key11 << 11) | (key10 << 10) | (key9 << 9) | (key8 << 8)| (key7 << 7)| (key6 << 6)| (key5 << 5)| (key4 << 4)| (key3 << 3)| (key2 << 2)| (key1 << 1)| (key0 << 0)); + + } + if(doubleImpulse) + test_double_impulse(Dkey0, Dkey1, p2, pM, pL, soft_off_enable, soft_on_enable); + else if(sinImpulse) + test_sin_impulse(Dkey0, Dkey1, Dkey2, p2, pM); + else + test_impulse(Dkey0,p2); + + //���������� ������� ����� + start_eva_timer2(); + IER |= M_INT9; //start CAN +#if (XPWMGEN==1) + i_WriteMemory(ADR_PWM_DIRECT,0xffff); + i_WriteMemory(ADR_PWM_DRIVE_MODE, 0); +#endif + return; +} diff --git a/Inu/Src/main/tk_Test.h b/Inu/Src/main/tk_Test.h new file mode 100644 index 0000000..2a44453 --- /dev/null +++ b/Inu/Src/main/tk_Test.h @@ -0,0 +1,12 @@ + +#ifndef TK_TEST_H +#define TK_TEST_H + + + +void test_tk_ak_one_impulse(int tk0, int tk1, int tk2, int tk3, int period, int periodMiddle, int periodLast, int doubleImpulse, int sinImpulse, int soft_off_enable, int soft_on_enable); +void test_double_impulse(unsigned int impulse_channel_1,unsigned int impulse_channel_2,long impulse_time,long middle_impulse_time, long last_impulse_time, int soft_off_enable, int soft_on_enable); + + +#endif + diff --git a/Inu/Src/main/ukss_tools.c b/Inu/Src/main/ukss_tools.c new file mode 100644 index 0000000..097fc1e --- /dev/null +++ b/Inu/Src/main/ukss_tools.c @@ -0,0 +1,605 @@ +/* + * ukss_tools.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 "control_station_project.h" +#include "control_station.h" +#include "sync_tools.h" + + +#pragma DATA_SECTION(Unites2VPU, ".slow_vars") +int Unites2VPU[SIZE_UNITS_OUT]={0}; + +#pragma DATA_SECTION(Unites2Zadat4ik, ".slow_vars") +int Unites2Zadat4ik[SIZE_UNITS_OUT]={0}; + +#pragma DATA_SECTION(Unites2BKSSD, ".slow_vars") +int Unites2BKSSD[SIZE_UNITS_OUT]={0}; + +#pragma DATA_SECTION(Unites2UMU, ".slow_vars") +int Unites2UMU[SIZE_UNITS_OUT]={0}; + + + +void edrk_clear_cmd_ukss(void) +{ + int i; + + for (i=0;i<SIZE_UNITS_OUT;i++) + { + Unites2Zadat4ik[i] = 0; + Unites2VPU[i] = 0; + Unites2UMU[i] = 0; + Unites2BKSSD[i] = 0; + } + +} + + + +void update_ukss_setup(unsigned int pause) +{ + static unsigned int old_time_ukss1=0; + int real_mbox; + unsigned long count_send = 0, start_adr = 0; + + +#if (CAN_PROTOCOL_UKSS == 1) // ������ �������� + + Unites2Zadat4ik[96] = 25; + Unites2Zadat4ik[97] = 100; + Unites2Zadat4ik[98] = 8; + + Unites2VPU[96] = 25; + Unites2VPU[97] = 100; + Unites2VPU[98] = 8; + + Unites2UMU[96] = 25; + Unites2UMU[97] = 100; + Unites2UMU[98] = 8; + + Unites2BKSSD[96] = 25; + Unites2BKSSD[97] = 100; + Unites2BKSSD[98] = 8; + + count_send = 3; + start_adr = 96; +#endif + + +#if (CAN_PROTOCOL_UKSS == 2) // ����� �������� + + Unites2Zadat4ik[ADR_CYCLES_TIMER_MAIN] = 2; + Unites2Zadat4ik[ADR_CYCLES_TIMER_ADD] = 100; + Unites2Zadat4ik[ADR_CYCLES_PAUSE_MAIN] = 10; + Unites2Zadat4ik[ADR_CYCLES_PAUSE_ADD] = 10; + Unites2Zadat4ik[ADR_CYCLES_REPEATE_MAIN] = 500; + Unites2Zadat4ik[ADR_CYCLES_REPEATE_ADD] = 1000; + Unites2Zadat4ik[ADR_CYCLES_REPEATE_DIGIO] = 5; + + Unites2VPU[ADR_CYCLES_TIMER_MAIN] = 2; + Unites2VPU[ADR_CYCLES_TIMER_ADD] = 100; + Unites2VPU[ADR_CYCLES_PAUSE_MAIN] = 10; + Unites2VPU[ADR_CYCLES_PAUSE_ADD] = 10; + Unites2VPU[ADR_CYCLES_REPEATE_MAIN] = 500; + Unites2VPU[ADR_CYCLES_REPEATE_ADD] = 1000; + Unites2VPU[ADR_CYCLES_REPEATE_DIGIO] = 1; + + Unites2UMU[ADR_CYCLES_TIMER_MAIN] = 2; + Unites2UMU[ADR_CYCLES_TIMER_ADD] = 100; + Unites2UMU[ADR_CYCLES_PAUSE_MAIN] = 10; + Unites2UMU[ADR_CYCLES_PAUSE_ADD] = 10; + Unites2UMU[ADR_CYCLES_REPEATE_MAIN] = 500; + Unites2UMU[ADR_CYCLES_REPEATE_ADD] = 1000; + Unites2UMU[ADR_CYCLES_REPEATE_DIGIO] = 1; + + Unites2BKSSD[ADR_CYCLES_TIMER_MAIN] = 2; + Unites2BKSSD[ADR_CYCLES_TIMER_ADD] = 100; + Unites2BKSSD[ADR_CYCLES_PAUSE_MAIN] = 10; + Unites2BKSSD[ADR_CYCLES_PAUSE_ADD] = 10; + Unites2BKSSD[ADR_CYCLES_REPEATE_MAIN] = 500; + Unites2BKSSD[ADR_CYCLES_REPEATE_ADD] = 1000; + Unites2BKSSD[ADR_CYCLES_REPEATE_DIGIO] = 1; + + start_adr = ADR_CYCLES_TIMER_MAIN; + count_send = ADR_CYCLES_REPEATE_DIGIO - ADR_CYCLES_TIMER_MAIN + 1; +#endif + + if (detect_pause_milisec(pause,&old_time_ukss1)) + { + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, ZADATCHIK_CAN); + + if (CAN_cycle_free(real_mbox)) + { + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, start_adr, &Unites2Zadat4ik[start_adr], count_send, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, VPU_CAN); + + if (CAN_cycle_free(real_mbox)) + { + CAN_cycle_send( UNITS_TYPE_BOX, VPU_CAN, start_adr, &Unites2VPU[start_adr], count_send, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, UMU_CAN_DEVICE); + + if (CAN_cycle_free(real_mbox)) + { + CAN_cycle_send( UNITS_TYPE_BOX, UMU_CAN_DEVICE, start_adr, &Unites2UMU[start_adr], count_send, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, BKSSD_CAN_DEVICE); + + if (CAN_cycle_free(real_mbox)) + { + CAN_cycle_send( UNITS_TYPE_BOX, BKSSD_CAN_DEVICE, start_adr, &Unites2BKSSD[start_adr], count_send, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + } + +} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ��������� �������� ��� ������� ������� ���� +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +void update_ukss_can_moment_kgnc(unsigned int pause) +{ + int real_mbox; + int t1; + + static unsigned int old_time_ukss2=0, test_flag = 0; + + + + if (edrk.flag_second_PCH==0) + t1 = pause; + if (edrk.flag_second_PCH==1) + t1 = pause; + + +////// + + + if (test_flag == 0) + { + // 32 ����� �������, ���� 13 + // 33 ������ ������� RS485 * 10 m��� 25 + + Unites2Zadat4ik[32] = 13;//9 + Unites2Zadat4ik[33] = 25; + + // 34 ��� ��� 1 �����, � + // 35 ���������� ��� 1 �����, � + // 36 ��� ��� 2 �����, � + // 37 ���������� ��� 2 �����, � + // 38 ��������, ��� + // 39 �������, ��/��� + // 40 ����� �� + + if (edrk.flag_second_PCH==0) + { + Unites2Zadat4ik[34] = global_time.total_seconds10full; + Unites2Zadat4ik[35] = _IQtoF(analog.iqIin_sum)*NORMA_ACP; + Unites2Zadat4ik[36] = _IQtoF(filter.iqU_1_long+filter.iqU_2_long)*NORMA_ACP; + Unites2Zadat4ik[37] = fast_round(_IQtoF(edrk.k_stator1)*1000.0); + Unites2Zadat4ik[38] = _IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP; + } + + if (edrk.flag_second_PCH==1) + { + + Unites2Zadat4ik[39] = global_time.total_seconds10full; + Unites2Zadat4ik[40] = _IQtoF(analog.iqIin_sum)*NORMA_ACP; + Unites2Zadat4ik[41] = _IQtoF(filter.iqU_1_long+filter.iqU_2_long)*NORMA_ACP; + Unites2Zadat4ik[42] = fast_round(_IQtoF(edrk.k_stator1)*1000.0); + Unites2Zadat4ik[43] = _IQtoF(filter.iqIm_1 + filter.iqIm_2)*NORMA_ACP; + + } + + Unites2Zadat4ik[44] = edrk.power_kw_full; + Unites2Zadat4ik[45] = _IQtoF(WRotor.iqWRotorSumFilter) * NORMA_FROTOR*6000.0;//;//_IQtoF(edrk.iq_f_rotor_hz) * NORMA_FROTOR*6000.0; + + + if (edrk.pult_data.data_from_pult.nPCH==11 || edrk.pult_data.data_from_pult.nPCH==12) + Unites2Zadat4ik[46] = 1; + else + Unites2Zadat4ik[46] = 2; + } + + + if (detect_pause_milisec(t1,&old_time_ukss2)) + { + + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, ZADATCHIK_CAN); + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + if (edrk.flag_second_PCH==0) + { + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 32, &Unites2Zadat4ik[32], 7, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 44, &Unites2Zadat4ik[44], 3, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + else + { + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 32, &Unites2Zadat4ik[32], 2, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 39, &Unites2Zadat4ik[39], 8, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + } + } + + +} + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// ��������� �������� � ��� +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +#define MAX_WAIT_UPDATE_ZAD 10 + +void update_ukss_can(unsigned int pause) +{ + int real_mbox; + int t1; + + static int disable_update_zadat4ik = MAX_WAIT_UPDATE_ZAD; + static int disable_update_vpu = MAX_WAIT_UPDATE_ZAD; + + static unsigned int old_time_ukss2=0; + + + static TO_ZADAT4IK prev_Zadat4ik = TO_ZADAT4IK_DEFAULT; + static TO_VPU prev_VPU = TO_VPU_DEFAULT; + + + + if (edrk.flag_second_PCH==0) + t1 = pause; + if (edrk.flag_second_PCH==1) + t1 = pause; + + Unites2Zadat4ik[4] = edrk.to_zadat4ik.OBOROTS1.all; + Unites2Zadat4ik[5] = edrk.to_zadat4ik.OBOROTS2.all; + Unites2Zadat4ik[6] = edrk.to_zadat4ik.BIG_LAMS.all; + Unites2Zadat4ik[7] = edrk.to_zadat4ik.APL_LAMS0.all; + Unites2Zadat4ik[8] = 0; + + Unites2VPU[4] = edrk.to_vpu.OBOROTS1.all; + Unites2VPU[5] = edrk.to_vpu.OBOROTS2.all; + Unites2VPU[6] = edrk.to_vpu.BIG_LAMS.all; + Unites2VPU[7] = 0; + Unites2VPU[8] = 0; + + + if (detect_pause_milisec(t1,&old_time_ukss2)) + { + + if (disable_update_zadat4ik) + disable_update_zadat4ik--; + + if (prev_Zadat4ik.APL_LAMS0.all != edrk.to_zadat4ik.APL_LAMS0.all + || prev_Zadat4ik.APL_LAMS_PCH.all != edrk.to_zadat4ik.APL_LAMS_PCH.all + || prev_Zadat4ik.BIG_LAMS.all != edrk.to_zadat4ik.BIG_LAMS.all + || prev_Zadat4ik.OBOROTS1.all != edrk.to_zadat4ik.OBOROTS1.all + || prev_Zadat4ik.OBOROTS2.all != edrk.to_zadat4ik.OBOROTS2.all) + disable_update_zadat4ik = 0; + + if (disable_update_vpu) + disable_update_vpu--; + + if ( prev_VPU.BIG_LAMS.all != edrk.to_vpu.BIG_LAMS.all + || prev_VPU.OBOROTS1.all != edrk.to_vpu.OBOROTS1.all + || prev_VPU.OBOROTS2.all != edrk.to_vpu.OBOROTS2.all) + disable_update_vpu = 0; + + + + if (disable_update_zadat4ik==0) + { + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, ZADATCHIK_CAN); + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + if (edrk.flag_second_PCH==0) + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 4, &Unites2Zadat4ik[4], 5, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + else + CAN_cycle_send( UNITS_TYPE_BOX, ZADATCHIK_CAN, 0xa, &Unites2Zadat4ik[4], 5, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + prev_Zadat4ik.APL_LAMS0.all = edrk.to_zadat4ik.APL_LAMS0.all; + prev_Zadat4ik.APL_LAMS_PCH.all = edrk.to_zadat4ik.APL_LAMS_PCH.all; + prev_Zadat4ik.BIG_LAMS.all = edrk.to_zadat4ik.BIG_LAMS.all; + prev_Zadat4ik.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; + prev_Zadat4ik.OBOROTS2.all = edrk.to_zadat4ik.OBOROTS2.all; + + disable_update_zadat4ik = MAX_WAIT_UPDATE_ZAD; + } + + if (disable_update_vpu==0) + { + real_mbox = get_real_out_mbox (UNITS_TYPE_BOX, VPU_CAN); + + if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON)) + { + if (edrk.flag_second_PCH==0) + CAN_cycle_send( UNITS_TYPE_BOX, VPU_CAN, 4, &Unites2VPU[4], 4, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + else + CAN_cycle_send( UNITS_TYPE_BOX, VPU_CAN, 0xa, &Unites2VPU[4], 4, CAN_BOX_STANDART_ADR, CAN_BOX_PRIORITY_NORMAL);// �������� 40 ����. ���� �������� ���� ������� + } + + prev_VPU.BIG_LAMS.all = edrk.to_vpu.BIG_LAMS.all; + prev_VPU.OBOROTS1.all = edrk.to_vpu.OBOROTS1.all; + prev_VPU.OBOROTS2.all = edrk.to_vpu.OBOROTS2.all; + + disable_update_vpu = MAX_WAIT_UPDATE_ZAD; + + } + + + + } + +} + + + +////////////////////////////////////////////////////////// + + +void update_zadat4ik(void) +{ + + static unsigned int time_toggle1 = 0, time_toggle2 = 0, time_toggle3 = 0, time_toggle4 = 0; + int b; + static unsigned int time_toggle_leds = 500; + + + // update zadatchik +// if (edrk.from_zadat4ik.bits.MINUS || edrk.from_zadat4ik.bits.PLUS || edrk.from_ing2.bits.KEY_MINUS || edrk.from_ing2.bits.KEY_PLUS || edrk.from_vpu.bits.PLUS || edrk.from_vpu.bits.MINUS) +// { +// if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) // UFCONST +// { +// edrk.to_zadat4ik.OBOROTS1.all = fast_round(edrk.zadanie.fzad*100.0); // ������� �������� +// edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; // ������� �������� +// } +// else +// { +// edrk.to_zadat4ik.OBOROTS1.all = (edrk.zadanie.oborots_zad); // ������� �������� +// edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; // ������� �������� +// } +// +// } +// else +// { +// +// if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) // UFCONST +// { +// edrk.to_zadat4ik.OBOROTS1.all = fast_round(_IQtoF(edrk.f_stator)*NORMA_FROTOR*100.0); // ������� ���. +// edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; // ������� ���. +// } +// else +// { +// edrk.to_zadat4ik.OBOROTS1.all = edrk.oborots; // ������� ���. +// edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; // ������� ���. +// } +// +// } + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) // UFCONST + { + edrk.to_zadat4ik.OBOROTS2.all = fast_round(_IQtoF(edrk.f_stator)*NORMA_FROTOR*100.0); // ������� ���. + edrk.to_vpu.OBOROTS2.all = edrk.to_zadat4ik.OBOROTS2.all; // ������� ���. + } + else + { + if (control_station.active_array_cmd[CONTROL_STATION_CMD_ROTOR_POWER]==0) // �� �������� + edrk.to_zadat4ik.OBOROTS2.all = edrk.zadanie.oborots_zad_no_dead_zone; // ������� �������� + else + edrk.to_zadat4ik.OBOROTS2.all = edrk.oborots; //������ ������� + + edrk.to_vpu.OBOROTS2.all = edrk.to_zadat4ik.OBOROTS2.all; // ������� �������� + } + + //edrk.to_zadat4ik.OBOROTS2.all = edrk.I_cur_vozbud_exp; // ��� ����������� + + if (edrk.Mode_ScalarVectorUFConst == ALG_MODE_UF_CONST) // UFCONST + { + edrk.to_zadat4ik.OBOROTS1.all = fast_round(_IQtoF(edrk.k_stator1)*10000.0); + edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; + } + else + { +// edrk.to_zadat4ik.OBOROTS2.all = edrk.to_zadat4ik.OBOROTS1.all; +// edrk.to_vpu.OBOROTS2.all = edrk.to_zadat4ik.OBOROTS2.all; + edrk.to_zadat4ik.OBOROTS1.all = edrk.oborots; //������ ������� + edrk.to_vpu.OBOROTS1.all = edrk.to_zadat4ik.OBOROTS1.all; + + } + + + // ����������2 + if (edrk.Status_Ready.bits.ready_final) + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA = 1;//edrk.from_shema.bits.QTV_ON_OFF; + else + { + if (edrk.SumSbor) + { + if (detect_pause_milisec(time_toggle_leds,&time_toggle1)) + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA = toggle_status_lamp((unsigned int)edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA,1); + } + else + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA = 0; + } + + + if (edrk.Ready2_another_bs && edrk.Status_Ready.bits.ready_final) + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV2 = 1; + else + { + if (edrk.Status_Ready.bits.ready_final) + { + if (detect_pause_milisec(time_toggle_leds,&time_toggle3)) + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV2 = toggle_status_lamp((unsigned int)edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV2,1); + } + else + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV2 = 0; + } + + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_MESTNOE = control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485];//edrk.from_ing1.bits.LOCAL_REMOUTE; // LOCAL + + + if (edrk.Status_Perehod_Rascepitel==0) + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN = edrk.Final_Status_Rascepitel; + else + { + b = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN; + if (detect_pause_milisec(time_toggle_leds,&time_toggle2)) + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN = toggle_status_lamp((unsigned int)edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN,1); + } + + // edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN = edrk.Status_Rascepitel_Ok || edrk.Status_Perehod_Rascepitel; + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_READY1 = edrk.Status_Ready.bits.ready1; + + //������� + edrk.to_zadat4ik.BIG_LAMS.bits.EMKOST = edrk.Status_Ready.bits.Batt;//edrk.Status_Charge; For 23550.3 + + + edrk.to_zadat4ik.BIG_LAMS.bits.PEREGREV = edrk.temper_limit_koeffs.code_status; + if (edrk.power_limit.all) + edrk.to_zadat4ik.BIG_LAMS.bits.OGRAN_POWER = 1; + else + edrk.to_zadat4ik.BIG_LAMS.bits.OGRAN_POWER = 0; + + if (edrk.Ready1_another_bs && edrk.Status_Ready.bits.ready1) + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV1 = 1; + else + { + if (edrk.Status_Ready.bits.ready1) + { + if (detect_pause_milisec(time_toggle_leds,&time_toggle4)) + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV1 = toggle_status_lamp((unsigned int)edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV1,1); + } + else + edrk.to_zadat4ik.BIG_LAMS.bits.GOTOV1 = 0; + } + edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_READY1 = edrk.Status_Ready.bits.ready1; + + edrk.to_zadat4ik.BIG_LAMS.bits.NEISPRAVNOST = edrk.warning; + + if (edrk.flag_second_PCH==0) + { + edrk.to_zadat4ik.APL_LAMS0.bits.PCH1_MESTNOE = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_MESTNOE; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH1_PODKLU4EN = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH1_READY1 = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_READY1; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH1_SHEMA_SOBRANA = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA; + } + else + { + edrk.to_zadat4ik.APL_LAMS0.bits.PCH2_MESTNOE = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_MESTNOE; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH2_PODKLU4EN = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_PODKLU4EN; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH2_READY1 = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_READY1; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH2_SHEMA_SOBRANA = edrk.to_zadat4ik.APL_LAMS_PCH.bits.PCH_SHEMA_SOBRANA; + } + + + // edrk.to_zadat4ik.APL_LAMS0.bits0.GED_PEREGRUZ = 0; + // edrk.to_zadat4ik.APL_LAMS0.bits0.PROVOROT = 0; + + + + + + if (control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485]) + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_ZADAT = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_MONITOR = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_SVU = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU = 0; + // edrk.to_zadat4ik.APL_LAMS0.bits.WORK_PMU = 0; + + + } + else // control_station.active_control_station[CONTROL_STATION_INGETEAM_PULT_RS485] == 0//edrk.RemouteFromDISPLAY==0 + { + if (edrk.from_shema_filter.bits.SVU==0) + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU = 0; + if (edrk.from_shema_filter.bits.ZADA_DISPLAY) + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_MONITOR = 1; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_ZADAT = 0; + } + else + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_MONITOR = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_ZADAT = 1; + } + } + else // SVU==1 + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_MONITOR = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_ZADAT = 0; + } + + if (edrk.from_shema_filter.bits.SVU) + { + + if (edrk.from_vpu.bits.UOM_READY_ACTIVE) + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU = 1; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_SVU = 0; + } + else + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_SVU = 1; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU = 0; + } + + } + else //edrk.from_shema.bits.SVU == 0 + { + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_SVU = 0; + edrk.to_zadat4ik.APL_LAMS0.bits.OBOROT_VPU = 0; + } + } + + + edrk.to_zadat4ik.APL_LAMS0.bits.HOD = edrk.Go; + edrk.to_zadat4ik.APL_LAMS0.bits.PCH1_PCH2_SYNC = sync_data.sync_ready; + + // if (edrk.from_zadat4ik.bits.PROVOROT) + // edrk.to_zadat4ik.APL_LAMS0.bits.PROVOROT = 1; + // else + // edrk.to_zadat4ik.APL_LAMS0.bits.PROVOROT = 0; + + edrk.to_zadat4ik.BIG_LAMS.bits.AVARIA = edrk.to_ing.bits.SMALL_LAMPA_AVARIA; + + +} + +////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/ukss_tools.h b/Inu/Src/main/ukss_tools.h new file mode 100644 index 0000000..5820afe --- /dev/null +++ b/Inu/Src/main/ukss_tools.h @@ -0,0 +1,33 @@ +/* + * ukss_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_UKSS_TOOLS_H_ +#define SRC_MAIN_UKSS_TOOLS_H_ + + + +#define SIZE_UNITS_OUT 128 + + +void update_ukss_can(unsigned int pause); + +void update_ukss_can_moment_kgnc(unsigned int pause); +void update_ukss_setup(unsigned int pause); +void edrk_clear_cmd_ukss(void); + +void update_zadat4ik(void); + +extern int Unites2VPU[SIZE_UNITS_OUT]; + +extern int Unites2Zadat4ik[SIZE_UNITS_OUT]; + +extern int Unites2BKSSD[SIZE_UNITS_OUT]; +extern int Unites2UMU[SIZE_UNITS_OUT]; + + + +#endif /* SRC_MAIN_UKSS_TOOLS_H_ */ diff --git a/Inu/Src/main/uom_tools.c b/Inu/Src/main/uom_tools.c new file mode 100644 index 0000000..b96c16e --- /dev/null +++ b/Inu/Src/main/uom_tools.c @@ -0,0 +1,149 @@ +/* + * uom_tools.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 "CAN_Setup.h" +#include "uom_tools.h" + + +#pragma DATA_SECTION(uom_levels, ".slow_vars") +int uom_levels[9] = {0, 0, 15, 30, 45, 60, 75, 90, 100}; +#pragma DATA_SECTION(iq_uom_levels, ".slow_vars") +_iq iq_uom_levels[9] = {_IQ(1.0), _IQ(1.0), _IQ(0.85), _IQ(0.7), _IQ(0.55), _IQ(0.4), _IQ(0.25), _IQ(0.1), _IQ(0.016)}; +void update_uom(void) +{ +// int index; + static _iq max_nominal_power = _IQ(MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + static _iq super_max_nominal_power = _IQ(SUPER_MAX_ZADANIE_LIMIT_POWER*1000.0/(NORMA_MZZ*NORMA_MZZ)); + + static unsigned int prev_CAN_count_cycle_input_units = 0, c_data = 0; + unsigned int cur_can_cycle; + + static FROM_ZADAT4IK zad = {0}, zad_w = {0}; + static unsigned int temp_code = 0 , temp_code1 = 0, temp_code2 = 0, temp_code3 = 0; + + + + cur_can_cycle = unites_can_setup.CAN_count_cycle_input_units[0]; + + if (prev_CAN_count_cycle_input_units != cur_can_cycle) + { + zad = edrk.from_zadat4ik; + + temp_code = (zad.bits.UOM_READY_ACTIVE & 0x1) + + (zad.bits.UOM_LIMIT_1 & 0x1) << 1 + + (zad.bits.UOM_LIMIT_2 & 0x1) << 2 + + (zad.bits.UOM_LIMIT_3 & 0x1) << 3 ; + + if (c_data == 0) + { + temp_code1 = temp_code; + c_data = 1; + } + else + if (c_data == 1) + { + temp_code2 = temp_code; + c_data = 2; + } + else + if (c_data == 2) + { + temp_code3 = temp_code; + c_data = 0; + } + + } + + prev_CAN_count_cycle_input_units = cur_can_cycle; + + if ((temp_code1 == temp_code2) && (temp_code2 == temp_code3)) + zad_w = zad; + + + edrk.from_uom.digital_line.bits.ready = zad_w.bits.UOM_READY_ACTIVE; + edrk.from_uom.digital_line.bits.level0 = zad_w.bits.UOM_LIMIT_1; + edrk.from_uom.digital_line.bits.level1 = zad_w.bits.UOM_LIMIT_2; + edrk.from_uom.digital_line.bits.level2 = zad_w.bits.UOM_LIMIT_3; + + + if (edrk.from_uom.digital_line.bits.ready && edrk.disable_uom==0) + { + edrk.from_uom.ready = 1; +//000 - 100 + if (edrk.from_uom.digital_line.bits.level0 == 0 && + edrk.from_uom.digital_line.bits.level1 == 0 && + edrk.from_uom.digital_line.bits.level2 == 0 ) + edrk.from_uom.code = 1; +//001 - 85 + if (edrk.from_uom.digital_line.bits.level0 == 1 && + edrk.from_uom.digital_line.bits.level1 == 0 && + edrk.from_uom.digital_line.bits.level2 == 0 ) + edrk.from_uom.code = 2; +//011 - 70 + if (edrk.from_uom.digital_line.bits.level0 == 1 && + edrk.from_uom.digital_line.bits.level1 == 1 && + edrk.from_uom.digital_line.bits.level2 == 0 ) + edrk.from_uom.code = 3; +//010 - 55 + if (edrk.from_uom.digital_line.bits.level0 == 0 && + edrk.from_uom.digital_line.bits.level1 == 1 && + edrk.from_uom.digital_line.bits.level2 == 0 ) + edrk.from_uom.code = 4; +//110 - 40 + if (edrk.from_uom.digital_line.bits.level0 == 0 && + edrk.from_uom.digital_line.bits.level1 == 1 && + edrk.from_uom.digital_line.bits.level2 == 1 ) + edrk.from_uom.code = 5; +//111 - 25 + if (edrk.from_uom.digital_line.bits.level0 == 1 && + edrk.from_uom.digital_line.bits.level1 == 1 && + edrk.from_uom.digital_line.bits.level2 == 1 ) + edrk.from_uom.code = 6; +//101 - 10 + if (edrk.from_uom.digital_line.bits.level0 == 1 && + edrk.from_uom.digital_line.bits.level1 == 0 && + edrk.from_uom.digital_line.bits.level2 == 1 ) + edrk.from_uom.code = 7; +//100 - 0 + if (edrk.from_uom.digital_line.bits.level0 == 0 && + edrk.from_uom.digital_line.bits.level1 == 0 && + edrk.from_uom.digital_line.bits.level2 == 1 ) + edrk.from_uom.code = 8; + } + else + { + edrk.from_uom.ready = 0; + edrk.from_uom.code = 0; + } + + edrk.from_uom.iq_level_value = iq_uom_levels[edrk.from_uom.code]; + + if (edrk.from_uom.code<=1) + edrk.from_uom.iq_level_value_kwt = super_max_nominal_power; + else + edrk.from_uom.iq_level_value_kwt = _IQmpy(max_nominal_power, + edrk.from_uom.iq_level_value); + + edrk.from_uom.level_value = uom_levels[edrk.from_uom.code]; + + + +} + +////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/uom_tools.h b/Inu/Src/main/uom_tools.h new file mode 100644 index 0000000..134648f --- /dev/null +++ b/Inu/Src/main/uom_tools.h @@ -0,0 +1,15 @@ +/* + * uom_tools.h + * + * Created on: 13 ����. 2024 �. + * Author: Evgeniy_Sokolov + */ + +#ifndef SRC_MAIN_UOM_TOOLS_H_ +#define SRC_MAIN_UOM_TOOLS_H_ + + +void update_uom(void); + + +#endif /* SRC_MAIN_UOM_TOOLS_H_ */ diff --git a/Inu/Src/main/v_pwm24_v2.c b/Inu/Src/main/v_pwm24_v2.c new file mode 100644 index 0000000..147c2c9 --- /dev/null +++ b/Inu/Src/main/v_pwm24_v2.c @@ -0,0 +1,948 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include <break_regul.h> +#include <params_pwm24.h> +#include <project_setup.h> +#include <PWMTMSHandle.h> +#include <v_pwm24_v2.h> +#include <vector.h> + +#include "rmp_cntl_v1.h" +#include "svgen_mf.h" +#include "uf_alg_ing.h" +#include "vhzprof.h" +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" +#include "MemoryFunctions.h" +#include "Spartan2E_Adr.h" +#include "TuneUpPlane.h" +#include "x_wdog.h" +#include "xp_write_xpwm_time.h" + + + + + + + + +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +//#pragma DATA_SECTION(var_freq_pwm_xtics,".fast_vars1"); +//int var_freq_pwm_xtics = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +//#pragma DATA_SECTION(var_period_max_xtics,".fast_vars1"); +//int var_period_max_xtics = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +//#pragma DATA_SECTION(var_period_min_xtics,".fast_vars1"); +//int var_period_min_xtics = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +#pragma DATA_SECTION(var_period_min_br_xtics,".fast_vars1"); +int var_period_min_br_xtics = DEF_PERIOD_MIN_BR_XTICS;// + + + + +#define IQ_ALFA_SATURATION1 15099494//16441671//15099494 +#define IQ_ALFA_SATURATION2 1677721//16441671//15099494 + + +#define PI 3.1415926535897932384626433832795 + +//#pragma DATA_SECTION(iq_alfa_coef,".fast_vars"); +//_iq iq_alfa_coef = 16777216; + + +//#pragma DATA_SECTION(pidCur_Ki,".fast_vars"); +//_iq pidCur_Ki = 0; + +//#pragma DATA_SECTION(ar_tph,".fast_vars"); +//_iq ar_tph[7]; + +//#pragma DATA_SECTION(winding_displacement,".fast_vars"); +//_iq winding_displacement = CONST_IQ_PI6; + + + +#pragma DATA_SECTION(svgen_pwm24_1,".v_24pwm_vars"); +SVGEN_PWM24 svgen_pwm24_1 = SVGEN_PWM24_DEFAULTS; +#pragma DATA_SECTION(svgen_pwm24_2,".v_24pwm_vars"); +SVGEN_PWM24 svgen_pwm24_2 = SVGEN_PWM24_DEFAULTS; + + + + +ALG_PWM24 alg_pwm24 = ALG_PWM24_DEFAULTS; + + + + + + + +#pragma CODE_SECTION(start_PWM24,".fast_run2") +void start_PWM24(int O1, int O2) +{ + if ((O1 == 1) && (O2 == 1)) + { + soft_start_x24_pwm_1_2(); + } + else + { + if ((O1 == 0) && (O2 == 1)) + { + soft_start_x24_pwm_2(); + } + if ((O1 == 1) && (O2 == 0)) + { + soft_start_x24_pwm_1(); + } + } +} + + + + +void InitPWM_Variables(int n_pch) +{ + +// init_DQ_pid(); +// break_resistor_managment_init(); + + +///////////// + + +////////////// +// a.k = 0; +// a.k1 = 0; +// a.k2 = 0; + + alg_pwm24.k1 = 0; + alg_pwm24.k2 = 0; + + alg_pwm24.freq1 = 0; + +/////////////////// + + +/////////////////// + svgen_pwm24_1.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_1.saw_direct.all = xpwm_time.saw_direct.all & 0x3f; + svgen_pwm24_1.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_1.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_high; + + svgen_pwm24_2.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_2.saw_direct.all = (xpwm_time.saw_direct.all >> 6) & 0x3f; + svgen_pwm24_2.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_2.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_high; + + + svgen_pwm24_1.XilinxFreq = CONST_IQ_1 / xpwm_time.Tclosed_high;//(var_freq_pwm_xtics + 1); + svgen_pwm24_2.XilinxFreq = svgen_pwm24_1.XilinxFreq; + + svgen_pwm24_1.number_svgen = 1; + svgen_pwm24_2.number_svgen = 2; + + // pwm_minimal_impuls_zero = DEF_PERIOD_MIN_XTICS_80; + + svgen_pwm24_1.pwm_minimal_impuls_zero_minus = (float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_100;//DEF_PERIOD_MIN_XTICS_80; + svgen_pwm24_1.pwm_minimal_impuls_zero_plus = (float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_80; + + svgen_pwm24_2.pwm_minimal_impuls_zero_minus = svgen_pwm24_1.pwm_minimal_impuls_zero_minus; + svgen_pwm24_2.pwm_minimal_impuls_zero_plus = svgen_pwm24_1.pwm_minimal_impuls_zero_plus; + + + if (n_pch==0) + { + svgen_pwm24_1.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_CBA; + svgen_pwm24_2.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_CBA; + } + else + { +// svgen_pwm24_1.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_ACB; // �� ����� +// svgen_pwm24_2.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_ACB; + svgen_pwm24_1.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_BAC; + svgen_pwm24_2.phase_sequence = V_PWM24_PHASE_SEQ_REVERS_BAC; + } + + + InitVariablesSvgen_Ing(xpwm_time.freq_pwm); +} + + + + + + + + + + +void InitXPWM(unsigned int freq_pwm) +{ + int i; + unsigned int pwm_t;//, freq_pwm_xtics; + + + + + pwm_t = (FREQ_INTERNAL_GENERATOR_XILINX_TMS / freq_pwm ); + // freq_pwm_xtics = (FREQ_INTERNAL_GENERATOR_XILINX_TMS / freq_pwm ); + +// write init pwm +// ��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� + xpwm_time.Tclosed_saw_direct_1 = pwm_t + 2;//1; // ��� ���� ����=1 ����� ��������� �������� ���� �������, ���� ��� �� �������� + xpwm_time.Tclosed_saw_direct_0 = 0; // ��� ���� ����=0 ����� ��������� �������� ���� �������, ���� ��� �� �������� + + xpwm_time.Tclosed_high = pwm_t + 2;//1; + + // ������� ����������� ��� + // "����������� ��� ��� ���� ����=0x0 + //���� SAW_DIRECTbit = 0 �� �������� ����>������� �������� �������� ���������� ���������=0 + //�� ������ ���� + //���� SAW_DIRECTbit = 1 �� �������� ����<=������� �������� �������� ���������� ���������=0 + //�� ������ ���� + xpwm_time.saw_direct.all = 0x0555; + + +// ������ � ����� + xpwm_time.pwm_tics = pwm_t; + xpwm_time.freq_pwm = freq_pwm; + xpwm_time.half_pwm_tics = xpwm_time.pwm_tics >> 1; + + xpwm_time.one_or_two_interrupts_run = PWN_COUNT_RUN_PER_INTERRUPT; + xpwm_time.init(&xpwm_time); + +// write to xilinx regs + xpwm_time.write_zero_winding_break_times(&xpwm_time); + + +// + i_WriteMemory(ADR_PWM_DIRECT, 0xffff); + i_WriteMemory(ADR_PWM_DRIVE_MODE, 0); //Choose PWM sourse PWMGenerator on Spartan 200e + // DeadTime ��� ����� ���� ���� �� ������������ + i_WriteMemory(ADR_PWM_DEAD_TIME, 360); //Dead time in tics. + stop_wdog(); + + i_WriteMemory(ADR_PWM_PERIOD, pwm_t); // Saw period in tics. 1 tic = FREQ_INTERNAL_GENERATOR_XILINX_TMS + // �������� ������� ����������� ��� + i_WriteMemory(ADR_PWM_SAW_DIRECT, xpwm_time.saw_direct.all); + //"����� �� ����� �� (15 �� 0). 0 - ����� ���, 1 - ����� ��������. + //���� ������������ ������������ Xilinx, �� ����� ����������� ��������� 0x2006(15) = 0, + //���� � ������ ������� ���� 0x2006(15) = 1, " + i_WriteMemory(ADR_TK_MASK_0, 0); + // "����� �� ����� �� (31 �� 16) ���� ������������ ������������ Xilinx, �� ����� ����������� ��������� 0x2006(15) = 0, + // ���� � ������ ������� ���� 0x2006(15) = 1, " + i_WriteMemory(ADR_TK_MASK_1, 0xffff); //Turn off additional 16 tk lines + + + i_WriteMemory(ADR_PWM_IT_TYPE, PWN_COUNT_RUN_PER_INTERRUPT); //1 or 2 interrupt per PWM period + +// +//#if (C_PROJECT_TYPE == PROJECT_BALZAM) || (C_PROJECT_TYPE == PROJECT_23550) +// i_WriteMemory(ADR_PWM_IT_TYPE, 1); //1 interrupt per PWM period +//#else +// i_WriteMemory(ADR_PWM_IT_TYPE, 0); //interrupt on each counter twist +//#endif + +/* End �f PWM Gen init */ +} + + + +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////// + +/* +void init_freq_array(void) +{ + unsigned int i = 0; + //unsigned int j = 0; + int var1 = 0; + + var1 = 32767 / (FREQ_PWM_MAX - FREQ_PWM_MIN); + + for (i = 0; i < COUNT_VAR_FREQ; i++) + { + //j = rand() / 1023; + //freq_array[i] = array_optim_freq[j]; + //do + freq_array[i] = FREQ_PWM_MIN + (rand() / var1); + //while ((freq_array[i] < 945) && (freq_array[i] > 930)); + } + + //freq_array[0] = 991; + //freq_array[1] = 1430; +} +*/ + + +//#pragma CODE_SECTION(calc_freq_pwm,".v_24pwm_run"); +//#pragma CODE_SECTION(calc_freq_pwm,".fast_run"); +/*void calc_freq_pwm() +{ + static int prev_freq_pwm = 0; + static float pwm_period = 0; + static float var0 = 0; + //static int line = 0; + //static int i = 0; + static unsigned int proc_ticks = 1; + int var1 = 0; + //static int i = 0; + + if ((f.flag_change_pwm_freq == 1) && (f.flag_random_freq == 1)) + { + if (proc_ticks >= 1) + { + proc_ticks = 0; + + + if (line == 0) + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ + 1; + if (VAR_FREQ_PWM_HZ > FREQ_PWM_MAX) + { + VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + line = 1; + } + } + else + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ - 1; + if (VAR_FREQ_PWM_HZ < FREQ_PWM) + { + VAR_FREQ_PWM_HZ = FREQ_PWM; + line = 0; + } + } + + + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //VAR_FREQ_PWM_HZ = freq_array[i]; + //i_led2_on_off(1); + + var1 = 32767 / (freq_pwm_max_hz - freq_pwm_min_hz); + VAR_FREQ_PWM_HZ = freq_pwm_min_hz + (rand() / var1); + + //i_led2_on_off(0); + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (VAR_FREQ_PWM_HZ > freq_pwm_max_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_max_hz; + } + else + { + if (VAR_FREQ_PWM_HZ < freq_pwm_min_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_min_hz; + } + } + //i++; + + //if (i >= COUNT_VAR_FREQ) + //{ + //i = 0; + //} + + } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //if (VAR_FREQ_PWM_HZ == FREQ_PWM_MIN) + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MIN; + //} + + //if (f.Rele1 == 1) + //{ + //if (i == 0) + //{ + //VAR_FREQ_PWM_HZ = 1192;; + //i = 1; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = 792; + //} + //} + //else + //{ + //i = 0; + //VAR_FREQ_PWM_HZ = 1192; + //} + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + } + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM; + //} + + + if (prev_freq_pwm != VAR_FREQ_PWM_HZ) + { + prev_freq_pwm = VAR_FREQ_PWM_HZ; + FREQ_MAX = _IQ(2.0*PI*F_STATOR_MAX/VAR_FREQ_PWM_HZ); + + var0 = (float)VAR_FREQ_PWM_HZ; + //pwm_period = ((float64)HSPCLK) / ((float64)VAR_FREQ_PWM_HZ); + + pwm_period = HSPCLK / var0; + + pwm_period = pwm_period / 2.0; + + FREQ_PWM_XTICS = ((int) pwm_period) >> 3; + + XILINX_FREQ = 16777216/(FREQ_PWM_XTICS + 1); + + FLAG_CHANGE_FREQ_PWM = 1; + } + + proc_ticks++; +} +*/ +/* +#pragma CODE_SECTION(test_calc_pwm24_dq,".v_24pwm_run"); +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta) +{ + svgen_pwm24_1.Freq = 0; + svgen_pwm24_2.Freq = 0; + + svgen_pwm24_1.Gain = U_zad1; + svgen_pwm24_2.Gain = U_zad2; + + svgen_pwm24_1.Alpha = teta; + svgen_pwm24_2.Alpha = teta; + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; +// svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIu_1; + svgen_pwm24_1.Ib = analog.iqIv_1; + svgen_pwm24_1.Ic = analog.iqIw_1;; + + svgen_pwm24_2.Ia = analog.iqIu_2; + svgen_pwm24_2.Ib = analog.iqIv_2; + svgen_pwm24_2.Ic = analog.iqIw_2; + + svgen_pwm24_1.calc_dq(&svgen_pwm24_1); + svgen_pwm24_2.calc_dq(&svgen_pwm24_2); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + +} +*/ + +/* +#pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt) +{ + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen,vt->direct_rotor, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} +*/ + + + + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt) +{ +//a + if (vt->saw_direct.bits.bit0) + vt->Ta_0 = vt->Tclosed_saw_direct_1; + else + vt->Ta_0 = vt->Tclosed_saw_direct_0; + + if (vt->saw_direct.bits.bit1) + vt->Ta_1 = vt->Tclosed_saw_direct_1; + else + vt->Ta_1 = vt->Tclosed_saw_direct_0; +//b + if (vt->saw_direct.bits.bit2) + vt->Tb_0 = vt->Tclosed_saw_direct_1; + else + vt->Tb_0 = vt->Tclosed_saw_direct_0; + + if (vt->saw_direct.bits.bit3) + vt->Tb_1 = vt->Tclosed_saw_direct_1; + else + vt->Tb_1 = vt->Tclosed_saw_direct_0; +//c + if (vt->saw_direct.bits.bit4) + vt->Tc_0 = vt->Tclosed_saw_direct_1; + else + vt->Tc_0 = vt->Tclosed_saw_direct_0; + + if (vt->saw_direct.bits.bit5) + vt->Tc_1 = vt->Tclosed_saw_direct_1; + else + vt->Tc_1 = vt->Tclosed_saw_direct_0; + + vt->prev_level = V_PWM24_PREV_PWM_CLOSE; + +} + + + + + +#pragma CODE_SECTION(correct_balance_uzpt_pwm24,".fast_run2"); +_iq correct_balance_uzpt_pwm24(_iq Tinput, _iq Kplus) +{ +//_iq pwm_t, timpuls_corr; + volatile _iq timpuls_corr; + + if (Tinput >= (-Kplus)) + timpuls_corr = CONST_IQ_1 - _IQdiv(CONST_IQ_1-Tinput, CONST_IQ_1+Kplus); + else + timpuls_corr = -CONST_IQ_1 + _IQdiv(CONST_IQ_1+Tinput, CONST_IQ_1-Kplus); + + + return timpuls_corr; +} + + + + + +#pragma CODE_SECTION(recalc_time_pwm_minimal_2_xilinx_pwm24,".fast_run2"); +void recalc_time_pwm_minimal_2_xilinx_pwm24(SVGEN_PWM24 *pwm24, + unsigned int *T0, unsigned int *T1, + int *T_imp, + _iq timpuls_corr ) +{ +//_iq pwm_t, timpuls_corr; + + volatile unsigned long pwm_t; + volatile unsigned int minimal_plus, minimal_minus; + + + + minimal_plus = pwm24->pwm_minimal_impuls_zero_plus; + minimal_minus = pwm24->pwm_minimal_impuls_zero_minus; + + // if (pwm24->prev_level == V_PWM24_PREV_PWM_CLOSE || pwm24->prev_level == V_PWM24_PREV_PWM_MIDDLE || pwm24->prev_level == V_PWM24_PREV_PWM_WORK_KM0) + // { + // minimal_plus *= 2; +// minimal_minus *= 2; +// } + + pwm_t = timpuls_corr / pwm24->XilinxFreq; + + *T_imp = pwm_t; + +// if (pwm_t>(pwm24->Tclosed_high-4*minimal_minus)) +// pwm_t=(pwm24->Tclosed_high-4*minimal_minus); + + + if (timpuls_corr >= 0) + { + *T0 = pwm_t + minimal_plus; + *T1 = pwm24->Tclosed_high - minimal_minus; + } + else + { + *T0 = minimal_plus; + *T1 = pwm24->Tclosed_high + pwm_t - minimal_minus; + } + + + if (*T0 < minimal_plus) + *T0 = minimal_plus; + + if (*T0 > (pwm24->Tclosed_high - 2 * minimal_plus)) + *T0 = (pwm24->Tclosed_high - 2 * minimal_plus); + + if (*T1 < (2 * minimal_minus)) + *T1 = 2 * minimal_minus; + + if (*T1 > (pwm24->Tclosed_high - minimal_minus)) + *T1 = (pwm24->Tclosed_high - minimal_minus); + +} + +#define WRITE_SWGEN_PWM_TIMES_VER 2//1 + +#if (WRITE_SWGEN_PWM_TIMES_VER==1) +#pragma CODE_SECTION(write_swgen_pwm_times,".fast_run2"); +void write_swgen_pwm_times(unsigned int mode_reload) +{ + + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_ABC) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + } + + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_ABC) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + } + + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_BCA) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + } + + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_BCA) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + } + + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_CAB) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + } + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_NORMAL_CAB) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + } + + // fix revers + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_BAC) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + } + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_BAC) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + } + + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_ACB) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + } + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_ACB) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + } + + if (svgen_pwm24_1.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_CBA) + { + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1; + } + if (svgen_pwm24_2.phase_sequence == V_PWM24_PHASE_SEQ_REVERS_CBA) + { + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1; + } + + xpwm_time.Tbr0_0 = break_result_1; + xpwm_time.Tbr0_1 = break_result_2; + xpwm_time.Tbr1_0 = 0;//break_result_3; + xpwm_time.Tbr1_1 = 0;//break_result_4; + xpwm_time.mode_reload = mode_reload; + + xpwm_time.write_1_2_winding_break_times(&xpwm_time); +} +#endif +/////////////////////////////////////////////////////// +// ver 2 +/////////////////////////////////////////////////////// +#if (WRITE_SWGEN_PWM_TIMES_VER==2) + +#pragma CODE_SECTION(set_pwm_times,".fast_run2"); +void set_pwm_times(unsigned int Ta0, unsigned int Ta1, unsigned int Tb0, unsigned int Tb1, unsigned int Tc0, unsigned int Tc1, unsigned int winding_num) +{ + if (winding_num == 0) + { + xpwm_time.Ta0_0 = Ta0; + xpwm_time.Ta0_1 = Ta1; + xpwm_time.Tb0_0 = Tb0; + xpwm_time.Tb0_1 = Tb1; + xpwm_time.Tc0_0 = Tc0; + xpwm_time.Tc0_1 = Tc1; + } + else + { + xpwm_time.Ta1_0 = Ta0; + xpwm_time.Ta1_1 = Ta1; + xpwm_time.Tb1_0 = Tb0; + xpwm_time.Tb1_1 = Tb1; + xpwm_time.Tc1_0 = Tc0; + xpwm_time.Tc1_1 = Tc1; + } +} + +#pragma CODE_SECTION(process_phase_sequence,".fast_run2"); +void process_phase_sequence(SVGEN_PWM24 svgen_pwm, unsigned int winding_num) +{ + switch (svgen_pwm.phase_sequence) + { + case V_PWM24_PHASE_SEQ_NORMAL_ABC: + set_pwm_times(svgen_pwm.Ta_0, svgen_pwm.Ta_1, svgen_pwm.Tb_0, svgen_pwm.Tb_1, svgen_pwm.Tc_0, svgen_pwm.Tc_1, winding_num); + break; + case V_PWM24_PHASE_SEQ_NORMAL_BCA: + set_pwm_times(svgen_pwm.Tb_0, svgen_pwm.Tb_1, svgen_pwm.Tc_0, svgen_pwm.Tc_1, svgen_pwm.Ta_0, svgen_pwm.Ta_1, winding_num); + break; + case V_PWM24_PHASE_SEQ_NORMAL_CAB: + set_pwm_times(svgen_pwm.Tc_0, svgen_pwm.Tc_1, svgen_pwm.Ta_0, svgen_pwm.Ta_1, svgen_pwm.Tb_0, svgen_pwm.Tb_1, winding_num); + break; + case V_PWM24_PHASE_SEQ_REVERS_BAC: + set_pwm_times(svgen_pwm.Tb_0, svgen_pwm.Tb_1, svgen_pwm.Ta_0, svgen_pwm.Ta_1, svgen_pwm.Tc_0, svgen_pwm.Tc_1, winding_num); + break; + case V_PWM24_PHASE_SEQ_REVERS_ACB: + set_pwm_times(svgen_pwm.Ta_0, svgen_pwm.Ta_1, svgen_pwm.Tc_0, svgen_pwm.Tc_1, svgen_pwm.Tb_0, svgen_pwm.Tb_1, winding_num); + break; + case V_PWM24_PHASE_SEQ_REVERS_CBA: + set_pwm_times(svgen_pwm.Tc_0, svgen_pwm.Tc_1, svgen_pwm.Tb_0, svgen_pwm.Tb_1, svgen_pwm.Ta_0, svgen_pwm.Ta_1, winding_num); + break; + } +} +#pragma CODE_SECTION(write_swgen_pwm_times,".fast_run2"); +void write_swgen_pwm_times(unsigned int mode_reload) +{ + process_phase_sequence(svgen_pwm24_1, 0); + process_phase_sequence(svgen_pwm24_2, 1); + + // fix breaks + xpwm_time.Tbr0_0 = break_result_1; + xpwm_time.Tbr0_1 = break_result_2; + xpwm_time.Tbr1_0 = 0; // break_result_3; + xpwm_time.Tbr1_1 = 0; // break_result_4; + xpwm_time.mode_reload = mode_reload; + + xpwm_time.write_1_2_winding_break_times(&xpwm_time); +} +#endif + + + + + + + + +/////////////////////////////////////////////////////// + +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt) +{ + //a + if (vt->saw_direct.bits.bit0) + vt->Ta_0 = vt->Tclosed_saw_direct_0; + else + vt->Ta_0 = vt->Tclosed_saw_direct_1; + + if (vt->saw_direct.bits.bit1) + vt->Ta_1 = vt->Tclosed_saw_direct_0; + else + vt->Ta_1 = vt->Tclosed_saw_direct_1; + //b + if (vt->saw_direct.bits.bit2) + vt->Tb_0 = vt->Tclosed_saw_direct_0; + else + vt->Tb_0 = vt->Tclosed_saw_direct_1; + + if (vt->saw_direct.bits.bit3) + vt->Tb_1 = vt->Tclosed_saw_direct_0; + else + vt->Tb_1 = vt->Tclosed_saw_direct_1; + //c + if (vt->saw_direct.bits.bit4) + vt->Tc_0 = vt->Tclosed_saw_direct_0; + else + vt->Tc_0 = vt->Tclosed_saw_direct_1; + + if (vt->saw_direct.bits.bit5) + vt->Tc_1 = vt->Tclosed_saw_direct_0; + else + vt->Tc_1 = vt->Tclosed_saw_direct_1; + + + vt->prev_level = V_PWM24_PREV_PWM_MIDDLE; + +/* + + vt->Ta_0 = 0; + vt->Ta_1 = vt->Tclosed;//var_freq_pwm_xtics + 1; + + vt->Tb_0 = 0; + vt->Tb_1 = vt->Tclosed;// var_freq_pwm_xtics + 1; + + vt->Tc_0 = 0; + vt->Tc_1 = vt->Tclosed;// var_freq_pwm_xtics + 1; + */ +} + +/////////////////////////////////////////////////////// +/////////////////////////////////////////////////////// +/////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(detect_level_interrupt,".fast_run"); +unsigned int detect_level_interrupt(int flag_second_PCH) +{ + unsigned int curr_period1, curr_period2, curr_period0; + static unsigned int count_err_read_pwm_xilinx = 0; + + + WriteMemory(ADR_SAW_REQUEST, 0x8000); + curr_period0 = ReadMemory(ADR_SAW_VALUE); + WriteMemory(ADR_SAW_REQUEST, 0x8000); + curr_period1 = ReadMemory(ADR_SAW_VALUE); + WriteMemory(ADR_SAW_REQUEST, 0x8000); + curr_period2 = ReadMemory(ADR_SAW_VALUE); + + xpwm_time.current_period = curr_period2; + + + // �� ��������� � ������ ����� ����? + if (xpwm_time.current_period<xpwm_time.half_pwm_tics) + { + xpwm_time.where_interrupt = PWM_LOW_LEVEL_INTERRUPT; + xpwm_time.what_next_interrupt = PWM_HIGH_LEVEL_INTERRUPT; + xpwm_time.do_sync_out = (flag_second_PCH==0); + } + else // �� ��������� � ������� ����� ����? + { + xpwm_time.where_interrupt = PWM_HIGH_LEVEL_INTERRUPT; + xpwm_time.what_next_interrupt = PWM_LOW_LEVEL_INTERRUPT; + xpwm_time.do_sync_out = !(flag_second_PCH==0); + } + +// �� ���� ���� ��� ���������� ��� ����� �� ����� ������� ����������� � ���������� + if (curr_period2>curr_period1) // ���� ����� �� ���� + { + if ((curr_period2-curr_period1)>xpwm_time.half_pwm_tics)// ����� ������� ������� + { +// xpwm_time.what_next_interrupt = 1; + // ���������� ������ + return 1; + } + } + else// ���� ���� �� ���� + { + if ((curr_period1-curr_period2)>xpwm_time.half_pwm_tics)// ����� ������� ������� + { + // ���������� ������ + return 1; + } + } + + // ��� ������, ��! + return 0; + + +} + diff --git a/Inu/Src/main/v_pwm24_v2.h b/Inu/Src/main/v_pwm24_v2.h new file mode 100644 index 0000000..e0e1baa --- /dev/null +++ b/Inu/Src/main/v_pwm24_v2.h @@ -0,0 +1,161 @@ +#ifndef _V_PWM24_H +#define _V_PWM24_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "IQmathLib.h" +#include "DSP281x_Device.h" +#include "word_structurs.h" + + +#include "vhzprof.h" +#include "rmp_cntl_v1.h" + +enum { V_PWM24_PREV_PWM_CLOSE = 1, + V_PWM24_PREV_PWM_MIDDLE, + V_PWM24_PREV_PWM_WORK_KM0, + V_PWM24_PREV_PWM_WORK +}; + +enum { V_PWM24_PHASE_SEQ_NORMAL_ABC = 1, + V_PWM24_PHASE_SEQ_NORMAL_BCA, + V_PWM24_PHASE_SEQ_NORMAL_CAB, + V_PWM24_PHASE_SEQ_REVERS_ACB, + V_PWM24_PHASE_SEQ_REVERS_CBA, + V_PWM24_PHASE_SEQ_REVERS_BAC +}; + + + + +typedef struct { _iq freq1; + _iq k1; + _iq k2; + } ALG_PWM24; + +typedef ALG_PWM24 *ALG_PWM24_handle; + + +#define ALG_PWM24_DEFAULTS {0,0,0} +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// + + +typedef struct { // _iq Gain; // Input: reference gain voltage (pu) + //_iq Offset; // Input: reference offset voltage (pu) +// _iq Freq; // Input: reference frequency (pu) +// _iq FreqMax; // Parameter: Maximum step angle = 6*base_freq*T (pu) +// _iq Alpha; // History: Sector angle (pu) + //_iq Full_Alpha; + //_iq NewEntry; // History: Sine (angular) look-up pointer (pu) +// _iq delta_U; +// _iq delta_t; + //int16 Periodmax; + //int16 PeriodMin; + unsigned int XilinxFreq; // Xilinx freq in TIC + + unsigned int pwm_minimal_impuls_zero_plus; + unsigned int pwm_minimal_impuls_zero; + unsigned int pwm_minimal_impuls_zero_minus; + + WORD_UINT2BITS_STRUCT saw_direct; + + //int region; + //Uint32 SectorPointer; // History: Sector number (Q0) - independently with global Q + //PIDREG3 delta_t; +// _iq Ia; +// _iq Ib; +// _iq Ic; + unsigned int number_svgen; + unsigned int phase_sequence; // ����� �� ��� ������� ������� ����������� ����������� + int prev_level; // ���������� ��������� ����, ��� �������� �� middle ��� close � ������� + unsigned int Tclosed_high; + unsigned int Tclosed_saw_direct_0; + unsigned int Tclosed_saw_direct_1; + + + unsigned int Ta_0; + unsigned int Ta_1; + + int Ta_imp; + + unsigned int Tb_0; + unsigned int Tb_1; + + int Tb_imp; + + unsigned int Tc_0; + unsigned int Tc_1; + + int Tc_imp; + +// void (*calc)(); // Pointer to calculation function +// void (*calc_dq)(); // Pointer to calculation function which don`t calculate angle from freq + } SVGEN_PWM24; + +typedef SVGEN_PWM24 *SVGEN_PWM24_handle; + + +//#define SVGEN_PWM24_TIME_DEFAULTS { 0,0,0,0 } + + +#define SVGEN_PWM24_DEFAULTS { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +// (void (*)(unsigned int))svgen_pwm24_calc } + +//extern int ar_sa_a[3][4][7]; + +extern SVGEN_PWM24 svgen_pwm24_1; +extern SVGEN_PWM24 svgen_pwm24_2; + +extern _iq pidCur_Kp; +extern _iq pidCur_Ki; + +extern _iq iq_alfa_coef; + +extern _iq iq_koef_mod_korrect_1; +extern _iq iq_koef_mod_korrect_2; + + + +void write_swgen_pwm_times(unsigned int mode_reload); + +//void change_freq_pwm(_iq FreqMax, int freq_pwm_xtics, _iq XilinxFreq); + +unsigned int detect_level_interrupt(int flag_second_PCH); + + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt); +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt); + + +_iq correct_balance_uzpt_pwm24(_iq Tinput, _iq Kplus); + +void recalc_time_pwm_minimal_2_xilinx_pwm24(SVGEN_PWM24 *pwm24, + unsigned int *T0, unsigned int *T1, + int *T_imp, + _iq timpuls_corr ); + + + +//////////////////////////////////////////////////////////// + +void InitXPWM(unsigned int freq_pwm); + +void start_PWM24(int O1, int O2); + +void InitPWM_Variables(int n_pch); + +////////////////////////////////////////////// + +extern ALG_PWM24 alg_pwm24; +extern RMP_V1 rmp_freq; +extern VHZPROF vhz1; + + +#ifdef __cplusplus + } +#endif + +#endif /* _V_PWM24_H */ diff --git a/Inu/Src/main/v_rotor.c b/Inu/Src/main/v_rotor.c new file mode 100644 index 0000000..1da2a2f --- /dev/null +++ b/Inu/Src/main/v_rotor.c @@ -0,0 +1,1095 @@ +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include <params_bsu.h> +#include <v_rotor.h> + +#include "filter_v1.h" +#include "xp_cds_in.h" +#include "xp_inc_sensor.h" +#include "xp_project.h" +#include "params.h" +#include "pwm_test_lines.h" +#include "params_norma.h" +#include "mathlib.h" #include "params_alg.h" + + +#pragma DATA_SECTION(WRotor,".fast_vars"); +WRotorValues WRotor = WRotorValues_DEFAULTS; + +#if (SENSOR_ALG==SENSOR_ALG_23550) + +#pragma DATA_SECTION(WRotorPBus,".slow_vars"); +WRotorValuesAngle WRotorPBus = WRotorValuesAngle_DEFAULTS; + +#pragma DATA_SECTION(rotor_error_update_count,".fast_vars"); +unsigned int rotor_error_update_count = 0; + + +#define SIZE_BUF_SENSOR_LOGS 32 +#pragma DATA_SECTION(sensor_1_zero,".slow_vars"); +unsigned int sensor_1_zero[6+4+8][SIZE_BUF_SENSOR_LOGS], count_sensor_1_zero=0; + +#endif + +_iq koefW = _IQ(0.05); //0.05 +_iq koefW2 = _IQ(0.01); //0.05 +_iq koefW3 = _IQ(0.002); //0.05 + + + + + + + +#if (SENSOR_ALG==SENSOR_ALG_23550) +/////////////////////////////////////////////////////////////// +void rotorInit(void) +{ + WRotorPBus.ModeAutoDiscret = 1; +} + + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +#define MAX_COUNT_OVERFULL_DISCRET 2250 +#define MAX_DIRECTION 4000 +#define MAX_DIRECTION_2 2000 +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +void RotorDirectionFilter(int RotorDirectionIn, int *RotorDirectionOut, int *RotorDirectionOut2, int *count_direction) +{ + +// static int count_direction = 0; +// static int count_direction_minus = 0; + + + if (RotorDirectionIn==0) + { + if (*count_direction>0) (*count_direction)--; + if (*count_direction<0) (*count_direction)++; +// if (count_direction_minus>0) count_direction_minus--; + } + else + if (RotorDirectionIn>0) + { + if (*count_direction<MAX_DIRECTION) (*count_direction)++; +// if (count_direction_minus>0) count_direction_minus--; + } + else + { + if (*count_direction>-MAX_DIRECTION) (*count_direction)--; +// if (count_direction_plus>0) count_direction_plus--; + } + + + if (RotorDirectionIn==0) + *RotorDirectionOut = 0; + else + if (RotorDirectionIn>0) + *RotorDirectionOut = 1; + else + *RotorDirectionOut = -1; + + + if (*count_direction>MAX_DIRECTION_2) + *RotorDirectionOut2 = 1; + else + if (*count_direction<-MAX_DIRECTION_2) + *RotorDirectionOut2 = -1; + else + *RotorDirectionOut2 = 0; + + + +} +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +#define LEVEL_VALUE_SENSOR_OVERFULL 65535 +#define MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS 4000 +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(AnalisatorRotorSensorPBus,".fast_run"); +int AnalisatorRotorSensorPBus(_iq d1, _iq d2, unsigned int *count_overfull_discret, unsigned int *count_zero_discret, _iq *prev_iqTimeRotor, + unsigned int *discret_out, unsigned int discret_in, _iq *iqWRotorCalcBeforeRegul, _iq *iqWRotorCalc, + int modeS1, int modeS2, + int valid_sensor_direct, int valid_sensor_90, + unsigned int *error_count ) +{ + int flag_not_ready_rotor, flag_overfull_rotor; + _iq iqTimeRotor; + // discret0 = 2 mks +// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + // discret1 = 20 ns +// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + +// _iq iqWRotorSumm;//,iqWRotorCalc; + + static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 ��. + static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 ��. + static unsigned int discret; + + + if (valid_sensor_direct == 0) + d1 = 0; + if (valid_sensor_90 == 0) + d2 = 0; + + +// ��� ���-�� ����� �� ���, ���� ����� ������������� �� ����� �������. + if (valid_sensor_direct == 0 && valid_sensor_90 == 0) + { + if (*error_count<MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS) + { + (*error_count)++; + return 0; + } + else + return 1; // ������!!! � �� ����� == MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS!!! + } + + + if (valid_sensor_direct == 1 && valid_sensor_90 == 0) + { + modeS2 = modeS1; + } + + if (valid_sensor_direct == 0 && valid_sensor_90 == 1) + { + modeS1 = modeS2; + } + + if (modeS1 == modeS2) + { + discret = modeS1; + *error_count = 0; + } + else + { + discret = 0; + if (*error_count<MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS) + { + (*error_count)++; + return 0; + } + else + return 1; // ������!!! � �� ����� == MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS!!! + } + +// ��� ��� ������ ���, ������� �������� + *error_count = 0; + + + flag_not_ready_rotor = 0; + flag_overfull_rotor = 0; + + if (d1 != LEVEL_VALUE_SENSOR_OVERFULL && d1 != 0 && d2 != LEVEL_VALUE_SENSOR_OVERFULL && d2 != 0) + { + // ��� ���������� + + } + else + if (d1 == 0 && d2 != LEVEL_VALUE_SENSOR_OVERFULL && d2 != 0) + { + // d1 - �����, d2 ���� ���������� + d1 = d2; + } + else + if (d1 == LEVEL_VALUE_SENSOR_OVERFULL && d2 != LEVEL_VALUE_SENSOR_OVERFULL && d2 != 0) + { + // d1 - �����, d2 ���� ���������� + d1 = d2; + } + else + if (d2 == LEVEL_VALUE_SENSOR_OVERFULL && d1 != LEVEL_VALUE_SENSOR_OVERFULL && d1 != 0) + { + // d2 - �����, d1 ���� ���������� + d2 = d1; + } + else + if (d2 == 0 && d1 != LEVEL_VALUE_SENSOR_OVERFULL && d1 != 0) + { + // d2 - �����, d1 ���� ���������� + d2 = d1; + } + else + if (d1 == 0 && d2 == 0) + { + flag_not_ready_rotor = 1; + } + else + if (d2 == LEVEL_VALUE_SENSOR_OVERFULL && d1 == LEVEL_VALUE_SENSOR_OVERFULL) + { + flag_overfull_rotor = 1; + d1 = d2 = 0; + } + else + if (d2 == LEVEL_VALUE_SENSOR_OVERFULL && d1 == 0) + { + flag_overfull_rotor = 1; + d1 = d2 = 0; + } + else + if (d1 == LEVEL_VALUE_SENSOR_OVERFULL && d2 == 0) + { + flag_overfull_rotor = 1; + d1 = d2 = 0; + } + + iqTimeRotor = (d1+d2)>>1; + + + +// max OVERFULL + if (flag_overfull_rotor) + { + if (*count_overfull_discret<MAX_COUNT_OVERFULL_DISCRET) + (*count_overfull_discret)++; + } + else + { + if (*count_overfull_discret>0) + (*count_overfull_discret)--; + } + +// zero? + if (flag_not_ready_rotor) + { + if (*count_zero_discret<MAX_COUNT_OVERFULL_DISCRET) + (*count_zero_discret)++; + } + else + { + if (*count_zero_discret>0) + (*count_zero_discret)--; + } + +// real zero? + if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) + { + // ���� ��� ������� �����, ������ ����� ����! + iqWRotorCalc = 0; + *prev_iqTimeRotor = 0; + iqTimeRotor = 0; + } + else + { + // ���� ��� �� ������� �����, ������ ����� ������ �������� prev_iqTimeRotor + if (iqTimeRotor==0) + iqTimeRotor = *prev_iqTimeRotor; + } + *prev_iqTimeRotor = iqTimeRotor; + + + +// ����� ������� ��������� + if (WRotorPBus.ModeAutoDiscret==1) + { + if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) || (iqTimeRotor==0) ) + { + // ��� ��� ������������ ��������� ��� ����� ������������, �������=0 + // ����� �������� discret_out = 0 + if (discret_in == 1) // ��� ��� ���� ����������� discret? + { + // discret ��� =1, ����������� �� 0. + *discret_out = 0; + *count_overfull_discret = 0; // ���� ��� ���� ����! + } + + } + else + { + // �����. ������� discret==0 �����... + if (discret==0 && iqTimeRotor<time_level_discret_0to1 && iqTimeRotor!=65535) + *discret_out = 1; + + // �����. ������� discret==1 �����... + if (discret==1 && iqTimeRotor>time_level_discret_1to0 && iqTimeRotor!=65535) + *discret_out = 0; + } + } + + if (WRotorPBus.ModeAutoDiscret==2) + { + *discret_out = 0; + } + + if (WRotorPBus.ModeAutoDiscret==3) + { + *discret_out = 1; + } + + if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) ) + { + // ��� ��� ����� � 0, �.�. ������� �������� ���� ��������! + *prev_iqTimeRotor = iqTimeRotor = 0; + } + + + + + if ((iqTimeRotor != 0)) // && (WRotorPBus.iqTimeRotor<65535) + { + if (discret==0) + *iqWRotorCalcBeforeRegul = KoefNorm_discret0 / iqTimeRotor; + if (discret==1) + *iqWRotorCalcBeforeRegul = KoefNorm_discret1 / iqTimeRotor; + + *iqWRotorCalc = exp_regul_iq(koefW, *iqWRotorCalc, *iqWRotorCalcBeforeRegul); + } + else + { + *iqWRotorCalc = 0; + *iqWRotorCalcBeforeRegul = 0; + } + + +// if (*iqWRotorCalc == 0) +// *RotorDirection = 0; + + + return 0; + +} +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(RotorMeasurePBus,".fast_run"); +void RotorMeasurePBus(void) +{ + // discret0 = 2 mks +// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + // discret1 = 20 ns +// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + + static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 ��. + static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 ��. + + static long long KoefNorm_angle = 16384LL; //2^24/1024 +// volatile float MyVar0 = 0; + + unsigned int MyVar3 = 0; +// int direction1 = 0, direction2 = 0; + volatile unsigned int discret; + + static unsigned int discret_out1, discret_out2; + + static int count_full_oborots = 0; + static unsigned int count_overfull_discret1 = 0; + static unsigned int count_zero_discret1 = 0; + static unsigned int count_overfull_discret2 = 0; + static unsigned int count_zero_discret2 = 0; + + static unsigned int count_discret_to_1 = 0; + static unsigned int count_discret_to_0 = 0; + + static unsigned int c_error_pbus_1 = 0; + static unsigned int c_error_pbus_2 = 0; + + + static _iq prev_iqTimeRotor1 = 0, prev_iqTimeRotor2 = 0; + + _iq iqWRotorSumm = 0; + + int flag_not_ready_rotor1, flag_overfull_rotor1; + int flag_not_ready_rotor2, flag_overfull_rotor2; + + //i_led1_on_off(1); + + + + flag_not_ready_rotor1 = 0; + flag_overfull_rotor1 = 0; + flag_not_ready_rotor2 = 0; + flag_overfull_rotor2 = 0; + + + + discret = project.cds_in[0].read.sbus.enabled_channels.bit.discret; + if (project.cds_in[0].read.sbus.enabled_channels.bit.discret != project.cds_in[0].write.sbus.enabled_channels.bit.discret) + discret = 2; + + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + sensor_1_zero[0][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S1; + sensor_1_zero[1][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1; + sensor_1_zero[2][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1; + sensor_1_zero[3][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S2; + sensor_1_zero[4][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2; + sensor_1_zero[5][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2; + } + sensor_1_zero[6][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt; + sensor_1_zero[7][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt90; + sensor_1_zero[8][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt; + sensor_1_zero[9][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt90; + + sensor_1_zero[10][count_sensor_1_zero] = inc_sensor.data.Time1; + sensor_1_zero[11][count_sensor_1_zero] = inc_sensor.data.Impulses1; + sensor_1_zero[12][count_sensor_1_zero] = inc_sensor.data.CountZero1; + sensor_1_zero[13][count_sensor_1_zero] = inc_sensor.data.CountOne1; + + sensor_1_zero[14][count_sensor_1_zero] = inc_sensor.data.Time2; + sensor_1_zero[15][count_sensor_1_zero] = inc_sensor.data.Impulses2; + sensor_1_zero[16][count_sensor_1_zero] = inc_sensor.data.CountZero2; + sensor_1_zero[17][count_sensor_1_zero] = inc_sensor.data.CountOne2; + + count_sensor_1_zero++; + if (count_sensor_1_zero>=SIZE_BUF_SENSOR_LOGS) + { + count_sensor_1_zero = 0; + count_full_oborots++; + if (count_full_oborots>3) + count_full_oborots = 0; + } +/* + if (count_sensor_1_zero==904) + { + discret = 3; + } +*/ + +#if (ENABLE_ROTOR_SENSOR_ZERO_SIGNAL==1) + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) + WRotorPBus.iqWRotorRawAngle1F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1-32768; + WRotorPBus.iqWRotorRawAngle1R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1-32768; + WRotorPBus.iqAngle1F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1F; + WRotorPBus.iqAngle1R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1R; +#else + WRotorPBus.iqWRotorRawAngle1F = 0; + WRotorPBus.iqWRotorRawAngle1R = 0; + WRotorPBus.iqAngle1F = 0; + WRotorPBus.iqAngle1R = 0; +#endif + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) + WRotorPBus.iqWRotorRawAngle2F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2-32768; + WRotorPBus.iqWRotorRawAngle2R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2-32768; + WRotorPBus.iqAngle2F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2F; + WRotorPBus.iqAngle2R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2R; +#else + WRotorPBus.iqWRotorRawAngle2F = 0; + WRotorPBus.iqWRotorRawAngle2R = 0; + WRotorPBus.iqAngle2F = 0; + WRotorPBus.iqAngle2R = 0; +#endif + } + else + { + WRotorPBus.iqWRotorRawAngle1F = 0; + WRotorPBus.iqWRotorRawAngle1R = 0; + WRotorPBus.iqAngle1F = 0; + WRotorPBus.iqAngle1R = 0; + + WRotorPBus.iqWRotorRawAngle2F = 0; + WRotorPBus.iqWRotorRawAngle2R = 0; + WRotorPBus.iqAngle2F = 0; + WRotorPBus.iqAngle2R = 0; + + } +#endif + + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) + //************************************************************************************************** + MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw0 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw0 = 0; + } + + MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt90; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw1 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw1 = 0; + } +#else + WRotorPBus.iqWRotorRaw0 = 0; + WRotorPBus.iqWRotorRaw1 = 0; +#endif + + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) + //*************************************************************************************************** + MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw2 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw2 = 0; + } + + MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt90; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw3 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw3 = 0; + } +#else + WRotorPBus.iqWRotorRaw2 = 0; + WRotorPBus.iqWRotorRaw3 = 0; +#endif + + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) +// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90 ) + AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw0, WRotorPBus.iqWRotorRaw1, &count_overfull_discret1, &count_zero_discret1, + &prev_iqTimeRotor1, &discret_out1, project.cds_in[0].read.sbus.enabled_channels.bit.discret, + &WRotorPBus.iqWRotorCalcBeforeRegul1, &WRotorPBus.iqWRotorCalc1, + project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_90, + project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90, + &c_error_pbus_1 ); +#endif + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) +// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90 ) + AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw2, WRotorPBus.iqWRotorRaw3, &count_overfull_discret2, &count_zero_discret2, + &prev_iqTimeRotor2, &discret_out2, project.cds_in[0].read.sbus.enabled_channels.bit.discret, + &WRotorPBus.iqWRotorCalcBeforeRegul2, &WRotorPBus.iqWRotorCalc2, + project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_90, + project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90, + &c_error_pbus_2); +#endif + + + // RotorDirectionFilter(WRotorPBus.RotorDirectionInstant, &WRotorPBus.RotorDirectionSlow); + + + + if (discret_out1==1 || discret_out2==1) + { + project.cds_in[0].write.sbus.enabled_channels.bit.discret = 1; + count_discret_to_1++; + } + else + { + project.cds_in[0].write.sbus.enabled_channels.bit.discret = 0; + count_discret_to_0++; + } + + +} + + + +#define MAX_COUNT_OVERFULL_DISCRET_2 150 +#pragma CODE_SECTION(RotorMeasure,".fast_run"); +void RotorMeasure(void) +{ + + // 600 Khz clock on every edge +// static long long KoefNorm = 53635601LL;//((600 000/6256/NORMA_WROTOR/2) * ((long)2 << 24)); //15 - NormaWRotor 782*8 = 6256 +// static long long KoefNormMS = 491520000LL;//((600 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 +// static long long KoefNormNS = 49152000000LL;//((60 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormMS = 122880000LL;//((600 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormNS = 12288000000LL;//((60 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormImpulses = 838860800000000LL;// (2^24 * 1000000000 / (Impulses(ns)) / NORMA_WROTOR + + static _iq max_value_rotor = _IQ(500.0/60.0/NORMA_FROTOR); + static _iq wrotor_add_ramp = _IQ(0.001/NORMA_FROTOR); + +// volatile float MyVar0 = 0; +// volatile unsigned int MyVar1 = 0; +// volatile unsigned int MyVar2 = 0; + unsigned int MyVar3; + + + inc_sensor.read_sensors(&inc_sensor); + + // flag_not_ready_rotor = 0; + +//************************************************************************************************** +// sensor 1 + + if (inc_sensor.use_sensor1) + { + MyVar3 = inc_sensor.data.CountOne1; +// MyVar3 = (unsigned long) rotation_sensor.in_plane.out.CountOne1; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_21_ON; +#endif + + WRotor.iqWRotorRaw0 = MyVar3; + } + else + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_21_OFF; +#endif + + WRotor.iqWRotorRaw0 = 0; + } + MyVar3 = inc_sensor.data.CountZero1; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_22_ON; +#endif + WRotor.iqWRotorRaw1 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_22_OFF; +#endif + WRotor.iqWRotorRaw1 = 0; + } + } + else + { + WRotor.iqWRotorRaw0 = 0; + WRotor.iqWRotorRaw1 = 0; + } + //logpar.uns_log0 = (Uint16)(my_var1); + //logpar.uns_log1 = (Uint16)(my_var2); + + // sensor 2 + if (inc_sensor.use_sensor2) + { + MyVar3 = inc_sensor.data.CountOne2; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_18_ON; +#endif + WRotor.iqWRotorRaw2 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_18_OFF; +#endif + WRotor.iqWRotorRaw2 = 0; + } + + MyVar3 = inc_sensor.data.CountZero2; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_23_ON; +#endif + WRotor.iqWRotorRaw3 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_23_OFF; +#endif + WRotor.iqWRotorRaw3 = 0; + } + } + else + { + WRotor.iqWRotorRaw2 = 0; + WRotor.iqWRotorRaw3 = 0; + } + +// if (WRotor.iqWRotorRaw0==0 && WRotor.iqWRotorRaw1==0 && WRotor.iqWRotorRaw2==0 && WRotor.iqWRotorRaw3==0) +// flag_not_ready_rotor = 1; + + if (WRotor.iqWRotorRaw0==0) + { + if (WRotor.count_zero_discret0==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0 = 0; + } + else + { + WRotor.iqWRotorRaw0 = WRotor.prev_iqWRotorRaw0; + WRotor.count_zero_discret0++; + } + } + else + { + WRotor.count_zero_discret0 = 0; + WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0; + } + + if (WRotor.iqWRotorRaw1==0) + { + if (WRotor.count_zero_discret1==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1 = 0; + } + else + { + WRotor.iqWRotorRaw1 = WRotor.prev_iqWRotorRaw1; + WRotor.count_zero_discret1++; + } + } + else + { + WRotor.count_zero_discret1 = 0; + WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1; + } + + if (WRotor.iqWRotorRaw2==0) + { + if (WRotor.count_zero_discret2==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2 = 0; + } + else + { + WRotor.iqWRotorRaw2 = WRotor.prev_iqWRotorRaw2; + WRotor.count_zero_discret2++; + } + } + else + { + WRotor.count_zero_discret2 = 0; + WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2; + } + + if (WRotor.iqWRotorRaw3==0) + { + if (WRotor.count_zero_discret3==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3 = 0; + } + else + { + WRotor.iqWRotorRaw3 = WRotor.prev_iqWRotorRaw3; + WRotor.count_zero_discret3++; + } + } + else + { + WRotor.count_zero_discret3 = 0; + WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3; + } + + + WRotor.iqTimeSensor1 = WRotor.iqWRotorRaw0 + WRotor.iqWRotorRaw1; + WRotor.iqTimeSensor2 = WRotor.iqWRotorRaw2 + WRotor.iqWRotorRaw3; + + // +// // zero? +// if (flag_not_ready_rotor) +// { +// if (*count_zero_discret<MAX_COUNT_OVERFULL_DISCRET) +// (*count_zero_discret)++; +// } +// else +// { +// if (*count_zero_discret>0) +// (*count_zero_discret)--; +// } +// +// // real zero? +// if (count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) +// { +// // ���� ��� ������� �����, ������ ����� ����! +// WRotor.iqTimeSensor1 = 0; +// WRotor.prev_iqTimeSensor1 = 0; +// } +// else +// { +// // ���� ��� �� ������� �����, ������ ����� ������ �������� prev_iqTimeRotor +// if (WRotor.iqTimeSensor1==0) +// WRotor.iqTimeSensor1 = WRotor.prev_iqTimeSensor1; +// } +// WRotor.prev_iqTimeSensor1 = WRotor.iqTimeSensor1; +// +// +// // max OVERFULL +// if (flag_overfull_rotor) +// { +// if (*count_overfull_discret<MAX_COUNT_OVERFULL_DISCRET) +// (*count_overfull_discret)++; +// } +// else +// { +// if (*count_overfull_discret>0) +// (*count_overfull_discret)--; +// } +// +// // zero? +// if (flag_not_ready_rotor) +// { +// if (*count_zero_discret<MAX_COUNT_OVERFULL_DISCRET) +// (*count_zero_discret)++; +// } +// else +// { +// if (*count_zero_discret>0) +// (*count_zero_discret)--; +// } +// +// // real zero? +// if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) +// { +// // ���� ��� ������� �����, ������ ����� ����! +// iqWRotorCalc = 0; +// *prev_iqTimeRotor = 0; +// iqTimeRotor = 0; +// } +// else +// { +// // ���� ��� �� ������� �����, ������ ����� ������ �������� prev_iqTimeRotor +// if (iqTimeRotor==0) +// iqTimeRotor = *prev_iqTimeRotor; +// } +// *prev_iqTimeRotor = iqTimeRotor; +// +// +// + +/// + if (WRotor.iqTimeSensor1 != 0 && inc_sensor.use_sensor1) + { + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==0) + WRotor.iqWRotorCalcBeforeRegul1 = KoefNormMS / WRotor.iqTimeSensor1; + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==1) + WRotor.iqWRotorCalcBeforeRegul1 = KoefNormNS / WRotor.iqTimeSensor1; + + if (WRotor.iqWRotorCalcBeforeRegul1 > max_value_rotor) + { + WRotor.iqWRotorCalc1 = 0; + WRotor.iqWRotorCalcBeforeRegul1 = 0; + } + else + WRotor.iqWRotorCalc1 = exp_regul_iq(koefW, WRotor.iqWRotorCalc1, WRotor.iqWRotorCalcBeforeRegul1); + + ///// + if (WRotor.iqWRotorCalc1) + { + if (WRotor.iqPrevWRotorCalc1 != WRotor.iqWRotorCalc1) + { + WRotor.iqWRotorCalc1Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc1Ramp, WRotor.iqWRotorCalc1); + WRotor.iqPrevWRotorCalc1 = WRotor.iqWRotorCalc1; + } + } + else + { + WRotor.iqPrevWRotorCalc1 = 0; + WRotor.iqWRotorCalc1Ramp = 0; + } + //// + } + else + { + WRotor.iqWRotorCalc1 = 0; + WRotor.iqWRotorCalcBeforeRegul1 = 0; + } +/// + if (WRotor.iqTimeSensor2 != 0 && inc_sensor.use_sensor2) + { + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==0) + WRotor.iqWRotorCalcBeforeRegul2 = KoefNormMS / WRotor.iqTimeSensor2; + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==1) + WRotor.iqWRotorCalcBeforeRegul2 = KoefNormNS / WRotor.iqTimeSensor2; + + if (WRotor.iqWRotorCalcBeforeRegul2 > max_value_rotor) + { + WRotor.iqWRotorCalc2 = 0; + WRotor.iqWRotorCalcBeforeRegul2 = 0; + } + else + WRotor.iqWRotorCalc2 = exp_regul_iq(koefW, WRotor.iqWRotorCalc2, WRotor.iqWRotorCalcBeforeRegul2); + + + + ///// + if (WRotor.iqWRotorCalc2) + { + if (WRotor.iqPrevWRotorCalc2 != WRotor.iqWRotorCalc2) + { + WRotor.iqWRotorCalc2Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc2Ramp, WRotor.iqWRotorCalc2); + WRotor.iqPrevWRotorCalc2 = WRotor.iqWRotorCalc2; + } + } + else + { + WRotor.iqPrevWRotorCalc2 = 0; + WRotor.iqWRotorCalc2Ramp = 0; + } + //// + } + else + { + WRotor.iqWRotorCalc2 = 0; + WRotor.iqWRotorCalcBeforeRegul2 = 0; + } +/// + if (inc_sensor.data.TimeCalcFromImpulses1 && inc_sensor.use_sensor1) + WRotor.iqWRotorImpulsesBeforeRegul1 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses1 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); + else + WRotor.iqWRotorImpulsesBeforeRegul1 = 0; + + WRotor.iqWRotorImpulses1 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses1, WRotor.iqWRotorImpulsesBeforeRegul1); + + if (inc_sensor.data.TimeCalcFromImpulses2 && inc_sensor.use_sensor2) + WRotor.iqWRotorImpulsesBeforeRegul2 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses2 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); + else + WRotor.iqWRotorImpulsesBeforeRegul2 = 0; + + WRotor.iqWRotorImpulses2 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses2, WRotor.iqWRotorImpulsesBeforeRegul2); + + + // WRotor.iqWRotorCalcBeforeRegul = _IQdiv(WRotor.iqWRotorCalcBeforeRegul,IQ_CONST_3); +} +#define LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS 50 // Oborot +void select_values_wrotor(void) +{ + static _iq level_switch_to_get_impulses_hz = _IQ(LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS/60.0/NORMA_FROTOR); + static unsigned int prev_RotorDirectionInstant = 0; + static unsigned int status_RotorRotation = 0; // ���� ��������? + static _iq wrotor_add = _IQ(0.002/NORMA_FROTOR); + + + + + if (WRotor.iqWRotorCalc1>level_switch_to_get_impulses_hz + || WRotor.iqWRotorCalc2>level_switch_to_get_impulses_hz) + { + // ��� ������� ������� + if (WRotor.iqWRotorImpulses1 || WRotor.iqWRotorImpulses2) + { + if(WRotor.iqWRotorImpulses1>WRotor.iqWRotorImpulses2) + WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul2; + } + else + { + if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; + } + + + } + else + { + if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; + + } + + + // ������� ����������� +// if (prev_prev_RotorDirectionInstant && WRotorPBus.RotorDirectionSlow) +// if (WRotor.iqWRotorSum) +// { +// inc_sensor.break_direction = 1; +// } +// prev_prev_RotorDirectionInstant = WRotorPBus.RotorDirectionSlow; + + + +//// ������ �����������!!! +// if (WRotorPBus.RotorDirectionSlow==0) +// { +// if (WRotor.iqWRotorSum) +// inc_sensor.break_direction = 1; +// } +// else +// inc_sensor.break_direction = 0; + + +// if (WRotorPBus.RotorDirectionSlow==0) +// { +// // ����� � 0 ������� !!! ������ �����������!!! +// WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, 0); +// } +// else + + + WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, WRotor.iqWRotorSum*WRotorPBus.RotorDirectionSlow); + + WRotor.iqWRotorSumRamp = zad_intensiv_q(wrotor_add, wrotor_add, WRotor.iqWRotorSumRamp, WRotor.iqWRotorSumFilter); + + + WRotor.iqWRotorSumFilter2 = exp_regul_iq(koefW2, WRotor.iqWRotorSumFilter2, WRotor.iqWRotorSumFilter); + WRotor.iqWRotorSumFilter3 = exp_regul_iq(koefW3, WRotor.iqWRotorSumFilter3, WRotor.iqWRotorSumFilter); + +} + + +#pragma CODE_SECTION(RotorMeasure,".fast_run"); +void RotorMeasureDetectDirection(void) +{ + int direction1, direction2, sum_direct; + + direction1 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_CLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? -1 : + 0; + + direction2 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_CLOCKWISE ? -1 : + 0; + + sum_direct = (direction1 + direction2) > 0 ? 1 : + (direction1 + direction2) < 0 ? -1 : + 0; + + WRotorPBus.RotorDirectionInstant = sum_direct; + +} + + +/////////////////////////////////////////////////////////////// + +#endif + + + +/////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(update_rot_sensors,".fast_run"); +void update_rot_sensors(void) +{ + inc_sensor.update_sensors(&inc_sensor); +} +/////////////////////////////////////////////////////////////// diff --git a/Inu/Src/main/v_rotor.h b/Inu/Src/main/v_rotor.h new file mode 100644 index 0000000..aad2216 --- /dev/null +++ b/Inu/Src/main/v_rotor.h @@ -0,0 +1,185 @@ +#ifndef V_ROTOR_H +#define V_ROTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "params_bsu.h" + + +// ������ �� ������� +#define ROTOR_SENSOR_CODE_CLOCKWISE 2 // �� ������� +#define ROTOR_SENSOR_CODE_COUNTERCLOCKWISE 1 // ������ ������� + +// ������ ������ ������� +//#define ROTOR_SENSOR_CODE_CLOCKWISE 1 // �� ������� +//#define ROTOR_SENSOR_CODE_COUNTERCLOCKWISE 2 // ������ ������� + + +void update_rot_sensors(void); +void RotorMeasure(void); +void RotorMeasurePBus(void); +void rotorInit(void); +void select_values_wrotor(void); + + +void RotorDirectionFilter(int RotorDirectionIn, int *RotorDirectionOut, int *RotorDirectionOut2, int *count_direction); + +int AnalisatorRotorSensorPBus(_iq d1, _iq d2, unsigned int *count_overfull_discret, unsigned int *count_zero_discret, _iq *prev_iqTimeRotor, + unsigned int *discret_out, unsigned int discret_in, _iq *iqWRotorCalcBeforeRegul, _iq *iqWRotorCalc, + int modeS1, int modeS2, + int valid_sensor_direct, int valid_sensor_90, + unsigned int *error_count); + +void RotorMeasureDetectDirection(void); + + +typedef struct +{ + _iq iqWRotorRaw0; + _iq iqWRotorRaw1; + _iq iqWRotorRaw2; + _iq iqWRotorRaw3; + + _iq iqWRotorFilter0; + _iq iqWRotorFilter1; + _iq iqWRotorFilter2; + _iq iqWRotorFilter3; + + _iq iqWRotorDelta; + + _iq iqTimeSensor1; + _iq iqTimeSensor2; + + _iq prev_iqWRotorRaw0; + _iq prev_iqWRotorRaw1; + _iq prev_iqWRotorRaw2; + _iq prev_iqWRotorRaw3; + + unsigned int count_zero_discret0; + unsigned int count_zero_discret1; + unsigned int count_zero_discret2; + unsigned int count_zero_discret3; + + + _iq iqWRotorCalc1; + _iq iqWRotorCalcBeforeRegul1; + _iq iqWRotorCalc2; + _iq iqWRotorCalcBeforeRegul2; + +// int RotorDirectionInstant; +// int RotorDirectionSlow; + + _iq iqWRotorImpulses1; + _iq iqWRotorImpulsesBeforeRegul1; + _iq iqWRotorImpulses2; + _iq iqWRotorImpulsesBeforeRegul2; + + _iq iqWRotorSum; + _iq iqWRotorSumFilter; + _iq iqWRotorSumFilter2; + _iq iqWRotorSumFilter3; + + _iq iqWRotorSumRamp; + + _iq iqWRotorCalc1Ramp; + _iq iqPrevWRotorCalc1; + _iq iqWRotorCalc2Ramp; + _iq iqPrevWRotorCalc2; + + int RotorDirectionSlow; + +} WRotorValues; + +#define WRotorValues_DEFAULTS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0, 0,0,0,0, 0} + +typedef struct +{ + _iq iqWRotorRaw0; + _iq iqWRotorRaw1; + _iq iqWRotorRaw2; + _iq iqWRotorRaw3; + + + _iq iqWRotorFilter0; + _iq iqWRotorFilter1; + _iq iqWRotorFilter2; + _iq iqWRotorFilter3; + + _iq iqWRotorDelta; +// _iq iqWRotorCalcBeforeRegul; + + _iq iqWRotorCalcBeforeRegul1; + _iq iqWRotorCalcBeforeRegul2; + + _iq iqTimeRotor1; + _iq iqTimeRotor2; + + _iq iqTimeRotor; + + + _iq iqWRotorCalc1; + _iq iqWRotorCalc2; +// _iq iqWRotorCalc; + + int ModeAutoDiscret; + + int RotorDirectionInstant; + int RotorDirectionSlow; + int RotorDirectionCount; + int RotorDirectionSlow2; + + + +#if (ENABLE_ROTOR_SENSOR_ZERO_SIGNAL==1) + _iq iqWRotorRawAngle1F; + _iq iqWRotorRawAngle1R; + _iq iqWRotorRawAngle2F; + _iq iqWRotorRawAngle2R; + + _iq iqAngle1F; + _iq iqAngle1R; + + _iq iqAngle2F; + _iq iqAngle2R; + + _iq iqAngleCalc; + +#endif + +} WRotorValuesAngle; + +#if (ENABLE_ROTOR_SENSOR_ZERO_SIGNAL==1) +#define WRotorValuesAngle_DEFAULTS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#else +#define WRotorValuesAngle_DEFAULTS {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +#endif + +extern WRotorValues WRotor; +extern WRotorValuesAngle WRotorPBus; + + + + + + +//#define NORMA_WROTOR 15 + +#define IQ_WROTOR_MAX_MIN_DELTA 3744914286 //17920 + + +#define WRMP_COEF 0.001 // 0.24 Hz per sec + +#define IQ_CONST_3 50331648 + +#define COUNT_DECODER_ZERO_WROTORPBus 65535 //0x00fe5000//0x01fca000 +#define COUNT_DECODER_ZERO_WROTOR 65500 //0x00fe5000//0x01fca000 +#define COUNT_DECODER_MAX_WROTOR 10 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Inu/Src/main/v_rotor_22220.c b/Inu/Src/main/v_rotor_22220.c new file mode 100644 index 0000000..c31de31 --- /dev/null +++ b/Inu/Src/main/v_rotor_22220.c @@ -0,0 +1,666 @@ + +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include "params_bsu.h" +#include "v_rotor.h" + +#include "filter_v1.h" +#include "xp_cds_in.h" + +#include "xp_inc_sensor.h" +#include "xp_project.h" +#include "params.h" + +//#include "pwm_test_lines.h" +#include "params_norma.h" +#include "edrk_main.h" +#include "params_pwm24.h" +#include "v_rotor_22220.h" + +#include "rmp_cntl_v1.h" +#include "mathlib.h" + + +//#define _ENABLE_PWM_LED2_PROFILE 1 + +#if (_ENABLE_PWM_LED2_PROFILE) +extern unsigned int profile_pwm[30]; +extern unsigned int pos_profile_pwm; +#endif + +// +//#pragma DATA_SECTION(buf1,".logs2") +//int buf1[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf2,".logs2") +//int buf2[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf3,".logs2") +//int buf3[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf4,".logs2") +//int buf4[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf5,".logs2") +//int buf5[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf6,".logs2") +//int buf6[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf7,".logs2") +//int buf7[SIZE_BUF_W]; +//#pragma DATA_SECTION(buf8,".logs2") +//int buf8[SIZE_BUF_W]; +// + +/////////////////////////////////////////////// +/////////////////////////////////////////////// +/////////////////////////////////////////////// +RMP_V1 rmp_wrot = RMP_V1_DEFAULTS; + +#pragma DATA_SECTION(rotor_22220,".fast_vars"); +ROTOR_VALUE_22220 rotor_22220 = ROTOR_VALUE_22220_DEFAULTS; + + +void rotorInit_22220(void) +{ + unsigned int i = 0, size = 0, *pint = 0; + + rmp_wrot.RampLowLimit = 0; + rmp_wrot.RampHighLimit = _IQ(1.0); + rmp_wrot.RampPlus = _IQ(0.0015/NORMA_FROTOR); + rmp_wrot.RampMinus = _IQ(-0.0015/NORMA_FROTOR); + rmp_wrot.DesiredInput = 0; + rmp_wrot.Out = 0; + + +// pint = (unsigned int*)&rotor; +// size = sizeof(rotor) / sizeof(unsigned int); +// for(i = 0; i < size; i++) +// { +// *(pint + i) = 0; +// } + +} + +_iq koef_Wout_filter = _IQ(0.2); //_IQ(0.15); +_iq koef_Wout_filter_long = _IQ(0.001);//_IQ(0.03); + +#define SIZE_BUF_F1 10 +#pragma DATA_SECTION(f1,".slow_vars") +static _iq f1[SIZE_BUF_F1]={0,0,0,0,0,0,0,0,0,0}; +#pragma DATA_SECTION(f1_int,".slow_vars") +static long f1_int[SIZE_BUF_F1]={0,0,0,0,0,0,0,0,0,0}; + +#pragma CODE_SECTION(clear_iqFsensors,".fast_run"); +void clear_iqFsensors(void) +{ + int i; + + for (i=0;i<SENSORS_NUMBER;i++) + rotor_22220.iqFsensors[i] = 0; +} + +//#pragma CODE_SECTION(Rotor_measure_22220,".fast_run"); +void Rotor_measure_22220(void) +{ + static long c_s=-1; +// static int flag_buf = 0, prev_flag_buf = 0 ; + + + + static unsigned long PrevAngle1 = 0, PrevAngle2 = 0, PrevAngle3 = 0, PrevAngle4 = 0; + static unsigned int peroid_shim_mks = (unsigned int)(1000000L / FREQ_PWM / 2.0); + static _iq prev_wrot = 0; + static unsigned int prev_wrot_count = 0; + static int direct_accum = 0; + static int sens1_err_count = 0; + static int sens2_err_count = 0; + + + + + unsigned int s_number = 0, begin_data = 0, end_data = 0, i; + unsigned int s_number2 = 0; + unsigned int s_number3 = 0; + _iq accumulator = 0, deltaF = 0, deltaAngle = 0; + long sum_count=0; + + int direction1, direction2, sum_direct, sens_err1, sens_err2; + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + clear_iqFsensors(); + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + +// rotation_sensor.read_sensors(&rotation_sensor); + inc_sensor.read_sensors(&inc_sensor); + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + direction1 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_CLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? -1 : + 0; + + direction2 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_CLOCKWISE ? -1 : + 0; + + sens_err1 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == 3; + sens_err2 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == 3; + + + + if(inc_sensor.pm67regs.read_comand_reg.bit.update_registers) + { + rotor_22220.error_update_count++; + } +// logpar.log22 = rotation_sensor.in_plane.out.CountOne1; +// logpar.log23 = rotation_sensor.in_plane.out.CountZero1; + + +// if (edrk.logs_rotor==1) +// flag_buf = edrk.logs_rotor; +// +// +// if (flag_buf==1 && prev_flag_buf==0) +// c_s = -1; +// +// if (flag_buf) +// { +// if (c_s>=(SIZE_BUF_W-1)) +// { +// flag_buf = 0; +// c_s = 0; +// } +// else +// c_s++; +// +// +// buf1[c_s] = inc_sensor.data.CountOne1;// rotation_sensor.in_plane.out.CountOne1; +// buf2[c_s] = inc_sensor.data.CountZero1;//rotation_sensor.in_plane.out.CountZero1; +// buf3[c_s] = inc_sensor.data.CountOne2;//rotation_sensor.in_plane.out.CountOne2; +// buf4[c_s] = inc_sensor.data.CountZero2;//rotation_sensor.in_plane.out.CountZero2; +// buf5[c_s] = direction1;//inc_sensor.data.;//(rotation_sensor.in_plane.out.direction1); +// buf6[c_s] = direction2;//(rotation_sensor.in_plane.out.direction2); +// buf7[c_s] = (project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1); +// buf8[c_s] = (project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2); +// +// } +// prev_flag_buf = flag_buf; + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + + if(inc_sensor.use_sensor1) + { + if((inc_sensor.data.CountOne1 <= 200)// && !rotation_sensor.in_plane.out.counter_freq1) + || inc_sensor.data.CountOne1 == 65535) + { inc_sensor.data.CountOne1 = 0; } + if((inc_sensor.data.CountZero1 <= 200)// && !rotation_sensor.in_plane.out.counter_freq1) + || inc_sensor.data.CountZero1 == 65535) + { inc_sensor.data.CountZero1 = 0; } + + //����� ��������� ���� ������� �� ������� + if (inc_sensor.data.Impulses1 < 5) { + + if(inc_sensor.data.CountOne1 && inc_sensor.data.CountZero1 ) + { + sum_count = (long)inc_sensor.data.CountOne1 + (long)inc_sensor.data.CountZero1; + + if (s_number3<SIZE_BUF_F1) f1[s_number3++] = counter_To_iqF2(sum_count, inc_sensor.data.counter_freq1); + + if (s_number2<SIZE_BUF_F1) + { + if (inc_sensor.data.counter_freq1) + f1_int[s_number2++] = sum_count/6; + else + f1_int[s_number2++] = sum_count*100/6; + } + if (s_number<SENSORS_NUMBER) + rotor_22220.iqFsensors[s_number++] = counter_To_iqF2(sum_count, inc_sensor.data.counter_freq1); + + } +// if(rotation_sensor.in_plane.out.CountOne1) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountOne1, +// rotation_sensor.in_plane.out.counter_freq1); +// } +// if(rotation_sensor.in_plane.out.CountZero1) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountZero1, +// rotation_sensor.in_plane.out.counter_freq1); +// } + } + else + { + if (s_number2<SIZE_BUF_F1) + f1_int[s_number2++] = -2; + } + + if(inc_sensor.data.Impulses1 > 2) + { + if (s_number<SENSORS_NUMBER) + rotor_22220.iqFsensors[s_number++] = impulses_To_iqF(inc_sensor.data.Time1, + inc_sensor.data.Impulses1); + + if (s_number3<SIZE_BUF_F1) f1[s_number3++] = impulses_To_iqF(inc_sensor.data.Time1, + inc_sensor.data.Impulses1); + + if (s_number2<SIZE_BUF_F1) f1_int[s_number2++] = inc_sensor.data.Time1*10/inc_sensor.data.Impulses1; + +// logpar.log11 = (int16) _IQtoIQ15(rotor.iqFsensors[s_number - 1]); + } else { +// logpar.log11 = 0; + if (s_number2<SIZE_BUF_F1) + f1_int[s_number2++] = -3; + } + + if (rotor_22220.iqF > 139810L)//10 rpm + { + if (inc_sensor.data.CountOne1 == 0 && inc_sensor.data.CountZero1 == 0 + && inc_sensor.data.Impulses1 == 0) { + sens1_err_count += 1; + } else { + sens1_err_count = 0; + } + if (sens1_err_count > 50) { + sens1_err_count = 50; + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 1; +// faults.faults4.bit.Speed_Datchik_1_Off |= 1; + } + } else { + sens1_err_count = 0; + edrk.warnings.e9.bits.SENSOR_ROTOR_1_BREAK = 0; + } + } + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + +// logpar.log4 = rotation_sensor.in_plane.out.CountOne2; +// logpar.log20 = rotation_sensor.in_plane.out.CountZero2; + if(inc_sensor.use_sensor2) + { + if((inc_sensor.data.CountOne2 <= 200)// && !rotation_sensor.in_plane.out.counter_freq2) + || inc_sensor.data.CountOne2 == 65535) + { inc_sensor.data.CountOne2 = 0; } + if((inc_sensor.data.CountZero2 <= 200)// && !rotation_sensor.in_plane.out.counter_freq2) + || inc_sensor.data.CountZero2 == 65535) + { inc_sensor.data.CountZero2 = 0; } + + //����� ��������� ����, ������� �� ������� + if (inc_sensor.data.Impulses2 < 5) { + + if(inc_sensor.data.CountOne2 && inc_sensor.data.CountZero2 ) + { + sum_count = (long)inc_sensor.data.CountOne2+(long)inc_sensor.data.CountZero2; + if (s_number3<SIZE_BUF_F1) f1[s_number3++] = counter_To_iqF2(sum_count, inc_sensor.data.counter_freq2); + + //f1_int[s_number2++] = sum_count/60; + if (s_number2<SIZE_BUF_F1) + { + if (inc_sensor.data.counter_freq2) + f1_int[s_number2++] = sum_count/6; + else + f1_int[s_number2++] = sum_count*100/6; + } + if (s_number<SENSORS_NUMBER) + rotor_22220.iqFsensors[s_number++] = counter_To_iqF2(sum_count, inc_sensor.data.counter_freq2); + + } +// if(rotation_sensor.in_plane.out.CountOne2) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountOne2, +// rotation_sensor.in_plane.out.counter_freq2); +// } +// if(rotation_sensor.in_plane.out.CountZero2) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountZero2, +// rotation_sensor.in_plane.out.counter_freq2); +// } + } + else + { + if (s_number2<SIZE_BUF_F1) + f1_int[s_number2++] = -4; + } + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + + if(inc_sensor.data.Impulses2 > 2) + { + if (s_number<SENSORS_NUMBER) + rotor_22220.iqFsensors[s_number++] = impulses_To_iqF(inc_sensor.data.Time2, + inc_sensor.data.Impulses2); + + if (s_number2<SIZE_BUF_F1) f1_int[s_number2++] = inc_sensor.data.Time2*10/inc_sensor.data.Impulses2; + +// logpar.log16 = (int16) _IQtoIQ15(rotor.iqFsensors[s_number - 1]); + } + else + { + if (s_number2<SIZE_BUF_F1) + f1_int[s_number2++] = -5; + } + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + + if (rotor_22220.iqF > 139810L)//10 rpm + { + if (inc_sensor.data.CountOne2 == 0 && inc_sensor.data.CountZero2 == 0 + && inc_sensor.data.Impulses2 == 0) { + sens2_err_count += 1; + } else { + sens2_err_count = 0; + } + if (sens2_err_count > 50) { + sens2_err_count = 50; +// faults.faults4.bit.Speed_Datchik_2_Off |= 1; + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 1; + } + } else { + sens2_err_count = 0; + edrk.warnings.e9.bits.SENSOR_ROTOR_2_BREAK = 0; + } + + } + + if(s_number > SENSORS_NUMBER_ONLY_IN) {s_number = SENSORS_NUMBER_ONLY_IN;} //TODO set SENSORS_NUMBER when tune angle measure + if(s_number > 3) + { + sort_F_array(rotor_22220.iqFsensors, s_number); + deltaF = rotor_22220.iqFout >> 2; + if(deltaF < 43000) // ~3 ob/min + { + deltaF = 43000; + } + i = 0; + begin_data = 0; + end_data = s_number; //TODO test, as usial + while(i < s_number) + { + if(_IQabs(rotor_22220.iqFout - rotor_22220.iqFsensors[i]) >= deltaF) + { + i++; + } + else + { + break; + } + } + if(i < s_number) { begin_data = i; } + else {begin_data = 0;} + while((i < s_number) && (_IQabs(rotor_22220.iqFout - rotor_22220.iqFsensors[i]) < deltaF)) + { + i++; + } + if(i <= SENSORS_NUMBER) + { + end_data = i; + } + else + { + end_data = SENSORS_NUMBER; + } + } + else + { + begin_data = 0; + end_data = s_number; + } + if (begin_data >= end_data) { //This part to prevent freeze of speed on some level if signal lost + begin_data = 0; + end_data = s_number; + } + // ��������� + for(i = begin_data; i < end_data; i++) + { + accumulator += rotor_22220.iqFsensors[i]; + } + // ��������� + if(end_data != begin_data) + { + rotor_22220.iqFdirty = accumulator / (end_data - begin_data); + prev_wrot_count = 0; + } + else + { + rotor_22220.iqFdirty = prev_wrot; + prev_wrot_count += 1; + } + +// logpar.log19 = (int16)(_IQtoIQ15(rotor.iqF)); +// rotor_22220.iqFdirty = rotor_22220.iqF; + + if (prev_wrot != rotor_22220.iqFdirty || rotor_22220.iqFdirty==0 ) + { + rmp_wrot.DesiredInput = rotor_22220.iqFdirty; + rmp_wrot.calc(&rmp_wrot); + rotor_22220.iqF = rmp_wrot.Out; + } + else + { + rotor_22220.iqF = rotor_22220.iqFdirty; + } + prev_wrot=rotor_22220.iqF; + + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + + //�� ���������� ������� ���������. + if (prev_wrot_count > 10) { + prev_wrot = 0; + prev_wrot_count = 10; + } + + rotor_22220.iqFout = exp_regul_iq(koef_Wout_filter, rotor_22220.iqFout, rotor_22220.iqF); + rotor_22220.iqFlong = exp_regul_iq(koef_Wout_filter_long, rotor_22220.iqFlong, rotor_22220.iqF); + +#if (_ENABLE_PWM_LED2_PROFILE) + if (profile_pwm[pos_profile_pwm++]) + i_led2_on_off(1); + else + i_led2_on_off(0); +#endif + + + rotor_22220.direct_rotor_in1 = direction1;//rotation_sensor.in_plane.out.direction1; + +#if (_STEND_40MWT==1) + // ������ ����������� �������� ��� ������� ������, �.�. �� ������ ���� ������ ��������� ������, � ������ ��������� ����!!! + + rotor_22220.direct_rotor_in2 = -rotation_sensor.in_plane.out.direction2; + +#else + + rotor_22220.direct_rotor_in2 = direction2;//rotation_sensor.in_plane.out.direction2; + +#endif + // rotor.direct_rotor_angle = rotation_sensor.rotation_plane.out.direction; + + rotor_22220.error.sens_err1 = sens_err1; + rotor_22220.error.sens_err2 = sens_err2; + +// rotor.direct_rotor = (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) > 0 ? 1 : // + rotor.direct_rotor_angle +// (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) < 0 ? -1 : // + rotor.direct_rotor_angle +// 0; + if(rotor_22220.iqFout >139810L) //10ob/min + { + if((rotor_22220.direct_rotor_in1 + rotor_22220.direct_rotor_in2) > 0) + { + direct_accum++; + } + else if((rotor_22220.direct_rotor_in1 + rotor_22220.direct_rotor_in2) < 0) + { + direct_accum--; + } + else + { + if(direct_accum > 0) {direct_accum--;} + if(direct_accum < 0) {direct_accum++;} + } + if(direct_accum > 60) { direct_accum = 60; } + if(direct_accum < -60) { direct_accum = -60; } + rotor_22220.direct_rotor = direct_accum > 0 ? 1 : + direct_accum < 0 ? -1 : + 0; +// if (f.flag_second_PCH) { +// rotor.direct_rotor = - rotor.direct_rotor; +// } + } + else + { + rotor_22220.direct_rotor = (rotor_22220.direct_rotor_in1 + rotor_22220.direct_rotor_in2) > 0 ? 1 : // + rotor.direct_rotor_angle + (rotor_22220.direct_rotor_in1 + rotor_22220.direct_rotor_in2) < 0 ? -1 : // + rotor.direct_rotor_angle + 0; +// if (f.flag_second_PCH) { +// rotor.direct_rotor = - rotor.direct_rotor; +// } + direct_accum = rotor_22220.direct_rotor; + } + +// if(rotation_sensor.in_plane.write.regs.comand_reg.bit.set_sampling_time) //�������� �������� +// { +// rotation_sensor.in_plane.write.regs.comand_reg.bit.filter_sensitivity = 0x5C; +// } +// else //�������� �������, ������ ��������� +// { +// rotation_sensor.in_plane.write.regs.comand_reg.bit.filter_sensitivity = 0xA8; +// } + if (s_number2<SIZE_BUF_F1) + f1_int[s_number2++] = -1; +} + +#pragma CODE_SECTION(impulses_To_iqF,".fast_run"); +_iq impulses_To_iqF(unsigned int time, unsigned int impulses) //time mks. impulses count +{ + //Flong = (impulses / time / IMPULSES_PER_TURN) * _IQ(1) / NORMA_FROTOR; + static unsigned long long koeff_to_F = 16777216LL / IMPULSES_PER_TURN * 1000000LL / NORMA_FROTOR; + long long Flong = (long long)impulses * koeff_to_F / time; + return (_iq)Flong; +} + +//Frot = Fimp / IMPULSES_PER_TURN / NORMA_FROTOR = +// = counter_freq / counter / 2 / IMPULSES_PER_TURN / NORMA_FROTOR +//���� �� 2, �.�. ������� ������������ �������� ������� +//��������� �� (1LL << 24) ����� �������� � iq24 +#pragma CODE_SECTION(counter_To_iqF,".fast_run"); +_iq counter_To_iqF(unsigned int count, unsigned int freq_mode) +{ + static long long koeff_to_F = 60000000LL * _IQ(1.0) / IMPULSES_PER_TURN / 2 / NORMA_FROTOR; + long long Flong = 0; + if(freq_mode == 0) // 60Mhz + { + Flong = koeff_to_F / count / 100; + } + else //600KHz + { + Flong = koeff_to_F / count; + } + return Flong; +} + +#pragma CODE_SECTION(counter_To_iqF2,".fast_run"); +_iq counter_To_iqF2(long count, unsigned int freq_mode) +{ + static long long koeff_to_F = 60000000LL * _IQ(1.0) / IMPULSES_PER_TURN / NORMA_FROTOR; + long long Flong = 0; + if(freq_mode == 0) // 60Mhz + { + Flong = koeff_to_F / count / 100; + } + else //600KHz + { + Flong = koeff_to_F / count; + } + return Flong; +} + +//#pragma CODE_SECTION(delta_Angle_To_iqF,".fast_run"); +//_iq delta_Angle_To_iqF(unsigned long delta, unsigned int period) +//{ +// // iqF = (delta / ANGLE_RESOLUTION) / (period * 10^-6) * (1LL << 24) / NORMA_FROTOR; +// // iqF = delta * 10^6 * (1LL << 24) / ANGLE_RESOLUTION / period / NORMA_FROTOR; +// static long long koeff_to_F = 1000000LL * (1LL << 24) / ANGLE_RESOLUTION / NORMA_FROTOR; +// return (_iq)(koeff_to_F * delta / period); +//} + +// ���������� ������� ��������� +#pragma CODE_SECTION(sort_F_array,".fast_run2"); +void sort_F_array(_iq *array, unsigned int size) +{ + unsigned int i, j; + _iq tmp = 0; + for(i = size; i > 0; i--) + { + for(j = 1; j < size; j++) + { + if(array[j - 1] > array[j]) + { + tmp = array[j]; + array[j] = array[j - 1]; + array[j - 1] = tmp; + } + } + } +} + + +void select_values_wrotor_22220(void) +{ + // static _iq level_switch_to_get_impulses_hz = _IQ(LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS/60.0/NORMA_FROTOR); + static unsigned int prev_RotorDirectionInstant = 0; + static unsigned int status_RotorRotation = 0; // ���� ��������? + static _iq wrotor_add = _IQ(0.002/NORMA_FROTOR); + + WRotor.RotorDirectionSlow = rotor_22220.direct_rotor; + WRotor.iqWRotorSum = rotor_22220.iqFout;// * rotor_22220.direct_rotor; + WRotor.iqWRotorSumFilter = rotor_22220.iqFout * rotor_22220.direct_rotor; + WRotor.iqWRotorSumFilter2 = rotor_22220.iqFlong * rotor_22220.direct_rotor; + WRotor.iqWRotorSumFilter3 = rotor_22220.iqFlong * rotor_22220.direct_rotor; + WRotor.iqWRotorSumRamp = zad_intensiv_q(wrotor_add, wrotor_add, WRotor.iqWRotorSumRamp, WRotor.iqWRotorSumFilter); + + +} diff --git a/Inu/Src/main/v_rotor_22220.h b/Inu/Src/main/v_rotor_22220.h new file mode 100644 index 0000000..aec28c5 --- /dev/null +++ b/Inu/Src/main/v_rotor_22220.h @@ -0,0 +1,54 @@ +#ifndef V_ROTOR_22220_H +#define V_ROTOR_22220_H + +#define SIZE_BUF_W 100 //2000 + +/////// 22220.5 +#define SENSORS_NUMBER 10 +#define SENSORS_NUMBER_ONLY_IN 6 +//#define IMPULSES_PER_TURN (1LL << 13) //Old sensor +#define IMPULSES_PER_TURN 4096 //Lira sensor +//#define ANGLE_RESOLUTION (1LL << 18) //2^18 + +typedef struct +{ + int direct_rotor; + int direct_rotor_in1; + int direct_rotor_in2; + int direct_rotor_angle; + union { + unsigned int sens_err1:1; + unsigned int sens_err2:1; + unsigned int reserved:14; + } error; + + _iq iqFsensors[SENSORS_NUMBER]; + + + _iq iqFdirty; + _iq iqF; + _iq iqFout; + _iq iqFlong; + + _iq iqFrotFromOptica; + + unsigned int error_update_count; +} ROTOR_VALUE_22220; + +#define ROTOR_VALUE_22220_DEFAULTS {0,0,0,0,0, {0,0,0,0,0,0,0,0},0,0,0,0,0,0} + + +_iq counter_To_iqF2(long count, unsigned int freq_mode); +void sort_F_array(_iq *array, unsigned int size); +_iq impulses_To_iqF(unsigned int time, unsigned int impulses); //time mks. impulses count +void Rotor_measure_22220(void); +void rotorInit_22220(void); +void select_values_wrotor_22220(void); + +extern ROTOR_VALUE_22220 rotor_22220; + +extern _iq koef_Wout_filter, koef_Wout_filter_long; + + +#endif + diff --git a/Inu/Src/main/vector.h b/Inu/Src/main/vector.h new file mode 100644 index 0000000..25bc4f1 --- /dev/null +++ b/Inu/Src/main/vector.h @@ -0,0 +1,254 @@ +/* + ???? ??? (?) 2006 ?. + + Processor: TMS320C32 + + Filename: vector_troll.h + + ??????? ?????????? ?????????y + + Edit date: 04-12-02 + + Function: + + Revisions: +*/ + + +#ifndef _VECTOR_SEV +#define _VECTOR_SEV + + +#ifdef __cplusplus + extern "C" { +#endif + + +#include "IQmathLib.h" +#include "x_basic_types.h" + +typedef struct +{ + float W; /* ������� ������� ������ */ + float Angle; /* ���� ��������� ������ */ + float Phi; /* �������� � ���� ������ */ + float k; /* �����. ��������� */ + float k1; /* �����. ��������� */ + float k2; /* �����. ��������� */ + float f; /* ������� ������� */ + + _iq iqk; + _iq iqk1; + _iq iqk2; + _iq iqf; + + + +} WINDING; + +#define WINDING_DEFAULT {0,0,0,0,0,0,0,0,0,0,0} + + +typedef struct +{ + unsigned int Prepare; + unsigned int terminal_prepare; + unsigned int Test_Lamps; + unsigned int fault; + + + + unsigned int Stop; + unsigned int Mode; + unsigned int Revers; + unsigned int Is_Blocked; + + unsigned int Ready1; + unsigned int Ready2; + unsigned int Discharge; + unsigned int Assemble; + + unsigned int ErrorChannel1; + unsigned int ErrorChannel2; + unsigned int FaultChannel1; + unsigned int FaultChannel2; + + unsigned int Set_power; + + unsigned int Impuls; + + unsigned int Obmotka1; + unsigned int Obmotka2; +// unsigned int Down50; + + unsigned int I_over_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ???? + unsigned int Moment_over_1_6_noninal; //????????? ?????? ?????? ? ??????????? ???????????? ??????? ? 1.6 ??? + unsigned int Moment_over_1_8_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ??????? ? 1.8 ??? + unsigned int DownToNominal; + unsigned int DownToNominalMoment; + unsigned int Down50Temperature; + unsigned int nominal_I_exceeded_counter; //??????? ??? ????????? ??????????? ??? + unsigned int nominal_M_exceeded_counter; //??????? ??? ????????? ??????????? ?????? + + unsigned int Up50; + unsigned int Ciclelog; + unsigned int Provorot; + unsigned int Bpsi; + unsigned int Piregul1; + unsigned int Piregul2; + unsigned int Startstoplog; + unsigned int Setspeed; + + unsigned int BWC_is_ON; + + unsigned int Setsdvigfaza; + unsigned int Off_piregul; + + unsigned int Restart; + unsigned int Log1_Log2; + + unsigned int Work_net; + unsigned int Mask_impuls; + unsigned int Impuls_width; + + + unsigned int Work; + + unsigned int Auto; + + unsigned int Uzad; + unsigned int Umin; + +// unsigned int RScount; + unsigned int vector_run; + unsigned int test_all_run; + + unsigned int decr_mzz_temp; +// unsigned int flag_decr_mzz_temp; + + unsigned int flag_Break_Resistor_Error; + unsigned int flag_local_control; //1 - local + unsigned int flag_leading; //??????? ?? ?????? + unsigned int flag_second_leading; //?????? ?? ?????? + unsigned int flag_distance; + unsigned int flag_kvitirovanie; + unsigned int flag_batary_loaded; + unsigned int flag_Pump_Is_On; + unsigned int power_units_doors_closed; + unsigned int power_units_doors_locked; + + unsigned int flag_decr_mzz_power; + + real decr_mzz_power; + _iq iq_decr_mzz_power; + + _iq iq_decr_mzz_voltage; + + real fzad; + real kzad; + real kzad_plus; +// real fzad_provorot; + real Sdvigfaza; +// real k_3garonica; +// _iq iq_k_3garonica; +// real bpsi_zad; + +// real Piregul1_p; +// real Piregul1_i; + +// real Piregul2_p; +// real Piregul2_i; + + + real mzz_zad; + real fr_zad; + real Power; + real p_zad; + + +// _iq iq_bpsi_zad; + _iq iq_mzz_zad; +// _iq iq_fzad_provorot; + _iq iq_fzad; + + _iq iq_p_zad; + + unsigned int flag_Enable_Prepare; + + + unsigned int status_MODE_WORK_SVU; + unsigned int status_MODE_WORK_MPU; + unsigned int status_MODE_WORK_VPU; +// unsigned int status_MODE_WORK_EVPU; + +// unsigned int filter_READY_UKSS_BV1; +// unsigned int filter_READY_UKSS_BV2; +// unsigned int filter_READY_UKSS_BI1; +// unsigned int filter_READY_UKSS_BI2; + unsigned int filter_READY_UMU; +// unsigned int filter_READY_UKSS_UKSI; + + unsigned int On_Power_QTV; + + unsigned int RS_MPU_ERROR; +// unsigned int CAN_MPU_ERROR; + +// unsigned int enable_fast_prepare; + +// unsigned int tau_break1; +// unsigned int tau_break2; + + unsigned int flag_tormog; + +// unsigned int GoPWM; + + int special_test_from_mpu; + + int MessageToCan1; + int MessageToCan2; + int flag_change_pwm_freq; + int flag_random_freq; + long tmp; + + + + + + +//optical bus data + unsigned int read_task_from_optical_bus; + + + + unsigned int count_wait_after_kvitir; + unsigned int flag_record_log; + unsigned int count_step_ram_off; + unsigned int count_start_impuls; + + int flag_send_alarm_log_to_MPU; + + +} FLAG; + +#define FLAG_DEFAULTS {\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0\ + } +extern FLAG f; +//extern WINDING a; + +#ifdef __cplusplus + } +#endif + +#endif /* _VECTOR_SEV */ + + diff --git a/Inu/Src/main/xPlatesAddress.h b/Inu/Src/main/xPlatesAddress.h new file mode 100644 index 0000000..fa0a62c --- /dev/null +++ b/Inu/Src/main/xPlatesAddress.h @@ -0,0 +1,21 @@ +#ifndef _XPLATESADDRESS_H +#define _XPLATESADDRESS_H + + #define ADC_0_addr 7 + #define ADC_1_addr 8 + + #define TK_0_addr 5 + #define TK_1_addr 6 + #define TK_2_addr 9 + #define TK_3_addr 10 + + #define IN_0_addr 2 + #define IN_1_addr 3 + #define IN_2_addr 4 + + #define OUT_0_addr 11 + #define OUT_1_addr 12 + + #define RotPlane_addr 14 + +#endif diff --git a/Inu/Src/main_matlab/DSP281x_Device.h b/Inu/Src/main_matlab/DSP281x_Device.h new file mode 100644 index 0000000..557612b --- /dev/null +++ b/Inu/Src/main_matlab/DSP281x_Device.h @@ -0,0 +1,3 @@ + +#include "DSP2833x_Device.h" +//#define int16 int diff --git a/Inu/Src/main_matlab/DSP281x_Ev.h b/Inu/Src/main_matlab/DSP281x_Ev.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Inu/Src/main_matlab/DSP281x_Ev.h @@ -0,0 +1 @@ + diff --git a/Inu/Src/main_matlab/DSP281x_Examples.h b/Inu/Src/main_matlab/DSP281x_Examples.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Inu/Src/main_matlab/DSP281x_Examples.h @@ -0,0 +1 @@ + diff --git a/Inu/Src/main_matlab/DSP281x_GlobalPrototypes.h b/Inu/Src/main_matlab/DSP281x_GlobalPrototypes.h new file mode 100644 index 0000000..139597f --- /dev/null +++ b/Inu/Src/main_matlab/DSP281x_GlobalPrototypes.h @@ -0,0 +1,2 @@ + + diff --git a/Inu/Src/main_matlab/DSP281x_SWPrioritizedIsrLevels.h b/Inu/Src/main_matlab/DSP281x_SWPrioritizedIsrLevels.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Inu/Src/main_matlab/DSP281x_SWPrioritizedIsrLevels.h @@ -0,0 +1 @@ + diff --git a/Inu/Src/main_matlab/IQmathLib.h b/Inu/Src/main_matlab/IQmathLib.h new file mode 100644 index 0000000..67bfcf2 --- /dev/null +++ b/Inu/Src/main_matlab/IQmathLib.h @@ -0,0 +1,684 @@ +//#define __IQMATHLIB_H_INCLUDED__ + + +/** +* ��������� ���������� IQmath ��� ������������ � MATLAB +* +*/ +#ifndef IQ_MATH_LIB +#define IQ_MATH_LIB + + +#ifndef GLOBAL_Q +#define GLOBAL_Q 24 +#endif + +typedef long _iq; +typedef long _iq30; +typedef long _iq29; +typedef long _iq28; +typedef long _iq27; +typedef long _iq26; +typedef long _iq25; +typedef long _iq24; +typedef long _iq23; +typedef long _iq22; +typedef long _iq21; +typedef long _iq20; +typedef long _iq19; +typedef long _iq18; +typedef long _iq17; +typedef long _iq16; +typedef long _iq15; +typedef long _iq14; +typedef long _iq13; +typedef long _iq12; +typedef long _iq11; +typedef long _iq10; +typedef long _iq9; +typedef long _iq8; +typedef long _iq7; +typedef long _iq6; +typedef long _iq5; +typedef long _iq4; +typedef long _iq3; +typedef long _iq2; +typedef long _iq1; + +//--------------------------------------------------------------------------- +#define _IQmpy2(A) ((A)<<1) +#define _IQmpy4(A) ((A)<<2) +#define _IQmpy8(A) ((A)<<3) +#define _IQmpy16(A) ((A)<<4) +#define _IQmpy32(A) ((A)<<5) +#define _IQmpy64(A) ((A)<<6) + +#define _IQdiv2(A) ((A)>>1) +#define _IQdiv4(A) ((A)>>2) +#define _IQdiv8(A) ((A)>>3) +#define _IQdiv16(A) ((A)>>4) +#define _IQdiv32(A) ((A)>>5) +#define _IQdiv64(A) ((A)>>6) +//--------------------------------------------------------------------------- +#define _IQ30(A) (long) ((A) * 1073741824.0L) +#define _IQ29(A) (long) ((A) * 536870912.0L) +#define _IQ28(A) (long) ((A) * 268435456.0L) +#define _IQ27(A) (long) ((A) * 134217728.0L) +#define _IQ26(A) (long) ((A) * 67108864.0L) +#define _IQ25(A) (long) ((A) * 33554432.0L) +#define _IQ24(A) (long) ((A) * 16777216.0L) +#define _IQ23(A) (long) ((A) * 8388608.0L) +#define _IQ22(A) (long) ((A) * 4194304.0L) +#define _IQ21(A) (long) ((A) * 2097152.0L) +#define _IQ20(A) (long) ((A) * 1048576.0L) +#define _IQ19(A) (long) ((A) * 524288.0L) +#define _IQ18(A) (long) ((A) * 262144.0L) +#define _IQ17(A) (long) ((A) * 131072.0L) +#define _IQ16(A) (long) ((A) * 65536.0L) +#define _IQ15(A) (long) ((A) * 32768.0L) +#define _IQ14(A) (long) ((A) * 16384.0L) +#define _IQ13(A) (long) ((A) * 8192.0L) +#define _IQ12(A) (long) ((A) * 4096.0L) +#define _IQ11(A) (long) ((A) * 2048.0L) +#define _IQ10(A) (long) ((A) * 1024.0L) +#define _IQ9(A) (long) ((A) * 512.0L) +#define _IQ8(A) (long) ((A) * 256.0L) +#define _IQ7(A) (long) ((A) * 128.0L) +#define _IQ6(A) (long) ((A) * 64.0L) +#define _IQ5(A) (long) ((A) * 32.0L) +#define _IQ4(A) (long) ((A) * 16.0L) +#define _IQ3(A) (long) ((A) * 8.0L) +#define _IQ2(A) (long) ((A) * 4.0L) +#define _IQ1(A) (long) ((A) * 2.0L) + +#if GLOBAL_Q == 30 +#define _IQ(A) _IQ30(A) +#endif +#if GLOBAL_Q == 29 +#define _IQ(A) _IQ29(A) +#endif +#if GLOBAL_Q == 28 +#define _IQ(A) _IQ28(A) +#endif +#if GLOBAL_Q == 27 +#define _IQ(A) _IQ27(A) +#endif +#if GLOBAL_Q == 26 +#define _IQ(A) _IQ26(A) +#endif +#if GLOBAL_Q == 25 +#define _IQ(A) _IQ25(A) +#endif +#if GLOBAL_Q == 24 +#define _IQ(A) _IQ24(A) +#endif +#if GLOBAL_Q == 23 +#define _IQ(A) _IQ23(A) +#endif +#if GLOBAL_Q == 22 +#define _IQ(A) _IQ22(A) +#endif +#if GLOBAL_Q == 21 +#define _IQ(A) _IQ21(A) +#endif +#if GLOBAL_Q == 20 +#define _IQ(A) _IQ20(A) +#endif +#if GLOBAL_Q == 19 +#define _IQ(A) _IQ19(A) +#endif +#if GLOBAL_Q == 18 +#define _IQ(A) _IQ18(A) +#endif +#if GLOBAL_Q == 17 +#define _IQ(A) _IQ17(A) +#endif +#if GLOBAL_Q == 16 +#define _IQ(A) _IQ16(A) +#endif +#if GLOBAL_Q == 15 +#define _IQ(A) _IQ15(A) +#endif +#if GLOBAL_Q == 14 +#define _IQ(A) _IQ14(A) +#endif +#if GLOBAL_Q == 13 +#define _IQ(A) _IQ13(A) +#endif +#if GLOBAL_Q == 12 +#define _IQ(A) _IQ12(A) +#endif +#if GLOBAL_Q == 11 +#define _IQ(A) _IQ11(A) +#endif +#if GLOBAL_Q == 10 +#define _IQ(A) _IQ10(A) +#endif +#if GLOBAL_Q == 9 +#define _IQ(A) _IQ9(A) +#endif +#if GLOBAL_Q == 8 +#define _IQ(A) _IQ8(A) +#endif +#if GLOBAL_Q == 7 +#define _IQ(A) _IQ7(A) +#endif +#if GLOBAL_Q == 6 +#define _IQ(A) _IQ6(A) +#endif +#if GLOBAL_Q == 5 +#define _IQ(A) _IQ5(A) +#endif +#if GLOBAL_Q == 4 +#define _IQ(A) _IQ4(A) +#endif +#if GLOBAL_Q == 3 +#define _IQ(A) _IQ3(A) +#endif +#if GLOBAL_Q == 2 +#define _IQ(A) _IQ2(A) +#endif +#if GLOBAL_Q == 1 +#define _IQ(A) _IQ1(A) +#endif + +//--------------------------------------------------------------------------- + +#define _IQ30toF(A) ((float) ((A) / 1073741824.0L)) +#define _IQ29toF(A) ((float) ((A) / 536870912.0L)) +#define _IQ28toF(A) ((float) ((A) / 268435456.0L)) +#define _IQ27toF(A) ((float) ((A) / 134217728.0L)) +#define _IQ26toF(A) ((float) ((A) / 67108864.0L)) +#define _IQ25toF(A) ((float) ((A) / 33554432.0L)) +#define _IQ24toF(A) ((float) ((A) / 16777216.0L)) +#define _IQ23toF(A) ((float) ((A) / 8388608.0L)) +#define _IQ22toF(A) ((float) ((A) / 4194304.0L)) +#define _IQ21toF(A) ((float) ((A) / 2097152.0L)) +#define _IQ20toF(A) ((float) ((A) / 1048576.0L)) +#define _IQ19toF(A) ((float) ((A) / 524288.0L)) +#define _IQ18toF(A) ((float) ((A) / 262144.0L)) +#define _IQ17toF(A) ((float) ((A) / 131072.0L)) +#define _IQ16toF(A) ((float) ((A) / 65536.0L)) +#define _IQ15toF(A) ((float) ((A) / 32768.0L)) +#define _IQ14toF(A) ((float) ((A) / 16384.0L)) +#define _IQ13toF(A) ((float) ((A) / 8192.0L)) +#define _IQ12toF(A) ((float) ((A) / 4096.0L)) +#define _IQ11toF(A) ((float) ((A) / 2048.0L)) +#define _IQ10toF(A) ((float) ((A) / 1024.0L)) +#define _IQ9toF(A) ((float) ((A) / 512.0L)) +#define _IQ8toF(A) ((float) ((A) / 256.0L)) +#define _IQ7toF(A) ((float) ((A) / 128.0L)) +#define _IQ6toF(A) ((float) ((A) / 64.0L)) +#define _IQ5toF(A) ((float) ((A) / 32.0L)) +#define _IQ4toF(A) ((float) ((A) / 16.0L)) +#define _IQ3toF(A) ((float) ((A) / 8.0L)) +#define _IQ2toF(A) ((float) ((A) / 4.0L)) +#define _IQ1toF(A) ((float) ((A) / 2.0L)) + +#if GLOBAL_Q == 30 +#define _IQtoF(A) _IQ30toF(A) +#endif +#if GLOBAL_Q == 29 +#define _IQtoF(A) _IQ29toF(A) +#endif +#if GLOBAL_Q == 28 +#define _IQtoF(A) _IQ28toF(A) +#endif +#if GLOBAL_Q == 27 +#define _IQtoF(A) _IQ27toF(A) +#endif +#if GLOBAL_Q == 26 +#define _IQtoF(A) _IQ26toF(A) +#endif +#if GLOBAL_Q == 25 +#define _IQtoF(A) _IQ25toF(A) +#endif +#if GLOBAL_Q == 24 +#define _IQtoF(A) _IQ24toF(A) +#endif +#if GLOBAL_Q == 23 +#define _IQtoF(A) _IQ23toF(A) +#endif +#if GLOBAL_Q == 22 +#define _IQtoF(A) _IQ22toF(A) +#endif +#if GLOBAL_Q == 21 +#define _IQtoF(A) _IQ21toF(A) +#endif +#if GLOBAL_Q == 20 +#define _IQtoF(A) _IQ20toF(A) +#endif +#if GLOBAL_Q == 19 +#define _IQtoF(A) _IQ19toF(A) +#endif +#if GLOBAL_Q == 18 +#define _IQtoF(A) _IQ18toF(A) +#endif +#if GLOBAL_Q == 17 +#define _IQtoF(A) _IQ17toF(A) +#endif +#if GLOBAL_Q == 16 +#define _IQtoF(A) _IQ16toF(A) +#endif +#if GLOBAL_Q == 15 +#define _IQtoF(A) _IQ15toF(A) +#endif +#if GLOBAL_Q == 14 +#define _IQtoF(A) _IQ14toF(A) +#endif +#if GLOBAL_Q == 13 +#define _IQtoF(A) _IQ13toF(A) +#endif +#if GLOBAL_Q == 12 +#define _IQtoF(A) _IQ12toF(A) +#endif +#if GLOBAL_Q == 11 +#define _IQtoF(A) _IQ11toF(A) +#endif +#if GLOBAL_Q == 10 +#define _IQtoF(A) _IQ10toF(A) +#endif +#if GLOBAL_Q == 9 +#define _IQtoF(A) _IQ9toF(A) +#endif +#if GLOBAL_Q == 8 +#define _IQtoF(A) _IQ8toF(A) +#endif +#if GLOBAL_Q == 7 +#define _IQtoF(A) _IQ7toF(A) +#endif +#if GLOBAL_Q == 6 +#define _IQtoF(A) _IQ6toF(A) +#endif +#if GLOBAL_Q == 5 +#define _IQtoF(A) _IQ5toF(A) +#endif +#if GLOBAL_Q == 4 +#define _IQtoF(A) _IQ4toF(A) +#endif +#if GLOBAL_Q == 3 +#define _IQtoF(A) _IQ3toF(A) +#endif +#if GLOBAL_Q == 2 +#define _IQtoF(A) _IQ2toF(A) +#endif +#if GLOBAL_Q == 1 +#define _IQtoF(A) _IQ1toF(A) +#endif + +#define _IQsat(A, Pos, Neg) ((A > Pos) ? Pos : (A < Neg) ? Neg : A) +//--------------------------------------------------------------------------- +#define _IQtoIQ30(A) ((long) (A) << (30 - GLOBAL_Q)) +#define _IQ30toIQ(A) ((long) (A) >> (30 - GLOBAL_Q)) + +#if (GLOBAL_Q >= 29) +#define _IQtoIQ29(A) ((long) (A) >> (GLOBAL_Q - 29)) +#define _IQ29toIQ(A) ((long) (A) << (GLOBAL_Q - 29)) +#else +#define _IQtoIQ29(A) ((long) (A) << (29 - GLOBAL_Q)) +#define _IQ29toIQ(A) ((long) (A) >> (29 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 28) +#define _IQtoIQ28(A) ((long) (A) >> (GLOBAL_Q - 28)) +#define _IQ28toIQ(A) ((long) (A) << (GLOBAL_Q - 28)) +#else +#define _IQtoIQ28(A) ((long) (A) << (28 - GLOBAL_Q)) +#define _IQ28toIQ(A) ((long) (A) >> (28 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 27) +#define _IQtoIQ27(A) ((long) (A) >> (GLOBAL_Q - 27)) +#define _IQ27toIQ(A) ((long) (A) << (GLOBAL_Q - 27)) +#else +#define _IQtoIQ27(A) ((long) (A) << (27 - GLOBAL_Q)) +#define _IQ27toIQ(A) ((long) (A) >> (27 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 26) +#define _IQtoIQ26(A) ((long) (A) >> (GLOBAL_Q - 26)) +#define _IQ26toIQ(A) ((long) (A) << (GLOBAL_Q - 26)) +#else +#define _IQtoIQ26(A) ((long) (A) << (26 - GLOBAL_Q)) +#define _IQ26toIQ(A) ((long) (A) >> (26 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 25) +#define _IQtoIQ25(A) ((long) (A) >> (GLOBAL_Q - 25)) +#define _IQ25toIQ(A) ((long) (A) << (GLOBAL_Q - 25)) +#else +#define _IQtoIQ25(A) ((long) (A) << (25 - GLOBAL_Q)) +#define _IQ25toIQ(A) ((long) (A) >> (25 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 24) +#define _IQtoIQ24(A) ((long) (A) >> (GLOBAL_Q - 24)) +#define _IQ24toIQ(A) ((long) (A) << (GLOBAL_Q - 24)) +#else +#define _IQtoIQ24(A) ((long) (A) << (24 - GLOBAL_Q)) +#define _IQ24toIQ(A) ((long) (A) >> (24 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 23) +#define _IQtoIQ23(A) ((long) (A) >> (GLOBAL_Q - 23)) +#define _IQ23toIQ(A) ((long) (A) << (GLOBAL_Q - 23)) +#else +#define _IQtoIQ23(A) ((long) (A) << (23 - GLOBAL_Q)) +#define _IQ23toIQ(A) ((long) (A) >> (23 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 22) +#define _IQtoIQ22(A) ((long) (A) >> (GLOBAL_Q - 22)) +#define _IQ22toIQ(A) ((long) (A) << (GLOBAL_Q - 22)) +#else +#define _IQtoIQ22(A) ((long) (A) << (22 - GLOBAL_Q)) +#define _IQ22toIQ(A) ((long) (A) >> (22 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 21) +#define _IQtoIQ21(A) ((long) (A) >> (GLOBAL_Q - 21)) +#define _IQ21toIQ(A) ((long) (A) << (GLOBAL_Q - 21)) +#else +#define _IQtoIQ21(A) ((long) (A) << (21 - GLOBAL_Q)) +#define _IQ21toIQ(A) ((long) (A) >> (21 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 20) +#define _IQtoIQ20(A) ((long) (A) >> (GLOBAL_Q - 20)) +#define _IQ20toIQ(A) ((long) (A) << (GLOBAL_Q - 20)) +#else +#define _IQtoIQ20(A) ((long) (A) << (20 - GLOBAL_Q)) +#define _IQ20toIQ(A) ((long) (A) >> (20 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 19) +#define _IQtoIQ19(A) ((long) (A) >> (GLOBAL_Q - 19)) +#define _IQ19toIQ(A) ((long) (A) << (GLOBAL_Q - 19)) +#else +#define _IQtoIQ19(A) ((long) (A) << (19 - GLOBAL_Q)) +#define _IQ19toIQ(A) ((long) (A) >> (19 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 18) +#define _IQtoIQ18(A) ((long) (A) >> (GLOBAL_Q - 18)) +#define _IQ18toIQ(A) ((long) (A) << (GLOBAL_Q - 18)) +#else +#define _IQtoIQ18(A) ((long) (A) << (18 - GLOBAL_Q)) +#define _IQ18toIQ(A) ((long) (A) >> (18 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 17) +#define _IQtoIQ17(A) ((long) (A) >> (GLOBAL_Q - 17)) +#define _IQ17toIQ(A) ((long) (A) << (GLOBAL_Q - 17)) +#else +#define _IQtoIQ17(A) ((long) (A) << (17 - GLOBAL_Q)) +#define _IQ17toIQ(A) ((long) (A) >> (17 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 16) +#define _IQtoIQ16(A) ((long) (A) >> (GLOBAL_Q - 16)) +#define _IQ16toIQ(A) ((long) (A) << (GLOBAL_Q - 16)) +#else +#define _IQtoIQ16(A) ((long) (A) << (16 - GLOBAL_Q)) +#define _IQ16toIQ(A) ((long) (A) >> (16 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 15) +#define _IQtoIQ15(A) ((long) (A) >> (GLOBAL_Q - 15)) +#define _IQ15toIQ(A) ((long) (A) << (GLOBAL_Q - 15)) +#define _IQtoQ15(A) ((long) (A) >> (GLOBAL_Q - 15)) +#define _Q15toIQ(A) ((long) (A) << (GLOBAL_Q - 15)) +#else +#define _IQtoIQ15(A) ((long) (A) << (15 - GLOBAL_Q)) +#define _IQ15toIQ(A) ((long) (A) >> (15 - GLOBAL_Q)) +#define _IQtoQ15(A) ((long) (A) << (15 - GLOBAL_Q)) +#define _Q15toIQ(A) ((long) (A) >> (15 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 14) +#define _IQtoIQ14(A) ((long) (A) >> (GLOBAL_Q - 14)) +#define _IQ14toIQ(A) ((long) (A) << (GLOBAL_Q - 14)) +#define _IQtoQ14(A) ((long) (A) >> (GLOBAL_Q - 14)) +#define _Q14toIQ(A) ((long) (A) << (GLOBAL_Q - 14)) +#else +#define _IQtoIQ14(A) ((long) (A) << (14 - GLOBAL_Q)) +#define _IQ14toIQ(A) ((long) (A) >> (14 - GLOBAL_Q)) +#define _IQtoQ14(A) ((long) (A) << (14 - GLOBAL_Q)) +#define _Q14toIQ(A) ((long) (A) >> (14 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 13) +#define _IQtoIQ13(A) ((long) (A) >> (GLOBAL_Q - 13)) +#define _IQ13toIQ(A) ((long) (A) << (GLOBAL_Q - 13)) +#define _IQtoQ13(A) ((long) (A) >> (GLOBAL_Q - 13)) +#define _Q13toIQ(A) ((long) (A) << (GLOBAL_Q - 13)) +#else +#define _IQtoIQ13(A) ((long) (A) << (13 - GLOBAL_Q)) +#define _IQ13toIQ(A) ((long) (A) >> (13 - GLOBAL_Q)) +#define _IQtoQ13(A) ((long) (A) << (13 - GLOBAL_Q)) +#define _Q13toIQ(A) ((long) (A) >> (13 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 12) +#define _IQtoIQ12(A) ((long) (A) >> (GLOBAL_Q - 12)) +#define _IQ12toIQ(A) ((long) (A) << (GLOBAL_Q - 12)) +#define _IQtoQ12(A) ((long) (A) >> (GLOBAL_Q - 12)) +#define _Q12toIQ(A) ((long) (A) << (GLOBAL_Q - 12)) +#else +#define _IQtoIQ12(A) ((long) (A) << (12 - GLOBAL_Q)) +#define _IQ12toIQ(A) ((long) (A) >> (12 - GLOBAL_Q)) +#define _IQtoQ12(A) ((long) (A) << (12 - GLOBAL_Q)) +#define _Q12toIQ(A) ((long) (A) >> (12 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 11) +#define _IQtoIQ11(A) ((long) (A) >> (GLOBAL_Q - 11)) +#define _IQ11toIQ(A) ((long) (A) << (GLOBAL_Q - 11)) +#define _IQtoQ11(A) ((long) (A) >> (GLOBAL_Q - 11)) +#define _Q11toIQ(A) ((long) (A) << (GLOBAL_Q - 11)) +#else +#define _IQtoIQ11(A) ((long) (A) << (11 - GLOBAL_Q)) +#define _IQ11toIQ(A) ((long) (A) >> (11 - GLOBAL_Q)) +#define _IQtoQ11(A) ((long) (A) << (11 - GLOBAL_Q)) +#define _Q11toIQ(A) ((long) (A) >> (11 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 10) +#define _IQtoIQ10(A) ((long) (A) >> (GLOBAL_Q - 10)) +#define _IQ10toIQ(A) ((long) (A) << (GLOBAL_Q - 10)) +#define _IQtoQ10(A) ((long) (A) >> (GLOBAL_Q - 10)) +#define _Q10toIQ(A) ((long) (A) << (GLOBAL_Q - 10)) +#else +#define _IQtoIQ10(A) ((long) (A) << (10 - GLOBAL_Q)) +#define _IQ10toIQ(A) ((long) (A) >> (10 - GLOBAL_Q)) +#define _IQtoQ10(A) ((long) (A) << (10 - GLOBAL_Q)) +#define _Q10toIQ(A) ((long) (A) >> (10 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 9) +#define _IQtoIQ9(A) ((long) (A) >> (GLOBAL_Q - 9)) +#define _IQ9toIQ(A) ((long) (A) << (GLOBAL_Q - 9)) +#define _IQtoQ9(A) ((long) (A) >> (GLOBAL_Q - 9)) +#define _Q9toIQ(A) ((long) (A) << (GLOBAL_Q - 9)) +#else +#define _IQtoIQ9(A) ((long) (A) << (9 - GLOBAL_Q)) +#define _IQ9toIQ(A) ((long) (A) >> (9 - GLOBAL_Q)) +#define _IQtoQ9(A) ((long) (A) << (9 - GLOBAL_Q)) +#define _Q9toIQ(A) ((long) (A) >> (9 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 8) +#define _IQtoIQ8(A) ((long) (A) >> (GLOBAL_Q - 8)) +#define _IQ8toIQ(A) ((long) (A) << (GLOBAL_Q - 8)) +#define _IQtoQ8(A) ((long) (A) >> (GLOBAL_Q - 8)) +#define _Q8toIQ(A) ((long) (A) << (GLOBAL_Q - 8)) +#else +#define _IQtoIQ8(A) ((long) (A) << (8 - GLOBAL_Q)) +#define _IQ8toIQ(A) ((long) (A) >> (8 - GLOBAL_Q)) +#define _IQtoQ8(A) ((long) (A) << (8 - GLOBAL_Q)) +#define _Q8toIQ(A) ((long) (A) >> (8 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 7) +#define _IQtoIQ7(A) ((long) (A) >> (GLOBAL_Q - 7)) +#define _IQ7toIQ(A) ((long) (A) << (GLOBAL_Q - 7)) +#define _IQtoQ7(A) ((long) (A) >> (GLOBAL_Q - 7)) +#define _Q7toIQ(A) ((long) (A) << (GLOBAL_Q - 7)) +#else +#define _IQtoIQ7(A) ((long) (A) << (7 - GLOBAL_Q)) +#define _IQ7toIQ(A) ((long) (A) >> (7 - GLOBAL_Q)) +#define _IQtoQ7(A) ((long) (A) << (7 - GLOBAL_Q)) +#define _Q7toIQ(A) ((long) (A) >> (7 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 6) +#define _IQtoIQ6(A) ((long) (A) >> (GLOBAL_Q - 6)) +#define _IQ6toIQ(A) ((long) (A) << (GLOBAL_Q - 6)) +#define _IQtoQ6(A) ((long) (A) >> (GLOBAL_Q - 6)) +#define _Q6toIQ(A) ((long) (A) << (GLOBAL_Q - 6)) +#else +#define _IQtoIQ6(A) ((long) (A) << (6 - GLOBAL_Q)) +#define _IQ6toIQ(A) ((long) (A) >> (6 - GLOBAL_Q)) +#define _IQtoQ6(A) ((long) (A) << (6 - GLOBAL_Q)) +#define _Q6toIQ(A) ((long) (A) >> (6 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 5) +#define _IQtoIQ5(A) ((long) (A) >> (GLOBAL_Q - 5)) +#define _IQ5toIQ(A) ((long) (A) << (GLOBAL_Q - 5)) +#define _IQtoQ5(A) ((long) (A) >> (GLOBAL_Q - 5)) +#define _Q5toIQ(A) ((long) (A) << (GLOBAL_Q - 5)) +#else +#define _IQtoIQ5(A) ((long) (A) << (5 - GLOBAL_Q)) +#define _IQ5toIQ(A) ((long) (A) >> (5 - GLOBAL_Q)) +#define _IQtoQ5(A) ((long) (A) << (5 - GLOBAL_Q)) +#define _Q5toIQ(A) ((long) (A) >> (5 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 4) +#define _IQtoIQ4(A) ((long) (A) >> (GLOBAL_Q - 4)) +#define _IQ4toIQ(A) ((long) (A) << (GLOBAL_Q - 4)) +#define _IQtoQ4(A) ((long) (A) >> (GLOBAL_Q - 4)) +#define _Q4toIQ(A) ((long) (A) << (GLOBAL_Q - 4)) +#else +#define _IQtoIQ4(A) ((long) (A) << (4 - GLOBAL_Q)) +#define _IQ4toIQ(A) ((long) (A) >> (4 - GLOBAL_Q)) +#define _IQtoQ4(A) ((long) (A) << (4 - GLOBAL_Q)) +#define _Q4toIQ(A) ((long) (A) >> (4 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 3) +#define _IQtoIQ3(A) ((long) (A) >> (GLOBAL_Q - 3)) +#define _IQ3toIQ(A) ((long) (A) << (GLOBAL_Q - 3)) +#define _IQtoQ3(A) ((long) (A) >> (GLOBAL_Q - 3)) +#define _Q3toIQ(A) ((long) (A) << (GLOBAL_Q - 3)) +#else +#define _IQtoIQ3(A) ((long) (A) << (3 - GLOBAL_Q)) +#define _IQ3toIQ(A) ((long) (A) >> (3 - GLOBAL_Q)) +#define _IQtoQ3(A) ((long) (A) << (3 - GLOBAL_Q)) +#define _Q3toIQ(A) ((long) (A) >> (3 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 2) +#define _IQtoIQ2(A) ((long) (A) >> (GLOBAL_Q - 2)) +#define _IQ2toIQ(A) ((long) (A) << (GLOBAL_Q - 2)) +#define _IQtoQ2(A) ((long) (A) >> (GLOBAL_Q - 2)) +#define _Q2toIQ(A) ((long) (A) << (GLOBAL_Q - 2)) +#else +#define _IQtoIQ2(A) ((long) (A) << (2 - GLOBAL_Q)) +#define _IQ2toIQ(A) ((long) (A) >> (2 - GLOBAL_Q)) +#define _IQtoQ2(A) ((long) (A) << (2 - GLOBAL_Q)) +#define _Q2toIQ(A) ((long) (A) >> (2 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 1) +#define _IQtoQ1(A) ((long) (A) >> (GLOBAL_Q - 1)) +#define _Q1toIQ(A) ((long) (A) << (GLOBAL_Q - 1)) +#else +#define _IQtoQ1(A) ((long) (A) << (1 - GLOBAL_Q)) +#define _Q1toIQ(A) ((long) (A) >> (1 - GLOBAL_Q)) +#endif + +#define _IQtoIQ1(A) ((long) (A) >> (GLOBAL_Q - 1)) +#define _IQ1toIQ(A) ((long) (A) << (GLOBAL_Q - 1)) + +///////////////////////////////////////////////////////////// +long multiply(long x, long y); +long long multiply_fixed_base_select(long long x, long long y, int base); +long divide(long num, long den); +long divide19(long num, long den); +long divideN(long num, long den, unsigned int d); +long sin_fixed(long x); +long cos_fixed(long x); +long sqrt_fixed(long x); +long exp_fixed(long x); +long exp_fixedN(long x, unsigned int n); + +#define _IQabs(A) ((A) > 0 ? (A): -(A)) +#define _IQmpy(A,B) multiply(A,B) +#define _IQ19mpy(A,B) multiply_fixed_base_select(A,B,19) +#define _IQ18mpy(A,B) multiply_fixed_base_select(A,B,18) + +#define _IQdiv(A,B) divide(A,B) +#define _IQ19div(A,B) divide19(A,B) +#define _IQ18div(A,B) divideN(A,B,18) +#define _IQsin(A) sin_fixed(A) +#define _IQcos(A) cos_fixed(A) +#define _IQsqrt(A) sqrt_fixed(A) +#define _IQexp(A) exp_fixed(A) +#define _IQ18exp(A) exp_fixedN(A,18) + + +#define _IQmpyI32(A,B) ((A)*(B)) + + +#define PI 3.1415926535897932384626433832795 +#define PI_2 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 + +#ifndef ONE_24 +#define ONE_24 16777216 +#endif +#ifndef ONE_27 +#define ONE_27 134217728 +#endif +#ifndef ONE_28 +#define ONE_28 268435456 +#endif + +// #ifndef FIXED_PI +// #define FIXED_PI 52707179 +// #endif + +// #ifndef FIXED_2PI +// #define FIXED_2PI 105414357 +// #endif + +#ifndef FIXED_PI_30 +#define FIXED_PI_30 3373259426 +#endif + +#ifndef FIXED_2PI_30 +#define FIXED_2PI_30 6746518852 +#endif + +#ifndef FIXED_3PIna2 +#define FIXED_3PIna2 79060768 +#endif + +#ifndef FIXED_PIna3 +#define FIXED_PIna3 17569059 +#endif + +#ifndef FIXED_PIna6 +#define FIXED_PIna6 8784529 +#endif + +//########################################################################### +// If FLOAT_MATH is used, the IQmath library function are replaced by +// equivalent floating point operations: +//=========================================================================== + +#define _IQ15sqrt(A) sqrt(A) + +#endif //IQ_MATH_LIB diff --git a/Inu/Src/main_matlab/IQmathLib_matlab.c b/Inu/Src/main_matlab/IQmathLib_matlab.c new file mode 100644 index 0000000..f77984b --- /dev/null +++ b/Inu/Src/main_matlab/IQmathLib_matlab.c @@ -0,0 +1,229 @@ +#include "IQmathLib.h" +#include <math.h> + + +// Преобразование числа с плавающей точкой в число с фиксированной точкой +#define float_to_fixed(A) (long)((A)*(1 << (GLOBAL_Q)) + (A > 0 ? 0.5: -0.5)) +// Преобразование числа с плавающей точкой в число с фиксированной точкой с выбором числа бит, отдаваемых под дробную часть +#define float_to_fixed_base_select(A, F_BITS) (long)((A)*(1 << (F_BITS)) + (A > 0 ? 0.5: -0.5)) +// Преобразование целого числа в число с фиксированной точкой +#define int_to_fixed(A) (long)((A) << (GLOBAL_Q)) +// Преобразование целого числа в число с фиксированной точкой с выбором числа бит, отдаваемых под дробную часть +#define int_to_fixed_base_select(A, F_BITS) (long)((A) << (F_BITS)) +//Преобразование числа с фиксированной точкой в число с плавающей точкой +#define fixed_to_float(A) ((double)A / (1 << GLOBAL_Q)) +//Перобразование числа с фиксированной точкой в целое число +#define fixed_to_int(A) ((int)(A >> GLOBAL_Q) ) + +long _IQmag(long a, long b) +{ + return _IQsqrt(_IQmpy(a, a) + _IQmpy(b, b)); +} + +long multiply(long x, long y) +{ + long long z = (long long)x * (long long)y; + return (long)(z >> GLOBAL_Q); +} +//служебная функция. Умножает числа с 27 битами, отданными под дробную часть +static inline long multiply_27(long x, long y) +{ + long long z = (long long)x * (long long)y; + return z & 0x4000000 ? (long)(z >> 27) + 1 : (long)(z >> 27); +} + +long long multiply_fixed_base_select(long long x, long long y, int base) +{ + long long z = (long long)x * (long long)y; + return z & (1 << base) ? (z >> base) + 1 : (z >> base); +} + +long divide(long num, long den) +{ + long long numLong = (long long)num; + long long quotient = (numLong << GLOBAL_Q) / den; + return (long)quotient; +} + +long divide19(long num, long den) +{ + long long numLong = (long long)num; + long long quotient = (numLong << 19) / den; + return (long)quotient; +} + +long divideN(long num, long den, unsigned int d) +{ + long long numLong = (long long)num; + long long quotient = (numLong << d) / den; + return (long)quotient; +} +// +static inline long long divide_fixed_base_select(long long num, long long den, int base) +{ + long long quotient = ((long long)num << base) / den; + return quotient; +} + +#define div_def(A,B) (long)(((long long)(A) << 24)/(B)) +#define div_mod(A,B) (A)%(B) +#define mult_def(A,B) (long)((((long long)(A))*((long long)(B))) >> 24) +#define abs_def(A) ((A) > 0 ? (A): -(A)) + +long sin_fixed(long x) +{ + //Константы сделал ститическими, что бы они вычислялись во время запуска программы, а не исполнения + static long FIXED_2PI = float_to_fixed(TWO_PI); + static long FIXED_PI = float_to_fixed(PI); + static long FIXED_PIna2 = float_to_fixed(PI_2); + //Здесть так же что бы не производить операции деления посчитал констаны ряда Тейлора + static long one_110 = float_to_fixed_base_select(1./110, 27); + static long one_72 = float_to_fixed_base_select(1./72, 27); + static long one_42 = float_to_fixed_base_select(1./42, 27); + static long one_20= float_to_fixed_base_select(1./20, 27); + static long one_6 = float_to_fixed_base_select(1./6, 27); + + long long xx, tmp ; + while(x >= FIXED_2PI) { x -= FIXED_2PI;} //Помещаю аргумент в диапазон 2 ПИ + while(x <= -FIXED_2PI) { x += FIXED_2PI;} + //Так как ряды быстрее сходнятся при малых значениях, помещаю значение аргумента + //в ближайшие к нулю области + if(x > FIXED_PI) + { + x -= FIXED_2PI; + } + else if(x < -FIXED_PI) + { + x += FIXED_2PI; + } + if(x < -FIXED_PIna2) + { + x = -FIXED_PI - x; + } + else if(x > FIXED_PIna2) + { + x = FIXED_PI - x; + } + //проверяю угол на значения, при которых синус раве 0 или 1 + if(x == 0) return 0; + if(x == FIXED_PIna2) return int_to_fixed(1); + if(x == -FIXED_PIna2) return int_to_fixed(-1); + //Перевожу в формат с максимальной точностью для возможного дипазано значений + x <<= (27 - GLOBAL_Q); + //Считаю ряд фурье + xx = multiply_27(x, x); + tmp = ONE_27 - multiply_27(one_110, xx); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_72); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_42); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_20); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_6); + tmp = multiply_27(x, tmp); + return tmp >> (27 - GLOBAL_Q); //Перед возвращением из функции преобразую в первоначальный формат +} + +long cos_fixed(long x) +{ + //Константы сделал ститическими, что бы они вычислялись во время запуска программы, а не исполнения + static long FIXED_2PI = float_to_fixed(TWO_PI); + static long FIXED_PI = float_to_fixed(PI); + static long FIXED_PIna2 = float_to_fixed(PI_2); + //Здесть так же что бы не производить операции деления посчитал констаны ряда Тейлора + static long one_132 = float_to_fixed_base_select(1./132, 27); + static long one_90 = float_to_fixed_base_select(1./90, 27); + static long one_56 = float_to_fixed_base_select(1./56, 27); + static long one_30 = float_to_fixed_base_select(1./30, 27); + static long one_12 = float_to_fixed_base_select(1./12, 27); + + long xx, tmp, counter = 0; + while(x >= FIXED_2PI) { x -= FIXED_2PI;} //Помещаю аргумент в диапазон 2 ПИ + while(x < 0) { x += FIXED_2PI;} + x = _IQabs(x); //Так как косинус симметричен относительно нуля, нахожу его модуль + //проверяю угол на значения, при которых синус раве 0 или 1 + if(x == 0) return 1 << GLOBAL_Q; + if(x == FIXED_PI) return -(1 << GLOBAL_Q); + if(x == (FIXED_PIna2) || (x == FIXED_3PIna2))return 0; + //Так как ряды быстрее сходнятся при малых значениях, помещаю значение аргумента + //в ближайшие к нулю области + while(x > FIXED_PIna2) + { + x -= FIXED_PIna2; + counter++; + } + + if(counter == 1 || counter == 3) { x = FIXED_PIna2 - x;} + //Перевожу в формат с максимальной точностью для возможного дипазона значений + x <<= (27 - GLOBAL_Q); + //Считаю ряд фурье + xx = multiply_27(x, x); + tmp = ONE_27 - multiply_27(xx, one_132); + tmp= multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(xx, one_90); + tmp= multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_56); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_30); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_12); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - (tmp >> 1); + tmp >>= (27 - GLOBAL_Q); + return (counter == 0) || (counter == 3) ? tmp : -tmp; +} + +long sqrt_fixed(long x) +{ + int variable_size_bits = sizeof(x) << 3; + long average_val, prev_avg_val; + if(x <= 0) return 0; + while(!(x & (1 << --variable_size_bits))); //Нахожу старший значащий бит + //Нахожу приближение корня сдвгом на половину числа бит между старшим значащим битом + //и положением точки + if(variable_size_bits > GLOBAL_Q) + { + average_val = x >> ((variable_size_bits - GLOBAL_Q) >> 1); + } + else + { + average_val = x << ((GLOBAL_Q - variable_size_bits) >> 1); + } + prev_avg_val = divide(x, average_val); //Нахожу 1/А + //В цикле нахожу среднее арифметическое между А и 1/А, пока число не перестанет меняться + while(_IQabs(prev_avg_val - average_val) > 1) + { + prev_avg_val = average_val; + average_val = (average_val + divide(x, average_val)) >> 1; + } + return average_val; +} + + +long exp_fixed(long x) +{ + // static long FIXED_2PI = float_to_fixed(TWO_PI); + float f = _IQtoF(x); + float r1 = exp(f); + if (r1>127) r1=127; + if (r1<-127) r1=-127; + long r2 = _IQ(r1); + + return r2; +} + + +long exp_fixedN(long x, unsigned int n) +{ + if (n==18) + { + float f = _IQ18toF(x); + float r1 = exp(f); + if (r1>8100) r1=8100; + if (r1<-8100) r1=-8100; + long r2 = _IQ(r1); + + return r2; + } +} \ No newline at end of file diff --git a/Inu/Src/main_matlab/adc_tools.h b/Inu/Src/main_matlab/adc_tools.h new file mode 100644 index 0000000..598df53 --- /dev/null +++ b/Inu/Src/main_matlab/adc_tools.h @@ -0,0 +1,445 @@ +#ifndef _ADC_TOOLS +#define _ADC_TOOLS + +#include "IQmathLib.h" +#include "xp_project.h" + +#define COUNT_DETECT_ZERO 3000 + +#define COUNT_ARR_ADC_BUF_FAST_POINT 10 + +#define NORMA_ACP 3000.0 +#define NORMA_ACP_RMS 2127.66 + +#define NORMA_ACP_TEMPER_MILL_AMP 100.0 // + +#ifndef PROJECT_SHIP +#error �� ���������� PROJECT_SHIP � predifine Name +#else + + +#if (PROJECT_SHIP == 1) +#define NORMA_ACP_TEMPER 100.0 // ��� 23550.1 +#endif + + +#if (PROJECT_SHIP == 2) +#define NORMA_ACP_TEMPER 200.0 // ��� 23550.3 +#endif + +#if (PROJECT_SHIP== 3) +#define NORMA_ACP_TEMPER 200.0 // ��� 23550.3 + +#endif + + +#endif + +#define DELTA_ACP_TEMPER 0.0 // ������� ����� pt100 ����� ���������� �������� 0.0 ��������, ��� �������� ���� SG3013 + +#define NORMA_ACP_P 100.0 +#define ADC_READ_FROM_PARALLEL_BUS 1 + +#define DEFAULT_ZERO_ADC 2048 + +#ifndef USE_INTERNAL_ADC +#define USE_INTERNAL_ADC 0 +#endif + + +#if (USE_INTERNAL_ADC==1) +#define COUNT_ARR_ADC_BUF (C_adc_number+1) +#else +#define COUNT_ARR_ADC_BUF C_adc_number +#endif + +#define COUNT_ARR_ADC_BUF_EXTERNAL C_adc_number + + + +// 23550.3 + +#if(C_adc_number>=1) +#define R_ADC_DEFAULT_0 { 271, 271, 876, 876, 876, 876, 876, 876, 249, 249, 301, 301, 301, 301, 301, 301 } +#define K_LEM_ADC_DEFAULT_0 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 8400, 8400, 8400, 8400, 5000, 5000 } +#define NORMA_ADC_DEFAULT_0 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + +#if(C_adc_number>=2) +#define R_ADC_DEFAULT_1 { 1, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190 } +#define K_LEM_ADC_DEFAULT_1 { 1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1 } +#define NORMA_ADC_DEFAULT_1 { NORMA_ACP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_TEMPER_MILL_AMP, NORMA_ACP_P, NORMA_ACP } +#endif + +#if(C_adc_number>=3) +#define R_ADC_DEFAULT_2 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 3125, 3125, 3125, 3125, 309, 309 } +#define K_LEM_ADC_DEFAULT_2 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 60000, 60000, 60000, 60000, 5000, 5000 } +#define NORMA_ADC_DEFAULT_2 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + +// 23550.1 + +//#if(C_adc_number>=1) +//#define R_ADC_DEFAULT_0 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 312, 312, 312, 312, 309, 309 } +//#define K_LEM_ADC_DEFAULT_0 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 8400, 8400, 8400, 8400, 5000, 5000 } +//#define NORMA_ADC_DEFAULT_0 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +//#endif +// +//#if(C_adc_number>=2) +//#define R_ADC_DEFAULT_1 { 1, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190, 6190 } +//#define K_LEM_ADC_DEFAULT_1 { 1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1 } +//#define NORMA_ADC_DEFAULT_1 { NORMA_ACP, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_TEMPER, NORMA_ACP_P, NORMA_ACP } +//#endif +// +//#if(C_adc_number>=3) +//#define R_ADC_DEFAULT_2 { 271, 271, 887, 887, 887, 887, 887, 887, 250, 250, 3125, 3125, 3125, 3125, 309, 309 } +//#define K_LEM_ADC_DEFAULT_2 { 7200, 7200, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 60000, 60000, 60000, 60000, 5000, 5000 } +//#define NORMA_ADC_DEFAULT_2 { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +//#endif + + + + +#if (USE_INTERNAL_ADC==1) +#define R_ADC_DEFAULT_INTERNAL { 100,100,100,100,100,100,100,100,1248,1248,1248,100,100,100,100,100 } +#define K_LEM_ADC_DEFAULT_INTERNAL { 30,30,30,30,10,10,10,10,621,621,621,100,10,10,10,10 } +#define NORMA_ADC_DEFAULT_INTERNAL { NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP, NORMA_ACP } +#endif + + + + + +/* + //awa3 + //14 ����� out1 + 0 - 11 ������ ������� + //15 ����� out2 + 0 - 11 ������ ������� + //8 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + //9 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + + //10 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + + //11 ����� + 0 - 20 �� | 0 ���� - 200 ���� / �������� + 0V - 1.5V / 0 ���� - 200 ���� / �������� + //12 ����� + 4 - 20 �� | 0 ��� - 10 ��� / �������� + 0.3V - 1.5V / 0 ��� - 10 ��� / �������� + + //13 ����� + 4 - 20 �� | 0 ��� - 10 ��� / �������� + 0.3V - 1.5V / 0 ��� - 10 ��� / �������� +*/ + + +typedef union +{ + + struct + { + unsigned int c0_plus : 1; /* 0 ������+ */ + unsigned int c1_plus : 1; /* 0 ������+ */ + unsigned int c2_plus : 1; /* 0 ������+ */ + unsigned int c3_plus : 1; /* 0 ������+ */ + unsigned int c4_plus : 1; /* 0 ������+ */ + unsigned int c5_plus : 1; /* 0 ������+ */ + unsigned int c6_plus : 1; /* 0 ������+ */ + unsigned int c7_plus : 1; /* 0 ������+ */ + unsigned int c8_plus : 1; /* 0 ������+ */ + unsigned int c9_plus : 1; /* 0 ������+ */ + unsigned int c10_plus : 1; /* 0 ������+ */ + unsigned int c11_plus : 1; /* 0 ������+ */ + unsigned int c12_plus : 1; /* 0 ������+ */ + unsigned int c13_plus : 1; /* 0 ������+ */ + unsigned int c14_plus : 1; /* 0 ������+ */ + unsigned int c15_plus : 1; /* 0 ������+ */ + } bit; /* ������ ������� */ + unsigned long all; /* ������ ������ */ + +} ERR_ADC_PLUS_PROTECT; + + +typedef union +{ + + struct + { + unsigned int c0_minus : 1; /* 0 ������- */ + unsigned int c1_minus : 1; /* 0 ������- */ + unsigned int c2_minus : 1; /* 0 ������- */ + unsigned int c3_minus : 1; /* 0 ������- */ + unsigned int c4_minus : 1; /* 0 ������- */ + unsigned int c5_minus : 1; /* 0 ������- */ + unsigned int c6_minus : 1; /* 0 ������- */ + unsigned int c7_minus : 1; /* 0 ������- */ + unsigned int c8_minus : 1; /* 0 ������- */ + unsigned int c9_minus : 1; /* 0 ������- */ + unsigned int c10_minus : 1; /* 0 ������- */ + unsigned int c11_minus : 1; /* 0 ������- */ + unsigned int c12_minus : 1; /* 0 ������- */ + unsigned int c13_minus : 1; /* 0 ������- */ + unsigned int c14_minus : 1; /* 0 ������- */ + unsigned int c15_minus : 1; /* 0 ������- */ + + } bit; /* ������ ������� */ + unsigned int all; /* ������ ������ */ + +} ERR_ADC_MINUS_PROTECT; + + +typedef struct +{ + ERR_ADC_PLUS_PROTECT plus; + ERR_ADC_MINUS_PROTECT minus; +} ERR_ADC_PROTECT; + + +/* ���������y ��������� �������� ����� � ����y����� ��� */ +typedef struct +{ + _iq iqU_1; + _iq iqU_2; + + _iq iqU_1_fast; + _iq iqU_2_fast; + + _iq iqU_1_long; + _iq iqU_2_long; + + _iq iqIu_1; + _iq iqIv_1; + _iq iqIw_1; + + _iq iqIu_2; + _iq iqIv_2; + _iq iqIw_2; + + _iq iqIu_1_rms; + _iq iqIv_1_rms; + _iq iqIw_1_rms; + + _iq iqIu_2_rms; + _iq iqIv_2_rms; + _iq iqIw_2_rms; + + _iq iqIu; + _iq iqIv; + _iq iqIw; + + _iq iqIin_1; + _iq iqIin_2; + + _iq iqUin_A1B1; + _iq iqUin_B1C1; + _iq iqUin_C1A1; + + _iq iqUin_A2B2; + _iq iqUin_B2C2; + _iq iqUin_C2A2; + + _iq iqUin_A1B1_rms; + _iq iqUin_B1C1_rms; + _iq iqUin_C1A1_rms; + + _iq iqUin_A2B2_rms; + _iq iqUin_B2C2_rms; + _iq iqUin_C2A2_rms; + + _iq iqUin_m1; + _iq iqUin_m2; + + _iq iqIbreak_1; + _iq iqIbreak_2; + + _iq T_U01; + _iq T_U02; + _iq T_U03; + _iq T_U04; + _iq T_U05; + _iq T_U06; + _iq T_U07; + + _iq T_Water_external; + _iq T_Water_internal; + + _iq T_Air_01; + _iq T_Air_02; + _iq T_Air_03; + _iq T_Air_04; + + _iq P_Water_internal; + + + _iq iqI_vozbud; + + _iq iqIin_sum; + + _iq iqIm_1; + _iq iqIm_2; + + _iq iqIm; + + + _iq iqM; + + _iq PowerScalar; + _iq PowerScalarFilter2; + _iq PowerFOC; + + _iq iqU_1_imit; + + + /* + _iq iqUzpt_1_2; //uzpt1 bs2 + _iq iqUzpt_2_2; //uzpt2 bs2 + _iq iqUzpt_1_2_fast; //uzpt1 bs2 + _iq iqUzpt_2_2_fast; //uzpt2 bs2 + _iq iqUzpt_1_2_long; //uzpt1 bs2 + _iq iqUzpt_2_2_long; //uzpt2 bs2 + _iq iqIin_1_1; //Iin AF1 BS1 + _iq iqIin_2_1; //Iin AF2 BS1 + _iq iqIin_3_1; //Iin AF3 BS1 + _iq iqIin_4_1; //Iin AF4 BS1 + _iq iqIin_5_1; //Iin AF5 BS1 + _iq iqIin_6_1; //Iin AF6 BS1 + _iq iqIin_1_2; //Iin AF1 BS2 + _iq iqIin_2_2; //Iin AF2 BS2 + _iq iqIin_3_2; //Iin AF3 BS2 + _iq iqIin_4_2; //Iin AF4 BS2 + _iq iqIin_5_2; //Iin AF5 BS2 + _iq iqIin_6_2; //Iin AF6 BS2 + _iq iqUin_AB; //������� �������� ���������� AB + _iq iqUin_BC; //������� �������� ���������� BC + _iq iqUin_CA; //������� �������� ���������� CA + _iq iqUin_AB_sf; //������� �������� ���������� AB + _iq iqUin_BC_sf; //������� �������� ���������� BC + _iq iqUin_CA_sf; //������� �������� ���������� CA + _iq iqT_WATER_in; // ����������� ���� �� ����� �� + _iq iqT_WATER_out; // ����������� ���� �� ������ �� + _iq iqT_AIR_in_up; // ����������� ������� �� ����� �� (����) + _iq iqT_AIR_in_down;// ����������� ������� �� ����� �� (���) + _iq iqP_WATER_in; // �������� ���� �� ����� �� + _iq iqP_WATER_out; // �������� ���� �� ������ �� + + _iq iqT_BK1_BK12; // ������� ��������� ������ �� �������� BK1_BK12 + _iq iqT_BK13_BK24; // ������� ��������� ������ �� �������� BK13_BK24 + + _iq iqUin_m1; //��������� ������� �������� ���������� + + + _iq iqIu_1_1; //Iu AF1 BS1 + _iq iqIu_1_2; //Iu AF2 BS1 + _iq iqIv_1_1; //Iv AF3 BS1 + _iq iqIv_1_2; //Iv AF4 BS1 + _iq iqIw_1_1; //Iw AF5 BS1 + _iq iqIw_1_2; //Iw AF6 BS1 + + + + _iq iqIu_2_1; //Iu AF1 BS2 + _iq iqIu_2_2; //Iu AF2 BS2 + _iq iqIv_2_1; //Iv AF3 BS2 + _iq iqIv_2_2; //Iv AF4 BS2 + _iq iqIw_2_1; //Iw AF5 BS2 + _iq iqIw_2_2; //Iw AF6 BS2 + + _iq iqIm_1; + _iq iqIm_2; + + _iq iqWexp; + _iq iqWout; + + _iq iqM; +*/ +} ANALOG_VALUE; + +typedef struct { + float U1_1; + float U1_2; + float Izpt1_1; + float Izpt1_2; + float Ia1; + float Ib1; + float Ic1; + float U2_1; + float U2_2; + float Izpt2_1; + float Izpt2_2; + float Ia2; + float Ib2; + float Ic2; + + void (*read_adc)(); +} ANALOG_RAW_DATA; + +#define ANALOG_VALUE_DEFAULT {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,\ + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0, 0} +/* ���������y ��������� �������� ����� � ����y����� ��� */ + + +#define ERR_LEVEL_ADC_PLUS 3950 //+1270A //2950 // +650A //3467 // 3367 //3367 //3267 // 0xfff-0x29c +#define ERR_LEVEL_ADC_MINUS 150 //-1270A //1150 //-650A // 267 //367 + +#define ERR_LEVEL_ADC_PLUS_6 3800 //3783 //3623~1150 // 3462 ~ 1050 A // 3320 ~ 960A //3680 //3267 // 0xfff-0x29c +#define ERR_LEVEL_ADC_MINUS_6 1000 //267 //367 + +#define MIN_DETECT_UD_ZERO 2300 + + +#define level_err_ADC_PLUS_default {ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,\ + ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS,ERR_LEVEL_ADC_PLUS} + +#define level_err_ADC_MINUS_default {ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,\ + ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS,ERR_LEVEL_ADC_MINUS} + + +extern ANALOG_VALUE analog; +extern ANALOG_VALUE filter; +extern ANALOG_VALUE analog_zero; +extern ANALOG_RAW_DATA rawData; +extern _iq iq_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +//void calc_norm_ADC(int fast); +void calc_norm_ADC_0(int run_norma); +void calc_norm_ADC_1(int run_norma); +void Init_Adc_Variables(void); +void norma_adc_nc(int nc); +void init_Adc_Variables(void); +void detect_zero_analog(int nc); + + +extern int ADC_f[COUNT_ARR_ADC_BUF][16]; +extern int zero_ADC[COUNT_ARR_ADC_BUF][16]; + +extern ERR_ADC_PROTECT err_adc_protect[COUNT_ARR_ADC_BUF], mask_err_adc_protect[COUNT_ARR_ADC_BUF]; + +extern unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16]; +extern unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16]; +extern float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16]; + +//void norma_all_adc(void); + + +void detect_zero_analog(int nc); + + +#if (USE_INTERNAL_ADC==1) + +void Init_Internal_Adc(void); + +#endif + + +#endif // end _ADC_TOOLS diff --git a/Inu/Src/main_matlab/adc_tools_matlab.c b/Inu/Src/main_matlab/adc_tools_matlab.c new file mode 100644 index 0000000..c2ffe34 --- /dev/null +++ b/Inu/Src/main_matlab/adc_tools_matlab.c @@ -0,0 +1,748 @@ +// #include "project.h" +#include "adc_tools.h" +// #include "xp_project.h" +#include "IQmathLib.h" +#include "math.h" +#include "filter_v1.h" +#include "params.h" +// #include "params_protect.h" +#include "vector.h" +// #include "xp_adc.h" +// #include "TuneUpPlane.h" //Ìîðãàíèå ñâåòîäèîäîì +// #include "log_to_memory.h" +// #include "errors.h" + +// #define COUNT_ARR_ADC_BUF 2 +#define Shift_Filter 1 //2 + +#define BTR_ENABLED + +#define R_ADC_DEFAULT { 1180 ,1180 , 256, 256, 256, 256, 256, 1180, 1180, 256, 256, 256, 256, 256, 256, 256, 256, 256 } +#define K_LEM_ADC_DEFAULT { 60000,60000,5000, 5000,5000,5000,5000,60000,60000,5000,5000,5000,5000,5000,5000,5000,5000,5000 } +//#define LOG_ACP_TO_BUF + + + +#if (USE_INTERNAL_ADC==1) + +#if(C_adc_number==1) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_INTERNAL }; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_INTERNAL }; +#endif +#if(C_adc_number==2) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_INTERNAL }; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_INTERNAL }; +#endif +#if(C_adc_number==3) +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1, R_ADC_DEFAULT_2,R_ADC_DEFAULT_INTERNAL }; +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_2, K_LEM_ADC_DEFAULT_INTERNAL }; +float const K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_2, NORMA_ADC_DEFAULT_INTERNAL }; +#endif + +#else + +#if(C_adc_number==1) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0 }; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0 }; +#endif +#if(C_adc_number==2) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int const R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int const K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1 }; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1 }; +#endif +#if(C_adc_number==3) +#pragma DATA_SECTION(R_ADC,".slow_vars") +unsigned int R_ADC[COUNT_ARR_ADC_BUF][16] = { R_ADC_DEFAULT_0, R_ADC_DEFAULT_1, R_ADC_DEFAULT_2 }; +#pragma DATA_SECTION(K_LEM_ADC,".slow_vars") +unsigned int K_LEM_ADC[COUNT_ARR_ADC_BUF][16] = { K_LEM_ADC_DEFAULT_0, K_LEM_ADC_DEFAULT_1, K_LEM_ADC_DEFAULT_2 }; +#pragma DATA_SECTION(K_NORMA_ADC,".slow_vars") +float K_NORMA_ADC[COUNT_ARR_ADC_BUF][16] = { NORMA_ADC_DEFAULT_0, NORMA_ADC_DEFAULT_1, NORMA_ADC_DEFAULT_2 }; +#endif + +#endif + +#pragma DATA_SECTION(ADC_f,".fast_vars"); +int ADC_f[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(ADC_fast,".fast_vars"); +int ADC_fast[COUNT_ARR_ADC_BUF][16][COUNT_ARR_ADC_BUF_FAST_POINT]; + + +#pragma DATA_SECTION(ADC_sf,".fast_vars"); +int ADC_sf[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(analog,".fast_vars"); +ANALOG_VALUE analog = ANALOG_VALUE_DEFAULT; + +#pragma DATA_SECTION(filter,".fast_vars"); +ANALOG_VALUE filter = ANALOG_VALUE_DEFAULT; + +#pragma DATA_SECTION(analog_zero,".fast_vars"); +ANALOG_VALUE analog_zero = ANALOG_VALUE_DEFAULT; + + + +unsigned int const level_err_ADC_PLUS[16] = level_err_ADC_PLUS_default; +unsigned int const level_err_ADC_MINUS[16] = level_err_ADC_MINUS_default; + + +#pragma DATA_SECTION(err_adc_protect,".fast_vars"); +#pragma DATA_SECTION(mask_err_adc_protect,".fast_vars"); +ERR_ADC_PROTECT err_adc_protect[COUNT_ARR_ADC_BUF], mask_err_adc_protect[COUNT_ARR_ADC_BUF]; + + + +_iq koef_Im_filter = 0; +_iq koef_Power_filter = 0; +_iq koef_Power_filter2 = 0; + +#pragma DATA_SECTION(k_norm_ADC,".slow_vars") +_iq19 k_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq19_zero_ADC,".fast_vars"); +_iq19 iq19_zero_ADC[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(zero_ADC,".slow_vars") +int zero_ADC[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(iq19_k_norm_ADC,".fast_vars"); +_iq19 iq19_k_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq_norm_ADC,".fast_vars"); +_iq iq_norm_ADC[COUNT_ARR_ADC_BUF][16]; + +#pragma DATA_SECTION(iq_norm_ADC_sf,".fast_vars"); +_iq iq_norm_ADC_sf[COUNT_ARR_ADC_BUF][16]; + + +#pragma DATA_SECTION(koef_Uzpt_long_filter,".fast_vars"); +_iq koef_Uzpt_long_filter = 0; + +#pragma DATA_SECTION(koef_Uzpt_fast_filter,".fast_vars"); +_iq koef_Uzpt_fast_filter = 0; + +#pragma DATA_SECTION(koef_Uin_filter,".fast_vars"); +_iq koef_Uin_filter = 0; + + +ANALOG_RAW_DATA rawData = {0}; + + + + +void calc_norm_ADC(void); +void analog_values_calc(void); +_iq im_calc( _iq ia, _iq ib, _iq ic); + +#define Shift_Filter 1 //2 +void read_adc() +{ + static unsigned int adr_adc = 0; + if(project.adc[0].status == component_Ready) + { + project.adc->read_pbus(&project.adc[0]); + ADC_f[0][0] = project.adc[0].read.pbus.adc_value[0]; + ADC_f[0][1] = project.adc[0].read.pbus.adc_value[1]; + ADC_f[0][2] = project.adc[0].read.pbus.adc_value[2]; + ADC_f[0][3] = project.adc[0].read.pbus.adc_value[3]; + ADC_f[0][4] = project.adc[0].read.pbus.adc_value[4]; + ADC_f[0][5] = project.adc[0].read.pbus.adc_value[5]; + ADC_f[0][6] = project.adc[0].read.pbus.adc_value[6]; + ADC_f[0][7] = project.adc[0].read.pbus.adc_value[7]; + ADC_f[0][8] = project.adc[0].read.pbus.adc_value[8]; + ADC_f[0][9] = project.adc[0].read.pbus.adc_value[9]; + ADC_f[0][10] = project.adc[0].read.pbus.adc_value[10]; + ADC_f[0][11] = project.adc[0].read.pbus.adc_value[11]; + ADC_f[0][12] = project.adc[0].read.pbus.adc_value[12]; + ADC_f[0][13] = project.adc[0].read.pbus.adc_value[13]; + ADC_f[0][14] = project.adc[0].read.pbus.adc_value[14]; + ADC_f[0][15] = project.adc[0].read.pbus.adc_value[15]; + + + ADC_sf[0][0] += (ADC_f[0][0] - ADC_sf[0][0]) >> Shift_Filter; + ADC_sf[0][1] += (ADC_f[0][1] - ADC_sf[0][1]) >> Shift_Filter; + ADC_sf[0][2] += (ADC_f[0][2] - ADC_sf[0][2]) >> Shift_Filter; + ADC_sf[0][3] += (ADC_f[0][3] - ADC_sf[0][3]) >> Shift_Filter; + ADC_sf[0][4] += (ADC_f[0][4] - ADC_sf[0][4]) >> Shift_Filter; + ADC_sf[0][5] += (ADC_f[0][5] - ADC_sf[0][5]) >> Shift_Filter; + ADC_sf[0][6] += (ADC_f[0][6] - ADC_sf[0][6]) >> Shift_Filter; + + ADC_sf[0][7] += (ADC_f[0][7] - ADC_sf[0][7]) >> Shift_Filter; + ADC_sf[0][8] += (ADC_f[0][8] - ADC_sf[0][8]) >> Shift_Filter; + ADC_sf[0][9] += (ADC_f[0][9] - ADC_sf[0][9]) >> Shift_Filter; + ADC_sf[0][10] += (ADC_f[0][10] - ADC_sf[0][10]) >> Shift_Filter; + ADC_sf[0][11] += (ADC_f[0][11] - ADC_sf[0][11]) >> Shift_Filter; + ADC_sf[0][12] += (ADC_f[0][12] - ADC_sf[0][12]) >> Shift_Filter; + ADC_sf[0][13] += (ADC_f[0][13] - ADC_sf[0][13]) >> Shift_Filter; + ADC_sf[0][14] += (ADC_f[0][14] - ADC_sf[0][14]) >> Shift_Filter; + ADC_sf[0][15] += (ADC_f[0][15] - ADC_sf[0][15]) >> Shift_Filter; + } + if(project.adc[1].status == component_Ready) + { + project.adc->read_pbus(&project.adc[1]); + // adr_adc = project.adc[1].adr_pbus.adr_table[0]; + ADC_f[1][0] = project.adc[1].read.pbus.adc_value[0]; + ADC_f[1][1] = project.adc[1].read.pbus.adc_value[1]; + ADC_f[1][2] = project.adc[1].read.pbus.adc_value[2]; + ADC_f[1][3] = project.adc[1].read.pbus.adc_value[3]; + + ADC_sf[1][0] += (ADC_f[1][0] - ADC_sf[1][0]) >> Shift_Filter; + ADC_sf[1][1] += (ADC_f[1][1] - ADC_sf[1][1]) >> Shift_Filter; + ADC_sf[1][2] += (ADC_f[1][2] - ADC_sf[1][2]) >> Shift_Filter; + ADC_sf[1][3] += (ADC_f[1][3] - ADC_sf[1][3]) >> Shift_Filter; + /* Not used + ADC_sf[1][4] += (ADC_f[1][4] - ADC_sf[1][4]) >> Shift_Filter; + ADC_sf[1][5] += (ADC_f[1][5] - ADC_sf[1][5]) >> Shift_Filter; + ADC_sf[1][6] += (ADC_f[1][6] - ADC_sf[1][6]) >> Shift_Filter; + ADC_sf[1][7] += (ADC_f[1][7] - ADC_sf[1][7]) >> Shift_Filter; + ADC_sf[1][8] += (ADC_f[1][8] - ADC_sf[1][8]) >> Shift_Filter; + ADC_sf[1][9] += (ADC_f[1][9] - ADC_sf[1][9]) >> Shift_Filter; + ADC_sf[1][10] += (ADC_f[1][10] - ADC_sf[1][10]) >> Shift_Filter; + ADC_sf[1][11] += (ADC_f[1][11] - ADC_sf[1][11]) >> Shift_Filter; + ADC_sf[1][12] += (ADC_f[1][12] - ADC_sf[1][12]) >> Shift_Filter; + ADC_sf[1][13] += (ADC_f[1][13] - ADC_sf[1][13]) >> Shift_Filter; + ADC_sf[1][14] += (ADC_f[1][14] - ADC_sf[1][14]) >> Shift_Filter; + ADC_sf[1][15] += (ADC_f[1][15] - ADC_sf[1][15]) >> Shift_Filter; + */ + } +} + +void acp_Handler(void) +{ + //read_adc(); + calc_norm_ADC_0(0); + //analog_values_calc(); + // Read_Fast_Errors(); +} + +//#define COUNT_DETECT_ZERO 500 + + + +void init_Adc_Variables(void) +{ + unsigned int k, i, j; + int* panalog, * pfilter; + volatile float k_f; + + + for (i = 0; i < COUNT_ARR_ADC_BUF; i++) + { + for (k = 0; k < 16; k++) + { + ADC_f[i][k] = 0; + ADC_sf[i][k] = 0; + + for (j = 0; j < COUNT_ARR_ADC_BUF_FAST_POINT; j++) + ADC_fast[i][k][j] = 0; + + k_f = K_LEM_ADC[i][k] * 2.5 / R_ADC[i][k] / 4096.0; + k_norm_ADC[i][k] = _IQ19(k_f); + + k_f = K_LEM_ADC[i][k] * 250.0 / R_ADC[i][k] / K_NORMA_ADC[i][k] / 4096.0; + iq19_k_norm_ADC[i][k] = _IQ19(k_f); + + zero_ADC[i][k] = DEFAULT_ZERO_ADC;//1835; + + iq19_zero_ADC[i][k] = _IQ19(zero_ADC[i][k]); //_IQ19(2030);//_IQ19(1770); + + } + } + + + panalog = (int*)&analog; + pfilter = (int*)&filter; + for (k = 0; k < sizeof(ANALOG_VALUE) / sizeof(int); k++) + { + + *(panalog + k) = 0; + *(pfilter + k) = 0; + } + + + for (i = 0; i < COUNT_ARR_ADC_BUF; i++) + { + if (project.adc[i].status >= component_Ready) + detect_zero_analog(i); + } + + // zero_ADC[1][2] = 2010;//1976; // uab + // zero_ADC[1][3] = 2010;//1989; // ubc + // zero_ADC[1][4] = 2010;//1994; // uca + + + zero_ADC[0][0] = zero_ADC[0][2];//2042;//1992;//1835; //uzpt + zero_ADC[0][1] = zero_ADC[0][2];//2042;//1992;//1835; //uzpt + + + +#if (COUNT_ARR_ADC_BUF>1) + zero_ADC[1][1] = zero_ADC[1][15]; + zero_ADC[1][2] = zero_ADC[1][15]; + zero_ADC[1][3] = zero_ADC[1][15]; + zero_ADC[1][4] = zero_ADC[1][15]; + zero_ADC[1][5] = zero_ADC[1][15]; + zero_ADC[1][6] = zero_ADC[1][15]; + zero_ADC[1][7] = zero_ADC[1][15]; + zero_ADC[1][8] = zero_ADC[1][15]; + zero_ADC[1][9] = zero_ADC[1][15]; + zero_ADC[1][10] = zero_ADC[1][15]; + zero_ADC[1][11] = zero_ADC[1][15]; + zero_ADC[1][12] = zero_ADC[1][15]; + zero_ADC[1][13] = zero_ADC[1][15]; + zero_ADC[1][14] = zero_ADC[1][15]; +#endif + + + for (k = 0; k < 16; k++) + { + for (i = 0; i < COUNT_ARR_ADC_BUF; i++) + { + if ((zero_ADC[i][k] > 2200) || (zero_ADC[i][k] < 1900)) + zero_ADC[i][k] = DEFAULT_ZERO_ADC; + } + } + + + + for (k = 0; k < 16; k++) + { + for (i = 0; i < COUNT_ARR_ADC_BUF; i++) + { + iq19_zero_ADC[i][k] = _IQ19(zero_ADC[i][k]);//_IQ19(1770); + } + } + + + // koef_allADC_filter = _IQ19(0.00002/0.00003185);//koef_ADC_filter[0]; + // koef_zero_ADC_filter=_IQ19(0.00002/0.0003185); + koef_Uzpt_long_filter = _IQ(0.001 / 0.016666); + koef_Uzpt_fast_filter = _IQ(0.001 / 0.002); //_IQ(0.001/0.00131); + koef_Uin_filter = _IQ(0.001 / 0.00931); + + // koef_Im_filter = _IQ(0.001/0.006); + koef_Im_filter = _IQ(0.001 / 0.065); + koef_Power_filter = _IQ(0.001 / 0.065); + koef_Power_filter2 = _IQ(0.001 / 0.2); + + // koef_Iabc_filter = _IQ(0.001/0.006); + + + filter.iqU_1_fast = 0; + filter.iqU_1_long = 0; + + filter.iqU_2_fast = 0; + filter.iqU_2_long = 0; + + filter.iqUin_m1 = 0; + filter.iqUin_m2 = 0; + + + // filter.iqU_3_fast = 0; + // filter.iqU_4_fast = 0; + + // filter.iqU_1_long = 0; + // filter.iqU_2_long = 0; + // filter.iqU_3_long = 0; + // filter.iqU_4_long = 0; + + // filter.iqIin_1 = 0; + // filter.iqIin_2 = 0; + + + filter.iqIm_1 = 0; + filter.iqIm_2 = 0; + // filter.iqUin_m1 = 0; + // filter.iqUin_m2 = 0; + + + for (i = 0; i < COUNT_ARR_ADC_BUF; i++) + { + mask_err_adc_protect[i].plus.all = 0; + mask_err_adc_protect[i].minus.all = 0x0; + + err_adc_protect[i].plus.all = 0; + err_adc_protect[i].minus.all = 0x0; + } + +#if (USE_INTERNAL_ADC==1) + Init_Internal_Adc(); +#endif + + +} + +inline _iq norma_adc(int plane, int chan, int n_norm) +{ + // return _IQ19toIQ(_IQ19mpy((iq19_zero_ADC[n_norm] - ((long)ADC_sf[plane][chan]<<19) ),iq19_k_norm_ADC[n_norm])); + // return _IQ19toIQ(_IQ19mpy((((long)ADC_sf[plane][chan]<<19) - iq19_zero_ADC[n_norm]),iq19_k_norm_ADC[n_norm])); + return _IQ19toIQ(_IQ19mpy((((long)ADC_sf[plane][chan]<<19)),iq19_k_norm_ADC[n_norm])); +} +//////////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(norma_adc_nc,".fast_run"); +#define SDVIG_K_FILTER_S 2 //1//(27.08.2009) //3 +void norma_adc_nc(int nc) +{ + int k; + // int bb; + + for (k = 0; k < 16; k++) + { + + ADC_f[nc][k] = project.adc[nc].read.pbus.adc_value[k]; + ADC_sf[nc][k] += (((int)(ADC_f[nc][k] - ADC_sf[nc][k])) >> SDVIG_K_FILTER_S); + iq_norm_ADC[nc][k] = _IQ19toIQ(_IQ19mpy((-iq19_zero_ADC[nc][k] + ((long)ADC_f[nc][k] << 19)), iq19_k_norm_ADC[nc][k])); + } +} + +//////////////////////////////////////////////////////////////////// +#pragma CODE_SECTION(calc_norm_ADC_0,".fast_run"); +void calc_norm_ADC_0(int run_norma) +{ + _iq a1, a2, a3; + +#if (USE_ADC_0) + + if (run_norma) + norma_adc_nc(0); + +#if (_FLOOR6) + analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1 + analog.iqU_1_imit; + analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2 + analog.iqU_1_imit; +#else + analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1; + analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2; +#endif + analog.iqIu_1 = iq_norm_ADC[0][2]; + analog.iqIv_1 = iq_norm_ADC[0][3]; + analog.iqIw_1 = iq_norm_ADC[0][4]; + + analog.iqIu_2 = iq_norm_ADC[0][5]; + analog.iqIv_2 = iq_norm_ADC[0][6]; + analog.iqIw_2 = iq_norm_ADC[0][7]; + + analog.iqIin_1 = -iq_norm_ADC[0][9]; // датчик перевернут + analog.iqIin_2 = -iq_norm_ADC[0][9]; // датчик перевернут + + analog.iqUin_A1B1 = iq_norm_ADC[0][10]; + + // два варианта подключения датчиков 23550.1 более правильный - по схеме + // 23550.1 + + analog.iqUin_B1C1 = iq_norm_ADC[0][11]; // 23550.1 + analog.iqUin_A2B2 = iq_norm_ADC[0][12]; // 23550.1 + +// 23550.3 bs1 bs2 + +// analog.iqUin_B1C1 = iq_norm_ADC[0][12]; // 23550.3 +// analog.iqUin_A2B2 = iq_norm_ADC[0][11]; // 23550.3 +// + analog.iqUin_B2C2 = iq_norm_ADC[0][13]; + + analog.iqIbreak_1 = iq_norm_ADC[0][14]; + analog.iqIbreak_2 = iq_norm_ADC[0][15]; + +#else + analog.iqU_1 = analog.iqIu_1 = analog.iqIu_2 = analog.iqIv_1 = analog.iqIv_2 = + analog.iqIw_1 = analog.iqIw_2 = analog.iqIin_1 = analog.iqIin_2 = analog.iqUin_A1B1 = + analog.iqUin_B1C1 = analog.iqUin_A2B2 = analog.iqUin_B2C2 = analog.iqIbreak_1 = analog.iqIbreak_2 + = 0; +#endif + + analog.iqUin_C1A1 = -(analog.iqUin_A1B1 + analog.iqUin_B1C1); + analog.iqUin_C2A2 = -(analog.iqUin_A2B2 + analog.iqUin_B2C2); + + + + filter.iqU_1_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_1_long, analog.iqU_1); + filter.iqU_2_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_2_long, analog.iqU_2); + + + // analog.iqU_1_fast = filter_U1_3point(analog.iqU_1_fast); + filter.iqU_1_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_1_fast, analog.iqU_1); + filter.iqU_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_2_fast, analog.iqU_2); + + + // filter.iqUzpt_2_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqUzpt_2_2_fast, analog.iqUzpt_2_2); + + + + //15 + + + analog.iqIm_1 = im_calc(analog.iqIu_1, analog.iqIv_1, analog.iqIw_1); + analog.iqIm_2 = im_calc(analog.iqIu_2, analog.iqIv_2, analog.iqIw_2); + + analog.iqIu = analog.iqIu_1 + analog.iqIu_2; + analog.iqIv = analog.iqIv_1 + analog.iqIv_2; + analog.iqIw = analog.iqIw_1 + analog.iqIw_2; + + analog.iqIm = im_calc(analog.iqIu, analog.iqIv, analog.iqIw); + + + analog.iqIin_sum = analog.iqIin_1 + analog.iqIin_2; + + // analog.iqIm_3 = im_calc(analog.iqIa1_1_fir_n+analog.iqIa2_1_fir_n, analog.iqIb1_1_fir_n+analog.iqIb2_1_fir_n, analog.iqIc1_1_fir_n+analog.iqIc2_1_fir_n); + + analog.iqUin_m1 = im_calc(analog.iqUin_A1B1, analog.iqUin_B1C1, analog.iqUin_C1A1); + analog.iqUin_m2 = im_calc(analog.iqUin_A2B2, analog.iqUin_B2C2, analog.iqUin_C2A2); + + // analog.iqUin_m2 = im_calc(analog.UinA2, analog.UinB2, analog.UinC2); + + filter.iqUin_m1 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m1, analog.iqUin_m1); + filter.iqUin_m2 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m2, analog.iqUin_m2); + + + + // i_led1_on_off(0); + // i_led1_on_off(1); + + //1 + + filter.iqIm_1 = exp_regul_iq(koef_Im_filter, filter.iqIm_1, analog.iqIm_1); + filter.iqIm_2 = exp_regul_iq(koef_Im_filter, filter.iqIm_2, analog.iqIm_2); + filter.iqIm = exp_regul_iq(koef_Im_filter, filter.iqIm, analog.iqIm); + + filter.iqIin_sum = exp_regul_iq(koef_Im_filter, filter.iqIin_sum, analog.iqIin_sum); + + //3 + // filter_batter2_Iin.InpVarCurr = (analog.iqIin_1)-ZERO_I_IN; + // filter_batter2_Iin.calc(&filter_batter2_Iin); + + // filter.iqIin = _IQmpy(filter_batter2_Iin.Out,_IQ_09); + + + filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); + filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); + + a1 = analog.iqU_1 + analog.iqU_2; + a2 = analog.iqIin_1; + a3 = _IQmpy(a1, a2); + analog.PowerScalar = a3; + // filter.Power = analog.iqU_1+analog.iqU_2; + filter.PowerScalar = exp_regul_iq(koef_Power_filter, filter.PowerScalar, analog.PowerScalar); + filter.PowerScalarFilter2 = exp_regul_iq(koef_Power_filter2, filter.PowerScalarFilter2, filter.PowerScalar); + +} +//////////////////////////////////////////////////////////////////// +void analog_values_calc(void) +{ + +//#if (USE_ADC_0) +// +//#if (_FLOOR6) +// analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1 + analog.iqU_1_imit; +// analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2 + analog.iqU_1_imit; +//#else +// analog.iqU_1 = iq_norm_ADC[0][0] - analog_zero.iqU_1; +// analog.iqU_2 = iq_norm_ADC[0][1] - analog_zero.iqU_2; +//#endif +// analog.iqIu_1 = iq_norm_ADC[0][2]; +// analog.iqIv_1 = iq_norm_ADC[0][3]; +// analog.iqIw_1 = iq_norm_ADC[0][4]; +// +// analog.iqIu_2 = iq_norm_ADC[0][5]; +// analog.iqIv_2 = iq_norm_ADC[0][6]; +// analog.iqIw_2 = iq_norm_ADC[0][7]; +// +// analog.iqIin_1 = -iq_norm_ADC[0][9]; // датчик перевернут +// analog.iqIin_2 = -iq_norm_ADC[0][9]; // датчик перевернут +// +// analog.iqUin_A1B1 = iq_norm_ADC[0][10]; +// +// // два варианта подключения датчиков 23550.1 более правильный - по схеме +// // 23550.1 +// +// analog.iqUin_B1C1 = iq_norm_ADC[0][11]; // 23550.1 +// analog.iqUin_A2B2 = iq_norm_ADC[0][12]; // 23550.1 +// +//// 23550.3 bs1 bs2 +// +//// analog.iqUin_B1C1 = iq_norm_ADC[0][12]; // 23550.3 +//// analog.iqUin_A2B2 = iq_norm_ADC[0][11]; // 23550.3 +//// +// analog.iqUin_B2C2 = iq_norm_ADC[0][13]; +// +// analog.iqIbreak_1 = iq_norm_ADC[0][14]; +// analog.iqIbreak_2 = iq_norm_ADC[0][15]; +// +// #else +// analog.iqU_1 = analog.iqIu_1 = analog.iqIu_2 = analog.iqIv_1 = analog.iqIv_2 = +// analog.iqIw_1 = analog.iqIw_2 = analog.iqIin_1 = analog.iqIin_2 = analog.iqUin_A1B1 = +// analog.iqUin_B1C1 = analog.iqUin_A2B2 = analog.iqUin_B2C2 = analog.iqIbreak_1 = analog.iqIbreak_2 +// = 0; +// #endif +// +// analog.iqUin_C1A1 = -(analog.iqUin_A1B1 + analog.iqUin_B1C1); +// analog.iqUin_C2A2 = -(analog.iqUin_A2B2 + analog.iqUin_B2C2); +// +// +// +// filter.iqU_1_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_1_long, analog.iqU_1); +// filter.iqU_2_long = exp_regul_iq(koef_Uzpt_long_filter, filter.iqU_2_long, analog.iqU_2); +// +// +// // analog.iqU_1_fast = filter_U1_3point(analog.iqU_1_fast); +// filter.iqU_1_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_1_fast, analog.iqU_1); +// filter.iqU_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqU_2_fast, analog.iqU_2); +// +// +// // filter.iqUzpt_2_2_fast = exp_regul_iq(koef_Uzpt_fast_filter, filter.iqUzpt_2_2_fast, analog.iqUzpt_2_2); +// +// +// +// //15 +// +// +// analog.iqIm_1 = im_calc(analog.iqIu_1, analog.iqIv_1, analog.iqIw_1); +// analog.iqIm_2 = im_calc(analog.iqIu_2, analog.iqIv_2, analog.iqIw_2); +// +// analog.iqIu = analog.iqIu_1 + analog.iqIu_2; +// analog.iqIv = analog.iqIv_1 + analog.iqIv_2; +// analog.iqIw = analog.iqIw_1 + analog.iqIw_2; +// +// analog.iqIm = im_calc(analog.iqIu, analog.iqIv, analog.iqIw); +// +// +// analog.iqIin_sum = analog.iqIin_1 + analog.iqIin_2; +// +// // analog.iqIm_3 = im_calc(analog.iqIa1_1_fir_n+analog.iqIa2_1_fir_n, analog.iqIb1_1_fir_n+analog.iqIb2_1_fir_n, analog.iqIc1_1_fir_n+analog.iqIc2_1_fir_n); +// +// analog.iqUin_m1 = im_calc(analog.iqUin_A1B1, analog.iqUin_B1C1, analog.iqUin_C1A1); +// analog.iqUin_m2 = im_calc(analog.iqUin_A2B2, analog.iqUin_B2C2, analog.iqUin_C2A2); +// +// // analog.iqUin_m2 = im_calc(analog.UinA2, analog.UinB2, analog.UinC2); +// +// filter.iqUin_m1 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m1, analog.iqUin_m1); +// filter.iqUin_m2 = exp_regul_iq(koef_Uin_filter, filter.iqUin_m2, analog.iqUin_m2); +// +// +// +// // i_led1_on_off(0); +// // i_led1_on_off(1); +// +// //1 +// +// filter.iqIm_1 = exp_regul_iq(koef_Im_filter, filter.iqIm_1, analog.iqIm_1); +// filter.iqIm_2 = exp_regul_iq(koef_Im_filter, filter.iqIm_2, analog.iqIm_2); +// filter.iqIm = exp_regul_iq(koef_Im_filter, filter.iqIm, analog.iqIm); +// +// filter.iqIin_sum = exp_regul_iq(koef_Im_filter, filter.iqIin_sum, analog.iqIin_sum); +// +// //3 +// // filter_batter2_Iin.InpVarCurr = (analog.iqIin_1)-ZERO_I_IN; +// // filter_batter2_Iin.calc(&filter_batter2_Iin); +// +// // filter.iqIin = _IQmpy(filter_batter2_Iin.Out,_IQ_09); +// +// +// filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); +// filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); +// +// a1 = analog.iqU_1 + analog.iqU_2; +// a2 = analog.iqIin_1; +// a3 = _IQmpy(a1, a2); +// analog.PowerScalar = a3; +// // filter.Power = analog.iqU_1+analog.iqU_2; +// filter.PowerScalar = exp_regul_iq(koef_Power_filter, filter.PowerScalar, analog.PowerScalar); +// filter.PowerScalarFilter2 = exp_regul_iq(koef_Power_filter2, filter.PowerScalarFilter2, filter.PowerScalar); + + +} + +#define CONST_IQ_11PI6 96629827 //11Pi/6 +#define CONST_IQ_PI6 8784529 // Pi/6 + + +/********************************************************************/ +/* Определение нулy показаний АЦП */ +/********************************************************************/ +#pragma DATA_SECTION(acp_zero,".slow_vars") +_iq19 acp_zero[16]; +#pragma DATA_SECTION(acp_summ,".slow_vars") +long acp_summ[16]; +void detect_zero_analog(int nc) +{ + long i, k; + + + _iq koef_zero_ADC_filter = _IQ19(0.00002 / 0.0003185); + + + for (k = 0; k < 16; k++) + { + acp_zero[k] = 0; + acp_summ[k] = 0; + } + + + + for (i = 0; i < COUNT_DETECT_ZERO; i++) + { + // norma_all_adc(); + norma_adc_nc(nc); + // norma_adc_nc(1); + + + for (k = 0; k < 16; k++) + { + acp_zero[k] = exp_regul_iq(koef_zero_ADC_filter, acp_zero[k], ((long)ADC_f[nc][k] << 19)); + acp_summ[k] = acp_summ[k] + ADC_f[nc][k]; + } + + + + pause_1000(1000); + } + + // 16 и 7 канал пропускаем т.к. это канал напрyжениy + for (k = 0; k < 16; k++) + { + + // if ((k==15)) + // { + // if (ADC_sf[k]<MIN_DETECT_UD_ZERO) + // iq19_zero_ADC[k] = acp_zero[k]; + // } + // else + { + iq19_zero_ADC[nc][k] = acp_zero[k]; + } + + // zero_ADC[k] =_IQ19toF(acp_zero[k]); + zero_ADC[nc][k] = acp_summ[k] / COUNT_DETECT_ZERO;//_IQ19toF(acp_zero[k]); + } + + + + + + +} + + + +unsigned int detect_protect_ACP_plus() +{ + + +} + + +unsigned int detect_protect_ACP_minus() +{ + + +} diff --git a/Inu/Src/main_matlab/dmctype.h b/Inu/Src/main_matlab/dmctype.h new file mode 100644 index 0000000..31b11d8 --- /dev/null +++ b/Inu/Src/main_matlab/dmctype.h @@ -0,0 +1,32 @@ +/* ================================================================================= +File name: DMCTYPE.H + +Originator: Digital Control Systems Group + Texas Instruments + +Description: DMC data type definition file. +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +------------------------------------------------------------------------------*/ + +#ifndef DMCTYPE +#define DMCTYPE + +//--------------------------------------------------------------------------- +// For Portability, User Is Recommended To Use Following Data Type Size +// Definitions For 16-bit and 32-Bit Signed/Unsigned Integers: +// +#ifndef DSP28_DATA_TYPES +#define DSP28_DATA_TYPES +typedef int int16; +typedef long int32; +typedef unsigned int Uint16; +typedef unsigned long Uint32; +typedef float float32; +typedef long double float64; +#endif + +#endif // DMCTYPE + diff --git a/Inu/Src/main_matlab/errors_matlab.c b/Inu/Src/main_matlab/errors_matlab.c new file mode 100644 index 0000000..b9256cf --- /dev/null +++ b/Inu/Src/main_matlab/errors_matlab.c @@ -0,0 +1,25 @@ +#include "DSP281x_Device.h" +//#include "errors.h" +// #include "adc_tools.h" +// #include "can_watercool.h" +// #include "xp_project.h" +// #include "x_basic_types.h" +// #include "CAN_Setup.h" +// #include "vector.h" +// #include "PWMTMSHandle.h" +// #include "params.h" +// #include "params_protect.h" +// //#include "all_main_stuff.h" +// #include "global_time.h" +// #include "errors_temperature.h" +// #include "PWMTMSHandle.h" +// #include "rotation_speed.h" +// #include "io_verbal_names.h" +// #include "isolation.h" +// #include "global_time.h" +// #include "regul_power.h" + + +//ERRORS errors = ERRORS_DEFAULTS; +//FAULTS faults = {0,0,0}; + diff --git a/Inu/Src/main_matlab/io_verbal_names.h b/Inu/Src/main_matlab/io_verbal_names.h new file mode 100644 index 0000000..e544881 --- /dev/null +++ b/Inu/Src/main_matlab/io_verbal_names.h @@ -0,0 +1,73 @@ + +#ifndef _IO_VERBAL_NAMES +#define _IO_VERBAL_NAMES + +//#include "xp_project.h" + +#define CHANNEL_IS_ON_IN1 1 +#define CHANNEL_IS_ON_IN2 0 +#define CHANNEL_IS_OFF 1 + +// //IN0 +// #define IN_OIL_PUMP_IS_READY project.cds_in[0].read.pbus.data_in.bit.in4 +// #define IN_LOCAL_CONTROL project.cds_in[0].read.pbus.data_in.bit.in9 + +// //IN0 UKSS READY +// #define IN_READY_BV1 project.cds_in[0].read.pbus.ready_in.bit.in5 +// #define IN_READY_BV2 project.cds_in[0].read.pbus.ready_in.bit.in7 +// #define IN_READY_UKSI project.cds_in[0].read.pbus.ready_in.bit.in10 +// #define IN_READY_BI1 project.cds_in[0].read.pbus.ready_in.bit.in11 +// #define IN_READY_BI2 project.cds_in[0].read.pbus.ready_in.bit.in13 +// #define IN_READY_UMU project.cds_in[0].read.pbus.ready_in.bit.in15 + +// //IN1 +// #define IN_EMERGENCY_STOP project.cds_in[1].read.pbus.data_in.bit.in0 +// #define IN_PCH_IS_BLOCKED project.cds_in[1].read.pbus.data_in.bit.in1 +// #define IN_PROTECTION_ERROR project.cds_in[1].read.pbus.data_in.bit.in2 +// #define IN_BTR_IS_OFF project.cds_in[1].read.pbus.data_in.bit.in3 +// #define IN_RESERVED_TO_INV2_1 project.cds_in[1].read.pbus.data_in.bit.in4 +// #define IN_RECEIVED_TASK_FROM_SVU project.cds_in[1].read.pbus.data_in.bit.in5 +// #define IN_QTV22_IS_ON project.cds_in[1].read.pbus.data_in.bit.in6 +// #define IN_ERROR_PAIR_INV project.cds_in[1].read.pbus.data_in.bit.in8 +// #define IN_BREAKING_K1 project.cds_in[1].read.pbus.data_in.bit.in9 +// #define IN_ALARM_K2 project.cds_in[1].read.pbus.data_in.bit.in10 +// #define IN_TURNDOWN_K4 project.cds_in[1].read.pbus.data_in.bit.in11 //����� +// #define IN_BWC_NO_24VOLT_ERROR project.cds_in[1].read.pbus.data_in.bit.in12 +// #define IN_BWC_AUTO_MODE project.cds_in[1].read.pbus.data_in.bit.in13 +// #define IN_BSU_DOORS_ARE_CLOSED project.cds_in[1].read.pbus.data_in.bit.in15 + +// //IN2 +// #define IN_PCH_IS_LEADING project.cds_in[2].read.pbus.data_in.bit.in0 +// #define IN_PCH_IS_LEADING_2 project.cds_in[2].read.pbus.data_in.bit.in2 +// #define IN_TEST_LAMPS project.cds_in[2].read.pbus.data_in.bit.in3 +// #define IN_EMERGANCY_BUTTON project.cds_in[2].read.pbus.data_in.bit.in4 +// #define IN_EMERGENCY_STOP_EXTERNAL project.cds_in[2].read.pbus.data_in.bit.in5 +// #define IN_RESET_ERRORS project.cds_in[2].read.pbus.data_in.bit.in6 +// #define IN_BSU_DOORS_ARE_BLOCKED project.cds_in[2].read.pbus.data_in.bit.in7 + +// //OUT0 +// #define OUT_READY1 project.cds_out[0].write.sbus.data_out.bit.dout0 +// #define OUT_READY2 project.cds_out[0].write.sbus.data_out.bit.dout1 +// #define OUT_INVERTOR_ERROR project.cds_out[0].write.sbus.data_out.bit.dout2 +// #define OUT_BATTERY_LOADED project.cds_out[0].write.sbus.data_out.bit.dout3 +// #define OUT_CHARGE_BLOCKED project.cds_out[0].write.sbus.data_out.bit.dout4 +// #define OUT_TURN_ON_BWC project.cds_out[0].write.sbus.data_out.bit.dout5 +// #define OUT_OIL_PUMP project.cds_out[0].write.sbus.data_out.bit.dout6 +// #define OUT_ALLOW_TURN_ON_QTV22 project.cds_out[0].write.sbus.data_out.bit.dout7 +// #define OUT_CHOOSE_CHANNEL project.cds_out[0].write.sbus.data_out.bit.dout8 +// #define OUT_RESET_ERRORS project.cds_out[0].write.sbus.data_out.bit.dout9 +// #define OUT_TURN_ON_HIDRO_PODPOR project.cds_out[0].write.sbus.data_out.bit.dout10 +// #define OUT_RECEIVED_TASK_FROM_SVU project.cds_out[0].write.sbus.data_out.bit.dout11 +// #define OUT_RESERV_2 project.cds_out[0].write.sbus.data_out.bit.dout12 + +// //OUT1 +// #define OUT_LAMP_READY1 project.cds_out[1].write.sbus.data_out.bit.dout0 +// #define OUT_LAMP_READY2 project.cds_out[1].write.sbus.data_out.bit.dout1 +// #define OUT_LAMP_BATTERY_LOADED project.cds_out[1].write.sbus.data_out.bit.dout2 +// #define OUT_LAMP_FAULT project.cds_out[1].write.sbus.data_out.bit.dout3 +// #define OUT_LAMP_OVERHEAT project.cds_out[1].write.sbus.data_out.bit.dout4 +// #define OUT_LAMP_POWER_LIMIT project.cds_out[1].write.sbus.data_out.bit.dout5 +// #define OUT_SWITCH_HI_VOLTAGE_TEST_LAMPS project.cds_out[1].write.sbus.data_out.bit.dout6 + +#endif //_IO_VERBAL_NAMES + diff --git a/Inu/Src/main_matlab/main_matlab.c b/Inu/Src/main_matlab/main_matlab.c new file mode 100644 index 0000000..5bd97c3 --- /dev/null +++ b/Inu/Src/main_matlab/main_matlab.c @@ -0,0 +1,269 @@ + +#include "DSP281x_Device.h" + +#include "vector.h" +#include "v_rotor.h" +//#include "xp_rotation_sensor.h" +#include "log_to_mem.h" +#include "main_matlab.h" +#include "xp_project.h" + +// #define PROJECT_DEFAULTS2 { +// (void (*)(Uint32))project_read_all_pbus2 \ +// } +// typedef struct TS_project{ +// void (*read_all_pbus)(); +// } T_project2; + + +T_project project = {0}; + +#pragma DATA_SECTION(modbus_table_in,".logs"); +MODBUS_REG_STRUCT modbus_table_in[1024]; + + +#pragma DATA_SECTION(modbus_table_out,".logs"); +MODBUS_REG_STRUCT modbus_table_out[1024]; + +FLAG f; +WINDING a; +EDRK edrk = EDRK_DEFAULT; + +//T_rotation_sensor rotation_sensor = T_CDS_ROTATION_SENSOR_DEFAULTS; +int Unites[128][256]; + + +_iq temperature_limit_koeff = _IQ(1.0); + + +void project_read_all_pbus2() +{ + +} + +#pragma DATA_SECTION(logpar, ".fast_vars1"); +LOGSPARAMS logpar = LOGSPARAMS_DEFAULTS; +int LOAG[10]; +float logpar_matlab[50]; + +#pragma DATA_SECTION(break_result_1,".fast_vars"); +_iq break_result_1 = 0; + +#pragma DATA_SECTION(break_result_2,".fast_vars"); +_iq break_result_2 = 0; + +#pragma DATA_SECTION(break_result_3,".fast_vars"); +_iq break_result_3 = 0; + +#pragma DATA_SECTION(break_result_4,".fast_vars"); +_iq break_result_4 = 0; + +//void read_in_sensor_line1(T_cds_in_rotation_sensor *rs){ +// +//} +// +//void read_in_sensor_line2(T_cds_in_rotation_sensor *rs){ +// +//} +//void read_command_reg(T_cds_in_rotation_sensor *rs){ +// +//} +//void write_command_reg(T_cds_in_rotation_sensor *rs){ +// +//} +//void tune_sampling_time(T_rotation_sensor *rs){ +// +//} +//void wait_for_registers_updated(T_cds_in_rotation_sensor *rs){ +// +//} +//void read_direction_in_plane(T_cds_in_rotation_sensor *rs){ +// +//} +//void sensor_set(T_rotation_sensor *rs) +//{ +// +//} +//void sensor_read(T_rotation_sensor *rs) +//{ +// +//} +//void update_sensors_data(T_rotation_sensor *rs) +//{ +// // rs->in_plane.write.regs.comand_reg.bit.update_registers = 1; +// // write_command_reg(&rs->in_plane); +//// rs->in_plane.write.regs.comand_reg.bit.update_registers = 0; +//} +//void angle_sensor_read(T_cds_angle_sensor *as) +//{} +// +//void angle_plane_set(T_cds_angle_sensor *rs) +//{} +//void in_plane_set(T_cds_in_rotation_sensor* rs) +//{} +// +//void in_sensor_read1(T_cds_in_rotation_sensor *rs) +//{} +// +//void in_sensor_read2(T_cds_in_rotation_sensor *rs) +//{} + + + + +// unsigned int BWC_Started() +// { + +// } + +void inc_RS_timeout_cicle(void) +{ + +} + +void inc_CAN_timeout_cicle(void) +{ + +} + +void pause_1000(void) +{ + +} + +int xerror(unsigned int er_ID, void* CallBackRef) +{ +}; +unsigned int ReadMemory(unsigned long addr) +{ + return (*(volatile int *)(addr)); +} + + +void WriteMemory(unsigned long addr, unsigned int data) +{ + (*(volatile int *)( addr )) = data; +} + +void start_pwm(void) +{ + // mPWM_a = 1; + // mPWM_b = 1; +} + +void stop_pwm(void) +{ + // mPWM_a = 0; + // mPWM_b = 0; + + // svgen_set_time_keys_closed(&svgen_pwm24_1); + // svgen_set_time_keys_closed(&svgen_pwm24_2); + // WriteMemory(ADR_TK_MASK_0, 0xFFFF); + // WriteMemory(ADR_PWM_START_STOP, 0x8000); +} +void start_break_pwm() { + +} + + +void stop_break_pwm() { + +} + +void start_pwm_b() { + +} +void start_pwm_a() { + +} +void stop_pwm_b() { + +} +void stop_pwm_a() { + +} + +void fillADClogs() { + +} +void break_resistor_managment_calc(){ + +} + + +void break_resistor_managment_init(){ + +} + + +void break_resistor_managment_update(){ + +} + + +void break_resistor_recup_calc(){ + +} + + +void break_resistor_set_closed(){ + +} + + +void DetectI_Out_BreakFase(){ + +} + + +void test_mem_limit(){ + +} + + +void set_start_mem(){ + +} + + +void getFastLogs(){ + +} + + +//void detect_I_M_overload{ +// +// } + + +void sync_inc_error(){ + +} + + +void optical_bus_read(){ + +} + + +void optical_bus_write(void){ + +} + + +void init_flag_a(void) +{ + + unsigned int i = 0; + int *pStr = (int*)&f; + for (i = 0; i < sizeof(f) / sizeof(int); i++) { + *(pStr + i) = 0; + } + + *pStr = (int*)&a; + for (i = 0; i < sizeof(a) / sizeof(int); i++) { + *(pStr + i) = 0; + } + + +} diff --git a/Inu/Src/main_matlab/main_matlab.h b/Inu/Src/main_matlab/main_matlab.h new file mode 100644 index 0000000..fe79cab --- /dev/null +++ b/Inu/Src/main_matlab/main_matlab.h @@ -0,0 +1,22 @@ + + +#include "vector.h" +#include "edrk_main.h" + +typedef union { + //unsigned int all; + int all; +// struct MODBUS_BITS_STRUCT bit; +// struct MODBUS_WORD_STRUCT byte; +} MODBUS_REG_STRUCT; + + +//extern MODBUS_REG_STRUCT modbus_table_in[1024]; +//extern MODBUS_REG_STRUCT modbus_table_out[1024]; + +void init_flag_a(void); + + + + + diff --git a/Inu/Src/main_matlab/old/PWMTools.c b/Inu/Src/main_matlab/old/PWMTools.c new file mode 100644 index 0000000..561b909 --- /dev/null +++ b/Inu/Src/main_matlab/old/PWMTools.c @@ -0,0 +1,719 @@ +#include <math.h> +#include <stdlib.h> +//#include "project.h" + +#include "IQmathLib.h" +//#include "f281xpwm.h" +// +////#include "SpaceVectorPWM.h" +//#include "MemoryFunctions.h" +//#include "PWMTools.h" +//#include "pwm_vector_regul.h" +//#include "PWMTMSHandle.h" +//#include "TuneUpPlane.h" +//#include "RS_Functions.h" +//#include "CAN_setup.h" +//#include "global_time.h" +#include "params.h" +#include "vector.h" +//#include "rmp_cntl_my1.h" +//#include "vhzprof.h" +//#include "adc_tools.h" +//#include "v_pwm24.h" +//#include "break_regul.h" +//#include "break_tools.h" +//#include "detect_phase.h" +//#include "mathlib.h" +//#include "project.h" +//#include "log_to_memory.h" +//#include "rotation_speed.h" +//#include "detect_overload.h" +//#include "xp_write_xpwm_time.h" +//#include "errors.h" +//#include "sync_tools.h" +//#include "optical_bus.h" +//#include "IQmathLib.h" + +#define DEF_FREQ_PWM_XTICS (3750000 / FREQ_PWM / 2) +#define DEF_PERIOD_MIN_XTICS 400 //375 ~ 100mks //315 ~ 84 mks //460//(3750000 * mks / 1000000) +#define DEF_PERIOD_MIN_BR_XTICS 165 + +#define DEF_FREQ_PWM_XTICS_MIN = 4261 +#define DEF_FREQ_PWM_XTICS_MAX = 4687 + +#define STOP_ROTOR_LIMIT 27962 //2 rpm +#define STOP_ROTOR_MIN_CURRENT 4194304 //750A //3355443 //600A + +#define K_MODUL_MAX 15770583 //13421772 //80% //10066329 //60% //5033164 //30% 15099494 ~ 90% //15435038 ~ 0.92% + //15770583 ~ 0.94% +#define MIN_Fsl_WHEN_STOPED 41943 //0.05 //67108 //0.08Hz + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + +//4464 +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +#pragma DATA_SECTION(VAR_FREQ_PWM_XTICS,".fast_vars1"); +int VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +#pragma DATA_SECTION(VAR_PERIOD_MAX_XTICS,".fast_vars1"); +int VAR_PERIOD_MAX_XTICS = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +#pragma DATA_SECTION(VAR_PERIOD_MIN_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_XTICS = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +#pragma DATA_SECTION(VAR_PERIOD_MIN_BR_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_BR_XTICS = DEF_PERIOD_MIN_BR_XTICS;// + +#pragma DATA_SECTION(freq1,".fast_vars1"); +_iq freq1; + +#pragma DATA_SECTION(k1,".fast_vars1"); +_iq k1 = 0; + +RMP_MY1 rmp_freq = RMP_MY1_DEFAULTS; +//VHZPROF vhz1 = VHZPROF_DEFAULTS; + +// WINDING a; +// FLAG f; + +#define COUNT_SAVE_LOG_OFF 100 //������� ������ ��� ����������� ����� ��������� +#define COUNT_START_IMP 2 + +int i = 0; +/*void InitPWM() +{ + WriteMemory(ADR_PWM_MODE_0, 0x0000); //�������� � �������� ��������� ��� TMS +}*/ + +static void write_swgen_pwm_times(); +void write_swgen_pwm_times_split_eages(unsigned int mode_reload); +void fix_pwm_freq_synchro_ain(); +void detect_level_interrupt(void); +void detect_current_saw_val(void); + +void InitXPWM(void) +{ + + #ifdef XPWMGEN + /* Start of PWM Generator initialization*/ + for(i = 0; i < 16; i++) // �������� + { + WriteMemory(ADR_PWM_KEY_NUMBER, i); + WriteMemory(ADR_PWM_TIMING, 0); + + } + WriteMemory(ADR_PWM_DIRECT, 0xffff); + WriteMemory(ADR_PWM_DRIVE_MODE, 0); //Choose PWM sourse PWMGenerator on Spartan 200e + WriteMemory(ADR_PWM_DEAD_TIME, 360); //Dead time in tics. 1 tic = 16.67 nsec +#ifndef _test_without_power + // OFF WDOG + WriteMemory(ADR_PWM_WDOG, 0x8005); //TODO turn on +#else + // ON WDOG + WriteMemory(ADR_PWM_WDOG, 0x0005); //TODO turn on +#endif + WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec + WriteMemory(ADR_PWM_SAW_DIRECT, 0x0555); + WriteMemory(ADR_TK_MASK_0, 0); + WriteMemory(ADR_TK_MASK_1, 0xffff); //Turn off additional 16 tk lines +#if C_PROJECT_TYPE == PROJECT_BALZAM + WriteMemory(ADR_PWM_IT_TYPE, 1); //1 interrupt per PWM period +#else + WriteMemory(ADR_PWM_IT_TYPE, 0); //interrupt on each counter twist +#endif +// WriteMemory(ADR_PWM_WDOG, 0x8008);//���������� ������ �� PWM + #endif + + #ifdef TMSPWMGEN + + WriteMemory(ADR_PWM_MODE_0, 0x0000); //�������� � �������� ��������� ��� TMS + + #endif + +/* End �f PWM Gen init */ +} + +void initPWM_Variables(void) +{ + //��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� +// xpwm_time.Tclosed_0 = 0; +// xpwm_time.Tclosed_1 = VAR_FREQ_PWM_XTICS + 1; +// xpwm_time.pwm_tics = VAR_FREQ_PWM_XTICS; +// xpwm_time.saw_direct.all = 0;//0x0555; +// xpwm_time.one_or_two_interrupts_run = PWM_TWICE_INTERRUPT_RUN; + + + init_alpha_pwm24(VAR_FREQ_PWM_XTICS); + InitVariablesSvgen(VAR_FREQ_PWM_XTICS); + init_DQ_pid(); + break_resistor_managment_init(); + + rmp_freq.RampLowLimit = _IQ(-4); //0 + rmp_freq.RampHighLimit = _IQ(4); + + rmp_freq.RampPlus = _IQ(0.00005); //_IQ(0.0002);_IQ(0.000005); + + rmp_freq.RampMinus = _IQ(-0.00005); //_IQ(-0.000005); + rmp_freq.DesiredInput = 0; + rmp_freq.Out = 0; + + a.k = 0; + a.k1 = 0; + a.k2 = 0; + + k1 = 0; + freq1 = 0; +} + +#pragma CODE_SECTION(start_PWM24,".fast_run2") +void start_PWM24(int O1, int O2) +{ + if ((O1 == 1) && (O2 == 1)) + { + start_pwm(); + } + else + { + if ((O1 == 0) && (O2 == 1)) + { + start_pwm_b(); + } + if ((O1 == 1) && (O2 == 0)) + { + start_pwm_a(); + } + } +} + +inline void init_regulators() +{ + if(f.Mode != 0) + { + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, f.Mode, 1, 1); + } +} + +#define select_working_channels(go_a, go_b) go_a = !f.Obmotka1; \ + go_b = !f.Obmotka2; + +void PWM_interrupt() +{ + static unsigned int pwm_run = 0; + static _iq Uzad1, Fzad, Uzad2; + static int count_step=0; + static int count_step_ram_off = 0; + static int count_start_impuls = 0; + static int flag_record_log = 0; + static int log_saved_to_const_mem = 0; + static int prevGo = -1; + static volatile unsigned int go_a = 0; + static volatile unsigned int go_b = 0; + + static int stop_rotor_counter = 0; + + static int prev_go_a = 1; + static int prev_go_b = 1; + + int pwm_enable_calc_main = 0; + + int start_int_xtics = 0, end_int_xtics = 0; + +// i_led1_on_off(1); + if (pwm_run == 1) + { +// stop_pwm(); +// errors.slow_stop.bit.PWM_interrupt_to_long |= 1; + return; + } + pwm_run = 1; + + +// detect_level_interrupt(); +// start_int_xtics = xpwm_time.current_period; + if (xpwm_time.where_interrupt == PWM_LOW_LEVEL_INTERRUPT + || xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + { + pwm_enable_calc_main = 1; + if (f.flag_second_PCH) { + fix_pwm_freq_synchro_ain(); + } + } + else { +// i_sync_pin_on(); + pwm_enable_calc_main = 0; + } + + +// project.cds_in[0].read_pbus(&project.cds_in[0]); //read direction +// project.read_all_pbus(); +// optical_bus_read(); + + update_rot_sensors(); + global_time.calc(&global_time); +// + inc_RS_timeout_cicle(); + inc_CAN_timeout_cicle(); + detect_I_M_overload(); + DetectI_Out_BreakFase(); + Rotor_measure(); + + if ((f.Go == 1) && (f.Stop == 0) + && (f.rotor_stopped == 0) +// && (faults.faults5.bit.rotor_stopped == 0) + /* && (f.Ready2 == 1)*/) + { + if (f.Ready2) {f.flag_turn_On_Pump = 1;} //�� ��-��� ������ + if (f.Go != prevGo) { + set_start_mem(FAST_LOG); +// clear_mem(FAST_LOG); +// count_start_impuls = 0; + count_step = 0; + count_step_ram_off = COUNT_SAVE_LOG_OFF; + + init_regulators(); + stop_rotor_counter = 0; + } else { + if (f.Mode == 0) { + rmp_freq.DesiredInput = freq1; + rmp_freq.calc(&rmp_freq); +// Fzad = rmp_freq.Out; + Fzad = freq1; +// if(k1 < 87772) +// { k1 = 87772;} + Uzad1 = k1; + Uzad2 = k1; + } + + select_working_channels(go_a, go_b); + + if (go_a == 0 && prev_go_a != go_a) { + stop_pwm_a(); + } + if (go_a == 1 && prev_go_a != go_a) { + start_pwm_a(); + } + if (go_b == 0 && prev_go_b != go_b) { + stop_pwm_b(); + } + if (go_b == 1 && prev_go_b != go_b) { + start_pwm_b(); + } + + prev_go_a = go_a; + prev_go_b = go_b; + + if (count_start_impuls < COUNT_START_IMP) { + count_start_impuls++; + + Fzad = 0; + rmp_freq.Out = 0; + +// set_start_mem(FAST_LOG); +// set_start_mem(SLOW_LOG); + } else { + + if (count_start_impuls==2) + { + if (go_a == 1 && go_b == 1) { + // ��� ���������� middle ��������� ������ ����� ����������� ������� pwm + // start_pwm(); ������ ��������� ���� ��� �� ��������� f.Go + start_pwm(); + } else if (go_a == 1) { + write_swgen_pwm_times(); //TODO: Check with new PWM + start_pwm_a(); + } else if (go_b == 1) { + write_swgen_pwm_times(); + start_pwm_b(); + } + } // end if (count_start_impuls==1) + + count_start_impuls++; + if (count_start_impuls > 2 * COUNT_START_IMP) { + count_start_impuls = 2 * COUNT_START_IMP; + } + + + } + } + flag_record_log = 1; + log_saved_to_const_mem = 0; + } else { + if (f.Discharge + && (errors.slow_stop2.bit.Break_Resistor == 0) + && (errors.plains_and_others.bit.er0_setted == 0) + && (errors.umu_errors.bit.Voltage380_BSU_Off == 0)) +// && !f.Stop) + { + start_break_pwm(); + break_resistor_managment_calc(); + } else { + //Do not stop, when come for the first time, to write to xilinx times to close keys. + //Otherwise mintime error can occure. + //Also we do not stop pwm wile break_resistor keys working + if (!count_start_impuls) { + // ��� ���������� ������ �� ������ ����� ���������� + stop_pwm(); + } + break_resistor_set_closed(); + } + if (count_step_ram_off > 0) { + count_step_ram_off--; + flag_record_log = 1; + } else { + flag_record_log = 0; + } + + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, 0, 1, 1); + + if (count_start_impuls > 0) { + count_start_impuls -= 1; + } else { + count_start_impuls = 0; + } + + Uzad1 = 87772; //0.5% + Uzad2 = 87772; + k1 = Uzad1; + svgen_pwm24_1.Gain = Uzad1; + svgen_pwm24_2.Gain = Uzad1; + svgen_dq_1.Ualpha = 0; + svgen_dq_1.Ubeta = 0; + svgen_dq_2.Ualpha = 0; + svgen_dq_2.Ubeta = 0; + a.iqk = Uzad1; + } +// a.iqk1 = Uzad1; +// a.iqk2 = Uzad2; +// a.iqk = (a.iqk1 + a.iqk2) >> 1; +// a.iqf = Fzad; + prevGo = f.Go; + + break_resistor_recup_calc(); + break_resistor_managment_update(); + + if (count_start_impuls >= (2 * COUNT_START_IMP) ) { + + if (f.Mode == 0) { +// test_calc_pwm24(Uzad1, Uzad2, Fzad); + if (pwm_enable_calc_main) { + test_calc_simple_dq_pwm24(Uzad1, Uzad2, Fzad, Fzad, K_MODUL_MAX); + } + analog_dq_calc_const(); + } else { + if ((_IQabs(rotor.iqFout) < STOP_ROTOR_LIMIT) + && (_IQabs(analog.iqIq1) > STOP_ROTOR_MIN_CURRENT)) { + if ((stop_rotor_counter >= 2520)) { + stop_rotor_counter = 2520; +// faults.faults5.bit.rotor_stopped |= 1; + f.rotor_stopped |= 1; + } else { + stop_rotor_counter += 1; + } + if (_IQabs(analog.Fsl) < MIN_Fsl_WHEN_STOPED) { +// faults.faults5.bit.rotor_stopped |= 1; + f.rotor_stopped |= 1; + } + } else { + if (stop_rotor_counter > 0) { + stop_rotor_counter -= 1; + } else { + stop_rotor_counter = 0; + } + } + + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, f.Mode, 0, pwm_enable_calc_main); + } + + } else { + // ��� ����� middle ��������� ����� ����������� ������ + if (count_start_impuls) + { +// svgen_set_time_keys_closed(&svgen_pwm24_1); +// svgen_set_time_keys_closed(&svgen_pwm24_2); + svgen_set_time_middle_keys_open(&svgen_pwm24_1); + svgen_set_time_middle_keys_open(&svgen_pwm24_2); + } + else + // � ��� �� ��� ����������� + { + svgen_set_time_keys_closed(&svgen_pwm24_1); + svgen_set_time_keys_closed(&svgen_pwm24_2); + //������� ������ ���� +// if (faults.faults5.bit.rotor_stopped == 1) { + if (f.rotor_stopped == 1) { + if (stop_rotor_counter > 0) { + stop_rotor_counter -= 1; + } else { +// faults.faults5.bit.rotor_stopped = 0; + f.rotor_stopped = 0; + stop_rotor_counter = 0; + } + } else { + stop_rotor_counter = 0; + } + } + } + + if (f.Mode) { + a.iqf = analog.iqFstator; + } else { + a.iqf = Fzad; + analog.iqFstator = Fzad; + a.iqk1 = _IQsqrt(_IQmpy(svgen_dq_1.Ualpha, svgen_dq_1.Ualpha) + _IQmpy(svgen_dq_1.Ubeta, svgen_dq_1.Ubeta)); //For output Kmodul to terminal + a.iqk2 = _IQsqrt(_IQmpy(svgen_dq_2.Ualpha, svgen_dq_2.Ualpha) + _IQmpy(svgen_dq_2.Ubeta, svgen_dq_2.Ubeta)); //end counting Uout + } + a.iqk = (a.iqk1 + a.iqk2) / 2; + +// write_swgen_pwm_times(); + + if (xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + else + { + if (f.Go == 1) + { + if (count_start_impuls == (2 * COUNT_START_IMP)) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_LOW); + } + else +// if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + } + else + { + if (count_start_impuls == (2 * COUNT_START_IMP) - 1) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_LOW); + + } + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + } + + // if (pwm_enable_calc_main) + // prev_run_calc_uf = run_calc_uf; + + } + + + + + + // logs recording +// if ((flag_record_log && !f.stop_Log) || f.Startstoplog) +// //if (f.Log1_Log2 == 1)// && f.Go == 1 && (!f.Stop)) +// //if(f.Go == 1) +// { +// test_mem_limit(FAST_LOG, !f.Ciclelog); +// count_step++; +// +// if (count_step >= 0) { +// fillADClogs(); +//// logpar.log13 = flag_record_log; +//// logpar.log14 = count_start_impuls; +//// logpar.log10 = (int16)_IQtoIQ15(analog.iqIq1_filter); +//// logpar.log11 = (int16)_IQtoIQ15(rotor.iqFrotFromOptica); +// logpar.log15 = (int16) _IQtoIQ15(analog.iqIq2); +// logpar.log16 = (int16) _IQtoIQ15(a.iqk1); +// logpar.log17 = (int16) _IQtoIQ15(analog.iqId1); +// logpar.log18 = (int16) _IQtoIQ15(analog.iqIq1); +// +//// logpar.log24 = (int16) break_result_1; +//// logpar.log25 = (int16) break_result_2; +// logpar.log27 = (int16)(_IQtoIQ15(analog.iqIbtr1_1)); +// logpar.log28 = (int16)(_IQtoIQ15(analog.iqIbtr2_1)); +// +// getFastLogs(!f.Ciclelog); +// count_step = 0; +// } +// } else { +// if (f.Stop && log_saved_to_const_mem == 0) { +// logpar.copy_log_to_const_memory = 1; +// log_saved_to_const_mem = 1; +// } +// } + +// optical_bus_write(); + +// detect_current_saw_val(); + end_int_xtics = xpwm_time.current_period; + f.PWMcounterVal = labs(start_int_xtics - end_int_xtics); + + pwm_run = 0; + + i_sync_pin_off(); +// i_led1_on_off(0); + +} + +void slow_vector_update() +{ + _iq iqKzad = 0; + freq1 = _IQ (f.fzad/F_STATOR_MAX);//f.iqFRotorSetHz; + iqKzad = _IQ(f.kzad); + k1 = zad_intensiv_q(30000, 30000, k1, iqKzad); //20000 + + +} + +//#pragma CODE_SECTION(write_swgen_pwm_times,".fast_run"); +//void write_swgen_pwm_times() +//{ +// xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0.Ti; +// xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1.Ti; +// xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0.Ti; +// xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1.Ti; +// xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0.Ti; +// xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1.Ti; +// +// xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0.Ti; +// xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1.Ti; +// xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0.Ti; +// xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1.Ti; +// xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0.Ti; +// xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1.Ti; +// +// xpwm_time.Tbr0_0 = break_result_1; +// xpwm_time.Tbr0_1 = break_result_2; +// xpwm_time.Tbr1_0 = break_result_3; +// xpwm_time.Tbr1_1 = break_result_4; +// +// xpwm_time.write_1_2_winding_break_times(&xpwm_time); +// +// +//// logpar.log29 = xpwm_time.Ta0_0; +//// logpar.log30 = xpwm_time.Ta0_1; +//// logpar.log10 = xpwm_time.Tb0_0; +//// logpar.log11 = xpwm_time.Tb0_1; +//// logpar.log12 = xpwm_time.Tc0_0; +//// logpar.log13 = xpwm_time.Tc0_1; +//// logpar.log7 = _IQtoIQ12(svgen_pwm24_1.Alpha); +//// logpar.log8 = xpwm_time.Ta0_0 - xpwm_time.Tb0_0; +//// logpar.log9 = xpwm_time.Ta0_1 - xpwm_time.Tb0_1; +//// logpar.log10 = xpwm_time.Tb0_0 - xpwm_time.Tc0_0; +//// logpar.log11 = xpwm_time.Tb0_1 - xpwm_time.Tc0_1; +//// logpar.log12 = xpwm_time.Tc0_0 - xpwm_time.Ta0_0; +//// logpar.log13 = xpwm_time.Tc0_1 - xpwm_time.Ta0_1; +// +//} + +//#pragma CODE_SECTION(write_swgen_pwm_times_split_eages,".fast_run2"); +//void write_swgen_pwm_times_split_eages(unsigned int mode_reload) +//{ +// +// xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0.Ti; +// xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1.Ti; +// xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0.Ti; +// xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1.Ti; +// xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0.Ti; +// xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1.Ti; +// +// xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0.Ti; +// xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1.Ti; +// xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0.Ti; +// xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1.Ti; +// xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0.Ti; +// xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1.Ti; +// +// xpwm_time.Tbr0_0 = break_result_1; +// xpwm_time.Tbr0_1 = break_result_2; +// xpwm_time.Tbr1_0 = break_result_3; +// xpwm_time.Tbr1_1 = break_result_4; +// +// xpwm_time.mode_reload = mode_reload; +// +// xpwm_time.write_1_2_winding_break_times_split(&xpwm_time); +//} + +#define CONST_IQ_1 16777216 //1 + +//#pragma CODE_SECTION(fix_pwm_freq_synchro_ain,".fast_run"); +//void fix_pwm_freq_synchro_ain() +//{ +//// if (f.Sync_input_or_output == SYNC_INPUT) +// { +// sync_inc_error(); +// +// if (f.disable_sync || f.sync_ready == 0) +// { +// +// +// return; +// } +// +// if (f.pwm_freq_plus_minus_zero==1) +// { +// +// +// //Increment xtics +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS + 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec +// +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// +// +// } +// +// if (f.pwm_freq_plus_minus_zero==-1) +// { +// //4464 +// //Decrement xtics +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS - 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec +// +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// +// } +// +// if (f.pwm_freq_plus_minus_zero==0) +// { +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS - 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// } +// +// } +// +// +// +//} + + +//void detect_level_interrupt(void) +//{ +// +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// xpwm_time.current_period = ReadMemory(ADR_SAW_VALUE); +// +// if (xpwm_time.current_period<xpwm_time.pwm_tics/2) +// xpwm_time.where_interrupt = PWM_LOW_LEVEL_INTERRUPT; +// +// if (xpwm_time.current_period>xpwm_time.pwm_tics/2) +// xpwm_time.where_interrupt = PWM_HIGH_LEVEL_INTERRUPT; +// +//} +// +//void detect_current_saw_val(void) +//{ +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// xpwm_time.current_period = ReadMemory(ADR_SAW_VALUE); +//} + + + + diff --git a/Inu/Src/main_matlab/old/v_pwm24.c b/Inu/Src/main_matlab/old/v_pwm24.c new file mode 100644 index 0000000..e15475e --- /dev/null +++ b/Inu/Src/main_matlab/old/v_pwm24.c @@ -0,0 +1,1642 @@ + + +#include "v_pwm24.h" +//#include "DSP281x_Device.h" // DSP281x Headerfile Include File +//#include "big_dsp_module.h" +//#include "rmp2cntl.h" // Include header for the VHZPROF object +//#include "rmp_cntl_my1.h" // Include header for the VHZPROF object +#include "pid_reg3.h" // Include header for the VHZPROF object + +#include "params.h" +// #include "PWMTools.h" +#include "adc_tools.h" +#include "v_pwm24.h" + +#include "dq_to_alphabeta_cos.h" + +#include "IQmathLib.h" +// #include "log_to_memory.h" +//Xilinx +//#include "x_parameters.h" +// #include "x_basic_types.h" +// #include "xp_project.h" +// #include "xp_cds_tk.h" +#include "svgen_dq.h" +#include "xp_write_xpwm_time.h" + +#include "def.h" + +#define DEF_FREQ_PWM_XTICS T1_PRD +#define DEF_PERIOD_MIN_XTICS (DT + 10e-6)*FTBCLK + +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +// #pragma DATA_SECTION(VAR_FREQ_PWM_XTICS,".fast_vars1"); +int VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +// #pragma DATA_SECTION(VAR_PERIOD_MAX_XTICS,".fast_vars1"); +int VAR_PERIOD_MAX_XTICS = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_XTICS = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_BR_XTICS,".fast_vars1"); +// int VAR_PERIOD_MIN_BR_XTICS = DEF_PERIOD_MIN_BR_XTICS;// + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + + +#define SQRT3 29058990 //1.7320508075688772935274463415059 +#define CONST_IQ_1 16777216 //1 +#define CONST_IQ_05 8388608 //0.5 +#define CONST_IQ_2 33554432 //2 + +#define CONST_IQ_PI6 8784530 //30 +#define CONST_IQ_PI3 17569060 // 60 +#define CONST_IQ_PI 52707178 // 180 +#define CONST_IQ_OUR1 35664138 // +#define CONST_IQ_2PI 105414357 // 360 +#define CONST_IQ_120G 35138119 // 120 grad +#define CONST_IQ_3 50331648 // 3 + +#define IQ_ALFA_SATURATION1 15099494//16441671//15099494 +#define IQ_ALFA_SATURATION2 1677721//16441671//15099494 + + +#define PI 3.1415926535897932384626433832795 + +// #pragma DATA_SECTION(iq_alfa_coef,".fast_vars"); +_iq iq_alfa_coef = 16777216; + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//#pragma DATA_SECTION(freq_array,".v_24pwm_vars"); +//int freq_array[COUNT_VAR_FREQ]; +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +//#pragma DATA_SECTION(pidCur_Kp,".v_24pwm_vars"); +//_iq pidCur_Kp = 0; + +// #pragma DATA_SECTION(pidCur_Ki,".fast_vars"); +_iq pidCur_Ki = 0; + +// #pragma DATA_SECTION(ar_tph,".fast_vars"); +_iq ar_tph[7]; + +// #pragma DATA_SECTION(winding_displacement,".fast_vars"); +_iq winding_displacement = CONST_IQ_PI6; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_1,".fast_vars");//v_24pwm_vars +//_iq iq_koef_mod_korrect_1; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_2,".v_24pwm_vars"); +//_iq iq_koef_mod_korrect_2; + +//#pragma DATA_SECTION(ar_sa_all,".v_24pwm_vars"); +// #pragma DATA_SECTION(ar_sa_all,".fast_vars"); +int ar_sa_all[3][6][4][7] = { { + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + } + }, + { + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + } + }, + { + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + } + } + }; + + +// #pragma DATA_SECTION(svgen_pwm24_1,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_1,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_1 = SVGEN_PWM24_DEFAULTS; +// #pragma DATA_SECTION(svgen_pwm24_2,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_2,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_2 = SVGEN_PWM24_DEFAULTS; + +// #pragma DATA_SECTION(svgen_dq_1,".v_24pwm_vars"); +SVGENDQ svgen_dq_1 = SVGENDQ_DEFAULTS; +// #pragma DATA_SECTION(svgen_dq_2,".v_24pwm_vars"); +SVGENDQ svgen_dq_2 = SVGENDQ_DEFAULTS; + +//#pragma DATA_SECTION(delta_t1_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t1_struct,".fast_vars"); +//PIDREG3 delta_t1_struct = PIDREG3_DEFAULTS; +//#pragma DATA_SECTION(delta_t2_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t2_struct,".fast_vars"); +//PIDREG3 delta_t2_struct = PIDREG3_DEFAULTS; + +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +int detect_sec(_iq teta); +int detect_region(_iq k, _iq teta); +// + + + + +//void init_alpha(void) +//{ +// +//// power_ain1.init(&power_ain1); +//// power_ain2.init(&power_ain2); +// +// svgen_mf1.NewEntry = 0;//_IQ(0.5); +// svgen_mf2.NewEntry = 0; +// +// svgen_mf1.SectorPointer = 0; +// svgen_mf2.SectorPointer = 0; +// +////����� �� ��������� 0 �������� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// +// +// +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_PLUS) +//// 30 ����. ����� +// svgen_mf1.Alpha = _IQ(0.5); +// svgen_mf2.Alpha = _IQ(0); +// +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_MINUS) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0.5); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_ZERO) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// #error "!!!������!!! �� ��������� SETUP_SDVIG_OBMOTKI � params_motor.h!!!" +// +// +//#endif +// +//#endif +// +// +// +//#endif +// +// +// +//} + +void InitVariablesSvgen(unsigned int freq) +{ +////////// Inserted from 'initPWM_Variables' for modulation project ////////// + + //��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� + xpwm_time.Tclosed_0 = 0; + xpwm_time.Tclosed_1 = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.Tclosed_high = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.pwm_tics = VAR_FREQ_PWM_XTICS; + // ������� ����������� ��� + // "����������� ��� ��� ���� ����=0x0 + //���� SAW_DIRECTbit = 0 �� �������� ����>������� �������� �������� ���������� ���������=0 + //�� ������ ���� + //���� SAW_DIRECTbit = 1 �� �������� ����<=������� �������� �������� ���������� ���������=0 + //�� ������ ���� + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //��� 22220 ������������� 0, �.�. ��� ������ � ������ ������ ���� ���������� ��������� ����������. + xpwm_time.saw_direct.all = 0;//0x0555; + xpwm_time.one_or_two_interrupts_run = PWM_TWICE_INTERRUPT_RUN; + + initXpwmTimeStructure(&xpwm_time); + init_alpha_pwm24(VAR_FREQ_PWM_XTICS); +///////////////////////////////////////////////////////////// + + svgen_pwm24_1.pwm_minimal_impuls_zero_minus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_100;//DEF_PERIOD_MIN_XTICS_80; + svgen_pwm24_1.pwm_minimal_impuls_zero_plus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_80; + + svgen_pwm24_2.pwm_minimal_impuls_zero_minus = svgen_pwm24_1.pwm_minimal_impuls_zero_minus; + svgen_pwm24_2.pwm_minimal_impuls_zero_plus = svgen_pwm24_1.pwm_minimal_impuls_zero_plus; + + + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_1; + + + + + svgen_dq_1.Ualpha = 0; + svgen_dq_1.Ubeta = 0; + + svgen_dq_2.Ualpha = 0; + svgen_dq_2.Ubeta = 0; + + + +} + + + + + + + + + + +// #pragma CODE_SECTION(recalc_time_pwm_minimal_2_xilinx_pwm24_l,".fast_run2"); +void recalc_time_pwm_minimal_2_xilinx_pwm24_l(SVGEN_PWM24 *pwm24, + _iq *T0, _iq *T1, + _iq timpuls_corr ) +{ + +//_iq pwm_t, timpuls_corr; + + volatile unsigned long pwm_t; + volatile unsigned int minimal_plus, minimal_minus; + + + + minimal_plus = pwm24->pwm_minimal_impuls_zero_plus; + minimal_minus = pwm24->pwm_minimal_impuls_zero_minus; + + // if (pwm24->prev_level == V_PWM24_PREV_PWM_CLOSE || pwm24->prev_level == V_PWM24_PREV_PWM_MIDDLE || pwm24->prev_level == V_PWM24_PREV_PWM_WORK_KM0) + // { + // minimal_plus *= 2; +// minimal_minus *= 2; +// } + + pwm_t = timpuls_corr / pwm24->XilinxFreq; + + // *T_imp = pwm_t; + +// if (pwm_t>(pwm24->Tclosed_high-4*minimal_minus)) +// pwm_t=(pwm24->Tclosed_high-4*minimal_minus); + + + if (timpuls_corr >= 0) + { + *T0 = pwm_t + minimal_plus; + // *T1 = 0; + *T1 = pwm24->Tclosed_high - minimal_minus; + } + else + { + *T0 = 0 + minimal_plus; + // *T1 = -pwm_t - minimal_minus; + *T1 = pwm24->Tclosed_high + pwm_t - minimal_minus; + } + + + // if (*T0 < minimal_plus) + // *T0 = minimal_plus; + + // if (*T0 > (pwm24->Tclosed_high - 2 * minimal_plus)) + // *T0 = (pwm24->Tclosed_high - 2 * minimal_plus); + + // if (*T1 < (2 * minimal_minus)) + // *T1 = 2 * minimal_minus; + + // if (*T1 > (pwm24->Tclosed_high - minimal_minus)) + // *T1 = (pwm24->Tclosed_high - minimal_minus); + +} + +static DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + +// #pragma CODE_SECTION(test_calc_dq_pwm24,".v_24pwm_run"); +void test_calc_dq_pwm24(_iq Ud, _iq Uq, _iq Ud2, _iq Uq2, _iq tetta,_iq Uzad_max, +_iq* maxUq1, _iq* maxUq2, _iq* Uq1Out, _iq* Uq2Out) +{ +// DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + //_iq maxUq = 0; + + *maxUq1 = 0; + *maxUq2 = 0; + + _iq Uzad_max_square = _IQmpy(Uzad_max, Uzad_max); + + if (tetta > CONST_IQ_2PI) + { + tetta -= CONST_IQ_2PI; + } + + if (tetta < 0) + { + tetta += CONST_IQ_2PI; + } + //��������� ����������� ��������� + *maxUq1 = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq > (*maxUq1)) { Uq = (*maxUq1);} + if (Uq < -(*maxUq1)) { Uq = -(*maxUq1);} + *Uq1Out = Uq; + + //Reculct dq to alpha-beta + dq_to_ab.Tetta = tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + svgen_dq_1.calc(&svgen_dq_1); + + //��������� ����������� ��������� + *maxUq2 = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq2 > *maxUq2) { Uq2 = *maxUq2;} + if (Uq2 < -(*maxUq2)) { Uq2 = -(*maxUq2);} + +*Uq2Out = Uq2; + + //Reculc dq to alpha-beta for 2-nd winding with winding displasement + dq_to_ab.Tetta = tetta - winding_displacement; + dq_to_ab.Ud = Ud2; + dq_to_ab.Uq = Uq2; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + svgen_dq_2.calc(&svgen_dq_2); + + //1 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +/* + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS);*/ +} + + +// #pragma CODE_SECTION(test_calc_simple_dq_pwm24,".v_24pwm_run"); +void test_calc_simple_dq_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2,_iq Uzad_max) +{ + static _iq hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM / 2); +// static _iq tetta = 0; + DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + + _iq Ud = 0; + _iq Uq = _IQsat(uz1,Uzad_max,0); + + analog.tetta += _IQmpy(fz1, hz_to_angle); + + if (analog.tetta >= CONST_IQ_2PI) + { + analog.tetta -= CONST_IQ_2PI; + } + + if (analog.tetta < 0) + { + analog.tetta += CONST_IQ_2PI; + } + + dq_to_ab.Tetta = analog.tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + +// svgen_dq_1.Ualpha = 0; +// svgen_dq_1.Ubeta = 0; + + svgen_dq_1.calc(&svgen_dq_1); + + dq_to_ab.Tetta = analog.tetta - winding_displacement; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + + svgen_dq_2.calc(&svgen_dq_2); + + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// logpar.log1 = (int16)(_IQtoIQ15(uz1)); +// logpar.log2 = (int16)(_IQtoIQ15(fz1)); +// logpar.log3 = (int16)(_IQtoIQ15(Ud)); +// logpar.log4 = (int16)(_IQtoIQ15(Uq)); +// logpar.log5 = (int16)(_IQtoIQ15(svgen_dq_1.Ualpha)); +// logpar.log6 = (int16)(_IQtoIQ15(svgen_dq_1.Ubeta)); +// logpar.log7 = (int16)(_IQtoIQ15(svgen_dq_1.Ta)); +// logpar.log8 = (int16)(_IQtoIQ15(svgen_dq_1.Tb)); +// logpar.log9 = (int16)(_IQtoIQ15(svgen_dq_1.Tc)); +// logpar.log10 = (int16)(_IQtoIQ12(analog.tetta)); +// logpar.log11 = (int16)(svgen_pwm24_1.Ta_0.Ti); +// logpar.log12 = (int16)((svgen_pwm24_1.Ta_1.Ti)); +// logpar.log13 = (int16)(svgen_pwm24_1.Tb_0.Ti); +// logpar.log14 = (int16)((svgen_pwm24_1.Tb_1.Ti)); +// logpar.log15 = (int16)(svgen_pwm24_1.Tc_0.Ti); +// logpar.log16 = (int16)((svgen_pwm24_1.Tc_1.Ti)); + + +// svgen_pwm24_1.calc(&svgen_pwm24_1); +// svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +} + +// #pragma CODE_SECTION(test_calc_pwm24,".v_24pwm_run"); +void test_calc_pwm24(_iq uz1, _iq uz2, _iq fz1) +{ + //static int i =0; + svgen_pwm24_1.Freq = fz1; + svgen_pwm24_2.Freq = fz1; + + svgen_pwm24_1.Gain = uz1;//_IQmpy(uz1,iq_koef_mod_korrect_1); + svgen_pwm24_2.Gain = uz2;//_IQmpy(uz2,iq_koef_mod_korrect_2); + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc(&svgen_pwm24_1); + svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +// if(((svgen_pwm24_2.Ta_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_1.Ti <= (VAR_FREQ_PWM_XTICS)))) +// { +// asm(" NOP "); +// } +// +// if( ((svgen_pwm24_2.Ta_0.Ti > 0) && (svgen_pwm24_2.Ta_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > 0) && (svgen_pwm24_2.Ta_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > 0) && (svgen_pwm24_2.Tb_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > 0) && (svgen_pwm24_2.Tb_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > 0) && (svgen_pwm24_2.Tc_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > 0) && (svgen_pwm24_2.Tc_1.Ti < (VAR_PERIOD_MIN_XTICS)))) +// { +// asm(" NOP "); +// } +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc(SVGEN_PWM24 *vt) +{ + _iq StepAngle; + + StepAngle = _IQmpy(vt->Freq,vt->FreqMax); + + vt->Alpha = vt->Alpha + StepAngle; + + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + + +// #pragma CODE_SECTION(calc_time_one_tk,".v_24pwm_run"); +void calc_time_one_tk(_iq gain, _iq teta, _iq delta_U, + _iq Ia, _iq Ib, _iq Ic, + unsigned int number, + SVGEN_PWM24_TIME *tk0, + SVGEN_PWM24_TIME *tk1, + SVGEN_PWM24_TIME *tk2, + SVGEN_PWM24_TIME *tk3, + SVGEN_PWM24_TIME *tk4, + SVGEN_PWM24_TIME *tk5) +{ + _iq iq_t0 = 0, iq_t1 = 0, iq_t2 = 0, iq_t3 = 0, iq_t4 = 0, iq_t5 = 0; + _iq t_pos = 0, t_neg = 0; + _iq delta_ttt; + _iq teta60; + + int sector, region; + int cur_sign, i, ki; + int updown_tk0; + int updown_tk1; + + volatile _iq t_tk0, t_tk1; + + updown_tk0 = 1; + updown_tk1 = 0; + + sector = detect_sec(teta); // + teta60 = teta - _IQmpy(_IQ(sector - 1),CONST_IQ_PI3); // + + if ((sector == 2) || (sector == 4) || (sector == 6)) + { + teta60 = CONST_IQ_PI3 - teta60; + } + + region = detect_region(gain, teta60); // + + calc_t_abc(gain, teta60, region, &iq_t0, &iq_t1, &iq_t2, &iq_t3, &iq_t4, &iq_t5); + + + delta_ttt = 0; //calc_delta_t(delta_U,number,region); + //delta_ttt = 0; + + //if (number == 1) + //{ + //logpar.log1 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log2 = (int16)(_IQtoIQ15(delta_ttt)); + //} + //else + //{ + //logpar.log3 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log4 = (int16)(_IQtoIQ15(delta_ttt)); + //} + + calc_arr_tph(sector, region, iq_t0, iq_t1, iq_t2, iq_t3, iq_t4, iq_t5, delta_ttt,number, Ia, Ib, Ic); + + for (ki = 0; ki < 3; ki++) + { + t_pos = 0; + t_neg = 0; + + for (i = 0; i < 7; i++) + { + cur_sign = ar_sa_all[ki][sector - 1][region - 1][i]; + + if (cur_sign > 0) + { + t_pos += ar_tph[i]; + } + + if (cur_sign < 0) + { + t_neg += ar_tph[i]; + } + } + + t_pos = t_pos << 1; + + t_neg = t_neg << 1; + + if (t_neg == 0) + { + t_tk0 = 0; + } + else + { + t_tk0 = t_neg; + } + + if (t_pos == 0) + { + t_tk1 = CONST_IQ_1; + } + else + { + t_tk1 = CONST_IQ_1 - t_pos; + } + + switch (ki) + { + case 0: + tk0->up_or_down = updown_tk0; + tk0->Ti = t_tk0; + + tk1->up_or_down = updown_tk1; + tk1->Ti = t_tk1; + + break; + + case 1: + tk2->up_or_down = updown_tk0; + tk2->Ti = t_tk0; + + tk3->up_or_down = updown_tk1; + tk3->Ti = t_tk1; + + break; + + case 2: + tk4->up_or_down = updown_tk0; + tk4->Ti = t_tk0; + + tk5->up_or_down = updown_tk1; + tk5->Ti = t_tk1; + + break; + + default: break; + } + } +} + + + + +// #pragma CODE_SECTION(detect_region,".v_24pwm_run"); +int detect_region(_iq k, _iq teta) +{ + volatile _iq x,y; + volatile int reg=0; + + x = _IQmpy(k,_IQcos(teta)); + y = _IQmpy(k,_IQsin(teta)); + + if (y>=CONST_IQ_05) reg=4; + else if (y < (CONST_IQ_1 - _IQmpy(x,SQRT3))) reg = 1; + else if (y < (_IQmpy(x,SQRT3) - CONST_IQ_1)) reg = 2; + else reg = 3; + + return reg; +} + + + + +// #pragma CODE_SECTION(detect_sec,".v_24pwm_run"); +int detect_sec(_iq teta) +{ + volatile _iq sector; + volatile int sectorint; + + sector = _IQdiv(teta,CONST_IQ_PI3); + sectorint = (sector >> 24) + 1; + + if (sectorint > 6) sectorint-=6; + + return sectorint; +} + + +#define nSIN_t(k,t) _IQmpy(k,_IQsin(t)) + +#define nSIN_p3pt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3+t)) + +#define nSIN_p3mt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3-t)) + +#define nSIN_tmp3(k,t) _IQmpy(k,_IQsin(t-CONST_IQ_PI3)) + +//k - (Uzad) +//teta - +//region - +/* + * iq_tt0 - time of vectors op, oo, on + * iq_tt1 - time of vectors ap, an + * iq_tt2 - time of vectors bp, bn + * iq_tt3 - time of vector c + * iq_tt4 - time of vector a + * iq_tt5 - time of vector b + */ +// #pragma CODE_SECTION(calc_t_abc,".v_24pwm_run"); +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5) +{ + switch(region) + { + case 1 : + *iq_tt0 = CONST_IQ_05 - nSIN_p3pt(k,teta); + *iq_tt1 = nSIN_p3mt(k,teta); + *iq_tt2 = nSIN_t(k,teta); + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 2 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt2 = 0; + *iq_tt3 = nSIN_t(k,teta); + *iq_tt4 = nSIN_p3mt(k,teta) - CONST_IQ_05; + *iq_tt5 = 0; + break; + + case 3 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_05 - nSIN_t(k,teta); + *iq_tt2 = CONST_IQ_05 - nSIN_p3mt(k,teta); + *iq_tt3 = nSIN_p3pt(k,teta) - CONST_IQ_05; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 4 : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt3 = nSIN_p3mt(k,teta); + *iq_tt4 = 0; + *iq_tt5 = nSIN_t(k,teta) - CONST_IQ_05; + break; + + default : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = 0; + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + } + + return; +} + +//sector +//region +//iq_ttt0 - iq_ttt5 - times from calc_t_abs +//delta_t - +//number_sv - +//iqIa, iqIb, iqIc +// #pragma CODE_SECTION(calc_arr_tph, ".v_24pwm_run"); +void calc_arr_tph(int sector,int region, _iq iq_ttt0, _iq iq_ttt1, _iq iq_ttt2, _iq iq_ttt3, _iq iq_ttt4, + _iq iq_ttt5, _iq delta_t, unsigned int number_sv, + _iq iqIa, _iq iqIb, _iq iqIc) +{ + _iq iq_var1 = 0; + _iq iqIx, iqIy, iqIz; + _iq iq_alfa_1_p = CONST_IQ_05, iq_alfa_1_n = CONST_IQ_05, iq_alfa_2_n = CONST_IQ_05, iq_alfa_2_p = CONST_IQ_05; + _iq iq_alfa = 0; +// _iq iqIa, iqIb, iqIc; + _iq iq_mpy1 = 0; + _iq iq_mpy3 = 0; + _iq summ = 0; + + + switch (sector) + { + case 1: + iqIx = iqIc; + iqIy = iqIa; + iqIz = iqIb; + + break; + case 2: + + iqIx = iqIb; + iqIy = iqIa; + iqIz = iqIc; + + break; + case 3: + + iqIx = iqIb; + iqIy = iqIc; + iqIz = iqIa; + + break; + case 4: + + iqIx = iqIa; + iqIy = iqIc; + iqIz = iqIb; + + break; + case 5: + + iqIx = iqIa; + iqIy = iqIb; + iqIz = iqIc; + + break; + case 6: + + iqIx = iqIc; + iqIy = iqIb; + iqIz = iqIa; + + break; + default: + + iqIx = 0; + iqIy = 0; + iqIz = 0; + + break; + } + + if (region == 1) + { +// if (delta_t != 0) //��������� ���������� //��������� ����������� +// { +// iq_alfa = _IQsat((CONST_IQ_05 - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + + //if (delta_t < 0) + //{ + //iq_alfa = IQ_ALFA_SATURATION1; + //} + //else + //{ + //iq_alfa = IQ_ALFA_SATURATION2; + //} +// } +// else + { + iq_alfa = CONST_IQ_05; + } + } + else + { + iq_mpy1 = _IQmpy(_IQabs(iqIx),iq_ttt1)+_IQmpy(_IQabs(iqIy),iq_ttt2); + iq_mpy3 = _IQmpy(iqIz,iq_ttt3); + + summ = _IQdiv((iq_mpy3),(iq_mpy1)); + + //iq_alfa = _IQsat((_IQmpy(CONST_IQ_05,(CONST_IQ_1 + summ)) - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + iq_alfa = CONST_IQ_05; //test + } + + + if (iqIx >= 0) + { + iq_alfa_1_p = iq_alfa; + iq_alfa_1_n = CONST_IQ_1 - iq_alfa; + } + else + { + iq_alfa_1_p = CONST_IQ_1 - iq_alfa; + iq_alfa_1_n = iq_alfa; + } + + if (iqIy >= 0) + { + iq_alfa_2_p = CONST_IQ_1 - iq_alfa; + iq_alfa_2_n = iq_alfa; + } + else + { + iq_alfa_2_p = iq_alfa; + iq_alfa_2_n = CONST_IQ_1 - iq_alfa; + } + + + //if (number_sv == 2) + //{ + //logpar.log1 = (int16)(sector); + //logpar.log2 = (int16)(region); + //logpar.log3 = (int16)(_IQtoIQ15(iq_alfa)); + //logpar.log4 = (int16)(_IQtoIQ15(iq_alfa_1_p)); + //logpar.log5 = (int16)(_IQtoIQ15(iq_alfa_2_p)); + //logpar.log6 = (int16)(_IQtoIQ13(summ)); + //logpar.log3 = (int16)(_IQtoIQ14(iq_ttt0)); + //logpar.log4 = (int16)(_IQtoIQ14(iq_ttt1)); + //logpar.log5 = (int16)(_IQtoIQ14(iq_ttt2)); + //logpar.log6 = (int16)(_IQtoIQ14(iq_ttt3)); + //logpar.log7 = (int16)(_IQtoIQ14(iq_ttt4)); + //logpar.log8 = (int16)(_IQtoIQ14(iq_ttt5)); + //logpar.log10 = (int16)(_IQtoIQ15(delta_t1_struct.Up)); + //logpar.log11 = (int16)(_IQtoIQ15(delta_t1_struct.Ui)); + //logpar.log12 = (int16)(_IQtoIQ15(delta_t1_struct.Ud)); + //logpar.log13 = (int16)(_IQtoIQ15(iqIx)); + //logpar.log14 = (int16)(_IQtoIQ15(iqIy)); + //logpar.log15 = (int16)(_IQtoIQ15(iqIz)); + + //logpar.log12 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_p,iq_ttt2))); + //logpar.log13 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_n,iq_ttt2))); + //logpar.log14 = (int16)(_IQtoIQ15(delta_t)); + //} + //else + //logpar.log15 = (int16)(_IQtoIQ15(delta_t)); + +// if (region == 1) +// { +// if (f.Rele3 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } +// else +// { +// if (f.Down50 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } + + switch (region) + { + case 1: + iq_var1 = _IQdiv(iq_ttt0,CONST_IQ_3); + + ar_tph[0] = iq_var1; + ar_tph[1] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[2] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[3] = iq_var1; + ar_tph[4] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[5] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[6] = iq_var1; + break; + + case 2: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = iq_ttt4; + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 3: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 4: + ar_tph[0] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[1] = iq_ttt3; + ar_tph[2] = iq_ttt5; + ar_tph[3] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + default : + break; + } + + +} + +/* + // Function is commented because of in project 222220 should not be large voltage diviation +// #pragma CODE_SECTION(calc_delta_t,".v_24pwm_run"); +_iq calc_delta_t(_iq delta_1, unsigned int number,int region) +{ + if(_IQabs(delta_1) > MAX_LEVEL_DELTA_T) + { + // ������ ���������� ConvErrors.m2.bit.Razbalans |= 1; + return 0; + } + + if (number == 1) + { + delta_t1_struct.Fdb = delta_1; + delta_t1_struct.calc(&delta_t1_struct); + + if (_IQabs(delta_t1_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t1_struct.Out; + } + else + { + delta_t2_struct.Fdb = delta_1; + delta_t2_struct.calc(&delta_t2_struct); + + if (_IQabs(delta_t2_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t2_struct.Out; + } +} + +*/ +//#pragma CODE_SECTION(set_predel_dshim24,".fast_run2"); + +// #pragma CODE_SECTION(set_predel_dshim24_simple0,".v_24pwm_run"); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + if (T->Ti < dmin/2) + T->Ti = 0; + else + T->Ti = dmin; + + } else if (T->Ti >= (dmax - dmin)) { + T->Ti = (dmax - dmin); + } +} +// #pragma CODE_SECTION(set_predel_dshim24_simple1,".v_24pwm_run"); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti >= (dmax - dmin)) + { + if (T->Ti >= (dmax - dmin/2)) + T->Ti = dmax; + else + T->Ti = dmax-dmin; +// T->Ti = dmax; + } else if (T->Ti <= dmin) { + T->Ti = dmin; + } +} + + +// #pragma CODE_SECTION(set_predel_dshim24,".v_24pwm_run"); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + //static unsigned int counter_pass = 0; + //static unsigned int summ = 0; + //int16 dshim24 = 0; + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; + + T->impuls_lenght_min = T->impuls_lenght_min + T->Ti; + T->counter_pass_min++; + + if (T->counter_pass_min <= 3) + { + if (T->impuls_lenght_min <= dmin) + { + T->Ti = 0; + } + else + { +// T->Ti = dmin; //T->impuls_lenght_min; +// T->impuls_lenght_min -= dmin;// = 0; + T->Ti = T->impuls_lenght_min; + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; +// if (T->impuls_lenght_min < 0) { +// T->counter_pass_min = 0; +// T->impuls_lenght_min = 0; +// } else { +// T->counter_pass_min -= 1; +// } + } + } + else + { + T->counter_pass_min = 1; + T->impuls_lenght_min = T->Ti; + T->Ti = 0; + } + } + else + { + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; + +// if (T->Ti > (dmax - dmin)) +// { +// dshim = dmax; +// } +// else +// { +// dshim = T->Ti; +// } + + if (T->Ti >= (dmax - dmin)) + { + T->impuls_lenght_max = T->impuls_lenght_max + (dmax - T->Ti - 1); + T->counter_pass_max++; + + if (T->counter_pass_max <= 3) + { + if (T->impuls_lenght_max <= dmin) + { + T->Ti = dmax; + } + else + { +// T->Ti = dmax - dmin; //T->impuls_lenght_max; +// T->impuls_lenght_max -= dmin;// = 0; + T->Ti = dmax - T->impuls_lenght_max; + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; +// if (T->impuls_lenght_max < 0) { +// T->impuls_lenght_max = 0; +// T->counter_pass_max = 0; +// } else { +// T->counter_pass_max -= 1; +// } + } + } + else + { + T->counter_pass_max = 1; + T->impuls_lenght_max = dmax - T->Ti; + T->Ti = dmax; + } + } + else + { + T->counter_pass_max = 0; + T->impuls_lenght_max = 0; + } + } + + //return dshim24; +} + + + +void init_alpha_pwm24(int xFreq) +{ + xFreq = xFreq + 1; + + svgen_pwm24_1.number_svgen = 1; + svgen_pwm24_2.number_svgen = 2; + + //pidCur_Kp = _IQ(PID_KP_DELTA_KOMP_I); + //pidCur_Ki = _IQ(PID_KI_DELTA_KOMP_I); + +// svgen_pwm24_1.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_1.saw_direct.all = xpwm_time.saw_direct.all & 0x3f; + svgen_pwm24_1.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_1.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_high; + +// svgen_pwm24_2.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_2.saw_direct.all = (xpwm_time.saw_direct.all >> 6) & 0x3f; + svgen_pwm24_2.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_2.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_high; + + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2); + + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; + + // 30 + svgen_pwm24_1.Alpha = 0; //winding_displacement; + svgen_pwm24_2.Alpha = -winding_displacement; + + svgen_pwm24_1.delta_t = 0; + svgen_pwm24_2.delta_t = 0; +} + +/* +void init_freq_array(void) +{ + unsigned int i = 0; + //unsigned int j = 0; + int var1 = 0; + + var1 = 32767 / (FREQ_PWM_MAX - FREQ_PWM_MIN); + + for (i = 0; i < COUNT_VAR_FREQ; i++) + { + //j = rand() / 1023; + //freq_array[i] = array_optim_freq[j]; + //do + freq_array[i] = FREQ_PWM_MIN + (rand() / var1); + //while ((freq_array[i] < 945) && (freq_array[i] > 930)); + } + + //freq_array[0] = 991; + //freq_array[1] = 1430; +} +*/ + + +//#pragma CODE_SECTION(calc_freq_pwm,".v_24pwm_run"); +//#pragma CODE_SECTION(calc_freq_pwm,".fast_run"); +/*void calc_freq_pwm() +{ + static int prev_freq_pwm = 0; + static float pwm_period = 0; + static float var0 = 0; + //static int line = 0; + //static int i = 0; + static unsigned int proc_ticks = 1; + int var1 = 0; + //static int i = 0; + + if ((f.flag_change_pwm_freq == 1) && (f.flag_random_freq == 1)) + { + if (proc_ticks >= 1) + { + proc_ticks = 0; + + + if (line == 0) + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ + 1; + if (VAR_FREQ_PWM_HZ > FREQ_PWM_MAX) + { + VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + line = 1; + } + } + else + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ - 1; + if (VAR_FREQ_PWM_HZ < FREQ_PWM) + { + VAR_FREQ_PWM_HZ = FREQ_PWM; + line = 0; + } + } + + + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //VAR_FREQ_PWM_HZ = freq_array[i]; + //i_led2_on_off(1); + + var1 = 32767 / (freq_pwm_max_hz - freq_pwm_min_hz); + VAR_FREQ_PWM_HZ = freq_pwm_min_hz + (rand() / var1); + + //i_led2_on_off(0); + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (VAR_FREQ_PWM_HZ > freq_pwm_max_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_max_hz; + } + else + { + if (VAR_FREQ_PWM_HZ < freq_pwm_min_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_min_hz; + } + } + //i++; + + //if (i >= COUNT_VAR_FREQ) + //{ + //i = 0; + //} + + } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //if (VAR_FREQ_PWM_HZ == FREQ_PWM_MIN) + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MIN; + //} + + //if (f.Rele1 == 1) + //{ + //if (i == 0) + //{ + //VAR_FREQ_PWM_HZ = 1192;; + //i = 1; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = 792; + //} + //} + //else + //{ + //i = 0; + //VAR_FREQ_PWM_HZ = 1192; + //} + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + } + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM; + //} + + + if (prev_freq_pwm != VAR_FREQ_PWM_HZ) + { + prev_freq_pwm = VAR_FREQ_PWM_HZ; + FREQ_MAX = _IQ(2.0*PI*F_STATOR_MAX/VAR_FREQ_PWM_HZ); + + var0 = (float)VAR_FREQ_PWM_HZ; + //pwm_period = ((float64)HSPCLK) / ((float64)VAR_FREQ_PWM_HZ); + + pwm_period = HSPCLK / var0; + + pwm_period = pwm_period / 2.0; + + FREQ_PWM_XTICS = ((int) pwm_period) >> 3; + + XILINX_FREQ = 16777216/(FREQ_PWM_XTICS + 1); + + FLAG_CHANGE_FREQ_PWM = 1; + } + + proc_ticks++; +} +*/ + +void change_freq_pwm(_iq xFreq) { + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/3750000 / xFreq / 2 /2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/ 3750000 / xFreq / 2 /2); + + xFreq += 1; + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; +} + +// #pragma CODE_SECTION(test_calc_pwm24_dq,".v_24pwm_run"); +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta) +{ + svgen_pwm24_1.Freq = 0; + svgen_pwm24_2.Freq = 0; + + svgen_pwm24_1.Gain = U_zad1; + svgen_pwm24_2.Gain = U_zad2; + + svgen_pwm24_1.Alpha = teta; + svgen_pwm24_2.Alpha = teta - winding_displacement; + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc_dq(&svgen_pwm24_1); + svgen_pwm24_2.calc_dq(&svgen_pwm24_2); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt) +{ + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Ta_1.Ti = 0; + + vt->Tb_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tb_1.Ti = 0; + + vt->Tc_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tc_1.Ti = 0; +} + +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = 0; + vt->Ta_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tb_0.Ti = 0; + vt->Tb_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tc_0.Ti = 0; + vt->Tc_1.Ti = VAR_FREQ_PWM_XTICS + 1; +} diff --git a/Inu/Src/main_matlab/old/v_pwm24.h b/Inu/Src/main_matlab/old/v_pwm24.h new file mode 100644 index 0000000..da8f527 --- /dev/null +++ b/Inu/Src/main_matlab/old/v_pwm24.h @@ -0,0 +1,190 @@ +#ifndef _V_PWM24_H +#define _V_PWM24_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "IQmathLib.h" +// #include "DSP281x_Device.h" +#include "word_structurs.h" +#include "svgen_dq.h" + +//#define COUNT_VAR_FREQ 400 + +//#define IQ_KP_DELTA_T 134217728//0.004 +//#define IQ_KP_DELTA_COMP_I 134217728//0.004 + +//#define PID_KP_DELTA_T 0.5//1//20//2//0.001//11.18 //0.036 //0.018 //0.18 //0.095 // PID Kp +//#define PID_KI_DELTA_T 0.000005//0.01 //0.08 // 0.008 // PID Ki +//#define PID_KD_DELTA_T 2//5//0.01 //0.08 // 0.008 // PID Ki +//#define PID_KC_DELTA_T 0.005 //0.09 // PID Kc + +//#define PID_KP_DELTA_KOMP_I 1//0.12//0.06//5//10 +//#define PID_KI_DELTA_KOMP_I 0.005//0//0.005//0.01 +//#define PID_KC_DELTA_KOMP_I 0.005//0//0.005//0.01 +//#define PID_KD_DELTA_KOMP_I 0//0//0.005//0.01 +//#define PID_KD_DELTA_T 0.0000 //*100 // PID Kd + + + +//#define DELTA_T_MAX 1258291//15099494//0.9//8388608//0.5//13421772//0.8 //8388608// 0.5//13421772 // 0.8 +//#define DELTA_T_MIN -1258291//-15099494//0.9//-8388608//-0.5//-13421772//0.8 //-8388608// -0.5//-13421772 // -0.8 + +//#define DELTA_KOMP_I_MAX 1258291//6//1677721//0.1//3355443//0.2//1677721//200 A//4194304// 500 A +//#define DELTA_KOMP_I_MIN -1258291//-6//-1677721//-0.1//-3355443//-0.2//-1677721//-200 A//-4194304// -500 A + + +//#define INSENSITIVE_LEVEL_DELTA_T 83886 //10 V//167772// 20V //335544//40 V//83886 //10 V//335544//40 V//58720//7V//167772// 20V //83886 //10 V +//#define MAX_LEVEL_DELTA_T 1258291//150V//1677721 //200v//2516582//300 V//4194304//500 V//2516582 // 838860 //100 V + + +typedef struct { _iq Ti; // Output: reference phase-a switching function (pu) + int up_or_down; // Output: reference phase-b switching function (pu) + int impuls_lenght_max; + int impuls_lenght_min; + int counter_pass_max; + int counter_pass_min; + } SVGEN_PWM24_TIME; + + +typedef struct { + _iq Gain; // Input: reference gain voltage (pu) + //_iq Offset; // Input: reference offset voltage (pu) + _iq Freq; // Input: reference frequency (pu) + _iq FreqMax; // Parameter: Maximum step angle = 6*base_freq*T (pu) + _iq Alpha; // History: Sector angle (pu) + + _iq delta_U; + _iq delta_t; + int XilinxFreq; // Xilinx freq in TIC + + unsigned int pwm_minimal_impuls_zero_minus; + unsigned int pwm_minimal_impuls_zero_plus; + + WORD_UINT2BITS_STRUCT saw_direct; + + int prev_level; // ���������� ��������� ����, ��� �������� �� middle ��� close � ������� + unsigned int Tclosed_high; + unsigned int Tclosed_saw_direct_0; + unsigned int Tclosed_saw_direct_1; + + _iq Ia; + _iq Ib; + _iq Ic; + unsigned int number_svgen; + SVGEN_PWM24_TIME Ta_0; // Output: reference phase-a switching function (pu) + SVGEN_PWM24_TIME Ta_1; // Output: reference phase-a switching function (pu) + SVGEN_PWM24_TIME Tb_0; // Output: reference phase-b switching function (pu) + SVGEN_PWM24_TIME Tb_1; // Output: reference phase-b switching function (pu) + SVGEN_PWM24_TIME Tc_0; // Output: reference phase-c switching function (pu) + SVGEN_PWM24_TIME Tc_1; // Output: reference phase-c switching function (pu) + void (*calc)(); // Pointer to calculation function + void (*calc_dq)(); // Pointer to calculation function which don`t calculate angle from freq +} SVGEN_PWM24; + +typedef SVGEN_PWM24 *SVGEN_PWM24_handle; + + +#define SVGEN_PWM24_TIME_DEFAULTS { 0,0,0,0 } + + +#define SVGEN_PWM24_DEFAULTS { 0,0,0,0,0,0,0,0,0, \ + {0}, 0,0,0,0,0,0,0,0,\ + SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS, \ + SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS, \ + (void (*)(unsigned int))svgen_pwm24_calc, (void (*)(unsigned int))svgen_pwm24_calc_dq } + +// extern int ar_sa_a[3][4][7]; + +extern SVGEN_PWM24 svgen_pwm24_1; +extern SVGEN_PWM24 svgen_pwm24_2; + +extern SVGENDQ svgen_dq_1; +extern SVGENDQ svgen_dq_2; + +// extern _iq pidCur_Kp; +// extern _iq pidCur_Ki; + +// extern _iq iq_alfa_coef; + +// extern _iq iq_koef_mod_korrect_1; +// extern _iq iq_koef_mod_korrect_2; + +//extern int freq_array[COUNT_VAR_FREQ]; + +void svgen_pwm24_calc(SVGEN_PWM24 *vt); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt); + +void init_alpha_pwm24(int xFreq); +void test_calc_pwm24(_iq uz1, _iq uz2, _iq fz1/*, _iq fz2, int revers*/); +void calc_arr_tph(int sector,int region, _iq iq_ttt0, _iq iq_ttt1, + _iq iq_ttt2, _iq iq_ttt3, _iq iq_ttt4, _iq iq_ttt5, _iq delta_t, unsigned int number_sv, + _iq iqIa, _iq iqIb, _iq iqIc); +_iq calc_delta_t(_iq delta_1, unsigned int number,int region); + +//void change_freq_pwm(_iq FreqMax, int freq_pwm_xtics, _iq XilinxFreq); +void change_freq_pwm(_iq freq_pwm_xtics); + +//void calc_freq_pwm(); + +void calc_time_one_tk(_iq gain, _iq teta, _iq delta_U, + _iq Ia, _iq Ib, _iq Ic, + unsigned int number, + SVGEN_PWM24_TIME *tk0, + SVGEN_PWM24_TIME *tk1, + SVGEN_PWM24_TIME *tk2, + SVGEN_PWM24_TIME *tk3, + SVGEN_PWM24_TIME *tk4, + SVGEN_PWM24_TIME *tk5); + +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta); + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt); +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt); + + + +void InitVariablesSvgen(unsigned int freq); +//void init_alpha(void); +_iq correct_balance_uzpt_pwm24(_iq Tinput, _iq Kplus); +void recalc_time_pwm_minimal_2_xilinx_pwm24_l(SVGEN_PWM24 *pwm24, + _iq *T0, _iq *T1, + _iq timpuls_corr ); +void test_calc_simple_dq_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2, _iq Uzad_max); +void test_calc_dq_pwm24(_iq Ud, _iq Uq, _iq Ud2, _iq Uq2, _iq tetta,_iq Uzad_max, _iq* maxUq1, _iq* maxUq2, _iq* Uq1Out, _iq* Uq2Out); +//void test_calc_simple_uf_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2,_iq Uzad_max); + +//void init_freq_array(void); + +typedef union { + unsigned int all; + struct { + unsigned int k0; + unsigned int k1; + unsigned int k2; + unsigned int k3; + unsigned int k4; + unsigned int k5; + unsigned int k6; + unsigned int k7; + unsigned int k8; + unsigned int k9; + unsigned int k10; + unsigned int k11; + unsigned int k12; + unsigned int k13; + unsigned int k14; + unsigned int k15; + }bit; +} UP_OR_DOWN; + +extern UP_OR_DOWN up_down; +extern _iq winding_displacement; + + +#ifdef __cplusplus + } +#endif + +#endif /* _V_PWM24_H */ diff --git a/Inu/Src/main_matlab/old/xp_write_xpwm_time.h b/Inu/Src/main_matlab/old/xp_write_xpwm_time.h new file mode 100644 index 0000000..5e1159d --- /dev/null +++ b/Inu/Src/main_matlab/old/xp_write_xpwm_time.h @@ -0,0 +1,183 @@ +/* + * xp_write_xpwm_time.h + * + * Created on: 03 ���. 2018 �. + * Author: stud + */ + +#ifndef XP_WRITE_TIME_H_ +#define XP_WRITE_TIME_H_ + + +#include "word_structurs.h" + + + +#define PWM_ERROR_LEVEL_INTERRUPT 0 // �� ���������� ��� ��, ������!!! +#define PWM_LOW_LEVEL_INTERRUPT 1 // �� ����� ���� +#define PWM_HIGH_LEVEL_INTERRUPT 2 // �� ������ ���� + + +#define PWM_MODE_RELOAD_FORCE 0 // ��������� ��� �������� +#define PWM_MODE_RELOAD_LEVEL_LOW 1 // ��������� �������� ��� ���� ����, ��� saw_direct=1 +#define PWM_MODE_RELOAD_LEVEL_HIGH 2 // ��������� �������� ��� ����� ����, ��� saw_direct=0 + + + + + +#define PWM_KEY_NUMBER_A1_PLUS 0 +#define PWM_KEY_NUMBER_A1_MINUS 1 +#define PWM_KEY_NUMBER_B1_PLUS 2 +#define PWM_KEY_NUMBER_B1_MINUS 3 +#define PWM_KEY_NUMBER_C1_PLUS 4 +#define PWM_KEY_NUMBER_C1_MINUS 5 + +#define PWM_KEY_NUMBER_A2_PLUS 6 +#define PWM_KEY_NUMBER_A2_MINUS 7 +#define PWM_KEY_NUMBER_B2_PLUS 8 +#define PWM_KEY_NUMBER_B2_MINUS 9 +#define PWM_KEY_NUMBER_C2_PLUS 10 +#define PWM_KEY_NUMBER_C2_MINUS 11 + +#define PWM_KEY_NUMBER_BR1_PLUS 12 +#define PWM_KEY_NUMBER_BR1_MINUS 13 + +#define PWM_KEY_NUMBER_BR2_PLUS 14 +#define PWM_KEY_NUMBER_BR2_MINUS 15 + +////////////////////////////////////////////////////////////////////// +#define ENABLE_PWM_BREAK_ALL 0x0fff +#define ENABLE_PWM_BREAK_1 0xcfff +#define ENABLE_PWM_BREAK_2 0x3fff + +#define ENABLE_PWM_1 0xffc0 +#define ENABLE_PWM_2 0xf03f +#define ENABLE_PWM_1_2 0xf000 + +#define ENABLE_PWM_ALL 0x0000 + +// +#define DISABLE_PWM_BREAK_ALL 0xf000 +#define DISABLE_PWM_BREAK_1 0x3000 +#define DISABLE_PWM_BREAK_2 0xc000 + +#define DISABLE_PWM_1 0x003f +#define DISABLE_PWM_2 0x0fc0 +#define DISABLE_PWM_1_2 0x0fff + +#define DISABLE_PWM_ALL 0xffff + +/// +#define DISABLE_PWM_A1 0x0003 +#define DISABLE_PWM_B1 0x000c +#define DISABLE_PWM_C1 0x0030 + +#define DISABLE_PWM_A2 0x00c0 +#define DISABLE_PWM_B2 0x0300 +#define DISABLE_PWM_C2 0x0c00 +// +////////////////////////////////////////////////////////////////////// +/* + * PWM - Start Stop + * (15) - Soft start-stop m0de 1- soft mode enabled, 0 -disabled. ���� ������ ����� ������ ���������, �� ��� ������ + * ������� ����(0)-������� = 0, ������ ����������� � ������ �������� ���� (����� ������ ������� ���������)., ���� ���- �����. + * ���������� ����������� �����- ��� soft mode ����� ����������� � ������ ��������. + * �����! ��� ������������ ��������� ���� ������ ������� ������ ���� ����� ����. + * (0) - 1 -start, 0 - stop + */ +#define PWM_START_SOFT 0x8001 +#define PWM_START_HARD 0x0001 + +#define PWM_STOP_SOFT 0x8000 +#define PWM_STOP_HARD 0x0000 + +///////////////////////////////////// + + + + +///////////////////////////////////// +typedef struct +{ + // Winding 1 times + unsigned int Ta0_0; + unsigned int Ta0_1; + unsigned int Tb0_0; + unsigned int Tb0_1; + unsigned int Tc0_0; + unsigned int Tc0_1; + // Winding 2 times + unsigned int Ta1_0; + unsigned int Ta1_1; + unsigned int Tb1_0; + unsigned int Tb1_1; + unsigned int Tc1_0; + unsigned int Tc1_1; + // Break transistors + unsigned int Tbr0_0; + unsigned int Tbr0_1; + unsigned int Tbr1_0; + unsigned int Tbr1_1; + //Level transistors closed + unsigned int Tclosed_0; + unsigned int Tclosed_1; + unsigned int Tclosed_high; + unsigned int pwm_tics; + unsigned int inited; + unsigned int freq_pwm; + unsigned int Tclosed_saw_direct_0; + unsigned int Tclosed_saw_direct_1; + unsigned int current_period; + unsigned int where_interrupt; + unsigned int mode_reload; + unsigned int one_or_two_interrupts_run; + WORD_UINT2BITS_STRUCT saw_direct; + void (*write_1_2_winding_break_times)(); + void (*write_1_2_winding_break_times_split)(); +} XPWM_TIME; + +#define DEFAULT_XPWM_TIME {0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,0,0,0,0, {0}, \ + xpwm_write_1_2_winding_break_times_16_lines, \ + xpwm_write_1_2_winding_break_times_16_lines_split_eages } + +void xpwm_write_1_2_winding_break_times_16_lines(); +void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p); +void xpwm_write_zero_winding_break_times_16_lines_split_eages(); +void initXpwmTimeStructure(XPWM_TIME *p); + +extern XPWM_TIME xpwm_time; + +#define write_winding1_fase_a(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 0); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 1); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding1_fase_b(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 2); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 3); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding1_fase_c(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 4); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 5); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_a(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 6); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 7); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_b(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 8); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 9); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_c(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 10); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 11); WriteMemory(ADR_PWM_TIMING, T1); +#define write_break_winding1(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 12); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 13); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_break_winding2(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 14); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 15); WriteMemory(ADR_PWM_TIMING, T1); + + +#endif /* XP_WRITE_TIME_H_ */ diff --git a/Inu/Src/main_matlab/rotation_speed_matlab.c b/Inu/Src/main_matlab/rotation_speed_matlab.c new file mode 100644 index 0000000..74c91d5 --- /dev/null +++ b/Inu/Src/main_matlab/rotation_speed_matlab.c @@ -0,0 +1,428 @@ +#include "rotation_speed.h" +#include "xp_rotation_sensor.h" +#include "IQmathLib.h" +#include "params.h" +#include "adc_tools.h" +#include "rmp_cntl_my1.h" +#include "my_filter.h" +#include "vector.h" +#include "TuneUpPlane.h" //����������� +#include "errors.h" +#include "log_to_memory.h" +#include "DSP281x_Device.h" //for int16 + +#pragma DATA_SECTION(rotor,".fast_vars1"); +ROTOR_VALUE rotor = ROTOR_VALUE_DEFAULTS; + +RMP_MY1 rmp_wrot = RMP_MY1_DEFAULTS; + +_iq koef_Wout_filter = _IQ(0.2); //_IQ(0.15); +_iq koef_Wout_filter_long = _IQ(0.12);//_IQ(0.03); + + +static _iq impulses_To_iqF(unsigned int time, unsigned int impulses); +static _iq counter_To_iqF(unsigned int count, unsigned int freq_mode); +static _iq delta_Angle_To_iqF(unsigned long delta, unsigned int period); +static void sort_F_array(_iq *array, unsigned int size); + +void rotorInit(void) +{ + unsigned int i = 0, size = 0, *pint = 0; + + rmp_wrot.RampLowLimit = 0; + rmp_wrot.RampHighLimit = _IQ(1); + rmp_wrot.RampPlus = _IQ(0.0015/NORMA_FROTOR); + rmp_wrot.RampMinus = _IQ(-0.0015/NORMA_FROTOR); + rmp_wrot.DesiredInput = 0; + rmp_wrot.Out = 0; + + pint = (unsigned int*)&rotor; + size = sizeof(rotor) / sizeof(unsigned int); + for(i = 0; i < size; i++) + { + *(pint + i) = 0; + } + + koef_Wout_filter = _IQ(0.2); //_IQ(0.15); + koef_Wout_filter_long = _IQ(0.001); //_IQ(0.0005); +} + +#pragma CODE_SECTION(update_rot_sensors,".fast_run"); +void update_rot_sensors() +{ +// rotation_sensor.update_registers(&rotation_sensor); +} + +#pragma CODE_SECTION(Rotor_measure,".fast_run"); +void Rotor_measure(void) +{ + static unsigned long PrevAngle1 = 0, PrevAngle2 = 0, PrevAngle3 = 0, PrevAngle4 = 0; + static unsigned int peroid_shim_mks = (unsigned int)(1000000L / FREQ_PWM / 2.0); + static _iq prev_wrot = 0; + static unsigned int prev_wrot_count = 0; + static int direct_accum = 0; + static int sens1_err_count = 0; + static int sens2_err_count = 0; + + +// unsigned int s_number = 0, begin_data = 0, end_data = 0, i; +// _iq accumulator = 0, deltaF = 0, deltaAngle = 0; +// rotation_sensor.read_sensors(&rotation_sensor); +// if(rotation_sensor.in_plane.read.regs.comand_reg.bit.update_registers) +// { +// rotor.error_update_count ++; +// } +// // logpar.log22 = rotation_sensor.in_plane.out.CountOne1; +// // logpar.log23 = rotation_sensor.in_plane.out.CountZero1; +// if(rotation_sensor.use_sensor1) +// { +// if((rotation_sensor.in_plane.out.CountOne1 <= 200)// && !rotation_sensor.in_plane.out.counter_freq1) +// || rotation_sensor.in_plane.out.CountOne1 == 65535) +// { rotation_sensor.in_plane.out.CountOne1 = 0; } +// if((rotation_sensor.in_plane.out.CountZero1 <= 200)// && !rotation_sensor.in_plane.out.counter_freq1) +// || rotation_sensor.in_plane.out.CountZero1 == 65535) +// { rotation_sensor.in_plane.out.CountZero1 = 0; } + +// //����� ��������� ���� ������� �� ������� +// if (rotation_sensor.in_plane.out.Impulses1 < 5) { +// if(rotation_sensor.in_plane.out.CountOne1) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountOne1, +// rotation_sensor.in_plane.out.counter_freq1); +// } +// if(rotation_sensor.in_plane.out.CountZero1) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountZero1, +// rotation_sensor.in_plane.out.counter_freq1); +// } +// } + +// if(rotation_sensor.in_plane.out.Impulses1 > 2) +// { +// rotor.iqFsensors[s_number++] = impulses_To_iqF(rotation_sensor.in_plane.out.Time1, +// rotation_sensor.in_plane.out.Impulses1); +// // logpar.log11 = (int16) _IQtoIQ15(rotor.iqFsensors[s_number - 1]); +// } else { +// // logpar.log11 = 0; +// } + +// if (rotor.iqF > 139810L)//10 rpm +// { +// if (rotation_sensor.in_plane.out.CountOne1 == 0 && rotation_sensor.in_plane.out.CountZero1 == 0 +// && rotation_sensor.in_plane.out.Impulses1 == 0) { +// sens1_err_count += 1; +// } else { +// sens1_err_count = 0; +// } +// if (sens1_err_count > 50) { +// sens1_err_count = 50; +// faults.faults4.bit.Speed_Datchik_1_Off |= 1; +// } +// } else { +// sens1_err_count = 0; +// } +// } + +// // logpar.log4 = rotation_sensor.in_plane.out.CountOne2; +// // logpar.log20 = rotation_sensor.in_plane.out.CountZero2; +// if(rotation_sensor.use_sensor2) +// { +// if((rotation_sensor.in_plane.out.CountOne2 <= 200)// && !rotation_sensor.in_plane.out.counter_freq2) +// || rotation_sensor.in_plane.out.CountOne2 == 65535) +// { rotation_sensor.in_plane.out.CountOne2 = 0; } +// if((rotation_sensor.in_plane.out.CountZero2 <= 200)// && !rotation_sensor.in_plane.out.counter_freq2) +// || rotation_sensor.in_plane.out.CountZero2 == 65535) +// { rotation_sensor.in_plane.out.CountZero2 = 0; } + +// //����� ��������� ����, ������� �� ������� +// if (rotation_sensor.in_plane.out.Impulses2 < 5) { +// if(rotation_sensor.in_plane.out.CountOne2) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountOne2, +// rotation_sensor.in_plane.out.counter_freq2); +// } +// if(rotation_sensor.in_plane.out.CountZero2) { +// rotor.iqFsensors[s_number++] = counter_To_iqF(rotation_sensor.in_plane.out.CountZero2, +// rotation_sensor.in_plane.out.counter_freq2); +// } +// } + +// if(rotation_sensor.in_plane.out.Impulses2 > 2) +// { +// rotor.iqFsensors[s_number++] = impulses_To_iqF(rotation_sensor.in_plane.out.Time2, +// rotation_sensor.in_plane.out.Impulses2); +// // logpar.log16 = (int16) _IQtoIQ15(rotor.iqFsensors[s_number - 1]); +// } + +// if (rotor.iqF > 139810L)//10 rpm +// { +// if (rotation_sensor.in_plane.out.CountOne2 == 0 && rotation_sensor.in_plane.out.CountZero2 == 0 +// && rotation_sensor.in_plane.out.Impulses2 == 0) { +// sens2_err_count += 1; +// } else { +// sens2_err_count = 0; +// } +// if (sens2_err_count > 50) { +// sens2_err_count = 50; +// faults.faults4.bit.Speed_Datchik_2_Off |= 1; +// } +// } else { +// sens2_err_count = 0; +// } + +// } + +// if(rotation_sensor.use_angle_plane && (s_number < SENSORS_NUMBER)) +// { +// if(rotation_sensor.rotation_plane.cds_rs->read.sbus.config.bit.channel1_enable && rotor.iqFsensors[0] && (s_number < (SENSORS_NUMBER - 1))) +// { +// if(rotation_sensor.rotation_plane.out.Delta_angle1 < 1500) +// { +// rotor.iqFsensors[s_number++] = delta_Angle_To_iqF(rotation_sensor.rotation_plane.out.Delta_angle1, +// rotation_sensor.rotation_plane.out.survey_time_mks); + +// } + +// deltaAngle = _IQabs(rotation_sensor.rotation_plane.out.Current_angle1 - PrevAngle1); +// if(deltaAngle > 1500) +// { +// deltaAngle = 262144 - deltaAngle; +// } +// if((deltaAngle < 291) && (deltaAngle >= 0)) +// { +// rotor.iqFsensors[s_number++] = +// delta_Angle_To_iqF(deltaAngle, peroid_shim_mks); +// } +// PrevAngle1 = rotation_sensor.rotation_plane.out.Current_angle1; +// } +// // else +// // { +// // rotor.iqFsensors[s_number++] = 0; +// // rotor.iqFsensors[s_number++] = 0; +// // } +// if(rotation_sensor.rotation_plane.cds_rs->read.sbus.config.bit.channel2_enable && (s_number < (SENSORS_NUMBER - 1))) +// { +// rotor.iqFsensors[s_number++] = delta_Angle_To_iqF(rotation_sensor.rotation_plane.out.Delta_angle2, +// rotation_sensor.rotation_plane.out.survey_time_mks); +// rotor.iqFsensors[s_number++] = +// delta_Angle_To_iqF(_IQabs(rotation_sensor.rotation_plane.out.Current_angle2 - PrevAngle2), +// peroid_shim_mks); +// PrevAngle2 = rotation_sensor.rotation_plane.out.Current_angle2; +// } +// if(rotation_sensor.rotation_plane.cds_rs->read.sbus.config.bit.channel3_enable && (s_number < (SENSORS_NUMBER - 1))) +// { +// rotor.iqFsensors[s_number++] = delta_Angle_To_iqF(rotation_sensor.rotation_plane.out.Delta_angle3, +// rotation_sensor.rotation_plane.out.survey_time_mks); +// rotor.iqFsensors[s_number++] = +// delta_Angle_To_iqF(_IQabs(rotation_sensor.rotation_plane.out.Current_angle3 - PrevAngle3), +// peroid_shim_mks); +// PrevAngle3 = rotation_sensor.rotation_plane.out.Current_angle3; +// } +// if(rotation_sensor.rotation_plane.cds_rs->read.sbus.config.bit.channel4_enable && (s_number < (SENSORS_NUMBER - 1))) +// { +// rotor.iqFsensors[s_number++] = delta_Angle_To_iqF(rotation_sensor.rotation_plane.out.Delta_angle4, +// rotation_sensor.rotation_plane.out.survey_time_mks); +// rotor.iqFsensors[s_number++] = +// delta_Angle_To_iqF(_IQabs(rotation_sensor.rotation_plane.out.Current_angle4 - PrevAngle4), +// peroid_shim_mks); +// PrevAngle2 = rotation_sensor.rotation_plane.out.Current_angle4; +// } +// } +// // logpar.log22 = (int16) _IQtoIQ15(rotor.iqFsensors[0]); +// // logpar.log23 = (int16) _IQtoIQ15(rotor.iqFsensors[1]); +// // logpar.log24 = (int16) _IQtoIQ15(rotor.iqFsensors[2]); +// // logpar.log25 = (int16) _IQtoIQ15(rotor.iqFsensors[3]); +// // logpar.log29 = (int16) _IQtoIQ15(rotor.iqFsensors[4]); +// // logpar.log30 = (int16) _IQtoIQ15(rotor.iqFsensors[5]); + +// if(s_number > SENSORS_NUMBER_ONLY_IN) {s_number = SENSORS_NUMBER_ONLY_IN;} //TODO set SENSORS_NUMBER when tune angle measure +// if(s_number > 3) +// { +// sort_F_array(rotor.iqFsensors, s_number); +// deltaF = rotor.iqFout >> 2; +// if(deltaF < 43000) // ~3 ob/min +// { +// deltaF = 43000; +// } +// i = 0; +// begin_data = 0; +// end_data = s_number; //TODO test, as usial +// while(i < s_number) +// { +// if(_IQabs(rotor.iqFout - rotor.iqFsensors[i]) >= deltaF) +// { +// i++; +// } +// else +// { +// break; +// } +// } +// if(i < s_number) { begin_data = i; } +// else {begin_data = 0;} +// while((i < s_number) && (_IQabs(rotor.iqFout - rotor.iqFsensors[i]) < deltaF)) +// { +// i++; +// } +// if(i <= SENSORS_NUMBER) +// { +// end_data = i; +// } +// else +// { +// end_data = SENSORS_NUMBER; +// } + +// } +// else +// { +// begin_data = 0; +// end_data = s_number; +// } +// if (begin_data >= end_data) { //This part to prevent freeze of speed on some level if signal lost +// begin_data = 0; +// end_data = s_number; +// } +// for(i = begin_data; i < end_data; i++) +// { +// accumulator += rotor.iqFsensors[i]; +// } + +// if(end_data != begin_data) +// { +// rotor.iqF = accumulator / (end_data - begin_data); +// prev_wrot_count = 0; +// } +// else +// { +// rotor.iqF = prev_wrot; +// prev_wrot_count += 1; +// } + +// // logpar.log19 = (int16)(_IQtoIQ15(rotor.iqF)); + +// if (prev_wrot != rotor.iqF || rotor.iqF==0 ) +// { +// rmp_wrot.DesiredInput = rotor.iqF; +// rmp_wrot.calc(&rmp_wrot); +// rotor.iqF = rmp_wrot.Out; +// } +// prev_wrot=rotor.iqF; +// //�� ���������� ������� ���������. +// if (prev_wrot_count > 10) { +// prev_wrot = 0; +// prev_wrot_count = 10; +// } + +// rotor.iqFout = exp_regul_iq(koef_Wout_filter, rotor.iqFout, rotor.iqF); +// rotor.iqFlong = exp_regul_iq(koef_Wout_filter_long, rotor.iqFlong, rotor.iqF); + +// rotor.direct_rotor_in1 = rotation_sensor.in_plane.out.direction1; +// rotor.direct_rotor_in2 = rotation_sensor.in_plane.out.direction2; +// rotor.direct_rotor_angle = rotation_sensor.rotation_plane.out.direction; + +// rotor.error.sens_err1 = rotation_sensor.in_plane.read.pbus.direction.bit.sens_err1; +// rotor.error.sens_err2 = rotation_sensor.in_plane.read.pbus.direction.bit.sens_err2; + +// // rotor.direct_rotor = (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) > 0 ? 1 : // + rotor.direct_rotor_angle +// // (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) < 0 ? -1 : // + rotor.direct_rotor_angle +// // 0; +// if(rotor.iqFout >139810L) //10ob/min +// { +// if((rotor.direct_rotor_in1 + rotor.direct_rotor_in2) > 0) +// { +// direct_accum++; +// } +// else if((rotor.direct_rotor_in1 + rotor.direct_rotor_in2) < 0) +// { +// direct_accum--; +// } +// else +// { +// if(direct_accum > 0) {direct_accum--;} +// if(direct_accum < 0) {direct_accum++;} +// } +// if(direct_accum > 60) { direct_accum = 60; } +// if(direct_accum < -60) { direct_accum = -60; } +// rotor.direct_rotor = direct_accum > 0 ? 1 : +// direct_accum < 0 ? -1 : +// 0; +// // if (f.flag_second_PCH) { +// // rotor.direct_rotor = - rotor.direct_rotor; +// // } +// } +// else +// { +// rotor.direct_rotor = (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) > 0 ? 1 : // + rotor.direct_rotor_angle +// (rotor.direct_rotor_in1 + rotor.direct_rotor_in2) < 0 ? -1 : // + rotor.direct_rotor_angle +// 0; +// // if (f.flag_second_PCH) { +// // rotor.direct_rotor = - rotor.direct_rotor; +// // } +// direct_accum = rotor.direct_rotor; +// } + +// if(rotation_sensor.in_plane.write.regs.comand_reg.bit.set_sampling_time) //�������� �������� +// { +// rotation_sensor.in_plane.write.regs.comand_reg.bit.filter_sensitivity = 0x5C; +// } +// else //�������� �������, ������ ��������� +// { +// rotation_sensor.in_plane.write.regs.comand_reg.bit.filter_sensitivity = 0xA8; +// } +} + +#pragma CODE_SECTION(impulses_To_iqF,".fast_run"); +_iq impulses_To_iqF(unsigned int time, unsigned int impulses) //time mks. impulses count +{ + //Flong = (impulses / time / IMPULSES_PER_TURN) * _IQ(1) / NORMA_FROTOR; + static unsigned long long koeff_to_F = 16777216LL / IMPULSES_PER_TURN * 1000000LL / NORMA_FROTOR; + long long Flong = (long long)impulses * koeff_to_F / time; + return (_iq)Flong; +} + +//Frot = Fimp / IMPULSES_PER_TURN / NORMA_FROTOR = +// = counter_freq / counter / 2 / IMPULSES_PER_TURN / NORMA_FROTOR +//���� �� 2, �.�. ������� ������������ �������� ������� +//��������� �� (1LL << 24) ����� �������� � iq24 +#pragma CODE_SECTION(counter_To_iqF,".fast_run"); +_iq counter_To_iqF(unsigned int count, unsigned int freq_mode) +{ + static long long koeff_to_F = 60000000LL * _IQ(1) / IMPULSES_PER_TURN / 2 / NORMA_FROTOR; + long long Flong = 0; + if(freq_mode == 0) // 60Mhz + { + Flong = koeff_to_F / count / 100; + } + else //600KHz + { + Flong = koeff_to_F / count; + } + return Flong; +} + +#pragma CODE_SECTION(delta_Angle_To_iqF,".fast_run"); +_iq delta_Angle_To_iqF(unsigned long delta, unsigned int period) +{ + // iqF = (delta / ANGLE_RESOLUTION) / (period * 10^-6) * (1LL << 24) / NORMA_FROTOR; + // iqF = delta * 10^6 * (1LL << 24) / ANGLE_RESOLUTION / period / NORMA_FROTOR; + static long long koeff_to_F = 1000000LL * (1LL << 24) / ANGLE_RESOLUTION / NORMA_FROTOR; + return (_iq)(koeff_to_F * delta / period); +} + +#pragma CODE_SECTION(sort_F_array,".fast_run2"); +void sort_F_array(_iq *array, unsigned int size) +{ + unsigned int i, j; + _iq tmp = 0; + for(i = size; i > 0; i--) + { + for(j = 1; j < size; j++) + { + if(array[j - 1] > array[j]) + { + tmp = array[j]; + array[j] = array[j - 1]; + array[j - 1] = tmp; + } + } + } +} + diff --git a/Inu/Src/main_matlab/v_pwm24_matlab.c b/Inu/Src/main_matlab/v_pwm24_matlab.c new file mode 100644 index 0000000..9df9ad3 --- /dev/null +++ b/Inu/Src/main_matlab/v_pwm24_matlab.c @@ -0,0 +1,1644 @@ + + +#include "v_pwm24.h" +//#include "DSP281x_Device.h" // DSP281x Headerfile Include File +//#include "big_dsp_module.h" +//#include "rmp2cntl.h" // Include header for the VHZPROF object +//#include "rmp_cntl_my1.h" // Include header for the VHZPROF object +#include "pid_reg3.h" // Include header for the VHZPROF object + +#include "params.h" +// #include "PWMTools.h" +#include "adc_tools.h" +#include "v_pwm24.h" + +#include "dq_to_alphabeta_cos.h" + +#include "IQmathLib.h" +// #include "log_to_memory.h" +//Xilinx +//#include "x_parameters.h" +// #include "x_basic_types.h" +// #include "xp_project.h" +// #include "xp_cds_tk.h" +#include "svgen_dq.h" +#include "xp_write_xpwm_time.h" + +#include "def.h" + +#define DEF_FREQ_PWM_XTICS T1_PRD +#define DEF_PERIOD_MIN_XTICS (DT + 10e-6)*FTBCLK + +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +// #pragma DATA_SECTION(VAR_FREQ_PWM_XTICS,".fast_vars1"); +int VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +// #pragma DATA_SECTION(VAR_PERIOD_MAX_XTICS,".fast_vars1"); +int VAR_PERIOD_MAX_XTICS = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_XTICS = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_BR_XTICS,".fast_vars1"); +// int VAR_PERIOD_MIN_BR_XTICS = DEF_PERIOD_MIN_BR_XTICS;// + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + + +#define SQRT3 29058990 //1.7320508075688772935274463415059 +#define CONST_IQ_1 16777216 //1 +#define CONST_IQ_05 8388608 //0.5 +#define CONST_IQ_2 33554432 //2 + +#define CONST_IQ_PI6 8784530 //30 +#define CONST_IQ_PI3 17569060 // 60 +#define CONST_IQ_PI 52707178 // 180 +#define CONST_IQ_OUR1 35664138 // +#define CONST_IQ_2PI 105414357 // 360 +#define CONST_IQ_120G 35138119 // 120 grad +#define CONST_IQ_3 50331648 // 3 + +#define IQ_ALFA_SATURATION1 15099494//16441671//15099494 +#define IQ_ALFA_SATURATION2 1677721//16441671//15099494 + + +#define PI 3.1415926535897932384626433832795 + +// #pragma DATA_SECTION(iq_alfa_coef,".fast_vars"); +_iq iq_alfa_coef = 16777216; + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//#pragma DATA_SECTION(freq_array,".v_24pwm_vars"); +//int freq_array[COUNT_VAR_FREQ]; +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +//#pragma DATA_SECTION(pidCur_Kp,".v_24pwm_vars"); +//_iq pidCur_Kp = 0; + +// #pragma DATA_SECTION(pidCur_Ki,".fast_vars"); +_iq pidCur_Ki = 0; + +// #pragma DATA_SECTION(ar_tph,".fast_vars"); +_iq ar_tph[7]; + +// #pragma DATA_SECTION(winding_displacement,".fast_vars"); +_iq winding_displacement = CONST_IQ_PI6; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_1,".fast_vars");//v_24pwm_vars +//_iq iq_koef_mod_korrect_1; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_2,".v_24pwm_vars"); +//_iq iq_koef_mod_korrect_2; + +//#pragma DATA_SECTION(ar_sa_all,".v_24pwm_vars"); +// #pragma DATA_SECTION(ar_sa_all,".fast_vars"); +int ar_sa_all[3][6][4][7] = { { + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + } + }, + { + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + } + }, + { + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + } + } + }; + + +// #pragma DATA_SECTION(svgen_pwm24_1,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_1,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_1 = SVGEN_PWM24_DEFAULTS; +// #pragma DATA_SECTION(svgen_pwm24_2,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_2,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_2 = SVGEN_PWM24_DEFAULTS; + +// #pragma DATA_SECTION(svgen_dq_1,".v_24pwm_vars"); +SVGENDQ svgen_dq_1 = SVGENDQ_DEFAULTS; +// #pragma DATA_SECTION(svgen_dq_2,".v_24pwm_vars"); +SVGENDQ svgen_dq_2 = SVGENDQ_DEFAULTS; + +//#pragma DATA_SECTION(delta_t1_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t1_struct,".fast_vars"); +//PIDREG3 delta_t1_struct = PIDREG3_DEFAULTS; +//#pragma DATA_SECTION(delta_t2_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t2_struct,".fast_vars"); +//PIDREG3 delta_t2_struct = PIDREG3_DEFAULTS; + +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +int detect_sec(_iq teta); +int detect_region(_iq k, _iq teta); +// + + + + +//void init_alpha(void) +//{ +// +//// power_ain1.init(&power_ain1); +//// power_ain2.init(&power_ain2); +// +// svgen_mf1.NewEntry = 0;//_IQ(0.5); +// svgen_mf2.NewEntry = 0; +// +// svgen_mf1.SectorPointer = 0; +// svgen_mf2.SectorPointer = 0; +// +////����� �� ��������� 0 �������� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// +// +// +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_PLUS) +//// 30 ����. ����� +// svgen_mf1.Alpha = _IQ(0.5); +// svgen_mf2.Alpha = _IQ(0); +// +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_MINUS) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0.5); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_ZERO) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// #error "!!!������!!! �� ��������� SETUP_SDVIG_OBMOTKI � params_motor.h!!!" +// +// +//#endif +// +//#endif +// +// +// +//#endif +// +// +// +//} + +void InitVariablesSvgen(unsigned int freq) +{ +////////// Inserted from 'initPWM_Variables' for modulation project ////////// + + //��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� + xpwm_time.Tclosed_0 = 0; + xpwm_time.Tclosed_1 = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.Tclosed_high = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.pwm_tics = VAR_FREQ_PWM_XTICS; + // ������� ����������� ��� + // "����������� ��� ��� ���� ����=0x0 + //���� SAW_DIRECTbit = 0 �� �������� ����>������� �������� �������� ���������� ���������=0 + //�� ������ ���� + //���� SAW_DIRECTbit = 1 �� �������� ����<=������� �������� �������� ���������� ���������=0 + //�� ������ ���� + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //��� 22220 ������������� 0, �.�. ��� ������ � ������ ������ ���� ���������� ��������� ����������. + xpwm_time.saw_direct.all = 0;//0x0555; + xpwm_time.one_or_two_interrupts_run = PWM_TWICE_INTERRUPT_RUN; + + initXpwmTimeStructure(&xpwm_time); + init_alpha_pwm24(VAR_FREQ_PWM_XTICS); +///////////////////////////////////////////////////////////// + + svgen_pwm24_1.pwm_minimal_impuls_zero_minus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_100;//DEF_PERIOD_MIN_XTICS_80; + svgen_pwm24_1.pwm_minimal_impuls_zero_plus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_80; + + svgen_pwm24_2.pwm_minimal_impuls_zero_minus = svgen_pwm24_1.pwm_minimal_impuls_zero_minus; + svgen_pwm24_2.pwm_minimal_impuls_zero_plus = svgen_pwm24_1.pwm_minimal_impuls_zero_plus; + + + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_1; + + + + + svgen_dq_1.Ualpha = 0; + svgen_dq_1.Ubeta = 0; + + svgen_dq_2.Ualpha = 0; + svgen_dq_2.Ubeta = 0; + + + +} + + + + + + + + + + +// #pragma CODE_SECTION(recalc_time_pwm_minimal_2_xilinx_pwm24_l,".fast_run2"); +void recalc_time_pwm_minimal_2_xilinx_pwm24_l(SVGEN_PWM24 *pwm24, + _iq *T0, _iq *T1, + _iq timpuls_corr ) +{ + +//_iq pwm_t, timpuls_corr; + + volatile unsigned long pwm_t; + volatile unsigned int minimal_plus, minimal_minus; + + + + minimal_plus = pwm24->pwm_minimal_impuls_zero_plus; + minimal_minus = pwm24->pwm_minimal_impuls_zero_minus; + + // if (pwm24->prev_level == V_PWM24_PREV_PWM_CLOSE || pwm24->prev_level == V_PWM24_PREV_PWM_MIDDLE || pwm24->prev_level == V_PWM24_PREV_PWM_WORK_KM0) + // { + // minimal_plus *= 2; +// minimal_minus *= 2; +// } + + pwm_t = timpuls_corr / pwm24->XilinxFreq; + + // *T_imp = pwm_t; + +// if (pwm_t>(pwm24->Tclosed_high-4*minimal_minus)) +// pwm_t=(pwm24->Tclosed_high-4*minimal_minus); + + + if (timpuls_corr >= 0) + { + *T0 = pwm_t + minimal_plus; + // *T1 = 0; + *T1 = pwm24->Tclosed_high - minimal_minus; + } + else + { + *T0 = 0 + minimal_plus; + // *T1 = -pwm_t - minimal_minus; + *T1 = pwm24->Tclosed_high + pwm_t - minimal_minus; + } + + + // if (*T0 < minimal_plus) + // *T0 = minimal_plus; + + // if (*T0 > (pwm24->Tclosed_high - 2 * minimal_plus)) + // *T0 = (pwm24->Tclosed_high - 2 * minimal_plus); + + // if (*T1 < (2 * minimal_minus)) + // *T1 = 2 * minimal_minus; + + // if (*T1 > (pwm24->Tclosed_high - minimal_minus)) + // *T1 = (pwm24->Tclosed_high - minimal_minus); + +} + +static DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + +// #pragma CODE_SECTION(test_calc_dq_pwm24,".v_24pwm_run"); +void test_calc_dq_pwm24(_iq Ud, _iq Uq, _iq Ud2, _iq Uq2, _iq tetta,_iq Uzad_max) +{ +// DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + _iq maxUq1 = 0; + _iq maxUq2 = 0; + _iq Uq1Out = 0; + _iq Uq2Out = 0; + + maxUq1 = 0; + maxUq2 = 0; + + _iq Uzad_max_square = _IQmpy(Uzad_max, Uzad_max); + + if (tetta > CONST_IQ_2PI) + { + tetta -= CONST_IQ_2PI; + } + + if (tetta < 0) + { + tetta += CONST_IQ_2PI; + } + //��������� ����������� ��������� + maxUq1 = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq > (maxUq1)) { Uq = (maxUq1);} + if (Uq < -(maxUq1)) { Uq = -(maxUq1);} + Uq1Out = Uq; + + //Reculct dq to alpha-beta + dq_to_ab.Tetta = tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + svgen_dq_1.calc(&svgen_dq_1); + + //��������� ����������� ��������� + maxUq2 = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq2 > maxUq2) { Uq2 = maxUq2;} + if (Uq2 < -(maxUq2)) { Uq2 = -(maxUq2);} + +Uq2Out = Uq2; + + //Reculc dq to alpha-beta for 2-nd winding with winding displasement + dq_to_ab.Tetta = tetta - winding_displacement; + dq_to_ab.Ud = Ud2; + dq_to_ab.Uq = Uq2; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + svgen_dq_2.calc(&svgen_dq_2); + + //1 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +/* + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS);*/ +} + + +// #pragma CODE_SECTION(test_calc_simple_dq_pwm24,".v_24pwm_run"); +void test_calc_simple_dq_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2,_iq Uzad_max) +{ + static _iq hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM / 2); +// static _iq tetta = 0; + DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + + _iq Ud = 0; + _iq Uq = _IQsat(uz1,Uzad_max,0); + + analog.tetta += _IQmpy(fz1, hz_to_angle); + + if (analog.tetta >= CONST_IQ_2PI) + { + analog.tetta -= CONST_IQ_2PI; + } + + if (analog.tetta < 0) + { + analog.tetta += CONST_IQ_2PI; + } + + dq_to_ab.Tetta = analog.tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + +// svgen_dq_1.Ualpha = 0; +// svgen_dq_1.Ubeta = 0; + + svgen_dq_1.calc(&svgen_dq_1); + + dq_to_ab.Tetta = analog.tetta - winding_displacement; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + + svgen_dq_2.calc(&svgen_dq_2); + + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// logpar.log1 = (int16)(_IQtoIQ15(uz1)); +// logpar.log2 = (int16)(_IQtoIQ15(fz1)); +// logpar.log3 = (int16)(_IQtoIQ15(Ud)); +// logpar.log4 = (int16)(_IQtoIQ15(Uq)); +// logpar.log5 = (int16)(_IQtoIQ15(svgen_dq_1.Ualpha)); +// logpar.log6 = (int16)(_IQtoIQ15(svgen_dq_1.Ubeta)); +// logpar.log7 = (int16)(_IQtoIQ15(svgen_dq_1.Ta)); +// logpar.log8 = (int16)(_IQtoIQ15(svgen_dq_1.Tb)); +// logpar.log9 = (int16)(_IQtoIQ15(svgen_dq_1.Tc)); +// logpar.log10 = (int16)(_IQtoIQ12(analog.tetta)); +// logpar.log11 = (int16)(svgen_pwm24_1.Ta_0.Ti); +// logpar.log12 = (int16)((svgen_pwm24_1.Ta_1.Ti)); +// logpar.log13 = (int16)(svgen_pwm24_1.Tb_0.Ti); +// logpar.log14 = (int16)((svgen_pwm24_1.Tb_1.Ti)); +// logpar.log15 = (int16)(svgen_pwm24_1.Tc_0.Ti); +// logpar.log16 = (int16)((svgen_pwm24_1.Tc_1.Ti)); + + +// svgen_pwm24_1.calc(&svgen_pwm24_1); +// svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + // set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + // set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +} + +// #pragma CODE_SECTION(test_calc_pwm24,".v_24pwm_run"); +void test_calc_pwm24(_iq uz1, _iq uz2, _iq fz1) +{ + //static int i =0; + svgen_pwm24_1.Freq = fz1; + svgen_pwm24_2.Freq = fz1; + + svgen_pwm24_1.Gain = uz1;//_IQmpy(uz1,iq_koef_mod_korrect_1); + svgen_pwm24_2.Gain = uz2;//_IQmpy(uz2,iq_koef_mod_korrect_2); + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc(&svgen_pwm24_1); + svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +// if(((svgen_pwm24_2.Ta_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_1.Ti <= (VAR_FREQ_PWM_XTICS)))) +// { +// asm(" NOP "); +// } +// +// if( ((svgen_pwm24_2.Ta_0.Ti > 0) && (svgen_pwm24_2.Ta_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > 0) && (svgen_pwm24_2.Ta_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > 0) && (svgen_pwm24_2.Tb_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > 0) && (svgen_pwm24_2.Tb_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > 0) && (svgen_pwm24_2.Tc_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > 0) && (svgen_pwm24_2.Tc_1.Ti < (VAR_PERIOD_MIN_XTICS)))) +// { +// asm(" NOP "); +// } +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc(SVGEN_PWM24 *vt) +{ + _iq StepAngle; + + StepAngle = _IQmpy(vt->Freq,vt->FreqMax); + + vt->Alpha = vt->Alpha + StepAngle; + + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + + +// #pragma CODE_SECTION(calc_time_one_tk,".v_24pwm_run"); +void calc_time_one_tk(_iq gain, _iq teta, _iq delta_U, + _iq Ia, _iq Ib, _iq Ic, + unsigned int number, + SVGEN_PWM24_TIME *tk0, + SVGEN_PWM24_TIME *tk1, + SVGEN_PWM24_TIME *tk2, + SVGEN_PWM24_TIME *tk3, + SVGEN_PWM24_TIME *tk4, + SVGEN_PWM24_TIME *tk5) +{ + _iq iq_t0 = 0, iq_t1 = 0, iq_t2 = 0, iq_t3 = 0, iq_t4 = 0, iq_t5 = 0; + _iq t_pos = 0, t_neg = 0; + _iq delta_ttt; + _iq teta60; + + int sector, region; + int cur_sign, i, ki; + int updown_tk0; + int updown_tk1; + + volatile _iq t_tk0, t_tk1; + + updown_tk0 = 1; + updown_tk1 = 0; + + sector = detect_sec(teta); // + teta60 = teta - _IQmpy(_IQ(sector - 1),CONST_IQ_PI3); // + + if ((sector == 2) || (sector == 4) || (sector == 6)) + { + teta60 = CONST_IQ_PI3 - teta60; + } + + region = detect_region(gain, teta60); // + + calc_t_abc(gain, teta60, region, &iq_t0, &iq_t1, &iq_t2, &iq_t3, &iq_t4, &iq_t5); + + + delta_ttt = 0; //calc_delta_t(delta_U,number,region); + //delta_ttt = 0; + + //if (number == 1) + //{ + //logpar.log1 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log2 = (int16)(_IQtoIQ15(delta_ttt)); + //} + //else + //{ + //logpar.log3 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log4 = (int16)(_IQtoIQ15(delta_ttt)); + //} + + calc_arr_tph(sector, region, iq_t0, iq_t1, iq_t2, iq_t3, iq_t4, iq_t5, delta_ttt,number, Ia, Ib, Ic); + + for (ki = 0; ki < 3; ki++) + { + t_pos = 0; + t_neg = 0; + + for (i = 0; i < 7; i++) + { + cur_sign = ar_sa_all[ki][sector - 1][region - 1][i]; + + if (cur_sign > 0) + { + t_pos += ar_tph[i]; + } + + if (cur_sign < 0) + { + t_neg += ar_tph[i]; + } + } + + t_pos = t_pos << 1; + + t_neg = t_neg << 1; + + if (t_neg == 0) + { + t_tk0 = 0; + } + else + { + t_tk0 = t_neg; + } + + if (t_pos == 0) + { + t_tk1 = CONST_IQ_1; + } + else + { + t_tk1 = CONST_IQ_1 - t_pos; + } + + switch (ki) + { + case 0: + tk0->up_or_down = updown_tk0; + tk0->Ti = t_tk0; + + tk1->up_or_down = updown_tk1; + tk1->Ti = t_tk1; + + break; + + case 1: + tk2->up_or_down = updown_tk0; + tk2->Ti = t_tk0; + + tk3->up_or_down = updown_tk1; + tk3->Ti = t_tk1; + + break; + + case 2: + tk4->up_or_down = updown_tk0; + tk4->Ti = t_tk0; + + tk5->up_or_down = updown_tk1; + tk5->Ti = t_tk1; + + break; + + default: break; + } + } +} + + + + +// #pragma CODE_SECTION(detect_region,".v_24pwm_run"); +int detect_region(_iq k, _iq teta) +{ + volatile _iq x,y; + volatile int reg=0; + + x = _IQmpy(k,_IQcos(teta)); + y = _IQmpy(k,_IQsin(teta)); + + if (y>=CONST_IQ_05) reg=4; + else if (y < (CONST_IQ_1 - _IQmpy(x,SQRT3))) reg = 1; + else if (y < (_IQmpy(x,SQRT3) - CONST_IQ_1)) reg = 2; + else reg = 3; + + return reg; +} + + + + +// #pragma CODE_SECTION(detect_sec,".v_24pwm_run"); +int detect_sec(_iq teta) +{ + volatile _iq sector; + volatile int sectorint; + + sector = _IQdiv(teta,CONST_IQ_PI3); + sectorint = (sector >> 24) + 1; + + if (sectorint > 6) sectorint-=6; + + return sectorint; +} + + +#define nSIN_t(k,t) _IQmpy(k,_IQsin(t)) + +#define nSIN_p3pt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3+t)) + +#define nSIN_p3mt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3-t)) + +#define nSIN_tmp3(k,t) _IQmpy(k,_IQsin(t-CONST_IQ_PI3)) + +//k - (Uzad) +//teta - +//region - +/* + * iq_tt0 - time of vectors op, oo, on + * iq_tt1 - time of vectors ap, an + * iq_tt2 - time of vectors bp, bn + * iq_tt3 - time of vector c + * iq_tt4 - time of vector a + * iq_tt5 - time of vector b + */ +// #pragma CODE_SECTION(calc_t_abc,".v_24pwm_run"); +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5) +{ + switch(region) + { + case 1 : + *iq_tt0 = CONST_IQ_05 - nSIN_p3pt(k,teta); + *iq_tt1 = nSIN_p3mt(k,teta); + *iq_tt2 = nSIN_t(k,teta); + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 2 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt2 = 0; + *iq_tt3 = nSIN_t(k,teta); + *iq_tt4 = nSIN_p3mt(k,teta) - CONST_IQ_05; + *iq_tt5 = 0; + break; + + case 3 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_05 - nSIN_t(k,teta); + *iq_tt2 = CONST_IQ_05 - nSIN_p3mt(k,teta); + *iq_tt3 = nSIN_p3pt(k,teta) - CONST_IQ_05; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 4 : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt3 = nSIN_p3mt(k,teta); + *iq_tt4 = 0; + *iq_tt5 = nSIN_t(k,teta) - CONST_IQ_05; + break; + + default : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = 0; + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + } + + return; +} + +//sector +//region +//iq_ttt0 - iq_ttt5 - times from calc_t_abs +//delta_t - +//number_sv - +//iqIa, iqIb, iqIc +// #pragma CODE_SECTION(calc_arr_tph, ".v_24pwm_run"); +void calc_arr_tph(int sector,int region, _iq iq_ttt0, _iq iq_ttt1, _iq iq_ttt2, _iq iq_ttt3, _iq iq_ttt4, + _iq iq_ttt5, _iq delta_t, unsigned int number_sv, + _iq iqIa, _iq iqIb, _iq iqIc) +{ + _iq iq_var1 = 0; + _iq iqIx, iqIy, iqIz; + _iq iq_alfa_1_p = CONST_IQ_05, iq_alfa_1_n = CONST_IQ_05, iq_alfa_2_n = CONST_IQ_05, iq_alfa_2_p = CONST_IQ_05; + _iq iq_alfa = 0; +// _iq iqIa, iqIb, iqIc; + _iq iq_mpy1 = 0; + _iq iq_mpy3 = 0; + _iq summ = 0; + + + switch (sector) + { + case 1: + iqIx = iqIc; + iqIy = iqIa; + iqIz = iqIb; + + break; + case 2: + + iqIx = iqIb; + iqIy = iqIa; + iqIz = iqIc; + + break; + case 3: + + iqIx = iqIb; + iqIy = iqIc; + iqIz = iqIa; + + break; + case 4: + + iqIx = iqIa; + iqIy = iqIc; + iqIz = iqIb; + + break; + case 5: + + iqIx = iqIa; + iqIy = iqIb; + iqIz = iqIc; + + break; + case 6: + + iqIx = iqIc; + iqIy = iqIb; + iqIz = iqIa; + + break; + default: + + iqIx = 0; + iqIy = 0; + iqIz = 0; + + break; + } + + if (region == 1) + { +// if (delta_t != 0) //��������� ���������� //��������� ����������� +// { +// iq_alfa = _IQsat((CONST_IQ_05 - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + + //if (delta_t < 0) + //{ + //iq_alfa = IQ_ALFA_SATURATION1; + //} + //else + //{ + //iq_alfa = IQ_ALFA_SATURATION2; + //} +// } +// else + { + iq_alfa = CONST_IQ_05; + } + } + else + { + iq_mpy1 = _IQmpy(_IQabs(iqIx),iq_ttt1)+_IQmpy(_IQabs(iqIy),iq_ttt2); + iq_mpy3 = _IQmpy(iqIz,iq_ttt3); + + summ = _IQdiv((iq_mpy3),(iq_mpy1)); + + //iq_alfa = _IQsat((_IQmpy(CONST_IQ_05,(CONST_IQ_1 + summ)) - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + iq_alfa = CONST_IQ_05; //test + } + + + if (iqIx >= 0) + { + iq_alfa_1_p = iq_alfa; + iq_alfa_1_n = CONST_IQ_1 - iq_alfa; + } + else + { + iq_alfa_1_p = CONST_IQ_1 - iq_alfa; + iq_alfa_1_n = iq_alfa; + } + + if (iqIy >= 0) + { + iq_alfa_2_p = CONST_IQ_1 - iq_alfa; + iq_alfa_2_n = iq_alfa; + } + else + { + iq_alfa_2_p = iq_alfa; + iq_alfa_2_n = CONST_IQ_1 - iq_alfa; + } + + + //if (number_sv == 2) + //{ + //logpar.log1 = (int16)(sector); + //logpar.log2 = (int16)(region); + //logpar.log3 = (int16)(_IQtoIQ15(iq_alfa)); + //logpar.log4 = (int16)(_IQtoIQ15(iq_alfa_1_p)); + //logpar.log5 = (int16)(_IQtoIQ15(iq_alfa_2_p)); + //logpar.log6 = (int16)(_IQtoIQ13(summ)); + //logpar.log3 = (int16)(_IQtoIQ14(iq_ttt0)); + //logpar.log4 = (int16)(_IQtoIQ14(iq_ttt1)); + //logpar.log5 = (int16)(_IQtoIQ14(iq_ttt2)); + //logpar.log6 = (int16)(_IQtoIQ14(iq_ttt3)); + //logpar.log7 = (int16)(_IQtoIQ14(iq_ttt4)); + //logpar.log8 = (int16)(_IQtoIQ14(iq_ttt5)); + //logpar.log10 = (int16)(_IQtoIQ15(delta_t1_struct.Up)); + //logpar.log11 = (int16)(_IQtoIQ15(delta_t1_struct.Ui)); + //logpar.log12 = (int16)(_IQtoIQ15(delta_t1_struct.Ud)); + //logpar.log13 = (int16)(_IQtoIQ15(iqIx)); + //logpar.log14 = (int16)(_IQtoIQ15(iqIy)); + //logpar.log15 = (int16)(_IQtoIQ15(iqIz)); + + //logpar.log12 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_p,iq_ttt2))); + //logpar.log13 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_n,iq_ttt2))); + //logpar.log14 = (int16)(_IQtoIQ15(delta_t)); + //} + //else + //logpar.log15 = (int16)(_IQtoIQ15(delta_t)); + +// if (region == 1) +// { +// if (f.Rele3 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } +// else +// { +// if (f.Down50 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } + + switch (region) + { + case 1: + iq_var1 = _IQdiv(iq_ttt0,CONST_IQ_3); + + ar_tph[0] = iq_var1; + ar_tph[1] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[2] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[3] = iq_var1; + ar_tph[4] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[5] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[6] = iq_var1; + break; + + case 2: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = iq_ttt4; + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 3: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 4: + ar_tph[0] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[1] = iq_ttt3; + ar_tph[2] = iq_ttt5; + ar_tph[3] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + default : + break; + } + + +} + +/* + // Function is commented because of in project 222220 should not be large voltage diviation +// #pragma CODE_SECTION(calc_delta_t,".v_24pwm_run"); +_iq calc_delta_t(_iq delta_1, unsigned int number,int region) +{ + if(_IQabs(delta_1) > MAX_LEVEL_DELTA_T) + { + // ������ ���������� ConvErrors.m2.bit.Razbalans |= 1; + return 0; + } + + if (number == 1) + { + delta_t1_struct.Fdb = delta_1; + delta_t1_struct.calc(&delta_t1_struct); + + if (_IQabs(delta_t1_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t1_struct.Out; + } + else + { + delta_t2_struct.Fdb = delta_1; + delta_t2_struct.calc(&delta_t2_struct); + + if (_IQabs(delta_t2_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t2_struct.Out; + } +} + +*/ +//#pragma CODE_SECTION(set_predel_dshim24,".fast_run2"); + +// #pragma CODE_SECTION(set_predel_dshim24_simple0,".v_24pwm_run"); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + if (T->Ti < dmin/2) + T->Ti = 0; + else + T->Ti = dmin; + + } else if (T->Ti >= (dmax - dmin)) { + T->Ti = (dmax - dmin); + } +} +// #pragma CODE_SECTION(set_predel_dshim24_simple1,".v_24pwm_run"); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti >= (dmax - dmin)) + { + if (T->Ti >= (dmax - dmin/2)) + T->Ti = dmax; + else + T->Ti = dmax-dmin; +// T->Ti = dmax; + } else if (T->Ti <= dmin) { + T->Ti = dmin; + } +} + + +// #pragma CODE_SECTION(set_predel_dshim24,".v_24pwm_run"); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + //static unsigned int counter_pass = 0; + //static unsigned int summ = 0; + //int16 dshim24 = 0; + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; + + T->impuls_lenght_min = T->impuls_lenght_min + T->Ti; + T->counter_pass_min++; + + if (T->counter_pass_min <= 3) + { + if (T->impuls_lenght_min <= dmin) + { + T->Ti = 0; + } + else + { +// T->Ti = dmin; //T->impuls_lenght_min; +// T->impuls_lenght_min -= dmin;// = 0; + T->Ti = T->impuls_lenght_min; + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; +// if (T->impuls_lenght_min < 0) { +// T->counter_pass_min = 0; +// T->impuls_lenght_min = 0; +// } else { +// T->counter_pass_min -= 1; +// } + } + } + else + { + T->counter_pass_min = 1; + T->impuls_lenght_min = T->Ti; + T->Ti = 0; + } + } + else + { + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; + +// if (T->Ti > (dmax - dmin)) +// { +// dshim = dmax; +// } +// else +// { +// dshim = T->Ti; +// } + + if (T->Ti >= (dmax - dmin)) + { + T->impuls_lenght_max = T->impuls_lenght_max + (dmax - T->Ti - 1); + T->counter_pass_max++; + + if (T->counter_pass_max <= 3) + { + if (T->impuls_lenght_max <= dmin) + { + T->Ti = dmax; + } + else + { +// T->Ti = dmax - dmin; //T->impuls_lenght_max; +// T->impuls_lenght_max -= dmin;// = 0; + T->Ti = dmax - T->impuls_lenght_max; + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; +// if (T->impuls_lenght_max < 0) { +// T->impuls_lenght_max = 0; +// T->counter_pass_max = 0; +// } else { +// T->counter_pass_max -= 1; +// } + } + } + else + { + T->counter_pass_max = 1; + T->impuls_lenght_max = dmax - T->Ti; + T->Ti = dmax; + } + } + else + { + T->counter_pass_max = 0; + T->impuls_lenght_max = 0; + } + } + + //return dshim24; +} + + + +void init_alpha_pwm24(int xFreq) +{ + xFreq = xFreq + 1; + + svgen_pwm24_1.number_svgen = 1; + svgen_pwm24_2.number_svgen = 2; + + //pidCur_Kp = _IQ(PID_KP_DELTA_KOMP_I); + //pidCur_Ki = _IQ(PID_KI_DELTA_KOMP_I); + +// svgen_pwm24_1.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_1.saw_direct.all = xpwm_time.saw_direct.all & 0x3f; + svgen_pwm24_1.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_1.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_high; + +// svgen_pwm24_2.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_2.saw_direct.all = (xpwm_time.saw_direct.all >> 6) & 0x3f; + svgen_pwm24_2.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_2.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_high; + + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2); + + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; + + // 30 + svgen_pwm24_1.Alpha = 0; //winding_displacement; + svgen_pwm24_2.Alpha = -winding_displacement; + + svgen_pwm24_1.delta_t = 0; + svgen_pwm24_2.delta_t = 0; +} + +/* +void init_freq_array(void) +{ + unsigned int i = 0; + //unsigned int j = 0; + int var1 = 0; + + var1 = 32767 / (FREQ_PWM_MAX - FREQ_PWM_MIN); + + for (i = 0; i < COUNT_VAR_FREQ; i++) + { + //j = rand() / 1023; + //freq_array[i] = array_optim_freq[j]; + //do + freq_array[i] = FREQ_PWM_MIN + (rand() / var1); + //while ((freq_array[i] < 945) && (freq_array[i] > 930)); + } + + //freq_array[0] = 991; + //freq_array[1] = 1430; +} +*/ + + +//#pragma CODE_SECTION(calc_freq_pwm,".v_24pwm_run"); +//#pragma CODE_SECTION(calc_freq_pwm,".fast_run"); +/*void calc_freq_pwm() +{ + static int prev_freq_pwm = 0; + static float pwm_period = 0; + static float var0 = 0; + //static int line = 0; + //static int i = 0; + static unsigned int proc_ticks = 1; + int var1 = 0; + //static int i = 0; + + if ((f.flag_change_pwm_freq == 1) && (f.flag_random_freq == 1)) + { + if (proc_ticks >= 1) + { + proc_ticks = 0; + + + if (line == 0) + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ + 1; + if (VAR_FREQ_PWM_HZ > FREQ_PWM_MAX) + { + VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + line = 1; + } + } + else + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ - 1; + if (VAR_FREQ_PWM_HZ < FREQ_PWM) + { + VAR_FREQ_PWM_HZ = FREQ_PWM; + line = 0; + } + } + + + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //VAR_FREQ_PWM_HZ = freq_array[i]; + //i_led2_on_off(1); + + var1 = 32767 / (freq_pwm_max_hz - freq_pwm_min_hz); + VAR_FREQ_PWM_HZ = freq_pwm_min_hz + (rand() / var1); + + //i_led2_on_off(0); + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (VAR_FREQ_PWM_HZ > freq_pwm_max_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_max_hz; + } + else + { + if (VAR_FREQ_PWM_HZ < freq_pwm_min_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_min_hz; + } + } + //i++; + + //if (i >= COUNT_VAR_FREQ) + //{ + //i = 0; + //} + + } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //if (VAR_FREQ_PWM_HZ == FREQ_PWM_MIN) + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MIN; + //} + + //if (f.Rele1 == 1) + //{ + //if (i == 0) + //{ + //VAR_FREQ_PWM_HZ = 1192;; + //i = 1; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = 792; + //} + //} + //else + //{ + //i = 0; + //VAR_FREQ_PWM_HZ = 1192; + //} + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + } + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM; + //} + + + if (prev_freq_pwm != VAR_FREQ_PWM_HZ) + { + prev_freq_pwm = VAR_FREQ_PWM_HZ; + FREQ_MAX = _IQ(2.0*PI*F_STATOR_MAX/VAR_FREQ_PWM_HZ); + + var0 = (float)VAR_FREQ_PWM_HZ; + //pwm_period = ((float64)HSPCLK) / ((float64)VAR_FREQ_PWM_HZ); + + pwm_period = HSPCLK / var0; + + pwm_period = pwm_period / 2.0; + + FREQ_PWM_XTICS = ((int) pwm_period) >> 3; + + XILINX_FREQ = 16777216/(FREQ_PWM_XTICS + 1); + + FLAG_CHANGE_FREQ_PWM = 1; + } + + proc_ticks++; +} +*/ + +void change_freq_pwm(_iq xFreq) { + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/3750000 / xFreq / 2 /2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/ 3750000 / xFreq / 2 /2); + + xFreq += 1; + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; +} + +// #pragma CODE_SECTION(test_calc_pwm24_dq,".v_24pwm_run"); +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta) +{ + svgen_pwm24_1.Freq = 0; + svgen_pwm24_2.Freq = 0; + + svgen_pwm24_1.Gain = U_zad1; + svgen_pwm24_2.Gain = U_zad2; + + svgen_pwm24_1.Alpha = teta; + svgen_pwm24_2.Alpha = teta - winding_displacement; + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc_dq(&svgen_pwm24_1); + svgen_pwm24_2.calc_dq(&svgen_pwm24_2); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt) +{ + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Ta_1.Ti = 0; + + vt->Tb_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tb_1.Ti = 0; + + vt->Tc_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tc_1.Ti = 0; +} + +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = 0; + vt->Ta_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tb_0.Ti = 0; + vt->Tb_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tc_0.Ti = 0; + vt->Tc_1.Ti = VAR_FREQ_PWM_XTICS + 1; +} diff --git a/Inu/Src/main_matlab/xp_write_xpwm_time_matlab.c b/Inu/Src/main_matlab/xp_write_xpwm_time_matlab.c new file mode 100644 index 0000000..093b88c --- /dev/null +++ b/Inu/Src/main_matlab/xp_write_xpwm_time_matlab.c @@ -0,0 +1,361 @@ +/* + * xp_write_xpwm_time.c + * + * Created on: 03 àïð. 2018 ã. + * Author: stud + */ + +#include "xp_write_xpwm_time.h" +// #include "MemoryFunctions.h" +// #include "Spartan2E_Adr.h" +// #include "PWMTMSHandle.h" + +#include "def.h" + + +// #pragma DATA_SECTION(xpwm_time,".fast_vars1"); +XPWM_TIME xpwm_time = DEFAULT_XPWM_TIME; + +#define set_default_tclosed(k,b) {if (b) k = p->Tclosed_saw_direct_1; else k = p->Tclosed_saw_direct_0;} + +void initXpwmTimeStructure(XPWM_TIME *p) { + p->Ta0_0 = p->Tclosed_0; + p->Ta0_1 = p->Tclosed_1; + p->Tb0_0 = p->Tclosed_0; + p->Tb0_1 = p->Tclosed_1; + p->Tc0_0 = p->Tclosed_0; + p->Tc0_1 = p->Tclosed_1; + + p->Ta1_0 = p->Tclosed_0; + p->Ta1_1 = p->Tclosed_1; + p->Tb1_0 = p->Tclosed_0; + p->Tb1_1 = p->Tclosed_1; + p->Tc1_0 = p->Tclosed_0; + p->Tc1_1 = p->Tclosed_1; + + p->Tbr0_0 = 0; + p->Tbr0_1 = 0; + p->Tbr1_0 = 0; + p->Tbr1_1 = 0; +} + + +// ������� �������� ����� ��������������� � ������� +void xpwm_write_1_2_winding_break_times_16_lines(XPWM_TIME *p) { + +} + +// void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p) { + +// } +/* +//#pragma CODE_SECTION(xpwm_write_1_2_winding_break_times_16_lines,".fast_run1"); +void xpwm_write_1_2_winding_break_times_16_lines(XPWM_TIME *p) +{ + if(!(ReadMemory(ADR_ERRORS_TOTAL_INFO))) + { + WriteMemory(ADR_PWM_KEY_NUMBER, 0); + WriteMemory(ADR_PWM_TIMING, p->Ta0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 1); + WriteMemory(ADR_PWM_TIMING, p->Ta0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 2); + WriteMemory(ADR_PWM_TIMING, p->Tb0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 3); + WriteMemory(ADR_PWM_TIMING, p->Tb0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 4); + WriteMemory(ADR_PWM_TIMING, p->Tc0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 5); + WriteMemory(ADR_PWM_TIMING, p->Tc0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 6); + WriteMemory(ADR_PWM_TIMING, p->Ta1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 7); + WriteMemory(ADR_PWM_TIMING, p->Ta1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 8); + WriteMemory(ADR_PWM_TIMING, p->Tb1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 9); + WriteMemory(ADR_PWM_TIMING, p->Tb1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 10); + WriteMemory(ADR_PWM_TIMING, p->Tc1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 11); + WriteMemory(ADR_PWM_TIMING, p->Tc1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 12); + WriteMemory(ADR_PWM_TIMING, p->Tbr0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 13); + WriteMemory(ADR_PWM_TIMING, p->Tbr0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 14); + WriteMemory(ADR_PWM_TIMING, p->Tbr1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 15); + WriteMemory(ADR_PWM_TIMING, p->Tbr1_1); + } + else + { + WriteMemory(ADR_PWM_KEY_NUMBER, 0); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 1); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 2); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 3); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 4); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 5); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 6); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 7); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 8); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 9); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 10); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 11); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 12); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 13); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 14); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 15); + WriteMemory(ADR_PWM_TIMING, 0); + } +} +*/ +// #pragma CODE_SECTION(xpwm_write_1_2_winding_break_times_16_lines_split_eages,".fast_run1"); +void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p) +{ + // if (!(i_ReadMemory(ADR_ERRORS_TOTAL_INFO))) + { +//a + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit0==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta0_0); + EPwm2Regs.CMPA.half.CMPA = p->Ta0_0; + } + + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit1 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit1==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta0_1); + EPwm1Regs.CMPA.half.CMPA = p->Ta0_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit2 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit2==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb0_0); + EPwm4Regs.CMPA.half.CMPA = p->Tb0_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit3 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit3==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb0_1); + EPwm3Regs.CMPA.half.CMPA = p->Tb0_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit4 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit4==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc0_0); + EPwm6Regs.CMPA.half.CMPA = p->Tc0_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit5 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit5==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc0_1); + EPwm5Regs.CMPA.half.CMPA = p->Tc0_1; + } +//b + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit6 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit6==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta1_0); + EPwm8Regs.CMPA.half.CMPA = p->Ta1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit7 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit7==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta1_1); + EPwm7Regs.CMPA.half.CMPA = p->Ta1_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit8 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit8==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb1_0); + EPwm10Regs.CMPA.half.CMPA = p->Tb1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit9 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit9==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb1_1); + EPwm9Regs.CMPA.half.CMPA = p->Tb1_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit10 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit10==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc1_0); + EPwm12Regs.CMPA.half.CMPA = p->Tc1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit11 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit11==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc1_1); + EPwm11Regs.CMPA.half.CMPA = p->Tc1_1; + } + +//br1 br2 + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr0_0); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr0_1); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr1_0); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr1_1); + } +// else +// { +// // hard_stop_x24_pwm_all(); +// // stop_pwm(); +// xpwm_write_zero_winding_break_times_16_lines_split_eages(p); +// } +} +/* +// #pragma CODE_SECTION(xpwm_write_zero_1,".fast_run2"); +void xpwm_write_zero_1(XPWM_TIME *p) +{ + unsigned int tclose; + + //a + set_default_tclosed(tclose, p->saw_direct.bits.bit0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit1); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta0_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit2); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit3); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb0_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit4); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit5); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc0_1 = tclose; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_2,".fast_run1"); +void xpwm_write_zero_2(XPWM_TIME *p) +{ + unsigned int tclose; + +//b + set_default_tclosed(tclose, p->saw_direct.bits.bit6); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit7); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta1_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit8); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit9); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb1_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit10); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit11); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc1_1 = tclose; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_break_1,".fast_run2"); +void xpwm_write_zero_break_1(XPWM_TIME *p) +{ + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + + p->Tbr0_0 = 0; + p->Tbr0_1 = 0; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_break_2,".fast_run2"); +void xpwm_write_zero_break_2(XPWM_TIME *p) +{ + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + + p->Tbr1_0 = 0; + p->Tbr1_1 = 0; +} + +// #pragma CODE_SECTION(xpwm_write_zero_winding_break_times_16_lines_split_eages,".fast_run2"); +void xpwm_write_zero_winding_break_times_16_lines_split_eages(XPWM_TIME *p) +{ + xpwm_write_zero_1(p); + xpwm_write_zero_2(p); + xpwm_write_zero_break_1(p); + xpwm_write_zero_break_2(p); +} + +*/ + diff --git a/Inu/Src2/VectorControl/abc_to_alphabeta.c b/Inu/Src2/VectorControl/abc_to_alphabeta.c new file mode 100644 index 0000000..7f37475 --- /dev/null +++ b/Inu/Src2/VectorControl/abc_to_alphabeta.c @@ -0,0 +1,23 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "abc_to_alphabeta.h" + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(abc_to_alphabeta_calc,".fast_run"); +void abc_to_alphabeta_calc(ABC_TO_ALPHABETA *v) +{ + static _iq iq_1_sqrt3 = _IQ(0.57735026918962576450914878050196); // = 1/sqrt(3) + static _iq iq_2_sqrt3 = _IQ(1.1547005383792515290182975610039); // =2/sqrt(3) + + v->Ualpha = v->Ua; + v->Ubeta = _IQmpy(iq_1_sqrt3,v->Ua) + _IQmpy(iq_2_sqrt3,v->Ub); + +} + + + +///////////////////////////////////////////////// diff --git a/Inu/Src2/VectorControl/abc_to_alphabeta.h b/Inu/Src2/VectorControl/abc_to_alphabeta.h new file mode 100644 index 0000000..eb16b58 --- /dev/null +++ b/Inu/Src2/VectorControl/abc_to_alphabeta.h @@ -0,0 +1,39 @@ +#ifndef __ABC_ALPHABETA_H__ +#define __ABC_ALPHABETA_H__ + +#include "IQmathLib.h" + +typedef struct { _iq Ua; //phase A voltage, input + _iq Ub; //phase B voltage, input + _iq Uc; //phase C voltage, input +// _iq Tetta; //phase angle, input + _iq Ualpha; // axis d voltage, output + _iq Ubeta; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + }ABC_TO_ALPHABETA; + + + + + +typedef ABC_TO_ALPHABETA *ABC_TO_ALPHABETA_handle; + +#define ABC_TO_ALPHABETA_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))abc_to_alphabeta_calc\ + } + + +void abc_to_alphabeta_calc(ABC_TO_ALPHABETA_handle); + + + + + + + + +#endif // end __ABC_ALPHABETA_H diff --git a/Inu/Src2/VectorControl/abc_to_dq.c b/Inu/Src2/VectorControl/abc_to_dq.c new file mode 100644 index 0000000..39c414d --- /dev/null +++ b/Inu/Src2/VectorControl/abc_to_dq.c @@ -0,0 +1,38 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "abc_to_dq.h" + + + + + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(abc_to_dq_calc,".fast_run"); +void abc_to_dq_calc(ABC_TO_DQ *v) +{ + static _iq iq_two_third_pi = _IQ(6.283185307179586476925286766559/3.0); + static _iq iq_two_third = _IQ(2.0/3.0); + + v->Id = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQsin(v->Tetta)) + _IQmpy(v->Ib, _IQsin(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQsin(v->Tetta + iq_two_third_pi))); + v->Iq = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQcos(v->Tetta)) + _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); +} + + +#pragma CODE_SECTION(abc_to_dq_calc_v2,".fast_run"); +void abc_to_dq_calc_v2(ABC_TO_DQ *v) +{ + static _iq iq_two_third_pi = _IQ(6.283185307179586476925286766559/3.0); + static _iq iq_two_third = _IQ(2.0/3.0); + + v->Id = _IQmpy(iq_two_third,_IQmpy(v->Ia, _IQcos(v->Tetta)) + _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) + _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); + v->Iq = _IQmpy(iq_two_third,_IQmpy(-v->Ia, _IQsin(v->Tetta)) - _IQmpy(v->Ib, _IQcos(v->Tetta - iq_two_third_pi)) - _IQmpy(v->Ic, _IQcos(v->Tetta + iq_two_third_pi))); +} + + +///////////////////////////////////////////////// + + diff --git a/Inu/Src2/VectorControl/abc_to_dq.h b/Inu/Src2/VectorControl/abc_to_dq.h new file mode 100644 index 0000000..1afd618 --- /dev/null +++ b/Inu/Src2/VectorControl/abc_to_dq.h @@ -0,0 +1,42 @@ +#ifndef __ABC_DQ_H__ +#define __ABC_DQ_H__ + + + +typedef struct { _iq Ia; //phase A voltage, input + _iq Ib; //phase B voltage, input + _iq Ic; //phase C voltage, input + _iq Tetta; //phase angle, input + _iq Id; // axis d voltage, output + _iq Iq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + void (*calc_v2)(); // Pointer to calculation function + }ABC_TO_DQ; + + + + + +typedef ABC_TO_DQ *ABC_TO_DQ_handle; + +#define ABC_TO_DQ_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(_iq))abc_to_dq_calc, \ + (void (*)(_iq))abc_to_dq_calc_v2 } + + +void abc_to_dq_calc(ABC_TO_DQ_handle); +void abc_to_dq_calc_v2(ABC_TO_DQ_handle); + + + + + + + + +#endif // end __ABC_DQ_H diff --git a/Inu/Src2/VectorControl/alphabeta_to_abc.c b/Inu/Src2/VectorControl/alphabeta_to_abc.c new file mode 100644 index 0000000..a161888 --- /dev/null +++ b/Inu/Src2/VectorControl/alphabeta_to_abc.c @@ -0,0 +1,24 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "alphabeta_to_abc.h" + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(alphabeta_to_abc_calc,".fast_run"); +void alphabeta_to_abc_calc(ALPHABETA_TO_ABC *v) +{ + static _iq iq_0_5 = _IQ(0.5); // = 1/2 + static _iq iq_sqrt3_2 = _IQ(0.86602540378443864676372317075294); // =sqrt(3)/2 + + v->Ua = v->Ualpha; + v->Ub = -_IQmpy(iq_0_5,v->Ualpha) + _IQmpy(iq_sqrt3_2,v->Ubeta); + v->Uc = -_IQmpy(iq_0_5,v->Ualpha) - _IQmpy(iq_sqrt3_2,v->Ubeta); + +} + + + +///////////////////////////////////////////////// diff --git a/Inu/Src2/VectorControl/alphabeta_to_abc.h b/Inu/Src2/VectorControl/alphabeta_to_abc.h new file mode 100644 index 0000000..c5dca95 --- /dev/null +++ b/Inu/Src2/VectorControl/alphabeta_to_abc.h @@ -0,0 +1,38 @@ +#ifndef __ALPHABETA_ABC_H__ +#define __ALPHABETA_ABC_H__ + +#include "IQmathLib.h" + +typedef struct { _iq Ualpha; // axis d voltage, output + _iq Ubeta; // axis q voltage, output + _iq Ua; //phase A voltage, input + _iq Ub; //phase B voltage, input + _iq Uc; //phase C voltage, input + void (*calc)(); // Pointer to calculation function + }ALPHABETA_TO_ABC; + + + + + +typedef ALPHABETA_TO_ABC *ALPHABETA_TO_ABC_handle; + +#define ALPHABETA_TO_ABC_DEFAULTS{ 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))alphabeta_to_abc_calc\ + } + + +void alphabeta_to_abc_calc(ALPHABETA_TO_ABC_handle); + + + + + + + + +#endif // end __ALPHABETA_ABC_H__ diff --git a/Inu/Src2/VectorControl/alphabeta_to_dq.c b/Inu/Src2/VectorControl/alphabeta_to_dq.c new file mode 100644 index 0000000..026a212 --- /dev/null +++ b/Inu/Src2/VectorControl/alphabeta_to_dq.c @@ -0,0 +1,22 @@ +#include "IQmathLib.h" // Include header for IQmath library +#include "alphabeta_to_dq.h" + + + + + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(alphabeta_to_dq_calc,".fast_run"); +void alphabeta_to_dq_calc(ALPHABETA_TO_DQ *v) +{ + + v->Ud = _IQmpy(v->Ualpha, _IQcos(v->Tetta)) + _IQmpy(v->Ubeta, _IQsin(v->Tetta)); + v->Uq = -_IQmpy(v->Ualpha, _IQsin(v->Tetta)) + _IQmpy(v->Ubeta, _IQcos(v->Tetta)); + +} +///////////////////////////////////////////////// diff --git a/Inu/Src2/VectorControl/alphabeta_to_dq.h b/Inu/Src2/VectorControl/alphabeta_to_dq.h new file mode 100644 index 0000000..cd7ac27 --- /dev/null +++ b/Inu/Src2/VectorControl/alphabeta_to_dq.h @@ -0,0 +1,32 @@ +#ifndef __ALPHABETA_DQ_H__ +#define __ALPHABETA_DQ_H__ + +#include "IQmathLib.h" + +typedef struct { _iq Ualpha; //phase A voltage, input + _iq Ubeta; //phase B voltage, input + _iq Tetta; //phase angle, input + _iq Ud; // axis d voltage, output + _iq Uq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + }ALPHABETA_TO_DQ; + + + + + +typedef ALPHABETA_TO_DQ *ALPHABETA_TO_DQ_handle; + +#define ALPHABETA_TO_DQ_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))alphabeta_to_dq_calc \ + } + + +void alphabeta_to_dq_calc(ALPHABETA_TO_DQ_handle); + + +#endif // end __ALPHABETA_DQ_H diff --git a/Inu/Src2/VectorControl/dq_to_alphabeta_cos.c b/Inu/Src2/VectorControl/dq_to_alphabeta_cos.c new file mode 100644 index 0000000..e0dd2f8 --- /dev/null +++ b/Inu/Src2/VectorControl/dq_to_alphabeta_cos.c @@ -0,0 +1,39 @@ +#include "dq_to_alphabeta_cos.h" + +#include "IQmathLib.h" // Include header for IQmath library + + + + + +///////////////////////////////////////////////// + + +#pragma CODE_SECTION(dq_to_alphabeta_calc,".fast_run2"); +void dq_to_alphabeta_calc(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQcos(v->Tetta)) + _IQmpy(v->Uq, _IQsin(v->Tetta)); + v->Ubeta = -_IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + +} + + +#pragma CODE_SECTION(dq_to_alphabeta_calc2,".fast_run2"); +void dq_to_alphabeta_calc2(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + v->Ubeta = -_IQmpy(v->Ud, _IQcos(v->Tetta)) + _IQmpy(v->Uq, _IQsin(v->Tetta)); + +} + +#pragma CODE_SECTION(dq_to_alphabeta_calc_cos,".fast_run2"); +void dq_to_alphabeta_calc_cos(DQ_TO_ALPHABETA_handle v) +{ + + v->Ualpha = _IQmpy(v->Ud, _IQcos(v->Tetta)) - _IQmpy(v->Uq, _IQsin(v->Tetta)); + v->Ubeta = _IQmpy(v->Ud, _IQsin(v->Tetta)) + _IQmpy(v->Uq, _IQcos(v->Tetta)); + +} +///////////////////////////////////////////////// diff --git a/Inu/Src2/VectorControl/dq_to_alphabeta_cos.h b/Inu/Src2/VectorControl/dq_to_alphabeta_cos.h new file mode 100644 index 0000000..b261ced --- /dev/null +++ b/Inu/Src2/VectorControl/dq_to_alphabeta_cos.h @@ -0,0 +1,40 @@ + + + +#ifndef __DQ_ALPHABETA_H__ +#define __DQ_ALPHABETA_H__ + +#include "IQmathLib.h" + +typedef struct { _iq Ualpha; //phase A voltage, input + _iq Ubeta; //phase B voltage, input + _iq Tetta; //phase angle, input + _iq Ud; // axis d voltage, output + _iq Uq; // axis q voltage, output + void (*calc)(); // Pointer to calculation function + void (*calc2)(); // Pointer to calculation function. Like in MATLAB + void (*calc_cos)(); // Pointer to calculation function, Ualpha = Uq*Cos(Tetta) + }DQ_TO_ALPHABETA; + + + + + +typedef DQ_TO_ALPHABETA *DQ_TO_ALPHABETA_handle; + +#define DQ_TO_ALPHABETA_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(Uint32))dq_to_alphabeta_calc, \ + (void (*)(Uint32))dq_to_alphabeta_calc2, \ + (void (*)(Uint32))dq_to_alphabeta_calc_cos \ + } + + +void dq_to_alphabeta_calc(DQ_TO_ALPHABETA_handle); +void dq_to_alphabeta_calc2(DQ_TO_ALPHABETA_handle); +void dq_to_alphabeta_calc_cos(DQ_TO_ALPHABETA_handle); + +#endif // end __DQ_ALPHABETA_H__ diff --git a/Inu/Src2/VectorControl/efficiency_compensation.c b/Inu/Src2/VectorControl/efficiency_compensation.c new file mode 100644 index 0000000..16ab749 --- /dev/null +++ b/Inu/Src2/VectorControl/efficiency_compensation.c @@ -0,0 +1,107 @@ +#include "IQmathLib.h" +#include "efficiency_compensation.h" + + +static int DetectCommandRegion(_iq *power); + +/***********************************************************/ +/** +* +*Increases the power demand depending on the machine efficiency +* +*@param p_zad - pointer to demanded power +*@param i_q - pointer to value of active current +* +*@return return value throw the pointer +* +*************************************************************/ +void EfficiencyCompensation(_iq *p_zad, _iq *i_q) +{ + static _iq efficiency_nominal = 16139681L; //96.2% + static _iq i_q_nom_levels[] = {3635063L, 4395630L, 4977240L, 5536481L, 6011835L, 6487190L, + 6934582L, 7381975L, 7751073L, 8220835L}; + + /** + * Coefficients of a square trinomial calculating the correction + */ + static _iq a0[10] = {17585441L, 17401328L, 17206712L, 17060750L, 17074172L, 16904722L, + 17129537L, 17698285L, 17188257L, 17740228L}; + static _iq a1[10] = {-2030043L, -1358954L, -905969L, -587202L, -553648L, -318767L, + -536870L, -1224736L, -570425L, -1224736L}; + static _iq a2[10] = {-385875L, -385875L, -385875L, -402653L, -335544L, + -348966L, -234881L, 0L, -167772L, 50331L}; + _iq efficiency, p_local; + _iq i_q_abs; + int region = 0; + region = DetectCommandRegion(p_zad); + efficiency = efficiency_nominal; + i_q_abs = _IQabs(*i_q); + p_local = *p_zad; + + if (i_q_abs <= i_q_nom_levels[region]) { + *p_zad = _IQdiv(*p_zad, efficiency_nominal); + return; + } + /** + * This is because of all electric values are normalized by 3000, + * but in a model in this place the current is normalized by 1000. + */ + i_q_abs = i_q_abs * 3; + efficiency = _IQmpy(i_q_abs, i_q_abs); + efficiency = a0[region] + _IQmpy(a1[region], i_q_abs) + _IQmpy(a2[region], efficiency); + p_local = _IQdiv(p_local, efficiency); + *p_zad = p_local; +} + + + +#define BOUND_1p5_MWT 2796202L +#define BOUND_2p5_MWT 4660337L +#define BOUND_3p5_MWT 6524472L +#define BOUND_4p5_MWT 8388608L +#define BOUND_6p5_MWT 12116878L +#define BOUND_7p5_MWT 13981013L +#define BOUND_8p5_MWT 15845148L +#define BOUND_5p5_MWT 10252743L +#define BOUND_9p5_MWT 17709283L + +/**************************************************************/ +/** + * Detects command mode: + * 0 corresponds to 1 MWt + * 1 - 2 MWt + * ... + * 9 - 10 MWt + * + * @param power - pointer to demanded power in watts + * + * @return corresponding mode + */ +int DetectCommandRegion(_iq *power) +{ + int region = 0; + if (*power < BOUND_1p5_MWT) + { + region = 0; + } else if (*power < BOUND_2p5_MWT) { + region = 1; + } else if (*power < BOUND_3p5_MWT) { + region = 2; + } else if (*power < BOUND_4p5_MWT) { + region = 3; + } else if (*power < BOUND_5p5_MWT) { + region = 4; + } else if (*power < BOUND_6p5_MWT) { + region = 5; + } else if (*power < BOUND_7p5_MWT) { + region = 6; + } else if (*power < BOUND_8p5_MWT) { + region = 7; + } else if (*power < BOUND_9p5_MWT) { + region = 8; + } else { + region = 9; + } + + return region; +} diff --git a/Inu/Src2/VectorControl/efficiency_compensation.h b/Inu/Src2/VectorControl/efficiency_compensation.h new file mode 100644 index 0000000..f1d744b --- /dev/null +++ b/Inu/Src2/VectorControl/efficiency_compensation.h @@ -0,0 +1,13 @@ +/* + * efficiency_compensation.h + * + * Created on: 26 ����. 2018 �. + * Author: stud + */ + +#ifndef SRC_VECTORCONTROL_EFFICIENCY_COMPENSATION_H_ +#define SRC_VECTORCONTROL_EFFICIENCY_COMPENSATION_H_ + +void EfficiencyCompensation(_iq *p_zad, _iq *i_q); + +#endif /* SRC_VECTORCONTROL_EFFICIENCY_COMPENSATION_H_ */ diff --git a/Inu/Src2/VectorControl/params_motor.h b/Inu/Src2/VectorControl/params_motor.h new file mode 100644 index 0000000..5f050ca --- /dev/null +++ b/Inu/Src2/VectorControl/params_motor.h @@ -0,0 +1,23 @@ +/* + * params_motor.h + * + * Created on: 14 ����. 2020 �. + * Author: yura + */ + +#ifndef SRC_MAIN_PARAMS_MOTOR_H_ +#define SRC_MAIN_PARAMS_MOTOR_H_ + + +#define L_SIGMA_S 0.000964 +#define L_SIGMA_R 0.001134 +#define L_M 0.03889 +#define R_STATOR 0.0118 +#define R_ROTOR_SHTRIH 0.0111 +#define SLIP_NOM 0.0106 +#define R_ROTOR (R_ROTOR_SHTRIH / SLIP_NOM) +#define F_STATOR_NOM 12.0 + + + +#endif /* SRC_MAIN_PARAMS_MOTOR_H_ */ diff --git a/Inu/Src2/VectorControl/pwm_vector_regul.c b/Inu/Src2/VectorControl/pwm_vector_regul.c new file mode 100644 index 0000000..3a45fc4 --- /dev/null +++ b/Inu/Src2/VectorControl/pwm_vector_regul.c @@ -0,0 +1,666 @@ +#include "IQmathLib.h" +#include "math.h" +#include "my_filter.h" +#include "params.h" +#include "adc_tools.h" +#include "abc_to_dq.h" +#include "regul_power.h" +#include "regul_turns.h" +#include "teta_calc.h" +#include "pwm_vector_regul.h" +#include "pid_reg3.h" +#include "vector.h" +#include "params_motor.h" +#include "v_pwm24.h" +//#include "power_distribution.h" +#include "rotation_speed.h" +//#include "calc_3_power.h" + +// #pragma DATA_SECTION(pidD,".fast_vars1"); +// PIDREG3 pidD = PIDREG3_UNDEPENDENT_DEFAULTS; +PIDREG3 pidD = PIDREG3_DEFAULTS; +// #pragma DATA_SECTION(pidQ,".fast_vars1"); +// PIDREG3 pidQ = PIDREG3_UNDEPENDENT_DEFAULTS; +PIDREG3 pidQ = PIDREG3_DEFAULTS; + +// #pragma DATA_SECTION(pidD2,".fast_vars1"); +// PIDREG3 pidD2 = PIDREG3_UNDEPENDENT_DEFAULTS; +PIDREG3 pidD2 = PIDREG3_DEFAULTS; +// #pragma DATA_SECTION(pidQ2,".fast_vars1"); +// PIDREG3 pidQ2 = PIDREG3_UNDEPENDENT_DEFAULTS; +PIDREG3 pidQ2 = PIDREG3_DEFAULTS; + +// #pragma DATA_SECTION(cos_fi,".fast_vars1"); +COS_FI_STRUCT cos_fi = {0,0}; + +// #pragma DATA_SECTION(vect_control,".fast_vars1"); +VECTOR_CONTROL vect_control = VECTOR_CONTROL_DEFAULTS; + +// #pragma DATA_SECTION(koeff_Fs_filter,".fast_vars"); +long koeff_Fs_filter = _IQ(0.01); + +// _iq winding_displacement = FIXED_PIna6; + +WINDING a; +FLAG f; + + +ROTOR_VALUE rotor = ROTOR_VALUE_DEFAULTS; + +#define IQ_ONE 16777216 + +#define CONST_IQ_2PI 105414357 +#define CONST_IQ_2PI3 35138119 // 120 grad +#define CONST_IQ_PI2 26340229 + +#define K_MODUL_MIN 167772 //83886 //0.5% - ����������� ��-�� �������������� +#define K_MODUL_MAX 15435038LL //13421772LL //80% 16106127LL ~ 96% //15435038LL ~ 0.92% + //15770583LL ~ 0.94% +#define K_MODUL_MAX_PART 15099494LL // 15099494LL ~ 0.9 + +#define I_ZERO_LEVEL_IQ 111848 //20A //279620 ~ 50A //55924 ~ 10A +#define K_MODUL_DEAD_TIME 503316 //3% + +//#define I_ZERO_LEVEL_IQ 27962 //5A //55924 ~ 10A + +#define Id_MIN 1118481 //200A //111848 ~ 20A //55924 ~ 10A + +// #pragma DATA_SECTION(zadan_Id_min,".fast_vars"); +_iq zadan_Id_min = Id_MIN; + +#define START_TETTA_IQ 4392264 //15 grad + +void analog_dq_calc(void); +void analog_Udq_calc(_iq Ud1, _iq Uq1, _iq Ud2, _iq Uq2); +void calcUdUqCompensation(_iq Frot); + +float kI_D = 0.2; +float kI_Q = 0.2; +float kP_D = 0.1;//.1; +float kP_Q = 0.3;//.3; + +// float kI_D_rev = 0.02; +// float kI_Q_rev = 0.03; +// float kP_D_rev = 0.1;//.3; +// float kP_Q_rev = 0.15;//.3; + +void init_DQ_pid() +{ + unsigned int i = 0; + int *pStr = (int*)&f; + for (i = 0; i < sizeof(f) / sizeof(int); i++) { + *(pStr + i) = 0; + } + + *pStr = (int*)&a; + for (i = 0; i < sizeof(a) / sizeof(int); i++) { + *(pStr + i) = 0; + } + + pidD.Ref = 0; + pidD.Kp = _IQ(kP_D);//_IQ(0.2); //_IQ(0.1); + pidD.Ki = _IQ(kI_D); //_IQ(0.2);// // + pidD.Kc = _IQ(0.3); + pidD.Kd = 0; + pidD.OutMax = K_MODUL_MAX_PART; + pidD.OutMin = -K_MODUL_MAX_PART; //0; + pidD.Up = 0; + pidD.Ui = 0; + pidD.Ud = 0; + pidD.Out = 0; + + pidQ.Ref = 0; + pidQ.Kp = _IQ(kP_Q);//_IQ(0.3);//_IQ(0.3); + pidQ.Ki = _IQ(kI_Q); //_IQ(0.2); // + pidQ.Kc = _IQ(0.3); + pidQ.Kd = 0; + pidQ.OutMax = K_MODUL_MAX_PART; //_IQ(0.9); + pidQ.OutMin = -K_MODUL_MAX_PART; //-_IQ(0.9); //0; + pidQ.Up = 0; + pidQ.Ui = 0; + pidQ.Ud = 0; + pidQ.Out = 0; + + pidD2.Ref = 0; + pidD2.Kp = _IQ(kP_D);//_IQ(0.1); //_IQ(0.1); + pidD2.Ki = _IQ(kI_D); //_IQ(0.2);// // + pidD2.Kc = _IQ(0.3); + pidD2.Kd = 0; + pidD2.OutMax = K_MODUL_MAX_PART; + pidD2.OutMin = -K_MODUL_MAX_PART; //0; + pidD2.Up = 0; + pidD2.Ui = 0; + pidD2.Ud = 0; + pidD2.Out = 0; + + pidQ2.Ref = 0; + pidQ2.Kp = _IQ(kP_Q);// _IQ(0.3);//_IQ(0.3); + pidQ2.Ki = _IQ(kI_Q); //_IQ(0.2); // + pidQ2.Kc = _IQ(0.3); + pidQ2.Kd = 0; + pidQ2.OutMax = K_MODUL_MAX_PART; //_IQ(0.9); + pidQ2.OutMin = -K_MODUL_MAX_PART; //-_IQ(0.9); //0; + pidQ2.Up = 0; + pidQ2.Ui = 0; + pidQ2.Ud = 0; + pidQ2.Out = 0; + + init_tetta_pid(); + init_Fvect_pid(); + init_Pvect_pid(); + init_tetta_calc_struct(); + + init_Adc_Variables(); + + cos_fi.cos_fi_nom = _IQ(0.87); + cos_fi.cos_fi_nom_squared = _IQ(0.87 * 0.87); + // cos_fi.cos_fi_nom = _IQ(COS_FI); + // cos_fi.cos_fi_nom_squared = _IQ(COS_FI * COS_FI); + + vect_control.koef_Ud_comp = _IQ((L_SIGMA_S + L_M * L_SIGMA_R / (L_M + L_SIGMA_R)) * 2 * 3.14 * NORMA_FROTOR); //Lsigm_s + Lm*Lsigm_r / (Lm + Lsigm_r) + vect_control.koef_Uq_comp = _IQ((L_M + L_SIGMA_S) * 2 * 3.14 * NORMA_FROTOR); + vect_control.k_modul_max = K_MODUL_MAX; + vect_control.k_modul_max_square = _IQmpy(K_MODUL_MAX, K_MODUL_MAX); + vect_control.iq_Id_out_max = _IQ(ID_OUT_SAT_POWER_LOW_SPEED / NORMA_ACP); + + vect_control.koeff_correct_Id = IQ_ONE; + + vect_control.equial_Iq_Proportional = _IQ(0.05); + vect_control.flag_reverse = 0; +} + +void reset_DQ_pid() +{ + pidD.Up = 0; + pidD.Up1 = 0; + pidD.Ui = 0; + pidD.Ud = 0; + pidD.Out = 0; + pidQ.Up = 0; + pidQ.Up1 = 0; + pidQ.Ui = 0; + pidQ.Ud = 0; + pidQ.Out = 0; + + pidD2.Up = 0; + pidD2.Up1 = 0; + pidD2.Ui = 0; + pidD2.Ud = 0; + pidD2.Out = 0; + pidQ2.Up = 0; + pidQ2.Up1 = 0; + pidQ2.Ui = 0; + pidQ2.Ud = 0; + pidQ2.Out = 0; +} + +// #pragma CODE_SECTION(Idq_to_Udq,".fast_run2"); +void Idq_to_Udq(_iq Id_zad, _iq Iq_zad, _iq Id_measured, _iq Iq_measured, _iq* Ud_zad, _iq* Uq_zad) +{ + pidD.Ref = Id_zad; + pidD.Fdb = Id_measured; + pidD.calc(&pidD); + *Ud_zad = pidD.Out; + + pidQ.Ref = Iq_zad; + pidQ.Fdb = Iq_measured; + pidQ.calc(&pidQ); + *Uq_zad = pidQ.Out; + +} + +// inline void set_pid_coeffs() { +// if (vect_control.flag_reverse == 0) { +// pidD.Kp = _IQ(kP_D);//_IQ(0.2); //_IQ(0.1); +// pidD.Ki = _IQ(kI_D); //_IQ(0.2);// // +// pidQ.Kp = _IQ(kP_Q);//_IQ(0.3);//_IQ(0.3); +// pidQ.Ki = _IQ(kI_Q); //_IQ(0.2); // +// pidD2.Kp = _IQ(kP_D);//_IQ(0.1); //_IQ(0.1); +// pidD2.Ki = _IQ(kI_D); //_IQ(0.2);// // +// pidQ2.Kp = _IQ(kP_Q);// _IQ(0.3);//_IQ(0.3); +// pidQ2.Ki = _IQ(kI_Q); //_IQ(0.2); // +// } else { +// pidD.Kp = _IQ(kP_D_rev);//_IQ(0.2); //_IQ(0.1); +// pidD.Ki = _IQ(kI_D_rev); //_IQ(0.2);// // +// pidQ.Kp = _IQ(kP_Q_rev);//_IQ(0.3);//_IQ(0.3); +// pidQ.Ki = _IQ(kI_Q_rev); //_IQ(0.2); // +// pidD2.Kp = _IQ(kP_D_rev);//_IQ(0.1); //_IQ(0.1); +// pidD2.Ki = _IQ(kI_D_rev); //_IQ(0.2);// // +// pidQ2.Kp = _IQ(kP_Q_rev);// _IQ(0.3);//_IQ(0.3); +// pidQ2.Ki = _IQ(kI_Q_rev); //_IQ(0.2); // +// } +// } + +void Idq_to_Udq_2_windings(_iq Id_zad, _iq Iq_zad, _iq Id_measured1, _iq Iq_measured1, _iq* Ud_zad1, _iq* Uq_zad1 + , _iq Id_measured2, _iq Iq_measured2, _iq* Ud_zad2, _iq* Uq_zad2) +{ + pidD.Ref = Id_zad; + pidD.Fdb = Id_measured1; + pidD.calc(&pidD); + *Ud_zad1 = pidD.Out; + + pidQ.Ref = Iq_zad; + pidQ.Fdb = Iq_measured1; + pidQ.calc(&pidQ); + *Uq_zad1 = pidQ.Out; + + pidD2.Ref = Id_zad; + pidD2.Fdb = Id_measured2; + pidD2.calc(&pidD2); + *Ud_zad2 = pidD2.Out; + + pidQ2.Ref = Iq_zad; + pidQ2.Fdb = Iq_measured2; + pidQ2.calc(&pidQ2); + *Uq_zad2 = pidQ2.Out; +} + +// #pragma CODE_SECTION(pwm_vector_model_titov,".fast_run"); +void pwm_vector_model_titov(_iq Pzad, _iq Fzad, int direction, _iq Frot, int mode, + int reset, int calcPWMtimes) +{ + int calc_channel = 1; + _iq U_zad1 = 0, U_zad2 = 0; + + + // if (f.flag_leading == 0 && f.read_task_from_optical_bus == 1 && f.sync_rotor_from_optical_bus == 1) { + // Frot = rotor.iqFrotFromOptica; + // } + + //��������� Id ��� ���������� ����������� �������� + if (_IQabs(Frot) > IQ_F_ROTOR_NOM) { + vect_control.koeff_correct_Id = _IQdiv(IQ_F_ROTOR_NOM, _IQabs(Frot)); + } else { + vect_control.koeff_correct_Id = IQ_ONE; + } + + + if(direction < 0) { Frot = -Frot; } +// prev_dir = direction; + if(reset == 1) //����� ���������� �������-���� �����-���� + { + reset_DQ_pid(); + reset_tetta_pid(); + analog.iqIq1_filter = 0; + analog.iqIq2_filter = 0; + analog.iqUq2_filter = 0; + U_zad1 = K_MODUL_MIN; + U_zad2 = K_MODUL_MIN; + vect_control.iq_Id_out_max = Id_out_max_low_speed; + vect_control.flag_reverse = 0; + } + + set_cos_tetta_calc_params(); + analog_dq_calc(); + + + vector_turns(Fzad, Frot, analog.iqIq1, mode, &vect_control.iqIq_zad, &vect_control.iqId_zad); + vector_power(Pzad, analog.iqPvsi1 + analog.iqPvsi2, analog.iqIq1, mode, Frot, &vect_control.iqIq_zad, &vect_control.iqId_zad); + + vect_control.iqPzad = pidPvect.Ref; + vect_control.iqPizm = pidPvect.Fdb; + vect_control.iqFrot = Frot; + + // ������� ������������ �������� Id + if (vect_control.iqId_zad < Id_MIN) { vect_control.iqId_zad = zadan_Id_min; } + + //��������� Id ��� ���������� ����������� �������� + // if (_IQabs(Frot) > IQ_F_ROTOR_NOM) { + // vect_control.iqId_zad = _IQmpy(vect_control.iqId_zad, vect_control.koeff_correct_Id); + // } + + +// Frot =_IQ(15.0 / 6 / NORMA_FROTOR); +// vect_control.iqIq_zad = _IQ(IQ_OUT_NOM / NORMA_ACP); +// vect_control.iqId_zad = 0;// _IQ(789.0 / NORMA_ACP); + + // set_pid_coeffs(); + Idq_to_Udq_2_windings(vect_control.iqId_zad, vect_control.iqIq_zad, analog.iqId1, analog.iqIq1, &vect_control.iqUdKm1, &vect_control.iqUqKm1, + analog.iqId2, analog.iqIq2, &vect_control.iqUdKm2, &vect_control.iqUqKm2); + + + calc_tetta_Id(Frot, vect_control.iqId_zad, vect_control.iqIq_zad, &analog.tetta, &analog.Fsl, &analog.iqFstator, reset); + filter.Fsl = exp_regul_iq(koeff_Fs_filter, filter.Fsl, analog.Fsl); + + // analog.tetta = _IQ(vect_control.theta); + analog.iqIq_zadan = vect_control.iqIq_zad; + + // calcUdUqCompensation(Frot); //TODO: test on power after testing rotating + vect_control.iqUdKm1Out = vect_control.iqUdKm1; + vect_control.iqUqKm1Out = vect_control.iqUqKm1; + vect_control.iqUdKm2Out = vect_control.iqUdKm2; + vect_control.iqUqKm2Out = vect_control.iqUqKm2; + + if(vect_control.iqUdKm1Out > K_MODUL_MAX_PART) { vect_control.iqUdKm1Out = K_MODUL_MAX_PART;} + if(vect_control.iqUdKm1Out < -K_MODUL_MAX_PART) { vect_control.iqUdKm1Out = -K_MODUL_MAX_PART;} + if(vect_control.iqUqKm1Out > K_MODUL_MAX_PART) { vect_control.iqUqKm1Out = K_MODUL_MAX_PART;} + if(vect_control.iqUqKm1Out < -K_MODUL_MAX_PART) { vect_control.iqUqKm1Out = -K_MODUL_MAX_PART;} + + if(vect_control.iqUdKm2Out > K_MODUL_MAX_PART) { vect_control.iqUdKm2Out = K_MODUL_MAX_PART;} + if(vect_control.iqUdKm2Out < -K_MODUL_MAX_PART) { vect_control.iqUdKm2Out = -K_MODUL_MAX_PART;} + if(vect_control.iqUqKm2Out > K_MODUL_MAX_PART) { vect_control.iqUqKm2Out = K_MODUL_MAX_PART;} + if(vect_control.iqUqKm2Out < -K_MODUL_MAX_PART) { vect_control.iqUqKm2Out = -K_MODUL_MAX_PART;} + + U_zad1 = _IQsqrt(_IQmpy(vect_control.iqUdKm1Out, vect_control.iqUdKm1Out) + _IQmpy(vect_control.iqUqKm1Out, vect_control.iqUqKm1Out)); + U_zad2 = _IQsqrt(_IQmpy(vect_control.iqUdKm2Out, vect_control.iqUdKm2Out) + _IQmpy(vect_control.iqUqKm2Out, vect_control.iqUqKm2Out)); + vect_control.iqUzad1 = U_zad1; + vect_control.iqUzad2 = U_zad2; + + if (U_zad1 > vect_control.k_modul_max) { + if (vect_control.iqUqKm1Out > 0) { + vect_control.iqUqKm1Out = _IQsqrt(vect_control.k_modul_max_square - _IQmpy(vect_control.iqUdKm1Out, vect_control.iqUdKm1Out)); + } else { + vect_control.iqUqKm1Out = -_IQsqrt(vect_control.k_modul_max_square - _IQmpy(vect_control.iqUdKm1Out, vect_control.iqUdKm1Out)); + } + } + if (U_zad2 > vect_control.k_modul_max) { + if (vect_control.iqUqKm2Out > 0) { + vect_control.iqUqKm2Out = _IQsqrt(vect_control.k_modul_max_square - _IQmpy(vect_control.iqUdKm2Out, vect_control.iqUdKm2Out)); + } else { + vect_control.iqUqKm2Out = -_IQsqrt(vect_control.k_modul_max_square - _IQmpy(vect_control.iqUdKm2Out, vect_control.iqUdKm2Out)); + } + } + + // ����������� ��������� Iq ����� ����� ��������� + // vect_control.equial_Iq_Delta = analog.iqIq1 - analog.iqIq2; + // vect_control.equial_Iq_Out = _IQmpy(vect_control.equial_Iq_Delta, + // vect_control.equial_Iq_Proportional); + // vect_control.iqUqKm1Out -= vect_control.equial_Iq_Out; + // vect_control.iqUqKm2Out += vect_control.equial_Iq_Out; + + // if (U_zad1 < K_MODUL_DEAD_TIME) { + // vect_control.iqUdKm1 = 0; + // vect_control.iqUqKm1 = 0; + // } + // if (U_zad2 < K_MODUL_DEAD_TIME) { + // vect_control.iqUdKm2 = 0; + // vect_control.iqUqKm2 = 0; + // } + + vect_control.iqUzad1 = _IQsqrt(_IQmpy(vect_control.iqUdKm1Out, vect_control.iqUdKm1Out) + _IQmpy(vect_control.iqUqKm1Out, vect_control.iqUqKm1Out)); + vect_control.iqUzad2 = _IQsqrt(_IQmpy(vect_control.iqUdKm2Out, vect_control.iqUdKm2Out) + _IQmpy(vect_control.iqUqKm2Out, vect_control.iqUqKm2Out)); + + analog_Udq_calc(vect_control.iqUdKm1, vect_control.iqUqKm1, vect_control.iqUdKm2, vect_control.iqUqKm2); + + + if(mode == 0) // �����-�� ��� ������ ����� ��� ��������� + { + U_zad1 = K_MODUL_MIN; + U_zad2 = K_MODUL_MIN; + vect_control.iqUdKm1Out = 0; + vect_control.iqUqKm1Out = 0; + vect_control.iqUdKm2Out = 0; + vect_control.iqUqKm2Out = 0; +// teta_st = analog.tetta; + } + + a.iqk1 = vect_control.iqUzad1; +// analog.iqUdKm = Ud_zad; +// analog.iqUqKm = Uq_zad; +// analog.iqId_zad = vect_control.iqId_zad; + + + if(mode && f.Go && calcPWMtimes) + { + test_calc_dq_pwm24(vect_control.iqUdKm1Out, vect_control.iqUqKm1Out, vect_control.iqUdKm2Out, vect_control.iqUqKm2Out, analog.tetta,K_MODUL_MAX); + } + + +} + + + +// #pragma DATA_SECTION(koeff_Iq_filter_slow,".fast_vars"); +long koeff_Iq_filter_slow = _IQ(0.5); //_IQ(0.3); +// #pragma DATA_SECTION(koeff_Idq_filter,".fast_vars"); +long koeff_Idq_filter = _IQ(0.15); +// #pragma DATA_SECTION(koeff_Uq_filter,".fast_vars"); +long koeff_Uq_filter = 500; +// #pragma DATA_SECTION(koeff_Ud_filter,".fast_vars"); +long koeff_Ud_filter = _IQ(0.5); + + +// #pragma CODE_SECTION(analog_dq_calc,".fast_run"); +void analog_dq_calc() +{ + ABC_TO_DQ abc_dq_converter = ABC_TO_DQ_DEFAULTS; + + abc_dq_converter.Ia = analog.iqIa1_1; + abc_dq_converter.Ib = analog.iqIb1_1; + abc_dq_converter.Ic = analog.iqIc1_1; + abc_dq_converter.Tetta = analog.tetta; + abc_dq_converter.calc(&abc_dq_converter); + analog.iqId1 = abc_dq_converter.Id; + filter.iqId1 = exp_regul_iq(koeff_Idq_filter, filter.iqId1, analog.iqId1); + analog.iqIq1 = abc_dq_converter.Iq; + filter.iqIq1 = exp_regul_iq(koeff_Idq_filter, filter.iqIq1, analog.iqIq1); +// analog.iqIq1_filter = zad_intensiv_q(koeff_Iq_filter_slow, koeff_Iq_filter_slow, +// analog.iqIq1_filter, analog.iqIq1); + analog.iqIq1_filter = exp_regul_iq(koeff_Iq_filter_slow, analog.iqIq1_filter, analog.iqIq1); + + abc_dq_converter.Ia = analog.iqIa2_1; + abc_dq_converter.Ib = analog.iqIb2_1; + abc_dq_converter.Ic = analog.iqIc2_1; + abc_dq_converter.Tetta = analog.tetta - winding_displacement; + abc_dq_converter.calc(&abc_dq_converter); + analog.iqId2 = abc_dq_converter.Id; + filter.iqId2 = exp_regul_iq(koeff_Idq_filter, filter.iqId2, analog.iqId2); + analog.iqIq2 = abc_dq_converter.Iq; + filter.iqIq2 = exp_regul_iq(koeff_Idq_filter, filter.iqIq2, analog.iqIq2); +// analog.iqIq2_filter = zad_intensiv_q(koeff_Iq_filter_slow, koeff_Iq_filter_slow, +// analog.iqIq2_filter, analog.iqIq2); + analog.iqIq2_filter = exp_regul_iq(koeff_Iq_filter_slow, analog.iqIq2_filter, analog.iqIq2); + + if (_IQabs(analog.iqId1) < I_ZERO_LEVEL_IQ) { analog.iqId1 = 0; } + if (_IQabs(analog.iqIq1) < I_ZERO_LEVEL_IQ) { analog.iqIq1 = 0; } + if (_IQabs(analog.iqId2) < I_ZERO_LEVEL_IQ) { analog.iqId2 = 0; } + if (_IQabs(analog.iqIq2) < I_ZERO_LEVEL_IQ) { analog.iqIq2 = 0; } + +// analog.iqPvsi1 = _IQmpy(_IQmpy(analog.iqIq1_filter, analog.iqUq1), 25165824L); +// analog.iqPvsi2 = _IQmpy(_IQmpy(analog.iqIq2_filter, analog.iqUq2), 25165824L); + + analog.iqPvsi1 = _IQmpy(_IQmpy(analog.iqIq1_filter, _IQabs(analog.iqUq1)), 25165824L); + analog.iqPvsi2 = _IQmpy(_IQmpy(analog.iqIq2_filter, _IQabs(analog.iqUq2)), 25165824L); + +// analog.iqM_1 = _IQdiv(analog.iqPvsi1, _IQmpy(rotor.iqW, CONST_IQ_2PI)); +// analog.iqM_2 = _IQdiv(analog.iqPvsi2, _IQmpy(rotor.iqW, CONST_IQ_2PI)); +// logpar.log11 = (int16)_IQtoIQ15(analog.iqIq1_filter); +} + +// #pragma CODE_SECTION(analog_Udq_calc,".fast_run"); +void analog_Udq_calc(_iq Ud1, _iq Uq1, _iq Ud2, _iq Uq2) +{ + analog.iqUd1 = _IQmpy(Ud1, _IQmpy((filter.iqU_1_long + filter.iqU_2_long), 8388608L)); // 8388608 = _IQ(0.5) + analog.iqUq1 = _IQmpy(Uq1, _IQmpy((filter.iqU_1_long + filter.iqU_2_long), 8388608L)); + analog.iqUd2 = _IQmpy(Ud2, _IQmpy((filter.iqU_3_long + filter.iqU_4_long), 8388608L)); + analog.iqUq2 = _IQmpy(Uq2, _IQmpy((filter.iqU_3_long + filter.iqU_4_long), 8388608L)); + + filter.iqUd1 = exp_regul_iq(koeff_Ud_filter, filter.iqUd1, analog.iqUd1); + +} + + +//#pragma CODE_SECTION(analog_dq_calc_const,".fast_run"); +void analog_dq_calc_const() +{ + ABC_TO_DQ abc_dq_converter = ABC_TO_DQ_DEFAULTS; + + abc_dq_converter.Ia = analog.iqIa1_1; + abc_dq_converter.Ib = analog.iqIb1_1; + abc_dq_converter.Ic = analog.iqIc1_1; + abc_dq_converter.Tetta = analog.tetta; // svgen_pwm24_1.Alpha; + abc_dq_converter.calc(&abc_dq_converter); + analog.iqId1 = abc_dq_converter.Id; + analog.iqIq1 = abc_dq_converter.Iq; + analog.iqIq1_filter = zad_intensiv_q(koeff_Iq_filter_slow, koeff_Iq_filter_slow, + analog.iqIq1_filter, analog.iqIq1); + + abc_dq_converter.Ia = analog.iqIa2_1; + abc_dq_converter.Ib = analog.iqIb2_1; + abc_dq_converter.Ic = analog.iqIc2_1; + abc_dq_converter.Tetta = analog.tetta; // svgen_pwm24_2.Alpha; + abc_dq_converter.calc(&abc_dq_converter); + analog.iqId2 = abc_dq_converter.Id; + analog.iqIq2 = abc_dq_converter.Iq; + analog.iqIq2_filter = zad_intensiv_q(koeff_Iq_filter_slow, koeff_Iq_filter_slow, + analog.iqIq2_filter, analog.iqIq2); + + analog.iqPvsi1 = _IQmpy(_IQmpy(analog.iqIq1_filter, analog.iqUq1), 25165824L); + analog.iqPvsi2 = _IQmpy(_IQmpy(analog.iqIq2_filter, analog.iqUq2), 25165824L); +// analog.iqPvsi1 = _IQmpy(_IQmpy(analog.iqIq1, analog.iqUq1), 25165824L); +// analog.iqPvsi2 = _IQmpy(_IQmpy(analog.iqIq2, analog.iqUq2), 25165824L); + +// analog.iqM_1 = _IQdiv(analog.iqPvsi1, _IQmpy(rotor.iqW, CONST_IQ_2PI)); +// analog.iqM_2 = _IQdiv(analog.iqPvsi2, _IQmpy(rotor.iqW, CONST_IQ_2PI)); +} + +void calcUdUqCompensation(_iq Frot) { + _iq Uzpt = (filter.iqU_1_long + filter.iqU_2_long) >> 1; + _iq UdVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Ud_comp), analog.iqIq1); + _iq UqVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Uq_comp), analog.iqId1); + if (Uzpt != 0) { + vect_control.iqUdCompensation1 = -_IQdiv(UdVolt, Uzpt); + vect_control.iqUqCompensation1 = _IQdiv(UqVolt, Uzpt); + } else { + vect_control.iqUdCompensation1 = 0; + vect_control.iqUqCompensation1 = 0; + } + + vect_control.iqUdKm1Out = vect_control.iqUdKm1 + vect_control.iqUdCompensation1; + vect_control.iqUqKm1Out = vect_control.iqUqKm1 + vect_control.iqUqCompensation1; + + Uzpt = (filter.iqU_3_long + filter.iqU_4_long) >> 1; + UdVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Ud_comp), analog.iqIq2); + UqVolt = _IQmpy(_IQmpy(Frot, vect_control.koef_Uq_comp), analog.iqId2); + if (Uzpt != 0) { + vect_control.iqUdCompensation2 = -_IQdiv(UdVolt, Uzpt); + vect_control.iqUqCompensation2 = _IQdiv(UqVolt, Uzpt); + } else { + vect_control.iqUdCompensation2 = 0; + vect_control.iqUqCompensation2 = 0; + } + + + vect_control.iqUdKm2Out = vect_control.iqUdKm2 + vect_control.iqUdCompensation2; + vect_control.iqUqKm2Out = vect_control.iqUqKm2 + vect_control.iqUqCompensation2; +} + +#define IQ_150_RPM 2097152 //150��/��� +#define IQ_140_RPM 1957341 //140��/��� +//#define IQ_135_RPM 1887436 //135��/��� +#define IQ_125_RPM 1747626 //125��/��� +#define IQ_120_RPM 1677721 //120��/��� +#define IQ_115_RPM 1607816 //115��/��� +#define IQ_110_RPM 1537911 //110��/��� + +#define K_MODUL_SWITCH_COS_FI 13925089 //83% +#define K_MODUL_SWITCH_COS_FI_2 14260633 //85% +#define K_MODUL_SWITCH_OFF 10905190 //65% //11744051 ~ 70% //12582912 ~ 75% + +#define U200V 1118481 + + +// #pragma CODE_SECTION(set_cos_tetta_calc_params,".fast_run1"); +void set_cos_tetta_calc_params() { + + _iq currentCos = _IQ(COS_FI); + _iq currentCosSq = _IQ(COS_FI * COS_FI); + static _iq cosFi_low_speed = _IQ(0.85); + static _iq cosFi_Sq_low_speed = _IQ(0.85 * 0.85); + static _iq cosFi_mid_speed = _IQ(COS_FI); + static _iq cosFi_Sq_mid_speed = _IQ(COS_FI * COS_FI); + static _iq cosFi_high_speed = _IQ(0.89); + static _iq cosFi_Sq_high_speed = _IQ(0.89 * 0.89); + static _iq stepChangeCos = _IQ(0.001); + static _iq kt_low_speed = _IQ(0.0045); + static _iq kt_over_140rpm = _IQ(0.0048); + static _iq kt_over_150rpm = _IQ(0.0049); + static _iq kt_single_inv = _IQ(0.0039); + + _iq current_kt = _IQ(0.0045); + static _iq stepChangeKt =_IQ(0.00001); + + static _iq addCompensateUd = _IQ(0.0004); + + static unsigned int flag_high_Km = 0; + + if (a.iqk1 < K_MODUL_SWITCH_OFF) { + flag_high_Km = 0; + } + +// if (_IQabs(rotor.iqFout) > IQ_150_RPM) { +// currentCos = _IQ(0.9); +// currentCosSq = _IQ(0.9 * 0.9); +//// tetta_calc.k_t = _IQ(0.0049); +// current_kt = kt_over_150rpm; //_IQ(0.0049); +// } else + if (_IQabs(rotor.iqFout) > IQ_140_RPM || (a.iqk1 > K_MODUL_SWITCH_COS_FI_2) + || flag_high_Km == 1) { + if (a.iqk1 > K_MODUL_SWITCH_COS_FI_2) { + flag_high_Km = 1; + } + currentCos = cosFi_high_speed; + currentCosSq = cosFi_Sq_high_speed; +// tetta_calc.k_t = _IQ(0.0048); + current_kt = kt_over_140rpm; //_IQ(0.0048); + } else if ((_IQabs(rotor.iqFout) > IQ_115_RPM && cos_fi.cos_fi_nom < _IQ(0.889)) + || (_IQabs(rotor.iqFout) < IQ_135_RPM && cos_fi.cos_fi_nom > _IQ(0.889)) + || (a.iqk1 > K_MODUL_SWITCH_COS_FI)) { + currentCos = cosFi_mid_speed; + currentCosSq = cosFi_Sq_mid_speed; +// tetta_calc.k_t = _IQ(0.0045); + current_kt = kt_low_speed; //_IQ(0.0045); + } else if (_IQabs(rotor.iqFout) < IQ_110_RPM) { + currentCos = cosFi_low_speed; + currentCosSq = cosFi_Sq_low_speed; + //(f.secondPChState != 4) + if(((analog.iqIm_1 > I_OUT_NOMINAL_IQ) || (analog.iqIm_2 > I_OUT_NOMINAL_IQ)) + && (f.secondPChState != 4)) { + current_kt = kt_single_inv; //_IQ(0.0039); + } else if ((analog.iqIm_1 < 9507089) || (analog.iqIm_2 < 9507089)) { + current_kt = kt_low_speed; //_IQ(0.0045); + } + } + + if (analog.iqUd1 < -U200V || (a.iqk1 > K_MODUL_SWITCH_COS_FI_2)) { + current_kt += addCompensateUd; // _IQ(0.0004); + } + cos_fi.cos_fi_nom = zad_intensiv_q(stepChangeCos, stepChangeCos, cos_fi.cos_fi_nom, currentCos); + cos_fi.cos_fi_nom_squared = zad_intensiv_q(stepChangeCos, stepChangeCos, cos_fi.cos_fi_nom_squared, currentCosSq); + + tetta_calc.k_t = zad_intensiv_q(stepChangeKt, stepChangeKt, tetta_calc.k_t, current_kt); +} + + +void limit_mzz_zad_power(_iq Frot) +{ + Frot = labs(Frot); + + if (vect_control.flag_reverse) { +// f.iq_mzz_zad = _IQ(1300.0/NORMA_MZZ); + f.iq_mzz_zad = _IQ(1100.0/NORMA_MZZ); + } else + if (Frot < 279620) //20 ob/min + { +// f.iq_mzz_zad = _IQ(1200.0/NORMA_MZZ); + f.iq_mzz_zad = _IQ(1400.0/NORMA_MZZ); + } + else if (Frot < 419430) //30 ob/min + { + f.iq_mzz_zad = _IQ(1400.0/NORMA_MZZ); + } +// else if(rotor.iqFout < 699050) //50 ob/min + else if (Frot < 838860) //60 ob/min +// else if (rotor.iqFout < 978670) //70 ob/min + { +// f.iq_mzz_zad = _IQ(1800.0/NORMA_MZZ); + f.iq_mzz_zad = _IQ(2000.0/NORMA_MZZ); + } + else + { + f.iq_mzz_zad = _IQ(2000.0/NORMA_MZZ); +// f.iq_mzz_zad = _IQ(1500.0/NORMA_MZZ); + } +} + + diff --git a/Inu/Src2/VectorControl/pwm_vector_regul.h b/Inu/Src2/VectorControl/pwm_vector_regul.h new file mode 100644 index 0000000..9b7c079 --- /dev/null +++ b/Inu/Src2/VectorControl/pwm_vector_regul.h @@ -0,0 +1,81 @@ +#ifndef PWM_VECTOR_REGUL +#define PWM_VECTOR_REGUL + +#include "pid_reg3.h" + +void pwm_vector_model_titov(_iq Pzad, _iq Fzad, int direction, _iq Frot, int mode, + int reset, int calcPWMtimes); +void init_DQ_pid(void); +//void detect_I_M_overload(void); +void analog_dq_calc_const(void); + +void set_cos_tetta_calc_params(); +void limit_mzz_zad_power(_iq Frot); + +extern _iq zadan_Id_min; +extern PIDREG3 pidD; +extern PIDREG3 pidQ; +extern PIDREG3 pidD2; +extern PIDREG3 pidQ2; + +extern long koeff_Ud_filter; + +typedef struct { + _iq cos_fi_nom; + _iq cos_fi_nom_squared; +} COS_FI_STRUCT; + +extern COS_FI_STRUCT cos_fi; + +#define ONE_IQ24 16777216 + +typedef struct { + _iq iqId_zad; + _iq iqIq_zad; + _iq iqUdKm1; + _iq iqUqKm1; + _iq iqUdKm2; + _iq iqUqKm2; + _iq iqUdCompensation1; + _iq iqUqCompensation1; + _iq iqUdCompensation2; + _iq iqUqCompensation2; + _iq iqUdKm1Out; + _iq iqUqKm1Out; + _iq iqUdKm2Out; + _iq iqUqKm2Out; + + _iq iqUzad1; + _iq iqUzad2; + + _iq koef_Ud_comp; + _iq koef_Uq_comp; + _iq koeff_correct_Id; + + _iq equial_Iq_Proportional; //Пропорциональный коэффициент регулятора поддержания Iq одинаковым на обоих обмотках + _iq equial_Iq_Delta; //Разница в Iq двух обмоток + _iq equial_Iq_Out; + + _iq k_modul_max; + _iq k_modul_max_square; + _iq iq_Id_out_max; + + _iq iqPzad; + _iq iqPizm; + _iq iqFrot; + + int flag_reverse; + + float theta; + +} VECTOR_CONTROL; + +#define VECTOR_CONTROL_DEFAULTS {0,0,0,0,0,0,0,0,0,0, 0,0, 0,0,0, 0,0,0, 0,0,0,0,0, 0,0} + +extern VECTOR_CONTROL vect_control; + +extern PIDREG3 pidFvect; + +#endif //PWM_VECTOR_REGUL + + diff --git a/Inu/Src2/VectorControl/regul_power.c b/Inu/Src2/VectorControl/regul_power.c new file mode 100644 index 0000000..8ffcb42 --- /dev/null +++ b/Inu/Src2/VectorControl/regul_power.c @@ -0,0 +1,269 @@ +#include "vector.h" +#include "IQmathLib.h" +#include "math.h" +#include "pid_reg3.h" +#include "adc_tools.h" +#include "params.h" +#include "regul_power.h" +#include "pwm_vector_regul.h" +#include "my_filter.h" + +// #pragma DATA_SECTION(pidPvect,".fast_vars1"); +PIDREG3 pidPvect = PIDREG3_DEFAULTS; + + +#define IQ_OUT_SAT_POWER (2880.0 * COS_FI) +#define MAX_PID_CURRENT_P 2200.0 // 2200.0 ~ 1.6 Inom + +#define IM_CURRENT_STOP_RMP 11184810 //2000 + +#define IQ_1500A 8388608 +#define IQ_1800A 10066329 + +#define K_RMP_100A_PER_TIC 559240 +#define K_RMP_400A_PER_SEC 2663 + +#define K_MODUL_MAX 15770583 + +// #define P_DELTA_ZAD_IZM 5592405 //3 MWt + +#define LIMIT_Iq_ON_POWER_REVERSE + +_iq Id_out_max_low_speed = _IQ(ID_OUT_SAT_POWER_LOW_SPEED / NORMA_ACP); +_iq Id_out_max_full = _IQ(ID_OUT_SAT_POWER / NORMA_ACP); + + +void init_Pvect_pid() +{ + pidPvect.Ref = 0; + pidPvect.Kp = _IQ(1.0);//_IQ(1.0); + pidPvect.Ki = _IQ(0.1);//_IQ(0.05);//_IQ(0.06); + pidPvect.Kc = _IQ(0.5); + // pidPvect.Kp = _IQ(1); //_IQ(2.5);//_IQ(5.0);// + // pidPvect.Ki = _IQ(0.1);//_IQ(0.05);//_IQ(0.06); + // pidPvect.Kc = _IQ(0.5); + pidPvect.OutMax = _IQ(MAX_PID_CURRENT_P / NORMA_ACP); + pidPvect.OutMin = -_IQ(MAX_PID_CURRENT_P / NORMA_ACP); +} + +void reset_Pvect_pid() +{ + pidPvect.Up = 0; + pidPvect.Up1 = 0; + pidPvect.Ui = 0; + pidPvect.Ud = 0; + pidPvect.Out = 0; +} + +_iq koeff_Iq_filter = _IQ(0.5); + +#define LEVEL_LIMIT_KM 14596177 //87% //15099494 ~ 90% //15435038 ~ 92% + +#define POWER_7_MWt 13048945 +#define POWER_4_MWt 7456540 +#define POWER_200_kWt 372827 + +// #pragma CODE_SECTION(vector_power,".fast_run2"); +void vector_power(_iq Pzad, _iq P_measured, _iq Iq_measured, int mode, _iq Frot, _iq* Iq_zad, _iq* Id_zad) +{ + static _iq Pzad_rmp = 0; + static _iq koef_slow = _IQ(0.000075); //_IQ(0.000065);15sec //_IQ(0.000085); 13sec // //_IQ(0.000065); normal rampa 13 seconds + static _iq koef_slow_low_task = _IQ(0.000040); //Ðàìïà äëÿ çàäàíèé ìîùíîñòè ìåíüøå ïîëîâèíû íîìèíàëà, ÷òîáû íåáûëî ïåðåðåãóëÿöèè + static _iq koef_slow_2 = _IQ(0.000045); //_IQ(0.000039); // _IQ(0.000015); //_IQ(0.000011) ~ 10 sec 0-10MWt //_IQ(0.00002) ~ 7 ñåê 0-10ÌÂò + static _iq koef_fast = _IQ(0.00013); //_IQ(0.00008); //_IQ(0.000025); ~3.1 sev 10-0MWt +// static _iq prev_Pzad = 0; +// static _iq cos_fi_nom_alg = _IQ(COS_FI), cos_fi_nom_squared_alg = _IQ(COS_FI * COS_FI); +// static _iq cos_fi_nom = _IQ(COS_FI), cos_fi_nom_squared = _IQ(COS_FI * COS_FI); + static _iq Iq_out_nom = _IQ(IQ_OUT_NOM / NORMA_ACP); //, Id_out_nom = _IQ(ID_OUT_NOM / NORMA_ACP); +// static _iq Iq_out_max = _IQ(IQ_OUT_SAT_POWER / NORMA_ACP); + static _iq Id_out_max = _IQ(ID_OUT_SAT_POWER_LOW_SPEED / NORMA_ACP); + static _iq pid_Out_max = _IQ(MAX_PID_CURRENT_P / NORMA_ACP); + _iq koef_rmp, koef_spad; //koef_spad - äëþ çàùèòû îò ïðåâûøåíèþ âèíòîì ðàçðåø¸ííûõ îáîðîòîâ (170îá/ìèí) + _iq Iq_out_unsat, Iq_out_sat, Id_out_sat, Id_out_unsat; +// _iq Iq_out_limited = 0; + static _iq Iq_out_filter = 0; + static _iq mzz_zad_int=0; + static int counterStopRampa = 0; +#ifdef LIMIT_Iq_ON_POWER_REVERSE + static int flag_reverse = 0; +#endif //LIMIT_Iq_ON_POWER_REVERSE + + // if (f.DownTemperature) { + // mzz_zad_int = zad_intensiv_q(35480, 35480, mzz_zad_int, _IQmpy(f.iq_mzz_zad, temperature_limit_koeff)); + // } else +// if(f.DownToNominal && (f.iq_mzz_zad > Iq_out_nom)) { +// mzz_zad_int = zad_intensiv_q(29480, 29480, mzz_zad_int, Iq_out_nom); +// } else if (a.iqk1 > LEVEL_LIMIT_KM || a.iqk2 > LEVEL_LIMIT_KM) { +// Pzad = 0; +// Pzad_rmp = zad_intensiv_q((koef_fast << 3), (koef_fast << 3), Pzad_rmp, Pzad); +// // f.DownToNominalVoltage = 1; +// } +// else + { + if (f.iq_mzz_zad != 0) { + mzz_zad_int = zad_intensiv_q(28480, 28480, mzz_zad_int, f.iq_mzz_zad); + } else { + mzz_zad_int = zad_intensiv_q(25480, 25480, mzz_zad_int, pid_Out_max); + } +// f.DownToNominalVoltage = 0; + } + + if((mode != 2) || (!f.Go) +// || (f.flag_leading == 0 && f.read_task_from_optical_bus == 1 && f.sync_Iq_from_optical_bus == 1) + ) + { + Pzad_rmp = P_measured; +// prev_Pzad = P_measured; + pidPvect.Ui = Iq_measured; + Id_out_max = Id_out_max_low_speed; + if(!f.Go) + { + *Iq_zad = *Id_zad = 0; + } + #ifdef LIMIT_Iq_ON_POWER_REVERSE + flag_reverse = 0; + #endif + return; + } + +#ifdef LIMIT_Iq_ON_POWER_REVERSE + // Ïðè òîðîæåíèè îãðàíè÷èâàåì Iq íóë¸ì ñî ñòîðîíû íå òîðìîæåíèÿ + // ò.ê. ïðè òîðìîæåíèè èç-çà êîëåáàíèé çàäàíèå íà òîê ìîæåò ïîìåíÿòü çíàê + if ((Frot > 0 && Pzad_rmp < 0 && pidPvect.Out < 0) || + (Frot < 0 && Pzad_rmp > 0 && pidPvect.Out > 0)) { + flag_reverse = 1; + vect_control.flag_reverse = 1; + } else + if ((Frot > 0 && Pzad_rmp > 0) || (Frot < 0 && Pzad_rmp < 0)) + { + flag_reverse = 0; + vect_control.flag_reverse = 0; + } + if (flag_reverse == 0) { + pidPvect.OutMax = mzz_zad_int; + pidPvect.OutMin = -mzz_zad_int; + } else { + if (Pzad_rmp < 0) { + pidPvect.OutMax = 0; + pidPvect.OutMin = -mzz_zad_int; + } else { + pidPvect.OutMax = mzz_zad_int; + pidPvect.OutMin = 0; + } + } +#else + pidPvect.OutMax = mzz_zad_int; + pidPvect.OutMin = -mzz_zad_int; +#endif //LIMIT_Iq_ON_POWER_REVERSE + +// if (f.setCosTerminal) { +// cos_fi.cos_fi_nom = f.cosinusTerminal; +// cos_fi.cos_fi_nom_squared = f.cosinusTerminalSquared; +// } + + + //if(Pzad != prev_Pzad) + //{ + if((_IQabs(Pzad_rmp) <= _IQabs(Pzad)) && + (((Pzad >= 0) && (Pzad_rmp >= 0)) || ((Pzad < 0) && (Pzad_rmp < 0)))) + { + // if (_IQabs(Pzad) < POWER_4_MWt) { + // koef_rmp = koef_slow_low_task; + // } else if (_IQabs(Pzad_rmp) < POWER_7_MWt) { // 7MWt + // koef_rmp = koef_slow; + // } else { + // koef_rmp = koef_slow_2; + // } + koef_rmp = koef_slow; + //Ïðè íàáðîñå ìîùíîñòè ýëåêòðè÷åñêàÿ ìîùíîñòü ìîæåò ïðåâûñèòü çàäàííóþ + //ïîýòîìó åñëè ïðèáëèçèëèñü ê çàäàíèþ, òî çàìåäëÿåì ðàìïó âåêòîðîé ìîùíîñòè + // if (_IQabs(f.iq_p_zad_electric) - _IQabs(analog.iqW) < POWER_200_kWt) { + // koef_rmp = koef_rmp / 4; + // } + } + else + { + koef_rmp = koef_fast; + } + //} + +// EfficiencyCompensation(&Pzad, &Iq_measured); + + // if (analog.iqIm_1 > IM_CURRENT_STOP_RMP || analog.iqIm_2 > IM_CURRENT_STOP_RMP) { + // counterStopRampa = 400; + // } else { + // if (counterStopRampa > 0) { + // counterStopRampa -= 1; + // } + // } + // if (counterStopRampa <= 0) { + // Pzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, Pzad_rmp, Pzad); + // counterStopRampa = 0; + // } else { + // Pzad_rmp = zad_intensiv_q(koef_slow_2, koef_slow_2, Pzad_rmp, Pzad); + // } + + Pzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, Pzad_rmp, Pzad); + +#ifdef P_DELTA_ZAD_IZM + //Åñëè èçìåðåííàÿ ìîùíîñòü íà ìíîãî ìåíüøå çàäàííîé ðàìïû, + //òî ðàìïà îãðàíè÷èâàåòñÿ çíà÷åíèåì èçìåðåííîé ïëþñ íåêîòîðàÿ äåëüòà + if ((Pzad_rmp > 0 && P_measured > 0) && + ((Pzad_rmp - P_measured) > P_DELTA_ZAD_IZM)) { + Pzad_rmp = P_measured + P_DELTA_ZAD_IZM; + } + if ((Pzad_rmp < 0 && P_measured < 0) && + ((Pzad_rmp - P_measured) < -P_DELTA_ZAD_IZM)) { + Pzad_rmp = P_measured - P_DELTA_ZAD_IZM; + } +#endif + + f.iq_p_rampa = Pzad_rmp; + + + //������ �� ���������� ������ ����������� �������� + if(_IQabs(Frot) > IQ_170_RPM) + { + koef_spad = _IQdiv((IQ_170_RPM + IQ_10_RPM - _IQabs(Frot)), IQ_10_RPM); + if(koef_spad < 0) { + koef_spad = 0; + } + pidPvect.OutMax = _IQmpy(pidPvect.OutMax, koef_spad); + pidPvect.OutMin = _IQmpy(pidPvect.OutMin, koef_spad); + Pzad_rmp = _IQmpy(Pzad_rmp, koef_spad); + } + pidPvect.Ref = Pzad_rmp; + pidPvect.Fdb = P_measured; + + + pidPvect.calc(&pidPvect); + + Iq_out_unsat = pidPvect.Out; + + Iq_out_filter = Iq_out_unsat; // exp_regul_iq(koeff_Iq_filter, Iq_out_filter, Iq_out_unsat); + + // ìîäåëè çäåñü íå áûëî îãðàíè÷åíèé + Iq_out_sat = _IQsat(Iq_out_filter, mzz_zad_int, -mzz_zad_int); //Test + + if(Iq_out_filter < 0) + { + Id_out_unsat = _IQdiv(_IQmpy((-Iq_out_filter), _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); + } else { + Id_out_unsat = _IQdiv(_IQmpy(Iq_out_filter, _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); + } + + if (_IQabs(Frot) < IQ_50_RPM) { + Id_out_max = zad_intensiv_q(5592, 5592, Id_out_max, Id_out_max_low_speed); //???? + } else { + Id_out_max = zad_intensiv_q(5592, 5592, Id_out_max, Id_out_max_full); + } + Id_out_sat = _IQsat(Id_out_unsat, Id_out_max, 0); + +// prev_Iq_zad = Iq_out_sat; + + *Iq_zad = Iq_out_sat; + *Id_zad = Id_out_sat; + +} + + diff --git a/Inu/Src2/VectorControl/regul_power.h b/Inu/Src2/VectorControl/regul_power.h new file mode 100644 index 0000000..2f1b127 --- /dev/null +++ b/Inu/Src2/VectorControl/regul_power.h @@ -0,0 +1,32 @@ +#ifndef REGUL_POWER +#define REGUL_POWER +#include "IQmathLib.h" +#include "pid_reg3.h" + +void init_Pvect_pid(void); +void vector_power(_iq Pzad, _iq P_measured, _iq Iq, int mode, _iq Frot, _iq* Iq_zad, _iq* Id_zad); + +extern PIDREG3 pidPvect; + +extern _iq Id_out_max_low_speed; +extern _iq Id_out_max_full; + + +#define IQ_5_RPM 69905L //5��/��� +#define IQ_10_RPM 139810L +#define IQ_20_RPM 279620L +#define IQ_50_RPM 699050L +#define IQ_135_RPM 1887436L +#define IQ_165_RPM 2306867L //165��/��� +#define IQ_170_RPM 2376772L //170��/��� +#define IQ_175_RPM 2446677L +#define IQ_190_RPM 2656392L +#define IQ_250_RPM 3495253L +#define IQ_255_RPM 3565158L + + +#define ID_OUT_SAT_POWER 800 //0.456 ~ sin(Fi) +#define ID_OUT_SAT_POWER_LOW_SPEED (500.0) //0.52 ~ sin(Fi) + + +#endif //REGUL_POWER diff --git a/Inu/Src2/VectorControl/regul_turns.c b/Inu/Src2/VectorControl/regul_turns.c new file mode 100644 index 0000000..444547f --- /dev/null +++ b/Inu/Src2/VectorControl/regul_turns.c @@ -0,0 +1,185 @@ +#include "IQmathLib.h" +#include "math.h" +#include "params.h" +#include "adc_tools.h" +#include "regul_turns.h" +#include "pid_reg3.h" +#include "vector.h" +#include "teta_calc.h" +#include "pwm_vector_regul.h" +#include "my_filter.h" + +// #pragma DATA_SECTION(pidFvect,".fast_vars1"); +PIDREG3 pidFvect = PIDREG3_DEFAULTS; + +#define MAX_PID_CURRENT IQ_OUT_NOM + +#define IQ_165_RPM 2306867 //165��/��� +#define IQ_170_RPM 2376772 //170��/��� +#define IQ_5_RPM 69905 //5��/��� + +#define TIME_RMP_FAST 10.0 //sec +#define TIME_RMP_SLOW 30.0 //sec +#define F_DEST 3.0 //Hz + +void init_Fvect_pid() +{ + pidFvect.Ref = 0; + pidFvect.Kp = _IQ(10.0);//_IQ(30.0);// // + pidFvect.Ki = _IQ(0.03); //_IQ(0.015); + pidFvect.Kc = _IQ(0.5); + pidFvect.OutMax = _IQ(MAX_PID_CURRENT / NORMA_ACP); + pidFvect.OutMin = -_IQ(MAX_PID_CURRENT / NORMA_ACP); +} + +void reset_F_pid() +{ + pidFvect.Up = 0; + pidFvect.Up1 = 0; + pidFvect.Ui = 0; + pidFvect.Ud = 0; + pidFvect.Out = 0; +} + +void vector_turns(_iq Fzad, _iq Frot, _iq Iq, int mode, _iq* Iq_zad, _iq* Id_zad) +{ + static _iq Fzad_rmp = 0, koef_fast = _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 2.5); + static _iq koef_slow = _IQ(F_DEST / (float)NORMA_FROTOR / TIME_RMP_SLOW / (float)FREQ_PWM / 5.0); +// static _iq cos_fi_nom = _IQ(COS_FI), cos_fi_nom_squared = _IQ(COS_FI * COS_FI); //prev_Fzad = 0, + static _iq Iq_out_max = _IQ(IQ_OUT_NOM / NORMA_ACP); + static _iq Id_out_max = _IQ(500.0 / NORMA_ACP); //_IQ(ID_OUT_NOM / NORMA_ACP); + static _iq mzz_zad_int=0; + static int Iq_rmp_to_optica = 0; +// static int flag_Iq_synced_with_optica = 0; +// static _iq step_Iq_rmp = _IQ(20.0 / NORMA_ACP); + _iq koef_rmp; //, koef_spad; + _iq Iq_out_unsat, Iq_out_sat, Id_out_sat, Id_out_unsat; + _iq deltaVar; + +// if (f.DownTemperature) { +// // mzz_zad_int = zad_intensiv_q(35480, 35480, mzz_zad_int, _IQmpy(Iq_out_max, temperature_limit_koeff)); +// mzz_zad_int = zad_intensiv_q(25480, 25480, mzz_zad_int, _IQmpy(f.iq_mzz_zad, temperature_limit_koeff)); +// } else + { + mzz_zad_int = zad_intensiv_q(35480, 35480, mzz_zad_int, f.iq_mzz_zad); +// mzz_zad_int = zad_intensiv_q(25480, 25480, mzz_zad_int, pid_Out_max); + } + + pidFvect.OutMax = Iq_out_max; + pidFvect.OutMin = -Iq_out_max; + + if (Fzad >= 0 && Frot > 0) { + pidFvect.OutMin = 0; + } + + if (Fzad <= 0 && Frot < 0) { + pidFvect.OutMax = 0; + } + + + + if((mode != 1) || (!f.Go)) //������� ������� ��������� � �����-���, ��� �� ��� ����� ������ �� ���� ������� + { // + Fzad_rmp = Frot; +// prev_Fzad = Frot; + reset_F_pid(); //���� ����, ����� ���� ���-�� ���� �� ��� + pidFvect.Ui = Iq; + pidFvect.Out = Iq; + *Iq_zad = Iq; + Iq_rmp_to_optica = Iq; +// *Id_zad = _IQdiv(_IQmpy(Iq, _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); + if(!f.Go) + { + *Iq_zad = *Id_zad = 0; + } +// flag_Iq_synced_with_optica = 0; + return; + } + + //������������� ������ �� + //������� �� Iq ��������� �� ���������� ���� +// if ((f.flag_leading == 0) && (f.read_task_from_optical_bus == 1) && (f.sync_Iq_from_optical_bus == 1)) { +// // if (flag_Iq_synced_with_optica == 0) { +// // if (_IQabs(analog.iqIq_zad_from_optica - Iq_rmp_to_optica) > 1118481) { //200A +// // Iq_rmp_to_optica = zad_intensiv_q(step_Iq_rmp, step_Iq_rmp, Iq_rmp_to_optica, analog.iqIq_zad_from_optica); +// // } else { +// // Iq_rmp_to_optica = analog.iqIq_zad_from_optica; +// // flag_Iq_synced_with_optica = 1; +// // } +// // } else { +// // Iq_rmp_to_optica = analog.iqIq_zad_from_optica; +// // } +// Iq_rmp_to_optica = analog.iqIq_zad_from_optica; +// Iq_out_unsat = Iq_rmp_to_optica; +// Iq_out_sat = _IQsat(Iq_out_unsat, mzz_zad_int, -mzz_zad_int); +// Id_out_unsat = _IQdiv(_IQmpy(_IQabs(Iq_out_sat), _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); +// Id_out_sat = _IQsat(Id_out_unsat, Id_out_max, 0); +// *Iq_zad = Iq_out_sat; +// *Id_zad = Id_out_sat; + +// reset_F_pid(); +// pidFvect.Ui = Iq_out_sat; +// pidFvect.Out = Iq_out_sat; +// Fzad_rmp = Frot; +// return; +// } + + //if(Fzad != prev_Fzad) //����� ������� �� ������. ���� ������ ���������, �� ��������. + //{ //���� ��������� ��� ������, �� ������. + if(_IQabs(Fzad_rmp) <= _IQabs(Fzad) && + (((Fzad >= 0) && (Fzad_rmp >= 0)) || ((Fzad < 0 ) && (Fzad_rmp < 0)))) + { + koef_rmp = koef_slow; + } + else + { + koef_rmp = koef_fast; + } +// prev_Fzad = Fzad; + //} + + // Fzad_rmp = zad_intensiv_q(koef_rmp, koef_rmp, Fzad_rmp, Fzad); +// logpar.log2 = (int16)(_IQtoIQ15(Fzad)); +// logpar.log19 = (int16)(_IQtoIQ15(Fzad_rmp)); + + //� �����-�� ������ ��������� ��������� �������� ������� zad_intensiv_q + // ������� ��� �� �� ������� ����. + deltaVar = Fzad-Fzad_rmp; + + if ((deltaVar>koef_rmp) || (deltaVar<-koef_rmp)) + { + if (deltaVar>0) Fzad_rmp += koef_rmp; + else Fzad_rmp -= koef_rmp; + } + else + Fzad_rmp = Fzad; + + pidFvect.Ref = Fzad_rmp; + pidFvect.Fdb = Frot; + + pidFvect.calc(&pidFvect); + Iq_out_unsat = pidFvect.Out; + + //TODO: ATTENTION!!! worked better on stend + if (_IQabs(Iq_out_unsat) < 27962) //5A + { + pidTetta.Ui = 0; + pidTetta.SatErr = 0; + } + Iq_out_sat = _IQsat(Iq_out_unsat, Iq_out_max, -Iq_out_max); +// if(f.DownToNominal) //In this mode max I equial Inom +// { +// Iq_out_sat = _IQsat(Iq_out_unsat, I_OUT_NOMINAL_IQ, -I_OUT_NOMINAL_IQ); +// } + // Iq_out_sat = _IQsat(Iq_out_unsat, mzz_zad_int, -mzz_zad_int); //Test + //������ d �������-���� ���� + Iq_out_unsat = _IQabs(Iq_out_unsat); + Id_out_unsat = _IQdiv(_IQmpy(Iq_out_unsat, _IQsqrt(ONE_IQ24 - cos_fi.cos_fi_nom_squared)), cos_fi.cos_fi_nom); + Id_out_sat = _IQsat(Id_out_unsat, Id_out_max, 0); + + + + *Iq_zad = Iq_out_sat; + *Id_zad = Id_out_sat; + +} diff --git a/Inu/Src2/VectorControl/regul_turns.h b/Inu/Src2/VectorControl/regul_turns.h new file mode 100644 index 0000000..57529b5 --- /dev/null +++ b/Inu/Src2/VectorControl/regul_turns.h @@ -0,0 +1,12 @@ +#ifndef REGUL_TURNS +#define REGUL_TURNS +#include "IQmathLib.h" +#include "pid_reg3.h" + +void init_Fvect_pid(void); +void vector_turns(_iq Fzad, _iq Frot, _iq Iq, int mode, _iq* Iq_zad, _iq* Id_zad); + + +#endif //REGUL_TURNS + + diff --git a/Inu/Src2/VectorControl/teta_calc.c b/Inu/Src2/VectorControl/teta_calc.c new file mode 100644 index 0000000..d76bfe5 --- /dev/null +++ b/Inu/Src2/VectorControl/teta_calc.c @@ -0,0 +1,262 @@ +#include "teta_calc.h" +#include "params.h" +#include "pid_reg3.h" +#include "IQmathLib.h" +#include "vector.h" +#include "my_filter.h" + +#define CONST_IQ_2PI 105414357 +#define PI 3.1415926535897932384626433832795 + +PIDREG3 pidTetta = PIDREG3_DEFAULTS; + +#define MAX_Ud_Pid_Out (167772 * 100) //419430 ~ 0.5 //251658 ~ 0.3 //209715 ~ 0.25 //167772 ~ 0.2Hz //100663 //0.12Hz +// 184549 ~ 2.2 + +#define MAX_Ud_Pid_Out_Id 176160 //0.2 ~ 167772 //0.21 ~ 176160 + //0.15 ~ 125829 +#define BPSI_START 0.17 //0.15 + +void init_tetta_pid() +{ + pidTetta.Ref = 0; + pidTetta.Fdb = 0; + pidTetta.Kp = _IQ(0.1); //_IQ(0.15); + pidTetta.Ki = _IQ(0.0003); //_IQ(0.00003) + pidTetta.Kc = _IQ(0.5); + pidTetta.OutMax = MAX_Ud_Pid_Out; + pidTetta.OutMin = -MAX_Ud_Pid_Out; + pidTetta.Up = 0; + pidTetta.Ui = 0; +} + +void reset_tetta_pid() +{ + pidTetta.Up = 0; + pidTetta.Up1 = 0; + pidTetta.Ui = 0; + pidTetta.Out = 0; +} + + +//#pragma CODE_SECTION(calc_tetta,".fast_run"); +void calc_tetta(_iq Frot, int direction, _iq Ud, int direct_zadan, _iq *tetta_out, _iq *Fsl_out, _iq *Fstator_out, int mode, int reset) // +{ + static _iq tetta = 0, Fsl_start = 0, bpsi_start = _IQ(BPSI_START / NORMA_FROTOR);// , bpsi_start_on_go = _IQ(0.1 / NORMA_FROTOR); + static _iq hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM / 2.0); + static int flag_start = 0; + static int koeff_zad_int = 30; //1000; + static long stop_frot = 27962; //2 rpm // 10000; +// static _iq prev_Fsl = 0; + static int flag_reverse = 0; +// static int flag_out_of_reverse = 0; + static int prev_direction = 0; + static _iq koeffKpRmp = _IQ(0.0003750); + static _iq koeffKiRmp = _IQ(0.00005); + static _iq lowSpeedKp = _IQ(0.1); + static _iq lowSpeedKi = _IQ(0.0003); + static _iq highSpeedKp = _IQ(0.01); + static _iq highSpeedKi = _IQ(0.011); //_IQ(0.02); + + _iq Fstat, Fsl; + int reverse_Ud = 1; + + if(reset == 1) + { + flag_start = 1; //Won`t work, if machine will stop without changing mode + Fsl_start = 0; + flag_reverse = 0; +// flag_out_of_reverse = 0; + } + if (_IQabs(Frot) < 768955) { //55 rpm + pidTetta.Kp = zad_intensiv_q(koeffKpRmp, koeffKpRmp, pidTetta.Kp, lowSpeedKp); + pidTetta.Ki = zad_intensiv_q(koeffKiRmp, koeffKiRmp, pidTetta.Ki, lowSpeedKi); + } + else if ((_IQabs(Frot) < 1118481)) { //80 rpm + pidTetta.Kp = zad_intensiv_q(koeffKpRmp, koeffKpRmp, pidTetta.Kp, highSpeedKp); + pidTetta.Ki = zad_intensiv_q(koeffKiRmp, koeffKiRmp, pidTetta.Ki, highSpeedKi); + } + //������ ����������� direction == 1 + //direction == 0 - ��������� ����� +// if(((Frot >= 0) && (direct_zadan == 1) && (direction >= 0)) || +// ((direct_zadan == -1) && (direction >= 0) && (Frot >= stop_frot))) + //27962 ~ 2 rpm +// if(((direct_zadan == 1) && (direction == 0)) || (direction > 0)) +// { +// Ud = -Ud; +// } + + + if(Frot >= 27962) { + reverse_Ud = -1; + flag_reverse = (Frot >= 27962 && direct_zadan == -1) ? 1 : 0; + prev_direction = 1; + } + else if (Frot <= -27962) { + reverse_Ud = 1; + flag_reverse = (Frot <= -27962 && direct_zadan == 1) ? 1 : 0; + prev_direction = -1; + } + if(_IQabs(Frot) < 27962) { + if (flag_reverse == 1) { + if (prev_direction == 1) { + reverse_Ud = -1; + } else { + reverse_Ud = 1; + } + } else +// if (flag_start) + { + if (direct_zadan == 1) { + reverse_Ud = -1; + } else { + reverse_Ud = 1; + } + } + } + Ud = Ud * reverse_Ud; + + pidTetta.Ref = Ud * 100; //Ref -������� + pidTetta.calc(&pidTetta); + Fsl = pidTetta.Out / 100; + + if(flag_start) // + { + if(_IQabs(Frot) < stop_frot) + { + Fsl_start = bpsi_start * direct_zadan; //���� ��������� �����, �������-�� ����������. + } + else + { + if(Fsl_start == 0) + { + Fsl_start = bpsi_start * direct_zadan; //direction; + } + flag_start = 0; + } + + } + else + { + //����� ��������� ����� ����, ����� �������� ����������, �.�. ���������� ���� �� ������������ ���������� ���������. + if(_IQabs(Frot) < (stop_frot)) + { +// if((direct_zadan == 1) && (Fsl + Fsl_start < bpsi_start)) +// { +// Fsl_start += (koeff_zad_int << 2); +//// Fsl_start += koeff_zad_int; +// } +// if((direct_zadan == -1) && (Fsl + Fsl_start > -bpsi_start)) +// { +// Fsl_start -= (koeff_zad_int << 2); +//// Fsl_start -= koeff_zad_int; +// } + } + else + { + if(_IQabs(Fsl_start) > koeff_zad_int) + { + if(Fsl_start > 0) + { + Fsl_start -= koeff_zad_int; + } + if(Fsl_start < 0) + { + Fsl_start += koeff_zad_int; + } + } + else + { + Fsl_start = 0; + } + } + + } + Fsl += Fsl_start; + Fstat = Frot * POLUS + Fsl; + tetta += _IQmpy(Fstat, hz_to_angle); + + + if (tetta > CONST_IQ_2PI) + { + tetta -= CONST_IQ_2PI; + } + + if (tetta < 0) + { + tetta += CONST_IQ_2PI; + } + *tetta_out = tetta; + *Fsl_out = Fsl; +// prev_Fsl = Fsl; + *Fstator_out = Fstat; + + +} + +TETTA_CALC tetta_calc = TETTA_CALC_DEF; + +void init_tetta_calc_struct() +{ + tetta_calc.Imds = 0; + tetta_calc.tetta = 0; + tetta_calc.k_r = _IQ(0.015); + tetta_calc.k_t = _IQ(0.0045); //_IQ(0.0045); + tetta_calc.hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM / 2.); +} + +void calc_tetta_Id(_iq Frot, _iq Id, _iq Iq, _iq *tetta_out, _iq *Fsl_out, _iq *Fstator_out, int reset) { + + _iq Fsl, Fst; + if (reset) { + tetta_calc.Imds = 0; + } + + tetta_calc.Imds = tetta_calc.Imds + _IQmpy(tetta_calc.k_r, (Id - tetta_calc.Imds)); + Fsl = _IQmpy(tetta_calc.k_t, Iq); + if (tetta_calc.Imds != 0) { + Fsl = _IQdiv(Fsl, tetta_calc.Imds); + } else { + Fsl = 0; + } + // Fsl = _IQ(0.2 / NORMA_FROTOR); + if (Fsl > MAX_Ud_Pid_Out_Id) { Fsl = MAX_Ud_Pid_Out_Id;} + if (Fsl < -MAX_Ud_Pid_Out_Id) { Fsl = -MAX_Ud_Pid_Out_Id;} + + Fst = Frot * POLUS + Fsl; + tetta_calc.tetta += _IQmpy(Fst, tetta_calc.hz_to_angle); + + if (tetta_calc.tetta > CONST_IQ_2PI) + { + tetta_calc.tetta -= CONST_IQ_2PI; + } + + if (tetta_calc.tetta < 0) + { + tetta_calc.tetta += CONST_IQ_2PI; + } + *Fsl_out = Fsl; + *tetta_out = tetta_calc.tetta; + *Fstator_out = Fst; + + +} + +#define LEVEL_REDUCE_UD 838860 //150V + +void correct_tetta_calc_Kt(void) { + static _iq coeff_add_Kt = _IQ(0.00005); + static _iq max_Kt = _IQ(0.0069); + static _iq min_Kt = _IQ(0.0029); + + if (tetta_calc.Imds > LEVEL_REDUCE_UD) { + tetta_calc.k_t -= coeff_add_Kt; + } + if (tetta_calc.Imds < -LEVEL_REDUCE_UD) { + tetta_calc.k_t += coeff_add_Kt; + } + if (tetta_calc.k_t > max_Kt) {tetta_calc.k_t = max_Kt; } + if (tetta_calc.k_t < min_Kt) {tetta_calc.k_t = min_Kt; } +} + + diff --git a/Inu/Src2/VectorControl/teta_calc.h b/Inu/Src2/VectorControl/teta_calc.h new file mode 100644 index 0000000..b04dda5 --- /dev/null +++ b/Inu/Src2/VectorControl/teta_calc.h @@ -0,0 +1,39 @@ +#ifndef TETA_CALC +#define TETA_CALC + +#include "IQmathLib.h" +#include "pid_reg3.h" + +void init_tetta_pid(void); +void reset_tetta_pid(void); +void calc_tetta(_iq Frot, int direction, _iq Ud, int direct_zadan, _iq *tetta_out, _iq *Fsl_out, _iq *Fstator_out, int mode, int reset); +void calc_tetta_Id(_iq Frot, _iq Id, _iq Iq, _iq *tetta_out, _iq *Fsl_out, _iq *Fstator_out, int reset); +void init_tetta_calc_struct(void); + +// k_r = Ts / Tr_cm +// Tr_cm = Lr / Rr +// Lr - ������������� ������ +// Rr - ������������� ������ +// +// k_t = 1 / (Tr_cm * 2 * Pi * f_b) +// +// K = Ts * f_b +// f_b - ������� ������������� ������� (12 ��) +// Ts - ������ ������� (840 ��) + +typedef struct { + _iq Imds; + _iq tetta; + + _iq hz_to_angle; + _iq k_r; + _iq k_t; +} TETTA_CALC; + +#define TETTA_CALC_DEF {0,0,0,0,0} + +extern TETTA_CALC tetta_calc; + +extern PIDREG3 pidTetta; +#endif //TETA_CALC + diff --git a/Inu/Src2/main/IQmathLib.c b/Inu/Src2/main/IQmathLib.c new file mode 100644 index 0000000..5720d7e --- /dev/null +++ b/Inu/Src2/main/IQmathLib.c @@ -0,0 +1,182 @@ +#include "IQmathLib.h" + + +// Преобразование числа с плавающей точкой в число с фиксированной точкой +#define float_to_fixed(A) (long)((A)*(1 << (GLOBAL_Q)) + (A > 0 ? 0.5: -0.5)) +// Преобразование числа с плавающей точкой в число с фиксированной точкой с выбором числа бит, отдаваемых под дробную часть +#define float_to_fixed_base_select(A, F_BITS) (long)((A)*(1 << (F_BITS)) + (A > 0 ? 0.5: -0.5)) +// Преобразование целого числа в число с фиксированной точкой +#define int_to_fixed(A) (long)((A) << (GLOBAL_Q)) +// Преобразование целого числа в число с фиксированной точкой с выбором числа бит, отдаваемых под дробную часть +#define int_to_fixed_base_select(A, F_BITS) (long)((A) << (F_BITS)) +//Преобразование числа с фиксированной точкой в число с плавающей точкой +#define fixed_to_float(A) ((double)A / (1 << GLOBAL_Q)) +//Перобразование числа с фиксированной точкой в целое число +#define fixed_to_int(A) ((int)(A >> GLOBAL_Q) ) + + +long multiply(long x, long y) +{ + long long z = (long long)x * (long long)y; + return (long)(z >> GLOBAL_Q); +} +//служебная функция. Умножает числа с 27 битами, отданными под дробную часть +static inline long multiply_27(long x, long y) +{ + long long z = (long long)x * (long long)y; + return z & 0x4000000 ? (long)(z >> 27) + 1 : (long)(z >> 27); +} + +long long multiply_fixed_base_select(long long x, long long y, int base) +{ + long long z = (long long)x * (long long)y; + return z & (1 << base) ? (z >> base) + 1 : (z >> base); +} + +long divide(long num, long den) +{ + long long numLong = (long long)num; + long long quotient = (numLong << GLOBAL_Q) / den; + return (long)quotient; +} +// +static inline long long divide_fixed_base_select(long long num, long long den, int base) +{ + long long quotient = ((long long)num << base) / den; + return quotient; +} + +#define div_def(A,B) (long)(((long long)(A) << 24)/(B)) +#define div_mod(A,B) (A)%(B) +#define mult_def(A,B) (long)((((long long)(A))*((long long)(B))) >> 24) +#define abs_def(A) ((A) > 0 ? (A): -(A)) + +long sin_fixed(long x) +{ + //Константы сделал ститическими, что бы они вычислялись во время запуска программы, а не исполнения + static long FIXED_2PI = float_to_fixed(TWO_PI); + static long FIXED_PI = float_to_fixed(PI); + static long FIXED_PIna2 = float_to_fixed(PI_2); + //Здесть так же что бы не производить операции деления посчитал констаны ряда Тейлора + static long one_110 = float_to_fixed_base_select(1./110, 27); + static long one_72 = float_to_fixed_base_select(1./72, 27); + static long one_42 = float_to_fixed_base_select(1./42, 27); + static long one_20= float_to_fixed_base_select(1./20, 27); + static long one_6 = float_to_fixed_base_select(1./6, 27); + + long long xx, tmp ; + while(x >= FIXED_2PI) { x -= FIXED_2PI;} //Помещаю аргумент в диапазон 2 ПИ + while(x <= -FIXED_2PI) { x += FIXED_2PI;} + //Так как ряды быстрее сходнятся при малых значениях, помещаю значение аргумента + //в ближайшие к нулю области + if(x > FIXED_PI) + { + x -= FIXED_2PI; + } + else if(x < -FIXED_PI) + { + x += FIXED_2PI; + } + if(x < -FIXED_PIna2) + { + x = -FIXED_PI - x; + } + else if(x > FIXED_PIna2) + { + x = FIXED_PI - x; + } + //проверяю угол на значения, при которых синус раве 0 или 1 + if(x == 0) return 0; + if(x == FIXED_PIna2) return int_to_fixed(1); + if(x == -FIXED_PIna2) return int_to_fixed(-1); + //Перевожу в формат с максимальной точностью для возможного дипазано значений + x <<= (27 - GLOBAL_Q); + //Считаю ряд фурье + xx = multiply_27(x, x); + tmp = ONE_27 - multiply_27(one_110, xx); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_72); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_42); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_20); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_6); + tmp = multiply_27(x, tmp); + return tmp >> (27 - GLOBAL_Q); //Перед возвращением из функции преобразую в первоначальный формат +} + +long cos_fixed(long x) +{ + //Константы сделал ститическими, что бы они вычислялись во время запуска программы, а не исполнения + static long FIXED_2PI = float_to_fixed(TWO_PI); + static long FIXED_PI = float_to_fixed(PI); + static long FIXED_PIna2 = float_to_fixed(PI_2); + //Здесть так же что бы не производить операции деления посчитал констаны ряда Тейлора + static long one_132 = float_to_fixed_base_select(1./132, 27); + static long one_90 = float_to_fixed_base_select(1./90, 27); + static long one_56 = float_to_fixed_base_select(1./56, 27); + static long one_30 = float_to_fixed_base_select(1./30, 27); + static long one_12 = float_to_fixed_base_select(1./12, 27); + + long xx, tmp, counter = 0; + while(x >= FIXED_2PI) { x -= FIXED_2PI;} //Помещаю аргумент в диапазон 2 ПИ + while(x < 0) { x += FIXED_2PI;} + x = _IQabs(x); //Так как косинус симметричен относительно нуля, нахожу его модуль + //проверяю угол на значения, при которых синус раве 0 или 1 + if(x == 0) return 1 << GLOBAL_Q; + if(x == FIXED_PI) return -(1 << GLOBAL_Q); + if(x == (FIXED_PIna2) || (x == FIXED_3PIna2))return 0; + //Так как ряды быстрее сходнятся при малых значениях, помещаю значение аргумента + //в ближайшие к нулю области + while(x > FIXED_PIna2) + { + x -= FIXED_PIna2; + counter++; + } + + if(counter == 1 || counter == 3) { x = FIXED_PIna2 - x;} + //Перевожу в формат с максимальной точностью для возможного дипазона значений + x <<= (27 - GLOBAL_Q); + //Считаю ряд фурье + xx = multiply_27(x, x); + tmp = ONE_27 - multiply_27(xx, one_132); + tmp= multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(xx, one_90); + tmp= multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_56); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_30); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - multiply_27(tmp, one_12); + tmp = multiply_27(xx, tmp); + tmp = ONE_27 - (tmp >> 1); + tmp >>= (27 - GLOBAL_Q); + return (counter == 0) || (counter == 3) ? tmp : -tmp; +} + +long sqrt_fixed(long x) +{ + int variable_size_bits = sizeof(x) << 3; + long average_val, prev_avg_val; + if(x <= 0) return 0; + while(!(x & (1 << --variable_size_bits))); //Нахожу старший значащий бит + //Нахожу приближение корня сдвгом на половину числа бит между старшим значащим битом + //и положением точки + if(variable_size_bits > GLOBAL_Q) + { + average_val = x >> ((variable_size_bits - GLOBAL_Q) >> 1); + } + else + { + average_val = x << ((GLOBAL_Q - variable_size_bits) >> 1); + } + prev_avg_val = divide(x, average_val); //Нахожу 1/А + //В цикле нахожу среднее арифметическое между А и 1/А, пока число не перестанет меняться + while(_IQabs(prev_avg_val - average_val) > 1) + { + prev_avg_val = average_val; + average_val = (average_val + divide(x, average_val)) >> 1; + } + return average_val; +} diff --git a/Inu/Src2/main/IQmathLib.h b/Inu/Src2/main/IQmathLib.h new file mode 100644 index 0000000..0e52bad --- /dev/null +++ b/Inu/Src2/main/IQmathLib.h @@ -0,0 +1,661 @@ +/** +* ��������� ���������� IQmath ��� ������������ � MATLAB +* +*/ +#ifndef IQ_MATH_LIB +#define IQ_MATH_LIB + + +#ifndef GLOBAL_Q +#define GLOBAL_Q 24 +#endif + +typedef long _iq; +typedef long _iq30; +typedef long _iq29; +typedef long _iq28; +typedef long _iq27; +typedef long _iq26; +typedef long _iq25; +typedef long _iq24; +typedef long _iq23; +typedef long _iq22; +typedef long _iq21; +typedef long _iq20; +typedef long _iq19; +typedef long _iq18; +typedef long _iq17; +typedef long _iq16; +typedef long _iq15; +typedef long _iq14; +typedef long _iq13; +typedef long _iq12; +typedef long _iq11; +typedef long _iq10; +typedef long _iq9; +typedef long _iq8; +typedef long _iq7; +typedef long _iq6; +typedef long _iq5; +typedef long _iq4; +typedef long _iq3; +typedef long _iq2; +typedef long _iq1; + +//--------------------------------------------------------------------------- +#define _IQmpy2(A) ((A)<<1) +#define _IQmpy4(A) ((A)<<2) +#define _IQmpy8(A) ((A)<<3) +#define _IQmpy16(A) ((A)<<4) +#define _IQmpy32(A) ((A)<<5) +#define _IQmpy64(A) ((A)<<6) + +#define _IQdiv2(A) ((A)>>1) +#define _IQdiv4(A) ((A)>>2) +#define _IQdiv8(A) ((A)>>3) +#define _IQdiv16(A) ((A)>>4) +#define _IQdiv32(A) ((A)>>5) +#define _IQdiv64(A) ((A)>>6) +//--------------------------------------------------------------------------- +#define _IQ30(A) (long) ((A) * 1073741824.0L) +#define _IQ29(A) (long) ((A) * 536870912.0L) +#define _IQ28(A) (long) ((A) * 268435456.0L) +#define _IQ27(A) (long) ((A) * 134217728.0L) +#define _IQ26(A) (long) ((A) * 67108864.0L) +#define _IQ25(A) (long) ((A) * 33554432.0L) +#define _IQ24(A) (long) ((A) * 16777216.0L) +#define _IQ23(A) (long) ((A) * 8388608.0L) +#define _IQ22(A) (long) ((A) * 4194304.0L) +#define _IQ21(A) (long) ((A) * 2097152.0L) +#define _IQ20(A) (long) ((A) * 1048576.0L) +#define _IQ19(A) (long) ((A) * 524288.0L) +#define _IQ18(A) (long) ((A) * 262144.0L) +#define _IQ17(A) (long) ((A) * 131072.0L) +#define _IQ16(A) (long) ((A) * 65536.0L) +#define _IQ15(A) (long) ((A) * 32768.0L) +#define _IQ14(A) (long) ((A) * 16384.0L) +#define _IQ13(A) (long) ((A) * 8192.0L) +#define _IQ12(A) (long) ((A) * 4096.0L) +#define _IQ11(A) (long) ((A) * 2048.0L) +#define _IQ10(A) (long) ((A) * 1024.0L) +#define _IQ9(A) (long) ((A) * 512.0L) +#define _IQ8(A) (long) ((A) * 256.0L) +#define _IQ7(A) (long) ((A) * 128.0L) +#define _IQ6(A) (long) ((A) * 64.0L) +#define _IQ5(A) (long) ((A) * 32.0L) +#define _IQ4(A) (long) ((A) * 16.0L) +#define _IQ3(A) (long) ((A) * 8.0L) +#define _IQ2(A) (long) ((A) * 4.0L) +#define _IQ1(A) (long) ((A) * 2.0L) + +#if GLOBAL_Q == 30 +#define _IQ(A) _IQ30(A) +#endif +#if GLOBAL_Q == 29 +#define _IQ(A) _IQ29(A) +#endif +#if GLOBAL_Q == 28 +#define _IQ(A) _IQ28(A) +#endif +#if GLOBAL_Q == 27 +#define _IQ(A) _IQ27(A) +#endif +#if GLOBAL_Q == 26 +#define _IQ(A) _IQ26(A) +#endif +#if GLOBAL_Q == 25 +#define _IQ(A) _IQ25(A) +#endif +#if GLOBAL_Q == 24 +#define _IQ(A) _IQ24(A) +#endif +#if GLOBAL_Q == 23 +#define _IQ(A) _IQ23(A) +#endif +#if GLOBAL_Q == 22 +#define _IQ(A) _IQ22(A) +#endif +#if GLOBAL_Q == 21 +#define _IQ(A) _IQ21(A) +#endif +#if GLOBAL_Q == 20 +#define _IQ(A) _IQ20(A) +#endif +#if GLOBAL_Q == 19 +#define _IQ(A) _IQ19(A) +#endif +#if GLOBAL_Q == 18 +#define _IQ(A) _IQ18(A) +#endif +#if GLOBAL_Q == 17 +#define _IQ(A) _IQ17(A) +#endif +#if GLOBAL_Q == 16 +#define _IQ(A) _IQ16(A) +#endif +#if GLOBAL_Q == 15 +#define _IQ(A) _IQ15(A) +#endif +#if GLOBAL_Q == 14 +#define _IQ(A) _IQ14(A) +#endif +#if GLOBAL_Q == 13 +#define _IQ(A) _IQ13(A) +#endif +#if GLOBAL_Q == 12 +#define _IQ(A) _IQ12(A) +#endif +#if GLOBAL_Q == 11 +#define _IQ(A) _IQ11(A) +#endif +#if GLOBAL_Q == 10 +#define _IQ(A) _IQ10(A) +#endif +#if GLOBAL_Q == 9 +#define _IQ(A) _IQ9(A) +#endif +#if GLOBAL_Q == 8 +#define _IQ(A) _IQ8(A) +#endif +#if GLOBAL_Q == 7 +#define _IQ(A) _IQ7(A) +#endif +#if GLOBAL_Q == 6 +#define _IQ(A) _IQ6(A) +#endif +#if GLOBAL_Q == 5 +#define _IQ(A) _IQ5(A) +#endif +#if GLOBAL_Q == 4 +#define _IQ(A) _IQ4(A) +#endif +#if GLOBAL_Q == 3 +#define _IQ(A) _IQ3(A) +#endif +#if GLOBAL_Q == 2 +#define _IQ(A) _IQ2(A) +#endif +#if GLOBAL_Q == 1 +#define _IQ(A) _IQ1(A) +#endif + +//--------------------------------------------------------------------------- + +#define _IQ30toF(A) ((float) ((A) / 1073741824.0L)) +#define _IQ29toF(A) ((float) ((A) / 536870912.0L)) +#define _IQ28toF(A) ((float) ((A) / 268435456.0L)) +#define _IQ27toF(A) ((float) ((A) / 134217728.0L)) +#define _IQ26toF(A) ((float) ((A) / 67108864.0L)) +#define _IQ25toF(A) ((float) ((A) / 33554432.0L)) +#define _IQ24toF(A) ((float) ((A) / 16777216.0L)) +#define _IQ23toF(A) ((float) ((A) / 8388608.0L)) +#define _IQ22toF(A) ((float) ((A) / 4194304.0L)) +#define _IQ21toF(A) ((float) ((A) / 2097152.0L)) +#define _IQ20toF(A) ((float) ((A) / 1048576.0L)) +#define _IQ19toF(A) ((float) ((A) / 524288.0L)) +#define _IQ18toF(A) ((float) ((A) / 262144.0L)) +#define _IQ17toF(A) ((float) ((A) / 131072.0L)) +#define _IQ16toF(A) ((float) ((A) / 65536.0L)) +#define _IQ15toF(A) ((float) ((A) / 32768.0L)) +#define _IQ14toF(A) ((float) ((A) / 16384.0L)) +#define _IQ13toF(A) ((float) ((A) / 8192.0L)) +#define _IQ12toF(A) ((float) ((A) / 4096.0L)) +#define _IQ11toF(A) ((float) ((A) / 2048.0L)) +#define _IQ10toF(A) ((float) ((A) / 1024.0L)) +#define _IQ9toF(A) ((float) ((A) / 512.0L)) +#define _IQ8toF(A) ((float) ((A) / 256.0L)) +#define _IQ7toF(A) ((float) ((A) / 128.0L)) +#define _IQ6toF(A) ((float) ((A) / 64.0L)) +#define _IQ5toF(A) ((float) ((A) / 32.0L)) +#define _IQ4toF(A) ((float) ((A) / 16.0L)) +#define _IQ3toF(A) ((float) ((A) / 8.0L)) +#define _IQ2toF(A) ((float) ((A) / 4.0L)) +#define _IQ1toF(A) ((float) ((A) / 2.0L)) + +#if GLOBAL_Q == 30 +#define _IQtoF(A) _IQ30toF(A) +#endif +#if GLOBAL_Q == 29 +#define _IQtoF(A) _IQ29toF(A) +#endif +#if GLOBAL_Q == 28 +#define _IQtoF(A) _IQ28toF(A) +#endif +#if GLOBAL_Q == 27 +#define _IQtoF(A) _IQ27toF(A) +#endif +#if GLOBAL_Q == 26 +#define _IQtoF(A) _IQ26toF(A) +#endif +#if GLOBAL_Q == 25 +#define _IQtoF(A) _IQ25toF(A) +#endif +#if GLOBAL_Q == 24 +#define _IQtoF(A) _IQ24toF(A) +#endif +#if GLOBAL_Q == 23 +#define _IQtoF(A) _IQ23toF(A) +#endif +#if GLOBAL_Q == 22 +#define _IQtoF(A) _IQ22toF(A) +#endif +#if GLOBAL_Q == 21 +#define _IQtoF(A) _IQ21toF(A) +#endif +#if GLOBAL_Q == 20 +#define _IQtoF(A) _IQ20toF(A) +#endif +#if GLOBAL_Q == 19 +#define _IQtoF(A) _IQ19toF(A) +#endif +#if GLOBAL_Q == 18 +#define _IQtoF(A) _IQ18toF(A) +#endif +#if GLOBAL_Q == 17 +#define _IQtoF(A) _IQ17toF(A) +#endif +#if GLOBAL_Q == 16 +#define _IQtoF(A) _IQ16toF(A) +#endif +#if GLOBAL_Q == 15 +#define _IQtoF(A) _IQ15toF(A) +#endif +#if GLOBAL_Q == 14 +#define _IQtoF(A) _IQ14toF(A) +#endif +#if GLOBAL_Q == 13 +#define _IQtoF(A) _IQ13toF(A) +#endif +#if GLOBAL_Q == 12 +#define _IQtoF(A) _IQ12toF(A) +#endif +#if GLOBAL_Q == 11 +#define _IQtoF(A) _IQ11toF(A) +#endif +#if GLOBAL_Q == 10 +#define _IQtoF(A) _IQ10toF(A) +#endif +#if GLOBAL_Q == 9 +#define _IQtoF(A) _IQ9toF(A) +#endif +#if GLOBAL_Q == 8 +#define _IQtoF(A) _IQ8toF(A) +#endif +#if GLOBAL_Q == 7 +#define _IQtoF(A) _IQ7toF(A) +#endif +#if GLOBAL_Q == 6 +#define _IQtoF(A) _IQ6toF(A) +#endif +#if GLOBAL_Q == 5 +#define _IQtoF(A) _IQ5toF(A) +#endif +#if GLOBAL_Q == 4 +#define _IQtoF(A) _IQ4toF(A) +#endif +#if GLOBAL_Q == 3 +#define _IQtoF(A) _IQ3toF(A) +#endif +#if GLOBAL_Q == 2 +#define _IQtoF(A) _IQ2toF(A) +#endif +#if GLOBAL_Q == 1 +#define _IQtoF(A) _IQ1toF(A) +#endif + +#define _IQsat(A, Pos, Neg) ((A > Pos) ? Pos : (A < Neg) ? Neg : A) +//--------------------------------------------------------------------------- +#define _IQtoIQ30(A) ((long) (A) << (30 - GLOBAL_Q)) +#define _IQ30toIQ(A) ((long) (A) >> (30 - GLOBAL_Q)) + +#if (GLOBAL_Q >= 29) +#define _IQtoIQ29(A) ((long) (A) >> (GLOBAL_Q - 29)) +#define _IQ29toIQ(A) ((long) (A) << (GLOBAL_Q - 29)) +#else +#define _IQtoIQ29(A) ((long) (A) << (29 - GLOBAL_Q)) +#define _IQ29toIQ(A) ((long) (A) >> (29 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 28) +#define _IQtoIQ28(A) ((long) (A) >> (GLOBAL_Q - 28)) +#define _IQ28toIQ(A) ((long) (A) << (GLOBAL_Q - 28)) +#else +#define _IQtoIQ28(A) ((long) (A) << (28 - GLOBAL_Q)) +#define _IQ28toIQ(A) ((long) (A) >> (28 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 27) +#define _IQtoIQ27(A) ((long) (A) >> (GLOBAL_Q - 27)) +#define _IQ27toIQ(A) ((long) (A) << (GLOBAL_Q - 27)) +#else +#define _IQtoIQ27(A) ((long) (A) << (27 - GLOBAL_Q)) +#define _IQ27toIQ(A) ((long) (A) >> (27 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 26) +#define _IQtoIQ26(A) ((long) (A) >> (GLOBAL_Q - 26)) +#define _IQ26toIQ(A) ((long) (A) << (GLOBAL_Q - 26)) +#else +#define _IQtoIQ26(A) ((long) (A) << (26 - GLOBAL_Q)) +#define _IQ26toIQ(A) ((long) (A) >> (26 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 25) +#define _IQtoIQ25(A) ((long) (A) >> (GLOBAL_Q - 25)) +#define _IQ25toIQ(A) ((long) (A) << (GLOBAL_Q - 25)) +#else +#define _IQtoIQ25(A) ((long) (A) << (25 - GLOBAL_Q)) +#define _IQ25toIQ(A) ((long) (A) >> (25 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 24) +#define _IQtoIQ24(A) ((long) (A) >> (GLOBAL_Q - 24)) +#define _IQ24toIQ(A) ((long) (A) << (GLOBAL_Q - 24)) +#else +#define _IQtoIQ24(A) ((long) (A) << (24 - GLOBAL_Q)) +#define _IQ24toIQ(A) ((long) (A) >> (24 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 23) +#define _IQtoIQ23(A) ((long) (A) >> (GLOBAL_Q - 23)) +#define _IQ23toIQ(A) ((long) (A) << (GLOBAL_Q - 23)) +#else +#define _IQtoIQ23(A) ((long) (A) << (23 - GLOBAL_Q)) +#define _IQ23toIQ(A) ((long) (A) >> (23 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 22) +#define _IQtoIQ22(A) ((long) (A) >> (GLOBAL_Q - 22)) +#define _IQ22toIQ(A) ((long) (A) << (GLOBAL_Q - 22)) +#else +#define _IQtoIQ22(A) ((long) (A) << (22 - GLOBAL_Q)) +#define _IQ22toIQ(A) ((long) (A) >> (22 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 21) +#define _IQtoIQ21(A) ((long) (A) >> (GLOBAL_Q - 21)) +#define _IQ21toIQ(A) ((long) (A) << (GLOBAL_Q - 21)) +#else +#define _IQtoIQ21(A) ((long) (A) << (21 - GLOBAL_Q)) +#define _IQ21toIQ(A) ((long) (A) >> (21 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 20) +#define _IQtoIQ20(A) ((long) (A) >> (GLOBAL_Q - 20)) +#define _IQ20toIQ(A) ((long) (A) << (GLOBAL_Q - 20)) +#else +#define _IQtoIQ20(A) ((long) (A) << (20 - GLOBAL_Q)) +#define _IQ20toIQ(A) ((long) (A) >> (20 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 19) +#define _IQtoIQ19(A) ((long) (A) >> (GLOBAL_Q - 19)) +#define _IQ19toIQ(A) ((long) (A) << (GLOBAL_Q - 19)) +#else +#define _IQtoIQ19(A) ((long) (A) << (19 - GLOBAL_Q)) +#define _IQ19toIQ(A) ((long) (A) >> (19 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 18) +#define _IQtoIQ18(A) ((long) (A) >> (GLOBAL_Q - 18)) +#define _IQ18toIQ(A) ((long) (A) << (GLOBAL_Q - 18)) +#else +#define _IQtoIQ18(A) ((long) (A) << (18 - GLOBAL_Q)) +#define _IQ18toIQ(A) ((long) (A) >> (18 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 17) +#define _IQtoIQ17(A) ((long) (A) >> (GLOBAL_Q - 17)) +#define _IQ17toIQ(A) ((long) (A) << (GLOBAL_Q - 17)) +#else +#define _IQtoIQ17(A) ((long) (A) << (17 - GLOBAL_Q)) +#define _IQ17toIQ(A) ((long) (A) >> (17 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 16) +#define _IQtoIQ16(A) ((long) (A) >> (GLOBAL_Q - 16)) +#define _IQ16toIQ(A) ((long) (A) << (GLOBAL_Q - 16)) +#else +#define _IQtoIQ16(A) ((long) (A) << (16 - GLOBAL_Q)) +#define _IQ16toIQ(A) ((long) (A) >> (16 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 15) +#define _IQtoIQ15(A) ((long) (A) >> (GLOBAL_Q - 15)) +#define _IQ15toIQ(A) ((long) (A) << (GLOBAL_Q - 15)) +#define _IQtoQ15(A) ((long) (A) >> (GLOBAL_Q - 15)) +#define _Q15toIQ(A) ((long) (A) << (GLOBAL_Q - 15)) +#else +#define _IQtoIQ15(A) ((long) (A) << (15 - GLOBAL_Q)) +#define _IQ15toIQ(A) ((long) (A) >> (15 - GLOBAL_Q)) +#define _IQtoQ15(A) ((long) (A) << (15 - GLOBAL_Q)) +#define _Q15toIQ(A) ((long) (A) >> (15 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 14) +#define _IQtoIQ14(A) ((long) (A) >> (GLOBAL_Q - 14)) +#define _IQ14toIQ(A) ((long) (A) << (GLOBAL_Q - 14)) +#define _IQtoQ14(A) ((long) (A) >> (GLOBAL_Q - 14)) +#define _Q14toIQ(A) ((long) (A) << (GLOBAL_Q - 14)) +#else +#define _IQtoIQ14(A) ((long) (A) << (14 - GLOBAL_Q)) +#define _IQ14toIQ(A) ((long) (A) >> (14 - GLOBAL_Q)) +#define _IQtoQ14(A) ((long) (A) << (14 - GLOBAL_Q)) +#define _Q14toIQ(A) ((long) (A) >> (14 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 13) +#define _IQtoIQ13(A) ((long) (A) >> (GLOBAL_Q - 13)) +#define _IQ13toIQ(A) ((long) (A) << (GLOBAL_Q - 13)) +#define _IQtoQ13(A) ((long) (A) >> (GLOBAL_Q - 13)) +#define _Q13toIQ(A) ((long) (A) << (GLOBAL_Q - 13)) +#else +#define _IQtoIQ13(A) ((long) (A) << (13 - GLOBAL_Q)) +#define _IQ13toIQ(A) ((long) (A) >> (13 - GLOBAL_Q)) +#define _IQtoQ13(A) ((long) (A) << (13 - GLOBAL_Q)) +#define _Q13toIQ(A) ((long) (A) >> (13 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 12) +#define _IQtoIQ12(A) ((long) (A) >> (GLOBAL_Q - 12)) +#define _IQ12toIQ(A) ((long) (A) << (GLOBAL_Q - 12)) +#define _IQtoQ12(A) ((long) (A) >> (GLOBAL_Q - 12)) +#define _Q12toIQ(A) ((long) (A) << (GLOBAL_Q - 12)) +#else +#define _IQtoIQ12(A) ((long) (A) << (12 - GLOBAL_Q)) +#define _IQ12toIQ(A) ((long) (A) >> (12 - GLOBAL_Q)) +#define _IQtoQ12(A) ((long) (A) << (12 - GLOBAL_Q)) +#define _Q12toIQ(A) ((long) (A) >> (12 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 11) +#define _IQtoIQ11(A) ((long) (A) >> (GLOBAL_Q - 11)) +#define _IQ11toIQ(A) ((long) (A) << (GLOBAL_Q - 11)) +#define _IQtoQ11(A) ((long) (A) >> (GLOBAL_Q - 11)) +#define _Q11toIQ(A) ((long) (A) << (GLOBAL_Q - 11)) +#else +#define _IQtoIQ11(A) ((long) (A) << (11 - GLOBAL_Q)) +#define _IQ11toIQ(A) ((long) (A) >> (11 - GLOBAL_Q)) +#define _IQtoQ11(A) ((long) (A) << (11 - GLOBAL_Q)) +#define _Q11toIQ(A) ((long) (A) >> (11 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 10) +#define _IQtoIQ10(A) ((long) (A) >> (GLOBAL_Q - 10)) +#define _IQ10toIQ(A) ((long) (A) << (GLOBAL_Q - 10)) +#define _IQtoQ10(A) ((long) (A) >> (GLOBAL_Q - 10)) +#define _Q10toIQ(A) ((long) (A) << (GLOBAL_Q - 10)) +#else +#define _IQtoIQ10(A) ((long) (A) << (10 - GLOBAL_Q)) +#define _IQ10toIQ(A) ((long) (A) >> (10 - GLOBAL_Q)) +#define _IQtoQ10(A) ((long) (A) << (10 - GLOBAL_Q)) +#define _Q10toIQ(A) ((long) (A) >> (10 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 9) +#define _IQtoIQ9(A) ((long) (A) >> (GLOBAL_Q - 9)) +#define _IQ9toIQ(A) ((long) (A) << (GLOBAL_Q - 9)) +#define _IQtoQ9(A) ((long) (A) >> (GLOBAL_Q - 9)) +#define _Q9toIQ(A) ((long) (A) << (GLOBAL_Q - 9)) +#else +#define _IQtoIQ9(A) ((long) (A) << (9 - GLOBAL_Q)) +#define _IQ9toIQ(A) ((long) (A) >> (9 - GLOBAL_Q)) +#define _IQtoQ9(A) ((long) (A) << (9 - GLOBAL_Q)) +#define _Q9toIQ(A) ((long) (A) >> (9 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 8) +#define _IQtoIQ8(A) ((long) (A) >> (GLOBAL_Q - 8)) +#define _IQ8toIQ(A) ((long) (A) << (GLOBAL_Q - 8)) +#define _IQtoQ8(A) ((long) (A) >> (GLOBAL_Q - 8)) +#define _Q8toIQ(A) ((long) (A) << (GLOBAL_Q - 8)) +#else +#define _IQtoIQ8(A) ((long) (A) << (8 - GLOBAL_Q)) +#define _IQ8toIQ(A) ((long) (A) >> (8 - GLOBAL_Q)) +#define _IQtoQ8(A) ((long) (A) << (8 - GLOBAL_Q)) +#define _Q8toIQ(A) ((long) (A) >> (8 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 7) +#define _IQtoIQ7(A) ((long) (A) >> (GLOBAL_Q - 7)) +#define _IQ7toIQ(A) ((long) (A) << (GLOBAL_Q - 7)) +#define _IQtoQ7(A) ((long) (A) >> (GLOBAL_Q - 7)) +#define _Q7toIQ(A) ((long) (A) << (GLOBAL_Q - 7)) +#else +#define _IQtoIQ7(A) ((long) (A) << (7 - GLOBAL_Q)) +#define _IQ7toIQ(A) ((long) (A) >> (7 - GLOBAL_Q)) +#define _IQtoQ7(A) ((long) (A) << (7 - GLOBAL_Q)) +#define _Q7toIQ(A) ((long) (A) >> (7 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 6) +#define _IQtoIQ6(A) ((long) (A) >> (GLOBAL_Q - 6)) +#define _IQ6toIQ(A) ((long) (A) << (GLOBAL_Q - 6)) +#define _IQtoQ6(A) ((long) (A) >> (GLOBAL_Q - 6)) +#define _Q6toIQ(A) ((long) (A) << (GLOBAL_Q - 6)) +#else +#define _IQtoIQ6(A) ((long) (A) << (6 - GLOBAL_Q)) +#define _IQ6toIQ(A) ((long) (A) >> (6 - GLOBAL_Q)) +#define _IQtoQ6(A) ((long) (A) << (6 - GLOBAL_Q)) +#define _Q6toIQ(A) ((long) (A) >> (6 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 5) +#define _IQtoIQ5(A) ((long) (A) >> (GLOBAL_Q - 5)) +#define _IQ5toIQ(A) ((long) (A) << (GLOBAL_Q - 5)) +#define _IQtoQ5(A) ((long) (A) >> (GLOBAL_Q - 5)) +#define _Q5toIQ(A) ((long) (A) << (GLOBAL_Q - 5)) +#else +#define _IQtoIQ5(A) ((long) (A) << (5 - GLOBAL_Q)) +#define _IQ5toIQ(A) ((long) (A) >> (5 - GLOBAL_Q)) +#define _IQtoQ5(A) ((long) (A) << (5 - GLOBAL_Q)) +#define _Q5toIQ(A) ((long) (A) >> (5 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 4) +#define _IQtoIQ4(A) ((long) (A) >> (GLOBAL_Q - 4)) +#define _IQ4toIQ(A) ((long) (A) << (GLOBAL_Q - 4)) +#define _IQtoQ4(A) ((long) (A) >> (GLOBAL_Q - 4)) +#define _Q4toIQ(A) ((long) (A) << (GLOBAL_Q - 4)) +#else +#define _IQtoIQ4(A) ((long) (A) << (4 - GLOBAL_Q)) +#define _IQ4toIQ(A) ((long) (A) >> (4 - GLOBAL_Q)) +#define _IQtoQ4(A) ((long) (A) << (4 - GLOBAL_Q)) +#define _Q4toIQ(A) ((long) (A) >> (4 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 3) +#define _IQtoIQ3(A) ((long) (A) >> (GLOBAL_Q - 3)) +#define _IQ3toIQ(A) ((long) (A) << (GLOBAL_Q - 3)) +#define _IQtoQ3(A) ((long) (A) >> (GLOBAL_Q - 3)) +#define _Q3toIQ(A) ((long) (A) << (GLOBAL_Q - 3)) +#else +#define _IQtoIQ3(A) ((long) (A) << (3 - GLOBAL_Q)) +#define _IQ3toIQ(A) ((long) (A) >> (3 - GLOBAL_Q)) +#define _IQtoQ3(A) ((long) (A) << (3 - GLOBAL_Q)) +#define _Q3toIQ(A) ((long) (A) >> (3 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 2) +#define _IQtoIQ2(A) ((long) (A) >> (GLOBAL_Q - 2)) +#define _IQ2toIQ(A) ((long) (A) << (GLOBAL_Q - 2)) +#define _IQtoQ2(A) ((long) (A) >> (GLOBAL_Q - 2)) +#define _Q2toIQ(A) ((long) (A) << (GLOBAL_Q - 2)) +#else +#define _IQtoIQ2(A) ((long) (A) << (2 - GLOBAL_Q)) +#define _IQ2toIQ(A) ((long) (A) >> (2 - GLOBAL_Q)) +#define _IQtoQ2(A) ((long) (A) << (2 - GLOBAL_Q)) +#define _Q2toIQ(A) ((long) (A) >> (2 - GLOBAL_Q)) +#endif + +#if (GLOBAL_Q >= 1) +#define _IQtoQ1(A) ((long) (A) >> (GLOBAL_Q - 1)) +#define _Q1toIQ(A) ((long) (A) << (GLOBAL_Q - 1)) +#else +#define _IQtoQ1(A) ((long) (A) << (1 - GLOBAL_Q)) +#define _Q1toIQ(A) ((long) (A) >> (1 - GLOBAL_Q)) +#endif + +#define _IQtoIQ1(A) ((long) (A) >> (GLOBAL_Q - 1)) +#define _IQ1toIQ(A) ((long) (A) << (GLOBAL_Q - 1)) + +///////////////////////////////////////////////////////////// +long multiply(long x, long y); +long long multiply_fixed_base_select(long long x, long long y, int base); +long divide(long num, long den); +long sin_fixed(long x); +long cos_fixed(long x); +long sqrt_fixed(long x); + +#define _IQabs(A) ((A) > 0 ? (A): -(A)) +#define _IQmpy(A,B) multiply(A,B) +#define _IQ19mpy(A,B) multiply_fixed_base_select(A,B,19) +#define _IQdiv(A,B) divide(A,B) +#define _IQsin(A) sin_fixed(A) +#define _IQcos(A) cos_fixed(A) +#define _IQsqrt(A) sqrt_fixed(A) + +#define PI 3.1415926535897932384626433832795 +#define PI_2 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 + +#ifndef ONE_24 +#define ONE_24 16777216 +#endif +#ifndef ONE_27 +#define ONE_27 134217728 +#endif +#ifndef ONE_28 +#define ONE_28 268435456 +#endif + +// #ifndef FIXED_PI +// #define FIXED_PI 52707179 +// #endif + +// #ifndef FIXED_2PI +// #define FIXED_2PI 105414357 +// #endif + +#ifndef FIXED_PI_30 +#define FIXED_PI_30 3373259426 +#endif + +#ifndef FIXED_2PI_30 +#define FIXED_2PI_30 6746518852 +#endif + +#ifndef FIXED_3PIna2 +#define FIXED_3PIna2 79060768 +#endif + +#ifndef FIXED_PIna3 +#define FIXED_PIna3 17569059 +#endif + +#ifndef FIXED_PIna6 +#define FIXED_PIna6 8784529 +#endif + + +#endif //IQ_MATH_LIB diff --git a/Inu/Src2/main/PWMTools.c b/Inu/Src2/main/PWMTools.c new file mode 100644 index 0000000..561b909 --- /dev/null +++ b/Inu/Src2/main/PWMTools.c @@ -0,0 +1,719 @@ +#include <math.h> +#include <stdlib.h> +//#include "project.h" + +#include "IQmathLib.h" +//#include "f281xpwm.h" +// +////#include "SpaceVectorPWM.h" +//#include "MemoryFunctions.h" +//#include "PWMTools.h" +//#include "pwm_vector_regul.h" +//#include "PWMTMSHandle.h" +//#include "TuneUpPlane.h" +//#include "RS_Functions.h" +//#include "CAN_setup.h" +//#include "global_time.h" +#include "params.h" +#include "vector.h" +//#include "rmp_cntl_my1.h" +//#include "vhzprof.h" +//#include "adc_tools.h" +//#include "v_pwm24.h" +//#include "break_regul.h" +//#include "break_tools.h" +//#include "detect_phase.h" +//#include "mathlib.h" +//#include "project.h" +//#include "log_to_memory.h" +//#include "rotation_speed.h" +//#include "detect_overload.h" +//#include "xp_write_xpwm_time.h" +//#include "errors.h" +//#include "sync_tools.h" +//#include "optical_bus.h" +//#include "IQmathLib.h" + +#define DEF_FREQ_PWM_XTICS (3750000 / FREQ_PWM / 2) +#define DEF_PERIOD_MIN_XTICS 400 //375 ~ 100mks //315 ~ 84 mks //460//(3750000 * mks / 1000000) +#define DEF_PERIOD_MIN_BR_XTICS 165 + +#define DEF_FREQ_PWM_XTICS_MIN = 4261 +#define DEF_FREQ_PWM_XTICS_MAX = 4687 + +#define STOP_ROTOR_LIMIT 27962 //2 rpm +#define STOP_ROTOR_MIN_CURRENT 4194304 //750A //3355443 //600A + +#define K_MODUL_MAX 15770583 //13421772 //80% //10066329 //60% //5033164 //30% 15099494 ~ 90% //15435038 ~ 0.92% + //15770583 ~ 0.94% +#define MIN_Fsl_WHEN_STOPED 41943 //0.05 //67108 //0.08Hz + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + +//4464 +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +#pragma DATA_SECTION(VAR_FREQ_PWM_XTICS,".fast_vars1"); +int VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +#pragma DATA_SECTION(VAR_PERIOD_MAX_XTICS,".fast_vars1"); +int VAR_PERIOD_MAX_XTICS = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +#pragma DATA_SECTION(VAR_PERIOD_MIN_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_XTICS = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +#pragma DATA_SECTION(VAR_PERIOD_MIN_BR_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_BR_XTICS = DEF_PERIOD_MIN_BR_XTICS;// + +#pragma DATA_SECTION(freq1,".fast_vars1"); +_iq freq1; + +#pragma DATA_SECTION(k1,".fast_vars1"); +_iq k1 = 0; + +RMP_MY1 rmp_freq = RMP_MY1_DEFAULTS; +//VHZPROF vhz1 = VHZPROF_DEFAULTS; + +// WINDING a; +// FLAG f; + +#define COUNT_SAVE_LOG_OFF 100 //������� ������ ��� ����������� ����� ��������� +#define COUNT_START_IMP 2 + +int i = 0; +/*void InitPWM() +{ + WriteMemory(ADR_PWM_MODE_0, 0x0000); //�������� � �������� ��������� ��� TMS +}*/ + +static void write_swgen_pwm_times(); +void write_swgen_pwm_times_split_eages(unsigned int mode_reload); +void fix_pwm_freq_synchro_ain(); +void detect_level_interrupt(void); +void detect_current_saw_val(void); + +void InitXPWM(void) +{ + + #ifdef XPWMGEN + /* Start of PWM Generator initialization*/ + for(i = 0; i < 16; i++) // �������� + { + WriteMemory(ADR_PWM_KEY_NUMBER, i); + WriteMemory(ADR_PWM_TIMING, 0); + + } + WriteMemory(ADR_PWM_DIRECT, 0xffff); + WriteMemory(ADR_PWM_DRIVE_MODE, 0); //Choose PWM sourse PWMGenerator on Spartan 200e + WriteMemory(ADR_PWM_DEAD_TIME, 360); //Dead time in tics. 1 tic = 16.67 nsec +#ifndef _test_without_power + // OFF WDOG + WriteMemory(ADR_PWM_WDOG, 0x8005); //TODO turn on +#else + // ON WDOG + WriteMemory(ADR_PWM_WDOG, 0x0005); //TODO turn on +#endif + WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec + WriteMemory(ADR_PWM_SAW_DIRECT, 0x0555); + WriteMemory(ADR_TK_MASK_0, 0); + WriteMemory(ADR_TK_MASK_1, 0xffff); //Turn off additional 16 tk lines +#if C_PROJECT_TYPE == PROJECT_BALZAM + WriteMemory(ADR_PWM_IT_TYPE, 1); //1 interrupt per PWM period +#else + WriteMemory(ADR_PWM_IT_TYPE, 0); //interrupt on each counter twist +#endif +// WriteMemory(ADR_PWM_WDOG, 0x8008);//���������� ������ �� PWM + #endif + + #ifdef TMSPWMGEN + + WriteMemory(ADR_PWM_MODE_0, 0x0000); //�������� � �������� ��������� ��� TMS + + #endif + +/* End �f PWM Gen init */ +} + +void initPWM_Variables(void) +{ + //��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� +// xpwm_time.Tclosed_0 = 0; +// xpwm_time.Tclosed_1 = VAR_FREQ_PWM_XTICS + 1; +// xpwm_time.pwm_tics = VAR_FREQ_PWM_XTICS; +// xpwm_time.saw_direct.all = 0;//0x0555; +// xpwm_time.one_or_two_interrupts_run = PWM_TWICE_INTERRUPT_RUN; + + + init_alpha_pwm24(VAR_FREQ_PWM_XTICS); + InitVariablesSvgen(VAR_FREQ_PWM_XTICS); + init_DQ_pid(); + break_resistor_managment_init(); + + rmp_freq.RampLowLimit = _IQ(-4); //0 + rmp_freq.RampHighLimit = _IQ(4); + + rmp_freq.RampPlus = _IQ(0.00005); //_IQ(0.0002);_IQ(0.000005); + + rmp_freq.RampMinus = _IQ(-0.00005); //_IQ(-0.000005); + rmp_freq.DesiredInput = 0; + rmp_freq.Out = 0; + + a.k = 0; + a.k1 = 0; + a.k2 = 0; + + k1 = 0; + freq1 = 0; +} + +#pragma CODE_SECTION(start_PWM24,".fast_run2") +void start_PWM24(int O1, int O2) +{ + if ((O1 == 1) && (O2 == 1)) + { + start_pwm(); + } + else + { + if ((O1 == 0) && (O2 == 1)) + { + start_pwm_b(); + } + if ((O1 == 1) && (O2 == 0)) + { + start_pwm_a(); + } + } +} + +inline void init_regulators() +{ + if(f.Mode != 0) + { + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, f.Mode, 1, 1); + } +} + +#define select_working_channels(go_a, go_b) go_a = !f.Obmotka1; \ + go_b = !f.Obmotka2; + +void PWM_interrupt() +{ + static unsigned int pwm_run = 0; + static _iq Uzad1, Fzad, Uzad2; + static int count_step=0; + static int count_step_ram_off = 0; + static int count_start_impuls = 0; + static int flag_record_log = 0; + static int log_saved_to_const_mem = 0; + static int prevGo = -1; + static volatile unsigned int go_a = 0; + static volatile unsigned int go_b = 0; + + static int stop_rotor_counter = 0; + + static int prev_go_a = 1; + static int prev_go_b = 1; + + int pwm_enable_calc_main = 0; + + int start_int_xtics = 0, end_int_xtics = 0; + +// i_led1_on_off(1); + if (pwm_run == 1) + { +// stop_pwm(); +// errors.slow_stop.bit.PWM_interrupt_to_long |= 1; + return; + } + pwm_run = 1; + + +// detect_level_interrupt(); +// start_int_xtics = xpwm_time.current_period; + if (xpwm_time.where_interrupt == PWM_LOW_LEVEL_INTERRUPT + || xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + { + pwm_enable_calc_main = 1; + if (f.flag_second_PCH) { + fix_pwm_freq_synchro_ain(); + } + } + else { +// i_sync_pin_on(); + pwm_enable_calc_main = 0; + } + + +// project.cds_in[0].read_pbus(&project.cds_in[0]); //read direction +// project.read_all_pbus(); +// optical_bus_read(); + + update_rot_sensors(); + global_time.calc(&global_time); +// + inc_RS_timeout_cicle(); + inc_CAN_timeout_cicle(); + detect_I_M_overload(); + DetectI_Out_BreakFase(); + Rotor_measure(); + + if ((f.Go == 1) && (f.Stop == 0) + && (f.rotor_stopped == 0) +// && (faults.faults5.bit.rotor_stopped == 0) + /* && (f.Ready2 == 1)*/) + { + if (f.Ready2) {f.flag_turn_On_Pump = 1;} //�� ��-��� ������ + if (f.Go != prevGo) { + set_start_mem(FAST_LOG); +// clear_mem(FAST_LOG); +// count_start_impuls = 0; + count_step = 0; + count_step_ram_off = COUNT_SAVE_LOG_OFF; + + init_regulators(); + stop_rotor_counter = 0; + } else { + if (f.Mode == 0) { + rmp_freq.DesiredInput = freq1; + rmp_freq.calc(&rmp_freq); +// Fzad = rmp_freq.Out; + Fzad = freq1; +// if(k1 < 87772) +// { k1 = 87772;} + Uzad1 = k1; + Uzad2 = k1; + } + + select_working_channels(go_a, go_b); + + if (go_a == 0 && prev_go_a != go_a) { + stop_pwm_a(); + } + if (go_a == 1 && prev_go_a != go_a) { + start_pwm_a(); + } + if (go_b == 0 && prev_go_b != go_b) { + stop_pwm_b(); + } + if (go_b == 1 && prev_go_b != go_b) { + start_pwm_b(); + } + + prev_go_a = go_a; + prev_go_b = go_b; + + if (count_start_impuls < COUNT_START_IMP) { + count_start_impuls++; + + Fzad = 0; + rmp_freq.Out = 0; + +// set_start_mem(FAST_LOG); +// set_start_mem(SLOW_LOG); + } else { + + if (count_start_impuls==2) + { + if (go_a == 1 && go_b == 1) { + // ��� ���������� middle ��������� ������ ����� ����������� ������� pwm + // start_pwm(); ������ ��������� ���� ��� �� ��������� f.Go + start_pwm(); + } else if (go_a == 1) { + write_swgen_pwm_times(); //TODO: Check with new PWM + start_pwm_a(); + } else if (go_b == 1) { + write_swgen_pwm_times(); + start_pwm_b(); + } + } // end if (count_start_impuls==1) + + count_start_impuls++; + if (count_start_impuls > 2 * COUNT_START_IMP) { + count_start_impuls = 2 * COUNT_START_IMP; + } + + + } + } + flag_record_log = 1; + log_saved_to_const_mem = 0; + } else { + if (f.Discharge + && (errors.slow_stop2.bit.Break_Resistor == 0) + && (errors.plains_and_others.bit.er0_setted == 0) + && (errors.umu_errors.bit.Voltage380_BSU_Off == 0)) +// && !f.Stop) + { + start_break_pwm(); + break_resistor_managment_calc(); + } else { + //Do not stop, when come for the first time, to write to xilinx times to close keys. + //Otherwise mintime error can occure. + //Also we do not stop pwm wile break_resistor keys working + if (!count_start_impuls) { + // ��� ���������� ������ �� ������ ����� ���������� + stop_pwm(); + } + break_resistor_set_closed(); + } + if (count_step_ram_off > 0) { + count_step_ram_off--; + flag_record_log = 1; + } else { + flag_record_log = 0; + } + + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, 0, 1, 1); + + if (count_start_impuls > 0) { + count_start_impuls -= 1; + } else { + count_start_impuls = 0; + } + + Uzad1 = 87772; //0.5% + Uzad2 = 87772; + k1 = Uzad1; + svgen_pwm24_1.Gain = Uzad1; + svgen_pwm24_2.Gain = Uzad1; + svgen_dq_1.Ualpha = 0; + svgen_dq_1.Ubeta = 0; + svgen_dq_2.Ualpha = 0; + svgen_dq_2.Ubeta = 0; + a.iqk = Uzad1; + } +// a.iqk1 = Uzad1; +// a.iqk2 = Uzad2; +// a.iqk = (a.iqk1 + a.iqk2) >> 1; +// a.iqf = Fzad; + prevGo = f.Go; + + break_resistor_recup_calc(); + break_resistor_managment_update(); + + if (count_start_impuls >= (2 * COUNT_START_IMP) ) { + + if (f.Mode == 0) { +// test_calc_pwm24(Uzad1, Uzad2, Fzad); + if (pwm_enable_calc_main) { + test_calc_simple_dq_pwm24(Uzad1, Uzad2, Fzad, Fzad, K_MODUL_MAX); + } + analog_dq_calc_const(); + } else { + if ((_IQabs(rotor.iqFout) < STOP_ROTOR_LIMIT) + && (_IQabs(analog.iqIq1) > STOP_ROTOR_MIN_CURRENT)) { + if ((stop_rotor_counter >= 2520)) { + stop_rotor_counter = 2520; +// faults.faults5.bit.rotor_stopped |= 1; + f.rotor_stopped |= 1; + } else { + stop_rotor_counter += 1; + } + if (_IQabs(analog.Fsl) < MIN_Fsl_WHEN_STOPED) { +// faults.faults5.bit.rotor_stopped |= 1; + f.rotor_stopped |= 1; + } + } else { + if (stop_rotor_counter > 0) { + stop_rotor_counter -= 1; + } else { + stop_rotor_counter = 0; + } + } + + pwm_vector_model_titov(f.iq_p_zad, f.iq_fzad, rotor.direct_rotor, + rotor.iqFout, f.Mode, 0, pwm_enable_calc_main); + } + + } else { + // ��� ����� middle ��������� ����� ����������� ������ + if (count_start_impuls) + { +// svgen_set_time_keys_closed(&svgen_pwm24_1); +// svgen_set_time_keys_closed(&svgen_pwm24_2); + svgen_set_time_middle_keys_open(&svgen_pwm24_1); + svgen_set_time_middle_keys_open(&svgen_pwm24_2); + } + else + // � ��� �� ��� ����������� + { + svgen_set_time_keys_closed(&svgen_pwm24_1); + svgen_set_time_keys_closed(&svgen_pwm24_2); + //������� ������ ���� +// if (faults.faults5.bit.rotor_stopped == 1) { + if (f.rotor_stopped == 1) { + if (stop_rotor_counter > 0) { + stop_rotor_counter -= 1; + } else { +// faults.faults5.bit.rotor_stopped = 0; + f.rotor_stopped = 0; + stop_rotor_counter = 0; + } + } else { + stop_rotor_counter = 0; + } + } + } + + if (f.Mode) { + a.iqf = analog.iqFstator; + } else { + a.iqf = Fzad; + analog.iqFstator = Fzad; + a.iqk1 = _IQsqrt(_IQmpy(svgen_dq_1.Ualpha, svgen_dq_1.Ualpha) + _IQmpy(svgen_dq_1.Ubeta, svgen_dq_1.Ubeta)); //For output Kmodul to terminal + a.iqk2 = _IQsqrt(_IQmpy(svgen_dq_2.Ualpha, svgen_dq_2.Ualpha) + _IQmpy(svgen_dq_2.Ubeta, svgen_dq_2.Ubeta)); //end counting Uout + } + a.iqk = (a.iqk1 + a.iqk2) / 2; + +// write_swgen_pwm_times(); + + if (xpwm_time.one_or_two_interrupts_run == PWM_ONE_INTERRUPT_RUN) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + else + { + if (f.Go == 1) + { + if (count_start_impuls == (2 * COUNT_START_IMP)) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_LOW); + } + else +// if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + } + else + { + if (count_start_impuls == (2 * COUNT_START_IMP) - 1) + { + if (pwm_enable_calc_main) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_LOW); + + } + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_FORCE); + } + + // if (pwm_enable_calc_main) + // prev_run_calc_uf = run_calc_uf; + + } + + + + + + // logs recording +// if ((flag_record_log && !f.stop_Log) || f.Startstoplog) +// //if (f.Log1_Log2 == 1)// && f.Go == 1 && (!f.Stop)) +// //if(f.Go == 1) +// { +// test_mem_limit(FAST_LOG, !f.Ciclelog); +// count_step++; +// +// if (count_step >= 0) { +// fillADClogs(); +//// logpar.log13 = flag_record_log; +//// logpar.log14 = count_start_impuls; +//// logpar.log10 = (int16)_IQtoIQ15(analog.iqIq1_filter); +//// logpar.log11 = (int16)_IQtoIQ15(rotor.iqFrotFromOptica); +// logpar.log15 = (int16) _IQtoIQ15(analog.iqIq2); +// logpar.log16 = (int16) _IQtoIQ15(a.iqk1); +// logpar.log17 = (int16) _IQtoIQ15(analog.iqId1); +// logpar.log18 = (int16) _IQtoIQ15(analog.iqIq1); +// +//// logpar.log24 = (int16) break_result_1; +//// logpar.log25 = (int16) break_result_2; +// logpar.log27 = (int16)(_IQtoIQ15(analog.iqIbtr1_1)); +// logpar.log28 = (int16)(_IQtoIQ15(analog.iqIbtr2_1)); +// +// getFastLogs(!f.Ciclelog); +// count_step = 0; +// } +// } else { +// if (f.Stop && log_saved_to_const_mem == 0) { +// logpar.copy_log_to_const_memory = 1; +// log_saved_to_const_mem = 1; +// } +// } + +// optical_bus_write(); + +// detect_current_saw_val(); + end_int_xtics = xpwm_time.current_period; + f.PWMcounterVal = labs(start_int_xtics - end_int_xtics); + + pwm_run = 0; + + i_sync_pin_off(); +// i_led1_on_off(0); + +} + +void slow_vector_update() +{ + _iq iqKzad = 0; + freq1 = _IQ (f.fzad/F_STATOR_MAX);//f.iqFRotorSetHz; + iqKzad = _IQ(f.kzad); + k1 = zad_intensiv_q(30000, 30000, k1, iqKzad); //20000 + + +} + +//#pragma CODE_SECTION(write_swgen_pwm_times,".fast_run"); +//void write_swgen_pwm_times() +//{ +// xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0.Ti; +// xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1.Ti; +// xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0.Ti; +// xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1.Ti; +// xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0.Ti; +// xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1.Ti; +// +// xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0.Ti; +// xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1.Ti; +// xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0.Ti; +// xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1.Ti; +// xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0.Ti; +// xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1.Ti; +// +// xpwm_time.Tbr0_0 = break_result_1; +// xpwm_time.Tbr0_1 = break_result_2; +// xpwm_time.Tbr1_0 = break_result_3; +// xpwm_time.Tbr1_1 = break_result_4; +// +// xpwm_time.write_1_2_winding_break_times(&xpwm_time); +// +// +//// logpar.log29 = xpwm_time.Ta0_0; +//// logpar.log30 = xpwm_time.Ta0_1; +//// logpar.log10 = xpwm_time.Tb0_0; +//// logpar.log11 = xpwm_time.Tb0_1; +//// logpar.log12 = xpwm_time.Tc0_0; +//// logpar.log13 = xpwm_time.Tc0_1; +//// logpar.log7 = _IQtoIQ12(svgen_pwm24_1.Alpha); +//// logpar.log8 = xpwm_time.Ta0_0 - xpwm_time.Tb0_0; +//// logpar.log9 = xpwm_time.Ta0_1 - xpwm_time.Tb0_1; +//// logpar.log10 = xpwm_time.Tb0_0 - xpwm_time.Tc0_0; +//// logpar.log11 = xpwm_time.Tb0_1 - xpwm_time.Tc0_1; +//// logpar.log12 = xpwm_time.Tc0_0 - xpwm_time.Ta0_0; +//// logpar.log13 = xpwm_time.Tc0_1 - xpwm_time.Ta0_1; +// +//} + +//#pragma CODE_SECTION(write_swgen_pwm_times_split_eages,".fast_run2"); +//void write_swgen_pwm_times_split_eages(unsigned int mode_reload) +//{ +// +// xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Tc_0.Ti; +// xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Tc_1.Ti; +// xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0.Ti; +// xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1.Ti; +// xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Ta_0.Ti; +// xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Ta_1.Ti; +// +// xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Tc_0.Ti; +// xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Tc_1.Ti; +// xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0.Ti; +// xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1.Ti; +// xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Ta_0.Ti; +// xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Ta_1.Ti; +// +// xpwm_time.Tbr0_0 = break_result_1; +// xpwm_time.Tbr0_1 = break_result_2; +// xpwm_time.Tbr1_0 = break_result_3; +// xpwm_time.Tbr1_1 = break_result_4; +// +// xpwm_time.mode_reload = mode_reload; +// +// xpwm_time.write_1_2_winding_break_times_split(&xpwm_time); +//} + +#define CONST_IQ_1 16777216 //1 + +//#pragma CODE_SECTION(fix_pwm_freq_synchro_ain,".fast_run"); +//void fix_pwm_freq_synchro_ain() +//{ +//// if (f.Sync_input_or_output == SYNC_INPUT) +// { +// sync_inc_error(); +// +// if (f.disable_sync || f.sync_ready == 0) +// { +// +// +// return; +// } +// +// if (f.pwm_freq_plus_minus_zero==1) +// { +// +// +// //Increment xtics +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS + 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec +// +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// +// +// } +// +// if (f.pwm_freq_plus_minus_zero==-1) +// { +// //4464 +// //Decrement xtics +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS - 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); // Saw period in tics. 1 tic = 16.67 nsec +// +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// +// } +// +// if (f.pwm_freq_plus_minus_zero==0) +// { +// VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS - 1; +// WriteMemory(ADR_PWM_PERIOD, VAR_FREQ_PWM_XTICS); +// change_freq_pwm(VAR_FREQ_PWM_XTICS); +// } +// +// } +// +// +// +//} + + +//void detect_level_interrupt(void) +//{ +// +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// xpwm_time.current_period = ReadMemory(ADR_SAW_VALUE); +// +// if (xpwm_time.current_period<xpwm_time.pwm_tics/2) +// xpwm_time.where_interrupt = PWM_LOW_LEVEL_INTERRUPT; +// +// if (xpwm_time.current_period>xpwm_time.pwm_tics/2) +// xpwm_time.where_interrupt = PWM_HIGH_LEVEL_INTERRUPT; +// +//} +// +//void detect_current_saw_val(void) +//{ +// WriteMemory(ADR_SAW_REQUEST, 0x8000); +// xpwm_time.current_period = ReadMemory(ADR_SAW_VALUE); +//} + + + + diff --git a/Inu/Src2/main/PWMTools.h b/Inu/Src2/main/PWMTools.h new file mode 100644 index 0000000..593f723 --- /dev/null +++ b/Inu/Src2/main/PWMTools.h @@ -0,0 +1,19 @@ +#ifndef PWMTOOLS_H +#define PWMTOOLS_H +#include "f281xpwm.h" + +void InitXPWM(void); +void InitPWM(void); +void PWM_interrupt(void); +void initPWM_Variables(void); + +void slow_vector_update(void); + +extern PWMGEND pwmd; + +extern int VAR_FREQ_PWM_XTICS; +extern int VAR_PERIOD_MAX_XTICS; +extern int VAR_PERIOD_MIN_XTICS; +extern int VAR_PERIOD_MIN_BR_XTICS; +#endif //PWMTOOLS_H + diff --git a/Inu/Src2/main/adc_tools.c b/Inu/Src2/main/adc_tools.c new file mode 100644 index 0000000..4af68a7 --- /dev/null +++ b/Inu/Src2/main/adc_tools.c @@ -0,0 +1,528 @@ +// #include "project.h" +#include "adc_tools.h" +// #include "xp_project.h" +#include "IQmathLib.h" +#include "math.h" +#include "my_filter.h" +#include "params.h" +// #include "params_protect.h" +#include "vector.h" +// #include "xp_adc.h" +// #include "TuneUpPlane.h" //Ìîðãàíèå ñâåòîäèîäîì +// #include "log_to_memory.h" +// #include "errors.h" + +// #define COUNT_ARR_ADC_BUF 2 +#define Shift_Filter 1 //2 + +#define BTR_ENABLED + +#define R_ADC_DEFAULT { 1180 ,1180 , 256, 256, 256, 256, 256, 1180, 1180, 256, 256, 256, 256, 256, 256, 256, 256, 256 } +#define K_LEM_ADC_DEFAULT { 60000,60000,5000, 5000,5000,5000,5000,60000,60000,5000,5000,5000,5000,5000,5000,5000,5000,5000 } +//#define LOG_ACP_TO_BUF + +int ADC_f[COUNT_ARR_ADC_BUF][16]; + +int ADC_sf[COUNT_ARR_ADC_BUF][16]; + + +#define ZERO_ADC_DEFAULT {2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048} +_iq19 iq19_zero_ADC[18] = ZERO_ADC_DEFAULT; + +int zero_ADC[18] = ZERO_ADC_DEFAULT; +_iq iq_k_norm_ADC[18]; +_iq19 iq19_k_norm_ADC[18]; + +_iq iq_norm_ADC[18]; + +unsigned int const R_ADC[18] = R_ADC_DEFAULT; +unsigned int const K_LEM_ADC[18] = K_LEM_ADC_DEFAULT; + +//#pragma DATA_SECTION(analog,".fast_vars"); +ANALOG_VALUE analog; +//#pragma DATA_SECTION(filter,".fast_vars"); +ANALOG_VALUE filter; + +ANALOG_RAW_DATA rawData = ANALOG_RAW_DATA_DEFAULT; + +_iq koef_Ud_long_filter=0; +_iq koef_Ud_fast_filter=0; +_iq koef_Im_filter=0; + +_iq koef_Iabc_filter=0; + +_iq koef_Wlong=0; + + +void calc_norm_ADC(void); +void analog_values_calc(void); +_iq im_calc( _iq ia, _iq ib, _iq ic); + +void read_adc(ANALOG_RAW_DATA *data) +{ + ADC_f[0][0] = data->U1_1; + ADC_f[0][1] = data->U1_2; + ADC_f[0][2] = data->Izpt1_1; + ADC_f[0][3] = data->Izpt1_2; + ADC_f[0][4] = data->Ia1; + ADC_f[0][5] = data->Ib1; + ADC_f[0][6] = data->Ic1; + ADC_f[0][7] = 0; + ADC_f[0][8] = data->U2_1; + ADC_f[0][9] = data->U2_2; + ADC_f[0][10] = data->Izpt2_1; + ADC_f[0][11] = data->Izpt2_2; + ADC_f[0][12] = data->Ia2; + ADC_f[0][13] = data->Ib2; + ADC_f[0][14] = data->Ic2; + ADC_f[0][15] = 0; + + + ADC_sf[0][0] += (ADC_f[0][0] - ADC_sf[0][0]) >> Shift_Filter; + ADC_sf[0][1] += (ADC_f[0][1] - ADC_sf[0][1]) >> Shift_Filter; + ADC_sf[0][2] += (ADC_f[0][2] - ADC_sf[0][2]) >> Shift_Filter; + ADC_sf[0][3] += (ADC_f[0][3] - ADC_sf[0][3]) >> Shift_Filter; + ADC_sf[0][4] += (ADC_f[0][4] - ADC_sf[0][4]) >> Shift_Filter; + ADC_sf[0][5] += (ADC_f[0][5] - ADC_sf[0][5]) >> Shift_Filter; + ADC_sf[0][6] += (ADC_f[0][6] - ADC_sf[0][6]) >> Shift_Filter; + + ADC_sf[0][7] += (ADC_f[0][7] - ADC_sf[0][7]) >> Shift_Filter; + ADC_sf[0][8] += (ADC_f[0][8] - ADC_sf[0][8]) >> Shift_Filter; + ADC_sf[0][9] += (ADC_f[0][9] - ADC_sf[0][9]) >> Shift_Filter; + ADC_sf[0][10] += (ADC_f[0][10] - ADC_sf[0][10]) >> Shift_Filter; + ADC_sf[0][11] += (ADC_f[0][11] - ADC_sf[0][11]) >> Shift_Filter; + ADC_sf[0][12] += (ADC_f[0][12] - ADC_sf[0][12]) >> Shift_Filter; + ADC_sf[0][13] += (ADC_f[0][13] - ADC_sf[0][13]) >> Shift_Filter; + ADC_sf[0][14] += (ADC_f[0][14] - ADC_sf[0][14]) >> Shift_Filter; + ADC_sf[0][15] += (ADC_f[0][15] - ADC_sf[0][15]) >> Shift_Filter; + + + ADC_f[1][0] = 0; + ADC_f[1][1] = 0; + ADC_f[1][2] = 0; + ADC_f[1][3] = 0; + + ADC_sf[1][0] += (ADC_f[1][0] - ADC_sf[1][0]) >> Shift_Filter; + ADC_sf[1][1] += (ADC_f[1][1] - ADC_sf[1][1]) >> Shift_Filter; + ADC_sf[1][2] += (ADC_f[1][2] - ADC_sf[1][2]) >> Shift_Filter; + ADC_sf[1][3] += (ADC_f[1][3] - ADC_sf[1][3]) >> Shift_Filter; +} + +void acp_Handler(void) +{ + // read_adc(); + calc_norm_ADC(); + analog_values_calc(); + // Read_Fast_Errors(); +} + +#define COUNT_DETECT_ZERO 500 + +// void detect_zero_analog() +// { +// int i, k; +// double tmp_buff[2][16] = {0}; +// // _iq koef_zero_ADC_filter = 1; +// for(i = 0; i < 16; tmp_buff[0][i++] = 0); +// for(i = 0; i < 16; tmp_buff[1][i++] = 0); +// i = 0; +// for (i = 0; i<COUNT_DETECT_ZERO; i++) +// { +// read_adc(); + +// for(k = 2; k < 15; k++) +// { +// if((k == 7) || (k == 8)) +// { +// continue; +// } +// tmp_buff[0][k] += ADC_f[0][k]; +// } +// for(k = 0;k < 4; k++) +// { +// tmp_buff[1][k] += ADC_f[1][k]; +// } +// pause_1000(1000); +// } +// k = 2; +// for(i = 2; i < 15; i++) +// { +// if(i == 7) +// { +// continue; +// } + +// if((i == 8) || (i == 9)) +// { +// k++; +// continue; +// } +// zero_ADC[k] = (int)(tmp_buff[0][i] / COUNT_DETECT_ZERO + 0.5); +// k++; +// } +// for(i = 0; i < 4; i++, k++) +// { +// zero_ADC[k] = (int)(tmp_buff[1][i] / COUNT_DETECT_ZERO + 0.5); +// } +// zero_ADC[0] = zero_ADC[2]; +// zero_ADC[1] = zero_ADC[2]; +// zero_ADC[7] = zero_ADC[9]; +// zero_ADC[8] = zero_ADC[9]; + + +// } + +void init_Adc_Variables(void) +{ + unsigned int k; + int *panalog, *pfilter; + + for (k=0;k<16;k++) + { + + ADC_f[0][k]=0; + ADC_sf[0][k]=0; + ADC_f[1][k]=0; + ADC_sf[1][k]=0; + } + + // detect_zero_analog(); + + for (k=0;k<18;k++) + { + iq19_k_norm_ADC[k] = _IQ19(K_LEM_ADC[k]*250.0/R_ADC[k]/NORMA_ACP/4096.0); + + iq19_zero_ADC[k]=_IQ19(zero_ADC[k]); //_IQ19(2030);//_IQ19(1770); + + } + + koef_Ud_long_filter = _IQ(0.05); + koef_Ud_fast_filter = _IQ(0.2); // _IQ(0.001/0.00931); //_IQ(0.001/0.00131); + + koef_Im_filter = _IQ(0.015); + + koef_Iabc_filter = _IQ(0.0005); //_IQ(0.002/0.006); + koef_Wlong = _IQ(0.001); + + panalog = (int*)&analog; + pfilter = (int*)&filter; + for (k=0;k < sizeof(ANALOG_VALUE) / sizeof(int) ;k++) + { + + *(panalog + k) = 0; + *(pfilter + k) = 0; + } + +} + +inline _iq norma_adc(int plane, int chan, int n_norm) +{ + // return _IQ19toIQ(_IQ19mpy((iq19_zero_ADC[n_norm] - ((long)ADC_sf[plane][chan]<<19) ),iq19_k_norm_ADC[n_norm])); + // return _IQ19toIQ(_IQ19mpy((((long)ADC_sf[plane][chan]<<19) - iq19_zero_ADC[n_norm]),iq19_k_norm_ADC[n_norm])); + return _IQ19toIQ(_IQ19mpy((((long)ADC_sf[plane][chan]<<19)),iq19_k_norm_ADC[n_norm])); +} + +void calc_norm_ADC(void) +{ + iq_norm_ADC[0] = norma_adc(0, 0, 0); + iq_norm_ADC[1] = norma_adc(0, 1, 1); + iq_norm_ADC[2] = norma_adc(0, 2, 2); + iq_norm_ADC[3] = norma_adc(0, 3, 3); + iq_norm_ADC[4] = norma_adc(0, 4, 4); + iq_norm_ADC[5] = norma_adc(0, 5, 5); + iq_norm_ADC[6] = norma_adc(0, 6, 6); + iq_norm_ADC[7] = norma_adc(0, 8, 7); + iq_norm_ADC[8] = norma_adc(0, 9, 8); + iq_norm_ADC[9] = norma_adc(0, 10, 9); + iq_norm_ADC[10] = norma_adc(0, 11, 10); + iq_norm_ADC[11] = norma_adc(0, 12, 11); + iq_norm_ADC[12] = norma_adc(0, 13, 12); + iq_norm_ADC[13] = norma_adc(0, 14, 13); + iq_norm_ADC[14] = norma_adc(1, 0, 14); + iq_norm_ADC[15] = norma_adc(1, 1, 15); + iq_norm_ADC[16] = norma_adc(1, 2, 16); + iq_norm_ADC[17] = norma_adc(1, 3, 17); +} + +void analog_values_calc(void) +{ + + analog.iqU_1 = iq_norm_ADC[0]; + analog.iqU_2 = iq_norm_ADC[1]; + analog.iqU_3 = iq_norm_ADC[7]; + analog.iqU_4 = iq_norm_ADC[8]; + + analog.iqIin_1 = iq_norm_ADC[2]; + analog.iqIin_2 = -iq_norm_ADC[3]; + analog.iqIin_3 = iq_norm_ADC[9]; + analog.iqIin_4 = -iq_norm_ADC[10]; + + +// #if PROJECT_ARKTIKA == 1 + analog.iqIa1_1 = iq_norm_ADC[4]; + analog.iqIb1_1 = iq_norm_ADC[5]; + analog.iqIc1_1 = iq_norm_ADC[6]; + + analog.iqIa2_1 = iq_norm_ADC[11]; + analog.iqIb2_1 = iq_norm_ADC[12]; + analog.iqIc2_1 = iq_norm_ADC[13]; +// #endif +#if PROJECT_SIBERIA == 1 + analog.iqIa1_1 = iq_norm_ADC[6]; + analog.iqIb1_1 = iq_norm_ADC[5]; + analog.iqIc1_1 = iq_norm_ADC[4]; + + analog.iqIa2_1 = iq_norm_ADC[13]; + analog.iqIb2_1 = iq_norm_ADC[12]; + analog.iqIc2_1 = iq_norm_ADC[11]; +#endif + + analog.iqIbtr1_1 = labs(iq_norm_ADC[14]); + analog.iqIbtr1_2 = labs(iq_norm_ADC[16]); + analog.iqIbtr2_1 = labs(iq_norm_ADC[15]); + analog.iqIbtr2_2 = labs(iq_norm_ADC[17]); + + analog.iqIa1_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIa1_rms, _IQabs(analog.iqIa1_1)); + analog.iqIb1_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIb1_rms, _IQabs(analog.iqIb1_1)); + analog.iqIc1_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIc1_rms, _IQabs(analog.iqIc1_1)); + + analog.iqIa2_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIa2_rms, _IQabs(analog.iqIa2_1)); + analog.iqIb2_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIb2_rms, _IQabs(analog.iqIb2_1)); + analog.iqIc2_rms = exp_regul_iq(koef_Iabc_filter, analog.iqIc2_rms, _IQabs(analog.iqIc2_1)); + + + filter.iqU_1_long = exp_regul_iq(koef_Ud_long_filter, filter.iqU_1_long, analog.iqU_1); + filter.iqU_2_long = exp_regul_iq(koef_Ud_long_filter, filter.iqU_2_long, analog.iqU_2); + filter.iqU_3_long = exp_regul_iq(koef_Ud_long_filter, filter.iqU_3_long, analog.iqU_3); + filter.iqU_4_long = exp_regul_iq(koef_Ud_long_filter, filter.iqU_4_long, analog.iqU_4); + + filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); + filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); + filter.iqIin_3 = exp_regul_iq(koef_Im_filter, filter.iqIin_3, analog.iqIin_3); + filter.iqIin_4 = exp_regul_iq(koef_Im_filter, filter.iqIin_4, analog.iqIin_4); + + + + + filter.iqU_1_fast = exp_regul_iq(koef_Ud_fast_filter, filter.iqU_1_fast, analog.iqU_1); + filter.iqU_2_fast = exp_regul_iq(koef_Ud_fast_filter, filter.iqU_2_fast, analog.iqU_2); + + filter.iqU_3_fast = exp_regul_iq(koef_Ud_fast_filter, filter.iqU_3_fast, analog.iqU_3); + filter.iqU_4_fast = exp_regul_iq(koef_Ud_fast_filter, filter.iqU_4_fast, analog.iqU_4); + + filter.iqIa1_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIa1_1, analog.iqIa1_1); + filter.iqIb1_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIb1_1, analog.iqIb1_1); + filter.iqIc1_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIc1_1, analog.iqIc1_1); + + filter.iqIa2_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIa2_1, analog.iqIa2_1); + filter.iqIb2_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIb2_1, analog.iqIb2_1); + filter.iqIc2_1 = exp_regul_iq(koef_Ud_fast_filter, filter.iqIc2_1, analog.iqIc2_1); + + + + analog.iqW1 = _IQmpy(filter.iqU_1_fast, analog.iqIin_1) + _IQmpy(filter.iqU_2_fast, analog.iqIin_2); + analog.iqW2 = _IQmpy(filter.iqU_3_fast, analog.iqIin_3) + _IQmpy(filter.iqU_4_fast, analog.iqIin_4); + analog.iqW = analog.iqW1 + analog.iqW2; + + + + analog.iqIm_1 = im_calc(filter.iqIa1_1, filter.iqIb1_1, filter.iqIc1_1); + analog.iqIm_2 = im_calc(filter.iqIa2_1, filter.iqIb2_1, filter.iqIc2_1); + + +// i_led1_on_off(0); +// i_led1_on_off(1); + + filter.iqIm_1 = exp_regul_iq(koef_Im_filter, filter.iqIm_1, analog.iqIm_1); + filter.iqIm_2 = exp_regul_iq(koef_Im_filter, filter.iqIm_2, analog.iqIm_2); +// filter.iqIm = exp_regul_iq(koef_Iabc_filter, filter.iqIm, filter.iqIm_2); + + filter.iqW1 = exp_regul_iq(koef_Iabc_filter, filter.iqW1, analog.iqW1); + filter.iqW2 = exp_regul_iq(koef_Iabc_filter, filter.iqW2, analog.iqW2); + filter.iqW = exp_regul_iq(koef_Wlong, filter.iqW, filter.iqW1 + filter.iqW2); + +// filter.iqIin_1 = exp_regul_iq(koef_Im_filter, filter.iqIin_1, analog.iqIin_1); +// filter.iqIin_2 = exp_regul_iq(koef_Im_filter, filter.iqIin_2, analog.iqIin_2); + +} + +#define CONST_IQ_11PI6 96629827 //11Pi/6 +#define CONST_IQ_PI6 8784529 // Pi/6 + + +// _iq err_level_adc_on_go = ERR_LEVEL_ADC_PLUS_6_ON_GO_IQ; + +// _iq err_level_adc = ERR_LEVEL_ADC_PLUS_6_IQ; + + +// unsigned int detect_protect_ACP_plus() +// { +// unsigned int mask = 0, result = 0; +// static unsigned int prev_mask = 0xFCFC; + +// if(f.Go) +// { +// mask |= filter.iqU_1_long > err_level_adc_on_go ? 1 : 0; +// mask |= filter.iqU_2_long > err_level_adc_on_go ? 1 << 1: 0; +// } +// else +// { +// mask |= filter.iqU_1_long > err_level_adc ? 1 : 0; +// mask |= filter.iqU_2_long > err_level_adc ? 1 << 1: 0; +// } + + +// #ifdef NEW_I_ZPT_REZISTORS +// mask |= ADC_sf[0][2] < ERR_LEVEL_I_ZPT_PLUS_REZ_249? 1 << 2: 0; +// mask |= ADC_sf[0][3] < ERR_LEVEL_I_ZPT_PLUS_REZ_249? 1 << 3: 0; +// #else +// mask |= ADC_sf[0][2] < ERR_LEVEL_I_ZPT_PLUS? 1 << 2: 0; +// mask |= ADC_sf[0][3] < ERR_LEVEL_I_ZPT_PLUS? 1 << 3: 0; +// #endif + +// mask |= ADC_sf[0][4] < ERR_LEVEL_I_FAZA_PLUS? 1 << 4: 0; +// mask |= ADC_sf[0][5] < ERR_LEVEL_I_FAZA_PLUS? 1 << 5: 0; +// mask |= ADC_sf[0][6] < ERR_LEVEL_I_FAZA_PLUS? 1 << 6: 0; + +// if(f.Go) +// { +// mask |= filter.iqU_3_long > err_level_adc_on_go ? 1 << 8: 0; +// mask |= filter.iqU_4_long > err_level_adc_on_go ? 1 << 9: 0; +// } +// else +// { +// mask |= (filter.iqU_3_long > err_level_adc) ? 1 << 8: 0; +// mask |= (filter.iqU_4_long > err_level_adc) ? 1 << 9: 0; +// } + + +// #ifdef NEW_I_ZPT_REZISTORS +// mask |= ADC_sf[0][10] < ERR_LEVEL_I_ZPT_PLUS_REZ_249? 1 << 10: 0; +// mask |= ADC_sf[0][11] < ERR_LEVEL_I_ZPT_PLUS_REZ_249? 1 << 11: 0; +// #else +// mask |= ADC_sf[0][10] < ERR_LEVEL_I_ZPT_PLUS? 1 << 10: 0; +// mask |= ADC_sf[0][11] < ERR_LEVEL_I_ZPT_PLUS? 1 << 11: 0; +// #endif + +// mask |= ADC_sf[0][12] < ERR_LEVEL_I_FAZA_PLUS? 1 << 12: 0; +// mask |= ADC_sf[0][13] < ERR_LEVEL_I_FAZA_PLUS? 1 << 13: 0; +// mask |= ADC_sf[0][14] < ERR_LEVEL_I_FAZA_PLUS? 1 << 14: 0; + +// //Calculate values for BTR +// #ifdef BTR_ENABLED +// mask |= ADC_sf[1][0] < ERR_LEVEL_BREAK_REZ? 1 << 7: 0; //BTR1pos +// mask |= ADC_sf[1][2] < ERR_LEVEL_BREAK_REZ? 1 << 15: 0; //BTR1neg +// #endif //BTR_ENABLED +// /* */ + +// result = mask & prev_mask; +// prev_mask |= mask; // +// // +// if(mask == 0) { prev_mask = 0xFFFF;} +// return result; + +// } + + +// unsigned int detect_protect_ACP_minus() +// { +// unsigned int mask = 0, result = 0; +// static unsigned int prev_mask = 0xFCFC; // + +// /* */ +// if(f.Ready2) +// { +// // mask |= (ADC_sf[0] > ERR_LEVEL_ADC_MINUS_6) ? 1: 0; +// // mask |= (ADC_sf[1] > ERR_LEVEL_ADC_MINUS_6) ? 1 << 1: 0; +// } +// #ifdef NEW_I_ZPT_REZISTORS +// mask |= (ADC_sf[0][2] > ERR_LEVEL_I_ZPT_MINUS_REZ_249)? 1 << 2: 0; +// mask |= (ADC_sf[0][3] > ERR_LEVEL_I_ZPT_MINUS_REZ_249)? 1 << 3: 0; +// #else +// mask |= (ADC_sf[0][2] < ERR_LEVEL_I_ZPT_PLUS)? 1 << 2: 0; +// mask |= (ADC_sf[0][3] < ERR_LEVEL_I_ZPT_PLUS)? 1 << 3: 0; +// #endif +// mask |= ADC_sf[0][4] > ERR_LEVEL_I_FAZA_MINUS? 1 << 4: 0; +// mask |= ADC_sf[0][5] > ERR_LEVEL_I_FAZA_MINUS? 1 << 5: 0; +// mask |= ADC_sf[0][6] > ERR_LEVEL_I_FAZA_MINUS? 1 << 6: 0; +// /* */ +// /* if(f.Ready2) +// { +// mask |= (ADC_sf[0][7] > ERR_LEVEL_ADC_MINUS_6) ? 1 << 8: 0; +// mask |= (ADC_sf[0][8] > ERR_LEVEL_ADC_MINUS_6) ? 1 << 9: 0; +// } */ +// #ifdef NEW_I_ZPT_REZISTORS +// mask |= ADC_sf[0][10] > ERR_LEVEL_I_ZPT_MINUS_REZ_249? 1 << 10: 0; +// mask |= ADC_sf[0][11] > ERR_LEVEL_I_ZPT_MINUS_REZ_249? 1 << 11: 0; +// #else +// mask |= ADC_sf[0][10] < ERR_LEVEL_I_ZPT_PLUS? 1 << 10: 0; +// mask |= ADC_sf[0][11] < ERR_LEVEL_I_ZPT_PLUS? 1 << 11: 0; +// #endif + +// mask |= ADC_sf[0][12] > ERR_LEVEL_I_FAZA_MINUS? 1 << 12: 0; +// mask |= ADC_sf[0][13] > ERR_LEVEL_I_FAZA_MINUS? 1 << 13: 0; +// mask |= ADC_sf[0][14] > ERR_LEVEL_I_FAZA_MINUS? 1 << 14: 0; + +// //Calculate values for BTR +// #ifdef BTR_ENABLED +// mask |= ADC_sf[1][1] < ERR_LEVEL_BREAK_REZ? 1 << 7: 0; //BTR2pos +// mask |= ADC_sf[1][3] < ERR_LEVEL_BREAK_REZ? 1 << 15: 0; //BTR2neg +// #endif //BTR_ENABLED +// /* */ + + +// result = mask & prev_mask; +// prev_mask |= mask; // +// // +// if(mask == 0) { prev_mask = 0xFFFF;} +// return result; + +// } + +// #pragma CODE_SECTION(fillADClogs,".fast_run"); +// void fillADClogs(void) +// { +// logpar.log1 = (int16)_IQtoIQ15(analog.iqU_1); +// logpar.log2 = (int16)_IQtoIQ15(analog.iqU_2); +// logpar.log3 = (int16)_IQtoIQ15(analog.iqIin_1); +// logpar.log4 = (int16)_IQtoIQ15(analog.iqIin_2); +// logpar.log5 = (int16)_IQtoIQ15(analog.iqIa1_1); +// logpar.log6 = (int16)_IQtoIQ15(analog.iqIb1_1); +// logpar.log7 = (int16)_IQtoIQ15(analog.iqIc1_1); +// logpar.log8 = (int16)_IQtoIQ15(analog.iqU_3); +// logpar.log9 = (int16)_IQtoIQ15(analog.iqU_4); +// logpar.log10 = (int16)_IQtoIQ15(analog.iqIin_3); +// logpar.log11 = (int16)_IQtoIQ15(analog.iqIin_4); +// logpar.log12 = (int16)_IQtoIQ15(analog.iqIa2_1); +// logpar.log13 = (int16)_IQtoIQ15(analog.iqIb2_1); +// logpar.log14 = (int16)_IQtoIQ15(analog.iqIc2_1); +// // logpar.log15 = (int16)_IQtoIQ15(filter.iqU_1_fast); +// // logpar.log16 = (int16)_IQtoIQ15(filter.iqU_1_long); +// } + +/********************************************************************/ +/* Расчет модулy тока из показаний трех фаз */ +/********************************************************************/ +_iq SQRT_32 = _IQ(0.8660254037844); +_iq CONST_23 = _IQ(2.0/3.0); +_iq CONST_15 = _IQ(1.5); + +_iq im_calc( _iq ia, _iq ib, _iq ic) +{ + _iq isa,isb, t; + + + isa = _IQmpy(CONST_15,ia); + isb = _IQmpy(SQRT_32,ib-ic ); + +// ( _IQ19mpy(SQRT_32, _IQ15toIQ19(ib)) - _IQ15mpy(SQRT_32, _IQ15toIQ19(ic)) ); + + // t = _IQmag(isa,isb); + t = _IQsqrt(_IQmpy(isa, isa) + _IQmpy(isb, isb)); + t = _IQmpy(CONST_23,t); + + return (t); + +} + + diff --git a/Inu/Src2/main/adc_tools.h b/Inu/Src2/main/adc_tools.h new file mode 100644 index 0000000..137324f --- /dev/null +++ b/Inu/Src2/main/adc_tools.h @@ -0,0 +1,137 @@ +#ifndef ADC_TOOLS_H +#define ADC_TOOLS_H + +#include "IQmathLib.h" +// #include "isr.h" + +typedef struct +{ + + _iq iqIin_1; + _iq iqIin_2; + _iq iqIin_3; + _iq iqIin_4; +// _iq iqIin_1_rms; +// _iq iqIin_2_rms; +// _iq iqIin_3_rms; +// _iq iqIin_4_rms; + _iq iqIin; + + _iq iqIa1_1; + _iq iqIb1_1; + _iq iqIc1_1; + _iq iqIa2_1; + _iq iqIb2_1; + _iq iqIc2_1; + + _iq iqIa1_rms; + _iq iqIb1_rms; + _iq iqIc1_rms; + _iq iqIa2_rms; + _iq iqIb2_rms; + _iq iqIc2_rms; + + _iq iqIq_zadan; + _iq iqIq_zad_from_optica; + _iq iqId1; + _iq iqIq1; + _iq iqIq1_filter; + _iq iqId2; + _iq iqIq2; + _iq iqIq2_filter; + + _iq iqUd1; + _iq iqUq1; + _iq iqUd2; + _iq iqUq2; + _iq iqUq2_filter; + _iq tetta; + _iq Fsl; + + _iq iqFstator; + + _iq iqU_1; + _iq iqU_2; + _iq iqU_3; + _iq iqU_4; + + _iq iqW1; + _iq iqWexp; + _iq iqWfir; + _iq iqWout; + _iq iqPvsi1; + _iq iqPvsi2; + _iq iqM_1; + _iq iqM_2; + + _iq iqW2; + + _iq iqW; + + _iq iqU_1_long; + _iq iqU_2_long; + _iq iqU_3_long; + _iq iqU_4_long; + + _iq iqU_1_fast; + _iq iqU_2_fast; + _iq iqU_3_fast; + _iq iqU_4_fast; + + _iq iqIm_1; + _iq iqIm_2; + _iq iqIm_1_long; + _iq iqIm_2_long; + + _iq iqIm; + + _iq iqIbtr1_1; + _iq iqIbtr1_2; + _iq iqIbtr2_1; + _iq iqIbtr2_2; + +} ANALOG_VALUE; + +typedef struct { + float U1_1; + float U1_2; + float Izpt1_1; + float Izpt1_2; + float Ia1; + float Ib1; + float Ic1; + float U2_1; + float U2_2; + float Izpt2_1; + float Izpt2_2; + float Ia2; + float Ib2; + float Ic2; + + void (*read_adc)(); +} ANALOG_RAW_DATA; + + + +extern ANALOG_VALUE analog; +extern ANALOG_VALUE filter; +extern _iq iq_norm_ADC[18]; +extern ANALOG_RAW_DATA rawData; + +#define COUNT_ARR_ADC_BUF 2 +extern int ADC_f[COUNT_ARR_ADC_BUF][16]; + +void log_acp(void); +void acp_Handler(void); +void init_Adc_Variables(void); +void calc_Izpt_rms(void); +unsigned int detect_protect_ACP_plus(void); +unsigned int detect_protect_ACP_minus(void); +void fillADClogs(void); +void read_adc(ANALOG_RAW_DATA *data); + +#define ANALOG_RAW_DATA_DEFAULT {0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ + read_adc} + +#endif // ADC_TOOLS_H + diff --git a/Inu/Src2/main/dmctype.h b/Inu/Src2/main/dmctype.h new file mode 100644 index 0000000..95f314f --- /dev/null +++ b/Inu/Src2/main/dmctype.h @@ -0,0 +1,31 @@ +/* ================================================================================= +File name: DMCTYPE.H + +Originator: Digital Control Systems Group + Texas Instruments + +Description: DMC data type definition file. +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +------------------------------------------------------------------------------*/ + +#ifndef DMCTYPE +#define DMCTYPE + +//--------------------------------------------------------------------------- +// For Portability, User Is Recommended To Use Following Data Type Size +// Definitions For 16-bit and 32-Bit Signed/Unsigned Integers: +// + +typedef int int16; +typedef long int32; +typedef unsigned int Uint16; +typedef unsigned long Uint32; +typedef float float32; +typedef long double float64; + + +#endif // DMCTYPE + diff --git a/Inu/Src2/main/my_filter.c b/Inu/Src2/main/my_filter.c new file mode 100644 index 0000000..3fc444f --- /dev/null +++ b/Inu/Src2/main/my_filter.c @@ -0,0 +1,122 @@ +// #include "DSP281x_Device.h" // DSP281x Headerfile Include File +// #include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "IQmathLib.h" +#include "my_filter.h" + + +// #pragma CODE_SECTION(exp_regul_iq19,".fast_run"); +_iq19 exp_regul_iq19(_iq19 k_exp_regul, _iq19 InpVarCurr, _iq19 InpVarInstant) +{ + _iq19 t1; + + t1 = (InpVarCurr + _IQ19mpy( (InpVarInstant-InpVarCurr), k_exp_regul)); + return t1; +} + + +// #pragma CODE_SECTION(exp_regul_iq,".fast_run"); +_iq exp_regul_iq(_iq k_exp_regul, _iq InpVarCurr, _iq InpVarInstant) +{ + _iq t1; + t1 = (InpVarCurr + _IQmpy( (InpVarInstant-InpVarCurr), k_exp_regul)); + return t1; +} + +// #pragma CODE_SECTION(exp_regul_iq,".fast_run"); +void exp_regul_iq_fast(_iq k_exp_regul, _iq *InpVarCurr, _iq InpVarInstant) +{ + _iq t1; + volatile _iq t2,t3,t4; + + + t2 = (InpVarInstant- *InpVarCurr); + t3 = _IQmpy( t2, k_exp_regul); + t4 = *InpVarCurr + t3; + t1 = t4; + *InpVarCurr = t1; +// t1 = (InpVarCurr + _IQmpy( (InpVarInstant-InpVarCurr), k_exp_regul)); +// return t1; +} + +_iq zad_intensiv_q(_iq StepP, _iq StepN, _iq InpVarCurr, _iq InpVarInstant) +{ + _iq deltaVar, VarOut; + + deltaVar = InpVarInstant-InpVarCurr; + + if ((deltaVar>StepP) || (deltaVar<-StepN)) + { + if (deltaVar>0) InpVarCurr += StepP; + else InpVarCurr -= StepN; + } + else + InpVarCurr=InpVarInstant; + + + VarOut = InpVarCurr; + return VarOut; + + +} + + + + + +/* + +_iq18 filter_1p(_iq18 predx,_iq18 predy, _iq18 inpx) +{ + _iq18 t1; + + t1 = _IQ18mpy(k1_filter_1p_fast,(predx+inpx))+_IQ18mpy(k2_filter_1p_fast,predy); + return t1; +} + + +*/ + +/* + +void init_filter_batter2() +{ + u_filter_batter2[0]=0; + u_filter_batter2[1]=0; + u_filter_batter2[2]=0; + + i_filter_batter2[0]=0; + i_filter_batter2[1]=0; + i_filter_batter2[2]=0; + + k_filter_batter2[0]=_IQ(K1_FILTER_BATTER2_3HZ); + k_filter_batter2[1]=_IQ(K2_FILTER_BATTER2_3HZ); + k_filter_batter2[2]=_IQ(K3_FILTER_BATTER2_3HZ ); + +} + + + + +//#pragma CODE_SECTION(filter_batter2,".fast_run"); +_iq filter_batter2(_iq InpVarCurr) +{ +_iq y; + + y = _IQmpy(k_filter_batter2[0],( InpVarCurr + _IQmpyI32(i_filter_batter2[0],2) + i_filter_batter2[1] ) ) + + _IQmpy(k_filter_batter2[1], u_filter_batter2[0]) + _IQmpy(k_filter_batter2[2], u_filter_batter2[1]); + + u_filter_batter2[1]=u_filter_batter2[0]; + u_filter_batter2[0]=y; + + i_filter_batter2[1]=i_filter_batter2[0]; + i_filter_batter2[0]=InpVarCurr; + return y; + +} + + +*/ + + + + diff --git a/Inu/Src2/main/my_filter.h b/Inu/Src2/main/my_filter.h new file mode 100644 index 0000000..cb8b6d3 --- /dev/null +++ b/Inu/Src2/main/my_filter.h @@ -0,0 +1,76 @@ +#ifndef _MY_FILTER +#define _MY_FILTER + + + +#ifdef __cplusplus + extern "C" { +#endif + + + + +#include "IQmathLib.h" +//#include "filter.h" +//#include "myfir16.h" + + + +#define k1_filter_1p_fast 62643 // 0.238965*262144 +#define k2_filter_1p_fast 136857 // 0.52207*262144 +#define k3_filter_1p_fast2 8552 + + +#define filter_1p_fast(predx, predy,inpx) predy=_IQ18mpy(k1_filter_1p_fast,(predx+inpx))+_IQ18mpy(k2_filter_1p_fast,predy);predx=inpx +#define filter_1p_fast2(predx, predy,inpx) predy=_IQ18mpy(k3_filter_1p_fast2,(predx+inpx));predx=inpx + + + + + +//extern FIR16 fir; +//extern FIR16 fir_wrotor; +//extern IIR5BIQ16 iir; + + +void init_my_filter_fir(); +int calc_my_filter_fir(int xn); + +void init_my_filter_fir_58(); +int calc_my_filter_fir_58(int xn); + + + +void calc_my_filter_fir_50_75hz(_iq xn_0,_iq xn_1,_iq xn_2,_iq xn_3,_iq xn_4,_iq xn_5, + _iq *yn_0,_iq *yn_1,_iq *yn_2,_iq *yn_3,_iq *yn_4,_iq *yn_5); + +void init_my_filter_fir_50_75hz(); + + + +void init_my_filter_iir(); +int calc_my_filter_iir(int xn); + + + +_iq19 exp_regul_iq19(_iq19 k_exp_regul, _iq19 InpVarCurr, _iq19 InpVarInstant); +_iq exp_regul_iq(_iq k_exp_regul, _iq InpVarCurr, _iq InpVarInstant); + + + + +_iq18 filter_1p(_iq18 predx,_iq18 predy, _iq18 inpx); + +void exp_regul_iq_fast(_iq k_exp_regul, _iq *InpVarCurr, _iq InpVarInstant); + + +_iq zad_intensiv_q(_iq StepP, _iq StepN, _iq InpVarCurr, _iq InpVarInstant); + + + +#ifdef __cplusplus + } +#endif + +#endif /* _MY_FILTER */ + diff --git a/Inu/Src2/main/params.h b/Inu/Src2/main/params.h new file mode 100644 index 0000000..e34752d --- /dev/null +++ b/Inu/Src2/main/params.h @@ -0,0 +1,181 @@ +#ifndef _PARAMS +#define _PARAMS + + +#define PROPUSK_TEST_TKAK_ON_GO 1 // ������� ������������ ��������� ������ ��� ������ Go=1 + + +/*************************************************************************************/ +//#define _test_without_power 1 // �������� �������� ��� ������� ��� ���� +//#define _test_without_skaf 1 // �������� �������� ��� ������� ��� ����� ���������� +//#define _test_fast_calc 1 // �������� �������� ��� ������� ��� ���� +//#define _test_fast_calc_level1 1 // ���������� �������� ������� ��� ��������� �������� + +#define _test_without_doors +//#define _test_without_BSO +//#define _test_without_CAN +//#define CHECK_IN_OUT_TERMINAL + +//#define OFF_ERROR_UKSS1 // ����1 +//#define OFF_ERROR_UKSS2 //���1 +//#define OFF_ERROR_UKSS3 //���2 +//#define OFF_ERROR_UKSS4 //����2 +//#define OFF_ERROR_UKSS5 //�� +//#define OFF_ERROR_UKSS6 //BTR1 +//#define OFF_ERROR_UKSS7 //BTR2 +//#define OFF_ERROR_UKSS8 //���� + +//#define DISABLE_RS_MPU 1 + +#define NEW_I_ZPT_REZISTORS + +#define ENABLE_RECUPER 1 + +#define FREQ_TIMER0 200 /* ������� �������_0 */ +#define FREQ_TIMER1 3300 /* ������� �������_1 */ + +//#define FREQ_PWM 1180 /* ������� ���� */ //3138 // 2360//2477 // +//#define DOUBLE_UPDATE_PWM 1 + +#define DMIN 750 // 15mks Dminimum +#define SECOND (FREQ_PWM*3) +#define MINUTE (SECOND*60) + + + +//#define REVERS_ON_CLOCK 1 // 0 // 1- �� ������� .. 0 - ������ ������� + +//#define BAN_ROTOR_REVERS_DIRECT 1 + +//#define TIME_PAUSE_ZADATCHIK 750//500 +// +//#define TIME_SET_LINE_RELAY_FAN 3000 // ����� ������ �������� �� ���� ��������� ���������� ����������� +//#define LEVEL_FAN_ON_TEMPER_ACDRIVE 1400 //������� ��������� ����������� ���������� ��������� +//#define LEVEL_FAN_OFF_TEMPER_ACDRIVE 1200 //������� ���������� ����������� ���������� ��������� +////(������ ���� ������ LEVEL_FAN_ON_TEMPER_ACDRIVE � ������� �� ���������� ~20 �������� ) +//#define TIME_SET_LINE_RELAY_FAN 3000 //����� ������ �������� �� ���� ��������� ���������� ����������� +// +// +//#define MAX_TIME_DIRECT_ROTOR 5000 // ����. �������� �������� �� ����������� ����������� �������� +//#define MIN_TIME_DIRECT_ROTOR -5000 // ����������� �������� �������� �� ����������� ����������� �������� +// +//#define LEVEL_FORWARD_TIME_DIRECT_ROTOR 4000 // �������� �������� ������� ��������� ��� ����������� ������ +//#define LEVEL_BACK_TIME_DIRECT_ROTOR -4000 // �������� �������� ������� ��������� ��� ����������� ����� +// +//#define MAX_TIME_ERROR_ROTOR 5000 // ����. �������� �������� �� ����������� ������������� ������������ �������� +//#define MIN_TIME_ERROR_ROTOR 0 // ���. �������� �������� �� ����������� ������������� ������������ �������� +// +// +//#define LEVEL_ON_ERROR_ROTOR 4000 // �������� �������� ������� ��������� ��� ����������� ������������ � ������� +//#define LEVEL_OFF_ERROR_ROTOR 1000 // �������� �������� ������� ��������� ��� ����������� ������������ ��� ������� +// +// +// +//#define WORK_TWICE 0 /* �������� � ����y ��������� */ +// +// +//#define PID_KP_IM 0.018 //0.036 //0.018 //0.18 //0.095 // PID Kp +//#define PID_KI_IM 0.08 // 0.008 // PID Ki +//#define PID_KD_IM 0.0000 //*100 // PID Kd +//#define PID_KC_IM 0.09 // PID Kc +// +// +//#define PID_KP_F 12//26//12 //40 //20 //12 //20 //60.0 //20.0 //0.095 // PID Kp +//#define PID_KI_F 0.00010 // 0.008 // PID Ki +//#define PID_KD_F 0.000 //*100 PID Kd +//#define PID_KC_F 0.005 // PID Kc +////#define PID_KC_F 0.000 // PID Kc +// +//#define ADD_KP_DF (1000.0/NORMA_MZZ)//(500.0/NORMA_MZZ)//(50.0/NORMA_MZZ) +//#define ADD_KI_DF (2000.0/NORMA_MZZ)//(1000.0/NORMA_MZZ)//(100.0/NORMA_MZZ) +//#define MAX_DELTA_pidF 2.0 +//#define MIN_MZZ_FOR_DF 1761607 //(210/NORMA_MZZ) +// +// +//#define Im_PREDEL 600 /* ���������� ������ ��� ��� ������ �� ���� */ +//#define I_OUT_PREDEL -20 /* ���������� ���. ��� ����������y ��� ������ �� ���� */ +//#define U_IN_PREDEL 500 /* ���������� ������������ ������� ����y����� ��� ������ �� ���� */ +// +//#define IQ_NORMAL_CHARGE_UD_MAX 12163481 // 1450 V //13002342 // 1550 //_IQtoF(filter.iqU_1_long)*NORMA_ACP +//#define IQ_NORMAL_CHARGE_UD_MIN 10066329 // 1200 V +// +// +//#define U_D_MAX_ERROR_GLOBAL 17616076 // 2100 V //17196646 //2050V // 16777216 //2000V/2000*2^24 +//#define U_D_MAX_ERROR 16777216 // 2000V //16357785 //1950V //15938355 //1900V/2000*2^24 +// +////#define U_D_NORMA_MIN 3774873 // 450 V // 13421772 // 450 V 22.05.08 //1600V/2000*2^24 +////#define U_D_NORMA_MAX 15518924 // //15099494 //1850V/2000*2^24 +// +//#define U_D_MIN_ERROR 10905190 // 1300V/2000*2^24 +// +//#define I_IN_MAX_ERROR_GLOBAL 18454937 // 2200 A //16777216 //2000 A // 13421772 //1600 A //10905190 //1300 // 900A +// +//#define KOEFF_WROTOR_FILTER_SPARTAN 7//8 +//#define MAX_DELTA_WROTOR_S_1_2 1 +// +//#define ENABLE_I_HDW_PROTECT_ON_GLOBAL 1 // ��������� ��������� ������� �������� �� ���������� ������� ������ +// +//#define TIME_WAIT_CHARGE 2000 //5000 // 10000 +//#define TIME_WAIT_CHARGE_OUT 15000 //15000 +//#define TIME_SET_LINE_RELAY 10000 +//#define TIME_SET_LINE_RELAY5 3000 +//#define TIME_WAIT_LEVEL_QPU2 3000 +// + +///--------------------------- 22220 paremetrs -------------------///////// + +//////////////////////////////////////////////////////////////// +// Loaded capasitors level +#define V_CAPASITORS_LOADED_IQ 11184810 //13421772 ~ 2400V // 11184810 ~ 2000V +#define V_NOMINAL 14260633 //15099494 ~ 2700V + +// Level of nominal currents +#define I_OUT_NOMINAL 1585.0 //A +#define I_OUT_NOMINAL_IQ 12482249 //9777761 ~ 1748 //8388608 ~ 1500A // 10066329 ~ 1800A // 8863067 ~ 1585 + //11184811 ~ 2000A // 12482249 ~ 2232A +#define I_OUT_1_6_NOMINAL_IQ 14180908 +#define I_OUT_1_8_NOMINAL_IQ 15953520 +#define I_ZPT_NOMINAL_IQ 6123683 //1095A + +#define IQ_OUT_NOM 2000.0 //1350.0 +#define ID_OUT_NOM (I_OUT_NOMINAL * 0.52) + +#define NORMA_FROTOR 20.0 +#define NORMA_MZZ 3000.0 //5000 +#define NORMA_ACP 3000.0 +#define DISABLE_TEST_TKAK_ON_START 1 +//#define MOTOR_STEND 1 +#define F_STATOR_MAX 20.0 /* ����. �������� ���������� ������������ */ +#define F_STATOR_NOM 12.0 //Hz +#define IQ_F_STATOR_NOM 10066329 + +#define F_ROTOR_NOM 2.0 //Hz +#define IQ_F_ROTOR_NOM 1677721 + +#define FREQ_PWM 450 //420 // 350 //401 //379 +#define FREQ_PWM_BASE 400 + +#ifdef MOTOR_STEND +#define POLUS 4 /* ����� ��� ������� */ +#define BPSI_NORMAL 0.9//0.7 //Hz +#define MAX_FZAD_FROM_SU 16.7 // ����������� �������� �������� ������� � ������ �� �� +#define MAX_FZAD_FROM_SU_OBOROT 1100 +#define COS_FI 0.98 +#else +#define POLUS 6 /* ����� ��� ������� */ +#define BPSI_NORMAL 0.9 //Hz +#define MAX_FZAD_FROM_SU 16.7 // ����������� �������� �������� ������� � ������ �� �� +#define MAX_FZAD_FROM_SU_OBOROT 1650 +#define COS_FI 0.87 +//PCH21 - 0.81 +//PCH32 - 0.82 +//PCH12 - 0.82 +#endif + + +#define KOEF_TEMPER_DECR_MZZ 2.0 + +#endif + + + diff --git a/Inu/Src2/main/pid_reg3.c b/Inu/Src2/main/pid_reg3.c new file mode 100644 index 0000000..4cc46c1 --- /dev/null +++ b/Inu/Src2/main/pid_reg3.c @@ -0,0 +1,107 @@ +/*===================================================================================== + File name: PID_REG3.C (IQ version) + + Originator: Digital Control Systems Group + Texas Instruments + + Description: The PID controller with anti-windup + +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +-------------------------------------------------------------------------------------*/ + +#include "IQmathLib.h" // Include header for IQmath library +// Don't forget to set a proper GLOBAL_Q in "IQmathLib.h" file +//#include "dmctype.h" +#include "pid_reg3.h" + +#define IQ_100 1677721600 + +#pragma CODE_SECTION(pid_reg3_calc,".fast_run"); +void pid_reg3_calc(PIDREG3 *v) +{ +_iq Ud2; + // Compute the error + v->Err = v->Ref - v->Fdb; + + // Compute the proportional output + v->Up = _IQmpy(v->Kp,v->Err); + + // Compute the integral output + v->Ui = v->Ui + _IQmpy(v->Ki,v->Up) + _IQmpy(v->Kc,v->SatErr); +/* + // Saturate the integral output + if (v->Ui > v->OutMax) + v->Ui = v->OutMax; + else if (v->Ui < v->OutMin) + v->Ui = v->OutMin; +*/ + // Compute the derivative output + Ud2 = v->Up - v->Up1;// _IQmpy(IQ_100,(v->Up - v->Up1)); + v->Ud = _IQmpy(v->Kd,Ud2); + + + // Compute the pre-saturated output + v->OutPreSat = v->Up + v->Ui + v->Ud; + + // Saturate the output + if (v->OutPreSat > v->OutMax) + v->Out = v->OutMax; + else if (v->OutPreSat < v->OutMin) + v->Out = v->OutMin; + else + v->Out = v->OutPreSat; + + // Compute the saturate difference + v->SatErr = v->Out - v->OutPreSat; + + // Update the previous proportional output + v->Up1 = v->Up; + + +} + +#pragma CODE_SECTION(pid_reg3_calc,".fast_run"); +void pid_reg3_undependent_calc(PIDREG3 *v) +{ +_iq Ud2; + // Compute the error + v->Err = v->Ref - v->Fdb; + + // Compute the proportional output + v->Up = _IQmpy(v->Kp,v->Err); + + // Compute the integral output + v->Ui = v->Ui + _IQmpy(v->Ki,v->Err) + _IQmpy(v->Kc,v->SatErr); +/* + // Saturate the integral output + if (v->Ui > v->OutMax) + v->Ui = v->OutMax; + else if (v->Ui < v->OutMin) + v->Ui = v->OutMin; +*/ + // Compute the derivative output + Ud2 = v->Up - v->Up1;// _IQmpy(IQ_100,(v->Up - v->Up1)); + v->Ud = _IQmpy(v->Kd,Ud2); + + + // Compute the pre-saturated output + v->OutPreSat = v->Up + v->Ui + v->Ud; + + // Saturate the output + if (v->OutPreSat > v->OutMax) + v->Out = v->OutMax; + else if (v->OutPreSat < v->OutMin) + v->Out = v->OutMin; + else + v->Out = v->OutPreSat; + + // Compute the saturate difference + v->SatErr = v->Out - v->OutPreSat; + + // Update the previous proportional output + v->Up1 = v->Up; + +} diff --git a/Inu/Src2/main/pid_reg3.h b/Inu/Src2/main/pid_reg3.h new file mode 100644 index 0000000..20b68c6 --- /dev/null +++ b/Inu/Src2/main/pid_reg3.h @@ -0,0 +1,117 @@ +/* ================================================================================= +File name: PID_REG3.H (IQ version) + +Originator: Digital Control Systems Group + Texas Instruments + +Description: +Header file containing constants, data type definitions, and +function prototypes for the PIDREG3. +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +------------------------------------------------------------------------------*/ +#ifndef __PIDREG3_H__ +#define __PIDREG3_H__ + +#include "IQmathlib.h" +//#include "dmctype.h" + +typedef struct { _iq Ref; // Input: Reference input + _iq Fdb; // Input: Feedback input + _iq Err; // Variable: Error + _iq Kp; // Parameter: Proportional gain + _iq Up; // Variable: Proportional output + _iq Ui; // Variable: Integral output + _iq Ud; // Variable: Derivative output + _iq OutPreSat; // Variable: Pre-saturated output + _iq OutMax; // Parameter: Maximum output + _iq OutMin; // Parameter: Minimum output + _iq Out; // Output: PID output + _iq SatErr; // Variable: Saturated difference + _iq Ki; // Parameter: Integral gain + _iq Kc; // Parameter: Integral correction gain + _iq Kd; // Parameter: Derivative gain + _iq Up1; // History: Previous proportional output + void (*calc)(); // Pointer to calculation function + } PIDREG3; + +typedef PIDREG3 *PIDREG3_handle; +/*----------------------------------------------------------------------------- +Default initalizer for the PIDREG3 object. +-----------------------------------------------------------------------------*/ +#define PIDREG3_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(PIDREG3_handle))pid_reg3_calc } + +#define PIDREG3_UNDEPENDENT_DEFAULTS { 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + (void (*)(PIDREG3_handle))pid_reg3_undependent_calc } + +/*------------------------------------------------------------------------------ +Prototypes for the functions in PIDREG3.C +------------------------------------------------------------------------------*/ +void pid_reg3_calc(PIDREG3_handle); +void pid_reg3_undependent_calc(PIDREG3 *v); + +#endif // __PIDREG3_H__ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Inu/Src2/main/rotation_speed.h b/Inu/Src2/main/rotation_speed.h new file mode 100644 index 0000000..a28fa49 --- /dev/null +++ b/Inu/Src2/main/rotation_speed.h @@ -0,0 +1,44 @@ +#ifndef _ROT_SPEED +#define _ROT_SPEED + +#include "IQmathLib.h" + +#define SENSORS_NUMBER 10 +#define SENSORS_NUMBER_ONLY_IN 6 +#define IMPULSES_PER_TURN (1LL << 13) //Old sensor +//#define IMPULSES_PER_TURN (1LL << 10) //New sensor +#define ANGLE_RESOLUTION (1LL << 18) //2^18 + +typedef struct +{ + int direct_rotor; + int direct_rotor_in1; + int direct_rotor_in2; + int direct_rotor_angle; + union { + unsigned int sens_err1:1; + unsigned int sens_err2:1; + unsigned int reserved:14; + } error; + + _iq iqFsensors[SENSORS_NUMBER]; + + _iq iqF; + _iq iqFout; + _iq iqFlong; + + _iq iqFrotFromOptica; + + unsigned int error_update_count; +} ROTOR_VALUE; + +#define ROTOR_VALUE_DEFAULTS {0,0,0,0,0, {0,0,0,0,0,0,0,0},0,0,0,0,0} + +extern ROTOR_VALUE rotor; + +void Rotor_measure(void); +void rotorInit(void); +void update_rot_sensors(); + +#endif //_ROT_SPEED + diff --git a/Inu/Src2/main/svgen_dq.h b/Inu/Src2/main/svgen_dq.h new file mode 100644 index 0000000..2949fd1 --- /dev/null +++ b/Inu/Src2/main/svgen_dq.h @@ -0,0 +1,38 @@ +/* ================================================================================= +File name: SVGEN_DQ.H (IQ version) + +Originator: Digital Control Systems Group + Texas Instruments + +Description: +Header file containing constants, data type definitions, and +function prototypes for the SVGEN_DQ. +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +------------------------------------------------------------------------------*/ +#ifndef __SVGEN_DQ_H__ +#define __SVGEN_DQ_H__ + +typedef struct { _iq Ualpha; // Input: reference alpha-axis phase voltage + _iq Ubeta; // Input: reference beta-axis phase voltage + _iq Ta; // Output: reference phase-a switching function + _iq Tb; // Output: reference phase-b switching function + _iq Tc; // Output: reference phase-c switching function + void (*calc)(); // Pointer to calculation function + } SVGENDQ; + +typedef SVGENDQ *SVGENDQ_handle; +/*----------------------------------------------------------------------------- +Default initalizer for the SVGENDQ object. +-----------------------------------------------------------------------------*/ +#define SVGENDQ_DEFAULTS { 0,0,0,0,0, \ + (void (*)(Uint32))svgendq_calc } + +/*------------------------------------------------------------------------------ +Prototypes for the functions in SVGEN_DQ.C +------------------------------------------------------------------------------*/ +void svgendq_calc(SVGENDQ_handle); + +#endif // __SVGEN_DQ_H__ diff --git a/Inu/Src2/main/svgen_dq_v2.c b/Inu/Src2/main/svgen_dq_v2.c new file mode 100644 index 0000000..cb8b85c --- /dev/null +++ b/Inu/Src2/main/svgen_dq_v2.c @@ -0,0 +1,120 @@ +/*===================================================================================== + File name: SVGEN_DQ.C (IQ version) + + Originator: Digital Control Systems Group + Texas Instruments + + Description: Space-vector PWM generation based on d-q components + +===================================================================================== + History: +------------------------------------------------------------------------------------- + 04-15-2005 Version 3.20 +-------------------------------------------------------------------------------------*/ + +#include "IQmathLib.h" // Include header for IQmath library +// Don't forget to set a proper GLOBAL_Q in "IQmathLib.h" file +#include "dmctype.h" +#include "svgen_dq.h" +_iq iq_max = _IQ(1.0)-1; + + +// #pragma CODE_SECTION(svgendq_calc,".fast_run2"); +void svgendq_calc(SVGENDQ *v) +{ + _iq Va,Vb,Vc,t1,t2,temp_sv1,temp_sv2; + Uint16 Sector = 0; // Sector is treated as Q0 - independently with global Q + + Sector = 0; \ + temp_sv1=_IQdiv2(v->Ubeta); /*divide by 2*/ \ + temp_sv2=_IQmpy(_IQ(0.8660254),v->Ualpha); /* 0.8660254 = sqrt(3)/2*/ \ + +// Inverse clarke transformation + Va = v->Ubeta; \ + Vb = -temp_sv1 + temp_sv2; \ + Vc = -temp_sv1 - temp_sv2; \ + +// 60 degree Sector determination + if (Va>0) + Sector = 1; + if (Vb>0) + Sector = Sector + 2; + if (Vc>0) + Sector = Sector + 4; + +// X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc \ Va = v.Ubeta; + Vb = temp_sv1 + temp_sv2; + Vc = temp_sv1 - temp_sv2; +// Sector 0: this is special case for (Ualpha,Ubeta) = (0,0) + + if (Sector==0) // Sector 0: this is special case for (Ualpha,Ubeta) = (0,0) + { + v->Ta = _IQ(0.5); + v->Tb = _IQ(0.5); + v->Tc = _IQ(0.5); + } + if (Sector==1) // Sector 1: t1=Z and t2=Y (abc ---> Tb,Ta,Tc) + { + t1 = Vc; + t2 = Vb; + v->Tb = _IQdiv2((_IQ(1)-t1-t2)); // tbon = (1-t1-t2)/2 + v->Ta = v->Tb+t1; // taon = tbon+t1 + v->Tc = v->Ta+t2; // tcon = taon+t2 + } + else if (Sector==2) // Sector 2: t1=Y and t2=-X (abc ---> Ta,Tc,Tb) + { + t1 = Vb; + t2 = -Va; + v->Ta = _IQdiv2((_IQ(1)-t1-t2)); // taon = (1-t1-t2)/2 + v->Tc = v->Ta+t1; // tcon = taon+t1 + v->Tb = v->Tc+t2; // tbon = tcon+t2 + } + else if (Sector==3) // Sector 3: t1=-Z and t2=X (abc ---> Ta,Tb,Tc) + { + t1 = -Vc; + t2 = Va; + v->Ta = _IQdiv2((_IQ(1)-t1-t2)); // taon = (1-t1-t2)/2 + v->Tb = v->Ta+t1; // tbon = taon+t1 + v->Tc = v->Tb+t2; // tcon = tbon+t2 + } + else if (Sector==4) // Sector 4: t1=-X and t2=Z (abc ---> Tc,Tb,Ta) + { + t1 = -Va; + t2 = Vc; + v->Tc = _IQdiv2((_IQ(1)-t1-t2)); // tcon = (1-t1-t2)/2 + v->Tb = v->Tc+t1; // tbon = tcon+t1 + v->Ta = v->Tb+t2; // taon = tbon+t2 + } + else if (Sector==5) // Sector 5: t1=X and t2=-Y (abc ---> Tb,Tc,Ta) + { + t1 = Va; + t2 = -Vb; + v->Tb = _IQdiv2((_IQ(1)-t1-t2)); // tbon = (1-t1-t2)/2 + v->Tc = v->Tb+t1; // tcon = tbon+t1 + v->Ta = v->Tc+t2; // taon = tcon+t2 + } + else if (Sector==6) // Sector 6: t1=-Y and t2=-Z (abc ---> Tc,Ta,Tb) + { + t1 = -Vb; + t2 = -Vc; + v->Tc = _IQdiv2((_IQ(1)-t1-t2)); // tcon = (1-t1-t2)/2 + v->Ta = v->Tc+t1; // taon = tcon+t1 + v->Tb = v->Ta+t2; // tbon = taon+t2 + } + +// Convert the unsigned GLOBAL_Q format (ranged (0,1)) -> signed GLOBAL_Q format (ranged (-1,1)) + v->Ta = _IQmpy2(v->Ta - _IQ(0.5)); + v->Tb = _IQmpy2(v->Tb - _IQ(0.5)); + v->Tc = _IQmpy2(v->Tc - _IQ(0.5)); + + if (v->Ta > iq_max) v->Ta = iq_max; + if (v->Tb > iq_max) v->Tb = iq_max; + if (v->Tc > iq_max) v->Tc = iq_max; + + if (v->Ta < -iq_max) v->Ta = -iq_max; + if (v->Tb < -iq_max) v->Tb = -iq_max; + if (v->Tc < -iq_max) v->Tc = -iq_max; + +} + + diff --git a/Inu/Src2/main/v_pwm24.c b/Inu/Src2/main/v_pwm24.c new file mode 100644 index 0000000..357cb98 --- /dev/null +++ b/Inu/Src2/main/v_pwm24.c @@ -0,0 +1,1635 @@ + + +#include "v_pwm24.h" +//#include "DSP281x_Device.h" // DSP281x Headerfile Include File +//#include "big_dsp_module.h" +//#include "rmp2cntl.h" // Include header for the VHZPROF object +//#include "rmp_cntl_my1.h" // Include header for the VHZPROF object +#include "pid_reg3.h" // Include header for the VHZPROF object + +#include "params.h" +// #include "PWMTools.h" +#include "adc_tools.h" +#include "v_pwm24.h" + +#include "dq_to_alphabeta_cos.h" + +#include "IQmathLib.h" +// #include "log_to_memory.h" +//Xilinx +//#include "x_parameters.h" +// #include "x_basic_types.h" +// #include "xp_project.h" +// #include "xp_cds_tk.h" +#include "svgen_dq.h" +#include "xp_write_xpwm_time.h" + +#include "def.h" + +#define DEF_FREQ_PWM_XTICS T1_PRD +#define DEF_PERIOD_MIN_XTICS (DT + 10e-6)*FTBCLK + +// ������� ��� � xilinx ����� (60000000 / 16 / FREQ_PWM = 3750000 / FREQ_PWM) +// #pragma DATA_SECTION(VAR_FREQ_PWM_XTICS,".fast_vars1"); +int VAR_FREQ_PWM_XTICS = DEF_FREQ_PWM_XTICS; + +// ����������� �������� ���� � xilinx ����� +// #pragma DATA_SECTION(VAR_PERIOD_MAX_XTICS,".fast_vars1"); +int VAR_PERIOD_MAX_XTICS = DEF_FREQ_PWM_XTICS - DEF_PERIOD_MIN_XTICS; + +// ����������� �������� ���� � xilinx ����� (mintime+deadtime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_XTICS,".fast_vars1"); +int VAR_PERIOD_MIN_XTICS = DEF_PERIOD_MIN_XTICS;// + +// ����������� �������� ���� � xilinx ����� ��� ��������� ������ (mintime) (F���� * T���.�����.��� = (60 / 16 / 2) * T��� = (60 * T��� / 16 / 2)) +// #pragma DATA_SECTION(VAR_PERIOD_MIN_BR_XTICS,".fast_vars1"); +// int VAR_PERIOD_MIN_BR_XTICS = DEF_PERIOD_MIN_BR_XTICS;// + +#define PWM_ONE_INTERRUPT_RUN 1 +#define PWM_TWICE_INTERRUPT_RUN 0 + + + +#define SQRT3 29058990 //1.7320508075688772935274463415059 +#define CONST_IQ_1 16777216 //1 +#define CONST_IQ_05 8388608 //0.5 +#define CONST_IQ_2 33554432 //2 + +#define CONST_IQ_PI6 8784530 //30 +#define CONST_IQ_PI3 17569060 // 60 +#define CONST_IQ_PI 52707178 // 180 +#define CONST_IQ_OUR1 35664138 // +#define CONST_IQ_2PI 105414357 // 360 +#define CONST_IQ_120G 35138119 // 120 grad +#define CONST_IQ_3 50331648 // 3 + +#define IQ_ALFA_SATURATION1 15099494//16441671//15099494 +#define IQ_ALFA_SATURATION2 1677721//16441671//15099494 + + +#define PI 3.1415926535897932384626433832795 + +// #pragma DATA_SECTION(iq_alfa_coef,".fast_vars"); +_iq iq_alfa_coef = 16777216; + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//#pragma DATA_SECTION(freq_array,".v_24pwm_vars"); +//int freq_array[COUNT_VAR_FREQ]; +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +//#pragma DATA_SECTION(pidCur_Kp,".v_24pwm_vars"); +//_iq pidCur_Kp = 0; + +// #pragma DATA_SECTION(pidCur_Ki,".fast_vars"); +_iq pidCur_Ki = 0; + +// #pragma DATA_SECTION(ar_tph,".fast_vars"); +_iq ar_tph[7]; + +// #pragma DATA_SECTION(winding_displacement,".fast_vars"); +_iq winding_displacement = CONST_IQ_PI6; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_1,".fast_vars");//v_24pwm_vars +//_iq iq_koef_mod_korrect_1; + +//#pragma DATA_SECTION(iq_koef_mod_korrect_2,".v_24pwm_vars"); +//_iq iq_koef_mod_korrect_2; + +//#pragma DATA_SECTION(ar_sa_all,".v_24pwm_vars"); +// #pragma DATA_SECTION(ar_sa_all,".fast_vars"); +int ar_sa_all[3][6][4][7] = { { + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + } + }, + { + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + } + }, + { + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,-1,0,0,0,1},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0},{-1,-1,-1,0,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,0,0,0,1,1,1},{0,1,1,1,0,0,0},{0,0,1,1,1,0,0},{0,1,1,1,0,0,0} + }, + { + {-1,-1,0,0,0,1,1},{-1,-1,0,0,0,0,0},{-1,0,0,0,1,0,0},{0,0,1,1,0,0,0} + } + } + }; + + +// #pragma DATA_SECTION(svgen_pwm24_1,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_1,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_1 = SVGEN_PWM24_DEFAULTS; +// #pragma DATA_SECTION(svgen_pwm24_2,".v_24pwm_vars"); +//#pragma DATA_SECTION(svgen_pwm24_2,".fast_vars"); +SVGEN_PWM24 svgen_pwm24_2 = SVGEN_PWM24_DEFAULTS; + +// #pragma DATA_SECTION(svgen_dq_1,".v_24pwm_vars"); +SVGENDQ svgen_dq_1 = SVGENDQ_DEFAULTS; +// #pragma DATA_SECTION(svgen_dq_2,".v_24pwm_vars"); +SVGENDQ svgen_dq_2 = SVGENDQ_DEFAULTS; + +//#pragma DATA_SECTION(delta_t1_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t1_struct,".fast_vars"); +//PIDREG3 delta_t1_struct = PIDREG3_DEFAULTS; +//#pragma DATA_SECTION(delta_t2_struct,".v_24pwm_vars"); +//#pragma DATA_SECTION(delta_t2_struct,".fast_vars"); +//PIDREG3 delta_t2_struct = PIDREG3_DEFAULTS; + +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax); +int detect_sec(_iq teta); +int detect_region(_iq k, _iq teta); +// + + + + +//void init_alpha(void) +//{ +// +//// power_ain1.init(&power_ain1); +//// power_ain2.init(&power_ain2); +// +// svgen_mf1.NewEntry = 0;//_IQ(0.5); +// svgen_mf2.NewEntry = 0; +// +// svgen_mf1.SectorPointer = 0; +// svgen_mf2.SectorPointer = 0; +// +////����� �� ��������� 0 �������� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// +// +// +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_PLUS) +//// 30 ����. ����� +// svgen_mf1.Alpha = _IQ(0.5); +// svgen_mf2.Alpha = _IQ(0); +// +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_30_MINUS) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0.5); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// +//#if (SETUP_SDVIG_OBMOTKI == SDVIG_OBMOTKI_ZERO) +//// -30 ����. ����� +// svgen_mf1.Alpha = _IQ(0); +// svgen_mf2.Alpha = _IQ(0); +// svgen_mf1.Full_Alpha = svgen_mf1.Alpha; +// svgen_mf2.Full_Alpha = svgen_mf2.Alpha; +//#else +// #error "!!!������!!! �� ��������� SETUP_SDVIG_OBMOTKI � params_motor.h!!!" +// +// +//#endif +// +//#endif +// +// +// +//#endif +// +// +// +//} + +void InitVariablesSvgen(unsigned int freq) +{ +////////// Inserted from 'initPWM_Variables' for modulation project ////////// + + //��� ������ ���� �������, ����� ���� ��������� ������, ��� ������ ���� + xpwm_time.Tclosed_0 = 0; + xpwm_time.Tclosed_1 = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.Tclosed_high = VAR_FREQ_PWM_XTICS + 1; + xpwm_time.pwm_tics = VAR_FREQ_PWM_XTICS; + // ������� ����������� ��� + // "����������� ��� ��� ���� ����=0x0 + //���� SAW_DIRECTbit = 0 �� �������� ����>������� �������� �������� ���������� ���������=0 + //�� ������ ���� + //���� SAW_DIRECTbit = 1 �� �������� ����<=������� �������� �������� ���������� ���������=0 + //�� ������ ���� + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //��� 22220 ������������� 0, �.�. ��� ������ � ������ ������ ���� ���������� ��������� ����������. + xpwm_time.saw_direct.all = 0;//0x0555; + xpwm_time.one_or_two_interrupts_run = PWM_TWICE_INTERRUPT_RUN; + + initXpwmTimeStructure(&xpwm_time); + init_alpha_pwm24(VAR_FREQ_PWM_XTICS); +///////////////////////////////////////////////////////////// + + svgen_pwm24_1.pwm_minimal_impuls_zero_minus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_100;//DEF_PERIOD_MIN_XTICS_80; + svgen_pwm24_1.pwm_minimal_impuls_zero_plus = 0;//(float)DEF_PERIOD_MIN_MKS*1000.0*FREQ_INTERNAL_GENERATOR_XILINX_TMS/1000000000.0;// DEF_PERIOD_MIN_XTICS_80; + + svgen_pwm24_2.pwm_minimal_impuls_zero_minus = svgen_pwm24_1.pwm_minimal_impuls_zero_minus; + svgen_pwm24_2.pwm_minimal_impuls_zero_plus = svgen_pwm24_1.pwm_minimal_impuls_zero_plus; + + + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_1; + + + + + svgen_dq_1.Ualpha = 0; + svgen_dq_1.Ubeta = 0; + + svgen_dq_2.Ualpha = 0; + svgen_dq_2.Ubeta = 0; + + + +} + + + + + + + + + + +// #pragma CODE_SECTION(recalc_time_pwm_minimal_2_xilinx_pwm24_l,".fast_run2"); +void recalc_time_pwm_minimal_2_xilinx_pwm24_l(SVGEN_PWM24 *pwm24, + _iq *T0, _iq *T1, + _iq timpuls_corr ) +{ + +//_iq pwm_t, timpuls_corr; + + volatile unsigned long pwm_t; + volatile unsigned int minimal_plus, minimal_minus; + + + + minimal_plus = pwm24->pwm_minimal_impuls_zero_plus; + minimal_minus = pwm24->pwm_minimal_impuls_zero_minus; + + // if (pwm24->prev_level == V_PWM24_PREV_PWM_CLOSE || pwm24->prev_level == V_PWM24_PREV_PWM_MIDDLE || pwm24->prev_level == V_PWM24_PREV_PWM_WORK_KM0) + // { + // minimal_plus *= 2; +// minimal_minus *= 2; +// } + + pwm_t = timpuls_corr / pwm24->XilinxFreq; + + // *T_imp = pwm_t; + +// if (pwm_t>(pwm24->Tclosed_high-4*minimal_minus)) +// pwm_t=(pwm24->Tclosed_high-4*minimal_minus); + + + if (timpuls_corr >= 0) + { + *T0 = pwm_t + minimal_plus; + // *T1 = 0; + *T1 = pwm24->Tclosed_high - minimal_minus; + } + else + { + *T0 = 0 + minimal_plus; + // *T1 = -pwm_t - minimal_minus; + *T1 = pwm24->Tclosed_high + pwm_t - minimal_minus; + } + + + // if (*T0 < minimal_plus) + // *T0 = minimal_plus; + + // if (*T0 > (pwm24->Tclosed_high - 2 * minimal_plus)) + // *T0 = (pwm24->Tclosed_high - 2 * minimal_plus); + + // if (*T1 < (2 * minimal_minus)) + // *T1 = 2 * minimal_minus; + + // if (*T1 > (pwm24->Tclosed_high - minimal_minus)) + // *T1 = (pwm24->Tclosed_high - minimal_minus); + +} + +static DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + +// #pragma CODE_SECTION(test_calc_dq_pwm24,".v_24pwm_run"); +void test_calc_dq_pwm24(_iq Ud, _iq Uq, _iq Ud2, _iq Uq2, _iq tetta,_iq Uzad_max) +{ +// DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + _iq maxUq = 0; + _iq Uzad_max_square = _IQmpy(Uzad_max, Uzad_max); + + if (tetta > CONST_IQ_2PI) + { + tetta -= CONST_IQ_2PI; + } + + if (tetta < 0) + { + tetta += CONST_IQ_2PI; + } + //��������� ����������� ��������� + maxUq = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq > maxUq) { Uq = maxUq;} + if (Uq < -maxUq) { Uq = -maxUq;} + + + //Reculct dq to alpha-beta + dq_to_ab.Tetta = tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + svgen_dq_1.calc(&svgen_dq_1); + + //��������� ����������� ��������� + maxUq = _IQsqrt(Uzad_max_square - _IQmpy(Ud, Ud)); + if (Uq2 > maxUq) { Uq2 = maxUq;} + if (Uq2 < -maxUq) { Uq2 = -maxUq;} + + //Reculc dq to alpha-beta for 2-nd winding with winding displasement + dq_to_ab.Tetta = tetta - winding_displacement; + dq_to_ab.Ud = Ud2; + dq_to_ab.Uq = Uq2; + dq_to_ab.calc2(&dq_to_ab); + //Calc swgen times for 1-st winding + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + svgen_dq_2.calc(&svgen_dq_2); + + //1 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 winding + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +/* + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS);*/ +} + + +// #pragma CODE_SECTION(test_calc_simple_dq_pwm24,".v_24pwm_run"); +void test_calc_simple_dq_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2,_iq Uzad_max) +{ + static _iq hz_to_angle = _IQ(2.0 * PI * NORMA_FROTOR / FREQ_PWM / 2); +// static _iq tetta = 0; + DQ_TO_ALPHABETA dq_to_ab = DQ_TO_ALPHABETA_DEFAULTS; + + _iq Ud = 0; + _iq Uq = _IQsat(uz1,Uzad_max,0); + + analog.tetta += _IQmpy(fz1, hz_to_angle); + + if (analog.tetta >= CONST_IQ_2PI) + { + analog.tetta -= CONST_IQ_2PI; + } + + if (analog.tetta < 0) + { + analog.tetta += CONST_IQ_2PI; + } + + dq_to_ab.Tetta = analog.tetta; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_1.Ualpha = dq_to_ab.Ualpha; + svgen_dq_1.Ubeta = dq_to_ab.Ubeta; + +// svgen_dq_1.Ualpha = 0; +// svgen_dq_1.Ubeta = 0; + + svgen_dq_1.calc(&svgen_dq_1); + + dq_to_ab.Tetta = analog.tetta - winding_displacement; + dq_to_ab.Ud = Ud; + dq_to_ab.Uq = Uq; + dq_to_ab.calc2(&dq_to_ab); + + svgen_dq_2.Ualpha = dq_to_ab.Ualpha; + svgen_dq_2.Ubeta = dq_to_ab.Ubeta; + + svgen_dq_2.calc(&svgen_dq_2); + + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Ta_0.Ti, &svgen_pwm24_1.Ta_1.Ti, svgen_dq_1.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tb_0.Ti, &svgen_pwm24_1.Tb_1.Ti, svgen_dq_1.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_1, &svgen_pwm24_1.Tc_0.Ti, &svgen_pwm24_1.Tc_1.Ti, svgen_dq_1.Tc); + + // 2 + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Ta_0.Ti, &svgen_pwm24_2.Ta_1.Ti, svgen_dq_2.Ta); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tb_0.Ti, &svgen_pwm24_2.Tb_1.Ti, svgen_dq_2.Tb); + recalc_time_pwm_minimal_2_xilinx_pwm24_l (&svgen_pwm24_2, &svgen_pwm24_2.Tc_0.Ti, &svgen_pwm24_2.Tc_1.Ti, svgen_dq_2.Tc); + +// logpar.log1 = (int16)(_IQtoIQ15(uz1)); +// logpar.log2 = (int16)(_IQtoIQ15(fz1)); +// logpar.log3 = (int16)(_IQtoIQ15(Ud)); +// logpar.log4 = (int16)(_IQtoIQ15(Uq)); +// logpar.log5 = (int16)(_IQtoIQ15(svgen_dq_1.Ualpha)); +// logpar.log6 = (int16)(_IQtoIQ15(svgen_dq_1.Ubeta)); +// logpar.log7 = (int16)(_IQtoIQ15(svgen_dq_1.Ta)); +// logpar.log8 = (int16)(_IQtoIQ15(svgen_dq_1.Tb)); +// logpar.log9 = (int16)(_IQtoIQ15(svgen_dq_1.Tc)); +// logpar.log10 = (int16)(_IQtoIQ12(analog.tetta)); +// logpar.log11 = (int16)(svgen_pwm24_1.Ta_0.Ti); +// logpar.log12 = (int16)((svgen_pwm24_1.Ta_1.Ti)); +// logpar.log13 = (int16)(svgen_pwm24_1.Tb_0.Ti); +// logpar.log14 = (int16)((svgen_pwm24_1.Tb_1.Ti)); +// logpar.log15 = (int16)(svgen_pwm24_1.Tc_0.Ti); +// logpar.log16 = (int16)((svgen_pwm24_1.Tc_1.Ti)); + + +// svgen_pwm24_1.calc(&svgen_pwm24_1); +// svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +// set_predel_dshim24_simple0(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// +// set_predel_dshim24_simple0(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); +// set_predel_dshim24_simple1(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +} + +// #pragma CODE_SECTION(test_calc_pwm24,".v_24pwm_run"); +void test_calc_pwm24(_iq uz1, _iq uz2, _iq fz1) +{ + //static int i =0; + svgen_pwm24_1.Freq = fz1; + svgen_pwm24_2.Freq = fz1; + + svgen_pwm24_1.Gain = uz1;//_IQmpy(uz1,iq_koef_mod_korrect_1); + svgen_pwm24_2.Gain = uz2;//_IQmpy(uz2,iq_koef_mod_korrect_2); + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc(&svgen_pwm24_1); + svgen_pwm24_2.calc(&svgen_pwm24_2); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + +// if(((svgen_pwm24_2.Ta_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Ta_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tb_1.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_0.Ti <= (VAR_FREQ_PWM_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > (VAR_FREQ_PWM_XTICS - VAR_PERIOD_MIN_XTICS)) && (svgen_pwm24_2.Tc_1.Ti <= (VAR_FREQ_PWM_XTICS)))) +// { +// asm(" NOP "); +// } +// +// if( ((svgen_pwm24_2.Ta_0.Ti > 0) && (svgen_pwm24_2.Ta_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Ta_1.Ti > 0) && (svgen_pwm24_2.Ta_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_0.Ti > 0) && (svgen_pwm24_2.Tb_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tb_1.Ti > 0) && (svgen_pwm24_2.Tb_1.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_0.Ti > 0) && (svgen_pwm24_2.Tc_0.Ti < (VAR_PERIOD_MIN_XTICS))) || +// ((svgen_pwm24_2.Tc_1.Ti > 0) && (svgen_pwm24_2.Tc_1.Ti < (VAR_PERIOD_MIN_XTICS)))) +// { +// asm(" NOP "); +// } +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc(SVGEN_PWM24 *vt) +{ + _iq StepAngle; + + StepAngle = _IQmpy(vt->Freq,vt->FreqMax); + + vt->Alpha = vt->Alpha + StepAngle; + + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + + +// #pragma CODE_SECTION(calc_time_one_tk,".v_24pwm_run"); +void calc_time_one_tk(_iq gain, _iq teta, _iq delta_U, + _iq Ia, _iq Ib, _iq Ic, + unsigned int number, + SVGEN_PWM24_TIME *tk0, + SVGEN_PWM24_TIME *tk1, + SVGEN_PWM24_TIME *tk2, + SVGEN_PWM24_TIME *tk3, + SVGEN_PWM24_TIME *tk4, + SVGEN_PWM24_TIME *tk5) +{ + _iq iq_t0 = 0, iq_t1 = 0, iq_t2 = 0, iq_t3 = 0, iq_t4 = 0, iq_t5 = 0; + _iq t_pos = 0, t_neg = 0; + _iq delta_ttt; + _iq teta60; + + int sector, region; + int cur_sign, i, ki; + int updown_tk0; + int updown_tk1; + + volatile _iq t_tk0, t_tk1; + + updown_tk0 = 1; + updown_tk1 = 0; + + sector = detect_sec(teta); // + teta60 = teta - _IQmpy(_IQ(sector - 1),CONST_IQ_PI3); // + + if ((sector == 2) || (sector == 4) || (sector == 6)) + { + teta60 = CONST_IQ_PI3 - teta60; + } + + region = detect_region(gain, teta60); // + + calc_t_abc(gain, teta60, region, &iq_t0, &iq_t1, &iq_t2, &iq_t3, &iq_t4, &iq_t5); + + + delta_ttt = 0; //calc_delta_t(delta_U,number,region); + //delta_ttt = 0; + + //if (number == 1) + //{ + //logpar.log1 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log2 = (int16)(_IQtoIQ15(delta_ttt)); + //} + //else + //{ + //logpar.log3 = (int16)(_IQtoIQ15(delta_U)); + //logpar.log4 = (int16)(_IQtoIQ15(delta_ttt)); + //} + + calc_arr_tph(sector, region, iq_t0, iq_t1, iq_t2, iq_t3, iq_t4, iq_t5, delta_ttt,number, Ia, Ib, Ic); + + for (ki = 0; ki < 3; ki++) + { + t_pos = 0; + t_neg = 0; + + for (i = 0; i < 7; i++) + { + cur_sign = ar_sa_all[ki][sector - 1][region - 1][i]; + + if (cur_sign > 0) + { + t_pos += ar_tph[i]; + } + + if (cur_sign < 0) + { + t_neg += ar_tph[i]; + } + } + + t_pos = t_pos << 1; + + t_neg = t_neg << 1; + + if (t_neg == 0) + { + t_tk0 = 0; + } + else + { + t_tk0 = t_neg; + } + + if (t_pos == 0) + { + t_tk1 = CONST_IQ_1; + } + else + { + t_tk1 = CONST_IQ_1 - t_pos; + } + + switch (ki) + { + case 0: + tk0->up_or_down = updown_tk0; + tk0->Ti = t_tk0; + + tk1->up_or_down = updown_tk1; + tk1->Ti = t_tk1; + + break; + + case 1: + tk2->up_or_down = updown_tk0; + tk2->Ti = t_tk0; + + tk3->up_or_down = updown_tk1; + tk3->Ti = t_tk1; + + break; + + case 2: + tk4->up_or_down = updown_tk0; + tk4->Ti = t_tk0; + + tk5->up_or_down = updown_tk1; + tk5->Ti = t_tk1; + + break; + + default: break; + } + } +} + + + + +// #pragma CODE_SECTION(detect_region,".v_24pwm_run"); +int detect_region(_iq k, _iq teta) +{ + volatile _iq x,y; + volatile int reg=0; + + x = _IQmpy(k,_IQcos(teta)); + y = _IQmpy(k,_IQsin(teta)); + + if (y>=CONST_IQ_05) reg=4; + else if (y < (CONST_IQ_1 - _IQmpy(x,SQRT3))) reg = 1; + else if (y < (_IQmpy(x,SQRT3) - CONST_IQ_1)) reg = 2; + else reg = 3; + + return reg; +} + + + + +// #pragma CODE_SECTION(detect_sec,".v_24pwm_run"); +int detect_sec(_iq teta) +{ + volatile _iq sector; + volatile int sectorint; + + sector = _IQdiv(teta,CONST_IQ_PI3); + sectorint = (sector >> 24) + 1; + + if (sectorint > 6) sectorint-=6; + + return sectorint; +} + + +#define nSIN_t(k,t) _IQmpy(k,_IQsin(t)) + +#define nSIN_p3pt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3+t)) + +#define nSIN_p3mt(k,t) _IQmpy(k,_IQsin(CONST_IQ_PI3-t)) + +#define nSIN_tmp3(k,t) _IQmpy(k,_IQsin(t-CONST_IQ_PI3)) + +//k - (Uzad) +//teta - +//region - +/* + * iq_tt0 - time of vectors op, oo, on + * iq_tt1 - time of vectors ap, an + * iq_tt2 - time of vectors bp, bn + * iq_tt3 - time of vector c + * iq_tt4 - time of vector a + * iq_tt5 - time of vector b + */ +// #pragma CODE_SECTION(calc_t_abc,".v_24pwm_run"); +void calc_t_abc(_iq k, _iq teta, int region, _iq *iq_tt0, _iq *iq_tt1, _iq *iq_tt2, _iq *iq_tt3, _iq *iq_tt4, _iq *iq_tt5) +{ + switch(region) + { + case 1 : + *iq_tt0 = CONST_IQ_05 - nSIN_p3pt(k,teta); + *iq_tt1 = nSIN_p3mt(k,teta); + *iq_tt2 = nSIN_t(k,teta); + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 2 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt2 = 0; + *iq_tt3 = nSIN_t(k,teta); + *iq_tt4 = nSIN_p3mt(k,teta) - CONST_IQ_05; + *iq_tt5 = 0; + break; + + case 3 : + *iq_tt0 = 0; + *iq_tt1 = CONST_IQ_05 - nSIN_t(k,teta); + *iq_tt2 = CONST_IQ_05 - nSIN_p3mt(k,teta); + *iq_tt3 = nSIN_p3pt(k,teta) - CONST_IQ_05; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + + case 4 : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = CONST_IQ_1 - nSIN_p3pt(k,teta); + *iq_tt3 = nSIN_p3mt(k,teta); + *iq_tt4 = 0; + *iq_tt5 = nSIN_t(k,teta) - CONST_IQ_05; + break; + + default : + *iq_tt0 = 0; + *iq_tt1 = 0; + *iq_tt2 = 0; + *iq_tt3 = 0; + *iq_tt4 = 0; + *iq_tt5 = 0; + break; + } + + return; +} + +//sector +//region +//iq_ttt0 - iq_ttt5 - times from calc_t_abs +//delta_t - +//number_sv - +//iqIa, iqIb, iqIc +// #pragma CODE_SECTION(calc_arr_tph, ".v_24pwm_run"); +void calc_arr_tph(int sector,int region, _iq iq_ttt0, _iq iq_ttt1, _iq iq_ttt2, _iq iq_ttt3, _iq iq_ttt4, + _iq iq_ttt5, _iq delta_t, unsigned int number_sv, + _iq iqIa, _iq iqIb, _iq iqIc) +{ + _iq iq_var1 = 0; + _iq iqIx, iqIy, iqIz; + _iq iq_alfa_1_p = CONST_IQ_05, iq_alfa_1_n = CONST_IQ_05, iq_alfa_2_n = CONST_IQ_05, iq_alfa_2_p = CONST_IQ_05; + _iq iq_alfa = 0; +// _iq iqIa, iqIb, iqIc; + _iq iq_mpy1 = 0; + _iq iq_mpy3 = 0; + _iq summ = 0; + + + switch (sector) + { + case 1: + iqIx = iqIc; + iqIy = iqIa; + iqIz = iqIb; + + break; + case 2: + + iqIx = iqIb; + iqIy = iqIa; + iqIz = iqIc; + + break; + case 3: + + iqIx = iqIb; + iqIy = iqIc; + iqIz = iqIa; + + break; + case 4: + + iqIx = iqIa; + iqIy = iqIc; + iqIz = iqIb; + + break; + case 5: + + iqIx = iqIa; + iqIy = iqIb; + iqIz = iqIc; + + break; + case 6: + + iqIx = iqIc; + iqIy = iqIb; + iqIz = iqIa; + + break; + default: + + iqIx = 0; + iqIy = 0; + iqIz = 0; + + break; + } + + if (region == 1) + { +// if (delta_t != 0) //��������� ���������� //��������� ����������� +// { +// iq_alfa = _IQsat((CONST_IQ_05 - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + + //if (delta_t < 0) + //{ + //iq_alfa = IQ_ALFA_SATURATION1; + //} + //else + //{ + //iq_alfa = IQ_ALFA_SATURATION2; + //} +// } +// else + { + iq_alfa = CONST_IQ_05; + } + } + else + { + iq_mpy1 = _IQmpy(_IQabs(iqIx),iq_ttt1)+_IQmpy(_IQabs(iqIy),iq_ttt2); + iq_mpy3 = _IQmpy(iqIz,iq_ttt3); + + summ = _IQdiv((iq_mpy3),(iq_mpy1)); + + //iq_alfa = _IQsat((_IQmpy(CONST_IQ_05,(CONST_IQ_1 + summ)) - _IQmpy(delta_t,IQ_KP_DELTA_T)),IQ_ALFA_SATURATION1,IQ_ALFA_SATURATION2); + iq_alfa = CONST_IQ_05; //test + } + + + if (iqIx >= 0) + { + iq_alfa_1_p = iq_alfa; + iq_alfa_1_n = CONST_IQ_1 - iq_alfa; + } + else + { + iq_alfa_1_p = CONST_IQ_1 - iq_alfa; + iq_alfa_1_n = iq_alfa; + } + + if (iqIy >= 0) + { + iq_alfa_2_p = CONST_IQ_1 - iq_alfa; + iq_alfa_2_n = iq_alfa; + } + else + { + iq_alfa_2_p = iq_alfa; + iq_alfa_2_n = CONST_IQ_1 - iq_alfa; + } + + + //if (number_sv == 2) + //{ + //logpar.log1 = (int16)(sector); + //logpar.log2 = (int16)(region); + //logpar.log3 = (int16)(_IQtoIQ15(iq_alfa)); + //logpar.log4 = (int16)(_IQtoIQ15(iq_alfa_1_p)); + //logpar.log5 = (int16)(_IQtoIQ15(iq_alfa_2_p)); + //logpar.log6 = (int16)(_IQtoIQ13(summ)); + //logpar.log3 = (int16)(_IQtoIQ14(iq_ttt0)); + //logpar.log4 = (int16)(_IQtoIQ14(iq_ttt1)); + //logpar.log5 = (int16)(_IQtoIQ14(iq_ttt2)); + //logpar.log6 = (int16)(_IQtoIQ14(iq_ttt3)); + //logpar.log7 = (int16)(_IQtoIQ14(iq_ttt4)); + //logpar.log8 = (int16)(_IQtoIQ14(iq_ttt5)); + //logpar.log10 = (int16)(_IQtoIQ15(delta_t1_struct.Up)); + //logpar.log11 = (int16)(_IQtoIQ15(delta_t1_struct.Ui)); + //logpar.log12 = (int16)(_IQtoIQ15(delta_t1_struct.Ud)); + //logpar.log13 = (int16)(_IQtoIQ15(iqIx)); + //logpar.log14 = (int16)(_IQtoIQ15(iqIy)); + //logpar.log15 = (int16)(_IQtoIQ15(iqIz)); + + //logpar.log12 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_p,iq_ttt2))); + //logpar.log13 = (int16)(_IQtoIQ15(_IQmpy(iq_alfa_2_n,iq_ttt2))); + //logpar.log14 = (int16)(_IQtoIQ15(delta_t)); + //} + //else + //logpar.log15 = (int16)(_IQtoIQ15(delta_t)); + +// if (region == 1) +// { +// if (f.Rele3 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } +// else +// { +// if (f.Down50 == 1) +// { +// iq_alfa_1_p = CONST_IQ_05; +// iq_alfa_2_p = CONST_IQ_05; +// iq_alfa_1_n = CONST_IQ_05; +// iq_alfa_2_n = CONST_IQ_05; +// } +// } + + switch (region) + { + case 1: + iq_var1 = _IQdiv(iq_ttt0,CONST_IQ_3); + + ar_tph[0] = iq_var1; + ar_tph[1] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[2] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[3] = iq_var1; + ar_tph[4] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[5] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[6] = iq_var1; + break; + + case 2: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = iq_ttt4; + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 3: + ar_tph[0] = _IQmpy(iq_alfa_1_n,iq_ttt1); + ar_tph[1] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[2] = iq_ttt3; + ar_tph[3] = _IQmpy(iq_alfa_1_p,iq_ttt1); + ar_tph[4] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + case 4: + ar_tph[0] = _IQmpy(iq_alfa_2_n,iq_ttt2); + ar_tph[1] = iq_ttt3; + ar_tph[2] = iq_ttt5; + ar_tph[3] = _IQmpy(iq_alfa_2_p,iq_ttt2); + ar_tph[4] = 0; + ar_tph[5] = 0; + ar_tph[6] = 0; + break; + + default : + break; + } + + +} + +/* + // Function is commented because of in project 222220 should not be large voltage diviation +// #pragma CODE_SECTION(calc_delta_t,".v_24pwm_run"); +_iq calc_delta_t(_iq delta_1, unsigned int number,int region) +{ + if(_IQabs(delta_1) > MAX_LEVEL_DELTA_T) + { + // ������ ���������� ConvErrors.m2.bit.Razbalans |= 1; + return 0; + } + + if (number == 1) + { + delta_t1_struct.Fdb = delta_1; + delta_t1_struct.calc(&delta_t1_struct); + + if (_IQabs(delta_t1_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t1_struct.Out; + } + else + { + delta_t2_struct.Fdb = delta_1; + delta_t2_struct.calc(&delta_t2_struct); + + if (_IQabs(delta_t2_struct.Out) <= INSENSITIVE_LEVEL_DELTA_T) return 0; + else return delta_t2_struct.Out; + } +} + +*/ +//#pragma CODE_SECTION(set_predel_dshim24,".fast_run2"); + +// #pragma CODE_SECTION(set_predel_dshim24_simple0,".v_24pwm_run"); +void set_predel_dshim24_simple0(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + if (T->Ti < dmin/2) + T->Ti = 0; + else + T->Ti = dmin; + + } else if (T->Ti >= (dmax - dmin)) { + T->Ti = (dmax - dmin); + } +} +// #pragma CODE_SECTION(set_predel_dshim24_simple1,".v_24pwm_run"); +void set_predel_dshim24_simple1(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti >= (dmax - dmin)) + { + if (T->Ti >= (dmax - dmin/2)) + T->Ti = dmax; + else + T->Ti = dmax-dmin; +// T->Ti = dmax; + } else if (T->Ti <= dmin) { + T->Ti = dmin; + } +} + + +// #pragma CODE_SECTION(set_predel_dshim24,".v_24pwm_run"); +void set_predel_dshim24(SVGEN_PWM24_TIME *T,int16 dmin,int16 dmax) +{ + //static unsigned int counter_pass = 0; + //static unsigned int summ = 0; + //int16 dshim24 = 0; + dmax++; //���� ������ �������� ������, ��� ���� �������� ����, ����� ������ ����������� + if (T->Ti < dmin) + { + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; + + T->impuls_lenght_min = T->impuls_lenght_min + T->Ti; + T->counter_pass_min++; + + if (T->counter_pass_min <= 3) + { + if (T->impuls_lenght_min <= dmin) + { + T->Ti = 0; + } + else + { +// T->Ti = dmin; //T->impuls_lenght_min; +// T->impuls_lenght_min -= dmin;// = 0; + T->Ti = T->impuls_lenght_min; + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; +// if (T->impuls_lenght_min < 0) { +// T->counter_pass_min = 0; +// T->impuls_lenght_min = 0; +// } else { +// T->counter_pass_min -= 1; +// } + } + } + else + { + T->counter_pass_min = 1; + T->impuls_lenght_min = T->Ti; + T->Ti = 0; + } + } + else + { + T->impuls_lenght_min = 0; + T->counter_pass_min = 0; + +// if (T->Ti > (dmax - dmin)) +// { +// dshim = dmax; +// } +// else +// { +// dshim = T->Ti; +// } + + if (T->Ti >= (dmax - dmin)) + { + T->impuls_lenght_max = T->impuls_lenght_max + (dmax - T->Ti - 1); + T->counter_pass_max++; + + if (T->counter_pass_max <= 3) + { + if (T->impuls_lenght_max <= dmin) + { + T->Ti = dmax; + } + else + { +// T->Ti = dmax - dmin; //T->impuls_lenght_max; +// T->impuls_lenght_max -= dmin;// = 0; + T->Ti = dmax - T->impuls_lenght_max; + T->impuls_lenght_max = 0; + T->counter_pass_max = 0; +// if (T->impuls_lenght_max < 0) { +// T->impuls_lenght_max = 0; +// T->counter_pass_max = 0; +// } else { +// T->counter_pass_max -= 1; +// } + } + } + else + { + T->counter_pass_max = 1; + T->impuls_lenght_max = dmax - T->Ti; + T->Ti = dmax; + } + } + else + { + T->counter_pass_max = 0; + T->impuls_lenght_max = 0; + } + } + + //return dshim24; +} + + + +void init_alpha_pwm24(int xFreq) +{ + xFreq = xFreq + 1; + + svgen_pwm24_1.number_svgen = 1; + svgen_pwm24_2.number_svgen = 2; + + //pidCur_Kp = _IQ(PID_KP_DELTA_KOMP_I); + //pidCur_Ki = _IQ(PID_KI_DELTA_KOMP_I); + +// svgen_pwm24_1.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_1.saw_direct.all = xpwm_time.saw_direct.all & 0x3f; + svgen_pwm24_1.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_1.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_1.Tclosed_high = xpwm_time.Tclosed_high; + +// svgen_pwm24_2.prev_level = V_PWM24_PREV_PWM_CLOSE; + svgen_pwm24_2.saw_direct.all = (xpwm_time.saw_direct.all >> 6) & 0x3f; + svgen_pwm24_2.Tclosed_saw_direct_0 = xpwm_time.Tclosed_saw_direct_0;// xpwm_time.Tclosed_high;//var_freq_pwm_xtics + 1; + svgen_pwm24_2.Tclosed_saw_direct_1 = xpwm_time.Tclosed_saw_direct_1; + svgen_pwm24_2.Tclosed_high = xpwm_time.Tclosed_high; + + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/FREQ_PWM/2); + + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; + + // 30 + svgen_pwm24_1.Alpha = 0; //winding_displacement; + svgen_pwm24_2.Alpha = -winding_displacement; + + svgen_pwm24_1.delta_t = 0; + svgen_pwm24_2.delta_t = 0; +} + +/* +void init_freq_array(void) +{ + unsigned int i = 0; + //unsigned int j = 0; + int var1 = 0; + + var1 = 32767 / (FREQ_PWM_MAX - FREQ_PWM_MIN); + + for (i = 0; i < COUNT_VAR_FREQ; i++) + { + //j = rand() / 1023; + //freq_array[i] = array_optim_freq[j]; + //do + freq_array[i] = FREQ_PWM_MIN + (rand() / var1); + //while ((freq_array[i] < 945) && (freq_array[i] > 930)); + } + + //freq_array[0] = 991; + //freq_array[1] = 1430; +} +*/ + + +//#pragma CODE_SECTION(calc_freq_pwm,".v_24pwm_run"); +//#pragma CODE_SECTION(calc_freq_pwm,".fast_run"); +/*void calc_freq_pwm() +{ + static int prev_freq_pwm = 0; + static float pwm_period = 0; + static float var0 = 0; + //static int line = 0; + //static int i = 0; + static unsigned int proc_ticks = 1; + int var1 = 0; + //static int i = 0; + + if ((f.flag_change_pwm_freq == 1) && (f.flag_random_freq == 1)) + { + if (proc_ticks >= 1) + { + proc_ticks = 0; + + + if (line == 0) + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ + 1; + if (VAR_FREQ_PWM_HZ > FREQ_PWM_MAX) + { + VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + line = 1; + } + } + else + { + VAR_FREQ_PWM_HZ = VAR_FREQ_PWM_HZ - 1; + if (VAR_FREQ_PWM_HZ < FREQ_PWM) + { + VAR_FREQ_PWM_HZ = FREQ_PWM; + line = 0; + } + } + + + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //VAR_FREQ_PWM_HZ = freq_array[i]; + //i_led2_on_off(1); + + var1 = 32767 / (freq_pwm_max_hz - freq_pwm_min_hz); + VAR_FREQ_PWM_HZ = freq_pwm_min_hz + (rand() / var1); + + //i_led2_on_off(0); + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (VAR_FREQ_PWM_HZ > freq_pwm_max_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_max_hz; + } + else + { + if (VAR_FREQ_PWM_HZ < freq_pwm_min_hz) + { + VAR_FREQ_PWM_HZ = freq_pwm_min_hz; + } + } + //i++; + + //if (i >= COUNT_VAR_FREQ) + //{ + //i = 0; + //} + + } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //if (VAR_FREQ_PWM_HZ == FREQ_PWM_MIN) + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MAX; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM_MIN; + //} + + //if (f.Rele1 == 1) + //{ + //if (i == 0) + //{ + //VAR_FREQ_PWM_HZ = 1192;; + //i = 1; + //} + //else + //{ + //VAR_FREQ_PWM_HZ = 792; + //} + //} + //else + //{ + //i = 0; + //VAR_FREQ_PWM_HZ = 1192; + //} + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + } + //else + //{ + //VAR_FREQ_PWM_HZ = FREQ_PWM; + //} + + + if (prev_freq_pwm != VAR_FREQ_PWM_HZ) + { + prev_freq_pwm = VAR_FREQ_PWM_HZ; + FREQ_MAX = _IQ(2.0*PI*F_STATOR_MAX/VAR_FREQ_PWM_HZ); + + var0 = (float)VAR_FREQ_PWM_HZ; + //pwm_period = ((float64)HSPCLK) / ((float64)VAR_FREQ_PWM_HZ); + + pwm_period = HSPCLK / var0; + + pwm_period = pwm_period / 2.0; + + FREQ_PWM_XTICS = ((int) pwm_period) >> 3; + + XILINX_FREQ = 16777216/(FREQ_PWM_XTICS + 1); + + FLAG_CHANGE_FREQ_PWM = 1; + } + + proc_ticks++; +} +*/ + +void change_freq_pwm(_iq xFreq) { + svgen_pwm24_1.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/3750000 / xFreq / 2 /2);//��������������� ������� �� 2, �.�. 2 ���� ������� � ���������� �� ������ ��� + svgen_pwm24_2.FreqMax = _IQ(2.0*PI*F_STATOR_MAX/ 3750000 / xFreq / 2 /2); + + xFreq += 1; + svgen_pwm24_1.XilinxFreq = CONST_IQ_1/xFreq; + svgen_pwm24_2.XilinxFreq = CONST_IQ_1/xFreq; +} + +// #pragma CODE_SECTION(test_calc_pwm24_dq,".v_24pwm_run"); +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta) +{ + svgen_pwm24_1.Freq = 0; + svgen_pwm24_2.Freq = 0; + + svgen_pwm24_1.Gain = U_zad1; + svgen_pwm24_2.Gain = U_zad2; + + svgen_pwm24_1.Alpha = teta; + svgen_pwm24_2.Alpha = teta - winding_displacement; + + svgen_pwm24_1.delta_U = filter.iqU_1_fast - filter.iqU_2_fast; + svgen_pwm24_2.delta_U = filter.iqU_3_fast - filter.iqU_4_fast; + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + svgen_pwm24_1.delta_U = 0; + svgen_pwm24_2.delta_U = 0; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + svgen_pwm24_1.Ia = analog.iqIa1_1; + svgen_pwm24_1.Ib = analog.iqIb1_1; + svgen_pwm24_1.Ic = analog.iqIc1_1; + + svgen_pwm24_2.Ia = analog.iqIa2_1; + svgen_pwm24_2.Ib = analog.iqIb2_1; + svgen_pwm24_2.Ic = analog.iqIc2_1; + + svgen_pwm24_1.calc_dq(&svgen_pwm24_1); + svgen_pwm24_2.calc_dq(&svgen_pwm24_2); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + set_predel_dshim24(&svgen_pwm24_1.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_1.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_1.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Ta_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Ta_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tb_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tb_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + set_predel_dshim24(&svgen_pwm24_2.Tc_0,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + set_predel_dshim24(&svgen_pwm24_2.Tc_1,VAR_PERIOD_MIN_XTICS,VAR_FREQ_PWM_XTICS); + + +} + + +// #pragma CODE_SECTION(svgen_pwm24_calc,".v_24pwm_run"); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt) +{ + + if (vt->Alpha > CONST_IQ_2PI) + { + vt->Alpha -= CONST_IQ_2PI; + } + + if (vt->Alpha < 0) + { + vt->Alpha += CONST_IQ_2PI; + } + + + calc_time_one_tk(vt->Gain, vt->Alpha, vt->delta_U, vt->Ia, vt->Ib, vt->Ic, + vt->number_svgen, &vt->Ta_0, &vt->Ta_1,&vt->Tb_0, &vt->Tb_1,&vt->Tc_0, &vt->Tc_1); + + + vt->Ta_0.Ti = vt->Ta_0.Ti/vt->XilinxFreq; + vt->Ta_1.Ti = vt->Ta_1.Ti/vt->XilinxFreq; + + vt->Tb_0.Ti = vt->Tb_0.Ti/vt->XilinxFreq; + vt->Tb_1.Ti = vt->Tb_1.Ti/vt->XilinxFreq; + + vt->Tc_0.Ti = vt->Tc_0.Ti/vt->XilinxFreq; + vt->Tc_1.Ti = vt->Tc_1.Ti/vt->XilinxFreq; + +} + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Ta_1.Ti = 0; + + vt->Tb_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tb_1.Ti = 0; + + vt->Tc_0.Ti = VAR_FREQ_PWM_XTICS + 1; + vt->Tc_1.Ti = 0; +} + +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt) +{ + vt->Ta_0.Ti = 0; + vt->Ta_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tb_0.Ti = 0; + vt->Tb_1.Ti = VAR_FREQ_PWM_XTICS + 1; + + vt->Tc_0.Ti = 0; + vt->Tc_1.Ti = VAR_FREQ_PWM_XTICS + 1; +} diff --git a/Inu/Src2/main/v_pwm24.h b/Inu/Src2/main/v_pwm24.h new file mode 100644 index 0000000..ff83ca4 --- /dev/null +++ b/Inu/Src2/main/v_pwm24.h @@ -0,0 +1,190 @@ +#ifndef _V_PWM24_H +#define _V_PWM24_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "IQmathLib.h" +// #include "DSP281x_Device.h" +#include "word_structurs.h" +#include "svgen_dq.h" + +//#define COUNT_VAR_FREQ 400 + +//#define IQ_KP_DELTA_T 134217728//0.004 +//#define IQ_KP_DELTA_COMP_I 134217728//0.004 + +//#define PID_KP_DELTA_T 0.5//1//20//2//0.001//11.18 //0.036 //0.018 //0.18 //0.095 // PID Kp +//#define PID_KI_DELTA_T 0.000005//0.01 //0.08 // 0.008 // PID Ki +//#define PID_KD_DELTA_T 2//5//0.01 //0.08 // 0.008 // PID Ki +//#define PID_KC_DELTA_T 0.005 //0.09 // PID Kc + +//#define PID_KP_DELTA_KOMP_I 1//0.12//0.06//5//10 +//#define PID_KI_DELTA_KOMP_I 0.005//0//0.005//0.01 +//#define PID_KC_DELTA_KOMP_I 0.005//0//0.005//0.01 +//#define PID_KD_DELTA_KOMP_I 0//0//0.005//0.01 +//#define PID_KD_DELTA_T 0.0000 //*100 // PID Kd + + + +//#define DELTA_T_MAX 1258291//15099494//0.9//8388608//0.5//13421772//0.8 //8388608// 0.5//13421772 // 0.8 +//#define DELTA_T_MIN -1258291//-15099494//0.9//-8388608//-0.5//-13421772//0.8 //-8388608// -0.5//-13421772 // -0.8 + +//#define DELTA_KOMP_I_MAX 1258291//6//1677721//0.1//3355443//0.2//1677721//200 A//4194304// 500 A +//#define DELTA_KOMP_I_MIN -1258291//-6//-1677721//-0.1//-3355443//-0.2//-1677721//-200 A//-4194304// -500 A + + +//#define INSENSITIVE_LEVEL_DELTA_T 83886 //10 V//167772// 20V //335544//40 V//83886 //10 V//335544//40 V//58720//7V//167772// 20V //83886 //10 V +//#define MAX_LEVEL_DELTA_T 1258291//150V//1677721 //200v//2516582//300 V//4194304//500 V//2516582 // 838860 //100 V + + +typedef struct { _iq Ti; // Output: reference phase-a switching function (pu) + int up_or_down; // Output: reference phase-b switching function (pu) + int impuls_lenght_max; + int impuls_lenght_min; + int counter_pass_max; + int counter_pass_min; + } SVGEN_PWM24_TIME; + + +typedef struct { + _iq Gain; // Input: reference gain voltage (pu) + //_iq Offset; // Input: reference offset voltage (pu) + _iq Freq; // Input: reference frequency (pu) + _iq FreqMax; // Parameter: Maximum step angle = 6*base_freq*T (pu) + _iq Alpha; // History: Sector angle (pu) + + _iq delta_U; + _iq delta_t; + int XilinxFreq; // Xilinx freq in TIC + + unsigned int pwm_minimal_impuls_zero_minus; + unsigned int pwm_minimal_impuls_zero_plus; + + WORD_UINT2BITS_STRUCT saw_direct; + + int prev_level; // ���������� ��������� ����, ��� �������� �� middle ��� close � ������� + unsigned int Tclosed_high; + unsigned int Tclosed_saw_direct_0; + unsigned int Tclosed_saw_direct_1; + + _iq Ia; + _iq Ib; + _iq Ic; + unsigned int number_svgen; + SVGEN_PWM24_TIME Ta_0; // Output: reference phase-a switching function (pu) + SVGEN_PWM24_TIME Ta_1; // Output: reference phase-a switching function (pu) + SVGEN_PWM24_TIME Tb_0; // Output: reference phase-b switching function (pu) + SVGEN_PWM24_TIME Tb_1; // Output: reference phase-b switching function (pu) + SVGEN_PWM24_TIME Tc_0; // Output: reference phase-c switching function (pu) + SVGEN_PWM24_TIME Tc_1; // Output: reference phase-c switching function (pu) + void (*calc)(); // Pointer to calculation function + void (*calc_dq)(); // Pointer to calculation function which don`t calculate angle from freq +} SVGEN_PWM24; + +typedef SVGEN_PWM24 *SVGEN_PWM24_handle; + + +#define SVGEN_PWM24_TIME_DEFAULTS { 0,0,0,0 } + + +#define SVGEN_PWM24_DEFAULTS { 0,0,0,0,0,0,0,0,0, \ + {0}, 0,0,0,0,0,0,0,0,\ + SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS, \ + SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS,SVGEN_PWM24_TIME_DEFAULTS, \ + (void (*)(unsigned int))svgen_pwm24_calc, (void (*)(unsigned int))svgen_pwm24_calc_dq } + +// extern int ar_sa_a[3][4][7]; + +extern SVGEN_PWM24 svgen_pwm24_1; +extern SVGEN_PWM24 svgen_pwm24_2; + +extern SVGENDQ svgen_dq_1; +extern SVGENDQ svgen_dq_2; + +// extern _iq pidCur_Kp; +// extern _iq pidCur_Ki; + +// extern _iq iq_alfa_coef; + +// extern _iq iq_koef_mod_korrect_1; +// extern _iq iq_koef_mod_korrect_2; + +//extern int freq_array[COUNT_VAR_FREQ]; + +void svgen_pwm24_calc(SVGEN_PWM24 *vt); +void svgen_pwm24_calc_dq(SVGEN_PWM24 *vt); + +void init_alpha_pwm24(int xFreq); +void test_calc_pwm24(_iq uz1, _iq uz2, _iq fz1/*, _iq fz2, int revers*/); +void calc_arr_tph(int sector,int region, _iq iq_ttt0, _iq iq_ttt1, + _iq iq_ttt2, _iq iq_ttt3, _iq iq_ttt4, _iq iq_ttt5, _iq delta_t, unsigned int number_sv, + _iq iqIa, _iq iqIb, _iq iqIc); +_iq calc_delta_t(_iq delta_1, unsigned int number,int region); + +//void change_freq_pwm(_iq FreqMax, int freq_pwm_xtics, _iq XilinxFreq); +void change_freq_pwm(_iq freq_pwm_xtics); + +//void calc_freq_pwm(); + +void calc_time_one_tk(_iq gain, _iq teta, _iq delta_U, + _iq Ia, _iq Ib, _iq Ic, + unsigned int number, + SVGEN_PWM24_TIME *tk0, + SVGEN_PWM24_TIME *tk1, + SVGEN_PWM24_TIME *tk2, + SVGEN_PWM24_TIME *tk3, + SVGEN_PWM24_TIME *tk4, + SVGEN_PWM24_TIME *tk5); + +void test_calc_pwm24_dq(_iq U_zad1, _iq U_zad2,_iq teta); + +void svgen_set_time_keys_closed(SVGEN_PWM24 *vt); +void svgen_set_time_middle_keys_open(SVGEN_PWM24 *vt); + + + +void InitVariablesSvgen(unsigned int freq); +//void init_alpha(void); +_iq correct_balance_uzpt_pwm24(_iq Tinput, _iq Kplus); +void recalc_time_pwm_minimal_2_xilinx_pwm24_l(SVGEN_PWM24 *pwm24, + _iq *T0, _iq *T1, + _iq timpuls_corr ); +void test_calc_simple_dq_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2, _iq Uzad_max); +void test_calc_dq_pwm24(_iq Ud, _iq Uq, _iq Ud2, _iq Uq2, _iq tetta,_iq Uzad_max); +//void test_calc_simple_uf_pwm24(_iq uz1, _iq uz2, _iq fz1, _iq fz2,_iq Uzad_max); + +//void init_freq_array(void); + +typedef union { + unsigned int all; + struct { + unsigned int k0; + unsigned int k1; + unsigned int k2; + unsigned int k3; + unsigned int k4; + unsigned int k5; + unsigned int k6; + unsigned int k7; + unsigned int k8; + unsigned int k9; + unsigned int k10; + unsigned int k11; + unsigned int k12; + unsigned int k13; + unsigned int k14; + unsigned int k15; + }bit; +} UP_OR_DOWN; + +extern UP_OR_DOWN up_down; +extern _iq winding_displacement; + + +#ifdef __cplusplus + } +#endif + +#endif /* _V_PWM24_H */ diff --git a/Inu/Src2/main/vector.h b/Inu/Src2/main/vector.h new file mode 100644 index 0000000..5245af8 --- /dev/null +++ b/Inu/Src2/main/vector.h @@ -0,0 +1,256 @@ +/* + ???? ??? (?) 2006 ?. + + Processor: TMS320C32 + + Filename: vector_troll.h + + ??????? ?????????? ?????????y + + Edit date: 04-12-02 + + Function: + + Revisions: +*/ + + +#ifndef _VECTOR_SEV +#define _VECTOR_SEV + + +#ifdef __cplusplus + extern "C" { +#endif + + +#include "IQmathLib.h" + + +typedef struct +{ + float W; /* ������� ������� ������ */ + float Angle; /* ���� ��������� ������ */ + float Phi; /* �������� � ���� ������ */ + float k; /* �����. ��������� */ + float k1; /* �����. ��������� */ + float k2; /* �����. ��������� */ + float f; /* ������� ������� */ + + _iq iqk; + _iq iqk1; + _iq iqk2; + _iq iqf; + + + +} WINDING; + + + + +typedef struct +{ + unsigned int Prepare; + unsigned int terminal_prepare; + unsigned int prepareSVU; + unsigned int Test_Lamps; + unsigned int fault; + + unsigned int prevGo; + unsigned int Go; + unsigned int Stop; + unsigned int Mode; + unsigned int Revers; + unsigned int Is_Blocked; + + unsigned int Ready1; + unsigned int Ready2; + unsigned int Discharge; + unsigned int is_charging; + + unsigned int ErrorChannel1; + unsigned int ErrorChannel2; + unsigned int FaultChannel1; + unsigned int FaultChannel2; + + unsigned int secondPChState; + + unsigned int Set_power; + + unsigned int Impuls; + + unsigned int Obmotka1; + unsigned int Obmotka2; +// unsigned int Down50; + + unsigned int Power_over_Nominal; + unsigned int I_over_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ???? + unsigned int I_over_1_6_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ???? + unsigned int I_over_1_8_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ???? + unsigned int Moment_over_1_6_noninal; //????????? ?????? ?????? ? ??????????? ???????????? ??????? ? 1.6 ??? + unsigned int Moment_over_1_8_nominal; //????????? ?????? ?????? ? ??????????? ???????????? ??????? ? 1.8 ??? + unsigned int DownToNominal; + unsigned int DownToNominalCurrent; + unsigned int DownToNominalMoment; + unsigned int DownTemperature; + unsigned int DownToNominalVoltage; + unsigned int DownToNominalFreq; + unsigned int nominal_I_exceeded_counter; //??????? ??? ????????? ??????????? ??? + unsigned int nominal_M_exceeded_counter; //??????? ??? ????????? ??????????? ?????? +// unsigned int I_zpt_over_nominal; + + unsigned int Up50; + unsigned int Ciclelog; + unsigned int pidD_set; + unsigned int Bpsi; + unsigned int Piregul1; + unsigned int Piregul2; + unsigned int Startstoplog; + unsigned int Setspeed; + + unsigned int BWC_turn_ON; + unsigned int BWC_Auto_mode; + + unsigned int Setsdvigfaza; + unsigned int Off_piregul; + + unsigned int Restart; + unsigned int stop_Log; + + unsigned int Work_net; + unsigned int Mask_impuls; + unsigned int Impuls_width; + + + unsigned int Work; + + unsigned int Auto; + + unsigned int Uzad; + unsigned int Umin; + + unsigned int RScount; + unsigned int vector_run; + unsigned int test_all_run; + + unsigned int decr_mzz_temp; +// unsigned int flag_decr_mzz_temp; + + unsigned int flag_Break_Resistor_Error; + unsigned int flag_local_control; //1 - local + unsigned int flag_leading; //������� �� ������ + unsigned int flag_second_leading; //������ �� ������ + unsigned int read_task_from_optical_bus; + unsigned int sync_rotor_from_optical_bus; + unsigned int sync_Iq_from_optical_bus; + unsigned int flag_distance; + unsigned int flag_second_PCH; + unsigned int leftShaft; + unsigned int inverter_number; + unsigned int ice_movement_limit; + unsigned int flag_batery_charged; + unsigned int flag_Pump_Is_On; //Gidropodpor + unsigned int flag_turn_On_Pump; + unsigned int flag_UMP_blocked; + unsigned int power_units_doors_closed; + unsigned int power_units_doors_locked; + + unsigned int flag_decr_mzz_power; + + unsigned int rotor_stopped; + + float decr_mzz_power; + _iq iq_decr_mzz_power; + + _iq iq_decr_mzz_voltage; + + float fzad; + float kzad; + float kzad_plus; + float fzad_provorot; + float Sdvigfaza; + + float mzz_zad; + float fr_zad; + float Power; + float p_zad; + + +// _iq iq_bpsi_zad; + _iq iq_mzz_zad; + _iq iq_fzad_provorot; + _iq iq_fzad; + _iq iq_p_zad; + _iq iq_p_rampa; + _iq iq_p_zad_electric; + _iq iq_p_limit_zad; + int p_limit_zad; //����������� �������� � �������� ������ + + unsigned int flag_Enable_Prepare; + + union { + unsigned int all; + struct { + unsigned int BV1: 1; + unsigned int BV2: 1; + unsigned int BI1: 1; + unsigned int BI2: 1; + unsigned int UMU: 1; + unsigned int UKSI: 1; + unsigned int reserved: 10; + } UKSS; + } status_ready; + + unsigned int On_Power_QTV; + unsigned int Power_QTV_is_On; + + unsigned int RS_MPU_ERROR; + unsigned int MPU_Ready; + + unsigned int flag_tormog; + + int special_test_from_mpu; + + int MessageToCan1; + int MessageToCan2; + int flag_change_pwm_freq; + int flag_random_freq; + long tmp; + + unsigned int rele1; + + _iq cosinusTerminal; + _iq cosinusTerminalSquared; +// _iq cosinusFiOut; + + int setCosTerminal; + int setTettaKt; + + //Sync vals + int pwm_freq_plus_minus_zero; + int disable_sync; + int sync_ready; + int flag_sync_vipr1_vipr2; + int level_find_sync_zero; + int delta_error_sync; + int delta_capnum; + int count_error_sync; + int capnum0; + int PWMcounterVal; + + int build_version; + +} FLAG; + + +extern FLAG f; +extern WINDING a; + +#ifdef __cplusplus + } +#endif + +#endif /* _VECTOR_SEV */ + + diff --git a/Inu/Src2/main/word_structurs.h b/Inu/Src2/main/word_structurs.h new file mode 100644 index 0000000..d94d243 --- /dev/null +++ b/Inu/Src2/main/word_structurs.h @@ -0,0 +1,64 @@ +/* + * word_structurs.h + * + * Created on: 5 ���. 2020 �. + * Author: Yura + */ + +#ifndef SRC_MYLIBS_WORD_STRUCTURS_H_ +#define SRC_MYLIBS_WORD_STRUCTURS_H_ + +//////////////////////////////////////////////////////////////////////////////// +typedef union +{ + struct + { + unsigned int bit0: 1; + unsigned int bit1: 1; + unsigned int bit2: 1; + unsigned int bit3: 1; + unsigned int bit4: 1; + unsigned int bit5: 1; + unsigned int bit6: 1; + unsigned int bit7: 1; + unsigned int bit8: 1; + unsigned int bit9: 1; + unsigned int bit10: 1; + unsigned int bit11: 1; + unsigned int bit12: 1; + unsigned int bit13: 1; + unsigned int bit14: 1; + unsigned int bit15: 1; + } bits; // ���������� �������� ������� ������� + int all; // ���������� �������� ������� ������ +} WORD_INT2BITS_STRUCT; // ��������� ���� ������ � ��������� �������� +////// +//////////////////////////////////////////////////////////////////////////////// +typedef union +{ + struct + { + unsigned int bit0: 1; + unsigned int bit1: 1; + unsigned int bit2: 1; + unsigned int bit3: 1; + unsigned int bit4: 1; + unsigned int bit5: 1; + unsigned int bit6: 1; + unsigned int bit7: 1; + unsigned int bit8: 1; + unsigned int bit9: 1; + unsigned int bit10: 1; + unsigned int bit11: 1; + unsigned int bit12: 1; + unsigned int bit13: 1; + unsigned int bit14: 1; + unsigned int bit15: 1; + } bits; // ���������� �������� ������� ������� + unsigned int all; // ���������� �������� ������� ������ +} WORD_UINT2BITS_STRUCT; // ��������� ���� ������ � ��������� �������� +////// + + + +#endif /* SRC_MYLIBS_WORD_STRUCTURS_H_ */ diff --git a/Inu/Src2/main/xp_write_xpwm_time.c b/Inu/Src2/main/xp_write_xpwm_time.c new file mode 100644 index 0000000..093b88c --- /dev/null +++ b/Inu/Src2/main/xp_write_xpwm_time.c @@ -0,0 +1,361 @@ +/* + * xp_write_xpwm_time.c + * + * Created on: 03 àïð. 2018 ã. + * Author: stud + */ + +#include "xp_write_xpwm_time.h" +// #include "MemoryFunctions.h" +// #include "Spartan2E_Adr.h" +// #include "PWMTMSHandle.h" + +#include "def.h" + + +// #pragma DATA_SECTION(xpwm_time,".fast_vars1"); +XPWM_TIME xpwm_time = DEFAULT_XPWM_TIME; + +#define set_default_tclosed(k,b) {if (b) k = p->Tclosed_saw_direct_1; else k = p->Tclosed_saw_direct_0;} + +void initXpwmTimeStructure(XPWM_TIME *p) { + p->Ta0_0 = p->Tclosed_0; + p->Ta0_1 = p->Tclosed_1; + p->Tb0_0 = p->Tclosed_0; + p->Tb0_1 = p->Tclosed_1; + p->Tc0_0 = p->Tclosed_0; + p->Tc0_1 = p->Tclosed_1; + + p->Ta1_0 = p->Tclosed_0; + p->Ta1_1 = p->Tclosed_1; + p->Tb1_0 = p->Tclosed_0; + p->Tb1_1 = p->Tclosed_1; + p->Tc1_0 = p->Tclosed_0; + p->Tc1_1 = p->Tclosed_1; + + p->Tbr0_0 = 0; + p->Tbr0_1 = 0; + p->Tbr1_0 = 0; + p->Tbr1_1 = 0; +} + + +// ������� �������� ����� ��������������� � ������� +void xpwm_write_1_2_winding_break_times_16_lines(XPWM_TIME *p) { + +} + +// void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p) { + +// } +/* +//#pragma CODE_SECTION(xpwm_write_1_2_winding_break_times_16_lines,".fast_run1"); +void xpwm_write_1_2_winding_break_times_16_lines(XPWM_TIME *p) +{ + if(!(ReadMemory(ADR_ERRORS_TOTAL_INFO))) + { + WriteMemory(ADR_PWM_KEY_NUMBER, 0); + WriteMemory(ADR_PWM_TIMING, p->Ta0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 1); + WriteMemory(ADR_PWM_TIMING, p->Ta0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 2); + WriteMemory(ADR_PWM_TIMING, p->Tb0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 3); + WriteMemory(ADR_PWM_TIMING, p->Tb0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 4); + WriteMemory(ADR_PWM_TIMING, p->Tc0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 5); + WriteMemory(ADR_PWM_TIMING, p->Tc0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 6); + WriteMemory(ADR_PWM_TIMING, p->Ta1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 7); + WriteMemory(ADR_PWM_TIMING, p->Ta1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 8); + WriteMemory(ADR_PWM_TIMING, p->Tb1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 9); + WriteMemory(ADR_PWM_TIMING, p->Tb1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 10); + WriteMemory(ADR_PWM_TIMING, p->Tc1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 11); + WriteMemory(ADR_PWM_TIMING, p->Tc1_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 12); + WriteMemory(ADR_PWM_TIMING, p->Tbr0_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 13); + WriteMemory(ADR_PWM_TIMING, p->Tbr0_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 14); + WriteMemory(ADR_PWM_TIMING, p->Tbr1_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 15); + WriteMemory(ADR_PWM_TIMING, p->Tbr1_1); + } + else + { + WriteMemory(ADR_PWM_KEY_NUMBER, 0); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 1); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 2); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 3); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 4); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 5); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 6); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 7); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 8); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 9); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 10); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_0); + WriteMemory(ADR_PWM_KEY_NUMBER, 11); + WriteMemory(ADR_PWM_TIMING, p->Tclosed_1); + WriteMemory(ADR_PWM_KEY_NUMBER, 12); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 13); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 14); + WriteMemory(ADR_PWM_TIMING, 0); + WriteMemory(ADR_PWM_KEY_NUMBER, 15); + WriteMemory(ADR_PWM_TIMING, 0); + } +} +*/ +// #pragma CODE_SECTION(xpwm_write_1_2_winding_break_times_16_lines_split_eages,".fast_run1"); +void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p) +{ + // if (!(i_ReadMemory(ADR_ERRORS_TOTAL_INFO))) + { +//a + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit0==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta0_0); + EPwm2Regs.CMPA.half.CMPA = p->Ta0_0; + } + + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit1 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit1==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta0_1); + EPwm1Regs.CMPA.half.CMPA = p->Ta0_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit2 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit2==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb0_0); + EPwm4Regs.CMPA.half.CMPA = p->Tb0_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit3 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit3==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb0_1); + EPwm3Regs.CMPA.half.CMPA = p->Tb0_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit4 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit4==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc0_0); + EPwm6Regs.CMPA.half.CMPA = p->Tc0_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit5 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit5==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc0_1); + EPwm5Regs.CMPA.half.CMPA = p->Tc0_1; + } +//b + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit6 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit6==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta1_0); + EPwm8Regs.CMPA.half.CMPA = p->Ta1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit7 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit7==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Ta1_1); + EPwm7Regs.CMPA.half.CMPA = p->Ta1_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit8 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit8==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb1_0); + EPwm10Regs.CMPA.half.CMPA = p->Tb1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit9 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit9==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tb1_1); + EPwm9Regs.CMPA.half.CMPA = p->Tb1_1; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit10 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit10==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc1_0); + EPwm12Regs.CMPA.half.CMPA = p->Tc1_0; + } + if ((p->mode_reload==PWM_MODE_RELOAD_FORCE) + || (p->saw_direct.bits.bit11 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_HIGH) + || (p->saw_direct.bits.bit11==0 && p->mode_reload==PWM_MODE_RELOAD_LEVEL_LOW) ) + { + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tc1_1); + EPwm11Regs.CMPA.half.CMPA = p->Tc1_1; + } + +//br1 br2 + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr0_0); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr0_1); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_PLUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr1_0); + // i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_MINUS); + // i_WriteMemory(ADR_PWM_TIMING, p->Tbr1_1); + } +// else +// { +// // hard_stop_x24_pwm_all(); +// // stop_pwm(); +// xpwm_write_zero_winding_break_times_16_lines_split_eages(p); +// } +} +/* +// #pragma CODE_SECTION(xpwm_write_zero_1,".fast_run2"); +void xpwm_write_zero_1(XPWM_TIME *p) +{ + unsigned int tclose; + + //a + set_default_tclosed(tclose, p->saw_direct.bits.bit0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit1); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta0_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit2); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit3); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb0_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit4); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc0_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit5); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc0_1 = tclose; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_2,".fast_run1"); +void xpwm_write_zero_2(XPWM_TIME *p) +{ + unsigned int tclose; + +//b + set_default_tclosed(tclose, p->saw_direct.bits.bit6); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit7); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_A2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Ta1_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit8); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit9); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_B2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tb1_1 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit10); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc1_0 = tclose; + + set_default_tclosed(tclose, p->saw_direct.bits.bit11); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_C2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, tclose); + p->Tc1_1 = tclose; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_break_1,".fast_run2"); +void xpwm_write_zero_break_1(XPWM_TIME *p) +{ + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_PLUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR1_MINUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + + p->Tbr0_0 = 0; + p->Tbr0_1 = 0; + +} + +// #pragma CODE_SECTION(xpwm_write_zero_break_2,".fast_run2"); +void xpwm_write_zero_break_2(XPWM_TIME *p) +{ + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_PLUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + i_WriteMemory(ADR_PWM_KEY_NUMBER, PWM_KEY_NUMBER_BR2_MINUS); + i_WriteMemory(ADR_PWM_TIMING, 0); + + p->Tbr1_0 = 0; + p->Tbr1_1 = 0; +} + +// #pragma CODE_SECTION(xpwm_write_zero_winding_break_times_16_lines_split_eages,".fast_run2"); +void xpwm_write_zero_winding_break_times_16_lines_split_eages(XPWM_TIME *p) +{ + xpwm_write_zero_1(p); + xpwm_write_zero_2(p); + xpwm_write_zero_break_1(p); + xpwm_write_zero_break_2(p); +} + +*/ + diff --git a/Inu/Src2/main/xp_write_xpwm_time.h b/Inu/Src2/main/xp_write_xpwm_time.h new file mode 100644 index 0000000..5e1159d --- /dev/null +++ b/Inu/Src2/main/xp_write_xpwm_time.h @@ -0,0 +1,183 @@ +/* + * xp_write_xpwm_time.h + * + * Created on: 03 ���. 2018 �. + * Author: stud + */ + +#ifndef XP_WRITE_TIME_H_ +#define XP_WRITE_TIME_H_ + + +#include "word_structurs.h" + + + +#define PWM_ERROR_LEVEL_INTERRUPT 0 // �� ���������� ��� ��, ������!!! +#define PWM_LOW_LEVEL_INTERRUPT 1 // �� ����� ���� +#define PWM_HIGH_LEVEL_INTERRUPT 2 // �� ������ ���� + + +#define PWM_MODE_RELOAD_FORCE 0 // ��������� ��� �������� +#define PWM_MODE_RELOAD_LEVEL_LOW 1 // ��������� �������� ��� ���� ����, ��� saw_direct=1 +#define PWM_MODE_RELOAD_LEVEL_HIGH 2 // ��������� �������� ��� ����� ����, ��� saw_direct=0 + + + + + +#define PWM_KEY_NUMBER_A1_PLUS 0 +#define PWM_KEY_NUMBER_A1_MINUS 1 +#define PWM_KEY_NUMBER_B1_PLUS 2 +#define PWM_KEY_NUMBER_B1_MINUS 3 +#define PWM_KEY_NUMBER_C1_PLUS 4 +#define PWM_KEY_NUMBER_C1_MINUS 5 + +#define PWM_KEY_NUMBER_A2_PLUS 6 +#define PWM_KEY_NUMBER_A2_MINUS 7 +#define PWM_KEY_NUMBER_B2_PLUS 8 +#define PWM_KEY_NUMBER_B2_MINUS 9 +#define PWM_KEY_NUMBER_C2_PLUS 10 +#define PWM_KEY_NUMBER_C2_MINUS 11 + +#define PWM_KEY_NUMBER_BR1_PLUS 12 +#define PWM_KEY_NUMBER_BR1_MINUS 13 + +#define PWM_KEY_NUMBER_BR2_PLUS 14 +#define PWM_KEY_NUMBER_BR2_MINUS 15 + +////////////////////////////////////////////////////////////////////// +#define ENABLE_PWM_BREAK_ALL 0x0fff +#define ENABLE_PWM_BREAK_1 0xcfff +#define ENABLE_PWM_BREAK_2 0x3fff + +#define ENABLE_PWM_1 0xffc0 +#define ENABLE_PWM_2 0xf03f +#define ENABLE_PWM_1_2 0xf000 + +#define ENABLE_PWM_ALL 0x0000 + +// +#define DISABLE_PWM_BREAK_ALL 0xf000 +#define DISABLE_PWM_BREAK_1 0x3000 +#define DISABLE_PWM_BREAK_2 0xc000 + +#define DISABLE_PWM_1 0x003f +#define DISABLE_PWM_2 0x0fc0 +#define DISABLE_PWM_1_2 0x0fff + +#define DISABLE_PWM_ALL 0xffff + +/// +#define DISABLE_PWM_A1 0x0003 +#define DISABLE_PWM_B1 0x000c +#define DISABLE_PWM_C1 0x0030 + +#define DISABLE_PWM_A2 0x00c0 +#define DISABLE_PWM_B2 0x0300 +#define DISABLE_PWM_C2 0x0c00 +// +////////////////////////////////////////////////////////////////////// +/* + * PWM - Start Stop + * (15) - Soft start-stop m0de 1- soft mode enabled, 0 -disabled. ���� ������ ����� ������ ���������, �� ��� ������ + * ������� ����(0)-������� = 0, ������ ����������� � ������ �������� ���� (����� ������ ������� ���������)., ���� ���- �����. + * ���������� ����������� �����- ��� soft mode ����� ����������� � ������ ��������. + * �����! ��� ������������ ��������� ���� ������ ������� ������ ���� ����� ����. + * (0) - 1 -start, 0 - stop + */ +#define PWM_START_SOFT 0x8001 +#define PWM_START_HARD 0x0001 + +#define PWM_STOP_SOFT 0x8000 +#define PWM_STOP_HARD 0x0000 + +///////////////////////////////////// + + + + +///////////////////////////////////// +typedef struct +{ + // Winding 1 times + unsigned int Ta0_0; + unsigned int Ta0_1; + unsigned int Tb0_0; + unsigned int Tb0_1; + unsigned int Tc0_0; + unsigned int Tc0_1; + // Winding 2 times + unsigned int Ta1_0; + unsigned int Ta1_1; + unsigned int Tb1_0; + unsigned int Tb1_1; + unsigned int Tc1_0; + unsigned int Tc1_1; + // Break transistors + unsigned int Tbr0_0; + unsigned int Tbr0_1; + unsigned int Tbr1_0; + unsigned int Tbr1_1; + //Level transistors closed + unsigned int Tclosed_0; + unsigned int Tclosed_1; + unsigned int Tclosed_high; + unsigned int pwm_tics; + unsigned int inited; + unsigned int freq_pwm; + unsigned int Tclosed_saw_direct_0; + unsigned int Tclosed_saw_direct_1; + unsigned int current_period; + unsigned int where_interrupt; + unsigned int mode_reload; + unsigned int one_or_two_interrupts_run; + WORD_UINT2BITS_STRUCT saw_direct; + void (*write_1_2_winding_break_times)(); + void (*write_1_2_winding_break_times_split)(); +} XPWM_TIME; + +#define DEFAULT_XPWM_TIME {0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,0,0,0,0, {0}, \ + xpwm_write_1_2_winding_break_times_16_lines, \ + xpwm_write_1_2_winding_break_times_16_lines_split_eages } + +void xpwm_write_1_2_winding_break_times_16_lines(); +void xpwm_write_1_2_winding_break_times_16_lines_split_eages(XPWM_TIME *p); +void xpwm_write_zero_winding_break_times_16_lines_split_eages(); +void initXpwmTimeStructure(XPWM_TIME *p); + +extern XPWM_TIME xpwm_time; + +#define write_winding1_fase_a(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 0); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 1); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding1_fase_b(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 2); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 3); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding1_fase_c(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 4); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 5); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_a(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 6); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 7); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_b(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 8); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 9); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_winding2_fase_c(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 10); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 11); WriteMemory(ADR_PWM_TIMING, T1); +#define write_break_winding1(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 12); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 13); WriteMemory(ADR_PWM_TIMING, T1); + +#define write_break_winding2(T0, T1) \ + WriteMemory(ADR_PWM_KEY_NUMBER, 14); WriteMemory(ADR_PWM_TIMING, T0); \ + WriteMemory(ADR_PWM_KEY_NUMBER, 15); WriteMemory(ADR_PWM_TIMING, T1); + + +#endif /* XP_WRITE_TIME_H_ */ diff --git a/Inu/controller.c b/Inu/controller.c new file mode 100644 index 0000000..e306f9b --- /dev/null +++ b/Inu/controller.c @@ -0,0 +1,1355 @@ +/************************************************************************** + Description: ��������� ���������� ������ ���������� - ������������ + ����� ������� init28335, detcoeff, isr. + ����� ���������� ��������� ������������ ���������� ���������� + TMS320F28335/TMS320F28379D (ADC, PWM, QEP � �.�.). + + �����: ���������� �.�. + ���� ���������� ����������: 2021.11.08 +**************************************************************************/ + + +#include "simstruc.h" +#include "wrapper_inu.h" +#include "def.h" +#include "controller.h" +#include "pwm_vector_regul.h" + + +extern UMotorMeasure motor; + +extern TimerSimHandle t1sim +extern TimerSimHandle t2sim; +extern TimerSimHandle t3sim; +extern TimerSimHandle t4sim; +extern TimerSimHandle t5sim; +extern TimerSimHandle t6sim; +extern TimerSimHandle t7sim; +extern TimerSimHandle t8sim; +extern TimerSimHandle t9sim; +extern TimerSimHandle t10sim; +extern TimerSimHandle t11sim; +extern TimerSimHandle t12sim; + +extern DeadBandSimHandle dt1sim +extern DeadBandSimHandle dt2sim; +extern DeadBandSimHandle dt3sim; +extern DeadBandSimHandle dt4sim; +extern DeadBandSimHandle dt5sim; +extern DeadBandSimHandle dt6sim; +extern DeadBandSimHandle dt7sim; +extern DeadBandSimHandle dt8sim; +extern DeadBandSimHandle dt9sim; +extern DeadBandSimHandle dt10sim; +extern DeadBandSimHandle dt11sim; +extern DeadBandSimHandle dt12sim; + +extern void init28335(void); +extern void detcoeff(void); +extern void isr(void); +extern void input_param(unsigned short num, unsigned short val); +// extern void init_DQ_pid(); +int calcAlgUpr = 0; + +int timers_adc = 0; +int timers_pwm = 0; + +void readInputParameters(const real_T *u) { + // int t; + //// ����� (begin) + //nn = 0; + //// ���������� �������� + //motor.udc1_ml = u[nn++];//� + //motor.udc2_ml = u[nn++];//� + + //motor.ia1_ml = u[nn++];//� + //motor.ib1_ml = u[nn++];//� + //motor.ic1_ml = u[nn++];//� + //motor.ia2_ml = u[nn++];//� + //motor.ib2_ml = u[nn++];//� + //motor.ic2_ml = u[nn++];//� + //motor.wm_ml = u[nn++];//���/� + + //// ���������� (��������, � ��) + //mst.faultReset = (unsigned short)u[nn++]; + //mst.start = (unsigned short)u[nn++]; + //mst.pzMode = (unsigned short)u[nn++]; + //mst.wmZz = u[nn++];//o.e. (�� N_BAZ) + //mst.pmZz = u[nn++]*(P_NOM/S_BAZ);//o.e. (�� S_BAZ) + //mst.wmLim = u[nn++];//o.e. (�� N_BAZ) + //mst.pmLim = u[nn++]*(P_NOM/S_BAZ);//o.e. (�� S_BAZ) + //mst.pIncrMaxTy = u[nn++]*TY*DECIM_PSI_WM_PM*(P_NOM/S_BAZ);//o.e. (�� S_BAZ) + //mst.pDecrMaxTy = u[nn++]*TY*DECIM_PSI_WM_PM*(P_NOM/S_BAZ);//o.e. (�� S_BAZ) + + //// + //mst.off_curr_pi = (unsigned short)u[nn++]; + //mst.only_one_km = (unsigned short)u[nn++]; + //mst.enable_compens_iq1_iq2 = (unsigned short)u[nn++]; + //mst.pi_iq_ki = u[nn++]; + //mst.pi_id_ki = u[nn++]; + //t = (unsigned short)u[nn++]; + //t = (unsigned short)u[nn++]; + //t = (unsigned short)u[nn++]; + //t = (unsigned short)u[nn++]; + //t = (unsigned short)u[nn++]; + + + //// ��������� (��������, � ��) + //paramNo = FIRST_WRITE_PAR_NUM; + //paramNew[paramNo++] = (unsigned short)u[nn++]; + //paramNew[paramNo++] = (unsigned short)u[nn++]; + + + //// ����� (end) + + +} + + +void processSFunctionIfChanged(SimStruct *S, int_T *iW) { + + // ������������ ��������� S-Function ������ ���, ����� ��� ���������� + if ( iW[0] == 1 ) { + iW[0] = 0; + kkk = 0; + for ( lll = 0; lll < NPARAMS; lll++ ) { + // ���������� ���-�� ��������� � ��������� + dimen = mxGetNumberOfElements(ssGetSFcnParam(S,lll)); + // ������������ �������� � ����������� �� ��� ������� + if ( dimen > LEN_PARAM_MATR*2 ) { + ssSetErrorStatus(S,"� ���������-������� ������� ����� ���������"); + return; + } + else if ( dimen > 1 ) { + // ���������� ���-�� ��������� ���������-������� + paramMatrDimen = dimen; + // ���������� �������� ��������� ���������-������� + for ( mmm = 0; mmm < dimen; mmm++ ) + paramMatr[mmm] = mxGetPr(ssGetSFcnParam(S,lll))[mmm]; + } + else { + // ���������� �������� ����������-�������� + paramScal[kkk++] = mxGetPr(ssGetSFcnParam(S,lll))[0]; + } + } + // ��������� (begin) + nn = 0; + dt = paramScal[nn++];//��� ������������� (������ ������ ������������ � S-function ���������!) + // ��������� (end) + } //if ( iW[0] == 1 ) + +} + +void initialisationOnStart(int_T *iW) { +//// ���-��� ��������� ���� ��� ��� ������� ������ +// if ( iW[1] == 1 ) { +// iW[1] = 0; +// +// timers_adc = 0; +// timers_pwm = 0; +// +// // ������������� ���������� +// init28335(); +// +// init_DQ_pid(); +// +// // �������� ���������� ���������� �� EEPROM +// // ... ��������� �� ������ (��. ���� "Parameters") +// for ( j = FIRST_WRITE_PAR_NUM; j < paramNo; j++ ) { +// param[j] = paramNew[j]; +// } +// // ... ��������� �� ����� +// param[180] = 930;//rf.PsiZ, %*10 �� PSI_BAZ +// +// param[200] = 2048;//offset.Ia1, ��. ��� +// param[201] = 2048;//offset.Ib1, ��. ��� +// param[202] = 2048;//offset.Ic1, ��. ��� +// param[203] = 2048;//offset.Udc1, ��. ��� +// param[206] = 2048;//offset.Ia2, ��. ��� +// param[207] = 2048;//offset.Ib2, ��. ��� +// param[208] = 2048;//offset.Ic2, ��. ��� +// param[209] = 2048;//offset.Udc2, ��. ��� +// +// param[210] = 100;//cc.Kp, % +// param[211] = 100;//cc.Ki, % +// param[212] = 100;//cf.Kp, % +// param[213] = 100;//cf.Ki, % +// param[214] = 100;//csp.Kp, % +// param[215] = 100;//csp.Ki, % +// +// param[220] = 99;//protect.IacMax, % �� IAC_SENS_MAX +// param[221] = 130;//protect.UdcMax, % �� U_NOM +// param[222] = 110;//IzLim, % �� I_BAZ (�.�. ������ cf.IdLim) +// param[223] = 105;//cf.IdLim, % �� I_BAZ (�.�. ������ IzLim) +// param[224] = 105;//csp.IqLim, % �� I_BAZ +// param[225] = 97;//protect.UdcMin, % �� U_NOM +// param[226] = 115;//protect.WmMax, % �� N_NOM +// param[228] = 103;//rf.WmNomPsi, % �� N_NOM +// param[229] = 97;//rf.YlimPsi, % �� Y_LIM +// param[231] = 300;//protect.TudcMin, �� +// param[233] = 1000;//protect.TwmMax, �� +// +// param[244] = 26000;//rs.WlimIncr, �� +// param[245] = 2000;//csp.IlimIncr, �� +// param[248] = 6000;//rp.PlimIncr, �� +// +// param[269] = 9964;//9700;//KmeCorr, %*100 +// +// param[285] = 10;//Kudc, ��*10 +// param[286] = 700;//Kwm, ��*10 +// param[288] = 250;//rs.Kwmz, �� +// param[289] = 50;//rf.Kpsiz, �� +// param[290] = 40;//Kme, �� +// param[292] = 80;//rp.Kpmz, �� +// +// param[303] = (unsigned short)(19200.);//sgmPar.Rs, ���� +// param[304] = (unsigned short)(19364.);//sgmPar.Lls, ����*10 +// param[305] = (unsigned short)(8500.);//sgmPar.Rr, ���� +// param[306] = (unsigned short)(10212.);//sgmPar.Llr, ����*10 +// param[307] = (unsigned short)(35810.);//sgmPar.Lm, ���� +// +// // ������������� ��������� +// detcoeff(); +// +// // ��� ������������� �������� +// T1Pr = (double)EPwm1Regs.TBPRD; +// T2Pr = (double)EPwm2Regs.TBPRD; +// T3Pr = (double)EPwm3Regs.TBPRD; +// T4Pr = (double)EPwm4Regs.TBPRD; +// T5Pr = (double)EPwm5Regs.TBPRD; +// T6Pr = (double)EPwm6Regs.TBPRD; +// T7Pr = (double)EPwm7Regs.TBPRD; +// T8Pr = (double)EPwm8Regs.TBPRD; +// T9Pr = (double)EPwm9Regs.TBPRD; +// T10Pr = (double)EPwm10Regs.TBPRD; +// T11Pr = (double)EPwm11Regs.TBPRD; +// T12Pr = (double)EPwm12Regs.TBPRD; +// t1cntAux = (double)EPwm1Regs.TBCTR; +// t2cntAux = (double)EPwm2Regs.TBCTR; +// t3cntAux = (double)EPwm3Regs.TBCTR; +// t4cntAux = (double)EPwm4Regs.TBCTR; +// t5cntAux = (double)EPwm5Regs.TBCTR; +// t6cntAux = (double)EPwm6Regs.TBCTR; +// t7cntAux = (double)EPwm7Regs.TBCTR; +// t8cntAux = (double)EPwm8Regs.TBCTR; +// t9cntAux = (double)EPwm9Regs.TBCTR; +// t10cntAux = (double)EPwm10Regs.TBCTR; +// t11cntAux = (double)EPwm11Regs.TBCTR; +// t12cntAux = (double)EPwm12Regs.TBCTR; +// // ... ���������� ��������� �������� �� ��� ������������� +// TxCntPlus = FTBCLK*dt; +// +// // ��� ������������� eQEP +// Qposmax = (double)EQep2Regs.QPOSMAX; +// qposcnt = 1.;//(double)EQep2Regs.QPOSCNT; +// +// // ��� ������������� ��� +// // (�� ���� 1e-6 ��. SetupAdc(), ���� ��� ������ �� 1.0 ���, � 0.8 ���) +//// Tadc = (int)(1e-6/dt); +// Tadc = (int)(1/FREQ_ADC_TIMER/dt); +// +// // ... �� ������ ������ +// if ( Tadc < 1 ) +// Tadc = 1; +// tAdc = 1; +// // ... ����� ��� ���� ������� +// nAdc = 0; +// +// // ��� ������������� Dead-Band Unit +// CntDt = (int)(DT/dt); +// stateDt1 = stateDt2 = stateDt3 = stateDt4 = stateDt5 = stateDt6 = 1; +// stateDt7 = stateDt8 = stateDt9 = stateDt10 = stateDt11 = stateDt12 = 1; +// cntDt1 = cntDt2 = cntDt3 = cntDt4 = cntDt5 = cntDt6 = 0; +// cntDt7 = cntDt8 = cntDt9 = cntDt10 = cntDt11 = cntDt12 = 0; +// +// // ��� ����� +// DI_24V_SOURCE_FAULT = 0; +// +// // ��� ������ +// inuWork = 0; +// ivc.psi = 0; +// rf.psiZ = 0; +// rs.wmZ = 0; +// csp.wmLimZi = 0; +// pm = 0; +// rp.pmZ = 0; +// csp.pmLimZi = 0; +// id1 = 0; +// iq1 = 0; +// id2 = 0; +// iq2 = 0; +// idZ = 0; +// iqZ = 0; +// cf.idP = 0; +// cf.idFF = 0; +// cf.idI = 0; +// csp.iqP = 0; +// csp.iqFF = 0; +// csp.iqI = 0; +// cc.yd1 = 0; +// cc.yq1 = 0; +// cc.y1 = 0; +// cc.y2 = 0; +// } //if ( iW[1] == 1 ) + + +} + +void simulatePWMcounterAndReadComarators(void) { + + //// ���������� Time-Base Submodule, Counter-Compare Submodule � + //// Event-Trigger Submodule + //// ePWM1 (up-down-count mode) + //// ------------------------- + //t1cntAuxPrev = t1cntAux; + //t1cntAux += TxCntPlus; + //if ( t1cntAux > T1Pr ) { + // t1cntAux -= T1Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp1A = (double)EPwm1Regs.CMPA.half.CMPA; + // // ������ ��� + // // tAdc = Tadc; + // // nAdc = 0; + // calcAlgUpr = 1; // ��� ���������� + //} + //if ( (t1cntAuxPrev < 0) && (t1cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp1A = (double)EPwm1Regs.CMPA.half.CMPA; + // // ������ ��� + // // tAdc = Tadc; + // // nAdc = 0; + // calcAlgUpr = 1; // ��� ���������� + //} + //t1cnt = fabs(t1cntAux); + + //// ePWM2 (up-down-count mode) + //// ------------------------- + //t2cntAuxPrev = t2cntAux; + //t2cntAux += TxCntPlus; + //if ( t2cntAux > T2Pr ) { + // t2cntAux -= T2Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp2A = (double)EPwm2Regs.CMPA.half.CMPA; + //} + //if ( (t2cntAuxPrev < 0) && (t2cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp2A = (double)EPwm2Regs.CMPA.half.CMPA; + //} + //t2cnt = fabs(t2cntAux); + + //// ePWM3 (up-down-count mode) + //// ------------------------- + //t3cntAuxPrev = t3cntAux; + //t3cntAux += TxCntPlus; + //if ( t3cntAux > T3Pr ) { + // t3cntAux -= T3Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp3A = (double)EPwm3Regs.CMPA.half.CMPA; + //} + //if ( (t3cntAuxPrev < 0) && (t3cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp3A = (double)EPwm3Regs.CMPA.half.CMPA; + //} + //t3cnt = fabs(t3cntAux); + + //// ePWM4 (up-down-count mode) + //// ------------------------- + //t4cntAuxPrev = t4cntAux; + //t4cntAux += TxCntPlus; + //if ( t4cntAux > T4Pr ) { + // t4cntAux -= T4Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp4A = (double)EPwm4Regs.CMPA.half.CMPA; + //} + //if ( (t4cntAuxPrev < 0) && (t4cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp4A = (double)EPwm4Regs.CMPA.half.CMPA; + //} + //t4cnt = fabs(t4cntAux); + + //// ePWM5 (up-down-count mode) + //// ------------------------- + //t5cntAuxPrev = t5cntAux; + //t5cntAux += TxCntPlus; + //if ( t5cntAux > T5Pr ) { + // t5cntAux -= T5Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp5A = (double)EPwm5Regs.CMPA.half.CMPA; + //} + //if ( (t5cntAuxPrev < 0) && (t5cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp5A = (double)EPwm5Regs.CMPA.half.CMPA; + //} + //t5cnt = fabs(t5cntAux); + + //// ePWM6 (up-down-count mode) + //// ------------------------- + //t6cntAuxPrev = t6cntAux; + //t6cntAux += TxCntPlus; + //if ( t6cntAux > T6Pr ) { + // t6cntAux -= T6Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp6A = (double)EPwm6Regs.CMPA.half.CMPA; + //} + //if ( (t6cntAuxPrev < 0) && (t6cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp6A = (double)EPwm6Regs.CMPA.half.CMPA; + //} + //t6cnt = fabs(t6cntAux); + + //// ePWM7 (up-down-count mode) + //// ------------------------- + //t7cntAuxPrev = t7cntAux; + //t7cntAux += TxCntPlus; + //if (t7cntAux > T7Pr) { + // t7cntAux -= T7Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp7A = (double)EPwm7Regs.CMPA.half.CMPA; + //} + //if ( (t7cntAuxPrev < 0) && (t7cntAux >= 0) ) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp7A = (double)EPwm7Regs.CMPA.half.CMPA; + //} + //t7cnt = fabs(t7cntAux); + + //// ePWM8 (up-down-count mode) + //// ------------------------- + //t8cntAuxPrev = t8cntAux; + //t8cntAux += TxCntPlus; + //if(t8cntAux > T8Pr) { + // t8cntAux -= T8Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp8A = (double)EPwm8Regs.CMPA.half.CMPA; + //} + //if((t8cntAuxPrev < 0) && (t8cntAux >= 0)) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp8A = (double)EPwm8Regs.CMPA.half.CMPA; + //} + //t8cnt = fabs(t8cntAux); + + //// ePWM9 (up-down-count mode) + //// ------------------------- + //t9cntAuxPrev = t9cntAux; + //t9cntAux += TxCntPlus; + //if(t9cntAux > T9Pr) { + // t9cntAux -= T9Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp9A = (double)EPwm9Regs.CMPA.half.CMPA; + //} + //if((t9cntAuxPrev < 0) && (t9cntAux >= 0)) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp9A = (double)EPwm9Regs.CMPA.half.CMPA; + //} + //t9cnt = fabs(t9cntAux); + + //// ePWM10 (up-down-count mode) + //// ------------------------- + //t10cntAuxPrev = t10cntAux; + //t10cntAux += TxCntPlus; + //if(t10cntAux > T10Pr) { + // t10cntAux -= T10Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp10A = (double)EPwm10Regs.CMPA.half.CMPA; + //} + //if((t10cntAuxPrev < 0) && (t10cntAux >= 0)) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp10A = (double)EPwm10Regs.CMPA.half.CMPA; + //} + //t10cnt = fabs(t10cntAux); + + //// ePWM11 (up-down-count mode) + //// ------------------------- + //t11cntAuxPrev = t11cntAux; + //t11cntAux += TxCntPlus; + //if(t11cntAux > T11Pr) { + // t11cntAux -= T11Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp11A = (double)EPwm11Regs.CMPA.half.CMPA; + //} + //if((t11cntAuxPrev < 0) && (t11cntAux >= 0)) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp11A = (double)EPwm11Regs.CMPA.half.CMPA; + //} + //t11cnt = fabs(t11cntAux); + + //// ePWM12 (up-down-count mode) + //// ------------------------- + //t12cntAuxPrev = t12cntAux; + //t12cntAux += TxCntPlus; + //if(t12cntAux > T12Pr) { + // t12cntAux -= T12Pr*2.; + // // active CMPA load from shadow when TBCTR == TBPRD + // cmp12A = (double)EPwm12Regs.CMPA.half.CMPA; + //} + //if((t12cntAuxPrev < 0) && (t12cntAux >= 0)) { + // // active CMPA load from shadow when TBCTR == 0 + // cmp12A = (double)EPwm12Regs.CMPA.half.CMPA; + //} + //t12cnt = fabs(t12cntAux); + + + //// ���������� ������ �������� � eQEP + //qposcnt += wm_ml/PI2*NOP*4.*dt; + //if ( qposcnt >= (Qposmax + 1.) ) + // qposcnt -= (Qposmax + 1.); + //else if ( qposcnt < 0 ) + // qposcnt += (Qposmax + 1.); + //EQep2Regs.QPOSCNT = (short)qposcnt; + +} + + +void update_norm_ADC_array() +{ + //// Udc1 + //if ( udc1_ml > UDC_SENS_MAX ) + // udc1_ml = UDC_SENS_MAX; + //else if ( udc1_ml < -UDC_SENS_MAX ) + // udc1_ml = -UDC_SENS_MAX; + //iq_norm_ADC[0] = _IQ(udc1_ml/NORMA_ACP); + //// Udc2 + //if ( udc2_ml > UDC_SENS_MAX ) + // udc2_ml = UDC_SENS_MAX; + //else if ( udc2_ml < -UDC_SENS_MAX ) + // udc2_ml = -UDC_SENS_MAX; + //iq_norm_ADC[1] = _IQ(udc2_ml/NORMA_ACP); + //// Udc3 + //if ( udc3_ml > UDC_SENS_MAX ) + // udc3_ml = UDC_SENS_MAX; + //else if ( udc3_ml < -UDC_SENS_MAX ) + // udc3_ml = -UDC_SENS_MAX; + //iq_norm_ADC[7] = _IQ(udc3_ml/NORMA_ACP); + //// Udc4 + //if ( udc4_ml > UDC_SENS_MAX ) + // udc4_ml = UDC_SENS_MAX; + //else if ( udc4_ml < -UDC_SENS_MAX ) + // udc4_ml = -UDC_SENS_MAX; + //iq_norm_ADC[8] = _IQ(udc4_ml/NORMA_ACP); + //// Idc1 + //if ( idc1_ml > IDC_SENS_MAX ) + // idc1_ml = IDC_SENS_MAX; + //else if ( idc1_ml < -IDC_SENS_MAX ) + // idc1_ml = -IDC_SENS_MAX; + //iq_norm_ADC[2] = _IQ(idc1_ml/NORMA_ACP); + //// Idc2 + //if ( idc2_ml > IDC_SENS_MAX ) + // idc2_ml = IDC_SENS_MAX; + //else if ( idc2_ml < -IDC_SENS_MAX ) + // idc2_ml = -IDC_SENS_MAX; + //iq_norm_ADC[3] = _IQ(idc2_ml/NORMA_ACP); + //// Idc3 + //if ( idc3_ml > IDC_SENS_MAX ) + // idc3_ml = IDC_SENS_MAX; + //else if ( idc3_ml < -IDC_SENS_MAX ) + // idc3_ml = -IDC_SENS_MAX; + //iq_norm_ADC[9] = _IQ(idc3_ml/NORMA_ACP); + //// Idc4 + //if ( idc4_ml > IDC_SENS_MAX ) + // idc4_ml = IDC_SENS_MAX; + //else if ( idc4_ml < -IDC_SENS_MAX ) + // idc4_ml = -IDC_SENS_MAX; + //iq_norm_ADC[10] = _IQ(idc4_ml/NORMA_ACP); + + //// Ia1 + //if ( ia1_ml > IAC_SENS_MAX ) + // ia1_ml = IAC_SENS_MAX; + //else if ( ia1_ml < -IAC_SENS_MAX ) + // ia1_ml = -IAC_SENS_MAX; + //iq_norm_ADC[4] = _IQ(ia1_ml/NORMA_ACP); + + //// Ib1 + //if ( ib1_ml > IAC_SENS_MAX ) + // ib1_ml = IAC_SENS_MAX; + //else if ( ib1_ml < -IAC_SENS_MAX ) + // ib1_ml = -IAC_SENS_MAX; + //iq_norm_ADC[5] = _IQ(ib1_ml/NORMA_ACP); + + //// Ic1 + //if ( ic1_ml > IAC_SENS_MAX ) + // ic1_ml = IAC_SENS_MAX; + //else if ( ic1_ml < -IAC_SENS_MAX ) + // ic1_ml = -IAC_SENS_MAX; + //iq_norm_ADC[6] = _IQ(ic1_ml/NORMA_ACP); + + + //// Ia2 + //if ( ia2_ml > IAC_SENS_MAX ) + // ia2_ml = IAC_SENS_MAX; + //else if ( ia2_ml < -IAC_SENS_MAX ) + // ia2_ml = -IAC_SENS_MAX; + //iq_norm_ADC[11] = _IQ(ia2_ml/NORMA_ACP); + + //// Ib2 + //if ( ib2_ml > IAC_SENS_MAX ) + // ib2_ml = IAC_SENS_MAX; + //else if ( ib2_ml < -IAC_SENS_MAX ) + // ib2_ml = -IAC_SENS_MAX; + //iq_norm_ADC[12] = _IQ(ib2_ml/NORMA_ACP); + + //// Ic2 + //if ( ic2_ml > IAC_SENS_MAX ) + // ic2_ml = IAC_SENS_MAX; + //else if ( ic2_ml < -IAC_SENS_MAX ) + // ic2_ml = -IAC_SENS_MAX; + //iq_norm_ADC[13] = _IQ(ic2_ml/NORMA_ACP); + + + + //vect_control.off_curr_pi = mst.off_curr_pi; + //vect_control.only_one_km = mst.only_one_km; + //vect_control.enable_compens_iq1_iq2 = mst.enable_compens_iq1_iq2; +} + +void simulateAdcAndCallIsr() { + + ///* ���������� �������������� ���������� ������� ���������, + //��������������� � ��� (� ������� nAdc ��������� ����� �� ������� + //����� ��� ������ ��������) */ + //if ( tAdc < Tadc ) { + // tAdc++; + //} + //else { + + // tAdc = 1; + // timers_adc++; + // if (timers_adc>=FREQ_ADC_TIMER) + // timers_adc = 0; + + // update_norm_ADC_array(); + // // ����� ���������� ����� ��� �������� isr() + // acp_Handler(); + // //isr(); + + + // // nAdc++; + // // switch ( nAdc ) { + // // case 5: + // + // // break; + // // case 6: + + // // break; + + // // case 7: + // // // ��� �� � �� + // // for ( j = FIRST_WRITE_PAR_NUM; j < paramNo; j++ ) { + // // if ( paramNew[j] != param[j] ) { + // // input_param((short)j, paramNew[j]); + // // break; + // // } + // // } + // // // ����� ���������� ����� ��� �������� isr() + // // isr(); + // // break; + // // } //switch ( nAdc ) + + //} //tAdc + + // if (calcAlgUpr) { + // // ��������� �������� ���������� + // upr(); + // calcAlgUpr = 0; + // timers_pwm++; + // if (timers_pwm>=FREQ_PWM_TIMER) + // timers_pwm = 0; + // } + + +} + +void simulateActionActionQualifierSubmodule(void) { + //// ���������� Action-Qualifier Submodule + //// ... ePWM1 + //if ( cmp1A > t1cnt ) { + // ci1A = 0; + // ci1B = 1; + //} + //else if ( cmp1A < t1cnt ) { + // ci1A = 1; + // ci1B = 0; + //} + //// ... ePWM2 + //if ( cmp2A > t2cnt ) { + // ci2A = 0; + // ci2B = 1; + //} + //else if ( cmp2A < t2cnt ) { + // ci2A = 1; + // ci2B = 0; + //} + //// ... ePWM3 + //if ( cmp3A > t3cnt ) { + // ci3A = 0; + // ci3B = 1; + //} + //else if ( cmp3A < t3cnt ) { + // ci3A = 1; + // ci3B = 0; + //} + //// ... ePWM4 + //if ( cmp4A > t4cnt ) { + // ci4A = 0; + // ci4B = 1; + //} + //else if ( cmp4A < t4cnt ) { + // ci4A = 1; + // ci4B = 0; + //} + //// ... ePWM5 + //if ( cmp5A > t5cnt ) { + // ci5A = 0; + // ci5B = 1; + //} + //else if ( cmp5A < t5cnt ) { + // ci5A = 1; + // ci5B = 0; + //} + //// ... ePWM6 + //if ( cmp6A > t6cnt ) { + // ci6A = 0; + // ci6B = 1; + //} + //else if ( cmp6A < t6cnt ) { + // ci6A = 1; + // ci6B = 0; + //} + //// ... ePWM7 + //if ( cmp7A > t7cnt ) { + // ci7A = 0; + // ci7B = 1; + //} + //else if ( cmp7A < t7cnt ) { + // ci7A = 1; + // ci7B = 0; + //} + //// ... ePWM8 + //if ( cmp8A > t8cnt ) { + // ci8A = 0; + // ci8B = 1; + //} + //else if ( cmp8A < t8cnt ) { + // ci8A = 1; + // ci8B = 0; + //} + //// ... ePWM9 + //if ( cmp9A > t9cnt ) { + // ci9A = 0; + // ci9B = 1; + //} + //else if ( cmp9A < t9cnt ) { + // ci9A = 1; + // ci9B = 0; + //} + //// ... ePWM10 + //if ( cmp10A > t10cnt ) { + // ci10A = 0; + // ci10B = 1; + //} + //else if ( cmp10A < t10cnt ) { + // ci10A = 1; + // ci10B = 0; + //} + //// ... ePWM11 + //if ( cmp11A > t11cnt ) { + // ci11A = 0; + // ci11B = 1; + //} + //else if ( cmp11A < t11cnt ) { + // ci11A = 1; + // ci11B = 0; + //} + //// ... ePWM12 + //if ( cmp12A > t12cnt ) { + // ci12A = 0; + // ci12B = 1; + //} + //else if ( cmp12A < t12cnt ) { + // ci12A = 1; + // ci12B = 0; + //} + + +} + +void simulateDeadBendSubmodule(void) { + + //// ���������� Dead-Band Submodule + //// ... ePWM1 + //if ( stateDt1 == 1 ) { + // ci1A_DT = ci1A; + // ci1B_DT = 0; + // if ( ci1A == 1 ) + // cntDt1 = CntDt; + // if ( cntDt1 > 0 ) + // cntDt1--; + // else + // stateDt1 = 2; + //} + //else if ( stateDt1 == 2 ) { + // ci1A_DT = 0; + // ci1B_DT = ci1B; + // if ( ci1B == 1 ) + // cntDt1 = CntDt; + // if ( cntDt1 > 0 ) + // cntDt1--; + // else + // stateDt1 = 1; + //} + //// ... ePWM2 + //if ( stateDt2 == 1 ) { + // ci2A_DT = ci2A; + // ci2B_DT = 0; + // if ( ci2A == 1 ) + // cntDt2 = CntDt; + // if ( cntDt2 > 0 ) + // cntDt2--; + // else + // stateDt2 = 2; + //} + //else if ( stateDt2 == 2 ) { + // ci2A_DT = 0; + // ci2B_DT = ci2B; + // if ( ci2B == 1 ) + // cntDt2 = CntDt; + // if ( cntDt2 > 0 ) + // cntDt2--; + // else + // stateDt2 = 1; + //} + //// ... ePWM3 + //if ( stateDt3 == 1 ) { + // ci3A_DT = ci3A; + // ci3B_DT = 0; + // if ( ci3A == 1 ) + // cntDt3 = CntDt; + // if ( cntDt3 > 0 ) + // cntDt3--; + // else + // stateDt3 = 2; + //} + //else if ( stateDt3 == 2 ) { + // ci3A_DT = 0; + // ci3B_DT = ci3B; + // if ( ci3B == 1 ) + // cntDt3 = CntDt; + // if ( cntDt3 > 0 ) + // cntDt3--; + // else + // stateDt3 = 1; + //} + //// ... ePWM4 + //if ( stateDt4 == 1 ) { + // ci4A_DT = ci4A; + // ci4B_DT = 0; + // if ( ci4A == 1 ) + // cntDt4 = CntDt; + // if ( cntDt4 > 0 ) + // cntDt4--; + // else + // stateDt4 = 2; + //} + //else if ( stateDt4 == 2 ) { + // ci4A_DT = 0; + // ci4B_DT = ci4B; + // if ( ci4B == 1 ) + // cntDt4 = CntDt; + // if ( cntDt4 > 0 ) + // cntDt4--; + // else + // stateDt4 = 1; + //} + //// ... ePWM5 + //if ( stateDt5 == 1 ) { + // ci5A_DT = ci5A; + // ci5B_DT = 0; + // if ( ci5A == 1 ) + // cntDt5 = CntDt; + // if ( cntDt5 > 0 ) + // cntDt5--; + // else + // stateDt5 = 2; + //} + //else if ( stateDt5 == 2 ) { + // ci5A_DT = 0; + // ci5B_DT = ci5B; + // if ( ci5B == 1 ) + // cntDt5 = CntDt; + // if ( cntDt5 > 0 ) + // cntDt5--; + // else + // stateDt5 = 1; + //} + //// ... ePWM6 + //if ( stateDt6 == 1 ) { + // ci6A_DT = ci6A; + // ci6B_DT = 0; + // if ( ci6A == 1 ) + // cntDt6 = CntDt; + // if ( cntDt6 > 0 ) + // cntDt6--; + // else + // stateDt6 = 2; + //} + //else if ( stateDt6 == 2 ) { + // ci6A_DT = 0; + // ci6B_DT = ci6B; + // if ( ci6B == 1 ) + // cntDt6 = CntDt; + // if ( cntDt6 > 0 ) + // cntDt6--; + // else + // stateDt6 = 1; + //} + //// ... ePWM7 + //if ( stateDt7 == 1 ) { + // ci7A_DT = ci7A; + // ci7B_DT = 0; + // if ( ci7A == 1 ) + // cntDt7 = CntDt; + // if ( cntDt7 > 0 ) + // cntDt7--; + // else + // stateDt7 = 2; + //} + //else if ( stateDt7 == 2 ) { + // ci7A_DT = 0; + // ci7B_DT = ci7B; + // if ( ci7B == 1 ) + // cntDt7 = CntDt; + // if ( cntDt7 > 0 ) + // cntDt7--; + // else + // stateDt7 = 1; + //} + //// ... ePWM8 + //if ( stateDt8 == 1 ) { + // ci8A_DT = ci8A; + // ci8B_DT = 0; + // if ( ci8A == 1 ) + // cntDt8 = CntDt; + // if ( cntDt8 > 0 ) + // cntDt8--; + // else + // stateDt8 = 2; + //} + //else if ( stateDt8 == 2 ) { + // ci8A_DT = 0; + // ci8B_DT = ci8B; + // if ( ci8B == 1 ) + // cntDt8 = CntDt; + // if ( cntDt8 > 0 ) + // cntDt8--; + // else + // stateDt8 = 1; + //} + //// ... ePWM9 + //if ( stateDt9 == 1 ) { + // ci9A_DT = ci9A; + // ci9B_DT = 0; + // if ( ci9A == 1 ) + // cntDt9 = CntDt; + // if ( cntDt9 > 0 ) + // cntDt9--; + // else + // stateDt9 = 2; + //} + //else if ( stateDt9 == 2 ) { + // ci9A_DT = 0; + // ci9B_DT = ci9B; + // if ( ci9B == 1 ) + // cntDt9 = CntDt; + // if ( cntDt9 > 0 ) + // cntDt9--; + // else + // stateDt9 = 1; + //} + //// ... ePWM10 + //if ( stateDt10 == 1 ) { + // ci10A_DT = ci10A; + // ci10B_DT = 0; + // if ( ci10A == 1 ) + // cntDt10 = CntDt; + // if ( cntDt10 > 0 ) + // cntDt10--; + // else + // stateDt10 = 2; + //} + //else if ( stateDt10 == 2 ) { + // ci10A_DT = 0; + // ci10B_DT = ci10B; + // if ( ci10B == 1 ) + // cntDt10 = CntDt; + // if ( cntDt10 > 0 ) + // cntDt10--; + // else + // stateDt10 = 1; + //} + //// ... ePWM11 + //if ( stateDt11 == 1 ) { + // ci11A_DT = ci11A; + // ci11B_DT = 0; + // if ( ci11A == 1 ) + // cntDt11 = CntDt; + // if ( cntDt11 > 0 ) + // cntDt11--; + // else + // stateDt11 = 2; + //} + //else if ( stateDt11 == 2 ) { + // ci11A_DT = 0; + // ci11B_DT = ci11B; + // if ( ci11B == 1 ) + // cntDt11 = CntDt; + // if ( cntDt11 > 0 ) + // cntDt11--; + // else + // stateDt11 = 1; + //} + //// ... ePWM12 + //if ( stateDt12 == 1 ) { + // ci12A_DT = ci12A; + // ci12B_DT = 0; + // if ( ci12A == 1 ) + // cntDt12 = CntDt; + // if ( cntDt12 > 0 ) + // cntDt12--; + // else + // stateDt12 = 2; + //} + //else if ( stateDt12 == 2 ) { + // ci12A_DT = 0; + // ci12B_DT = ci12B; + // if ( ci12B == 1 ) + // cntDt12 = CntDt; + // if ( cntDt12 > 0 ) + // cntDt12--; + // else + // stateDt12 = 1; + //} + +} + + +void simulateTripZoneSubmodule(void) { + +//// ���������� Trip-Zone Submodule +// // ... clear flag for one-shot trip latch +// if ( EPwm1Regs.TZCLR.all == 0x0004 ) { +// EPwm1Regs.TZCLR.all = 0x0000; +// EPwm1Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm2Regs.TZCLR.all == 0x0004 ) { +// EPwm2Regs.TZCLR.all = 0x0000; +// EPwm2Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm3Regs.TZCLR.all == 0x0004 ) { +// EPwm3Regs.TZCLR.all = 0x0000; +// EPwm3Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm4Regs.TZCLR.all == 0x0004 ) { +// EPwm4Regs.TZCLR.all = 0x0000; +// EPwm4Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm5Regs.TZCLR.all == 0x0004 ) { +// EPwm5Regs.TZCLR.all = 0x0000; +// EPwm5Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm6Regs.TZCLR.all == 0x0004 ) { +// EPwm6Regs.TZCLR.all = 0x0000; +// EPwm6Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm7Regs.TZCLR.all == 0x0004 ) { +// EPwm7Regs.TZCLR.all = 0x0000; +// EPwm7Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm8Regs.TZCLR.all == 0x0004 ) { +// EPwm8Regs.TZCLR.all = 0x0000; +// EPwm8Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm9Regs.TZCLR.all == 0x0004 ) { +// EPwm9Regs.TZCLR.all = 0x0000; +// EPwm9Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm10Regs.TZCLR.all == 0x0004 ) { +// EPwm10Regs.TZCLR.all = 0x0000; +// EPwm10Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm11Regs.TZCLR.all == 0x0004 ) { +// EPwm11Regs.TZCLR.all = 0x0000; +// EPwm11Regs.TZFRC.all = 0x0000; +// } +// if ( EPwm12Regs.TZCLR.all == 0x0004 ) { +// EPwm12Regs.TZCLR.all = 0x0000; +// EPwm12Regs.TZFRC.all = 0x0000; +// } +// // ... forces a one-shot trip event +// if ( EPwm1Regs.TZFRC.all == 0x0004 ) +// ci1A_DT = ci1B_DT = 0; +// if ( EPwm2Regs.TZFRC.all == 0x0004 ) +// ci2A_DT = ci2B_DT = 0; +// if ( EPwm3Regs.TZFRC.all == 0x0004 ) +// ci3A_DT = ci3B_DT = 0; +// if ( EPwm4Regs.TZFRC.all == 0x0004 ) +// ci4A_DT = ci4B_DT = 0; +// if ( EPwm5Regs.TZFRC.all == 0x0004 ) +// ci5A_DT = ci5B_DT = 0; +// if ( EPwm6Regs.TZFRC.all == 0x0004 ) +// ci6A_DT = ci6B_DT = 0; +// if ( EPwm7Regs.TZFRC.all == 0x0004 ) +// ci7A_DT = ci7B_DT = 0; +// if ( EPwm8Regs.TZFRC.all == 0x0004 ) +// ci8A_DT = ci8B_DT = 0; +// if ( EPwm9Regs.TZFRC.all == 0x0004 ) +// ci9A_DT = ci9B_DT = 0; +// if ( EPwm10Regs.TZFRC.all == 0x0004 ) +// ci10A_DT = ci10B_DT = 0; +// if ( EPwm11Regs.TZFRC.all == 0x0004 ) +// ci11A_DT = ci11B_DT = 0; +// if ( EPwm12Regs.TZFRC.all == 0x0004 ) +// ci12A_DT = ci12B_DT = 0; + + +} + + +void writeOutputParameters(real_T *xD) { + +// // ������ (begin) +// nn = 0; +// // ���������� +// // ... INU1 +// xD[nn++] = ci1A_DT; +// xD[nn++] = ci2A_DT; +// xD[nn++] = ci1B_DT; +// xD[nn++] = ci2B_DT; +// +// xD[nn++] = ci3A_DT; +// xD[nn++] = ci4A_DT; +// xD[nn++] = ci3B_DT; +// xD[nn++] = ci4B_DT; +// +// xD[nn++] = ci5A_DT; +// xD[nn++] = ci6A_DT; +// xD[nn++] = ci5B_DT; +// xD[nn++] = ci6B_DT; +// // ... INU2 +// xD[nn++] = ci7A_DT; +// xD[nn++] = ci8A_DT; +// xD[nn++] = ci7B_DT; +// xD[nn++] = ci8B_DT; +// +// xD[nn++] = ci9A_DT; +// xD[nn++] = ci10A_DT; +// xD[nn++] = ci9B_DT; +// xD[nn++] = ci10B_DT; +// +// xD[nn++] = ci11A_DT; +// xD[nn++] = ci12A_DT; +// xD[nn++] = ci11B_DT; +// xD[nn++] = ci12B_DT; +// +// +//// ������ ��� ��� �������� +// xD[nn++] = udc1_ml; +// xD[nn++] = udc2_ml; +// xD[nn++] = udc3_ml; +// xD[nn++] = udc4_ml; +// +// xD[nn++] = idc1_ml; +// xD[nn++] = idc2_ml; +// xD[nn++] = idc3_ml; +// xD[nn++] = idc4_ml; +// +// xD[nn++] = _IQtoF(analog.iqIa1_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqIb1_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqIc1_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqIa2_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqIb2_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqIc2_1) * NORMA_ACP; +// +//// timers out +// +// xD[nn++] = timers_adc; +// xD[nn++] = timers_pwm; +// xD[nn++] = Tadc; +// xD[nn++] = dt; +// +// // ������ ��� ��������� +// xD[nn++] = _IQtoF(rp.pmZ); +// xD[nn++] = _IQtoF(rs.wmZ); +// +// xD[nn++] = mst.start; +// xD[nn++] = inuWork; +// xD[nn++] = mst.pzMode; +// +// xD[nn++] = psi; +// xD[nn++] = rf.psiZ; +// +// xD[nn++] = wm; +// xD[nn++] = _IQtoF(vect_control.koeff_correct_Id);//rs.wmZ; +// xD[nn++] = _IQtoF(vect_control.iqFrot) * NORMA_FROTOR * 60.0 / N_BAZ;//csp.wmLimZi; +// +// xD[nn++] = pm*S_BAZ;///P_NOM; +// xD[nn++] = rp.pmZ*S_BAZ;///P_NOM; +// xD[nn++] = csp.pmLimZi*S_BAZ;///P_NOM; +// +// xD[nn++] = _IQtoF(analog.iqId1)* NORMA_ACP;//_IQtoF(vect_control.iqPzad); +// xD[nn++] = _IQtoF(analog.iqIq1)* NORMA_ACP;// * NORMA_ACP; +// xD[nn++] = _IQtoF(analog.iqId2)* NORMA_ACP;//_IQtoF(vect_control.iqUqCompensation1);// +// xD[nn++] = _IQtoF(analog.iqIq2)* NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.iqId_zad)* NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.iqIq_zad)* NORMA_ACP;//iqZ; +// +// xD[nn++] = me*M_BAZ/M_NOM; +// +// xD[nn++] = _IQtoF(vect_control.iqPzad) * NORMA_ACP * NORMA_ACP / 1000.0;; +// xD[nn++] = _IQtoF(vect_control.iqPizm) * NORMA_ACP * NORMA_ACP / 1000.0;; +// // xD[nn++] = sqrt(idZ*idZ + iqZ*iqZ); +// // xD[nn++] = IzLim; +// +// // xD[nn++] = EPwm2Regs.CMPA.half.CMPA;//xpwm_time.Ta0_0;//cc.yd1; +// // xD[nn++] = xpwm_time.Ta0_0; +// // xD[nn++] = xpwm_time.Ta0_1; +// // xD[nn++] = _IQtoF(cos_fi.cos_fi_nom);//cc.yd1; +// // xD[nn++] = _IQtoF(cos_fi.cos_fi_nom_squared);//cc.yq1; +// // xD[nn++] = _IQtoF(tetta_calc.k_t); +// xD[nn++] = _IQtoF(vect_control.iqUzad1);//cc.yd1; +// xD[nn++] = _IQtoF(vect_control.iqUzad2);//cc.yd1; +//// xD[nn++] = _IQtoF(vect_control.iqUdKm1Out);//cc.yq1; +//// xD[nn++] = _IQtoF(vect_control.iqUqKm1Out); +// +// xD[nn++] = _IQtoF(vect_control.iqUdKm1);//sqrt(cc.yd1*cc.yd1 + cc.yq1*cc.yq1); +// xD[nn++] = _IQtoF(vect_control.iqUqKm1);//sqrt(cc.yd2*cc.yd2 + cc.yq2*cc.yq2); +// xD[nn++] = _IQtoF(vect_control.iqUdKm2);//Y_LIM; +// xD[nn++] = _IQtoF(vect_control.iqUqKm2);//Y_LIM; +// +// +// xD[nn++] = _IQtoF(vect_control.iqUdKm1Out);//sqrt(cc.yd1*cc.yd1 + cc.yq1*cc.yq1); +// xD[nn++] = _IQtoF(vect_control.iqUqKm1Out);//sqrt(cc.yd2*cc.yd2 + cc.yq2*cc.yq2); +// xD[nn++] = _IQtoF(vect_control.iqUdKm2Out);//Y_LIM; +// xD[nn++] = _IQtoF(vect_control.iqUqKm2Out);//Y_LIM; +// +// xD[nn++] = _IQtoF(vect_control.k_modul_max);//Y_LIM; +// +// xD[nn++] = _IQtoF(vect_control.k_modul_max_def); +// xD[nn++] = _IQtoF(vect_control.maxUq1); +// xD[nn++] = _IQtoF(vect_control.maxUq2); +// xD[nn++] = _IQtoF(vect_control.Uq1Out); +// xD[nn++] = _IQtoF(vect_control.Uq2Out); +//// xD[nn++] = _IQtoF(vect_control.K_MODUL_MAX); +//// xD[nn++] = _IQtoF(vect_control.K_MODUL_MAX); +//// xD[nn++] = _IQtoF(vect_control.K_MODUL_MAX); +// +// +// // xD[nn++] = sqrt(cc.yd1*cc.yd1 + cc.yq1*cc.yq1); +// // xD[nn++] = sqrt(cc.yd2*cc.yd2 + cc.yq2*cc.yq2); +// // xD[nn++] = Y_LIM; +// // ������ (end) +// +// +///////////////// new +// xD[nn++] = _IQtoF(f.iq_mzz_zad) * NORMA_ACP;// +// xD[nn++] = _IQtoF(pidPvect.OutMax) * NORMA_ACP; +// xD[nn++] = _IQtoF(pidPvect.OutMin) * NORMA_ACP; +// xD[nn++] = _IQtoF(pidPvect.Out) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.mzz_zad_int) * NORMA_ACP ; +// xD[nn++] = _IQtoF(filter.iqIm_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(filter.iqIm_2) * NORMA_ACP; +// +// xD[nn++] = _IQtoF(vect_control.Pzad_rmp) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(f.iq_p_rampa) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(analog.iqPvsi1) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(analog.iqPvsi1) * NORMA_ACP * NORMA_ACP / 1000.0; +// +// xD[nn++] = _IQtoF(analog.iqW1) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(analog.iqW2) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(analog.iqW) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(filter.iqW1) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(filter.iqW2) * NORMA_ACP * NORMA_ACP / 1000.0; +// xD[nn++] = _IQtoF(filter.iqW) * NORMA_ACP * NORMA_ACP / 1000.0; +// +// +// +// xD[nn++] = _IQtoF(vect_control.iqFrot) * NORMA_FROTOR * 60.0; +// xD[nn++] = vect_control.flag_reverse;//_IQtoF(0); +// +// xD[nn++] = _IQtoF(vect_control.koeff_correct_Id); +// xD[nn++] = _IQtoF(cos_fi.cos_fi_nom); +// +// xD[nn++] = _IQtoF(filter.Fsl) * NORMA_FROTOR; +// +// xD[nn++] = _IQtoF(filter.iqIa1_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(filter.iqIb1_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(filter.iqIc1_1) * NORMA_ACP; +// +// xD[nn++] = _IQtoF(filter.iqIa2_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(filter.iqIb2_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(filter.iqIc2_1) * NORMA_ACP; +// +// xD[nn++] = _IQtoF(tetta_calc.Imds); +// xD[nn++] = _IQtoF(tetta_calc.tetta); +// +// xD[nn++] = _IQtoF(vect_control.Is) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.Ids) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.Id_ref_fw) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.Id_ref_1) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.Is_max) * NORMA_ACP; +// +// xD[nn++] = vect_control.flag_fw; +// +// xD[nn++] = _IQtoF(vect_control.ws_Iq1) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.ws_Id_filter1) * NORMA_ACP; +// xD[nn++] = _IQtoF(vect_control.ws_Id_filter2) * NORMA_ACP; +// +// xD[nn++] = _IQtoF(vect_control.ws_ws_t1) * NORMA_FROTOR; +// +// xD[nn++] = _IQtoF(analog.Fsl) * NORMA_FROTOR; +// xD[nn++] = _IQtoF(filter.Fsl) * NORMA_FROTOR; +// +// xD[nn++] = vect_control.tmp1; +// xD[nn++] = vect_control.tmp2; +// xD[nn++] = vect_control.tmp3; +// //xD[nn++] = _IQtoF(0) * NORMA_ACP; +// //xD[nn++] = _IQtoF(0) * NORMA_ACP; +// xD[nn++] = _IQtoF(0) * NORMA_ACP; +// +// +// +// xD[nn++] = _IQtoF(svgen_dq_1.Ta)*1000.0; +// xD[nn++] = _IQtoF(svgen_dq_1.Tb)*1000.0; +// xD[nn++] = _IQtoF(svgen_dq_1.Tc)*1000.0; +// +// xD[nn++] = _IQtoF(svgen_dq_2.Ta)*1000.0; +// xD[nn++] = _IQtoF(svgen_dq_2.Tb)*1000.0; +// xD[nn++] = _IQtoF(svgen_dq_2.Tc)*1000.0; +// + + + + +} + + + +void controller(SimStruct *S, const real_T *u, real_T *xD, real_T *rW, int_T *iW) { + + readInputParameters(u); + processSFunctionIfChanged(S, iW); + initialisationOnStart(iW); + + simulatePWMcounterAndReadComarators(); + + + simulateAdcAndCallIsr(); + simulateActionActionQualifierSubmodule(); + + // convertSVGenTimesToTkLines(); + simulateDeadBendSubmodule(); + + // xilinxPwm3LevelSimulation(); + simulateTripZoneSubmodule(); + + + writeOutputParameters(xD); + +} //void controller(SimStruct ... diff --git a/Inu/controller.h b/Inu/controller.h new file mode 100644 index 0000000..c81e487 --- /dev/null +++ b/Inu/controller.h @@ -0,0 +1,222 @@ +// ������������ ����� ���������-������� +#define LEN_PARAM_MATR 21 + +// ������� � ����������� S_Function +double paramScal[NPARAMS]; +double paramMatr[LEN_PARAM_MATR*2]; +int paramMatrDimen; + +// ������ �������� � ��������� �������, � ����� ������� ���������� +int nn; +// ��� �������������� +double dt; +// ��� ��������� ���������� +int kkk, lll, mmm, dimen; + + + +// ����������, ������� ���������� � controller.c (begin) +//######################################################################### +// ��������� +//double ; + +// ����� +typedef struct +{ + double udc1_ml; + double udc2_ml; + double ia1_ml; + double ib1_ml; + double ic1_ml; + double ia2_ml; + double ib2_ml; + double ic2_ml; + double wm_ml; +}UMotorMeasure; +extern UMotorMeasure motor; + +// ��� �������� ������ � �� +int j; +unsigned short paramNo; +unsigned short paramNew[PAR_NUMBER]; + +// ��� ������������� Event Manager +// ... Time-Base Submodule, Counter-Compare Submodule � Event-Trigger Submodule +typedef struct +{ + double TxCntPlus; + double TPr; + double tcntAux; + double tcntAuxPrev; + double tcnt; + double cmp1A; + double cmp1B; +}TimerSimHandle; +extern TimerSimHandle t1sim +extern TimerSimHandle t2sim; +extern TimerSimHandle t3sim; +extern TimerSimHandle t4sim; +extern TimerSimHandle t5sim; +extern TimerSimHandle t6sim; +extern TimerSimHandle t7sim; +extern TimerSimHandle t8sim; +extern TimerSimHandle t9sim; +extern TimerSimHandle t10sim; +extern TimerSimHandle t11sim; +extern TimerSimHandle t12sim; + + +// ... Action-Qualifier Submodule +int ci1A; +int ci1B; +int ci2A; +int ci2B; +int ci3A; +int ci3B; +int ci4A; +int ci4B; +int ci5A; +int ci5B; +int ci6A; +int ci6B; +int ci7A; +int ci7B; +int ci8A; +int ci8B; +int ci9A; +int ci9B; +int ci10A; +int ci10B; +int ci11A; +int ci11B; +int ci12A; +int ci12B; +// ... Dead-Band Submodule +typedef struct +{ + int CntDt; + int stateDt; + int cntDt; + int ciA_DT; + int ciB_DT; +}DeadBandSimHandle; +extern DeadBandSimHandle dt1sim +extern DeadBandSimHandle dt2sim; +extern DeadBandSimHandle dt3sim; +extern DeadBandSimHandle dt4sim; +extern DeadBandSimHandle dt5sim; +extern DeadBandSimHandle dt6sim; +extern DeadBandSimHandle dt7sim; +extern DeadBandSimHandle dt8sim; +extern DeadBandSimHandle dt9sim; +extern DeadBandSimHandle dt10sim; +extern DeadBandSimHandle dt11sim; +extern DeadBandSimHandle dt12sim; + +// ��� ������������� eQEP +double Qposmax; +double qposcnt; + +// ��� ������������� ADC +int tAdc; +int Tadc; +int nAdc; +//######################################################################### +// ����������, ������� ���������� � controller.c (end) + + + + +// ����������, ������� ��������� � controller.c (begin) +//######################################################################### +// ��� isr.c +//------------------------------------------------------------------------- +extern struct Offset offset; +extern volatile struct Result result; +extern volatile short state; +extern volatile short faultNo; +extern volatile struct Out out; +// Udc +extern float Kudc; +extern volatile float udc1Nf; +extern volatile float udc1; +extern volatile float udc2Nf; +extern volatile float udc2; +// Iac +extern volatile float ia1Nf; +extern volatile float ib1Nf; +extern volatile float ix1; +extern volatile float iy1; +extern volatile float iac1Nf; +extern volatile float ia2Nf; +extern volatile float ib2Nf; +extern volatile float ix2; +extern volatile float iy2; +extern volatile float iac2Nf; +// Wm +extern float Kwm; +extern volatile float wmNf; +extern volatile float wm; +extern volatile float wmAbs; +// Me +extern volatile float kMe; +extern float KmeCorr; +extern float Kme; +extern volatile float meNf; +extern volatile float me; +// Pm +extern volatile float pm; +// ������ +extern struct Protect protect; +extern volatile struct Emerg emerg; +extern short csmSuccess; +// ����������� ������ +extern volatile short onceShutdown; +extern volatile short testParamFaultNo; +extern volatile short onceFaultReset; +extern volatile short stopPause; +extern volatile short inuWork; +// ����� +extern struct Mst mst; + + + +// ��� main.c +//------------------------------------------------------------------------- +extern struct Eprom eprom; + + + +// ��� upr.c +//------------------------------------------------------------------------- +extern volatile short onceUpr; +extern struct SgmPar sgmPar; +extern struct Rf rf; +extern struct Rs rs; +extern struct Rp rp; + +extern float IzLim; +extern volatile float psi; +extern float idZ; +extern float iqZ; +extern float iZ; +extern float ws; +extern float sinTheta; +extern float cosTheta; +extern float id1; +extern float iq1; +extern float id2; +extern float iq2; +extern struct Cc cc; +extern struct Cf cf; +extern struct Csp csp; +extern struct Ivc ivc; +extern struct Ip ip; + + + +// ��� param.c +//------------------------------------------------------------------------- +extern unsigned short param[]; +//######################################################################### +// ����������, ������� ��������� � controller.c (end) diff --git a/Inu/def.h b/Inu/def.h new file mode 100644 index 0000000..233c12a --- /dev/null +++ b/Inu/def.h @@ -0,0 +1,482 @@ +/************************************************************************** + Description: ������ ������ ������������� � �������. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.11.08 +**************************************************************************/ + +#ifndef DEF +#define DEF + +// �����������������, ���� ���� ����� ����� ��������� ��� (30 ����.) +#define SHIFT + + +// ������ ������ (��� state) +#define STATE_SHUTDOWN 0 //��������� ��������� +#define STATE_STOP 1 //������� ��������� +#define STATE_WORK 2 //������ + + +// ������� �������� ��������� ����������, �� +#define FSYSCLKOUT 200e6 //150e6 // +// prescaled version of the system clock and is used by +// all submodules within the ePWM, �� +// (��. EPwmxRegs.TBCTL.bit.CLKDIV � EPwmxRegs.TBCTL.bit.HSPCLKDIV) +#define FTBCLK (FSYSCLKOUT*0.5*0.5) +//#define FTBCLK (FSYSCLKOUT*0.5*0.5*0.5*0.5) +// ������ ���, c +#define T_PWM 2220e-6 //F_PWM = 450 �� +//#define T_PWM 6000e-6 //F_PWM = 166.7 �� +// ������ ������ �������� ���������, � +#define TY (T_PWM*0.5) +// "������� �����", � +#define DT 30e-6 +//#define DT 60e-6 +// Time-Base Period Register, ��. �������� ������� +#define T1_PRD (FTBCLK*T_PWM*0.5) +// ������������ �������� ��������� ���������� ���������� ������������� ���, +// ����� ����������� ������ �������� ���� 10 ���, ��. �������� ������� +#define Y_LIM (T1_PRD - (DT + 10e-6)*FTBCLK) + + +// ��������� ��� ���������� ������� +#define PI2 6.283185307179586476925286766559 //pi*2 +#define SQRT2 1.4142135623730950488016887242097 //sqrt(2) +#define SQRT3 1.7320508075688772935274463415059 //sqrt(3) +#define ISQRT3 0.57735026918962576450914878050196 //1./sqrt(3) + +// ����������� �������� ��� +// ... �������� �� ����, �� +#define P_NOM (5000e3*2.) +// ... �������� ����������, � (ampl) +#define U_NOM (3000.*SQRT2) +// ... ������������ ��������, ��/��� +#define N_NOM 165. +// ... ����� ��� ������� +#define PP 6. +// ... ����������� �������� +#define COS_FI 0.89 +// ... ��� +#define EFF 0.962 +// ... ����������� � ���� ������ �������, ��*�^2 +#define J (87e3*0.50) +// ... ������ ��������, �� +#define S_NOM (P_NOM/(COS_FI*EFF)) +// ... ������������ ��������, ���/� +#define WM_NOM (N_NOM/60.*PI2) +// ... ������ �� ����, �*� +#define M_NOM (P_NOM/WM_NOM) + + +// ������� �������� ��� +// ... ������ ��������, BA +#define S_BAZ S_NOM +// ... �������� ����������, � (ampl) +#define U_BAZ U_NOM +// ... ������ ���, � (ampl) +#define I_BAZ (S_BAZ*2./(U_BAZ*SQRT3)*0.5) //0.5 - �.�. ������� ��� +// ... ������������ ��������, ��/��� +#define N_BAZ N_NOM +// ... ������������ ��������, ���/� +#define WM_BAZ (N_BAZ/60.*PI2) +// ... ������������� ��������, ���/� +#define WE_BAZ (WM_BAZ*PP) +// ... ������ �� ����, �*� +#define M_BAZ (S_BAZ/WM_BAZ) +// ... ��������������� �������, �� +#define PSI_BAZ (U_BAZ/(WE_BAZ*SQRT3)) +// ... �������������, �� +#define L_BAZ (PSI_BAZ/I_BAZ) +// ... �������������, �� +#define R_BAZ (U_BAZ/(I_BAZ*SQRT3)) + + +// ��� ��������� �� ��������� ������� ���������� � ������� ������� ���������� +#define U_2_Y (T1_PRD*SQRT3/U_BAZ) + +// ���������� � ����� ����. ����, ������� ���� �� �� ������ ��� ����. 2048, � +#define UDC_SENS_MAX (U_BAZ*1.15*1.3) +// �������� ���, ������� ��� �� �� ������ ��� ����. 2048, � (ampl) +#define IAC_SENS_MAX (I_BAZ*1.5) +// number of pulses per rev. (from tacho, Hall, optical sensor...etc) +#define NOP 1024. +// ���������� �������� QEP �� TY ���. ��� ������� ����. WM_BAZ +#define QEP_CNT_DEL_NOM (NOP*4.*TY*WM_BAZ/PI2) + + +// ������������ ��� �������� ���������� ������� � o.e. +#define GAIN_UDC (UDC_SENS_MAX/(2048.*U_BAZ)) +#define GAIN_IAC (IAC_SENS_MAX/(2048.*I_BAZ)) +#define GAIN_WM (1.0/QEP_CNT_DEL_NOM) + + +// ����������� �������� ��� ��������� �������� � ���, o.e. +#define WM_MIN 0.03 //0.003 //? +// ��� ������������ ����������� ������, �������� � �������� +#define DECIM_PSI_WM_PM 2. //1. //5. //? + + +// for specify the PLL +#define PLLSTS_DIVSEL 2 +#define PLLCR_DIV 10 + +// ��� ������ +#define CONTROLLER_BIAS 3.2 +#define CONTROLLER_GAIN 2500. + +// ����� ���������� ���������� +#define PAR_NUMBER 400 +// ����� ������� �������������� ��������� +#define FIRST_WRITE_PAR_NUM 150 + + + +// ���������� �����/������ (begin) +//------------------------------------------------------------------------- +// ����� +// ---------------------------- +#define DI_24V_SOURCE_FAULT GpioDataRegs.GPBDAT.bit.GPIO50 + +// ������ +// ---------------------------- +// ... ������ +#define DO_GPIO00_SET GpioDataRegs.GPASET.bit.GPIO0 = 1 +#define DO_GPIO00_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 +#define DO_GPIO01_SET GpioDataRegs.GPASET.bit.GPIO1 = 1 +#define DO_GPIO01_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 +#define DO_GPIO02_SET GpioDataRegs.GPASET.bit.GPIO2 = 1 +#define DO_GPIO02_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 +#define DO_GPIO03_SET GpioDataRegs.GPASET.bit.GPIO3 = 1 +#define DO_GPIO03_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 +#define DO_GPIO04_SET GpioDataRegs.GPASET.bit.GPIO4 = 1 +#define DO_GPIO04_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO4 = 1 +#define DO_GPIO05_SET GpioDataRegs.GPASET.bit.GPIO5 = 1 +#define DO_GPIO05_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO5 = 1 +#define DO_GPIO06_SET GpioDataRegs.GPASET.bit.GPIO6 = 1 +#define DO_GPIO06_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO6 = 1 +#define DO_GPIO07_SET GpioDataRegs.GPASET.bit.GPIO7 = 1 +#define DO_GPIO07_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO7 = 1 +#define DO_GPIO08_SET GpioDataRegs.GPASET.bit.GPIO8 = 1 +#define DO_GPIO08_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO8 = 1 +#define DO_GPIO09_SET GpioDataRegs.GPASET.bit.GPIO9 = 1 +#define DO_GPIO09_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO9 = 1 +#define DO_GPIO10_SET GpioDataRegs.GPASET.bit.GPIO10 = 1 +#define DO_GPIO10_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO10 = 1 +#define DO_GPIO11_SET GpioDataRegs.GPASET.bit.GPIO11 = 1 +#define DO_GPIO11_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO11 = 1 +// ... �� ������������ +#define DO_GPIO019_SET GpioDataRegs.GPASET.bit.GPIO19 = 1 +#define DO_GPIO019_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO19 = 1 +#define DO_GPIO020_SET GpioDataRegs.GPASET.bit.GPIO20 = 1 +#define DO_GPIO020_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO20 = 1 +#define DO_GPIO022_SET GpioDataRegs.GPASET.bit.GPIO22 = 1 +#define DO_GPIO022_CLEAR GpioDataRegs.GPACLEAR.bit.GPIO22 = 1 +#define DO_GPIO48_SET GpioDataRegs.GPBSET.bit.GPIO48 = 1 +#define DO_GPIO48_CLEAR GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1 +#define DO_GPIO49_SET GpioDataRegs.GPBSET.bit.GPIO49 = 1 +#define DO_GPIO49_CLEAR GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1 +// ... ��� ���������� ������ CS EEPROM +#define CS_SET GpioDataRegs.GPBSET.bit.GPIO57 = 1 +#define CS_CLEAR GpioDataRegs.GPBCLEAR.bit.GPIO57 = 1 +// ... ���������� +// (������ "����������") +#define LED_GREEN1_ON GpioDataRegs.GPBCLEAR.bit.GPIO59 = 1 +#define LED_GREEN1_OFF GpioDataRegs.GPBSET.bit.GPIO59 = 1 +#define LED_GREEN1_TOGGLE GpioDataRegs.GPBTOGGLE.bit.GPIO59 = 1 +// (������ "������") +#define LED_GREEN2_ON GpioDataRegs.GPBCLEAR.bit.GPIO60 = 1 +#define LED_GREEN2_OFF GpioDataRegs.GPBSET.bit.GPIO60 = 1 +#define LED_GREEN2_TOGGLE GpioDataRegs.GPBTOGGLE.bit.GPIO60 = 1 +// (������� "������") +#define LED_RED_ON GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1 +#define LED_RED_OFF GpioDataRegs.GPBSET.bit.GPIO61 = 1 +#define LED_RED_TOGGLE GpioDataRegs.GPBTOGGLE.bit.GPIO61 = 1 +// ... �� ������������ +#define DO_GPIO63_SET GpioDataRegs.GPBSET.bit.GPIO63 = 1 +#define DO_GPIO63_CLEAR GpioDataRegs.GPBCLEAR.bit.GPIO63 = 1 +//------------------------------------------------------------------------- +// ���������� �����/������ (end) + + +#include "DSP2833x_Device.h" +#include "math.h" +#include "C28x_FPU_FastRTS.h" + + +// ��������� ��� ����������� ���� (��. control_current()) +struct Cc { + short once; + float KpOrig; + float KiOrig; + float Kp; + float Ki; + float K1; + float K2; + float K3; + float Xyff; + float yffAux2; + float yffAux3; + float del; + float kYlim; + float yd1P; + float yd1I; + float yd1FF; + float yd1; + float yq1P; + float yq1I; + float yq1FF; + float yq1; + float y1; + float yd2P; + float yd2I; + float yd2FF; + float yd2; + float yq2P; + float yq2I; + float yq2FF; + float yq2; + float y2; + short y1LimFlag; + short y2LimFlag; +}; //Cc + + +// ��������� ��� ���������� ������ (��. control_flux()) +struct Cf { + short once; + float KpOrig; + float KiOrig; + float Kp; + float Ki; + float IdLim; + float IdLimNeg; + float del; + float idP; + float idI; + float idFF; + short idLimFlag; +}; //Cf + + +// ��������� ��� ����������� �������� � �������� (��. control_speed_power()) +struct Csp { + short once; + float KpOrig; + float KiOrig; + float Kp; + float Ki; + float kMeNom; + float del; + float iqP; + float iqI; + float iqFF; + float IlimIncr; + float iqLimAux; + float iqLimZi; + float IqLim; + float IqLimNeg; + float iqLim; + float iqLimNeg; + float delWmAbs; + float KizIncr; + float pmZiRampDown; + float wmLimZi; + float pmLimZi; + short iqLimFlag; +}; //Csp + + +// ��������� ��� ������ � EEPROM ������� +struct Eprom { + short writeRequestNumber; + short readFaultNo; +}; //Eprom + + +// ��������� ��� ����������� ������� � ������ ������������ ������ +struct Emerg { + float udc1; + float udc2; + float iac1; + float iac2; + float me; + float wm; + float pm; +}; //Emerg + + +// ��������� ��� inverse park (��. ipark()) +struct Ip { + float yx1Aux; + float yy1Aux; + float yx2Aux; + float yy2Aux; + float theta; + float sinTheta; + float cosTheta; + float yx1; + float yy1; + float yx2; + float yy2; +}; //Ip + + +// ��������� ��� indirect vector control (��. indirect_vector_control()) +struct Ivc { + short once; + float im; + float wr; + float wsNf; + float ws; + float sinTheta; + float cosTheta; + float id1; + float iq1; + float psi; + float id2; + float iq2; +}; //Ivc + + +// ��������� ��� ������, ���������� � �� +struct Mst { + short pzMode; + short faultReset; + short start; + float wmZz; + float pmZz; + float wmLim; + float pmLim; + float pIncrMaxTy; + float pDecrMaxTy; +}; //Mst + + +// ��������� ��� �������� ���� �������� +struct Offset { + short Udc1; + short Udc2; + short Ic1; + short Ic2; + short Ia1; + short Ia2; + short Ib1; + short Ib2; +}; //Offset + + +// ��������� ��� ������ +struct Out { + float K; + float udc1; + float udc2; + float iac1; + float iac2; + float me; + float wm; + float pm; +}; //Out + + +// ��������� ��� ����� +struct Protect { + short IacMax; + short IacMin; + unsigned short Tdi24VSource; + volatile unsigned short tDI24VSource; + unsigned short TudcMin; + volatile unsigned short tUdc1Min; + volatile unsigned short tUdc2Min; + unsigned short TwmMax; + volatile unsigned short tWmMax; + float UdcMin; + float UdcMax; + float WmMax; +}; //Protect + + +// ��������� ��� ����������� ��� +struct Result { + short udc1; + short udc2; + short ic1; + short ic2; + short ia1; + short ia2; + short ib1; + short ib2; +}; //Result + + +// ��������� ��� ��������� ������ (��. reference_flux()) +struct Rf { + short once; + float PsiZ; + float PsizIncr; + float psiZi; + float psiZCorr; + float psiSub; + float psiZCorr2; + float psiZ; + float KpsiSub; + float Kpsiz; + float WmNomPsi; + float YlimPsi; + float pPsiZ; + float psiZPrev1; + float psiZPrev2; + float psiZPrev3; +}; //Rf + + +// ��������� ��� �������� �������� (��. reference_power()) +struct Rp { + short once; + float pmZz; + float pmZi; + float pmZ; + float Kpmz; + float PlimIncr; + float KpIncrDecr; + volatile float pmEqv; +}; //Rp + + +// ��������� ��� �������� �������� (��. reference_speed()) +struct Rs { + short once; + float wmZz; + float wmZi; + float wmZ; + float Kwmz; + float WlimIncr; + float wzIncrNf; + float wzIncr; + float pWmZ; + float wmZPrev1; + float wmZPrev2; + float wmZPrev3; + short tPwmZ; +}; //Rs + + +// ��������� ��� ���������� ��� +struct SgmPar { + float Rs; + float Lls; + float Rr; + float Llr; + float Lm; + float Ls; + float Lr; + float SigmaLs; + float LmInv; + float LrInv; + float Tr; + float TrInv; + float Kl; + float KlInv; +}; //SgmPar + +#endif //DEF diff --git a/Inu/detcoeff.c b/Inu/detcoeff.c new file mode 100644 index 0000000..7e14b81 --- /dev/null +++ b/Inu/detcoeff.c @@ -0,0 +1,242 @@ +/************************************************************************** + Description: ������� ���������� ���� ��� � ������ ���������� + ��������� � �������������� ������ ����������� ��� � ������. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.11.08 +**************************************************************************/ + + +#include "def.h" +#include "detcoeff.h" + + +void process_sgm_parameters(void); +short read_eeprom(void); +short test_param(void); + + + +void detcoeff(void) { + float Tci; + float Tcf; + float Tcs; + float Km; + + // ��� ������������ + testParamFaultNo = 0; + + // ������ EEPROM + // ( -> param[]) + eprom.readFaultNo = read_eeprom(); + if ( eprom.readFaultNo != 0 ) { + faultNo = 1; + state = STATE_SHUTDOWN; + } + else { + // ��������� ������ param[] + testParamFaultNo = test_param(); + if ( testParamFaultNo != 0 ) { + faultNo = 4; + state = STATE_SHUTDOWN; + } + else { + faultNo = 0; + state = STATE_STOP; + } + } + + + rf.PsiZ = (float)param[180]*0.001;//%*10 -> o.e. + + // �������� ���� ��������, ��. ��� + offset.Ia1 = param[200]; + offset.Ib1 = param[201]; + offset.Ic1 = param[202]; + offset.Udc1 = param[203]; + offset.Ia2 = param[206]; + offset.Ib2 = param[207]; + offset.Ic2 = param[208]; + offset.Udc2 = param[209]; + + // ��������� �� + sgmPar.Rs = (float)param[303]*1e-6;//���� -> �� + sgmPar.Lls = (float)param[304]*1e-7;//����*10 -> �� + sgmPar.Rr = (float)param[305]*1e-6;//���� -> �� + sgmPar.Llr = (float)param[306]*1e-7;//����*10 -> �� + sgmPar.Lm = (float)param[307]*1e-6;//���� -> �� + // �������� �� ���������� �� ������ ��������������� �������� + process_sgm_parameters(); + + // ������������ ����������� Id � Iq + // ... ���������� ������� ������� ����, � + Tci = TY*3.8; + cc.KpOrig = 0.01*sgmPar.SigmaLs/Tci*I_BAZ*U_2_Y; + cc.Kp = cc.KpOrig*(float)param[210]; + cc.KiOrig = 0.01*(sgmPar.Rs + sgmPar.Rr*sgmPar.Kl*sgmPar.Kl)/Tci*I_BAZ*U_2_Y*TY; + cc.Ki = cc.KiOrig*(float)param[211]; + + // ������������ ���������� Psi + // ... ���������� ������� ������� ������, � + Tcf = 50e-3; + cf.KpOrig = 0.01*sgmPar.KlInv/(sgmPar.Rr*Tcf)*PSI_BAZ/I_BAZ; + cf.Kp = cf.KpOrig*(float)param[212]; + cf.KiOrig = 0.01/(sgmPar.Lm*Tcf)*PSI_BAZ/I_BAZ*TY*DECIM_PSI_WM_PM; + cf.Ki = cf.KiOrig*(float)param[213]; + + // ������������ ���������� N + // ... ���������� ������� ������� ��������, � + Tcs = 200e-3; + // ... ����������� ��� ��������� ���� � ������ + Km = 1.5*PP*sgmPar.Kl*PSI_BAZ*rf.PsiZ; + csp.KpOrig = 0.01*J/(Km*Tcs)*WM_BAZ/I_BAZ; + csp.Kp = csp.KpOrig*(float)param[214]; + csp.KiOrig = 0.01*J/(Km*Tcs*Tcs*5.)*WM_BAZ/I_BAZ*TY*DECIM_PSI_WM_PM; + csp.Ki = csp.KiOrig*(float)param[215]; + + // ������ ������� + protect.IacMax = (short)(2047.*(float)param[220]*0.01);//% -> ��. ��� + protect.IacMin = -protect.IacMax; + protect.UdcMax = (float)param[221]*0.01;//% -> o.e. + IzLim = (float)param[222]*0.01;//% -> o.e. + cf.IdLim = (float)param[223]*0.01;//% -> o.e. + cf.IdLimNeg = cf.IdLim*(-0.4); + csp.IqLim = (float)param[224]*0.01;//% -> o.e. + csp.IqLimNeg = -csp.IqLim; + protect.UdcMin = (float)param[225]*0.01;//% -> o.e. + protect.WmMax = (float)param[226]*0.01;//% -> o.e. + rf.WmNomPsi = (float)param[228]*0.01;//% -> o.e. + rf.YlimPsi = (float)param[229]*0.01*Y_LIM;//% -> ��. �������� ������� + protect.TudcMin = (unsigned short)((float)param[231]*0.001/TY); + protect.TwmMax = (unsigned short)((float)param[233]*0.001/TY); + + // ��� ������ �� + rs.WlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[244]*0.001); + csp.IlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[245]*0.001); + rp.PlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[248]*0.001); + rf.PsizIncr = 1.0*TY*DECIM_PSI_WM_PM/2.0; + + // ��� ��������� + KmeCorr = (float)param[269]*0.0001;//%*100 -> o.e. + + // ��� ������ �������� + Kudc = (TY*10000.)/(float)param[285]; + if ( Kudc > 1.0 ) + Kudc = 1.0; + Kwm = (TY*10000.)/(float)param[286]; + if ( Kwm > 1.0 ) + Kwm = 1.0; + rs.Kwmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[288]; + rf.Kpsiz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[289]; + Kme = (TY*1000.)/(float)param[290]; + rp.Kpmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[292]; + out.K = TY/100e-3; + + // �������� + protect.Tdi24VSource = (unsigned short)(5.0/TY); + + // �� � �������� ��������� + udc1 = 0; + udc2 = 0; + wmNf = 0; + wm = 0; + me = 0; + out.udc1 = 0; + out.udc2 = 0; + out.iac1 = 0; + out.iac2 = 0; + out.wm = 0; + out.me = 0; + out.pm = 0; + protect.tWmMax = 0; + protect.tDI24VSource = 0; + onceShutdown = 0; + onceFaultReset = 0; + stopPause = 1; + mst.pzMode = 0; + mst.faultReset = 0; + mst.start = 0; + mst.wmZz = 0; + mst.pmZz = 0; + mst.wmLim = 0; + mst.pmLim = 0; + mst.pIncrMaxTy = 0; + mst.pDecrMaxTy = 0; +} //void detcoeff(void) + + + +// ��������� �� ���������� �� ������ ��������������� �������� +void process_sgm_parameters(void) { + // ������ ������������� ���� �������, �� + sgmPar.Ls = sgmPar.Lm + sgmPar.Lls; + // ������ ������������� ���� ������, �� + sgmPar.Lr = sgmPar.Lm + sgmPar.Llr; + // �����-����� + sgmPar.SigmaLs = (1. - sgmPar.Lm*sgmPar.Lm/(sgmPar.Ls*sgmPar.Lr))*sgmPar.Ls; + sgmPar.LmInv = 1.0/sgmPar.Lm; + sgmPar.LrInv = 1.0/sgmPar.Lr; + sgmPar.Kl = sgmPar.Lm*sgmPar.LrInv; + sgmPar.KlInv = 1.0/sgmPar.Kl; + sgmPar.Tr = sgmPar.Lr/sgmPar.Rr; + sgmPar.TrInv = sgmPar.Rr*sgmPar.LrInv; +} //void process_sgm_parameters(void) + + + +// ������ PAR_NUMBER ���������� �� EEPROM � ��������� � ������� param[] +// ( -> param[]) +short read_eeprom(void) { + return 0; +} + + + +// ��������� ������������ �������� ����������, ���������� �� EEPROM +// (� param.c � ���������� �.�. �� �� ������� ���������� ��������!) +short test_param(void) { + if ( param[180] > 2000 ) return 180;//rf.PsiZ + + if ( (param[200]<1748) || (param[200]>2348) ) return 200;//offset.Ia1 + if ( (param[201]<1748) || (param[201]>2348) ) return 201;//offset.Ib1 + if ( (param[202]<1748) || (param[202]>2348) ) return 202;//offset.Ic1 + if ( (param[203]<1748) || (param[203]>2348) ) return 203;//offset.Udc1 + if ( (param[206]<1748) || (param[206]>2348) ) return 206;//offset.Ia2 + if ( (param[207]<1748) || (param[207]>2348) ) return 207;//offset.Ib2 + if ( (param[208]<1748) || (param[208]>2348) ) return 208;//offset.Ic2 + if ( (param[209]<1748) || (param[209]>2348) ) return 209;//offset.Udc2 + + if ( param[210] > 5000 ) return 210;//cc.Kp + if ( param[211] > 5000 ) return 211;//cc.Ki + if ( param[212] > 5000 ) return 212;//cf.Kp + if ( param[213] > 5000 ) return 213;//cf.Ki + if ( param[214] > 5000 ) return 214;//csp.Kp + if ( param[215] > 5000 ) return 215;//csp.Ki + + if ( param[220] > 99 ) return 220;//protect.IacMax + if ( param[221] > 136 ) return 221;//protect.UdcMax + if ( param[222] > 200 ) return 222;//IzLim + if ( param[223] > 200 ) return 223;//cf.IdLim + if ( param[224] > 200 ) return 224;//csp.IqLim + if ( param[225] > 110 ) return 225;//protect.UdcMin + if ( param[226] > 200 ) return 226;//protect.WmMax + if ( param[228] > 200 ) return 228;//rf.WmNomPsi + if ( param[229] > 101 ) return 229;//rf.YlimPsi + if ( (param[231]<1) || (param[231]>8500) ) return 231;//protect.TudcMin + if ( (param[233]<1) || (param[233]>8500) ) return 233;//protect.TwmMax + + if ( param[244] < 1 ) return 244;//rs.WlimIncr + if ( param[245] < 1 ) return 245;//csp.IlimIncr + if ( param[248] < 1 ) return 248;//rp.PlimIncr + + if ( (param[269]<5000) || (param[269]>20000) ) return 269;//KmeCorr + + if ( (param[285]<1) || (param[285]>20000) ) return 285;//Kudc + if ( (param[286]<1) || (param[286]>20000) ) return 286;//Kwm + if ( (param[288]<1) || (param[288]>20000) ) return 288;//rs.Kwmz + if ( (param[289]<1) || (param[289]>20000) ) return 289;//rf.Kpsiz + if ( (param[290]<1) || (param[290]>20000) ) return 290;//Kme + if ( (param[292]<1) || (param[292]>20000) ) return 292;//rp.Kpmz + + return 0; +} //short test_param(void) diff --git a/Inu/detcoeff.h b/Inu/detcoeff.h new file mode 100644 index 0000000..c3465ec --- /dev/null +++ b/Inu/detcoeff.h @@ -0,0 +1,47 @@ +#ifndef DETCOEFF +#define DETCOEFF + +// ����������, ������� ���������� � detcoeff.c (begin) +//######################################################################### +//######################################################################### +// ����������, ������� ���������� � detcoeff.c (end) + + + + +// ����������, ������� ��������� � detcoeff.c (begin) +//######################################################################### +extern short testParamFaultNo; +extern struct Eprom eprom; +extern volatile short faultNo; +extern volatile short state; +extern unsigned short param[]; + +extern struct Rf rf; +extern struct Offset offset; +extern struct SgmPar sgmPar; +extern struct Cc cc; +extern struct Cf cf; +extern struct Csp csp; +extern float IzLim; +extern struct Protect protect; +extern struct Rs rs; +extern struct Rp rp; +extern float KmeCorr; +extern float Kudc; +extern float Kwm; +extern float Kme; + +extern volatile struct Out out; +extern volatile float udc1; +extern volatile float udc2; +extern volatile float wmNf; +extern volatile float wm; +extern volatile float me; +extern short onceShutdown; +extern short onceFaultReset; +extern short stopPause; +extern struct Mst mst; +//######################################################################### +// ����������, ������� ��������� � detcoeff.c (end) +#endif //DETCOEFF diff --git a/Inu/init28335.c b/Inu/init28335.c new file mode 100644 index 0000000..42dfaa5 --- /dev/null +++ b/Inu/init28335.c @@ -0,0 +1,1621 @@ +/************************************************************************** + Description: ����� �������� ���������� ������� ���������� ���� ��� + � �������������� ����������� �������� ���������� + TMS320F28335/TMS320F28379D. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.10.04 +**************************************************************************/ + + +#include "def.h" +#include "init28335.h" + + +#ifndef ML +extern void InitPll(Uint16 val, Uint16 divsel); +extern void InitPieCtrl(void); +extern void InitPieVectTable(void); +extern void ADC_cal(void); +extern void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr); +extern void InitFlash(void); +extern short CsmUnlock(void); +void InitPeripheralClocks(void); +void SetupGpio(void); +extern interrupt void isr(void); +#endif //ML +void SetupAdc(void); +void SetupEpwm(void); +void SetupEqep(void); + + +void init28335(void) { +#ifndef ML + // Global Disable all Interrupts + DINT; + // Disable CPU interrupts + IER = 0x0000; + // Clear all CPU interrupt flags + IFR = 0x0000; + + // Initialize the PLL control: PLLCR[DIV] and PLLSTS[DIVSEL] + InitPll(PLLCR_DIV, PLLSTS_DIVSEL); + + // Initialize interrupt controller and Vector Table + // to defaults for now. Application ISR mapping done later. + InitPieCtrl(); + InitPieVectTable(); + + // Initialize the peripheral clocks + InitPeripheralClocks(); + + // Ulock the CSM + csmSuccess = CsmUnlock(); + + /* Copy time critical code and Flash setup code to RAM + (the RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart, + RamfuncsLoadStart2, RamfuncsLoadEnd2 and RamfuncsRunStart2 + symbols are created by the linker) */ + MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); + MemCopy(&RamfuncsLoadStart2, &RamfuncsLoadEnd2, &RamfuncsRunStart2); + /* Copy the .switch section */ + // (the SwitchLoadStart, SwitchLoadEnd and SwitchRunStart + // symbols are created by the linker) + MemCopy(&SwitchLoadStart, &SwitchLoadEnd, &SwitchRunStart); + /* Copy the .econst section */ + // (the EconstLoadStart, EconstLoadEnd and EconstRunStart + // symbols are created by the linker) + MemCopy(&EconstLoadStart, &EconstLoadEnd, &EconstRunStart); + // Call Flash Initialization to setup flash waitstates + // (this function must reside in RAM) + InitFlash(); +#endif //ML + + // Setup ePWM + SetupEpwm(); + // Setup ADC + SetupAdc(); + // Setup eQEP + SetupEqep(); + +#ifndef ML + // Setup GPIO + SetupGpio(); + + // Reassign ISR + EALLOW; + PieVectTable.ADCINT = &isr; + EDIS; +#endif //ML +} //void init28335(void) + + + +#ifndef ML +/* This function initializes the clocks to the peripheral modules. +First the high and low clock prescalers are set +Second the clocks are enabled to each peripheral. +To reduce power, leave clocks to unused peripherals disabled + +Note: If a peripherals clock is not enabled then you cannot +read or write to the registers for that peripheral */ +void InitPeripheralClocks(void) { + EALLOW; + + // HISPCP/LOSPCP prescale register settings, normally it will be set + // to default values + // High speed clock = FSYSCLKOUT/2 + SysCtrlRegs.HISPCP.all = 0x0001; + // Low speed clock = FSYSCLKOUT/4 + SysCtrlRegs.LOSPCP.all = 0x0002; + + /* Peripheral clock enables set for the selected peripherals. + If you are not using a peripheral leave the clock off + to save on power. + + This function is not written to be an example of efficient code */ + + SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC + + /* IMPORTANT + The ADC_cal function, which copies the ADC calibration values from + TI reserved OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs + automatically in the Boot ROM. If the boot ROM code is bypassed + during the debug process, the following function MUST be called for + the ADC to function according to specification. The clocks to the + ADC MUST be enabled before calling this function. + See the device data manual and/or the ADC Reference + Manual for more information */ + ADC_cal(); + + SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0; // I2C + SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 0; // SCI-A + SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 0; // SCI-B + SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 0; // SCI-C + SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 0; // SPI-A + SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 0;// McBSP-A + SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 0;// McBSP-B + SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 0; // eCAN-A + SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 0; // eCAN-B + + SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM + SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1 + SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2 + SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3 + SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4 + SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5 + SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6 + SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM + + SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 0; // eCAP3 + SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 0; // eCAP4 + SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 0; // eCAP5 + SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 0; // eCAP6 + SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 0; // eCAP1 + SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 0; // eCAP2 + SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 0; // eQEP1 + SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2 + + SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 0; // CPU Timer 0 + SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 0; // CPU Timer 1 + SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 0; // CPU Timer 2 + + SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 0; // DMA Clock + SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK + SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock + + EDIS; +} //void InitPeripheralClocks(void) + + + +// ����������� GPIO +void SetupGpio(void) { + EALLOW; + // GPIO and Peripheral Multiplexing + // GPIO0 ... GPIO15 + GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;//EPWM1A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;//EPWM1B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;//EPWM2A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;//EPWM2B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;//EPWM3A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1;//EPWM3B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1;//EPWM4A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1;//EPWM4B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1;//EPWM5A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1;//EPWM5B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1;//EPWM6A (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1;//EPWM6B (INU) + GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;//DI + GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;//DO + GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0;//DI + GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;//DO + // GPIO16 ... GPIO31 + GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0;//DI + GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0;//DO + GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0;//DI + GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;//DO + GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;//DO + GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;//DI + GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 3;//SCITXDB + GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 3;//SCIRXDB + GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 2;//EQEP2A + GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 2;//EQEP2B + GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 2;//EQEP2I + GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0;//DI + GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;//SCIRXDA + GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;//SCITXDA + GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0;//DO + GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 3;//XA17 + // GPIO32 ... GPIO47 + GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2;//EPWMSYNCI + GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 2;//EPWMSYNCO + GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;//DO + GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 0;//DO + GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 3;//XZCS0 + GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 3;//XZCS7 + GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 3;//XWE0 + GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 3;//XA16 + GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 3;//XA0/XWE1 + GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 3;//XA1 + GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;//XA2 + GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;//XA3 + GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 3;//XA4 + GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 3;//XA5 + GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 3;//XA6 + GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 3;//XA7 + // GPIO48 ... GPIO63 + GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;//DO + GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0;//DO + GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;//DI (������������� ��������� ������� +24 �) + GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 0;//DI + GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;//DI + GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 0;//DI + GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1;//SPISIMOA + GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1;//SPISOMIA + GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1;//SPICLKA + GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 0;//DO + GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0;//DO + GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 0;//DO (������� ��������� "����������") + GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;//DO (������� ��������� "������") + GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;//DO (������� ��������� "������") + GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 1;//SCIRXDC + GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 1;//SCITXDC + // GPIO64 ... GPIO79 + GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 3;//XD15 + GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 3;//XD14 + GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 3;//XD13 + GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 3;//XD12 + GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 3;//XD11 + GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 3;//XD10 + GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 3;//XD9 + GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 3;//XD8 + GpioCtrlRegs.GPCMUX1.bit.GPIO72 = 3;//XD7 + GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 3;//XD6 + GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 3;//XD5 + GpioCtrlRegs.GPCMUX1.bit.GPIO75 = 3;//XD4 + GpioCtrlRegs.GPCMUX1.bit.GPIO76 = 3;//XD3 + GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 3;//XD2 + GpioCtrlRegs.GPCMUX1.bit.GPIO78 = 3;//XD1 + GpioCtrlRegs.GPCMUX1.bit.GPIO79 = 3;//XD0 + // GPIO80 ... GPIO87 + GpioCtrlRegs.GPCMUX2.bit.GPIO80 = 3;//XA8 + GpioCtrlRegs.GPCMUX2.bit.GPIO81 = 3;//XA9 + GpioCtrlRegs.GPCMUX2.bit.GPIO82 = 3;//XA10 + GpioCtrlRegs.GPCMUX2.bit.GPIO83 = 3;//XA11 + GpioCtrlRegs.GPCMUX2.bit.GPIO84 = 3;//XA12 + GpioCtrlRegs.GPCMUX2.bit.GPIO85 = 3;//XA13 + GpioCtrlRegs.GPCMUX2.bit.GPIO86 = 3;//XA14 + GpioCtrlRegs.GPCMUX2.bit.GPIO87 = 3;//XA15 + + // �������� ��������� �������� ������� + DO_GPIO019_CLEAR; + DO_GPIO020_CLEAR; + DO_GPIO022_CLEAR; + // ... ���������� ��������� + LED_GREEN1_OFF; + LED_GREEN2_OFF; + LED_RED_OFF; + DO_GPIO63_CLEAR; + + // Select the direction of the GPIO pins + // GPIO0 ... GPIO31 + GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO2 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO4 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO5 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO6 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO7 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO8 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO9 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO10 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO11 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO12 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO13 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO14 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO15 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO16 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO17 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO18 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO21 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO22 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO23 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO24 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO25 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO26 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO27 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO28 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO29 = 0; + GpioCtrlRegs.GPADIR.bit.GPIO30 = 1; + GpioCtrlRegs.GPADIR.bit.GPIO31 = 0; + // GPIO32 ... GPIO63 + GpioCtrlRegs.GPBDIR.bit.GPIO32 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO33 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO35 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO36 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO37 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO38 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO39 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO40 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO41 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO42 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO43 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO44 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO45 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO46 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO47 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO50 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO51 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO52 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO53 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO54 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO55 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO56 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO57 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO59 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1; + GpioCtrlRegs.GPBDIR.bit.GPIO62 = 0; + GpioCtrlRegs.GPBDIR.bit.GPIO63 = 1; + // GPIO64 ... GPIO87 + GpioCtrlRegs.GPCDIR.bit.GPIO64 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO65 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO66 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO67 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO68 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO69 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO70 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO71 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO72 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO73 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO74 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO75 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO76 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO77 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO78 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO79 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO80 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO81 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO82 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO83 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO84 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO85 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO86 = 0; + GpioCtrlRegs.GPCDIR.bit.GPIO87 = 0; + + // Each input can have different qualification: + // 0 - Synchronize to FSYSCLKOUT only; + // 1 - Qualification using 3 samples; + // 2 - Qualification using 6 samples; + // 3 - Asynchronous. + // GPIO0 ... GPIO15 + GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO2 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO4 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO8 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO9 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO11 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; + GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 0; + GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 2; + GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 0; + // GPIO16 ... GPIO31 + GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 2; + GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 2; + GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 2; + GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3; + GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3; + GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 2; + GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; + GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 3; + GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 0; + GpioCtrlRegs.GPAQSEL2.bit.GPIO31 = 0; + // GPIO32 ... GPIO47 + GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO35 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO37 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO38 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO39 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO41 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO42 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO43 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO44 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO45 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO46 = 0; + GpioCtrlRegs.GPBQSEL1.bit.GPIO47 = 0; + // GPIO48 ... GPIO63 + GpioCtrlRegs.GPBQSEL2.bit.GPIO48 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO49 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO50 = 2; + GpioCtrlRegs.GPBQSEL2.bit.GPIO51 = 2; + GpioCtrlRegs.GPBQSEL2.bit.GPIO52 = 2; + GpioCtrlRegs.GPBQSEL2.bit.GPIO53 = 2; + GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3; + GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3; + GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3; + GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3; + GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 0; + GpioCtrlRegs.GPBQSEL2.bit.GPIO62 = 2; + GpioCtrlRegs.GPBQSEL2.bit.GPIO63 = 0; + + // Qualification Control (sampling period = (1/FSYSCLKOUT)*QUALPRDx*2) + // ( (1/150e6)*255*2 = 3.4 ��� ) + // Port A + GpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 255;//GPIO0 ... GPIO7 + GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 255;//GPIO8 ... GPIO15 + GpioCtrlRegs.GPACTRL.bit.QUALPRD2 = 255;//GPIO16 ... GPIO23 + GpioCtrlRegs.GPACTRL.bit.QUALPRD3 = 255;//GPIO24 ... GPIO31 + // Port B + GpioCtrlRegs.GPBCTRL.bit.QUALPRD0 = 255;//GPIO32 ... GPIO39 + GpioCtrlRegs.GPBCTRL.bit.QUALPRD1 = 255;//GPIO40 ... GPIO47 + GpioCtrlRegs.GPBCTRL.bit.QUALPRD2 = 255;//GPIO48 ... GPIO55 + GpioCtrlRegs.GPBCTRL.bit.QUALPRD3 = 255;//GPIO56 ... GPIO63 + + // Pull-ups (the internal pullup �������� ��� ���-�������) + // GPIO0 ... GPIO31 + GpioCtrlRegs.GPAPUD.all = 0x00000FFF; + // GPIO32 ... GPIO63 + GpioCtrlRegs.GPBPUD.all = 0x00000000; + // GPIO64 ... GPIO87 + GpioCtrlRegs.GPCPUD.all = 0x00000000; + EDIS; +} //void SetupGpio(void) +#endif //ML + + + +// ����������� ePWM +void SetupEpwm(void) { + // ePWM1 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm1Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm1Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm1Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;//TBCTR==0 -> EPWMxSYNCO + EPwm1Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm1Regs.TBCTL.bit.PHSEN = 0;//do not load TBCTR from TBPHS + EPwm1Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm1Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm1Regs.TBPHS.half.TBPHS = 0; + // Time-Base Counter Register + EPwm1Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm1Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm1Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;//active CMPB load from shadow - load on CTR = Zero + EPwm1Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm1Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm1Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm1Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm1Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm1Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm1Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm1Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm1Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm1Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm1Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm1Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm1Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm1Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm1Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm1Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm1Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm1Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm1Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm1Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm1Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm1Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm1Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm1Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm1Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm1Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm1Regs.ETSEL.bit.SOCBEN = 1;//enable EPWMxSOCB pulse + EPwm1Regs.ETSEL.bit.SOCBSEL = 1;//EPWMxSOCB selection - enable event CTR == 0 + EPwm1Regs.ETSEL.bit.SOCAEN = 1;//enable EPWMxSOCA pulse + EPwm1Regs.ETSEL.bit.SOCASEL = 2;//EPWMxSOCA selection - enable event CTR == PRD + EPwm1Regs.ETSEL.bit.INTEN = 0;//disable EPWMx_INT generation + EPwm1Regs.ETSEL.bit.INTSEL = 0;//reserved + // Event-Trigger Prescale Register + EPwm1Regs.ETPS.bit.SOCBPRD = 1;//generate the EPWMxSOCB pulse on the first event + EPwm1Regs.ETPS.bit.SOCAPRD = 1;//generate the EPWMxSOCA pulse on the first event + EPwm1Regs.ETPS.bit.INTPRD = 0;//disable the interrupt event counter (no interrupt will be generated) + + // ePWM2 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm2Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm2Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm2Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm2Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm2Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm2Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm2Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm2Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm2Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm2Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm2Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm2Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm2Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm2Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm2Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm2Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm2Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm2Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm2Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm2Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm2Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm2Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm2Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm2Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm2Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm2Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm2Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm2Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm2Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm2Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm2Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm2Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm2Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm2Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm2Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm2Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm2Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm2Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm2Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm2Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm2Regs.ETPS.all = 0; + + // ePWM3 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm3Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm3Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm3Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm3Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm3Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm3Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm3Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm3Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm3Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm3Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm3Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm3Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm3Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm3Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm3Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm3Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm3Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm3Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm3Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm3Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm3Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm3Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm3Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm3Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm3Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm3Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm3Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm3Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm3Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm3Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm3Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm3Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm3Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm3Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm3Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm3Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm3Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm3Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm3Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm3Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm3Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm3Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm3Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm3Regs.ETPS.all = 0; + + // ePWM4 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm4Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm4Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm4Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm4Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm4Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm4Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm4Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm4Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm4Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm4Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm4Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm4Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm4Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm4Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm4Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm4Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm4Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm4Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm4Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm4Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm4Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm4Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm4Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm4Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm4Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm4Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm4Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm4Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm4Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm4Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm4Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm4Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm4Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm4Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm4Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm4Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm4Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm4Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm4Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm4Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm4Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm4Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm4Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm4Regs.ETPS.all = 0; + + // ePWM5 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm5Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm5Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm5Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm5Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm5Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm5Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm5Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm5Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm5Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm5Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm5Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm5Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm5Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm5Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm5Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm5Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm5Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm5Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm5Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm5Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm5Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm5Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm5Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm5Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm5Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm5Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm5Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm5Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm5Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm5Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm5Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm5Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm5Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm5Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm5Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm5Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm5Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm5Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm5Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm5Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm5Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm5Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm5Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm5Regs.ETPS.all = 0; + + // ePWM6 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm6Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm6Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm6Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm6Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm6Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm6Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm6Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm6Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm6Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm6Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm6Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm6Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm6Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm6Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm6Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm6Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm6Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm6Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm6Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm6Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm6Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm6Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm6Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm6Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm6Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm6Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm6Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm6Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm6Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm6Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm6Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm6Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm6Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm6Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm6Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm6Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm6Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm6Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm6Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm6Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm6Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm6Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm6Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm6Regs.ETPS.all = 0; + +#ifdef ML + // ePWM7 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm7Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm7Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm7Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm7Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm7Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm7Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm7Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm7Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm7Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm7Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm7Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm7Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm7Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm7Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm7Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm7Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm7Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm7Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm7Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm7Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm7Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm7Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm7Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm7Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm7Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm7Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm7Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm7Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm7Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm7Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm7Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm7Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm7Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm7Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm7Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm7Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm7Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm7Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm7Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm7Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm7Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm7Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm7Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm7Regs.ETPS.all = 0; + + // ePWM8 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm8Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm8Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm8Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm8Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm8Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm8Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm8Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm8Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm8Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm8Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm8Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm8Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm8Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm8Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm8Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm8Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm8Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm8Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm8Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm8Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm8Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm8Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm8Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm8Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm8Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm8Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm8Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm8Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm8Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm8Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm8Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm8Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm8Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm8Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm8Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm8Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm8Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm8Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm8Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm8Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm8Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm8Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm8Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm8Regs.ETPS.all = 0; + + // ePWM9 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm9Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm9Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm9Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm9Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm9Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm9Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm9Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm9Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm9Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm9Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm9Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm9Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm9Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm9Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm9Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm9Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm9Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm9Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm9Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm9Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm9Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm9Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm9Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm9Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm9Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm9Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm9Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm9Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm9Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm9Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm9Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm9Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm9Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm9Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm9Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm9Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm9Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm9Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm9Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm9Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm9Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm9Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm9Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm9Regs.ETPS.all = 0; + + // ePWM10 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm10Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm10Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm10Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm10Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm10Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm10Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm10Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm10Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm10Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm10Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm10Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm10Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm10Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm10Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm10Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm10Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm10Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm10Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm10Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm10Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm10Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm10Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm10Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm10Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm10Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm10Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm10Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm10Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm10Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm10Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm10Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm10Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm10Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm10Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm10Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm10Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm10Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm10Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm10Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm10Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm10Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm10Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm10Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm10Regs.ETPS.all = 0; + + // ePWM11 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm11Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm11Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm11Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm11Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm11Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm11Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm11Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm11Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm11Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm11Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm11Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm11Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm11Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm11Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm11Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm11Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm11Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm11Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm11Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm11Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high + EPwm11Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low + EPwm11Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm11Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm11Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm11Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm11Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm11Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm11Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm11Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm11Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm11Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm11Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm11Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm11Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm11Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm11Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm11Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm11Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm11Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm11Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm11Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm11Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm11Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm11Regs.ETPS.all = 0; + + // ePWM12 + // #################################################################### + // Time-Base (TB) Submodule + // -------------------------------------------------------------------- + // Time-Base Control Register + EPwm12Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement + EPwm12Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event + EPwm12Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm12Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) + EPwm12Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI + EPwm12Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register + EPwm12Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs + EPwm12Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation + // Time-Base Period Register + EPwm12Regs.TBPRD = (unsigned short)T1_PRD; + // Time-Base Phase Register + EPwm12Regs.TBPHS.half.TBPHS = 2; + // Time-Base Counter Register + EPwm12Regs.TBCTR = 1; + // Counter-Compare (CC) Submodule + // -------------------------------------------------------------------- + // Counter-Compare A Register + EPwm12Regs.CMPA.half.CMPA = 0; + // Counter-Compare B Register + EPwm12Regs.CMPB = 0; + // Counter-Compare Control Register + EPwm12Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow + EPwm12Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow + EPwm12Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode + EPwm12Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD + // Action-Qualifier (AQ) Submodule + // -------------------------------------------------------------------- + // Action-Qualifier Output A Control Register + EPwm12Regs.AQCTLA.bit.CBD = 0;//do nothing + EPwm12Regs.AQCTLA.bit.CBU = 0;//do nothing + EPwm12Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low + EPwm12Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high + EPwm12Regs.AQCTLA.bit.PRD = 0;//do nothing + EPwm12Regs.AQCTLA.bit.ZRO = 0;//do nothing + // Action-Qualifier Output B Control Register + EPwm12Regs.AQCTLB.bit.CBD = 0;//do nothing + EPwm12Regs.AQCTLB.bit.CBU = 0;//do nothing + EPwm12Regs.AQCTLB.bit.CAD = 0;//do nothing + EPwm12Regs.AQCTLB.bit.CAU = 0;//do nothing + EPwm12Regs.AQCTLB.bit.PRD = 0;//do nothing + EPwm12Regs.AQCTLB.bit.ZRO = 0;//do nothing + // Action-Qualifier Software Force Register + EPwm12Regs.AQSFRC.all = 0; + // Action-Qualifier Continuous Software Force Register + EPwm12Regs.AQCSFRC.all = 0; + // Dead-Band Generator (DB) Submodule + // -------------------------------------------------------------------- + // Dead-Band Generator Control Register + EPwm12Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay + EPwm12Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode + EPwm12Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB + // Dead-Band Generator Rising Edge Delay Register + EPwm12Regs.DBRED = (unsigned short)(FTBCLK*DT); + // Dead-Band Generator Falling Edge Delay Register + EPwm12Regs.DBFED = (unsigned short)(FTBCLK*DT); + // PWM-Chopper (PC) Submodule + // -------------------------------------------------------------------- + // PWM-Chopper Control Register + EPwm12Regs.PCCTL.all = 0; + // Trip-Zone (TZ) Submodule + // -------------------------------------------------------------------- + EALLOW; + // Trip-Zone Select Register + EPwm12Regs.TZSEL.all = 0; + // Trip-Zone Control Register + EPwm12Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state + EPwm12Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state + // Trip-Zone Enable Interrupt Register + EPwm12Regs.TZEINT.all = 0; + // Trip-Zone Force Register + EPwm12Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit + EDIS; + // Event-Trigger (ET) Submodule + // -------------------------------------------------------------------- + // Event-Trigger Selection Register + EPwm12Regs.ETSEL.all = 0; + // Event-Trigger Prescale Register + EPwm12Regs.ETPS.all = 0; +#endif //ML +} //void SetupEpwm(void) + + + +// ����������� ADC +void SetupAdc(void) { +#ifndef ML + unsigned short i; + + // ADC Control Register 1 + AdcRegs.ADCTRL1.bit.SUSMOD = 0;//emulation suspend is ignored + AdcRegs.ADCTRL1.bit.ACQ_PS = 3;//width of SOC pulse is (ACQ_PS+1) times the ADCLK period + AdcRegs.ADCTRL1.bit.CPS = 0;//ADCCLK = HSPCLK/(2*ADCCLKPS*(CPS+1)) + AdcRegs.ADCTRL1.bit.CONT_RUN = 0;//start-stop mode + AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0;//sequencer override disabled + AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;//cascaded mode + + // ADC Control Register 2 + AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ = 1;//allows SEQ to be started by ePWMx SOCB trigger + AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0;//clears a pending SOC trigger + AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//interrupt request by INT_SEQ1 is enabled + AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;//INT_SEQ1 is set at the end of every SEQ1 sequence + AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;//allows SEQ1/SEQ to be started by ePWMx SOCA trigger + AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1 = 0;//disables an ADC autoconversion sequence to be started by a signal from a GPIO Port A pin + AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 0;//clears a pending SOC trigger + AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = 0;//interrupt request by INT_SEQ2 is disabled + AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2 = 0;//INT_SEQ2 is set at the end of every SEQ2 sequence + AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2 = 0;//SEQ2 cannot be started by ePWMx SOCB trigger + + /* The ADC resets to the ADC off state. When powering up the ADC, use + the following sequence: + 1. If external reference is desired, enable this mode using bits + 15-14 in the ADCREFSEL Register. This mode must be enabled before + band gap is powered; + 2. Power up the reference, bandgap, and analog circuits together by + setting bits 7-5 (ADCBGRFDN[1:0], ADCPWDN) in the ADCTRL3 register; + 3. Before performing the first conversion, a delay of 5 ms is required */ + + // ADC Reference Select Register + AdcRegs.ADCREFSEL.bit.REF_SEL = 1;//external reference, 2.048 V on ADCREFIN + + // ADC Control Register 3 + AdcRegs.ADCTRL3.all = 0x00E0;//power up the reference, bandgap, and analog circuits together + AdcRegs.ADCTRL3.bit.ADCCLKPS = 5;//ADCCLK = HSPCLK/(2*ADCCLKPS*(CPS+1)) -> ADCCLK = 75e6/(2*5*(0+1)) = 7.5e6 �� + AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;//simultaneous sampling mode + + // Delay before converting ADC channels + for ( i = 0; i < 65500; i++ ) + ; +#endif //ML + + // Maximum Conversion Channels Register + AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 5;//6 double conv's (12 total) + // ADC Input Channel Select Sequencing Control Registers + AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; + AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; + AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; + AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; + AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4; + AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5; + AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6; + AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7; + AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0; + AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0; + AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0; + AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0; + AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0; + AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0; + AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0; + AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0; +} //void SetupAdc(void) + + + +// ����������� eQEP +void SetupEqep(void) { + // eQEP Decoder Control Register + EQep2Regs.QDECCTL.bit.QSRC = 0;//Position-counter source selection: Quadrature count mode (QCLK = iCLK, QDIR = iDIR) + EQep2Regs.QDECCTL.bit.SOEN = 0;//Sync output-enable: Disable position-compare sync output + EQep2Regs.QDECCTL.bit.SPSEL = 0;//Sync output pin selection: Index pin is used for sync output + EQep2Regs.QDECCTL.bit.XCR = 0;//External clock rate: 2x resolution: Count the rising/falling edge + EQep2Regs.QDECCTL.bit.SWAP = 0;//Swap quadrature clock inputs: Quadrature-clock inputs are not swapped + EQep2Regs.QDECCTL.bit.IGATE = 0;//Index pulse gating option: Disable gating of Index pulse + EQep2Regs.QDECCTL.bit.QAP = 0;//QEPA input polarity: No effect + EQep2Regs.QDECCTL.bit.QBP = 0;//QEPB input polarity: No effect + EQep2Regs.QDECCTL.bit.QIP = 0;//QEPI input polarity: No effect + EQep2Regs.QDECCTL.bit.QSP = 0;//QEPS input polarity: No effect + // eQEP Control Register + EQep2Regs.QEPCTL.bit.FREE_SOFT = 0;//Emulation Control Bits: all stops immediately + EQep2Regs.QEPCTL.bit.PCRM = 1;//Position counter reset mode: position counter reset on the maximum position + EQep2Regs.QEPCTL.bit.SEI = 0;//Strobe event initialization of position counter: does nothing (action disabled) + EQep2Regs.QEPCTL.bit.IEI = 0;//Index event initialization of position counter: do nothing (action disabled) + EQep2Regs.QEPCTL.bit.SWI = 0;//Software initialization of position counter: do nothing (action disabled) + EQep2Regs.QEPCTL.bit.SEL = 0;//Strobe event latch of position counter: the position counter is latched on the rising edge of QEPS strobe + EQep2Regs.QEPCTL.bit.IEL = 1;//Index event latch of position counter (software index marker): latches position counter on rising edge of the index signal + EQep2Regs.QEPCTL.bit.QPEN = 1;//Quadrature position counter enable/software reset: eQEP position counter is enabled + EQep2Regs.QEPCTL.bit.QCLM = 0;//eQEP capture latch mode: latch on position counter read by CPU + EQep2Regs.QEPCTL.bit.UTE = 1;//eQEP unit timer enable: Enable unit timer + EQep2Regs.QEPCTL.bit.WDE = 0;//eQEP watchdog enable: disable the eQEP watchdog timer + // eQEP Position-compare Control Register + EQep2Regs.QPOSCTL.bit.PCSHDW = 0;//Position-compare shadow enable: Shadow disabled, load Immediate + EQep2Regs.QPOSCTL.bit.PCLOAD = 0;//Position-compare shadow load mode: Load on QPOSCNT = 0 + EQep2Regs.QPOSCTL.bit.PCPOL = 0;//Polarity of sync output: Active HIGH pulse output + EQep2Regs.QPOSCTL.bit.PCE = 0;//Position-compare enable/disable: Disable position compare unit + EQep2Regs.QPOSCTL.bit.PCSPW = 0;//Select-position-compare sync output pulse width: 1 * 4 * SYSCLKOUT cycles + // eQEP Capture Control Register + EQep2Regs.QCAPCTL.bit.CEN = 1;//Enable eQEP capture: eQEP capture unit is enabled + EQep2Regs.QCAPCTL.bit.CCPS = 2;//eQEP capture timer clock prescaler: CAPCLK = SYSCLKOUT/4 + EQep2Regs.QCAPCTL.bit.UPPS = 0;//Unit position event prescaler: UPEVNT = QCLK/1 + // eQEP Position Counter Register + EQep2Regs.QPOSCNT = 0x00000000; + // eQEP Maximum Position Count Register Register + EQep2Regs.QPOSMAX = 0x7FFF; + // eQEP Position-compare Register + EQep2Regs.QPOSCMP = 0x00000000; + // eQEP Unit Timer Register + EQep2Regs.QUTMR = 0x00000000; + // eQEP Register Unit Period Register + EQep2Regs.QUPRD = 0x00000000; + // eQEP Watchdog Timer Register + EQep2Regs.QWDTMR = 0x0000; + // eQEP Watchdog Period Register + EQep2Regs.QWDPRD = 0x0000; + // eQEP Interrupt Enable Register + EQep2Regs.QEINT.all = 0x0000; + // eQEP Capture Timer Register + EQep2Regs.QCTMR = 0x0000; + // eQEP Capture Period Register + EQep2Regs.QCPRD = 0x0000; +} //void SetupEqep(void) diff --git a/Inu/init28335.h b/Inu/init28335.h new file mode 100644 index 0000000..d75c3cf --- /dev/null +++ b/Inu/init28335.h @@ -0,0 +1,24 @@ +#ifndef INIT28335 +#define INIT28335 + +// ����������, ������� ���������� � init28335.c (begin) +//######################################################################### +//######################################################################### +// ����������, ������� ���������� � init28335.c (end) + + + + +// ����������, ������� ��������� � init28335.c (begin) +//######################################################################### +#ifndef ML +extern Uint16 RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart; +extern Uint16 RamfuncsLoadStart2, RamfuncsLoadEnd2, RamfuncsRunStart2; +extern Uint16 SwitchLoadStart, SwitchLoadEnd, SwitchRunStart; +extern Uint16 EconstLoadStart, EconstLoadEnd, EconstRunStart; +extern short csmSuccess; +#endif //ML +//######################################################################### +// ����������, ������� ��������� � init28335.c (end) + +#endif //INIT28335 diff --git a/Inu/isr.c b/Inu/isr.c new file mode 100644 index 0000000000000000000000000000000000000000..9f6f1624f99fcfafd11d78d5178c1634ab5a3b57 GIT binary patch literal 11865 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 HPM`WOPi<*D literal 0 HcmV?d00001 diff --git a/Inu/isr.h b/Inu/isr.h new file mode 100644 index 0000000..f0a8d7a --- /dev/null +++ b/Inu/isr.h @@ -0,0 +1,72 @@ +#ifndef ISR +#define ISR + +// ����������, ������� ���������� � isr.c (begin) +//######################################################################### +struct Offset offset; +volatile struct Result result; +volatile short state; +volatile short faultNo; +volatile struct Out out; +// Udc +float Kudc; +volatile float udc1Nf; +volatile float udc1; +volatile float udc2Nf; +volatile float udc2; +// Iac +volatile float ia1Nf; +volatile float ib1Nf; +volatile float ic1Nf; +volatile float ix1; +volatile float iy1; +volatile float iac1Nf; +volatile float ia2Nf; +volatile float ib2Nf; +volatile float ic2Nf; +volatile float ix2; +volatile float iy2; +volatile float iac2Nf; +// Wm +float Kwm; +volatile float wmNf; +volatile float wm; +volatile float wmAbs; +// Me +volatile float kMe; +float KmeCorr; +float Kme; +volatile float meNf; +volatile float me; +// Pm +volatile float pm; +// ������ +struct Protect protect; +volatile struct Emerg emerg; +short csmSuccess; +// ����������� ������ +volatile short onceShutdown; +volatile short testParamFaultNo; +volatile short onceFaultReset; +volatile short stopPause; +volatile short inuWork; +// ����� +struct Mst mst; +//######################################################################### +// ����������, ������� ���������� � isr.c (end) + + + + +// ����������, ������� ��������� � isr.c (begin) +//######################################################################### +extern struct SgmPar sgmPar; +extern unsigned short param[]; +extern volatile short onceUpr; +extern volatile float psi; +extern float iq1; +extern float iq2; +extern struct Rp rp; +//######################################################################### +// ����������, ������� ��������� � isr.c (end) +#endif //ISR diff --git a/Inu/main.c b/Inu/main.c new file mode 100644 index 0000000..05cade6 --- /dev/null +++ b/Inu/main.c @@ -0,0 +1,144 @@ +/************************************************************************** + Description: ��������� ���������� INU. + �������� �/� ������������� ���������� � �/� ������. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.10.05 +**************************************************************************/ + + +#include "def.h" +#include "main.h" + + +void control_processor_led(void); +void talk_with_desk(void); +void talk_with_mst(void); +void write_eeprom(void); +extern void detcoeff(void); +extern void init28335(void); + + +#ifndef ML +void main(void) { + // disable the watchdog + EALLOW; + SysCtrlRegs.WDCR = 0x0068; + EDIS; + + // ������������� ���������� + init28335(); + + // ������������� ��������� + detcoeff(); + + // re-enable the watchdog + EALLOW; + SysCtrlRegs.WDCR = 0x00A8; + // ... clear the WD counter + SysCtrlRegs.WDKEY = 0x55; + SysCtrlRegs.WDKEY = 0xAA; + EDIS; + + // clear Interrupt Flag ADC Sequencer 1 + AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; + // clear PIEIFR1 register + PieCtrlRegs.PIEIFR1.all = 0; + + // before we can start we have to enable interrupt mask in the PIE unit + PieCtrlRegs.PIEIER1.bit.INTx6 = 1; + // core line 1 (INT1) + IER |= M_INT1; + // enable global interrupts and higher priority real-time debug events + EINT; + ERTM; + + // ��������� ������� (up-down-count mode) + EPwm1Regs.TBCTL.bit.CTRMODE = 2; + EPwm2Regs.TBCTL.bit.CTRMODE = 2; + EPwm3Regs.TBCTL.bit.CTRMODE = 2; + EPwm4Regs.TBCTL.bit.CTRMODE = 2; + EPwm5Regs.TBCTL.bit.CTRMODE = 2; + EPwm6Regs.TBCTL.bit.CTRMODE = 2; +#ifdef ML + EPwm7Regs.TBCTL.bit.CTRMODE = 2; + EPwm8Regs.TBCTL.bit.CTRMODE = 2; + EPwm9Regs.TBCTL.bit.CTRMODE = 2; + EPwm10Regs.TBCTL.bit.CTRMODE = 2; + EPwm11Regs.TBCTL.bit.CTRMODE = 2; + EPwm12Regs.TBCTL.bit.CTRMODE = 2; +#endif + + // loop forever + while(1) { + // ����� � �� + // ( -> mst) + talk_with_mst(); + // ����� � �� + // ( -> param[], eprom.writeRequestNumber) + talk_with_desk(); + // ������ � EEPROM + // (param[], eprom.writeRequestNumber -> eprom.writeRequestNumber) + if ( eprom.writeRequestNumber > 0 ) { + write_eeprom(); + } + + // ��������� ������������ �� ������������ ����� + control_processor_led(); + } //while(1) +} //void main(void) + + + +// ��������� ������������ �� ������������ ����� +void control_processor_led(void) { + static unsigned short Tled = (unsigned short)(0.5/TY); + static unsigned short tLed = 0; + + if ( tLed < Tled ) { + tLed++; + } + else { + tLed = 1; + // � ��������� ���. ������� ������� ����������� + if ( state == STATE_SHUTDOWN ) { + LED_GREEN1_OFF; + LED_GREEN2_OFF; + LED_RED_TOGGLE; + } + // � ���. ��������� ������� ������ ������ ����������� + else if ( state == STATE_STOP ) { + LED_GREEN1_TOGGLE; + LED_GREEN2_OFF; + LED_RED_OFF; + } + // � ������� ���. ������� ������ ������ ����������� + else { + LED_GREEN1_OFF; + LED_GREEN2_TOGGLE; + LED_RED_OFF; + } + } +} //void control_processor_led(void) + + + +// �������� ��������� � �� +// ( -> param[], eprom.writeRequestNumber) +void talk_with_desk(void) { +} + + + +// �������� ������� � �� +// ( -> mst) +void talk_with_mst(void) { +} + + + +// ���������� ��������� � EEPROM +// (param[], eprom.writeRequestNumber -> eprom.writeRequestNumber) +void write_eeprom(void) { +} +#endif //ML diff --git a/Inu/main.h b/Inu/main.h new file mode 100644 index 0000000..f93fa02 --- /dev/null +++ b/Inu/main.h @@ -0,0 +1,17 @@ +#ifndef MAIN +#define MAIN + +// ����������, ������� ���������� � main.c (begin) +//######################################################################### +struct Eprom eprom; +//######################################################################### +// ����������, ������� ���������� � main.c (end) + + + +// ����������, ������� ��������� � main.c (begin) +//######################################################################### +extern volatile short state; +//######################################################################### +// ����������, ������� ��������� � main.c (end) +#endif //MAIN diff --git a/Inu/param.c b/Inu/param.c new file mode 100644 index 0000000..4ebbffa --- /dev/null +++ b/Inu/param.c @@ -0,0 +1,426 @@ +/************************************************************************** + Description: ������� ��� ����� � ������ ����������. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.11.08 +**************************************************************************/ + + +#include "def.h" +#include "param.h" + + +#pragma CODE_SECTION(input_param, "ramfuncs"); +#pragma CODE_SECTION(output_param, "ramfuncs"); + + +extern short test_param(void); +extern void process_sgm_parameters(void); + + +// �������� �������� ��������� +void input_param(unsigned short num, unsigned short val) { + switch ( num ) { + case 180://rf.PsiZ, %*10 �� PSI_BAZ + if ( (val <= 2000) && (val != param[num]) ) { + param[num] = val; + rf.PsiZ = (float)val*0.001;//%*10 -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 200://offset.Ia1, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ia1 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 201://offset.Ib1, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ib1 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 202://offset.Ic1, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ic1 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 203://offset.Udc1, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Udc1 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 206://offset.Ia2, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ia2 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 207://offset.Ib2, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ib2 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 208://offset.Ic2, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Ic2 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 209://offset.Udc2, ��. ��� + if ( (val >= 1748) && (val <= 4096) && (val != param[num]) ) { + offset.Udc2 = param[num] = val; + eprom.writeRequestNumber += 1; + } + break; + case 210://cc.Kp, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + cc.Kp = (float)val*cc.KpOrig; + eprom.writeRequestNumber += 1; + } + break; + case 211://cc.Ki, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + cc.Ki = (float)val*cc.KiOrig; + eprom.writeRequestNumber += 1; + } + break; + case 212://cf.Kp, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + cf.Kp = (float)val*cf.KpOrig; + eprom.writeRequestNumber += 1; + } + break; + case 213://cf.Ki, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + cf.Ki = (float)val*cf.KiOrig; + eprom.writeRequestNumber += 1; + } + break; + case 214://csp.Kp, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + csp.Kp = (float)val*csp.KpOrig; + eprom.writeRequestNumber += 1; + } + break; + case 215://csp.Ki, % + if ( (val <= 5000) && (val != param[num]) ) { + param[num] = val; + csp.Ki = (float)val*csp.KiOrig; + eprom.writeRequestNumber += 1; + } + break; + case 220://protect.IacMax, % �� IAC_SENS_MAX + if ( (val <= 99) && (val != param[num]) ) { + param[num] = val; + protect.IacMax = (short)(2047.*(float)val*0.01);//% -> ��. ��� + protect.IacMin = -protect.IacMax; + eprom.writeRequestNumber += 1; + } + break; + case 221://protect.UdcMax, % �� U_NOM + if ( (val <= 136) && (val != param[num]) ) { + param[num] = val; + protect.UdcMax = (float)val*0.01;//% -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 222://IzLim, % �� I_BAZ + if ( (val <= 200) && (val != param[num]) ) { + param[num] = val; + IzLim = (float)val*0.01;//% -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 223://cf.IdLim, % �� I_BAZ + if ( (val <= 200) && (val != param[num]) ) { + param[num] = val; + cf.IdLim = (float)val*0.01;//% -> o.e. + cf.IdLimNeg = cf.IdLim*(-0.4); + eprom.writeRequestNumber += 1; + } + break; + case 224://csp.IqLim, % �� I_BAZ + if ( (val <= 200) && (val != param[num]) ) { + param[num] = val; + csp.IqLim = (float)val*0.01;//% -> o.e. + csp.IqLimNeg = -csp.IqLim; + eprom.writeRequestNumber += 1; + } + break; + case 225://protect.UdcMin, % �� U_NOM + if ( (val <= 110) && (val != param[num]) ) { + param[num] = val; + protect.UdcMin = (float)val*0.01;//% -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 226://protect.WmMax, % �� N_NOM + if ( (val <= 200) && (val != param[num]) ) { + param[num] = val; + protect.WmMax = (float)val*0.01;//% -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 228://rf.WmNomPsi, % �� N_NOM + if ( (val <= 200) && (val != param[num]) ) { + param[num] = val; + rf.WmNomPsi = (float)val*0.01;//% -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 229://rf.YlimPsi, % �� Y_LIM + if ( (val <= 101) && (val != param[num]) ) { + param[num] = val; + rf.YlimPsi = (float)val*0.01*Y_LIM;//% -> ��. �������� ������� + eprom.writeRequestNumber += 1; + } + break; + case 231://protect.TudcMin, �� + if ( (val >= 1) && (val <= 8500) && (val != param[num]) ) { + param[num] = val; + protect.TudcMin = (unsigned short)((float)val*0.001/TY); + eprom.writeRequestNumber += 1; + } + break; + case 233://protect.TwmMax, �� + if ( (val >= 1) && (val <= 8500) && (val != param[num]) ) { + param[num] = val; + protect.TwmMax = (unsigned short)((float)val*0.001/TY); + eprom.writeRequestNumber += 1; + } + break; + case 244://rs.WlimIncr, �� + if ( (val >= 1) && (val != param[num]) ) { + param[num] = val; + // ���. �� 1.0 �� �������-�� �� + rs.WlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)val*0.001); + eprom.writeRequestNumber += 1; + } + break; + case 245://csp.IlimIncr, �� + if ( (val >= 1) && (val != param[num]) ) { + param[num] = val; + // ���. �� I_BAZ �� �������-�� �� + csp.IlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)val*0.001); + eprom.writeRequestNumber += 1; + } + break; + case 248://rp.PlimIncr, �� + if ( (val >= 1) && (val != param[num]) ) { + param[num] = val; + // ���. �� 1.0 �� �������-�� �� + rp.PlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)val*0.001); + eprom.writeRequestNumber += 1; + } + break; + case 269://KmeCorr, %*100 + if ( (val >= 5000) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + KmeCorr = (float)val*0.0001;//%*100 -> o.e. + eprom.writeRequestNumber += 1; + } + break; + case 285://Kudc, ��*10 + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + Kudc = (TY*10000.)/(float)val; + if ( Kudc > 1.0 ) + Kudc = 1.0; + eprom.writeRequestNumber += 1; + } + break; + case 286://Kwm, ��*10 + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + Kwm = (TY*10000.)/(float)val; + if ( Kwm > 1.0 ) + Kwm = 1.0; + eprom.writeRequestNumber += 1; + } + break; + case 288://rs.Kwmz, �� + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + rs.Kwmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)val; + eprom.writeRequestNumber += 1; + } + break; + case 289://rf.Kpsiz, �� + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + rf.Kpsiz = (TY*DECIM_PSI_WM_PM*1000.)/(float)val; + eprom.writeRequestNumber += 1; + } + break; + case 290://Kme, �� + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + Kme = (TY*1000.)/(float)val; + eprom.writeRequestNumber += 1; + } + break; + case 292://rp.Kpmz, �� + if ( (val >= 1) && (val <= 20000) && (val != param[num]) ) { + param[num] = val; + rp.Kpmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)val; + eprom.writeRequestNumber += 1; + } + break; + case 303://sgmPar.Rs, ���� + if ( val != param[num] ) { + param[num] = val; + sgmPar.Rs = (float)val*1e-6;//���� -> �� + eprom.writeRequestNumber += 1; + } + break; + case 304://sgmPar.Lls, ����*10 + if ( val != param[num] ) { + param[num] = val; + sgmPar.Lls = (float)val*1e-7;//����*10 -> �� + process_sgm_parameters(); + eprom.writeRequestNumber += 1; + } + break; + case 305://sgmPar.Rr, ���� + if ( val != param[num] ) { + param[num] = val; + sgmPar.Rr = (float)val*1e-6;//���� -> �� + process_sgm_parameters(); + eprom.writeRequestNumber += 1; + } + break; + case 306://sgmPar.Llr, ����*10 + if ( val != param[num] ) { + param[num] = val; + sgmPar.Llr = (float)val*1e-7;//����*10 -> �� + process_sgm_parameters(); + eprom.writeRequestNumber += 1; + } + break; + case 307://sgmPar.Lm, ���� + if ( val != param[num] ) { + param[num] = val; + sgmPar.Lm = (float)val*1e-6;//���� -> �� + process_sgm_parameters(); + eprom.writeRequestNumber += 1; + } + break; + default: + if ( num < PAR_NUMBER ) { + param[num] = val; + } + break; + } //switch ( num ) +} //void input_param(unsigned short num, unsigned short val) + + + +// ����� �������� ��������� +unsigned short output_param(unsigned short num) { + static unsigned short output; + + switch ( num ) { + case 1: //udc1, o.e. -> o.e.*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + output = (unsigned short)(emerg.udc1*CONTROLLER_GAIN); + } + else { + output = (unsigned short)(out.udc1*CONTROLLER_GAIN); + } + break; + case 2: //udc2, o.e. -> o.e.*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + output = (unsigned short)(emerg.udc2*CONTROLLER_GAIN); + } + else { + output = (unsigned short)(out.udc2*CONTROLLER_GAIN); + } + break; + case 5: //iac1, o.e. -> o.e.*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + output = (unsigned short)(emerg.iac1*CONTROLLER_GAIN); + } + else { + output = (unsigned short)(out.iac1*CONTROLLER_GAIN); + } + break; + case 6: //iac2, o.e. -> o.e.*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + output = (unsigned short)(emerg.iac2*CONTROLLER_GAIN); + } + else { + output = (unsigned short)(out.iac2*CONTROLLER_GAIN); + } + break; + case 7: //me, o.e. -> (o.e. + CONTROLLER_BIAS)*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + if ( emerg.me > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( emerg.me > -CONTROLLER_BIAS ) + output = (unsigned short)((emerg.me + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + else { + if ( out.me > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( out.me > -CONTROLLER_BIAS ) + output = (unsigned short)((out.me + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + break; + case 8: //nm, o.e. -> (o.e. + CONTROLLER_BIAS)*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + if ( emerg.wm > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( emerg.wm > -CONTROLLER_BIAS ) + output = (unsigned short)((emerg.wm + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + else { + if ( out.wm > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( out.wm > -CONTROLLER_BIAS ) + output = (unsigned short)((out.wm + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + break; + case 9: //pm, o.e. -> (o.e. + CONTROLLER_BIAS)*CONTROLLER_GAIN + if ( state == STATE_SHUTDOWN ) { + if ( emerg.pm > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( emerg.pm > -CONTROLLER_BIAS ) + output = (unsigned short)((emerg.pm + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + else { + if ( out.pm > CONTROLLER_BIAS ) + output = (unsigned short)((CONTROLLER_BIAS + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else if ( out.pm > -CONTROLLER_BIAS ) + output = (unsigned short)((out.pm + CONTROLLER_BIAS)*CONTROLLER_GAIN); + else + output = 0; + } + break; + case 10: //compound + output = faultNo + (inuWork<<7); + break; + default: + output = param[num]; + break; + } //switch ( num ) + return output; +} //unsigned short output_param(unsigned short num) diff --git a/Inu/param.h b/Inu/param.h new file mode 100644 index 0000000..9dc480e --- /dev/null +++ b/Inu/param.h @@ -0,0 +1,41 @@ +#ifndef PARAM +#define PARAM + +// ����������, ������� ���������� � param.c (begin) +//######################################################################### +unsigned short param[PAR_NUMBER]; +//######################################################################### +// ����������, ������� ���������� � param.c (end) + + + + +// ����������, ������� ��������� � param.c (begin) +//######################################################################### +extern volatile short state; +extern volatile short faultNo; +extern short onceFaultReset; +extern struct SgmPar sgmPar; +extern struct Offset offset; +extern float Kudc; +extern float Kwm; +extern short testParamFaultNo; +extern float IzLim; +extern float Kme; +extern struct Protect protect; +extern float KmeCorr; +extern volatile struct Out out; +extern volatile struct Emerg emerg; +extern struct Rf rf; +extern struct Rs rs; +extern struct Rp rp; +extern struct Cf cf; +extern struct Csp csp; +extern struct Cc cc; +// ��� �������� �� �� +extern volatile short inuWork; +// ��� ������ � EEPROM +extern struct Eprom eprom; +//######################################################################### +// ����������, ������� ��������� � param.c (end) +#endif //PARAM diff --git a/Inu/upr.c b/Inu/upr.c new file mode 100644 index 0000000..6d48221 --- /dev/null +++ b/Inu/upr.c @@ -0,0 +1,974 @@ +/************************************************************************** + Description: ������� ��������� �������� ���������� INU + (��������� N � P). + + �����: ���������� �.�. + ���� ���������� ����������: 2021.11.08 +**************************************************************************/ + + +#include "def.h" +#include "upr.h" +#include "pwm_vector_regul.h" +#include "IQmathLib.h" +#include "adc_tools.h" +#include "params.h" +#include "vector.h" +#include "v_pwm24.h" +#include "xp_write_xpwm_time.h" +#include "rotation_speed.h" + + +#pragma CODE_SECTION(control_current, "ramfuncs"); +#pragma CODE_SECTION(control_flux, "ramfuncs"); +#pragma CODE_SECTION(control_speed_power, "ramfuncs"); +#pragma CODE_SECTION(indirect_vector_control, "ramfuncs"); +#pragma CODE_SECTION(ipark, "ramfuncs"); +#pragma CODE_SECTION(limit_current, "ramfuncs2"); +#pragma CODE_SECTION(pwm, "ramfuncs2"); +#pragma CODE_SECTION(reference_flux, "ramfuncs"); +#pragma CODE_SECTION(reference_power, "ramfuncs"); +#pragma CODE_SECTION(reference_speed, "ramfuncs"); +#pragma CODE_SECTION(select_feedback, "ramfuncs"); +#pragma CODE_SECTION(upr, "ramfuncs"); + + +void control_current(void); +void control_flux(void); +void control_speed_power(void); +void indirect_vector_control(void); +void ipark(void); +void limit_current(void); +void pwm(void); +void reference_flux(void); +void reference_power(void); +void reference_speed(void); +void select_feedback(void); + +void write_swgen_pwm_times_split_eages(void); +void write_CMP_tims(void); + +int reset = 1; +extern double wm_ml; + +void upr(void) { + static short decim_psi_wm_pm; + static int calcPWMtimes = 0; + + if ( onceUpr == 0 ) { + onceUpr = 1; + decim_psi_wm_pm = (short)DECIM_PSI_WM_PM; + psi = 0; + rf.once = 0; + rs.once = 0; + rp.once = 0; + cf.once = 0; + csp.once = 0; + ivc.once = 0; + cc.once = 0; + reset = 1; + init_DQ_pid(); + InitVariablesSvgen(FREQ_PWM); + pwm_vector_model_titov(0, 0, 0, 0, 0, 1, calcPWMtimes); + analog.tetta = 0; + } else { + reset = 0; + } + + // ������� ������� ������������� (�� ������, �������� � ��������) + // �� ������ ���� ������ �� �������� ��� ���������� (�� ����) (?) + if ( decim_psi_wm_pm < (short)DECIM_PSI_WM_PM ) { + decim_psi_wm_pm++; + calcPWMtimes = 0; + } + else { + decim_psi_wm_pm = 1; + calcPWMtimes = 1; + + // �������� ��������������� + // (rf.PsiZ -> rf.psiZ, rf.pPsiZ) + reference_flux(); + + // �������� �������� + // (mst.wmZz, mst.wmLim -> rs.wmZ, rs.pWmZ) + reference_speed(); + + // �������� �������� + // (mst.pmZz, mst.pmLim -> rp.pmZ) + reference_power(); + + // �������� ��� (idZ, iqZ) + // ... ��������� ��������������� + // (rf.psiZ, psi, rf.pPsiZ, cf.IdLim, cf.IdLimNeg -> idZ) + control_flux(); + // ... ���������� �������� � �������� + // (rs.wmZ, wm, rs.pWmZ, rp.pmZ, mst.wmLim, mst.pmLim, csp.IqLim, + // csp.IqLimNeg -> iqZ, inuWork) + control_speed_power(); + // ... ����������� ������� ���� + // (idZ, iqZ, IzLim -> idZ, iqZ, csp.iqLimFlag) + limit_current(); + } //decim_psi_wm_pm + + + if ( mst.start == 1 ) { + inuWork = 1; + } else { + inuWork = 0; + } + + + + _iq Pzad = _IQ(rp.pmZ * 1.1); + // _iq Pzad = _IQ(1.1); + _iq Fzad = _IQ(rs.wmZ / (PI2 * 1.1574233675198942802148869545233)); + // _iq Frot = _IQ(10.0 / 6.0 / NORMA_FROTOR); + _iq Frot = _IQ(wm_ml / PI2 / NORMA_FROTOR); + int direction = Frot >= 0 ? 1 : -1; + rotor.iqFout = Frot; + int mode = 2; + // int reset = 0; + f.Go = 1; + if (mode != 0) { + limit_mzz_zad_power(Frot); + // set_cos_tetta_calc_params(); + pwm_vector_model_titov(Pzad, Fzad, direction, labs(Frot), mode, 0, calcPWMtimes); + } else { + // U/f=Const + #define K_MODUL_MAX 15435038LL + vect_control.iqUqKm1 = _IQ(0.6); + vect_control.iqUqKm2 = _IQ(0.6); + _iq Fconst = IQ_F_STATOR_NOM / 10; + test_calc_simple_dq_pwm24(vect_control.iqUqKm1, vect_control.iqUqKm2, Fconst, Fconst, K_MODUL_MAX); + } + + + reset = 0; + float theta = _IQtoF(analog.tetta); + sincos(theta, &sinTheta, &cosTheta); + + if (calcPWMtimes) + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_HIGH); + else + write_swgen_pwm_times_split_eages(PWM_MODE_RELOAD_LEVEL_LOW); + write_CMP_tims(calcPWMtimes); + // cc.yd1 = _IQtoF(vect_control.iqUdKm1Out) * Y_LIM; + // cc.yq1 = _IQtoF(vect_control.iqUqKm1Out) * Y_LIM; + // cc.yd2 = _IQtoF(vect_control.iqUdKm2Out) * Y_LIM; + // cc.yq2 = _IQtoF(vect_control.iqUqKm2Out) * Y_LIM; + + + + // indirect vector control + // (wmNf, wm, ix1, iy1, ix2, iy2 -> ivc.ws, ivc.sinTheta, ivc.cosTheta, + // ivc.id1, ivc.iq1, ivc.id2, ivc.iq2, ivc.psi) + // indirect_vector_control(); + + + // ����� �������� �.�. + // (... -> ws, sinTheta, cosTheta, id1, iq1, id2, iq2, psi) + // select_feedback(); + + +// idZ = 0.1; +// iqZ = 0.2; + // ���������� ���� + // (idZ, iqZ, id1, iq1, id2, iq2, ws, wm, psi -> + // -> cc.yd1, cc.yq1, cc.yd2, cc.yq2) + // control_current(); + + + // ������� �������� ���������� �� �.�. d-q � �.�. x-y + // (cc.yd1, cc.yq1, cc.yd2, cc.yq2, sinTheta, cosTheta, ws -> + // -> ip.yx1, ip.yy1, ip.yx2, ip.yy2) + // ipark(); + + // ��� + // (ip.yx1, ip.yy1, ip.yx2, ip.yy2 -> + // -> EPwm1Regs.CMPA.half.CMPA, EPwm2Regs.CMPA.half.CMPA, + // EPwm3Regs.CMPA.half.CMPA, EPwm4Regs.CMPA.half.CMPA, + // EPwm5Regs.CMPA.half.CMPA, EPwm6Regs.CMPA.half.CMPA, + // EPwm7Regs.CMPA.half.CMPA, EPwm8Regs.CMPA.half.CMPA, + // EPwm9Regs.CMPA.half.CMPA, EPwm10Regs.CMPA.half.CMPA, + // EPwm11Regs.CMPA.half.CMPA, EPwm12Regs.CMPA.half.CMPA) + // pwm(); +} //void upr(void) + + + +// ���������� ��� +// (idZ, iqZ, id1, iq1, id2, iq2, ws, wm, psi -> +// -> cc.yd1, cc.yq1, cc.yd2, cc.yq2) +void control_current(void) { + if ( cc.once == 0 ) { + cc.once = 1; + cc.y1LimFlag = 0; + cc.yd1I = 0; + cc.yq1I = 0; + cc.yd1 = 0; + cc.yq1 = 0; + cc.y2LimFlag = 0; + cc.yd2I = 0; + cc.yq2I = 0; + cc.yd2 = 0; + cc.yq2 = 0; + // ��� ���������� ���������� + cc.K1 = sgmPar.SigmaLs*I_BAZ*WE_BAZ*U_2_Y; + cc.K2 = sgmPar.Rr*sgmPar.Lm/(sgmPar.Lr*sgmPar.Lr)*PSI_BAZ*U_2_Y; + cc.K3 = sgmPar.Kl*PSI_BAZ*WE_BAZ*U_2_Y; + } + + // ��� ���������� ���������� + cc.Xyff = ws*cc.K1; + cc.yffAux2 = psi*cc.K2; + cc.yffAux3 = psi*wm*cc.K3; + + // ��������� Id1 + cc.del = idZ - id1; + cc.yd1P = cc.del*cc.Kp; + if ( (cc.y1LimFlag == 0) || (cc.yd1*cc.del < 0) ) + cc.yd1I += cc.del*cc.Ki; + cc.yd1FF = -iq1*cc.Xyff - cc.yffAux2; + cc.yd1 = cc.yd1P + cc.yd1I + cc.yd1FF; + // ��������� Iq1 + cc.del = iqZ - iq1; + cc.yq1P = cc.del*cc.Kp; + if ( (cc.y1LimFlag == 0) || (cc.yq1*cc.del < 0) ) + cc.yq1I += cc.del*cc.Ki; + cc.yq1FF = id1*cc.Xyff + cc.yffAux3; + cc.yq1 = cc.yq1P + cc.yq1I + cc.yq1FF; + // ����������� + cc.y1 = sqrt(cc.yd1*cc.yd1 + cc.yq1*cc.yq1); + if ( cc.y1 > Y_LIM ) { + cc.kYlim = Y_LIM/cc.y1; + cc.yd1 *= cc.kYlim; + cc.yq1 *= cc.kYlim; + cc.y1LimFlag = 1; + } + else { + cc.y1LimFlag = 0; + } + + // ��������� Id2 + cc.del = idZ - id2; + cc.yd2P = cc.del*cc.Kp; + if ( (cc.y2LimFlag == 0) || (cc.yd2*cc.del < 0) ) + cc.yd2I += cc.del*cc.Ki; + cc.yd2FF = -iq2*cc.Xyff - cc.yffAux2; + cc.yd2 = cc.yd2P + cc.yd2I + cc.yd2FF; + // ��������� Iq2 + cc.del = iqZ - iq2; + cc.yq2P = cc.del*cc.Kp; + if ( (cc.y2LimFlag == 0) || (cc.yq2*cc.del < 0) ) + cc.yq2I += cc.del*cc.Ki; + cc.yq2FF = id2*cc.Xyff + cc.yffAux3; + cc.yq2 = cc.yq2P + cc.yq2I + cc.yq2FF; + // ����������� + cc.y2 = sqrt(cc.yd2*cc.yd2 + cc.yq2*cc.yq2); + if ( cc.y2 > Y_LIM ) { + cc.kYlim = Y_LIM/cc.y2; + cc.yd2 *= cc.kYlim; + cc.yq2 *= cc.kYlim; + cc.y2LimFlag = 1; + } + else { + cc.y2LimFlag = 0; + } +} //void control_current(void) + + + +// ���������� ��������������� +// (rf.psiZ, psi, rf.pPsiZ, cf.IdLim, cf.IdLimNeg -> idZ) +void control_flux(void) { + if ( cf.once == 0 ) { + cf.once = 1; + cf.idLimFlag = 0; + cf.idI = 0; + idZ = 0; + } + + // ��������� Psi + cf.del = rf.psiZ - psi; + cf.idP = cf.del*cf.Kp; + if ( (cf.idLimFlag == 0) || (idZ*cf.del < 0) ) + cf.idI += cf.del*cf.Ki; + cf.idFF = (rf.psiZ + rf.pPsiZ*sgmPar.Tr)*sgmPar.LmInv*PSI_BAZ/I_BAZ; + idZ = cf.idP + cf.idI + cf.idFF; + // ����������� ����������������� ���� + if ( idZ > cf.IdLim ) { + idZ = cf.IdLim; + cf.idLimFlag = 1; + } + else if ( idZ < cf.IdLimNeg ) { + idZ = cf.IdLimNeg; + cf.idLimFlag = 1; + } + else { + cf.idLimFlag = 0; + } +} //void control_flux(void) + + + +// ���������� �������� ��� �������� +// (rs.wmZ, wm, rs.pWmZ, rp.pmZ, mst.wmLim, mst.pmLim, csp.IqLim, +// csp.IqLimNeg -> iqZ, inuWork) +void control_speed_power(void) { + if ( csp.once == 0 ) { + csp.once = 1; + csp.wmLimZi = mst.wmLim; + csp.pmLimZi = mst.pmLim; + csp.iqLimFlag = 0; + csp.iqI = 0; + iqZ = 0; + csp.iqLimZi = csp.IqLim; + csp.iqLim = csp.IqLim; + csp.pmZiRampDown = 0; + } + + // ��� ����������� �������� + if ( mst.wmLim - csp.wmLimZi > rs.WlimIncr ) { + csp.wmLimZi += rs.WlimIncr; + } + else if ( csp.wmLimZi - mst.wmLim > rs.WlimIncr ) { + csp.wmLimZi -= rs.WlimIncr; + } + else { + csp.wmLimZi = mst.wmLim; + } + // ��� ����������� �������� + if ( mst.pmLim - csp.pmLimZi > rp.PlimIncr ) { + csp.pmLimZi += rp.PlimIncr; + } + else if ( csp.pmLimZi - mst.pmLim > rp.PlimIncr ) { + csp.pmLimZi -= rp.PlimIncr; + } + else { + csp.pmLimZi = mst.pmLim; + } + + if ( inuWork == 0 ) { + if ( mst.start == 1 ) { + // ��� ����������, ����� ���������� � ��������� N ��� P + //if ( (rf.psiZ > rf.PsiZ*0.97) && (psi > rf.psiZ*0.97) ) + inuWork = 1; + } + else { + // �� ��������� + inuWork = 2; + } + // ����� ���������� ��� ������� ���� + rs.wmZi = rs.wmZ = wm; + rp.pmZi = rp.pmZ = 0; + iqZ = 0; + } + else if ( inuWork == 1 ) { + if ( mst.start == 1 ) { + // ��������� N -------------- + if ( mst.pzMode == 0 ) { + csp.del = rs.wmZ - wm; + csp.iqP = csp.del*csp.Kp; + if ( (csp.iqLimFlag == 0) || (iqZ*csp.del < 0) ) + csp.iqI += csp.del*csp.Ki; + csp.iqFF = rs.pWmZ/kMe*(WM_BAZ*J/M_BAZ); + iqZ = csp.iqP + csp.iqI + csp.iqFF; + // ����������� ���� ��� ����������� �������� + if ( wmAbs > WM_MIN ) { + csp.iqLimAux = csp.pmLimZi/(wmAbs*kMe); + } + else { + csp.iqLimAux = csp.pmLimZi/(WM_MIN*kMe); + } + if ( csp.iqLimAux < csp.IqLim ) { + csp.iqLim = csp.iqLimAux; + } + else { + csp.iqLim = csp.IqLim; + } + } + // ��������� P -------------- + else { //if ( mst.pzMode == 1 ) + if ( wmAbs <= WM_MIN ) { + iqZ = rp.pmZ/(WM_MIN*kMe); + } + else if ( wmAbs <= rf.WmNomPsi ) { + iqZ = rp.pmZ/(wmAbs*kMe); + csp.kMeNom = kMe; + } + else { + iqZ = rp.pmZ/(wmAbs*csp.kMeNom); + } + // ����������� ���� ��� ����������� �������� + if ( wmAbs < csp.wmLimZi*0.98 ) { + csp.iqLimAux = fabs(iqZ); + } + else if ( wmAbs > csp.wmLimZi*1.02 ) { + csp.iqLimAux = 0; + } + else { + csp.iqLimAux = csp.iqLimZi; + } + // ... ������ �������� ��������� ����������� ���� (?) + csp.delWmAbs = fabs(wmAbs - csp.wmLimZi); + if ( csp.delWmAbs > 0.12 ) + csp.KizIncr = 10.0; + else if ( csp.delWmAbs < 0.02 ) + csp.KizIncr = 0.1; + else + csp.KizIncr = 0.1 + (csp.delWmAbs - 0.02)*(10.0 - 0.1)/(0.12 - 0.02); + // ... �� + if ( csp.iqLimAux - csp.iqLimZi > csp.IlimIncr*csp.KizIncr ) + csp.iqLimZi += csp.IlimIncr*csp.KizIncr; + else if ( csp.iqLimZi - csp.iqLimAux > csp.IlimIncr*csp.KizIncr ) + csp.iqLimZi -= csp.IlimIncr*csp.KizIncr; + else + csp.iqLimZi = csp.iqLimAux; + if ( csp.iqLimZi < csp.IqLim ) { + csp.iqLim = csp.iqLimZi; + } + else { + csp.iqLim = csp.IqLim; + } + } //mst.pzMode + // ��� ������� ��������� + csp.pmZiRampDown = rp.pmEqv; + } + else { //if ( mst.start == 0 ) + // ������� �������� �������� + if ( 0 - csp.pmZiRampDown > mst.pDecrMaxTy ) { + csp.pmZiRampDown += mst.pDecrMaxTy; + } + else if ( csp.pmZiRampDown - 0 > mst.pDecrMaxTy ) { + csp.pmZiRampDown -= mst.pDecrMaxTy; + } + else { + csp.pmZiRampDown = 0; + // ��� ������ - ��������� ������ + inuWork = 2; + } + // ��������� �������� ��� + if ( wmAbs > WM_MIN ) { + iqZ = csp.pmZiRampDown/(wmAbs*kMe); + } + else { + iqZ = csp.pmZiRampDown/(WM_MIN*kMe); + } + // �� ������, ���� mst.start ������������� ������ + // ���������� ������ (inuWork = 2) + rs.wmZi = rs.wmZ = wm; + csp.iqI = iqZ; + rp.pmZi = rp.pmZ = rp.pmEqv; + } //mst.start + + // ������� ����������� ����� + if ( -csp.iqLim > csp.IqLimNeg ) + csp.iqLimNeg = -csp.iqLim; + else + csp.iqLimNeg = csp.IqLimNeg; + // ����������� ������������������ ���� + if ( iqZ > csp.iqLim ) { + iqZ = csp.iqLim; + csp.iqLimFlag = 1; + } + else if ( iqZ < csp.iqLimNeg ) { + iqZ = csp.iqLimNeg; + csp.iqLimFlag = 1; + } + else { + csp.iqLimFlag = 0; + } + // ��� �������� �������� + if ( mst.pzMode == 0 ) { + // ... � ����� ������������� P + rp.pmZ = iqZ*kMe*wmAbs; + rp.pmZi = rp.pmZ; + csp.iqLimZi = fabs(iqZ); + } + else { + // ... � ����� ������������� N + csp.iqI = iqZ; + csp.iqFF = 0; + rs.wmZ = wm; + rs.wmZi = rs.wmZ + csp.iqFF*0.05; + } + } //inuWork +} //void control_speed_power(void) + + + +// ������� ��� indirect vector control +// (wmNf, wm, ix1, iy1, ix2, iy2 -> ivc.ws, ivc.sinTheta, ivc.cosTheta, +// ivc.id1, ivc.iq1, ivc.id2, ivc.iq2, ivc.psi) +void indirect_vector_control(void) { + static float theta; + + if ( ivc.once == 0 ) { + ivc.once = 1; + ivc.im = 0; + ivc.iq1 = 0; + ivc.iq2 = 0; + ivc.wr = 0; + theta = 0; + } + + // ������� �������� ���, o.e. + if ( ivc.im > 4e-3 ) { + ivc.wr = (ivc.iq1 + ivc.iq2)*0.5/ivc.im*sgmPar.TrInv*(1.0/WE_BAZ); + } + // ������� ���� �������, �.�. + ivc.wsNf = wmNf + ivc.wr; + ivc.ws = wm + ivc.wr; + // ������������� ����, ���. + theta += ivc.wsNf*WE_BAZ*TY; + if ( theta > PI2 ) + theta -= PI2; + else if ( theta < 0 ) + theta += PI2; + + vect_control.theta = theta; + // ��� ������������ �������������� + sincos(theta, &ivc.sinTheta, &ivc.cosTheta); + // park transformations, �.�. + ivc.id1 = ix1*ivc.cosTheta + iy1*ivc.sinTheta; + ivc.iq1 = -ix1*ivc.sinTheta + iy1*ivc.cosTheta; + ivc.id2 = ix2*ivc.cosTheta + iy2*ivc.sinTheta; + ivc.iq2 = -ix2*ivc.sinTheta + iy2*ivc.cosTheta; + // ��� ��������������, o.e. + ivc.im += ((ivc.id1 + ivc.id2)*0.5 - ivc.im)*sgmPar.TrInv*TY; + // ��������� ������, o.e. + ivc.psi = ivc.im*sgmPar.Lm*(1.0/L_BAZ); +} //void indirect_vector_control(void) + + + +// ��������� ������� ���������� �� �.�. d-q � �.�. x-y +// (cc.yd1, cc.yq1, cc.yd2, cc.yq2, sinTheta, cosTheta, ws -> +// -> ip.yx1, ip.yy1, ip.yx2, ip.yy2) +void ipark(void) { + ip.yx1Aux = cc.yd1*cosTheta - cc.yq1*sinTheta; + ip.yy1Aux = cc.yd1*sinTheta + cc.yq1*cosTheta; + ip.yx2Aux = cc.yd2*cosTheta - cc.yq2*sinTheta; + ip.yy2Aux = cc.yd2*sinTheta + cc.yq2*cosTheta; + // ���������, ��������� � ������������� �� + ip.theta = ws*WE_BAZ*TY*1.5;//���. + sincos(ip.theta, &ip.sinTheta, &ip.cosTheta); + ip.yx1 = ip.yx1Aux*ip.cosTheta - ip.yy1Aux*ip.sinTheta; + ip.yy1 = ip.yx1Aux*ip.sinTheta + ip.yy1Aux*ip.cosTheta; + ip.yx2 = ip.yx2Aux*ip.cosTheta - ip.yy2Aux*ip.sinTheta; + ip.yy2 = ip.yx2Aux*ip.sinTheta + ip.yy2Aux*ip.cosTheta; +} //void ipark(void) + + + +// ������������ ������ ��� +// (idZ, iqZ, IzLim -> idZ, iqZ, csp.iqLimFlag) +void limit_current(void) { + iZ = sqrt(idZ*idZ + iqZ*iqZ); + if ( iZ > IzLim ) { + if ( iqZ >= 0 ) { + iqZ = sqrt(IzLim*IzLim - idZ*idZ); + } + else { + iqZ = -sqrt(IzLim*IzLim - idZ*idZ); + } + csp.iqLimFlag = 1; + } +} //void limit_current(void) + + + +// ��� +// (ip.yx1, ip.yy1, ip.yx2, ip.yy2 -> +// -> EPwm1Regs.CMPA.half.CMPA, EPwm2Regs.CMPA.half.CMPA, +// EPwm3Regs.CMPA.half.CMPA, EPwm4Regs.CMPA.half.CMPA, +// EPwm5Regs.CMPA.half.CMPA, EPwm6Regs.CMPA.half.CMPA, +// EPwm7Regs.CMPA.half.CMPA, EPwm8Regs.CMPA.half.CMPA, +// EPwm9Regs.CMPA.half.CMPA, EPwm10Regs.CMPA.half.CMPA, +// EPwm11Regs.CMPA.half.CMPA, EPwm12Regs.CMPA.half.CMPA) +void pwm(void) { + static float yAux1; + static float yAux2; + static float ya; + static float yb; + static float yc; + static float yPredm = 0; + static float yaPredm; + static float ybPredm; + static float ycPredm; + + // ��������� �� �.�. x-y � �.�. a-b-c + yAux1 = ip.yx1*(-0.5*ISQRT3); + yAux2 = ip.yy1*0.5; + ya = ip.yx1*ISQRT3; + yb = yAux1 + yAux2; + yc = yAux1 - yAux2; + // ���������������� ����������� + if ((ya >= yb) && (ya <= yc)) { + yPredm = ya*0.5; + } + else if ((yc >= yb) && (yc <= ya)) { + yPredm = yc*0.5; + } + else if ((yb >= yc) && (yb <= ya)) { + yPredm = yb*0.5; + } + else if ((ya >= yc) && (ya <= yb)) { + yPredm = ya*0.5; + } + else if ((yc >= ya) && (yc <= yb)) { + yPredm = yc*0.5; + } + else if ((yb >= ya) && (yb <= yc)) { + yPredm = yb*0.5; + } + yaPredm = (ya + yPredm)*2.; + ybPredm = (yb + yPredm)*2.; + ycPredm = (yc + yPredm)*2.; + // full compare unit compare registers + if (yaPredm >= 0) { + EPwm1Regs.CMPA.half.CMPA = (unsigned short)yaPredm; + EPwm2Regs.CMPA.half.CMPA = 0; + } + else { + EPwm1Regs.CMPA.half.CMPA = 0; + EPwm2Regs.CMPA.half.CMPA = (unsigned short)(-yaPredm); + } + if (ybPredm >= 0) { + EPwm3Regs.CMPA.half.CMPA = (unsigned short)ybPredm; + EPwm4Regs.CMPA.half.CMPA = 0; + } + else { + EPwm3Regs.CMPA.half.CMPA = 0; + EPwm4Regs.CMPA.half.CMPA = (unsigned short)(-ybPredm); + } + if (ycPredm >= 0) { + EPwm5Regs.CMPA.half.CMPA = (unsigned short)ycPredm; + EPwm6Regs.CMPA.half.CMPA = 0; + } + else { + EPwm5Regs.CMPA.half.CMPA = 0; + EPwm6Regs.CMPA.half.CMPA = (unsigned short)(-ycPredm); + } + + // ��������� �� �.�. x-y � �.�. a-b-c +#ifndef SHIFT + yAux1 = ip.yx2*(-0.5*ISQRT3); + yAux2 = ip.yy2*0.5; + ya = ip.yx2*ISQRT3; + yb = yAux1 + yAux2; + yc = yAux1 - yAux2; +#else //SHIFT + yAux1 = ip.yx2*0.5; + yAux2 = ip.yy2*0.5*ISQRT3; + ya = yAux1 + yAux2; + yb = -yAux1 + yAux2; + yc = ip.yy2*(-ISQRT3); +#endif //SHIFT + // ���������������� ����������� + if ((ya >= yb) && (ya <= yc)) { + yPredm = ya*0.5; + } + else if ((yc >= yb) && (yc <= ya)) { + yPredm = yc*0.5; + } + else if ((yb >= yc) && (yb <= ya)) { + yPredm = yb*0.5; + } + else if ((ya >= yc) && (ya <= yb)) { + yPredm = ya*0.5; + } + else if ((yc >= ya) && (yc <= yb)) { + yPredm = yc*0.5; + } + else if ((yb >= ya) && (yb <= yc)) { + yPredm = yb*0.5; + } + yaPredm = (ya + yPredm)*2.; + ybPredm = (yb + yPredm)*2.; + ycPredm = (yc + yPredm)*2.; +#ifdef ML + // full compare unit compare registers + if (yaPredm >= 0) { + EPwm7Regs.CMPA.half.CMPA = (unsigned short)yaPredm; + EPwm8Regs.CMPA.half.CMPA = 0; + } + else { + EPwm7Regs.CMPA.half.CMPA = 0; + EPwm8Regs.CMPA.half.CMPA = (unsigned short)(-yaPredm); + } + if (ybPredm >= 0) { + EPwm9Regs.CMPA.half.CMPA = (unsigned short)ybPredm; + EPwm10Regs.CMPA.half.CMPA = 0; + } + else { + EPwm9Regs.CMPA.half.CMPA = 0; + EPwm10Regs.CMPA.half.CMPA = (unsigned short)(-ybPredm); + } + if (ycPredm >= 0) { + EPwm11Regs.CMPA.half.CMPA = (unsigned short)ycPredm; + EPwm12Regs.CMPA.half.CMPA = 0; + } + else { + EPwm11Regs.CMPA.half.CMPA = 0; + EPwm12Regs.CMPA.half.CMPA = (unsigned short)(-ycPredm); + } +#endif //ML + + // ��������� �������� + EALLOW; + EPwm1Regs.TZCLR.all = 0x0004; + EPwm2Regs.TZCLR.all = 0x0004; + EPwm3Regs.TZCLR.all = 0x0004; + EPwm4Regs.TZCLR.all = 0x0004; + EPwm5Regs.TZCLR.all = 0x0004; + EPwm6Regs.TZCLR.all = 0x0004; +#ifdef ML + EPwm7Regs.TZCLR.all = 0x0004; + EPwm8Regs.TZCLR.all = 0x0004; + EPwm9Regs.TZCLR.all = 0x0004; + EPwm10Regs.TZCLR.all = 0x0004; + EPwm11Regs.TZCLR.all = 0x0004; + EPwm12Regs.TZCLR.all = 0x0004; +#endif //ML + EDIS; +} //void pwm(void) + + + +// ��������� �������� ����� +// (rf.PsiZ -> rf.psiZ, rf.pPsiZ) +void reference_flux(void) { + if ( rf.once == 0 ) { + rf.once = 1; + rf.KpsiSub = TY*DECIM_PSI_WM_PM/6.0; + rf.psiZi = 0; + cc.y1 = 0; + cc.y2 = 0; + rf.psiSub = 0; + rf.psiZ = 0; + rf.psiZPrev1 = 0; + rf.psiZPrev2 = 0; + rf.psiZPrev3 = 0; + } + + // �� + if ( rf.PsiZ - rf.psiZi > rf.PsizIncr ) { + rf.psiZi += rf.PsizIncr; + } + else if ( rf.psiZi - rf.PsiZ > rf.PsizIncr ) { + rf.psiZi -= rf.PsizIncr; + } + else { + rf.psiZi = rf.PsiZ; + } + // ��������� � ������������ �� ��������� + if ( wmAbs <= rf.WmNomPsi ) + rf.psiZCorr = rf.psiZi; + else + rf.psiZCorr = rf.psiZi*rf.WmNomPsi/wmAbs; + // ��������� � ������������ � ���������� + if ( (cc.y1 > rf.YlimPsi) || (cc.y2 > rf.YlimPsi) ) { + rf.psiSub += (rf.psiZCorr - rf.psiSub)*rf.KpsiSub; + } + else { + rf.psiSub += (0 - rf.psiSub)*rf.KpsiSub; + } + rf.psiZCorr2 = rf.psiZCorr - rf.psiSub; + // ����� ������� �������� ���� ������� + rf.psiZ += (rf.psiZCorr2 - rf.psiZ)*rf.Kpsiz; + + // ����������� ��������� ��������������� + rf.pPsiZ = (rf.psiZ - rf.psiZPrev3)/(TY*DECIM_PSI_WM_PM*3.); + rf.psiZPrev3 = rf.psiZPrev2; + rf.psiZPrev2 = rf.psiZPrev1; + rf.psiZPrev1 = rf.psiZ; +} //void reference_flux(void) + + + +// ��������� �������� �������� +// (mst.pmZz, mst.pmLim -> rp.pmZ) +void reference_power(void) { + if ( rp.once == 0 ) { + rp.once = 1; + rp.pmZi = 0; + rp.pmZ = 0; + } + + // ����������� + if ( fabs(mst.pmZz) > mst.pmLim ) { + if ( mst.pmZz >= 0 ) + rp.pmZz = mst.pmLim; + else + rp.pmZz = -mst.pmLim; + } + else { + rp.pmZz = mst.pmZz; + } + // ��� ����������� ���������� �������� (?) + if ( fabs(rp.pmZi - rp.pmEqv) > 0.02 ) + rp.KpIncrDecr = 0.10; + else + rp.KpIncrDecr = 1.00; + // �� + if ( rp.pmZz - rp.pmZi > mst.pIncrMaxTy*rp.KpIncrDecr ) { + rp.pmZi += mst.pIncrMaxTy*rp.KpIncrDecr; + } + else if ( rp.pmZi - rp.pmZz > mst.pDecrMaxTy*rp.KpIncrDecr ) { + rp.pmZi -= mst.pDecrMaxTy*rp.KpIncrDecr; + } + else { + rp.pmZi = rp.pmZz; + } + // ����� ������� �������� ���� ������� + // rp.pmZ += (rp.pmZi - rp.pmZ)*rp.Kpmz; + rp.pmZ = rp.pmZz; +} //void reference_power(void) + + + +// ��������� �������� �������� +// (mst.wmZz, mst.wmLim -> rs.wmZ, rs.pWmZ) +void reference_speed(void) { + if ( rs.once == 0 ) { + rs.once = 1; + rs.wmZi = rs.wmZ = wm; + rs.wzIncr = rs.WlimIncr; + rs.wmZPrev1 = rs.wmZ; + rs.wmZPrev2 = rs.wmZ; + rs.wmZPrev3 = rs.wmZ; + rs.tPwmZ = 0; + } + + // ����������� + if ( fabs(mst.wmZz) > mst.wmLim ) { + if ( mst.wmZz >= 0 ) + rs.wmZz = mst.wmLim; + else + rs.wmZz = -mst.wmLim; + } + else { + rs.wmZz = mst.wmZz; + } + // ��� ����������� ���������� �������� (?) + if ( fabs(rs.wmZi) < 0.5 ) + rs.wzIncrNf = rs.WlimIncr*3.5; + else if ( fabs(rs.wmZi) < 0.8 ) + rs.wzIncrNf = rs.WlimIncr*2.0; + else + rs.wzIncrNf = rs.WlimIncr; + rs.wzIncr += (rs.wzIncrNf - rs.wzIncr)*(TY*DECIM_PSI_WM_PM)/0.25; + // �� + if ( rs.wmZz - rs.wmZi > rs.wzIncr ) { + rs.wmZi += rs.wzIncr; + } + else if ( rs.wmZi - rs.wmZz > rs.wzIncr ) { + rs.wmZi -= rs.wzIncr; + } + else { + rs.wmZi = rs.wmZz; + } + // ����� ������� �������� ���� ������� + // rs.wmZ += (rs.wmZi - rs.wmZ)*rs.Kwmz; + rs.wmZ = rs.wmZz; + + // ����������� �������� �������� + rs.pWmZ = (rs.wmZ - rs.wmZPrev3)/(TY*DECIM_PSI_WM_PM*3.); + rs.wmZPrev3 = rs.wmZPrev2; + rs.wmZPrev2 = rs.wmZPrev1; + rs.wmZPrev1 = rs.wmZ; + // ... ����� �������� ������� ��� ����� � ������� ����� + // if ( (inuWork == 0) || (mst.start == 0) || (mst.pzMode == 1) ) + // rs.tPwmZ = 0; + // if ( rs.tPwmZ <= 3 ) { + // rs.tPwmZ++; + // rs.pWmZ = 0; + // } +} //void reference_speed(void) + + + +// �������� �.�. +// (... -> ws, sinTheta, cosTheta, id1, iq1, id2, iq2, psi) +void select_feedback(void) { + ws = ivc.ws; + sinTheta = ivc.sinTheta; + cosTheta = ivc.cosTheta; + id1 = ivc.id1; + iq1 = ivc.iq1; + id2 = ivc.id2; + iq2 = ivc.iq2; + psi = ivc.psi; +} //void select_feedback(void) + +void write_swgen_pwm_times_split_eages(unsigned int mode_reload) { + + xpwm_time.Ta0_0 = (unsigned int) svgen_pwm24_1.Ta_0.Ti; + xpwm_time.Ta0_1 = (unsigned int) svgen_pwm24_1.Ta_1.Ti; + xpwm_time.Tb0_0 = (unsigned int) svgen_pwm24_1.Tb_0.Ti; + xpwm_time.Tb0_1 = (unsigned int) svgen_pwm24_1.Tb_1.Ti; + xpwm_time.Tc0_0 = (unsigned int) svgen_pwm24_1.Tc_0.Ti; + xpwm_time.Tc0_1 = (unsigned int) svgen_pwm24_1.Tc_1.Ti; + + xpwm_time.Ta1_0 = (unsigned int) svgen_pwm24_2.Ta_0.Ti; + xpwm_time.Ta1_1 = (unsigned int) svgen_pwm24_2.Ta_1.Ti; + xpwm_time.Tb1_0 = (unsigned int) svgen_pwm24_2.Tb_0.Ti; + xpwm_time.Tb1_1 = (unsigned int) svgen_pwm24_2.Tb_1.Ti; + xpwm_time.Tc1_0 = (unsigned int) svgen_pwm24_2.Tc_0.Ti; + xpwm_time.Tc1_1 = (unsigned int) svgen_pwm24_2.Tc_1.Ti; + + // xpwm_time.Tbr0_0 = break_result_1; + // xpwm_time.Tbr0_1 = break_result_2; + // xpwm_time.Tbr1_0 = break_result_3; + // xpwm_time.Tbr1_1 = break_result_4; + + xpwm_time.mode_reload = PWM_MODE_RELOAD_FORCE;// mode_reload; + + xpwm_time.write_1_2_winding_break_times_split(&xpwm_time); +} + +void write_CMP_tims(int calcPWMtimes) { + + // if (calcPWMtimes == 0) { + // return; + // } + + // EPwm1Regs.CMPA.half.CMPA = xpwm_time.Ta0_1; + // EPwm2Regs.CMPA.half.CMPA = xpwm_time.Ta0_0; + + // EPwm3Regs.CMPA.half.CMPA = xpwm_time.Tb0_1; + // EPwm4Regs.CMPA.half.CMPA = xpwm_time.Tb0_0; + + // EPwm5Regs.CMPA.half.CMPA = xpwm_time.Tc0_1; + // EPwm6Regs.CMPA.half.CMPA = xpwm_time.Tc0_0; + + + // EPwm7Regs.CMPA.half.CMPA = xpwm_time.Ta1_1; + // EPwm8Regs.CMPA.half.CMPA = xpwm_time.Ta1_0; + + // EPwm9Regs.CMPA.half.CMPA = xpwm_time.Tb1_1; + // EPwm10Regs.CMPA.half.CMPA = xpwm_time.Tb1_0; + + // EPwm11Regs.CMPA.half.CMPA = xpwm_time.Tc1_1; + // EPwm12Regs.CMPA.half.CMPA = xpwm_time.Tc1_0; + + // ��������� �������� + EALLOW; + EPwm1Regs.TZCLR.all = 0x0004; + EPwm2Regs.TZCLR.all = 0x0004; + EPwm3Regs.TZCLR.all = 0x0004; + EPwm4Regs.TZCLR.all = 0x0004; + EPwm5Regs.TZCLR.all = 0x0004; + EPwm6Regs.TZCLR.all = 0x0004; +#ifdef ML + EPwm7Regs.TZCLR.all = 0x0004; + EPwm8Regs.TZCLR.all = 0x0004; + EPwm9Regs.TZCLR.all = 0x0004; + EPwm10Regs.TZCLR.all = 0x0004; + EPwm11Regs.TZCLR.all = 0x0004; + EPwm12Regs.TZCLR.all = 0x0004; +#endif //ML + EDIS; +} + diff --git a/Inu/upr.h b/Inu/upr.h new file mode 100644 index 0000000..aba741d --- /dev/null +++ b/Inu/upr.h @@ -0,0 +1,50 @@ +#ifndef UPR +#define UPR + +// ����������, ������� ���������� � upr.c (begin) +//######################################################################### +volatile short onceUpr; +struct SgmPar sgmPar; +struct Rf rf; +struct Rs rs; +struct Rp rp; + +float IzLim; +volatile float psi; +float idZ; +float iqZ; +float iZ; +float ws; +float sinTheta; +float cosTheta; +float id1; +float iq1; +float id2; +float iq2; +struct Cc cc; +struct Cf cf; +struct Csp csp; +struct Ivc ivc; +struct Ip ip; +//######################################################################### +// ����������, ������� ���������� � upr.c (end) + + + + +// ����������, ������� ��������� � upr.c (begin) +//######################################################################### +extern volatile float wmNf; +extern volatile float wm; +extern volatile float wmAbs; +extern volatile float ix1; +extern volatile float iy1; +extern volatile float ix2; +extern volatile float iy2; +extern volatile float kMe; +extern volatile short inuWork; +extern struct Mst mst; +extern volatile short faultNo; +//######################################################################### +// ����������, ������� ��������� � upr.c (end) +#endif //UPR diff --git a/Inu/wrapper_inu.c b/Inu/wrapper_inu.c new file mode 100644 index 0000000..9b07a3b --- /dev/null +++ b/Inu/wrapper_inu.c @@ -0,0 +1,267 @@ +/************************************************************************** + Description: ��������� - ���������. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.09.23 +**************************************************************************/ + + + +#define S_FUNCTION_NAME wrapper_inu +#define S_FUNCTION_LEVEL 2 +#include "simstruc.h" +#include "math.h" +#include "wrapper_inu.h" + + + +#define MDL_UPDATE +/* Function: mdlUpdate ==================================================== + * Abstract: + * This function is called once for every major integration time step. + * Discrete states are typically updated here, but this function is useful + * for performing any tasks that should only take place once per + * integration step. + */ +static void mdlUpdate(SimStruct *S, int_T tid) +{ + const real_T *u = (const real_T*) ssGetInputPortRealSignal(S,0); + real_T *xD = ssGetDiscStates(S); + real_T *rW = ssGetRWork(S); + int_T *iW = ssGetIWork(S); + + controller(S, u, xD, rW, iW); + +}//end mdlUpdate + + + +/* Function: mdlCheckParameters =========================================== +* Abstract: +* mdlCheckParameters verifies new parameter settings whenever parameter +* change or are re-evaluated during a simulation. +*/ +#define MDL_CHECK_PARAMETERS /* Change to #undef to remove function */ +#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) +static void mdlCheckParameters(SimStruct *S) +{ + int i; + + // ��������� � ��������� ��������� � ��������� ��� ��������� �� ������ + // � �������� ������������� + for (i=0; i<NPARAMS; i++) + { + // Input parameter must be scalar or vector of type double + if (!mxIsDouble(ssGetSFcnParam(S,i)) || mxIsComplex(ssGetSFcnParam(S,i)) || + mxIsEmpty(ssGetSFcnParam(S,i))) + { + ssSetErrorStatus(S,"Input parameter must be of type double"); + return; + } + // �������� �.�. ������ ��������, �������� ��� �������� + if (mxGetNumberOfDimensions(ssGetSFcnParam(S,i)) > 2) + { + ssSetErrorStatus(S,"�������� �.�. ������ ��������, �������� ��� ��������"); + return; + } + + // Parameter not tunable +// ssSetSFcnParamTunable(S, i, SS_PRM_NOT_TUNABLE); + // Parameter tunable (we must create a corresponding run-time parameter) + ssSetSFcnParamTunable(S, i, SS_PRM_TUNABLE); + // Parameter tunable only during simulation +// ssSetSFcnParamTunable(S, i, SS_PRM_SIM_ONLY_TUNABLE); + + }//for (i=0; i<NPARAMS; i++) + +}//end mdlCheckParameters + +#endif //MDL_CHECK_PARAMETERS + + +#define MDL_PROCESS_PARAMETERS /* Change to #undef to remove function */ +#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE) +/* Function: mdlProcessParameters ========================================= + * Abstract: + * This method will be called after mdlCheckParameters, whenever + * parameters change or get re-evaluated. The purpose of this method is + * to process the newly changed parameters. For example "caching" the + * parameter changes in the work vectors. Note this method is not + * called when it is used with the Real-Time Workshop. Therefore, + * if you use this method in an S-function which is being used with the + * Real-Time Workshop, you must write your S-function such that it doesn't + * rely on this method. This can be done by inlining your S-function + * via the Target Language Compiler. + */ +static void mdlProcessParameters(SimStruct *S) +{ + int_T *iW = ssGetIWork(S); + + iW[0] = 1;//processParameters +} +#endif //MDL_PROCESS_PARAMETERS + + + +/* Function: mdlInitializeSizes =========================================== + * Abstract: + * The sizes information is used by Simulink to determine the S-function + * block's characteristics (number of inputs, outputs, states, etc.). + */ +static void mdlInitializeSizes(SimStruct *S) +{ + //--------------------------------------------------------------------- + // Number of expected parameters + ssSetNumSFcnParams(S, NPARAMS); + + // � ���������� ������ ������, ��� ��������� ���������� �������� �-��� + // mdlCheckParameters() + #ifdef MATLAB_MEX_FILE + // ���-�� ��������� � ����������� ���������� ������ ��������� + if(ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) + { + // ��������� � ��������� ��������� + mdlCheckParameters(S); + } + else + { + return;// Parameter mismatch will be reported by Simulink + } + #endif // MATLAB_MEX_FILE + + //--------------------------------------------------------------------- + // Register the number and type of states the S-Function uses + ssSetNumContStates(S, 0); // number of continuous states + ssSetNumDiscStates(S, OUTPUT_0_WIDTH); // number of discrete states + + //--------------------------------------------------------------------- + // ������������� ���-�� ��-�� ������ + if (!ssSetNumInputPorts(S, 1)) return; + // ������������� ���-�� �������� �� ��-�� ����� + ssSetInputPortWidth(S, 0, INPUT_0_WIDTH); + + // ��������, ��� ��� ������ ��-�� ����� ��� direct feedthrough + ssSetInputPortDirectFeedThrough(S, 0, 0); + + // �������, ����� ������� �� ������� ����� ��� ���������������, � �� + // � ������� + ssSetInputPortRequiredContiguous(S, 0, 1); // direct input signal access + + //--------------------------------------------------------------------- + // ������������� ���-�� ���-�� ������ + if (!ssSetNumOutputPorts(S, 1)) return; + // ������������� ���-�� �������� � ���-�� ����� + ssSetOutputPortWidth(S, 0, OUTPUT_0_WIDTH); + + //--------------------------------------------------------------------- + // Number of sample times + ssSetNumSampleTimes(S, 1); + + //--------------------------------------------------------------------- + // Set size of the work vectors + ssSetNumRWork( S, RWORK_0_WIDTH); // number of real work vector elements + ssSetNumIWork( S, IWORK_0_WIDTH); // number of integer work vector elements + ssSetNumPWork( S, 0); // number of pointer work vector elements + ssSetNumModes( S, 0); // number of mode work vector elements + ssSetNumNonsampledZCs( S, 0); // number of nonsampled zero crossings +// ssSetNumDWork(S, 1); + +// ssSetDWorkWidth(S, 0, 12);//Inm +// ssSetDWorkDataType(S, 0, SS_DOUBLE); + + //--------------------------------------------------------------------- + /* + * All options have the form SS_OPTION_<name> and are documented in + * matlabroot/simulink/include/simstruc.h. The options should be + * bitwise or'd together as in + * ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_name2)) + */ + // � ������� ����� SS_OPTION_EXCEPTION_FREE_CODE �������, ��� � + // ����� ��������� ��� "����������" + ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE)); + +}//end mdlInitializeSizes + + + +/* Function: mdlInitializeSampleTimes ===================================== + * Abstract: + * This function is used to specify the sample time(s) for your + * S-function. You must register the same number of sample times as + * specified in ssSetNumSampleTimes. + */ +static void mdlInitializeSampleTimes(SimStruct *S) +{ + double dt; + + // ��� ������������� + dt = mxGetPr(ssGetSFcnParam(S,NPARAMS-1))[0]; + + // Register one pair for each sample time + ssSetSampleTime(S, 0, dt); + ssSetOffsetTime(S, 0, 0.0); + +}//end mdlInitializeSampleTimes + + +#define MDL_START // Change to #undef to remove function +#if defined(MDL_START) +/* Function: mdlStart ===================================================== + * Abstract: + * This function is called once at start of model execution. If you + * have states that should be initialized once, this is the place + * to do it. + */ +static void mdlStart(SimStruct *S) +{ + int_T *iW = ssGetIWork(S); + + iW[0] = 1;//processParameters + iW[1] = 1;//start +} +#endif // MDL_START + + + +/* Function: mdlOutputs =================================================== + * Abstract: + * In this function, you compute the outputs of your S-function + * block. Generally outputs are placed in the output vector(s), + * ssGetOutputPortSignal. + */ +static void mdlOutputs(SimStruct *S, int_T tid) +{ + real_T *y = ssGetOutputPortRealSignal(S,0); + real_T *xD = ssGetDiscStates(S); + + int i; + + // OUTPUTS + for (i=0; i<OUTPUT_0_WIDTH; i++) + y[i] = xD[i]; + +}//end mdlOutputs + + + +/* Function: mdlTerminate ================================================= + * Abstract: + * In this function, you should perform any actions that are necessary + * at the termination of a simulation. For example, if memory was + * allocated in mdlStart, this is the place to free it. + */ +static void mdlTerminate(SimStruct *S) +{ +} + + + +/*=============================* + * Required S-function trailer * + *=============================*/ + +#ifdef MATLAB_MEX_FILE // Is this file being compiled as a MEX-file? +#include "simulink.c" // MEX-file interface mechanism +#else +#include "cg_sfun.h" // Code generation registration function +#endif diff --git a/Inu/wrapper_inu.h b/Inu/wrapper_inu.h new file mode 100644 index 0000000..326ea68 --- /dev/null +++ b/Inu/wrapper_inu.h @@ -0,0 +1,25 @@ +/************************************************************************** + Description: ������� ���������� ������, �������, ����������, � ����� + ������� ������� �������� S-function. + + �����: ���������� �.�. + ���� ���������� ����������: 2021.09.22 +**************************************************************************/ + + +#ifndef WRAPPER +#define WRAPPER + + +#define INPUT_0_WIDTH 20 //���-�� ������ +#define OUTPUT_0_WIDTH 49 //���-�� ������� +#define NPARAMS 1 //���-�� ���������� (�������� � ��������) +#define RWORK_0_WIDTH 5 //width of the real-work vector +#define IWORK_0_WIDTH 5 //width of the integer-work vector + + +void controller(SimStruct *S, const real_T *u, real_T *xD, real_T *rW, + int_T *iW); + + +#endif diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..23ba3bc --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,2 @@ +��� ������������ ��������� ������ �������������� ����������� ���������. + diff --git a/allmex.m b/allmex.m new file mode 100644 index 0000000..5be3931 --- /dev/null +++ b/allmex.m @@ -0,0 +1,24 @@ +clear, clc +% ����������� S-function +currFolder = cd; +%cd([currFolder, '\Inu']); + +delete("wrapper_inu.mexw64") + +status=system('run_mex.bat wrapper_inu.c') +if status==0 +else + error('Error!') +end + +% status=system('run_mex.bat wrapper_inu_2.c') +% if status==0 +% else +% error('Error!') +% end + +%mex -D"ML" -D"__IQMATHLIB_H_INCLUDED__" -D"_MATLAB_SIMULATOR" -I"..\device_support_ml\include" -I"." -I".\Inu" -I".\Inu\Src\main" -I".\Inu\Src\VectorControl" -I".\Inu\Src\main_matlab" -I".\Inu\Src\myLibs" -I".\Inu\Src\myXilinx" -outdir "." .\Inu\wrapper_inu_1.c .\Inu\controller.c .\Inu\init28335.c .\Inu\detcoeff.c .\Inu\isr.c .\Inu\main.c .\Inu\param.c .\Inu\upr.c .\Inu\Src\main_matlab\IQmathLib_matlab.c .\Inu\Src\main_matlab\main_matlab.c .\Inu\Src\main_matlab\adc_tools_matlab.c .\Inu\Src\myLibs\modbus_read_table.c .\Inu\Src\myLibs\my_filter.c .\Inu\Src\myLibs\pid_reg3.c .\Inu\Src\myLibs\svgen_dq_v2.c .\Inu\Src\myLibs\rmp_cntl_my1.c .\Inu\Src\myLibs\modbus_table.c .\Inu\Src\myLibs\mathlib.c .\Inu\Src\main_matlab\v_pwm24_matlab.c .\Inu\Src\main_matlab\xp_write_xpwm_time_matlab.c .\Inu\Src\main_matlab\errors_matlab.c .\Inu\Src\main\detect_overload.c .\Inu\Src\main\rotation_speed.c .\Inu\Src\main\global_time.c .\Inu\Src\main\PWMTools.c .\Inu\Src\VectorControl\pwm_vector_regul.c .\Inu\Src\VectorControl\abc_to_dq.c .\Inu\Src\VectorControl\regul_power.c .\Inu\Src\VectorControl\regul_turns.c .\Inu\Src\VectorControl\teta_calc.c .\Inu\Src\VectorControl\dq_to_alphabeta_cos.c ..\device_support_ml\source\C28x_FPU_FastRTS.obj ..\device_support_ml\source\DSP2833x_GlobalVariableDefs.obj +%mex -D"ML" -D"__IQMATHLIB_H_INCLUDED__" -D"_MATLAB_SIMULATOR" -I"..\device_support_ml\include" -I"." -I".\Inu" -I".\Inu\Src\main" -I".\Inu\Src\VectorControl" -I".\Inu\Src\main_matlab" -I".\Inu\Src\myLibs" -I".\Inu\Src\myXilinx" -outdir "." .\Inu\wrapper_inu_2.c .\Inu\controller.c .\Inu\init28335.c .\Inu\detcoeff.c .\Inu\isr.c .\Inu\main.c .\Inu\param.c .\Inu\upr.c .\Inu\Src\main_matlab\IQmathLib_matlab.c .\Inu\Src\main_matlab\main_matlab.c .\Inu\Src\main_matlab\adc_tools_matlab.c .\Inu\Src\myLibs\modbus_read_table.c .\Inu\Src\myLibs\my_filter.c .\Inu\Src\myLibs\pid_reg3.c .\Inu\Src\myLibs\svgen_dq_v2.c .\Inu\Src\myLibs\rmp_cntl_my1.c .\Inu\Src\myLibs\modbus_table.c .\Inu\Src\myLibs\mathlib.c .\Inu\Src\main_matlab\v_pwm24_matlab.c .\Inu\Src\main_matlab\xp_write_xpwm_time_matlab.c .\Inu\Src\main_matlab\errors_matlab.c .\Inu\Src\main\detect_overload.c .\Inu\Src\main\rotation_speed.c .\Inu\Src\main\global_time.c .\Inu\Src\main\PWMTools.c .\Inu\Src\VectorControl\pwm_vector_regul.c .\Inu\Src\VectorControl\abc_to_dq.c .\Inu\Src\VectorControl\regul_power.c .\Inu\Src\VectorControl\regul_turns.c .\Inu\Src\VectorControl\teta_calc.c .\Inu\Src\VectorControl\dq_to_alphabeta_cos.c ..\device_support_ml\source\C28x_FPU_FastRTS.obj ..\device_support_ml\source\DSP2833x_GlobalVariableDefs.obj + + +clear currFolder diff --git a/am_two_wind.mexw64 b/am_two_wind.mexw64 new file mode 100644 index 0000000000000000000000000000000000000000..b8e22fb9dd85969754d5d4dcc68c951da5a1b44f GIT binary patch literal 27648 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 a+mkz=Y<&`hCd6+5euzf!AHV;R7WfbHPh_nC literal 0 HcmV?d00001 diff --git a/asynchronous_machine.p b/asynchronous_machine.p new file mode 100644 index 0000000000000000000000000000000000000000..9a34a055c104d3ebae3ff35aabe5cd0b5b92a68f GIT binary patch literal 1232 zcmV;>1TXt`FflGLFm^C7E-)|v3&0#uTK};C00sa600giA01I%3WS>#l#CH?VLlszn z9m>FgGApMiho?*j1|z-xl~O0qmv05Gx_<^jm!C<9lu9vixUj4r#f?dEwheRSgqJW1 z5~VH;4hos5#erWk5FRt=8L;S^!b%v$>}X!g-69b512qdf(?1f}(mDBTDX9W32!AKi zWJ)3c^Q0z67uc&KwI}HtjZ2pc<mwJdPiTapYNGPA3>q$I|3VtRHZq&E)P@hhI&^-x z(;%tYId&ex1(}3XiakquXZ-j_;{jrQ-i$UZ3VLDBD&@uUGt3c@e^wg6`pweX)F5MG zjs1K$+m;(0hoU#F9v>%Tr`CntDcQ-&-su2j11h}J2gq1^rU1pcA7PA~Xge6r8)VaP zec2Zedg0?MNc+=Kehs*?&cCuIT^&J0!Zz-S#p)A-<G3i?AAVM2!z!M+_D2~ssB&>2 z*!jP$SV9&xMYS7}aPzugzgM0Ojk+2jff#}kAHRMYx+p1Br*s8_N=%Vm$i~*HSK1LG zmb9fZ5~mdr-Y=vx^}G=!_552)7=*GuJpCqnx+fwpsOH$(&>n_*X6F)(1m?1W{-n}7 zro6uBn2L7&zidH7_}wQXHmt&aJWK8V>FEpE@MkC@FV_JJ2?-=}Z|Y%sQ38JK%oK=j zY8%VndYs@U<t{kPgw%fN<!Iub*7kno5xqFGz#-a33K|(ugGghn*~7~VK`bPI{(Gpk zWgFq9=*Xbp|E_FzG1B)(^an{BFhCQz5jmlGEH=5uM)uqZ@9>MzsSv|7$C7(ZatmtX zP%Xl1S)5Gi6Zc7y1#oB=Z>~zEC!faL+{4*rfm}eYFR5Mm;7|NwFf2$kq{*DxJZf4q zLA&E3#x!*Z^~y$v7sA)?rsdYuC7ZK{BjkXPXB{9n>Os`f`(1nPj2wJrW$3uQm4gh( z|0Zp58ZK<FFqy<b6u7H7G>5D2yh$8>?x7Hgd?RC{qWJjN6X;lDaN|bK$Kj(-Tob<~ z8D^U-Jrcp)Xw;o!!oANV?u{#J6CMyKTD-Fgw0M9fPeL^%(M31`dc_lMKCHo@M;z0x zIbNM@$~E)j&vhU!7k{>j==Go8_54i*{P!g(L@`^^nBS)mS={LT@~=Bk2tqvca0lK1 z$VaQ~A4an^o>k-BRebM3QR+}2VQ{_VLFTrGjwiSR1d=y=HuT0A@GQ#he@UjS4DW%S zHMYre($0(NAd`4OG6CgJm}^8zrB>0)KteWsni_muh;vuBO1Y<Q3sPW<+)B4j2A$bH z+P56V*aPn7mM`FP_a<Q(I-7+rF(pi&!|IdRa;zg5{Np>FSJebUMX@x*ItR@)8#T!# zXdOt7cMZ59Am(&ijgO<3R)}NvdS|%ezi3X&b*_-Ny8(|Em|)01_wE;t5HG0?PTbT* z2~DB(tA-Jpev~;<Yc>qjOs-jUIH>ezH|B<CRR#$%M+m0^*DpJu5zR@)xBii`fNT(9 zYEmX>$%1(FKF!`h*a~A%w4C~-v+&`Hr1y?HJVr3+EfD)nK>8sg3D_dJw5k}~F&MXS uMGvO>D+@C)rFLP>l}n=Smgz5(k&=UT$4_sM_@DVD-N~lj=mt4?@q-r&^-b;o literal 0 HcmV?d00001 diff --git a/electr_mach.slx b/electr_mach.slx new file mode 100644 index 0000000000000000000000000000000000000000..8b9774982362fa932436f7af3fb9bd224dcba6ce GIT binary patch literal 41878 zcmaI7V{m7|yEPhnV%xTD+qN^YZQHhOClgO>;}_e;#Ba{Ib#I;jxmEA3+WSL)+N;*n z{q$PBT2TfR3>63n2nvX<R8GYS9tq?P7zl_H1_%h{XH-YT-p<9$&c#60)4|MHkKV)9 zW;o5>euEKlq)+;=9fb)HZIuP323yS<>005kA!C{&({L;B3dj2X*exhy#EMKO>v{Iz z{Ng>+i1$*5A1kkpsK}Mw7;lwMW>`9zO2_hivDfwxN`@Ia9qNY8tPb3CSheF_!D}cy zj?Tg!Kkt8pdxRU)zvS7#s?uR7T4F@miQz;fy_?^)HLJ^wGcY1wW8L6q4;89;o&nc( z*X1&jQu(x<M*I3KxmP>jHHE_*@}ez;BsHeN{yi#wGA@iQXwS;2fiIA-3nbXQCb{M{ zsOFg>-k9v0nEkpD3SL$*rA*T;DOVRSy<$TBn#?b+$n~dM;|#>br(hisjn|b2ooE|c zM6Dx`(g_K?KJ*}$-WTP)G~f5~A6S*vx5Bj@odQRLOlM89_Z%T&FJLhD+Kl0>$Ik6N zT3)ws0{Sn>M{~#x>DJ`DzU{vZk3{s=EO4Z%?A;ZpJ^Vi+XnGY{ui;p@Pp5<qZ6qo# z*?S{L1>w>w;1QneQx|5Hw22WYXWaJW_Nim_bb1!9<9Fn9LBWN{rLLH%IkY_p0jDzt zPwfEAPUUfH8kZ+XVe4qe6JkT_$4F+%&~SpMHXkXQ*;z|Q%U^L>_{>gBbSY&amG+aP z_8D@dpYRS|7io_m-MdD)RumXduOuAP;wux!E*RH4vpx^E7vJED|4}M>!xSEFKcxZ; z0R#m5Qz`~dW;V_Y^#AoOUD~n>Vnl_!)gbCg2Vr@SI*rxYA5JoJMsN^En3L35SgEw{ zYeGPylHVf3o%#L{R^ZO65kvDSVAmZ_`D-K!l9Fkxi%#X4EdXyPWk@Rtk(!i|^a~qV zcBB}iroRhc<$eQ<UNkEuWo6|hC96ghm|T@jT4OvF-Egaz-tyNv2uz6-s-8+uzR*VI zKuoErKK*bvn0}%me3xK0av(aUX2Eki`bv|-lU(dK=$svEA^wtgY143uNTJZBZdkP0 z@KKOo>bg6Z%aFGvylP#Feg>mTkX?5&WgNU_t*3urS;kOP(+H%=Ww{5^#W9pM&+_PG z%9Q6_lpDG8kz?yQ#(WrL%d=>{6lK_Qip8|d98UcCZgjJrf}DTwh0XeaC4s`M=B1Wr z<3!4c#np<oPF#8Zf!*0b$wU1!$~)^gbXIt)*t#xBdPA4QY3%ibUhb~5FBHV=MibxO zmeQWSN511JQ=U&A#<r>4SAiWKgYDMlfx>^%BU?QJq5eZp4+szt&JR7dW-dmiMlMDS zCiYHdica<pW=<|vX3qaLqhpmP<%bv%KT^kD{yHivnUYm{R8UY8QGz(K%&@m+aVFYg z-@mMRwhAI_US_VZ-+3i3Yp8iiC~7Y;i;+SlLME+tCWuApw^@H<du}jhHaDdu6v4CJ zt7{G7Ojv`*SJ??-0dF*mE30gmSlY{qFs=9?pe+WfNy=RRR%0@$uj>DG0I3cXH+T!9 zVW>F+H#9S6Z!W>AeeBa_!>_iEbBHSfjV4*l1P#S+MPt+jL9Z@*n7I*9^(f{zJ2k;T zXRZcl6T*4n&d%R$pB{4lRyC01poX{1Kwwc^s+yF(E6g}Y_JJoiah^caq<yi0<rdA) zSp9eH*DbDvD*l(EP+^}=YawIK;Vy62;AzHzbCtTAYOkQsxd_WSQMzn;#P3>O&<~Jn z>R-vF&u08R(@w~$op+QC_XY$LH(0AJ9#mn^0~&|-!szW3S93yPiMbsgJJ}2TpL9rO zU{nwP&>-<c3Euyt!`A)(Pl#DOlid&_oLD`vWxbg<42afx6B*RPBT$X#-ykw+#MF{r zUtX66KqA=Ad;Z%kO0b8qQNCq@-lBA%Y4U>$!QtxFzsBSsnuOp4C`c|68AnF$UK?r; zDk_sod@Wl1eWAG4;~r%jiI{%55bj>(%#KE?Dmb?wo~qs}uhyf|d3GhSs&=m8z?|TA z#dP&^DZ3*h0)m0XrN4)amaSzgQ6_hi^iviQmi+!ij&G2**N;gkyYErJf%CfWZ8w6| zS8kc#y!PAwi9bkF`Ksgx_u9`({(r+S=JC^SoUQEb{;M+e;--;<2r+>SLige#sH}oL zs+_~UfCd>{Q5}F5w|nz-w%py-S+g_eKz%TCYMEq|WBPxu!nal5JvkARi4#!+s>Zb{ z?odF)V^PhQXNK0hv3zg|3*1M;uwR&FAf<z^2PzUU(cYI|nMgOVxM}#R;4Rada=zY1 z>4H9G4XM)1EX|a*Jco(Mv^@I~|Cn-BuH_|H87f}0YKT>VeHI0M?TlgkC(eVQ62tZ% zeDps&Q~uv@Dx2Au89AFt*_qq_7gASwE`*;YbNdxd;dvnqj82LUCmZ$-Q);*znSQb8 z?nLG&A{yY{N0IEVG6Wk-*X?%k5bzpcJFhqK-1da<o&qJHl&6aXGRg#Q=6xkw>>UmX z#<R7fkXuP>N(9>(24}s59+*(r+41T^=I(n0JSL^+*ss+O(raFbXf0*2Wj57OI$|Yd zas3B&V=x8bB_ioD-B)j`So#jm2egitG-tnNKTganKQ^jZ@^3aLY7%`G#aUmzz<+{A z2y@J0CIbSxr2qm#|DWJpEM0Al?ToB!=pF1Vma{@NQuJCzB)Ym&;DLdy60gzug|)H8 zNWp>6?4(MSxWP(zM6tonP!Xl5fTgT%^4>KzC$*;<G;erL_$+QdFL#`0M1Oykhr~NW zLIw)%R#Q$|4|xmRW59yyPr^;G?EQK#ZQ7#&1Mx+B^}c}S`i2J?2vAH+pTG0ydmjLB zdR^=YG()pJK@LYgzmSUwkXgH{J4dcXUjkO<6)-g34h@`rU#{A660_TUdgM#>#AqKQ ze7S8lb1URy#j>gDqxnYET{N$5{Bm~U^Fyt?S3XLdc~0>0E05A`(Rh@~$o&;I(3z-E zTgDpZf?D+CzKe`PdH+m{h9G-feBa8@j*2)r-RC4BFTZN!RcE7!g+S;o@?>I8B5=3D z&K+|!eL&;$+eFCW6{a;e8c`6DU1@%K(4sR}6}29H-;7@5^V#3<SEWjNVh)!ju6Mb| zTO$4ZHnA=K9JLrJwj9mzO#gV~d-3}8``3BjLu`%siCWA-GKyXwV@-lm^mHv<^zwGb zL>2Yydv)p5e9dPLYT(sEDdq6+FteYZpY%}SLNV^YfB!CDuC1<0&I;Y_aOu9k@Z>({ z9GCVc1+Hh}cDpUAL$uRp)iAX)b8>SV8yd}2)g1j!&(1=@!3!Vl);2coz3>1_j$~<j zym}W38MV#Drpse7aZ!UpE$=(B2`ps0%bML!vZ>@odpjBqu4q^UeRsd&p)${KCOkBs z9%-c9-8q6YFkLx`dWzD}8*6iOAG8G;{}dI`@~ltP7sh;j`H8MbcJMCNcJ$VTmTCCJ z!466Z{H$(vc(yTy)RqGQRJpFBqqy@e52tBr9te1@wC0{?>grsrF6H8Y=hy}X`LV36 znws8Hr=4}rmy^d+htK(&e1lUH6O;GwFjTl-_5}F&ap=57e_>LOyp-e9Gc&P}u+|-& zeb*a5oUCkr{bJIw3XHPM&nx2;5ZK9~F4bjoV61{koW^o5U+ga->Q_^3vB%Gn8|Glb z`rRZis~V?ZW+7&D+1}6^t4$y))Oz<iz(7cNays_;H54AV3`#65E&J=&FLd>l8T*~3 zupYvEH8r(qJUr;b!>)6thYE9m&u|`}ciFBtb7}p`Er<Xkk6WGi*;K`9%Ru6@T~O26 z?qxVB^o@#Kis0F@^_Ml33oEPKWYv=Hb4B!#gO?ixMR{OjBN%*y)m`tl0fdc>4J|LP zCqcftj+!~KigGJXdTu7nR0qGRsA#;IpVIvKvnmy2kN)T8{ITZtfHEXC8k=in1oXtc zqU6r`y>2dEeL(-g11p~|aUtB3U8Y>FG-zE{zR@RjQQ#Gnam}}{7JD)aQz4!oLlOra z;Vj|;A{%2tR9Ix^Mt;BSW7+7_y~O0jQ_n!Xff+9DL=20u3G^dB7TDKgx2l0age8&= zz0R4Z$T$t@5>Akuw5Tw$D8=3~KaY&r!lf6DbxA!<&fMTO|JyIJ_@k#`DN$8a=?Ozi z56-gcY#b&!+bLUMYp|dofX8$CsEW&oI>!My#$&JMMx8<!8v{p})i@=ky1e^Is+w9b zGjjz(eB3{u8U5pvlXm~lC^}+dCtVT@`ME`;n9e`F_-`cxjq)KNWh&;a3wTzF7BXLz zHB<Y;(UN1ccUWw$uHwWs|6Xp2F$BC>oE>(3zP~=#=oGQ{Zf^YDJlCH-y%!bHme!oK zC`x2}efjoh#y|-O2ts!86}ZvS(S?PqU2JF>IWb$Cn^6LH6@~x+08ckJHdn@60<}D@ z#yXh=60&r!XMS239##H@WF-0$EC*?Vaa>a$11d2T0=-8{P|(`;`ku2ks=|4vnhx3{ zol21QMpU%D%i@NG_kG^Q7xC5O<D<<J%VxpuZqCBO!tg2#TrH-Dhezs)i2M2W_CABf z8s^s=n%GRGm1RUM;&V6hS5LQ$tb{~BbTrP}QfLyO<MV=t{bYzO6@)+SN`4ZOBSy3= zWu9`_%#5$nM?D)YI5>C`2Pb1`X{iV_mH6E@eG}6|6}VlIsYyoKK~+`NZ4u=t)AaJH z^Bj+!>Tz;5qod=Nu+Y7IN76e%B~#7!BR%zyJLL-qNzsBMIH;qmOPEkrPEPM@W_DJ= zbbeuuwzdw!`iKg>{n$D&bdarymK43Ow=}o5+;kvjTX6m3OFuX>Ee*m86%z}~>OGnL zRv~42u3hK?yH}%cX<OzE8%=j`vs!mW4JSJ*EuA|^1>7J3mw=#MN1cw24t(xCck7=2 za|<{#Ue*KhDQ13bKPgH6JDcQfys~n?+Oh{JGn7Cef{JR0f&Pyd!&%8k(J$*79&vFf zjraW=c~SyCuaK}fJ75{E_u+3Dqj?ep-MOlNlaIR3q3k;pM`qv;)FnnnMwh(2dtzc@ zpt2@p3lO@fwi@B_1@zc|#O2-0;oYcv8SfsFeV)HAG>eIdh=fQ!kcp_NxpmA!J$)r! zFWHdzdPbbTykD+eed;~sW#vA}InvM0UACdce=DGPd^tI%C`m|IoH_V5+#NAX3)-vi zh$e>NVuY&MKibAgzT&mj?(OY;4G3{5%$Ch`ML^LWpu2yht-c#ULqm(NZW6i=WQ6oI zKxxMloS@k!(iW9Gl(%}}7C`Y5h(}+*rkO*HO_kuxBoRM8JsmMuh*A#EQ+0I1&d<%+ zWF18>BCYTeD1``i|M6l|P@%S{snf92wegFJkEVIq@dsNxA}?i-c;J-OTHbI*+g8nT zFQ};Qc~7>nvx`GSMAWqO#5?Kma<S8Y;L~s2Js6E&fPheq{`&SAr=-$2D6s=s(o{ma z3C&fqv$MngtP^8`vNZR{nyXujOFw_GOe%zwhBTG-sLvs=W$oP{blB11B)BE}LlW_H zzRH1xhsS)e_c9!~BZZzn$YMld2)6ngj)kT9c&iwxG9|6&%62&oA$f5zO@*w>;+BDb z(ypdt8*lrBPb%l_KuEE6y#${@5egbwOH(sVFgIaqh&%owcS6Z`Z|sxcTT5H(uCs=U z;>q?7qO7c}4FLg#P^_FMX=!lY@h-hzvMdDGvX1&G5HR!TM9}kX+7AB=$sFXMN=8=N zHAOeQT2H|5(=m4%lXc`=q5P)NDG2Z@OvFr2(!m!L)Y0*_G9keo?1e$0P4=-fLXxC( zE!8p~3Qux2aJdf$gO!Qs4%267!Q2P5lL%qb7Akd4Rq%Vc04<)KUk!Vt494a$S6u9I ze2z1!UAlJu4kFV=48I_UR|&e`2vUEmu4b{Y?31|)tl*@H02(EjMt^vMPhDOXa&!!N z-55UbyV>bmU78;!cpya^25XHfPG10Y>V+RWHPzxEBQs0ev~1zgUi*uHp4Z*D=0`#g zH$_zq`(lupNY2UxtLEAw5Q?aoG@te%R6Tn9EqZ)m8`<gcl@XPm;AP<}-#@ybna7ct ze9f6b(qK}&>S1J}0{9axz(I-n2?Y*o)(MNcwET&JaqIbf*&GV7jsVUFw8@`Z+13)m z;s8RXK9RT6Wft)9@sANja<CK|LrO|OFq#v>IL2*sNE0o=!NFtgc)YM|bj~5+6x-gy zXy>=@tgRIi&485S<029)f~eDseBBu!RQ}p#PpvL2^%H_fI|sGmo0301(1Fv@>TcHc z5YTm<J=e#`$tFZ8mL#$<9vSJIF><pMm(;}}>~nXf-=D1hMVquJ&$neH2d6bCk4kT1 zM)y{=c(eu1mLM>a+q<#J-2I0@U<||nW?Wt~oC>KlE+;EX?^1Q+<m{{><pE7SGQTGh z<ilJw#Kpz+`tL0HPnx>$+y`08dw#u*R;#h>3<W^Nf`Y~T(3vn52}Io{REKtTh~V!G zJfvp;!~Rb1G~V}4tMB_W9gr;4<AQdiY8)h~#_DPp8F;b1|99Jop&=BaZ)eEqI;S>+ zg0%F4wyy5xmK|bZVq)fI7A0~1yOXn##=^$N+rirvxJcJRH%jK;i~JyYHw@U~;st~J zdx@j%b!hd;qz?y)er$!+xdsp2wThX0({Bns)~EL)a|7eTV)(2GPyD6`8OaP!agoOY zld9u?gNw5uWlmqqw}>80MGH3lXk}9iSWz;S2lzb8InNl^LyjMEW&Kcw?{RWN_MgXx z|1vIZZ|STmDnJX`y9jA&5SFH<rbedgs9z*<CLLDe+Q}WtU>_c|iq1%5YHE1@^k{t3 zy6;_@zv^uUTTs<IjW{Ja6`0kfGKfk2dqY)c14CR}18n99>FVk#QnJ(iiVQSW+M=7D zmQ6}3Q?C}~=w<JMgM@@sMZnv^5ol~PSBvRXaWJ$=Av!GhERQyjthi+g7_5_}l1{!r zhpzVGo`eHON_3gXr%Jn+?34ELLgnn}xNsH`5z!VGCxe94lz((}bsenBz7r>5KZhgH zQr?5m4Q2bFWI`M1UlcDrOV<(85+cC~b`@mBEND>y#V2aSX~3U5Zh1?lSm;sHhh9Yd zr-w&bXk?fYVIkk{B|J<1vR+?VckH{Na2OC@TVMa}T^RZ3Sg1Y2tIB{xXRC!rz<x!d zqZ23m6w`2R=ShiY&dxsd{q=rhA{BYLSWY|7#MEEKX>4q4je|1~d?D0%>A^ZE$_kc2 zwMpJ-CI&hpCEn?J_}baogjc)0iecy4DVNOG+zfF95G`hRj$fzbN)KQAJ8XrDipq{5 z5DjdEr<>asM4zD~KV!cg_b=@(0r4%SC_bLE<gn~7e**{-7S@j)r&>`x)qjc`$Nn#J zH9AlF=!Jm4g!O@kp#nh!=V>=LM7NlN(9JEiWS3b`a1`x@e^^Fd{`&iwuH;V+AS5|7 zI~yoKPfLytj2LRf;)1KE12QNt@9V{8`Fx!9m`{FY6lwL7goFhnB;UyibHL!P^E+>O zM}1$?*w}<7i<<<YX_*u@biLq3E<Y~%n=(3bpnR7}ZBp8wk}@Kqp0NIzx2bnd?MSi- zcUI%|;idj-1v>5+$<xY{3;1sZ#pE{xPj{5~$~8Jqyp{C_P9w3~a?o`;8tC4mU-L?h zbQb{)^&3$3SV-Nx{C=v|Oq&eN7aZS*mGevWdUYS^?73+<%@owxK4Wt$rd!!0KF)%q zN-<}5clh!WlxdWA5n+Ra12<70-PAN_Tf43Qx24tG=YDFz)V=mb|J*H4v9!{9xkA>+ zNPZdkBh6z5nDzL`$Vw_fYEcY(QUH@?ko?5NVI=%1C?isPr&Vx?i4{$dasjX>ICy(} zJ8A*V_4)hbxj%@JVW)R`VjwV4Zg^2$T^!ia^t9Z=u)2cg{f95r%Z_T9EkC0H-nxce z%Hbj2!NG=^!384`tE*ES3QFmp>*o|Cz7N<~?Lu@t_YaLuxa#@M%}xET?iXQ*53R>- ze<QZrz?qquy6*b=>T*au?s`@tvd{%z_v@0E*Jo#Dvji0rlLG-o7)ti}#Rr3r(x3T< z?7v(J%fmA7M89GO`x^`Az|qNRzq-BSXVr?GVsCOQY$PhN-&gn0P!txnUh%(0N=r+V z0RWt1(Dn!x1kpuH)-p36@Us@cO7h19@eE5Ujph~>g5n*wa%J|vBFL^Ve>aPjS=iuS zx%=J?x;4^rFfiOGbmDn*42fWLNV>}u)Ls#gm8X<`oVUfGV~vTw-^)<ezt1*e2~Z1R zk?r^+Kie?AuB>CULb-mg(wd#7yBay;zok&hFY^mw%lRk^}myX)Kw{W>{57Kh4) zVCRVTW40s4!odN2=r<3%rYB`^GV<q1nzHr2-QB&vu=Z1cx+e0a{XPq#p3E;IfyUQ! zBa<JWU8QCUV4KjI?%)1JpgTJ~BR=<zPeG}lU|fjR;&nSdF;4b(6jJkP__(DF+nK@z z7*Ca-pircV_%`yk+Q0+2hh_SRoGuNJJdA69-#wSH?JK7W=OO|i8%ZMX_#{kuBA|<q zE?rcRYL&eMgoTA&Zf-`2i@WnbPBtVnNlDEIQ>ZAb#U>qnDw!=?*xBNtQ+O8oa14kC z0`J#S3*N|^Pt_XO;mt3R78!qw3?J+~?HuLias)i#B`2G9b#+PVjG@9)g@=ZLWTm`# z`6K1%T`L{bVqU~H@|Nx<{*p%!kms6VI0yy>WfV4&?X)}T2a2<i|AQ!UW$oaV7t~&i zbZp42mxoj;<K^uUvrPuZN>)^$m_kfO0=u4TZ-|aqfhC;+Be@c7pvee7OaN(IdnB{O zzALS-ITJ!&fc;Kf5~!$=Dt~*ur7%2<w`itNFpObEFefRn9|QFxo1?6Z{5m271C_K4 z4E~X6Wtzp3V*=N}YyNZGs-cYJ-Fd&kpR@jxi<j#V7;IGyX%Z!}T&|FR2z7151HBHb z)ZN_;kUmT#p>j;gt|k6=rGvbhdzO(6+x{s@OMy>fToY3$oXp80>*M2t(dOJRTYi9! z180aYSlBK=U+;-qQ-ET!wLnkq-P2wG4i+XaEEk*2cT7V>Z}(wCfy8Ms<LKO85Fjx- z$0+v%%+!WL=D$&1ncguwp|wXZAt3?iE>Rdyp^+7c2jPwO#xs%90hdJ=p#QzY>9lQ- za(jEP4P0H9b>x80mKtym0%*2)?_q|8hNZcHVKym<Wnp6a1O}8^6v1=L$cmvk-Z&Bs z1w(d$`>2Z4N-o^<8gJ!3fR^Rt=39ih5gvc(Y>XTiH%>KVe!DI-99$Lx`uhb@-QDxJ zIW?W=FDff5efZ4U41jQVf#IrX=grK_nxmuE*lqOe>UbH@#q>Xu%%vF(E);-X8wHRN z9L2*Uh&~@$v&+k&FeRL6stp|!X!<SaOLGlPs{&pw{aKSmJV`H8q`|7LgnOMD{s@U? zobe-E=%g~S6o+eqbc>}o3!@WTv^6v^ZtOm)oGQmBU!Ps;;(-v6J&8%mMx=A}KHhq0 z+U&IEtIV#y_Ft<}Wz($wSXJx2-vTq420T0+N}Z9@XLADLqzrdn-rk{GZ76E?K{3B+ zFXBEmbh9EHgio&jet~Qppdn}VBEoxSFx%GXD{KEYvdYw<!xa<^OWiu<4HlAQsC+=< zIiB@%_%Szj^1t4KQAXS-wfkr>bo6;r&D3UO71A%iD5e#wG4*GFj^!cj>JeZQEfxl` z8(JHU3fxj{v1HOAj2v|>O>>Yy7?Shz?M=#KS}^pC{@q*(V(A*J6^&&qHI1-Lgf=P| z%g;<b0$1>Qc-MLAP^F1i=g;_CynVH^0+Y?C?Tgvz=l~`xf>B*R_S??kbWuBgnlR^h zso_W_;fcCNqIZ^JBWJo}ax!<J_&d>%qyZF*jK@1W)L;$99~iomqZ_SW1#&vCS!A0s zxLgH)|L~(3j=a&57ige-ljel(-adlz+pvB8E0VN!FeaFoy8QzDIZ#wnGo=YRf$Fc~ z9%l-eEOg8u9rn?W?|w#<tzJFdTHQ$`hBNPh{-NT;gKjqc-6-Sw8Ns`e!NH(JWnkF7 zv$OSF@4?0Gc}G}~>I|~8Nx`sS(}St0H9^&>nP)dEiM-IP6YS@Qr+>Si_&Y=1P0j5u z>ldQx3JmL<#ie2~fD*30sQTvWY8V^q(=$Vuc)ZoR!+S-`_@n!Q-vo+8vAigbm_&TQ zk9I+~ymHEs?=N?d$u|Oa?2E%xf>|p`p@VJ-1^cI#ynr}DmmDlq)usLMajBPN&n#B9 z;rEf)EFIVWrwzrIZa}?1Yd6^hi)UCF5{_E1W;HWn>k5HS=OzkHMvg41t5!57=Bp-# z>Bo9>PGVxCzsH(V06l3sUT3<emsb~;h6Z*EKO>V+l$2!o!)7s1O!FoB#j^Blwrb!B z7;!~RaZpguu>ip57q-DMT+Ho$$YU*pa2uU_D9LpRst_XP>uak)1dRasUf_NP<-#d8 z_Mp9;9lwruxsa&5pL<zh-8FDWGINhWRX}pvU1a2|Oll3PeT0-$@Q>Yap`Bxz_zy~k zT;n+hMo&E&4!3mhs}cmoQBe_bsJs48LK>^G-^iv5t)!<%&+4x_@W1L(#qPhOaAk|0 z%f6i~PS@>*X1T%}J7>2M?7#e8-Rs@HC18&ZioUPYjOi(~I(q%|%>;+PQLXnz<LQWQ z<v$f(MFs~GU;;LCO3^BwxdfKF|Ik^AurhLX`2DLn@8(n9qJQao{KTHfkj9w7KATjD zlKCK$4MK@J>{O;g%>>L-G88#n7Blv(^6**>$euJ0V$LK*fnM-wmM2bl(}a%JV04CJ zsV2WQ*3>{k$Y9fVQ3U^{40II;$Ae6ndS1WzoKUDigh3n}bnK1^m+y(r?{S4}!naBk zQh{~{WL}?Mrs(woDa^k7$ox;)yrZo@=f9CHEG$F?jft_ieXXUSB}|;1?QCmjx=J#z zhaM7TA7hBburm8+Ai?$qUh<dPXJ=JVP*4thED#i10_xV;I3r+5`?!=)Ij%pRw|KVp z(3j;*4&i6gt3@^gwl9q3+&n!!SuLM1*VU3fi@BV9&~q)NU=GkJsn5^(Qq1`S*Vo~| zSqxPQ_<zL@^rxPuf~%?C{z&q_86{Dh7^FWB35f|JI=iNyqMN*$fkB^JlP&t^HQw3u zIyF%P)p0Zi10hkeb(4`1Wgy&Jz^$vK>Y(fI8%M`bQnEym+`oCbo)O+3LIuXVR_r5B zn%Yz9+KSNYDrV9i;apRz3?h>p70q%m($;?_^TQxhV>UIa?T2oB7U1>aJMkhPk)ooa z@JF-%vbMD7@SJ}ygE+|q8=LBOi%E_y$PC}N<Q5Ws1#q=xQO|=rwf#|c4?+h{u<MwS z5TuDZK0HM2N<!IJfNHL&sivVklCa&uozy|tKy}K11@7y-f5OX#eZEEM%!L7E2FHRZ zns+xTNNHst|9YH%2dqih$Cxq&%NVIg<+6^!V5NB;)f88E`?xh=BVm;9h@!B^UW0IN z;O>gRa78aM!OPD;e)K%SKYYq%aGn3yl!{!mZ_~9e)}067c?iuiv{`Bb!(|=zE;SQi zov4_YV>FZ%Cf*+Dlz4=!H!h^g2zr1i+Uxy6SiWIuZ=1S>_xgkNS1uA4DwLhcNtx=> zXF*!pnt3}78&(%Y@k9Ps!TlcQ#jx{p`3NW=Y+z;hmCsW$-xQh>E%e~#<-M*1#1>2K z#zRo<9~+Y~#gI>fNB~#9&kk2D@DVVpK7oo+E)DpLy79d}BcHatz3u1ur;_Zq4-AvL zt*aLp6|=fUIYZP;)5QL{_8B7sSehvoD>iPAo5_!mqC+gUJ6s`ymO>10Z4A&kNk`n( zJ{$*vTRv?|{_qn~l80B*6*i`x*f1gvM&2t>2na@5n!CN7l3-R@;5bL89zk{?)3A#J zGh^L#19K995HvmC$4ENN%*@;qvJccLec>@V+~4=|^!rC!H0t#H?tZwQeia!tN@GmR z8XtY&4Rwg08?xFs+I4s|F7Kg;IB`4^mlFm-bV`*P0h<K6v8qRS@NGgOhvHM1>o^_0 z_^Y-^7n#P4v8Cf*o-yk(T@=SDSJq_;%hKT?j4^A{7e_5QF+HKkBmlr^_1nmhw2-zo zY=NMGv8&O{`?r0g9}YG)4&L+%&547^G0$4&^eh<`))HaVpS*B|@0|DD`N(p74{8Vy zwEbY`n}Dx~vEzqp2%8@Z3L4nl9IUwe`zXKUCjDHyachpqx_YR!zH&crxd(%`)=yj? zdjfpJEU|(;-?*2dWvnTIwmjq2)g^5Id|x#qnMwh7CIJaQj%r?HVon6Sai@FL(bey< zAS?QCL{!2cUrRU$9UU<M1<AqnsJX3odwvn++;UV!U%&2ccz&eJ_v)hisI@g=UTL~y zkw4CP5|Y<E)YEf-@Rnf{PD>Z>?)I+G4;m#oX(X+DueiTN!vU#5I9pR&3tC&7S>c{< zxw36@V;ldrC%>eNjTDzt+TF1$8kX=E9#eM%;!sAmQ{PpSZoU0gze(Ew)nr6L49QS) zOUolrfF%4m;?c!e1ad%pl?euRR8Sgh8)b!{ygq)FqIjlEakjF)>*P@!68LktLxR#F zaA3%bm82=Dn~N+QlvcPI8WJnDgY#}s0JUwN9&k{Me(&7!e#xZ!+j^Ue%k@M&^qK0& z1Gy<DCaS}W?|6Ibg5HjvX`7?Zz`rs4?`mNdc6M~niQoNfa$AF9O%-YK!kcAZiDbRE z&YC*eqz#UvU9fP^$Q9U^I`pSgAw!#;v(xhCC&>e(^1cmwA&l0ov{K33X^l<N>8@(; zog4d=yJ%31Tk|859+s5c_bza7+=83PtaQQT>D_7S>NDQ3#FbcB)odh5ZW70-?pzJ| zbqJ(FjApX3mi0Yl!Y-V`uADAc;y8Bmi;EPW`XVZVU9LYHe<LI$*#7?MI}lyQwt`yb zcb_&lH|+xI(+*S_LQjIg>dA@g8#+Hf(C5QsAv9@iZS36(tVcOIIk}LGjEs(1EF{v| z{GlO2v$RbiCH!P_<{#(K&CTsBX)Z$-41@*iRS!r^4DPlAxaY=@T1!2<m}>$Xd(X<M z9k^mnQc9|_qN0h0CbAzT)iX4$=`RHeWD$5OP&OkYQ{j(eO!RV3WUS`5s{b5a+rGzr z2*jYj35q3_Cl_p4X$G}N;xP?Cij9qho0_WNSv1qz?G0p10~&9B&EebH#E*%O*XY$v z3pFbXJ#naFp^(D51a=6Xv*h=@C#Qxfe?4K{_*Wn0ci0pi5wWI!GEPJJ$5M|IJMk?X z7Xm3ENf;U{r{mw-W&H3k4FQ2;bxq&9z`LLu^;O@4ySqDpQ@uDeB%FnXkuU+!j$kt` zh)jozdn<%U{i}mM$8d1V*SFf))eS$~dJXfRyYOys_Tv_TfFCY0cGM>Sy2?RVQ3-mJ z{Y`8kIXMMFs4EQSdP5gCkK&dl01*Au$2I!#bg_E8e}aC%V20PJy2F@(+&~ycAS2Ta zbd!LG9ai~a7tdQT|D)qY#UZrs@7sY6<5^)NW0H`M$H$==80>*UGV=5DSItubW0IPz zJvh_$`4sW~h0XGhM@Ald!^$BcAuVWY|D`2evpwmn;An5BGx8kBE9G}7vgXkl=;`X* z#CYa95DNp{#X|+I(+Ug~^K0Ex(aKCKBx2`{>)1g{b<v+6`E9T{Q1tS()(3Uy8Igs( zJ$#3L4|MqA14_i&hbZ^_k)m;qQMsystP1OJ&3?g-1}{@$p&a+TAF~>Uii$qb)SDbg z6(F4~S_J&280mc*v_Xg<h@s6VW#$~Qv9Xb+o26X(LAICK5))gTNJ~Q~2t!MMazqA` z5?50;+4rsp7>G;Jw2a{Cy_%ccpsQZ_*zU1mhR`S81^}8H8-+^Xr~^VZwe*ghx0W7n zpRdoa#X%o$K;y>+LrSe|Vj!2nwvKu#aNyS@mnGzhi;83i2UX?d<YM(Ha5+wJ9{DL$ z-Z)_<*189D_OhfN`QeeAr2N|FM|~THH`~U44(bvXZs|UO>F+UDyuVpGAi3;u`1JIm zCl~eH<Y(O7SX5M`6v7s@ymz5bdI7ND;E*iJe}v5IDyiJ1hpoqc9imf?{mKo|fNHQ( zj5izI+{F97K#@MYzSWg=Ta1|wVS*sib8&7yy}YFDRv7lXKpOb>_b>2VD=lau7b<y0 zjaFg->wL*0Br@OC{@<S?YV&kg-1bzv%b-3(1RQ#w%WL>j4&IM;!i;gpTIGV;iMKd= zM^Q%IZ|8{$(p^_3OI0a1xBlU?KZ`vToAJ981fVlj*C_k@8@VO0nG9g7)YOy(CfO|O zqUn5Ary=2B_RlAeEf_hb-LBKHT(OY`WtXP1HZ~apnE&i`V4|Z21Cxwg4i{b?2^DgN zP<g6P@@<=H8P^hkszk?F*xFhcAMTOo-wo~x3&H3!@_>#omo^ZC9TL(7yq~A`F96*H zGSZ6Mk6?lFv*y%?jar7tKiSWnrjpYETj)OBBzn3W2<6Zfi>B=>*|G-Rl%rM8E}ok| z{DN`3fFgbx7k2B1$Pg@cTR~w$1wHvs{7^*GY~Q<R4Z4D)M<h4Tr-}V_7MGCdcKQ<D z&D7j%nr<~n!Q70T99X{TjSXxNw)H+jOYhNxk6ZfO6auFUry0rBenMil)ZcdZ`vviN zSXthVj*e!wwIBZ9NIp;xI%jb<E;~KJVNS5JaSwes1`!3Xx>v9b_%LN<F8uubSG#75 zi)zE?<5W~iwqSh}WaRX%m+eQD@%{JgZ#fV4H<zTQW>z0+_a3Pe-*6|vOTJ3;JQ1zx zqi|C4f%QjWY?z8NiYozGL{wB%QRlhtvZe_;palg`!R)e(?Ck1VDi0a$^eUHZfh8rT zW+Eb-n$VQ+J9@h?!R!Qy<}Z4<*QkeykGjd+5(_Xf@w`uF#^&--M^ehul@)ViV>y@v zt4k~J6N#|1t=UxWo#gr{tX)&%$llY_Re5nELqm(+To^SGGdCTCACK!Shbsl*X{HM9 zq-SZlUWNE%WJmT6sQxd0ymqKw8w!u!Z7|CcNq)Y*z7O8Nvg=!8&@<m}*85Y@WKN@l znT%I<D(2?qrYt7pDoQ^7`e(@P@<RB5;5<EvS}k(2@oly3mUkPaS}nLZy{G$gEEN_O zeu{|jVNmc$McY76m^J|i_D~kx7XQYmmI{-<D=V-Y6m&D`fu|v5?j*$EF+HYX!$F#8 z@<PnwL_)_`+Wihrr=g1L_}kph&cuLtTU>OT@6%c1Irk0ppDC-uXhzlWpLkg~BoGkk zPs+;K%GTA!%FdeM|4HB)+t`~}n_3xJI2qagSF-HC6S+O9LNcICh@syTN!@a2XsLCj z)WU_*jZve>&5O2{Nzj=~U0+@%-fLHG?FHd{=Eq0V>5x(oLkz{q3b!S5WtT0h7SNiJ znN6M(+xi3wb(+FLYqFLt2~8joWJ7=fSWBdRd~Iq8Db~i6CNrq(Fy|y0#vrfL{*f7w z9wZ`q-<jM5nnX~6ix-B@danlGS<{?S8`IQv^)jzqn#m-MJ!dE?X8_w>Rslx2n9|;E z0NF$u&Lhpa6l+e3mbICNLPlU5WBJKDqYsB6^&dt=W9}G^T|UZ0osxn>o2wj1;>Yk9 zxvDrJiVPaACSi=7T|ko!qHD}+3~<G-`h`nOYxd4Q`(kQuJrODqWzMy(lnwP6ll!>& zojnus1AyRzgzjkg(Hgk@svDe~R}uf8+u_{NUqVND7d_ndu-{X!(H=@7ycydun7&89 zdlk9yO|G?xZBtxx&4qxcHc7&e9W-JB%pMH(o-X!mKe4&kC(N1V8ubjvm8iZ1(k`$? zU6o1qyuVMb5dM?Myw02GmLCG~e#rbu&HZm8P3-N=tt?c`T>jsT;D0k|7C-R&CmR}O zFnroeiB}whRNg*NXZ;Q|qJ)>M$)2`aYj2P%JrwsA+N<#G@K2_?Q#mzbeX#Cg0P&qy z3?6-^d^X*kaRFDsZdw-Ij?@tT;8w2M+Ka@Q));lr*vPKdhcGIiitEgYXl0sg^)M@r z&Ct=$G4Qta=0!6ftHCU*emrQ_Cvs0xu8+GDyMoUmw~4I}?ae}c=Og=qICmDBtSq1H zzG!6&uo8uUyUV#-w(J4<pRj#B(@m&<YPatvmW=T~VH=y8nwcB9+PM68D)~xl%O0Bx z(f`JvaU<NjOFwBb*M%S?Dr8O+2H4ChL0c_#9j`xjb-TF-_-%D3rUwy<U8;Jq5@8zD zsHYEW_9aH{V!8=+9Mp0sl~+!|k4qjUp_95JC%3FMxA%+0chPT|8-=>>#)*Bg=5jD) zc`)m_n$*gS#>B`18Y6uC7tJ0kUK7ltpmRc+)+V7XEIDlQfzyR0CI~|6UdUxN$O3zH zZ4{71H4Jbok|EtG)M@VFN{KD~16PLcR0J#~Zo}+jj7*3h=hxAT$=f>@*W;B*$~s(A z4m9eODM8ZoauA|LRT{WR^KRI0?k&iq=Y84gP+;HDU-=FLS1<$jjBZn~JPLq5d;&=J zS+)RP4dJtvo(yLkhXL=>3H(VqA$eihFlikOnB&|)XEk-GUM1@j2v;oChKDNG76N8D zkI>+Xa@Hx<%o-#=VokrkzIm*=>s?}Lx7MmAE}A7`VkTex>OV@qi)z%4_^ZlGO6{%Q zk^h2f<~1`?9vD#Kf~=IZo9s4s$^n$mk|G()NGwp5n4m&a(@9YY(*Fd&A1g(^9Xe(_ z^k0pn0$bq~&9;&Q?B1PcJ!|7qew9ZkFr*$ED6)`q2hEyBf`eFt%3gi7xfhJL0R*e7 z5(>Xg7+?KBfT~x0^<JYimATf!4ZGYrE5USP4Xt>Nb#Fhua-f-noJCQ69*Znu6>cMK z(Lsyu$xzc{`HixXiYk?b`cwb@*0<`P-6DhySG~xRiCBrPzn{(juJzWIP!O|z%3Lpz zN(#&{K08*KAqROasIwaCa#VFnrCDFJ!;qDF;jCB_VB_olwsO*$q`7p&e1CjKhnYq% zr%INsQKXRAcfyt`N$L;=_vumg(BhqHl_njQHqr&<`CUR(86NXjFrO3yL3SxFOB8## zDG{H*4rnwYhL3fEbS9Nj>cIoH22--}H$DTd*`AbMyv_p_6`A-SCj<$cWX3}C6HDvb z5QCxRV^2jT%?v$yo)3F8ZLvXOIeb_JbEb*=PDnVmXXbADw{j}=4AymQUHQe=Fh)7u zZ~-}R?hGqbOqM8SFhH@PZkGkBq1Il_qNNO3*C;sl-<uPPz>x|L9E|u>`jITpEfkHr zKc*uOTG<Ddv-q{eSEpW=mDzH6q><j49SRIy7!zKZcCy`P+pV>~vkLtHAzyB>kBR4a z0ch!Gi03uzm{$n`Gp;<9H}4X%b@=Cf3@bWj%MsHHZWJv<!_Fky8{(Q!!IOYwG`o)6 zt#GrVtv-p&ytzKXev1tKahQu?{_;W{K2LRpL9!-#3Pd<K0^J_%uDJrc798yEIsQ?^ z_gkjtG&+PoSIm==WU_B9zGNo_ou4%8T>3UhhIk$JW&a{LF&Fgz#R;Xk+7(MyRl9&V z>VyHA7SoRogvlFbSk?!d_n2gDsE%0Ryoxl$q^1TSmDgdIhu}7lzlY&3?l=yB8tx*t z*^-4FJ=iRRyRZe#<3mWu%?kX6mk2RZQ<*&nMrHN)z(ygv7YRgOb9W109hwIqps}{U zz+ParP8BHpQUsFa9|9h=Ct^1c>A)eo>1bm^fqJi6kVN`N!slONf$2&lS6djFNVE7? za|toC$`wACDmIx@*W+PpuOVFLpA`u{@d1~jVrL+Y?W_>$9_{u%E^L^e?Ij&%DCoPS zrwMPeMLhAJWKKk>ze%VJf+yB4#mA0w&4Q~$b}`I&&I`j$Y-=XBY-(0(eb{gYDQ&Zi z6Z-Wk&iTu4u>#+i?t93OZ`cuys<2)0Z;@&fA6Eh<uMTnL7FC5z7%-Dpx(9y{#6~8| zS3PDe)f7HH=X#axEJv>D*TE`u<}4*=RTqPbg6KP~?$hFaPCI=U{G(dZaak8%bL?<* z;a0Xg@Q8#(NtO^{Wk;)$PI}`+gWzRMB&O<8s~|k}t$#85dp)(+n)5?Ci9-_g8j_;Z zh$EiUKKZD1;>GekZl=b_mzWaPq<3cwz+1u}bOf9PUYt7p@|kcNqaIs)4&EQ8c;ggh z8Nr+=82sBT_(^1^hfTG;UpdZY*Q|ybzwk0|nXo9Ynj(JsDYq_PhN(7wO(z}m&luWM zj%8e9A&FbFD#naHwl~nrx9y93e>(Ga*xLks$5GR8_G}PTz!2a{Lcklal4JbKf{gpe zFs~8wdO)s{5B>Z#CE2;zT`7agL?M`f-3(g}Ta*ja+M(Wzb^Xv3`{_CnIL7?q;wyb( z<4_k>YGbc5u<$&+drZts;y`|&R^+*Zd+zHTZdN*w+5n1*H<b?QuW<5PP!BDGMQYE# z78<EYZF!&1vbEbncc4%mEt_anB53ea9)-ec;y|bN90ulhhBf(VEMj&+RP0$e_5nQl zbgBGDf#C?FV;v_@XHveN!fcaBIcm*(^_ZmK^32a=v9WLyNB!u21VW+4Fxj98_}A&x z{@m%eq|Y-1hi{PoY_HW@+Y1ojKtLQwKtNdk(O&=8#xPb>$9|s^)i2*5kof9PYk!OC z75sEWbrcvllJ>K$SyHm$-kKJmkg?A%E;;2F8OFBozqr{e9*pw$3&f@o{F0&|0i7#A z+A`2JO#J=sdQ_|bgXL#apR2_nDEnS-0?|B_?Vl5|OZ!-HcWI8Kv0~2=gXj?&=)HAm zu$^skkx2;m2M>P<ZH~kFC%bC`{N3ZT>$9_CqeVx+zw`MWkFDeVN#OOyY7?-uEsMb| zGkf|%5_xtwuR2)iTG4z;P1sHqBu6FHTNz-Bw^_lEL{Z+iq$&?K`X-PX8e+|$_}#0h zun3#2wrlQM^$TR4(E#c5fl}E-G?6OgZY-Hw7^Pl+XdDLh$&74^$&qmJcVuRg@O207 zGPtsoAykio_Oz`pCByv`%BuuE556<IN(hZnWQ4DRkG(JC&!Cw{V>;P;y$9)3Fx0Q; zME+a(J<t+IPojZR@~$*rjd1@$X;@Fu=-DD}#Le=77zgA47eVX8GU;y~3hXB;kIw^6 zqDr&xr`)srk@K6tFHi0|K~qUqUAh+CT7jb&|2T3Z)AigLk?MyvKg-lp;54+U&^%~& zvXK6#ohtx=g>?5c%xpJFym5o{&|ZNSTudnFK*)!1m9SyFb7As1y@W+;_~QnVEr~dz zj{bx}Jyf6gJ|?~T=}r_vFlG_Bt{OGRTxbIJgP3fiI!R+5y0R!~|D_lFFHR$sCSY~? zQ~{ocYZg5|@kr*IlN`KB)~u8a!MGAxl9`JHYvN9+9k#W+_Hya50rX8h-<WOA<>d+@ zO1O!n+X8wXVbR|+DD@L?xnR1Irz-KrJvcB%4c3d-gn^0cpyH}*4&c%ZU`Jm2WgnEk z)U!^=C<ly9#A^jNJgJRtM3o2G&`HdR&rI1=#XoLJ;$~>71|iT;#QldtXcER&j;aho z^N~8Ei<w24Nv2JN&9GCmvVkx}_Yq>J&!{<*Mp9Xs>AAFtUF(zHum`vcQxR(vq{qYf zG)AjH=F;~;NivTQmKr9w*yB8fwOJELd}#os-QW!74&bcKAd?m^BYX)gMbtJK!?G$p zse-(Vb;6V6oOn({1r>YlNSMtbMn}oJU`)<qO|P#($v6I_>f@w>G(2JftDKtwIqz{{ zP)t{YK#s_jwR4|qFHGQLzgcFh6HwwF0VwKW?@L)Vw3%?f8UE&_?#P0V=)s51NbemK zsq(|g8s$7oNc>%}No?N!y>XGRf3l#G7I}RdaBZZ*Jl{7L<e&B8TeM}Hm51!iY}mCQ zmq{othV{*IE4@Id_giG}U_a-i!1ZxVXgY*y+#jCJc-%Nx_BfP<1yb()nRi90W_k~W zHbX=z&e?cKGpU6vzcyxh_q*6#-Dp^tA;{Btr*9BdGObX1?IfVZCeoV;;rFe|8fY~? z`}*#S!!O^aQ0Ez7@8UWU669$;`@k1dP4AWyF3tPL2ILzli#pMIvTZI05gGD8&Gh!+ z<oLoyl8Y|3Kkja<*ii^^p3gI-)UL8(0qDy)w#5I?Jv&s&R4fgT0k38io?3TXNC*uq zsn4f2f^m^AtyOm|AoGv>aU3!U$8W0J@6&A#5OODuUKo|SrZ9iWACx0I{{lnm6E7tT z*_?k(;x%fSHFq9%HvaX0JO#4T<(mJ=BPgZ+wwdQ%r&uUBVwj%Zc<7o@vVy{~oNF#k zI`J><FR~;zV96?<#me04j3;<*|6ezl2Ip(WE`M~%P}Kj@CjXxpWBe~oJ<Vrre=wG~ z^FRY;<RBU3>1pn6ht5$gn0AS!N2-H(lsN<uI8Xi)BO%oRkg}=!eX6N(P$?S=93DEs zf@#I;EytgGX}CTt8ssgMv>!0Xi#<Dk?>_<j;w=gz_H90$`)Jkc`Jca;{|%KVj;Y^q z?+))G^lX;{!VNq%AA8j;Z-5Y(B%miBaMJGc--UA0q;mLr>zLjnV8$Nuf-pz9yd^zY z(~YyOH}l^UDfiMp2X?-`&Za*wgHH-$+QFyR{focZQ<AQ{Im3dmB3)>h^UxR%o%%v| ze2lcfNS;R=Cs=x>1-?r(oY!LBW=-L`&)%<S5up+7SgXRlW{!1nY(9HBxn_xigT{@a zb#4$0Nysr9)d(@fGxkJ!QKkI*CxkHxcNv7nko5zjYH)73{q~g<Z)<H^q|h;#WONN# zo?U22=--10x`F+m({aWhVkL<Ioc*O-2$RIycLw5IGhMsTSNr={`3&2>A1ph^BWNv& zNJq7SQ5p)NraFm?yv9AZ1YJV*6OVzDIA1-8>m|EMiVhA3%sDMlEC^2Q>?$Of$2C%a z4SF~(IYg*3Ql*d>w7#IE!Pksine&7+rJ*ll8#=+2rSQKt34F|$N2DA|MGi(#NBo-= zdH>R8-x-q-XVfRS<>9mBo$SeqZbG2htfkEcPIheGd8yWdgh?6i%F+)@M)B4&T|4ok z5egO1!V;zi?*0B_)P&AV&u-=KK*EgPNQa*##F@<IpFj&=E^LFw^ahI2Nxm*kJM0zv z*G$ZcCs8Uc_*XlC^mv{WmfZQ|jxInylsockH|t1@<5u^O>Drp!Wb;a2Cf3nGcN9!h z6CGClw$yap?A}rbPNp4N;wd}_VIRxFu<E)W;@tmktfbH~>8R8=-X15<aZTMGRsv;c zpu0?D5eW2hwgJA75;zl+V@6u(IJsumx)hsM2aGFDCG7)Qet`}Y=OomHr?<;WP#qH7 z+jiouoMXZ+tM<%W!J69~JbUwNrj`m9SW#JNrT|rF*g3P&G|5)Ru%r)-!MoI`<$_ZL z7Sg6lbsgn%&<Ft-oA61X+o;?T8$)uoGs4jwea28hj<b0$3kDtUYKoI`ur1vhsTWT` zaRAt(n~Wx-)~d5kDKsP)gboe>%4Y%;v_s)`$P9v^B=1uF&?93RX$!^dX9fxrfD zE{{1UrjyX_B?`#&k9|lYyA$Ay$aBUCJ*3r(vKQt*F5syF5Uow%(!|Z2xfiu4Ds$zP zfzx^@P1NM+*K)MeVOquw{f=aok6pyyg(1nwx&!LuurKq>f#D2HW*j7#Q3ICf%vAi1 z)-Ij?3*86YT<R14#mE5_8^}C%Mb5C5_`qoiB!*hi-kPfJ;O_{N_5|u4^*oJ3kM2mB z-r0cTsaI+}@FGlXnC!J?P>2VbMRhvgzdmxYO}9%(1)i|*l#y>jlKD3C(ZcgYHI@1E z2#QE1^-?3mq9%>Kus{YED$zl$G=zuA4$WcS$N)E}<NoZSSy=t!x215WUn0C1&G5~C zAOtDenkZQEU^)rVQLEB)?EepE?;PG)v#brrw#|t(v2EKnCbn(cwrxx_v2ELSCiyZO z=j{EQeVyw&?;n+{?yl~2ceU!*tGe2gW8QT4OmX+PgQREDtVZOz0sR*C`{P_Q#!$x? zH!TQUEdXtpJcV0sKnA{VbM#Ijk?lkem`9#=m5LpPp`((560>Q1k*chwTjcK(Si9Bk zA>wu^q370Zc}xqR+1ym-nEYYlf(*dkwkQLf2$GSHQ^>FH(|94mXE86~{E^})J3S~V zp8d`UwD;iYDjR0D2)4oWqnKtn*waFgt@~nu^|oz8IfM+kFQhAAjmmcFgOIL^?lz>< zsW%*mmA;{^>62(mWqD0_A#uRhyU4UD*vX)|3+JQCGyAjwwiGqX7ku7M)q~1-^rcR5 zxsTg{&SuYyRpVA4q9pFW*b~-r5#p<8VC>YZRWNA$o9ThIjrkH{MN_CfJHbfyhnZ?^ zfe~_$Z+hfj+xC4eH5-8*G@xGjSK61Eg8DEjML0EBrVB@b97jkb*r!l)R6H8S)aTID z4r}ym?O~jX45E?V&)$j<4?JMPb^Xnw1e4dT-+&=3++q&8P@2jpbQaqPvV+&U+<u>4 zMP+V)3wl@1x%MhRK`POaT#cM+b=_b$=yWm)yDW%DzBDh(6$VY?OJ9P^g<@=+w9yL1 zGok5;na2A-ivn0DTxiKpZpif`AX70FYHTX26l>t260d&`JeJ4vm2}`4)f=7YXj-<> zOhiUs5|4v#Fnf>Pm-H)8do*pHLn~YzkI(l8kHD#0N3&XlU<8ZafHgRF!fd9GQq9#> zKNR}~#NIaqfMV>E3(IdqBD@MrStXr!!q1;qsU6M`k=iJR?OJ7a*^`ni-Mui%NGRKb z=#9WGnt}de;jX$_4J5KCjJIz=hZfdG&A;nV%eqY!aI!&)(7kR&jOv)d733<ck;m6} zXys*1zY2ZhHRz36A7}4m6$rt8z?sd56Z%PSmPqQFv<H%sO=5(x&Q`!cCnRBMV8r&= zlQ3nBb2Hqenp6(X{0jiXVL*kZpAlv?KA_`4y}r~4k{!1~$kRn^ypGI+D}|HtZHBdD z7+)eB<dd0jC5Y-9aCY0ov`>`7xEkoS<oH@P7{;fHsaIWQfO2GS)}8`X0M8H;TO}6t zk$2-x9_6ah_XK{z?OXA=eV*-6-b|wk>}0oIbR<Q{`f-7QOXg@}Xp4BzvBh=MXi(cX z5?#N^7qHnO)0fp2G{NhB)aAM(!`*XJf@Vtgz^AMcm~H7H#b4xB)a=NJiaJ|-3(7?F zp!B1^XHL~%m=fq{vy>5z*X!)XA;t=qS9_xd=iKeae`vyM=w%>;jvRqRly8fFMv({w zt)!2uL=%>3>)0+($_amf$fon65}58!GO_AU0n@qC#=D0yp87S8kJ@`iIoYj9TWN0y z3m$_FQty6$MYV**()4E?n-dq$+@|@KS@#|%+8wx;TEz&6#pp<F3Z!>S4WsOkIhGhb zRtI=tb7Ph!ThAAa_p4H3eNXRj-3m0K49+N1@2XfXND-Ae3xks1Hr!y7S$RX=nLe`u zW3<cZ`?>&86~cxK?Y5f~y_PY1phZY}X-RY{eJzx1Yd?ej1EtlG_|4dbj2p?NI>65F zj-p%y02%Y6!P18fHBWHGB=qXLGDMAvTmI56s-fy1AaWvv#%;w!Pjdatcx|S3K=%)V zg=P`u$3G>x^cqXI18mzV7}03R*kt_K;~4M+D&YZ93{X6zU@cU>8+w5f6BQcBfv8TF z{ZQ3sF@Qu<A=~y4*1|??2~`|`?0QqrEUAQGo#YMzYEjN@s)R{+kiy1*)jW&<3f>Yd zj+(6ZdJ_9GX7636Aaz1ikJmtUEyjSz%+)w-AKTp;6*N0dg#=PW&1;Mv<PQu&*r)NO z)xO>u#Q@ghjvN~pt3y1Hs?ksNtp$C%=l@2pHZz}`s!(Tx3jlh6rfMER<fJToutnNJ z>yrm6Qw+DC+XL_%3?v027sjpd=~h<Rx?#`^w!m*dLrT7s>iDRQa^8#oK<hEy1C@JM z3uxfx3SZS0JK?xdpM4H<j}3^13CB!Z+OSI{DS_VK3@)eT=i@ecKfmirEC;SfPtY=E zyYTK0cz%dIZlGz>0T?(NLWOo4PNu;z-M))0l_6KM<4=}(AX-I2YbD3HL#Xf*jRC^Z ze!w7(q?Hg;Ca4_IpS}%#G{h6$u(0&1vug$O5}BT-Vh7F-oLcCh$Ci59)wzWnj8Xxh zru+(T2Y0!t7GOdsS5=I7)DDva5CFjk!@$PC$M=YHJRfwcewj~$4YOxPxUgtntW4iK ztSbb~^fq@;sqHjl)!&frm~FipYnZ(#A~bypH_waoft&@=Oiwji+#``xRSj(Rp^>yP z$Y{w0^E=gxfbBO`&T(SG^0Rlq7+$N9R>LY-qpVpfs0E9vI-%5GqgT1+f{nitEI|%` z@~PaXe~83-$R~w5B_#+%w-O~A5`yd1wj5h;)aEBr19qdAZi|EHP1pv6#c|x`FiIu6 z5{l|=g!wDfLIeac9{Z^Mj-AD(v{P1{=o*yE#$kgZ&@A*PTanr(cSYer*{5&?5c?f? zks*A-5qqa0(vz@oGr}%sVF4de;1~n{7<u|r3%Ak0`^ehq90MWd*;r+`WfzexN|>)5 zw-KGO$&VOCjNi4EBpX?;fblUu*k!&$AqcA(X^$L(#ubcL^pYLn`4LcawaoGi?jsPU z&Sf{xT3XTBEFQG3O3S}uD8LnfaXsyb2Wpd&ZhmK0uCMzLO>O<*{PM@Ro^cBmF357Z zmeT$XpVk2;1f=M_vJ=~UzKM%fbRN8Z&rJS?a5Q|ja5SBih^@%G%cc-4bSUkf!Q?@x z1xfJg3n2BfT&vwpFDP4Y^Y&A)z#5<><uvJAFNK;RvH+}P8Bq@ZP&&sY;RyObdKorK zLaSsAJ#-j}9QZkk<hUFCuReoPR6QTxl7p~<GX78c0;%cMOEfi34XA}VQ?Q>v>;{-& z7fiHJ-#hQ28T(iXiIsU;teBU7RTv=Fuwux@E@wQDSt;HHw%_Y35kR~itfgM<%C#sE zU?!-3*3o{Po$Q6E;(H(ezR}DS-u3v{3E@q<ty4RGicKWV6;w&jRWUaQT0J<xn5Ctc zHVYYN;@4J~3#>XAG}WVF=g9?MsT0hh;>J}=XJAd%;@-{d?{r7weN^rdy$uU?HU0@- zWQ%3sp0ZHHjy=dPb72&;?FJo;-N$)u31z_g)J%WL^?j8H`<Yso%mb%=`;-;bs?7NC zoziPtzEC0OHoahIgys^b+1z68DomaoA_d5MdfSn)gZVB+&pX-UHYfX1oKyCm(?uci zZdIqALm>CcNZ5NH1N+Em!EP7{;l|PmL2cnTgrGLJRZYJo8VP^v4x)ld)vb7PvRS#C z6Lrz#l=}O0Mf(6)eq$jw6tnHh`?fWc#M`<FM{W-En(@^oqDlXOqia};%rwk^in2@M z2K5{zYvvhS1#fO*o&0mNB`i4ThwFkAxL}z|J9zo^)2@_LwZ<X-9S!(HN)Y|9Dtbhd zs`x~a07|*tZ+qR(-r46>Qn^gn1ZHQ8_25&5#xCBrO_KuBMC63o)?_%oq;cL+fT1#j z?+aQir{B@6o33Y`FoS-a3%q;%0M;UmBSIhvYLj=V)adu>1>-mgu1LVxCQ<`T(JHnJ zjw^+<&b!PJO|%`zykzeH)+AckY+um~kgESqK`%>FrAOIfg@g*rL~7axp-`87D$^yi zyb2gDEuzA=-%w#|crrdv2bC6CiEygG<YcaqTTZDZ=|8@mOX_e5$q53u^%;<1+yLtx z4|yZ}KHeZ+?!noE?|)aXLm~oeuWgc;IKJQ&R%2HUUD^D`<JgzVq}78Zu7BM8iZ5Mb zMy{!0B8)teuQ9S3`Gg6)<UXj_h`p1xJ%J6$`|-Sqpd<Z~9`sg@k7mX#3L9$P1#~|3 zjdOi{X-OxFRq2$mTug$9+t~H<9!6Sh#qLc{&mB6X!~-KY8n8T$U^oW(+<<-qm3x~q zdpN``h_lUUOP3?pFaYnA&k_mZhe(4PoQzfgPuaTBsngMdB&1SXgkV9dl0J?|cY$^3 z)LqA8s>)5q*2FU6Sr_BRl<Kvkv2UPhG^E@4?x5uFD;WL;0V11fXZ{Ol4)TNgZQ|yI z3w}}oqTm=Hd|BojCFw?9G5iEoc@q`CJqnZV6l3SFuRr^#dQIi)7QJOzF$1^Qt$46C z2V}A}!h|d;Pv<JP@YOo@R*v005J*SaM$pj~D`$(Pw8RFAI>R^oDR*_*oEd%4@ur5= z*%59@uhJagYFvespgS%vZRyw8KFb5|Z|ZENktR41$1jY-;mf|k=-LVvI&2<+>X}EB z<DW-^ZT@>@_oe8&p%yQ_MjSa(WeOJ|pwQeXYDH=Tkf^y_@;_i6JRvB4-^I~yCXyh9 zJ6S!wu(B!H$(8XuDD`Qe)kOT#Gt^kY&e(uv+3kQ6q?BylSasy=QN<+SjXZEH99e0j z-$p7VV0lo-&vE<ZuRqGLEDiP9ni8}#C^zvFph+P{0^<&Lhgef}137#lL|tf!K+UWR zu1x+0KdYm!++|h+1ZT;s@ICR3h#8jZR)Ez}se^esQl&C*re3O+>-8h+VFd-v6yU_w z514=){9ZV8r~%5g)khDAGeT}(9~?6bcWJ4cMy|Yn=4Xrp5H08?1VdF`tm^(1>Z2+> z?}`I-VEP!49J_=G1gf?s0BuP>Kt?pa@0k@N>{0)WE;m3;O$we|wP%QGy&;7VkUPiZ zJhJmVh+mEHeNVM7$b;Hq1ifgg@7n?u<@RMi$)l=GVsesdbj*z1isFhqw(LA~Sz=xd zNSYSMT7?G8_{AWk^X}|2#@jNfW<Z&YqNUg54Tzs=jo<_L`!U@ieS4&<4?<$D!~vdk zB=~6@WXnq5NaIhcQ|j220Pd=33J3vE!{REFkTHf&B;aTm);IB@t`oge-Ko?G>KwMW zpS3d0r;g`Sfx21X@G_m?{?2{e1hQH-vYE)DE5K8`CTms8X)QO(>+Y_&$coh;DSq8e z4wVz^9ltr0L&K3497=0Gx6(HxoMHk-nT4zIwat0z^~a@r$KR92A{Eiwe>SY2Fil)3 z^*S?L!s}qB$DRp=Q@V@NyB>6Y58YK)Pq|a1^+ilJbDx-m^aE*`t5JmpM@ZG83e+_b zB{N@z%<6qx3Pu;390zhM@(n$fwbLj*our9X!1eLb%Y7Fg9G-<Vn?!BOGioBq0`PZu zKY7pu#!SB!472hoD%;pelTGaYaTFwT`UBmDTTvMW$f~8vQTeFPQ&HuL2QO+qt2v*u zeKk)xW^{V1qn>(^Fqw<4`Cg!mm8cF;MDuwV#IoN<#C<+xn%<ok*@iaW%Xf<WwCp!J zj+P-jHO{4aL%GC&Q)*U_GX0=~iIP5OEi}YjzSKKp#p&!6U*THmR8NHtdb*G;0(lbI z)xNsijW{DhfYOHiwaEOq3@e9!pHCk#mo}H-6y7#<GH+kk;8Ra_6pphI@NYTg-`6kC zz8s0TW&FJ7WBYdYZ<h8YYd*WRCe(?z>TbOI9YmL6PH#IpMY5kT1pu!vLqS2GMXvj4 z?n?vM9=$&O6#`jwj?RU8Cn?cPme7OUWcwJf51n>u?I`?MFhCh>W#fHitc!gdLio(C zhgyPi=XOnGHm@yu6D%t{Lv@7CmH?S;;!H)V2)zlN-+@)|rE@bYyv9jOz4d}!x_~wX z^2eQ#6d549*?~TD+Uv?W@%yQfg&#Ix-?&Oh7lQ0A;MW-LWM=mo@KG;l3YTWmevWDo zdNy9C^@=@!)1lE>>x_5OD?8BSQtOOI>!da2#px4qeU|x}EZpj7c^E1ei{)iAVyfkS z@S)L>npVX}!tZjg=ZK2cbDG8nj!&$7or?=5#d0e!yPL(oz7Lzf<HqslWlnM<w8ZZu z?l(}mS3Z|WM>YM<kJr(T3&};?X|+xqvdC-+yv}l3=W~J83~7V?L{4CDhA)V*U&fsw zpV3c%3+~FX-_P0l+LC-S4YRGuNSXYoRjAOXj5-W0{7}}!J}KU_R~kg=dN{`p79s|1 z18}qV154EG0wAPX$!|i^o^i4l*uj!tc`<#Xv|2i6qs?9DfFaB7RSj(pUfhxS*OLrK zz_H8XCBX*Bh6O@<>$Oyerw;XxcOUuPgHqMdL54@@iTuLyf*S`Mr*nuQ)@TZkQl9ty zD32z!QwstWS~W25N?!Ye$8yd6@AHx6&Oa47b5<Q?B0sEtmxq3~k7)Ol+?NMqc$$9c zS^3w}crdg`oiLt{;iV7vnf)0l@njxeC+E~e#}NRHDw{XLK%A@BemZo8ESq;FmMjC= z5wIpQ6^xz;qo4C=T&SGYB=EAAQc|y;E9$PwAc|}Fr>b%>2xf#=S|6X9juo5<eU@0f z_u$Vm{a$qvmt{Xabqlv-c{*nOU`zSiILfyidnQP{TmgIHC>J+;ZA)Xwee0I!O7yX> zFX~y_PBuVQCrS82K}>yR4F$RAUr$Ol@yU8Ga;Wi4I-*sVaL)12+Q;qcMA6tg4|buZ zPe|un2rHsJ^c*aZ&YZNn&Ic<6+FWdWYK0uyyR_ZLPH`=rxKB4?@W<7XblPbXgdW=2 zZoyoaB+B1_-OdJ>Q_dV;(K3T@WhR16gNv$ewDI)bJ`9THFHiuUaAD~6PDGIDzJYXX zpxxKUvr0VNjDP77I;k6%{tkXaSDv}I4+08tA+K`i+F6dp{e|Q$NhOlHEX(-T_{+c% zimHPrKFIXbUYHJ2IH+0pqn104?A&<Job~C>tI`8l0$%T!t#X{N^{p)jex*h8_Xn*7 z0b#B*pykl<wtU^<zbX7S%dH=o?O*H8c0_?w_c<naqeb63a+^GMAw3*d2BYlvrIzhv zxFAeZ=WemzhZTJ`lX;d+pPOagaLDP~{mkuuzxZLtWqYdCPXI(FUP!f2u;(g&(+c5Q z5||w1f4~G%;ce6Q`sSgm$6LqHg@MvUfV;XlR^dEt$doguq5N4DBO+usm3E({$MS)% zE4S=TW0p-?4h6U_@3IjUnx&hqSruj4p*mDW_s#s^?p-{|QcgFX8{UBuB=ATQ1q3yW zYK$I)j^9UhfA^px<x2PC`u5A1JX!xTS=v#c3U92?g`utv0p#MKX#ZS3i9?50mWSXF z&tZsB$~O*;+ofl5qZ4sCgvldm7q~LHf6BgyCUKLYQ+GuGu%HNstr5vpSvyHjhgwJN z-IPxOvX(J!+6=#7Jz%b<^1br4HZ$5_=6A9<I!Zf$9os!V+VB2J5xJq`(WJqt6FeXJ z76&xQx};NBN8qXF1dG!n*#R%|*?Dl_Zfj%5TxJY%(zaQ&f<5UeG^j^7xFclVfI>ft zxC=<h%{(&du7+v5gho)!A9H$aK1Z`h6X2oB@VIu%Nvbk8<QgvB3AQ(radIG%E!a^y z6{Jq{XP>OHB=amCs@kK+O|QEiPH1@^m8M)3xsJUfoy9jUlzG+{>|3COUP?Dmp1dQ< z*Oq|`n;#06xHU%9t`KoeL&m58y;wp%*MprsubO>%%UR^Tq~8=!luLF{BeG6SsyAOQ z;q$LdX3I2Ji{pM$n<}ma(E{}1`|89i5L8co;xh9zcEh@NXsqY}E-Nn}J%C(IzJ|#W z?E*I5_*qbfYP<k<k5~PSvIASxr^OAPIl=YjY|b`>J+uT|f>!cl&gzPS!lDiyID)J^ z(wU~)>?Cj&sYMrAA0_?a;n~v)f1y?OXqz#S_Q04roWr5NOWe$SjvQw6gv-8<^t-6H zVx<vpv5#~c*3DNLe>A|=Gb{#E`&za5=N8z#KN$!t)Y`NgT+eaJ5Je3S-vyidyHPBZ z3ar-@$hT(NRCSCKYnS&%nYW3>W?_r83gUrvh0h0w5I3ct=9!g8g(wST&K%ojsclk- z3Z+Bdy`=Y>KPx|$-rgwCx`?-C#Y2L8+zSRl7FeJA|7u;K>(jsO_GML(_eEI$YF+VP z9|-?xt=UjlGdv+rE=fZ<IX=~(%rMU=ryw>VIVn3bF4>|?Nh3bjBv;?ES8q2tB{?Pq zFGF)PE;-h+ry$1{N)GZ3E$Nx$uy~d71l{y7`OxUl_>8RI2=?9=jhupwG{q<xP&pAL zshDzw|2`RwBpJY}X(j|4v{4Lyg7h!e!e`|US|VTmd9QK+0F?d}u%)?yy}rGhfW3{2 zgRwmwzk{2#p_#pnwT+VlAH#P(X?;U8b8F*2k4i2!eEfW>=GI2$)~0_;R22UcuWW7p zWvc1mY<i)+rm`l6=9SZQh|e@CY3e7PHCq+ldygS7`z;nv>{#Y?LQjAGd9l7HwkEwL zE#xKCb9P?Z9>#Hyhcrl=$|#6Z{D5P2vqWOGB>H+WhPA8OCF`)ja@yuuj_ha3;}qCM z<(By~*_G~M>gV3$;&J<4RD-kK%ymHRr1|{W%cgL;6K!}fejNu1b!<m<gJUOStNHUU zVmy%f0wqUsse4h_&wTRW3~cPZn^qpU(}2zfen>*>e49C=yW)%oI(!R=%sW`8`K`@U z*CX|owd=P4?^BNgB7Ci4*w4l_jt*+pABRT0s#ZT<lvSC;Yvw+3H>$D1K4u#hYj<Kk zS}hJv=0CQ;(|Y!lJPRwNvYi_At(N1nEIM?v`}LMN#=<p?Yq)agrm9t#5zJ8BDtI~Y z_q&3(exSNJ-vL)5-^l*<ri~P*(&^a254XDF%T+@IlDhIu1ij(m_H<f0QKujNaq`ku znu@%#yt#U8Y11@!H}ja>nd~D$oK{Q3>Q7hYUrPWp?>j4AL|TeO#!re$c`;@^wkf3S z!V9{ny!m@4t^Vfy)9^8}H0KTEAfUqg4ba<NJ??P9yJ=xUXy*FF>wKr$WjbWI)SN{q zkJdgswid5yDc}7YA7Q<Ok@6+VCw@f4vt$5}hdvk|U$#;a<$RpDG;T&jjH~c7Ie19h z<_RE?I0Ol#f1=Ys@H#3t9`^g>aA}YoJ5f2-w>&IFV~Ut@VNl(`@VSb7S4YxqDq=y{ z$nVKQMqMgoRhPiyPr+^+5_e~f>{w8NF`B|G<aDF=)L0v(=5iB<8R%~Ao7Zbq`AuaU zYZ#B5KD<^@vus*Z-YYLJu2P$wr!eWeM;9Fl5nTz<l}JrpYwzUYS!=ErsUx@@_|A_$ zzir7a5JPo&TViyC@%67%@ZO>vpQ63lv9z*h3vT4Q+qOF0UI=kOa~9)e99Tyls|nsu zHt4nBhBEus_8E9LP02!VALp*nJ>u9BoR7Zacd=PByxKWtL_f01%(9xhr(Uo$WMoCO zv{<n%Z}>RXFS*54&osICIO=wrH|xB&FXC=`j>1iea1N~4rB*r(Efu6(J#zl;9s14| zZ`yqK`uuHmj84~uBTJ<JX<mBwOa}74T9q_ORfQQMN;O>pFKvv<uR2?kbZg@la)Y7$ zESZn8J5vcT(lA{CH+_n+VBt>6E^bTv?nEnL!(l>iH(fc&JjSTV5bTbFRFi)Q<|pTu zl1Uom5sfK}(@-w5N?b5YzsHW7&<Dj~^1eZzGfm&`5j{c{t*%`5D5k+dnzKaTkLoD( z@wcRe6M!%namXV@dP;2ty;;tYLZayLqa^Wzq^Ze;m@qQW6XqC{`-GzxzIpik`doyH z(i~bm##2_Ot1?i7X9n|l8Ok0Ke}3gr;5*^pCO>a7vnFs;grg6jUV45#h2IyGpU}!4 z;B6cQc*}FzJk(b&TOX=d{CJG2m)*s3ZBt%%P9om#Dj!%LN8B-jquPlrhM)Bo&7!Wl zOO-wh)p2q7Cd1cAV~WPi2juhSW%EPO`}XX9_QWsWmBfE2mr^+|TFT;d*%N09hujq? zI%!*rG&#Y2xR0+vE5q`geTC5ucO7?BpFMF5>X!+5h5}w{%wZ7G^Oh&MD11D%>;XkE z!}#~`jPKA5JK81*@hkN}e)@}vw>_TYwD$;)6KTd&L+6uH<04Pi-G%L+$;{kz;L2gC zS?Ey7UJmx3M)uwe&If@wU!D>!rBH^R$l)l%$29WOq$T_V+#q$#NUqk9acI$d8>Ge^ z(X10Z)(25rjA`ZzgGpL$I@d|ZCami1*DuF^(R2*a)U?w4&@(xV*W{sVfd-AB5i2;@ zbv_JpBlRy?dLT~I;OhcTj}<4$jW@F^Egu%Vljph{{pn?_6d+gB0I>5Q21)?7p=oY- z8W_^2M{n_r;`oZFJe2{0Yz+~HI(~35h&v9ti1!T;%b_;lMPLkiEV%97L9A77lx@5W zcN|?}N{w_Jc5!toE*0GQyY4Q+Fp&48U24dm=WUR_skR%3Z-;STmXK^FzE2KG5z#$d z%>ge+W6v+YwG8oc>1EILe*U_32jqokhjK6hzavTRg5ZU3d;H4f>}b|17yQDY&vS4D z33WFd4Hspym^T*P)~oTxj^x0}!DO!x0tOP&hKq~EUL***I676Ax;B$1?>jDAuAzCv z-<{8rbo|XrYuAg<FHC}nk_jb=Pvuu4G4KUb=psde6;Ls09x#@FX<$84^_&_DT!Pcg z<hlIsP!>v2d2a~`+6DOU)7*jrO*Bb*R8;||qQ>IGEZ<l>AdXpjh<{V)X*~f`FLDDz zH`3?{X@&%z+{t?w@zzIin7&Xrq1NL&Y1f;274;?mbk^4{(7$$T46GTBHi!|ZbgAy6 zmajL+L>maeMa37kzRM+pl{m1(&2_CUI4@W>$7A})POF#aT9$u9WT|iwcAajK@*4Ve zqeljWKwsiE{p@k*2RaatRm%5k<B*^Cd-{>^e2zgaGDT?E99Qa*(_L%yZm-Ne0a%OM zw0&4`oe~*2-nkHp!6^$ol+RSCG77wNJ`6p_Xe}1kv7TQT>Yw+P7`8k#hAkY+!Twih zaEmdH;fwd)@w_>kB~AjlROm)eRCZ|c%pCJJ=>|5`?#Z0fox@pE_QyLna<S;&60Oh7 z8>9?W#J_WW`^vccm9av}Bo6AUrrcSrRV5Qdc{;>G8~8|H8SVa-u|X(ew>LUlCUbG_ z0I5x#@NdPC$()@q2=bGWZ~uXYT=LM^t9y-LuqPSzRSa8I3G7F<_!R%27ygZtd(=oY z?;o6wX;~)mb8=kEGjm~c?(I@=iFe5MUg;|{bK~aRR@YBb7Np_eobKuDRV8EdYFU^O zqq+vp_e>5Nve@t338|5Pz?ghhF=?vguJ5Z2{+3Vs@F1hn^N%e4Fs9T9r@njqGgQGk zXOs=_>lPO6pD|wrN$@AOx{Z95By(mS(7nxn=vA<YpNh*p@l{PQpWk>A{^4|XUnn^L z)CDg|R}Hh^9=N5Tq;1Z9b(_vL)@`fw8R@^n2v27aO>n<1j?FI{vss?cp6YGS;Mb$G z55L46)r|-5n~`$<mDZfS_<Z&T+#B_$f*n;Q%pb3AVY#==tzR$RSe(Q1$#R*pyNmw{ z;V#WV`4p7^qAzWK)yYLiHX!_mFS+~~Jl{El1wk~G#ei>kE0ExCZfOGNZ%ws(Ovveg zzu`b=RRKbA<!R1aCjt$63IcbA0&&%8&e<jcP58beZeJlg2Y&IgAcq6OvkmdE1J)5& z1>vToeTO-AQLxnj3dObidse>hekx0R=fgkrhpb2&e}c)>-jEVFgEapmFGjzJUJ#+A z6kAmtEHK9tMhhvRp15Ja9M;<R+#wL_B)FdVL9i0$W_`XbGTXC7AccRhzOF!~jQlsN z!>wJLG(a*F%iqe8FeGmH4M1&fX{%#c;mM1ncc%;ZC!}GB4W>kmmWBxT&v$I6;dr4S zJD#qHV<aD%YkOyb25~w;g{@CV6|*Q+yp-lad&P~PD9dy43D8l^cCOYmx2KVVs6;3f z(5==g?2^Di+7eJgL)E$PjrtS(925N7$EaEqe>2~toNZ=3_Smc3!iyB$<o%UeK!8x= z=gDu*7$}|YI&|f8SNha{<m2-(b@b`|v2>>)eb3N-Y5Dm;_X+&(X55@;%-{@PX52kg z004adi{36|Y~|$oM;kY>vH$arU;5AAe^=T6=;#aS@-`JLC_`Ih7o4v5MM+R~u)%Uc z>sIgy)$>%^(pjVzQKT}X5(MaG@sElZRvybC$D-*`Rsz*)I+c#%Vu_iC=Xws_fp<sW z3g9z@p;Q{l6SyL%_xYfwE#qYqEb-L4H{K24tKj$K+tLG^7^*IpW2XuEL(!q3*Jq5p zRfW+A;T*M7Y&1w5e>?mPqlO@W;PTy>2C@vVjI8V^*U*6lJ9}7F?~u_M2geX#(|b!6 ztY$Hf-{@vS2-0UO^{BcrgEJ9N7g0$zod+^j-hX1Mx1MvguSsv#s8o(=iU>)B&7(>` zm@{V#y@-+7H8x7p#oP7&k}RXF8khBo=&bvwcslik@wf}+p;Zl`?qEWpd*zYhnR(5m zHCXMnig0F9L#LY1B2jg?kwY{sp~vDCx+Mb-bgIZA*&^7IAK8{Vc`vgPn14x1jFm8% zvd*$2i($0ZpdJ_2_)q~wR?;3KZ~T;Jc;G}YwzbFPHWEL))|&TN-4B}|ZEoc*<&Ohe zb$3~O+$bk6>fHSUEqhL2XCZJU!}#?l(3WW8!VxAO8xqJSM9^n;UoI&ypGgp!33{cx zVmZHag=nq*BBcHn+Y#I0N$k;u4%y9}7upHa8R}6w90-dkh~zCRR$2qXyQ~f8bj^+D z3AR^X+`}68RDfWCqQ%dTfkF;7x`Qi%()S^63oi|*4-1Tl5y&s3F9&z^z0cS7lPxyD zfdDIn&lUl!Ej+;9H3SoUmKUzKmmP)~E^nIvM&R#}A^M+efgy*!aoL5+$!IDhM^^DH z6SEi(@E{zn*@M|K0>u#K$|hzEAPmxo%V&gP0Y?xx$KMJ~;#I_pL>LGaCjtZT;@Mg) z?DM`@A<Z+GW@5ifBh#M$;e=dT5Et9|Ry8XbWi3$LH*zr+<&^QOHz}dRLvsQss<&wi z1I7#Ov&uMQg23{sY|7+8khT-Iz@;3aPWcp-NVm&SC)<3SQzf)>qau8ail5r`+cHO! zG56>qu87_JV|(Q~kJ3U%&e$;x8bmpkyfAAL2k`uBBcoojX%cq?y7=fSFRFOvsFm^U zFF0zYs#E%^sVIY)NVPGJiWY8LRAQb7=7~ekCciyc?vy3Xvj(#Uu^NeH02XKU>3B3M zmh6d%YRQNhU!QBM!w!xXlZol}(cIX8!~LXw&hgMI5(jwM^(Q0xQz2i&shjsa0BalU z8i!9U(t*P|XwS-C7f?@qx!i545SP^6t%_%Rl;=zFUNWoaLhSdG6xwTTSRTadAbz1< z)vpE%=uWX^hw`*nxb~urvAFH?z<nD+8fZzNUFL@MAgF~7&<fIK@9c+p({Y&-?ZvxC z<Gc*bGFuk()5ZuyaXz?)V?6g*aEbBf=At<N1sQUFRz~|!e{)#$^E~;;OM9OpiL4UI zMKjK{^7ip{;)ad#s?jKWYw*gYe~V@goWr~9u2A{5I?ioa?dU?eg%j>00m+@*a%YQW zv-O^?y%+!Vx@a;%Wu!yokkBxzWr<E=$j?VX0KTrmtKhaJYH8<l^JJ4}enzs2tSa6$ zYF=<q!={Fp9S8ikco=t}8@H&}RmR}iG4BlAG2|Cl7nxPT6V`pPd(3@h{LoBJ;<jLI z6rMNs?+I=6`wj`-?I4%&vx}eIX9naSM`)f0OM>H*f!P$Fuc5fN-HXdFXW(nubCGCv z!X*S#Jscy&FYO?_Krr+M!)cQSmq{VjwgBE;FTi@XAMa0hyi=b%pHBK~mUIUeJRct& ze?4`LX4bs?`ZW*VejV0j{a@zezaPSOu$20@?UnyJh}|?JEgSe90c^W__MR3LDT;oK z7Q;|rS0^#*NJC_mucS~h`Cv=4lU%(<=QU1z%Wd@%4xO`>(Uk!XI-7*T)OWNAtiwMi z{V2m@l3dL4U>gDICxD&v@|BK$EMYdGm52d7NZB?=;0-^70#;?=uPEQT+mp^DLTfKF zkuvuczu~!inddD`&y11N=Ix)>j9-4cI3Yl5%=nAC1X<<NN)F^Htq>NC89VAJw_vL; zuXZ)NqRE)*=(9Rf>mzMRB5Aofw-oa;QH{=-FwP5TJ2p;1VCfF~CA+!YS&^St2Y=Y! zuyTCz^ZI4cQjz@Z<4_*@arFr_a9HuE`|ryeZx81E&6g-=zLq%Z|3#etNsvv6+Fv)2 zVFX>hpw{GTTh67^twt&L29>1;G8LQ4U6>#-j6kcgIU8Y{eRyR}0csD<o3n;F-DW2k zzKG{{3?=sCC7CF|Wc57Y@*$1|hCNKXrTYBDV#|d^g*;H$o<^MY<3zG+R#G~s&2z7w zK3y!aohnbg%EJenC!C2NbL~K2;7^slwEF3AZk98LGNN`wv`J2}FVmkmh)s%c2>zn@ zu9sh0U<JYjVdA)t`*IqYs#qodY2})<!kQbrb-+Am(dtZEYRDkY7)=3H;3tp)bkFv! zN?=_FS&`!`F)|(2tw|~|anPezN5UtIgb@Y3!97d9s4LpwwSq}EwwmXL<|ZQyxoO3B zetdb3xOW1U4<Qg>2OK{aA8s{zLJS#i?ZK{F{y63|d|<X2C+h3Oqd=N;_>Yyvg*T_Q z5{U5TRQy7T^Iq5P<g_oneK?UJFANtM107Xs^yT8sC5=nX(Lo!wRb7vHV$t6|B}}-f z9TrRcQmR6DQ{29bIKfoRq~m~k32d%dr)&`!O11PH-2k*klET$z(tCO0gS)sxR81Uo z?}UPEqckPkI(LdVZ{Xm8)k96H(=P%;w|YVRqOHm0@?BJ{=FJ=M1YrBs5YqfvRBVg` z)V*2W4qG<o?gfe9Gn)DHv;S~`*XS1H-@6W)2eIh!SC?V`>OMIC+I6gKjEpUX%ncpC zZV&p}+59u+q+`dd1HK~&KfOTxcpQYs@h2we5YtvFUp3Kwp$9>Mfyiurd7GV9*_ens z#M9o`y~gCYjh<VF^MWMW;j48Cuz7QUELkF+*pageA0qzzB=L2voM?)W9n>DjluYed z1jbb5lD^OqK;COLwRDCBO8`O6h|zB!55oq6W;WeIe57vMf0VY*3qrsthb0^svx>$L z>x_zU10`7caV9C}M%!48+N9oIB(WELs+~QTzBaEGM`3lLU2lf>8mef8^O5@TtQx#p z5GOIK6dFls$i_Una)4BJ*Xopp(sP-#tYNs~Ph+U`m%(LLWudD0B^jG9`Zo^|ww6w& z=GG2${MP1H`hUbE_qT{YlKTI>T|GWFE=>(s4mnIAJvH9&wO?HeDfeY`E8V0lkf2yU zHq|f#4`4AnG!6Qfjp!`Aig)!dK;B<O@kRgTw&I_lguZ-MSlc)_nj0!Q+1lD0J2=?b z|DTYJNJ&kN(b0}b!O_x?lS|OhPSVx?E55#Bz7bm9DG^?PQf>SW@4w(<%AUGZ`@-e% zMdbeppOlTMxgo!`zNMSHvHkyDa5p2eQ&P_3lH+BS5;Rc%Q+j<wHAX2prUm!_^OZ5m ztbaiV68Qs0?hBRS7ZLm?bTT%M#t#1vsK)5TY2f}R8UZBLf3zj#qNqIVU(m$ZHss5G zq0svx{QrbTQA$wo{|*N7(a!llVS%7pIXGH51_wwwC9e2uzk)XWMe_$o+7~hWM=a)6 z4u<-+#?pVL2RZ#Ow<yMr#`gaYvVxo(r;(AN7JHbG6`z0<qm~$#rUA70_of7fTBY1k zF8fDIGRfumhW$l$l<HJ-I$t<rzliQX;Z-#@P&E9ypU**8#Ky_`>(0Lar*R4?D-9(x zNhd}V?J`C;At_D`ND2Qxo4Kz_>K{YGERlz&;V)1P8v#=_z99O25#@h^>R@STW^DLF z*TmfNOQgDgAIblhF-tKiJ}D+W87(_DP9aVcPWK-WmJ9q7p)U^{@?Q|TA<0&@e<4f% zS_}Sd&^ov|I2v0y{KF^C-$T0ef1v%%i%QirH+0{31mB%*B<q$Gj?nPBjBQE|NwX=I z#uox~-q$PGRy7o|p>?|};1wl!&QNS&mQ4zBXh?sp3+z1&(2_mtW{_U-4iWgxIR7{d zp{5NSvuTPgTT`G29J|U~Ns3Cuw##7)T2F!$R&@L-nHNk=nD$F2NwySwznd<=x#DG3 zDA#?VN3CpCf@qHB#7$FS>!TNpW5G!sm#4a;{71Bv<ug64oCO6LWzPcupVM1xy3g~y zeaV);-0~Q7YhTj#RsYzp`hRT{{P(2#AM0;#W8?UrMX=<I5GTUgt9(kG$GtXv7@+lj z+|9b3Thz*a80~>C*5s2ezfMu>tRfJ1KrqZwz0jOsTMb_U3lTlqY~h&vP3jlHW5=mb zLHJ3q$Ax-fs4=8hq<6%yw5*8TA=gS{Tf3f;)YNpI>O?L_AH&oV#!u|;HsOX;eq_-` zw4k9HLD9Qk$B(SjWwOyM>R&^kflZ?rhga7{tU|t_y=eV%fw^wcqTRopVwmKyfBMUD z_kil)O!+S*()LRg_;a!1e=RHjl)%5XeV4kGO#vIi$Iot{89En*_JQDQg(h{Yj5F;* z6Kv*-YR3{~;n0M9ph>@#=Fbny9zPI6fw1b+2*bf~t{Brn#>;_}mhW=jd2Ba!j%EH+ z>E*e@{gS*Iy5$t=S*xchGbIr(9s+V~uZ863j0YLm`H~N49<+HC^E14*rLZV$a=v+f zeg?pIM*}OCqHMZ8F<b%zO;Z|=%yLErubc=kd$4X4iX4M^XNn81O{?f@32v@i1WrsM zWAlP<`96j?o2_`gbsRtl^C&WdJ}+lS__X|X$AfgIW)QG`)6^o}8iDWMVc(C9vuRro zJi{Y&K$kt_>$k@DC7qD0Y^CORVd3-2<&+&GCjCayls0+#!*tJoQRKp4$(5}2g0&B* zSLXkWNC_q40evuKWfM8WD4Ds%0*_1<j<q)D9IHgu<P_0=9gL#kL3!+J@1hqkt(#YM z^z%YxLx3xbv{q!}=w}RM;Hv#NAAQhyyq->LUw_B!u9sgZpp3avs269<plG<qX5)n? zJRlt;JPM5JO-9yk4}odaSD3cc!(<qDH>F+zl$nkaWkz)Ay59h(NwTb_eI+A(?$xd+ z5cR8=2H*PqOZVANc5^{~cL!F(I}laPo#nfxTOI#oL>@bmj_=*)HIZ!_{GCE)Q+;ZM z$Fq)mG@(8O7M25sM69rSJyY5qMi%61ezxyV+ff?)=3YPmG*@5xL_jQWoM}TFzE`wZ zs}>^rXSkU{(z_kJP|{jDq5`4)MnZqIEn@A23&i6c#~5&81uDt0);MD{v-;K%f6*}_ zF)a2&M4}_Lm;CUibkQo6Mi$W@0GJx3xV?}ue$E=n=yMWwgaBA~0a(Kk5&9~cY`_EK z63}t?&Qn#B)YG?CB?btcUgu;PJzm{w`(QNd&j>_^C9LNA#*(chNtk#I@#z&oXq;3W zY7cQ9A&u{~pd?26l9N%`JaMY;_ot$gek!cRKIS`8G;hIzy!HY1r>xg+d}UJtJC!n~ zN56`aJew;q7*;&S$?gy{I$%#^8F0xJ_qjXbuG;uX<zFCNc<Z0Y5~J}^z^$U<UmCiJ zl&1FSZ^aqp@R0lhY)J>rkhh-@gpI;eq(5#&_i2F~lSuCz6Hq@4>e#E~NFn<}E_H}e zOrz`Oz{S1DwD+@?7oBE><E0bB6k;zNmh`*S4?2n*U6$MQ<ZKMXz%Yu(BR~dLxnEg@ z#TT!&_d;`78N#yV&yiVgA1THODW1%n$_~x4dlCw=A94%Ei=v&mczh=yXP7Yw`Q#R! z$b>k3<5nE)St}Z|bS1len~<3#ZyQdSH3<eL-B~xrkuT)ZWqprZZ`7yP^HJG<4Ll)g zDI?6oMaV!@0{Ib(60q$udWiVX)#5jvK{aahU4cZg=&-Zoj`c!*-`^JUGNZHAr6N@8 zxH$%!r0C&4QD2OdR%&{@8-Z$Gy$~a_j156e98_*l40n(8mQn9j={PtJjsnL?6v-qv z-d`39awoGqUo8Qu>huqoO&&H{LXOqeV7D|9qpK2X`<T{j)#MeBu7s!^!pq_fA!8#s z@;}-OtUWpm!_P{ArC%acBptPEW9Sl2Battz)qN3}My3;R3tH3jC;!|hWh3(wO_7ZB zJrwUGo*hDvuU}>s>Oo`u#gR{#KfL+%jLG^d8GANY0mZgWqGAC4{8EO@V#MCqIfB8J zx&+ygH`Aah$xxJc*Ce8v^NHI0updygQAn-#B5f825biy8FKn_!fP%&fZiK%!<L6-{ zINVIJ%iLn-`mGTyq)~~79;D4l`DuC!Jb=DHH{0GP@B3dIn(+uDb)S7*2mPJ%FKXdm z=VD#<Kg-aCrj<>G7{bS<uHW$zX)vheI%zdl2fMmG)>t8TS&5?1Fsb?i7(SiVtgcT7 z^%aZ_oO}&gKFCVP*f?Xu-S}ng{{HVhYbwv7YEhgwrNkH#`JU#3b)>fsC7AaPVr@@e z4<`dIH=fN29mu{Bjc23F>#|mR>bVk^u!io~;%-Egdy!bObcveyuiFY4G>(EDAh9i9 z?!ivfpnNtVoN`7PYCmrfH31bnY@JE-MzcCPc5C}mD@wT0Orbro)mqu^EB4MOrN>;f z>_~sOixaMZY8v=3`e&%=uA{(nuW>B05_U2Om+S&v`HRvcA$ZXzL!Yj<)PJk@V1QbT zKJ%C-WO&fEw60zwj*BtYF34V3HkR-Tj0KDQbU)cNuo#Wgx@5%5#6MSDG)}u5>)8T_ zi9ph1fr|2v;&RE-wj}<<$skXWma^hQiio4{icEuz*DwV>we0sibA4XVFZaCrNKVx} z(t%hT75udIJR0ppH<j#BZrp>u8HQa!`V`M}OKuoyv0Cpd49A2m)0B(SRAR{sm!eDW z<0(_f(oCGR7PtJpUQ&ha8KRv|Wovn@ATyzC0i-?pK3ik&wN5oof_$0;3G0PQB)*H; zwBAC*T7AOfwF4P#|Bhi0jNFO_CtU!y?BOu<sBPLY&~n#PMEdFpki;y}5m+j_ou#bc zc6;Kvw(4Zoemf-vKb56Psc%&%n9_WdF@FO+$Lgkd_%X4NgYIgocg9s)RV4jRb$)4< zx(2^Y^3zsygz~&}*ovs;)FfNP?#Kg^+TwfvaPhluM@n;y_S!n0<K3#GIWg+A25SZ` z2gwg~AF}5m(Y4Mz<fJ176Q(-~X_|eqf(+QGZAI6Kl8=5ItXut-5>M#maS6H4SHDS5 z;jOlaPe}5cY|2-<+7nRP&7JArIXIli#svoFj)iOz6xENCcIu*tBl7JYzG~I5)c9&V zweKYA)rHhcuf}Z*GRgL3&NTS&e~a(rP1Y?GJ`ryIhO3IGWp31ng=Y7f81Gg|Z!Nfo zEF#OXL?g+m8)wpv_G`^%qGXIa#NMzSJc&9(YJ{Q8KG0FFSQ05qC*$Zo`!<um&97_1 z!uxPG)>ZE%iWRa^dOPaDt?J>r|86C`ey$j_#PpfA&Ya)f%W4l_Z`)=S{=lpa5nB%J z5kgcrD{RP?NRL!lFq)qk>~TcGLV{!_UXK5$t&Nptw)Ch@egfU}EaOR8{Q&d{EJF%3 z_h}5H@K++g290SkuqoK&yG-WDc}dA{dlBIg@Ai+CRBG5lOtCxcxI>3_X2GN((oAwl zb2(%~M-IFoO=V}bq6Hq)6hMYRU)E@RT+ckno^so9P&;ks;zSC{c);^?yzI99kKU`W zjF~Ube?c>h7N`sp4<Hw|{c>v`rav@QoH?vrwJ?J;2Kc;h(RtT%2dKS44lqp{RY<lb ztOzf-GEPpCkpN3Vz!`C+4U4Htvrl@&_j>OAPJrj$Ox)WMMSA?6d!<w#Qcu#grX08B zXaAm-Gj#tja2tQaO8Od-c+`_Y0O=<GylguDp+=+m#u5wDxuK7MmQCe}K4ec8Yf2%u zP2B;Y5Ko*amc7^q5?vx##CYsfY`T+E^6aPB&gCsE+o|<An*@W?Y4<+uA?oz3`fCuV z!}h*%d=PC2<P0o+XO)nJH!?NY=F{wIIX+kHDv&sd27X8NShzJv6tO}1@L@4Oe9I(r zs=}49ufG>F<K<zu;OqKa%y_}vV;ufw`$|OdPo%I|Dax?qG<J2=S&UY$KCDEssNabx z>x<9+w*5`1bjH7%uwNBuA%bk>P>c_VtADTfLM=*g!6;Rg)@Hc&7&Oi9Hna4rw7{iN zDpT7Q`*u0a0E-73IhgR*1A2>-cr&YSf(w~=v$tjx1~_CZB22v%nr!L|U9T^><>42O z@{9T5EW)%B#S$u{tokM|@=vn}NY+sV)Tsw5ylyfWCl(6;m*lf6-2y;uwbQ83CsF_u zL5iu|jD%LLjZo?|=>Tg6VffvzLcX^&QMuQ9<M+ZF6qpwh$|y)`5Cv>94-*2j7}oJT z0C@FKc<bQTx&d(!#+>2g;R3+0QAYX7yDLe_SK5r<=gGVx$Z-z6${C7DK_fx}DYOIn zQ=UV}IYb6yf4T@zX`v#|nS)3A)=KpU{tn=ChORWzcJ9ICgqNli=GU{Xo}{F4;l8%7 zVYzDcTL9ih&=bl)1<**5L|kx&lv}L<oPr`FfIaM|s6tr{PFPoEJLzW1M5#)#RnTS1 z+`ipQ2}+nv%_7w<5I?0#C;bfBFYGj9>Mat;nNdPzW$vi6n<E8r+PWwIdK{FF0XgBs z9QgcvrTh0C%mdUMmzA$|Quu3~B>3Ncv*@z_&E3quER@4bq$cRKdD2?U&JOkaOvzb~ zh1oKQy%`{X7D{vb?hj|TJFH-4w!(HXB^n9mkgPP*BTN%D_tz8iu6VpKe70;4(gI}R z<j@};l0#j*2?f_*A8L7Fx3Xxn17a&fuD+c(l6o~Q?n`C6H>1vW?C<ERv2IFIdei0k zRnJuTM|R74G~nJC1+mu&x(C?j|MJ<C%+DG95qmv`Tt{5&d|pKpLiu!g8EycYc6J0C z7h+f+X{mtnd&lhzdJK+R7msLzoWgN&X4KAyHh)b@mnAVQyN2tn1VuM3pV3WfaV8;? zHuj@FHIkwgf81~UatCFcix-BRAapmSt%DJljbd<knxdYgBNc@>(uwb5D5?9~e3GG3 zwkDTr_p&UP(fYkIiZzi*M7rBzM3#S6=XICUq2aB=VZOYx-5IcoTIBsn(UhkgQyhG2 z9ehC&dMtECIaJkKkzrM*2L&Eg#K%t1W|I>gJee;R$IS+0rl#pZ;MDE++Adi2MZcgb zN(Zdw+EgGlrsh1#d~|JNUh{AWv?hA$wwkTgdncL8P+14i5uEJYb?riOe=*h8?t9g5 zaGpu}47s&1X6HW;B<;-_Z`bGB9%w#aJmPoAM`Q^sT;psKmRZAlNHN^3k3A|-)uV}W zUNK049IG~+B_xgtjp{8HzP&O1v^w-)(hWLN;S<@6ul}xSDNJUKpn>vIhpI7x;PUzY zIwe`JgYZUVe-U;Txb#bRj?D!>^eS)`*SMmwShD)|q1;;LmfYNvjxmB`+|o$XyJrKL z_1n)MRdDTYCNGY$v~rrPYq;$sj5%B!`%CCc?M2v4lB6=}`VtNicXWFh(Bj`TT@x&S zA0d9bb?eFtj98weoPIy|yYw7b50d=|Bfrb0I;0Cj72;7(!1$=i9urot!Qg~tk7kc9 zaAuE&$*jk*IRg(pbQisgKE$2SO*o_!by%mJSn&S%t{NzN=l%EiwSt#}X1cEZc7?)H zWf;{b1&s)7_WnZ4%d^P!SWlS~{=H4(-Am`9_4#E;7OJxsi-c7BA1~ldG!8$lX3Asb z;6|O?${7RGCe0}3XvjImzUM?wdSRi!Q}>eyBH<>)^V^wJ(0IFwWGHyIH=e<u<z2Nl zQgyZ2jnI9+KY9>G{(($(xUKQc7O8?fwGh4p=um;u9;jSBb~=snEnfUpu9V<@cvY>r zL3L_Qhk2_@*=$4gAW4-P{?HRWw?z`O(j>FDJ(kHtG(DQhCXC5bdc!7#32X9)#SJz? zp=0HV+Fh{PT~y5^WsEFR@qT6R8@ZvJ8%|2a`LqQ3Pa9DHY=ej+om4#E9YDScwZqvP zFX!f8PH1fa9oFzOo<|>qmSLGE)^=-s&uP&T>$RzQu-3;|>z`HuWA3t3F)=iAauo<t zG5`&%IE@7)vfJ(v4y&~sF^lD~E;>?9Kg&U)5#ftDSQyJI)TErYJu3^`MIWM1trW9r zg8T|@0?Mi}F&CV^6?0q*l>I%4uHg0D-hSXYgZ}qj@-f6S={Hll=&j%PE4+(SP`oe# zJuZ0AAp=K=>&Ct7!=nz968~Ro=N;9=5-;G;JBn1L_a<E_(tD96MM4Q3r3wih>0J<z zq9{ca2}lVYRC-66G(`}Q4l3masZw9mtKsg$d*2^#a&pdYPWGGMY&N?)v){~28`N6D zL-j<2gd@B#@!pk<FmE~x$I{V2NkL1VwWQBg;wyHEE@IO)vy;j(GT)(lc!fWI0Mkxp zDtC@ibMAF)%bDONaeSMQ=ES+hjl6ozST%a=fNWCkFERnSa#?NsU2CP@1Z~<(QHWsV zRfJr3qU$gYljM!Za~yagn?jwkQ%T<E^a{ie&#w2(?%fb#>|!s^TVqm|FrhTuN`h}A zdiWP2UTl|@jN$I7ZcoT8Hr^}*C#SutWvi4n=`sO-Tjv*7&co(F+RO8beC1+fuX+w@ z@dANO<x=-o*_*NH7#Etu11$uf8j)}m!3T4`tSTiR<z{#7x(s3)cKC|VOi^p^8n&wI zn`&zxicxAWUTw+eal`hFzR?<^%IhkVyO<vFiThEpXwV|-bdlhT-U%mT>EyR699B<W z^lE)D+R3>96^RQ~;2on6-ZdR6Wstf-{Dr8j2`|O=-DP9P^Gr?BUTM5V+R()#xk&{m zF(bX(g5lK#mdGoQT^7f(l9zMm1M)=zlO5Ue^<BB$A7pWR`rC^^8CVT^A8iSqn@%yj z=xDXD2X6NH%w)bL80IE9njKoJp+Kl5z~fvkH4l3g<MQRwir4Cse7$ysPHehc6tW6n zJVSX8{BpsXG|(gmzR|OZ2k?cFm+^49>JP4N3qA<gb=z}%5`{B`&a6TdHg0N)2mEmu ztX0y5%le+Q70X)O$wt?+<Hqk;dzy(>)`%|_kUpW2S+zUn-UbZ5Mnv~bAsZ6}swDaM zraa;AmB-9fQ`d1Oir}ez-m?LH7sBEM^piC7Mf3Gus9c4sr|;dn;!$Oi{w9_0+fKW< z_(f^aDpqHS5M+Sc^u1nw@6RH8JsT`!V|2+xc&v}xt<!BAmtOKP%7pL2prWRK#U|y& ziiF?b-E>L*D$zi-o|`h&5^KS~#TosUnzb1_B7CwhxA53RjNX3<$~`Vg9q*^5J2gBm z<MYk8bFLtlU%3W#wv>{}5S4UruML{<DVrbXS<KT4B1{Y%YlFXD5A`{swM@F+ufAPb zymnb9C?`G8k7}J<Z|B0LPNT8d*H`^NF}K?XRAtyuzemIs8)d7JRxAlg*lV;9d~Mn5 zg8R+qe%5MO=uW~(lQsl{ZMudX^Y}<zQ||1Hun7?5%iHeK1v@_!W;s;w4yCaopWl-& zv6swRyektEw3U2b{MlYEj|GpN;)0S|IFAAKP)hBNrrhLxvS`D^`PxG(Qn1b?nq)<y zg?3EeSa8tAmPDR$Sv<<AT!m;a=C>^5^3BN;IP_M&hWGjc{7Z?89+*3I?ePWV^`I^` z>In~?z7w|RQ;cQ*T)x?%TxU;hVOx<CU!ButtzLU^Os&TYa;~%Bb9LHd<>A$#&CYNs zX^nG*Ia3<ARO%&Hze2ukD}9a9J_t9VWJP?sLZv(c7v~@eSTHI3%S|ta--Qwq%W`jn zw%tB_cJ<kHY;6R&@(9l!Rr`~xiQ>U?o=NM)4Z$0H33e=!)P~>4o<pcSF(q`$t6`$= z4tGL=U5e$*u`q=TSQ5#&EDJAiO@}+Et+|~mog&s7RnBfzZ>knjYl7LU*@_eFwY#%n zRFQO@*TyU&IVWhX91|H9EJwq{6irA$iihFU1HxF=3kjWJvTvkev#j7wk_~-(pSkWM zaWm79bHQ;~J)oUBWTLoq4b@I<L-p_Xe81Z0>%ms;AH>fdz9|`9*Amh0#BhG1PCL!v z@_{#Vz!p>MFaF_WE|p+B(;;<O^5**~jcRfx(t!bU4y^KnoPb)L50s9_fyr&iI1NhZ z2=u^l5~Eu|CT28eF2}FVd-~ubq7v_g#&C`)hJ9AEYSKWwdy8T=G-bGc^Dq~$uL*0a zgwdz;xO@u^ku;UNNuDvR%i3U$7?(YBy^5h1%EM(cx6(Xe&{+S}%5ju#BU}mhGJ`<t z1Ho2P`OGyTdN?yA^09t1T+}76Fq<uoRdk$oP)OYda$iB#azHYWQ7bp=POdOBY|-Oz z5ld61pQ)ZljS7OZ>Dk+QepIKGv@^%Zcsj#BiPf{GC4c^I9^oEahRWR*WZGW`UhW>d z64okWIAIL_)`{0itK+X3cJ|7sE)ZwxtB4s8&p{3vxmX%NhS#3L3hgLV9)$%ciG_xp zJDAFYDZ$r+8n=+E5{F{&?t-mI5iM7b1g-qLm#mmGsYyCF@1!*ccg)EYcR-bjtuva= zmX(lMD!g@(I<wuD!d39(qUdUxGNocXE4wv}sQzAs_mG}KdVGKkC3cr59Up;ys9Lwj zc1vXWoM8M=$DsEWSPgT+D-ZAJ=`TngZHJK$(nZk^os4!L<4X-9mB?$U%GfgaLQEg~ z%-jjkq4SxAbNUk_kWgIWN+gtY!n8&8UIG`RmCUR^HZCp=jXpl{SsErmIm_TCPzVMl z7PcsHX-HEfb3_v^CM~`*6Kdth!Uaq6keBzBhX+(q3tHHsWTQ%`1wJfi=2A);v1rn~ z;vpsXZ+Upea{_0I2j0uF>5P4fBaoj#3YUILm0GTz8XYfQaGWeuHRNKodSLS+HTogP z^F&Nc?^w|5g9~cqmvs@-2JVWnpZ%UY*-}(F6zw|?RA?yTeTnLSBV)Lhb*SiXoNxAq zVEO*1>xk>T=^8i7XbVtpLi;jWNBgozcg>$_Jbmn&%9}(m%h&Y{=L)U}BeKM|X`@}H zk#S?yzFL2KC`{caVo0&JI!BQ?VeI&3o3ox~f$!1o>*VOf-C|l1vj<$CxrV$SHM7xm zkw2}KV8Cw79SU=m8nIPqZqK>8)7x2$7anJMQOnwThR>|!yt_cW7Y0All!MUJX0hS8 zfylz#3f8??FXkcdw(l)~cb79*{k?y~GkYq1o9zO(yz1$G4FSCCVV8^TnC=-UcjxLX z<6jTH)XN|+WA@5F?FklV8EmS=YuYTN-KBLuqa@EosL;5_Ibs4T@c6wi69NxLdqz9y z^5%ZNHdMNgOhz5_Nczn(+gN16mlEdi=*!zSTXYGY2tM$pgE;#|LiM^x&4g=rOwYTe z(t1`!(ee`Z6-NpY#35B&<XQ5A6QD*N;A(-HFv)a-<RDCg{mlKcG=sieN%A$vdRfa_ zQrwquvjq(!oavd!yLUUw)uuvuhbU(nie2SzyyVX!iRQlj<QcY30HIk`XqT=_Gpg;1 zG<Oh8ozucia?|J_H+*z*Q2!CeG-@oD?Bp+N&sKW5k3JKWr!u-Oh2l^r#*~Y&JpQEN zA*I##P?g{t?N^D8_9o87O&;G2azVRm6sjKXZ%gT^l^!5{s>zoXMXJu%hzv%t-|coL zUN4n$ZIKc%;VKjIUh!=+aA_W?-&mM*%502%AA?WP=x5HI8P9U$_}cd%?e%{4$GnS^ zf;_H>%>;VVZtIQZ1nh;f@urZvwbZgB<9A106XhSwRaU7DHaRQW_8=<jss-D_E;a~$ zk%nvq*|8BbWqy%w$8TpiD>~Cm-}tp^?Ax}seoZMgHaui5bk)rFkAs(2K7NomS{FL| zaAGvSZ-r1;3CjE)s=22#c6Z$=eLM4mPM5atAm9D9!Pz~mE%w5fzLK@uq3%~Ywyei3 z4to>4`poaS_*i*qCU4?)yqr(iJHy}ob-&E=-61$&3l1KhDBj&|Wk?fPg@a4?^j6xp zQ>|mEEk~NaIu(Bi=$zQ<gegtmT6p!GA$F8MWg@kRoD+O555ik~7wCR}!N}-a!v=xW z&w@ZSC))?SQGGB`-8Fx8G3^6GytCEL2K1LqBTLVST)QUJTm;o-4qP2Hw9y<{c@%|f z(h^-sL}R_Z5;Vm>5RHGne?{uz87}aPy%EIKLG`(w<!&<b=S$<g^^`rz>J-nN1c$v4 zrcm;WgfY8t-$9>BNODBr6r^-9g6WdVo|q$c%c#xrR9DQ$n1V<6WD&bN4ITP13O&pX zj8R&v?>fpR?XJB`T7M|Q>!kfg!|RRsmBf2_bVN|yDLmFvi%+D!yjOb5NoJ$_V9zee z5HJdcVVfoGxFx%IM8)*U_Sn7Rf)K)R`nUW%ppZf;cuAKO=Y8Tw>h$mC+I0mW+LvoH z$Y0Cc4qXac9e=&tT5xXtg2)4##c|cD^Zjk)=~y-R<?;#D=cO7|$8YH(qWjWP=qH|4 zZ_#DYPL^c``+ff8=Y<^bTD^a$(nqn8n4Z!=L6klfv%UPmiebwDHbfv%OYYE?AUaEY zE0<pIuQp^Ao%uBn2KdIsAncc%HIMJ@+z!S|kIa}q^wQGj8`H15xr`C;R9iH#DO!SE zpt1x$Epf}C5%(?0K~YrsIq7I4qkKFej6iGWcg(odE7<*==At($!Mm5lAv!JXITP?) zT+h$++i#Tbd|gis)hnUqO;tefP%e}(8skVMIFoBPbG~Z7?zEWAR%TU7MsS-hqKz!A zK6~xfNKgSAq@rTB+1==l1$mX-rCP~{RlH(qaemF!f9*NN2s1h)R~pxh-_AioK0TV_ z53%=6!LC%MQ|0XV>NBIqVcpS*P{D+0J9k<gT%Iw>3(t{KVAPzJ%*gP4xx#E#Jl}q^ zf2M$C3FA##ab8Dn`J1h=k+Iub91M11-X8MO4H!>3f<$zWor&n(TB4fFuokwLZ=Qet zZAT!;1&mx~@tf1iGJY+gTH+&nG{bR(Uq=$x2)O~ur9E6hCN4W)PM0-GWKn&N13jQ$ z$%?J(4k~`7Q%!x0=h|;3^HH|a`xynv$7B-gy7w8l6SVmmO$mC@HxcnSOD(-CktT;y zq^3Ub_<#eS@NMi(-9uamBZGn`$s~bPL;+Sk0dcEnN1ckeI9--d<CQ2$U5h7@*yjp@ z<h%)Vp41Fvh7d5dCz=o>VCmI%Z1n2g9w42u%J!05R%A3F@C)!sLwZWo`bPV*3uYe( zf1F~<lHav?`H6;=9On++x_6O9)sxn5I=l5Bi9MS3?99)Y$={CLDkAIO8Vl{X_X2BD zVsX+svnHZO844-NntOFiab6;B&BnjiHSEfIKl|6Z3b)L&B~wFJ5F8)kIiC|uro2q3 zS8K!*AF;B{CpU}QAcjI(6(A1;<GwIvGmsX$X7fwMZ}i+<@;i#$qOILG(;=uKJeIye zme}@Dw%@ArMSa^c3Ei$rS)!{6bS^4NxRmmP|NFeNTYixY(|%?NfkhTkJ3>ReUpk53 zFG&U1@2nqDEicv}d@L&G8aNWRC9}vZ6DWEY6ko)d)LE4*QknN#M$%cA><--Vqlc!0 zUn3HvmnMjrK2-_!3`4_6x5|#e7H_E?mTH;yB|^vNZ}8Pi(9SWw4V2RYmmD586e-g$ z+2e5p@GzP)=XVK@kAAkY(}>X%bM$-K%L$R^NHQD9HxL+r)my8*Hyh8o>{Y4kSC zut&|T@V%Czu>nz}^;^PnW^Np1PCa>k-ds)FBkJa@z*)v2Q4Q5&@?C1(s~D)tAqDDu zh!5g}Yw5#C$uRd&-itUP2t<zh^m{_B{+&z}U2l2V-SV(7@I|RqkndGSAOO<N>Engk z0t3|)i|Qf&BmD&MqB8m^a{sV}fE#KScHmw|eX}0*HQIk{*o_4Oq4Y8<l(l6gVB-q2 z(}kf-E|`ad-H$nqfFQMp)P?ORfGP_1U0(T~enw!7sw(^jxp@CKDio}@nuFSW6!qr# z&OxQWQK;hm5vA;d+DYyx!|b#jG#8p<`2xk^M}fZERo~N3raWr?rav<E?40ea-0gl{ zrGSM#6A4WdW(R?goFEXYGIS!z;Gdv+*n7HI-?DOW=6Abw6UYG0f%YBpGqN1M6AsYN z-|*BK(SStYWL#*X3(C^_Z590_{;$CvPCZP36J4Q^wt^>+|D5&;7#DCl4>Y6|)eYfy zT);8{F~EWC(HM~Q3C!<;{dn#Gga8M>Ktq^OX7BG<enb9r1OUgRKy!vpa{eDjr~sA( z*t-rLL5$srk^mz3zxK5Q<_7FLg3j%N)1PzukDesJOn^Nq(3v<m|2dP>`d0wSK;a%u z&bf7he2RV#Bmu>AG^qpSs{cNKetM**YU)5D&?-k0P2El*{>d>1Vu3O^8oPfQ_77?} zkP4Kz(bPxKQ-TF3-9Q>p!ba0LVW-gksbm9TK#Lj;t2h<*UrsfU544`qd>i*ug8g>~ z8VCn^%4j&L$0_hXTFXE#&@M)EOHXot*-d}{VSkv%CtPD773l1qpn9H&_EhSx*1=P+ zH$W8@4KDXO1^hFEpMe5n1e#oEl#KtspniH?Kp60GHyU;$>|bH0UW9;83DC3v)TAxH z&mq5d-`}PD@yq}i7_dzijWUV*GwRoG0HgtH?PywL@(CKC4zGI^2X%i20<oZ8Bd9ys Jf`{MN{s*87E<6AL literal 0 HcmV?d00001 diff --git a/init.m b/init.m new file mode 100644 index 0000000..15e83d0 --- /dev/null +++ b/init.m @@ -0,0 +1,78 @@ +% C����� ��� ������� ���������� ������ + +clear;%������� ������� ������������ +Ts = 10e-6;%��� �������������� +Decim = 20;%�������� ������������ +Limit = 2000000;%���-�� ������������ ����� +% Scope-� ���������� ��������� tt ������ ������� +tt = Ts*Decim*Limit; + + +% ��� ��������� ������ +SQRT2 = sqrt(2); +SQRT3 = sqrt(3); +PI2 = pi*2; + +% ��������� �������� ���, ���� �� NmNom +w0 = 0;%0.5;%-0.75;% +% �������� ������, �.�. +Mst = 0.6;%0.6; + +% ���������/��������� ������/������� ������� �������� +changingLoadEnable = 1;%1 +% ���������/��������� ��� � ���������� ���� +noiseEnable = 0;%1;% +% ... �������� ���� +NP = 0.08; + +% ����������� �������� ��� +% ... �������� �� ����, �� +Pnom = 5000e3*2; +% ... �������� ����������, � (rms) +Unom = 3000; +% ... ������������ ��������, ��/��� +NmNom = 165; +% ... ����� ��� ������� +Pp = 6; +% ... ����������� �������� +CosFi = 0.87; +% ... ��� +Eff = 0.962; +% ... ����������� � ���� ������ �������, ��*�^2 +J = 87e3*0.5; +% ... ������ ��������, �� +Snom = Pnom/CosFi/Eff; +% ... ������������ ��������, ���/� +WmNom = NmNom/60*PI2; +% ... ������ �� ����, �*� +Mnom = Pnom/WmNom; +% ... ��. ��������, ���/� +WeNom = WmNom*Pp; +% ... ��. ��������, �� +FeNom = WeNom/PI2; +% ... ��������������� �������, �� +PsiNom = Unom*SQRT2/(WeNom*SQRT3); +% ... ���������� �� ����� ���������, B +UdcNom = Unom*SQRT2*1.18; +% ... ���, � (ampl) +Inom = Snom/(Unom*SQRT3)*SQRT2*0.5;%0.5 - �.�. ������� ��� + +% ��������� ��� +Rs = 11.8e-3;%�� +Xls = 72.7e-3;%72.7e-3;%�� +Rr = 11.1e-3*2.0;%*0.8;%�� +Xlr = 85.5e-3;%�� +Xm = 2.87 * 1.5;%2.87;%�� +Fe = 12;%�� +Lls = Xls/(Fe*PI2);%�� +Llr = Xlr/(Fe*PI2);%�� +Lm = Xm/(Fe*PI2);%�� + +% ������� �� ����� INU, � +Cdc = 50e-3; +% ������� � INU +Csn = Pnom/(1000*WeNom*Unom^2)/10*0.5;%� (0.5 - �.�. ���������������� ���) +Rsn = 2*Ts/Csn*10;%�� + +% ���������� ������� ������� ��� ���� ���, c +Tiac = 30e-6; diff --git a/inu_im_2wnd_3lvl.slx b/inu_im_2wnd_3lvl.slx new file mode 100644 index 0000000000000000000000000000000000000000..e40b9cb4eacb29ba050d3d0ecab51b7e644b466a GIT binary patch literal 80373 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 S5ai&$U_=NAJ@((eG5!x7J*q+g literal 0 HcmV?d00001 diff --git a/inu_im_2wnd_3lvl.slx.original b/inu_im_2wnd_3lvl.slx.original new file mode 100644 index 0000000000000000000000000000000000000000..e7437a6b99b732cead6d0b45d80d869df4500548 GIT binary patch literal 88153 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 L1}ib2z4QDR#e_tK literal 0 HcmV?d00001 diff --git a/inu_im_2wnd_3lvl.slx.r2021a b/inu_im_2wnd_3lvl.slx.r2021a new file mode 100644 index 0000000000000000000000000000000000000000..0981defa1dbb67ab2f3066e0ec89f2fc2d971db1 GIT binary patch literal 64466 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 WfdZbKf`QQh|E7Saa(gGgefmF1hr=@f literal 0 HcmV?d00001 diff --git a/inu_im_2wnd_3lvl.slxc b/inu_im_2wnd_3lvl.slxc new file mode 100644 index 0000000000000000000000000000000000000000..47210db9640dad243d787f581b1fb5de9149b0f1 GIT binary patch literal 113909 zcmcG!Wl*Hewk3?ayEX3a?(SB&yE_zajW^o3L*wr54vo7v?rx1YFudoS8%Msl6Z1{n z`H@dO6<HA#d+n8b?aY<Ra^MgcAW$GMARr(lATr}+V8fqp5uhL-e4n4Htjw$|CQQb5 zc1-TZE~dt&R_06^#x7!iy%_#|((tdz&#$Jou0VSwi@!}V+8evw0TFJT-Bg(u*_5w= z2(t>~6Ece`Fh6DJWyYDtnp9z&kRE@tvCXPDG0G~?%P6S)oNiEsfu3V58-<fBh6}UM zpd8kKf`XHTlB9$a2ZO>f`u+O=ydFF-4KaczFbz9GBoH$~#21U$BE-a>_#!7UHz^H0 z$1q7>?|WJn+!7TCMvu#{C*c>Fo0CvXz_Q=^4;7inHh$r^sb??i^pn0a3Xw8vVa9&F z)tt;XgiI|1PNyl)yMeM;3|A2wzdL|xd{)%F9*FY4!P5x)(B%LI0<uj30>bwH1D;Rp zWE?CU|AOTrL&R~O8DnIg1qBTTMUzqRyfsg`9rk`f6$*hueE~?T$>kg+fu<x==%+4- zbX5c^!=Tea@hgX7xhe6ex#!PgKr=@G|Kl*x>Va<R^WO82?C@?DBny)Uty~y=8ofiY zX0R*gC<K%Epc=0kyp_<m@Apir9Thv<Z!<vctqbHdbLZ2!jvK??S3}F#JBYOsWuL{S z5p|+<uEi%gtDZrd(Y??y|HDUq45Z-><+CS%XIxS2$TOix)sY`$mkdUVGa1encDO5- zvm$Q8ewz_;fM7Slt5F)XP=NsQ!}7t^%Ea>q3bJSOZrzo}0hsPZQ8!eJ_D$c_l5dZ} z=pA*nm#p4b^Qt|4Jq2%(3(jfN0`n)IM45YjshI=^u4p{P7>Br>S8aLBn~jG_{TGhs zD#FJYw~pjEH^HCiZx1*d-mLMEH%+^?b5-4n*SpcTxK`sy(?~}d=*vj0IlTl5?|jbu z(niN*WTlOQD_w%jCzy{Yh|7QxC3R7~jz>@-Ch3|VO#%0s8_>m|&%!<*J+@uIQe=pI z@a)P4w=Ss1LQVXxj0fldK1(<kZ3jD=0N_<aL$sT1fo|gTsXz1hH(PAI`?vGxDNDXl z!<YB%lqJZI&@;W;@3$I{Ubc$wHbu*(OS&E^(q{}S^X~CIZn<4#xlOw^a}0u+hrYIV zl~^(~y1a39+;PuvkLP@bepNR^{!hUrw&~RZLj`9^Os1g0%G5pSck3|R7kh6A)h+kY zZ)&4@jl$@bY)4{`*2pNrdXswV{(5JPQ*kRMeK$wSRJ8h|_f^yuCZT&jmpKWq?$yb4 zJ_rx~K>d@x$dw9!I$U0G_0N?(_(@^BPx@Maa+1m3*wxMaZ}fEeq^Gr`1EZ(CU6bm# z;s7&B=N)GJRqPk4Cex%s=t5b7v9BX-Yisy;JNy_W81ID8I$u#RcLR}AmO65>aTV%( zt@VFL7dXCDlgmuVgk+!C&kLmN@Ayl&)>kq{-bV&x%Sy8cdId@O;@}%5Y_KDyMte03 zVC`ZRZ{!i>`r5suG;vsZT*8UQQRq15T!*M(tEhQe9xi(#`uE?oSG=<LB8umq0DBX% zE)uPJ9PMOURcz>5B6ou<*~bfi=mtmXklD~d6!)(^svG0F&#(OWfbxq%>f6H$L${z! zVxgS2rnFUP$e=4%ku7)4w(u$@*Sw9uRfdM1mtWW1*6R}-|KTWT2!*6T)sQPWjEuBc zwN3gpDErhSBIwJv>DV_BC?(fzVq2Tv^rm^3kk&y$QF<b+jbSfD=5_(`vkzDsh>cnt z8~*c+_|C`Yl)&k}!Rbu`G<Qx&k`(&=dT;Q5CgZPC>%MLpSn`>Sz|Ulm|9dU@TVBjP z-CT_Ssv7^27JJoomrQ09ziCZo@5w-NMiH~XXt`aPEXo|TJ&TuJRAPiC2#l}UFK2Yo zi6;t<9Y^Op9ToSEn-I$nm5J&AXb^lDtIDa2&hi#eX${xxz|8CZfQ*7IZ5%6xNq4vL zgz5xP>eueBFl7r0^aYegCS-+{M9C!>YB&f(PjO7Bx+BsMRH&WM;^zcQ(<RT+sA7Ob zIb_wxYCXswXwWrgH7^k9$cxS&S{~m+f$J32itwk$oQ!tMjiZ<*mof&pwe455lpkpN zvkv1grDm&&NW1ziPFcU?07}#LS*M(G4B2`t2g35=stLuEtkdnX+D(4tNG-G8&D_LK zLnf|=6m`ixoBoF_<43H`R}(|{0iAkNrv26`b7sqax=e%MaTBB>k3(=w+wgDu-XkS% z+w=`Ji*b85v*I=3#Me9Fp*o9CzO(!EdeggBSQ}f<*BCj>L^;r3TD&Q5Eors176*#a z@b8q5@T0Dt)i{jNTMinDT8LDuXX32D_=a(l>7y6Vx$k#;`12B4HXiTYcu6F~x<m%= zc8IKp2-rUUH1N`tI?(=s{AZ&7T6M(q1c{xW3Eufk_Lu)!b*4ZU7jp+UNk=;~a~Dw; zM-NwXm%kQX)oh>afH2DNji&aY11GGicmjsbv38_jZ(6j)$+=znD*MAlW^fKd(DB>e z2vN7iE9$DgGy}PH9<8hsxgTCoXUp}iZ>tZ8C9b)!q9}vjXs>-oaju%oEy;~=`#d{- znJ#@D)^OHz+@`LOsyH3#p|hfQeZJDHZUj0s&vSbv=X-R<BOQj@WPIApF+8M)NKQ(S zss0isV=&e5pA>d~U1GMU>YLnt!&07~hws=cXCJ^f=_<G9Cb@R}zlRO-k5+=>4(ZMW z3Iv2283Y9TzruDhc5wq(TRIrK0bR^p{|dM(bv3p?8Y|3@;y`y{)CRm@%ApRAd1Zwj z%0bnRQ@0j!xOYCTq21PdLH(1#i2yF@2z1_;o``|xV8ei1;d}OCfr-o)^H3qvijv0I zO!Ar<Cc2T70Amd$Czvzx$_!pV?MWIvfw%Yd8s?s*9j7zE)9;_k1F7nq2p2-i7{l6d zqE86@BpqCSu(^9sKbWCgXlvw>dY!=R2mEW_la1~jR|Tnb1-_cS)$g8b4^!Q3OMJ^% zU@2`=J#X~yxp5XTVv_DSLEoZ)$8=g;{IaJrFz+PR20#YoX8*a!yQYr<mdVg%fSVuX zzml+=nz}fj8Ip?WP09?0JX>2n!*afNO+pA9F!03hd`I>5gBLW|L)+}#xuy9n*&_PU zaJlCn4ktBUcL##8?Yqxsl*3_r%+5$)ta&h-jA!Dh)ch!HE^eBKB_wIYJD4*x;U(o# z(n?#!iqfo3VB<Y!T=!1aE_C&JRzfk2oP0Ivpir@d>=Qy)Ppa?pE;C?yx}Xi~0ZRy3 zzeFDj25LFbU@$D+ta62JBW+{Rq<nu#R<q$LP@uelVjd%3<KM{gv~dG%CKP1jXWiX2 z>2Q^D)Lpi+?aaOI^+3(&O4VE{IV+EQwSR^mTYPa%Yx)S!1m%5FI@)?g(S8j%Pzbqn z7fV4#Zi_&R$psO4*kQPO=wskm+R}xv$6Ym}G(GL|5v^`-_y<+^?&TpPSaa8as>X~% za0xuEr@wJ};8a(9Rrtsv<bXxReZ63TY+i<S`(60Nnyb0vJZWAYiL0^QGJYd8dU}I8 z*(3#5^G1|1FWA6>P-%>$HZq^}V3rl0YDX~Z_zJzo3o-m1YR(%bT#CwT25F!mwAb-A z=o`@=pvYL{q`PZaAqOE5O%k8UfC1*dMLu~L5Xio8Q9VO5(KL;yj7(pTS;n2&>sy%) zSyA^AQpW{%f<#;y0CqLgSVQI+yZg9J9k5ax)C?f@SXGeBj)nFR_=UdC()QEvHj9ZZ zrO^yEJ5I5lW7s=@GAmHy8zejBM1@NHKHFt!luYF7894##ng55i(_%-LNsr);wk#Vv z9u-nG9>Op7FN`d^VeVhhXGS>_<?Z8NqYuA}{5q%Ha{t<`pOP<)J7~w@of9FFPaQ<X zVBYCt-1YX9h~H~E`~3m<w8be_k6?koL#)jJNEWiSlsWi@i%Ni%OQ6x9Dht0Dxk_OJ z-A{;yAGypcu5B1bp#mj(1?w3FSCdS(q+Fv=3~IK!1@60N71<*hP~z*C>FW>DRid-W zQZkW&*)Z-aywg~K!|S4JqQz4GjeZu9EI|i`d-TUzuxG5mAcL$@w_GP!Vx}#(35v)% zd%H?<FYo!-iF8$u@|UjV{sJQBiT+Dyg972y0g%jd19Y6L?k$mcTJE#%2lJiEobq*- z!XIh}>vT#qtQK|K?FXPfKS>T@Tjd>DGtR#zoXWcIKwL&S9`LyZl-#@hA*cg*_mPTd zO!3;wx=3d5?nRyLpZAk>=9*Ut>8Df=rTFMWEg0*U$Qj9(*KT^0z;u*$+9X8`rAY!B zU(?_Zm@28fOa2rfHxu&90O5+bvaptKrGZs~cGFsDC+Z>^OQRUgvP4vwj12g*r2?#u z^~Mn6M&Z#}&AqX~#^{P?8(HaG5;<Q;1H<n$6}JP(UzpEU!8KX9^r)^^wA_E3A4&9= zRP3gS(3HPz6oEf@f`UzFBbO8<`=l9Z&gWi@jIkVwn%=W(cLKl4P^Dl@LHMjOtSN0b zWt=)2V%OJp7jFT|+*eu6uTtAGPo!A0yhqfp%9f;c2L*YWhSzUrNpSrqAAEhaU4Ck_ z#WW+<Un;i{JQK7Ka`i2N7k62+T2R?5t3K_jKHg+)nb&2B!@FU*gS}C2^kG$8H?uJ| zV4|8(V!y2zYZXWDinlKPFg<tn!D*KNI&d1qndURp*|ET)_=}Y|B2%D3Jky)9XYTS{ z$>~a$e&05GXnotpzy#sf_qNIL$`)+g@Iq=0*fObT8-Op|gxQFtoRagGc=iTaFTrX$ zMyWJ@8eOz#)5(Il;!H5o=O@CuJuEt+IIGj~9Az=@LAwOA_<{xvJs%+re&@EAp~j<m z0YG?FwR@y<Do>;gd2whm2gyEZdetcD`A^Y0vcApxuQR7t*_+D@oG<M|`2lZx?+;4< zl%>DaIAuyhVCGYfbpN5o_U3NJX2x#DO!gk8jxOfPE{;y-E^gL;7bo-YeKrHk2w_)V zaC<&`<RvTwkIcu;N!30elc+J@81Tn!Q(JPOP1!dT{v5yhlXQK+8R)SzM6r)`Ula=0 zJG;2y9=tx+`XmIw&p-&G#kxqOm^k8nap1JzKTKoB4yP}V@Jw>0InkzRW`o-16i#<! zVfwX(qXyQ|3%NLRAG~%u$1ZAxUq+mKmoXzOyQxim&k8I$Q5<6Q^_CjnGRj-B1}X`y zAgz)p`1^$h9$sLhGkvs9ZpIZfdp~jKNg1)1<l%eI*kp2YczT9gcZ2>r6fnc9Lgk-O zY<>>P&+*?vA>rv}?%?{5t$}`Q7g8`W4v0r?P%T-0vrRB>lWX_`D2zX?N-v1U>%-gX z+S{c|=f-_B;dW<z@i4t2GZ>kD$%OLW>xHOnv@c3AdIN{@9+hYG8s)Bc;!@w@Dx{wB z_AH;7Z_Efv3VM-2?2pj6CYU{ojeS#V4*ig<K@fHYEyaMhJHlRHMkjQV!DV$I;?D$3 z=vCB|-vXm-?&PEw6f_b;w;|^0xma2Lvk~(j1(e?Z5$#@3p;60cl#HK=r~cnXt7>j% zZtQCQw+;Jeg923KK@MWZ*nGxRdYDUrV31+J&xF6hkr^sMW1P>wIg&ewh+6mPp-S`s z48X@Qbhw}01wIGb&+3moG~Xk?Ccy})<mjP-jj%wP`&`Hu_=H14@NH}<WtY*Lk-)cw zA=oZpef^%-*81#5;o)}x`cp>PxmUXvtlJ_F#a700!+fH(XxLiD^0E_ttv?C*F(To2 zs-ONwf$R-}FL*USdDd>_ZmfiPZcJo>^k618Mgn67)k#mT(7&fT0W_bK?lW+{&&>w@ zzXt#R<$P#@h|&Nt#>mwhMu?9b%{+bK1yV*fJBv=iYRpVaj21O$<9bW#VwHo%w~>*L zM}MztYHYrZJSHcD`{I7~aTYMLSB-RqP{T}f-jScs#yYe2P_&)UakKe~ves?qU-;WL zgW%!#BPsXV8ZkG+jCe>497N!ACHe=QHuxAs={Lf(NQ4HVq~niT#KlmmV1fuj%Ce)M zO6?8`8*{7iA*;w|zCxk%=iyTHRB9MI?%0gb@E3q{U)1!Qvc~h(P}<;x*%^^xAC>IC z-Rzim+LTZ1RFQA<ij?xNwYd?4HB$3FP1}|1$82nH$?0Kxi2yQ6k~rL^wEMKXX-9M4 z;Y(uabSgdy8<McBo#&N@Eu#VMlmf7lwt9y*$P3fq+Tt=(u?cnUzudEZ|FNO_tKt2t zvcOP6txbR8i-8FOg8qrIu9&04=elt-RP%B&ch&!^**(zOQd(z5@jt4GxQ)b1br7Am z64v1=>_ULBtC<~QsVWN)Z=UZD=#fLvmjg&!t8!jcHBWnNS#EhaJ9@e^NidrZyHxF7 zQ=f)|0@N(^V)m|&CcUlzI9kxO;CYx)1JD)&+vmTHJnz1<;cq*b?>X)2y{DtdQOO6z zxJ_YH|FR+L+nI@$L2`pLm4teGXUWsyDb|}#7VMw@T+#mKEy^(1(SKA=1dvFkAxpMV z@YBoaMI95{I05+DjPQMnZa2YT!?A&?lnE6g0ZtI3SrvP6;WPrHkgaHPdXrf=lsH;g zJ`K!I?s2FBA4y?_y4<36pi&XlJKH%7*FWw#12yJ<Jf?x6LY3N`ha5eiAZnOwm)j?E z#8&={>DD#B-1mh)wA!GhR{Lgp*l}wayuLJ*NAMbfO|3M*)@&-RgA?2_-Sji<+2r>x z*1ZCQAZH=rd_X@cYFR_H&Pbx^f~}y&Hr#-nK!SQ^6^os;a5>_cvE=>)w*k5iD>N=Q zana5}ze6~gR;=$Tac!0dfp@&sBny3WBhum6S+$y&E4N(c+O&fE6#{+PU71@T3PrzA zC^*&9*f5&6ki^W`(Vc701=$Crh1$E8WT)zWCRxtcGT#KeT!?Tt8+b2gK5u%fY9CTZ z{uk_T{1OVjD*+FpPIYslXV`Tz@b7HxE)@5<vq0A5jcyE;yVF%r_Lpjc1Yk>{uf?xt zNODbbJ<8y=u>@ojN|<h9?m1?-_UX14IyrnRYJJO`Zo_9;{8DqWT|^t1tpZ=5l-YE> z5<YEd%7o9Tp#78O5#$W8UMce@Vc`L6cP>xF!__g<&XX_c&KNI1n*0zj!g|z-xBhVi zQQagQQ~+DbaweI}F=1#8JP&Q1_hL<)&5xh^vaZQX^J+%dUZc;4@r!GI<0$b!JC)LY zrN}G2`BD1RkL<B9E1J-UPfWFmT?yI$KltyHfN;6>$$!4j-5&fW{|#Nt?Od4{|9Vbp zDLC#jqjWuLinnngef6)BrL%8J_Fhw8->_wu(Q~?yGQ+p}c;l@N-3?4k5`G9uKuGtR zW+Utwy}!UO*hG+%fFOG5BK|Ef0f<Kx#Cz$<y;5TGQ?lO1Rqnf)2^blBbZ}IxCSrlK zH&8WApquvGu{n-wn(84boMW;00TyrSK+hz~I&-KItBiC4A&Dbl>>0anN%TJX?a03M zp0GZTiKss3N+6iPSl~BN0rM#+nCvWq85||b3;1nyYeedBD|5!WTYmBR(Re>b+SBl; zPplkHj5$BHOMZ|Vb0JKoYCly)lz9a8xxQWg2G*if2Th1AQb-R>l48-I-WGg@@w0wp zTR$taZ4;HOtwKwfb00m^eb)7z2rA4R2B7ijZTru(r0a7#J8^#ri?K8Nk@l~WhTCAR zDE^!}Vi{cv9jL=y+$t~DN)m9yh)Dp+4U=`bhE0(Ag<GX<JND{X&(3UUsUi4m99N82 z9iRuyemkVu<)WXv^y_SAgvbswVBb*0>p=W@v<?1f6)UUBb-mO&5AmbKt4b}G$To4d zd0nPK!F`rfX>uZ$J%!*H&bAZ8Cva&s`s~1=8j|9sy}KTEWN4t*X+2IDLkFT6+AY4d zUYa~MgaU{LB_F>+zyo0gFI7t>CPUFy+7@BeHTW=(qO#)dE$bKTRCJJpJ5(Ftpjy(T z5>$S-zuI2tcd8VGhwIA)C8$Gapbuz<Z}uCL`fkGE`4BgB_r1gzF((*JNeWz+H{B$m z9La4dE10FZG5cZAp`tpDS2x=9NkNX<2`j(mTW_@?gL}kUsOfm=LB0oKhe?yYK;vWe zrR?jX^mj2%`(^*px+X&o*beyR?@}XctLp8gjsd!(BBxZWyFW_m`*3>ja|IS1p`3&p zUJo|WXJ#RQ_l-_ZG|l)NI+K6;%el~3*oz06cT^FeyY(BaTBIcJ+t>Us-h+c37JaK{ zhq13R6MO!ywSRdif9XIJru%#8r`G=4!JhHoJe2?bU@t-6HJ=$H?CO;c=aK}L2+ut* z)+D>Bp}or9`XUBh6onmBw)gVoj4R^eT=R0uYx6E=fB$J&2x2+5GG0O*ikCI7x-LP( zTICY#?Znx^=#97YHr4g11MWme;rQ$M3IOm^czV709W1br2YnEuaB{2SkXS(nmY5ZW z&{G@({3pIx1o7Meox&YOiQkf5lJ;ULDG;*iO}jz(19`Tonr=?mLyB`0Ed>{Y(saOh zg*Aa47nkhVt9mbgP;S1V%cgg%nI`Se`0sdjz9mVX0_fFm$XgJm;;`aj;0$)$jPi(a zW@_o{xXq|VoKuY5W7_(!dS7(TuCjaSkb~yOH+g=v|5O@ZJmefdu525a^?d1Ep`Ve{ z8@`+9&g`1xs%dHjG{z}`w9b#}dZ2WiuHWKrjGZ9x+jYL~`Jp^*H-zG;2l%QK(MMCA zS)uuL-SqMBvk~bLt|{G<?$eQKX(eqmqv)P>$+vI{-R9XC1veiSUX&1_RUccj_l7x3 zlEW`!HKN?~N%1R>o>>qfSD=$xt?5Qc2|kfkCHWoZ258VhE+~ff{EHp*lxPKbqxr-C z^Rv?Zn_KqxO#e4-neqRmTXsD;4Y(d>0w~uiGdI?<ayGKE0GK}wJ2hf7=3bD35+<VW zUqA-!geO1;JB1OzDuoet8$ejdFz&#uAG7`x4rX2d$v@u>8r)Z_6$Jh9l)N_#J*O0@ z#8jEqez^`6Bda=b0D9^%H7z$TkF3Z5E2{wRf_gai@ax=iW$?ECtLtzkks`1#4PNyu zGdCe}UoYzr>^}galmmd_el7*i&%yf%)ZZM#{{w(rt?hw!)(*CYe{&rF>YVJqt2lmk z;h|fp=R)j$95bZU^?}26wcMszVw1bNc~xpOC_2gyXW_c_=Y7jQ4pSaeH<p^|!6}Qf zNfICo=wiK*jfMH#P);o|(Xd$xL_~koLq2-6QPju<63NyVMIo8z+r34li*OSMlf*4k z>jml97$_153b>JFYDmUiS(<AheUw0alS^6}aKB|uHdRZ^SrrFf(qi?#l0qnuS%C;B zQia^r?ZiqhIN6=!4Z7Qr;TDU9--h_4eW-dXPD@Xh$IqK70|Z<O1TOL+JN%n%M+kqq ztJ)u)d7sq29nzg2mu*N^%bU!>b^AskOO*9*jGUQI*Hv_;%K1w7Up|u$KkN!L3}+Hw z&l2sH;ItFHH<O>1Wc`;0|5bbbVkBD+z}4|nga6H-{67Hve`ioS{Zi%|R=Z!A1I3pu zFFjMMcGyjc7|cnC@LTjF*py48XtKIUaq>ygTUN|jf4^P+Sk>s7o%rHskt^ty&XtkP zSfG`~EOhv+S~ME?X;|Lx@BRsi0ra_|vQj`#01^}y9EV>jmx+AO5vQ0|v>z)+=%WD1 zQ%#R>n?ju)S(Y<`;cGNC0t~M!-E<>{Vy_Gu@PyOqFLWJyU!9n{;hQ3b!XCBCJ+rQ0 z7i>1UX7IyBP`N^G^qsjqz8qn&z~{iae>~j`X>Bnh`%AhKp4UWf)#coUlMr6p4Vw1o zrU2}kQcv-ISqwq<=)S%2LQV&_S|qfBjmwU#w`TkfTC2(((HT!AjYzolLdv7qsK#B) zve_W)f2>HO-t9QaT>ou*t1EEHcj8V)bmIG+>g9r@9aum<_N@lfFwx;27=&MvG%c)K z?At7~9NpU7dk=G1dbbt7CkiG;gezKf-}i9;Ri>sjytIvwFGmg5*?tSUlb)(8Xz6{? z5J;5vv=2V{_R)O5)GfH3h}>8|HFtly6>nhw+h&dE&qdbgbiRqH+;fFrZgz2@F8)S_ zuf}7rwWQwqcKMZMiJRcM?EBm!G*=_z6O*1LDl)ZWQ*MjJevO8=fLRw1AF6RPNWdQd zS?+OF_g0&(nsQ^ep=`QkY1$?SqrT`4C+aSZuGMn+`BXQC=^;2*ubQ;Y1rxbPx;p|A zK{W4=#gwDic4O2deCy@{+e1+#>nw;u)@0V>M#+X4h%<+){fl$aJgtyP6y%7Z=oh-S zXbmpX+(?R8GQ)Mx&SgNJ)gOVe=YKK9{?bkdo|XEp&tlQ?$>G0_B>qt_Jggl!*_r-( z_57zT*6A*chQjzoWVjf(POg~A4LjfIX;uei6M_Tko={W6EK{6%EVI_&Gj(}7(;%gS z@1v|wk-0+7$%$yyI#E#^G1;*mikV?K3aig}ovS^_t~2aW8OWy&tkZt*dqvHQO(jla z&@v<}Tmy2Zf_-C<tl%}r6C;OXrc6s4{boE<eQ3JyzGPQ4C(#aB5MV>Xxg{cRic`+d zslUw~+1mhy<(YC+3$Weu%p3Y;CH6!^=>;O?%>bfMLwo#A(q&#AD9G^js$Hb>7L5x! zTHCCR-zbBte<|!Kwh1<vdZZfP3C7Tqqru@-E8ExU!BA+jD9dp2?zc;dW%_n{mVkI1 z_Ufa3?-cY?kc=+$@-IV#^0#!(ilb|5;R+&TE-};`zHSWdCMAz^6K(o&62!4H(pVbr z#F+{_WK7m@vy|doCK}$&I1mXYKrG#&wz@}8mNOCu^^zP1V&-ofkjTxE;`aEuZWFMC za@?h4ExvF{!;bszoCQj|F?-vkIKvcz^5I8nZy%-Fx!ua({oy_&V~nnDs>TZ4`!jzR zJ<-~WYUg9XZ%r-B*!Yk0yzGcZ%*3sKHc#})Rsh^R{<fjd#9w|6_5UQmrz{wonwr}& z{q6bp`zOYRe<z2los)~r-zPqa0yMO?H)Qp2Ff(McbN~Fky{on1r^9A#Z1;bAHRV6V zmZg!ERsG+@R_J>+)F7rSAr%$588dl04Zo>0n(3aj)f@S$XYg!AS{pM>4Rcj7GaWO- zHzpHCv7cS&gwe7Mq$QH_89YJ)K%2oN9(1yjD%qb}sl79EDZ?BME+-@Dd_wI4RSSPS zCs-F*^OTL`0zttCc#&jy{zYm3!tDnt63Mquyc$1;>;D*T{|Tg_wS%jh3()@aRO4?~ z1wJu#bF+4^bp0Pf^|OVkQ~nQBtHA$(s-2NEE5LL3`+mu=#rK&P8JB#Kkv}{)^ZCUS zX&#Xh^ekV$_Q`}lbN>f2_Oth6267-ES&kqeM*r`SadUJsbhl?TF-`7*)k>6F26?d{ zfkh$yO5Il*B7qo*hlMFF3#O6>wi^p1A<l26B>s_)DGdYX0At1Q-ugqm!mue49!!=b zFhxTRqf$*-xy+;~2rM6SOn^;h#pcSdTFE%=qSAG0A}ihFbWiuiiZq<~H%t(WCES-k z*l+CRO_a`AA^Sm*FuIf?mG~kkVP?8P2+up$Vw!7~k#uG6>?u)FSTvzLs&U4~3LB`^ zwONu6qpZKJE!v!Z;r>d8Vq~%QpT%r`K$~C4rgz5T$xnzM*?Cn|+WQc7`6jayiyA%Z zwCU?0L-}ze8_1Vgkr$jgOywX$(;TfD#o>#$nhgegR}NQgFtcWjGEN~4?P<AzB}G-m z?vVBKAH+H(d^M%HKC>Q+M~Jl+eo-7qIt0;B$E{dM7(|>hM<Fk`fIuaXOfE)mMr*En zCxEUC;+x#4a&gb7`4V+yY1|oey_K^w!aJoZ`;_nJO0SSi8tN348%%R@X`l)foGeQ~ zwL2Oj(|=?qM4N7QjrfhYT!|HDkc+)O*9nR)5Q88`(Mi!F0h1;rM2xTRafZqtne-2W zxM@U(IFy*N3_$^B_GKE&?lkUd%=5=%>;5{E5Is_M-5-{=K%5$8yBD>&6kmqjptku^ zf?lW(m#b|E|Cr@BQ0t4-M9&UVra#>lXpX`sACI|+5Gpo>)XRaFwv1^iY7*ki&r!c4 zBto_nzm*LT_*0r^QWUJFIw~3r(mshKyPZp$j6ts=V}1Dg*%-=Lp7XCQZl#Nli}8Sb z>%LWfPehCwXIZINK+CxpS<!I*t=Jhn@KZ|`N`FU~pmkyIXnnw{#&COWgTqp9ZoI^Q z_=XK%KER)Y<;Y?`G)B{5jOuY#6h&bcoE3s3m%!CSNtz(^(YE>^Sg#_M@(kLyLKAK; zR&_5$uYfi|Ch_O~x1X&H%cWn<=K8q&DOkNI=awYb@VL+^9Rz<>+6|wgG8Wc^fQzs_ zeo%7cBT}oZT;fvAn%<`-S#;L&OIrNKmZp2m_&n4*f(>d5=+Zy$4XOflo-&yYMB75= zSVj8t4%SPWnugS0zc!Aup4%MXIM)|eC3SH{8jaJZNJbX5@V?jntCBx|{6|uoP^`BB z%MUZ#-c(nMC@74loa-s{+gEsuX4mO!h1WZA>*2Ccf&!6=;TR?Sz$6q&JJwVL0zSRe z@G#6mP>P8+k@*p7D3A@j?K;Z_E8(wKrJen(CMYRgiMFkS#Ka^8;UF}{+(>~UPdT0~ zTY+1K`L!IT5Y@y`GUp$$SthhEnJBv8q&ywc;DgnrKWO5H16#)TD24ennU^C+QsM~` zG&5>^WS<p@ApK1F1vq^e?r@E7vBz7*jL*k@*D(TgH+W5OX%+@1)jDY-HH&JN6(cp( z|4g-7y(}ZVNcJooTfG!pjlDcASoxPrV6H!@huxUwebckLZJcanSXoI{H@^S5R6n&; zPCvn`+B$hxKGv|dyhmz&s=l~@5oxK8Z`qafeoy<duU^J-ts9S*9goLQRD(UU+_MZ` zi;q#37roH*Ya#7?A!b#!WZ8bWCNr8(F2)d+W+z#SJ~K{BV`mG|IHhMzM}xY`AF<#q zW#>%g<SafW06VGU>K>?6;CacA3nJZ-C}2yIb2OGNRHGP!Bop&ZW2h>BL=LdmTISqV zhShSI(Mc)435CyPi6exW&JV=~&iDjY0o4RdUwNsnG7p|>&l|0Ou3O9{Ka;++dvxsv zAeHi01bu0YmIiPQ&hIr?Lc5uz5yNT)Sijk(nMYMEk~OK5j^d%(*)C#9X0}Ki7^q)* zO)bMi%;|GBtuC`6)*tZI;DVHt;Rg~z`6UJtCRXX)CYk>!UwDc$+H=qAdZ}J%f3EY| zFs+ah4$KWb;z?eXz+@`=<yTT8rT)AC)+A-lbIsi(d)(a3&Jh-mr+`vol*0nCfsZ!` zBV7Djfn;{I+kiO3wVQD9V04<khKR)ml`L7Pp=oYL_SaXEkSwS!n^TtLBTy9LAv#SC z%#if2Z#FodqcqiLN*3lxa_xxo%LFuw&QcgyBtVv&n5{V7QFsK@jjb{8Z|H?#(` z*IN~YxJYw~i6~bpPf(Wmm2D1+mLkefnt(#?0JW-(Ta_~aWDUjA<Cs;REW9vd^{T`b z&HwdNQ@o>Btv+Q%^B9*QJ|%~2a)}Jq5)R)&Gm9*AM=1TS6isj-=!tFBu>#eU-OyOA zm>kBZ*Jp$3$CyW5Uc(*z>QiK7+4B&6!$a6fH>i5KH<{(px{D_DAKlynk13`D>}qYF zJBl{bwt63zT4l68yzY^D)<(+N)Q-iW6AiSoAU3`Oga*!X|IE_xseELY7YBj6Qip@8 z+{H2Pt>*Mc#;bI;7TsN52EMQDj~E4vHl$5=-F(VoD8{~8_`)`l_d~aAK|MTR36grF z(s~H<2WnYC``(UDGNmx@KI?Q@idOF-k)XGQ!Tj+s<6x!qkfSP@&S>xh!LWkChkT+& zmndYEsq?BUm2>PYGJQv^%W6zCRSTv%k#zTo$hE@xUTWpFUpbm4MpKoVN={Hm=eFU@ z*+=`b4vIltClhQK-L%Qj;-zi1hSmC^js?G(={g3Q@ga@63%M#vAw|42+ku(EFA$#| z?hv0|d1@`7=hf<xorWtf)@=^epvg4_sfo1XpX)DW2gI%F@?V817$xAISgd0v0`DmR z9X0o1NeeEWR}i&iQVD!#mJ#&LblxBxk}0Iplcgr~a_kPqpI1iQ!PM&$O*`$M7)@#- zy0Cc+HJf|f|FDP{h_b)W4Kj<jUD9bgFKg>%<jnE#<H1IAnAjLKNwoDRh;`)@OYWli zjiN<qvbK;zH?%&m^TLGx1OV=lcy*zkB8vFhQXt6E7vwXiS4R)}bH{Ynm|L7^g3QM< zTYTsscZi^bdWIm>njSSm;`00}X=IGLGeXTg_-sVYhZZ)q74-{$iKw<#A!tG}Pu(yq zxMMX7STXDGWj1;E9C0YA8gn1b;-S64@1YM$O9NeI*7lRe2QEhyHSDZfbK2j8Pirx$ zuJ}^~3Xl_IerQmJ6}FxoaW7BBuYjpGL7MZFWKoV5MQX4*PC=2WWuQT4Z@gvoc?wZ! zv^Ajo@pGR`fUx;ueJ9Lzz1b_<oT<+-ZtnoMi~F~~laK~B=9R^hNmIqG+S77pO`t;1 zj&p+rB!tl_KGM&517;Q}mlW9(;+|ppEUlon4dB1+o!kTAppqwmSSa+g2TF&qC6GD7 z80i?Pq`SJzOPc#=q*$(J7{eGueFldM>EzuM>yB!(hM~=?dx#Mu)`PkM&j^4f!V5vC zF>-awV(O$qnVmi(M|MNdMO)U7C|q)X@bRnW*@@~^2vb(fjPKTTuy{X%l`tonvqvYx z@&*n9)yrKG2U}t;o!F$kBdrX(@yq0MF^-IU#O=I<5w~$cx=onutAZ?)GNHsIwNA)P z?vQJ7Oe7kSjSq-WDT>D9g?^Ll62z7cX+YXc2AW~jm(xVgs^v0+`D<FLwgGK2ZN5mu zwusmRDs0yV%Zm$&mq2hzb+r|Q++$;{)q86*k?W^EijSr?13J0xCYKat65V=Sq7o}T z1^upi;P^&j$3Db&pwdVDGJCPR4&1OG9%*|b*G0P74keJncp~>T(EJ1Df&$CiIN)cl zUZ)S;z~|77Ub=ZGe+tNpUG}9QR;L>1J7vOr|DCq6A0m(#h;P6@vFg>rkAsKd5CZk( ztOQa`e|y7+%k*-q%YG~{65Ds43)`lA^>Jzm%d%S9g>Tc=1VF=MWH-WiL*<ZT-};Nk zQF^Bu;?%mPNDK}f`F0{ZTOl7T-~*d4yS^ycGny5X!BL-xOBye21a{dTtg4+u1ACYX z1|MhNLM`Cj$H-R3sg?XI>$ui;RK}mtsN@~d0>`AS7=jPq<F@m5OHJ3jM(jsp*T)GE zIfB2ulBZZGHiG54Ekc`5#Lf);OqCl}9uSABwquEU$exK-Kt#v0(u?~Yn^1w`+DGpf z64HE}laX00E`g>N(%Ev1oG?_^32ltQhb30d0{=Bt8S_UIHcsD9OFuEgWR-jKa+QpT z8qdzf&C(>tC#QwXut550d|w+0yl)6oN*OESiR$y+Xkm2UrN*0SQ0}J6q|WzmQ9~@< zyf_$c2_|h>UArZi`#g{PUa*Q1%RJcBrDBcdiN~xl>C0j4PJQsgsiPPzVZTgQZI$d7 z^B41^C&@kvU{UgYnY@Vu7sWsrBE79UYP6rAgw!5PhE9|^eRCfV?V%7uTkgK#;MCob z4-NA-PucP4PoJ&e#0lWb*O2dU)nl=fl|KlkG)-l<mqVQVb<<`Zt6(zHI(ur8u&1s+ z-h8MUTWx+X0^6c<p;c9}SI+;|%p6C0wJSFmgH&K|#~Lw>GQuO<Qpl%9Ctqkx`KC`N z*@?{uwCb>^QiZfUgVel@>O~4wn}wRU$`b({?-jje@Dhp2jdKoM`8BPvXfk11radV3 zp);4JIU0*vSp-EQb>89?W~a>wa&xEml5QlXuq<2j?f1>Kf8_yZ^8U@5e_0>Zeab@t zyC9amr-WP;#rFC_-1HufSHBNYRi$Wi2wE90V}(3!oW!6F&IlfUkqQ2ry&$5tYJojg zl)d{%tTo>#y}argy^J?1X&LdA*Lm(f<(Y!ZdGu+uwEv3-=>eW)v-qLRI}WXT&ak!* z&f8RF%Xym0UG?KSPZ#FsW7IzEBInopuDsmGG~D;!w>HzA#usc25MJUPiR27MU}uV> z&d3ZC+KPaEgXLa>0*hduR&M-XV)lg+z{l(;fvyqTu4#_B!^xVA?SRH0J>XaKGgbPG zWuNSI&1?^$TOli^XKqZZnpt{@N-GB)w-!U-ic6YZ6vj0XVY<ye6=xxjG%YzcZnrfT zg<kW_o+8E$S88K{@~`Rp*(0{XELFY-K7l1YSRe5B4yz0(t39v$H+6sFAoIlyTl11> zcZ)bW)6kCk5&(D*FK6ZR&K!wfhM`bxWrl(Z;OpK?X@ss0Nn0`b?O~V1?Q2j^z+)z^ z>q*xS(mzbmN+`oC(AG;r)H#r6M7PX+c10V^eR@SFX<o7&EO*I_rdZUbVX(0j$mj&q zc$D1EZfV=EcLNYq<6*Fh8(%1&wi1nlh&GYXvnY|Vvsk_`KFvC`8i8@sC|)AmQvzZ^ zCReM^8!9o_sagW1<|ap*I7^10gtQcP6O#wsia|xx={CzL)x!)$0Vwj)2)P}0x$;`X z@y6=EV=w2$8|n{y9W;NZhU@zR=9&KR`>Y{2X|$!AxnoWg(IB}Y?YOQ-aH6X2Q*mPr zrjboA3t39o39}V3^^vl5Qg+-__6_tl6LSY~Kd-S0jG57SGDD$?5qNbk#y=Z;C4lBy zjV0B2?DVc#gQ_yp3RyO@Hp_&1k3fa1&k<cAE>tX_dGCZgt6bIF?n|*EQAN6um5ce4 z1TMV)p6|X8SSm3n5qV4{K`!XZ3doWfV~C`n28cBi3&~CSbpuU`Yy{Itj<Tkq_99eY zaBD@JY*fQ`QEJK-%wW@YvQ&e^2}cHlRBJ_0^y(SvWc*b*_z<%u<>yvfj}#iwMVX%v zYiCwv8!;jkf|8By_U;umiRfGSv-uf=?oqxwqq1J9>tdOj?RVA-I8SS1j&36<Gvrok zk>=FNOlcLdFW>9iKFx!exHEdyh-s}I?g@e%bKJpwNlq9c-Sd}~CQ~(atGu}5-mW0q znoOvJ8XobEvSL4SjNp}Mk76jvOSR*!T7N`wY|00pJkZdmC=xv1tSotLC1r1Vh|Efd z_om8%FBUBSDE`u<^#`<x+gRksX<@F<4@J_NIO1#7ZQ+<)ZJ=;X9{N$tj^wIl3u<gB zra<Y4n*)AM#Ra&>G7IZ{YML+GXzLgCR;de$Hw25Mh4)G#OY(jiSRH<7`ID=cVa5=z zlFZcPDl@gl<xc2J^@z*jIC76Z@fw}*t()%P+|7N?merFa?d`;42{~rIC~OjLn)(;q zBIFb#dY(kn>QNJirP0D35>?aSb8w03h@wd9>Y-k!+m$>-J5eMcX*pEwc{`Bs);m5v zZT85)qs)Ort9zZ1LG<#ud4!Q`ZW4)p=OD@k+EiXfm=VhNNrztW1-kJ_{G<N~q7Gek zV=W6QU|_9NzV@|R*ei!Dtw=XTDh`S%*teHbBg{gd@$?Z??~&x}_G04KJCJ8<j?|w> zTg}?g>Ocwc1suTxiXO4_yvXAkkH@s*k1fyMpnHAkP@M1BmpQQYXt(ekbxn583(?*} z?v3yD0Nr>x%R}3k827h=Kxr8d910BOkTwXpDQ=6J56ruiq}46;5B3I)z7PxkTlgL) z!!dFX%*!eqq^H;^bp<RHBg0yCc8Vxv1zCW?LMtfF+#vh5hk#D+610(h-t0^s>7_-% zy&ahGAFm&y;vb5Q^L3?!3qLpm$aRhmrw7VKC%vEGTF|T~OCxglnoc*#=U-`DZG6GI z?rh-sf0)lN^&NECTks9u#do{!Ss=Vm!U97jXX-D%yy_LMqtt!{dOF~CaiRdMcC$58 zuZU9io2#oHorVU<n!faLY;IugR3#c|ca^-mvL9nl2kl5)UECX*gpF3T>gEbYglfij zi%B0`;&9)D+`#VQK>#O8AMC^;WT(KicbXhqjXdh>j8dbB86=&i+|D0(g0ht$)~DcQ z<<o;)h6swcEhVr3-;Gb7g5$OWJYpae;P_1Y;D@|S`{;)BO+_mDr&xF_&Y$<|B#uUM zy7>-AT1@@DZOJ{$VYsl^=?-z={Q-kGu%{T>l0k_qriubASdBFD3J@1?*ds`xai*5H z1n45Eq^siB3ab!(&=Rc$(!d4r>#FR`?E=!(I;oo_@!F5lOrzrR2?dl=?_J8YB2rff zlLHkgq9S;y?|TEN@_-Z`M%4{qR(13a3{rY5jrvLq4WKo;O!+CgtvZdZSQS<9P;<zu z_=l`>DotyV=QzfvEXP22U@}Su=?oE&^??t0k%@rkZCFIzalgOvbW3py#`*|7uJ8f6 zxVDj`(3(BkU21ZLEZ5e$<~fmmL3>8^{S@~k5}vF4_y{oH#M$l=i)<>sqM3|Vz_bmr zr{P`+(<!7;(IWHS+uLDXSzwbc-0t$d&@fs5UA&{B{8I&e(JwT8Ui;8C?|ThpP|w#C z&v0j7?_tEr&9BsKF*D~ZikqgL`oFR3?aHm3>)lhGtwXq_JET{})^+7ev1aXX8Q9oX zFlb4zQW)zTS8o7CB-#>9PFQ(<Zx!G66R-w$_40D7zb(9X?ey^u<hPnmx1?lrDpE$d zeB3gv4P3*zzUqo#wXK_nsQi>Pa~Wr#2#^ze3Q9@WK1msMZIiTGo?fO`aDk7`0Ej2c zLy&u{=z|2khT<oVwmJBh`bi%k@xv1}^xrWhpI_z<X~ch(?z=w#*lBBHRA3XjC+nWl zwh+{pFbY_=CY{me*Oitpl`U*xmKR@$N3l@Ob|U`3zHUIenai(0M1(o;>HbK<kt}i{ zZ6)<_$?G!VX)97b$<;w@j6ITEpuy0^s6~mWfzKo-F3okseIxzJnDZ`}7JH11d9lNl z*qJe4r0^Zg7VQ3GmPn*0U*IyJT*wDP4$~>U<_mXbfk!~qjbY}#f};!w^+D6X2L=1Z zCQM8pkN2tOT4SkQt!v1=v_#@$Dy>t8$PU!{yR~RUGg!W>zu>0ej*d8a!L%QxDf7{z z6C0bGQIKRL0fCzlULhGeOB$7-{T}zJZC@?*s^|kDBF9lx++iiX-}Ty#=1D0J4H*z0 zXLbvhIRU5k4}joNbHyX-f`_u<k}yd;Qz4dR4`n~I{C6yrM%2D-=ThP|*#a`X7{4Qo z_CdZisqL)Hnk$S}@ri4NUaU&7GM6mnbgdX)wUI_yqKmAQ*rj5Zeyin=W37{53Egom zZR=Zfv`&J(0Yca8TvL@i8l9kcz&Gi)HD;YBG>n!UX5Xz0`&yp82>ADt3l42EQbuJ% zjS<yL#K+sO>RZvjQfDH6$Ra2b>FtcvZ7ki=gCJw!@%WfYmrJa@<ZK#bR*;Y!N%bAF zq`e$%b#-kXNf*-2&mYLcLbXkdS{L9FW08mFHv{2>4L$aGs(`-gaP)lhp^u>8-{OZs z9V#~b<gb457p_jJhO)`+*d0)S;pTc&dtnhznX7p`JW$He1RB5{vq%eH?S{-^Kj!ru z`>b1G+KOXXkeY&^TO&n$lkk(T1fzD=q0}2Trk;Mu13|Zp*9-jCzmxW@$WNXf1f7sX z5)g+{S@nP!K_6rn?tXRm(0923<lj^P2xCAVOhk$@U?96fgc8gnL$cQ?SA3i2tEKcm zpBJaI>MwSGktx)6M<<OUHc#l$vED&Dw$xOMFuF-hCZ3TpZY<#S>+V-hdV8^(e2TrV z#ZOImF>X;GDJST#E@3&(h3d^=g*Rftn}zPM?$t_fxBaPQjjp<>2Xd=^7{;a~AHLI^ z9oLo)5zNTbUG$y(PxYH<ZP^H(It_;Zm>hPRu`izL?>9k-26;X0$p|QAw?Vv0D|(g6 zV|L|PlB!4(N@GmS`?69r41MxOuOQ4SoF7)8Lzt_*Y~pGe7^@%zRj@NgfU6Z&mtX;{ zY4)AC??u<&5f!S?y1XIVifzrcht9)|X*=3|zN_Q06uuTNW$yo32oRk>j9~WQqqh_c zi2cn(wS`KR{Nrq;%&)zg*0T86t?Q?EM0IZH?70S*vKbKIK_-)MecZ3H4El1--%CCG z;>jvZge+@Z;>mu*L=5LHDjeI-n-BmW)6#rhYuGLvX7XS#=t+YpFA0&5^+$znbW$rJ z^F{v9?3BbH^Wt|;3-Q1n5;H%RK-g8Uzb7W@kSZC~3{4?*yxVt^+)3d`hM{QFA%}8# z*~Ffuq=&N1KOE;<1WP5A!lxG7sMYF^yfk0RGK*lXK;u=3Z$mXUCau$?Cr~sVd6XZ; zs@kXJYTM;r7B)am-7^Gi@|j!|(`>6;%L_e8fFH*t0FT?{)iI;&c5FUkAl=JC)k8TN zM-SA)_jal@QXqOMg9evzgN(n!`aTzy^oBY3qWv9V*=zrAK_J&xYiw%;p8^3@4_0@| zmGQpkqr`g<jIs_|*N7coka;BQ_XCg0%OmiG3$jCEpbxkT9`Med^clztgctdQWK<An z8A#4#y||GjFz8e+veC42m(ffLjDjlVTiJ$C_2|tJ1b#3S{+ca&mBPsQ#i$=CEp<vs zWk%OPB#MNqD3D^-vr{T`W`&ZTJDL$Kii1WEA8!Gdfn6D{cL7Q)+b4V{p<fPZ8mw3+ zqE%P(g7G@`c;DFSu0Znu;fZAp4y3C7;)7O!?^>n)NZS=Ey>aD)fvM|Z(#&d5a%muM z2Fz`j*;LOD<J<-*dxg>9dVtW{X#3$XTYYS=A-%El2_leBow9)Yyi*Y9k;GP}`Pst= zLFsZ?z*M|CUiaxXof_OCs<xo{fZ1()1OjV#y7o9UxDIvBMtjtdrB0{L03I}@uiq3m zqH5b~9?Cjk7cSPSnl9PI5RL>&`QAIsmjUtZnuy9CVaBMc9^j<1rW;+Nkr&!OFtr~$ zrsLbcnMb(UZOE*SHI952J5|KvS#gr~|AMG`wpl;@y&X_ZtZlW}Rf$-}S6{2NF~}L! z7^4I1(GOaDD^}WwgtG`G*%oFyd%qDw7&$t2UGwRA3)oA)M@<NIw@^@NWBWsqh>xm* zM$&3uXP8`yCj(9MfT&?7nfvALOR<^6)u_8*!W(>~N_>>#k6M)r#X~sz73yV!0NK2u z>$_KuzS3D^26f2*h+|R#Kt1gwl6`|f1mCM2bC+`m!&5V(+n{A?Ea@Tx>4=jOnxVYO zNx1ghF!ckD%vfvL*abXpPZR-dVM;ViBfo>r9Txi>TGIK5>swZdK1=&@_KG&NyS7n9 zV3RL-<pI1s*R3Rhgq)@pQOSiS3QN3{>+kLi{BKf3S<f+)8|&s?N5xVazpU27B~yCv z^IW;zR-B?_V>H&1=S#1ppq}X(lKljdvO6k2+S{n99Dc_WlATR;69Uy}TXSatdKBdT zzmB=mhrtlpyO;Md?xUcv1b2Lndo-Udb(V75J$DW6a~YHYe&2a_O=i-Nac}~dREle& z@%_Tx-#e!7^lokpq{KKbf>zyN?EAHaYb`fBX_z&llls)S+kzo$)aBae_jI}ONXIq` z^wArvrg^?-qYM6ud9cr<!Q6!5^dE-vXTQg$YLdzd_7;_So=6ZlW*5Dh&YER%Sam^W zddDQ<j+h}S+W0k{BP}?eg$I%R%`QcOrxN~lgr^et%*I&?>9KjcX1vAscEu->_f(mW z@q_J1U*YglT>_6Nll8!%l4+a|HA-C1d>1$f5!GkQ`k4K8l!pHnkTL1q8$<;#Egnz_ z(|rup-tgo1NQ?eTwh;cFzX{*K+iSREx=1gXLxYxXmVs<I4L!aCf<GlqkASpvioYX# zA@-pji+vRRD+*cHfKMLxeW;A^OK5(+wzK8~3hiAQ;A6YqdhwZgg@)g43T^5Z^L;0V zG^H(C>T0H3OQJXSJ8t?z6(^jIu?jXpD}xr-k0_Hj>XiMfreJ-AJAO_Nj30~Qc80o~ z`^6f(Hl)q(nB)#hRdvIP#80Q`r+qIDOc4YU-U`dmN^!@(FOZW3IlF<k?3-M`YY%(8 z2Ke`oC%}wKVteB}(0YyK-3%UYFHV85iWl_$1W8V^L<l!AHWN$s%m3o-9GY}tf^FTl zy?eK9+qP}nwszaLZQHhO+qT~OorpU+Kj4fqYp^n-qH0jFqT)#>-j}o7X8O;*JC}jl zj<a5Fpiu@sEI13j6L-jiJ4($G$e!P~Ak5Z;(;Sfnyb+AMHh!5u|BN@Xj$wKXf*R^S zno&Ep%y15Clx}N+-?8^XvJJ)Pnu)J_g}bKrk3^kgiy~60-&YVvqJ_Wz;aw)*;pn|@ zjNsSpu%OrrvQO*~<M@MJ!c~b}MC;7iuDwOrT`$>!G+_elvw<ClmG$p$FhlpOHsJl4 z9tS{|y{Un3y5X@p<}CgFxP2jEUPAu*?1|yU$m-XpS;zrzYFEnX_Vj9XJ*jxb_J*~? z1KXM7!VUONrpDO;gqF@Q3j0+beAmwQu8xl~**@LR55(mdiTfzf{{DDU;jh2<B?O1r zj%qkb$LBbXRaDut-aC_{E}I-WMpDd#dt}p0?+fy744+LIEu>-j--<N5-p1p3^S-91 zW)zVD_ococ+>^YMcLhnfTP1P!VSpyyF9Zam3kwp;%qHsBg;*4(V_nsUGp?Ok<Uf-C zdu|s8a_bbX{|t5^U*tw)De$;KqWk45z2v|kXAC1cT+$SbPVOQI*gmZx$XcX58+<~r ze%9j5R)__PY5c{reJPw*dk?yBpO4KC5F5)D!iN7a9G=Fn7dwa+a6N@a(Nl1G)^Hd8 z?<kY-uYQl`tg&_Uvz<H?Ewgyt9^qM%r)Cp|-AGVuy8HoT$Tn-){_LrbGlRF5B)^PG zxY#U_YpH=KPPuaD{yFG^25fIU*oylh9_H&jJg@s`l!bu=1G;brC`0+W=u7S?zY&M5 zz@cv>>Ddko?H@1LP66>#3~blRYdV*1gR8G!AnCvJ35ok~nRMabq!gdhCPFMHZzkrT zgQ>b+;i{a`V16Dy3>eweS5tQmtazKm$CHsK=l2m(Hkv>W<UV4uQA&Bf8gEBACG`7x zVN92V&FH>67x(jdpB{zXQ0Y;BZ@Qfg4~7mL$k1ZzZfNY2zQpGCxqX0vq4h_YE=YXd zlOI;brEW4j=I))Nn&R%6-U_frE<!d4s?nA;7MrVYhM63!ZA`bF6-U~>Sm|i(8hWE% z-@h??W?vHQOY=DG?pQN68|Y9r$tajtJwEIi$VhWPaq%70%~QGAvh>08VJnbatu+aV zs(IuRlVC89oVTi{Hb3CVFhs|Jiz%cPlC?dqT~NRxT_PKgbUFgiODwRcb7xHkE^r<i z6&}R@KE<UT^8MhjeGk6BW<QtqlHtQj11w<Qh3}R1lbl1RqV4G=>~F1&JVHEHTc6@o ze`FuwhGOjf6a3uC9to6AZB4vT<1cUz|3sI&gOfiWm-s8v2>X2^!+GHVd)s#GOx`ED zk=X8hHqFr~F!^I;|FnJc;Qr3CmKgAZ3(qc&D6hr83acVnQ5X%58|-EW{n{~E$q`2y z&8^&Ym;G7M^z2k9REF%>uZsBCbL^e<x{2rU97~BXpxJaVctIb*tV2?q%k~TMQ{oVC z5yNm@bVX)C`G&KTY?h?+@cv}qKdot6P1siI?Wh-Fo}{izO1ncn=@cMAg@g_oA~%V9 zF4As6B1G-LwF?Z77%bGdSl^H*x4O2I|3-A?)5|EjfSdKY)>%88141AE8J%U$hO4>> zWDtuKmOuap!5&54#vm&4Nu@G%Q?$8Q52;m%BX)7+52m3<SOB)f?y`_~WPng&e~lUu z4uFdj5h$Hew$;@}o5F8XDFHq7Gs~#-$Uq3U(6Q)R1A!a%)p<q~4$!C*67b6{lbWK5 zRE>_RSpc5kLlvitSOT8FZL_O=GlC=W-u{de4v79l0e;A<+ssu*+hVaR>IqBDc{6A8 zOto1ACM5Im9q<N)c=X#o&6u~yml>@S6tJ6Czv)&+qt1*+s{%!FVmlI&3`Gcc5h~5d z+=J7~Vg{BA)HKolw4YOebHI#a3kg@)nac5AVGz)1CU+lXf3^C>_m~er{e7z9$AJ0+ zr2N4d(UJn$V01!?*k1maUI;T)63(Y>p+aU<1y?3Km)i7Yyi#c1nY+WCTZ7UHJS8=e zpKCZRMM<=w=|!J5;YdrsffT~(tz|K*L%%ldA}CMA_9Ic|14`4D4%B2M7Fl8jv`rM< zN)-c*IO$W=Rk%Sl)JMqmH_!dILhC^)Oik;hQYt+Z$`6sS%`b2$`jTNYqR_iTEPDc+ z2vxxP&lRN!-+V#K*T;f2@ua5!HCFU1vSIYRUGX%l7ty53pI(UOXjt{sw6xyUf*OO? zR_HlTkWHmig62_LtQtswUM=HTlYk+p1-Vjpclr)j^8vdrnFGa0fLqE8f!)C;tB|%t zhV8SOi@51KMsT)o!RoJ;au|ZGw7?n9nN4u3ZGF7#u5q*8aE}gZth-<ZYyOXo`~yxY zixl;7Q5$hlXcf|C(rVEBudoBsCL)?WF+QVr)B&>qb^Ei!9IIa%f^C0ot;ZP%y}%X^ z7VQ{4+=ZK)vMgN~b6bFb1?HwVy_wqiJYUD#m8P`n-^H30f@Z;DLya~sJu&CurZy}- zpl0y2-Hacan}vdy-i@VwoI`kvH7t0P$9kk_H$O|+TZY*|kOdEczrF+9xgRoNtF;HN zRV|gM7jEAK%~KLX4R$X)F@qx++Hm+EXg3dC+uBb}h3a9gtKm`;2D_W^SHn|CErkP} zVpPnb8t$#Tm^voBL)zPNm%4xX^sL^A#?KV%>u=9=Do<t5Q%(MwSAGzy>Pqw+K^Uec zO*eSG@I)I8ySHNPf=|1qbxa$iS+uBB6(5g68IID!@Ny)mswF`_*x<!^>Q$Ccu$~2D zBy$1JX|h_4NTAC*ufwi>b!69ajq3!;1<G^53*|~Q4oj_O*{G12m0{~a9#_HSWGv8$ zbYOIdzvHJ2UORy&J@#jL95_D5Q5o8KQYw#>iXa&se3{d2Ytzv@Lb;-9jclVw+DTZ3 zTWYX;L02&&Zjj5Hv_cC{I_EJbizQb~a}~TASPX)}SmKNjrVa79Ogn2QA)hckNfY8k z^|v7M^ZH~atJO06_qJy*Y03<dJs~p2o%GkyXrWs;mc>r?hjF&2IM+&6f|rsn9q#}t zAjwb&1n$8&(PWQw;xU!Eg^E_P5~4Iyvr<%BWSC5K0vCVzBeX$#tWV9lP@uCvdFfC= z#y_9`>_}$!7}HE~#7be#9F)_shLnag$y1uw6gwq}miSk6JfP~WR)#5qe%Rbb7H86j z!>epF#kgX|8KI+sL2&HGlA)&4{~+5JH1_s>A;l5OIkxIBQw=l3aI01_Ojvkbz8Xu; z6UgI!LOGIhbFAB~UT+Z2o%Y=R=ZZC<qx8kfd6M`P#MZj|%JYVSFZ0jQW~uE=-qdo9 z)udC8%3?)w+q9H=ZT3SIb-`um6GrcaGM}`7Fg2%TCs*z(B&J&%;!g(cb`N#Qg+mtd z;lya1D43wafzomp>3d_wTVd|srtDo(2>Gn7SKCi_@Fuv5P<szj=$E<F(?jQHvDSjZ zGe6_qj6JrLZq}`bK?1Cu_s$%SIX;4#(k`RarB5L6&fNpeY+~tAOr`ALrVXL3{8#EW zUsAcjT+22+Im7|kUOg>9oQFm}my6VA(%fi6HdSFK`43vBKX8Naq9ZGs-&*GjR->*L zRdKbVp6q*VfMGum)u6KvXO=Bie6g2S^C};<J~m+%JaGoE<C0DoGpv`SH2!qpTjT0g z9+*<0hi1Hh@5pK492ttmlB8VeqymWUyK#PB+%XP$`#GC}ebN>!dujo5m)M24a=Yh{ zE<_UOMAN_NRz+hdpN9D@-?S>l5P1Pn9R4V<6_Y-<Cv$+VdE*_41Na*N4uphfu@;S{ zzo<sto0M`do$@}1Hz~giIGHCkqe)c@>|m{y=+=!~dt;_+=z{N8<-Rkt`t_n0?}Z64 zdk(Pa^{pB3U%l~o+WT?C_+^K_5dZyqdK={8&O>xhn;U-QwaDfI5LZ3YBX+8c2b;g4 z34m@FJ;eRZe1Ouu?NFe~P|G~@YkFZub<?v9>*?}wr29v&$O{HdH}@kCC3!%P^|bSx zsMl@}@KAJ#Ree0YfcVHI6n()z0TjUvqH>vX3>q({%zDcTr6G559sAE8P`Ucvg(_W+ zaP6JvcU(`Sy$NIp)xk(f-(tQ=QORu#+Db_p9G%phTW3Z<+IpB)%Q)JK7e*gY7tGXB z=CWnSz4I+2=&umgczGvIFXvH;><IGaIwYJVqSX2=cqf^0Am0fk`ON|jP2=8eu0BCw zT&|Mtd?X#=?9BAgMV~Ri@m2%$(vU&~_wJO8x25y4%80hFA`!KXwyz2i5KUV(Ufm=X zmJl1Aeg>4hI^=$p>QEeC8x30F3%MvO9aV%FN<WXTb;mVk%*0lfQ0g-<=xvwxweyg| zpeye>!=Mv+^&_A=RkkfcptbN_0~hY?Q^Z_!e@6L!_tdnUTP>B0cpx^`KOiA8=HGcC zHazPWu!F9pwyP}_zSDm84g0!Y7TXztR9Cfy*t(c?P3&P$?{e0dT2``f-6BKpPHsEY z7j+fg_yHqO?>LpKvai&Zzb&^kVRJcBW!Q~3R&b=ais}|?)TMGd*j7OcBjhATF7jPo z47^>rOC2!P_jy7k!KISRuG=RDv!0|nc`!blyx!qu9V@IpF=)O54w`vk50m!$cq1?7 zj&YwgtABPJe5o#`mlWAH`!>ZV9MY<)9Mjs%#mlEU`#-T3e9ln9Y)eB2xA-ViaE~{5 zU(%41OWw++6yv@=Jln;~t}!I<j(%bqt&-6uZwrruuJNRJj$Pa3{E|N<rPn#E9}tCc z9!`V0;fY@Ouk2_?CyGY+4U6gP#0`tpZEBFsQH!`3GP*o6FVBkD4lfT4ArQ_t)hw=5 zTL!SN5dx)1&t%@K6FYj^%s6GWCcQ)VC#?L2a4+dK7dYpuNl=4k(sGJH-_lT=kRGK4 zqX2_3d3RgE`D>Wn12wx7b^B`O9`+8dn6}Kdy`N_9RMCrdrJ*;dg1vX%KI)!hXdida zb34yoaqgJ-$F6AznHjyZd7)-xMbnv4zo+{>`v^pxXQ?E<;z3zc4hP7bU(nm|Qr9Wi z_4@jK2?ESYi||gW-XFOWUvZHSEzHM_n=`!bXFMy%8$$d^at>P?^bjt&KDw*HrD%6_ z$MZ{J8w8qisXu}17dn&H;@2e0fY1%g?rtq*TL0iG#8vl$%QRS<{+WK<ZeUcWxM=s~ zvW=`?6O69SyQVHbls3_al613U`#;~h{(k~m@ads#aM87Ro0+Fi+5K#E`~H@a<jb%x z^xByhM5sMH9>VOZkYtF_{An1`9w`$Uk8hKITi!NU5uBG>>4hI@+#09Sf5xkQ><KI9 zv}*#ps_?&w?`!_$X6(nkCil-dIo@br*RK8@dpbRg0rUAF@|FygeomuXI9TfHJYXvf zs9gU9Qy~NdP{Hu$N2V%*l(+YDM^Y8GCKMFD@AfJ5awj>LpzTer)F?L>38q*=5o3l1 zx|tSyNaUM=u%|_{;{IFSd=%7^t;IioY;KDBi2%aDAkiYrCv13Oz@xA41<|$98r>=m zO_{slv_hz$DQsivEGs%bIa$dYUdM7$i%EG00!m@mBgrtezTJ;QZ!}e5SH^T$Q+zUO zTIV(6_OrR+RN=3vM%8WbXEiqZBU9D1ZycH#*e}nu4-Kze)Hv>7-q!mTm=XUIIaqE{ z6EZ=iWr$I3cU`eL)6HMy?xFRZp8<TyKAC9g{z)@*nqt0e+5-s{d9@SUtXut4k~2`1 z2NQ+roEa`3ofw8`x+WpW;OO4r)kPzDdEogSwg34o7Zm<)ajp95Ri^oCE&hY?tQ_j& zU}Uer#PWwRc^o58KvL-Ejbfwa9Zd>h6@W-;j*%xO=_uERl^E8I58Vt^-bb+~IXZ;8 ztQ8enwu$pqpO_~4Wy@iZul^(^@kx_keC;<tYCT&uni++!V7ntK&Yi5I6`b^K%hBNj zK@N`bT7D}<K8qf5p!0y6{gp4T9ioQO)rn%*;#t-cY^u#1B?<eLQ2W+EE$4<oifP*R zXN{^<F7h)97~lP0t<5dtyvf_>G(*p+=B&a?vrh62{-(p&%oq7$(16@+-_eQGX)AD& zE2%vaA$(d`jF99%6moUD!@+NThuU>e@{ln{Cs)|ou6DGuNSf*TJY1e1FR_xVnqX4= z?TH)x)zw!y{L-=Bqnx+P#iCW8vxRloiNE5w!Qi92{*jTG+z7b92fCuy3j%6OB|_Q9 z?u%G;g`LlWaJP?$6cK4}g~bB3ECI(o-#ZGa@Q5vS{F;%kME;Pz*`&}L*Pwm`4SKPO z`6IRYK1td<?8!Wp^aKL|;%=M2g1>FMye!QvL;GguRn(1K?RHr2hc?D%$kgw2W`|08 z(NMa4r?w=0A;%}7<>H$VA!|1GE^87@RS4{g-e7V`>3oh?*+@hb-eES2QWDs2v99@M zxx)i&7IyYh`G4-$eH>}!=;E5cRL-^tdoJZ&<?;X%r#*zT^~+#7pxZ$kvD!CDfdW6? zxq0_=xX1gfx1L9`yCf#?Q<siJb$O9aaUNMLa2Vq%(Smw%U20`#_T21HnP#073Aeu{ z&QC9rc~-Z$zlpz;=f;-l$7LTJmL(e&JQV3>h!o@|r19<CJ-^J!G*xeST!D$&QLzRM z7!fmq<Fq4d4!4*16qX$xJ{(fD*MpJ;xtua~je2(mrI&gS1tSemr!^y21Rc1;UnnPj z)0%NkPIzKj?eEt3G{@@8K$qfy-=j^aeD_lN-N-GR$w~JSlj59N3McX}e-#qPqr@dY zjdb3P5yV=m{g|n`Rr^2^cOJbEV|KqBo88oLZaQtat;$iO_u%sw4>=3*=8(ayn&hiH z*>+Al`a>Zhu1m}5co{M)8u5~CQYkIsby9kSJL-y*6zwXzwGoq*_PkqFoRCvdQ|bvX z8M_{qmdwMLLv8G*-Eh2m4bY=&A4h$%dGgSR0^u2Tw(!?Axy5H_DmWX0>vH~rCXjWt z$@~SLwCHMtB3D;GD%OZjDs;uJ^TwFT+C5>#lq}+FNrAF`jJ7HnzzOb^og%(W^s2t> z<5^<ud{_H{Mmnw5eAz1^VL2m_O2jxKsr*HoyqW#LmqIwhL3Vao(zB>Dx0tn5(NT&^ z+Tt`<sAW8ZOwO*E8%nf^OS>tfby<4Ktzb`^TwgNQ-}UT!Q?xD?Um|Flul;BAx32Ob z+mUmL2Vu%w7+iC6E21~Yo28)Z@Ow&n%f>*?vfIUK9FM=ERKt=d+<wQYxIm$nEDUaU z#f5DZ)BY%8-X!JNsId@}#QhLxcM5&N!!t94QcI?}%Wdy?<X^;Ew|7R~cs4NV{B`Ep z!Z~ceG&D`NFP9hX>?AB-kLKN`sWbeDfK{E|5n<h}@9W32>Iy(hyES8{T@^KAo7dy0 z|1*yzsHKJ&OSaj1!H0la(ueCZzI0&5i#%_@v0!Q>j4`t_mO&b=ECIJSwtf}egV1xu zy?Ug?903q5UH58XLFw6P@Ir3s`TX3bN>feP4btaU#i}3VB~>U(3bNp!IET#x;*%#k zHuVOYx#*q&B|lO-)VD7tI=h;Fw)LiL9G^@k?kg;gI&$+$Z68W?Z+S4R7{p#5X3du? zv|ldB#*Wlp>K?+8Wv3j{<PQjJYI7Prpct7d1Y<8woX(sW0KT?tp*BXI90cQimuevz zz*Xnn38>8MTT>yuEUFx?Xs`TXs=V}Q^SvKm=DJS*62&Xc!`6?P!F!x?>4uF2(cNKz zmYlaSi7&Ejo7>wCHa5PC|5NpBdw*I1mSJ`G7z(^&Ba|Ix#llD)$YbGH9)bAFsF?dR zp<8(X=^2~$&M)kE`-Rc)OARHy(PL45eZ}u1uqX@NSRpoO=UHYS(s;q<?(k|4o88mW zE?upOMRP|>cgjmXFqyZjtrV9tHA#gHQ@HJ?#SjCTcY_EOn9BQO5%sAK_Mqm^1aawJ ze)`2x+)E7&EWzz5pJ&||F~G6K$J5|)zScj2Xox%%LuU$EnS>+F6DlH{xJge6ck*y? z5(bg2uE-klCCgW$byr#i?Tp0bIuq?0o?g``ovHc*QG7Aq`W+13{%KiRs-+i&@ezbu zUEsd^Z!dm)vldT8jQojDyGb68$70C9<JIrCFA{t04jYH<!gu|JdGsiy9<HEASzbS` z{80*SY$J`CWurVvcu;eWeIhYoV`a~d7AFEu=~Q<yg<qM=1)@`v$vabHk#VYmqGw7u zS13$X51_<VcN6JzHBU5GzJuL=^HC;N_N^}9rnT;8TUE7G9R?TtI<*#RRnnsII`QY) z=E-z}aC4{t1n(+m%}r5FbOaXgd+~fqQ+A<`h+(i;eMasSipFcT^S08*yRXeWRKDt7 zP@f&hK#K70|LxdtpG2(cTmP%u&w1QhU?@5*#XmoNof+j>nw8*=)5vaTBHQtY%LpMl zbTg_kCoj5lQy<~D<(nIgigT-lp2Vws6vVsPI`r=pws$J+?3am!ffdqSnfwitcl4ki z;ej}vhjj#@_f2^dXj`3a&Lgwe{l!7R!hPk{!BiA)-ttl~2K$HWV)uZvpX5OwTj^i7 z75jjklkL7c`@|o_5h#e;25Ex+&-#}P)@gTdK*#gaVI3c(&qLhJSE><YR`6K`ZBrQF zjDjU$r^JXoCg#mXH)>S&$RqixxExr)O&begQ_EVPf4um}{_RW7X%IkG&_UD8+7}jU z)=_+Tw)6ubkC$m0<F00`cnXE}&Y+$6b6U6}me_fEIpi-{EUktwe;H*$qyFdI*QbNA zG8+%55iD%U1JKB~W52%;%5};6vKQEe{OnR?JUY*MKAlBhHs!#u;_Z%UYyM1tc$~Ag zpCFJ6Va!gW>_3j-b=v5)d0>STJJgWjyAhPJJR2WbTev}dp9oYZ(ic1Vq4!*e+ux~K zK*hnC=?myIy`OLQOGBI4)Lm+?57J4qaKqhAr9jvT)N+scJlsZd+aKOv;r^f(Zfj<r zZRUTX`59hh;;Tpg2h#<x#WJY4N+hJYLahOkmU5Ikp6^jqGZqK2Lw@NoOW4Ez`Iq2H z++a2!bD&^+?VQIO!I@;>Fo3{Zh{~4An((;qyc^a<)Hf^xxBU`ym6>h;%c4SKD<e#9 z6$3l;uR9bG68W)KL|o;CVa%4olkrBh>$hd>p<T64k=bj0(byA%YrsR%32@2Atl={5 zWlkHg-j{X_jotiGK>wt#ab%<cn7wn7#)eHVpAvEhLY^F@6A@Vovknh`i>NKXTsX7< zul|9|7Fp~yA>@2JOo2CET{2hfH<dgZJehCncp|*~A{+qyltN%F1zn$B{c5jVe@IGb zorjR$KnOo+mQTs~U4#05Fg-4eCM52^4(%obD3`>nrBNts4Fn=^{@9;suuWM$3GXuE z>~{LI4*U(5)x^jI9>%lG#sT(e_Q5g(_W91?09EDH`i8l)?A$)KuXx`H;(fa(8(?NQ zV>b1lZt9{sH~l4x7c>5H&35sP3h24S2@CL*fdVr?55s-~%I#KrLNBjeFZB2S@qUPl zG8JacUD4a;Fx%yC`1a>0)}49nB1!D{R|Ag7s?9IUpr@<<Za7@#CTkk=F_Kx{V;0xm zEz)%V4O3@ysb`5pxO+E$A=`0}{(&b+?-h6rIs@Dd-(Hod%NCS&s`$naL1e~8J`HJB zF8LxpKLj6CxcJs9rxkvQ5OxbHwo;RZTx2_914@{SwSe;8X1d;^&pFIpaJ!YQe@@l7 zLX*VU(lh11AS3GG+S64d(25z8IP=IaiOdn1ntXXi3>|-sRJsgaTrcT8&0;;bcQ01d z@cY9hVlE^^F;653GXtS@%d?jmu;UAj*R|$efWaG)P%dgbiv~~0;kDDVGzC-#2k>=} z{bvm<f`#837G{4qQ~p=ue9Plm4o@5?FXXv&u*(J4Y3kzsr%QlDiVoGLhgyPn5*f#j z2uf+t+u}aKyKzoKb#*<NTr6-b63ci%TeNXMhe&$9hJ)%|+)?koj3|ouUU~Nf3Pgg> zTl$a4uFK(*4ur78tv`1C79xLlxhKUug1>g`u2leR^#aj*s}7COoMb{d^0{q=eD^7X zz0Auzrtayv=cS&@0v|q>kCfn=Z|9ZqjzHt2s`cGS?qt4wcxeqvNuhT`V#+%-Q4go) z*tN3rSvkudfkb$0=sBtWK_%@)>NK-hCw<@nZ1khh4yX(v{|j${Nd13=Ih)sJW17s{ zSl?Q!_2lYi{Va~PkIuB@ZZdk!ihS!lDW$oAyZZe)?ES!c(mGklwp+y|23(<p-*t|# zvA*&gs(iI4ENNJ;y$YJOcWKi-VkII}3)0dNbFA96o_rynh+QkE8fDs=Wv3HZ9n~ci zsg^k&RjL?~OFo|aiX>C54UHXb+1o%`LSK8<9kxv*TL(Sz81+KKs?S}k$INXpZ0#!V zstUQ5`usals`y<%k7xw1_6EX{|98SDQ#<+>I)P9)}`NPWw!Lbg%<3dLFAs>Ofh^ zzW5e<iwN3A(uGUs)18UYqzY0no@UC{{Lw!sbemc89i_$4s-@m5_T%SQ0!cCrEEXnC zuM!0?y^_Hoe?!nr2PsTXVFwSowzQSrOx~Xh*;(C9LR|7Tb-~lTcCUP=LgMswKMKHn z=H>svs_Lk+9eJ(u4NBO3Af}5cVJG2SP1ic0#Fe9z5NZ>apTz%z-Sxkpp%~2QXm)yC zQ@ECOZ32gJj|B=<;<2I*r&>xXwx{Ta@p4z3u}wV2*3b7t|0x4m*#A2)Nw+r|R##Qh zeBYNJFnd-glOvSr1*FIlku@785AJPy^_<hBZo;!aG*b;ZxxjMKt5d{6O;lKz96)`& zmL*0$W*!%<c9RdlXK8IvPGOra<eIZ78VD;<*q1F2iT`&OTS`?6ELw7DVTGQYMIpSn zEQf}Tn|q6zMdKc7FHt0VAKA(q1A*TIYngCOX0W*U*z^_-kqZ8znWDQ%)F|GX_y7ze z5nU4x9La^p4J@j3RP%~^|Db_#REx;GcvuO!-6|ywwJSJ@mm%9BO-_>?a_<&6>A4b1 zmL>6%TIxS6!CR5ybMSL;NVTNJs_X=gOo~znr^C#iLL9jYOFI;A<O}`eZ~%{N%L^N9 zH^v58AbpW+2t!_p`X{Yks>ruUmO5KSh{_aeBI2P4DN?*Kqr}TPrAWGs1~v6^q=wbp zkCyBo0biNY{?WG??>k2xtE|RMEel+hKo;(q0F$e6R@Xp^o5!=lSGW-+BAy>Mx*3~l z^^edv<I*+rH@nX`i9*&$)eOtq$6WjXTwJ=J+t@a>@>|R-p*Q75#n*&IyK=2>nPCR6 zgiQ~we!)!DE%TyS5ZS{}d>=|uB77Uh)7S|5`sW{*CiQmprvqo!KJrC-odRue7w_(t z2})b!8NocZ&}>SS4NaLtfYq2PR;aQWWprc-%#f=5nDZWKlHhw97K`OS+Y;n{=w0%e zmbrc1B<CUh_k<j+Yck%Y?gAis)kHyRDSM`jz`l)uI=OI4O`)Mf=dM~1DGz5U1MprE zfYDNH*vkE9@aaGY!qnIh>Pq(v0p!eI>_hI={3aP^6v?c%b`Ig@2ry%4-VtOO?-@NJ zpOUwq1SjGbtB}o!HxOCc#iOjhKVB%E31aaQ(-X@_hg6tvnu7*z7pY}K_IbpdaSEu? zo7G22eRc~)GzVKYK=l3pA`aJGo=<DJfcF(R93&M#6rWdfdA&m|3u)_8hKDu-B7k~w zCbNw)4TJbRV8!|lUZfwwK^kOx#RhOwGl*eE*g}3}C~o2@?>{rfUr==~%?B6I7$3mW z6-GfHAI*kE=<MZ>M9)(pcLE~F42V4V7#2jd2fEy2pVJ{_jyFfXY{X?$wl31g)BmL_ z+=6jby7q%j7%fzyy$=2<4RNm)-)q4e9_Ct#4Q11-YJ&g8sVVwr|KrB?`xnbd+nulV zYMBwu>?hWCZ)0x$T2bK7R%u>A&u?Md51gn`s8@noV!T@D(m%qAoDu$#d0FV4fC4-N zixndS3S!%2UEX_3P&m=JNcr73tV!GwV~P<(Yf?zd6TZdC;1>DJ4QccAUT!1I1aN%r zL3VnsnrwFX(Yin_D?RWVvW+^wDoeu7nO4>o{ijs~jTIj7=?PYFVK=4~Uij`bmqaaV z$XkA_p4aw3R<RoOUYa#O7@m;<Am?42F{4@HV|&;;4Iy^*bBvp+`Z|X~2j$`ZVNTy$ zN&jc06B6ZnIPoO$G8^&S1CQucW(9ZSIfq3cfs%?26$P1nHYEkJi43z7{e!l?uQZ!; zxVje0J((U3Wwbaw!IzDEPuLctHOn96F~0$P>C;2+^c#{u4TBgEb%!~Sy{2r23Z@VS zpIb4(uy3}Ue=qo^TNC{1GO}Dt?E#qZ^k=(yiRE#F#!c21AnO=#9=PawA3E;k4R9l; zR!==}GzT3!()=N*M?MK@BY4nNJQHB<w)nRiH*I6lF}bkan#_{-dtlXFs&|z3<Tp-F z22}^I+B>S6vi@e3J}+tSwR-_UW4K~;ttF;-?C1_{52_0p*v>wg43q<Kgb3c9Najzd zGmfpkdr<B52igEqU~-zqy?NQ#DZ_Iz@g+X$^7Wypu*jXqvhu^oObB$_A`b;c)JQ~7 z?8m+V9XT4y<>Q5xSyzflZAY@RVvxOubMN4k%WYrZ)Fsy#xH2-uQerQm6bUZbyHPd7 z#NwoM&Bsw2af7Z?!QuaI*F%c(&Qi^8u9#Yrck9%qeDnaeWIQgBFiQm>N7Ez7)y`WT zB=!{Yfx}@i%_Is-ZB>4B4C3}NhPr;A1ycRJ<oKLGosa8~{y*oyPXny#bAt^Oub}xs z@ap@MI<s9JU-{j1qZ6?)>R2CV9o_cDvC#|V_v)8>gBu0svL>lVe1dcXGTCJ^*+hln zPP8K;qUhWqNpYi-5JK0(SsrEIX3a&MV<T&;B{wWF?aN`&%V?WiG<n_vFWRUzp?vN! z)1HweE|?KY>GWrcLpyyxxGCn1wI$-n@zpb}lua?bsphmH943wgGy7)K+}EyLZhxVH zZo_bRfO|teJV-JE!XmDz*^hLy2HwLFGg%jTNW>NT{dVj&tJ|U-r15Lt5U0knq$pp~ z*0BLNTWD4HBkDFFn)uoB0lz%I;HZ?eF`6JN%VN6CWp_yP!%+5>X<J7)jpCOnKzM`j z?!!zUh^B3BIV|PS7<Oi7E|IJE&&GuSJgS_E{pPZ41XrAf2L21JoC&02Vx9raaw*M8 zjwn#-<1}Hc#NCU`e*R)mm}7YvD|(n$WEwWn_sA><rB8JS8?%Xx*TEz;-e+CmE#Z4o z(XB<;ILQYqN#|6f$)dV&w7cD1e?mHezbEOEf<v385V&dRj!@5`=^S$NTO%fgV_I85 zF@YnPf@Xq25{$9S&C^-<WGMBlgp@3189XRqickK~NP?fHA!z5DU}|NDq-w2q?nZOr zjLm7r*AV$Jf)cM^@4KgAE}@$8^3tJlcvtD5XlPLWA!f=I+0^Sn3`_S$xO@m?W3tHi zZ;Q<gplgl_;v0kG5Tc9^l)DeMQIL@K<Y$2+b6FI|5gT2iW$c$LDn?IB=MKmzA8%4q z6^0A0hB9@*?T{F3CgV<EZaqg!r*DptxL;*jhRQBxJCZyAc+Cm|Aww6k>rvdwEWBWD zJyqrRKc^PMTBJ9r`I}!yD&pDnK@d9=VHNz*Pk2p34@17_$VX^)5&50NzJDf1uzilD zSNmPRDap6t+H@h67BFCxBfh)|D1^H8KdxiND(0DqU#GDq5o~VVOFG2t66Yjj*XCDL zlMBqKH@Wz^S}ouIh4_doC!jnyari4MxIAZ3OQZSea)5IzBc=(7h%3<-GgQwu?mtqG zq8E!@M;X5P4X{JVD$>J<WpP=`5Vls#74$!?>;vc8VgKg<-H<Ae1QFkf)pV^CzDKzo zJ%_$*XC<*@6!MGjm2$>LrJ?=;epv<61Ua2_tv^vd2SX;94@irrG_~h}SJJ>hN-7XT zREl83hok%qQ$kA{05FqDlo>%~q6xA2dcLE!2~&Qut0nEDy~^|i2bIF5T=}`2z~)E8 z^LL`9Fz5eBQ3wOHv2`n{!_0x8x!)H`xHvc!%z*hjRn%kmmcyKMD}$bxlQRb5=vGqr z1DHhqC-wz1aebdF;eNMmzILjt<$?r?0`?I9tHB=R1SXz#xgR~>x>nNpYMk$b)%;)L zWKSV}hjpc-`{DCnf^_wtvP2<vG?H$mMZdzfPTKXRsQKi-hP}X($oicskmTr-3B4{A zwLbjGMF7OW|2pD_I5|`NSLsoRLfmWNzex4}W0*qh`9euKPE1>0v%`N9USMOaf&XdA zY}@glE-uh1SUv4>5;?rYK-!xCTzgXVwO*^2&ZUKB*))iUXxVk<leK`+vEa&Rkbs@v zE2m2OyfA!zeEuB1py6>`o;Ah4v%)5a#7g%)6Wuv2tOhy?I$Vph-QadJz1?5%Dd&J* zAGeLmX690s`gBnKx=*`WtKqw9-L>(haejThgZj{?<pbQ%I-kNvcKNaH+q|H*9VC*7 zO=QGpMV*14i-^W9g!z`&SadtPyqse~$ReK_Dmqf5!Awr4xikj}^J{DtK1sAr^Pr6j z;V}S%>(Gr4+onCiem#@*@MNmsiHnmiuZ51zOIN3Q%1cv5XCG$c@jPY|#oV?M7@__& zWW<lvzQtw)>7!bY5|S58MAWy1PD@<;Ir4-co6ia2?S2aj7oELb0tb)V-PmRuMzc=? zl0ChbjEc(4A;I59L1TWN$lvpLzmSvK<n}1!DCbCRc(j1=1@OPvUVHZcoF@O{dVR!! z{2#ErY;10NtnEq0Qpmn{0sx>5Kn-|xv<yv+c6!|bv@g-(8e7EeCyW?@iUvt5v~o?7 znKYA&2(Nv2&bg>>+NP?eFKO;@)8$>%%tzaEsN`}Y-*Zv?e7n87_I-ZN4*=cox1Cqh zw>|&grnIrOv#gubpPirAgU=<5zHj!AlfIvC^RBBi#I2o?o0r?q-_NqKwVdzPpO><| z@1r&Mr~~$>gS9(#^}dVGl{$R2z6*@LjF(4y`v*jik2C(RZ!_n&`_7K9<_o}sLs!NQ zz@hKsH42=s@$16U`ymf=?*)@zZ=0{Tw`=eBM*S4A@3YRoM1U+|$iWp|>b=Vl8Q{w| z?63c<`|N`c;JG<ddC<Ev2K?$`Dx(8juhn09)mvwL?Q=fA+@mCZANJH1>>u`w2#bj# z^Ky>u%bY&-@1)ncw?D@wZ@M%sXj|GQ<$c#i$WQ<+uQhXDcbEW7=+hZ}=|5(8X6c?3 zp?8S^7ywq&{Vqe?9vsPLnvQ4G*Sm+Muy5LkeQ0h_sBY~al#Qn@zIW$)amj|)h(-K| zt-532CxApIAO5%TJu>p(PIVe`5WkyH+Q*rklf=Q?E3(z?RN`T1=wa%6xs-BfEbU`g z?}zobaiI!w3gDK--x^EG>R*g_%}w@KUj>8lMy~hs=Gzq?(d*Mw-j3bg9<NQzC7oXu z@XXoH>B|Rp{S&=>U6bEapFR5>yF6gMo2MH9Zu69enN|mIdC21jYyjWcwjy?&<@x<r zKzIKHUgqWV_xIscO9pq>+1LN=;J}EqulE`+ukG8M2dZ!Ij%k<7>-_PT@i+9xbsuPN zuf^|&@_hk@fdI((CI9aC;Zsda9YrFFZ`m<?r>u;c=jF5eheRGa#H0BtZR%v2Z~ow) zeBB!+VjW=K{Fs!dSwokWSdE_ULE2m##GaA+U6I18r{}AHYn2A;>R==evhZ`oCIOMX zX-H7x!C`Q1XQr$yYV9kh=<hOg!tu?{(}=FSBedFW-Jb2;!_X6TV#CMO*VR{A4OYhY zl|3E8#~z^D!)tf9*Wi09NH$6cl743e6LAaieR%4MTM3Z~_vA6mlRT;XO55t~aIptO z&~?ZupdP|XJU1qH+5N?u1;o4($G{LArV5@0e2^*dqj@A)0ZbSgmn0(z9CVYEUn2v` zzCg@aE_5L~zQmYQv8sdRb+CONIzfJKPtkEtvthB9j>P#vUm&;F<$;|_cl-Lq?(O|| z!V8kG$(v;%CN5xyG}nuMx17%35&E~zFZ<^y<wJiC;Kkn%H&KOQL4@>koE@@oscH6} z?UcxZHM{=)>0shh)6MSa<LkMLN}@lAq#ar4U0Cf7%NUe26w*+lv}^$ry-Emt2k|j( z^;qs>aU;WrvGM0n9uR`P@#?RmyKy#bwI_`RGYuK{+bNx^x(0_AxO2H@5TlR;&&Dz) z{c&khEwLD(F)&Z6M)Fo%O>p<$dKnoquJ?jCLAsg=Try9vGjUDVE@eDBmhvC)+;o&& z^!@e7sd8>)Ot#dd_czi9v!2w8VIuy!HCbPhQFkX8QK1Bz(plLWdo-K<L*3e(zsL7| zR6i32z$Atm)(vT|PP$S%0t;LnEKjf<l@WzmC$bkCt^4QeiH^kZL_%XKZOFsA8P#Og zVA?f5$1Pm93&|T4+5=8I2@VRSd&`T%V30@F<$LI8#}@dn|I1e${;iw4!~?+m3j^@> z2s`~kN4IBJJDJYm%?G#QK@HWM%>tpYTx|N}X>yWcVCYHy>SaOwKIxv_@041xM?_JI zVol@Q*YolI_<4bOyP~hh!^6kZO+*$+X`@nwvZ=7RyKB!6Ji~tj1d6}Q+sg;k(1Dpy zd~;8rx(mJ$bpTQj18BhL+yLS@rT80{V)=Wpbb4}f<Mx(9__9}bm$MD6&JhUY_y-kV zJ&_dezu%d#(vPZ+<1S_a<sLLM9w|wX!cQ_0sTM9o3%(TQ5oMGM;re4JG3vsFXHv}) zry_;A4w#bCP|^`%Xxyn5Iky~F8j0uq<Oce841_=LFMSd6OOq&Hm*&#&^$*%@01uyE z4R7;vb#)v`heD1#SiKo2Wrwk;JgS8ep1%+&NM4@y&5f{T8^7W}Tl3Bbosww1Jlh`+ zBg;=eJV$FgmsY*EYgg38f74OLTzc#9+}p24K_Mc<reD^6RQs}N&3=qbAzfmtK=E$f z9s-^_;)h1+HE2R#QnKVZ%a(u<-7`D{KBXB9{9AHq>r#i5VsMFE5r%-7iI<DZB@0jt zD5-z>*Bj)EZ*vltSn%e0NPRdQBKvp@4_vnX;1}Oy`NPoqK6QVQjr*jqF17c&M5HNv zig_@SmTM96c+SkAkn8|b4?ln0-p<Cvec%cEl_vYCTfc7Y+?{_KyUP9WJ{gM*8mTID z_289yi)F}s%**hqnIJ@i4Q#!<0cShPB4HZoMMd5DG~q%c8l^&oycG_u#VSw?)x%%h z4-CMxWEY6))V|^<38Z0&4!Lx@@)gjf<i-$K7-xnl7uglknI<F?#`undSOF6@8qZp+ zXf!yAZO^J;r14Ih-!ETXJFoI_?(|zTTRS&dH;5i_8B!An@ifQzA5uTKntWNfMxh0V zbNtd7P|>mBmm%eu1yv8MLaryGNQw=yQBy6Gk}eSpo0hbUWgl@{S7DU|og}ToD2GHB zU<mRl{M9}odL^%-nkuUeDyF)`m1{hxD$BhQjR^*9pcbNdDBCA>LWNxR3^fBypX?mM zX(E7H<X`I}e4#(mYpIRWYO8Y2bnL|EaB?G^sw*>8uPy-v@Ruy;d0Rf!f46v?xo7W& zCd$ic*;!rBX2e<9p~X`On1J22peEZ<*{vQzJraV^7>kw@46HcaKP^vckO|7_dl0C~ zy}_9x-eCIs;t8wsR!a09CWE>M+v~8^$q!tq>KIxOX`<FRDa1EGyNyb%Q8RYRFPKV` zofY%K_Ny`02v^VCjQM4!CLl1Xj0h+YwZp$@?nqPS3b`-KIBB%1E`@UXX>72{G))X~ zR<Ge&-7REf%lVxH8w|Ij$#(e?23~t+x0zEm86@t?%UR<Zs>eeaTf_3!sx6-ygb5MR zXKfr}l$PC1&w0Qaw=*<UkTo{qs$^LSu9F4pZIllRl@Om0gADehs!=t*rojYjP+rQ8 z>>%O2K>L|nDrFNI8ns{_B1SI83nQgk@@ltGxpb_MdXVxoI^?RMC3<Ztdq$086+mH8 zEv84y@<);SWrA(-^AdwM^SBE#J(C+spi!;tQLIK%+3?L1(I!_(fJmMxG8{~t>v|Jz zkFQ*V2J2A5sg2KoVRUslB~X{B|EBol2F+<{7{N3#an#tTF|9bdu|_=zm!y&`H9Fan zP~nTlg`~hfsi;A9Hk!g)axV(at7<@b{atpxcdYu(U!8zH((YGk3Ps^1vU+EFA2#h6 zqWi7AM2Kv0EoN$;(hocgY@@Q0(KGJ3xJqkV%geoO19-K4y<MGIoJbf1Vs~RO!_2u4 zl&4RQ%|#U;tB;fDvtmV?6(e3uB&!38LTvT@Oj^Q1whz}I91anQ!-94u$~PROAjnoj z4!%J$q=XqV5!74ctE(t+P{vx()3D(fM41(j4^*47<L5zfa19%(nfA8TyOK7+W_Cn{ zYlb?4>E#F~M>jX`+PD)RN@@c&{Ee{^pD#p|9N}q+2O}my1Z7l|bi9<5NVpp|Y`)wp zGi*6=SgL#)G&GXH^bNz?f?@2_VAaB@NUpezA{V%|468ayx=p-*fM5o5+27hExwHxi z$b%MbbasADPN;)(_I9@O&%ZteN<`(Xdc<<dx|DR>mf55G@}A*=p;5Tta4A9sFIl@) z{u=|DdV-&S+AhY4$o!VomG+mU>ZZ*-uT`J_x)ndSZo#ng!@>9MeyBw|aFqqKxGSjA z)$|Kw-~?Zw{`faPa=mL}J}qnJZnsB(1KsAJ@_y2|qPW_lVy2A<5m#nse>#b9gqZ-| zucc!C_4MXHTkkdRs++v2*bUk9j$_b`Z3z)M?my6=aBj;sr#r}JDOFw{53g<Bp5EOh zij$*WO;Aqloh`LJgCS5Bgr}N{VVKeu)KTA$)Y9bjl?(*zsR1f8H%TCa1rY<7uL{A} z@asB-O`!CWOOzBSb(CV|Kg32DYf0(DjxrSxuFlEkk`C^YJ=K#xrEHM(hI)xym_c+p z_0bkjiT)Dm)6>EbJ_Y0c8-#U}U6^STBG}V^fX9Bueh6*Ae#UCqYcvz7#jVbZzJ>7y z(c4&Kt`Xw^7G1&(DrL7wZ67zTklbi1Yhh51$=vH}&hF<uKgzrb>;xp`6Eg@4E28-{ zZiJZ`9boU%x%tE6=R)%xd*{W2=FxPqJm5t|h&jVyQ2am)rMLuOm3|sbu?S+QvKV1- z*^`KB)*$^OA$hOA-{$1(ebT-vtR|uJ<uhJ7@PAW~!FTBa@xn0~bUY0PDOsQojZuOQ z`~t!F{BBwDTOrgQ`{reCVW;pH=5%Zs8#;`Bh4bj?PDt3sbT}9N(SmM>a8XYaisxRm zulR$TW<90V1)wVA9jJqA#jX>V>ZO7TND_iq*vtE`c=p&De=HQF2L55u4anlAtDlM( z6g)<y<3kWEP*L4bnY~Oe;@PPU!R8a}=a-8ggy^S?p^ETW18*#;=3A~-=3~(b3ib=+ z2O?Tn>x@$mzZRezo_lgy)AFi|_=cl2oAJUL>Q)9*Afct?Z*#DcBp9qlf|XSbcm#^& zXfomj1U6!~z6rM>L7Q8J3lEacx^vXgmzz_d3TuQpRA7>T$)LUDUu*EfMerli`t#`` zj^e_>axw%41qKF$4C96x9;}*ygkhnS;c3b7h6syfQh2dSK&?|)3GoPFIdw{Gds%e6 zTy!$<6*$;K<!ogsAFuwS6L@zbq|5poj(>ldf4qWbL1tETv5BvjN1cpa5<XmeO4ZM+ zg*-y74D(#5`EPSV`H+kSA1gxda;%K<Jl?yH*Z)bH6kTlNk?Iv+pbf__jdDF+yH7UA zuL{-M8R@-PLJ`UllkY7lArdF}A5J}|vdH86EHh|78AlN$=wa|=I5Nojc<ev!FPPL_ z80kOhLJ^=4O?q`Bi%gj0c`(Tta#)G2|F|hWYewV7>m_rh*E8vp>~>msUR^M)MIfJ9 zV5oKF#}$AM#!UC6qzsoJrA+!Hcu<tVw_Kcqx$RyAC--xd@jfodoQJ}aKM#vWJX#g! z(YZ9Gt34~g<-qEiEv`*1if9Q4bHE$Z)hhCZ%%e9jE*uNRWwW4m9t=YBzAh9)9I^3S z=%HrNVydS-u)1~56jRRJF<a6rh{fG%V?Pn!%X^j$^!424>bcYVHpjYoK7|KK<K6Xn z`t17pei5@5u0sw%fMNXEmu<z&x6z#_<eSPGkWM))XN7NJhyGWsrm^wfvgPt6jx}bL zqE6sKDm;xIHKJt7OqB+%B1xnp<n|y_5kHQs*kBILIgHq%m6E8WE0oGAl6VM`oVX}} zWJey^9VM_@;~m2W0!4Luvdbv#(qy<nnVJ-g|M>miB%9ZznI(A^tThnw6ljUrA6&)= z)<VPiUl3@_uTZw*SM^ReCraq8&I%u#u7~{EOexKh)MxEKrH^=2Q0SoD?Zb-_3d0u= zhLfs=g{JOlZmVzs)Yxd10!1d|>B{RzkL75q)$?R}^l}@D=@R_wJ|AK5Y?ytMin%f| zlk*MIL#7dUM3?mkUsYpaX*(}NcK9K)!YtFyPmq{=cy~Lop03_wbP`IxM~oKIIv>sA z)%(YJ*FNZUEMgE+(~8b6KNdsCRP=$PQaa$WtsIrNrSLA;<0?TOU}{&>${5pw(SND) zUb&QhXjyzaKUqgpRGJc$W2smM`-M-}Cwj(!iWRh3{>?yMM!_Z)AkPn|=6(jed(a*y zzqo}9K|30UOe&QrTXb%wQ7o_MzJ%<LG_MqGEckZ{=~h8vd>ZR-eT%CWG|FL7C0oaT zp}{!QQ$O>o=qGZ3h8$)|P!$OM)oeTr52I*ykc(m&^bQI94L@5A{xa#AM#s{qx_Av< z$2%Y+szslXBbPh!V1(gWi6Mh_v;nWfjyY&IW0tpK2B8+pI#403&!|xEPb{Am$pHhN z=FgrX(Ve6l`*V7}c@m#Nl{{tLV&T>)gszBz{#jc&e`vJB7b0~|5%$krg>vl>B<1o` zyL|CKjtT)B(%vvt3M+4&(s1zn5(?sp)rUk%>*2-)6+Cx)V*hVN?IOvz<Ar^l)B(C_ zil0)76a$Rvq>)JZB8C|!uPSO236&_#BbDqvH0J&6nY9+qkyY+Uc`jN`>3S_SYppze zR~h?O))~JZ;Qje?X6T4q7D7k4pdv(CwV$BC(+Rh3bn2o|^|@cQCmItDcR5?-mr43R zcGO9vGv{<?D3}QxlVx3lQ)eFoK;Oxd-aJGDZ20PVq3Yx+Oo!HJIzub5oUz#lVA28y zgV)}l_JqRvioT+BJXt~d51VD^sY3K@Q0Ht)^B@5$Ld#B{-}iHZL?atfcV6`H)~9^5 z|Dsc&dRVkK```Euv+i)U2KY28=2@m*%<t0AV0E5E2yGF*FeIHFPL|3WcG0-oCEU|+ z!x`-upDwW3iL!z4tibWQDL98(HVBIOsn_lYTE4Pf?cK?<_^giHAUjLE40Oa_;!@uZ z!z{SGY641?XzRXpr-~W=(Cbx^V}~7VstRcD;oW?Ru&MBlfI_4MN)BK#q!eW*6jH3G z2sjl!(=n6}6+gufpQP-Rao33pn=yqy6J=Rht|F8xXCRS6@eTRx`hVVNYsX0+!mg57 zG02n}G!<wd2&3`A3S>rdF{?I3QT*HGG>!ACXF4<CyE81K{<SRF6;NhWrDY%p2=ogU z2F-AfjxGC_oG^fS>C{&<GA3Z45jp;0J|m12QKf}qmqV0<GP+ZZ38{ECP{SS~g$w(C zWPM|JWKGv~CeFm1*tTukwr$(Ct%+^hnb@{HvGw)b&-?HDS$$o7dY^S_t+l&O)!sb< z{6g^0)^KAF@k3BG2FvN`;_#6Xt7wTA1a~JLxP388K~1K?B}3a`n9xdR0*#DmA56IX zfbX<UwwB|jMkqPybdC%Od&-+PQ4>N(<K4)wfV4SyhU=`eJ!c7RPGz#F7S);J)I9Bh zbUh4Lt3qHcPo3L4JOBP{H6DKHou-9RjaeAJFduHa1bu(v8x;IawhPpXTY_G$FzZ;^ zdq<lH5et!B`8)wS&k6U7VlC595MzRN2pDVW@%VXFKa%Z~<xO55NFtI~aW$5=dZIIh z7d{86RbTf=<ZyPJ4gpay=qBn<QRUKcZ7M@o+v~#9XwKd=-gfqFDoV};mokVz03#$F zR!~r@qzbAloWbI0hPgmcsN+y!AOUQlK5al41DCa3A;)Q?*|7W=)XJC@V#9|a^b@ha z85%7$SOcmMg_eQm6YMV@s|Oi;%PGHKwlqWwtyH+iq9jpCzaOr)cW#{XCqMNgL>d(Z zShRkU?k=OFwNJr7U$PHMuHZ58il2$2wwOL4)0-%ts?sr{HZ0`}Rz?k2{+RtOO;;cV z{Ig3fdG!niuwFf98iO`wUn25x+Kg@l#f;_OifKT`)tM1!w!gl)*v%usdAU}G$R1Em zKF-Kh%x`W;*?Q_+yO1fZtWRmUYNNEai6SEcK7ZqNoLs&@ZNkok`f(~lB9Q<_)38>s zFItW}lZ_vPYo(wyw4ttgmAHn<OmS+JM_Sxih|uXmzf?jT#gth)XUgF{xYEsf@TI0C z4T*GfT;g!4<0-Fk|1f*j)qvJVvCC;FK8+UN$x1wVwM1%NRw9!#&jOE}?r&2#<%ka9 zBAX@gOM#VSlFV~%&bZ<!O=5=BYrFfvnvlImYOFb4oQ&nE-gn4}&lmf477rJX@9XGn z!)mjs^VNR${#um#+w|VT$?e_98ALXwzP0w+b!LUF)As@E>0+<k?4YOT8aDXi+b<7w z6!xxn=WkE9?<@Hz<sNm1kLXF}vI>|fJpWBh*%>eQ#Z(u5%;}rhq)HU%(Dse%0$3&e zaj0(B8><G~jn7zf4%8i7kIC`yTV6bW2JJ+-$xAH>4Lb*X!`Wv1PmLp|o=H72ncO+o zdsYizh1=kacC(_h8I$>Wr@LV0ADY6rn)`;I#3`BF$gTrc7-ZehLcAqB*9QGHnn6Gj zKan*?2ip=)P{kbrX&AB>*^8<J<ib;bJR#C#P?B+Sc**q?Glz*}_((~kMuKrB7($rw z3=2;2Mv@?kp+Fopykzsn+sJOiUR=Jb!ciH6<WjD|byBPawiSRR>uXkJ>CePzLqg-D z;9ebmm571oxD!}sYe4-FxgGe6%b*ze?g~+!7PL2;@?f`>QV)qSlR}P9Kvgot1&1yt z$-eDk6Ad+T5IQ>cqP2?tdoZ(a@8y8I=-`|%tV)BYPum0d;=JC0I=Ahw$rvbdk3L6P z#2uT6)D*C_=G%amo-L>Cyz=q{G#W(h2%D7U5d;3#9XuwUgy~QRIcnf3PRVEnkKOmt z<DRM8^UG|u$>45cLFVBZaON)!#fr#-q#xedEn}GXf%JM>=I2PiDJwMss3vyx_g(~{ z!ds>wSWU^>f7FpD@6*4Y;_D!rRE$9ftCUcTP~23ewCwqwE8<wIN5oVOx)krX8o}!d zAIn?{>o0h<%dA^w!ySTFnKrly=lqGX$6%Uj^~KUVdPP$k?4%NPNuTXt(HPuq&?NkV z1&^JQ#0IzX1(E4!x1kB%ix~{uXma6|GA$ZxfBJF5)?qO7Z5PAHW&{)`Y@qQfO<ZC* zz>9Kg_h~wp_S+8!gy7GcV_rH_c;RDvu=XQFbR=10WoGZEp{`5H@^svID<+_K+1f2- zAAVRF4?t^|*hg6_iu=zSXiU4-w)MW7UL6X_(rOaMX)tdgl#8*Z+~G`~d=M)q$Abi5 z9>9E-_RLA-BWoKhtOFc}D+|P9{e+}b6JuOQ4&8Q`KV-KZb5m2ijoH09yXFh;&7c=Q zpzN>@EvDwxU!@)i$dy1r&kP|Af_0P&DVQr2kz>fGii!EfoRfI5VDj9sD2BRtGtkj5 zsZ%Yp`^0`Q9pBn#Ub^Bx=P2c{D|%`qqnvQNBV@F-OUMYgv{Q;pWc_W^saCDx(Tr#8 zzT37+J!28?v49ZgXk&zm-+xT#4aNiRt#gnm?si{p_kfzaRP%CoSlFu*-l3U63@7VN zA2E(8mhS4J)EOZS3^%lHb!MVx@vwTM@8Xs7A`A{xRVkXSi0zFyU?0h65<Fs5Kc{P` ziq6w6I(i`Wfn@Ua5a(Ouo^ztShfn(^$#e6X99bgXw4^4Z0<(CnrBL!Tlxi75)%j&; zAQ*_0`Fto%9MLZm>~C$0hX+^{#Xu$NyYA`rdetXmoTVc3Y)3qba!Pls);6t`na0n& zOCI*mq*Iazw^$w!|A(FVA7Z9EA`0@pO3q(0#``UU-5qv$HFhmoqctpCmpYH5SmL4e zEaJ<-FoC!H2J%xb``Tuy{xXP+`nGj{J}dm7aK{*Roro@!Q_o4wV5PRS)ofU{uGTjj zIqPNG?Um&1T9L99o@$-psRD`ZXsCyBGBs>!DnmmOEVP98^F~|7sfKje&F<2!%BUPB zY+?W}b0<jVQf-#B=%>AFXb*q~EGcv|m^{aS7ivkxR2XVOp&)IH9}8T?H@DYrENha< zHZDi|5z;X^RCejo{8DObW0B&QyT9Bmx2CERQ|^B7(UF6C+Lah$@k<vkxEbYXzo}1w zHG`r?SQtO<_maNw8E!JxkI~Hgfs8(3cs#~L==+$O0^}dzW}&2>ZY7GSKYP<H7BA;A zA=%)54|x(nQ<;k>(!aHyg3C0?p%0uVE%tbx+ST2BZX*YKFtFNG8}VEsB*k&e{AT<# zb_E@KeR+{zSWz0OO&QMf<f7GF8`Sbg&Pp$)iu`FwPeP_A``5xj6N$UZIgZMEht2A* z5!H9g6j9Q|(0V%4{LLPO;%*-jbAK@)6zE#U{us&Hw2+*S>=~oTDpbuQwP5$-E|Zs~ zHg;3Bo}VI)IBoj&!<VMwhOZkken%DF$kZkWR_Nn&Chu7clj|HtVAD)ZteRQWgX80& ziW#DE-l_g1Op=n6B0FQ$fEL0%>w>UCiLvNzZ&YbeB^9--a?E^;&ViHaKMgd%TI0L- z33)X1UEO?^3gm8IKza5_+d?A}<qj(dAnwx!?49|a6ozT9B;o2qfon~|l=h16*aLdA zSbv>?L0?ll`8BrE<hX}uY@PvQ+;ncGO!Kb3r?RG3dzBY+`}m3BeZ+p6r`@{Iemzw} zf5>}%MwOn}&@T?}DEA=E7N+K{zdMk{Tf4w&1$0nJKL}<>45XiPHjkhEopabqJ6gal zlFVpoPyMy~fqUMb)mc|@9LII+BEN;|-#qs{##S|@b!I|Y3nwKXkkw8#QK6e79ljc2 z0#~!1L9G2WoT#?3w|G93{>)kCQ@oom?ix^UaQthXF#gQBwW6MniWGGXEfRY2w81;~ z!+m3cMZ$XpkFs~>DO8D;dx3w(v@DwCa3h@MjOq_A=1k_YUocB6;fnrM5!Ydt-#(*w zej)Idkaz8X$*c6++$OA3Ek_?w&R)tINH))HMMrwK>fn%a0uePZD&goc93kzD7#eNp zc~^iAN1>q@-8+-90)gx@E1LCRbbfbFU+a{qv^xaClUoRaq3@V>bk0SD2JWG$hA0fw z1-0qjxObUxF}dg#;e}IRzI!pbOQxYEg05mWQc5fC6~bi@arF4QL3BmlL_=n~LF_%; z1snsoJ>%Lm2?Pzi0j)B&0~5<P?ps1LIu7j;Z_Q!%ry&g(FIz#aWgJT^(r{-r2zvBW zTGLvUlU&O1;Ky`Dgz~)K_$h;R<}Jo{QQEE_?mOW4pD=_rpa~G*3B~!f>Yada@f(Kd z1rQP*ZxO=(R0D&9;5nDt=hHDU$$J*NV=qwACcJ3ERo~2-8)=^>%lBNEws_gxB4BIp z*^pTAV%P~eHcm-W>aQskW(-Q;Eib6bt5C(yE)d5%L+DIl*_(08OyzBXVeEkf`l6Gm zl^RqVluO~uZ(G8z3X*JqCkpu+r*x}o*jMoHS6rhS%kQA~IvS|V{fWHbECh~72F46H z42>NdzWFaw{)Rw<(14+D6%e3?YAE7+K>45al?Sd4<F0X#yj5vu<b|UObQ{t4^>LEs zluGGT5DERLu+4q!Rl^}IhA-GY{okby5gf~_1PYGyGR5v@SE{a<n+);Tpd=uFrSTQ+ z^?niU`YWT=li6^S)wKdEMT#%m^exqo7vAxK%Brqe*<_@X$5XRFE|#J{4iiv#hJ_o` zIM{7AiSp|b#cwjkSCP;Uds_7*LnJoWPRyOg4+#kqN=cK(V+Y5B_+Xe&bqD@2^c*HB za9XErr_SVI=8Uh>nbz$LRGwP`*1C)n9!0bpehHIOHj<+X&6=Bp4Qz-mZN5!)B;&k_ z8&1R&KNKp9%U{=?--<U5h>eOJwX##^;E#~gxTd(EBd@}ZAV-EH`MHdCUGkIEtD-V1 zY=lKgkqLef%5oy#U7H&bXd|2qUaRn^3uf7u2A(2+91L+i@0;qg*zIxoOTDUUXRg9{ z)MR3Ezpf8~Lw7V~<g$J)H;ku#`TmBYGORn)gIF^bgL<I$$0^_B-j)gjP>iYl4J1q+ zW<Q{KCUqBcZt3={4r-yHBblRGkBTjKkanP{24tQk(`jYxX97BtX<hq;TfuC@Dzc{O zO}OS~vsB!|MH{M{wz&q|@1LPdvjZjDt3R-Qi<GI{r?yTBQk6vtNhyY2?Zy36do!AA z^vqSI;(Cf4AqJ`CSFb;*zozrDZZdG4$E=d*zAxoV5t7nR7u!Ec?<d5^qTh-Tg!T%G zHM5V`2r#jSCnpMmp&131J@C*>xEjx*T5!pU^}>?_WTe@*<*wGZB5P|2bxg-M*q!)| zs_-eMK5)UZd7i&q({hoP9q^9IP8pN7kHPH|0$6%(Cfn6R-gT*k(KTd$Qc^W=5M(1v zX-BxaQdgCLOjFMdBjJLgapAY3k96TE`kfw*(;fIb7U~uzu7MqU5Ld)vOqQ1Ad-qMU zMAB~}xN!#sO+HcwdCg`}EltOU<c)kcDQ`GHXo<eXQ@=TPSpn|RIWZl&q6PbJfLV_q zD;JU<DfUlpuKOYL-}6;s>0ueYm?Rfzf9Iz(aont8qUakiN)ZhJrb)jkgIa076BPnU z<kd6)nY3tYR^!UWg{EBzVtLhaFjAUs-cNrDAB7#y72hx_nq@{7FrQw!L#{kRAK-xt zRbvExPeFyAU8sx5qz)roh><;UxWNdS(kw`hfda$Cg%*POy?|*uio=~@JHM14n`PQC z3b#9Jgx=d;TsE+s=3pi^FdHnC(V5FNP{w?Lcx*b7+vgZ2$>t=mf-=<hZlWEW5V|57 z3_x@MrG|L(*^px3g_5><_B$n($Zg?_+QOB3L=}SBAR$Yfu`{U85Q17yfqk8uYYo{5 zd)BUF)hu@~0fEc34s!mOoLdC3#M@!d9Q>rDTeIMP7Tn_8uV7<O9i`%n3@>rt)`LvA zLwXUFRltA!78@K{XDwnj{C79qU$}oU4$jPScKQ{Yk8I~j24ie4u3Cx|?6*M@eQL)* zIz<J<l-w(B^!$QG6m^XQMHg*B4rwgvPjL@3VrUViRN|!6+gjb*p7`^_qsIy@{2z>2 zOwz##E*}Yihdl(~3vJ)D!fiALHF&`s%yhB0DMs-46XPF9C+eRpUuKeB-0>_6GA-W9 zwp)DuLU9I%s-<XQJ;|)tP(sLXd_qxIj&d=-Cd3+D3MVg~Dbo=Kalj4)qpRSV1!2UN z(UsaD9IvxN@R^>MbTA9PE8pN8dk50@)YGeX7*?am+D*~cNpN=CL=gly08|Ot_t!iL za(p`%hvq>t5rau}!<kg*jt!J<pYmf4a^l#Y2F383GQucrH@vo|Mqr^ekL>OeWn7Ty zh*h?I#GA>_Mm5FQ3|jDJu<<2EkU>wDxNJX>@G_k2b7}h-nh-0&Vu7shu5wfc#PsK< z6;GeOdJOF*76MiKrzSy@xSNc>ULdUZLwbAV-E`dW${UW9qk~1upl#yny`!}&WY>sB z$u|8)6oL<c#RC`N{dcy(9-1Sxt>1XN9=N^K&p^zK<Q7K0)W9scr7jXY-Ha`qr=(h9 zl-EG){z7>;MO>{ZINlh5&_HF_Kd@!my;c&ym&d5)OwI<XBWStP9krbkNa8)6*ES9G zW9T+n5v)A_V@DR^0OY}UMeIRE*S*ngv+t<%#ZNEfqFDbkQxpStaO24h0Yp(&`t(II zGUiz38KOOxNqq*^X@@W4A$<?Mz8_yFLS@X&e@)^MkJVo+K4z2wuN_buT#D|N{co`) zUAD{Q;WjMo*@KcYYQA3+UYPdeOKML<=`d?ARJOwcRH`I{Z?OoZg9ZE!{$NhxgN^@> z6ZU)pm;Y0lwPFO(^rCU9m7I$Qb6@JVf263dvk)MZUJp^-rlSAHi8cKx<R12E?q6bo z7XbYe&oUxlh@~IqXU^<zuVU2%-@upolp~zn|35}h+IjpEYKc|eX0itg!yT;JAh$WL z?1~~XFdx`6GvCv>)DgpEAFL8a?-d&O#|Cy7qUIpc;P(DL(S_H{)Bo6jNg4!6#C12N zcgD_`E}A}EkFM2gRM8c(1%qTDKNE><uXCw^Ws{p@?LiMmo)c9KiJX4&A7NMjaE;z3 zFa-TCI_mBJMHdG^55@9B&I)|1108$8rKqPXO`kigVLKmtU&#jbjq-Y5939i4EUY32 zWAIW>4D;i5L4yuPyoqoQa-s3oO*<ITe<z&26+IoX<YYPM7F|?#k_d*}i6BH3aw3K> zn(CG|c6jyN|7X`*B{wzUK)9?B#A48_;Wk_bi2&<1w+>I0`j4D{3jL3?BO@H^KMld7 z0#1RxozO#L3aSw#!OJ&{6v}S-s<9uAbl}c774^0i0Pw*L?kX+kj8i@oHytI=Gattv zEjfv$^RVbv5lMik*mUw=Kg*>f6taOuuMzTyf7t}1$5t_fdLbC{ZN8fl`~e-M4kwU2 zqK9FWQoGc_g>F0xlA?Kf3h{wMGEQvX?CEONZwh(xrTLYIY4cmG;4;16kZcQ^hgczg zFQB>p2`-|*$s&wiqGuy$LA&0~;~#CyhJ$*#b_g`Y&L^~>MXl`r#>Eeou46tlZyzP_ zGaJa;uV)xd_I!#vjn{HZoqv-4MAmQX)<+37NE7-$(gq=Hm=SeAHd}7rwXDT0PK<== zhoYePEE#F10Dhup`TDe}hR)hS-#o(0!%MdY#mP1N<W`*Kz~f7|$ng#u=3d+#he;jO z{C@G?{bKeOX8HuT_k}7D6Nb?SJBmN%#9}F*&dynUCE@L^BoM?fYLw2WGn%!pUm9@v zfAmd0yJ$CxD(Lr2dA6M{Ig@mjuxmK;&^&KDCA@lnJZ<=A!}bt@)<pmt7D3lrE=GOp zop(^J8Smsq)2jr@%vWFC$43N@a#XOTv!g_}$?b-m6Grz#m7Mzla<7d8RcizuMdN&b z2-@MR`k%K+T_>8<#Y`s)%w3(Uzmx-9LolWF#D=(jOCaQo6DgKED9bc1=0v_CAa#(H zI|<88CRhU}g72S1(_Mc7p!6H{)(yJFBCk><ri_iEpV!_9r-w&hHRr5tx$>$<FfcX} z@;5LBqt3>y24Lty-L@=l@>48?1`f%f&VwY9{zwL_aH=tnKpyk{VMQ{TNLoMlKPo%Y z(Y=8Kq75(yDD+u%BaEO)3}*Bj9?@hy`Ql5SD(u^xXqYojIp8({Di~)F>WX1=W74z) zn2CEgOb>T|^~5sYshsX157^|>A%kpR>Jd$6_7vIB)rq9{JR?+t6aG1y>77CFt)I$h zfYv$Z{JDBGz&`q-*!Ybzsz)3A4*mZZTpGO%_N<<{eC&VuK|K-p#5?w}1ebwc8}weh z#qMS+^1jj)q!2iUL9EE{k#Cfh=MXFm&_UwS<;Q;)P+@<D&<9W%&L_pqhZqK+(J(n( z?<)z%F`f6Gy#WKl=(cg#VFpDU#Q_Gk40WRDw*28aF8?X?J7ypxkqrbvs75E!^_zOM z41}}rFEw+5I^u!DmrDeQ%OHthZ0sG$+kc76zreDvkH=mceLTea0qV>!nVSUzuC}j( z7bO_;oq=TMk@lbV{Ua|gz`|zrZ;G29{{bdnQfF2(7`+<Tv>T~YjL>MWuo8@}TSreh zL~VT4hG>Y}g05i%^Nb%I$Kc(FU~FtBgl_zyx8w#Oo)7ip@^$)}jzM0Kbn>hgN`Lym z5;z1HhF_*PU6#0(0BPMUk%BA0IJl>iK*rziwgW-5XVVOyHeK>*$>~jf{?BeVujQQt zv`zf}|2@vo=u0L?zsgX-<UUp<u37R=0FB7xBblTEj(Hn;ynO`W4Fw11<ZQm8CwhB* zdVJm654LpldV2f-g8@`iD_fKN9Yb;mm(Q4==k+g>X<1-}6nWJ;%it|=9V68zH!N!@ zd@6WBi9|W|yOY7J9SM7#Yr}EJ9R<A+g8}jUw*4laM8v1Vso<P{wae<&82pi?2ZL7z zw!s_FLDGDpY0%j1BpRe_acYpvA*@r*Nf!zzm*6zO&2BgMfLJJ7b(3ht*Kakg$``EW zCnqPcaNbP1P}=m8CRk_~7K(O0^;Zv{f;0PNt0X3j>JyiP5)ZH)>k({oNI#z-CJfaR zlU^+MZFs~n<$yRe^A)=Kc|g$YqCems5qw7Vh)Xq+RFLjRLEs+YWA|Ie&Y<s8rl#(< zY#X~j@qc|<tP_DmpHVDqyo1HPq;Y|zXteXxeU-KI)$x|J`_-K&D~PeB!7THRZ%G}D z=+%tG#hsV$@nZXpNpYAoY3@6I(50#wi4j?er-cyo3Sg$l7g#iTlV8%^>K^?Pf!MJo zgmhbTs+E|snaHb%6YxorjcEh-t7^6c*|uK-ubn>nuGD*mtDw$Ue$)h8Au5DsMo+Mi z&5Nk9k=dPj+NQ*(Ya4%sh>T4!-OQN0JAMC<{mT!IU^<*FQ^hV6D2>6EG9G^W{U~&i zxvm>)AeVu9;O*z*WwrI4h-43Q7d4>l3e}ihS#TGeaNM^QYiw#2&3MwHPJ>!G+@p~7 zxhn6Ic;C-nIht@Tf~l{(2+LN7NApwod^mxB+nU$rudUyvw#i?uY@#DZ7^Zy_z17pf ziHa?q7)!6m7+yQQovYkhJJ;^tlpo$eIrQ-pC1a|12y^REO!ZP+amE(hic)AP+5M(H zz3Q0ALoq0i^JBtATBXYKETXd^Xu+<Nz#a&ab|{EaC>*7}7S{v=Q;Sc9CQ`zrk<<)5 zAFQr27}CVZV`(VS%wERp=JZxiI+jme<imvIJ|W;Rx~Oj$AhfOpk#0lan<8%QV&Io% zEshT2@}K@c{6?~i!qto^?kmLm!q9KVF>lN!DJ4D4`>I92{3xQHHRcRW`{bj?vMu{G zy=EMvs1=1-ml$__eL}aH^IITItD0X5EjxX@-8Z*vuUk8>{=Rpn!LPW%XWE>%#s!F5 zg;N&fc2-zoI271}t|VtfYEK7{5-uHY;6w`j-}0;NJ!D^<zH!wsX{+d-3Kgw#-EoI{ z_HtBEQX7UF>Ea;+V#)9)fhy9UV|oF@4mthONuKb?X40NX)K>)DaXw&C%;?=7%hklr z4ohp9B2%ZK9Krt04F9)mrm1-!W6uELn7*;Y8t5Re&6E1ykVQ=h9n)<p)uK<rj?I4$ zOa;ZeNT5?+l$h|niHfwWMR56sd~mb=7LEy!Tv*$!t)3_`Tgrkc7K;9njKRcXb=}eo z&lLY!uEFqd?1Ur3XW}rUM0tp2gIt0!X6#(fZyT+t)e5}=iuAP{p^C9|mLpcTTD2We zX1*kGQ(cDP%42u(c|{oPvDIJ|r5ipcIZ`5`gkRB~iVY8h9>?%$H>qScrAExr__5rO z5z9D{YI2WnNY?n&npLdl)2;Q}Gx$4<<7ETXZsuii>hY6jCCT@Fuykr-Vuj8wuZ7KR z<=L*5k7vv78?f&kx{HSHpztM;n)}Sp7%9A0=QHWnEds%<;g|ip+n0UB^|z!_>>4{$ zl1z$1*ob6QVw)*#m1O8db^p21*`B5ZbD3WUXN3s+ge^@77gmy02(LQ-T9$BXuq10f z{Qzl*R-N(t#`37ESV;0rCYCUnwmp4~T>-nB`-l>wJ>3xKuzLbHxwz%%7OA$X^M+)Q z$*_j!H%f8GVY>5fCNP{b>?x0!ieTBV2W#x#3--)Wu7RWzk%Hp*>@JsYngWD^aALP) z`9D^U`ZBEuEIbeBGs?U{QW21E+IHAex2&gFoX)u$;+UTu+$>^d8d{fahTR!1Y32&Q zmKZ7Qdv<>)=$#QnD!X>mCY|yefRAAU7DyDyxEt?O)CDI4I<%{Nz8#AujC0G>#Fk#N z)zd=929D(%N?-cM2c0P{Id#Ta6n~6Rmx7AA6oqM?cl`NEBWpBVUp%5#3wv>FJd`$E zG)x_fut!UB{t0N@#)VaMOTBWv?E86{H8pQ{T}`90*Ui|$>cOHjnd$ItH6=d|kTe5* zoYUxR-=lci<Ig3|;iL(}$R0ryQou%xjxd#+!ffm51Xm8R4EkT3@=Rl(&R)HTq~|~J zpSXNjHldzOOgOU7_d0FL`8Sv9QE~1l8=WrXv$&rDOUT9ndIDi**a=#(R>pW(g_NAm zDW%pmB%CNl6=(Egi3NjI`n_tDusD{z$=<0Z=f({3Y0W0mh38Hvvq~8OCW3SrjCr^M zF}|LQWXN+EZW=4eoGRQ<m9$IlcX+VHC3XH}hs$NTe^9QP^o#_?ii@$kih!&}!rL%I z1?n+X-{2w1zZL35nA#YaGVGQQ8B)-67;T1oJ44ZwW(TkKSSrYt4SDkA<B5w4MApi4 zEN^EEzI3Fbj!C8K;Zi3S(t*EIMT0^p+U<khGKNXhZX~6D-<~j#P$o`vyZ!by-Nf`W z1vbg0h++YsOuhb#EQvHk`+BISi)Xuf4*i@nwOlo%@Jt~5toD-84*xuumqA743Y*?| z$NPjq4%HS(;F-WTF4^}<Jr>*OptZXr5;giV$+4_TrBU68N&D3Flfp!UI+}XS6)EiZ zgJ@Sa`JK9sEBMc3Hy>z<cZ_(a6rx`T+c!*Dh1!W>jC)nyR$DN{put#^?`I~@508UW z_jt8_-kzVwd$$Xjr&RZ}em*(3HG59d2-fmU0Zm;IUf_zrBaF|K^{3dAJDO&%mNt&r zf96dyGt7=U&rHY4jU$bNqu4gY6#~tiM2h_rysBobJ*Hipk(j71`_Wos>G-H9DNW|6 zC}E*C8GTH9CSQpg?|LpWE@a+GaO6;3-rvp^<hC-~7#3o8Tx=#|ru58?2P{U7%kM}p zFvKm|6AmWIhpy{dCcQ(`>C+z+x5apb8rAxOp&W^Ex)p$dol=SxOt(*-+La9nf3#AZ zxU9Ro*&fr!($yv|zOT(F7?~DCi2kZJkz9}{ttNZ4J<qsAjzuD_^kESsi|lkfEy{Ao z+6d>O>{JcAl}3;gZ_@ve>=YsgV@vrnIv+e`wK+Z6sgtA<o&WnMEb6mOXc9&~{iJTB z^9V>kx<{tnPb14(&52nkMBWogEDNEVPUnC$`d-qM2x&JQRn8v8N*}XAVO_)f)}4&- z(Z^@Zm<1ZQzDlCbl*e(ljrWT@RzBP9uFog8ov-`jl5+806&<KB!gethOB{cNd`11@ ze9Y=-;m(ve@o%+t2nsD#lP@kd_hgo}%=i*V8xYhC9LB+<d#9YesSi{?)u`$&mV{y# zwVIiqf~?g~F+gXn+g>p$mK#q-lrB!9Gto!WnTupblvSEo6BZ09$C?F2m<bE7@QG8r z-><7rdB(W3C3@wGS`^BkVxo>;N)-|lnb|LK9Oe3=n~KQuLtjEfQ=epjPoLiDVW-u> zDiPT;%0qs?xxp;O@aObF2e(KPYcU2RqoVEmC{iF7E1&mEDyW<x<uW86dj*CzPEb*Q z`?kyJLN$y%6KUI|_AtgvR6KOCAT4Eu*C+<7?BjRLtI=0Dr7G5|u#V1aY+{n9#$vpe zEsSN_hkIFaaxFtm5rEkWFi+mMBa4b?pY6iu#E*HMndLN_Sc+F(CNzUt?+0TZ9LX(> z)<Lg2(n1k2ei6xd92Y2y;Gauoi5_(Dp$PFvZh4)Nxi8(5^J|h+qkr92qE=<l=A8+{ z$YYJ^8^>xguBz^*^cpM%g^q&`|HJ^MfDn^VLYF2&>olCU1(nU<7so_ljX5fRP=}A8 z&(1!Ka(Ob+N0Y+{4(4;%&;-{rVH}LZ*w#9=r<{Rr&hzNOw%*;V>@{90Le8~vusu>f zd6C*-NGT4{@O(e3@(BH-Jixr*Z6>R3G*-GT<%caE@E7~~mOf&@n<D#62<=?188JpA zr*I5^jKsAE?`QwyRGRcqGeV+2*KOjw?G$Rh0{79VSxEP$Cjqiqx0l&x7wXgGh<5fP zorkiJ3?)=<_U#^KMhXl_fQqkx!)9?EIYm0kUUK-e6!N!;(Kn5FGn5P;5vI+I&b9zr z#nzj9lkr^14nk*9R5A%Vp9PfTtb8rCOogOl6%&I2bFjm2Cu&GiTH}jj(EN4{F{c6( z;8D{>@hSe2K$+ppfy4po${)rWYhFfWljhbMKX!s}(IJ$dri@%jjjEM3)bA>mF|Edo zZARKulmv#6<8A<*ZM1kLshg3Ks^@Ya^dg(68cDSD{HZH=Ek_DF4wZ@{lCsSNt22jH zMuIb&O2#L_pVW}R&>bTTQ+2Jl3pG|CvnMa_C<hZu1s72ucEn2zn$yQXfGP7RhEGZD zArw@u8kg%>u{ft4(&0)n6jIM??lcDz#SoQOWoG8b$iB9~OQlpkiyyj{f@UbD#(++P zfTZvS`j#EsDfu}8NA_O($E&vH6s%l1QVxRo@ufr@izIg0p#r1GmMWLG*Y3JFMX-@{ zRJ-yUOSZW)Z#PqcJzEy!<5il?m~c}HCRblKE1JU^>G_Jtew9J?m<1NpFcP`mJ@_wz z9`2$?<T#2qI&aeV<!*oua3^H})hX%&yR$|}rYnXqrKIc_m)C~Wnl-i@zlthlv}H7x zi~l~^$F>~K31;b>NT3a}6*!2XUVO47!X)tn|6^fh^BZBZ%4XQcpJf{Pg`!15J&oVe zD}jXlF%R|0F-S1n4V=V)k-LaktI{ODila}s-Q$X~%lF6CL1Y#Lm1060dWXRHNZ3?l zC(uOgiQGnQJIWxoS{<!dB3fCH$r0W_od9zqRSnhlo;s;%i?p`qNVq2QtMlnHF|JuW zs&nH$TG!93uWTB&Gkr%oaoYHhH)9`eNx+6@ehL=nvA=hP6#BVG#<hU0(toJj$U(_Y z03Kua+rm<}QK<&iEk>nCBYohuDJPIQ=o-TT<?`=mBvy!JVR2){v4GLSTF#g&O(zkp zxy=cAHg{-s)O>w>TKHAd&w(<`T#Q*v-7u-P`@dl<g7xaS&$H0%`adf;&Xva&fE+cw zOg-_L8@j!x1H&uCt(Vr-2}1mb%&q>8(SV^QQ3iux>nN*66;@QBWL#C5PRnl2_eXwy zqaw{iK|ZQbL{hL1o$w3tB;P|9FL~FQ!VWN}GBM?C;19Iv&_mKAgA%FB6{wjZWXV-# zfUZX3!>2RU<@MZU6qKr-E833ZxAw81)vA`@<^FaV2KSED)%qS99TzWdVO;07uKg%~ zLq9ysf<28cUCybb;+WXptX|#MOEO{nE;Lb%l(5|=`uv<s%fx??Ew>D2CH1N6bhN*e zlE3ntBh#`c6HH%~;y0t-qMtzN0_B6yO(dYdjlv8`I^&DB_IrDHsOWBXiIa}o&&oL< z?@^8iT5rhSu?k)o(`vJ^8rFei37R6K!znEdVZI^(Vxo>6yyT{zT5)zVo|nm3)@p|~ zMJD8tPXtpVo<eP<Gv}`GC*@%8d`i-yZ`fI;7~>aKH0r#oAE9UM3S9qVcWIv3)L7#} zKzP<a`o{wCY-^p3vCsL%!=6RF1;#N!Qq8&&>FkK>>B#qpdQ5Ruvomi}Bxi|8SnJQH z<|CkfJqJ)&e~V(3b6%su3M1){){@gPbgD_T^RRB%GXfV7`0~c5da*D=MocT5F4OW- z1P~bIw1Xx3V85>55rs_FL?#;1K@Qpc2|^I5K@a2jK~HVLA0!FoK^S9gW@;4^8+EEs zr9Pc(2+G68KfzP))=Y<|NRIOV;x=4YY(<tg#;V9ymV#kAT^k`F&uOi>7KCp%8g=Kh zffn=INo3s85brHNor^8sR(0UvUfa?=06O8>yKY_E+O|CV`TD%v0S-bJ@>Ig<2?-Cv zNH$P@F&*T@&6B#ZoO-xOdsFqods5D_Xy^PMf#Sr-r{O}QV%HBcG!90^#A(N$#Z2Dc z|LxJRS#PTFdv*9V+E9YYL<}f^Vc0ofUYY5gJWvE`-(1MLUwn`R=!DPJK8ekpTZd*y z8Un%D!aBcl19TS$Quq=A^1I$Ni@6vR7_^;(8VE8?$k{jtOBhuDU9_g)>c)#8B-)w) ztj9J?3F_S1@r`%mx5v-zdJG<&vMc8FL?~#LbFrTRq!V3Ko32HT2tBZh9t~%zIVSo6 z-KO?Q^{6#`Snl$GHE-r&Ygq1#nRN@0vRP7S{$j=Qx@3N0^Z^i5*^#6`mP1PtF>$3E zyS|V=T?f!0^Iq)WHKf^EcbN<%(m!NAT%I2~Af%n4()F2*e-luT-Rbq)zUhbnPcea$ z{e1N#*ARfp-=Q#wcUm1#2PH<(7EtHua^(gz1kiIV!T(YI*=WGa4@{2vs=BNR1>Hc+ zrB&R<V$Wk{d65ue;y^bM!uKXqb+YAqA<@vgkMD=IY0Ms8I=$4!w>&h-W1H%Q2yDE! z>z?_IrPCo4mnJlb<<5S1La<sKAHD0DgZ@wqDs|-_oB!AOc0;b#4p(ny%Wh|1uQu=d zv9xq_i*C}61ii_5uP!_>l`3Q$hD1=Ez=R_z3CKp4l#%r4=EIqEiBbgHMv+nJ2CkSJ zr9f3VK{8H8c=7IYP-#-nI+@WncDmbe@$PD%dDYo|k#kfchRVVPK6ukZN?_5mr^jav ztMv_3tURHfPesb#<WmZ)?k)-qs8{-l6841s&VeLN7W^Zt?Wj0@<cDjbs;N*z2PQae zhgmV8cPd(7{^Wkd{<!|+7tA|_Voh_Cjy;WgJ_P8QL(IM=Fq{h-(+~Xkkcm2Ge6|l% zpn&V7-09|Nh3rJ!<Gv=&UVosKH&xkNh_a89oRs{ZoJj6J<QP4~_IUe~z6L>)N3e9B zDqc7Dw%ubBQ=0O?2^Tiv96M2h5mrrrmBV^ePBUuYcAs6wk^1zu(-$Z)-=q<8&0|*q zHH9v?2IE`QAcK%l3gDx7p&KA4Y825|nVc+hoj88mOG8DS2(7P`u3(g{>XEF~e1cWg z{mcxdE-W(RhD+x`S+*RYlz1HBAUZtkL&R8vKZ#^4nI5{wv2t(XMh@Vd;4`loWG0J3 z+j|Qx=Ua4xg+GHzXsVXniTK0}S43VcH@lY}V|)~=J3?R$%r7V4UepoAR2oR;6fTvQ zEUU9soYgm23n^t0+d~FNkOvN>2R#y)L&?%T<abEP9-HHCYcNGHi4USn_N&`9OBorE zJQChj+f@_K_}vv>xF*Q15u1woLN6w@V3S;EBFxsG4s0(qqrqGt0A<_1du4j{{zZn4 zs3#>V?GPSK4(+HUfeIL)oFdRh{t4foT8JTU`$dGVYNlG7psaJ`hg4p$iXCJAa4uRz zR`XdCra4pvfrBMo4ZrH{1MUpL*&myi<LV<X$o3hU^=6?pNZs$6ST#WV059JLvVy@p znHQ^JdRc*DD-*TG70&Pt1I{v*4|W|Z4QTZ{FyCUa($S)t%fKTpr;Wa;Pp>B^U7+(O zLQ}A8R1Mqm)VZv$3Dkhya$%Id2Kbu~JF*5{l79K2!PZg@(}?71&DNt6L>l?WXZwUj zwRnM&r!&ZcQ?nHduz}P;SL$fisS3Czq|IAbY6crO(+p0|B=4BoIRtXV?wrg&fYeIN zS0o}01O+JU6Vur^O%9xucX@~hLrya5&e*%AUNSW|hMFJ<7RicMX8xK{&IMk>qpW(N ziSiLa3hHogdjw(Hki$lzwSwSu-{Z3?wAv|qGh2h2z}mLnk=akb-qvPmGI&+g)Ag!j z1jJv{$cW~O^hQ&73`1+nFmK2ZRv6bl^ZrnVM<X@8990<2%gV^t)GL2XGv`@Q76F<Y zqq4JE6{V}6Hk4U#d@||D)bkD^*HK65TsT88L8O0sAQw^|sS$SQwDwmfaIb_6VV~Wl zY6Lx{(^Mu{jK#t&hwLkOjshpzvHx*J$c~HA$~-->zU?l?UJO|NPPdl@^|yXiKC0!F z9eO6rZuWt<!z_kG6Ws%pAiYAgG(W74_mm4<bH3wzQgP5YT?z)!40~<6#jDaILwH3` zfENjqzlQrobwoGbxdSB+t<L;*9Nz63>*XlX@|=&V$yo`)4mGO&h@UQ#$-Vv4m@pDr zy>y+8bmTFVe}i~_m@@YG3}KI71%CQC@t=7^P@?eAAonhXOQStr3Q`FsnSF<QmO)O| zFS6Jo@+O3D#9N+iarmlMH}H*#!0*qu_8{~^XjjA@jD<ax;n8Yti`B85h$lFm%U&!$ zy?qf+1Hz*iWszBdJiL^OuPf9o_Rh3v*OYx9(aB&@YdK`bsqWZMcTOcn15(FALU+`_ zyw*<WGnW)Qzja=}zTTPGZ`J}xzSz_9AbC>5MF*aIvzeq#jB?4|mub*~sf~-Ri+dJ2 z#J7osg(nQZ)}1>xAz*m$na{mjygetTZ|$z#h|jPW6fpMm4PppwA$bTNv2|~{&wT-o zVI$tz`(sbH&nr1V8jFkPyUN?U$-~>WuZ0G~pVO=ff82l;QQ+K9P9SZ;eQvzl4TJ3E zHQrv0^e4Q1M(oTfH~)DLyOpcx0fVPqJ8ezs8c|<>3yK}jokLirNUY>HFGVvoc6~jv zy4jkywecCKD*WcJ8(mu^zmK}c8gm%3(}&OlegsR!W`!7q2$vBm<7I@#>kJX5`vU1= zXu9Q4XkF3lt_%9Oq%6unuC3qMH%RWvrrQ2lczC<)fU-hE>M-`1oY1s?G}iwBwZ5A7 z9t){Ww!u1Jwf~hZc%J9eVASLuW^Zk9sPPaRRCbuoFy)xG!OZD73xN%kYB-lvnAC5^ zJY!|E)S24ABi+YM?N8T>bxFr|cTdv2qt8Cr50R{brfQCmay+Wl1_cRmAjNbad1*Jw zv1*U*?jP=W`#qRXN0L5~S7^8e<DeK_!CJvU8E_C1pYl!wS_un$ECLw(vKj=V+fXNi z1r?|YatW!I&E(Lo)568OG=>NpU{8%iaCMF;+zq3)iiUM#4d0W!)<aFmgLZ?D1^PCZ z=y8`0aJUB6waT$3Ok+zK^n9_n>`$Jm+k1lt*4>6vL1|hyB^lzyM7FASml@)TuED+8 zuOVG4L1yI2K8XL4>|<Kdu1HJ_AMFsJ*(Z6--ork*Fgu+NIgz9{N5P&)<^}J*H&Y%; zG87@&?^deZ|FIv^m*Q2_Suov2-dHsdr9$e{)`Tc0I|)yid-)V8h+7v1?QwxDm>cXX z8yA502(MXB*GAa*w3<#PwfJF6&l9ueCU8B%%V`J3Qz0F+JpkT){No<E{d1D!ND|VL z*|qotRdV*g^u}IJL17+2f@ji~5s;(wWrTaJ5wC}P(gO+w7-LDGJhmwmg=UZv&PrQM z(Y6>a-nZHvI%%#|Aueo=7a~ttr2VbwTqVMuwyIJp9le6(zVX@2R;7J17w&!@siIU` z;64|q<F(g;+pJ{ZJ@1Csbya|mV2bwijjYU#b2cc{b>lx{q=9M>Nt=U`kQ+>HVMX&! zIQfc;@x0zT@g|RQxh%k4p(&=t$R9`yzZJQIYkFW)k-tyBkJz+4*5sj5sI8}`*-#V& zlygjTX+$HbKGwjRv!~1BbdpavpvP2zUjW5>G)9*Eb7dcUKTf4SW9K+UGiqlzUa0FC z{AwRdG^te83bTO~=-3kF8RID7*|*a-MRib++l@f{B*a(2P&rQAOukBfE-`?P_h|c5 zLGEc9R6$NMj$k>-#pc(eta?>EiySzYM&Uf4c}Dkc6nCn#^<pCs+^Xp{sGC(7oV|g> zh`aP)u2u*8sK!jW-qfad5mIoAysHT?3D1rJetg}iXfluf3~ss}*4%2T@sU#)PjG|i zYS0p>0bLF)tDI&oIh978SOQAD?t%R`0gnp?9{FhScI%c|J(JEW-UHC9LZfW%<qoEb zip&m`aPp>1pACAXJFxBEFlXAAO;q0@%pyJ7>uk|q^eQT6vMMU`d%RsaJ2kYo_4$El zv+w9=5&0Zg`hIIhH2)BNCLW*^;g>#@#0F?lS04fItjDDmyCCPTicn2;NS5<d_?)#y z0%Hg3(06MC#_bToEWrVK*6ai2Rp!5#qpmn)8Azrv2a5s*(vC~RfD#bg3dKnMCuhd; zaSC_`8~Ji9I9ZuO7>soaZeVmM8c$yy9Q5QdPqrpYz1JUD+@W8vAh7kJ50&gy4uTXq znM#lhO&5yZRjN{X^*rW9en~X<7S^a+5Nxx=LBOE|Lwq`kEVxF&gMuZ~jYFf2a7EaZ z0p4Ajj}D#0Zn1;1N_2v!R_+|xL#1|W>8PHsAJ`{}B@Y;MZdhWDEcU4FmpS?Lr0su? z+!{v^H`XNAwB@Amj*gfwp86i{IM}>Vvzz}kJkL+OE*TUXHJtCT>B6OEYe{7Yv8Ida z;wr~=B3F!RvmXM{(>^w6KDv*%-q-8WTDQ}A_QnKNP90>0VaRQ&3Vtk*XmHWBvKZgq zSyRdOPZTqC?;Ul(v7CUnF`YQN+YV0b8BI?J$X+r!*-CLS`HW0VeZj*<-*PTS({!`2 z;pI&3Os)27e8HvGDsGn_E7;QF_bQO51jJ;;$sX&kby940&9kFuwFSW&13=v5mOXBu zV{p9B*Iv()r%i#?KHma1J2P!|Jd5^0GTPE!b<}%^#e(i{f1Q#B$^<}|)5)<kY8)$L z&zlidQ^0!>m?ecJGC1XOWa1mUAiiL1p{7fjj#B~m!98_+!tTvXGW+JCP9giTiI<!) zQ@C&-cA@e387(!(!WTwNNIaM%ES3Up)*!oc<AkC9*=4U=#*&n6a$TBsKY)?{E()_B z{OD9J29dAxL>cPK3ko*y6%71aTaf=5(>lPu3>DIhnlA3q39;z&;R|z*#_ohQxalMN zT#2t$MNr~|h%;2ccVQ+kdYx}@akGX+`2!p6{F9sK$$6W5$a%dWiw}tbzOBom;W7`O z;c2ELZ)Z|{pT-YD3gy=AID0Ja-iaf+V($bn{a#MJ;ZlkC_^9)eRK9!e?*Vm#j-x-g z$$K8jP<D)o(mK+lbx88ym-ewvs*OJXLoHWp>;ztG8*rxTHZJWFT2Dm`p30sG)6`)M zQdb2*v#igiMf5tazC+i+c@~4+Gjn#0>e<7;Q>$d+!9NP6Vgk>JqAA#;?fk@ZPGD_f z;rvZ|!(_zYb^A`<%`v*7;#lz^J)_<JLg&G8dN_L^s@_HG53TlFYjqHWl$SGC8He+Y zhrG{)Tv-o?@>B^0PQ>O(xSE_1?%8e^hTx}*-BrxV#JvXdXgjCQSV@(g5$j1`2QJ2J zO-;~4svVY#UnmM3qp_&$=vc+Y+!(M^d2^U9Bj0F$I%-i3Tz);hXf?Z0%id}s^2=zy z-S-p_pDT26Ra|a-5bu)n+6pTGvgcJ$T57NFU^l$fzOf3womW6TDHA@e!ySRGYQEop zkB|GEPDOpHRNWSYRz%;}z|MM3yIIjXv*LGPZ86|GS1@^H9~u0NCeoj85v$|zdyfuE zI(Y4JF*y+7z#A;wIgXKeeV#4eY;iZ)5q;=+mcd-cHJ$HAWWt;xlnjh3j<2V3a9x$A zcRf6GW{5FT1~kkq;j3(?T>=GZrx&2rpKLujPHy8uei=cxN@#05UTd+XiO?LZBx(oc zxLY0yY}vR9ZppAll)DY)KEOA3WZ7QgTpSk&Jd0en)gxqQ@!fbM35EN05L<aCBlSIT zT^|#9ez)DX{#cOl==K;t61D|ZVB5qtytmE8wdXkbk(LKh?3Q^GY0I0Yt?DWl&%Qjh z1N((r%AI9)<np%!iv<Vom{FptvmM5I)7zO9Vq#ln?>NlF2_PhHwzy_aYa{5U_agGH zSvm5qNmDitv}k!G`P7ysY+DD6%TpmV?`J?kYMURXkdPMb980CPxXD}S8qdiq0zH<v z^@Yq>Y)6l4C+RUljIewV_Rt^PGAAeOTD8FIkF;{gn8=IUZQ(|_xE*S4t<N1H`Pg)! z&b|HFVb3x5PHWn8|8X-r>;$#JG1suK;dx<#BQBb%3q7k%>I9%7cAwm3r3>!}ghYJs z<F<{+<F?dlPC#0&T8rbhgOb|%Re8`_%QGO@xX}H@_ZtG5%PhN1Elcpqd2b%_E)#K7 zlqjf&Jqx0ofDn(%J&}u@v~+8wrx887^CsTJAOlXOi0%OSMBmf;o(X%Dp*q{R?OB9} z3tumW=2X3gM^5PhAW91i>lXlYAKuQq0O;iQPQs4<gU&bi&<Wk*^rT_c%xlM#OnE1D zxjX&p^rm^cl>@#H=i+1_^>MTNv2|)Nl}5?g**eBXdZwI@lhd`!bCb8=750G*XDfMS z#=%%8lg{Mcm*_W92}Eoz>BBLG(*kD)7Xp)%ty2wS+Wif8b+p>2_x5SB3?Ji3=#7Fb z+`gu4tisapTB6dQKO(l>QM%I}j4FG>>``mV|0AkYJ6C$z1c^&R5X4dI8q^URspzfM z+HJ*`3RSO#k6Tet5XCdkb!|P6HD=xfsvoCo{GF8Ih|&3m!I_Ql1eW+{WgU}u6VP%@ z2cMot4&n5~MR@pj{en{Sao(+RwI?2orPU);d$PUItb)ts)Tl=x4=Y{my>pF24^4Bg zC~#UpOvfmxy}{Z$S=W0V;Mm9K`*iOCD6Lb{pWdL34ST@!uZd7vK|+@jt6kc124|e_ zEf;tm_QCA|oNW49H;Mo2gjf1@daxRJb>DhwITMV1Sb03bYddk#CGs)pLZhTx>(0T9 z1Lz>t!#8T7N6(YG(#%|Fz>ph9C0TuV{m@t2k+nmxqBba^t9zoMcd(i5gLf6MH03cb zM)2#T1VaDs7C_tn&J093z%@!>qv19WYqG)rwAuHbuSD&5r7Y`&C0pDw9v8Y!y_$Us z)7-L=rHFHJGMMmjsLkS=B(cKy&rA;(T<+`sk|wz1Wkm^JlzSVEU#JiAzRNPV)wC%L zPa%SKWl3=`PDVTF+WH>T8*g>>pxSJ+%YhP)Ft2o9ZFSAzWVzKk%{tijoTS5JthT+L zTI1$D{7#N@15B{NV5fWbEQrqCr9VLp0La#+nv2G0Y|c%a8#b^#T)o$1{%4@0oKY)m zY))#w`bg3r*Vrc~+C9`=k;k9fUlng6OG<zZchc|PPS~R-U2D}ou${qub4%`z$BY)H zM>^k3n>gTy%Zl!uUn~EfT%W}JUG3`P{X$@xEnSa=ohDHO_@?&*hv~q7yu6OayZ%2; za*Rt`4jORkL724e1vg;LC?Is<YppKLRGPFl3-{EY{m-SaqPAXNue7Hzc3;>r^Y>1a z@rZC(Ke!gBi;I1Hdu-LVq&+^JvSUprE=>5+M98mC&MeIDkIdNnCJ&wb{Om$2(Y_pc zi&+XhoOydSm^+N_|GLy{#f+ci*Pa24^Y*^}Ra^bZ_a`5pwd;Q~Z05kbN4CQ5BL9sw zTi(Zs#eVIn)>rg`YBRib_ba^K_rHv2ruyY|(AB|YfiG6PjH}~Z4u^-l|BTbJa}f2R z@|<eHNlBN?l7or1<>)c8kmwK`z)0s@7&RjM3Zch*t_%(QEbVkE2H)N-AFt25+l@{+ zt<C(o|3}+928q%w?SgIFwr$(CZQHhO+qT`k+qP|U_ilI3e$RKlxf5sZj~n;S{K$%m zSQQm3^Lf@&6)SRO+M|6dl};~thKs!ijXZ+Uv%~9UN5NWbH#6!>KB>51E<DA#OaDEf zD;?qI`EdVwfA8h*@5q@xl&W(DBCY~<71SUvQhz0i6GedDNA6Ko9sT$J2J3Ihlt{|E zLnb1D)9(%)7)!4<LRydt2R})eb_hEgs_NhS*fA&)ayH)u%tqR)BtqSmrK?Q(5iBS8 z*S#_u2?B%%2~A}TyDB5PhE;Z>{son@!P;$T+k^5Ye7TiUbhQ`P<D3xZF)n7Ztw%mA zt*U3k2|qfgb)ed)M5%XCmzPqlTCIDnjB*76v3HLI&y3SWLqc&9g{2j<rP`z{IcnW& zD#Aphpu&$0O%H8UzlYRJmAqASbi+q4(SymD)$#<@ls6kksj8s@7jqiX{?t289zFHT z3^*A-uZgT2%IqXijZP*nTKV8xb1rV<-p}M*I*jC)*W`LjNCysiwf)4fsbzxYBWSEO zkE`jPEx5F8PRfXHRe}1CD#C&#L=!G%XPhqHAgxp3(XLk^aM~J}KCK*w87~wqbcPCz zI%siTTf9hwwJ;3BP+l1K)JpO3;DOYnC)Q5RF9iiS<7~DjG)D!!9v)JWKR`kxEWrS4 z%bu!2X>8E)R@TyGg$Lr=a<GA7=W3^y9?*C|tR3Gb!dS|#!FY~uLosoVs14%VvaZrg z1IzVW;@@;1Hz}yHdzX@{xnC&_7_ZQB#{e;>Q_-KEXp#5-M~Ym>pfWv~zdrw)pJS^0 zTHiL!Iv`)=nl)~{S=5*rg=GuGupv{=MjKS6gr<{w?^d60SKo#m9{2Arx^;Zn-DR;L zjR7UqjCO~6NLpel+`CjZ1a()NBa&Jd-c(zQFS*Jueg1hA8yb3tJQJG(9&Yo@Lxo#~ ze&#(EoC%)i>C03(Xe;fo7~i~Ou`CfJ7}ib$d5746N|D=54T8KX?$tXrkVMLr+Q_3} zJ!INhb3Nj}DFkZ*^o2E|m_Uy34_KW&4W}%2tP9vXMUEGLo0%9)9XcTLk}$QJ`mAO+ zTmRun+^*$BFY^<^$#9UgAr!|8C(>h?Bg&r4Y2|m6@2TEf1}0LjGIjQvfh0$&mIdmP z(Qc%4YfzikRNE8MjAm+@-Sri!%zoN_)3lhaJ7u9`nL5h+yNQiSVIcHmREL`e{bwLw z^L907$~y>5gw1}o=@v2S^~P+_PQt3hZ}0geh`isCjD$I7Z<D+0-<feYGrNC~Y<yG> zO4mX1*bSbf$T^_@{N9_ud%xLx>-PCkH>(v^?_4x}_lTXVSvU~3d(gG-$6M7uUtG3w ze)4JGva#pij{<Avn_F?A7`=_6<kji+rs;4ViyICQW!9&u@AL3-OQ)1k)p-Sy_SL`6 ztH;;t>+ts2;JcgM|0U%Ka|+Yu%!z7nJ2&982Sw`MvxRM8*9oOLn?qjA+tz)3c6*6) z^&!S6`bQ^*wyB*ffwz#~2$2k{HMD@>%YWpzT|4{BS_5io#zV>8M=7r(As4I<ssH=Z zRrc7L`^#3l!^qWHyE{JKbeHDCg^gn@e%r&q_e=Uh_s8~@4^Vt;>7%~Cm)ABX(@n-g zf*J~=bHDcs($k;sTf?cTTYA5bKjrB=f0owZ8^lDKf0|hx&+_TMpU(KD{kLrJ-RAhe z!gk-?fYH19`u%%4`wDVc(VQ9u9BIFw4<BhYw7-<T6Q(u)7T&zEeT7X7@)OQROK1wp zuT=*rw#d6zS&kl?khcHE@_9w_@AmfC+4kN1{o~QGGkxpdvFGzKf|G{aM;5z=)jXIw zYNN54kB{$e|NZ{@xgZr=gcx8DZ1?=6)q$o|q7Ourqz*hNnNz;6L$>CMp`L~Cz$Ntk z8X@_V?=Fvsdk}cQda(ZP84A@XqZBBB7A0KZND?<Q1$`{Y)E6S_^ZC9fr1W|YAMf5C zc35w~(cj$(I8hJpv&|#J-#|G_(sNrC9;tus5bh_;3w_1>4$F$!#>phRRsw{eG@5TT z5hB~jG0TV=N3C+IV>#%s+OkY4Fu&b$Js$$&<>mb1^b|uC)xzQP)v)E~(YMRXXW#c- zb*B0PrBo7+m8|GPlxZ0xs!_(T({43_pfcmHqV&p&rds`|^QK~qU=>`Fglx^F#g^b{ zPF7<|L33oUF^oybMqO=Eww`608e3tf8x|v4<SjaoLudL~BkV_m{_hkh8I_;Qhl4bO z;+M02ft$2^m#|;PN!9}1OsJL#^f>u2-GHE*B4}VE0+OzOaOCMSDSi{3);+Mqrj<m) zy2=1O%1C4I?~hkd3I=ty>GTpUtHs39WrKgomC-u8v&gTuPW!TVzb+Wm_eU-kF{F5| z`kCe4J{p8*p60!zTNFBE7i%59(>#p*8OA)K1}mz=jU2tdB1sD&$z8wu80tFPEoDJ1 z5tlr|TJ-8Q76K+__EI?|-Fm3W?c@QM0wU*H9!eXkPu1`uqm@tQb@rL3(Bm*gn+<*d zUi}mDFrz!?>rr`HvL`E;wTX+pY9%9E##yWQ;3Hq%NWv5l7tkqVZ%=iQW5X3nYFO{d zb;$zQ+pUB#h{rUQ#Vm$^z@Qp)uA3Lo3CpykjdbsEv$FAQR%aL)$1aQNE)hZHbhWG= zqu@GIk1(qnE{QP9jQm402>A{O>m|8M+TG&hY%x~Go1?{;8owC>>`8ZqN|bFa4H=rc zj`~r<7pyC~nDk~vMyr6tA&-VA#&~U#Cc-Q0=Nef5v3s`!Q<~}%KDL^xt2Nrv5;Th3 z;$(=6%{Nhrtc)ZejX}s>``n}7(d0)_v)rP^yg#87tI{@t7~2w+Y?#yH8D*JhNZy<> zh31h%aglN41a+nYL^fR%&;w7_bM+;5DB!+mhB6d#S{RjlAy=)wJ)EZfnmDM8(b6Rq z&w5OkmGvQ4O8rZPaWpVs0O950vg}2*Qb2u?8u>En3x>6hY$=sa&H0Oa36%n3eNxDs z^%g2vPF<45DzA(^u}(%9R$b7!tf;`y<vE?5)9;D2Q9)8N14GNuh>6q^`pWbGfCmIB zVSZ65leIjLM1Td}GFyt*OuT9O!1-C^!7!h?_rrUxcad^>c9z4M_E^50EH@fejz2hS z9&k}fc_nkaNHu-?0&x@~FI_Df5xH_|H<Jj1R~a1wqGPkX?#}yGXs#u7IO5b(H`!A9 z?3{;Ssws6kQb2rQ`}LLFhAWm7Fqrg>*?O84y;-XA{H}g)@21V)tH*o8Zg<jZ`w!k_ z3DLDvcJ}S0<e$VuN!jQruJ`c~`y<jZ|4x4&AGYYYwvIgbu~6L9!Z#Q;mW@!^*YFy^ zO-I(Xrjel<o>F7KugCH${!Yd-YQNmQa}Rps%w``LG^A={pRfDfSi-x*EiQy=%lJ7B zhF@M#X?JvIS>l@2oqioF_zFRb5d%sASKA5h2Kd*Zt+bc|-3MLmAK2YwCX(4-n5}Hl z(ThJpyU~w_bhW`Yj-7@r<J&<78#v!RUntPD>x{0?NAq7(s;~T$OZD&Eex+B(0ZUs1 z0Rj3?s43@zc_o=I^!0Z(cLVkHeF{KrKf;@xD;6@LA<kDX^4()=+#el&LWcpIKXCae zHbnX?vRvt2A<jc119_O2wfrKEqI|!P^J5xh&DF3|+K51jCV=6_sU(y*9HCd6K<ls_ z8kekQW(=G4a?+_kSA9FVk`{sT+0=M)h+s=kl9*M!maoEd*@Ok@&jqi$4LNJfq5}zl zMYdfX*hN|jvLWL$`xg|zlE{p>_5%tvWR{sW*ffEZ9#aU=ap+1{B$XB+q|Q!rVTyCT z<!k10wB^WI91U`u;UiM`e=xHr;SLy_?cd_KIud%;2F=L?q!Ah29e4+3xjT4JIXU*^ zWVGn5iZ8pXfjuN~w;hJw#N;;1ewFNm=M%xgq=Ac0rGOorsGz5tnH(MN5F*ygOpylq zo*pWpKjx8&VB^cfVI-Xik*gn4R0IbZ3glREoujAT-&tbbofH<Jkz>SNe3zwvAa!{a zKTi@h5kc7#bWKl{2JaKlr{keLKi&o`<vfzuc^Q(NHI;kn<LOgWon@+a(jQ>&CX+N8 z8?w3mCS40uBLBs&^^1>$2E6T;h;fGDl$qRinXuB+F{)+37oLNSoM3^;ym_Uu(;H6a z?07Lh>HUoBLM*v}X&ha<iPsqv?oPQqqPRnL8C2%*1wHtyT82JKGb!T2l2br2cn}xJ zvq_k+MWIBiBX1K3Q1l=Qz<ofaFplo5B+v9hBd-ANSHe^Tv|HsC%m7e&`pfB4>ugQh z;lO{*Qp8S27>@ZpDUisODL~A6ogCE6G>qKpWZ0GqXJvnadQsqmm(~dhApiV)5aqOF zpd6JSPcfC7%W7n|Q%HOa9?&ZN1En}d?r#8%iHo?nbVr~k|CyJ!;EY@lUyBr%*W7MT zV@GbdHSYfT>w96`t(j!Fj<cGB3p*>I*CzaSAuMC0G+uY=2U6bwujKJ)>Gu4BIt)r> zvLlkv^PC*i^dt=Y`DEl)z-vGc5v);v_%^vJ0>v5Gu3!Abxzk!6q)&4)Q2uO_$FTb8 zIrH>TuQO;Iow>u`%Uoz&-LRs<n3%|l3lbtP?GY|7!m<O@Z^m?NsnJ{btb!+=O<|m` zeaNnD?h4GWgezpHZk8AHAW_~~7kHPu85rM@+Ir1W=)DNs+~~f<V&)4nxw188rLSL< zfg23JlzpV*cC(79|Ctkxiavq`(=*TH!k3B}2kAYeJW?vC-(UQ^1ACoA<8FDg5AP-N z=6wYZf2S)Kd<>)<5Eqr70Em;*l3XDu4OxnGUdBZ+&m=w~|D+??dBHVKw?8xTDzi{( zruWyJfm3gR{klpKv?6?mAF%>3NAZHX`I;^A|1slmtB{^X2`Yf)F#Hy~<@hT94aYgd znUa?Q$XBJLU`=fOX)(t@VcsPLd&-UWaAMeJ5@+}<UXh)g+AF9drf-EYLRxRo<Nt=| zY66qew?<iaBIu;^Ov%H1m3~^`D@Z>7`<XT^{8$hV5m!+td!N&eesAwe_z@{B(S;zg z^ficv=K*-AiBlPrUvl3CKVAIciV6_CNX-LRk6!(T-ZKk}chin(m3?T1ic^<Hp?7W< z%be7=;xaym`P@8)OOSS@suf7r;(Yz~dIeuh$XCObz{Tggo3}{aQ)#Pd&4LBqHQQ!o z1DA%p3yx-y(JYmioIJd`;SJDXLru&^$9KT)Xlq74PtW}8)PK)z*FNvN(Q}ZB4E1(4 zqV=r%VEoXl|3~Bom^pXxxO%>Oi+u~9!Ot^__>3$3TG*HdAk3T;TwN~gYUZ<{E2+on zcEs&(2kCx(yL$Y~ZBkvp{kTvV$2|g<Bg!Qu#CvjlwcF!VEcay0nrp;FvFQRFG=+$e zTc&6n3H&M<Q6*cOx4vxMXPV_jpdhm9-$3oHHTOBWiVE~TR=SbleH(2EbA`R<=jnkj zhq=AJ^pjNJ0^7R9Nr+HY+*69y7$IK2{1a%nwor;bO;4?|gt%t&r|2M=l)Fp`dl)e> z*D!+^p=StpP@A%od2mQ5ZH@BladC7pB&DUc@q*+*zX;E<>OgZBDUzBdj4V@X1WnB1 zNNzpg11=B-Z;?2dAj-Df)Mb{-BthUe=@M_HhEk_`EszI`9rGdZ94pf`7lRpQI%=#l z`0)a?mx7q-A(sFpnjyqi37K=E9$2Ff)3WpdBSH-j`7tpRM9Y{lES1M%qMVK=jG<&t zRvcIgk(2o~Z^tT;<fMWi9!w%+OS2aVQr;4sJ)TrecU;WFB;;h4ejx+u76d{J?;eo5 zkFBo>KOn4&<`?~_&0}>jFeqW>1C?N|SI{bo21JDu1xywd11EYQs)#LDKsFmv3|A=0 z{U%7&_NA4&Dft2CT3AF78GMVw7XAiQ*$*s%qgFbi3!qZFk*IaX2pm4mMW{WbEcc&< z|J1iUXxdxJ`bB7c9yphA7XS@Muv<r5`P9H!W^7%{9tG1JgxRG4rbS5Kt1-l2K0UgN zzQigoodpA~u|N5l2)qWER@4kNpIib-#Uq70CamtGYwVdf81cc?Hk^j60jTT*?e4;a zT6UzM|8=Ee`KLLcsm@U<eOn!=%tx`bB=80D@aUw!wH|vfnR0()AtBT^u!~ipI-Zce zvjbK-E>rm(djQ^@!2!_+|Ne?^F3vspQ^qTftq)uVZwqESQ9FoH<e^TQrqCE(NH$+t zb||476ox7~(^vEUj6ITiFEI((WzW@HYeX!lU-Uvo$A<?4dp0SE|5l}bsHuS+BOhuY ze=jB5Q3E5?d#SqEWZ&K}PWG;2WIKp|!ym5I`u(bdeA^A;ND%y6W6_~gW+2}tAQmZe z`wt=@COjBqOUuRR=L5)Za`uXBlA}wxYdOgSe0t{P<8bL%t5<k#e2?Z#GT2n^;s~GS zTC*EaibH<S*03Khkdgv{m4gKdJDo`tPTWNpG!vgPcc0Y=$#g*B0utRZz76E`@uT;= zi8H4^nO_1FMKHiaK`iZP?>2_yIrAviDIN<(0(Q3aMglx2#sY(HaQUuI`jR1lmdO}u z4W1!@fPg$;C3hS!6zTr^sOECN5!k_W<a<lbu;e1>?xAZMM|wjD&)C6$C%GH1UL%oI z0hENJ&mS5_0>tT}=V8Y~VF*AfnqaS0VaDB1?a?^FSeAlefQ9tnfFHNaI9RbI)Lhi0 ziIR;4$`Tc%)3~cC=aGehPy___RWKS}+$;AxG78xKs4)^`gNhjogdJl5KmOHz+0A-( z27>fHYGLwB{TjV0XiBh@j(lJRqUlt%!S1=1Ui^oN!Y~>yX|~6Ei864)ft&qE*XSIG z)sCZ+DJa64xB1OW5Gv&+-QF>hs*)xau$A$I(x_FM6b(STdzk>L?FfNb%1lYU4HunI z+ASSR6iM_IMJ9!2rWb1$8|8)qGqNeB9T{(Du4`5C(FRo73yygz;;6XSK~Qr**2Qf^ zQL{>EvBLE;yP0_jNH!MyCVpax)py)<o0&fbQE}0>NC~lRjVToA6_#pX?-jvV%{D2W zp)N0=af(U-!<Ua<)je9ktV;J#0<!S1B2L0~txjA`q2ZCzDAg09$*h<qAl`qN->*qW z$yFHU07EQ-lDvDb!L<s)Ui??2xvw!P(b|qhp{>?Ilz><t6+o;a)NuCC!6xPqt+_f+ zpCJh=5ciP+uo}(5tw=ui5ja|15ye1qj`2m%b_BfDg$Y}ZirG}r2ytJ&x%(Rnz`zhX z<8;UowLm0dX@~+k!&&4&^NPa=bmrLv0=@@ZD4A|vdRj-aMZv5Hyt2gLtZW#UA%-(z zd;eA-nkKk;3dXWXgeEltEKH+uS5qz^mqg>4HlR{qhT)RG@vsw&y{Tj>$Fc=Iw7GQW z3+U2-n8$6@g()Zjr5Iy?nq$L{t#4hWFF#C%OI9YbsG1=4p$uUjDy4BN)u@F*dA<sh zhQwsGl?$7`0aX&LfF#=ln&nYR9?4B$ua#Mo$dN)Eow9Nx_g(~Lf9@)J@UTT6BA#5* z9O21U#pz?+iO~YGaf%5^#+D(d6?#yMr%H(e*xJrHq}RWI-?ZO(;EBAXpfvb3CW~W8 zx(&p}$q97khNZ)nK7I-Ccl&?%n_z#Q6c5m*2?O6W*As{bL@2wZSb$oBTbvEx!hJs| z3-Pm0#!aPMm7+6efo~naW?YDG2z-`sZ@bvcEia`?!KW2${WKy)&<pK1ewjJo99jcz zQy`(lTvEzObC|d25n&bLkgplq!06aBFYx*?pUFp{f`}z*R66t;V0Ip>Zk5nPG+M)h z${~@#FJVN3Bc@((8z(gpkad(?Hy#oq5E~}uhkzMbEfC=YLm!Z54>2=Durt~=eEEN* z9B?Qb0cyM$4GaYkdoIzz&lo_PZ7s2wNGMu@cS87eBoTTE#O64N3l04c-$ghnX}7uR za)t=l2EiAzK~N9sk&@eI3&y-!L5IJBG-<*K_fDZ9m#Z)hr9tvR{VFsU2MF7gD{qbw z)qt5AowK8Xq5Lc``y|p6Q5;ew!Z8I0Wf3Q!EN74dl%TiYRO3h&;nYD!hz47clDzED zS<oZp%~LKATR;#lU3Iq31KKI0TIGST(82Djnx>f+0nK=&oeUW{IA@g!`#`LEO3JI> zcv5$8)WO?CvWosilNKQ~XWIaja{OR{SoIY#FemiFFRA`___OANK>Q^I=D4G;8qc5k zARJBPpi5b+eM)b*<MD?;u;cp@Q1lwm<8e<{#PP&GISiUpiNU9LAmm+=f5kbZlnoDW zn4(G*2<>+R>gcg;v4cvfS_2epdqoTbM0f*mKPByJEs)cnR;`DQP$N~S<K=3liAHE8 z^~hr|bp`@+$K!A834NNiij3uUp799;xcrrLnxVuRyIr`GWCEOQwkSwFcsl9<>~J=& zKTT*2vOqQ(TMq+fl&>?*#SbYvh=f&%O7Y^XG%+1aDCvldT>7C`jZ_C<3H}IM7ik++ zu{@h*Tv@OfD#UlgeTRlHBXCN@$oCxXj>lHjmvSBZ02uN=2)B^uFVE_Nx27t<o}4Pb zx<WB$i?Hm9_`RK)E6A4q7L+aMm%4XJA?T>$K&{fGb9v7&gbKI9!c`+xN!AxzrzMqZ z2P>d7hsT&-uxO?##KK$1T(vEUN>$zmW6*omlx7b+lwD6ZLC_Uhm(=7|;I;cYSkX(B zUc78Ys94`iQnRx8W9fTW%*QSspVk<~uQ?h7*Z2EB`w0FHVYS5o1OV{(YbF2y07^^@ zOpJ!~?v{3JEcDKnwuZ*WrZ)8dy6XSenEt=VY#f}d{%e5V(#}=i(pI0z-Ofax*~ZO= z-o^IsLoTLHc7`_pyu{VU(#~4n*wEO*l+MG}#x_CMK8OJ$^e+9HpQV>|UJcX~FgCGp zip7k}cwLv0*2O0-jq~&Q7p<n-!HxHB&RNdUY=0Dv&!gBx)o%huMvxv8Rhp^c;IXxV zjG?#d@7W!&*B|V_f-;(7NPadYPllB)KLLrx6!c}93b{GeWXfb!P%03ya34u;SVZ$6 z#zBxjc>o<$=4;KE<2m##b|%YKbpf|lw}V?mAhy)T@SDPem8QnTZWOGe9B8A<htmar zh7s4J!V*tDmAvHU3^J{vHQN`vSG==fyUJ}}Uz6PDRARuHx<V}535vAct@|~^ipr#Q zHYLdMC&qVQIUwW@NGHzmXyZt>dM0FEzazK07yKMJyz`>J5%@>uZ|>Jf75PuDu@$6& zK~Mm|03ZNpQZ1Ad1HXKf|042_asE$`asCT{z12VA{ja<Kgh&6MVY<IaK+jIo&P+^C zsX5HbOVTP)P)yEA$<ir~%hF7OIV~|cD?OtCIVmAWE2AnsJ}pb5BrzjBEh?ijN&iOa zh;oLCY8q0Cj$(d#szHH){T*`zOEdld=tT(tKnRc@@m$~imp|=5003nFJyWB9bI8)p z%%0xV!^O!^^6#CKt)Yvhz1_c9ptR+b&4A!Lr_RvhCV<3-!4woTR?Cg4zlgGB`*etC z#JIjKhUED5f=V_~V*9&f$N5jriq*x=T@_27;CNA`aPs;(OTnqE)^hm#w%uu({jMmx z3+vdO<}i!asQfj6w&M8wbgGp-ViHey)CQ{ZTPGs9<x`oEYM7$VY{n=8BpC*>%=Gyv zLj{dze(T*;4Puu>yFrCCbm1GI5tgocN#Vsk4M82c#sHH|>=#R8M*Xj0Q_M3Og1{@C zlUBfGDHMVq#2p4l0M@C%d=vHF%ed_rQpp5Ofd=bXPJ?K~bWObhq<lmGbaMJGEzNe{ z+PJvJAIjHG-S&sCwFTsBs=0@w(6LCV=5U{7UAL(*$#2ZnrIWCq{fDYf9$q_~m)D!Y zx7K@fqeSp19FB(Pg&VSOr#f&pSmCH$n%@=g!qsG<7F^lBno2Ic`hZb-dK>X7%}|}% zvYg>aAj+{Ac-WK+fTH-u!n*Yub()}xitZmpo7`tyJMoieP7c@&fm>-Z&-!S&(VN)H zztP|u=1*mWe(wyzNm6*lf~%y}a@>Z+MnklXd0&I0e5I~V^F8f(oy&@Np%(N152F49 zKaRqs|Hxn1Z~vO=f5QJilMti-6$vr4b+*)ZHg&Qzw4wV;nkQG72S*nrh81RodsmnR z*{NyC6-9_~NgBy1`pH%$2nV>A-^|PliVk#AvNV#iisN(5N)FVMD)+K9N(?M23@pt| zENx6IiVT1CO^E=BVE~}GoSr`+7i<{S8IPQt#Dsw)laj|+0?GJD!s3f$!y|a1I-`?; zvYw%~jDebgHj>_mPI$Z*881evnW$V$CX17w*VSq`g%g>$yjE&lBYj|gF>RE!+38{| zlbgSbw|4o{W14A&sZhZ{Isg#(7Z;o)=YK34tIChxYJcMu@Yk&WKa1OcYO%huy^Wix zldy%Mow?~hOYr|Bnhuh(Y6=W$3@nXIEDcO7s{ce&<-eo(AMVxqml#I=b*tsCIsgCX zo~50$i<7IZsh!Kel;tmFTwE;e%$@&F-2A^u)5^r!#KicYq^Sk|H)(7PB$$*vMiY+9 zN6ixE-zA-j1jjx(AC`*BrZe25L}?fU0|zC;-#GpwGB{94{nzpU02&?u|D$*Bf9vJ{ z_Ja9;0q<h(pzmf&XJlOC>#Y;Bf&IFjm1&h#7A-?1+bIjBoTQU|Aw+TVJ`+|pJeoz> zqM^c!ib^zWW-MzLjVfB2kR_G9!>~+621Q$_TPsCZy5~I0ogDS`_5Jp|aq~OxCFjg9 z@9FQi`NiRd!jEM(MP!jMQG$?WaQ<&TYwi742673%_^EIh7dBdC%S@8UV)=Rk#k~#K z5A(6`p9m@o=5w5KNbiY<8bdCbr@<CnLMCbYs1H5g7qPhHO6p{8={ZZ=B6pF@83g&G zkX)PvJt+%N=B<=7M%qO8;OiE)JnkfZrV&T!)kEH%Jt_b@q<9gj;KhkHp>*`F)HeI^ z2anfh7Cz#U<#qElxvy6-d^u^z=Jlj&x_kjdk1@16bjB|E*=EUEjeW_Zv>Ug&U0RBy z80uKer?YJ7h3>-%r`{71GU}vyViX5WAMq@P+0{Vp8G1;>n>Nw~8S~*J-}YpbZ*mTj zQjOPQ<Vdlv9hG6_*Ufq3)TT&nP8qCcVXFq%HU5Qbkpa1PxME&rTuvIU6-$2yH-Ix3 z<vQmqInPm)$<8YaDdi-)L%qp3kEwvd+L5*w*BLmv*~i^mRio<$cIlq*-d~)5i{{b( znx@-Y>9d||gBP2lGp+M@c^_uazwPZqR<Lw?c()oGs7I?(^+fAN`+guY8hcK-1_*yv zcQ9-_dbjcj0#ePA)${5*RsAR%5`UFce*2+oyYA3)y3kEWiz*A|Gp#eI$$S&N3w5Gr z1~-mJ(W;>=R~$8---D)Vi<;K>>9J|h^PJ@3(CW3)epzJp4;6=<RdYfD!bK`y4d=1* z?H{?i=#R|%^)izHeZwLAqHsJ^Ga`4<w`cbHr22t!*WByw3G22_t%sbo@~r>f-A4WA zoyb)`*KhL#Z~E>rHWNSTL-uq?KX7xbHojeFX;S#tdve?WUL!%6)~>zg>s3DUk2;h4 z7+OO;r_RtWEs|%6wow&q^STdfyqsg{P&ej%99XGj4M*B9mPqt+$BcW4ru&HopMnM} zYmCnTmX5~29Rd~~GL!bmjaaB)FvJghyl-rEBv`D_uo)&dZN_d%LkIN<yP<gaC|Yfa zYc{;@M3dKo^(s+|*Ak5-L@a)UY+l4B?GWKZ+oU8VxlI_02BC^p{$S9ty_`}*tB5M2 z%eJ>fATHr804dC1S1l|Xh6;7mi3D!;N}B}dJ1T%yD{*8@Sc@6?=xH<mgmyyl519ZY z?*<$GwFHC;>?L%f{(`R!jhv>*s}eu{sxmHGbSrHE$n&<lBjt}mZd1$UYS<#5+XnC^ zJ=NrqUGi&HmlC)cdEgD>;}_)jWEb83tnFwr0!x!~%wRu~&f!q2!U817rB6%#B(UwX zXY$Ilyyb4}gk#p-eCf+*JMUvhF@6`%52f+15X`Ub$jK{Em=Mps`da*o^oL)$jm0Z0 zB3_2k@5-vUZIY|dND9wqzkP$>0~fg&e02B~{JXqD4WCwB><F;6=i8Rnk|azCNfrSs zaHmo<(|Fr-45jjt&JVEkyOwlEUk!<kbvLnAnUfCoaNM$Ec+*b!Iz%j8sed_z3V^dm zH&>L%Ro-VbC3BTJ9nFqIjGB=hf!~EhK#Z0_T)xLbBKCkhNfEm_Lwz(3C{Qu@Y!2By zn8%-_X!15S*0eTKLE`lYC9qsrZIh&qh2UHsS34#jRVGtu%dACXX8*!C`h~PQWUnbC zA|(`((U>=<@goO5V3$A&!ic=;fV^5p`k6rH{#qXTB@f))o3TSv5T;_H!DgnRcDUy{ znAX3gkv3852Vb@){g9z>z(@%DGfVF(`|KcFA}2+Q3oOBHOs=X-ZkpQUr=5v_n9#sR zM8_1<sF;H=AseAWlChU%{t7>FAIsm(82Y7R@tQGa2S(@NQ_Xd<kF>Dg&6ei+IOqzS z78_rymjqtFKkGR2nBhTTr&Ri*084xr0*j4_y>$B8Qi?$Y38TmQ`eHCehFvW#Rc-NT zAkq-4D$U^gy~?pRxhScLrz}8_OPY+$OGY|md@+0FHDEaeRuDe1K5Skin@sOFX~>S= z{PSqu4i!dm7X`-7ho|weeu;>%Z_7tXZ6_s{BkEImB^M8wTAKWnicBRHI5v^G%W0hf zQ(y%P!9XymqdRMdhW))GV1I!5P0H{YZT`BNPkYjk54C>3zA50pFktuFydT+v$Irm{ zndVnhXbdHMo|<p}GHObyDp%R6u~F&Rut<F5K<lKjRjI+_`(a4ybO=O4_0qn2BI?yu z?Md)1Mm7-9B2QVsYcmg7g_Lo=W|}z$OJss3Z*wEjvEk{b%Cz4tyb&9SIaGiCNAp&~ z!ERunXn2w$=bOiNiEshWC5q^_iGqm~C052D4-(`zapt@ToCOR~|LrvCQ?^8P(t*5E zVL&kol_z&64-&IlOB&x!K63=D-YCXyCZ;)Kh>LwZomsWl!TM}mXK|F?^ot%E+dzcO z&)RXB<^6ptT(<<ATD5qHNvBd1k#^UTxxMRd+x)o1G-Xu&0}0W~>a-&S<R{1zfnQJ) zKknQ&zDtGxet~eXCA4K}jl0egv_5V9<eaD8=NAcGS!J_21q+!+{ng=gv@<LK+B@WF zqC|5cOQEMx=K0Xxtk2ud$-<{S@A2)_%*3bNtD#TxlEkR7-5H~?Cu-QdS&brTyq`{k zmc$aNx>wU-2e-7(BuJ!`Uun584twY!26|!6lq*9Rnht5D+(^-#Nh1x%5@?AMFg)QG zk@T!4Pl?Q!L1PC;G>>>VO$KR2wsM*%+^B!kX)}+fjB|K;<L(wr2C)ZIFcN1Z3&=g6 z^GoG#g)45ZcS#Ua)8wZ*XBn+4HIG-7QP3t_Tzly;!4q&@<y@M(S8ko;)lr>F-^w26 zp8f&ml%uA(CZY<e&0z1vi32s5&S@7pAG&HT9*6FR=t0BZtF|%DYd%@d7gv=lNw@5@ zz}@MtGr4OQoU7Ef)U>SGn%I1Kt9nOJ%LtFzz@?Bgz*F!OE1B|S!>G~2BP@DizepwO zKH%vvRR{g;yFiyDhV$=>(s?im<Vl1Q%9V*W<ev5kkV0OQJ!HBD3BCsktwmFmym}DJ zITS_G9y(_CD$&r@&l_k&QM($$IS3YPuw)g+GIb932a90~uM&(#Xh$9)9_Isb%z>uu zq&Ecum#hjCWb|eLiQB=trV?#{8*Ro2Hq07M+cX;ls*uDzruzYl>|6j9@uk@Xityl5 zb3-bAg4Aunb9$&7RHnvFkGsF^NOL{?o4TOSehhE0jfMI)oJQ`wT^EjLuXX@MSIX?% zePYyN3R=LupyBP(T>;&M(u62lkAPxL8$^jSY5D0^XXI?4f3c`qq(qHAY7`^Iel-f{ z@r{2Yi5e7bzfp78vUBKk$>kVJfFNnazM1H+L?~sJQdaXQMh>@nkcyLV4Q*mw(eJ|r zGEl1FBvzJOh;VAYcTkUTcczh;)jZ0-11;t1(0x);mBTy0Arfo6fY0pp#zx)42mI{S zJy+V?&_O#E_|{NuPFnpDZtBLp)lg*X+?p#4t~n<T-Fi&mz&Asi)3LO+TMCW2Ae$>` zU83!FG{gyW27Dv_jXX`97$#Vm8f+%xx6Zj^&-e4tGkfBQk0!_N!0me1E-Q`UYob(} z7|GXpBbIjYOw)vzUxOv6Yo;ajqB0*MuEBmbK#+o+T$H2Ji)(m4OA^}Ygz(9u?YN+( zMe8YjXSm-Mh-}SWj`W5!%>1u4#i?LrDSQyi>|ee#Zesks&|2n${|2hu$DUa*sd6o^ zh8<kT1X4Mk6fONZXpR7eVR37z-qxo!TB6ty=YtfE=AP`jNN9qDAWGOi5yIm<_|62X zJZ=b^HNH)9T;5bRqqM1o<q5C;t!tCarZso%NOTdagJoQ^T(|~MPSbQL(IX@02Kf;F zAjZDGRHNg$C!@Z(>ez#Mt%>X0lyPJ^A0qUVCIaqxZ!v^%q`A$)<W9bZB35dVpBFLM z_e+-W>N?_npEI6nfwVogVFE!DPYK9_EP!6Rv_5eme7<+UM8))Wh`TMELuMfk!d+=C zX5N8OIO?;IyV6!9Ovxm*o&;u*GrzcN97oU@el}>YikQW&c2TPo^kSk`SxenI8_iKA zU13Qa0HfkVZG<ClWT0ho;2JHU=I-XMEBSrG7JANPW>{oy*6d7T?qp8A#7}X<j-U39 zIu)BF*{a4@-zA+XC&n-GiLRS>%lQ4%*4Ge@oEtrKnMUVanX}%C_gz;we+^P%%JAG< z!y(}+H*PyP7qLSxjOvGNVyqcjHqeFM;nyW#TwHglbD>}$4ps|pz-07=e_t-&ov?fK zcKJ2v-0NPnDpfK6oH{z54&ISZ(bjy|&=bPeYJ~;Z#pzp@wC>Y~Dw%z0?z7fn{o;$m zyMVa(FNgjQ{e~qv$je{G9gPkfSHOwBC4rtUH0^&{FG<978RA8Zf)cam%?$YK;%~5g z;<<l9r+4hObh<&bzef@h9i4BUR^xmqobfX`+)L;TPv=|G`I*4|mjiN>BNOrd9I=3_ zMJU+UC{o7z$rv1tLm{3c+KH=D)N2CA<@}-|<54ydnR<b59w)+5WtO6;F)0$<P^06C z%3+Bu6)&P3=~u#~4m%|*p6~iuNfdgAz0pYOQcKW4&rmwr%x;-N*Sr;y<#1N9R|Vmf zfmxjbxsv5X<vvfaP{?9RlmU$A_#G4UO&i`PL`wgh9{g23tGs4IIx4sZatmC?kHu}U zO@m0;L`dz_sbD#UHAi&k{Bx`QB!Z}}wJl;)%U}*)>Co@QU;_+uDWbH=a4;N^0@Vn} zPw>s?oAI;V(2rZ;oXI>is{J$5wok!X65Rr2^!_+)X{b{|+T)Arm}P@mrBU=E8>T&^ z87$9JRaP2yic+P^Ga_}WXQE@iP}wryV)EL!W7|U8Z8n-*i$tlWMG^P5+=)6wO+X7M zt6|bZ6zZro$^iet=w_IVKeC_eF|dV4qRTutS=+o_%c`5Klfm^vY-@T#5PvLa)lAMD z2l<;>>G<kqsLc;+Q^Tf9%I>n{J^Y^MjJFo0v3PO&0$z>+%x66vzrDcY>T@n)BU{C5 zBdad$PQr|u51FS?`L<y3xAxffyQ~`gq?GZgF(FOA1htsU&cwwfpQ7&X`pEA(bzGA( z|Is8FksS-T#B22;zy?Cc3iC{JxFzC;GV(PEh6A~I5$59SLy1e*CC<Dg$dq_NB60d9 zR`K~e-oP~5rRrU`ACC5Jnzqv>ljg}y^&MQ6<|&b%&FarTZ@^mSHz(%FTDUyOzM~Ge zC>sm8#yO-rjBYo6vg&a1^WQfNicP6L%1f@-rWYkw0umkgFrPV?4ENRfGujHAW}^#C zQYWHuvC4%GelIPcE-X=3wtt*rWNz1+Y;<ITc%!j-qxt0i&=jj2C=^YPrkI-G!3*y? z&aH7mlY7n)-;JYLo<rQxaBDGtYLXKYvd53o5z|F|7b*Ctn}z<QO^&;>hG-4=WIs6< zRC=D}TAieq41cD*%v1+A|A4-gsP_sgy@#!}KIz-VJiX9TT#r2E<NiS&#sW&Crw}WI z*`G_?g4@q`#2WZn@dfy~-Uj>(ee5RwA@^ru68JVdCgL3V#_nwNE!bZ5Yuujji`?Gf z+g*>{Bk^Vm$p0_{;Ey*N?KiO*ooi=3k_TuvdbjIp+Fe%(JXMcy1re#CMI93EGa%2B zIdUXr%+y*({e==_l)W;>83U=MFECw=v}E3MtcBt1L}&>W&pDOgxkE`31nF#&fSYWy zLiU7CvOuSp?2&%-s&YbCM+!QWum77z8AGiu=PlUqTD#K;z5q$c{b#;L`9bsY2~YEG z0cDg3n%agKTP2Y(L>l2n5%251*E(|EC0np4K~l>)O;A>2B8x2k`B18}vCUEMrd}od z*o^|}AfZNQ#L$RW8QdN0qg*hYf{Po(^>5ce-?1sIH?2z`IuBlKC1nAgt)`4&y>;x6 z!?^7{0L56YdIaX#mr?m5Imrzynbs2pl;se|)@4x!Bw6R}==DO_7#xf+NU%twvKZS9 z0VZ8gV#hkEdh0_+(tfxw!j4T1?8V^-Wk=^|Ly}pfjrLxvf_$a(Y~%j6*ku(OrW|~p zc}Z3+a%I=PWu`G-nTkU~f+HdmJ8ah=1|})G6M-#ixzcXxhcxlT(1?&F4IGDqo)<}@ zDJE>`GR<p8E1_V`$TYBBQ@{^qJk#J=E!qS2u@X-oGP;7}#?r6=4*5UPdN>cOZ{!vg zaU6oV%h64$YVa)<L<IOnqQz1Bi9~~=x3GtWkW8oTb&Q(drmL~)_Vc|D2D(eNcLwiw z8Tdoy%6wWOs6Wt8uS?q$_dw)b(SM5F2h->GfzVafWEWm8W3qGmbXMccyf0k^1=JNA zyA`MV%D2E0`GQ}1%HW6(0`?VB+ao8zjpykT>bhh1L+HnHCufM~Gj<X31nR_A!pcey z-9ic()mZ=<&?V2mBOuuQ)wX>>4CkE1f{VIl{Pii^VkGMtRr$Q>@bYhRRJwfNJMjiF zyxVCRGo2eccKlD20dJMzuP%Ur5iNJ1?+ooO_x^bL<i60t;pB1em2#>Z!kxtZriFO2 zy{n=keo>H$9g93(ltaiaUp^$C_M~s4QJaT6&sPAJ^z!-vBcAkTABRCf9=ZZGy54$| zK!WZkFmXr8UFzwcw9(>+63l%i&k!fN3F&WX<dT9AuJKFB_X(uux0=kag<ZlHJGjRi zxv&(;p}UP-TI#I(I&^`Q{##z=Of&0_2jNOpuy>m^nC*k!0cpw7J$^nWZF`W>d2%{J z5^*|t%edE|kM{=3v`==jywEIF9pY!-B<&!LMK-@n`ALY-^u!X3uK1HU1TH@e4*k9o zD0E$7lIOPU1NSN|<GHi?R#UAt26Tpog8oy8r-H7|v7`MOV4s_d-mWJB>MF!`2>wID zkuK8l2qOK^W`e{skOr<GfNj1V7L(e4JLR&CV^Nnb%D!0QI<qhA$gHI}bxu$<A8f_5 zSYg}So)3-7YIP);6FsuJEYz)#l616#%+D@0yk6VQwGTpzE$3Q$Z^x*~cofKlzuS?S z?CvyUGYD|L3C+ea+nK+?ua!dV2Cs1xUD@J1O*fmJ979%oM|^VBG@w_#(={!$M-RgA zPv3y1g-6xbz$nJf4l`P|!Q<pD*zN5vp(nO@zml@QRlQ>D5+MKe>-dn6!u&Utb20pL z?WX|lv;#pRb%c9^bt30Aa?~xIe%+pTa<4J1|0ULU5xGz4bofv|z1H->eq8F+oGwPj z@0Yw|`<A{@zNw9Wp^3?9a^l$?)_pxM<34|~;`--VQ?Jc8e-pcnU-a~Pf`7o!VY#x{ z=xl30iuI4i>Fg<gB4^_p`p%91BwfSXOjEbbH}-~(uwV7`PQs5`+iJp(Ufb$zFwLr+ z*|uJHzSOncUMsij+V>f|8@{PK?3<vYJj@&BDBY)B=FRwtBZ~5OV=LWfLq{*&r>Y~m z&TI8ijO^R3(@SE)5z|S&1J+!8Og493KcC%=$M-~M*{9`WE3vf6Esb9%P1?whu3O+p zeag;X=O%U=Ua2x00e|YICj#_ov#kgE$+fKq>Qi+Y_V?0pSrxX8g`$Kk?6|52Tt)?z z<6)HDyH(<sD*4=%d_^nu1}m42D|aVV<~Yli{26k;hER&4<~m~_5P3cW(H_V)hO-WS zmV$Ng>qU6pK$d9$XK8#B+o&Z|iV2AHzIWujFk~8Tg%*8wpk_8n<|s_Dt9~OT5P4HQ z#VVas7cOcGNQFuffl;zpv8WXXj;C}c%|uch-#s*Hvs8PpK;R`NPhMuFG1;?Dj|$~o zGk(2y7(D<YCNo7q`G!ysBXF^{iKY3(pAAbg7A;B;1-dUGXg+>H1Sj&!#>vOl+DcU^ zu6xVJ7`%^*KLK07H^qUIK7iHmnL))FLX2#Os!ttF6xC)xcfNa>Jyw3Ax7)H^E(c0) zjKEMTClHJ<yw*CfG4~~f2h>2}mEOF-$BSo4ir!GS^%0gGrgL}!c)h@`FpN5ITM9L1 z4s1{1VPPXC;w+H3oH1B&K#DCZ6l92h4O5mi8Q)MwNzM-^HPxX-c;G;1c(~)s13Kj! zfEbC9lT|pPTc+0qO=9qMaKiZ%agb(US&J32pz_Zev<O3g0}Si_GRQ9sW=y63Mz1z< zsYYs%d*Z$VJ74?VPc947Yy)=i`R4=Ln3p@)P!kRQAX-QNg%;qwf!`+UqlGP^YJgZA z{^;guuQ}Zz9+{ZK@dF9=d73FG={hVl436~k>PJe*rIR_SB_ijS3%?Nqsx;-&mock> z4!jv=snwv!Fm4U$Kn{K%sb2<I3^z5A+dDg9MphIp)x})V9pCNQ7_MLY89@X_{j$W} zkx7>6RdV8EzEURtn>^Ya1(VwQ$@YCP<>-cji~8*#^HF!PD}{L8;qwlchF%(!<}%<i zz62;*xD+wZr+5UYe@R0&M=T~ht?Po65=jv2nRF`8ZO{hQ_EKgKc&))RPmke_Rg5t| zr)8*J>r6v`{><=09x179hJTP}k?7w8{H~o2`++MENtG0D%I@ujA`tg_mB-7Vz-t5^ zOWIiks(GSM%Tqi(+gr<GFL&mA7*Mzc1A0<L0?;QkVMKdhm{9>-XBaMYCv2(LxcLtZ z9J6dUa6IN13?twsYRJS|e4QVG0Qk(c2r<A+cQM=1HOGX)%y?|ZyD1T9>$~sm;8ECN zi}TQvP`goWx3?H{u95-Cz%|ximT~x9-8)X>$5KZ)@L=3Drt^%`;==TNNZ~|$XwUbE zU_LObj|au^C4_q`zsB}}subZt_Y9%f{wOHG_>>Iqpu^8IL%Y#tf?bos92NEij5+C! zL-V+fZJwcUkCUrHWh24@y`R*Kjs$2A#t4*zD+(qd3JeO+f|@ge7UA-u^nm$lw98J3 zOra8+59b3Hnv(0!I}Hxt(egu;ZOMtVa8$LyeMC5TM<QM%98$R{$XOkS$KH*$j)=Fm z9#15~8ugwH7R%yF5gob{<ur$kslub#cAGY-lkzse*3)=2iKfI_KKcy1Gf*?VilLf7 ziioX55U#hPO%q|po#=?9+@!?2ad1FT9FAoXh8d)Lhu$W`P!SV2zP!UUF0>J97y_bf z)xOwqj!bn@_#zz_q9$87l_FF_MN+!3qAgwGF_H#l0JRu#nFOFdYs%OgV8qzTQG5!? z^rJT)hM$(82izLS0<V(e^aQo5S+iS@8Fypu8MC97)->rS5~NZ7Ht!V$THoCVjUnp@ zz%cR$a5v^`W`xkRJ0uW^8Ff;pI=>x-xBHepmKPucN|+F-l|h3QV=C16Gk&be@O2IZ zf_ibuh7^EaDXxA@nFtGe&DbcXLG58;)pCd=2zsR3*g585SkHzCPr#DWj&WG{x#6(| zvV6@P017|k-}pfG2czETemLR~WQxSuq(|NhyWTXEht$vaN+pM~Xh@@q&UE2^UW~~z zEx?3mI4#Vysgg*H^een##6W@8l(~jFJk7gq)EI}kE^+zA2rLQZ3~rVsuw<B^l2S`j zwqay7*mG!g2}j1iNr$>pGfzS(2v3qyP-$c|sh3VdDKEn@wuG!Yp(M}tE>XoVh;vEH znzuSOp=3ONM>Raa>nuo3$vBS4z4Sa0Wx~ryL~XHz7fnLxHp6j-q1`W>#MMzNz65K) z%Zuch0#Q<GftYeKjm2}ocOVEnkrblfg+Pk2#VOS@*NQEmCeW1a59cUOcg{1ojSR0S z!{Q$N1?Gi)&;<&9t&CKo43?J(QI-}Z&n}F8W4+`RdxQ$4&D3QA=q_YJ|9YseWrJPO z1$*-M{TlZK@Y$6yP*R|-u|psJz;o{M<S{o*vO6ymqE`L>j9;~5AG*&6Y>}BmU!wCh zGw(df;_B3!*A>lvfN^JPi7QQ`qNS5usu~$`ql^jtJ|=e>jqtraJNbduHHL#Nqr~OT z^V8kBgi^e>B$e@i5lQ6-@n8SwGVm6OEA40~;SM1`M4Gfq@2~mqLw05;X(+ET8r1E8 zB;VjQAGy;|%yft;<Gw*jDkp%wNLEM-qP$34v817%Lddy6C9Lei#gwek4I~Z60?I4h z2`ZuEjK2qyhGMMCwv@R7C6rFKT9b-~OD5iUle9uio0`RyU>PF(-YOgiqp$z^B)=bo z&-(R>*u9T*{J}!k!RW@~G>F~PLZ<=ABq^-WC^KuEsq(vH-+kZi)(Tva97*6#aJZW| z{^I~48WLN%RE*F<#M-P%b~11r^anJFP=~?t9BP-g7TT{FW6H!c9y%?xaWbog?)5mX zFPMU@v@(N-)#O#}ItbUh(}1Hi2xkf`0p|E&pwS^_%xS14Zo~&B3DVRi9@>rnvW)vX z>}`J!{_r#D5(>n`X5l7<lY>^Yk<@p+eBFKce0`2RLMQv7ZSzR1l^2qty<~#z!Wg_1 zd4lreT6h8t+_x2z_DHlk)*T0LR64=_hdQ+@Tp6zhV&O}g!{rR?w(_u6c|Gs8#;MbR zBWe~u)gD-`D4g_^I{qZskANB>1%=#JIz^}z6jW%g;ebct=BD>?9ZbAGfktA<^l_+M zSM%@YwGWmOPCT$S;P*47J3cNJkmAYC`*P<q1N<RwoE$!(B>_I$DE2;lH%>ZhzBfqE zIFp|v1-ciHM`H6!XxkW}J|PJc@hs1CfQVUQ<8$?8F9-{SVyC*h<3r!k&QsngYP;A@ zM`$w<RcE;8iH)<z600)d`$sNV#s}>BpC>w|Gzv1*5qY7I#SoY_66-}P`BK`=016#8 z?6(LmxFu*dTu)u*>XSRT8E<hDAzpH&93c~nbT84ye5c1}&t%xqrQP}ciV=Mywm14< z;MCD@9-|oUH922IPE`9qiaN>{G3}8y`uEWFllzcdY3%ZTZS(%kaCgq4@W$N<ahCw0 z$ggCKBShitO_`mDujHT59KNQDbHp1kNCA4(%NRKnSqSekt~)|!YcY|2B$k~#q3fQ! z`2M5OpQTuX>WJKVU9%vzEFOwm`vOzkMM=_T1HL7I^000*E_l}5G3gbAB8Cm?m&Wh} zqCYyl;ZG60X<y|)S#oW$^L7AV45)4fJ$%>o2;pCkh2?G5r&i^cp7{Z^8a7lJ4H!8b z5l&jh(I)S&h0wNu$cboiZB$33uQ4QxL(Iw(Vc{=VbZcfF!APTR>o%{t#)s7$OKN9c z7Rr^ftWLpBcloT58%)tHoYCE%tz@^j!A`wB$Now4mo#a<b043hB0UyRWnK27&^)HY zjTOZfx@v;1Uk3C6{H4?LTACtZFpCR-b6If)-FGV2m!G_VTU<0Y!f)fNp2^_<7jM_p zTnQ7VClfoF*tTuk$rszn#5PWB+qP|EV%v5yv2${E_I7{3UUpY?z13aS)m`tSjf0g< z{FO#N%dp?mc~*sEAu&&xI~3HPFG7<6N(yH}sMN*b4Ctk^d8t(dtl7*NQ!YC<U@`xa zcwngr<?+J?V-%N9w9~I+2_>~Xd0YmG6`XU3+8xo@{qV0iSVW}}*O35IQ<-c+*QRyS zle%E|U7Ka{ML)73hrbbd3iVmKFp;~Xu(zpVmKkC~G#c*Abo<o4-jHC_<i99KL;f?O zizejso>3}Z{Xr}JtrSxct6R(kH$e32EKw`Of&Z`zCV)}%M|?3HSkiGzWah8bV#gW) zSzTwk&g9UK6KDl$$XD9&w3vpXmvO44-w%mV1B=~uCBPtyc|nc+^_tD`2fQSrgP|=h z8&<j;A%J5}e3{)!Zz<w0wD^*XyhOrZ^0M3wqJE<^Gh_F0G6h{X42}D(8N#vQFe<>y z?fJzCY%VM(%?t5Q-K79FiAPPV)!jilrFL+h-Mx`)Wdn2}#ipx(@&)-zh>_Q?m}EB1 z{E-O-Wm+NNKa;)X&{6j^P2qm(*iOT?XJ+$jV+JYhe&Vg)>rGV%2Val}A-%s2HZl_w z?H*jXsx!Q*bEG@tN~wzya7|s}4ET%GixaZ&4kMPi2@vQR9T>hCur5hBIAeOAVR)@q zGVZIh$Lb;GVx<G?X11ygO$Ks$oebWG{4k|Al>FUPY;-sxVrenK;&G0^51;8m{!7qH zB0tMiic8~D@|rafKL*MEvG9L{ZYs4S7FerY@j(@dP$hic4Q_mGu|R2f-o^0*$BAsj zlY)c{k`N{n6a|At32wNp66;@zTDM(^+q+ZtT29cs$PTyTC!7AwDUaTThR2Fk!3L{H z7%RTH)l~e8%brBvkGL}gufGD8lOEufP5hjEBDb-!sj`k2a3x#5V06&pesO6fyETgH zSV!)q8rV4-m-2ujWO3yF%hu2CX5B}{^d7cr4L49`*UxN|$@&;P%fC0YFo`i{v8-b< zi^hjBP65Xmgg3jbg2ZHP8#PuV6vnDrm^HmD0xZ*$ekZ4n+O37cY)?dg{zH>bKN=sM zMQ%RIFKuu$$yLZdzTD{b1Fo$I+YcXkNG7C~(p9J6z$wtS_PYjokIgc_7HZps(&`ku zX=Zr6H=mvcyaG~knOpk5&c0+;I>y40r0b7bmAOXYbMSsTZiE!#9hR_^y=0?z+Rc8M z$TnFPB0ex1;b5~93~i2oywMlJz~jHztY$NRd7*T;;W82?qHW^Sd%qNy)grXt?JgK? z^(39p2m0>w7kZF0+{ZLKiFp|%PH)J*8tU4Lnk;amCBPV)%GU3A8}V?vYYKi;d^F@& zJ6HI?8a>zzWZ&XjIz^&*D~oO`5UDW)UoPL9wywzVwhLZ&Me^XW9~@y|P2+T|scx_? zhPxehL|$m#xiYhRQSkN)7gIx>7rXAHaFZ)WQI%W?zVQcr=UHU$c!7!sM>tGYO77o! zkk5$C1S4J0?ZBg<4e79bg@`Gd0+V^qapnES(jm7)-yPMN@g;(e<Rq?}*lw)xp<pP6 zNl>HWO<N#KZNFRmUA9<L)~&UkVW;I%F%b&G&aXd9EgcI6x}@X3Aul7vtd2!2uXx-f zr<YEDXEz=UB4%(N$dBGTw2BBP5$b;n4nOp&bj>0_>3T5^|7RJ_Y_io*m)T<DwU7>m zLivYHs6CGOR129U)ns;s3~;P-`!16m>JpEZXd)>TpVu!7?;i%HzpSnN>NIyjxU1jM z!Zo+nCJ!owR?f{(^*WBfTE!6vFgX$*%2*&Xi33DqD<sB26*|twRL!SKalV~FX#6Y} z(<Jdq9GWxnQrAk{GI+0E=89|>m|W@f1M+J1UD_UNcf#!v3;^<v6{O&35cB1!$xnQd zRsLhNBX6JiFMjtWH|+@z)3ub)Z!*5o%&RL+L^h~`Tf_CUMeD62{G-W8F;1&>HZMDA z58R$1ofCK9V(AP3t>z843fGZ~*-%H?c7TX@aoi6@5{j>*SFJMck+IN9G7t+gXDE)o z1uu^M57-()qY_@DTUp4zSFkO@Xe%XNpqib7H<%-PbmVj`9WDvK3JJfIj=5bIi72!? zjX4~~m19fC`rQH85w|BR6kqYunTDSdaRoC94(1g}<{Bv|^`{BvAseFrbCyoS_^Hmx zbl}kSx3NugC?NsSDN9w54H<HK4)MjX9(FF~oo-dixq8rIUt0OUKL_3gSneP%v0MIz zkQIlt0<|~YnqhPJvt0GFN<R3shKqnP;a!W{4qJsWPL*8F2-VV+2{9dEnFcu__sy^+ zVJv+7q;k(+u)0-XE3%*&KAJHndsLr?3B<w?nd0uVDff2W`wNv2W#T7&RN$8T0yy!| zWNY%4t0l9O+Q1I?BjsdpR*b0xuNp!xWf$Q*hl<mkgmHrg_a4Fe6W!|@8R?~<lAMr$ zC%Zr}%4}3KLG~w{r4z%i+4$Rw)3HrM*#6!-xgZU0x9IO#r2D-ZjM+aJ*?66_#G)O7 z$RmfdHfpFQ+QB1DT@$3vpHQ6y=aTofE~xDi(YudoYl|{Z_-3%~1*zOfE<X!X8BD-T z_P1<E8HLD2C&Kf}*QEMS%T{e*;)Rl(%-{szz02-CpSEQ<Edyb4&towwA5cDowQaL| zXFM3@JSK#!)s^2BEZ0~u8e}g-hb$*m`C$&S=~5#09K6=VgWsx2#a9DfCId4R?Q=01 zZoc5JGM^-cryBnTztC^|EbJ9_Xc$ivDnz#ZITKydww<E<U(Ko6k=I<18H;6p4}416 zWI!?je->Z1vL<(A;IXUvcUGUIO5yUx54ueJR>GatuMRDjpvCXT<-jfUEDU&D6wX)F zrU2B)Qu7VcXG`059X(smS6|-)f<}-ag`7)W^LU4;aSm&MAY7(uoH5byT`ZWW0Tn3x zJGe-u@{usX0}6LBJ-hvhn5zC?OI+t~d}6;?7)X0Kh5`G1AF48{amTw6J7LLR2%Dat znDth~zTG(cH*BD<zu_?pxj;yd>Nl5wSfW<Z65ROICH=Y0%wuqC&Q?wIexGjLdKfog z3A$7GmRoXGQwI3lw#7h6GV36Kr14eJaw#HsF$QrW`|%p_$mvcr3rI9R4mZiZD90$5 zb^V4q=1af3z?(5A(K#-9mg*d((@8jh7h`-r(7UCV6l~I}THLbl&)`Dg*33tm_>i$$ z3)XYC>Xw#`7a3Q8ei8A{D~Wd_{EW)0t)O0jZ4X?z5`+H0cswLL9>jC*h}?T<BRgKa z-W`Yh;KA+`OItPsd{&H(S`2sr`$?i)7tRTfSvdGovd^U&XJ<Z$`^ksLuS^UV;n5W+ zc<I323ro??6;30kT5_hi1dgiu>^1@u!k<O*N&y&TM70T3PwnyA^ianwr$Oc=WRsBs z<IQ~TktXL%s1NUciCBs2T4#++=kXYkrMy!=ypD=#o&eM8xW|b-9NBwLN}-eP$;jbm z_cc9ufIQiDE(aY-n8ZdS0U}!dGI<`_vx@7B--{|Yln&*f(NJ|E`L`B=q7>;om9wU_ zURkcLRIX%8e~y$EtXVhSK}q{4U#uNJz8&3+snJi%-KT|MbnI$q8gq1lGD;;-uPo6A z^P_a0f=-1|zAqF$N^L--lr$EyNgU3x>^Glym<bf0i#oPd`|0?aI-?!buoh3U;O>`g zg)E_AkLHD(2Xi<BA1zy&ZC+cFCIRI#%Z`NLyoG}+hnkZ-J0z^EFc}5I5kl)j8BZ2h zxbsUS_Mb+<Cz(@>LLJFyrOD>FiJ5@b{!aF+JDj0m%=g9ej9|TZv^!i;GR3H#1z%J0 zaGn~TmXnG<C*zeApGM0^?D9cG`m7b)YHY|2mQeHMNTd(s8g+Ffr*N(ztux<>lg=wL z1-ThL28l>an)p{>ZO;MJ2|wCy@jkjltSaEMoHpRWFYE;dhDuH`AQ}WFPZ;_WI0i`Z zbnF?iKrpKimJ{6;_Sz1+P5*rrW4hC{+k3%zSMn0g+37LziM^2hzU%)n)^Gg5258sw z48t#BVS@VXP9vHyhG41Y7D}93OecwqDeo*MJKt{~9u-Oil;$&2X~hT;uR(A+yKH#m zbg6&$N3mX%LOsayUPnH}<U4->8)(dd<U(>nvBGXMX69Md8W<o5aaar3jrdUVUyy<b z8JH!a;qlv;Zoq>xVZ)lcthI-uI@5Rm4|X7c;V-%XaJT*RGC;)mO?WblHL9cAZ}`&C zg(x?ijmDY4H_v7-KMehLwGrOb>>TAiWh0QM#ND-_$?Kyd$#X5+fBpfj_-CBuiqMRq zpfj1Ewgd}~FsIjH4G%W%vZwk76A(!d{}k%X+`U~sg}+Dy%S}aL?K{<RbLsI#>S?RJ zD#BFtWUL7K*2pAc&IOCP=QhJV&vOz~9#!Oe+k^8R^Z^6brFDIwj&L67(qwm}KL=SC zN3dUwkkxTDv8;k0-sCv<H=AQvDe{xm_xOS$5(k+;Aa%80f$2}U+mqkvlJBo-UXaxZ z_Qhw1MHQbp!MSu|uu)v%fQ9>2e0L8&0fc^vi_(H|GdX?OQ0eLePYFR@>t2*Xv|a4( zh2yCgF2#O7)7j<3-Gt`whLT^!20ofp^@wtk2OYlRC4HONnYPsdB)Sv4D5~a(4uvcA z<CF1v*02qC1Ui~8P-xFBn(2zsbv4rKpbKak#~iI{w%l4MC=fp+5p`kj*mp9$;K5#% z<g;Wxt2Mj54f6FUd7;1P|G<FM`=0YZ0}q-2t=ziZyn{kEaxuwlBrL@6W9VMV4w^^o z>n2PQC%643Nxgg~da}nCpJrx3XWfk!;dp&TZ0+miUW490&Agw_+1DmYL9m0QxA4iH zsaL;~e&Pn3>b(3UgPqw}hixGg1R#x7Oqr$CcisIlGGk%!w{D*BYs}ZOfWTZLxaS2K zDkQH#yQ2(`Fx`cNQj$5=CV&h{p{W7<mkejhE537uoXuyIAj)F2DT3L5dKSXGCmwZz zOistN&863OhpqWDha<RPdRcBC@s-4bN^juxK9DS$OZ?V-0s}6GN7ciS9Tl5HHPgJl zI$B4;J*N2&KSVDfAtc19tAv2OkeK$l7Q32(hQfx=TG}&{xzZY4IyH@?{*pn23R9&e zIq~uy5mM7g#a8j!FGM)D2xHg3D{w!J3dMIwZ~1<h233VgeHJ(0+7q3T7Z;kb()F0~ zhh=n+Y{H58;ynw5Rrmvlic@-ah1orS-y1BCEpWRsz#<er;bdvr`wYzY2vPKiw#RFF z3ap?g&b4oxQ9*w%&e4tVd+QU1NZdJ9J{!pog;fwS!#)!*F~h3NF&Y2bgs-iQggS6O zj$eLOf+s|C-qt@#T90qusmJtJS?OXxEzWwN7LY=MM)RwlhWdOJ(74^`H6WGDzieqY zJ)Yp0V|j2|c!qe0U0`LUyuFYj;6=s}cMgw6|Mzh)2HTU?_(zgDAFyP<{M$!pxgqB5 zwQ=mEf~m=J8D}M49wfhAsh|^WD7VZq#C3jW^tbMb1l=|OGKqW=k)6<*GK}j;l8Zs- znEBGBOAx@$clIb%d5=6Jnkd&xAOL`IE-}Zt<oaCI>kGV(N#-YE>e%h{IF}DUocNGz zQ~$`jIjDuXe3koIPcoTSF*S_J$C3WRCZ8RgcSiU}Vi#6VZ}N|XKM5n;H|t-v;gKE~ z;e5gl4#h-UOX7^oO9s)C@>>UO@xsHzQRUY@PIL^rdvr3tn+I@7Z*>pmqyug%{=Wcj zAddfzlLJSN=c-~(ZXc$vC?{HJID1nj`Zt~g@I?5r)+-FG+NFqj|2av@?5#<Zz#o5b zF15mt^eyQlboE=CB~#r(7X{-oNXW?)ODnZNBlH4vs8PQwd9W7x%SOCJ?oDC{$<Wa2 zcl4Nx%9!_Unjm4~oeT?M>}(QJuI}$Dz3|hYSDWz<8tf;_#zftYQbJb@)&zvB0jH?# zNbD+h1eRBk+m#$Vbu&aCRP{L5QI_t$TJ9T$5tHtF1Mv})6}ZjV;^uz4i1Oy)$7KGw zHEod+_4(N{U!T)M_AJk@NsjS!25k}ba*Idu5O;-H@jfkeAQJd|$6Bt%bhnjdOUvCY z^drL)QlJ8~T+bZOol{a3xCUb0qYmRNmgfWnax^Qmyyiqb%xOm{<_nBP)5k7S$ioFi zE(uI&bqhrQ_eRlp??UYT$ei?vz;j)Dd9#-*OB$LyS;Q^Q2k{x2L|^^Xd($_$LT7HD z;0xV%MYM07^??V2be4pJNEX8pIW!J;+Gc<n>M_WDa_!%ywVqd0!bTQc6@HYm+<MQ3 zIYvve3PSJ~t@IP9bzJ`dlH@hjG|9BG=xbc6XA->FZ_MbHq{_c}BW?FT=gY$kZhv!Z zkW|v_75)H&1RCsReKLXfJ*y+0!HZyH;*h_sD<w$>#``lW%m-s3y7GB8GTlLVlL$l@ z=tYV$>70`tNTi0!$>iTd3>pGYz^+%;IX`~gX!z7(1IXu@;-Um<K&_|U;Cd1nBBFO( z!9UA_28YOTHtiqAY+E<58(<m~?HbBh9?dsmAbUwk+tcEtBSonYg6JeY+VkSeA$fQR z_5O2vZ2{wz^bi)jO4sO3HCVc#A_Z<J-R1`0Bf(&j!1v?lGQL+?$l15mCA=)w*m!mm z`uaZ?;Ym%58DPw^u-P&Gch-Z=j~=@Gte&oP4r#Q<-M!8>l`uw=1x<u6L_7yo#P_F* zhr#`-DdR3wI{$1J2f<!(aYu;X+9tVV9&}c7#3^S<7~5HIBW>lQ{#u&_juzEVnsfgv z8j%&v(A-b+#9l)|`Sn8#)$i1#{W^?ah6551P>EO`8Ohdi0*^Q8YtFeyBwuEY%V@25 zD5}sdmHJHQc;AALH5blTFsZrac;DsA@*4^N0>!ZZVp^ap8u7Ke;b2&8B7gd7zkb+3 zb$%Mxz>P;+DWV3(*2jRW!sv~%CjKv8vTC;x0wj0mFm+$0J#h@VE12~Xjk?gqqc7bZ zQR2f=%5Y%aym!09KDin_Y)%xMj1e<!(PDZbDUTxtEgZv;a$;p#(P5!C4=qwP2I)Tt z>5IpYqpHJ8oSsf9aqZ6<ILT)IVy(mRvO48yM(zdELK%MKCH&E*x_VzXV0e=u$;aC; zQ_#H?sa@0*L#vKq65ALqpY|9pMtn3?;*G`u%%2uNJm0z4(P;uz(|}`0iHFJ2N!u*Y zj~gj6TK4ksx<(=U%I2Z|s2$Sg+8BGN1h~QM@XlkKR0Rl)wBHTabfD<;{*CBv;5TaV zb||>ioj?5Xc+nqV^v?@Hso13Q<0oy&rJmX~Tu(?;KDdiAsvRl~-M8z$BLIwD9)`*C zCE8>StISZukFfGl#cB4Z&`uM#0yU13e$33-68!v@P2kZ9chp~umh5X!wbWO-5WUKL zLHb7jA4GDqm6HTU@%o;wSGsh7r$5*93;PWcBm?)^b}V(rbPJvyH4BdP1>Q}Ov?Izq zgKJYuZ;>wDL>@sf-ZCp45p5YyE3<qjVtuRc93GdN*|&mrKWXi!nMNc6)15}rk=%9{ zS250vjc%&7Z^NTjlRM6}8sYzFGR;ZTo0^W~XBZjeV@+lyXaU~l41XU+J<Vut{UaG| zJG|o?<hTD~fg)0R)<3+h%Z({<X7HoGTeG>5hd9^Ys`Z9?Wo37~hz<xgRSJhLD6+s~ zTpnf-s@F>^nv6T>n0Rcjc+g6fBc?SF;=2WXw|(vKXFcxj%>I$=+mlik&<)yc+10&> zFC933C-qqH0;;S`G}El#%adkPmrsV|Hh0UrUsrj*Kq@KKM_fm~JwGZ_^L?;`{s_;@ zxa8&Hpev+1->cTW6RUYqU}+ls(^p}d?UPytGQ`xMY1TL<R|5_w<(M23^LdIu*qa@E zci7|CFU12#%Ge*;)bmT7u3zXSap&#!PP!l7Kv|<!HNRh2&rj;-7w>m2hR*Mg)!=XD zS6ih$g8yxJV=t^aO9VxKnd#~E@xUOWaP`MIZ&weWoQ2hEr+huHEQ$T}wlpnktz?pG zI^Q2Fmo~UKpcp?>FV}TnqLjJPv=)-CFJRP9A|<7IB7lpsZ;yeWlUz|rlB=Lj`3gJ; zGaL<V2~hOagRw&l%ImVFrSvsBOS^lD9)Gx8IWh*q``bi|M-EC)F=Jbuu02W+a51bt zr#n79hE|J|sn?fNh}ilcuWY4ij|X^<p`wVO%UVx7dXM5Kglac-gSfr?N`K%CU-bYj zqP{Cby>>9+<pl(~rx+{R->T{b%>Z^1Y-M%Ao1^pZ>-UPz0kESXcdAc3n*}6gS8i&a zxK(-7UK?`EQp@ljKTp~X_xOU-bJHm>$HY+zSi4Ni_!4%Z4(f}$WxwzR1^>$*y~@<| zTBx}&gFfO>cW4)zEBZJ?rOr>Kn~<F6l5)A5Dkodr*RlH0Oy3aWO{%Rgw*B{}P<X<i z&x)|c@>&i?_@6#J^^&&%;B5RlLW8>>RM+YTTp(nQC<w$`^mI-FgBmd`KV)8g6-53~ zWVK~fo>Z}Fs?N3&l;$oz?v(vvwN6pMhFY+VXv>at<@@B&v7FFqzC%4@+D78*^U&fC zsQP0no<;Ulhd>vm<&cXWPfYT?=Bn(-BD$&)N+Sn_*(b-=Fy^ZphdR$st<nKU#o<R| znsc0oG{2kjpKqn@-83yT@Gl)GHxZWOZ0i36X7g<;!E_s*T_SuB*`@Z(;=HtOPN~-P zV=BA1$428sN+)Ro!)T_{drF}}Qr3$MhvP&Mn_(WZaw((y9wono3|fa}=Q;x!z8?;l zQjp|uLrj%cJOM;x^_LE7B--fW7Xv#`<|=h>D@%yy>PJi?)xY(hXuVneSG-|+t?~Tt zY!oYh+s&K+4HaOQxfBx!jSnFmxt*EAz^GuSl#3zn5|X#@l<DVVS1oh9$1;svx?Y|F zAhuM_W(F$i&9lC7sRWd+lC2hx^Pl(Rz|$kY=~%4KKd$M|`X6$acj#)-MBXnAxZ>PG zl<*zXKV#F&<z3G?e>tn-ZNQlkGO6d2m=uObL<c5QNU6O&^O1dh<ah%CXpL`M(&TTE z2Sm@bU_0-tJ@#{Nj6Swl66nc%OCe&m^HD6_8}ANW#rrz4!u>4@el{ZMwRBm)==qMA z$U8~6$vPdtrA?L7)@RQQl8QQIYn`Y#XMc78(VVvC(O9(s_yL-m*6{$=K49oUQ0YI3 zf2iw{U(sV`FhC>m_R+`Q@4$MowrRDU4TU%>|2ZE<d1_1I&8hua;LG#9KG5*mGUkF_ z_a9uXvGK9>Dh;PvlvXsxXZ^?f3!5N_$WVcbaQG^MMTvf0SC3*1o0;B-<Kz9mr8(Lv zh7YAe=*080Z`DWe_E~I%^phvqoYa=nUZMp{-g(=?9ETqAcNOT$+6qDFWeslX2RdC& z3U$pS1;?BPsr>D9ZjNmo>KSo7j>|0q%?Ys_V^U~}zFLRg6k|jZ0^fvf8_=1w+pKYP z4bxfN9uU9oL&x?@$v>Wbmk(L?ip^>Wl87MURA9LOPo|rGAUPQ9YxNe1J=P*6^}PTg zHKOA>)G|`HIHMqg-%oVA+3E=%i&C!NZi?y#51N)MJ8q0gxSQ?3CGgxV*!S}*>b;Nc z;o!4ZBxn2GztqxAZ&e-nnB<7RNFhHMuKi6P#)``w^rQP_u|0|r00lses>^(FT5r=L zKuN2wTt0fHoBVt=KOKqLOhn15Uk;5lK<2M7=eoyQMX8*(T7A6IV%P^-@)DmB3A_Ly zOb6NaC;1s4d}$z_w6dE|-C~N~uT6c_g%v^rDW3rRg?E!V{PA%0f*XNwnZCe6ARD@k z&BHC5@;r93w&`g=F?su(@eBEzd!Jkv2E(->L~j@A$7NZ8+tJ9KwMhah>|`3^qCKgx z3_{nY?JMY^e5VS$x$!e@aANXiV|AVGAk_Y~DcnyLHzXVhD6L0QtPpJujZanR*?1at z{6pmY>gR+eRnksudP({xg}(K6P+on*;q$EZf6*HLjq-mJw0z4)Y^M5XuTp4c?j9Np z{l|E3sBx%>hypweHU8**m4b&kxgJ&fbuVqhsLikwZA$$**^{}cCqXk*zZ=Smmv?Q~ z_izL!D1X+~FFi|)@xDb3oUD_jI|md|kjY1`aI0)2Q7I6!*5wa-ugia!TBS}Yp?cbt z?yNaY)n%hd+y^ycZLbP}SZpf2x4azB*Q_z~R10O&#~V`tZmBBdR~`JJMhy-YCN366 zWhhe*Y{C9Wd!LY_h3fvX@Qw9DF4L(5;WjCCaAMtjBh;JccZWl(*RKndCyvSg8P97h zcbV#<BbS-VcsLO4x)A)n+xW)+O5EsjoLrN9k=*l!VD2~_Ga69eA`$6WmC^;Pdm9?a z_#U=!@Y6-NNA=GIBWnYNDbSJ0{z`$lTV0Mp2J>_y_*A(<T+DY(d-c#3z?r$snf@SO zK6CRThV?NhB(pJAFf*QaSKDf22Er@or`j)FrT@rntzMZ%4nyC)`vJ)1viIzt?-gYI z`nQ-+q<+_ew24zP_9v&+!lh}*Oi_pR4z}8}%e<m613<tZhj~GnyZjc@-|OwxHRtW) z+T8cxvg&RXRCpSDgN%Cjs)Cl#=U=x6neftM(EmgySmvd=jJ|xH_~DajRi6vWnDr4F z#D6lEHJiE0p&|QZ8it?Mw*B55@Ja=Mrg$)iB9gLtwnez>-SMDBCaZ!Z4972Pp9~3l zV7J1@2*RJ0GjLo~cLKHStk+neHH5^yeqh}TLEnIBuo*bONYuk2Mr;!xwQS2SdxZuo zWIK4cB8mxcO3efjnlFfa7D&B3A}trc7i0Nj<h_JiI|v9gKoo5*D`gjhiyd>15pKo} z?M{|nVq||cZ(rv339LJ~p+2?<ZwSQ!b}4s?gX`fI@nJW7+3p}vRmlJ=yzT<1sz(Cx zv$fHEIc$k<mqJPU3+mKjxBGPBw+WWQym*I?8D0Zu4Aej@*JkB>$gBKpQ_KPnmgmnv z!;?p%bnt!#B8mt@t#4IgT2ju=Bnoj?Z$dgrUnOY6m@q~{o!jcZln{d<j^B!5@VuNd z^(b=SIX*DR$_d{NuaOL!#2-WVw%<JGQU#}qGk2vl>uCOY-}2vYovq*t>#L0z3)mRF z2;;Bxyv`_Y=iE54sS6n9PVZB1aI2@f7S&A8lO9Mp_;!s|hGj*3&EErw{<wTajNBFB z;5Giqa1~*2SOWt}|KwC3KLFYDX)g1<%;&ROsvY^M?BnQt0oO0go9uZ4W>gc)x@#$8 zXd4;cJZ0Vr(gKX^xXgB?2A4UhWmh4RWqTRrjQ;XUh*+B}^6fAZWeY<%Wr?DR2A3?x z4F;F62Ss4;76{BUxsq9xMqxbv2^uDCUBuQCQ`SwlLN1^0qT@I*=|FU0)vATnX-->& z7ItH@LBJhSk}Zq6$ZSfdO4r}&M>V@rs;|HF%H5~L6!IkRoeN_387Qq7Bx)rLMW8IE z!<QEq1M>>sIE8XMqmJxhqavL)k<Ur-NHN2$m_AJ3abNUMsLRtVq9d4AS0Uxyt~xJ< zsL|@k2}I}i=Uej=Y2pSUgChH<<fnY<C|jKMziPEy><;Ws^e)e`A#rTwqA3}+H>H}u zbV7!3UhK#S_lWsY26YerYo>H{Fpdl&ptXE$c?i}Z{g7<@_P(JoDN%R)G+A8NxjckJ z)FgB~D~=*8ohR%2>}KFXne@3ESYu9${QI)`iK+jt3o1WB?9<;yDNHX-m27qtHlJ$^ z*Vtt+`xI02;r1%)%<I?yS2Q7X#!8B?gand>vn`6a6i?GM;n@+}G&@_XhDfE6<QN}? zB)Q0$wC0PB^Lu?@S-m!on*kNUe4~KGK`(>|i}S+_Di^{t^MTFbNVl>wseg>w{rt*N zd{Z4V2DI3#7Cqf)dZ!D~dZVdFximW(Jvr}Y$X$r>OQ#O7RUw<BZn=LDyqVyK`a&@n zGRr|)RzG^4>jw`$p}&c@={B(C>0Xd)!SOGvSTyXzMPGPnJBH;WNzs_Q@)e){f~LU# z2RlgJj_a+uN>E*<hIzw|;t#m-{2U}(P!&?uvZW_dwZcaZhf4kMmHKzDj4}fS2N)Gt zkWjx!<bQ#6wXJ8u5Tvt}g-f5%Z<-F$gW(g><GHjUXvwKaj)0;dL~}zSSYwfhC$3ds z%qj+i_*BU8AUq_KH_TXV_-~jBPasYSOW*R18!<?NXu&-I1%G+;RH}}siB$0W)s$<F zdZ1EBNQ1Sg1{F%(a-eV<2A@zW@YQ7wQQ4*5Vp4!<W)GO-!B>tPYgZbGAy;nMW?}rO zf|3(P{gbRMqkv(Bb|yT8F(FQf0DjyHlI>0|(TP(Ug|1df8dGFDbi^IAe-VKTzU)sU zn0?Pcqv2%Kxo@X;$Cg3)#}&0!N7tI~HqqVlao=olKaovm|2!>JlVst{H1O98gi_^> z|4z5H*3{zca+>T}?B?9=WuiSHf9U<5O1<bWd82uPA7urmQ5APOn9|(IsNyCw&bC_# z7eI86M42Ok%LQ{QWqrwpN&bm5kkhjmb~{$xS1mtCrfGA!YbCWr`C#~DXAd~MJDq?z z9IoGM9~v#D7@m~<gT7@gq}}?Uv4H7jkNC!qNn0Lx%qt)i9~v#06EJ5g5;QhsjSc@3 z-gQi&<Uh}yRe3J9pLI$4Axz(b)y)>Eu~Y(e`(R7%;ft31su1Y{X9J@O;8*8D(F~k4 zGT_;h=`dMtuEOnCF<PUjgorRHLn1U^vFuJh$pr|EPM>Aw)g`d{q%-8f@Dk~?d-5fr zmxW64XT^JtS5Dun4Hmwt=v^}l-4EVcE?(=Fg0yAeM7KSHkN1D1F_wqJo#79~`XJx- zwZWZNF!zrtB%Dtq8-i0a;#HqG%2A2X1fLGcY;f;XrrtL8aPJr1veV+>GmtTUt}x@g z{dP2ElQ378n$+NQ*jm)v&5l22@4)A^)Ok~c63n+b(UITFhyp?7)ulPue%X=1Ks}Ze zf#x5!{><^Kdz0<Re@-uHna=(p%p0H3;^IrR5BouqQ%j0%)ViCOJU<3$wG`?I>~%&v zOCS7O7}R3;ddKKUM|Q-0?)`U$-8zJ|Q)KPrTv#K-S2I`f;y(a(O5CdKFNDcT^g9_3 z1?@!o(Rp%Hru;e_I7xYP33idvQ_0I*w$QgYD-RZ@CD*T0@zc6DxI?^OUK?q-7~O}N z0z`B-g5uylkzhP%OGmW3FwScZ`>F~Dvo7xilQ^i8HGvp1*Y_>0Fz@+#xNZY+hG%?; z{~Q^TVV;@S*8joP^2<P53vEY?^#Proe4v!k^Y(nz*aUWFCfv>>xk1qKk>x3Y-pg5H zQ_1OwSS&;;E}PtJ`9ecxD+>(U)V*SLcVo6un~kWyiOy!Mcqa@}hi)G&4o#GCyc2HU z&o5qR`4lG#%d$%tH%r+?kqpA$j;R;93uiG~c`jk}$T&zynF#H@XP|pJ#BcL(XVz^W ztNMpsOOuelISjV?+|)nqP3kkLtw_b5fbVIx9U|VlkK5r0avk*oTwMl{i~o2O;f3^V zmKH`;M+jM_mYw>@1=;GaH9|rak2Qiq{Q3^}?+5C;GC9jPskU@gCz;ClNa~Hse~)v# zO<DwH>7X=M_U$mze~W#scg+N9DZKPS_3Q{TY4_sJ?qJJ0PdNUie1#;K-C0i69q7#N z7;yAFpbE`?pQ1Eu6P5DJTGJhjUL1Hnmw01@Bexf1^WEyGfwZ4Q<TgOijS{IPFo;-T zmHB`@e4o_NX=bXMY|)ZXJK4I3RIzAZGvDnCC2)|cx)YU^D-Vu<^uWHo^W)9qe&PQ? zWEqDO(2=Bx7|w^Fdv&j<EcU&Z6&-t@`9J`r$T>=ZW<NQ9FMR6tJaTuI(j^E{>@yuL znulq@x=4(L)Sl?S;qY-#?l4z59I7a-zbC{`8sg|3%h89*11v(xAHM7?z^7TBBe^yH zfFg;oj2x9zlU^1o_}6koqeX%~oU9-_k>%c8n5SukAS)7p)04{4xkRk8t?Nptf#xe; z2?eky--|$l;4!)?>Nv-KVBOfD{Fo~h=_m1wbpQ;+cV9-1y*ht+GF1HR@8v~!oxlr? zmK*Hww2VvZ+mrLZw&|75qy(%Nc-$l*z}d!ig%F91Zv7T$Y4FVOhkFYgro)3>i22ke zh{dKyn5LwC@Lf_W!VHf$I##foh)8=YUFAYyP)KKeHd5J^dj3aQ$_plJFa9}KFvNu- zBvYeON6}G+p9|F1e6*$O3-)?J)%(l}R3#2AeiET{3pLY2KR-Nd0%NR;aLpc8Lfz<G z+{Ie|r-Uc<*Q1yl_nX1i9_^3{d>0NmV0=EUw>o`KHO78hK~Q7YGbo<x-#V8G245aT zMwyRQ`9oaNG`vc!(tP^7r6TO32W(lO5&UB`Ju#<`Sx|Z(xDX{67I&Kt$jc5f#$3M` z4ig1{oyhz{S#FDF<`3C7b=(Dx>&k^69mMwm|51X;loS$2#eL0oOb@J#{$|&}K$^$v znoCy2efn6GJzO!4-ai!a<f~dsY~8IJd5!RHHY4)FnN32Y`erVQ*f8~KFkd40;sumq zBxpTR`)RYxX8pqJ>op$WC?%r6(=<WJkDs2t`in??t79|{cxkWeB~7fmT<dRrowsM4 z_Vstbeu*?R_+{V(K+9qO`mg_HjUMXRvacCgW#Pgy@pwN*i!v=;u5i>U7K<7V9p3l? z35)0m@vq?5U;8P#8fP4(gka>PIH$@8stX~HvLf(rv4`18vZ#BvJ^@pLZ+-B$bm+vc z&GeFRW4Dzv2I7D1Y&I4Q4xR~J(6GdcLE1KP{Tma-jEW(n@AnbDYo32-DFEQYh8KFu z_zX3{^Wb2f99^_b$BwbcRY7{{IMyr&w9J0lMM!l&7HC@E`y^cF_+K}fOsOQaY*Rd? z$<li=U-M;Tc85_DoFnFIRXMX7yBLpAKC?e3-n)|R=HTB-hL*Qm>?mRPFet<%X^g%I zsc#v=RY~p^(z**evUm}?edK1HvlJOQesz9|DfZ0w(8Q9M*v6(7CPro^H~j(F*feuj z+p1>&8DHGgf4_I~on2Q{LGLY$*1s~%5n@ua^NVkVF4Y5aAe9Q~{l{+!(7&HJ2@B28 z48+X;@(dSA+d_{Yv4{nK@-vQ+&&7^~zA>FuIJvA!u9l!vp#umF(z?3?Ni)+uws$2H zpO|w0o$JsMMknHbJx?GUdoYPbKyY^)>BgK=2OV|N_fJacRiA&OqDOK+c!SyS62s8+ zSHa}#Jr}Q}cdEN4PD~ll_On=1zF#_3CIF1d<~ZTWVgDreh5XYCp6L~e<{RVmv3DwY z8sL~$0)k*VQ;JHzdVn;jgO>pj7_9b_Tp%AX4JJSJ@0;hze7JOIo_HrdX&#*TO5ZyJ zcAftf;hRl<dd;D_AoJuQN+PVfN8cOtAnpt9p9^r(fpYpque9jjP&CH7&U(a6&^AVk z9B!QhA<>9wy%R@T>SNwjrNI6H$R3b0<-?k=Q$8hu+L)P4J=u2>!iLx&r(PVCS$I1B z{a;<Svl5*UoLh#+bOYlT(AR&zHTKe1lz@nuNPRlC{Y74)xJbSV`HF4|2wfPqnXGi} zR%+$;qe_V7{aowX0ytl#vEnVZk;mc=B>9Q1TNYp0yg|QK)1vuioMhFCqkC-{x6m-D z{&?lqT{<JHOHV}`*;Kh@!!z3@9G%;MeKRt?Ts9gXPGiw+I$bf%ty5OSy*w7Ys@w7! z)wP~u@#kY{sOtFkc!kWPmBmZnYt+31SpTpnqW`S6XwArxuA_m`H2$OQ|5$TUK^PmG zx&HVO*ZTAS!D-Oe_NMpKfqc!4@uM3Ih&%!oarCzS^XgybDat?+Wn<`ioY5o;5=8L; ziI3#X0iBs@nxf<P>t}82i|LJ}riUim>){`1_F-f7n_h#xkC)AQ0RQLk(aqJ)$CZaA z$n{02{VM$i^mT2?6kk8bb#*^{Y7cbu>;L2M4gD`H!}q26=J|2#`Q`e>+sDrXxO8-t z=HLFk0;~spSC_kc-Cxy>f))(%Kx;2+(S)Ga>e#P)W4HUOGJW8s@$;31h|+<k<{Pvx zusJ`s|8wdse2j<_nW+EG80ZUh60j#U7@GmEe*+KPumAdY;PnH2g^RcH^HwcEUTqhf zhIxK#`9RM$ZQ%1Y=n#DGc(>!p!FTQOU~6pc)#IxFd+`f0|LqnKDr&JH25>6m_|or( z0T{F#%uSWS=f(T?Ub%>Uz324|;=Fa=xjfwN{#6Bh*TMGVese$5b>~g_9MrYP0f8RT z!o~+m)%zY)pbIVS?@zy<Z9t%pVXq(7i0#GAm+BrzAzr9ZTHmwb<897=3CXP5ze`;v zQ9@)Qc=(9VyT4gIdFE{mf;F%X9A4jPhR!QKlav5~UvK)=-+3T9^Vu0$!dW0j|0jh& zKz!owhl&rW=RSu4&@M>9;8y1n6Cm@wseCpFex9FA3Gx7qvj^QzHG{Iw)_3}*y|$XJ z?Fe8Q7zcS_imMR;2*Eeq=6BY|k!DDs9c}-nJl&7x%V8C*8&vAj)7{HG&>o_fdMUJy zAjp}E&yd)2_nQTchi?oCo=D2X*ZaOXf2U5!mT=Wlh~M6R&ObT8?`|a@JaKlmzDyJ% zuh-{aG@s9FI)M9gZq8o=^wQzKE(m(Mn)7#eclQs>GpT9q)7?8V%x{~s%npBzuSafY zVhc{bC2{m#$k*SGuM_CrH^}IVPuwx|_kRC)8FL^4J$(e&?+O^~O)4WW9lE>?J@1?z z4Qq?-1>AW^HVbXXGcg$+oH5zkuX=dC%lU$mm#8^xTGg!<o|L|SGkyRHH1b&JDIWb^ z*i7fMyRR&57M#1kP(eh#)=ZYz{r>B=`k-<O#QIwrLJ`ETc3u2^OuJnM?pcNN^2F~R z0>k`z73;UhC7ZQ4(5L$svmnsV*X!-h#p!0PXJ+!&YO6O62GdjME?@{UMS93g0_m&C zFQh+9W1S2DrsPEs9F9V8z;*556SsQH)w=gx;%~*4fB9q6nr-mQI(y$paBo)#m9<x} z{uYPwyw)&}<Hou3x&zs>U=aMZ-op~P9*}N%PQl-zrB4s8GI#D03nNGAJ`~0MM)7?9 z?EWa$SgY9je0R7dR=%m;E}ea4>!O^7p^!z^$;tJqWLfW_yXNo|$2-x~3k}7E;NY=# zyXNsW`bY<*dm4_s=D}n$g#58)n1A!w58(IlHUM7-U0n0apmgg^;r4aDeHjB$^F6)% z=6b{b=+9j+iHS|zexwzCT;m^3(J8AfG5JteTVBmK4<<j<`NrlBbkcGKgxvOM3<{>0 zqr3D=E+n82<8I2aNzp<1-KHu^bJ{H^C;2y#(=Qe#MXcrE0Ys_*1S(1&<;~@{T(%vz zH98ypvk}XW{RKV`iyMX;=jayo**8bwRQDR+(=Q8-?*0&mi{l6262)M>F5`fE)7Lqy zQvd_#;%G!rvVK$aXTUiX7JZCHiv4pk<IUfZwQ%tJ*1O&5w~vP&aB@TTkyB+?=*f=; zVlHl6#u%m(<>D&l7o?y37M6dKpijiEET0+&<^qIn&JNA4KyD<iNkj2@Wa$6>4VD6| zh|kIXt_t68e?aR&wP;$O`Rl1@n5%#;%Nt1jo0kgiBu@+dI9D89lmPB-Kf44jv@&Ks z(=ws%T$8c=7weeaFXsJB61<TB%X-fI2XQ-kn$n)JcoF`i(se@0_kRiI4}5S(6yyOB zB^v`dul2W{v!`$%Z{XMGSiF#CUZYW!6s`0C(&eZ6tgBk@r*My`AC#lip3$tM;!D-j z{-sb}dlx+28f2CY9D-d<F>AT?<A2)aNR8=8Cgx_Qf)CkA7SqaQFAcwj`1SE10nfU) z(Y6VPpt%n?5Xj_@z>!2A8r7UlMISB``n+?Zl8Q=lnpc6qPy9O{2!UQSNr9TuKGMek zJ=hcnmReIXOsE$_zy7}Wrw4D4%j+f6EFmEgp#h5tg(miB6@*=AVTTW@Ox9HTZ$kZ2 zj|DrntTG{b`8cu&Q}c2B*Ua!b&8ym*%YMT>o?bTn#v?a-G@^7yG(y4+^Rd^;DfEPU zW}>^)wa34LN9vA}3uu1&yb8Zv&B}FaEwiZO_z=H%Tb4Z4J-ibXlP%(|TfjXQ*+sOr ztqRr)bJGsumY$OMYE6E&c`Hd|)PrJ8vU=$s>fN!;=n4AVK3~VqluA85?A58K)KDqW z;?9IH=12LfMI=<2h+;K7tW$0PuqM@HTohfcyg8pS-w*(nIA5XJH}xe%yZ&oTIpO}8 z>>rLM`jH(#F)Y#wDD@%|5B=JYDf{2NW?WXYp|$MofcelFrxB}n#t#cEgC_$)Ea%1j zZ!k2@@r5G1o@*wJ8^?w2zzTRQdq)p*=1|R53=s6aD8^t#Rt9|L<dId)dAPdt*E_77 z&1!6<@Qd%G(&pUQ*$o%%Eyik3$VsV7Pe`PEKs1f8N+T-{r|&0^!g3@RoS3UA1g#G! zED_j#b(2p>bkFf4;D%<H(d+N$%**MA`4q?H^%<&3869@je<rUrsaXYwjU_&3<#|=C zKOqSQFDcNI+Lc6v#)tKU9^iu_lp=5+dx>i-7Y}@8yhU0X0$#E)`pJF~pS;e9HVKxJ zY!P5K3KdJL{4lFUEw&t_FP2*l`=xBmOr<U(r7bU8gx*x0Ois+Z!LTU;!^Cn}kS=#w z`Xs|U`GE_109tf^A03^V3mDir?9~DWd~)iKRYolfkz;N4#V4>)N$4!3g{HblSP5LK zN)=P_4RRWWR^gb6&>)$3_^47i*^!Lk?oK6tsec*!-B^hJl3+(25<^3$y=O*JDxEAq zj@IMtT90Ma!YXA>OQ$_I`1#|h=xL_;F)Sl{G2DsF-F49HXjEM4zUH2&2iqL1=7W~k zsuJkuy^2^?Toi7`?ctfg5msw*Afg@ABXo1{yVpqS@b@p5BdV6%_%5g*DdVx?uL1~Z z)5XJb2~!9;NE90JDZ)iJ>=~1ceAmF9UP`<>(xljJY9#Uwor@(>T}a}yyWTKqE=btc zG;v7(i{hU(^6()iIOerjMZbnH{e$tbMs1*nRp&w?IUwrUO7s4x2{%X=(+@7Fkf8Ba zI#JMKt3IeKl%eFP9pf7Ly)T)En-h<7WsCTW#;zMTA4oUOOLtk(nFb}@zdFJHv^>L% z9R8`CGu#%Jnz=9>i53&;w1g}1DUY-@S<q&7caJ6|HCRLQ$5~&))Ha&C-mm9c>4>V$ zqwoU#XXiPN`f~G#?0hRnSB>(9w(n#BaeLZZN}i7O!8b0%mW~O7@IP-Tdl6-8iJO?O zZVm|k37a4#dad0W9N)uVZu=_Q#hXg$z)Cj?3RqK&*?*HCZpR8n5C2S~xmsCGrx{Yl zhY&EE-%6|zN#WL7e{2!v7llNf#Gkmbi_Oss;uvPJ6t+<oV)|Nrg}CMWI1W(a__U_F zN*OZoq5I1T=e!<MLQ>ODDYy`J8thh{KW=+!9{pm&o_lEN(M5H0_FoD8DpXd5lSLDW zC8s8XjK6>j^P;7J(O-XnVjxKgnh#}!(XZ@660|>1Q|I>@@C>DQu=p=XY8=6^O34Ul z!OH*f@@W31-$;O9b0y>DoZbg9T-gq15o2)FwY0{hx%R5$akXdH2J#2uPZKS0GRu%O zrBFTk7VAjdQ26HID@4g*AIqi6wOX_w->AR}e|PMQb{%tkSk~#@Uyj*s8M~k(qh$y0 zEu1Bvmf#t^WuAVqXZ{Z6&SG!x4wDMBqhqANHHxw{8wXZfT1mM=7^THy_|!#Pgx;Ul z;S$EWt?v-%CgbMGy`iI<+0x4bZ@i~=_8}_`LD{ifVI;EoiWH&q3C^TJ)b%JvMXsZz zR2OjOR0hs%-^iS7OtS})$&*-Eh;mu`n%IYSQZj9ikeU&2`e`2H7{MMTLmF^$-V-$t zKWOIZ_O_LpYiwYJ<8aN}6Rq@K-s-EWBPO2EIUb~3NP4ad95OtGF7eoVNY9yp!Yl|n zO!uYyairR(05G<2j!6;AzaH7?c;wa3?b)BtYsg#AV`nxsYy?6E4ut+4?q~}%Os;R# zMAaHs58t6kXMjK?)xVnRBZ@(R>=gpXv96moyFVF|<!wB${fNf7H_TI>yqA*{KR0 z55W>0ab1xbIWWCn|6Xn}^#RYCo))Al4WxHBkRo$qrrEEoie40T9`JL5`e-iC=9HAK z&Z@8Mw8fCFVvim=wiz$ggP|g<)-4Co+i30)bHT4QtNbkt&q5mZ`E4DOVVa;6L$Y*K zLhXq<l{o_xrLEHTinb?LMu~TbkvgTVx-pHrZfOE}tyP*jI(aNks?Sx+xulv73{nKK zdZ)RZXckT>K?&1&nc)avVlt0CBKD;obF;;R>>+G$NSdVWpAm%`q}}S)D@}TYwZ`#Z zO#fkH{nc=5+7tTjB}CeA-hoC6cO2ZCb!<>*eAk)zMHL$CCx95f`YDu66#*q2)S=fN zUpt%9=qXTylZ!S$^$kG=rC1($W?x=RoA1<x;>D^s#^RcSU*aoaGQIdiLBp?^p1aH) zF^m4iihGr)XZ1(G?(gS~xi|wT<eP~kcWy8)l8PCQ&R;^4&2T;WAc-*h@nbZs+W$O^ zX0MrH4xp3nj>;{143Qyp<mK*cEZxV>71osW99hY_=>3b<OZBuxOsPY!cs+{`|C?+q zW4o4n04Ug1b7c2~zAzJz@TEAUsX9Z_Hxhdnv=Fx<w(Wl)S%#KiUI+NeBAz9b$<M+c zkwz%LA$Ahs?kh%DnRP;H&fD%iBkA=75K_Z7xsz+ZRX=%-M0VpQ3hY8?;LbwmV=^v) zQv|RMO3^#&b##@&kyRB#NfPgBhz0~zy|M%?*YYV`nUFyUCvXHwA5Ei>h-iuh9nBb# ziYS*)9fEl$a1DPTMJJEXn6h7qN^{>T=>?W{MP$eQbz>MRHE<PyO>7O0Fuj?Vy5C+q zeD~zba75vIqG1sYD1w#^p~nC4KZv@ZCH|nUaH?6b0w-+{=d4<Qq>x<wg^o&|&@6$z z>c>zM-yRwXTj<k^WPhtDqD7}$a3t4Zf{W&dzUIeJXBqG>vPm++)~Fc1o1Wy5n@`+H zVEORlU!@Eb)G%AEVrW?ib7<$n0}~NK?BXR9i5KPQYaDtK@JTi@NzRu4EyhAAO>7fQ z5_MgOxgoVRRFi?zgc@6>ew&K=7Yn^2^1Jvqq4ffP@OLRax7iW4U3Hx$1~N&`Y%w;W zHH&Z0Y^eU7=iq<*(89lU-1IJddx=HRa-|Zd&|gAEr2j}xFC^6!+pRp;%#wtxypzVP z{x-wCu_$H{ci%-cES})~qT&n9%I}gnQvuz$eLi*hSp`@2JZ4Mfv_E*h&Kx~rj%D6C z`+V+$xXLww{HK321%u29A2+O+h2SxnDyVW=ca^IQ1J4|5qx8x3SCwc2sg8`~Nj`q< zgj9(zJz%;$20^6N(Y;G^JO+(UaGOwVV`%Ph3I{7;kxtd#U|G1V8n`B5(88SWvTQWy zy7tEG(#-Zwzg~T2m*=mu07d=(7VSk#3riMX8@Q|IYVJ>Q*mQ5wn~zjxLd+pKA5@zu z(k!k17VV3R6w&&|x<eMu#Dx~aer#?@ErrckA|Kb5k;pikxy%xS%notMIv#A-(08My z+k5siTl@s?`vOMXWYxO{Fb;Pe|7fiW!7MmeVIl%oaU2ZNdA-Pf3sg(#_xAPNFc7l! zc%C1PKydVgihv)F_poW^|D#x<<+M<$hi76Ahwbwla`wN(q<(5i!ugH7ofa}=YK+(8 zTv={(192kw{R7Hh*Vj&SiHsYHyirmp35>;DcRY3ysJqs|e(pu@|HITfhG*6^fx0uX zZQHhOCllLtGSS4g?I*Tv+qP{RC-1lSIoJ8Me)YPltLm=m)vK$TQbgX&+kljFKGNA% z1`vbzy(5{13nwuCSVza;ZT#=HBg_%V6PZj^Ze}UeYs>Z>Bas|SIABgBjG01KQW@r~ zq_!hhH*!DiSW?bRf!!t=a-Jc3xEmE#iWyClBl9L~(A^VEgfVY)^B(Lo10zukeJz)# zY6h(GU{r|U%1A-3JWh~N^%hL@8#oQpSk4T+v-NO%o1L4WDQbvpk+fW#yhQMtIz02J z^nwL(pfONcw3rbo#q%i4E0`RrVOm>^pl9(jJ}w&kx7-3?dWJ~;nEAHBSM)D2PKXO0 zlTm=bSLV#R{~=$T;5It!8M;6^5Yz3A4w#A-)?V;H0SM_>LFzt)LzWq|oSD)Qdz@si zUWa7<o2a!C`&TmiLPnURm79xa<k$*PM(Mb8ejCJro1;;&<ZnKA<8Jf>q{cZim3IF_ zKP)p&KB=^N5i(FT_XM$r0xkoG4g=$`xx_H2{Dt-9_xBtaV|&6xLgD4tek#aG)WqIB zH!moYR3=$Msp4BrRTR9o*$puf^0IrBVQc}g8Ly^v%qjU)-R*AcoUKZ`>~H(e{rPit z_?YMTs8;996{5b7Rx|1XmZKq5A><;NKO{{QQil^rap7kLgSVz}iu6<P&x4rgdAr6z zOykS&r5bgA3=|`$dEF7y2N4P=>(MmojSK5cSFOPI-RehteNq{m;=*ok{mjVr2sj@f zM2%qq<bR6jk*v%wNDVR(^BAh-jBxBgm@#wDvFO<PG+=B3mv)q0@MxfH5rXK&b%A<@ zs9;KJ3X2}FOE<kSv#QwcNy1J^wR#PA^pBS6dJv})4<^qS4kEGr1{X&X1v*x=MSnX~ z3u&|#aTvJ%<_iuMI2lbliIM(kt3;n}G%^?{gD`;R{!OTb;!WK2LUyt3{&$W1yU-Dt zEPq}IQYQvC5Jx8MoiQ6L3doit-moY1$ZyJhchob$w?Ye2em@A+rLJcXXRSEivCWrb zyqOT$3epr{0^1heQw}QSKVgE*jGscvbK)C6uyU}e2FAHzE><g>9t0;+5@qycmZ6~q zVX{9uxqz0Wp}hvWW9+~dnro*>{W)a}>=Zdq1g&%;unM;SZ)k>uh$vEXsYt`L&Yz*d z#3df|k{S~!w^5bAq5?O0w#GyQyJ^A%d>3e(CQA@J5k`?F(si}5eVigU<-TfQL@Yp| z&V(&{wksZB4KA^NfdKkYhc@H1Dj5I7G;Tign^f33Wc>na!vtkvTvK5h1-@@Ac{Nq+ zT`IT^mmsQM7-O#SbJx2Iot~N4!3uj}$gUoakOOMwD?>M<M-sZfs(B@-^ZE=3`gyQ% zw(oC^Qs`qA9TvgkolK`NHh=<z%^NFKt^9k*dM7G{&b($tv=yo|_mF%88XUbST&ZfI zMbga!-2!X)qVj+g_l2jkv`ET0Ududm#p8pP%`y*jil9$l`Ib7|3(Bk9@r$M3L-AF+ zD<6YSF;!UA9#W(3VJmxm_Xy`^^fu-kzgdjS2gQ*{3k34eD_crYX-sBKU(hO+DIgaJ zBnY|tMtYbpKMW;`-<ny@h*aD}(k;Vv)bw4rqX5Z_u^S!zL;7^7c631L7L&<yO}x~H zxnwOcG4?lzw4vRc1)sh-V`x#g%XbBz2{|Oc8&P3x17@vQ)XM}xr2|c}DpMSWuY8vu z$5buFQiF9EPGb;+xoEeR4l#3p!cd@XI`J$meIVt^44}sCm$d{LMD)h=h%SR6ael&C zUj`-!o2s!NGPMx)R(R_pTcJJ|*NTZn1fd1h%5a7wgs5Z)Ju1~-d$7sgHSPQzed+!i zwDQ4muPD=j9V!v<vnr-7W1S$Zcwc^pF%cPVKV&sOwvKWUN+yT5+hFu_ls<~4{V?Q$ zS|i9t$<B_m;+b^{o4)uC>q4jv5}(=RN?&;VJ6EA+)}@L5=Io53esWfj<BC(u-aX(o zbRw&|U3rS+T2siL)pU~~gv;sTe1FLX9fwt+5gD@NAr7{3>^rkx#72`mk@>E4Z24Z# zqxKBAC!pe<kSN^~9z)CbPrNZd)xPRWQ3Kb;o`(2V<UG&&#gOoyU$?jOIXPXOL!Afv z!@M~@EBCMGygA?A)5rW*ZMcyQu8(it@19=umt>wFn{NEJwmvX){gfJm-pyGb!Jln> zZ`NzeuARS~-@c#y9GZ@9E+5CqxwIg`=PtuB)OZn*U&c``*!?>x-+I{Zfp8hgeMC1& z)_-RRkt9|RiP3UWPI<ky&zlobw?l>;jo;8RAg7<j^E-o|=A51|eOR;?MNbFVVzFnD zdS>v6S7g=m4t2UEQPa#eY_!rpEVPROL-7c*WPF8AA0_A=x1-@Fi|Y_4x0G8w$Y=&Y z!Fi!HrtR;ARj-`M)RNVg6NtH|pdJQ8ZY?bIRLT8Gm*vLA?Ewc(wIOTEQ!bN~NO8c2 zOp=*pml`NCmJ**Kq?U@oMStdX@dT4!88(C`Ktp_JY2k<1WE;LlO8Q$iwH)Dki3rr3 zY|FhzxmmO(WbcopEuE7Kf>u23;>bUmCMdoIi#-Qq%5zXjas}644^}*3w{I1T!)Q#_ zA}i8*YGXOQs5WN0p3hsx|N2BTv~ud)P+SBPZp+lkOSk&|1Y^(fn(D&-6&fDD91wOS zzI~-Ih7e&!x3+34<XS?9P5ii*$K;sX=g{eavwX=>Ty8`t6(LIS7M&U{Qp`C#r%v); zB<1<_f+Qyxe4m#9c9Vd)P)oAE*xkXmVa*-`zlii3M-IN70R_O5g&EEfG)4eY40H;{ zbGB+MtEcq3c4wIaF{r+nKwzd6&94rh)g;YEV=CdQBF_9*Br+4rd^uN!(Or-+h%p%w z>SM`rT|!>6;Q%YhPDQgeU)Y)L22KMOsJe$7{wE)$vELy(p2It@HZ``iWU17&j836p z4z_-bV3>BHZl1X}zP{|(V#{`F$xQ_HlLje#VB>sjD0AK(vDXw}r=}3V*j<3zCXPs( zPWY5=fMCb9W3JfGU{h0~t>d1csfgr;6+DS!Au}6P_4_bmkJogsfMpI1IbyfgyJ1wd z@{5)%kUhmfqK-Y|Nyu_$Y7a0`kh4j3T54{n8g5lySNUN1;2fUJjVB@F=^e@o8#uG% zN8|B@GQIMZCP_h+Aqtbsb{jfXMTM63wn&B{e1pjpc_d6o6rt|~HlKnyh}*SFNS~=J z;P7phbn3y<hZ~rxh8H_xsB7AwlKW~@p5tO!j5DM>xroIAN;Q=-N(Xxj>=>a^{D2t- zK3$bXJ-nDON}62n{p@p{oRumE4U$|o*>0K~it+`*>30BQdF1c{_`12w)u)!NSNfuJ zH)G<}tz$6`-kxgUBX0N<IH`Gj{hkNHNbK=a?$ak5zTJ_=v(``LxOF{mSb8uB_gqAb zhQA3daBWZ3ko;aMKbs(XHS4H7%jd#Dn@rPy4H1oD7@Kxgq-j!GI{tb+q*@+mBG*v; zb{s0pQ+lXa01M&YD&Ez_p=TkN`}qTNb3^70LG0}zfl%vFaIAe*-IIb_w7SbyMYdZM ze^?gptQofA=P4U#iBTT^+PX7^AdPGYp2xuLa07ze-W&rTqoth?ZnV?9ZKun3g@ZZN zj=M{U;aI8NTgCDfV0kBure;$+Wg!%%U0)FPkuoM*L+r#3EK%SO^sCOnTnM<CmTtAv zqpeFLCPvoAd4)@E7nfvrWd`oVNOJUqp`6}AxsDoiIgC}`APGwb7p-+0k*5t&B0&6+ zW;xBU$u*!p9BJ69gc9Cuc97?o`5LRaD(8_BoE<aAQgwhC%1bT+u49iZV2-pIt2!b& zD0#KHCwyzH`EGvQ87ug{@*?;?{&@OOiz&Sn{6t-s-*GSCuT|F~6#A5~xRWGnnZKQ= zG6ZC5IrRI>lFn)~U7;Sc-NCeF-;Szx-R8YlY<4FceD-*=GjAS7A^w<4cnkRT68&Jm zOlz!Z%vtMAZ8B`TIf{H$Qe=QD$a;vsm14iYrd<zYq?yB!Br}osxgs^uua40=<HA-R z>79QeL^)&Gs3x~(aS+V^R5^*`{W7H0JY>M=8fulC;2r7kN{h8SFl^*ekA>DR^g3AU zjeFA?3_c?2<<ImWJdgGMWvTF{_=FL;ye!+yc6%s@*--My><wVCj;M@=ALw0zE*{*w zGx8Ptf0Qd+Q@kzP40g{ny`ZDw%2&Yd>t*^WeFI7T`wm|b_}YPCS6D1ucH;XaqL~}Z zbNXixKB9#^IfX6nAK@7<x<ae)D>E;S9{U-BorKqer0=f0wlnu(@QbNmnXN0h=wqR- z8>_#fNI!XAx5Yuwq6UV3oVto3^2mtY)P>WT8RKpxXXS_{H2bTf7L1DAszrapf?k^} zwVXwl7xh5kM1)<Kwgt2rqhb%MPHm$|9C_lZt{Ul0AxMkbZ`ovYRptz@C{q{I@out~ z(G6Dx1HS5D$E;^m2#Meh2{oUY{%~E<ZV%-cHu|!lQU7g@={cd(_H=}MqA!VV=C@CC zYwRp|wO0gss!kO}YEIX-J&gD8`Rr8xb>`<|irI_k>Em=x_HtQieRp^n#7qDwf8ld~ zl7RD8s4mokHi4aGmSSJ(IbUPnD@AYDl@nhUAq$s&To1o`egtckJ4IoF9*ESb42Xjn zUHNN%=c`c35zxdMN6)Nl#qH@eseJ}@#a~#dpvLxw3XG-M(9jgaG~(qZGU(#~M)aj7 zP6zHXnBbv3`XEG0y-^X0x~x04R5@<ql2gy;vRk0an(`ZJ47t`>_b=r*-b{H@(pv+c z>=C--^O)9qncQr6YDr_^Ay{MSS?BJacu4hlSeG?Sb@5H&V`3C^p*#!(ZcMJ(YNA^R zb!1!_b{(J7LtxReQE;h$2VQ>xo&$|?uy}0<iN9kU0{9MwNu2qEOhG%C%#b`A8hQiC z(C+LRY%zr02&K$h&ZH^BXKdi0L_g#+V-S7(iN?KvXj`)s-Mn_)lI$lTa}trH8q^AC zeZ%AXlB44e6$k$9S>o^RWgv?-ebiF(E{&OE>>d({LoDl!8KbiZNprajVeXC`^7UDa zr*R-3Pveiy>4^=E=S}i)>^b(#MOoc135WIXNI2Do1de$CJOh1;hY)p=M|UM&aUe7~ z0S<xierdtP&gRyj;&>S1Oyr%)dQuL?VWue2Gc2t|#IW&|fWCj5v=tX7U=VY9WrXB@ zfuy{G4TT_9^b`PLE11L<#49<ojSx8WK&{ygc_M8eOsVEEyoUz)3eE!UUUgQQU3Fp_ zi>I~%wJ<Y7Ss>pOOp-fTbkAfK%1qe~u4KowH!zv5wcb{R`6l%`cmU0q8a2WcYp%oJ z7a)F$>uWtu<0KEVn6hF6NK{ZNbw}c0Vkxxr<~OBqQtI5SA*Ano{a;E|z3~R{C(Es} zUBn5))KtnrpQJgEa%Wt}qSd3q^Z7QQZYVSwtwbhx(uvGhPWknYLjo-{U~uTW8kRik zo`KH5=whv4|5^k7*1AQK{!^49&F)2l^c|;xf;&<oj37;EP}swGH3tNw#)xsDR#>+j z5TmVxsG=Qm_omOa9JQk0P{go~F^ekyUhX)E&$Yu!o|!4}CvA=-9dWPSEu$|~cRY=7 zzW6(Gke)K*na~^G8CqAD!r1h{KFFs(YLdF@7X1KW*8zfuW#+tCN|Q`sW(`j=>SwPp z$EqFJ7&uO|CnG-Ai$f{qQ9e(H7*nx^H%196eIi_vl>3tDhV8+qkES?37JN()Q?spq z#WCD`ON%Yw4qe7|?l-}NRNG{1O=erSp=gbZPxV}=2&+R3B{i8q802ORs)V;RG;vDN z_@x<6b&}MN=pyh<EG~0CR(%Ob)aW8+9SbgIL{8}s6h27PcuB+iw?bkCC?tH-mUbRv zh9{W>1ZtqMiEziKN6>)Drr78HaRcGGt%O9X`wL%~M)pL4hxN-Oa{@xQk1{hDeT}?m zOSo@IQP#7Z4nXhM2<|wk(0A7B%M2Jd1aEVO2v_243X1`^c5}UA>2uT|r7>5X30i&) zek#v}epHQz?zB15oh?Vu$t$yt&?YP><V_TjzL31E+da%TNTFo!O&8qSFZ3NXn&+** zrD?O!7NpL3PBg=l$QOpJ@8Q@9uU6=zf%s3#Nlq}GkLZ!`z(~3fBzfe2O1U<7+;sbC z*}?20cm@N0wzBm^S3721V(YjP{KAOxwd_oIFtj3BhrI|(--*kn?6<vUu-8?YAPl&b zZdEhrmg)q-&+@@+8;^!y#^(N#DjFkI9>yZe_|PNHA$3-8y;Ck+TGIi2eFz6pApq;1 zyi>xJnZ@iOel4}rv5?%mY2eYn6b4-Cg&)!Dc)+o{UXJ1t95cZf)Vpx;M^w$50G0)j zTxHt~Ht5(}7KMIvZ9LMvV+QY^T8Pjt-6h-+Vd9@oTAwM?Ab)WYH$Ms-k+1hG-LRKg zVgWi_sIl$>{Xk3|lT;16Rp`tF!d+#8WK@SPRf+4kW3{9pg^BAo(IqwW1IG4g76|?= zO-%g*&%ZE}Kt9p(vcB92hT%wMz^g%+91+O@{<XSj5k=A*Gtt<<Oy2jhqC$pDn*i${ z;S!xQ=;W93UID?+^CV4M!Xi%GNSvYDFY&0gk1Cs20$f;O60=^Gv50?@(<Wq(?VO}s ztXQ(JaWl>^t|QaHm>MvefS49)S}3ozA#GaD2XRJT^61(D-*LjluB=;E3T3o}=CO=E zoD?W%{xIA3m}6jS8CN;5+af~=R8iY;wd4Hnz-cZN259&pB7HPyKSrKGT53%fA<$^% zPmGcRnF}dd%Gf4Hl*eIBqec3M>2TAId{b%3TJ(t8`1L>Oj4uZW>i=Dp>~p6;$rQOF zV=U2tM9vEYt9qyi9HGHt|0(|4tV3@q5X_cBK_=WD^<ZD>in{&vBbmO*m_)}ap<oQz z2B;I=a5q_uEPU@!Ca8$yjGj(9IObsvIMby<-$lWN@1*H(wef8mE}cHWv&_)8wPswb z;E@8GCDDws=c~u!0M}@slDEw_9?@NIXFMgCgcjv`b63q0zJ&OXg)6eKj9n5v837Bo zC_cYUK1{&^m^u#ivBqZlqM*j?$AOqTSP593rr4P|m|qO(|K)uv=7DEZo1}dyG|_G| z!bDDc!2X+5N1(e%B-TtAE^05y<f5jN0&kFWo&_FtAu#aP>qF4dq#e$~Biz-W;vl}9 zT`lA$H9p6al8{A6U$guA>8@l-*^RE>1`F<^NR`vAkua086buY$L9(k=F}?YlnOA-i zm4U3wwNV3sL9Q<~+f-*9Bfu0?p9#HUNpCzCy0T4?M(px#KNYZ^4yqF@Y|-R7?83>d zvrf}jSRw0e*5f=q5LR5JSz976)$kKwj92{vUq7LM)unq3@7{rbTu(ul{Sm{5*(!Um zCGXmv0-3eeEWGPg2YPfu$vdJ4k7%xmo;puUEg5|l-75sR)SQGU%2<BF&}EwDQJbCq zSL8N=fdmY`J}0ccxm*DZ!#)@+^uSG*KLg~I2O}_3gO*@G<hP>GFsfI`|AdRYX39XP zfDCcH+&lhptLN$9CJyy)=fT?l&=~(gL%b%|{?|T?09m(#ep_Hb_hpmDC4mKwpNPTF z>`KA}{ya?DnMs%?-~9uBLY&2RP%*Q>-J7t6#(+Bj#DyxWaI=m;n5IN@!SkjxKoRV_ zN@2wIGQE`21c$q$#sY#tjotctonv?LB68;6U7}!YjAjUsQN2#3T>FjT4p)%;!7yKI zx@+b^m{tmrg7sbeo!fla8lHQ7C&o~R>j?5coE-imcw%qgw^sBAkN@aJ_|x<s8xj%( z^&J0~jgyS+V}xrS%exGyCxkeRbi_CpYgI6*Ec!B9xPtt+P`jEQ*IFmj(&Jjw-^L$k zP*!L_Ll!c@bk(K46R=opMRLbvE}f|cOby+FelRv$?EH==3PwOo5yGWE21fB>UdM$n zR#=A;LTI;*$>=JQMO@;KgC~DG_LJdGWQd3XeyR;YGOabwfe>M;`#;<UO#CmdP`(|p z3k)zz+j!Ua@)2>71=uY{okVm+0H2x@<Yo4`7?RchGcA2SRw18XKFL!F^OYGN_b>K? zLHvXo*~l{hOG|zx3oOuIj-VXLHG@-Gfz1!U23p<rod76n2`QYY{fi?a76`U36IPIu zgEr|mn*T%|t0f#cE?N{2d;R~!gF^Yqb2RC6yZTqm`j?kGmNbM~&;MboK-FdAjW5De zzi`xyb3sUCQ;LW)*laCwcv?bVK?`4y4+zz^;bk4Upm;Sjwb0L<`jfU~SHnO-+zh?3 z!JoyuwKyGeMhU5=5Uhokx+@E1Kyl^C9Kd`g19m4uRGL0PqjTx%PO*MOp)GaUJZT-6 zD-qUo)bu(DKCjd8_zrqoIZEe2u=-<Px;ktHb13^@`BvD;X7qSC<p@T>m5W@fs;73I z#MpF#L@uFm@)9zy7}MmnkF9`HHk^;ApDSB!h4tQa@FXONA-4@Xui;WL)%{2#9a^jy zf}ina44FDonj#s^ReuGuQwFM5{epQ^#mU@adrVDs;VS{em;IKW_<`_FA)R(R?p7yb z6}a~Vsp`R|w*R;UfP~*~VmQ5BoG9=6KaPJCn9U}FTHG}0Kf_mhe8%{)6u7d#;qV{9 z<e-6U-Ka#_8kYC%a8C%c_!&RDC!!aKMnxy>Jh9<oL~{~P12m@36LURQWzfI&UDefn z2_-VY7#g~||6hdBf<_Vg>5l}4)ZABLKVxvXsMQ{H@TBTVL15`jp9By_M7TZHKB@vv zzgFLHd0&>4zqN5k>V6gmFB~GrON~1JC$H5qfQhwpNhUy$oL9jW0+9TEdRcjCb&Zld z@L(|hU-=McmyJ#)8pqsHY(<y|>bYV=#E80jrM3sB(hB`jxX}cLu4`&c3H397vf9H> zR)aTRN#)AQSoz=D;5fjLiG{pqSn@yde)2D9g$yEPJ-ELB*t(X#qKNl$uk*Jxw{Ib& zpbw>J@~HVYPpnZ0(vjMm*zjJ1=cEWy$vi2}M=!^Z_8^R7ITNGOAy7=WpEP_U&3+8~ zGd&`@k_w9`b#kjt`m)OZ%kG@(kLq@+H)JEayhDP1W74GLKrwMo<+lm`EDX}lDJ=<v z|4VExeCDyY{8A?b4237{T#1(Bt}vf_*d*~QmbGXEztaAX@{p9VzaQ9%4g~)X9<j0X z+7cu<beHOn=!TsWCQt(Fr$}_>RfAG30p+cE*JuArZYW;&T7>awg+H(G5_ymbzTzlh z#MFD}<cW>`Pj_6~o6OR=<vmeA3AfxdFe5i~V?V(Ktx`F4f)<O-HhoI=;(x(eU&{{$ zHh?vu)fshrT)31iB=_9eWvOZKDH*|7DY;1vqNzc&FF2Pv`tbjij==}9k7zA@<3Bo) z{kq8N_n88-NlD0@+$peG5h*^pCbvUkCuk1;2k)d92Jux3GT=F=ar`H~kPyW+A}<@0 z;rKW2NOk~?(cs)*CHAJjhAEp0B9Eaax~u1#_+f4pAdpRF*_ql0Cp%kY{;2PvW$pS9 zV6D|<6zrZBg}`Fim!AL2j46fqB7|84vNB@HjI<#FPon9^^$;ZCkR?*LJ!|9<JecbD z+d$%C9gY-)Ed6H|yxqk`C?U2#O*VKsqBGuWKi~T=S2jQG*}dO6lYT>W`x(?8p>_{2 z*|Du*N(T4gOwRNLn~_x?Ju@|&M5<PJT7DqYA$~u-zU`XyyZU<lJp12X{i|9#dcuf; z33m3Uq(2H_kQ!d5Quh1oeCamdz*?W$;HwTh(MS&u`BiKKRE9rcSj~`tT(=DeTsK!^ zj@I(Kl_r9$s1C}6l$vYBbb@s47*}q$g5y0w(K-4!VFpZH_-i5weO3=~A`XFu1Gs=N zUqZ^E*U+qj+E*_qOdDm7B(c~OOCVPIW5u-Xq(c&$1fi0e>kBapkDrAa#_hfBn`!9{ zq+O3onhLiG3=R%(VMsa6nhH^wwA8I;6NGI>_qep)aFJBScy$;kr)*eqg_Wui_j=!< zXi8*0VpEA;V!Ko1=E&7#C-k0MumrM>Y!ViZkEr)2?@hU@?D*#f{o=pWfr6hfww7F_ zb!kOhQNkOXu?=1oo$w7>Wu0;i#`nc6Hnla?UrzkRs}k0R^XJ#aITt0W*Y)l!;ukb2 zeK=py%Uvw3Xt3%`i$?8+KtnJSj#{r!ZQO;WC>`N>n$SK`e#&YNl<0rIUOpZf9DFBM z$B0*3pALfQRsQ-%(9`2D$bPz@1SJlT1|_dwAgAq_<HDmvm&|bhXGY)PD{%Fs#_gF2 zN`_I-B#<8RpC9s9zw!A5xLn$tKOegpxRdukURJ_>J1zMl$978yk*09X&ywU#Z(x`- zShDW3bwwX6;8Ew(s)MObbRfHaDl>W|K1<qTnSmD-`;bsT@~5jo?C~p%wBLGfY<zL( zl8lYOCC4i&*q@%dXRJaGr0BJ0t?&Ii>=aO|zHXjgW?x@=D2sKPMfiutIBL#}@C9hn zGCPWWk{e431SUq(=%)zQ?mX~k{<{fQ=&ZxwFKn*Jc~uxiPfA!!eDZ-XO!{l-SInpR z7V>XPKXR~?Q?V_HsM~^sCHiOmymesTfT4<Yc12;@?M6e
}j>tpB0tnl-GA#hv& z7X{#7EC;wNha|uv9jK=Ry82G>vAT1l^tdxnXgq0&N<A}?hFc8f63a=z^wh-*%_%p2 z91%!Eq;N1Ji*S)KN4OZAd^e@(z|E<Q)ZkCr))JP`hE40kA;XuKZ?>H}cHP?@p3Vm) zo*|fAm}Mo0I%?!DBF1!i5YEA9XlP-q)lC#gI=njD6~n`(o*)M5cP6+&byeMSL%odC zlpq?8DVmv!^-)g8TzDag4~z+@mo}GkdioULJG>j@^t@cCny|GKe@Oiv9%9_4>_MJY zh|!`3r41*O{?d?6fgw*0x9Fek*_b-Mi<Aa1pMEO!xQ1l#s9x-lRSiOOZ;hy)J<3=% z&Jt52h0p%sG=|)i`3%8O-r;XwP>R5FT2MNek>2vH50Ss85I82kv*4%P_r$_yv(?Fn zOPBl(aIj)?XZp(J<TzYX6l^k*q2?UXwxwkT=Du*%xwjIRuh8r6ja_|fl(x`|HUdj^ zM^_jPnKNL%oACDb`c(gGjs6#7g7Q0GTklL6tRf)}n3E0FGCmYB^o(xH-xzavDgi$| zLpd5(vAo>jwEBLf!rKp~`wcYMQVnta%B||>%<NUPS(5jC|L4oy-Q)P;{F|whm+N1z zZ|CN(P1AR$4q5vB{1+ry{!#p+;s~Fg`$w&9h1)@vzk6e{_TRe`^CDK|=Vx8U^=pTu zq~ayo+Q>?abryNtuXdFLl~wq4P#5nqOol~;&PfZI@OcPglz#dv4y6FN^6O~tAv7*s z+)tz^H}9+3{yGnx5^L=tm)~to+Y5l5mNJ)N$*&2(=Z!fqgC#@+YT_j2X4n((vDHUh zR~a_axd$NgYt{8+HwlKwD<<Yn{?XQBb}+ahTp_`drBf15JX(l#j)&{qBU<u}aLL_P zV#?U&m7yEc%Mr~|6uNSWF^K^6=^&<hjOF-rn4*MChhM2{P8A3q7EMmXuS^7aNh7Ec zh13mhjiHR{*h)wAckOVkBRTk3Vu_^ni9!2oDsNS#FPjn+;3f_<qw=fOwT$FsVu?k` zlr0#kASi|H(o8maStEfCpd@sJ3~a<5FGA^;MfxrMN0ZHcEHODhOD|el7lGA6XxvzA zAVQKi4Q=8fOVpBQ+{rD)6s~e#w!%qkp+eIUT7P2z+0CM8!SGL%J;`L!$%2FlcIqbz z>2^!I?GoYk=55>DF2qS#CRvako0uG8johv4eq(`KSJuS>7_)Qoc;YFCEP6h-Pk)-9 z-WIIq8Qj^M+ED(`Gb-{RWq9+ioVI@3n?E<D#Zn>6!pv3I=c9pj+a1*&iwU=7e_-PG zT9|YPz2iNSvj3iZ;8~ojG{)Zm(#X#UVB<<!EScq9l&T||w!-(SzYZUFgHuibZ)>y; zr7p<=!^=f~J0#8*y38JIUu?a_86QPvgBbuyoP?+|CJJrgGy)b|QJ#jS9@KCqfr*y@ zXek`%^6KYj{#_|UJ|&XfsxK_oeW#AYmjT0-LHHw}7rJhh7GbqSj<CPBS^8TPj1#yG z?HtXt7OM$R^?{6Qe?7NuVJ++mg^-&)?F@#9rN*HXEZ&Z1Lr;=0Cm)?Xkyo`wNgqnb zujdM@4s?wCwVm~C5n4M2p9dUanci0q?a0q(KuKf5Hr`V%=a=Exr+r$!ZciUGLWcjr zXgHp0-Oj4#HS0&R)k`K{-)T9t-{=BJLhG5h&@c8qIP4C1YfH^XdC%;1zToQMbVf4H zHn~_-Y+tGPurkhQB|{g++9y;sv2=q|v`u7_Mowf=^Fi®=UhG~B(LaXS;TCKW{8 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ΠZKF7RV%duy987F<pA1*W8%jkAl(6OY@Ql4%Twx5=4%l2OVMgD8~k z9N!5~B!NLs_(=uSHEgf+uGI6eH1XZyX)2&#_WG=><O|<V7&48M{p=?}sDh%lnp$I{ zHJat=eV1an988f<NAePS<SJU5?yPPdIScQmHab{hBN8y6xS#iI$umSdQR3t`ExB=! zdM)f^gA{iC-@8v|7QRu(ADO2&z<C))Q=$6W02yUnqa<`D%bO;e4J;9__5#a~ZaQo~ zqIvgbbDCWmavG+_w0M8nPteQn@o(_kRIr~n1-jJAe|p?;O8Ny@F&`B(uH@2!bT=#b zynXaKQon=?Q9?VvSkD;ZUD2#$f<-M`WRcj-x`41%nnqOeVA00Gkc(C{t^p-UfVr)) zg-hyGC!z~QK)Di~V{kQ*9cyF&h+`r0t)I}f?W*4D`oq+$(}`r|)Js!~s?<TiS+)$5 z=4;g5U~JZkg(kSvs-$5<tizLJAkAzF-4Qndc5CzFv9RrS0#X$*Gpv?AYQt9<opxBO zCoOU`bLLeke8&Fet`*~5K?{i4mE)i@Gpu5pYrNIPp;o5!clB2(emI94CA@li7073w zReJJCV|2JA1EWF>YTzmxDvLEWH?^8+uh4E8NAV-HaBQ>a7~QcY9&>2zYcqeCAnbN$ z7jf0#9u2H)2QExw*i_eMe^H+q9l{UnuAx3UnTsl_L=RL>m@Hy|8zqsJ;qvCIE;cyo zL9MP4V@gXrZcTncXlsVpvD?R1)&<9()}=PxyP+Uk5Wh!aK$X%c2Iy_FZ2y)JbrUh6 z==IdprEAJ2(r#Z$U0S{igef2^@}k7uV_a5~F7Qnm+Y5-tlr<$TD3io7vD8jS=z_Oa zqZzf(6J^b&Hl~l$U?d^Tg@P#BZ&(ux|D-=3+j9_C%Y4Ok`%>f$^Qga|&4u?s0ViE; z*l4!r*b;1)c}(EVhuSc0lAEm8@-en-;FzRgV=Uhi)|sR}<FsS}=-GnIf$z0XmHv+t z$FoYZa?3kIZ;R{dXKef<qTG@n_Hnzw3wja>(jz`NN{P1vOB)+i$*dJyZPk1VnX~LI z*Mod4&m9EbnzPt6!FdP-4jtKPI;KEA-k#h<l?{CwoEhhNhr+|HOg&JYWsWe;-Rg6- zI{$3NoNd^n_V$F3#s@drKX)fUg+AS@)u%olLSZu`j5yJIj(#hyOj*KbnhtWE=n@!_ zk9D{m$qQYpTKq9-<LCnlE6|f*ri3Sn2dhhAXf3WOAAFOsdTeiU8czOg8^U`2Lp#GK zeY{WpZ1ZJm+9L#dk0Gu1A5T(cCN|(cOwrgA9O~3J4CXvf+$gr5j3V=~<XriZbEBv1 zKr1lWEsta%Y-h&uz&WZ>ZsB~uXNtwM3^7RqVgCkyT%x*D1l0X;wg93dd8lmdBCyx{ z6@ItoW2EM{bDC+a(AQnOhmpJeWS?bnmb@3E^X0!f^^iS>-MJ;YHbpS<NP#q_75ZKt zd-zGB&Ai}wTA^+dGQ>TBmxgp?)!QFr+k%}eT56KDbKXy|N5W)XKB|#sQfK3yWPEz$ z?^A?V!z-rxXm$>G%~)6TtPkVMMxrxAzk!b|M@l#FD{mp~g?#eUi+wwEKe-0!$kG`D zk{mn2tW)(D>xtDL1rHMU(Me8)JXw$BS5xV&Gn#fDN)q<911`OjBNKI0zft4iQKc^J z^5X-Ug4?23=5gsB4{#)ZyP_d|P@4hCHn5*;=~1=vZ<Lg%Y1kgc6*^YquUHnkW>Bpg z6g_^oJ_&pfzD$5?Fg_)V4AjNQprmk%6ucY-aK{X-CK{+Nv4sZW+TB)e<t))|<mnQc zq_Pm1byj0TR%U?7!_kdj8(8Qz5=mrw)@YV!%un6j)IHfnj~+dFr#H^~>`P+0awX_E zwOf8K_0}ANS$Ws2z!gZ^4~);gF~JURXpT7kuoMnCeZ5BJ9$NloFR}Wi=&@7AL^k+i zoIa-X4GlhE?&%2IUf*Hws^mG6!8loQGsIJx`U{w6n8RRv8YQPtP-y`Tx66HQ<k{!w zR)@MvBrH;@YgN85q(xc895nLwC+X<DGe@T;PJq>}9rk>KALS??de3eXw{DeAFaj#r zmm5V4Vtg}=9Q&WR7oe|Xx!2XGw|y*Hs7=c^z6eg7`Fgnr*$W;O&7UA(e-zC`lu;X1 zPW+AcyMdkMGcEpA3msxP2sOo1LV{E75gBipWhp`#xsC0I%v`!9TLXFq4uCGSpfxn1 z*T|&aaYS5AfZ@G%8bNh_jOFqVEzsn1k884;r#I&3>4!T4J97xEIA-a4^Lc!CM5Nh) z3Nv+ubYlTtAn38=G|$XONb5(an#z(aKEWzVoMw?)7kQigG2ROrIik-S=k(tbm^2qd zzLB-#mG8*Y?&yteVb<wVAJa5v4d{+Zx~AjF@~Wv<+1@;4c;^*#i(Kemd#(JupI#&V z5tHHOYsK*nHw(`YDhzoN5A{lN4n&(U1?=QYn{PCG<?3D;r3y#Gs9^%*NahjZ1b4fY zEGwc<sLM=ixTm*;4aK{TVBhx6l#%}UdUR#vb@T1&RV5wqB56ZCN$%(8Ed=&u`!)4t z3RU}{)62`H8^l6^5&FblQXMbtH^}jy5|~|1OiqoEXkInO$nL}_2VsYL`D#Oi<MP7u zu_#EVaD-K^7@4K>rUnxku6H{qmr~wee@IMYc&s7#I$p0hD`&N)Pl9I4D*n-c1K;lK z!%5`V?mviEwzb$dY@(4=Z`TtB1^oaD&YK?ysj=dTGe_!6QQ0$8TB__=dC)rLo2L{g zxk`0~smwLDBkU_T!Vlp@K&E6!Eav$!yJ5IHT8|?OcR%4_+j-8Yj~C<Q=Gb%IF}F$7 zD-g$_huKntW%a4h*htyHvd*76ujLr|>-`_h%_-1~&3*1Zf33p0WXu@)`ORoU0&DEE z06wMgJ89X9OhxX6&tT^e6v}1}9ik7;a5t2A5(;=nDf~v2>QkHFDS7fZ;;e&czQ#W6 zH?fnmx1P6Z>a%er;5mZNy_Two)9=p{OHWaw<K*F5$iCL8IJcd~`6L#Uf~^Z)jQjkQ zqFZcn@=im^Rs~g&L+qU!s~T4;?E&k6;z@ee8!s)5gp~DUzm!u~#2)fJiVMHbVZ>(_ z%I{LgpWmj#7Vdf^uY6rOBHytf(*5uh1?`wCs!~@ZRQaRG0$xQQlYZ|L+i@n4&2Eyb zMsbe8K7BR=5)OBVP^<`}4X?H~ym8T_5QlQryU9^LgHcf|3C)pX_1#qa7cwD?aWpf$ zPh4aMMO&P#9zwiaPTyF<zGe(sWeG=%*y&Pm2DJ{~dQC~bB|_gRPQ0@mwOo3LBV#iX z#ILaZwwZ~BBKlG%yuF9eJjPj;<oy}~T3`a$r{^2k_|?qllhSh+yGBohDVxQf7y&aY zQL7-vM)Wp+*Sq#2<N;#OH-4oNjLcEMR8WI5F%fmZHZAli-W8#z6UC6pb1b~(L`(=q z2OP>?R&Y!R2aaI$vlABibNBCJ%N}Dx^(%JIBTm8!lZ0*iR5+M9)G>6`;@uv6rYxH| zo>Gvc%%4GPSSme_52EWh!`{|$Jj3IYOCD_z)jnuoR%Z7qUrP}fHHuseDrc{Z!@$rP zo;j8X8!)8scIQ-pxKqn%yNk@6n^h*wO*>59qAS=sg)^~5ppAqFc1Gn_9R-+eBg$;T z(_HI`KK6zNCl8p(dU8pBcPCgLZp`Idlin|5@a~Yt^~iCSSJ0mjZf1D26;ZH9pbgn4 ze%GeDN)H!8BcIBFpotV7@{zN$L?t?N6^DDkT$6WA<5iphl7t?i`Sdg3K&6NPZl#D^ zK_tSuWRl=+gepRGgCF9n5l^z-Z_~^eoqYILkA=F*#X6e%25UrrhzujB?moyv@Tq1M zlq?OW?m)0=@!Nh?h~BtrR2Ecb%`U?<#6l?G5c9f^LS7V21@Sd%*v1p~-oPayLe81b zw5FIhPNr`^+P>p3{os*OTAqMbNmvvA8tt^$oU9~MSoLmIBrOzU{eXR337mo{#%jIo zC=6ELv<-Ri)P~5=R<6J7aAqz%wmTW?)GRVEA1u|ofNdfrL)<jpJv5_uh$RxQ-FX<N zlB~Pt;cy`~0qEoWVeejGUlh)PMG6{=Lv|(EFX~U)^?J|pMhduLhjWGC)95Q3{%&xL zq>;2O+LA(70s4f!U@W!!Eyj&phgp5|$d*o)v#JeE7GJH`v_q2iyN)N5NoXLnrivWC z&5vsH?PZu~!xGTm7jUri&H3TzFNIO+M3=h7&V-<y)~T#3S&j*r`39Df{<vc#$iioa zf!j%ZRHCAI_|Fi<vaHRE4K|td^lrc$A6fNd$lS(L<KIt;<|U^qnX4F~N~+RVsY%1V zn?QbO<Gx^fgAk+WD_#Znj$)d#AbuP$LGsnji&yUW6J2p=y4%jS6?%O@9-m&z@HmM8 z?kGvZm?|c2meFM<4_r-ikH$nQ{<a2ZFmFi?Uo}3dke!ndCy5G!8sG6F42gq?!Y49E ziA)A+^-7lL%Sf+6%QByR>STu3M>7tek(cE?ta_{56$AfB_7mFM@mv~5ji+#*(<j7+ zP>M%pnlpjQ(A|Z6K6$9fmt~4Cs%dk1ct{SkdqJJ54KmDAR{@Qvt0zix6y78Tm+dow z+nmjWmy-?EaT3YrZ?+!Vj5R$AZcpa36qA$G(lb@7zHSWVg3HAjn3HudpVQUo4;hPz zi<33E?8a2NYK)FqZJ^%r+C;mFOw~3kS}l8*A0AexctIPS+?OJul+7l+tkaqbQnnu* z8~sYO%uE8mYIKWMx=l}F`=o5kby-A@T1zyqn1cYRJ-RyqMbd+C@2jTFbK?19$;Vxq z#>l}@#3XAGZ3*pTtZQf8uf;ov-ADtejBPO^>gF0d#c?CK*B?DE2rk*<6fd;&Nzls~ zAND`+R~W7&{G>b?!IEf7iM&%!hW&^RSD(LKdT>WBp3$qy&b(oTvd%9OGF2*T0I#jG zKQFm<Tx<AR&*7~KuNQT$L#jO-^2~sM1(n4t9mLSP$ezBtikdNpfh27Q7>cn($18gF zOc*K=j~}2sJDF6fe!{)V9GDYM$P&1L*35@2je&q0X;B~;xIuWB$s?8A+0Gf51OJ7A zWMyrGp5!P#@GZ6#{HeeTSPwlWtYQn`zujGsL%Fro@LYB|pbT}ky0>`kC?m2o%-$&T zJRMnG{v`#;;0oN%#mAz_?a4?^Y<dGGV{&=O#Uo(e-2qkJyIQMZHQsb~eviv4+(=Oc z-B2XP+^U3j+;jx3hwff@vTsErGaUk+<HY3ih<oXfQSL+w54^9JDl12L;ojs_`XKVv z<^x9hhzuRyfYMDa1TXFHSo=Y@@x}~m0-R*@JQS+hf>B<s^Es&HRv51q^1he@@)5Y0 zmJjt$hmx(7ZJi>KWo*qzHN~5TI?{2V=&6??^RfEjQ=@jS1w8Je3Nlwd@sv-IEJqBj z>(1j{%eS<X1ggc9k~2Gc(2fWXpQO#A9CdX2DrN;(JSIKL+Bif*J~mfIoW7;>q7$)x zhcPj#@LFzyY!0Da-NbPf8OMWgCEniwcqpPSjUQ!+VMZIIi`hwe<Zl{?)R?f|Vs5_N znOv%OQo=Xiq3%L=#MV%-R{F+j35i@a4q=@m8qIP<Y+ZJnWdhhXwW$|t8i-$A$cJGo zP?H)wFfiz03a7e-HNtK~*@sQW7tB#5G;k6Xgpoe@AuVM88QNF%;7EJ*DMnH4<=I>h zbS&ryG^rYtUS&vBg;^`ZNaO2-HY$u6YKK2IOtjAIGo@@`i3}zH1?`OT8=X_2<Bf#& zU{>e!oThr$ruXDACcJV-ck%O3DzC$;Zc4Ba{o;`xKtMXOW-q@wR|=1oF{jl}Q<cX* z0G-5*a4$b5v1d4^lOt@Fr;{O+K28lJ9HgZd*&b};U<|Kz5}<2&Rgxth1Ww2zDm+c? zS1TnMS<8|egu;Al{-Jp8U;`Z57YL|f&BLF1Rg%!)grpH^-~pc}ZgP4ZXIgVOw&kIb z)3WzE#Mk}S=<N6;oP2s@hJ40LtdRdUeOL{{H?8^m(M|_&crhr!+-gGbOBblc`TccW z?C|s}52R0fc_u{XuH(sEH)vl3`CFV*Lzk663^eQLaIKcP4rcPn9|F2>_;sBoXK)VF zqHfj=j|)FVTB>HOWZAF1hTQl9ROBDR;{qN59s>Y?r-0hx-6X;X0DwDen8MysgI!b0 zW(;(*vg76iLal6#OiavdfWJLLexHN<F=yl8Wc~XD(8|sQVr2_qce68vaM-xo0G(}N zf8=cDWM^b^58`5DW%mMNVq{`z#_DcsWBXPS-2Uvz>o3Ds<m?UXw%F8)2b|AT-Xk7U zgdx{e=W^C&)yQ7oT;QiU3OIOwP4jl;At7}^x~ya?o_CbdL-k+Go02-JC1Hh_^aSUu z9VuSnZv3!^f2ETfINNWQgBsjWb0H{3JCuiChR-dmu4uGaJuYMMq$MtTms0{Ri0u=+ zYdYX{z5>vKM>CH^ccC!1W*qRcm?n5e^6|W;EiY=Ns2GlHT4&B6;nf>HB=n>JHnUf6 zTNmNa6UQAvQaVYR7+nC#6YZmKeP<r7Jz?n~LY1%^;F4*cZ3|?SRh9GHG7zMHO;Sep z_>g`M$CB@XZ`;zPHx$X?Dv<egwtPcKFvDxfTCpcJco*XYjH-{}`yAT^jQ;V#&!)i? zF*X3hOmaW?{>C&=m<8;u@AdopZ@=0HazD)qGX=`<Aj?qS;DDyXu(B+R8a;jgh@2v; zYOf-5|0AafcBt9~E}WAZPB<7(?euI?9yf*q`)nMH$1Z=4TOS5R4y$Ze3lHNsJA03d zigvEBj>gOkWBLFN0Qk2X$qp33b;CG@z}$!*_Wbkqhf^8Z*Z^IPoPP5Ipr(<N_`O5? zi}n2^?4`*IsEe(#`EOIKwnoms3aUoBY_WrhUZnv5IDV2s4io)P1;JRz+L_z`DgfiX zBDjJO^iTr^)d>?q^oIc0OW3yj5CE`(?FF<og2H_J9>594(8}KK-l=~j>bhX!R{-15 z4~9ei6V3~SpNRejY3A<iWb|JU@0n3Blf*W|kk(+Rq(335BmTk6#Kp<U%+6WL-p16- zNzBRK4Ql4}XL5i)qMqgq{ml3g06>oc01*5HB@asrzcF$!a&iV+S=bplyEvIae+9Yc zlQ66)I11ZY_b+_b(E$KkGiM`HBWEL^t(%FxlbMQ>y@Q#Pv(?{2J?@?pE`~uZ!v^h7 ze2!oY|09&7yR(@c^cMr%ALBi}jaRvbbucVe7(M!*Fc&cY3#OWxjhPYD?A{iCchE5p zvMHHhi2N|K690rci}feee{jgOkLE{UAh>t{0M1W90<f35;`XroY3B@4_i!+S>i->+ zmoccHS6~4AFax6e41f;+K%C5Mpg`99$3J`Ky<)=gT<;2DhwxX=lpy@WGmU`v;rNd{ z^D5R7{GH)epch8ruhGv6)6s81`8(o&h<+o;KZyQ&LA3H<xPMhE&`-y#O!ChK{k0<f zSw;79I6i`*_AuT4HOsWYBJZCb(0|D?c6_syEifC@!G!$m@O~8kBjEQ!`;V-^9B&CG z+z@E!f+^)QY-s$UoZp}PDSyHIyTWetPYSz{Ez}AEODa}IHoqp%dkUFY=ubmoGOJ+& z`V)l)s{bttzcw2XD?6yOlZ!1ZT7FB$FnZ3;R(2N9zawZncF}Jj4*;av1Ae=q`@cC( zz>@SIhW*dY&p*=9UkEzeJ3w4*S&dEp>}L1sTCw+c>W4A8j{5!f^7m|DP66A>9saM` z*!)zn?%ABb=CXYP6aTMP@Sex-Y`(7kZ?XCBjp48QiT3~Q1%|P>ANL*5{q{Sf==Hxc z`ul$9-zNK?e(29)?t9>jkc;vr817$#k$>Y4G5_j_|4}gBW0I)s`~H0}g0_Ca{JUT@ z{{IZddkWS?-_A8*8uNpV7qIc~&1w68i^5-g9c*voYUU(vX=G>ddky`Y9<J0k*XZxF zgzC=!8L@wwC4Ms=a?Hm=WdK0i{nsq<V)y@y;NND6dp30NMn<O206=8TuUTS>_rbqf z-v6Al{*f#F#g2cl`8iA6v-$M{<Gok?9+P#Y|66SSd6u|m^y}xOe=|}m|0|=v&l3Mu Z(x0*f0<1#@0LWoK8>j%lEes3*_<t4&Oilm* literal 0 HcmV?d00001 diff --git a/run_mex.bat b/run_mex.bat new file mode 100644 index 0000000..411f269 --- /dev/null +++ b/run_mex.bat @@ -0,0 +1,59 @@ +@echo off + + +IF [%1]==[] (set params_f1=.\Inu\wrapper_inu_1.c) +IF NOT [%1]==[] (set params_f1=.\Inu\%1) + +echo %params_f1% + +set params_d1=-D"ML" -D"__IQMATHLIB_H_INCLUDED__" -D"_MATLAB_SIMULATOR" +set params_d2=-D"_MATLAB_FAST_SIMULATOR" -D"PROJECT_SHIP=1" + +set params_i=-I"..\device_support_ml\include"^ + -I"."^ + -I".\Inu"^ + -I".\Inu\Src\main"^ + -I".\Inu\Src\N12_VectorControl"^ + -I".\Inu\Src\main_matlab"^ + -I".\Inu\Src\N12_Libs"^ + -I".\Inu\Src\N12_Xilinx" + +set params_o=-outdir "." + +set params_f2=.\Inu\controller.c^ + .\Inu\Src\main_matlab\IQmathLib_matlab.c^ + .\Inu\Src\main_matlab\main_matlab.c^ + .\Inu\Src\main_matlab\errors_matlab.c^ + .\Inu\Src\main_matlab\adc_tools_matlab.c^ + .\Inu\Src\main\v_pwm24_v2.c^ + .\Inu\Src\N12_Libs\mathlib.c^ + .\Inu\Src\N12_Libs\filter_v1.c^ + .\Inu\Src\N12_Libs\pid_reg3.c^ + .\Inu\Src\N12_Libs\rmp_cntl_v1.c^ + .\Inu\Src\N12_Libs\svgen_dq_v2.c^ + .\Inu\Src\N12_Libs\svgen_mf.c^ + .\Inu\Src\N12_Libs\uf_alg_ing.c^ + .\Inu\Src\N12_Xilinx\xp_write_xpwm_time.c^ + .\Inu\Src\N12_Libs\global_time.c^ + .\Inu\Src\N12_VectorControl\vector_control.c^ + .\Inu\Src\N12_VectorControl\abc_to_dq.c^ + .\Inu\Src\N12_VectorControl\regul_power.c^ + .\Inu\Src\N12_VectorControl\regul_turns.c^ + .\Inu\Src\N12_VectorControl\teta_calc.c^ + .\Inu\Src\N12_VectorControl\dq_to_alphabeta_cos.c + +set params_f3=.\Inu\Src\N12_Libs\modbus_table.c^ + .\Inu\Src\main\detect_overload.c^ + .\Inu\Src\N12_VectorControl\filter_analog.c^ + .\Inu\Src\N12_VectorControl\filter_bat2.c^ + .\Inu\Src\main\PWMTools.c + +set params_obj=..\device_support_ml\source\C28x_FPU_FastRTS.obj ..\device_support_ml\source\DSP2833x_GlobalVariableDefs.obj + + + + +echo mex %params_d1% %params_d2% %params_i% %params_o% %params_f1% %params_f2% %params_obj% -g + + +mex %params_d1% %params_d2% %params_i% %params_o% %params_f1% %params_f2% %params_obj% -g