[r84]: / tags / v2.0.0.0 / IoDrvMEGAIO.library  Maximize  Restore  History

Download this file

701 lines (564 with data), 1.2 MB

-------------------------------------------------------------------------------
IoDrvFB
-------------------------------------------------------------------------------


FUNCTION_BLOCK IoDrvFB EXTENDS IoDrvBase

VAR
    _Instance: MEGAIO;
    _IIoDrv: ICmpIoDrv;
    _IIoDrvParameter: ICmpIoDrvParameter;
    _xBackGroundDiagStarted: BOOL;
    _bDeactivated: BOOL;
    _dwInUse: DWORD;
END_VAR

-------------------------------------------------------------------------------
IoDrvReadInputs
-------------------------------------------------------------------------------


METHOD IoDrvReadInputs: UDINT

VAR_INPUT
    pConnectorMapList: pointer;
    nCount: DINT;
END_VAR

VAR
    i: DINT;
    j: DINT;
END_VAR
IoDrvReadInputs_Count := IoDrvReadInputs_Count + 1;

IF pConnectorMapList = 0 OR nCount = 0 THEN
	IoDrvReadInputs := Errors.ERR_PARAMETER;
	RETURN;
END_IF

FOR i:=0 TO nCount - 1 DO
	IF (pConnectorMapList[i].dwNumOfChannels = 0) THEN
		CONTINUE;
	END_IF
	FOR j:= 0 TO UDINT_TO_UINT(pConnectorMapList[i].dwNumOfChannels) - 1 DO	
		IoMgrCopyInputLE(ADR(pConnectorMapList[i].pChannelMapList[j]), pConnectorMapList[i].pChannelMapList[j].pParameter^.dwDriverSpecific);
	END_FOR	
END_FOR

IoDrvReadInputs := Errors.ERR_OK;
-------------------------------------------------------------------------------
IoDrvIdentify
-------------------------------------------------------------------------------


METHOD IoDrvIdentify: UDINT

VAR_INPUT
    pConnector: pointer;
END_VAR
IoDrvIdentify_Count := IoDrvIdentify_Count + 1;
IoDrvIdentify := Errors.ERR_NOTIMPLEMENTED;
-------------------------------------------------------------------------------
IoDrvUpdateConfiguration
-------------------------------------------------------------------------------


METHOD IoDrvUpdateConfiguration: UDINT

VAR_INPUT
    pConnectorList: pointer;
    nCount: DINT;
END_VAR

VAR
    pParameter: pointer;
    pChild: pointer;
    pstConnectorVendorName: pointer;
    pstConnectorDeviceName: pointer;
    pudtConfig: pointer;
    Result: RTS_IEC_RESULT;
END_VAR
IoDrvUpdateConfiguration_Count := IoDrvUpdateConfiguration_Count + 1;
IoDrvUpdateConfiguration := Errors.ERR_OK;

IF (pConnectorList = 0) THEN
	// Reset application
	// TODO: Free ressources
	RETURN;
END_IF

m_pConnector := IoMgrConfigGetConnector(pConnectorList, ADR(nCount), m_wModuleType, m_dwInstance);

IF m_pConnector = 0 THEN
	IoDrvUpdateConfiguration := ERRORS.ERR_PARAMETER;
	RETURN;
END_IF

//check if device is enabled in the device tree
IF (m_pConnector^.dwFlags AND ConnectorFlags.CF_ENABLE) = 0 THEN
	_bDeactivated := TRUE;
	IoDrvUpdateConfiguration := Errors.ERR_OK;
	RETURN;
END_IF

