﻿%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Device definition for IMSE MxD8
%
% Settings module:
%       Parity: None
%       Baud:   38400
%       Mode:   RTU
%       
% Factory default 
%       Address: 1
% 
% Author: Daniel Carlson, ABELKO AB Luleå
%
% History:  2016-09-23 Initial version (Converted to WMPro)
%
DEVICETYPE MxD8_DI_DO NAMED "MxD8_DI_DO" TYPEID 21478 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Communication timeout
    ComTimeout: "ComTimeout";
       
    % Trip voltage
    DI_TripVoltage: "DI Trip voltage";
    
    % Digital output
    DO1: "DO1";
    DO2: "DO2";
    DO3: "DO3";
    DO4: "DO4";
      
  PUBLIC
    % Digital input
    DI1  :"DI1";
    DI2  :"DI2";
    DI3  :"DI3";
    DI4  :"DI4";
    
    % Short circuit
    DI_ShortCirc: "DI Short Circuit";
    
    % DO Override
    DO1_Overridden : "DO1 Man. overr.";
    DO2_Overridden : "DO2 Man. overr.";
    DO3_Overridden : "DO3 Man. overr.";
    DO4_Overridden : "DO4 Man. overr.";
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  TELEGRAM SetComTimeout NAMED "SetCommunicationTimeout" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(6);       % Modbus command "6" write single register
      DATA[2]  := RWORD(35);     % Start register
      DATA[4]  <- RWORD(DATA := ComTimeout;); 
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(6);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(35);
  
    TIMEOUT 300
  END;
  
  TELEGRAM SetDO1_4 NAMED "SetDO1-4" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(36);     % Start register
      DATA[4]  := RWORD(4);      % Number of registers to write
      DATA[6]  := BYTE(8);       % Numer of bytes of data, two for each DO
      DATA[7]  <- RWORD(DATA := DO1;);
      DATA[9]  <- RWORD(DATA := DO2;);
      DATA[11] <- RWORD(DATA := DO3;);
      DATA[13] <- RWORD(DATA := DO4;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(36);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(4);

    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for settting values in the unit
  TELEGRAM SetDISettings NAMED "SetDISettings" IS
    QUESTION
      DATA[0] := BYTE(Addr);     % Modbus unit address
      DATA[1] := BYTE(6);        % Modbus command "16" write multiple registers
      DATA[2] := RWORD(34);      % Start register
      DATA[4] <- RWORD(DATA := DI_TripVoltage;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(6);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(34);
  
    TIMEOUT 300
  END;
  
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit
  
  TELEGRAM GetDIStatus NAMED "GetDIStatus" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(25);     % Start register
      DATA[4]  := RWORD(1);      % Number of registers to read
            
    ANSWER SIZE 7
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(2);      % Numer of bytes of data
      DATA[3]  -> RWORD(DI_ShortCirc := DATA;); 
          
    TIMEOUT 300
  END;
  
  TELEGRAM GetDI1_4 NAMED "DI1-4" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(1);      % Start register
      DATA[4]  := RWORD(4);      % Number of registers to read
            
    ANSWER SIZE 13
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(8);       % Numer of bytes of data, two for each DI
      DATA[3]  -> RWORD(DI1 := DATA;); 
      DATA[5]  -> RWORD(DI2 := DATA;); 
      DATA[7]  -> RWORD(DI3 := DATA;);
      DATA[9]  -> RWORD(DI4 := DATA;);
      
    TIMEOUT 300
  END;
      
  TELEGRAM GetDOManualOverrideStatus NAMED "DOManualOverrideStatus" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(26);     % Start register
      DATA[4]  := RWORD(4);      % Number of registers to read
            
    ANSWER SIZE 13
      DATA[0]  =   BYTE(Addr);    % Modbus unit address
      DATA[1]  =   BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =   BYTE(8);       % Numer of bytes of data
      DATA[3]  ->  RWORD(DO1_Overridden := DATA;);
      DATA[5]  ->  RWORD(DO2_Overridden := DATA;);
      DATA[7]  ->  RWORD(DO3_Overridden := DATA;);
      DATA[9]  ->  RWORD(DO4_Overridden := DATA;);
      
    TIMEOUT 300
  END;  
END;

DEVICETYPE MxD8_Freq_Count NAMED "MxD8_Freq_Count" TYPEID 21479 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Flank Settings
    DI1_FlankSettings: "DI1 Pulse edge";      
    DI2_FlankSettings: "DI2 Pulse edge";      
    DI3_FlankSettings: "DI3 Pulse edge";      
    DI4_FlankSettings: "DI4 Pulse edge";
          
  PUBLIC
    % Frequency
    DI1_Freq   :"DI1 Frequency";      
    DI2_Freq   :"DI2 Frequency";      
    DI3_Freq   :"DI3 Frequency";      
    DI4_Freq   :"DI4 Frequency";      
      
    % Counter
    DI1_Counter  :"DI1 Counter";      
    DI2_Counter  :"DI2 Counter";      
    DI3_Counter  :"DI3 Counter";      
    DI4_Counter  :"DI4 Counter";      
        
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for settting values in the unit
  
  TELEGRAM SetFlankSettings NAMED "SetFlankSettings" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(30);     % Start register
      DATA[4]  := RWORD(4);      % Number of registers to write
      DATA[6]  := BYTE(8);       % Numer of bytes of data, two for each register
      DATA[7]  <- RWORD(DATA := DI1_FlankSettings * 4;);
      DATA[9]  <- RWORD(DATA := DI2_FlankSettings * 4;);
      DATA[11] <- RWORD(DATA := DI3_FlankSettings * 4;);
      DATA[13] <- RWORD(DATA := DI4_FlankSettings * 4;);

    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(30);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(4);
  
    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit

  TELEGRAM GetDI1_4Freq_Cnt NAMED "DI1-4Freq_Cnt" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(5);      % Start register
      DATA[4]  := RWORD(16);     % Number of registers to read
            
    ANSWER SIZE 37
      DATA[0]   =  BYTE(Addr);    % Modbus unit address
      DATA[1]   =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]   =  BYTE(32);      % Numer of bytes of data, two for each DI
      DATA[3]   ->  RWORD(Tmp      :=  DATA;);
      DATA[5]   ->  RWORD(DI1_Freq := (DATA + Tmp*65536) / 1000;);
      DATA[7]   ->  RWORD(Tmp      :=  DATA;);
      DATA[9]   ->  RWORD(DI2_Freq := (DATA + Tmp*65536) / 1000;);
      DATA[11]  ->  RWORD(Tmp      :=  DATA;);
      DATA[13]  ->  RWORD(DI3_Freq := (DATA + Tmp*65536) / 1000;);
      DATA[15]  ->  RWORD(Tmp      :=  DATA;);
      DATA[17]  ->  RWORD(DI4_Freq := (DATA + Tmp*65536) / 1000;);

      DATA[19]  ->  RWORD(Tmp         := DATA;);
      DATA[21]  ->  RWORD(DI1_Counter := DATA + Tmp*65536;);
      DATA[23]  ->  RWORD(Tmp         := DATA;);
      DATA[25]  ->  RWORD(DI2_Counter := DATA + Tmp*65536;);
      DATA[27]  ->  RWORD(Tmp         := DATA;);
      DATA[29]  ->  RWORD(DI3_Counter := DATA + Tmp*65536;);
      DATA[31]  ->  RWORD(Tmp         := DATA;);
      DATA[33]  ->  RWORD(DI4_Counter := DATA + Tmp*65536;);

    TIMEOUT 300
  END;
END;
