FUNCTION_BLOCK "FB3_ZC_CHECKSUM"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      Comprobar : Bool;
      Copiar : Bool;
   END_VAR

   VAR_OUTPUT 
      CheckSumOK : Bool;
   END_VAR

   VAR 
      s_GetCheckSum {InstructionName := 'GetChecksum'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : GetChecksum;
   END_VAR
   VAR RETAIN
      s_EstadoCheckSum { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..7] of Byte;
      s_CheckSumFabrica { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..7] of Byte;
   END_VAR
   VAR 
      s_Comprobar { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      s_OldComprobar { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
   END_VAR


BEGIN
	REGION DESCRIPCION
	//=======================================================================
	// (C)Copyright ZeusControl 2020 - 2026
	//=======================================================================
	(*
	### Información del Sistema
	| Hardware Compatible | Entorno de Ingeniería |
	|---------------------|-----------------------|
	| PLC serie 1200/1500 | TIA Portal 18         |
	
	---
	### Descripción Funcional
	El bloque `FB3_CHECKSUM` implementa la lectura del checksum del programa actual del PLC y su comparación con el checksum de fábrica, permitiendo detectar modificaciones no autorizadas en el proyecto.
	
	Funcionalidades principales:
	- Detección de flanco ascendente en la entrada `#Comprobar` para ejecutar la comprobación bajo demanda (modo "pulso"), mediante la variable interna `#s_OldComprobar`.
	- Lectura del checksum del bloque `Scope:=1` (objeto PLC) con `Range:=0` y `Subrange:=0` (rango completo), invocando la función de sistema `GetChecksum` a través del FB `GetChecksum` y depositando el resultado en `#s_EstadoCheckSum`.
	- Captura del checksum de fábrica: cuando se activa la entrada `#Copiar`, se copia el checksum actual al valor de referencia `#s_CheckSumFabrica`, operación que se realiza una sola vez durante la puesta en marcha para fijar la línea base.
	- Comparación continua entre el checksum actual y el de fábrica, exponiendo el resultado en la salida `#CheckSumOK` (TRUE cuando coinciden).
	
	> **Restricciones:** Ninguna.
	
	---
	### Dependencias Requeridas
	| Tipo | Elementos |
	|------|-----------|
	| FC   | - |
	| FB   | `GetChecksum` |
	| DB   | - |
	| UDT  | - |
	    
	---
	### Historial de Cambios
	| Versión  | Fecha      | Técnico | Cambios |
	|----------|------------|---------|---------|
	| 01.00.00 | 28.09.2020 | (ABH)   | Primera versión. |
	| 01.00.01 | 02.07.2026 | (ABH)   | Cambio a SCL. |
	*)
	END_REGION DESCRIPCION
	
	
	//  ==========================================================================================================
	REGION ORDEN_COMPROBACION
	    
	    //  Comprobacion mediante un pulso
	    #s_Comprobar := #Comprobar AND NOT #s_OldComprobar;
	    
	    //  Estado anterior
	    #s_OldComprobar := #Comprobar;
	    
	END_REGION ORDEN_COMPROBACION
	
	
	//  ==========================================================================================================
	REGION LECTURA_CHECKSUM
	    
	    //  Comprobacion mediante un pulso
	    #s_GetCheckSum(Scope:=1,
	                  Range:=0,
	                  Subrange:=0,
	                  Checksum:=#s_EstadoCheckSum);
	   
	   //   Copia de checksum a valor de fabrica
	   IF #Copiar THEN
	       #s_CheckSumFabrica := #s_EstadoCheckSum;
	   END_IF;
	    
	END_REGION LECTURA_CHECKSUM
	
	
	//  ==========================================================================================================
	REGION SALIDAS
	    
	    //  Checksum OK
	    #CheckSumOK := #s_EstadoCheckSum = #s_CheckSumFabrica;
	    
	END_REGION SALIDAS
	
END_FUNCTION_BLOCK