IF m_pConnector^.hIoDrv = 0 THEN
	m_pConnector^.hIoDrv := m_hInterface;
	m_pConnector^.pFather^.hIoDrv := m_hInterface;
	
	{IF defined (pou:IoMgrConfigSetDiagnosis)}
	IoMgrConfigSetDiagnosis(m_pConnector,
							ConnectorFlags.CF_DRIVER_AVAILABLE OR
							ConnectorFlags.CF_CONNECTOR_FOUND OR
							ConnectorFlags.CF_CONNECTOR_CONFIGURED OR
							ConnectorFlags.CF_CONNECTOR_ACTIVE);
	{END_IF}
	
	{IF defined (pou:IoMgrConfigSetDiagnosis)}
	IoMgrConfigSetDiagnosis(m_pConnector^.pFather,
							ConnectorFlags.CF_DRIVER_AVAILABLE OR
							ConnectorFlags.CF_CONNECTOR_FOUND OR
							ConnectorFlags.CF_CONNECTOR_CONFIGURED OR
							ConnectorFlags.CF_CONNECTOR_ACTIVE);
	{END_IF}

	{IF defined (pou:IoMgrSetDriverProperties)}			
		IoMgrSetDriverProperties(m_hInterface, DRVPROP_CONSISTENCY OR DRVPROP_BACKGROUND_GETDIAG);
		//Note: background diagnosis property flag is optional (supported with 3.5.1.0 runtime)
	{END_IF}										

	//Setup I/O area
	//1000 (Contains DO/AO)
	pParameter := IoMgrConfigGetParameter(m_pConnector, 1000);
	IF (pParameter <> 0) THEN
		pParameter^.dwDriverSpecific := ADR(_instance.udtInput);
	END_IF

	//2000 (Contains DI/AI)
	pParameter := IoMgrConfigGetParameter(m_pConnector, 2000);
	IF (pParameter <> 0) THEN
		pParameter^.dwDriverSpecific := ADR(_instance.udtOutput);
	END_IF
	
	//3000 Parameters
	pParameter := IoMgrConfigGetParameter(m_pConnector, 3000);
	IF (pParameter <> 0) THEN
		pudtConfig := IoStandard.ConfigGetParameterValuePointer(pParameter, ADR(Result));
		_instance.udtConfig := pudtConfig^;
	END_IF
	
	//Go through all childs of the device (if applicable)
	pChild := IoMgrConfigGetFirstChild(m_pConnector, ADR(nCount), m_pConnector);
	WHILE (pChild <> 0) DO
		IF (pChild^.dwFlags AND ConnectorFlags.CF_ENABLE) <> 0 THEN
			pChild^.hIoDrv := m_hInterface;	
			{IF defined (pou:IoMgrConfigSetDiagnosis)}
			IoMgrConfigSetDiagnosis(pChild,
									ConnectorFlags.CF_DRIVER_AVAILABLE OR
									ConnectorFlags.CF_CONNECTOR_FOUND OR
									ConnectorFlags.CF_CONNECTOR_CONFIGURED OR
									ConnectorFlags.CF_CONNECTOR_ACTIVE);
			{END_IF}
		END_IF
		pChild := IoMgrConfigGetNextChild(pChild, ADR(nCount), m_pConnector);
	END_WHILE
END_IF
-------------------------------------------------------------------------------
IoDrvWatchdogTrigger
-------------------------------------------------------------------------------


METHOD IoDrvWatchdogTrigger: UDINT

VAR_INPUT
    pConnector: pointer;
END_VAR
IoDrvWatchdogTrigger_Count := IoDrvWatchdogTrigger_Count + 1;
IoDrvWatchdogTrigger := Errors.ERR_OK;
-------------------------------------------------------------------------------
IoDrvScanModules
-------------------------------------------------------------------------------


METHOD IoDrvScanModules: UDINT

VAR_INPUT
    pConnector: pointer;
    ppConnectorList: pointer;
    pnCount: pointer;
END_VAR
IoDrvScanModules_Count := IoDrvScanModules_Count + 1;
IoDrvScanModules := Errors.ERR_NOTIMPLEMENTED;
-------------------------------------------------------------------------------
IoDrvUpdateMapping
-------------------------------------------------------------------------------


METHOD IoDrvUpdateMapping: UDINT

