From 930ea864c71ab359633d9205015ab55fa2bae661 Mon Sep 17 00:00:00 2001 From: pavel Date: Wed, 15 Apr 2026 23:55:09 +0300 Subject: [PATCH] added files --- FOExp.v | 1108 +++++++++++++++++++++++++++++++++++++++++ UML/Activity.plantuml | 31 ++ UML/Sequence.plantuml | 20 + UML/Sequence.png | Bin 0 -> 16620 bytes UML/State.plantuml | 19 + UML/State.png | Bin 0 -> 38943 bytes 6 files changed, 1178 insertions(+) create mode 100644 FOExp.v create mode 100644 UML/Activity.plantuml create mode 100644 UML/Sequence.plantuml create mode 100644 UML/Sequence.png create mode 100644 UML/State.plantuml create mode 100644 UML/State.png diff --git a/FOExp.v b/FOExp.v new file mode 100644 index 0000000..77b1e53 --- /dev/null +++ b/FOExp.v @@ -0,0 +1,1108 @@ +// Unit name to specify here - UNIT1, UNIT2, UNIT3 or UNIT4 +`define UNIT4 + +module FOExp (SKiiP_EN, SKiiP_CTRL, SKiiP_ERR, PCON_IN, PCON_OUT, PCON_OUT_EN , SENS_IN, clock, DINPUT, DOUTPUT, INP_1V2OK, INP_2V5OK, INP_3V3OK); + +output [4:1] SKiiP_EN; +output [4:1] SKiiP_CTRL; +input [2:1] SKiiP_ERR; + +input PCON_IN; +output PCON_OUT; +output PCON_OUT_EN; + +input [6:1] SENS_IN; + +input clock; + +input [4:1] DINPUT; +output [2:1] DOUTPUT; + +input INP_1V2OK; +input INP_2V5OK; +input INP_3V3OK; + +reg [2:1] SKiiP_ERR_DATA; +reg PCON_IN_DATA; +reg [6:1] SENS_IN_DATA; +reg [4:1] DINPUT_DATA; +reg INP_1V2OK_DATA; +reg INP_2V5OK_DATA; +reg INP_3V3OK_DATA; + +reg [4:1] SKiiP_ENABLE; +reg [4:1] SKiiP_CONTROL; +reg [2:1] DIGITAL_OUTPUT; + +reg [4:1] SKiiP_EN_BUF; +reg [4:1] SKiiP_CTRL_BUF; +reg [2:1] DOUTPUT_BUF; +reg PCON_OUT_BUF; +reg PCON_OUT_EN_BUF; + + +reg [25:0] clock_div; +reg [5:0] clock_div2; + +wire [15:0] CHOPP_CURR_IN; +reg [11:0] CHOPPER_CURRENT /*synthesis preserve */; +reg [31:0] CHOPPER_CURRENT_ADC; +wire CHOPP_CURR_DATA_READY; +wire [1:0] CHOPPER_CURR_ERR; + +wire [15:0] BRAKE_CURR_IN; +reg [11:0] BRAKE_CURRENT /*synthesis preserve */; +reg [31:0] BRAKE_CURRENT_ADC; +wire BRAKE_CURR_DATA_READY; +wire [1:0] BRAKE_CURR_ERR; + +wire [15:0] INPUT_VOLTAGE_IN; +reg [11:0] INPUT_VOLTAGE /*synthesis preserve */; +reg [31:0] INPUT_VOLTAGE_ADC; +wire INPUT_VOLTAGE_DATA_READY; +wire [1:0] INPUT_VOLTAGE_ERR; + +wire [15:0] OUTPUT_VOLTAGE_IN; +reg [11:0] OUTPUT_VOLTAGE /*synthesis preserve */; +reg [31:0] OUTPUT_VOLTAGE_ADC; +wire OUTPUT_VOLTAGE_DATA_READY; +wire [1:0] OUTPUT_VOLTAGE_ERR; + +wire [11:0] SKIIP_CHOPP_CURRENT_IN; +reg [11:0] SKIIP_CHOPP_CURRENT /*synthesis preserve */; +reg [31:0] SKIIP_CHOPP_CURRENT_ADC; +wire [11:0] SKIIP_CHOPP_TEMP_IN; +reg [11:0] SKIIP_CHOPP_TEMP /*synthesis preserve */; +reg [31:0] SKIIP_CHOPP_TEMP_ADC; +wire SKIIP_CHOPP_DATA_READY; +wire [1:0] SKIIP_CHOPP_ERR; + +wire [11:0] SKIIP_BRAKE_CURRENT_IN; +reg [11:0] SKIIP_BRAKE_CURRENT /*synthesis preserve */; +reg [31:0] SKIIP_BRAKE_CURRENT_ADC; +wire [11:0] SKIIP_BRAKE_TEMP_IN; +reg [11:0] SKIIP_BRAKE_TEMP /*synthesis preserve */; +reg [31:0] SKIIP_BRAKE_TEMP_ADC; +wire SKIIP_BRAKE_DATA_READY; +wire [1:0] SKIIP_BRAKE_ERR; + +reg [155:0] DATA_TO_PCON; +wire [155:0] DATA_FROM_PCON_wire; +reg [155:0] DATA_FROM_PCON; +wire PCON_DATA_READY; +wire [2:0] PCON_IO_ERR; + +reg [15:0] CALC_SM_COUNTER; +reg [4:0] CALC_SM_STATE; +reg CALC_ERROR_FLAG; + +reg [7:0] CRITICAL_DATA_INPUT; +reg [11:0] FO_INPUT_VAL1; +reg [11:0] FO_INPUT_VAL2; +reg [11:0] FO_INPUT_VAL3; +reg [11:0] FO_INPUT_VAL4; +reg [11:0] FO_INPUT_VAL5; +reg [11:0] FO_INPUT_VAL6; +reg [11:0] FO_INPUT_VAL7; +reg [7:0] FO_SLOW_INPUT_VAL1; +reg [7:0] FO_SLOW_INPUT_VAL2; +reg [7:0] FO_SLOW_INPUT_VAL3; +reg [7:0] FO_SLOW_INPUT_VAL4; +reg [7:0] FO_SLOW_INPUT_VAL5; +reg [7:0] FO_SLOW_INPUT_VAL6; +reg [7:0] FO_SLOW_INPUT_VAL7; +reg [7:0] FO_SLOW_INPUT_VAL8; + +reg [23:0] ERROR_FLAGS /*synthesis preserve */; +reg [23:0] ERROR_LATCH /*synthesis preserve */; +reg GlobalError /*synthesis preserve */; +reg [15:0] Error_Reset_Counter; + +reg [63:0] BRAKE_ENERGY_STOCK = 12000000; +reg [63:0] BRAKE_ENERGY_APPLIED; +reg [63:0] BRAKE_ENERGY_DISSIPATED; +reg [15:0] BRAKE_ENERGY_ON; +reg [15:0] BRAKE_ENERGY_OFF; +reg [15:0] BRAKE_ENERGY_COUNTER; +reg [15:0] BREAK_OUTPUT_VOLTAGE; + +//reg REACTOR_OVERHEAT_ERROR1; +//reg REACTOR_OVERHEAT_ERROR2; +//reg BRAKE_RESISTANCE_OVERHEAT; + +reg INP_OVERVOLTAGE_ERR; +reg OUT_OVERVOLTAGE_ERR; +reg CHOPP_OVERCURRENT_ERR; +reg BRAKE_OVERCURRENT_ERR; +reg OVERTEMP_ERR; +reg BRAKE_OVERLOAD_ERR=1; +reg PCON_ERROR_FLAG; +reg ERROR_RESET_FLAG; + +reg [32:0] FAN_START_COUNTER; + +reg BRAKE_ENABLE; +reg [15:0] BRAKE_PWM_COUNTER; +reg [15:0] BRAKE_PWM_WIDTH; + +reg CHOPPER_ENABLE; +reg [15:0] CHOPPER_PWM_COUNTER; +reg [15:0] CHOPPER_PWM_WIDTH; + +reg CHOPP_TOP_IGBT; +reg CHOPP_BOT_IGBT; + +reg BRAKE_TOP_IGBT; +reg BRAKE_BOT_IGBT; + +reg [4:1] DINPUT_FILTERED; +reg [15:0] DFILTER_COUNTER; +reg [15:0] DINP_FILTER1; +reg [15:0] DINP_FILTER2; +reg [15:0] DINP_FILTER3; +reg [15:0] DINP_FILTER4; + +reg signed [31:0] REG_INTEGRATOR_LIMIT = 0; +reg signed [31:0] CHOPPER_VOLTAGE_SETPOINT=0/*synthesis preserve */; +reg signed [31:0] REG_VOLTAGE_INPUT=0; +reg signed [31:0] REG_INPUT=0; +reg signed [31:0] REG_INTEGRATOR=0; +reg signed [31:0] REG_OUTPUT=0/*synthesis preserve */; +reg signed [31:0] REG_ERROR = 1; +reg signed [31:0] REG_PROP_OUTPUT = 0; +reg signed [31:0] REG_INTEGRATOR_OUTPUT = 0; +reg signed [31:0] REG_PROP = 5; // A/V +reg signed [31:0] REG_INT = 15; //~x0.1 40 = 40 * 10000/1024 = 390 A/V/s +reg signed [31:0] REG_INT_T = 4; //~x0.1 40 = 40 * 10000/1024 = 390 A/V/s +reg signed [31:0] REG_RESULT = 1/*synthesis preserve */; +reg [15:0] REG_INTEGRATOR_COUNTER = 0; +reg signed [31:0] CHOPPER_CURRENT_LIMIT = 0/*synthesis preserve */; +reg signed [31:0] REG_CURRENT_LIMIT = 0/*synthesis preserve */; +reg [31:0] REG_DC_POWER = 0/*synthesis preserve */; + +/*reg signed [12:0] INPV_FILTER_INPUT; +reg INPV_FILTER_DATA_INP_READY; +reg [1:0] INPV_FILTER_DATA_INP_ERROR; +wire [26:0] INPV_FILTER_OUTPUT; +wire INPV_FILTER_DATA_OUTP_READY; +wire [1:0] INPV_FILTER_DATA_OUTP_ERROR; +reg signed [26:0] INPUT_VOLTAGE_FILTERED; +reg [15:0] FILTERS_COUNTER; +reg [1:0] FILTER_ERROR; +reg FILTER_DATA_READY; +reg filter_reset; +*/ + +reg [11:0] VIN_FILTER_INPUT /*synthesis preserve */; +reg [11:0] VIN_FILTER_OUTPUT /*synthesis preserve */; +wire [11:0] VIN_FILTER_OUTPUT_wire; + +reg [11:0] VOUT_FILTER_INPUT /*synthesis preserve */; +reg [11:0] VOUT_FILTER_OUTPUT /*synthesis preserve */; +wire [11:0] VOUT_FILTER_OUTPUT_wire; + +reg [11:0] CURRENT_FILTER_INPUT /*synthesis preserve */; +reg [11:0] CURRENT_FILTER_OUTPUT /*synthesis preserve */; +wire [11:0] CURRENT_FILTER_OUTPUT_wire; +reg [15:0] MEAN_CHOPPER_CURRENT; + +reg signed [31:0] INPUT_VOLTAGE_MAXPWM; +reg signed [31:0] OUTPUT_VOLTAGE_MAXPWM; +reg signed [31:0] CHOPPER_PWM_WIDTH_MAX; +reg signed [31:0] INPUT_VOLTAGE_PWM_WIDTH_MAX; +reg signed [31:0] CHOPPER_PWM_WIDTH_MAX_N_MULT; +reg signed [31:0] CHOPPER_PWM_WIDTH_MAX_N_DIV; +reg [15:0] CHOPPER_PWM_WIDTH_LIMIT; +reg [15:0] CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER=0; + + +reg [31:0] TEST_COUNTER=0; +reg TEST_DIRECTION=0; +reg [11:0] TEST_OUTPUT=0; + +reg [15:0] REG_CALC_COUNTER=0; + +reg BRAKE_ERROR; +reg [31:0] BRAKE_ENABLE_COUNTER = 0; + +reg [11:0] BRAKE_CURRENT_MAX; +reg [11:0] BRAKE_CURRENT_MAX_CYCLE; + +reg [11:0] SKIIP_BRAKE_CURRENT_MAX; +reg [11:0] SKIIP_BRAKE_CURRENT_MAX_CYCLE; + +reg [15:0] MAXCURR_COUNTER=0; + +PCON_DATA_IO MAIN_FO_IO(.clockin(clock), .FO_INPUT(PCON_IN), .FO_OUTP(PCON_OUT), + .DATA_TO_SEND(DATA_TO_PCON), + .DATA_RECIEVED(DATA_FROM_PCON_wire), + .DATA_CLOCK(PCON_DATA_READY), .IO_ERR(PCON_IO_ERR)); + +SKIIPInput CHOPPER_SKIIP_INPUT(.clockin(clock), .FO_INPUT(SENS_IN[1]), + .CURRENT_OUTPUT(SKIIP_CHOPP_CURRENT_IN), + .TEMP_OUTPUT(SKIIP_CHOPP_TEMP_IN), + .DATA_CLOCK(SKIIP_CHOPP_DATA_READY), + .SENSOR_ERR(SKIIP_CHOPP_ERR)); + +SKIIPInput BRAKE_SKIIP_INPUT(.clockin(clock), .FO_INPUT(SENS_IN[2]), + .CURRENT_OUTPUT(SKIIP_BRAKE_CURRENT_IN), + .TEMP_OUTPUT(SKIIP_BRAKE_TEMP_IN), + .DATA_CLOCK(SKIIP_BRAKE_DATA_READY), + .SENSOR_ERR(SKIIP_BRAKE_ERR)); + +SensorInput CHOPPER_CURRENT_SENSOR_INP(.clockin(clock), .FO_INPUT(SENS_IN[3]), + .DATA_OUTPUT(CHOPP_CURR_IN), .DATA_CLOCK(CHOPP_CURR_DATA_READY), .SENSOR_ERR(CHOPPER_CURR_ERR)); +SensorInput BRAKE_CURRENT_SENSOR_INP(.clockin(clock), .FO_INPUT(SENS_IN[4]), + .DATA_OUTPUT(BRAKE_CURR_IN), .DATA_CLOCK(BRAKE_CURR_DATA_READY), .SENSOR_ERR(BRAKE_CURR_ERR)); +SensorInput INP_VOLTAGE_SENSOR_INP(.clockin(clock), .FO_INPUT(SENS_IN[5]), + .DATA_OUTPUT(INPUT_VOLTAGE_IN), .DATA_CLOCK(INPUT_VOLTAGE_DATA_READY), .SENSOR_ERR(INPUT_VOLTAGE_ERR)); +SensorInput OUTP_VOLTAGE_SENSOR_INP(.clockin(clock), .FO_INPUT(SENS_IN[6]), + .DATA_OUTPUT(OUTPUT_VOLTAGE_IN), .DATA_CLOCK(OUTPUT_VOLTAGE_DATA_READY), .SENSOR_ERR(OUTPUT_VOLTAGE_ERR)); + + +MeanFilter VIN_FILTER(.clockin(clock), .DATA_INPUT(VIN_FILTER_INPUT), .DATA_OUTPUT(VIN_FILTER_OUTPUT_wire)); +MeanFilter VOUT_FILTER(.clockin(clock), .DATA_INPUT(VOUT_FILTER_INPUT), .DATA_OUTPUT(VOUT_FILTER_OUTPUT_wire)); +MeanFilter CHOPPER_CURRENT_FILTER(.clockin(clock), .DATA_INPUT(CURRENT_FILTER_INPUT), .DATA_OUTPUT(CURRENT_FILTER_OUTPUT_wire)); + +assign SKiiP_EN = SKiiP_EN_BUF; +assign SKiiP_CTRL = SKiiP_CTRL_BUF; +assign PCON_OUT_EN = PCON_OUT_EN_BUF; +assign DOUTPUT = DOUTPUT_BUF; + +initial +begin +SKiiP_EN_BUF = 0; +SKiiP_CTRL_BUF = 0; +PCON_OUT_EN_BUF = 0; +DOUTPUT_BUF = 0; +CALC_ERROR_FLAG=0; +end + +always@* +begin + +SKiiP_CONTROL[1] = CHOPP_TOP_IGBT; +SKiiP_CONTROL[2] = CHOPP_BOT_IGBT; + +SKiiP_CONTROL[3] = BRAKE_TOP_IGBT; +SKiiP_CONTROL[4] = BRAKE_BOT_IGBT; + + +ERROR_FLAGS[0] = CHOPPER_CURR_ERR[0]|CHOPPER_CURR_ERR[1]; + +`ifdef UNIT3 +ERROR_FLAGS[1] = 0;//BRAKE_CURR_ERR[0]|BRAKE_CURR_ERR[1]; //TEMPLOCK U3!!!! +`else +ERROR_FLAGS[1] = BRAKE_CURR_ERR[0]|BRAKE_CURR_ERR[1]; //NORMAL U1,2,4!!!! +`endif + +ERROR_FLAGS[2] = INPUT_VOLTAGE_ERR[0]|INPUT_VOLTAGE_ERR[1]; +ERROR_FLAGS[3] = OUTPUT_VOLTAGE_ERR[0]|OUTPUT_VOLTAGE_ERR[1]; +ERROR_FLAGS[4] = SKIIP_CHOPP_ERR[0]|SKIIP_CHOPP_ERR[1]; + +`ifdef UNIT2 +ERROR_FLAGS[5] = 0; //TEMPLOCK U2!!!! +`else +ERROR_FLAGS[5] = SKIIP_BRAKE_ERR[0]|SKIIP_BRAKE_ERR[1]; //NORMAL U1,3,4!!!! +`endif + +ERROR_FLAGS[6] = ~SKiiP_ERR[1]; +ERROR_FLAGS[7] = ~SKiiP_ERR[2]; +ERROR_FLAGS[8] = PCON_IO_ERR[0]|PCON_IO_ERR[1]|PCON_IO_ERR[2]; +ERROR_FLAGS[9] = CALC_ERROR_FLAG; + +`ifdef UNIT4 +ERROR_FLAGS[10] = (~INP_1V2OK)|(~INP_2V5OK); //TEMPLOCK U4!!!! +`else +ERROR_FLAGS[10] = (~INP_1V2OK)|(~INP_2V5OK)|INP_3V3OK; //NORMAL U1,2,3!!!! +`endif + +ERROR_FLAGS[11] = 0; + +ERROR_FLAGS[12] = ~DINPUT_FILTERED[1]; // +ERROR_FLAGS[13] = ~DINPUT_FILTERED[2]; // +ERROR_FLAGS[14] = ~DINPUT_FILTERED[3]; // +ERROR_FLAGS[15] = DINPUT_FILTERED[4]; +ERROR_FLAGS[16] = INP_OVERVOLTAGE_ERR; +ERROR_FLAGS[17] = OUT_OVERVOLTAGE_ERR; +ERROR_FLAGS[18] = CHOPP_OVERCURRENT_ERR; +ERROR_FLAGS[19] = BRAKE_OVERCURRENT_ERR; +ERROR_FLAGS[20] = OVERTEMP_ERR; +ERROR_FLAGS[21] = BRAKE_OVERLOAD_ERR; +ERROR_FLAGS[22] = PCON_ERROR_FLAG; +ERROR_FLAGS[23] = GlobalError; + +if ((ERROR_LATCH & (24'b001111111111111111111111)) == 0) begin BRAKE_ERROR = 0; end +else begin BRAKE_ERROR = 1; end + +//BRAKE_ERROR = ERROR_LATCH[1]|ERROR_LATCH[3]|ERROR_LATCH[5]|ERROR_LATCH[6]|ERROR_LATCH[7]| +// ERROR_LATCH[8]|ERROR_LATCH[9]|ERROR_LATCH[10]|ERROR_LATCH[14]| +// ERROR_LATCH[19]|ERROR_LATCH[20]|ERROR_LATCH[21]; + +if (Error_Reset_Counter == 0) + begin + ERROR_LATCH = ERROR_LATCH | ERROR_FLAGS; + end +else + begin + ERROR_LATCH = ERROR_FLAGS & (24'b001111111111111111111111); + end + +if ((ERROR_LATCH == 0)) + begin + GlobalError=0; + SKiiP_EN_BUF[1] = 0; + SKiiP_EN_BUF[2] = 0; + SKiiP_EN_BUF[3] = 1; + SKiiP_EN_BUF[4] = 1; + SKiiP_CTRL_BUF[1] = ~SKiiP_CONTROL[1]; + SKiiP_CTRL_BUF[2] = ~SKiiP_CONTROL[2]; + SKiiP_CTRL_BUF[3] = 1; + SKiiP_CTRL_BUF[4] = 1; + DOUTPUT_BUF = ~DIGITAL_OUTPUT; + end +else + begin + SKiiP_EN_BUF[1] = 1; + SKiiP_EN_BUF[2] = 1; + SKiiP_EN_BUF[3] = 0; + SKiiP_EN_BUF[4] = 0; + SKiiP_CTRL_BUF[1] = 1; + SKiiP_CTRL_BUF[2] = 1; + SKiiP_CTRL_BUF[3] = ~SKiiP_CONTROL[3]; + SKiiP_CTRL_BUF[4] = ~SKiiP_CONTROL[4]; + DOUTPUT_BUF = ~DIGITAL_OUTPUT; + GlobalError=1; + end + +end + + +always@(posedge clock) +begin + + + +DATA_FROM_PCON = DATA_FROM_PCON_wire; +PCON_OUT_EN_BUF = 0; + +//DINP FILTERS ----------------------------------- + +if (DFILTER_COUNTER>5000) + begin + DFILTER_COUNTER = 0; + DINP_FILTER1 = 0; + DINP_FILTER2 = 0; + DINP_FILTER3 = 0; + DINP_FILTER4 = 0; + end +else if (DFILTER_COUNTER>4950) + begin + if (DINP_FILTER1>2500) begin DINPUT_FILTERED[1]=1; end else begin DINPUT_FILTERED[1]=0; end + if (DINP_FILTER2>2500) begin DINPUT_FILTERED[2]=1; end else begin DINPUT_FILTERED[2]=0; end + if (DINP_FILTER3>2500) begin DINPUT_FILTERED[3]=1; end else begin DINPUT_FILTERED[3]=0; end + if (DINP_FILTER4>2500) begin DINPUT_FILTERED[4]=1; end else begin DINPUT_FILTERED[4]=0; end + DFILTER_COUNTER = DFILTER_COUNTER + 1; + end +else + begin + if (DINPUT[1]==1) begin DINP_FILTER1 = DINP_FILTER1 + 1; end + if (DINPUT[2]==1) begin DINP_FILTER2 = DINP_FILTER2 + 1; end + if (DINPUT[3]==1) begin DINP_FILTER3 = DINP_FILTER3 + 1; end + if (DINPUT[4]==1) begin DINP_FILTER4 = DINP_FILTER4 + 1; end + DFILTER_COUNTER = DFILTER_COUNTER + 1; + end + + +//----------SENSOR VALUES CALCULATIONS ---------------------------- + +if (CALC_SM_STATE==0) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + CHOPPER_CURRENT_ADC=0; + BRAKE_CURRENT_ADC=0; + INPUT_VOLTAGE_ADC=0; + OUTPUT_VOLTAGE_ADC=0; + SKIIP_CHOPP_CURRENT_ADC=0; + SKIIP_CHOPP_TEMP_ADC=0; + SKIIP_BRAKE_CURRENT_ADC=0; + SKIIP_BRAKE_TEMP_ADC=0; + + if (CALC_SM_COUNTER>5) begin CALC_SM_STATE=1; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==1) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + + CHOPPER_CURRENT_ADC[14:0] = CHOPP_CURR_IN[14:0]; + + `ifdef UNIT3 + BRAKE_CURRENT_ADC[14:0] = 16560; //TEMPLOCK U3!!!! + `else + BRAKE_CURRENT_ADC[14:0] = BRAKE_CURR_IN[14:0]; //NORMAL U1,2,4!!!! + `endif + + INPUT_VOLTAGE_ADC[14:0] = INPUT_VOLTAGE_IN[14:0]; + OUTPUT_VOLTAGE_ADC[14:0] = OUTPUT_VOLTAGE_IN[14:0]; + + SKIIP_CHOPP_CURRENT_ADC[11:0] = SKIIP_CHOPP_CURRENT_IN; + SKIIP_CHOPP_TEMP_ADC[11:0] = SKIIP_CHOPP_TEMP_IN; + + `ifdef UNIT2 + SKIIP_BRAKE_CURRENT_ADC[11:0] = 1707; //TEMPLOCK U2!!!! + SKIIP_BRAKE_TEMP_ADC[11:0] = 1707; //TEMPLOCK U2!!!! + `else + SKIIP_BRAKE_CURRENT_ADC[11:0] = SKIIP_BRAKE_CURRENT_IN; //NORMAL U1,3,4!!!! + SKIIP_BRAKE_TEMP_ADC[11:0] = SKIIP_BRAKE_TEMP_IN; //NORMAL U1,3,4!!!! + `endif + + CHOPPER_CURRENT_ADC[31:15] = 0; + BRAKE_CURRENT_ADC[31:15] = 0; + INPUT_VOLTAGE_ADC[31:15] = 0; + OUTPUT_VOLTAGE_ADC[31:15] = 0; + SKIIP_CHOPP_CURRENT_ADC[31:12] = 0; + SKIIP_CHOPP_TEMP_ADC[31:12] = 0; + SKIIP_BRAKE_CURRENT_ADC[31:12] = 0; + SKIIP_BRAKE_TEMP_ADC[31:12] = 0; + if (CALC_SM_COUNTER>5) begin CALC_SM_STATE=2; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==2) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + if (CALC_SM_COUNTER==1) + begin + + `ifdef UNIT1 + if (CHOPPER_CURRENT_ADC>=16585) begin CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC - 16585; end //U1=16585 //U2 = 16560 //U3 = 16590 //U4 = 16580 + else begin CHOPPER_CURRENT_ADC = 16585 - CHOPPER_CURRENT_ADC; end + `endif + + `ifdef UNIT2 + if (CHOPPER_CURRENT_ADC>=16560) begin CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC - 16560; end + else begin CHOPPER_CURRENT_ADC = 16560 - CHOPPER_CURRENT_ADC; end + `endif + + `ifdef UNIT3 + if (CHOPPER_CURRENT_ADC>=16590) begin CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC - 16590; end + else begin CHOPPER_CURRENT_ADC = 16590 - CHOPPER_CURRENT_ADC; end + `endif + + `ifdef UNIT4 + if (CHOPPER_CURRENT_ADC>=16580) begin CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC - 16580; end + else begin CHOPPER_CURRENT_ADC = 16580 - CHOPPER_CURRENT_ADC; end + `endif + + `ifdef UNIT4 + BRAKE_CURRENT_ADC = 0; + `else + if (BRAKE_CURRENT_ADC>=16560) begin BRAKE_CURRENT_ADC = BRAKE_CURRENT_ADC - 16560; end + else begin BRAKE_CURRENT_ADC = 16560 - BRAKE_CURRENT_ADC; end + `endif + + + if (INPUT_VOLTAGE_ADC>=16384) begin INPUT_VOLTAGE_ADC = INPUT_VOLTAGE_ADC - 16384; end + else begin INPUT_VOLTAGE_ADC = 16384 - INPUT_VOLTAGE_ADC; end + + if (OUTPUT_VOLTAGE_ADC>=16384) begin OUTPUT_VOLTAGE_ADC = OUTPUT_VOLTAGE_ADC - 16384; end + else begin OUTPUT_VOLTAGE_ADC = 16384 - OUTPUT_VOLTAGE_ADC; end + + if (SKIIP_CHOPP_CURRENT_ADC>=1707) begin SKIIP_CHOPP_CURRENT_ADC = SKIIP_CHOPP_CURRENT_ADC - 1707; end + else begin SKIIP_CHOPP_CURRENT_ADC = 1707 - SKIIP_CHOPP_CURRENT_ADC; end + + if (SKIIP_CHOPP_TEMP_ADC>=1707) begin SKIIP_CHOPP_TEMP_ADC = SKIIP_CHOPP_TEMP_ADC - 1707; end + else begin SKIIP_CHOPP_TEMP_ADC = 1707 - SKIIP_CHOPP_TEMP_ADC; end + + if (SKIIP_BRAKE_CURRENT_ADC>=1707) begin SKIIP_BRAKE_CURRENT_ADC = SKIIP_BRAKE_CURRENT_ADC - 1707; end + else begin SKIIP_BRAKE_CURRENT_ADC = 1707 - SKIIP_BRAKE_CURRENT_ADC; end + + if (SKIIP_BRAKE_TEMP_ADC>=1707) begin SKIIP_BRAKE_TEMP_ADC = SKIIP_BRAKE_TEMP_ADC - 1707; end + else begin SKIIP_BRAKE_TEMP_ADC = 1707 - SKIIP_BRAKE_TEMP_ADC; end + end + + if (CALC_SM_COUNTER>5) begin CALC_SM_STATE=3; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==3) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + if (CALC_SM_COUNTER==1) + begin + CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC*256; + BRAKE_CURRENT_ADC=BRAKE_CURRENT_ADC*256; + INPUT_VOLTAGE_ADC=INPUT_VOLTAGE_ADC*256; + OUTPUT_VOLTAGE_ADC=OUTPUT_VOLTAGE_ADC*256; + SKIIP_CHOPP_CURRENT_ADC=SKIIP_CHOPP_CURRENT_ADC*256; + SKIIP_CHOPP_TEMP_ADC=SKIIP_CHOPP_TEMP_ADC*256; + SKIIP_BRAKE_CURRENT_ADC=SKIIP_BRAKE_CURRENT_ADC*256; + SKIIP_BRAKE_TEMP_ADC=SKIIP_BRAKE_TEMP_ADC*256; + end + if (CALC_SM_COUNTER>20) begin CALC_SM_STATE=4; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==4) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + if (CALC_SM_COUNTER==1) + begin + CHOPPER_CURRENT_ADC = CHOPPER_CURRENT_ADC/1006; + BRAKE_CURRENT_ADC=BRAKE_CURRENT_ADC/1006; + INPUT_VOLTAGE_ADC=INPUT_VOLTAGE_ADC/1610; + OUTPUT_VOLTAGE_ADC=OUTPUT_VOLTAGE_ADC/1610; + SKIIP_CHOPP_CURRENT_ADC=SKIIP_CHOPP_CURRENT_ADC/175; + SKIIP_CHOPP_TEMP_ADC= 20 + SKIIP_CHOPP_TEMP_ADC/4369; + SKIIP_BRAKE_CURRENT_ADC=SKIIP_BRAKE_CURRENT_ADC/175; + SKIIP_BRAKE_TEMP_ADC= 20 + SKIIP_BRAKE_TEMP_ADC/4369; + end + if (CALC_SM_COUNTER>20) begin CALC_SM_STATE=5; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==5) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + if (CHOPPER_CURRENT_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (BRAKE_CURRENT_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (INPUT_VOLTAGE_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (OUTPUT_VOLTAGE_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (SKIIP_CHOPP_CURRENT_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (SKIIP_CHOPP_TEMP_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (SKIIP_BRAKE_CURRENT_ADC>4095) begin CALC_ERROR_FLAG=1; end + else if (SKIIP_BRAKE_TEMP_ADC>4095) begin CALC_ERROR_FLAG=1; end + else begin CALC_ERROR_FLAG=0; end + + if (CALC_SM_COUNTER>5) begin CALC_SM_STATE=6; CALC_SM_COUNTER=0; end + end +else if (CALC_SM_STATE==6) + begin + CALC_SM_COUNTER = CALC_SM_COUNTER + 1; + //if (CALC_ERROR_FLAG==0) + // begin + CHOPPER_CURRENT<=CHOPPER_CURRENT_ADC[11:0]; + BRAKE_CURRENT<=BRAKE_CURRENT_ADC[11:0]; + INPUT_VOLTAGE<=INPUT_VOLTAGE_ADC[11:0]; + OUTPUT_VOLTAGE<=OUTPUT_VOLTAGE_ADC[11:0]; + SKIIP_CHOPP_CURRENT<=SKIIP_CHOPP_CURRENT_ADC[11:0]; + SKIIP_CHOPP_TEMP<=SKIIP_CHOPP_TEMP_ADC[11:0]; + SKIIP_BRAKE_CURRENT<=SKIIP_BRAKE_CURRENT_ADC[11:0]; + SKIIP_BRAKE_TEMP<=SKIIP_BRAKE_TEMP_ADC[11:0]; + // end + if (CALC_SM_COUNTER>5) begin CALC_SM_STATE=0; CALC_SM_COUNTER=0; end + end + +//----------SENSOR VALUES CALCULATIONS ---------------------------- + +//-----------------FILTERS------------------------------- + +VIN_FILTER_INPUT = INPUT_VOLTAGE; +VIN_FILTER_OUTPUT = VIN_FILTER_OUTPUT_wire; + +VOUT_FILTER_INPUT = OUTPUT_VOLTAGE; +VOUT_FILTER_OUTPUT = VOUT_FILTER_OUTPUT_wire; + +MEAN_CHOPPER_CURRENT = (CHOPPER_CURRENT+SKIIP_CHOPP_CURRENT)/2; +CURRENT_FILTER_INPUT = MEAN_CHOPPER_CURRENT; +CURRENT_FILTER_OUTPUT = CURRENT_FILTER_OUTPUT_wire; +REG_DC_POWER = CURRENT_FILTER_OUTPUT*VIN_FILTER_INPUT/1000; +//----------PROTECTIONS ------------------------------------------- + + +if ( + (CHOPPER_ENABLE==1 && ((CHOPPER_CURRENT>1000) || (SKIIP_CHOPP_CURRENT>1200))) + || (CHOPPER_CURRENT>1500) + || (SKIIP_CHOPP_CURRENT>1800) + ) begin CHOPP_OVERCURRENT_ERR = 1; end +else begin CHOPP_OVERCURRENT_ERR = 0; end + +if ( + (BRAKE_ENABLE==1 && ((BRAKE_CURRENT>1500) || (SKIIP_BRAKE_CURRENT>1200))) + || (BRAKE_CURRENT>1500) + || (SKIIP_BRAKE_CURRENT>2000) + ) begin BRAKE_OVERCURRENT_ERR = 1; end +else begin BRAKE_OVERCURRENT_ERR = 0; end + + +if (INPUT_VOLTAGE>1100 || VIN_FILTER_OUTPUT>1000) begin INP_OVERVOLTAGE_ERR=1; end +else begin INP_OVERVOLTAGE_ERR=0; end + +if (OUTPUT_VOLTAGE>1100 || VOUT_FILTER_OUTPUT>1000) begin OUT_OVERVOLTAGE_ERR=1; end +else begin OUT_OVERVOLTAGE_ERR=0; end + +if ((SKIIP_BRAKE_TEMP>70) || (SKIIP_CHOPP_TEMP>70)) begin OVERTEMP_ERR = 1; end +else begin OVERTEMP_ERR = 0; end + +if (BRAKE_ENERGY_COUNTER>50000) + begin + BRAKE_ENERGY_COUNTER = 0; + BRAKE_ENERGY_ON = 0; + BRAKE_ENERGY_OFF = 0; + BREAK_OUTPUT_VOLTAGE = VOUT_FILTER_OUTPUT; + //BREAK_OUTPUT_VOLTAGE = 700; + end +if (BRAKE_ENERGY_COUNTER==49990) + begin + if (BRAKE_ENERGY_STOCK<20000000) begin BRAKE_ENERGY_STOCK = BRAKE_ENERGY_STOCK + BRAKE_ENERGY_APPLIED; end + else begin BRAKE_ENERGY_STOCK = 20000000; end + end +if (BRAKE_ENERGY_COUNTER==49995) + begin + if (BRAKE_ENERGY_STOCK>BRAKE_ENERGY_DISSIPATED) + begin + BRAKE_ENERGY_STOCK = BRAKE_ENERGY_STOCK - BRAKE_ENERGY_DISSIPATED; + end + else + begin + BRAKE_ENERGY_STOCK = 0; + end + end + +BRAKE_ENERGY_APPLIED = (BRAKE_ENERGY_ON*BREAK_OUTPUT_VOLTAGE*BREAK_OUTPUT_VOLTAGE)/50000000; +BRAKE_ENERGY_DISSIPATED = (BRAKE_ENERGY_STOCK/200000)+1; // 75000kW/15000000MJ/1000ms = 1/200/1000 = 1/200000 +BRAKE_ENERGY_COUNTER = BRAKE_ENERGY_COUNTER + 1; + +if (BRAKE_TOP_IGBT==1) + begin + BRAKE_ENERGY_ON = BRAKE_ENERGY_ON + 1; + end +else + begin + BRAKE_ENERGY_OFF = BRAKE_ENERGY_OFF + 1; + end + +if (BRAKE_ENERGY_STOCK>12000000) //12MJ limit = 12000000 + begin + BRAKE_OVERLOAD_ERR = 1; + end +else + begin + BRAKE_OVERLOAD_ERR = 0; + end + + PCON_ERROR_FLAG = ~CRITICAL_DATA_INPUT[0]; + + + if ((ERROR_RESET_FLAG == 0) && (CRITICAL_DATA_INPUT[1]==1)) //ERROR RESET + begin + Error_Reset_Counter = 15000; + ERROR_RESET_FLAG = 1; + end + if ((ERROR_RESET_FLAG == 1) && (CRITICAL_DATA_INPUT[1]==0)) + begin + ERROR_RESET_FLAG = 0; + end + if (Error_Reset_Counter>0) + begin + Error_Reset_Counter = Error_Reset_Counter - 1; + end + +//----------PROTECTIONS ------------------------------------------- + +//----------CONTROL AND PWM GENERATION----------------------------- +//CHOPPER CONTROL +CHOPPER_ENABLE = CRITICAL_DATA_INPUT[2]; +CHOPP_TOP_IGBT=0; + +//TEST-------------------------------------------- +/* +if (TEST_COUNTER>50000) begin TEST_COUNTER=0; end +else begin TEST_COUNTER = TEST_COUNTER + 1; end +if (TEST_COUNTER==0) +begin +if (CURRENT_FILTER_OUTPUT > 500) begin TEST_DIRECTION=1; CURRENT_FILTER_OUTPUT=500; end +if (CURRENT_FILTER_OUTPUT == 0) begin TEST_DIRECTION=0; CURRENT_FILTER_OUTPUT = 1; end +else + begin + if (TEST_DIRECTION==0) begin CURRENT_FILTER_OUTPUT = CURRENT_FILTER_OUTPUT + 1; end + else begin CURRENT_FILTER_OUTPUT = CURRENT_FILTER_OUTPUT - 1; end + end +end +*/ +//TEST-------------------------------------------- + +CHOPPER_VOLTAGE_SETPOINT = FO_INPUT_VAL1; +CHOPPER_CURRENT_LIMIT = FO_INPUT_VAL2; +REG_INTEGRATOR_LIMIT = CHOPPER_CURRENT_LIMIT*1024; +REG_VOLTAGE_INPUT = VOUT_FILTER_OUTPUT; + + `ifdef UNIT1 + REG_PROP = 1; //A/V + REG_INT = 9; //~x0.1 10 = 10 * 10000/1024 = 95 A/V/s = 9500A/100V/s = 950A/100ms + `endif + + `ifdef UNIT2 + REG_PROP = 1; //A/V + REG_INT = 10; // + `endif + + `ifdef UNIT3 + REG_PROP = 1; //A/V + REG_INT = 11; // + `endif + + `ifdef UNIT4 + REG_PROP = 1; //A/V + REG_INT = 12; // + `endif + + +if (CHOPPER_ENABLE==1 && GlobalError==0) + begin + //TEST-------------------------------------------- + //if (TEST_COUNTER>2000000) begin TEST_COUNTER=0; end + //else begin TEST_COUNTER = TEST_COUNTER + 1; end + //if (TEST_COUNTER<1000000) begin REG_INPUT = 5; end + //else begin REG_INPUT = -5; end + //TEST-------------------------------------------- + + /*if (REG_CALC_COUNTER>50) begin REG_CALC_COUNTER=0; end + else begin REG_CALC_COUNTER = REG_CALC_COUNTER + 1; end + + if (REG_CALC_COUNTER<20) + begin + REG_PROP = REG_PROP; + REG_INT = REG_INT; + if (REG_DC_POWER>50) + begin + if (REG_DC_POWER>100) + begin + REG_PROP_T = 1; //A/V + REG_INT_T = 20; //~x0.1 20 = 20 * 10000/1024 = 195 A/V/s + end + else + begin + if (REG_DC_POWER<75) + begin + REG_PROP_T = 2; //A/V + REG_INT_T = 30; //~x0.1 30 = 30 * 10000/1024 = 293 A/V/s + end + else + begin + REG_PROP_T = REG_PROP_T; + REG_INT_T = REG_INT_T; + end + end + end + else + begin + if (REG_DC_POWER<25) + begin + REG_PROP_T = 5; //A/V + REG_INT_T = 40; //~x0.1 40 = 40 * 10000/1024 = 390 A/V/s + end + else + begin + REG_PROP_T = REG_PROP_T; + REG_INT_T = REG_INT_T; + end + end + end + else if (REG_CALC_COUNTER>30) + begin + REG_PROP = REG_PROP_T; + REG_INT = REG_INT_T; + end + else + begin + REG_PROP = REG_PROP; + REG_INT = REG_INT; + end*/ + + REG_INPUT = CHOPPER_VOLTAGE_SETPOINT - REG_VOLTAGE_INPUT; + + if (REG_INPUT>100) begin REG_ERROR = 100; end + else if (REG_INPUT<-100) begin REG_ERROR = -100; end + else begin REG_ERROR = REG_INPUT; end + + REG_PROP_OUTPUT = REG_ERROR*REG_PROP; + + if (REG_INTEGRATOR_COUNTER==5000) + begin + REG_INTEGRATOR = REG_INTEGRATOR + REG_ERROR*REG_INT_T; //Integrator x1024 + REG_INTEGRATOR_COUNTER = 0; + REG_INT_T = REG_INT_T; + end + else if (REG_INTEGRATOR_COUNTER>5000) + begin + REG_INTEGRATOR_COUNTER = 0; + REG_INTEGRATOR = REG_INTEGRATOR; + REG_INT_T = REG_INT_T; + end + else + begin + REG_INTEGRATOR_COUNTER = REG_INTEGRATOR_COUNTER + 1; + if (REG_INTEGRATOR>REG_INTEGRATOR_LIMIT) begin REG_INTEGRATOR = REG_INTEGRATOR_LIMIT; end //Integrator x1024 + else if (REG_INTEGRATOR<0) begin REG_INTEGRATOR = 0; end + else begin REG_INTEGRATOR = REG_INTEGRATOR; end + + if (CURRENT_FILTER_OUTPUT>200) begin REG_INT_T = REG_INT; end + else if (CURRENT_FILTER_OUTPUT<50) begin REG_INT_T = 4; end + else begin REG_INT_T = REG_INT_T; end + + end + + + REG_INTEGRATOR_OUTPUT = REG_INTEGRATOR/1024; + REG_RESULT = REG_PROP_OUTPUT + REG_INTEGRATOR_OUTPUT; + if (REG_RESULT>850) begin REG_OUTPUT = 850; end + else if (REG_RESULT<0) begin REG_OUTPUT = 0; end + else begin REG_OUTPUT = REG_RESULT; end + if (REG_OUTPUTSKIIP_CHOPP_CURRENT) + begin + REG_INTEGRATOR=CHOPPER_CURRENT*1024; + end + else + begin + REG_INTEGRATOR=SKIIP_CHOPP_CURRENT*1024; + end + REG_INT_T = 4; + REG_INPUT = 0; + REG_ERROR=0; + REG_PROP_OUTPUT=0; + REG_INTEGRATOR_COUNTER=0; + REG_RESULT=0; + REG_OUTPUT=0; + REG_CURRENT_LIMIT = 0; + end + +//if (FO_INPUT_VAL1<50) begin CHOPPER_PWM_WIDTH = 0; end +//else begin CHOPPER_PWM_WIDTH = FO_INPUT_VAL1*4; end +//if (VIN_FILTER_OUTPUT>10) begin INPUT_VOLTAGE_MAXPWM = VIN_FILTER_OUTPUT; end +//else begin INPUT_VOLTAGE_MAXPWM = 10; end +//if (VOUT_FILTER_OUTPUT>10) +// begin +// if (VOUT_FILTER_OUTPUT<800) begin OUTPUT_VOLTAGE_MAXPWM = VOUT_FILTER_OUTPUT+100; end +// else begin OUTPUT_VOLTAGE_MAXPWM = 900; end +// end +//else begin OUTPUT_VOLTAGE_MAXPWM = 110; end +//CHOPPER_PWM_WIDTH_MAX = 15000 - (15000*INPUT_VOLTAGE_MAXPWM)/OUTPUT_VOLTAGE_MAXPWM; + +//TEST-------------------------------------------- +/* +if (TEST_COUNTER>50000) begin TEST_COUNTER=0; end +else begin TEST_COUNTER = TEST_COUNTER + 1; end +if (TEST_COUNTER==0) +begin +if (TEST_OUTPUT > 800) begin TEST_DIRECTION=1; TEST_OUTPUT=800; end +if (TEST_OUTPUT == 0) begin TEST_DIRECTION=0; TEST_OUTPUT = 1; end +else + begin + if (TEST_DIRECTION==0) begin TEST_OUTPUT = TEST_OUTPUT + 1; end + else begin TEST_OUTPUT = TEST_OUTPUT - 1; end + end +end +*/ +//TEST-------------------------------------------- + + + +if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER>250) begin CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER=0; end +else begin CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER = CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER+1; end + +//if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER==0) begin INPUT_VOLTAGE_PWM_WIDTH_MAX = TEST_OUTPUT; end //TEST!! +if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER==0) begin INPUT_VOLTAGE_PWM_WIDTH_MAX = VIN_FILTER_OUTPUT; end +else begin INPUT_VOLTAGE_PWM_WIDTH_MAX = INPUT_VOLTAGE_PWM_WIDTH_MAX; end + +if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER==50) begin CHOPPER_PWM_WIDTH_MAX_N_MULT = INPUT_VOLTAGE_PWM_WIDTH_MAX*15000; end +else begin CHOPPER_PWM_WIDTH_MAX_N_MULT = CHOPPER_PWM_WIDTH_MAX_N_MULT; end + +if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER==100) begin CHOPPER_PWM_WIDTH_MAX_N_DIV = CHOPPER_PWM_WIDTH_MAX_N_MULT/800; end +else begin CHOPPER_PWM_WIDTH_MAX_N_DIV = CHOPPER_PWM_WIDTH_MAX_N_DIV; end + +if (CHOPPER_PWM_WIDTH_MAX_CALC_COUNTER==200) begin CHOPPER_PWM_WIDTH_MAX = 15000 - CHOPPER_PWM_WIDTH_MAX_N_DIV; end +else begin CHOPPER_PWM_WIDTH_MAX = CHOPPER_PWM_WIDTH_MAX; end + +if (CHOPPER_PWM_WIDTH_MAX>12000) begin CHOPPER_PWM_WIDTH_LIMIT = 12000; end +else if (CHOPPER_PWM_WIDTH_MAX<200) begin CHOPPER_PWM_WIDTH_LIMIT = 0; end +else begin CHOPPER_PWM_WIDTH_LIMIT = CHOPPER_PWM_WIDTH_MAX; end + +//CHOPPER_PWM_WIDTH_LIMIT = 12000; + +if (GlobalError==1 || CHOPPER_ENABLE==0) begin CHOPP_BOT_IGBT = 0; CHOPPER_PWM_COUNTER = 0; end +else + begin + + if (CHOPPER_PWM_COUNTER>15000) //300uS cycle, 3333Hz + begin + CHOPPER_PWM_COUNTER = 0; + CHOPP_BOT_IGBT = 0; + end + else if (CHOPPER_PWM_COUNTER == 0) + begin + if (CHOPPER_CURRENT200) + begin + CHOPP_BOT_IGBT = 1; + CHOPPER_PWM_COUNTER = 1; + end + else + begin + CHOPP_BOT_IGBT = 0; + CHOPPER_PWM_COUNTER = 0; + end + end + else + begin + CHOPPER_PWM_COUNTER = CHOPPER_PWM_COUNTER + 1; + if (CHOPPER_CURRENT>REG_CURRENT_LIMIT || SKIIP_CHOPP_CURRENT>REG_CURRENT_LIMIT || CHOPPER_PWM_COUNTER>CHOPPER_PWM_WIDTH_LIMIT) + begin + if (CHOPPER_PWM_COUNTER>200) begin CHOPP_BOT_IGBT = 0; end + else begin CHOPP_BOT_IGBT = CHOPP_BOT_IGBT; end + end + else + begin + CHOPP_BOT_IGBT = CHOPP_BOT_IGBT; + end + end + + end + +//BRAKE CONTROL +BRAKE_BOT_IGBT=0; + +if (FO_INPUT_VAL3<25) begin BRAKE_PWM_WIDTH = 0; end +else begin BRAKE_PWM_WIDTH = FO_INPUT_VAL3*8; end + +//BRAKE_PWM_WIDTH = 25000; + +if (GlobalError==0) begin BRAKE_ENABLE_COUNTER = 0; BRAKE_ENABLE=0; end +else + begin + if (BRAKE_ENABLE_COUNTER<3000000000) // 3000000000 = 60s, + begin + if (BRAKE_ENABLE_COUNTER>5000000) + begin + BRAKE_ENABLE = CRITICAL_DATA_INPUT[3]; + end + else + begin + BRAKE_ENABLE = 0; + end + BRAKE_ENABLE_COUNTER = BRAKE_ENABLE_COUNTER + 1; + end + else + begin + BRAKE_ENABLE = 0; + BRAKE_ENABLE_COUNTER = 3000000000; + end + end + +if (MAXCURR_COUNTER>30000) + begin + MAXCURR_COUNTER = 0; + BRAKE_CURRENT_MAX = BRAKE_CURRENT_MAX_CYCLE; + SKIIP_BRAKE_CURRENT_MAX = SKIIP_BRAKE_CURRENT_MAX_CYCLE; + end +else if (MAXCURR_COUNTER == 0) + begin + MAXCURR_COUNTER = MAXCURR_COUNTER + 1; + BRAKE_CURRENT_MAX_CYCLE = 0; + SKIIP_BRAKE_CURRENT_MAX_CYCLE = 0; + end +else + begin + MAXCURR_COUNTER = MAXCURR_COUNTER + 1; + if (BRAKE_CURRENT>BRAKE_CURRENT_MAX_CYCLE) begin BRAKE_CURRENT_MAX_CYCLE = BRAKE_CURRENT; end + if (SKIIP_BRAKE_CURRENT>SKIIP_BRAKE_CURRENT_MAX_CYCLE) begin SKIIP_BRAKE_CURRENT_MAX_CYCLE = SKIIP_BRAKE_CURRENT; end + end + +if (GlobalError==0 || BRAKE_ENABLE==0 || BRAKE_ERROR==1) begin BRAKE_TOP_IGBT = 0; BRAKE_PWM_COUNTER = 0; end +else + begin + + if (BRAKE_PWM_COUNTER>30000) //1000uS cycle, 1000Hz + begin + BRAKE_PWM_COUNTER = 0; + end + else + begin + BRAKE_PWM_COUNTER = BRAKE_PWM_COUNTER + 1; + end + + if (BRAKE_PWM_COUNTER100) || (VIN_FILTER_OUTPUT>100)) + begin + if (FAN_START_COUNTER<50000000) begin FAN_START_COUNTER = FAN_START_COUNTER + 1; end + else begin DIGITAL_OUTPUT[2] = 1; end //FAN OUTP + end + else + begin + if (FAN_START_COUNTER>0) begin FAN_START_COUNTER = FAN_START_COUNTER - 1; end + else + begin + if ((VIN_FILTER_OUTPUT<50) && (VOUT_FILTER_OUTPUT<50)) begin DIGITAL_OUTPUT[2] = 0; end //FAN OUTP + end + end + + //if (CHOPPER_ENABLE || BRAKE_ENABLE || (VOUT_FILTER_OUTPUT>100) || (VIN_FILTER_OUTPUT>100)) + //begin DIGITAL_OUTPUT[2] = 1; end //FAN OUTP + //else begin DIGITAL_OUTPUT[2] = 0; end + //DIGITAL_OUTPUT[2] = CHOPPER_ENABLE || BRAKE_ENABLE; + +//----------CONTROL AND PWM GENERATION----------------------------- + +//-------------------------------DATA IO------------------------- +DATA_TO_PCON[0] = ~GlobalError; +DATA_TO_PCON[1] = BRAKE_ENABLE; +DATA_TO_PCON[2] = CHOPPER_ENABLE; +DATA_TO_PCON[3] = ~BRAKE_ERROR; +DATA_TO_PCON[4] = 0; +DATA_TO_PCON[5] = 0; +DATA_TO_PCON[6] = 0; +DATA_TO_PCON[7] = 0; + +DATA_TO_PCON[19:8] = CHOPPER_CURRENT; +DATA_TO_PCON[31:20] = BRAKE_CURRENT_MAX; +DATA_TO_PCON[43:32] = VIN_FILTER_OUTPUT; +DATA_TO_PCON[55:44] = VOUT_FILTER_OUTPUT; +DATA_TO_PCON[67:56] = SKIIP_CHOPP_CURRENT; +DATA_TO_PCON[79:68] = SKIIP_BRAKE_CURRENT_MAX; +DATA_TO_PCON[91:80] = REG_CURRENT_LIMIT; + +//DATA_TO_PCON[91:80] = BRAKE_ENERGY_STOCK/10000; + +//DATA_TO_PCON[19:8] = CHOPPER_CURRENT; +//DATA_TO_PCON[31:20] = BRAKE_CURRENT; +//DATA_TO_PCON[43:32] = VIN_FILTER_OUTPUT; +//DATA_TO_PCON[55:44] = VOUT_FILTER_OUTPUT; +//DATA_TO_PCON[67:56] = SKIIP_CHOPP_CURRENT; +//DATA_TO_PCON[79:68] = SKIIP_BRAKE_CURRENT; +//DATA_TO_PCON[91:80] = REG_CURRENT_LIMIT; + + +DATA_TO_PCON[99:92] = SKIIP_CHOPP_TEMP[7:0]; +DATA_TO_PCON[107:100] = SKIIP_BRAKE_TEMP[7:0]; +DATA_TO_PCON[115:108] = ERROR_LATCH[7:0]; +DATA_TO_PCON[123:116] = ERROR_LATCH[15:8]; +DATA_TO_PCON[131:124] = ERROR_LATCH[23:16]; +DATA_TO_PCON[139:132] = ERROR_FLAGS[7:0]; +DATA_TO_PCON[147:140] = ERROR_FLAGS[15:8]; +DATA_TO_PCON[155:148] = ERROR_FLAGS[23:16]; + +CRITICAL_DATA_INPUT = DATA_FROM_PCON[7:0]; +FO_INPUT_VAL1 = DATA_FROM_PCON[19:8]; +FO_INPUT_VAL2 = DATA_FROM_PCON[31:20]; +FO_INPUT_VAL3 = DATA_FROM_PCON[43:32]; +FO_INPUT_VAL4 = DATA_FROM_PCON[55:44]; +FO_INPUT_VAL5 = DATA_FROM_PCON[67:56]; +FO_INPUT_VAL6 = DATA_FROM_PCON[79:68]; +FO_INPUT_VAL7 = DATA_FROM_PCON[91:80]; + + +FO_SLOW_INPUT_VAL1 = DATA_FROM_PCON[99:92]; +FO_SLOW_INPUT_VAL2 = DATA_FROM_PCON[107:100]; +FO_SLOW_INPUT_VAL3 = DATA_FROM_PCON[115:108]; +FO_SLOW_INPUT_VAL4 = DATA_FROM_PCON[123:116]; +FO_SLOW_INPUT_VAL5 = DATA_FROM_PCON[131:124]; +FO_SLOW_INPUT_VAL6 = DATA_FROM_PCON[139:132]; +FO_SLOW_INPUT_VAL7 = DATA_FROM_PCON[147:140]; +FO_SLOW_INPUT_VAL8 = DATA_FROM_PCON[155:148]; + +//-------------------------------DATA IO------------------------- + +end + +endmodule \ No newline at end of file diff --git a/UML/Activity.plantuml b/UML/Activity.plantuml new file mode 100644 index 0000000..a7f7d1e --- /dev/null +++ b/UML/Activity.plantuml @@ -0,0 +1,31 @@ +@startuml +start + +:Считать DATA_FROM_PCON; +:Обновить фильтры DINPUT (DFILTER_COUNTER, DINP_FILTER*); +:Обработать CALC_SM_STATE (0..6)\nADC -> физ. величины; + +:Обновить VIN/VOUT/CURRENT фильтры; +:Рассчитать защиты\n(OVERCURRENT, OVERVOLTAGE, OVERTEMP); +:Обновить BRAKE_ENERGY_*; + +if (CHOPPER_ENABLE && !GlobalError) then (yes) + :PI-регулятор\n(REG_INPUT, REG_OUTPUT, REG_CURRENT_LIMIT); +else (no) + :Сброс регулятора\n(REG_INTEGRATOR и др.); +endif + +:Расчёт CHOPPER_PWM_WIDTH_LIMIT; +:Генерация ШИМ для CHOPP_BOT_IGBT; + +if (GlobalError || !BRAKE_ENABLE || BRAKE_ERROR) then (off) + :BRAKE_TOP_IGBT = 0; +else (on) + :Генерация ШИМ для BRAKE_TOP_IGBT; +endif + +:Логика вентилятора (DIGITAL_OUTPUT[2]); +:Формирование DATA_TO_PCON\nи разбор DATA_FROM_PCON; + +stop +@enduml diff --git a/UML/Sequence.plantuml b/UML/Sequence.plantuml new file mode 100644 index 0000000..87be1e4 --- /dev/null +++ b/UML/Sequence.plantuml @@ -0,0 +1,20 @@ +@startuml +participant "PCON_DATA_IO" as PCON +participant "FOExp" as FO +participant "CHOPPER_SKIIP_INPUT" as SK_CH +participant "BRAKE_SKIIP_INPUT" as SK_BR +participant "MeanFilter VIN" as VIN_F + +PCON -> FO : DATA_FROM_PCON +FO -> SK_CH : read SENS_IN[1] +SK_CH --> FO : SKIIP_CHOPP_CURRENT_IN, SKIIP_CHOPP_TEMP_IN + +FO -> VIN_F : VIN_FILTER_INPUT = INPUT_VOLTAGE +VIN_F --> FO : VIN_FILTER_OUTPUT + +FO -> FO : CALC_SM_STATE 0..6 (ADC->физ.величины) +FO -> FO : PI-регулятор (REG_INPUT, REG_OUTPUT) +FO -> FO : PWM (CHOPPER_PWM_COUNTER, CHOPP_BOT_IGBT) + +FO -> PCON : DATA_TO_PCON +@enduml diff --git a/UML/Sequence.png b/UML/Sequence.png new file mode 100644 index 0000000000000000000000000000000000000000..058ec4cbe4039ae1ecc8b68724bf0e9b037c93f8 GIT binary patch literal 16620 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 literal 0 HcmV?d00001 diff --git a/UML/State.plantuml b/UML/State.plantuml new file mode 100644 index 0000000..1453947 --- /dev/null +++ b/UML/State.plantuml @@ -0,0 +1,19 @@ +@startuml +[*] --> S0 + +state "S0_Init" as S0 +state "S1_Sample" as S1 +state "S2_Offset" as S2 +state "S3_Scale" as S3 +state "S4_Convert" as S4 +state "S5_Check" as S5 +state "S6_Latch" as S6 + +S0 --> S1 : CALC_SM_COUNTER>5 +S1 --> S2 : CALC_SM_COUNTER>5 +S2 --> S3 : CALC_SM_COUNTER>5 +S3 --> S4 : CALC_SM_COUNTER>20 +S4 --> S5 : CALC_SM_COUNTER>20 +S5 --> S6 : CALC_SM_COUNTER>5 +S6 --> S0 : CALC_SM_COUNTER>5 +@enduml diff --git a/UML/State.png b/UML/State.png new file mode 100644 index 0000000000000000000000000000000000000000..1a2a0d0f37dd75597ab0d952b1662687e0bf6581 GIT binary patch literal 38943 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

