diff --git a/ptxdist/configs/ecu02/ptxconfig b/ptxdist/configs/ecu02/ptxconfig index 7814817..5ddc16e 100644 --- a/ptxdist/configs/ecu02/ptxconfig +++ b/ptxdist/configs/ecu02/ptxconfig @@ -2220,19 +2220,8 @@ PTXCONF_USBMOUNT_SYSTEMD_UNIT=y # PTXCONF_VPNC is not set # PTXCONF_SMSTOOLS3 is not set # PTXCONF_EUPDATE is not set -PTXCONF_CODESYS3_RT=y -PTXCONF_CODESYS3_RT_ARM=y +# PTXCONF_CODESYS3_RT_ARM is not set # PTXCONF_CODESYS3_RT_X86 is not set -# PTXCONF_CODESYS3_RT_TARGETVISU is not set -# PTXCONF_CODESYS3_RT_DEBUG_VERSION is not set -PTXCONF_CODESYS3_RT_BIN_PATH="/usr/bin" -PTXCONF_CODESYS3_RT_LIB_PATH="/usr/lib" -PTXCONF_CODESYS3_RT_EXECUTABLE="codesyscontrol" -PTXCONF_CODESYS3_RT_HOME="/home" -PTXCONF_CODESYS3_RT_APP="Application.app" -PTXCONF_CODESYS3_RT_OUTPUT="/dev/console" -PTXCONF_CODESYS3_RT_SYSTEMD_UNIT=y -# PTXCONF_CODESYS3_RT_SYSTEMD_MULTIUSER_TARGET is not set # # System Tools @@ -2271,8 +2260,7 @@ PTXCONF_CODESYS3_RT_SYSTEMD_UNIT=y # PTXCONF_ECU_BASICSYS=y # PTXCONF_ECU_EXPLORE is not set -PTXCONF_ECU_CODESYS=y -# PTXCONF_ECU_JOBCTL is not set +PTXCONF_ECU_JOBCTL=y # PTXCONF_ECU_JOBCTL_AXENT is not set # PTXCONF_ECU_JOBCTL_AXIS is not set PTXCONF_ECU_JOBCTL_DEMO=y @@ -2287,10 +2275,10 @@ PTXCONF_ECU_CONTROL=y # PTXCONF_ECU01_CODESYS is not set # PTXCONF_ECU01_MOTOR_CTL is not set # PTXCONF_ECU01_COMP_CAP is not set -# PTXCONF_ECU01_MMC is not set # PTXCONF_LIBVT is not set # PTXCONF_QADRIVER is not set # PTXCONF_POWER_BUTTON is not set +# PTXCONF_ADS7953 is not set # PTXCONF_TESTSTAND is not set # PTXCONF_ECU01_CONTROL is not set diff --git a/ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp b/ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp index 3563e23..23a7d78 100644 --- a/ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp +++ b/ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp @@ -904,47 +904,58 @@ void copyMaxToProcessImage( Ecu02Max116x::MAX116XX_CHANNEL_DATA *max_data ) ECU02_INS->FB_HB_2 = max_data->data[15]; } -void readFeedbackHSPwm( void ) +/* + * This functionality is duplicated in: + * - ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp, function IODriver::readFeedbackHSPwm() + * - ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp, function readFeedbackHSPwm() + */ +void readFeedbackHSPwm(void) { - unsigned long tleFeedbackCh0; - unsigned long tleFeedbackCh1; - unsigned long tleFeedbackCh2; - bool ok1,ok2,ok3; - - ok1 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH0,tleFeedbackCh0 ); - ok2 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH1,tleFeedbackCh1 ); - ok3 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH2,tleFeedbackCh2 ); - if ( ok1 && ok2 && ok3 ){ - - unsigned long currentFeedback0 = (tleFeedbackCh0 & 0x00fff000) >> 12; - unsigned long periodFeedback0 = (tleFeedbackCh0 & 0x00000fff); - unsigned short powerMa0 = 0; - unsigned long currentFeedback1 = (tleFeedbackCh1 & 0x00fff000) >> 12; - unsigned long periodFeedback1 = (tleFeedbackCh1 & 0x00000fff); - unsigned short powerMa1 = 0; - unsigned long currentFeedback2 = (tleFeedbackCh2 & 0x00fff000) >> 12; - unsigned long periodFeedback2 = (tleFeedbackCh2 & 0x00000fff); - unsigned short powerMa2 = 0; - - /* Average load current = 0.75 * CurrentFB / PeriodFB - * 1000 ~ A -> mA - * 3 / 4 ~ 0,75 - */ - if( periodFeedback0 != 0 ){ - powerMa0 = (currentFeedback0 * 3000) / (periodFeedback0 * 4); - } - - if( periodFeedback1 != 0 ){ - powerMa1 = (currentFeedback1 * 3000) / (periodFeedback1 * 4); - } - - if( periodFeedback2 != 0 ){ - powerMa2 = (currentFeedback2 * 3000) / (periodFeedback2 * 4); - } - ECU02_INS->FB_HS_PWM1 = powerMa0; - ECU02_INS->FB_HS_PWM2 = powerMa1; - ECU02_INS->FB_HS_PWM3 = powerMa2; - } + unsigned long currentFeedback0; + unsigned long periodFeedback0; + unsigned long currentFeedback1; + unsigned long periodFeedback1; + unsigned long currentFeedback2; + unsigned long periodFeedback2; + bool ok0, + ok1, + ok2; + unsigned short powerMa0 = 0; + unsigned short powerMa1 = 0; + unsigned short powerMa2 = 0; + + ok0 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH0, currentFeedback0, periodFeedback0); + ok1 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH1, currentFeedback1, periodFeedback1); + ok2 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH2, currentFeedback2, periodFeedback2); + if (!(ok0 && ok1 && ok2)) + return; + + /* + * Average load current = 0.75 * CurrentFB / PeriodFB + * 1000 ~ A -> mA + * 3 / 4 ~ 0,75 + */ +#define AVERAGE_LOAD_CURRENT(currentFeedback, periodFeedback) \ + (((currentFeedback) * 3000UL) / ((periodFeedback) * 4UL)) + + if (periodFeedback0 != 0) + { + powerMa0 = AVERAGE_LOAD_CURRENT(currentFeedback0, periodFeedback0); + } + + if (periodFeedback1 != 0) + { + powerMa1 = AVERAGE_LOAD_CURRENT(currentFeedback1, periodFeedback1); + } + + if (periodFeedback2 != 0) + { + powerMa2 = AVERAGE_LOAD_CURRENT(currentFeedback2, periodFeedback2); + } + + ECU02_INS->FB_HS_PWM1 = powerMa0; + ECU02_INS->FB_HS_PWM2 = powerMa1; + ECU02_INS->FB_HS_PWM3 = powerMa2; } static void threadIO(SYS_TASK_PARAM *ptp) diff --git a/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.cpp b/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.cpp index d70b823..d3c443f 100644 --- a/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.cpp +++ b/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.cpp @@ -319,6 +319,7 @@ unsigned long Ecu02ClkDividerParameters::rawValue() const Ecu02Tle::Ecu02Tle() : _hdl(-1), + _icVersion(0xDEADBEEF), _hdl_mutex() { @@ -343,17 +344,31 @@ Ecu02Tle::~Ecu02Tle() void Ecu02Tle::init(unsigned long value) { - /* value == rawValue of Clk Divider Regsiter */ + /* value == rawValue of Clk Divider Regsiter */ - pthread_mutex_lock(&_hdl_mutex); - _hdl = open( TLE82353SA_DEVICEPATH, O_RDWR ); - if( isOpen() ){ - if( ! TLE82353SA::initTLE( _hdl, value, true, true ) ){ - close(_hdl); - _hdl = -1; - } - } - pthread_mutex_unlock(&_hdl_mutex); + (void)pthread_mutex_lock(&_hdl_mutex); + + _hdl = open( TLE82353SA_DEVICEPATH, O_RDWR ); + if (_hdl >= 0) + { + bool ok = false; + + if (TLE82353SA::initTLE(_hdl, value, true, true)) + { + if (TLE82353SA::readICVersion(_hdl, _icVersion)) + { + ok = true; + } + } + + if (!ok) + { + (void)close(_hdl); + _hdl = -1; + } + } + + (void)pthread_mutex_unlock(&_hdl_mutex); } bool Ecu02Tle::isOpen() const @@ -475,6 +490,52 @@ bool Ecu02Tle::setChannelValue(int channel, int current_value, int pwm_value) return bRet; } + +bool Ecu02Tle::readFeedbackRegister(unsigned char adr, unsigned long ¤tfb_value, unsigned long &periodfb_value) +{ + unsigned long fbrv; /* feedback register value */ + + /* + * Handle a functional change in the TLE82353SA between chip version + * B13 and chip version C11. + * + * In version C11 the "Current FB" value (bits 23:12) of registers 0x40, + * 0x41 and 0x41 needs to be multiplied by factor 2 compared to the older + * chip version B13. + * + * Fortunately the chip version can be used to distinguish between + * both versions via |_icVersion|. + */ + + /* + * |readFeedbackRegister()| is for currentFB registers only, so bail + * out if someone asks for something else we cannot handle + */ + if ((adr != 0x40) && (adr != 0x41) && (adr != 0x42)) + return false; + + if (!readRegister(adr, fbrv)) + return false; + + switch(_icVersion) + { + case 4: /* B13 step = 00000100 */ + currentfb_value = (fbrv & 0x00FFF000) >> 12; + periodfb_value = (fbrv & 0x00000FFF); + return true; + case 6: /* C11 step = 00000110 */ + currentfb_value = (fbrv & 0x00FFF000) >> 12; + periodfb_value = (fbrv & 0x00000FFF); + currentfb_value *= 2; + return true; + default: /* unknown chip version, we return |false| below */ + break; + } + + return false; +} + + /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-* Ecu02Tle *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*/ diff --git a/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.h b/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.h index 224062c..9fff6b6 100644 --- a/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.h +++ b/ptxdist/local_src/ecu-codesys/io_driver/ecu02tle.h @@ -148,8 +148,10 @@ public: bool writeRegister( unsigned char adr, unsigned long value ); bool readRegister( unsigned char adr, unsigned long &value ); + bool readFeedbackRegister(unsigned char adr, unsigned long ¤tfb_value, unsigned long &periodfb_value); + bool setChannelValue(int channel, int current_value, int pwm_value ); - + void init(unsigned long value); private: @@ -157,6 +159,7 @@ private: Ecu02Tle(); int _hdl; + unsigned long _icVersion; pthread_mutex_t _hdl_mutex; }; diff --git a/ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp b/ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp index 6f07f70..2cd095b 100644 --- a/ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp +++ b/ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp @@ -562,47 +562,58 @@ void IODriver::copyMaxToProcessImage( void* t ) } } -void IODriver::readFeedbackHSPwm( void ) +/* + * This functionality is duplicated in: + * - ptxdist/local_src/ecu-jobctl/platform/iodriver/IODriver.cpp, function IODriver::readFeedbackHSPwm() + * - ptxdist/local_src/ecu-codesys/io_driver/IODriverECU02.cpp, function readFeedbackHSPwm() + */ +void IODriver::readFeedbackHSPwm(void) { - unsigned long tleFeedbackCh0; - unsigned long tleFeedbackCh1; - unsigned long tleFeedbackCh2; - bool ok1,ok2,ok3; - - ok1 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH0,tleFeedbackCh0 ); - ok2 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH1,tleFeedbackCh1 ); - ok3 = Ecu02Tle::getInst().readRegister(REGISTER_FEEDBACK_CH2,tleFeedbackCh2 ); - if ( ok1 && ok2 && ok3 ){ - - unsigned long currentFeedback0 = (tleFeedbackCh0 & 0x00fff000) >> 12; - unsigned long periodFeedback0 = (tleFeedbackCh0 & 0x00000fff); - unsigned short powerMa0 = 0; - unsigned long currentFeedback1 = (tleFeedbackCh1 & 0x00fff000) >> 12; - unsigned long periodFeedback1 = (tleFeedbackCh1 & 0x00000fff); - unsigned short powerMa1 = 0; - unsigned long currentFeedback2 = (tleFeedbackCh2 & 0x00fff000) >> 12; - unsigned long periodFeedback2 = (tleFeedbackCh2 & 0x00000fff); - unsigned short powerMa2 = 0; - - /* Average load current = 0.75 * CurrentFB / PeriodFB - * 1000 ~ A . mA - * 3 / 4 ~ 0,75 - */ - if( periodFeedback0 != 0 ){ - powerMa0 = (currentFeedback0 * 3000) / (periodFeedback0 * 4); - } - - if( periodFeedback1 != 0 ){ - powerMa1 = (currentFeedback1 * 3000) / (periodFeedback1 * 4); - } - - if( periodFeedback2 != 0 ){ - powerMa2 = (currentFeedback2 * 3000) / (periodFeedback2 * 4); - } - ECU02_INS.FB_HS_PWM1 = powerMa0; - ECU02_INS.FB_HS_PWM2 = powerMa1; - ECU02_INS.FB_HS_PWM3 = powerMa2; - } + unsigned long currentFeedback0; + unsigned long periodFeedback0; + unsigned long currentFeedback1; + unsigned long periodFeedback1; + unsigned long currentFeedback2; + unsigned long periodFeedback2; + bool ok0, + ok1, + ok2; + unsigned short powerMa0 = 0; + unsigned short powerMa1 = 0; + unsigned short powerMa2 = 0; + + ok0 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH0, currentFeedback0, periodFeedback0); + ok1 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH1, currentFeedback1, periodFeedback1); + ok2 = Ecu02Tle::getInst().readFeedbackRegister(REGISTER_FEEDBACK_CH2, currentFeedback2, periodFeedback2); + if (!(ok0 && ok1 && ok2)) + return; + + /* + * Average load current = 0.75 * CurrentFB / PeriodFB + * 1000 ~ A -> mA + * 3 / 4 ~ 0,75 + */ +#define AVERAGE_LOAD_CURRENT(currentFeedback, periodFeedback) \ + (((currentFeedback) * 3000UL) / ((periodFeedback) * 4UL)) + + if (periodFeedback0 != 0) + { + powerMa0 = AVERAGE_LOAD_CURRENT(currentFeedback0, periodFeedback0); + } + + if (periodFeedback1 != 0) + { + powerMa1 = AVERAGE_LOAD_CURRENT(currentFeedback1, periodFeedback1); + } + + if (periodFeedback2 != 0) + { + powerMa2 = AVERAGE_LOAD_CURRENT(currentFeedback2, periodFeedback2); + } + + ECU02_INS.FB_HS_PWM1 = powerMa0; + ECU02_INS.FB_HS_PWM2 = powerMa1; + ECU02_INS.FB_HS_PWM3 = powerMa2; } diff --git a/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.cpp b/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.cpp index 3e00896..5ca9825 100644 --- a/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.cpp +++ b/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.cpp @@ -319,6 +319,7 @@ unsigned long Ecu02ClkDividerParameters::rawValue() const Ecu02Tle::Ecu02Tle() : _hdl(-1), + _icVersion(0xDEADBEEF), _hdl_mutex() { @@ -343,17 +344,31 @@ Ecu02Tle::~Ecu02Tle() void Ecu02Tle::init(unsigned long value) { - /* value == rawValue of Clk Divider Regsiter */ + /* value == rawValue of Clk Divider Regsiter */ - pthread_mutex_lock(&_hdl_mutex); - _hdl = open( TLE82353SA_DEVICEPATH, O_RDWR ); - if( isOpen() ){ - if( ! TLE82353SA::initTLE( _hdl, value, true, true ) ){ - close(_hdl); - _hdl = -1; - } - } - pthread_mutex_unlock(&_hdl_mutex); + (void)pthread_mutex_lock(&_hdl_mutex); + + _hdl = open( TLE82353SA_DEVICEPATH, O_RDWR ); + if (_hdl >= 0) + { + bool ok = false; + + if (TLE82353SA::initTLE(_hdl, value, true, true)) + { + if (TLE82353SA::readICVersion(_hdl, _icVersion)) + { + ok = true; + } + } + + if (!ok) + { + (void)close(_hdl); + _hdl = -1; + } + } + + (void)pthread_mutex_unlock(&_hdl_mutex); } bool Ecu02Tle::isOpen() const @@ -475,6 +490,52 @@ bool Ecu02Tle::setChannelValue(int channel, int current_value, int pwm_value) return bRet; } + +bool Ecu02Tle::readFeedbackRegister(unsigned char adr, unsigned long ¤tfb_value, unsigned long &periodfb_value) +{ + unsigned long fbrv; /* feedback register value */ + + /* + * Handle a functional change in the TLE82353SA between chip version + * B13 and chip version C11. + * + * In version C11 the "Current FB" value (bits 23:12) of registers 0x40, + * 0x41 and 0x41 needs to be multiplied by factor 2 compared to the older + * chip version B13. + * + * Fortunately the chip version can be used to distinguish between + * both versions via |_icVersion|. + */ + + /* + * |readFeedbackRegister()| is for currentFB registers only, so bail + * out if someone asks for something else we cannot handle + */ + if ((adr != 0x40) && (adr != 0x41) && (adr != 0x42)) + return false; + + if (!readRegister(adr, fbrv)) + return false; + + switch(_icVersion) + { + case 4: /* B13 step = 00000100 */ + currentfb_value = (fbrv & 0x00FFF000) >> 12; + periodfb_value = (fbrv & 0x00000FFF); + return true; + case 6: /* C11 step = 00000110 */ + currentfb_value = (fbrv & 0x00FFF000) >> 12; + periodfb_value = (fbrv & 0x00000FFF); + currentfb_value *= 2; + return true; + default: /* unknown chip version, we return |false| below */ + break; + } + + return false; +} + + /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-* Ecu02Tle *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*/ diff --git a/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.h b/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.h index 224062c..db65a02 100644 --- a/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.h +++ b/ptxdist/local_src/ecu-jobctl/platform/iodriver/ecu02tle.h @@ -147,7 +147,9 @@ public: bool writeRegister( unsigned char adr, unsigned long value ); bool readRegister( unsigned char adr, unsigned long &value ); - + + bool readFeedbackRegister(unsigned char adr, unsigned long ¤tfb_value, unsigned long &periodfb_value); + bool setChannelValue(int channel, int current_value, int pwm_value ); void init(unsigned long value); @@ -157,6 +159,7 @@ private: Ecu02Tle(); int _hdl; + unsigned long _icVersion; pthread_mutex_t _hdl_mutex; }; diff --git a/ptxdist/rules/ecu-codesys.make b/ptxdist/rules/ecu-codesys.make index 5d2b021..df0efb9 100644 --- a/ptxdist/rules/ecu-codesys.make +++ b/ptxdist/rules/ecu-codesys.make @@ -102,7 +102,8 @@ $(STATEDIR)/ecu-codesys.targetinstall: @$(call install_replace, ecu-codesys, /sbin/update-ecu-codesys-application.sh, @ECU_PATH_ON_STICK@, "ecu02" ) @$(call install_copy, ecu-codesys, 0, 0, 0755, $(ECU_CODESYS_DIR)/90_update_codesys_application, /etc/usbmount/mount.d/90_update_codesys_application) - @$(call install_link, ecu-codesys, /lib/systemd/system/codesys3-rt.service, /etc/systemd/system/application.target.wants/codesys3-rt.service) +# service disabled for teststand usage +# @$(call install_link, ecu-codesys, /lib/systemd/system/codesys3-rt.service, /etc/systemd/system/application.target.wants/codesys3-rt.service) @$(call install_finish, ecu-codesys)