VAR_INPUT
    pTaskMapList: pointer;
    nCount: DINT;
END_VAR
IoDrvUpdateMapping_Count := IoDrvUpdateMapping_Count + 1;

IF (pTaskMapList = 0) THEN
	IoDrvUpdateMapping := Errors.ERR_PARAMETER;
	RETURN;
END_IF

IoDrvUpdateMapping := Errors.ERR_OK;
-------------------------------------------------------------------------------
IoDrvWriteOutputs
-------------------------------------------------------------------------------


METHOD IoDrvWriteOutputs: UDINT

VAR_INPUT
    pConnectorMapList: pointer;
    nCount: DINT;
END_VAR

VAR
    i: DINT;
    j: DINT;
END_VAR
IoDrvWriteOutputs_Count := IoDrvWriteOutputs_Count + 1;

IF pConnectorMapList = 0 OR nCount = 0 THEN
	IoDrvWriteOutputs := Errors.ERR_PARAMETER;
	RETURN;
END_IF

FOR i:=0 TO nCount - 1 DO
	IF (pConnectorMapList[i].dwNumOfChannels = 0) THEN
		CONTINUE;
	END_IF
	FOR j:= 0 TO UDINT_TO_UINT(pConnectorMapList[i].dwNumOfChannels) - 1 DO	
		IoMgrCopyOutputLE(ADR(pConnectorMapList[i].pChannelMapList[j]), pConnectorMapList[i].pChannelMapList[j].pParameter^.dwDriverSpecific);
	END_FOR

END_FOR

IoDrvWriteOutputs := Errors.ERR_OK;
-------------------------------------------------------------------------------
IoDrvStartBusCycle
-------------------------------------------------------------------------------


METHOD IoDrvStartBusCycle: UDINT

VAR_INPUT
    pConnector: pointer;
END_VAR
IoDrvStartBusCycle_Count := IoDrvStartBusCycle_Count + 1;

//if background diagnosis is not active call IoDrvGetModuleDiagnosis; normally it will be called by the runtime if DRVPROP_BACKGROUND_GETDIAG is set
IF NOT _xBackGroundDiagStarted THEN
	IoDrvGetModuleDiagnosis(m_pConnector); //DRVPROP_BACKGROUND_GETDIAG not set or runtime version < V3.5.1.0
END_IF

//optional: call IoDrvWatchdogTrigger or set driver property DRVPROP_WATCHDOG in UpdateConfiguration
IoDrvWatchdogTrigger(pConnector);

IF NOT _bDeactivated THEN
	_Instance.AfterReadInputs();
	_Instance.BeforeWriteOutputs();
END_IF

IoDrvStartBusCycle := Errors.ERR_OK;
-------------------------------------------------------------------------------
IoDrvGetModuleDiagnosis
-------------------------------------------------------------------------------


METHOD IoDrvGetModuleDiagnosis: UDINT

VAR_INPUT
    pConnector: pointer;
END_VAR
IF pConnector = 0 THEN
	//we are called from the background task
	_xBackGroundDiagStarted := TRUE;
END_IF

//Todo: update connectorflags if something changed

IoDrvGetModuleDiagnosis_Count := IoDrvGetModuleDiagnosis_Count + 1;
IoDrvGetModuleDiagnosis := Errors.ERR_NOTIMPLEMENTED;
-------------------------------------------------------------------------------
IoDrvWriteParameter
-------------------------------------------------------------------------------


METHOD IoDrvWriteParameter: UDINT

VAR_INPUT
    pConnector: pointer;
    pParameter: pointer;
    pData: pointer;
    dwBitSize: DWORD;
    dwBitOffset: DWORD;
END_VAR

VAR
    pParam: pointer;
    pstDiagString: pointer;
END_VAR
IF pConnector = 0 OR pParameter = 0 OR pData = 0 THEN
	IoDrvWriteParameter := Errors.ERR_PARAMETER;
	RETURN;	