_Qg!0R>9}rAn_Hb^FqOnf$WUg_% z&gWCb%*6~3x#GkNqsPZa1(xQfZL0G<45@YnEh6A6K$GovaoIKuP{Ba5c5pxLdH2Sm zY_rdi3X4Qiq&Ux#*&+4{R34UEQ4*Z9&<)s2qt7W7{jgFpvA}tMLz;m?2tr|rYlYE6 zthAyV%5u`uldDCcfZHFnMS2R|`ls*a%`?L?3{EV};wS=VP#j%MpNcJ>*@ zz9BF~3EYIdsmU>IO&L4KbRh%0qj!&rQ!BWb5um2S;u(lJIon1sUjA!=K}Lf3@gsILJ4H?F=~zbe&Uuuc0R0c8WhAn8!Wm58X;rAF zKWk(#qyZ|SexD+&tpQpQ8U_SoXOL--_E6f9@hZ$A`9PhgWt9TT2{c!SXBwbOPdwZw z^-M=}*w{(aH`f31O_eIu2GvX0kOArFYV1thsG-7 z7RBr0RfbSt3u7`Ux%L>(Hgq+zFgImK@d}hJSTWN;UhnU@m3#01aI8{_lvS@31`vF? zi7+h$zbF|_UY9!7DH?wIKYot>V@CkTgSlYyBG#;5>)6TDmn$p!hlQ-q;S5-t2JqJU zPfy{X$T0H#`}vnzg4fA)p$?$1Fu42W%TEJcHld@G+~rKh@jEzHMq0Y{imoEoZ(n<7 z$q{tuT!^J^10wqV_9+L@O$dfMq21VEalG)1a%|tFvpiIQGXLzlEfCr|@dx5}4koO$ zoZMY!AJu`+pT$tnyz3;{HmQy&0e;pU*eB1MPLw-$@9tC5w_-`C(|$~vuDalA#CKEk zT(Jz~+~GTSo_{&MCFaj|Ij0X|bbWpO!*k~lI&a7JL4Zelreqsf9}Tv4c5}_mXRaty zH#UYTQy(I-{?)Ig``;jZfeyM89%x_DsHTLM79SYLO4Il95#Z;)sxS>KFehi{^#V4M v$6?B0CAr!XuPs^xFVQLp{-Y{_2Ez*;$*VYqNAFxZ3I7(_IoqDK_KN;ru7VY! literal 0 HcmV?d00001