diff --git a/ptxdist/local_src/ecu01-codesys/linbus/Linbus.c b/ptxdist/local_src/ecu01-codesys/linbus/Linbus.c index 822d132..96e2d73 100755 --- a/ptxdist/local_src/ecu01-codesys/linbus/Linbus.c +++ b/ptxdist/local_src/ecu01-codesys/linbus/Linbus.c @@ -1,10 +1,13 @@ /******************************************************************************/ -/*! -\brief Library for Linbus Protocol +/*! +\file $URL: https://subversion.eckelmann.local/svn/max/quantron_a/trunk/src/codesys/qa/QA.c $ + +\brief Schnittstellenmodul Quantron-A Funktionsbibliothek -\author $Author: Gudert +\author $Author: HILTENKA $ +\date $Date: 2011-11-24 12:26:30 +0100 (Do, 24 Nov 2011) $ -\version $Rev: $ +\version $Rev: 2090 $ \b ECKELMANN INDUSTRIEAUTOMATION, WIESBADEN\n © Copyright 2009 @@ -15,30 +18,150 @@ @Includes *******************************************************************************/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Headerfiles Codesys-Componenten-Lib */ #include "CmpStd.h" #include "CmpErrors.h" #include "CmpItf.h" -#include "LinbusDep.h" +/* Headerfile Dependend */ +#include "LinbusDep.h" #include "linbus_imp.h" +/******************************************************************************* +@Konstanten (modullokal) +*******************************************************************************/ + +#define DEBUG_FUNC DEBUG_PRINT +#ifndef DEBUG_FUNC + #define DEBUG_FUNC(a...) +#endif +#ifndef DEBUG_ITF_FUNC + #define DEBUG_ITF_FUNC(a...) +#endif +#ifndef DEBUG_INTERLAL_FUNC + #define DEBUG_INTERLAL_FUNC(a...) +#endif + + + + +/******************************************************************************* +@Typdefinitionen (modullokal) +*******************************************************************************/ + + +typedef struct LIN_SLAVE_DATA_R { + LIN_SLAVE_VERSION_TR tVers; /* Version */ + LIN_SLAVE_VALUE_TR tValue; /* FaceValue */ + unsigned char ucSlaveOnline; /* Verbindungsstatus */ + unsigned char ucSetNewValue; /* Flag fuer neuen Sollwert */ + unsigned short usSetValue; /* Sollwert */ + unsigned char ucSetControl; /* Steuerbits fuer Sollwert */ +} LIN_SLAVE_DATA_TR; +/******************************************************************************* +@Konstanten (modullokal) +*******************************************************************************/ + +#define DEBUG_FUNC DEBUG_PRINT +#ifndef DEBUG_FUNC + #define DEBUG_FUNC(a...) +#endif +#ifndef DEBUG_ITF_FUNC + #define DEBUG_ITF_FUNC(a...) +#endif +#ifndef DEBUG_INTERLAL_FUNC + #define DEBUG_INTERLAL_FUNC(a...) +#endif + +#define WORKING_DIR_LEN 100 +#define STORAGE_NAME_LEN 40 +#define MNT_POINT_NAME_LEN 40 +#define MNT_DEV_CNT 4 +#define MNT_DEV_NAME_LEN 40 +#define FILENAME_LEN 40 + +#define QADRV_VERSION_LEN 20 + +/******************************************************************************* +@Variablen (modullokal) +*******************************************************************************/ + + +/******************************************************************************* +@Makros (modullokal) +*******************************************************************************/ + +/******************************************************************************* +@Prototypen der lokalen Funktionen +*******************************************************************************/ +static int lin_getslaveversion( void ); +static int lin_getslavefacevalue( void ); +static int lin_setslavevalue( void ); +static int lin_clrslaveaddr( void ); +static int lin_setslaveaddr( int iSlave ); +static void lin_master_thread(SYS_TASK_PARAM *ptp); +static int lin_missing_slave( void ); +static void lin_rx_thread(SYS_TASK_PARAM *ptp); +static int lin_recv( unsigned char *pucLinData, int iLinByteCnt, int iTimeout ); +static int lin_recv_message( unsigned char *pucLinMsgData, int iLinMsgLen ) ; +static int lin_send( unsigned char *pucLinData, int iLinBytesCnt ); +static int lin_send_breakbyte( void ); +static int lin_send_message( unsigned char *pucLinMsgData, int iLinMsgLen ); +static unsigned char lin_pidbyte( unsigned char ucVal ); +static unsigned char lin_checksum( unsigned char *pucData, int iDataLen ); +static int lin_master_alive( unsigned char ucNextFreeAdr, unsigned char ucSlaves, unsigned char ucAliveFlags ); +static int lin_reset_all( void ); +static int lin_set_value( unsigned char ucAdr, unsigned short usSollPos, unsigned char ucControlFlags ); +static int lin_face_value( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); +static int lin_get_version( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult); static RTS_RESULT CDECL DeleteInstance(IBase *pIBase); static int CDECL ExportFunctions(void); static int CDECL ImportFunctions(void); static RTS_UI32 CDECL CmpGetVersion(void); static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2); -static void GetSettings( void ); +static void GetQASettings( void ); USE_STMT +USE_SysSemCreate +USE_SysSemDelete +USE_SysSemEnter +USE_SysSemLeave +USE_SysTaskCreate +USE_SysTaskResume +USE_SysTaskSetExit +USE_SysTaskJoin +USE_SysTaskExit +USE_SysTaskWaitSleep +USE_SysTaskDestroy +USE_SysTaskEnter +USE_SysTaskLeave +USE_SysTaskEnd + + + /******************************************************************************/ /*! \fn ComponentEntry \brief Used to exchange function pointers between component manager and components.\n - Called at startup for each component. + Called at startup for each component. \return Return ERR_OK if library could be initialized, else error code @@ -71,8 +194,7 @@ DLL_DECL int CDECL ComponentEntry(INIT_STRUCT *pInitStruct) return ERR_OK; -} /* eofn: ComponentEntry */ - +} /* eofn: ComponentEntry */ /******************************************************************************/ /*! @@ -89,7 +211,7 @@ DLL_DECL int CDECL ComponentEntry(INIT_STRUCT *pInitStruct) static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult) { return NULL; -} /* eofn: CreateInstance */ +} /* eofn: CreateInstance */ /******************************************************************************/ /*! @@ -99,20 +221,20 @@ static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult) \return ERR_NOTIMPLEMENTED -\param pIBase - +\param pIBase - *******************************************************************************/ static RTS_RESULT CDECL DeleteInstance(IBase *pIBase) { return ERR_NOTIMPLEMENTED; -} /* eofn: DeleteInstance */ +} /* eofn: DeleteInstance */ /******************************************************************************/ /*! \fn ExportFunctions -\brief Export function pointers as api +\brief Export function pointers as api \return ERR_OK = successfull @@ -124,15 +246,15 @@ static int CDECL ExportFunctions(void) /* Macro to export functions */ EXPORT_STMT; - return ERR_OK; + return ERR_OK; -} /* eofn: ExportFunctions */ +} /* eofn: ExportFunctions */ /******************************************************************************/ /*! \fn ImportFunctions -\brief Get function pointers of other components +\brief Get function pointers of other components \return ERR_OK = successfull @@ -146,13 +268,13 @@ static int CDECL ImportFunctions(void) return ERR_OK; -} /* eofn: ImportFunctions */ +} /* eofn: ImportFunctions */ /******************************************************************************/ /*! \fn CmpGetVersion -\brief Get Versionnumber +\brief Get Versionnumber \return Versionnumber @@ -163,27 +285,7 @@ static RTS_UI32 CDECL CmpGetVersion(void) { return CMP_VERSION; -} /* eofn: CmpGetVersion */ - -/******************************************************************************/ - -/******************************************************************************/ -/*! -\fn GetSettings - -\brief Einlesen der Konfigurationseintrage - -\return keine - -\param keine - -*******************************************************************************/ -static void GetSettings( void ) -{ - - return; - -} /* eofn: GetQASettings */ +} /* eofn: CmpGetVersion */ /******************************************************************************/ /*! @@ -193,7 +295,7 @@ static void GetSettings( void ) \return 0 -\param ulHook -\n +\param ulHook -\n ulParam1 -\n ulParam2 -\n @@ -205,16 +307,11 @@ static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_ case CH_INIT_SYSTEM: break; - case CH_INIT: - - /********************************/ - /* Konfigurationsdaten einlesen */ - /********************************/ - GetSettings(); + case CH_INIT: break; - case CH_INIT2: + case CH_INIT2: break; case CH_INIT3: @@ -228,23 +325,17 @@ static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_ /* Cyclic */ case CH_COMM_CYCLE: - break; case CH_EXIT_COMM: break; case CH_EXIT_TASKS: break; - case CH_EXIT3: - break; + case CH_EXIT3: + break; case CH_EXIT2: break; - case CH_EXIT: - - /*******************************************************/ - /* LIN-Schnittstelle schliessen falls geoeffnet wurde */ - /*******************************************************/ - LIN_Close(); + case CH_EXIT: break; case CH_EXIT_SYSTEM: @@ -254,90 +345,89 @@ static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_ } return 0; -} /* eofn: HookFunction */ +} /* eofn: HookFunction */ + + -/***********************************/ -/*! Funktionsschnittstelle LIN-BUS */ -/***********************************/ void CDECL CDECL_EXT lin_open(lin_open_struct *p) { - p->Lin_Open = LIN_Open( p->iSlaveCount, p->iIntervall ); + p->Lin_Open = LIN_Open( p->iSlaveCount, p->iIntervall ); } /* eofn: lin_open */ void CDECL CDECL_EXT lin_close(lin_close_struct *p) { - p->Lin_Close = LIN_Close(); + p->Lin_Close = LIN_Close(); } /* eofn: lin_close */ void CDECL CDECL_EXT lin_getmasterstate(lin_getmasterstate_struct *p) { - p->Lin_GetMasterState = LIN_GetMasterState(); + p->Lin_GetMasterState = LIN_GetMasterState(); } /* eofn: lin_getmasterstate */ void CDECL CDECL_EXT lin_getslavestate(lin_getslavestate_struct *p) { - p->Lin_GetSlaveState = LIN_GetSlaveState( p->iSlave ); + p->Lin_GetSlaveState = LIN_GetSlaveState( p->iSlave ); } /* eofn: lin_getslavestate */ void CDECL CDECL_EXT lin_resetaddress(lin_resetaddress_struct *p) { - p->Lin_ResetAddress = LIN_ResetAddress(); + p->Lin_ResetAddress = LIN_ResetAddress(); } /* eofn: lin_resetaddress */ void CDECL CDECL_EXT lin_setaddress(lin_setaddress_struct *p) { - p->Lin_SetAddress = LIN_SetAddress(); + p->Lin_SetAddress = LIN_SetAddress(); } /* eofn: lin_setaddress */ void CDECL CDECL_EXT lin_getversion(lin_getversion_struct *p) { - LIN_SLAVE_VERSION_TR tLinSlaveVersion; + LIN_SLAVE_VERSION_TR tLinSlaveVersion; - if (( p->Lin_GetVersion = LIN_GetVersion( p->iSlave, &tLinSlaveVersion ) ) == 0 ) { + if (( p->Lin_GetVersion = LIN_GetVersion( p->iSlave, &tLinSlaveVersion ) ) == 0 ) { /* Daten uebernehmen */ - p->ptVersion->bRelease = tLinSlaveVersion.ucRelease; + p->ptVersion->bRelease = tLinSlaveVersion.ucRelease; p->ptVersion->bVersion = tLinSlaveVersion.ucVersion; p->ptVersion->bVariant = tLinSlaveVersion.ucVariant; p->ptVersion->bFormat = tLinSlaveVersion.ucFormat; p->ptVersion->wManCode = tLinSlaveVersion.usManCode; p->ptVersion->wFunction = tLinSlaveVersion.usFunction; - } + + } } /* eofn: lin_getversion */ void CDECL CDECL_EXT lin_getfacevalue(lin_getfacevalue_struct *p) { - LIN_SLAVE_VALUE_TR tLinSlaveValue; + LIN_SLAVE_VALUE_TR tLinSlaveValue; - if (( p->Lin_GetFaceValue = LIN_GetFaceValue( p->iSlave, &tLinSlaveValue ) ) == 0 ) { + if (( p->Lin_GetFaceValue = LIN_GetFaceValue( p->iSlave, &tLinSlaveValue ) ) == 0 ) { /* Daten uebernehmen */ - p->ptValue->bFormat = tLinSlaveValue.ucFormat; + p->ptValue->bFormat = tLinSlaveValue.ucFormat; p->ptValue->wIstPos = tLinSlaveValue.usIstPos; p->ptValue->bStatus = tLinSlaveValue.ucStatus; p->ptValue->bErrorCnt = tLinSlaveValue.ucErrorCnt; - } + + } } /* eofn: lin_getfacevalue */ void CDECL CDECL_EXT lin_setvalue(lin_setvalue_struct *p) { - p->Lin_SetValue = LIN_SetValue( p->iSlave, p->wPosition, p->bPosFlags, p->bDeviceTyp ); + p->Lin_SetValue = LIN_SetValue( p->iSlave, p->wPosition, p->bPosFlags, p->bDeviceTyp ); -} /* eofn: lin_setvalue */ +} /* eofn: lin_setvalue */ void CDECL CDECL_EXT lin_mastersetvalue(lin_mastersetvalue_struct *p) { - p->Lin_MasterSetValue = LIN_MasterSetValue( p->wPosition, p->bPosFlags, p->bDeviceTyp ); - -} /* eofn: lin_mastersetvalue */ + p->Lin_MasterSetValue = LIN_MasterSetValue( p->wPosition, p->bPosFlags, p->bDeviceTyp ); -/*--- eof ---*/ +} /* eofn: lin_mastersetvalue */ diff --git a/ptxdist/local_src/ecu01-codesys/linbus/LinbusItf.m4 b/ptxdist/local_src/ecu01-codesys/linbus/LinbusItf.m4 index b742b61..470b6af 100755 --- a/ptxdist/local_src/ecu01-codesys/linbus/LinbusItf.m4 +++ b/ptxdist/local_src/ecu01-codesys/linbus/LinbusItf.m4 @@ -15,17 +15,6 @@ extern "C" { #endif /** - * T_LIN_SLAVE_VALUE - */ -typedef struct tagT_LIN_SLAVE_VALUE -{ - RTS_IEC_BYTE bFormat; - RTS_IEC_WORD wIstPos; - RTS_IEC_BYTE bStatus; - RTS_IEC_BYTE bErrorCnt; -} T_LIN_SLAVE_VALUE; - -/** * T_LIN_SLAVE_VERSION */ typedef struct tagT_LIN_SLAVE_VERSION @@ -39,6 +28,17 @@ typedef struct tagT_LIN_SLAVE_VERSION } T_LIN_SLAVE_VERSION; /** + * T_LIN_SLAVE_VALUE + */ +typedef struct tagT_LIN_SLAVE_VALUE +{ + RTS_IEC_BYTE bFormat; + RTS_IEC_WORD wIstPos; + RTS_IEC_BYTE bStatus; + RTS_IEC_BYTE bErrorCnt; +} T_LIN_SLAVE_VALUE; + +/** * Close Lin-Bus device */ typedef struct taglin_close_struct @@ -46,7 +46,7 @@ typedef struct taglin_close_struct RTS_IEC_DINT Lin_Close; /* VAR_OUTPUT */ } lin_close_struct; -DEF_API(`void',`CDECL',`lin_close',`(lin_close_struct *p)',1,0x172A91EA,0x01000000) +DEF_API(`void',`CDECL',`lin_close',`(lin_close_struct *p)',1,RTSITF_GET_SIGNATURE(0x172A91EA, 0),0x01000000) /** * Get face value for a slave @@ -58,7 +58,7 @@ typedef struct taglin_getfacevalue_struct RTS_IEC_DINT Lin_GetFaceValue; /* VAR_OUTPUT */ } lin_getfacevalue_struct; -DEF_API(`void',`CDECL',`lin_getfacevalue',`(lin_getfacevalue_struct *p)',1,0xF2C42FE1,0x01000000) +DEF_API(`void',`CDECL',`lin_getfacevalue',`(lin_getfacevalue_struct *p)',1,RTSITF_GET_SIGNATURE(0xF2C42FE1, 0),0x01000000) /** * Get status of the master @@ -68,7 +68,7 @@ typedef struct taglin_getmasterstate_struct RTS_IEC_DINT Lin_GetMasterState; /* VAR_OUTPUT */ } lin_getmasterstate_struct; -DEF_API(`void',`CDECL',`lin_getmasterstate',`(lin_getmasterstate_struct *p)',1,0xD369816F,0x01000000) +DEF_API(`void',`CDECL',`lin_getmasterstate',`(lin_getmasterstate_struct *p)',1,RTSITF_GET_SIGNATURE(0xD369816F, 0),0x01000000) /** * Get state of the slave @@ -79,7 +79,7 @@ typedef struct taglin_getslavestate_struct RTS_IEC_DINT Lin_GetSlaveState; /* VAR_OUTPUT */ } lin_getslavestate_struct; -DEF_API(`void',`CDECL',`lin_getslavestate',`(lin_getslavestate_struct *p)',1,0x5B508641,0x01000000) +DEF_API(`void',`CDECL',`lin_getslavestate',`(lin_getslavestate_struct *p)',1,RTSITF_GET_SIGNATURE(0x5B508641, 0),0x01000000) /** * Get version of the slave @@ -91,7 +91,7 @@ typedef struct taglin_getversion_struct RTS_IEC_DINT Lin_GetVersion; /* VAR_OUTPUT */ } lin_getversion_struct; -DEF_API(`void',`CDECL',`lin_getversion',`(lin_getversion_struct *p)',1,0x8E7D4D48,0x01000000) +DEF_API(`void',`CDECL',`lin_getversion',`(lin_getversion_struct *p)',1,RTSITF_GET_SIGNATURE(0x8E7D4D48, 0),0x01000000) /** * Set value for all clients @@ -100,11 +100,11 @@ typedef struct taglin_mastersetvalue_struct { RTS_IEC_WORD wPosition; /* VAR_INPUT */ /* new value */ RTS_IEC_BYTE bPosFlags; /* VAR_INPUT */ /* flags to set the new value */ - RTS_IEC_BYTE bDeviceTyp; /* VAR_INPUT */ /* flags to set the new value */ + RTS_IEC_BYTE bDeviceTyp; /* VAR_INPUT */ /* Device Type */ RTS_IEC_DINT Lin_MasterSetValue; /* VAR_OUTPUT */ } lin_mastersetvalue_struct; -DEF_API(`void',`CDECL',`lin_mastersetvalue',`(lin_mastersetvalue_struct *p)',1,0xA5CE5514,0x01000000) +DEF_API(`void',`CDECL',`lin_mastersetvalue',`(lin_mastersetvalue_struct *p)',1,RTSITF_GET_SIGNATURE(0xA5CE5514, 0),0x01000000) /** * Open Lin-Bus device @@ -116,7 +116,7 @@ typedef struct taglin_open_struct RTS_IEC_DINT Lin_Open; /* VAR_OUTPUT */ } lin_open_struct; -DEF_API(`void',`CDECL',`lin_open',`(lin_open_struct *p)',1,0x97229571,0x01000000) +DEF_API(`void',`CDECL',`lin_open',`(lin_open_struct *p)',1,RTSITF_GET_SIGNATURE(0x97229571, 0),0x01000000) /** * Reset slave adress @@ -126,7 +126,7 @@ typedef struct taglin_resetaddress_struct RTS_IEC_DINT Lin_ResetAddress; /* VAR_OUTPUT */ } lin_resetaddress_struct; -DEF_API(`void',`CDECL',`lin_resetaddress',`(lin_resetaddress_struct *p)',1,0x357557FD,0x01000000) +DEF_API(`void',`CDECL',`lin_resetaddress',`(lin_resetaddress_struct *p)',1,RTSITF_GET_SIGNATURE(0x357557FD, 0),0x01000000) /** * Set slave adress @@ -136,7 +136,7 @@ typedef struct taglin_setaddress_struct RTS_IEC_DINT Lin_SetAddress; /* VAR_OUTPUT */ } lin_setaddress_struct; -DEF_API(`void',`CDECL',`lin_setaddress',`(lin_setaddress_struct *p)',1,0x2015BA0E,0x01000000) +DEF_API(`void',`CDECL',`lin_setaddress',`(lin_setaddress_struct *p)',1,RTSITF_GET_SIGNATURE(0x2015BA0E, 0),0x01000000) /** * Set value for a slave @@ -146,11 +146,11 @@ typedef struct taglin_setvalue_struct RTS_IEC_INT iSlave; /* VAR_INPUT */ /* Slavenumber */ RTS_IEC_WORD wPosition; /* VAR_INPUT */ /* new value */ RTS_IEC_BYTE bPosFlags; /* VAR_INPUT */ /* flags to set the new value */ - RTS_IEC_BYTE bDeviceTyp; /* VAR_INPUT */ /* flags to set the new value */ + RTS_IEC_BYTE bDeviceTyp; /* VAR_INPUT */ /* Device Type */ RTS_IEC_DINT Lin_SetValue; /* VAR_OUTPUT */ } lin_setvalue_struct; -DEF_API(`void',`CDECL',`lin_setvalue',`(lin_setvalue_struct *p)',1,0xBEFBC8F0,0x01000000) +DEF_API(`void',`CDECL',`lin_setvalue',`(lin_setvalue_struct *p)',1,RTSITF_GET_SIGNATURE(0xBEFBC8F0, 0),0x01000000) #ifdef __cplusplus } diff --git a/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.c b/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.c index a111c56..fe9d495 100755 --- a/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.c +++ b/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.c @@ -1,1762 +1,1702 @@ -/******************************************************************************/ -/*! -\file $URL: https://svn.eckelmann.group/svn/max/quantron_a/trunk/src/codesys/qa/linbus.c $ - -\brief Modul fuer die LIN-Bus-Kommunikation - -\author $Author: Strunck $ -\date $Date: 2016-10-20 10:31:12 +0200 (Do, 20 Okt 2016) $ - -\version $Rev: 3796 $ - -\b ECKELMANN INDUSTRIEAUTOMATION, WIESBADEN\n - © Copyright 2010 - -*******************************************************************************/ - -/******************************************************************************* -@Includes -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -/* Headerfiles Codesys-Componenten-Lib */ -#include "CmpStd.h" -#include "CmpErrors.h" -#include "CmpItf.h" - -/* Headerfile Dependend */ -#include "LinbusDep.h" - -/* Sonstige Headerfiles */ -#include "linbus_imp.h" -#include "debug.h" -#include "log.h" - -/******************************************************************************* -@Konstanten (modullokal) -*******************************************************************************/ - -#define DEBUG_FUNC DEBUG_PRINT -#ifndef DEBUG_FUNC - #define DEBUG_FUNC(a...) -#endif -#ifndef DEBUG_ITF_FUNC - #define DEBUG_ITF_FUNC(a...) -#endif -#ifndef DEBUG_INTERLAL_FUNC - #define DEBUG_INTERLAL_FUNC(a...) -#endif - -#define ISBITSET(val, bit) ( ((val) & (1 << (bit)))? 1:0 ) - -/**************************/ -/* LIN-Kommandos/Adressen */ -/**************************/ -#define ADDR(x) (x << 2) -#define PID_PARITY(x) (x << 6) - -#define LIN_SLAVE_1 0x0 -#define LIN_SLAVE_2 0x1 -#define LIN_SLAVE_3 0x2 -#define LIN_SLAVE_4 0x3 -#define LIN_SLAVE_5 0x4 -#define LIN_SLAVE_6 0x5 -#define LIN_SLAVE_7 0x6 -#define LIN_SLAVE_8 0x7 -#define LIN_SLAVE_9 0x8 -#define LIN_SLAVE_10 0x9 -#define LIN_SLAVE_11 0xA -#define LIN_SLAVE_12 0xB -#define LIN_SLAVE_13 0xC -#define LIN_SLAVE_14 0xD -#define LIN_MASTER 0xE -#define CMD_FACEVALUE(adr) (ADDR(adr) | 0x0 ) -#define CMD_SETVALUE(adr) (ADDR(adr) | 0x1 ) -#define CMD_RESERVED(adr) (ADDR(adr) | 0x2 ) -#define CMD_VERSION(adr) (ADDR(adr) | 0x3 ) - -#define CMD_MASTER_ALIVE (ADDR(LIN_MASTER) | 0x0 ) -#define CMD_MASTER_SETVALUE (ADDR(LIN_MASTER) | 0x1 ) -#define CMD_RESET_ADDR (ADDR(LIN_MASTER) | 0x3 ) - -/**************************/ -/* LIN-Steuerflags Master */ -/**************************/ -#define LIN_MASTER_INITFLAG 0x02 - -/***********************************/ -/* LIN-Steuerflags Sollwert setzen */ -/***********************************/ -#define LIN_SET_SOLL_POS 0x01 -#define LIN_SET_SLOW 0x02 -#define LIN_SET_MANUAL_OU 0x04 -#define LIN_SET_MANUAL_IN 0x08 -#define LIN_SET_SELFTEST 0x80 - -/*******************/ -/* LIN-Fehlercodes */ -/*******************/ -#define ERR_LIN_DEVICE (-1) -#define ERR_LIN_PORTSETTING (-2) -#define ERR_LIN_BAUDRATE (-3) -#define ERR_LIN_TIMEOUT (-4) -#define ERR_LIN_TIMEOUT_ECHO (-5) -#define ERR_LIN_TIMEOUT_MSG (-6) -#define ERR_LIN_SEND_MESSAGE (-7) -#define ERR_LIN_CHECKSUM (-8) - -/***************/ -/* LIN-Timeout */ -/***************/ -#define LIN_TIMEOUT_ECHO 50 /* 50 ms Timeoutzeit fuer Echobytes */ -#define LIN_TIMEOUT_MESSAGE 100 /* 100 ms Timeoutzeit fuer Clientantwort */ - -/*************************/ -/* Sonstige Definitionen */ -/*************************/ -#define LIN_BAUD_RATE B9600 -#define MAX_LIN_FRAME_BUFFER 30 -#define MAX_LIN_SLAVE 14 -#define LIN_SYNCBYTE 0x55 -#define LIN_TYP_MOTOR 0 -#define LIN_PROTOKOLL_VERS 0 -#define DRV_NAME_LEN 20 -#define LIN_MSG_RETRY 3 - -#ifndef x86 -#define LINTHREAD_PRIO 38 /* RT-Linux; SCHED_FIFO */ -#else -#define LINTHREAD_PRIO 54 /* kein RT-Linux; SCHED_OTHER */ -#endif -#define LINTHREAD_ZYKLUS 10 /* 10ms Zykluszeit */ - -#ifndef x86 -#define RXTHREAD_PRIO 38 /* RT-Linux; SCHED_FIFO */ -#else -#define RXTHREAD_PRIO 54 /* kein RT-Linux; SCHED_OTHER */ -#endif - -/**************/ -/* Tracetypen */ -/**************/ -#define MSG_TX_TRACE_DATA 0 -#define MSG_RX_TRACE_DATA 1 - -//#define _DEBUG - -/******************************************************************************* -@Typdefinitionen (modullokal) -*******************************************************************************/ - -typedef struct LIN_SLAVE_DATA_R { - LIN_SLAVE_VERSION_TR tVers; /* Version */ - LIN_SLAVE_VALUE_TR tValue; /* FaceValue */ - unsigned char ucSlaveOnline; /* Verbindungsstatus */ - unsigned char ucSetNewValue; /* Flag fuer neuen Sollwert */ - unsigned short usSetValue; /* Sollwert */ - unsigned char ucSetControl; /* Steuerbits fuer Sollwert */ - unsigned char ucDevice; - -} LIN_SLAVE_DATA_TR; - -/******************************************************************************* -@Konstanten (modullokal) -*******************************************************************************/ - -static const char cacDeviceName[DRV_NAME_LEN] = { "/dev/ttymxc1"}; - -/******************************************************************************* -@Variablen (modullokal) -*******************************************************************************/ - -/* Variablen Linbus-Schnittstellen */ -static int iLinPort = -1; /* Porthandle */ -static struct termios initial_settings, new_settings; /* Portsettings */ -static speed_t BaudRate; /* Baudrate */ - -/* Variablen Masterthread */ -static RTS_HANDLE rtsMasterThreadHandle = RTS_INVALID_HANDLE; /* Handle MasterThread */ -static char acMasterThreadName[15] = { "LinMasterThread" }; -static int iLinMasterState; /* Zustand Master */ - -/* Variablen Empfangsthread */ -static RTS_HANDLE rtsRxThreadHandle = RTS_INVALID_HANDLE; /* Handle RxThread */ -static char acRxThreadName[15] = { "LinRxThread" }; - -/* Variablen Empfang/Sendefunktion */ -static unsigned char acLinMsgBuffer[MAX_LIN_FRAME_BUFFER]; /* Nachrichtenpuffer */ -static unsigned char acLinRxBuffer[MAX_LIN_FRAME_BUFFER]; /* Empfangspuffer */ -static int iLinRxWrIndex; /* Schreibzeiger Empfangspuffer */ -static int iLinRxRdIndex; /* Lesezeiger Empfangspuffer */ - -/* Zustaende von Master und Slaves */ -static LIN_SLAVE_DATA_TR atLinSlaveData[MAX_LIN_SLAVE]; /* Slavezustaende */ -static int iLinSlaveCnt; /* Anzahl der konfigurieren Slaves */ -static int iLinIntervall; /* Intervall fuer die Bearbeitung des Linbus */ -static int iLinResetAddr; /* Flag fuer das Ruecksetzen der Adressen */ -static int iLinSetAddr; /* Flag fuer das Setzen der Adressen */ -static unsigned char ucLinMasterNewValue; /* Flag fuer neuen Sollwert */ -static unsigned short usLinMasterValue; /* Neuer Sollwert fuer alle Slaves */ -static unsigned char ucLinMasterControl; /* Controlbyte fuer Sollwert aller Slaves */ -static unsigned char ucLinMasterDevice; /* Device Type */ -static int iLinAdrSlaveCnt; /* zu adressierender Lin-Slave */ - -/******************************************************************************* -@Prototypen der lokalen Funktionen -*******************************************************************************/ - -#ifdef _DEBUG -static void lin_trace_message( int iTyp, unsigned char *pucMsg, int iLen ); -#endif -static int lin_getslaveversion( void ); -static int lin_getslavefacevalue( void ); -static int lin_setslavevalue( void ); -static int lin_clrslaveaddr( void ); -static int lin_setslaveaddr( int iSlave ); -static void lin_master_thread(SYS_TASK_PARAM *ptp); -static int lin_missing_slave( void ); -static void lin_rx_thread(SYS_TASK_PARAM *ptp); -static int lin_recv( unsigned char *pucLinData, int iLinByteCnt, int iTimeout ); -static int lin_recv_message( unsigned char *pucLinMsgData, int iLinMsgLen ) ; -static int lin_send( unsigned char *pucLinData, int iLinBytesCnt ); -static int lin_send_breakbyte( void ); -static int lin_send_message( unsigned char *pucLinMsgData, int iLinMsgLen ); -static unsigned char lin_pidbyte( unsigned char ucVal ); -static unsigned char lin_checksum( unsigned char *pucData, int iDataLen ); -static int lin_master_alive( unsigned char ucNextFreeAdr, unsigned char ucSlaves, unsigned char ucAliveFlags ); -static int lin_reset_all( void ); -static int lin_set_value( unsigned char ucAdr, unsigned short usSollPos, unsigned char ucControlFlags, unsigned char ucDeviceTyp ); -static int lin_face_value( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); -static int lin_get_version( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); - -USE_SysSemCreate -USE_SysSemDelete -USE_SysSemEnter -USE_SysSemLeave -USE_SysTaskCreate -USE_SysTaskResume -USE_SysTaskSetExit -USE_SysTaskJoin -USE_SysTaskExit -USE_SysTaskWaitSleep -USE_SysTaskDestroy -USE_SysTaskEnter -USE_SysTaskLeave -USE_SysTaskEnd - -#ifdef _DEBUG -/******************************************************************************/ -/*! -\fn lin_trace_message - -\brief Message ausgeben - -\return keine - -\param iTyp - Typ Empfang- bzw. Sendenachricht - pucMsg - Zeiger auf Nachricht - iMsgLen - Nachrichtenlaenge - -*******************************************************************************/ -static void lin_trace_message( int iTyp, unsigned char *pucMsg, int iMsgLen ) -{ - - char acTraceMsg[100]; - char acTraceByte[5]; - int iBytes; - int iRet; - struct timeval tv_trace; - - iRet = gettimeofday(&tv_trace, 0); - if ( iRet == 0 ) { - - strcpy(acTraceMsg, "\0"); - for ( iBytes = 0; iBytes < iMsgLen; iBytes++ ) { - - sprintf(acTraceByte, "%02x", pucMsg[iBytes]); - strcat(acTraceMsg, acTraceByte); - } - - if ( iTyp == MSG_TX_TRACE_DATA ) { - - Log_Printf(COMPONENT_ID, "TxMsg: Daten: %s Time: %lu, %lu\n", - acTraceMsg, - (unsigned long)tv_trace.tv_sec, - (unsigned long)tv_trace.tv_usec/1000); - } - else { - - Log_Printf(COMPONENT_ID, "RxMsg: Daten: %s Time: %lu, %lu\n", - acTraceMsg, - (unsigned long)tv_trace.tv_sec, - (unsigned long)tv_trace.tv_usec/1000); - } - } - else{ - Log_Warning(COMPONENT_ID, "TraceMsg: gettimeofday\n"); - } - - return; - -} /* eofn: lin_trace_message */ -#endif - -/******************************************************************************/ -/*! -\fn lin_getslaveversion - -\brief Version aller Slaves auslesen - -\return Anzahl der nicht gefunden Slaves - -\param keine - -*******************************************************************************/ -static int lin_getslaveversion( void ) -{ - int iSlave; - int iRetry; - int iRet; - - int iMissingSlaves = 0; - - for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { - - iRetry = 0; - - do { - /* Version der Slaves auslesen */ - iRet = lin_get_version( LIN_SLAVE_1 + iSlave, &atLinSlaveData[iSlave] ); - if ( iRet < 0 ) { - /* Slave antwortet nicht; nochmal wiederholen */ - iRetry++; - } - } while (( iRet < 0 ) && (iRetry <= LIN_MSG_RETRY ) ); - - if ( iRet < 0 ) { - /* Slave antwortet nicht */ - atLinSlaveData[iSlave].ucSlaveOnline = FALSE; - iMissingSlaves++; - } - else { - atLinSlaveData[iSlave].ucSlaveOnline = TRUE; - } - } - - return iMissingSlaves; - -} /* eofn: lin_getslaveversion */ - -/******************************************************************************/ -/*! -\fn lin_getslavefacevalue - -\brief Istposition aller Slaves auslesen - -\return 0 - -\param keine - -*******************************************************************************/ -static int lin_getslavefacevalue( void ) -{ - int iSlave; - int iRetry; - int iRet; - - int iMissingSlaves = 0; - - for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { - - iRetry = 0; - - do { - /* Version der Slaves auslesen */ - iRet = lin_face_value( LIN_SLAVE_1 + iSlave, &atLinSlaveData[iSlave] ); - if ( iRet < 0 ) { - /* Slave antwortet nicht; nochmal wiederholen */ - iRetry++; - } - } while (( iRet < 0 ) && (iRetry <= LIN_MSG_RETRY ) ); - - if ( iRet < 0 ) { - /* Slave antwortet nicht */ - atLinSlaveData[iSlave].ucSlaveOnline = FALSE; - iMissingSlaves++; - } - else { - atLinSlaveData[iSlave].ucSlaveOnline = TRUE; - } - } - - return iMissingSlaves; - -} /* eofn: lin_getslavefacevalue */ - -/******************************************************************************/ -/*! -\fn lin_setslavevalue - -\brief Sollposition fuer Slaves setzen - -\return keine - -\param keine - -*******************************************************************************/ -static int lin_setslavevalue( void ) -{ - int iSlave; - - /* Masterwert wurde geaendert */ - if ( ucLinMasterNewValue == TRUE ) { - ucLinMasterNewValue = FALSE; - - /* Neue Sollposition fuer alle uebernehmen senden */ - lin_set_value(LIN_MASTER, usLinMasterValue, ucLinMasterControl, ucLinMasterDevice); - } - else { - - for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { - - if ( atLinSlaveData[iSlave].ucSetNewValue == TRUE ) { - atLinSlaveData[iSlave].ucSetNewValue = FALSE; - - /* Neue Sollposition fuer Slave uebernehmen senden */ - lin_set_value(LIN_SLAVE_1 + iSlave, atLinSlaveData[iSlave].usSetValue, atLinSlaveData[iSlave].ucSetControl, atLinSlaveData[iSlave].ucDevice); - } - } - } - - return 0; - -} /* eofn: lin_setslavevalue */ - - -/******************************************************************************/ -/*! -\fn lin_clrslaveaddr - -\brief Slaveadressen neu setzen - -\return kein - -\param keine - -*******************************************************************************/ -static int lin_clrslaveaddr( void ) -{ - int iSlave; - - /* Kommando Reset senden */ - lin_reset_all(); - - /* Alle Slaves alle nicht erkannt markieren */ - for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { - - atLinSlaveData[iSlave].ucSlaveOnline = FALSE; - } - - return 0; - -} /* eofn: lin_clrlaveaddr */ - -/******************************************************************************/ -/*! -\fn lin_setslaveaddr - -\brief Slaveadressen neu setzen - -\return Slavestatus - 0 - Slave nicht vorhanden - -1 - Slave vorhanden - -\param iSlave - Slave - -*******************************************************************************/ -static int lin_setslaveaddr( int iSlave ) -{ - /* Kommando Alive an alle Slaves senden */ - lin_master_alive( iSlave, iLinSlaveCnt, LIN_MASTER_INITFLAG ); - - /* Kommando FaceValue an Slave senden */ - if ( lin_face_value( iSlave, &atLinSlaveData[iSlave] ) < 0 ) { - - atLinSlaveData[iSlave].ucSlaveOnline = FALSE; - return -1; - } - - /* Kommando FaceValue an Slave senden */ - if ( lin_get_version( iSlave, &atLinSlaveData[iSlave] ) < 0 ) { - - atLinSlaveData[iSlave].ucSlaveOnline = FALSE; - return -1; - } - atLinSlaveData[iSlave].ucSlaveOnline = TRUE; - - return 0; - -} /* eofn: lin_setslaveaddr */ - -/******************************************************************************/ -/*! -\fn lin_missing_slave - -\brief Fehlenden Slave suchen - -\return Slavenummer - -\param keine - -*******************************************************************************/ -static int lin_missing_slave( void ) -{ - int iSlave = 0; - - do { - - if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { - - /* Slave ist nicht vorhanden */ - return iSlave; - } - iSlave++; - } while ( iSlave < iLinSlaveCnt ); - - return -1; - -} /* eofn: lin_missing_slave */ - -/******************************************************************************/ -/*! -\fn lin_master_thread - -\brief Protokollverarbeitung Linbus Master - -\return keine - -\param keine - -*******************************************************************************/ -static void lin_master_thread(SYS_TASK_PARAM *ptp) -{ - int iMissingSlaves; - - CAL_SysTaskEnter(ptp->hTask); - - while(!ptp->bExit) { - - DEBUG_PRINT("Zustand Master : %i\n", iLinMasterState); - DEBUG_PRINT("\n"); - - switch ( iLinMasterState ) { - - /*********************************************************************/ - case LIN_MASTER_CHECK : { - /*********************************************************************/ - - /* Kommando Alive an alle Slaves senden */ - lin_master_alive( 0, iLinSlaveCnt, 0 ); - - /* Version der Slaves abfragen */ - iMissingSlaves = lin_getslaveversion(); - if ( iMissingSlaves == 1 ) { - - /* fehlenden Slave setzen */ - iLinAdrSlaveCnt = lin_missing_slave(); - - /* Timeout eines Slaves */ - iLinMasterState = LIN_MASTER_INIT; - break; - } - else if ( iMissingSlaves > 1 ) { - - /* Timeout mehrere Slaves */ - iLinMasterState = LIN_MASTER_REPAIR; - break; - } - - /* Slave haben sich gemeldet */ - iLinMasterState = LIN_MASTER_ONLINE; - } break; - - /*********************************************************************/ - case LIN_MASTER_INIT : { - /*********************************************************************/ - - /* Adressen fuer Slaves setzen */ - lin_setslaveaddr( iLinAdrSlaveCnt ); - - /* Version der Slaves abfragen */ - iMissingSlaves = lin_getslaveversion(); - if ( iMissingSlaves == 0 ) { - - /* Alle Slave sind da */ - iLinMasterState = LIN_MASTER_ONLINE; - break; - } - else if ( iMissingSlaves > 1 ) { - - /* Timeout mehrerr Slaves */ - iLinMasterState = LIN_MASTER_REPAIR; - break; - } - - if ( iLinResetAddr == TRUE ) { - iLinResetAddr = FALSE; - iLinSetAddr = FALSE; - - /* Slaveadresse loeschen */ - lin_clrslaveaddr(); - - /* Adressen loeschen */ - iLinMasterState = LIN_MASTER_ADR_CLR; - break; - } - } break; - - /*********************************************************************/ - case LIN_MASTER_ONLINE : { - /*********************************************************************/ - - /* Kommando Alive an alle Slaves senden */ - lin_master_alive( 0, iLinSlaveCnt, 0 ); - - /* Sollwert der Slaves senden */ - lin_setslavevalue(); - - /* Istwert der Slaves abfragen */ - iMissingSlaves = lin_getslavefacevalue(); - if ( iMissingSlaves == 1 ) { - - /* fehlenden Slave setzen */ - iLinAdrSlaveCnt = lin_missing_slave(); - - /* Timeout eines Slaves */ - iLinMasterState = LIN_MASTER_INIT; - break; - } - else if ( iMissingSlaves > 1 ) { - - /* Timeout eines Slaves */ - iLinMasterState = LIN_MASTER_REPAIR; - break; - } - - if ( iLinResetAddr == TRUE ) { - iLinResetAddr = FALSE; - iLinSetAddr = FALSE; - - /* Slaveadresse loeschen */ - lin_clrslaveaddr(); - - /* Adressen loeschen */ - iLinMasterState = LIN_MASTER_ADR_CLR; - break; - } - } break; - - /*********************************************************************/ - case LIN_MASTER_REPAIR : { - /*********************************************************************/ - - if ( iLinResetAddr == TRUE ) { - iLinResetAddr = FALSE; - iLinSetAddr = FALSE; - - /* Slaveadresse loeschen */ - lin_clrslaveaddr(); - - /* Adressen loeschen */ - iLinMasterState = LIN_MASTER_ADR_CLR; - break; - } - /* Version der Slaves abfragen */ - iMissingSlaves = lin_getslaveversion(); - if ( iMissingSlaves == 1 ) { - - /* fehlenden Slave setzen */ - iLinAdrSlaveCnt = lin_missing_slave(); - - /* Timeout eines Slaves */ - iLinMasterState = LIN_MASTER_INIT; - break; - } - - - /* Slave haben sich gemeldet */ - iLinMasterState = LIN_MASTER_ONLINE; - } break; - - /***************************************************************/ - case LIN_MASTER_ADR_CLR : { - /***************************************************************/ - - if ( iLinResetAddr == TRUE ) { - iLinResetAddr = FALSE; - - /* Slaveadresse loeschen */ - lin_clrslaveaddr(); - break; - } - - if ( iLinSetAddr == TRUE ) { - iLinSetAddr = FALSE; - - /* Neuadressierung mit Adresse 0 */ - iLinAdrSlaveCnt = 0; - - /* Warte auf Slave */ - iLinMasterState = LIN_MASTER_WAIT_FOR_SLAVE; - break; - } - } break; - - /***************************************************************/ - case LIN_MASTER_WAIT_FOR_SLAVE : { - /***************************************************************/ - - /* Adressen fuer Slaves setzen */ - lin_setslaveaddr( iLinAdrSlaveCnt ); - - /* pruefen ob Slave erkannt wurde */ - if ( atLinSlaveData[iLinAdrSlaveCnt].ucSlaveOnline == TRUE ) { - - /* naechster Slave */ - iLinAdrSlaveCnt++; - - if ( iLinAdrSlaveCnt == iLinSlaveCnt ) { - - /* alle Slaves adressiert */ - iLinMasterState = LIN_MASTER_ONLINE; - break; - } - } - - if ( iLinResetAddr == TRUE ) { - iLinResetAddr = FALSE; - iLinSetAddr = FALSE; - - /* Slaveadresse loeschen */ - lin_clrslaveaddr(); - - /* Adressen loeschen */ - iLinMasterState = LIN_MASTER_ADR_CLR; - break; - } - } break; - - /***************************************************************/ - default : { - /***************************************************************/ - - } break; - } - - CAL_SysTaskWaitSleep(ptp->hTask, iLinIntervall); - } - - CAL_SysTaskLeave(ptp->hTask); - CAL_SysTaskEnd(ptp->hTask, 0); - - return; - -} /* eofn: lin_master_thread */ - -/******************************************************************************/ -/*! -\fn lin_rx_thread - -\brief Empfangsthread - -\return keine - -\param arg - -*******************************************************************************/ -static void lin_rx_thread(SYS_TASK_PARAM *ptp) -{ - CAL_SysTaskEnter(ptp->hTask); - - while(!ptp->bExit) { - - if ( read( iLinPort, &acLinRxBuffer[iLinRxWrIndex], 1 ) > 0 ) { - - iLinRxWrIndex++; - if ( iLinRxWrIndex >= MAX_LIN_FRAME_BUFFER ) { - - iLinRxWrIndex = 0; - } - } - } - - CAL_SysTaskLeave(ptp->hTask); - CAL_SysTaskEnd(ptp->hTask, 0); - - return; - -} /* eofn: lin_rx_thread */ - -/******************************************************************************/ -/*! -\fn lin_recv - -\brief Lin-Bytes empfangen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param pucLinData - Zeiger auf die Daten - iLinByteCnt - Anzahl an Bytes - iTimeout - Timeoutzeit fuer das Lesen - -*******************************************************************************/ -static int lin_recv( unsigned char *pucLinData, int iLinByteCnt, int iTimeout ) -{ - int iTimer = 0; - int iByteCnt = 0; - - do { - - if ( iLinRxRdIndex != iLinRxWrIndex ) { - - pucLinData[iByteCnt] = acLinRxBuffer[iLinRxRdIndex]; - iByteCnt++; - - iLinRxRdIndex++; - if ( iLinRxRdIndex >= MAX_LIN_FRAME_BUFFER ) { - - iLinRxRdIndex = 0; - } - } - else { - - /* Timeoutzeit abwarten */ - usleep(1000); - iTimer++; - } - - } while (( iByteCnt < iLinByteCnt ) && ( iTimer < iTimeout )); - - /* pruefen ob alle Bytes gelesen wurden */ - if ( iTimer >= iTimeout ) { - - /* Fehler beim lesen; keine weiteren Bytes mehr lesen */ - iLinRxRdIndex = 0; - iLinRxWrIndex = 0; - return ERR_LIN_TIMEOUT; - } - - return 0; - -} /* eofn: lin_recv */ - -/******************************************************************************/ -/*! -\fn lin_recv_message - -\brief Lin-Message empfangen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param pucLinData - Zeiger auf die Daten - iLinBytesCnt - Anzahl an Bytes - -*******************************************************************************/ -static int lin_recv_message( unsigned char *pucLinMsgData, int iLinMsgLen ) -{ - unsigned char ucChecksum; - - /************************************/ - /* Response vom Client zuruecklesen */ - /************************************/ - if ( lin_recv( &pucLinMsgData[1], iLinMsgLen-1, LIN_TIMEOUT_MESSAGE ) < 0 ) { - - /* Timeout/Fehler beim Empfang des Response */ - return ERR_LIN_TIMEOUT_MSG; - } - - /****************/ - /* Traceausgabe */ - /****************/ - #ifdef _DEBUG - lin_trace_message( MSG_RX_TRACE_DATA, pucLinMsgData, iLinMsgLen ); - #endif - - /*******************************/ - /* Empfangsschecksumme pruefen */ - /*******************************/ - ucChecksum = lin_checksum(pucLinMsgData, iLinMsgLen -1); - if ( ucChecksum != pucLinMsgData[iLinMsgLen-1] ) { - - /* Checksumme ist ungueltig */ - Log_Warning(COMPONENT_ID, "Checksumme ist ungueltig\n"); - - /* BUG 1898 - Clean Buffer */ - // Kein Mutex benötigt - iLinRxWrIndex = 0; /* Schreibzeiger Empfangspuffer */ - iLinRxRdIndex = 0; /* Lesezeiger Empfangspuffer */ - - return ERR_LIN_CHECKSUM; - } - - return 0; - -} /* eofn: lin_recv_message */ - -/******************************************************************************/ -/*! -\fn lin_send - -\brief Lin-Bytes senden - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param pcLinData - Zeiger auf die Daten - iLinBytesCnt - Anzahl an Bytes - -*******************************************************************************/ -static int lin_send( unsigned char *pucLinData, int iLinBytesCnt ) -{ - if ( write( iLinPort, pucLinData, iLinBytesCnt ) < 0 ) { - - Log_Warning(COMPONENT_ID, "Fehler beim Senden\n"); - return ERR_LIN_SEND_MESSAGE; - } - - return 0; - -} /* eofn: lin_send */ - -/******************************************************************************/ -/*! -\fn lin_send_breakbyte - -\brief Breakbyte senden - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param keine - -*******************************************************************************/ -static int lin_send_breakbyte( void ) -{ - - unsigned char ucTmp = 0; - - tcgetattr(iLinPort, &initial_settings); - new_settings = initial_settings; - - /************************************/ - /* Schnittstelleneinstellung setzen */ - /************************************/ - /* Baudrate */ - if (cfsetispeed(&new_settings, BaudRate-1) != 0) { - - Log_Warning(COMPONENT_ID, "Baudrate kann nicht initialsiert werden\n"); - return ERR_LIN_BAUDRATE; - } - - if (cfsetospeed(&new_settings, BaudRate-1) != 0) { - - Log_Warning(COMPONENT_ID, "Baudrate kann nicht initialsiert werden\n"); - return ERR_LIN_BAUDRATE; - } - cfmakeraw(&new_settings); - - /* Flags */ - new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ - new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ - new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ - new_settings.c_cflag |= CS8; - - if (tcsetattr(iLinPort, TCSANOW, &new_settings) != 0) { - - Log_Warning(COMPONENT_ID, "Schnittstlleneinstellung koennen nicht gesetzt werden\n"); - return ERR_LIN_PORTSETTING; - } - - /********************/ - /* Breakbyte senden */ - /********************/ - lin_send( &ucTmp, 1 ); - - /*************************/ - /* Echobyte zuruecklesen */ - /*************************/ - lin_recv( &ucTmp, 1, LIN_TIMEOUT_ECHO ); - - tcgetattr(iLinPort, &initial_settings); - new_settings = initial_settings; - - /************************************/ - /* Schnittstelleneinstellung setzen */ - /************************************/ - - if (cfsetispeed(&new_settings, BaudRate) != 0) { - return ERR_LIN_BAUDRATE; - } - if (cfsetospeed(&new_settings, BaudRate) != 0) { - return ERR_LIN_BAUDRATE; - } - - cfmakeraw(&new_settings); - - /* Flags */ - new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ - new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ - new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ - new_settings.c_cflag |= CS8; - - if (tcsetattr(iLinPort, TCSADRAIN, &new_settings) != 0) { - - Log_Warning(COMPONENT_ID, "Device konnte nicht initialsiert werden\n"); - return ERR_LIN_PORTSETTING; - } - - return 0; -} /* eofn: lin_send_breakbyte */ - -/******************************************************************************/ -/*! -\fn lin_send_message - -\brief Lin-Message senden - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param pucLinMsgData - Zeiger auf die Daten - iLinMsgLen - Anzahl an Bytes - -*******************************************************************************/ -static int lin_send_message( unsigned char *pucLinMsgData, int iLinMsgLen ) -{ - int iRet = 0; - - /******************************/ - /* Breakbyte zunaechst senden */ - /******************************/ - if (( iRet = lin_send_breakbyte()) < 0 ) { - - /* Break konnte nicht gesendet werden */ - return iRet; - } - - /******************/ - /* Message senden */ - /******************/ - if (( iRet = lin_send( pucLinMsgData, iLinMsgLen )) < 0 ) { - - /* Message konnte nicht gesendet werden */ - return iRet; - } - - /**************************/ - /* Echobytes zuruecklesen */ - /**************************/ - if ( lin_recv( pucLinMsgData, iLinMsgLen, LIN_TIMEOUT_ECHO ) < 0 ) { - - /* Timeout/Fehler beim Empfang des Echos */ - return ERR_LIN_TIMEOUT_ECHO; - } - - /****************/ - /* Traceausgabe */ - /****************/ - #ifdef _DEBUG - lin_trace_message( MSG_TX_TRACE_DATA, pucLinMsgData, iLinMsgLen ); - #endif - - return 0; - -} /* eofn: lin_send_message */ - -/******************************************************************************/ -/*! -\fn lin_pidbyte - -\brief PID-Byte erzeugen - -\return PID-Byte - -\param ucVal - Wert fuer Kommando bzw Adresse - -*******************************************************************************/ -static unsigned char lin_pidbyte( unsigned char ucVal ) -{ - - unsigned char ucTmp = 0; - - if ((ISBITSET(ucVal,0) ^ ISBITSET(ucVal,1) ^ ISBITSET(ucVal,2) ^ ISBITSET(ucVal,4)) != 0 ) { - - ucTmp = 0x01; - } - - if ((ISBITSET(ucVal,1) ^ ISBITSET(ucVal,3) ^ ISBITSET(ucVal,4) ^ ISBITSET(ucVal,5)) == 0 ) { - - ucTmp |= 0x02; - } - - return PID_PARITY(ucTmp) | ucVal; - -} /* eofn: lin_pidbyte */ - -/******************************************************************************/ -/*! -\fn lin_checksum - -\brief Checksumme erzeugen - -\return Checksumme - -\param pucData - Zeiger auf Daten - iDataLen - Datenlaenge - -*******************************************************************************/ -static unsigned char lin_checksum( unsigned char *pucData, int iDataLen ) -{ - unsigned short usTmp = 0; - int i; - - for ( i = 0; i < iDataLen; i++ ) { - - usTmp += pucData[i]; - /* Ueberlauf pruefen */ - if ( usTmp > 0xFF ) { - usTmp &= 0x00FF; - usTmp++; /* Carrybit addrieren */ - } - } - - return (unsigned char)(~usTmp); - -} /* eofn: lin_checksum */ - -/******************************************************************************/ -/*! -\fn lin_master_alive - -\brief Master Alive-Message senden - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param ucNextFreeAdr - Naechste freie Adresse - ucSlaves - Anzahl Teilnehmer - ucAliveFlags - Flags - -*******************************************************************************/ -static int lin_master_alive( unsigned char ucNextFreeAdr, unsigned char ucSlaves, unsigned char ucAliveFlags ) -{ - int iRet; - - DEBUG_PRINT("MasterAlive:\n"); - DEBUG_PRINT("Naechste freie Adresse : %i\n", ucNextFreeAdr); - DEBUG_PRINT("Anzahl LIN-Teilnehmer : %i\n", ucSlaves); - DEBUG_PRINT("Flags : %i\n", ucAliveFlags); - DEBUG_PRINT("\n"); - - /* MasterALive-Message aufbauen */ - acLinMsgBuffer[0] = LIN_SYNCBYTE; - acLinMsgBuffer[1] = lin_pidbyte(CMD_MASTER_ALIVE); - acLinMsgBuffer[2] = ucNextFreeAdr; - acLinMsgBuffer[3] = 1 + ucSlaves; /* Master + Slaves */ - acLinMsgBuffer[4] = ucAliveFlags; - acLinMsgBuffer[5] = LIN_PROTOKOLL_VERS; - acLinMsgBuffer[6] = lin_checksum( &acLinMsgBuffer[1], 5); - iRet = lin_send_message( acLinMsgBuffer, 7 ); - - return iRet; - -} /* eofn: lin_master_alive */ - -/******************************************************************************/ -/*! -\fn lin_reset_all - -\brief Alle Adressen loeschen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param keine - -*******************************************************************************/ -static int lin_reset_all( void ) -{ - int iRet; - - DEBUG_PRINT("ResetAll:\n"); - - /* Reset-Message aufbauen */ - acLinMsgBuffer[0] = LIN_SYNCBYTE; - acLinMsgBuffer[1] = lin_pidbyte(CMD_RESET_ADDR); - acLinMsgBuffer[2] = 0x52; - acLinMsgBuffer[3] = 0x45; - acLinMsgBuffer[4] = 0x53; - acLinMsgBuffer[5] = 0x45; - acLinMsgBuffer[6] = 0x54; - acLinMsgBuffer[7] = 0x4E; - acLinMsgBuffer[8] = 0x4F; - acLinMsgBuffer[9] = 0x57; - acLinMsgBuffer[10] = lin_checksum( &acLinMsgBuffer[1], 9); - iRet = lin_send_message( acLinMsgBuffer, 11 ); - - return iRet; - -} /* eofn: lin_reset_all */ - -/******************************************************************************/ -/*! -\fn lin_set_value - -\brief Sollwert setzen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param usAdr - LinAdresse - usSollPos - Sollposition - ucClontrolFlags - Steuerflags - -*******************************************************************************/ -static int lin_set_value( unsigned char ucAdr, unsigned short usSollPos, unsigned char ucControlFlags, unsigned char ucDeviceTyp ) -{ - int iRet; - - DEBUG_PRINT("SetValue:\n"); - DEBUG_PRINT("Slave : %i\n", ucAdr ); - DEBUG_PRINT("SollPos : %i\n", usSollPos ); - DEBUG_PRINT("Flags : %i\n", ucControlFlags ); - DEBUG_PRINT("Flags : %i\n", ucControlFlags ); - DEBUG_PRINT("\n"); - - /* SetValue-Message aufbauen */ - acLinMsgBuffer[0] = LIN_SYNCBYTE; - acLinMsgBuffer[1] = lin_pidbyte(CMD_SETVALUE(ucAdr)); - acLinMsgBuffer[2] = ucDeviceTyp; - acLinMsgBuffer[3] = ucControlFlags; - acLinMsgBuffer[4] = (unsigned char)(0x00ff & usSollPos); - acLinMsgBuffer[5] = (unsigned char)( usSollPos >> 8); - acLinMsgBuffer[6] = lin_checksum( &acLinMsgBuffer[1], 5); - iRet = lin_send_message( acLinMsgBuffer, 7 ); - - return iRet; - -} /* eofn: lin_set_value */ - -/******************************************************************************/ -/*! -\fn lin_face_value - -\brief Istwert auslesen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param usAdr - Adresse - ptLinSlaveData - Zeiger auf Slavedaten - -*******************************************************************************/ -static int lin_face_value( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ) -{ - int iRet; - - DEBUG_PRINT("FaceValue: \n"); - - /* Face-Message aufbauen */ - acLinMsgBuffer[0] = LIN_SYNCBYTE; - acLinMsgBuffer[1] = lin_pidbyte(CMD_FACEVALUE(ucAdr)); - if (( iRet = lin_send_message( acLinMsgBuffer, 2 )) < 0 ) { - - /* Fehler beim Senden des Kommandos FaceValue */ - return iRet; - } - - /* Response vom Slave auswerten */ - if (( iRet = lin_recv_message( &acLinMsgBuffer[1], 7 )) < 0 ) { - - /* Fehler beim Empfang */ - return iRet; - } - - /* Empfangsdaten uebernehmen */ - ptLinSlaveData->tValue.ucFormat = acLinMsgBuffer[2]; - ptLinSlaveData->tValue.usIstPos = acLinMsgBuffer[3]; - ptLinSlaveData->tValue.usIstPos |= acLinMsgBuffer[4] << 8; - ptLinSlaveData->tValue.ucStatus = acLinMsgBuffer[5]; - ptLinSlaveData->tValue.ucErrorCnt = acLinMsgBuffer[6]; - - DEBUG_PRINT("Format : %i\n", ptLinSlaveData->tValue.ucFormat); - DEBUG_PRINT("IstPos : %i\n", ptLinSlaveData->tValue.usIstPos); - DEBUG_PRINT("Status : %i\n", ptLinSlaveData->tValue.ucStatus); - DEBUG_PRINT("Fehler : %i\n", ptLinSlaveData->tValue.ucErrorCnt); - DEBUG_PRINT("\n"); - - return 0; - -} /* eofn: lin_face_value */ - -/******************************************************************************/ -/*! -\fn lin_get_version - -\brief Version auslesen - -\return Ergebnis - = 0 - OK - < 0 - Fehler - -\param ucAdr - Adresse - ptLinSlaveData - Zeiger auf Slavedaten - -*******************************************************************************/ -static int lin_get_version( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ) -{ - int iRet; - - DEBUG_PRINT("GetVersion %i: \n", ucAdr); - - /* Face-Message aufbauen */ - acLinMsgBuffer[0] = LIN_SYNCBYTE; - acLinMsgBuffer[1] = lin_pidbyte(CMD_VERSION(ucAdr)); - if (( iRet = lin_send_message( acLinMsgBuffer, 2 )) < 0 ) { - - /* Fehler beim Senden des Kommandos GetVersion */ - return iRet; - } - - /* Response vom Slave auswerten */ - if (( iRet = lin_recv_message( &acLinMsgBuffer[1], 10 )) < 0 ) { - - /* Fehler beim Empfang */ - return iRet; - } - - /* Empfangsdaten uebernehmen */ - ptLinSlaveData->tVers.ucRelease = acLinMsgBuffer[2]; - ptLinSlaveData->tVers.ucVersion = acLinMsgBuffer[3]; - ptLinSlaveData->tVers.ucVariant = acLinMsgBuffer[4]; - ptLinSlaveData->tVers.ucFormat = acLinMsgBuffer[5]; - ptLinSlaveData->tVers.usManCode = acLinMsgBuffer[6]; - ptLinSlaveData->tVers.usManCode |= acLinMsgBuffer[7]<<8; - ptLinSlaveData->tVers.usFunction = acLinMsgBuffer[8]; - ptLinSlaveData->tVers.usFunction |= acLinMsgBuffer[9]<<8; - - DEBUG_PRINT("Release : %i\n", ptLinSlaveData->tVers.ucRelease); - DEBUG_PRINT("Version : %i\n", ptLinSlaveData->tVers.ucVersion); - DEBUG_PRINT("Build : %i\n", ptLinSlaveData->tVers.ucVariant); - DEBUG_PRINT("Format : %i\n", ptLinSlaveData->tVers.ucFormat); - DEBUG_PRINT("ManCode : %i\n", ptLinSlaveData->tVers.usManCode); - DEBUG_PRINT("Function: %i\n", ptLinSlaveData->tVers.usFunction); - DEBUG_PRINT("\n"); - - return 0; - -} /* eofn: lin_get_version */ - -/******************************************************************************/ -/*! -\fn LIN_Open - -\brief Schnittstelle fuer den LIN-Bus oeffnen - -\return 0 - Schnittstelle konnte geoffnet werden - -1 - Fehler beim Oeffnen - -\param iSlaveCount - Anzahl der Linbus-Slaves - iIntervall - Intervallzeit fuer Lin-Bus-Verarbeitung - -*******************************************************************************/ -int LIN_Open( int iSlaveCount, int iIntervall ) -{ - RTS_RESULT rtsResult; - - /* pruefen ob Linbus bereits geoeffnet wurde */ - if ( rtsMasterThreadHandle != RTS_INVALID_HANDLE ) { - /* Linbus schliessen */ - LIN_Close(); - } - - /******************/ - /* Device oeffnen */ - /******************/ - iLinPort = open( cacDeviceName, O_RDWR); - if ( iLinPort < 0 ) { - - Log_Warning(COMPONENT_ID, "Device kann nicht geoeffnet werden\n"); - return ERR_LIN_DEVICE; - } - - tcgetattr(iLinPort, &initial_settings); - new_settings = initial_settings; - - /************************************/ - /* Schnittstelleneinstellung setzen */ - /************************************/ - /* Baudrate */ - BaudRate = LIN_BAUD_RATE; - if (cfsetispeed(&new_settings, BaudRate) != 0) { - return ERR_LIN_BAUDRATE; - } - cfmakeraw(&new_settings); - - /* Flags */ - new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ - new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ - new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ - new_settings.c_cflag |= CS8; - - if (tcsetattr(iLinPort, TCSAFLUSH, &new_settings) != 0) { - - Log_Warning(COMPONENT_ID, "Device konnte nicht initialsiert werden\n"); - return ERR_LIN_PORTSETTING; - } - - /*******************************/ - /* Initialisierung uebernehmen */ - /*******************************/ - iLinSlaveCnt = iSlaveCount; - iLinIntervall = iIntervall; - - /*********************************/ - /* Empfangspuffer initialisieren */ - /*********************************/ - iLinRxWrIndex = 0; - iLinRxRdIndex = 0; - - /***************************/ - /* Empfangsthread erzeugen */ - /***************************/ - rtsRxThreadHandle = CAL_SysTaskCreate( acRxThreadName, lin_rx_thread, NULL, RXTHREAD_PRIO, 0, 0, NULL, &rtsResult); - if ((rtsRxThreadHandle == RTS_INVALID_HANDLE) || (rtsResult != ERR_OK)) { - - Log_Warning(COMPONENT_ID, "LIN_Open: Rx-Task kann nicht angelegt werden\n"); - return ERR_LIN_DEVICE; - } - - /* Task starten */ - CAL_SysTaskResume(rtsRxThreadHandle); - - /*************************/ - /* Masterthread erzeugen */ - /*************************/ - rtsMasterThreadHandle = CAL_SysTaskCreate( acMasterThreadName, lin_master_thread, NULL, LINTHREAD_PRIO, 0, 0, NULL, &rtsResult); - if ((rtsMasterThreadHandle == RTS_INVALID_HANDLE) || (rtsResult != ERR_OK)) { - - Log_Warning(COMPONENT_ID, "LIN_Open: Master-Task kann nicht angelegt werden\n"); - return ERR_LIN_DEVICE; - } - - /* Task starten */ - CAL_SysTaskResume(rtsMasterThreadHandle); - iLinMasterState = LIN_MASTER_CHECK; - - return 0; - -} /* eofn: LIN_Open */ - - -/******************************************************************************/ -/*! -\fn LIN_Close - -\brief Schnittstelle fuer den LIN-Bus schliessen - -\return 0 - Schnittstelle konnte geschlossen werden - -1 - Fehler beim Schliessen - -\param keine - -*******************************************************************************/ -int LIN_Close( void ) -{ - - unsigned char ucTmp = 0; - - /*************************/ - /* Mastertask schliessen */ - /*************************/ - if ( rtsMasterThreadHandle != RTS_INVALID_HANDLE ) { - - CAL_SysTaskSetExit(rtsMasterThreadHandle); - CAL_SysTaskExit(rtsMasterThreadHandle, 1000); - rtsMasterThreadHandle = RTS_INVALID_HANDLE; - } - - /***************************/ - /* Empfangstask schliessen */ - /***************************/ - if ( rtsRxThreadHandle != RTS_INVALID_HANDLE ) { - - lin_send( &ucTmp, 1 ); /* Dummy-Byte senden um Empfangsthread abzubrechen */ - - CAL_SysTaskSetExit(rtsRxThreadHandle); - CAL_SysTaskExit(rtsRxThreadHandle, 1000); - rtsRxThreadHandle = RTS_INVALID_HANDLE; - } - - /*********************/ - /* Device schliessen */ - /*********************/ - if ( iLinPort >= 0 ) { - - if ( close( iLinPort ) != 0 ) { - - Log_Warning(COMPONENT_ID, "Device kann nicht geschlossen werden\n"); - return ERR_LIN_DEVICE; - } - } - - return 0; - -} /* eofn: LIN_Close */ - -/******************************************************************************/ -/*! -\fn LIN_GetMasterState - -\brief Funktion liefert den Status des Linbus-Master - -\return Status des Linbus-Masters - -\param keine - -*******************************************************************************/ -int LIN_GetMasterState( void ) -{ - return iLinMasterState; - -} /* eofn: LIN_GetMasterState */ - -/******************************************************************************/ -/*! -\fn LIN_GetSlaveState - -\brief Funktion liefert den Status des Linbus-Slave - -\return Status des Linbus-Slave - -\param iSlave - Linbus-Slave - -*******************************************************************************/ -int LIN_GetSlaveState( int iSlave ) -{ - if ( iSlave > MAX_LIN_SLAVE ) { - - return -1; - } - - return atLinSlaveData[iSlave].ucSlaveOnline; - -} /* eofn: LIN_GetSlaveState */ - -/******************************************************************************/ -/*! -\fn LIN_ResetAddress - -\brief Alle Adressen der Linbus-Slaves loeschen - -\return Adressen werden geloescht - 0 - Loeschen wird ausgefuehrt - -1 - Fehler beim Loeschen - -\param keine - -*******************************************************************************/ -int LIN_ResetAddress( void ) -{ - - /* Reset ausfuehren */ - iLinResetAddr = TRUE; - - return 0; - -} /* eofn: LIN_ResetAddress */ - -/******************************************************************************/ -/*! -\fn LIN_SetAddress - -\brief Adressen der Linbus-Slaves neu setzen - -\return Adressen werden gesetzt - 0 - Setzen wird ausgefuehrt - -\param keine - -*******************************************************************************/ -int LIN_SetAddress( void ) -{ - - /* Setzen ausfuehren */ - iLinSetAddr = TRUE; - - return 0; - -} /* eofn: LIN_SetAddress */ - -/******************************************************************************/ -/*! -\fn LIN_GetVersion - -\brief Version des Linbus-Slaves auslesen - -\return Versionsdaten gueltig - 0 - Gueltig - -1 - Ungueltig - -\param iSlave - Linbus-Slave - ptLinSlaveVersion - Zeiger auf Versionsdaten des Slaves - -*******************************************************************************/ -int LIN_GetVersion( int iSlave, LIN_SLAVE_VERSION_TR *ptLinSlaveVersion ) -{ - if ( iSlave > MAX_LIN_SLAVE ) { - - /* Slavenummer ist ungueltig */ - return -1; - } - - if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { - - /* Slave nicht vorhanden; Versioneintrag loeschen */ - memset(&atLinSlaveData[iSlave].tVers, 0, sizeof(LIN_SLAVE_VERSION_TR)); - } - - /* Versionseintrag uebernehmen */ - memcpy( ptLinSlaveVersion, &atLinSlaveData[iSlave].tVers, sizeof(LIN_SLAVE_VERSION_TR)); - - return 0; - -} /* eofn: LIN_GetVersion */ - -/******************************************************************************/ -/*! -\fn LIN_GetFaceValue - -\brief Istwert des Linbus-Slaves auslesen - -\return Istwert des Linbus-Slaves - >=0 - Istwert gueltig - -1 - ungueltiger Wert - -\param iSlave - Linbus-Slave - ptLinSlaveValue - Zeiger auf Istwerte des Slaves - -*******************************************************************************/ -int LIN_GetFaceValue( int iSlave, LIN_SLAVE_VALUE_TR *ptLinSlaveValue ) -{ - - if ( iSlave > MAX_LIN_SLAVE ) { - - return -1; - } - - if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { - - /* Slave nicht vorhanden; Versioneintrag loeschen */ - memset(&atLinSlaveData[iSlave].tValue, 0, sizeof(LIN_SLAVE_VALUE_TR)); - } - - /* Werte uebernehmen */ - memcpy( ptLinSlaveValue, &atLinSlaveData[iSlave].tValue, sizeof(LIN_SLAVE_VALUE_TR)); - - return 0; - -} /* eofn: LIN_GetFaceValue */ - -/******************************************************************************/ -/*! -\fn LIN_SetValue - -\brief Sollwert des Linbus-Slaves setzen - -\return Sollwert wird uebernommen - 0 - Uebernahme wird ausgefuehrt - -1 - Fehler bei der Uebernahme - -\param iSlave - Linbus-Slave - usValue - Sollwert - ucControl - Steuerflags - -*******************************************************************************/ -int LIN_SetValue( int iSlave, unsigned short usValue, unsigned char ucControl, unsigned char ucDevice ) -{ - if ( iSlave > MAX_LIN_SLAVE ) { - - /* Adressierung ungueltig */ - return -1; - } - - if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { - - /* Slave nicht vorhanden */ - return -1; - } - - /* Werte uebernehmen */ - atLinSlaveData[iSlave].ucSetNewValue = TRUE; - atLinSlaveData[iSlave].usSetValue = usValue; - atLinSlaveData[iSlave].ucSetControl = ucControl; - atLinSlaveData[iSlave].ucDevice = ucDevice; - - return 0; - -} /* eofn: LIN_SetValue */ - -/******************************************************************************/ -/*! -\fn LIN_MasterSetValue - -\brief Sollwert fuer alle Linbus-Slaves setzen - -\return Sollwert wird uebernommen - 0 - Uebernahme wird ausgefuehrt - -1 - Fehler bei der Uebernahme - -\param usValue - Sollwert - ucControl - Steuerflags - -*******************************************************************************/ -int LIN_MasterSetValue( unsigned short usValue, unsigned char ucControl, unsigned char ucDevice ) -{ - if ( iLinMasterState != LIN_MASTER_ONLINE ) { - - /* Master nicht Online */ - return -1; - } - - /* Werte uebernehmen */ - ucLinMasterNewValue = TRUE; - usLinMasterValue = usValue; - ucLinMasterControl = ucControl; - ucLinMasterDevice = ucDevice; - - - return 0; - -} /* eofn: LIN_MasterSetValue */ - -/*--- eof ---*/ - +/******************************************************************************/ +/*! +\file $URL: https://subversion.eckelmann.local/svn/max/quantron_a/trunk/src/codesys/qa/linbus.c $ + +\brief Modul fuer die LIN-Bus-Kommunikation + +\author $Author: HILTENKA $ +\date $Date: 2011-03-09 17:18:26 +0100 (Mi, 09 Mrz 2011) $ + +\version $Rev: 1700 $ + +\b ECKELMANN INDUSTRIEAUTOMATION, WIESBADEN\n + � Copyright 2010 + +*******************************************************************************/ + +/******************************************************************************* +@Includes +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/* Headerfiles Codesys-Componenten-Lib */ +#include "CmpStd.h" +#include "CmpErrors.h" +#include "CmpItf.h" + +/* Headerfile Dependend */ +#include "linbus_imp.h" +#include "LinbusDep.h" + + + +#define ISBITSET(val, bit) ( ((val) & (1 << (bit)))? 1:0 ) + + + +/**************************/ +/* LIN-Kommandos/Adressen */ +/**************************/ +#define ADDR(x) (x << 2) +#define PID_PARITY(x) (x << 6) + +#define LIN_SLAVE_1 0x0 +#define LIN_SLAVE_2 0x1 +#define LIN_SLAVE_3 0x2 +#define LIN_SLAVE_4 0x3 +#define LIN_SLAVE_5 0x4 +#define LIN_SLAVE_6 0x5 +#define LIN_SLAVE_7 0x6 +#define LIN_SLAVE_8 0x7 +#define LIN_SLAVE_9 0x8 +#define LIN_SLAVE_10 0x9 +#define LIN_SLAVE_11 0xA +#define LIN_SLAVE_12 0xB +#define LIN_SLAVE_13 0xC +#define LIN_SLAVE_14 0xD +#define LIN_MASTER 0xE +#define CMD_FACEVALUE(adr) (ADDR(adr) | 0x0 ) +#define CMD_SETVALUE(adr) (ADDR(adr) | 0x1 ) +#define CMD_RESERVED(adr) (ADDR(adr) | 0x2 ) +#define CMD_VERSION(adr) (ADDR(adr) | 0x3 ) + +#define CMD_MASTER_ALIVE (ADDR(LIN_MASTER) | 0x0 ) +#define CMD_MASTER_SETVALUE (ADDR(LIN_MASTER) | 0x1 ) +#define CMD_RESET_ADDR (ADDR(LIN_MASTER) | 0x3 ) + +/**************************/ +/* LIN-Steuerflags Master */ +/**************************/ +#define LIN_MASTER_INITFLAG 0x02 + +/***********************************/ +/* LIN-Steuerflags Sollwert setzen */ +/***********************************/ +#define LIN_SET_SOLL_POS 0x01 +#define LIN_SET_SLOW 0x02 +#define LIN_SET_MANUAL_OU 0x04 +#define LIN_SET_MANUAL_IN 0x08 +#define LIN_SET_SELFTEST 0x80 + +/*******************/ +/* LIN-Fehlercodes */ +/*******************/ +#define ERR_LIN_DEVICE (-1) +#define ERR_LIN_PORTSETTING (-2) +#define ERR_LIN_BAUDRATE (-3) +#define ERR_LIN_TIMEOUT (-4) +#define ERR_LIN_TIMEOUT_ECHO (-5) +#define ERR_LIN_TIMEOUT_MSG (-6) +#define ERR_LIN_SEND_MESSAGE (-7) +#define ERR_LIN_CHECKSUM (-8) + +/***************/ +/* LIN-Timeout */ +/***************/ +#define LIN_TIMEOUT_ECHO 50 /* 50 ms Timeoutzeit fuer Echobytes */ +#define LIN_TIMEOUT_MESSAGE 100 /* 100 ms Timeoutzeit fuer Clientantwort */ + +/*************************/ +/* Sonstige Definitionen */ +/*************************/ +#define LIN_BAUD_RATE B9600 +#define MAX_LIN_FRAME_BUFFER 30 +#define MAX_LIN_SLAVE 14 +#define LIN_SYNCBYTE 0x55 +#define LIN_TYP_MOTOR 0 +#define LIN_PROTOKOLL_VERS 0 +#define DRV_NAME_LEN 20 +#define LIN_MSG_RETRY 3 + +#ifndef x86 +#define LINTHREAD_PRIO 38 /* RT-Linux; SCHED_FIFO */ +#else +#define LINTHREAD_PRIO 54 /* kein RT-Linux; SCHED_OTHER */ +#endif +#define LINTHREAD_ZYKLUS 10 /* 10ms Zykluszeit */ + +#ifndef x86 +#define RXTHREAD_PRIO 38 /* RT-Linux; SCHED_FIFO */ +#else +#define RXTHREAD_PRIO 54 /* kein RT-Linux; SCHED_OTHER */ +#endif + + +/******************************************************************************* +@Typdefinitionen (modullokal) +*******************************************************************************/ + +typedef struct LIN_SLAVE_DATA_R { + LIN_SLAVE_VERSION_TR tVers; /* Version */ + LIN_SLAVE_VALUE_TR tValue; /* FaceValue */ + unsigned char ucSlaveOnline; /* Verbindungsstatus */ + unsigned char ucSetNewValue; /* Flag fuer neuen Sollwert */ + unsigned short usSetValue; /* Sollwert */ + unsigned char ucSetControl; /* Steuerbits fuer Sollwert */ + unsigned char ucDevice; +} LIN_SLAVE_DATA_TR; + + +/******************************************************************************* +@Konstanten (modullokal) +*******************************************************************************/ + +/* + * Device name, Quantron uses /dev/ttymxc1, Jobrechner /dev/ttymxc3 + */ +static const char cacDeviceName[DRV_NAME_LEN] = { "/dev/ttymxc1"}; + +/******************************************************************************* +@Variablen (modullokal) +*******************************************************************************/ + +/* Variablen Linbus-Schnittstellen */ +static int iLinPort = -1; /* Porthandle */ +static struct termios initial_settings, new_settings; /* Portsettings */ +static speed_t BaudRate; /* Baudrate */ + +/* Variablen Masterthread */ +static RTS_HANDLE rtsMasterThreadHandle = RTS_INVALID_HANDLE; /* Handle MasterThread */ +static char acMasterThreadName[64] = { "LinMasterThread" }; +static int iLinMasterState; /* Zustand Master */ + +/* Variablen Empfangsthread */ +static RTS_HANDLE rtsRxThreadHandle = RTS_INVALID_HANDLE; /* Handle RxThread */ +static char acRxThreadName[64] = { "LinRxThread" }; + +/* Variablen Empfang/Sendefunktion */ +static unsigned char acLinMsgBuffer[MAX_LIN_FRAME_BUFFER]; /* Nachrichtenpuffer */ +static unsigned char acLinRxBuffer[MAX_LIN_FRAME_BUFFER]; /* Empfangspuffer */ +static int iLinRxWrIndex; /* Schreibzeiger Empfangspuffer */ +static int iLinRxRdIndex; /* Lesezeiger Empfangspuffer */ + +/* Zustaende von Master und Slaves */ +static LIN_SLAVE_DATA_TR atLinSlaveData[MAX_LIN_SLAVE]; /* Slavezustaende */ +static int iLinSlaveCnt; /* Anzahl der konfigurieren Slaves */ +static int iLinIntervall; /* Intervall fuer die Bearbeitung des Linbus */ +static int iLinResetAddr; /* Flag fuer das Ruecksetzen der Adressen */ +static int iLinSetAddr; /* Flag fuer das Setzen der Adressen */ +static unsigned char ucLinMasterNewValue; /* Flag fuer neuen Sollwert */ +static unsigned short usLinMasterValue; /* Neuer Sollwert fuer alle Slaves */ +static unsigned char ucLinMasterControl; /* Controlbyte fuer Sollwert aller Slaves */ +static unsigned char ucLinMasterDevice; /* Device Type */ +static int iLinAdrSlaveCnt; /* zu adressierender Lin-Slave */ + + + + + +/******************************************************************************* +@Prototypen der lokalen Funktionen +*******************************************************************************/ +static int lin_getslaveversion( void ); +static int lin_getslavefacevalue( void ); +static int lin_setslavevalue( void ); +static int lin_clrslaveaddr( void ); +static int lin_setslaveaddr( int iSlave ); +static void lin_master_thread(SYS_TASK_PARAM *ptp); +static int lin_missing_slave( void ); +static void lin_rx_thread(SYS_TASK_PARAM *ptp); +static int lin_recv( unsigned char *pucLinData, int iLinByteCnt, int iTimeout ); +static int lin_recv_message( unsigned char *pucLinMsgData, int iLinMsgLen ) ; +static int lin_send( unsigned char *pucLinData, int iLinBytesCnt ); +static int lin_send_breakbyte( void ); +static int lin_send_message( unsigned char *pucLinMsgData, int iLinMsgLen ); +static unsigned char lin_pidbyte( unsigned char ucVal ); +static unsigned char lin_checksum( unsigned char *pucData, int iDataLen ); +static int lin_master_alive( unsigned char ucNextFreeAdr, unsigned char ucSlaves, unsigned char ucAliveFlags ); +static int lin_reset_all( void ); +static int lin_set_value( unsigned char ucAdr, unsigned short usSollPos, unsigned char ucControlFlags, unsigned char ucDeviceTyp ); +static int lin_face_value( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); +static int lin_get_version( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ); +static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult); +static RTS_RESULT CDECL DeleteInstance(IBase *pIBase); +static int CDECL ExportFunctions(void); +static int CDECL ImportFunctions(void); +static RTS_UI32 CDECL CmpGetVersion(void); +static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2); +static void GetQASettings( void ); + +USE_SysSemCreate +USE_SysSemDelete +USE_SysSemEnter +USE_SysSemLeave +USE_SysTaskCreate +USE_SysTaskResume +USE_SysTaskSetExit +USE_SysTaskJoin +USE_SysTaskExit +USE_SysTaskWaitSleep +USE_SysTaskDestroy +USE_SysTaskEnter +USE_SysTaskLeave +USE_SysTaskEnd + + +/******************************************************************************/ +/*! +\fn lin_getslaveversion + +\brief Version aller Slaves auslesen + +\return Anzahl der nicht gefunden Slaves + +\param keine + +*******************************************************************************/ +static int lin_getslaveversion( void ) +{ + int iSlave; + int iRetry; + int iRet; + + int iMissingSlaves = 0; + + for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { + + iRetry = 0; + + do { + /* Version der Slaves auslesen */ + iRet = lin_get_version( LIN_SLAVE_1 + iSlave, &atLinSlaveData[iSlave] ); + if ( iRet < 0 ) { + /* Slave antwortet nicht; nochmal wiederholen */ + iRetry++; + } + } while (( iRet < 0 ) && (iRetry <= LIN_MSG_RETRY ) ); + + if ( iRet < 0 ) { + /* Slave antwortet nicht */ + atLinSlaveData[iSlave].ucSlaveOnline = FALSE; + iMissingSlaves++; + } + else { + atLinSlaveData[iSlave].ucSlaveOnline = TRUE; + } + } + + return iMissingSlaves; + +} /* eofn: lin_getslaveversion */ + +/******************************************************************************/ +/*! +\fn lin_getslavefacevalue + +\brief Istposition aller Slaves auslesen + +\return 0 + +\param keine + +*******************************************************************************/ +static int lin_getslavefacevalue( void ) +{ + int iSlave; + int iRetry; + int iRet; + + int iMissingSlaves = 0; + + for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { + + iRetry = 0; + + do { + /* Version der Slaves auslesen */ + iRet = lin_face_value( LIN_SLAVE_1 + iSlave, &atLinSlaveData[iSlave] ); + if ( iRet < 0 ) { + /* Slave antwortet nicht; nochmal wiederholen */ + iRetry++; + } + } while (( iRet < 0 ) && (iRetry <= LIN_MSG_RETRY ) ); + + if ( iRet < 0 ) { + /* Slave antwortet nicht */ + atLinSlaveData[iSlave].ucSlaveOnline = FALSE; + iMissingSlaves++; + } + else { + atLinSlaveData[iSlave].ucSlaveOnline = TRUE; + } + } + + return iMissingSlaves; + +} /* eofn: lin_getslavefacevalue */ + +/******************************************************************************/ +/*! +\fn lin_setslavevalue + +\brief Sollposition fuer Slaves setzen + +\return keine + +\param keine + +*******************************************************************************/ +static int lin_setslavevalue( void ) +{ + int iSlave; + + /* Masterwert wurde geaendert */ + if ( ucLinMasterNewValue == TRUE ) { + ucLinMasterNewValue = FALSE; + + /* Neue Sollposition fuer alle uebernehmen senden */ + lin_set_value(LIN_MASTER, usLinMasterValue, ucLinMasterControl, ucLinMasterDevice); + } + else { + + for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { + + if ( atLinSlaveData[iSlave].ucSetNewValue == TRUE ) { + atLinSlaveData[iSlave].ucSetNewValue = FALSE; + + /* Neue Sollposition fuer Slave uebernehmen senden */ + lin_set_value(LIN_SLAVE_1 + iSlave, atLinSlaveData[iSlave].usSetValue, atLinSlaveData[iSlave].ucSetControl, atLinSlaveData[iSlave].ucDevice); + } + } + } + + return 0; + +} /* eofn: lin_setslavevalue */ + + +/******************************************************************************/ +/*! +\fn lin_clrslaveaddr + +\brief Slaveadressen neu setzen + +\return kein + +\param keine + +*******************************************************************************/ +static int lin_clrslaveaddr( void ) +{ + int iSlave; + + /* Kommando Reset senden */ + lin_reset_all(); + + /* Alle Slaves alle nicht erkannt markieren */ + for ( iSlave = 0; iSlave < iLinSlaveCnt; iSlave++ ) { + + atLinSlaveData[iSlave].ucSlaveOnline = FALSE; + } + + return 0; + +} /* eofn: lin_clrlaveaddr */ + +/******************************************************************************/ +/*! +\fn lin_setslaveaddr + +\brief Slaveadressen neu setzen + +\return Slavestatus + 0 - Slave nicht vorhanden + -1 - Slave vorhanden + +\param iSlave - Slave + +*******************************************************************************/ +static int lin_setslaveaddr( int iSlave ) +{ + /* Kommando Alive an alle Slaves senden */ + lin_master_alive( iSlave, iLinSlaveCnt, LIN_MASTER_INITFLAG ); + + /* Kommando FaceValue an Slave senden */ + if ( lin_face_value( iSlave, &atLinSlaveData[iSlave] ) < 0 ) { + + atLinSlaveData[iSlave].ucSlaveOnline = FALSE; + return -1; + } + + /* Kommando FaceValue an Slave senden */ + if ( lin_get_version( iSlave, &atLinSlaveData[iSlave] ) < 0 ) { + + atLinSlaveData[iSlave].ucSlaveOnline = FALSE; + return -1; + } + atLinSlaveData[iSlave].ucSlaveOnline = TRUE; + + return 0; + +} /* eofn: lin_setslaveaddr */ + +/******************************************************************************/ +/*! +\fn lin_missing_slave + +\brief Fehlenden Slave suchen + +\return Slavenummer + +\param keine + +*******************************************************************************/ +static int lin_missing_slave( void ) +{ + int iSlave = 0; + + do { + + if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { + + /* Slave ist nicht vorhanden */ + return iSlave; + } + iSlave++; + } while ( iSlave < iLinSlaveCnt ); + + return -1; + +} /* eofn: lin_missing_slave */ + +/******************************************************************************/ +/*! +\fn lin_master_thread + +\brief Protokollverarbeitung Linbus Master + +\return keine + +\param keine + +*******************************************************************************/ +static void lin_master_thread(SYS_TASK_PARAM *ptp) +{ + int iMissingSlaves; + + CAL_SysTaskEnter(ptp->hTask); + + while(!ptp->bExit) { + + #ifdef _DEBUG + printf("Zustand Master : %i\n", iLinMasterState); + printf("\n"); + #endif + + switch ( iLinMasterState ) { + + /*********************************************************************/ + case LIN_MASTER_CHECK : { + /*********************************************************************/ + /* Kommando Alive an alle Slaves senden */ + lin_master_alive( 0, iLinSlaveCnt, 0 ); + + /* Version der Slaves abfragen */ + iMissingSlaves = lin_getslaveversion(); + if ( iMissingSlaves == 1 ) { + + /* fehlenden Slave setzen */ + iLinAdrSlaveCnt = lin_missing_slave(); + + /* Timeout eines Slaves */ + iLinMasterState = LIN_MASTER_INIT; + break; + } + else if ( iMissingSlaves > 1 ) { + + /* Timeout mehrere Slaves */ + iLinMasterState = LIN_MASTER_REPAIR; + break; + } + + /* Slave haben sich gemeldet */ + iLinMasterState = LIN_MASTER_ONLINE; + } break; + + /*********************************************************************/ + case LIN_MASTER_INIT : { + /*********************************************************************/ + + /* Adressen fuer Slaves setzen */ + lin_setslaveaddr( iLinAdrSlaveCnt ); + + /* Version der Slaves abfragen */ + iMissingSlaves = lin_getslaveversion(); + if ( iMissingSlaves == 0 ) { + + /* Alle Slave sind da */ + iLinMasterState = LIN_MASTER_ONLINE; + break; + } + else if ( iMissingSlaves > 1 ) { + + /* Timeout mehrerr Slaves */ + iLinMasterState = LIN_MASTER_REPAIR; + break; + } + + if ( iLinResetAddr == TRUE ) { + iLinResetAddr = FALSE; + iLinSetAddr = FALSE; + + /* Slaveadresse loeschen */ + lin_clrslaveaddr(); + + /* Adressen loeschen */ + iLinMasterState = LIN_MASTER_ADR_CLR; + break; + } + } break; + + /*********************************************************************/ + case LIN_MASTER_ONLINE : { + /*********************************************************************/ + + /* Kommando Alive an alle Slaves senden */ + lin_master_alive( 0, iLinSlaveCnt, 0 ); + + /* Sollwert der Slaves senden */ + lin_setslavevalue(); + + /* Istwert der Slaves abfragen */ + iMissingSlaves = lin_getslavefacevalue(); + if ( iMissingSlaves == 1 ) { + + /* fehlenden Slave setzen */ + iLinAdrSlaveCnt = lin_missing_slave(); + + /* Timeout eines Slaves */ + iLinMasterState = LIN_MASTER_INIT; + break; + } + else if ( iMissingSlaves > 1 ) { + + /* Timeout eines Slaves */ + iLinMasterState = LIN_MASTER_REPAIR; + break; + } + + if ( iLinResetAddr == TRUE ) { + iLinResetAddr = FALSE; + iLinSetAddr = FALSE; + + /* Slaveadresse loeschen */ + lin_clrslaveaddr(); + + /* Adressen loeschen */ + iLinMasterState = LIN_MASTER_ADR_CLR; + break; + } + } break; + + /*********************************************************************/ + case LIN_MASTER_REPAIR : { + /*********************************************************************/ + + if ( iLinResetAddr == TRUE ) { + iLinResetAddr = FALSE; + iLinSetAddr = FALSE; + + /* Slaveadresse loeschen */ + lin_clrslaveaddr(); + + /* Adressen loeschen */ + iLinMasterState = LIN_MASTER_ADR_CLR; + break; + } + /* Version der Slaves abfragen */ + iMissingSlaves = lin_getslaveversion(); + if ( iMissingSlaves == 1 ) { + + /* fehlenden Slave setzen */ + iLinAdrSlaveCnt = lin_missing_slave(); + + /* Timeout eines Slaves */ + iLinMasterState = LIN_MASTER_INIT; + break; + } + + + /* Slave haben sich gemeldet */ + iLinMasterState = LIN_MASTER_ONLINE; + } break; + + /***************************************************************/ + case LIN_MASTER_ADR_CLR : { + /***************************************************************/ + + if ( iLinResetAddr == TRUE ) { + iLinResetAddr = FALSE; + + /* Slaveadresse loeschen */ + lin_clrslaveaddr(); + break; + } + + if ( iLinSetAddr == TRUE ) { + iLinSetAddr = FALSE; + + /* Neuadressierung mit Adresse 0 */ + iLinAdrSlaveCnt = 0; + + /* Warte auf Slave */ + iLinMasterState = LIN_MASTER_WAIT_FOR_SLAVE; + break; + } + } break; + + /***************************************************************/ + case LIN_MASTER_WAIT_FOR_SLAVE : { + /***************************************************************/ + + /* Adressen fuer Slaves setzen */ + lin_setslaveaddr( iLinAdrSlaveCnt ); + + /* pruefen ob Slave erkannt wurde */ + if ( atLinSlaveData[iLinAdrSlaveCnt].ucSlaveOnline == TRUE ) { + + /* naechster Slave */ + iLinAdrSlaveCnt++; + + if ( iLinAdrSlaveCnt == iLinSlaveCnt ) { + + /* alle Slaves adressiert */ + iLinMasterState = LIN_MASTER_ONLINE; + break; + } + } + + if ( iLinResetAddr == TRUE ) { + iLinResetAddr = FALSE; + iLinSetAddr = FALSE; + + /* Slaveadresse loeschen */ + lin_clrslaveaddr(); + + /* Adressen loeschen */ + iLinMasterState = LIN_MASTER_ADR_CLR; + break; + } + } break; + + /***************************************************************/ + default : { + /***************************************************************/ + + } break; + } + + CAL_SysTaskWaitSleep(ptp->hTask, iLinIntervall); + } + + CAL_SysTaskLeave(ptp->hTask); + CAL_SysTaskEnd(ptp->hTask, 0); + + return; + +} /* eofn: lin_master_thread */ + +/******************************************************************************/ +/*! +\fn lin_rx_thread + +\brief Empfangsthread + +\return keine + +\param arg + +*******************************************************************************/ +static void lin_rx_thread(SYS_TASK_PARAM *ptp) +{ + CAL_SysTaskEnter(ptp->hTask); + + while(!ptp->bExit) { + + if ( read( iLinPort, &acLinRxBuffer[iLinRxWrIndex], 1 ) > 0 ) { + iLinRxWrIndex++; + if ( iLinRxWrIndex >= MAX_LIN_FRAME_BUFFER ) { + + iLinRxWrIndex = 0; + } + } + } + + CAL_SysTaskLeave(ptp->hTask); + CAL_SysTaskEnd(ptp->hTask, 0); + + return; + +} /* eofn: lin_rx_thread */ + +/******************************************************************************/ +/*! +\fn lin_recv + +\brief Lin-Bytes empfangen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param pucLinData - Zeiger auf die Daten + iLinByteCnt - Anzahl an Bytes + iTimeout - Timeoutzeit fuer das Lesen + +*******************************************************************************/ +static int lin_recv( unsigned char *pucLinData, int iLinByteCnt, int iTimeout ) +{ + int iTimer = 0; + int iByteCnt = 0; + + do { + + if ( iLinRxRdIndex != iLinRxWrIndex ) { + + pucLinData[iByteCnt] = acLinRxBuffer[iLinRxRdIndex]; + iByteCnt++; + + iLinRxRdIndex++; + if ( iLinRxRdIndex >= MAX_LIN_FRAME_BUFFER ) { + + iLinRxRdIndex = 0; + } + } + else { + + /* Timeoutzeit abwarten */ + //TODO minimal granularity of system timers, CONFIG_HZ=200Hz => 5ms + usleep(1000); + iTimer++; + } + + } while (( iByteCnt < iLinByteCnt ) && ( iTimer < iTimeout )); + + /* pruefen ob alle Bytes gelesen wurden */ + if ( iTimer >= iTimeout ) { + + /* Fehler beim lesen; keine weiteren Bytes mehr lesen */ + iLinRxRdIndex = 0; + iLinRxWrIndex = 0; + return ERR_LIN_TIMEOUT; + } + + return 0; + +} /* eofn: lin_recv */ + +/******************************************************************************/ +/*! +\fn lin_recv_message + +\brief Lin-Message empfangen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param pucLinData - Zeiger auf die Daten + iLinBytesCnt - Anzahl an Bytes + +*******************************************************************************/ +static int lin_recv_message( unsigned char *pucLinMsgData, int iLinMsgLen ) +{ + unsigned char ucChecksum; + int i = 0; + + /************************************/ + /* Response vom Client zuruecklesen */ + /************************************/ + if ( lin_recv( &pucLinMsgData[1], iLinMsgLen-1, LIN_TIMEOUT_MESSAGE ) < 0 ) { + + /* Timeout/Fehler beim Empfang des Response */ + return ERR_LIN_TIMEOUT_MSG; + } + + /****************/ + /* Traceausgabe */ + /****************/ + #ifdef _DEBUG + printf ("REC: "); + for (i = 0; i < iLinMsgLen; i++) + { + printf ("%02x ", pucLinMsgData[i]); + } + printf ("\n"); + #endif + + /*******************************/ + /* Empfangsschecksumme pruefen */ + /*******************************/ + ucChecksum = lin_checksum(pucLinMsgData, iLinMsgLen -1); + if ( ucChecksum != pucLinMsgData[iLinMsgLen-1] ) { + + /* Checksumme ist ungueltig */ + printf("Checksumme ist ungueltig\n"); + /* BUG 1898 - Clean Buffer */ + // Kein Mutex benötigt + iLinRxWrIndex = 0; /* Schreibzeiger Empfangspuffer */ + iLinRxRdIndex = 0; /* Lesezeiger Empfangspuffer */ + /* Clean Buffer */ + + return ERR_LIN_CHECKSUM; + } + + return 0; + +} /* eofn: lin_recv_message */ + +/******************************************************************************/ +/*! +\fn lin_send + +\brief Lin-Bytes senden + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param pcLinData - Zeiger auf die Daten + iLinBytesCnt - Anzahl an Bytes + +*******************************************************************************/ +static int lin_send( unsigned char *pucLinData, int iLinBytesCnt ) +{ + if ( write( iLinPort, pucLinData, iLinBytesCnt ) < 0 ) { + + printf("Fehler beim Senden\n"); + return ERR_LIN_SEND_MESSAGE; + } + + return 0; + +} /* eofn: lin_send */ + +/******************************************************************************/ +/*! +\fn lin_send_breakbyte + +\brief Breakbyte senden + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param keine + +*******************************************************************************/ +static int lin_send_breakbyte( void ) +{ + + unsigned char ucTmp = 0x80; + + tcgetattr(iLinPort, &initial_settings); + new_settings = initial_settings; + + /************************************/ + /* Schnittstelleneinstellung setzen */ + /************************************/ + /* Baudrate */ + if (cfsetspeed(&new_settings, BaudRate-1) != 0) { + + printf("Baudrate kann nicht initialsiert werden\n"); + return ERR_LIN_BAUDRATE; + } + + + cfmakeraw(&new_settings); + + /* Flags */ + new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ + new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ + new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ + new_settings.c_cflag |= CS8; + + if (tcsetattr(iLinPort, TCSANOW, &new_settings) != 0) { + + printf("Schnittstlleneinstellung koennen nicht gesetzt werden\n"); + return ERR_LIN_PORTSETTING; + } + + /********************/ + /* Breakbyte senden */ + /********************/ + lin_send( &ucTmp, 1 ); + + /*************************/ + /* Echobyte zuruecklesen */ + /*************************/ + lin_recv( &ucTmp, 1, LIN_TIMEOUT_ECHO ); + + tcgetattr(iLinPort, &initial_settings); + new_settings = initial_settings; + + /************************************/ + /* Schnittstelleneinstellung setzen */ + /************************************/ + + if (cfsetspeed(&new_settings, BaudRate) != 0) { + return ERR_LIN_BAUDRATE; + } + + cfmakeraw(&new_settings); + + /* Flags */ + new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ + new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ + new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ + new_settings.c_cflag |= CS8; + + if (tcsetattr(iLinPort, TCSADRAIN, &new_settings) != 0) { + + printf("Device konnte nicht initialsiert werden\n"); + return ERR_LIN_PORTSETTING; + } + + return 0; +} /* eofn: lin_send_breakbyte */ + +/******************************************************************************/ +/*! +\fn lin_send_message + +\brief Lin-Message senden + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param pucLinMsgData - Zeiger auf die Daten + iLinMsgLen - Anzahl an Bytes + +*******************************************************************************/ +static int lin_send_message( unsigned char *pucLinMsgData, int iLinMsgLen ) +{ + int iRet = 0; + int i = 0; + + /******************************/ + /* Breakbyte zunaechst senden */ + /******************************/ + if (( iRet = lin_send_breakbyte()) < 0 ) { + + /* Break konnte nicht gesendet werden */ + return iRet; + } + + /******************/ + /* Message senden */ + /******************/ + if (( iRet = lin_send( pucLinMsgData, iLinMsgLen )) < 0 ) { + + /* Message konnte nicht gesendet werden */ + return iRet; + } + + /**************************/ + /* Echobytes zuruecklesen */ + /**************************/ + if ( lin_recv( pucLinMsgData, iLinMsgLen, LIN_TIMEOUT_ECHO ) < 0 ) { + + /* Timeout/Fehler beim Empfang des Echos */ + return ERR_LIN_TIMEOUT_ECHO; + } + + usleep(15000); + /****************/ + /* Traceausgabe */ + /****************/ + #ifdef _DEBUG + printf ("SEND: "); + for (i = 0; i < iLinMsgLen; i++) + { + printf ("%02x ", pucLinMsgData[i]); + } + printf ("\n"); + #endif + + return 0; + +} /* eofn: lin_send_message */ + +/******************************************************************************/ +/*! +\fn lin_pidbyte + +\brief PID-Byte erzeugen + +\return PID-Byte + +\param ucVal - Wert fuer Kommando bzw Adresse + +*******************************************************************************/ +static unsigned char lin_pidbyte( unsigned char ucVal ) +{ + + unsigned char ucTmp = 0; + + if ((ISBITSET(ucVal,0) ^ ISBITSET(ucVal,1) ^ ISBITSET(ucVal,2) ^ ISBITSET(ucVal,4)) != 0 ) { + + ucTmp = 0x01; + } + + if ((ISBITSET(ucVal,1) ^ ISBITSET(ucVal,3) ^ ISBITSET(ucVal,4) ^ ISBITSET(ucVal,5)) == 0 ) { + + ucTmp |= 0x02; + } + + return PID_PARITY(ucTmp) | ucVal; + +} /* eofn: lin_pidbyte */ + +/******************************************************************************/ +/*! +\fn lin_checksum + +\brief Checksumme erzeugen + +\return Checksumme + +\param pucData - Zeiger auf Daten + iDataLen - Datenlaenge + +*******************************************************************************/ +static unsigned char lin_checksum( unsigned char *pucData, int iDataLen ) +{ + unsigned short usTmp = 0; + int i; + + for ( i = 0; i < iDataLen; i++ ) { + + usTmp += pucData[i]; + /* Ueberlauf pruefen */ + if ( usTmp > 0xFF ) { + usTmp &= 0x00FF; + usTmp++; /* Carrybit addrieren */ + } + } + + return (unsigned char)(~usTmp); + +} /* eofn: lin_checksum */ + +/******************************************************************************/ +/*! +\fn lin_master_alive + +\brief Master Alive-Message senden + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param ucNextFreeAdr - Naechste freie Adresse + ucSlaves - Anzahl Teilnehmer + ucAliveFlags - Flags + +*******************************************************************************/ +static int lin_master_alive( unsigned char ucNextFreeAdr, unsigned char ucSlaves, unsigned char ucAliveFlags ) +{ + int iRet; + + /*printf("MasterAlive:\n"); + printf("Naechste freie Adresse : %i\n", ucNextFreeAdr); + printf("Anzahl LIN-Teilnehmer : %i\n", ucSlaves); + printf("Flags : %i\n", ucAliveFlags); + printf("\n");*/ + + /* MasterALive-Message aufbauen */ + acLinMsgBuffer[0] = LIN_SYNCBYTE; + acLinMsgBuffer[1] = lin_pidbyte(CMD_MASTER_ALIVE); + acLinMsgBuffer[2] = ucNextFreeAdr; + acLinMsgBuffer[3] = 1 + ucSlaves; /* Master + Slaves */ + acLinMsgBuffer[4] = ucAliveFlags; + acLinMsgBuffer[5] = LIN_PROTOKOLL_VERS; + acLinMsgBuffer[6] = lin_checksum( &acLinMsgBuffer[1], 5); + iRet = lin_send_message( acLinMsgBuffer, 7 ); + + return iRet; + +} /* eofn: lin_master_alive */ + +/******************************************************************************/ +/*! +\fn lin_reset_all + +\brief Alle Adressen loeschen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param keine + +*******************************************************************************/ +static int lin_reset_all( void ) +{ + int iRet; + + //printf("ResetAll:\n"); + + /* Reset-Message aufbauen */ + acLinMsgBuffer[0] = LIN_SYNCBYTE; + acLinMsgBuffer[1] = lin_pidbyte(CMD_RESET_ADDR); + acLinMsgBuffer[2] = 0x52; + acLinMsgBuffer[3] = 0x45; + acLinMsgBuffer[4] = 0x53; + acLinMsgBuffer[5] = 0x45; + acLinMsgBuffer[6] = 0x54; + acLinMsgBuffer[7] = 0x4E; + acLinMsgBuffer[8] = 0x4F; + acLinMsgBuffer[9] = 0x57; + acLinMsgBuffer[10] = lin_checksum( &acLinMsgBuffer[1], 9); + iRet = lin_send_message( acLinMsgBuffer, 11 ); + + return iRet; + +} /* eofn: lin_reset_all */ + +/******************************************************************************/ +/*! +\fn lin_set_value + +\brief Sollwert setzen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param usAdr - LinAdresse + usSollPos - Sollposition + ucClontrolFlags - Steuerflags + +*******************************************************************************/ +static int lin_set_value( unsigned char ucAdr, unsigned short usSollPos, unsigned char ucControlFlags, unsigned char ucDeviceTyp) +{ + int iRet; + + /* printf("SetValue:\n"); + printf("Slave : %i\n", ucAdr ); + printf("SollPos : %i\n", usSollPos ); + printf("Flags : %i\n", ucControlFlags ); + printf("\n");*/ + + /* SetValue-Message aufbauen */ + acLinMsgBuffer[0] = LIN_SYNCBYTE; + acLinMsgBuffer[1] = lin_pidbyte(CMD_SETVALUE(ucAdr)); + acLinMsgBuffer[2] = ucDeviceTyp; + acLinMsgBuffer[3] = ucControlFlags; + acLinMsgBuffer[4] = (unsigned char)(0x00ff & usSollPos); + acLinMsgBuffer[5] = (unsigned char)( usSollPos >> 8); + acLinMsgBuffer[6] = lin_checksum( &acLinMsgBuffer[1], 5); + iRet = lin_send_message( acLinMsgBuffer, 7 ); + + return iRet; + +} /* eofn: lin_set_value */ + +/******************************************************************************/ +/*! +\fn lin_face_value + +\brief Istwert auslesen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param usAdr - Adresse + ptLinSlaveData - Zeiger auf Slavedaten + +*******************************************************************************/ +static int lin_face_value( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ) +{ + int iRet; + + //printf("FaceValue: \n"); + + /* Face-Message aufbauen */ + acLinMsgBuffer[0] = LIN_SYNCBYTE; + acLinMsgBuffer[1] = lin_pidbyte(CMD_FACEVALUE(ucAdr)); + if (( iRet = lin_send_message( acLinMsgBuffer, 2 )) < 0 ) { + + /* Fehler beim Senden des Kommandos FaceValue */ + return iRet; + } + + /* Response vom Slave auswerten */ + if (( iRet = lin_recv_message( &acLinMsgBuffer[1], 7 )) < 0 ) { + + /* Fehler beim Empfang */ + return iRet; + } + + /* Empfangsdaten uebernehmen */ + ptLinSlaveData->tValue.ucFormat = acLinMsgBuffer[2]; + ptLinSlaveData->tValue.usIstPos = acLinMsgBuffer[3]; + ptLinSlaveData->tValue.usIstPos |= acLinMsgBuffer[4] << 8; + ptLinSlaveData->tValue.ucStatus = acLinMsgBuffer[5]; + ptLinSlaveData->tValue.ucErrorCnt = acLinMsgBuffer[6]; + + //printf("Format : %i\n", ptLinSlaveData->tValue.ucFormat); + //printf("IstPos : %i\n", ptLinSlaveData->tValue.usIstPos); + //printf("Status : %i\n", ptLinSlaveData->tValue.ucStatus); + //printf("Fehler : %i\n", ptLinSlaveData->tValue.ucErrorCnt); + //printf("\n"); + + return 0; + +} /* eofn: lin_face_value */ + +/******************************************************************************/ +/*! +\fn lin_get_version + +\brief Version auslesen + +\return Ergebnis + = 0 - OK + < 0 - Fehler + +\param ucAdr - Adresse + ptLinSlaveData - Zeiger auf Slavedaten + +*******************************************************************************/ +static int lin_get_version( unsigned char ucAdr, LIN_SLAVE_DATA_TR *ptLinSlaveData ) +{ + int iRet; + + //printf("GetVersion %i: \n", ucAdr); + + /* Face-Message aufbauen */ + acLinMsgBuffer[0] = LIN_SYNCBYTE; + acLinMsgBuffer[1] = lin_pidbyte(CMD_VERSION(ucAdr)); + if (( iRet = lin_send_message( acLinMsgBuffer, 2 )) < 0 ) { + + /* Fehler beim Senden des Kommandos GetVersion */ + return iRet; + } + + /* Response vom Slave auswerten */ + if (( iRet = lin_recv_message( &acLinMsgBuffer[1], 10 )) < 0 ) { + + /* Fehler beim Empfang */ + return iRet; + } + + /* Empfangsdaten uebernehmen */ + ptLinSlaveData->tVers.ucRelease = acLinMsgBuffer[2]; + ptLinSlaveData->tVers.ucVersion = acLinMsgBuffer[3]; + ptLinSlaveData->tVers.ucVariant = acLinMsgBuffer[4]; + ptLinSlaveData->tVers.ucFormat = acLinMsgBuffer[5]; + ptLinSlaveData->tVers.usManCode = acLinMsgBuffer[6]; + ptLinSlaveData->tVers.usManCode |= acLinMsgBuffer[7]<<8; + ptLinSlaveData->tVers.usFunction = acLinMsgBuffer[8]; + ptLinSlaveData->tVers.usFunction |= acLinMsgBuffer[9]<<8; + + // printf("Release : %i\n", ptLinSlaveData->tVers.ucRelease); + // printf("Version : %i\n", ptLinSlaveData->tVers.ucVersion); + // printf("Build : %i\n", ptLinSlaveData->tVers.ucVariant); + // printf("Format : %i\n", ptLinSlaveData->tVers.ucFormat); + // printf("ManCode : %i\n", ptLinSlaveData->tVers.usManCode); + // printf("Function: %i\n", ptLinSlaveData->tVers.usFunction); + // printf("\n"); + + return 0; + +} /* eofn: lin_get_version */ + +/******************************************************************************/ +/*! +\fn LIN_Open + +\brief Schnittstelle fuer den LIN-Bus oeffnen + +\return 0 - Schnittstelle konnte geoffnet werden + -1 - Fehler beim Oeffnen + +\param iSlaveCount - Anzahl der Linbus-Slaves + iIntervall - Intervallzeit fuer Lin-Bus-Verarbeitung + +*******************************************************************************/ +int LIN_Open( int iSlaveCount, int iIntervall ) +{ + + + RTS_RESULT rtsResult; + + /* pruefen ob Linbus bereits geoeffnet wurde */ + if ( rtsMasterThreadHandle != RTS_INVALID_HANDLE ) { + /* Linbus schliessen */ + LIN_Close(); + } + + /******************/ + /* Device oeffnen */ + /******************/ + iLinPort = open( cacDeviceName, O_RDWR); + if ( iLinPort < 0 ) { + + printf("Device kann nicht geoeffnet werden\n"); + return ERR_LIN_DEVICE; + } + + tcgetattr(iLinPort, &initial_settings); + new_settings = initial_settings; + + /************************************/ + /* Schnittstelleneinstellung setzen */ + /************************************/ + /* Baudrate */ + BaudRate = LIN_BAUD_RATE; + if (cfsetspeed(&new_settings, BaudRate) != 0) { + return ERR_LIN_BAUDRATE; + } + cfmakeraw(&new_settings); + + /* Flags */ + new_settings.c_cflag &= ~CSTOPB; /* 1 Stopbit */ + new_settings.c_cflag &= ~PARENB; /* keine Paritaet */ + new_settings.c_cflag &= ~CSIZE; /* 8 Datenbits */ + new_settings.c_cflag |= CS8; + + if (tcsetattr(iLinPort, TCSAFLUSH, &new_settings) != 0) { + + printf("Device konnte nicht initialsiert werden\n"); + return ERR_LIN_PORTSETTING; + } + + /*******************************/ + /* Initialisierung uebernehmen */ + /*******************************/ + iLinSlaveCnt = iSlaveCount; + iLinIntervall = iIntervall; + + /*********************************/ + /* Empfangspuffer initialisieren */ + /*********************************/ + iLinRxWrIndex = 0; + iLinRxRdIndex = 0; + + /***************************/ + /* Empfangsthread erzeugen */ + /***************************/ + rtsRxThreadHandle = CAL_SysTaskCreate( acRxThreadName, lin_rx_thread, NULL, RXTHREAD_PRIO, 0, 0, NULL, &rtsResult); + if ((rtsRxThreadHandle == RTS_INVALID_HANDLE) || (rtsResult != ERR_OK)) { + + printf("LIN_Open: Rx-Task kann nicht angelegt werden\n"); + return ERR_LIN_DEVICE; + } + + /* Task starten */ + CAL_SysTaskResume(rtsRxThreadHandle); + + /*************************/ + /* Masterthread erzeugen */ + /*************************/ + rtsMasterThreadHandle = CAL_SysTaskCreate( acMasterThreadName, lin_master_thread, NULL, LINTHREAD_PRIO, 0, 0, NULL, &rtsResult); + if ((rtsMasterThreadHandle == RTS_INVALID_HANDLE) || (rtsResult != ERR_OK)) { + + printf("LIN_Open: Master-Task kann nicht angelegt werden\n"); + return ERR_LIN_DEVICE; + } + + /* Task starten */ + CAL_SysTaskResume(rtsMasterThreadHandle); + iLinMasterState = LIN_MASTER_CHECK; + + return 0; + +} /* eofn: LIN_Open */ + + +/******************************************************************************/ +/*! +\fn LIN_Close + +\brief Schnittstelle fuer den LIN-Bus schliessen + +\return 0 - Schnittstelle konnte geschlossen werden + -1 - Fehler beim Schliessen + +\param keine + +*******************************************************************************/ +int LIN_Close( void ) +{ + + unsigned char ucTmp = 0; + + + /*************************/ + /* Mastertask schliessen */ + /*************************/ + if ( rtsMasterThreadHandle != RTS_INVALID_HANDLE ) { + + CAL_SysTaskSetExit(rtsMasterThreadHandle); + CAL_SysTaskExit(rtsMasterThreadHandle, 1000); + rtsMasterThreadHandle = RTS_INVALID_HANDLE; + } + + /***************************/ + /* Empfangstask schliessen */ + /***************************/ + if ( rtsRxThreadHandle != RTS_INVALID_HANDLE ) { + + //lin_send( &ucTmp, 1 ); /* Dummy-Byte senden um Empfangsthread abzubrechen */ + + CAL_SysTaskSetExit(rtsRxThreadHandle); + CAL_SysTaskExit(rtsRxThreadHandle, 1000); + rtsRxThreadHandle = RTS_INVALID_HANDLE; + } + + /*********************/ + /* Device schliessen */ + /*********************/ + if ( iLinPort >= 0 ) { + + if ( close( iLinPort ) != 0 ) { + + printf("Device kann nicht geschlossen werden\n"); + return ERR_LIN_DEVICE; + } + } + + return 0; + +} /* eofn: LIN_Close */ + +/******************************************************************************/ +/*! +\fn LIN_GetMasterState + +\brief Funktion liefert den Status des Linbus-Master + +\return Status des Linbus-Masters + +\param keine + +*******************************************************************************/ +int LIN_GetMasterState( void ) +{ + return iLinMasterState; + +} /* eofn: LIN_GetMasterState */ + +/******************************************************************************/ +/*! +\fn LIN_GetSlaveState + +\brief Funktion liefert den Status des Linbus-Slave + +\return Status des Linbus-Slave + +\param iSlave - Linbus-Slave + +*******************************************************************************/ +int LIN_GetSlaveState( int iSlave ) +{ + if ( iSlave > MAX_LIN_SLAVE ) { + + return -1; + } + + return atLinSlaveData[iSlave].ucSlaveOnline; + +} /* eofn: LIN_GetSlaveState */ + +/******************************************************************************/ +/*! +\fn LIN_ResetAddress + +\brief Alle Adressen der Linbus-Slaves loeschen + +\return Adressen werden geloescht + 0 - Loeschen wird ausgefuehrt + -1 - Fehler beim Loeschen + +\param keine + +*******************************************************************************/ +int LIN_ResetAddress( void ) +{ + + /* Reset ausfuehren */ + iLinResetAddr = TRUE; + + return 0; + +} /* eofn: LIN_ResetAddress */ + +/******************************************************************************/ +/*! +\fn LIN_SetAddress + +\brief Adressen der Linbus-Slaves neu setzen + +\return Adressen werden gesetzt + 0 - Setzen wird ausgefuehrt + +\param keine + +*******************************************************************************/ +int LIN_SetAddress( void ) +{ + + /* Setzen ausfuehren */ + iLinSetAddr = TRUE; + + return 0; + +} /* eofn: LIN_SetAddress */ + +/******************************************************************************/ +/*! +\fn LIN_GetVersion + +\brief Version des Linbus-Slaves auslesen + +\return Versionsdaten gueltig + 0 - Gueltig + -1 - Ungueltig + +\param iSlave - Linbus-Slave + ptLinSlaveVersion - Zeiger auf Versionsdaten des Slaves + +*******************************************************************************/ +int LIN_GetVersion( int iSlave, LIN_SLAVE_VERSION_TR *ptLinSlaveVersion ) +{ + if ( iSlave > MAX_LIN_SLAVE ) { + + /* Slavenummer ist ungueltig */ + return -1; + } + + if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { + + /* Slave nicht vorhanden; Versioneintrag loeschen */ + memset(&atLinSlaveData[iSlave].tVers, 0, sizeof(LIN_SLAVE_VERSION_TR)); + } + + /* Versionseintrag uebernehmen */ + memcpy( ptLinSlaveVersion, &atLinSlaveData[iSlave].tVers, sizeof(LIN_SLAVE_VERSION_TR)); + + return 0; + +} /* eofn: LIN_GetVersion */ + +/******************************************************************************/ +/*! +\fn LIN_GetFaceValue + +\brief Istwert des Linbus-Slaves auslesen + +\return Istwert des Linbus-Slaves + >=0 - Istwert gueltig + -1 - ungueltiger Wert + +\param iSlave - Linbus-Slave + ptLinSlaveValue - Zeiger auf Istwerte des Slaves + +*******************************************************************************/ +int LIN_GetFaceValue( int iSlave, LIN_SLAVE_VALUE_TR *ptLinSlaveValue ) +{ + + if ( iSlave > MAX_LIN_SLAVE ) { + + return -1; + } + + if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { + + /* Slave nicht vorhanden; Versioneintrag loeschen */ + memset(&atLinSlaveData[iSlave].tValue, 0, sizeof(LIN_SLAVE_VALUE_TR)); + } + + /* Werte uebernehmen */ + memcpy( ptLinSlaveValue, &atLinSlaveData[iSlave].tValue, sizeof(LIN_SLAVE_VALUE_TR)); + + return 0; + +} /* eofn: LIN_GetFaceValue */ + +/******************************************************************************/ +/*! +\fn LIN_SetValue + +\brief Sollwert des Linbus-Slaves setzen + +\return Sollwert wird uebernommen + 0 - Uebernahme wird ausgefuehrt + -1 - Fehler bei der Uebernahme + +\param iSlave - Linbus-Slave + usValue - Sollwert + ucControl - Steuerflags + +*******************************************************************************/ +int LIN_SetValue( int iSlave, unsigned short usValue, unsigned char ucControl, unsigned char ucDevice ) +{ + if ( iSlave > MAX_LIN_SLAVE ) { + + /* Adressierung ungueltig */ + return -1; + } + + if ( atLinSlaveData[iSlave].ucSlaveOnline == FALSE ) { + + /* Slave nicht vorhanden */ + return -1; + } + + /* Werte uebernehmen */ + atLinSlaveData[iSlave].ucSetNewValue = TRUE; + atLinSlaveData[iSlave].usSetValue = usValue; + atLinSlaveData[iSlave].ucSetControl = ucControl; + atLinSlaveData[iSlave].ucDevice = ucDevice; + + return 0; + +} /* eofn: LIN_SetValue */ + +/******************************************************************************/ +/*! +\fn LIN_MasterSetValue + +\brief Sollwert fuer alle Linbus-Slaves setzen + +\return Sollwert wird uebernommen + 0 - Uebernahme wird ausgefuehrt + -1 - Fehler bei der Uebernahme + +\param usValue - Sollwert + ucControl - Steuerflags + +*******************************************************************************/ +int LIN_MasterSetValue( unsigned short usValue, unsigned char ucControl, unsigned char ucDevice ) +{ + if ( iLinMasterState != LIN_MASTER_ONLINE ) { + + /* Master nicht Online */ + return -1; + } + + /* Werte uebernehmen */ + ucLinMasterNewValue = TRUE; + usLinMasterValue = usValue; + ucLinMasterControl = ucControl; + ucLinMasterDevice = ucDevice; + + + return 0; + +} /* eofn: LIN_MasterSetValue */ +/*--- eof ---*/ + diff --git a/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.h b/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.h index e7362c5..4167cf9 100755 --- a/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.h +++ b/ptxdist/local_src/ecu01-codesys/linbus/linbus_imp.h @@ -1,99 +1,99 @@ -/******************************************************************************/ -/*! -\file $URL: https://svn.eckelmann.group/svn/max/quantron_a/trunk/src/codesys/qa/linbus.h $ - -\brief Modul fuer die LIN-Bus-Kommunikation - -\author $Author: gudertm $ -\date $Date: 2015-07-01 15:07:27 +0200 (Mi, 01 Jul 2015) $ - -\version $Rev: 3724 $ - -\b ECKELMANN INDUSTRIEAUTOMATION, WIESBADEN\n - © Copyright 2010 - -*******************************************************************************/ - -#ifndef __LINBUS_H__ -#define __LINBUS_H__ - -/******************************************************************************* -@Includes -*******************************************************************************/ - -/******************************************************************************* -@Konstanten (modulglobal) -*******************************************************************************/ - -/************************/ -/* LIN-Master-Zustaende */ -/************************/ -#define LIN_MASTER_CHECK 0 -#define LIN_MASTER_INIT 1 -#define LIN_MASTER_ONLINE 2 -#define LIN_MASTER_REPAIR 4 -#define LIN_MASTER_ADR_CLR 5 -#define LIN_MASTER_WAIT_FOR_SLAVE 6 - -/******************************************************************************* -@Typdefinitionen (modulglobal) -*******************************************************************************/ - -typedef struct LIN_SLAVE_VERSION_R { - unsigned char ucRelease; /* Software Release */ - unsigned char ucVersion; /* Software Version */ - unsigned char ucVariant; /* Software Variante */ - unsigned char ucFormat; /* Geraetetyp */ - unsigned short usManCode; /* Herstellercode 5248hex */ - unsigned short usFunction; /* Sachnummer */ -} LIN_SLAVE_VERSION_TR; - -typedef struct LIN_SLAVE_VALUE_R { - unsigned char ucFormat; /* Geraetetyp */ - unsigned short usIstPos; /* Istposition */ - unsigned char ucStatus; /* Statusbyte */ - unsigned char ucErrorCnt; /* Fehlerzaehler */ -} LIN_SLAVE_VALUE_TR; - -/******************************************************************************* -@Makros (modulglobal) -*******************************************************************************/ - -/******************************************************************************* -@Prototypen der globalen Funktionen -*******************************************************************************/ - -/* \brief Schnittstelle fuer den LIN-Bus oeffnen */ -int LIN_Open( int iSlaveCount, int iIntervall ); - -/* \brief Schnittstelle fuer den LIN-Bus schliessen */ -int LIN_Close( void ); - -/* \brief Status des Linbus-Master */ -int LIN_GetMasterState( void ); - -/* \brief Status des Linbus-Slaves */ -int LIN_GetSlaveState( int iSlave ); - -/* \brief Alle Adressen der Linbus-Slaves loeschen */ -int LIN_ResetAddress( void ); - -/* \brief Adressen der Linbus-Slaves neu setzen */ -int LIN_SetAddress( void ); - -/* \brief Version des Linbus-Slaves auslesen */ -int LIN_GetVersion( int iSlave, LIN_SLAVE_VERSION_TR *ptLinSlaveVersion ); - -/* \brief Istwert des Linbus-Slaves auslesen */ -int LIN_GetFaceValue( int iSlave, LIN_SLAVE_VALUE_TR *ptLinSlaveValue ); - -/* \brief Sollwert des Linbus-Slaves setzen */ -int LIN_SetValue( int iSlave, unsigned short usValue, unsigned char ucFlags, unsigned char ucDevice ); - -/* \brief Sollwert fuer alle Linbus-Slaves setzen */ -int LIN_MasterSetValue( unsigned short usValue, unsigned char ucFlags, unsigned char ucDevice ); - -#endif /* __LINBUS_H__ */ - -/*--- eof ---*/ - +/******************************************************************************/ +/*! +\file $URL: https://subversion.eckelmann.local/svn/max/quantron_a/trunk/src/codesys/qa/linbus.h $ + +\brief Modul fuer die LIN-Bus-Kommunikation + +\author $Author: HILTENKA $ +\date $Date: 2011-03-04 13:25:07 +0100 (Fr, 04 Mrz 2011) $ + +\version $Rev: 1686 $ + +\b ECKELMANN INDUSTRIEAUTOMATION, WIESBADEN\n + © Copyright 2010 + +*******************************************************************************/ + +#ifndef __LINBUS_H__ +#define __LINBUS_H__ + +/******************************************************************************* +@Includes +*******************************************************************************/ + +/******************************************************************************* +@Konstanten (modulglobal) +*******************************************************************************/ + +/************************/ +/* LIN-Master-Zustaende */ +/************************/ +#define LIN_MASTER_CHECK 0 +#define LIN_MASTER_INIT 1 +#define LIN_MASTER_ONLINE 2 +#define LIN_MASTER_REPAIR 4 +#define LIN_MASTER_ADR_CLR 5 +#define LIN_MASTER_WAIT_FOR_SLAVE 6 + +/******************************************************************************* +@Typdefinitionen (modulglobal) +*******************************************************************************/ + +typedef struct LIN_SLAVE_VERSION_R { + unsigned char ucRelease; /* Software Release */ + unsigned char ucVersion; /* Software Version */ + unsigned char ucVariant; /* Software Variante */ + unsigned char ucFormat; /* Geraetetyp */ + unsigned short usManCode; /* Herstellercode 5248hex */ + unsigned short usFunction; /* Sachnummer */ +} LIN_SLAVE_VERSION_TR; + +typedef struct LIN_SLAVE_VALUE_R { + unsigned char ucFormat; /* Geraetetyp */ + unsigned short usIstPos; /* Istposition */ + unsigned char ucStatus; /* Statusbyte */ + unsigned char ucErrorCnt; /* Fehlerzaehler */ +} LIN_SLAVE_VALUE_TR; + +/******************************************************************************* +@Makros (modulglobal) +*******************************************************************************/ + +/******************************************************************************* +@Prototypen der globalen Funktionen +*******************************************************************************/ + +/* \brief Schnittstelle fuer den LIN-Bus oeffnen */ +int LIN_Open( int iSlaveCount, int iIntervall ); + +/* \brief Schnittstelle fuer den LIN-Bus schliessen */ +int LIN_Close( void ); + +/* \brief Status des Linbus-Master */ +int LIN_GetMasterState( void ); + +/* \brief Status des Linbus-Slaves */ +int LIN_GetSlaveState( int iSlave ); + +/* \brief Alle Adressen der Linbus-Slaves loeschen */ +int LIN_ResetAddress( void ); + +/* \brief Adressen der Linbus-Slaves neu setzen */ +int LIN_SetAddress( void ); + +/* \brief Version des Linbus-Slaves auslesen */ +int LIN_GetVersion( int iSlave, LIN_SLAVE_VERSION_TR *ptLinSlaveVersion ); + +/* \brief Istwert des Linbus-Slaves auslesen */ +int LIN_GetFaceValue( int iSlave, LIN_SLAVE_VALUE_TR *ptLinSlaveValue ); + +/* \brief Sollwert des Linbus-Slaves setzen */ +int LIN_SetValue( int iSlave, unsigned short usValue, unsigned char ucFlags, unsigned char ucDevice ); + +/* \brief Sollwert fuer alle Linbus-Slaves setzen */ +int LIN_MasterSetValue( unsigned short usValue, unsigned char ucFlags, unsigned char ucDevice ); + +#endif /* __LINBUS_H__ */ + +/*--- eof ---*/ +