END_IF

IoDrvWriteParameter := Errors.ERR_FAILED;
-------------------------------------------------------------------------------
IoDrvReadParameter
-------------------------------------------------------------------------------


METHOD IoDrvReadParameter: UDINT

VAR_INPUT
    pConnector: pointer;
    pParameter: pointer;
    pData: pointer;
    dwBitSize: DWORD;
    dwBitOffset: DWORD;
END_VAR
IF 	pConnector = 0 OR pParameter = 0 OR pData = 0 THEN
	IoDrvReadParameter := Errors.ERR_PARAMETER;
	RETURN;	
END_IF

// All standard parameters of our device are handled by the IO-manager!
IoDrvReadParameter := Errors.ERR_FAILED;

-------------------------------------------------------------------------------
QueryInterface
-------------------------------------------------------------------------------


METHOD QueryInterface: pointer

VAR_INPUT
    iid: DWORD;
    pResult: pointer;
END_VAR
QueryInterface_Count := QueryInterface_Count + 1;
IF iid = ITFID_ICmpIoDrv THEN
	QueryInterface := ADR(_IIoDrv);
	AddRef();
	IF (pResult <> 0) THEN
		pResult^ := Errors.ERR_OK;
	END_IF
	RETURN;	
ELSIF iid = ITFID_ICmpIoDrvParameter THEN
	QueryInterface := ADR(_IIoDrvParameter);
	AddRef();
	IF (pResult <> 0) THEN
		pResult^ := Errors.ERR_OK;
	END_IF	
	RETURN;	
ELSE
	QueryInterface := SUPER^.QueryInterface(iid, pResult);
END_IF

-------------------------------------------------------------------------------
FB_Reinit
-------------------------------------------------------------------------------


METHOD FB_Reinit: BOOL
FB_Reinit_Count := FB_Reinit_Count + 1;
FB_Reinit := TRUE;
-------------------------------------------------------------------------------
Initialize
-------------------------------------------------------------------------------


METHOD Initialize: UDINT

VAR_INPUT
    wModuleType: UINT;
    dwInstance: UDINT;
    pConnector: pointer;
END_VAR
Initialize_Count := Initialize_Count + 1;

m_wModuleType := wModuleType;
m_dwInstance := dwInstance;
m_Info.wModuleType := wModuleType;

_Instance.Initialize(wModuleType, dwInstance, pConnector);

Initialize := Errors.ERR_OK;
-------------------------------------------------------------------------------
FB_Exit
-------------------------------------------------------------------------------


METHOD FB_Exit: BOOL

VAR_INPUT
    bInCopyCode: BOOL;
END_VAR
FB_Exit_Count := FB_Exit_Count + 1;
FB_Exit := TRUE;

-------------------------------------------------------------------------------
FB_Init
-------------------------------------------------------------------------------


METHOD FB_Init: BOOL

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
END_VAR

VAR
    Result: UDINT;
END_VAR
FB_Init_Count := FB_Init_Count + 1;

m_Info.szDriverName := cDriverName;
m_Info.szVendorName := cVendorName;
m_info.szDeviceName := cDeviceName;
m_Info.wModuleType := cModuleType;

_IIoDrv := THIS^;
_IIoDrvParameter := THIS^;

m_IBaseItf := THIS^;
m_hInterface := IoMgrRegisterInstance2(cClassID, m_IBaseItf, ADR(Result));
FB_Init := TRUE;
-------------------------------------------------------------------------------
IoDrvGetConnector
-------------------------------------------------------------------------------


METHOD IoDrvGetConnector: pointer

VAR_INPUT
    pResult: pointer;
END_VAR
IF m_pConnector = 0 THEN
	IF pResult <> 0 THEN
		pResult^ := Errors.ERR_FAILED;
	END_IF
	IoDrvGetConnector := 0;	
	RETURN;
END_IF
IF pResult <> 0 THEN
	pResult^ := Errors.ERR_OK;
END_IF
IoDrvGetConnector := m_pConnector;


-------------------------------------------------------------------------------
MEGAIO
-------------------------------------------------------------------------------


FUNCTION_BLOCK MEGAIO EXTENDS i2c

VAR_INPUT
    udtConfig: IoDrvConfig;
    udtOutput: IoDrvOutput;
END_VAR

VAR_OUTPUT
    udtInput: IoDrvInput;
END_VAR

VAR
    timer: TON;
    dacRawValue: UINT;
    relayRaw: USINT;
    odRaw: USINT;
    odLastState: ARRAY [..] OF ;
    gpioDirRaw: USINT;
    gpioOutLastState: ARRAY [..] OF ;
    _byHardwareAddress: BYTE;
    _AfterReadInputs: UINT;
    _BeforeWriteOutputs: UINT;
    _Initialize: UINT;
END_VAR

VAR_TEMP
    i: USINT;
    usi: USINT;
    buff: ARRAY [..] OF ;
END_VAR
SUPER^();

CASE _iState OF
0:	
	IF usiAddress = 0 THEN
		usiAddress := _byHardwareAddress;
	END_IF
	IF usiAddress < 16#31 OR  usiAddress > 16#34 THEN
		usiAddress := 16#31;
	END_IF
	//usiAddress := 16#31 + StackLevel;
	IF SUPER^.init() THEN
		_iState := 5;
	END_IF	

5:	
	Timer.pt := T#70MS;
	buff[0] := MEGAIO_DAC_ADD;
	buff[1] := 0;
	buff[2] := 0;
	// init DAC 0.0V
  	write(ADR(buff), 3);
	// init all relay off
	write8(0, relayRaw);
	// set all gpio input
	write8(GPIO_DIR_ADD, gpioDirRaw);
	// set all open drain
	write8(MEGAIO_OD_ADD, odRaw);
	
	_iState := 10;
END_CASE
-------------------------------------------------------------------------------
AfterReadInputs
-------------------------------------------------------------------------------


METHOD AfterReadInputs: INT

VAR
    Buffer: ARRAY [..] OF ;
    adc: USINT;
    value: REAL;
    len: DINT;
    opto: USINT;
    gpio: USINT;
END_VAR
SUPER^.AfterReadInputs();

IF _iState = 10 THEN
	timer(IN:=TRUE);
	IF timer.Q THEN	
		FOR adc:=0 TO 7 DO
		len := readregister(16#7 + 2 * adc,ADR(Buffer), 2);		
			IF len = 2 THEN
				value := BYTE_TO_REAL(Buffer[1]) + BYTE_TO_REAL(Buffer[0]) * 256;
				udtInput.adcVoltages[adc] := value * 3.3 / 4095;
				udtInput.adcRaw[adc] := REAL_TO_UINT(value);
			END_IF	
		END_FOR
		
		opto := read8(MEGAIO_OPTO_ADD);  
		FOR len:=0 TO 7 DO
			udtInput.optoIn[len] := USINT_TO_BOOL(SHL(2#00000001, len) AND opto);
		END_FOR
		
		gpio:= read8(GPIO_VAL_ADD);
		FOR len:=0 TO 5 DO
			udtInput.gpioIn[len] := USINT_TO_BOOL(SHL(2#00000001, len) AND gpio);
		END_FOR
		timer(IN:=FALSE);
	END_IF		
END_IF

_AfterReadInputs :=	_AfterReadInputs + 1;
-------------------------------------------------------------------------------
BeforeWriteOutputs
-------------------------------------------------------------------------------


METHOD BeforeWriteOutputs: INT

VAR
    i: USINT;
    inVal: UINT;
    inSVal: USINT;
    buff: ARRAY [..] OF ;
    wStat: BOOL;
END_VAR
SUPER^.BeforeWriteOutputs();

IF _iState = 10 THEN
	
	inVal:= REAL_TO_UINT(udtOutput.dacVoltage * 4096 / 3.3);
	IF inVal > 4095 THEN
		inVal := 4095;
	END_IF
	
	IF inVal <> dacRawValue THEN
		buff[0] := MEGAIO_DAC_ADD;
		buff[1] := UINT_TO_USINT(inVal / 256);
		buff[2] := UINT_TO_USINT(inVal - (inVal / 256));
		i := DINT_TO_USINT(write(ADR(buff), 3));
		IF i = 3 THEN
			dacRawValue := inVal;
		END_IF	
	END_IF
	
	inSVal:= 0;
	FOR i:= 0 TO 7 DO
		inSVal:= inSVal + SHL(BOOL_TO_USINT(udtOutput.relayState[i]), i);
	END_FOR
	IF inSVal <> relayRaw THEN
		IF write8(0, inSVal) THEN
			relayRaw:=inSVal;
		END_IF
	END_IF
	
	inSVal:= 0;
	FOR i:= 0 TO 3 DO
		//inSVal:= inSVal + SHL(BOOL_TO_USINT(openDrainState[i]), i);
		IF udtOutput.openDrainState[i] <> odLastState[i] THEN
			IF udtOutput.openDrainState[i] THEN
				wStat:= write8(OC_SET_ADD, i+1);
			ELSE
				wStat:= write8(OC_CLR_ADD, i+1);
			END_IF
		
			IF wStat THEN
				odLastState[i]:= udtOutput.openDrainState[i];
			END_IF
		END_IF
	END_FOR

	inSVal:= 0;
	FOR i:= 0 TO 5 DO
		inSVal:= inSVal + SHL(BOOL_TO_USINT(udtOutput.gpioDir[i]), i);
	END_FOR
	IF inSVal <> gpioDirRaw THEN
		IF write8(GPIO_DIR_ADD, inSVal) THEN
			gpioDirRaw:=inSVal;
		END_IF
	END_IF
	
	inSVal:= 0;
	FOR i:= 0 TO 5 DO
		IF gpioOutLastState[i] <> udtOutput.gpioOut[i] THEN
			IF udtOutput.gpioOut[i] THEN
				wStat:= write8(GPIO_SET_ADD, i+1);
			ELSE
				wStat:= write8(GPIO_CLR_ADD, i+1);
			END_IF
			IF wStat THEN
				gpioOutLastState[i] := udtOutput.gpioOut[i];
			END_IF
		END_IF
	END_FOR
	
END_IF

_BeforeWriteOutputs := _BeforeWriteOutputs + 1;
-------------------------------------------------------------------------------
Initialize
-------------------------------------------------------------------------------


METHOD Initialize: UDINT

VAR_INPUT
    wModuleType: UINT;
    dwInstance: UDINT;
    pConnector: pointer;
END_VAR

VAR
    pParam: pointer;
    udiResult: UDINT;
END_VAR
SUPER^.Initialize(wModuleType, dwInstance, pConnector);

(* initialise the I2c address *)
pParam := ConfigGetParameter(_pConnector, 1);
IF pParam <> 0 THEN
	_byHardwareAddress := IoStandard.ConfigGetParameterValueByte(pParam, ADR(udiResult));
END_IF

_Initialize := _Initialize + 1;
VAR_GLOBAL
    cClassID: DWORD;
    cDriverName: string;
    cDeviceName: string;
    cVendorName: string;
    cModuleType: WORD;
END_VAR

VAR_GLOBAL
    MEGAIO_DAC_ADD: USINT;
    MEGAIO_OPTO_ADD: USINT;
    MEGAIO_OD_ADD: USINT;
    OC_SET_ADD: USINT;
    OC_CLR_ADD: USINT;
    GPIO_VAL_ADD: USINT;
    GPIO_DIR_ADD: USINT;
    GPIO_SET_ADD: USINT;
    GPIO_CLR_ADD: USINT;
END_VAR